xymon-4.3.30/0000775000076400007640000000000013534041775013214 5ustar rpmbuildrpmbuildxymon-4.3.30/lib/0000775000076400007640000000000013534041774013761 5ustar rpmbuildrpmbuildxymon-4.3.30/lib/osdefs.c0000664000076400007640000000227511615341300015400 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* Compatibility definitions for various OS's */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #include #include #include #include "osdefs.h" #ifndef HAVE_SNPRINTF int snprintf(char *str, size_t size, const char *format, ...) { va_list args; va_start(args, format); return vsprintf(str, format, args); } #endif #ifndef HAVE_VSNPRINTF int vsnprintf(char *str, size_t size, const char *format, va_list args) { return vsprintf(str, format, args); } #endif xymon-4.3.30/lib/sha1.c0000664000076400007640000002004411535462534014761 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was taken from the */ /* "mutt" source archive and adapted for use in Xymon. According to the */ /* copyright notice in the "mutt" version, this file is public domain. */ /*----------------------------------------------------------------------------*/ /* SHA-1 in C By Steve Reid , with small changes to make it fit into mutt by Thomas Roessler . 100% Public Domain. Test Vectors (from FIPS PUB 180-1) "abc" A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 A million repetitions of "a" 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #include typedef unsigned int uint32_t; typedef struct { uint32_t state[5]; uint32_t count[2]; unsigned char buffer[64]; } SHA1_CTX; #if !defined(XYMON_BIG_ENDIAN) && !defined(XYMON_LITTLE_ENDIAN) #error "Endianness is UNDEFINED" #endif #define SHA1HANDSOFF #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #ifdef XYMON_BIG_ENDIAN # define blk0(i) block->l[i] #else # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |(rol(block->l[i],8)&0x00FF00FF)) #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); /* Hash a single 512-bit block. This is the core of the algorithm. */ static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) { uint32_t a, b, c, d, e; typedef union { unsigned char c[64]; uint32_t l[16]; } CHAR64LONG16; #ifdef SHA1HANDSOFF CHAR64LONG16 block[1]; /* use array to appear as a pointer */ memcpy(block, buffer, 64); #else /* The following had better never be used because it causes the * pointer-to-const buffer to be cast into a pointer to non-const. * And the result is written through. I threw a "const" in, hoping * this will cause a diagnostic. */ CHAR64LONG16* block = (const CHAR64LONG16*)buffer; #endif /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; #ifdef SHA1HANDSOFF memset(block, '\0', sizeof(block)); #endif } /* SHA1Init - Initialize new context */ static void SHA1Init(SHA1_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ static void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) { uint32_t i; uint32_t j; j = context->count[0]; if ((context->count[0] += len << 3) < j) context->count[1]++; context->count[1] += (len>>29); j = (j >> 3) & 63; if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1Transform(context->state, &data[i]); } j = 0; } else i = 0; memcpy(&context->buffer[j], &data[i], len - i); } /* Add padding and return the message digest. */ static void SHA1Final(unsigned char digest[20], SHA1_CTX* context) { unsigned i; unsigned char finalcount[8]; unsigned char c; #if 0 /* untested "improvement" by DHR */ /* Convert context->count to a sequence of bytes * in finalcount. Second element first, but * big-endian order within element. * But we do it all backwards. */ unsigned char *fcp = &finalcount[8]; for (i = 0; i < 2; i++) { uint32_t t = context->count[i]; int j; for (j = 0; j < 4; t >>= 8, j++) *--fcp = (unsigned char) t } #else for (i = 0; i < 8; i++) { finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } #endif c = 0200; SHA1Update(context, &c, 1); while ((context->count[0] & 504) != 448) { c = 0000; SHA1Update(context, &c, 1); } SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ memset(context, '0', sizeof(*context)); memset(&finalcount, '\0', sizeof(finalcount)); } /* * Not part of the original file. Added for use with Xymon, * to avoid namespace-pollution when compiled with OpenSSL. */ int mySHA1_Size(void) { return sizeof(SHA1_CTX); } void mySHA1_Init(void* context) { SHA1Init((SHA1_CTX *)context); } void mySHA1_Update(void* context, const unsigned char* data, uint32_t len) { SHA1Update((SHA1_CTX *)context, data, len); } void mySHA1_Final(unsigned char digest[20], void* context) { SHA1Final(digest, (SHA1_CTX *)context); } #ifdef STANDALONE #include #include #include int main(int argc, char *argv[]) { FILE *fd; int n; unsigned char buf[8192]; void *context; unsigned char digest[20]; int i; fd = fopen(argv[1], "r"); if (fd == NULL) return 1; context = (void *)malloc(mySHA1_Size()); mySHA1_Init(context); while ((n = fread(buf, 1, sizeof(buf), fd)) > 0) mySHA1_Update(context, buf, n); fclose(fd); mySHA1_Final(digest, context); for (i=0; (i < sizeof(digest)); i++) { printf("%02x", digest[i]); } printf("\n"); return 0; } #endif xymon-4.3.30/lib/rmdconst.h0000664000076400007640000002162511535462534015771 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was taken from the */ /* FreeBSD sources. It was originally written by Eric Young, and is NOT */ /* licensed under the GPL. Please adhere the original copyright notice below. */ /*----------------------------------------------------------------------------*/ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #define KL0 0x00000000L #define KL1 0x5A827999L #define KL2 0x6ED9EBA1L #define KL3 0x8F1BBCDCL #define KL4 0xA953FD4EL #define KR0 0x50A28BE6L #define KR1 0x5C4DD124L #define KR2 0x6D703EF3L #define KR3 0x7A6D76E9L #define KR4 0x00000000L #define WL00 0 #define SL00 11 #define WL01 1 #define SL01 14 #define WL02 2 #define SL02 15 #define WL03 3 #define SL03 12 #define WL04 4 #define SL04 5 #define WL05 5 #define SL05 8 #define WL06 6 #define SL06 7 #define WL07 7 #define SL07 9 #define WL08 8 #define SL08 11 #define WL09 9 #define SL09 13 #define WL10 10 #define SL10 14 #define WL11 11 #define SL11 15 #define WL12 12 #define SL12 6 #define WL13 13 #define SL13 7 #define WL14 14 #define SL14 9 #define WL15 15 #define SL15 8 #define WL16 7 #define SL16 7 #define WL17 4 #define SL17 6 #define WL18 13 #define SL18 8 #define WL19 1 #define SL19 13 #define WL20 10 #define SL20 11 #define WL21 6 #define SL21 9 #define WL22 15 #define SL22 7 #define WL23 3 #define SL23 15 #define WL24 12 #define SL24 7 #define WL25 0 #define SL25 12 #define WL26 9 #define SL26 15 #define WL27 5 #define SL27 9 #define WL28 2 #define SL28 11 #define WL29 14 #define SL29 7 #define WL30 11 #define SL30 13 #define WL31 8 #define SL31 12 #define WL32 3 #define SL32 11 #define WL33 10 #define SL33 13 #define WL34 14 #define SL34 6 #define WL35 4 #define SL35 7 #define WL36 9 #define SL36 14 #define WL37 15 #define SL37 9 #define WL38 8 #define SL38 13 #define WL39 1 #define SL39 15 #define WL40 2 #define SL40 14 #define WL41 7 #define SL41 8 #define WL42 0 #define SL42 13 #define WL43 6 #define SL43 6 #define WL44 13 #define SL44 5 #define WL45 11 #define SL45 12 #define WL46 5 #define SL46 7 #define WL47 12 #define SL47 5 #define WL48 1 #define SL48 11 #define WL49 9 #define SL49 12 #define WL50 11 #define SL50 14 #define WL51 10 #define SL51 15 #define WL52 0 #define SL52 14 #define WL53 8 #define SL53 15 #define WL54 12 #define SL54 9 #define WL55 4 #define SL55 8 #define WL56 13 #define SL56 9 #define WL57 3 #define SL57 14 #define WL58 7 #define SL58 5 #define WL59 15 #define SL59 6 #define WL60 14 #define SL60 8 #define WL61 5 #define SL61 6 #define WL62 6 #define SL62 5 #define WL63 2 #define SL63 12 #define WL64 4 #define SL64 9 #define WL65 0 #define SL65 15 #define WL66 5 #define SL66 5 #define WL67 9 #define SL67 11 #define WL68 7 #define SL68 6 #define WL69 12 #define SL69 8 #define WL70 2 #define SL70 13 #define WL71 10 #define SL71 12 #define WL72 14 #define SL72 5 #define WL73 1 #define SL73 12 #define WL74 3 #define SL74 13 #define WL75 8 #define SL75 14 #define WL76 11 #define SL76 11 #define WL77 6 #define SL77 8 #define WL78 15 #define SL78 5 #define WL79 13 #define SL79 6 #define WR00 5 #define SR00 8 #define WR01 14 #define SR01 9 #define WR02 7 #define SR02 9 #define WR03 0 #define SR03 11 #define WR04 9 #define SR04 13 #define WR05 2 #define SR05 15 #define WR06 11 #define SR06 15 #define WR07 4 #define SR07 5 #define WR08 13 #define SR08 7 #define WR09 6 #define SR09 7 #define WR10 15 #define SR10 8 #define WR11 8 #define SR11 11 #define WR12 1 #define SR12 14 #define WR13 10 #define SR13 14 #define WR14 3 #define SR14 12 #define WR15 12 #define SR15 6 #define WR16 6 #define SR16 9 #define WR17 11 #define SR17 13 #define WR18 3 #define SR18 15 #define WR19 7 #define SR19 7 #define WR20 0 #define SR20 12 #define WR21 13 #define SR21 8 #define WR22 5 #define SR22 9 #define WR23 10 #define SR23 11 #define WR24 14 #define SR24 7 #define WR25 15 #define SR25 7 #define WR26 8 #define SR26 12 #define WR27 12 #define SR27 7 #define WR28 4 #define SR28 6 #define WR29 9 #define SR29 15 #define WR30 1 #define SR30 13 #define WR31 2 #define SR31 11 #define WR32 15 #define SR32 9 #define WR33 5 #define SR33 7 #define WR34 1 #define SR34 15 #define WR35 3 #define SR35 11 #define WR36 7 #define SR36 8 #define WR37 14 #define SR37 6 #define WR38 6 #define SR38 6 #define WR39 9 #define SR39 14 #define WR40 11 #define SR40 12 #define WR41 8 #define SR41 13 #define WR42 12 #define SR42 5 #define WR43 2 #define SR43 14 #define WR44 10 #define SR44 13 #define WR45 0 #define SR45 13 #define WR46 4 #define SR46 7 #define WR47 13 #define SR47 5 #define WR48 8 #define SR48 15 #define WR49 6 #define SR49 5 #define WR50 4 #define SR50 8 #define WR51 1 #define SR51 11 #define WR52 3 #define SR52 14 #define WR53 11 #define SR53 14 #define WR54 15 #define SR54 6 #define WR55 0 #define SR55 14 #define WR56 5 #define SR56 6 #define WR57 12 #define SR57 9 #define WR58 2 #define SR58 12 #define WR59 13 #define SR59 9 #define WR60 9 #define SR60 12 #define WR61 7 #define SR61 5 #define WR62 10 #define SR62 15 #define WR63 14 #define SR63 8 #define WR64 12 #define SR64 8 #define WR65 15 #define SR65 5 #define WR66 10 #define SR66 12 #define WR67 4 #define SR67 9 #define WR68 1 #define SR68 12 #define WR69 5 #define SR69 5 #define WR70 8 #define SR70 14 #define WR71 7 #define SR71 6 #define WR72 6 #define SR72 8 #define WR73 2 #define SR73 13 #define WR74 13 #define SR74 6 #define WR75 14 #define SR75 5 #define WR76 0 #define SR76 15 #define WR77 3 #define SR77 13 #define WR78 9 #define SR78 11 #define WR79 11 #define SR79 11 xymon-4.3.30/lib/notifylog.h0000664000076400007640000000203111615341300016122 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __NOTIFYLOG_H_ #define __NOTIFYLOG_H_ extern void do_notifylog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pagematch, char *expagematch, char *hostmatch, char *exhostmatch, char *testmatch, char *extestmatch, char *rcptmatch, char *exrcptmatch); #endif xymon-4.3.30/lib/availability.c0000664000076400007640000004425413531275564016613 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file contains code to calculate availability percentages and do */ /* SLA calculations. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: availability.c 8081 2019-08-27 18:50:28Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" typedef struct { int dow; time_t start, end; } reptime_t; static reptime_t reptimes[10]; static int reptimecnt = 0; replog_t *reploghead = NULL; /* TODO: This logic differs from elsewhere below */ char *durationstr(time_t duration) { static char dur[100]; char dhelp[100]; if (duration <= 0) { strncpy(dur, "none", sizeof(dur)); } else { dur[0] = '\0'; if (duration > 86400) { snprintf(dhelp, 100, "%u days ", (unsigned int)(duration / 86400)); duration %= 86400; strncpy(dur, dhelp, 100); } snprintf(dhelp, 100, "%u:%02u:%02u", (unsigned int)(duration / 3600), (unsigned int)((duration % 3600) / 60), (unsigned int)(duration % 60)); strncat(dur, dhelp, (100 - strlen(dur))); } return dur; } static time_t secs(int hour, int minute, int sec) { return (hour*3600 + minute*60 + sec); } static void build_reportspecs(char *reporttime) { /* Timespec: W:HHMM:HHMM */ char *spec, *timespec; int dow, start, end; int found; reptimecnt = 0; spec = strchr(reporttime, '='); timespec = strdup(spec ? (spec+1) : reporttime); spec = strtok(timespec, ","); while (spec) { if (*spec == '*') { dow = -1; found = sscanf(spec+1, ":%d:%d", &start, &end); } else if ((*spec == 'W') || (*spec == 'w')) { dow = -2; found = sscanf(spec+1, ":%d:%d", &start, &end); } else { found = sscanf(spec, "%d:%d:%d", &dow, &start, &end); } if (found < 2) { errprintf("build_reportspecs: Found too few items in %s\n", spec); } reptimes[reptimecnt].dow = dow; reptimes[reptimecnt].start = secs((start / 100), (start % 100), 0); reptimes[reptimecnt].end = secs((end / 100), (end % 100), 0); reptimecnt++; spec = strtok(NULL, ","); } xfree(timespec); } static unsigned long reportduration_oneday(int eventdow, time_t eventstart, time_t eventend) { int i; unsigned long result = 0; for (i=0; (i= 1) && (eventdow <= 5)) ) { if ((reptimes[i].start > eventend) || (reptimes[i].end < eventstart)) { /* Outside our window */ } else { time_t winstart, winend; winstart = ((eventstart < reptimes[i].start) ? reptimes[i].start : eventstart); winend = ((eventend > reptimes[i].end) ? reptimes[i].end : eventend); result += (winend - winstart); } } } return result; } static unsigned long reportingduration(time_t eventstart, time_t eventduration) { struct tm start, end; time_t eventend; unsigned long result; memcpy(&start, localtime(&eventstart), sizeof(start)); eventend = eventstart + eventduration; memcpy(&end, localtime(&eventend), sizeof(end)); if ((start.tm_mday == end.tm_mday) && (start.tm_mon == end.tm_mon) && (start.tm_year == end.tm_year)) result = reportduration_oneday(start.tm_wday, secs(start.tm_hour, start.tm_min, start.tm_sec), secs(end.tm_hour, end.tm_min, end.tm_sec)); else { int fulldays = (eventduration - (86400-secs(start.tm_hour, start.tm_min, start.tm_sec))) / 86400; int curdow = (start.tm_wday == 6) ? 0 : (start.tm_wday+1); result = reportduration_oneday(start.tm_wday, secs(start.tm_hour, start.tm_min, start.tm_sec), 86400); while (fulldays) { result += reportduration_oneday(curdow, 0, 86400); curdow = (curdow == 6) ? 0 : (curdow+1); fulldays--; } result += reportduration_oneday(curdow, 0, secs(end.tm_hour, end.tm_min, end.tm_sec)); } return result; } static char *parse_histlogfile(char *hostname, char *servicename, char *timespec) { char cause[MAX_LINE_LEN]; char fn[PATH_MAX]; char *p; FILE *fd; char l[MAX_LINE_LEN]; int causefull = 0; cause[0] = '\0'; snprintf(fn, PATH_MAX, "%s/%s", xgetenv("XYMONHISTLOGS"), commafy(hostname)); for (p = strrchr(fn, '/'); (*p); p++) if (*p == ',') *p = '_'; snprintf(p, (PATH_MAX - (p - fn)), "/%s/%s", servicename, timespec); dbgprintf("Looking at history logfile %s\n", fn); fd = fopen(fn, "r"); if (fd != NULL) { while (!causefull && fgets(l, MAX_LINE_LEN, fd)) { p = strchr(l, '\n'); if (p) *p = '\0'; if ((l[0] == '&') && (strncmp(l, "&green", 6) != 0)) { p = skipwhitespace(skipword(l)); if ((strlen(cause) + strlen(p) + strlen("
\n") + 1) < MAX_LINE_LEN) { strncat(cause, p, (MAX_LINE_LEN - strlen(cause))); strncat(cause, "
\n", (MAX_LINE_LEN - strlen(cause))); } else causefull = 1; } } #if 1 if (strlen(cause) == 0) { strncpy(cause, "See detailed log", MAX_LINE_LEN); } #else /* What is this code supposed to do ? The sscanf seemingly never succeeds */ /* storner, 2006-06-02 */ if (strlen(cause) == 0) { int offset; rewind(fd); if (fgets(l, MAX_LINE_LEN, fd)) { p = strchr(l, '\n'); if (p) *p = '\0'; if (sscanf(l, "%*s %*s %*s %*s %*s %*s %*s %n", &offset) == 1) { strncpy(cause, l+offset, MAX_LINE_LEN); } else { errprintf("Scan of file %s failed, l='%s'\n", fn, l); } cause[MAX_LINE_LEN-1] = '\0'; } } #endif if (causefull) { cause[MAX_LINE_LEN - strlen(" [Truncated]") - 1] = '\0'; strncat(cause, " [Truncated]", (MAX_LINE_LEN - strlen(cause))); } fclose(fd); } else { strncpy(cause, "No historical status available", MAX_LINE_LEN); } return strdup(cause); } static char *get_historyline(char *buf, int bufsize, FILE *fd, int *err, char *colstr, unsigned int *start, unsigned int *duration, int *scanres) { int ok; do { ok = 1; if (fgets(buf, bufsize, fd) == NULL) { return NULL; } if (strlen(buf) < 25) { ok = 0; *err += 1; dbgprintf("Bad history line (short): %s\n", buf); continue; } *scanres = sscanf(buf+25, "%s %u %u", colstr, start, duration); if (*scanres < 2) { ok = 0; *err += 1; dbgprintf("Bad history line (missing items): %s\n", buf); continue; } if (parse_color(colstr) == -1) { ok = 0; *err += 1; dbgprintf("Bad history line (bad color string): %s\n", buf); continue; } } while (!ok); return buf; } static int scan_historyfile(FILE *fd, time_t fromtime, time_t totime, char *buf, size_t bufsize, time_t *starttime, time_t *duration, char *colstr, unsigned int colstr_buflen) { time_t start, dur; unsigned int uistart, uidur; int scanres; int err = 0; /* * Format of history entries: * asctime-stamp newcolor starttime [duration] */ /* Is start of history after our report-end time ? */ rewind(fd); if (!get_historyline(buf, bufsize, fd, &err, colstr, &uistart, &uidur, &scanres)) { *starttime = getcurrenttime(NULL); *duration = 0; strncpy(colstr, "clear", colstr_buflen); return err; } if (scanres == 2) uidur = getcurrenttime(NULL)-uistart; start = uistart; dur = uidur; if (start > totime) { *starttime = start; *duration = dur; strncpy(colstr, "clear", colstr_buflen); return 0; } /* First, do a quick scan through the file to find the approximate position where we should start */ while ((start+dur) < fromtime) { if (get_historyline(buf, bufsize, fd, &err, colstr, &uistart, &uidur, &scanres)) { start = uistart; dur = uidur; if (scanres == 2) dur = getcurrenttime(NULL) - start; if (scanres >= 2) { dbgprintf("Skipped to entry starting %lu\n", start); if ((start + dur) < fromtime) { fseeko(fd, 2048, SEEK_CUR); if (!fgets(buf, bufsize, fd)) {}; /* Skip partial line */ } } } else { start = getcurrenttime(NULL); dur = 0; } }; /* We know the start position of the logfile is between current pos and (current-~2048 bytes) */ if (ftello(fd) < 2300) rewind(fd); else { fseeko(fd, -2300, SEEK_CUR); if (!fgets(buf, bufsize, fd)) {}; /* Skip partial line */ } /* Read one line at a time until we hit start of our report period */ do { if (get_historyline(buf, bufsize, fd, &err, colstr, &uistart, &uidur, &scanres)) { start = uistart; dur = uidur; if (scanres == 2) dur = getcurrenttime(NULL) - start; dbgprintf("Got entry starting %lu lasting %lu\n", start, dur); } else { start = getcurrenttime(NULL); dur = 0; } } while ((start+dur) < fromtime); dbgprintf("Reporting starts with this entry: %s\n", buf); *starttime = start; *duration = dur; return err; } static char *timename(char *timestring) { static char timespec[26]; char *timecopy; char *tokens[5]; int i; /* Compute the timespec string used as the name of the historical logfile */ *timespec = '\0'; timecopy = strdup(timestring); tokens[0] = tokens[1] = tokens[2] = tokens[3] = tokens[4] = NULL; tokens[0] = strtok(timecopy, " "); i = 0; while (tokens[i] && (i < 4)) { i++; tokens[i] = strtok(NULL, " "); } if (tokens[4]) { /* Got all 5 elements */ snprintf(timespec, 25, "%s_%s_%s_%s_%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]); } else { errprintf("Bad timespec in history file: %s\n", timestring); } xfree(timecopy); return timespec; } int parse_historyfile(FILE *fd, reportinfo_t *repinfo, char *hostname, char *servicename, time_t fromtime, time_t totime, int for_history, double warnlevel, double greenlevel, int warnstops, char *reporttime) { char l[MAX_LINE_LEN]; time_t starttime, duration; unsigned int uistart, uidur; char colstr[MAX_LINE_LEN]; int color, done, i, scanres; int fileerrors = 0; repinfo->fstate = "OK"; repinfo->withreport = 0; repinfo->reportstart = getcurrenttime(NULL); for (i=0; (icount[i] = 0; repinfo->fullduration[i] = 0; repinfo->fullpct[i] = 0.0; repinfo->reportduration[i] = 0; repinfo->reportpct[i] = 0.0; } repinfo->fullavailability = 0.0; repinfo->reportavailability = 0.0; repinfo->fullstops = 0; repinfo->reportstops = 0; if (reporttime) build_reportspecs(reporttime); /* Sanity check */ if (totime > getcurrenttime(NULL)) totime = getcurrenttime(NULL); /* If for_history and fromtime is 0, don't do any seeking */ if (!for_history || (fromtime > 0)) { fileerrors = scan_historyfile(fd, fromtime, totime, l, MAX_LINE_LEN, &starttime, &duration, colstr, MAX_LINE_LEN); } else { /* Already positioned (probably in a pipe) */ if (get_historyline(l, MAX_LINE_LEN, fd, &fileerrors, colstr, &uistart, &uidur, &scanres)) { starttime = uistart; duration = uidur; if (scanres == 2) duration = getcurrenttime(NULL) - starttime; } else { starttime = getcurrenttime(NULL); duration = 0; strncpy(colstr, "clear", MAX_LINE_LEN); fileerrors = 1; } } if (starttime > totime) { repinfo->fullavailability = repinfo->reportavailability = 100.0; repinfo->fullpct[COL_CLEAR] = repinfo->reportpct[COL_CLEAR] = 100.0; repinfo->count[COL_CLEAR] = 1; return COL_CLEAR; } /* If event starts before our fromtime, adjust starttime and duration */ if (starttime < fromtime) { duration -= (fromtime - starttime); starttime = fromtime; } repinfo->reportstart = starttime; done = 0; do { /* If event ends after our reportend, adjust duration */ if ((starttime + duration) > totime) duration = (totime - starttime); strncat(colstr, " ", (MAX_LINE_LEN - strlen(colstr))); color = parse_color(colstr); if (color != -1) { unsigned long sladuration = 0; dbgprintf("In-range entry starting %lu lasting %lu color %d: %s", starttime, duration, color, l); repinfo->count[color]++; repinfo->fullduration[color] += duration; if (color > COL_YELLOW) repinfo->fullstops++; if (reporttime) { sladuration = reportingduration(starttime, duration); repinfo->reportduration[color] += sladuration; if ((color > COL_YELLOW) && (sladuration > 0)) repinfo->reportstops++; } if (for_history || ((hostname != NULL) && (servicename != NULL))) { replog_t *newentry; char *timespec = timename(l); newentry = (replog_t *) malloc(sizeof(replog_t)); newentry->starttime = starttime; newentry->duration = duration; newentry->color = color; newentry->affectssla = (reporttime && (sladuration > 0)); if (!for_history && timespec && (color != COL_GREEN)) { newentry->cause = parse_histlogfile(hostname, servicename, timespec); } else newentry->cause = ""; newentry->timespec = (timespec ? strdup(timespec): NULL); newentry->next = reploghead; reploghead = newentry; } } if ((starttime + duration) < totime) { if (get_historyline(l, MAX_LINE_LEN, fd, &fileerrors, colstr, &uistart, &uidur, &scanres)) { starttime = uistart; duration = uidur; if (scanres == 2) duration = getcurrenttime(NULL) - starttime; } else done = 1; } else done = 1; } while (!done); for (i=0; (ifullduration[i]); repinfo->fullpct[i] = (100.0*repinfo->fullduration[i] / (totime - repinfo->reportstart)); } repinfo->fullavailability = 100.0 - repinfo->fullpct[COL_RED]; if (reporttime) { repinfo->withreport = 1; duration = repinfo->reportduration[COL_GREEN] + repinfo->reportduration[COL_YELLOW] + repinfo->reportduration[COL_RED] + repinfo->reportduration[COL_CLEAR]; if (duration > 0) { repinfo->reportpct[COL_GREEN] = (100.0*repinfo->reportduration[COL_GREEN] / duration); repinfo->reportpct[COL_YELLOW] = (100.0*repinfo->reportduration[COL_YELLOW] / duration); repinfo->reportpct[COL_RED] = (100.0*repinfo->reportduration[COL_RED] / duration); repinfo->reportpct[COL_CLEAR] = (100.0*repinfo->reportduration[COL_CLEAR] / duration); repinfo->reportavailability = 100.0 - repinfo->reportpct[COL_RED] - repinfo->reportpct[COL_CLEAR]; if (repinfo->reportavailability > greenlevel) color = COL_GREEN; else if (repinfo->reportavailability >= warnlevel) color = COL_YELLOW; else color = COL_RED; if ((warnstops >= 0) && (repinfo->reportstops > warnstops)) color = COL_RED; } else { /* Reporting period has no match with REPORTTIME setting */ repinfo->reportpct[COL_CLEAR] = 100.0; repinfo->reportavailability = 100.0; color = COL_GREEN; } } else { if (repinfo->fullavailability > greenlevel) color = COL_GREEN; else if (repinfo->fullavailability >= warnlevel) color = COL_YELLOW; else color = COL_RED; if ((warnstops >= 0) && (repinfo->fullstops > warnstops)) color = COL_RED; /* Copy the full percentages/durations to the SLA ones */ repinfo->reportavailability = repinfo->fullavailability; repinfo->reportstops = repinfo->fullstops; for (i=0; (ireportduration[i] = repinfo->fullduration[i]; repinfo->reportpct[i] = repinfo->fullpct[i]; } } if (fileerrors) repinfo->fstate = "NOTOK"; return color; } replog_t *save_replogs(void) { replog_t *tmp = reploghead; reploghead = NULL; return tmp; } void restore_replogs(replog_t *head) { reploghead = head; } int history_color(FILE *fd, time_t snapshot, time_t *starttime, char **histlogname) { char l[MAX_LINE_LEN]; time_t duration; char colstr[MAX_LINE_LEN]; int color; char *p; *histlogname = NULL; scan_historyfile(fd, snapshot, snapshot, l, MAX_LINE_LEN, starttime, &duration, colstr, MAX_LINE_LEN); strncat(colstr, " ", (MAX_LINE_LEN - strlen(colstr))); color = parse_color(colstr); if ((color == COL_PURPLE) || (color == -1)) { color = -2; } p = timename(l); if (p) *histlogname = strdup(p); return color; } #ifdef STANDALONE time_t reportstart, reportend; double reportgreenlevel = 99.995; double reportwarnlevel = 98.0; int warnstops = -1; int main(int argc, char *argv[]) { FILE *fd; reportinfo_t repinfo; int i, color; char *p, *hostsvc, *host, *svc; replog_t *rwalk; debug=1; if (argc != 4) { fprintf(stderr, "Usage: %s HISTFILE STARTTIME ENDTIME\n", argv[0]); fprintf(stderr, "Start- and end-times are in Unix epoch format - date +%%s\n"); return 1; } fd = fopen(argv[1], "r"); if (fd == NULL) { printf("Cannot open %s\n", argv[1]); exit(1); } reportstart = atol(argv[2]); reportend = atol(argv[3]); hostsvc = strdup(argv[1]); p = strrchr(hostsvc, '.'); *p = '\0'; svc = p+1; p = strrchr(hostsvc, '/'); host = p+1; while ((p = strchr(host, ','))) *p = '.'; color = parse_historyfile(fd, &repinfo, host, svc, reportstart, reportend, 0, reportwarnlevel, reportgreenlevel, warnstops, NULL); for (i=0; (inext) { char start[MAXDURSIZE]; char end[MAXDURSIZE]; char dur[MAXDURSIZE], dhelp[MAXDURSIZE]; time_t endtime; time_t duration; strftime(start, MAXDURSIZE, "%a %b %d %H:%M:%S %Y", localtime(&rwalk->starttime)); endtime = rwalk->starttime + rwalk->duration; strftime(end, MAXDURSIZE, "%a %b %d %H:%M:%S %Y", localtime(&endtime)); duration = rwalk->duration; dur[0] = '\0'; if (duration > 86400) { snprintf(dhelp, MAXDURSIZE, "%lu days ", (duration / 86400)); duration %= 86400; strncpy(dur, dhelp, MAXDURSIZE); } snprintf(dhelp, MAXDURSIZE, "%lu:%02lu:%02lu", duration / 3600, ((duration % 3600) / 60), (duration % 60)); strncat(dur, dhelp, (MAXDURSIZE - strlen(dur))); dbgprintf("Start: %s, End: %s, Color: %s, Duration: %s, Cause: %s\n", start, end, colorname(rwalk->color), dur, rwalk->cause); } return 0; } #endif xymon-4.3.30/lib/memory.c0000664000076400007640000001464513515623702015443 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains memory management routines. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: memory.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #define LIB_MEMORY_C_COMPILE 1 #include "libxymon.h" #ifdef MEMORY_DEBUG static xmemory_t *mhead = NULL; static xmemory_t *dmem; static void *allocend, *copyend; #endif #ifdef MEMORY_DEBUG void add_to_memlist(void *ptr, size_t memsize) { xmemory_t *newitem; newitem = (xmemory_t *)malloc(sizeof(xmemory_t)); newitem->sdata = ptr; newitem->ssize = memsize; newitem->next = mhead; mhead = newitem; } static void dump_memitems(void) { xmemory_t *mwalk; for (mwalk = mhead; (mwalk); mwalk = mwalk->next) { errprintf("%8x : %5d\n", mwalk->sdata, mwalk->ssize); } } static xmemory_t *find_in_memlist(void *ptr) { xmemory_t *mwalk = mhead; int found = 0; while (mwalk) { found = (((void *)ptr >= (void *)mwalk->sdata) && ((void *)ptr < (void *)(mwalk->sdata + mwalk->ssize))); if (found) return mwalk; mwalk = mwalk->next; } return NULL; } void remove_from_memlist(void *ptr) { xmemory_t *mwalk, *mitem; if (ptr == NULL) { errprintf("remove_from_memlist called with NULL pointer\n"); dump_memitems(); abort(); } mitem= find_in_memlist(ptr); if (mitem == NULL) { errprintf("remove_from_memlist called with bogus pointer\n"); abort(); } if (mitem == mhead) { mhead = mhead->next; free(mitem); } else { for (mwalk = mhead; (mwalk->next != mitem); mwalk = mwalk->next) ; mwalk->next = mitem->next; free(mitem); } } #endif const char *xfreenullstr = "xfree: Trying to free a NULL pointer\n"; void *xcalloc(size_t nmemb, size_t size) { void *result; result = calloc(nmemb, size); if (result == NULL) { errprintf("xcalloc: Out of memory!\n"); abort(); } #ifdef MEMORY_DEBUG add_to_memlist(result, nmemb*size); #endif return result; } void *xmalloc(size_t size) { void *result; result = malloc(size); if (result == NULL) { errprintf("xmalloc: Out of memory!\n"); abort(); } #ifdef MEMORY_DEBUG add_to_memlist(result, size); #endif return result; } void *xrealloc(void *ptr, size_t size) { void *result; if (ptr == NULL) { errprintf("xrealloc: Cannot realloc NULL pointer\n"); abort(); } #ifdef MEMORY_DEBUG dmem = find_in_memlist(ptr); if (dmem == NULL) { errprintf("xrealloc: Called with bogus pointer\n"); abort(); } #endif result = realloc(ptr, size); if (result == NULL) { errprintf("xrealloc: Out of memory!\n"); abort(); } #ifdef MEMORY_DEBUG dmem->sdata = result; dmem->ssize = size; #endif return result; } char *xstrdup(const char *s) { char *result; if (s == NULL) { errprintf("xstrdup: Cannot dup NULL string\n"); abort(); } result = strdup(s); if (result == NULL) { errprintf("xstrdup: Out of memory\n"); abort(); } #ifdef MEMORY_DEBUG add_to_memlist(result, strlen(result)+1); #endif return result; } char *xstrncat(char *dest, const char *src, size_t maxlen) { if (src == NULL) { errprintf("xstrncat: NULL destination\n"); abort(); } if (dest == NULL) { errprintf("xstrncat: NULL destination\n"); abort(); } #ifdef MEMORY_DEBUG dmem = find_in_memlist(dest); if (dmem == NULL) { errprintf("xstrncat: Bogus destination\n"); abort(); } allocend = dmem->sdata + dmem->ssize - 1; if (strlen(src) <= maxlen) copyend = dest + strlen(dest) + strlen(src); else copyend = dest + strlen(dest) + maxlen; if ((void *)copyend > (void *)allocend) { errprintf("xstrncat: Potential overwrite of %d bytes\n", (copyend - allocend)); abort(); } if (strlen(dest) + strlen(src) >= maxlen) { errprintf("xstrncat: destination is not NULL terminated - dst '%s', src '%s', max %d\n", dest, src, maxlen); } #endif strncat(dest, src, maxlen); return dest; } char *xstrncpy(char *dest, const char *src, size_t maxlen) { if (src == NULL) { errprintf("xstrncpy: NULL destination\n"); abort(); } if (dest == NULL) { errprintf("xstrncpy: NULL destination\n"); abort(); } #ifdef MEMORY_DEBUG dmem = find_in_memlist(dest); if (dmem == NULL) { errprintf("xstrncpy: Bogus destination\n"); abort(); } allocend = dmem->sdata + dmem->ssize - 1; if (strlen(src) <= maxlen) copyend = dest + strlen(src); else copyend = dest + maxlen; if ((void *)copyend > (void *)allocend) { errprintf("xstrncpy: Potential overwrite of %d bytes\n", (copyend - allocend)); abort(); } if (strlen(src) >= maxlen) { errprintf("xstrncpy: destination is not NULL terminated - src '%s', max %d\n", dest, src, maxlen); } #endif strncpy(dest, src, maxlen); return dest; } int xsprintf(char *dest, const char *fmt, ...) { va_list args; size_t printedbytes; #ifdef MEMORY_DEBUG size_t availablebytes; #endif if (dest == NULL) { errprintf("xsprintf: NULL destination\n"); abort(); } #ifdef MEMORY_DEBUG dmem = find_in_memlist(dest); if (dmem == NULL) { errprintf("xsprintf: Bogus destination\n"); abort(); } availablebytes = (dmem->sdata + dmem->ssize - dest); va_start(args, fmt); printedbytes = vsnprintf(dest, availablebytes, fmt, args); va_end(args); if (printedbytes >= availablebytes) { errprintf("xsprintf: Output was truncated\n"); abort(); } #else va_start(args, fmt); printedbytes = vsprintf(dest, fmt, args); va_end(args); #endif return printedbytes; } char *xresultbuf(int maxsz) { static char rrbuf[10000]; static char *rrbufnext = rrbuf; char *result; if ((rrbufnext + maxsz) >= (rrbuf + sizeof(rrbuf))) result = rrbufnext = rrbuf; else { result = rrbufnext; rrbufnext += maxsz; } return result; } xymon-4.3.30/lib/osdefs.h0000664000076400007640000000230111615341300015373 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* Compatibility definitions for various OS's */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LIBXYMON_OSDEFS_H__ #define __LIBXYMON_OSDEFS_H__ #include "config.h" #include #include #ifndef HAVE_SOCKLEN_T typedef unsigned int socklen_t; #endif #ifndef HAVE_SNPRINTF extern int snprintf(char *str, size_t size, const char *format, ...); #endif #ifndef HAVE_VSNPRINTF extern int vsnprintf(char *str, size_t size, const char *format, va_list ap); #endif #endif xymon-4.3.30/lib/calc.c0000664000076400007640000001102011615341300015003 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: calc.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include "libxymon.h" long compute(char *expression, int *error) { /* * This routine evaluates an expression. * * Expressions are of the form "expr [operator expr]" or "(expr)" * "operator" is + - / * % & | && || > >= < <= == * * All operators have equal precedence! * */ char *exp, *startp, *operator; char *inp, *outp; char op; long xval, yval, result; if (*error) return -1; /* Copy expression except whitespace */ exp = (char *) malloc(strlen(expression)+1); inp = expression; outp=exp; do { if (!isspace((int) *inp)) { *outp = *inp; outp++; } inp++; } while (*inp); *outp = '\0'; /* First find the value of the first sub-expression */ startp = exp; while (isspace((int) *startp)) startp++; if (*startp == '(') { /* Starts with parentheses: * - find matching end parentheses * - find the operator following the end parentheses * - compute value of expression inside parentheses (recursive call) */ int pcount = 1; char *endp; for (endp = startp+1; (*endp && pcount); ) { if (*endp == '(') pcount++; else if (*endp == ')') pcount--; if (pcount) endp++; } if (*endp == '\0') { *error = 1; return -1; } operator = endp+1; *endp = '\0'; xval = compute(startp+1, error); } else { /* No parentheses --> it's a number */ xval = strtol(startp, &operator, 10); if (operator == startp) { *error = 2; return -1; } } /* Now loop over the following operators and expressions */ do { /* There may not be an operator */ if (*operator) { while (isspace((int) *operator)) operator++; op = *operator; /* For the && and || operators ... */ if ((op == '&') && (*(operator+1) == '&')) { op = 'a'; operator++; } else if ((op == '|') && (*(operator+1) == '|')) { op = 'o'; operator++; } else if ((op == '>') && (*(operator+1) == '=')) { op = 'g'; operator++; } else if ((op == '<') && (*(operator+1) == '=')) { op = 'l'; operator++; } else if ((op == '=') && (*(operator+1) == '=')) { op = 'e'; operator++; } /* Since there is an operator, there must be a value after the operator */ startp = operator + 1; while (isspace((int) *startp)) startp++; if (*startp == '(') { int pcount = 1; char *endp; for (endp = startp+1; (*endp && pcount);) { if (*endp == '(') pcount++; else if (*endp == ')') pcount--; if (pcount) endp++; } operator = endp+1; *endp = '\0'; yval = compute(startp+1, error); } else { yval = strtol(startp, &operator, 10); if (operator == startp) { *error = 3; return -1; } } switch (op) { case '+': xval = (xval + yval); break; case '-': xval = (xval - yval); break; case '*': xval = (xval * yval); break; case '/': if (yval) xval = (xval / yval); else { *error = 10; return -1; } break; case '%': if (yval) xval = (xval % yval); else { *error = 10; return -1; } break; case '&': xval = (xval & yval); break; case 'a': xval = (xval && yval); break; case '|': xval = (xval | yval); break; case 'o': xval = (xval || yval); break; case '>': xval = (xval > yval); break; case 'g': xval = (xval >= yval); break; case '<': xval = (xval < yval); break; case 'l': xval = (xval <= yval); break; case 'e': xval = (xval == yval); break; default : { *error = 4; return -1; } } } else { /* Do nothing - no operator, so result is the xval */ } result = xval; } while (*operator); xfree(exp); return result; } #ifdef STANDALONE int main(int argc, char *argv[]) { long result; int error = 0; result = compute(argv[1], &error); printf("%s = %ld\n", argv[1], result); return error; } #endif xymon-4.3.30/lib/sha2.h0000664000076400007640000001106612000300516014746 0ustar rpmbuildrpmbuild/* * FIPS 180-2 SHA-224/256/384/512 implementation * Last update: 02/02/2007 * Issue date: 04/30/2005 * * Copyright (C) 2005, 2007 Olivier Gay * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef SHA2_H #define SHA2_H #define SHA224_DIGEST_SIZE ( 224 / 8) #define SHA256_DIGEST_SIZE ( 256 / 8) #define SHA384_DIGEST_SIZE ( 384 / 8) #define SHA512_DIGEST_SIZE ( 512 / 8) #define SHA256_BLOCK_SIZE ( 512 / 8) #define SHA512_BLOCK_SIZE (1024 / 8) #define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE #define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE #ifndef SHA2_TYPES #define SHA2_TYPES typedef unsigned char uint8; typedef unsigned int uint32; typedef unsigned long long uint64; #endif #ifdef __cplusplus extern "C" { #endif typedef struct { unsigned int tot_len; unsigned int len; unsigned char block[2 * SHA256_BLOCK_SIZE]; uint32 h[8]; } sha256_ctx; typedef struct { unsigned int tot_len; unsigned int len; unsigned char block[2 * SHA512_BLOCK_SIZE]; uint64 h[8]; } sha512_ctx; typedef sha512_ctx sha384_ctx; typedef sha256_ctx sha224_ctx; extern void sha224_init(sha224_ctx *ctx); extern void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len); extern void sha224_final(sha224_ctx *ctx, unsigned char *digest); extern void sha224(const unsigned char *message, unsigned int len, unsigned char *digest); extern void sha256_init(sha256_ctx * ctx); extern void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len); extern void sha256_final(sha256_ctx *ctx, unsigned char *digest); extern void sha256(const unsigned char *message, unsigned int len, unsigned char *digest); extern void sha384_init(sha384_ctx *ctx); extern void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len); extern void sha384_final(sha384_ctx *ctx, unsigned char *digest); extern void sha384(const unsigned char *message, unsigned int len, unsigned char *digest); extern void sha512_init(sha512_ctx *ctx); extern void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len); extern void sha512_final(sha512_ctx *ctx, unsigned char *digest); extern void sha512(const unsigned char *message, unsigned int len, unsigned char *digest); extern int mySHA224_Size(void); extern void mySHA224_Init(void *c); extern void mySHA224_Update(void *c, unsigned char *in, int len); extern void mySHA224_Final(char md[20], void *c); extern int mySHA256_Size(void); extern void mySHA256_Init(void *c); extern void mySHA256_Update(void *c, unsigned char *in, int len); extern void mySHA256_Final(char md[20], void *c); extern int mySHA384_Size(void); extern void mySHA384_Init(void *c); extern void mySHA384_Update(void *c, unsigned char *in, int len); extern void mySHA384_Final(char md[20], void *c); extern int mySHA512_Size(void); extern void mySHA512_Init(void *c); extern void mySHA512_Update(void *c, unsigned char *in, int len); extern void mySHA512_Final(char md[20], void *c); #ifdef __cplusplus } #endif #endif /* !SHA2_H */ xymon-4.3.30/lib/holidays.h0000664000076400007640000000307511615341300015735 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HOLIDAYS_H__ #define __HOLIDAYS_H__ typedef struct holiday_t { enum { HOL_ABSOLUTE, HOL_EASTER, HOL_ADVENT, HOL_MON_AFTER, HOL_TUE_AFTER, HOL_WED_AFTER, HOL_THU_AFTER, HOL_FRI_AFTER, HOL_SAT_AFTER, HOL_SUN_AFTER, HOL_MON, HOL_TUE, HOL_WED, HOL_THU, HOL_FRI, HOL_SAT, HOL_SUN } holtype; char *desc; /* description */ int month; /* month for absolute date */ int day; /* day for absolute date or offset for type 2 and 3 */ int yday; /* day of the year this holiday occurs in current year */ int year; /* year for absolute date */ struct holiday_t *next; } holiday_t; extern int load_holidays(int year); extern int getweekdayorholiday(char *key, struct tm *t); extern char *isholiday(char *key, int dayinyear); extern void printholidays(char *key, strbuffer_t *buf, int mfirst, int mlast); #endif xymon-4.3.30/lib/xymond_ipc.c0000664000076400007640000001531012656200750016271 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This module implements the setup/teardown of the xymond communications */ /* channel, using standard System V IPC mechanisms: Shared memory and */ /* semaphores. */ /* */ /* The concept is to use a shared memory segment for each "channel" that */ /* xymond supports. This memory segment is used to pass a single xymond */ /* message between the xymond master daemon, and the xymond_channel workers. */ /* Two semaphores are used to synchronize between the master daemon and the */ /* workers, i.e. the workers wait for a semaphore to go up indicating that a */ /* new message has arrived, and the master daemon then waits for the other */ /* semaphore to go 0 indicating that the workers have read the message. A */ /* third semaphore is used as a simple counter to tell how many workers have */ /* attached to a channel. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_ipc.c 7891 2016-02-08 21:00:24Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_ipc.h" #define FEEDBACKQUEUE_MODE 0620 char *channelnames[C_LAST+1] = { "", /* First one is index 0 - not used */ "status", "stachg", "page", "data", "notes", "enadis", "client", "clichg", "user", "feedback", NULL }; xymond_channel_t *setup_channel(enum msgchannels_t chnid, int role) { key_t key; struct stat st; struct sembuf s; xymond_channel_t *newch; unsigned int bufsz; int flags = ((role == CHAN_MASTER) ? (IPC_CREAT | 0600) : 0); char *xymonhome = xgetenv("XYMONHOME"); if ( (xymonhome == NULL) || (stat(xymonhome, &st) == -1) ) { errprintf("XYMONHOME not defined, or points to invalid directory - cannot continue.\n"); return NULL; } bufsz = 1024*shbufsz(chnid); dbgprintf("Setting up %s channel (id=%d)\n", channelnames[chnid], chnid); dbgprintf("calling ftok('%s',%d)\n", xymonhome, chnid); key = ftok(xymonhome, chnid); if (key == -1) { errprintf("Could not generate shmem key based on %s: %s\n", xymonhome, strerror(errno)); return NULL; } dbgprintf("ftok() returns: 0x%X\n", key); newch = (xymond_channel_t *)malloc(sizeof(xymond_channel_t)); newch->seq = 0; newch->channelid = chnid; newch->msgcount = 0; newch->shmid = shmget(key, bufsz, flags); if (newch->shmid == -1) { errprintf("Could not get shm of size %d: %s\n", bufsz, strerror(errno)); xfree(newch); return NULL; } dbgprintf("shmget() returns: 0x%X\n", newch->shmid); newch->channelbuf = (char *) shmat(newch->shmid, NULL, 0); if (newch->channelbuf == (char *)-1) { errprintf("Could not attach shm %s\n", strerror(errno)); if (role == CHAN_MASTER) shmctl(newch->shmid, IPC_RMID, NULL); xfree(newch); return NULL; } newch->semid = semget(key, 3, flags); if (newch->semid == -1) { errprintf("Could not get sem: %s\n", strerror(errno)); shmdt(newch->channelbuf); if (role == CHAN_MASTER) shmctl(newch->shmid, IPC_RMID, NULL); xfree(newch); return NULL; } if (role == CHAN_CLIENT) { /* * Clients must register their presence. * We use SEM_UNDO; so if the client crashes, it wont leave a stale count. */ s.sem_num = CLIENTCOUNT; s.sem_op = +1; s.sem_flg = SEM_UNDO; if (semop(newch->semid, &s, 1) == -1) { errprintf("Could not register presence: %s\n", strerror(errno)); shmdt(newch->channelbuf); xfree(newch); return NULL; } } else if (role == CHAN_MASTER) { int n; n = semctl(newch->semid, CLIENTCOUNT, GETVAL); if (n > 0) { errprintf("FATAL: xymond sees clientcount %d, should be 0\nCheck for hanging xymond_channel processes or stale semaphores\n", n); shmdt(newch->channelbuf); shmctl(newch->shmid, IPC_RMID, NULL); semctl(newch->semid, 0, IPC_RMID); xfree(newch); return NULL; } } #ifdef MEMORY_DEBUG add_to_memlist(newch->channelbuf, bufsz); #endif return newch; } void close_channel(xymond_channel_t *chn, int role) { if (chn == NULL) return; /* No need to de-register, this happens automatically because we registered with SEM_UNDO */ if (role == CHAN_MASTER) semctl(chn->semid, 0, IPC_RMID); MEMUNDEFINE(chn->channelbuf); shmdt(chn->channelbuf); if (role == CHAN_MASTER) shmctl(chn->shmid, IPC_RMID, NULL); } int setup_feedback_queue(int role) { char *xymonhome = xgetenv("XYMONHOME"); struct stat st; key_t key; int flags = ((role == CHAN_MASTER) ? (IPC_CREAT | FEEDBACKQUEUE_MODE) : 0); int queueid; if ( (xymonhome == NULL) || (stat(xymonhome, &st) == -1) ) { errprintf("XYMONHOME not defined, or points to invalid directory - cannot continue.\n"); return -1; } key = ftok(xymonhome, C_FEEDBACK_QUEUE); if (key == -1) { errprintf("Could not generate backfeed key based on %s: %s\n", xymonhome, strerror(errno)); return -1; } queueid = msgget(key, flags); if ((role == CHAN_MASTER) && (queueid == -1)) { /* Check if the permissions simply don't match, and re-create if necessary */ if ((errno == EACCES) && (msgget(key, 0) != -1)) { errprintf("BFQ 0x%X already existed but did not match expected permissions; recreating\n", key); } if (msgctl(msgget(key, 0), IPC_RMID, NULL) != 0) errprintf("Existing BFQ 0x%X could not be removed: %s\n", key, strerror(errno)); /* try creating again */ queueid = msgget(key, flags); } if ((queueid == -1) && (errno != ENOENT)) errprintf("Could not retrieve BFQ ID from key 0x%X: %s\n", key, strerror(errno)); dbgprintf(" setup_feedback_queue: got ID %d for key 0x%X\n", queueid, key); return queueid; } void close_feedback_queue(int queueid, int role) { int n; if ((queueid >= 0) && (role == CHAN_MASTER)) { n = msgctl(queueid, IPC_RMID, NULL); if (n) errprintf("Error closing BFQ (%d): %s\n", queueid, strerror(errno)); } } xymon-4.3.30/lib/strfunc.h0000664000076400007640000000431413515623702015614 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __STRFUNC_H__ #define __STRFUNC_H__ extern strbuffer_t *newstrbuffer(int initialsize); extern strbuffer_t *convertstrbuffer(char *buffer, int bufsz); extern void addtobuffer(strbuffer_t *buf, char *newtext); extern void addtobuffer_many(strbuffer_t *buf, ...); extern void addtostrbuffer(strbuffer_t *buf, strbuffer_t *newtext); extern void addtobufferraw(strbuffer_t *buf, char *newdata, int bytes); extern void clearstrbuffer(strbuffer_t *buf); extern void freestrbuffer(strbuffer_t *buf); extern char *grabstrbuffer(strbuffer_t *buf); extern strbuffer_t *dupstrbuffer(char *src); extern void strbufferchop(strbuffer_t *buf, int count); extern void strbufferrecalc(strbuffer_t *buf); extern void strbuffergrow(strbuffer_t *buf, int bytes); extern void strbufferuse(strbuffer_t *buf, int bytes); extern char *htmlquoted(char *s); extern char *prehtmlquoted(char *s); extern strbuffer_t *replacetext(char *original, char *oldtext, char *newtext); #define SBUF_DEFINE(NAME) char *NAME = NULL; size_t NAME##_buflen = 0; #define STATIC_SBUF_DEFINE(NAME) static char *NAME = NULL; static size_t NAME##_buflen = 0; #define SBUF_MALLOC(NAME, LEN) { NAME##_buflen = (LEN); NAME = (char *)malloc((LEN)+1); } #define SBUF_CALLOC(NAME, NMEMB, LEN) { NAME##_buflen = (LEN); NAME = (char *)calloc(NMEMB, (LEN)+1); } #define SBUF_REALLOC(NAME, LEN) { NAME##_buflen = (LEN); NAME = (char *)realloc(NAME, (LEN)+1); } /* How much can a string expand when htmlquoted? ' ' --> ' ' */ #define MAX_HTMLQUOTE_FACTOR 6 #endif xymon-4.3.30/lib/xymond_ipc.h0000664000076400007640000000262412174246230016300 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __XYMOND_IPC_H__ #define __XYMOND_IPC_H__ #include "xymond_buffer.h" /* Semaphore numbers */ #define BOARDBUSY 0 #define GOCLIENT 1 #define CLIENTCOUNT 2 #define CHAN_MASTER 0 #define CHAN_CLIENT 1 typedef struct xymond_channel_t { enum msgchannels_t channelid; int shmid; int semid; char *channelbuf; unsigned int seq; unsigned long msgcount; struct xymond_channel_t *next; } xymond_channel_t; extern char *channelnames[]; extern xymond_channel_t *setup_channel(enum msgchannels_t chnname, int role); extern void close_channel(xymond_channel_t *chn, int role); extern int setup_feedback_queue(int role); extern void close_feedback_queue(int queueid, int role); #endif xymon-4.3.30/lib/xymonrrd.c0000664000076400007640000002657613515623702016023 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for working with RRD graphs. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonrrd.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" #include "version.h" /* This is for mapping a status-name -> RRD file */ xymonrrd_t *xymonrrds = NULL; void * xymonrrdtree; /* This is the information needed to generate links on the trends column page */ xymongraph_t *xymongraphs = NULL; static const char *xymonlinkfmt = "
\"xymongraph \"Zoom
\n"; static const char *metafmt = "\n %s\n \n \n\n"; /* * Define the mapping between Xymon columns and RRD graphs. * Normally they are identical, but some RRD's use different names. */ static void rrd_setup(void) { static int setup_done = 0; SBUF_DEFINE(lenv); char *ldef, *p, *services; SBUF_DEFINE(tcptests); int count; xymonrrd_t *lrec; xymongraph_t *grec; /* Do nothing if we have been called within the past 5 minutes */ if ((setup_done + 300) >= getcurrenttime(NULL)) return; /* * Must free any old data first. * NB: These lists are NOT null-terminated ! * Stop when svcname becomes a NULL. */ lrec = xymonrrds; while (lrec && lrec->svcname) { if (lrec->xymonrrdname != lrec->svcname) xfree(lrec->xymonrrdname); xfree(lrec->svcname); lrec++; } if (xymonrrds) { xfree(xymonrrds); xtreeDestroy(xymonrrdtree); } grec = xymongraphs; while (grec && grec->xymonrrdname) { if (grec->xymonpartname) xfree(grec->xymonpartname); xfree(grec->xymonrrdname); grec++; } if (xymongraphs) xfree(xymongraphs); /* Get the tcp services, and count how many there are */ services = strdup(init_tcp_services()); SBUF_MALLOC(tcptests, strlen(services)+1); strncpy(tcptests, services, tcptests_buflen); count = 0; p = strtok(tcptests, " "); while (p) { count++; p = strtok(NULL, " "); } strncpy(tcptests, services, tcptests_buflen); /* Setup the xymonrrds table, mapping test-names to RRD files */ SBUF_MALLOC(lenv, strlen(xgetenv("TEST2RRD")) + strlen(tcptests) + count*strlen(",=tcp") + 1); strncpy(lenv, xgetenv("TEST2RRD"), lenv_buflen); p = lenv+strlen(lenv)-1; if (*p == ',') *p = '\0'; /* Drop a trailing comma */ p = strtok(tcptests, " "); while (p) { unsigned int curlen = strlen(lenv); snprintf(lenv+curlen, (lenv_buflen - curlen), ",%s=tcp", p); p = strtok(NULL, " "); } xfree(tcptests); xfree(services); count = 0; p = lenv; do { count++; p = strchr(p+1, ','); } while (p); xymonrrds = (xymonrrd_t *)calloc((count+1), sizeof(xymonrrd_t)); xymonrrdtree = xtreeNew(strcasecmp); lrec = xymonrrds; ldef = strtok(lenv, ","); while (ldef) { p = strchr(ldef, '='); if (p) { *p = '\0'; lrec->svcname = strdup(ldef); lrec->xymonrrdname = strdup(p+1); } else { lrec->svcname = lrec->xymonrrdname = strdup(ldef); } xtreeAdd(xymonrrdtree, lrec->svcname, lrec); ldef = strtok(NULL, ","); lrec++; } xfree(lenv); /* Setup the xymongraphs table, describing how to make graphs from an RRD */ lenv = strdup(xgetenv("GRAPHS")); p = lenv+strlen(lenv)-1; if (*p == ',') *p = '\0'; /* Drop a trailing comma */ count = 0; p = lenv; do { count++; p = strchr(p+1, ','); } while (p); xymongraphs = (xymongraph_t *)calloc((count+1), sizeof(xymongraph_t)); grec = xymongraphs; ldef = strtok(lenv, ","); while (ldef) { p = strchr(ldef, ':'); if (p) { *p = '\0'; grec->xymonrrdname = strdup(ldef); grec->xymonpartname = strdup(p+1); p = strchr(grec->xymonpartname, ':'); if (p) { *p = '\0'; grec->maxgraphs = atoi(p+1); if (strlen(grec->xymonpartname) == 0) { xfree(grec->xymonpartname); grec->xymonpartname = NULL; } } } else { grec->xymonrrdname = strdup(ldef); } ldef = strtok(NULL, ","); grec++; } xfree(lenv); setup_done = getcurrenttime(NULL); } xymonrrd_t *find_xymon_rrd(char *service, char *flags) { /* Lookup an entry in the xymonrrds table */ xtreePos_t handle; rrd_setup(); if (flags && (strchr(flags, 'R') != NULL)) { /* Don't do RRD's for reverse tests, since they have no data */ return NULL; } handle = xtreeFind(xymonrrdtree, service); if (handle == xtreeEnd(xymonrrdtree)) return NULL; else { return (xymonrrd_t *)xtreeData(xymonrrdtree, handle); } } xymongraph_t *find_xymon_graph(char *rrdname) { /* Lookup an entry in the xymongraphs table */ xymongraph_t *grec; int found = 0; char *dchar; rrd_setup(); grec = xymongraphs; while (!found && (grec->xymonrrdname != NULL)) { found = (strncmp(grec->xymonrrdname, rrdname, strlen(grec->xymonrrdname)) == 0); if (found) { /* Check that it's not a partial match, e.g. "ftp" matches "ftps" */ dchar = rrdname + strlen(grec->xymonrrdname); if ( (*dchar != '.') && (*dchar != ',') && (*dchar != '\0') ) found = 0; } if (!found) grec++; } return (found ? grec : NULL); } static char *xymon_graph_text(char *hostname, char *dispname, char *service, int bgcolor, xymongraph_t *graphdef, int itemcount, hg_stale_rrds_t nostale, const char *fmt, int locatorbased, time_t starttime, time_t endtime) { STATIC_SBUF_DEFINE(rrdurl); static int gwidth = 0, gheight = 0; SBUF_DEFINE(svcurl); int rrdparturlsize; char rrdservicename[100]; char *cgiurl = xgetenv("CGIBINURL"); MEMDEFINE(rrdservicename); if (locatorbased) { char *qres = locator_query(hostname, ST_RRD, &cgiurl); if (!qres) { errprintf("Cannot find RRD files for host %s\n", hostname); return ""; } } if (!gwidth) { gwidth = atoi(xgetenv("RRDWIDTH")); gheight = atoi(xgetenv("RRDHEIGHT")); } dbgprintf("rrdlink_url: host %s, rrd %s (partname:%s, maxgraphs:%d, count=%d)\n", hostname, graphdef->xymonrrdname, textornull(graphdef->xymonpartname), graphdef->maxgraphs, itemcount); if ((service != NULL) && (strcmp(graphdef->xymonrrdname, "tcp") == 0)) { snprintf(rrdservicename, sizeof(rrdservicename), "tcp:%s", service); } else if ((service != NULL) && (strcmp(graphdef->xymonrrdname, "ncv") == 0)) { snprintf(rrdservicename, sizeof(rrdservicename), "ncv:%s", service); } else if ((service != NULL) && (strcmp(graphdef->xymonrrdname, "devmon") == 0)) { snprintf(rrdservicename, sizeof(rrdservicename), "devmon:%s", service); } else { strncpy(rrdservicename, graphdef->xymonrrdname, sizeof(rrdservicename)); } SBUF_MALLOC(svcurl, 2048 + strlen(cgiurl) + strlen(hostname) + strlen(rrdservicename) + strlen(urlencode(dispname ? dispname : hostname))); rrdparturlsize = 2048 + strlen(fmt) + 3*svcurl_buflen + strlen(rrdservicename) + strlen(xgetenv("XYMONSKIN")); if (rrdurl == NULL) { SBUF_MALLOC(rrdurl, rrdparturlsize); } *rrdurl = '\0'; { SBUF_DEFINE(rrdparturl); int first = 1; int step; step = (graphdef->maxgraphs ? graphdef->maxgraphs : 5); if (itemcount) { int gcount = (itemcount / step); if ((gcount*step) != itemcount) gcount++; step = (itemcount / gcount); } SBUF_MALLOC(rrdparturl, rrdparturlsize); do { if (itemcount > 0) { snprintf(svcurl, svcurl_buflen, "%s/showgraph.sh?host=%s&service=%s&graph_width=%d&graph_height=%d&first=%d&count=%d", cgiurl, hostname, rrdservicename, gwidth, gheight, first, step); } else { snprintf(svcurl, svcurl_buflen, "%s/showgraph.sh?host=%s&service=%s&graph_width=%d&graph_height=%d", cgiurl, hostname, rrdservicename, gwidth, gheight); } strncat(svcurl, "&disp=", (svcurl_buflen - strlen(svcurl))); strncat(svcurl, urlencode(dispname ? dispname : hostname), (svcurl_buflen - strlen(svcurl))); if (nostale == HG_WITHOUT_STALE_RRDS) strncat(svcurl, "&nostale", (svcurl_buflen - strlen(svcurl))); if (bgcolor != -1) snprintf(svcurl+strlen(svcurl), (svcurl_buflen - strlen(svcurl)), "&color=%s", colorname(bgcolor)); snprintf(svcurl+strlen(svcurl), (svcurl_buflen - strlen(svcurl)), "&graph_start=%d&graph_end=%d", (int)starttime, (int)endtime); snprintf(rrdparturl, rrdparturl_buflen, fmt, rrdservicename, svcurl, svcurl, rrdservicename, svcurl, xgetenv("XYMONSKIN"), xgetenv("IMAGEFILETYPE")); if ((strlen(rrdparturl) + strlen(rrdurl) + 1) >= rrdurl_buflen) { SBUF_REALLOC(rrdurl, rrdurl_buflen + strlen(rrdparturl) + 4096); } strncat(rrdurl, rrdparturl, (rrdurl_buflen - strlen(rrdurl))); first += step; } while (first <= itemcount); xfree(rrdparturl); } dbgprintf("URLtext: %s\n", rrdurl); xfree(svcurl); MEMUNDEFINE(rrdservicename); return rrdurl; } char *xymon_graph_data(char *hostname, char *dispname, char *service, int bgcolor, xymongraph_t *graphdef, int itemcount, hg_stale_rrds_t nostale, hg_link_t wantmeta, int locatorbased, time_t starttime, time_t endtime) { return xymon_graph_text(hostname, dispname, service, bgcolor, graphdef, itemcount, nostale, ((wantmeta == HG_META_LINK) ? metafmt : xymonlinkfmt), locatorbased, starttime, endtime); } rrdtpldata_t *setup_template(char *params[]) { int i; rrdtpldata_t *result; rrdtplnames_t *nam; int dsindex = 1; result = (rrdtpldata_t *)calloc(1, sizeof(rrdtpldata_t)); result->dsnames = xtreeNew(strcmp); for (i = 0; (params[i]); i++) { if (strncasecmp(params[i], "DS:", 3) == 0) { char *pname, *pend; pname = params[i] + 3; pend = strchr(pname, ':'); if (pend) { int plen = (pend - pname); nam = (rrdtplnames_t *)calloc(1, sizeof(rrdtplnames_t)); nam->idx = dsindex++; if (result->template == NULL) { result->template = (char *)malloc(plen + 1); *result->template = '\0'; nam->dsnam = (char *)malloc(plen+1); strncpy(nam->dsnam, pname, plen); nam->dsnam[plen] = '\0'; } else { /* Hackish way of getting the colon delimiter */ pname--; plen++; result->template = (char *)realloc(result->template, strlen(result->template) + plen + 1); nam->dsnam = (char *)malloc(plen); strncpy(nam->dsnam, pname+1, plen-1); nam->dsnam[plen-1] = '\0'; } strncat(result->template, pname, plen); xtreeAdd(result->dsnames, nam->dsnam, nam); } } } return result; } xymon-4.3.30/lib/digest.h0000664000076400007640000000253312605347542015414 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is used to implement the message digest functions. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DIGEST_H_ #define __DIGEST_H_ typedef enum { D_MD5, D_SHA1, D_SHA256, D_SHA512, D_SHA224, D_SHA384, D_RMD160 } digesttype_t; typedef struct digestctx_t { char *digestname; digesttype_t digesttype; void *mdctx; } digestctx_t; extern char *md5hash(char *input); extern digestctx_t *digest_init(char *digest); extern int digest_data(digestctx_t *ctx, unsigned char *buf, int buflen); extern char *digest_done(digestctx_t *ctx); #define dohash(P) md5hash(P) #endif xymon-4.3.30/lib/memory.h0000664000076400007640000000656412271166607015455 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __MEMORY_H__ #define __MEMORY_H__ #undef XYMON_MEMORY_WRAPPERS /* If defined, will wrap mem-alloc routines */ #undef MEMORY_DEBUG /* If defined, use debugging code */ typedef struct xmemory_t { char *sdata; size_t ssize; struct xmemory_t *next; } xmemory_t; extern const char *xfreenullstr; extern void add_to_memlist(void *ptr, size_t memsize); extern void remove_from_memlist(void *ptr); extern void *xcalloc(size_t nmemb, size_t size); extern void *xmalloc(size_t size); extern void *xrealloc(void *ptr, size_t size); extern char *xstrdup(const char *s); extern char *xstrcat(char *dest, const char *src); extern char *xstrcpy(char *dest, const char *src); extern char *xstrncat(char *dest, const char *src, size_t maxlen); extern char *xstrncpy(char *dest, const char *src, size_t maxlen); extern int xsprintf(char *dest, const char *fmt, ...); extern char *xresultbuf(int maxsz); #ifdef XYMON_MEMORY_WRAPPERS #ifndef LIB_MEMORY_C_COMPILE #undef calloc #undef malloc #undef realloc #undef strdup /* * This arranges for all memory-allocation routines to * go via a wrapper that checks for bogus input data * and malloc() returning NULL when running out of memory. * Errors caught here are fatal. * Overhead is small, so this is turned on always. */ #define calloc(N,S) xcalloc((N), (S)) #define malloc(N) xmalloc((N)) #define realloc(P,S) xrealloc((P), (S)) #define strdup(P) xstrdup((P)) #endif /* LIB_MEMORY_C_COMPILE */ #endif /* XYMON_MEMORY_WRAPPERS */ #ifdef MEMORY_DEBUG /* * This arranges for all calls to potentially memory-overwriting routines * to do strict allocation checks and overwrite checks. The performance * overhead is significant, so it should only be turned on in debugging * situations. */ #ifndef LIB_MEMORY_C_COMPILE #define MEMDEFINE(P) { add_to_memlist((P), sizeof((P))); } #define MEMUNDEFINE(P) { remove_from_memlist((P)); } #define xfree(P) { remove_from_memlist((P)); free((P)); (P) = NULL; } #undef strcat #undef strncat #undef strcpy #undef strncpy #undef sprintf #define strcat(D,S) xstrcat((D), (S)) #define strncat(D,S,L) xstrncat((D), (S), (L)) #define strcpy(D,S) xstrcpy((D), (S)) #define strncpy(D,S,L) xstrncpy((D), (S), (L)) #define sprintf xsprintf #endif #else /* * This defines an "xfree()" macro, which checks for freeing of * a NULL ptr and complains if that happens. It does not check if * the pointer is valid. * After being freed, the pointer is set to NULL to catch double-free's. */ #define xfree(P) { if ((P) == NULL) { errprintf(xfreenullstr); abort(); } free((P)); (P) = NULL; } #define MEMDEFINE(P) do { } while (0); #define MEMUNDEFINE(P) do { } while (0); #endif /* MEMORY_DEBUG */ #endif xymon-4.3.30/lib/readmib.h0000664000076400007640000000725612173472453015547 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __READMIB_H__ #define __READMIB_H__ /* This holds one OID and our corresponding short-name */ typedef struct oidds_t { char *dsname; /* Our short-name for the data item in the mib definition */ char *oid; /* The OID for the data in the mib definition */ enum { RRD_NOTRACK, RRD_TRACK_GAUGE, RRD_TRACK_COUNTER, RRD_TRACK_DERIVE, RRD_TRACK_ABSOLUTE } rrdtype; /* How to store this in an RRD file */ enum { OID_CONVERT_NONE, /* No conversion */ OID_CONVERT_U32 /* Convert signed -> unsigned 32 bit integer */ } conversion; } oidds_t; /* This holds a list of OID's and their shortnames */ typedef struct oidset_t { int oidsz, oidcount; oidds_t *oids; struct oidset_t *next; } oidset_t; /* This describes the ways we can index into this MIB */ enum mibidxtype_t { MIB_INDEX_IN_OID, /* * The index is part of the key-table OID's; by scanning the key-table * values we find the one matching the wanted key, and can extract the * index from the matching rows' OID. * E.g. interfaces table looking for ifDescr or ifPhysAddress, or * interfaces table looking for the extension-object ifName. * IF-MIB::ifDescr.1 = STRING: lo * IF-MIB::ifDescr.2 = STRING: eth1 * IF-MIB::ifPhysAddress.1 = STRING: * IF-MIB::ifPhysAddress.2 = STRING: 0:e:a6:ce:cf:7f * IF-MIB::ifName.1 = STRING: lo * IF-MIB::ifName.2 = STRING: eth1 * The key table has an entry with the value = key-value. The index * is then the part of the key-OID beyond the base key table OID. */ MIB_INDEX_IN_VALUE /* * Index can be found by adding the key value as a part-OID to the * base OID of the key (e.g. interfaces by IP-address). * IP-MIB::ipAdEntIfIndex.127.0.0.1 = INTEGER: 1 * IP-MIB::ipAdEntIfIndex.172.16.10.100 = INTEGER: 3 */ }; typedef struct mibidx_t { char marker; /* Marker character for key OID */ enum mibidxtype_t idxtype; /* How to interpret the key */ char *keyoid; /* Key OID */ void *rootoid; /* Binary representation of keyoid */ size_t rootoidlen; /* Length of binary keyoid */ struct mibidx_t *next; } mibidx_t; typedef struct mibdef_t { enum { MIB_STATUS_NOTLOADED, /* Not loaded */ MIB_STATUS_LOADED, /* Loaded OK, can be used */ MIB_STATUS_LOADFAILED /* Load failed (e.g. missing MIB file) */ } loadstatus; char *mibfn; /* Filename of the MIB file (for non-standard MIB's) */ char *mibname; /* MIB definition name */ int tabular; /* Does the MIB contain a table ? Or just simple data */ oidset_t *oidlisthead, *oidlisttail; /* The list of OID's in the MIB set */ mibidx_t *idxlist; /* List of the possible indices used for the MIB */ int haveresult; /* Used while building result messages */ strbuffer_t *resultbuf; /* Used while building result messages */ } mibdef_t; extern int readmibs(char *cfgfn, int verbose); extern mibdef_t *first_mib(void); extern mibdef_t *next_mib(void); extern mibdef_t *find_mib(char *mibname); #endif xymon-4.3.30/lib/cgiurls.c0000664000076400007640000001131413515623702015571 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for generating the Xymon CGI URL's */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: cgiurls.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" static char *cgibinurl = NULL; char *hostsvcurl(char *hostname, char *service, int htmlformat) { static char *url; unsigned int url_buflen; if (url) xfree(url); if (!cgibinurl) cgibinurl = xgetenv("CGIBINURL"); url_buflen = 1024 + strlen(cgibinurl) + strlen(hostname) + strlen(service); url = (char *)malloc(url_buflen); snprintf(url, url_buflen, (htmlformat ? "%s/svcstatus.sh?HOST=%s&SERVICE=%s" : "%s/svcstatus.sh?HOST=%s&SERVICE=%s"), cgibinurl, hostname, service); return url; } char *hostsvcclienturl(char *hostname, char *section) { static char *url; unsigned int url_buflen; int n; if (url) xfree(url); if (!cgibinurl) cgibinurl = xgetenv("CGIBINURL"); url_buflen = 1024 + strlen(cgibinurl) + strlen(hostname) + (section ? strlen(section) : 0); url = (char *)malloc(url_buflen); n = snprintf(url, url_buflen, "%s/svcstatus.sh?CLIENT=%s", cgibinurl, hostname); if (section) snprintf(url+n, (url_buflen - n), "&SECTION=%s", section); return url; } char *histcgiurl(char *hostname, char *service) { static char *url = NULL; unsigned int url_buflen; if (url) xfree(url); if (!cgibinurl) cgibinurl = xgetenv("CGIBINURL"); url_buflen = 1024 + strlen(cgibinurl) + strlen(hostname) + strlen(service); url = (char *)malloc(url_buflen); snprintf(url, url_buflen, "%s/history.sh?HISTFILE=%s.%s", cgibinurl, commafy(hostname), service); return url; } char *histlogurl(char *hostname, char *service, time_t histtime, char *histtime_txt) { static char *url = NULL; unsigned int url_buflen; if (url) xfree(url); if (!cgibinurl) cgibinurl = xgetenv("CGIBINURL"); /* cgi-bin/historylog.sh?HOST=foo.sample.com&SERVICE=msgs&TIMEBUF=Fri_Nov_7_16:01:08_2002 */ url_buflen = 1024 + strlen(cgibinurl) + strlen(hostname) + strlen(service); url = (char *)malloc(url_buflen); if (!histtime_txt) { snprintf(url, url_buflen, "%s/historylog.sh?HOST=%s&SERVICE=%s&TIMEBUF=%s", xgetenv("CGIBINURL"), hostname, service, histlogtime(histtime)); } else { snprintf(url, url_buflen, "%s/historylog.sh?HOST=%s&SERVICE=%s&TIMEBUF=%s", xgetenv("CGIBINURL"), hostname, service, histtime_txt); } return url; } char *replogurl(char *hostname, char *service, int color, char *style, int recentgifs, reportinfo_t *repinfo, char *reportstart, time_t reportend, float reportwarnlevel) { static char *url; unsigned int url_buflen, n; if (url) xfree(url); if (!cgibinurl) cgibinurl = xgetenv("CGIBINURL"); url_buflen = 4096 + strlen(cgibinurl) + strlen(hostname) + strlen(service); url = (char *)malloc(url_buflen); n = snprintf(url, url_buflen, "%s/reportlog.sh?HOST=%s&SERVICE=%s&COLOR=%s&PCT=%.2f&ST=%u&END=%u&RED=%.2f&YEL=%.2f&GRE=%.2f&PUR=%.2f&CLE=%.2f&BLU=%.2f&STYLE=%s&FSTATE=%s&REDCNT=%d&YELCNT=%d&GRECNT=%d&PURCNT=%d&CLECNT=%d&BLUCNT=%d&WARNPCT=%.2f&RECENTGIFS=%d", cgibinurl, hostname, service, colorname(color), repinfo->fullavailability, (unsigned int)repinfo->reportstart, (unsigned int)reportend, repinfo->fullpct[COL_RED], repinfo->fullpct[COL_YELLOW], repinfo->fullpct[COL_GREEN], repinfo->fullpct[COL_PURPLE], repinfo->fullpct[COL_CLEAR], repinfo->fullpct[COL_BLUE], style, repinfo->fstate, repinfo->count[COL_RED], repinfo->count[COL_YELLOW], repinfo->count[COL_GREEN], repinfo->count[COL_PURPLE], repinfo->count[COL_CLEAR], repinfo->count[COL_BLUE], reportwarnlevel, use_recentgifs); if (reportstart) snprintf(url+n, (url_buflen - n), "&REPORTTIME=%s", reportstart); return url; } xymon-4.3.30/lib/xymond_buffer.c0000664000076400007640000000462012174246230016767 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This module contains a shared routine to find the size of a shared memory */ /* buffer used for one of the Xymon communications-channels. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_buffer.c 7217 2013-07-25 16:04:40Z storner $"; #include #include #include "libxymon.h" #include "xymond_buffer.h" unsigned int shbufsz(enum msgchannels_t chnid) { unsigned int defvalue = 0, result = 0; char *v = NULL; if (chnid != C_LAST) { switch (chnid) { case C_STATUS: v = getenv("MAXMSG_STATUS"); defvalue = 256; break; case C_CLIENT: v = getenv("MAXMSG_CLIENT"); defvalue = 512; break; case C_CLICHG: v = getenv("MAXMSG_CLICHG"); defvalue = shbufsz(C_CLIENT); break; case C_DATA: v = getenv("MAXMSG_DATA"); defvalue = 256; break; case C_NOTES: v = getenv("MAXMSG_NOTES"); defvalue = 256; break; case C_STACHG: v = getenv("MAXMSG_STACHG"); defvalue = shbufsz(C_STATUS); break; case C_PAGE: v = getenv("MAXMSG_PAGE"); defvalue = shbufsz(C_STATUS); break; case C_ENADIS: v = getenv("MAXMSG_ENADIS"); defvalue = 32; break; case C_USER: v = getenv("MAXMSG_USER"); defvalue = 128; break; case C_FEEDBACK_QUEUE: v = getenv("MAXMSG_STATUS"); defvalue = 256; break; default: break; } if (v) { result = atoi(v); /* See if it is an old setting in bytes */ if (result > 32*1024) result = (result / 1024); } if (result < 32) result = defvalue; } else { enum msgchannels_t i; unsigned int isz; result = 0; for (i=C_STATUS; (i < C_LAST); i++) { isz = shbufsz(i); if (isz > result) result = isz; } } return result; } xymon-4.3.30/lib/errormsg.h0000664000076400007640000000254612466407063016001 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __ERRORMSG_H__ #define __ERRORMSG_H__ #include extern char *errbuf; extern int save_errbuf; extern int debug; extern void errprintf(const char *fmt, ...); extern void real_dbgprintf(const char *fmt, ...); #define dbgprintf(...) { if (debug) real_dbgprintf(__VA_ARGS__); } #define logprintf(...) printf(__VA_ARGS__); extern void flush_errbuf(void); extern void set_debugfile(char *fn, int appendtofile); extern void starttrace(const char *fn); extern void stoptrace(void); extern void traceprintf(const char *fmt, ...); extern void redirect_cgilog(char *cginame); extern void reopen_file(char *fn, char *mode, FILE *fd); #endif xymon-4.3.30/lib/stackio.h0000664000076400007640000000220611615341300015551 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __STACKIO_H__ #define __STACKIO_H__ #define MAX_LINE_LEN 16384 extern int initfgets(FILE *fd); extern char *unlimfgets(strbuffer_t *buffer, FILE *fd); extern FILE *stackfopen(char *filename, char *mode, void **v_filelist); extern int stackfclose(FILE *fd); extern char *stackfgets(strbuffer_t *buffer, char *extraincl); extern int stackfmodified(void *v_listhead); extern void stackfclist(void **v_listhead); #endif xymon-4.3.30/lib/url.h0000664000076400007640000000401513460440436014730 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __URL_H__ #define __URL_H__ /* Fix building on GNU */ #ifndef MAXPATHLEN # ifdef PATH_MAX # define MAXPATHLEN PATH_MAX # elif defined(MAX_PATH) # define MAXPATHLEN MAX_PATH # elif defined(_MAX_PATH) # define MAXPATHLEN _MAX_PATH # elif defined(CCHMAXPATH) # define MAXPATHLEN CCHMAXPATH # else # define MAXPATHLEN 1024 # endif #endif extern int obeybbproxysyntax; typedef struct urlelem_t { char *origform; char *scheme; char *schemeopts; char *host; char *ip; int port; char *auth; char *relurl; int parseerror; } urlelem_t; enum webtesttype_t { WEBTEST_PLAIN, WEBTEST_CONTENT, WEBTEST_CONT, WEBTEST_NOCONT, WEBTEST_POST, WEBTEST_NOPOST, WEBTEST_TYPE, WEBTEST_STATUS, WEBTEST_HEAD, WEBTEST_SOAP, WEBTEST_NOSOAP, }; typedef struct weburl_t { int testtype; char *columnname; struct urlelem_t *desturl; struct urlelem_t *proxyurl; unsigned char *postcontenttype; unsigned char *postdata; unsigned char *expdata; unsigned char *okcodes; unsigned char *badcodes; } weburl_t; extern char *urlunescape(char *url); extern char *urldecode(char *envvar); extern char *urlencode(char *s); extern int urlvalidate(char *query, char *validchars); extern char *cleanurl(char *url); extern void parse_url(char *inputurl, urlelem_t *url); extern char *decode_url(char *testspec, weburl_t *weburl); #endif xymon-4.3.30/lib/color.c0000664000076400007640000000776013515623702015251 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for color <-> string conversion */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: color.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include "libxymon.h" int use_recentgifs = 0; char *colorname(int color) { static char *cs = ""; switch (color) { case COL_CLEAR: cs = "clear"; break; case COL_BLUE: cs = "blue"; break; case COL_PURPLE: cs = "purple"; break; case COL_GREEN: cs = "green"; break; case COL_YELLOW: cs = "yellow"; break; case COL_RED: cs = "red"; break; default: cs = "unknown"; break; } return cs; } int parse_color(char *colortext) { char inpcolor[10]; int n; if (!colortext) return -1; MEMDEFINE(inpcolor); strncpy(inpcolor, colortext, 7); inpcolor[7] = '\0'; n = strspn(inpcolor, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); inpcolor[n] = '\0'; strncat(inpcolor, " ", sizeof(inpcolor)-strlen(inpcolor)); if (strncasecmp(inpcolor, "green ", 6) == 0) { MEMUNDEFINE(inpcolor); return COL_GREEN; } else if (strncasecmp(inpcolor, "yellow ", 7) == 0) { MEMUNDEFINE(inpcolor); return COL_YELLOW; } else if (strncasecmp(inpcolor, "red ", 4) == 0) { MEMUNDEFINE(inpcolor); return COL_RED; } else if (strncasecmp(inpcolor, "blue ", 5) == 0) { MEMUNDEFINE(inpcolor); return COL_BLUE; } else if (strncasecmp(inpcolor, "clear ", 6) == 0) { MEMUNDEFINE(inpcolor); return COL_CLEAR; } else if (strncasecmp(inpcolor, "purple ", 7) == 0) { MEMUNDEFINE(inpcolor); return COL_PURPLE; } else if (strncasecmp(inpcolor, "client ", 7) == 0) { MEMUNDEFINE(inpcolor); return COL_CLIENT; } MEMUNDEFINE(inpcolor); return -1; } int eventcolor(char *colortext) { if (!colortext) return -1; if (strcmp(colortext, "cl") == 0) return COL_CLEAR; else if (strcmp(colortext, "bl") == 0) return COL_BLUE; else if (strcmp(colortext, "pu") == 0) return COL_PURPLE; else if (strcmp(colortext, "gr") == 0) return COL_GREEN; else if (strcmp(colortext, "ye") == 0) return COL_YELLOW; else if (strcmp(colortext, "re") == 0) return COL_RED; else return -1; } char *dotgiffilename(int color, int acked, int oldage) { static char *filename = NULL; /* yellow-recent.gif */ unsigned int bytesleft = 1024; /* Max length of a the gif-file, without path */ /* Allocate the first time, never free */ if (filename == NULL) filename = (char *)malloc(bytesleft); strncpy(filename, colorname(color), bytesleft); bytesleft -= strlen(filename); if (acked) { strncat(filename, "-ack", bytesleft); bytesleft -= 4; } else if (use_recentgifs) { strncat(filename, (oldage ? "" : "-recent"), bytesleft); bytesleft -= 7; } snprintf(filename+strlen(filename), bytesleft, ".%s", xgetenv("IMAGEFILETYPE")); return filename; } #ifndef CLIENTONLY int colorset(char *colspec, int excludeset) { char *cspeccopy = strdup(colspec); int c, ac; char *p; char *pp = NULL; p = strtok_r(cspeccopy, ",", &pp); ac = 0; while (p) { c = parse_color(p); if (c != -1) ac = (ac | (1 << c)); p = strtok_r(NULL, ",", &pp); } xfree(cspeccopy); /* Some color may be forbidden */ ac = (ac & ~excludeset); return ac; } #endif xymon-4.3.30/lib/environ.h0000664000076400007640000000177311615341300015604 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __ENVIRON_H__ #define __ENVIRON_H__ extern char *xgetenv(const char *name); extern void envcheck(char *envvars[]); extern void loadenv(char *envfile, char *area); extern char *getenv_default(char *envname, char *envdefault, char **buf); extern char *expand_env(char *s); #endif xymon-4.3.30/lib/loadhosts.h0000664000076400007640000000562412616464461016143 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOADHOSTS_H__ #define __LOADHOSTS_H__ enum xmh_item_t { XMH_NET, XMH_DISPLAYNAME, XMH_CLIENTALIAS, XMH_COMMENT, XMH_DESCRIPTION, XMH_NK, XMH_NKTIME, XMH_TRENDS, XMH_WML, XMH_NOPROPRED, XMH_NOPROPYELLOW, XMH_NOPROPPURPLE, XMH_NOPROPACK, XMH_REPORTTIME, XMH_WARNPCT, XMH_WARNSTOPS, XMH_DOWNTIME, XMH_SSLDAYS, XMH_SSLMINBITS, XMH_DEPENDS, XMH_BROWSER, XMH_HTTPHEADERS, XMH_HOLIDAYS, XMH_DELAYRED, XMH_DELAYYELLOW, XMH_FLAG_NOINFO, XMH_FLAG_NOTRENDS, XMH_FLAG_NOCLIENT, XMH_FLAG_NODISP, XMH_FLAG_NONONGREEN, XMH_FLAG_NOBB2, XMH_FLAG_PREFER, XMH_FLAG_NOSSLCERT, XMH_FLAG_TRACE, XMH_FLAG_NOTRACE, XMH_FLAG_NOCONN, XMH_FLAG_NOPING, XMH_FLAG_DIALUP, XMH_FLAG_TESTIP, XMH_FLAG_LDAPFAILYELLOW, XMH_FLAG_NOCLEAR, XMH_FLAG_HIDEHTTP, XMH_PULLDATA, XMH_NOFLAP, XMH_FLAG_MULTIHOMED, XMH_FLAG_SNI, XMH_FLAG_NOSNI, XMH_FLAG_HTTP_HEADER_MATCH, XMH_LDAPLOGIN, XMH_IP, XMH_HOSTNAME, XMH_DOCURL, XMH_NOPROP, XMH_PAGEINDEX, XMH_GROUPID, XMH_DGNAME, XMH_PAGENAME, XMH_PAGEPATH, XMH_PAGETITLE, XMH_PAGEPATHTITLE, XMH_ALLPAGEPATHS, XMH_ACCEPT_ONLY, XMH_RAW, XMH_CLASS, XMH_OS, XMH_NOCOLUMNS, XMH_DATA, XMH_NOTBEFORE, XMH_NOTAFTER, XMH_COMPACT, XMH_INTERFACES, XMH_LAST }; enum ghosthandling_t { GH_ALLOW, GH_IGNORE, GH_LOG, GH_MATCH }; extern int load_hostnames(char *hostsfn, char *extrainclude, int fqdn); extern int load_hostinfo(char *hostname); extern char *hostscfg_content(void); extern char *knownhost(char *hostname, char *hostip, enum ghosthandling_t ghosthandling); extern int knownloghost(char *logdir); extern void *hostinfo(char *hostname); extern void *localhostinfo(char *hostname); extern char *xmh_item(void *host, enum xmh_item_t item); extern char *xmh_custom_item(void *host, char *key); extern enum xmh_item_t xmh_key_idx(char *item); extern char *xmh_item_byname(void *host, char *item); extern char *xmh_item_walk(void *host); extern int xmh_item_idx(char *value); extern char *xmh_item_id(enum xmh_item_t idx); extern void *first_host(void); extern void *next_host(void *currenthost, int wantclones); extern void xmh_set_item(void *host, enum xmh_item_t item, void *value); extern char *xmh_item_multi(void *host, enum xmh_item_t item); #endif xymon-4.3.30/lib/netservices.c0000664000076400007640000003036213515623702016457 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for parsing the protocols.cfg file. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: netservices.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include "libxymon.h" /* * Services we know how to handle: * This defines what to send to them to shut down the * session nicely, and whether we want to grab the * banner or not. */ static svcinfo_t default_svcinfo[] = { /* ------------- data to send ------ ---- green data ------ flags */ /* name databytes length databytes offset len */ { "ftp", "quit\r\n", 0, "220", 0, 0, (TCP_GET_BANNER), 21 }, { "ssh", NULL, 0, "SSH", 0, 0, (TCP_GET_BANNER), 22 }, { "ssh1", NULL, 0, "SSH", 0, 0, (TCP_GET_BANNER), 22 }, { "ssh2", NULL, 0, "SSH", 0, 0, (TCP_GET_BANNER), 22 }, { "telnet", NULL, 0, NULL, 0, 0, (TCP_GET_BANNER|TCP_TELNET), 23 }, { "smtp", "mail\r\nquit\r\n", 0, "220", 0, 0, (TCP_GET_BANNER), 25 }, /* Send "MAIL" to avoid sendmail NOQUEUE logs */ { "pop", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER), 110 }, { "pop2", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER), 109 }, { "pop-2", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER), 109 }, { "pop3", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER), 110 }, { "pop-3", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER), 110 }, { "imap", "ABC123 LOGOUT\r\n", 0, "* OK", 0, 0, (TCP_GET_BANNER), 143 }, { "imap2", "ABC123 LOGOUT\r\n", 0, "* OK", 0, 0, (TCP_GET_BANNER), 143 }, { "imap3", "ABC123 LOGOUT\r\n", 0, "* OK", 0, 0, (TCP_GET_BANNER), 220 }, { "imap4", "ABC123 LOGOUT\r\n", 0, "* OK", 0, 0, (TCP_GET_BANNER), 143 }, { "nntp", "quit\r\n", 0, "200", 0, 0, (TCP_GET_BANNER), 119 }, { "ldap", NULL, 0, NULL, 0, 0, (0), 389 }, { "rsync", NULL, 0, "@RSYNCD",0, 0, (TCP_GET_BANNER), 873 }, { "bbd", "dummy", 0, NULL, 0, 0, (0), 1984 }, { "ftps", "quit\r\n", 0, "220", 0, 0, (TCP_GET_BANNER|TCP_SSL), 990 }, { "telnets", NULL, 0, NULL, 0, 0, (TCP_GET_BANNER|TCP_TELNET|TCP_SSL), 992 }, { "smtps", "mail\r\nquit\r\n", 0, "220", 0, 0, (TCP_GET_BANNER|TCP_SSL), 0 }, /* Non-standard - IANA */ { "pop3s", "quit\r\n", 0, "+OK", 0, 0, (TCP_GET_BANNER|TCP_SSL), 995 }, { "imaps", "ABC123 LOGOUT\r\n", 0, "* OK", 0, 0, (TCP_GET_BANNER|TCP_SSL), 993 }, { "nntps", "quit\r\n", 0, "200", 0, 0, (TCP_GET_BANNER|TCP_SSL), 563 }, { "ldaps", NULL, 0, NULL, 0, 0, (TCP_SSL), 636 }, { "clamd", "PING\r\n", 0, "PONG", 0, 0, (0), 3310 }, { "vnc", "RFB 000.000\r\n", 0, "RFB ", 0, 0, (TCP_GET_BANNER), 5900 }, { NULL, NULL, 0, NULL, 0, 0, (0), 0 } /* Default behaviour: Just try a connect */ }; static svcinfo_t *svcinfo = default_svcinfo; typedef struct svclist_t { struct svcinfo_t *rec; struct svclist_t *next; } svclist_t; static char *binview(unsigned char *buf, int buflen) { /* Encode a string with possibly binary data into an ascii-printable form */ static char hexchars[16] = "0123456789ABCDEF"; static char *result = NULL; unsigned char *inp, *outp; int i; if (result) xfree(result); if (!buf) { result = strdup("[null]"); return result; } if (buf && (buflen == 0)) buflen = strlen(buf); result = (char *)malloc(4*buflen + 1); /* Worst case: All binary */ for (inp=buf, i=0, outp=result; (irec = (svcinfo_t *)calloc(1, sizeof(svcinfo_t)); newitem->rec->svcname = strdup(svcname); newitem->next = NULL; if (first == NULL) first = newitem; if (head == NULL) { head = tail = newitem; } else { tail->next = newitem; tail = newitem; } svcname = strtok(NULL, "|"); } } else if (strncmp(l, "send ", 5) == 0) { if (first) { getescapestring(skipwhitespace(l+4), &first->rec->sendtxt, &first->rec->sendlen); for (walk = first->next; (walk); walk = walk->next) { walk->rec->sendtxt = strdup(first->rec->sendtxt); walk->rec->sendlen = first->rec->sendlen; } } } else if (strncmp(l, "expect ", 7) == 0) { if (first) { getescapestring(skipwhitespace(l+6), &first->rec->exptext, &first->rec->explen); for (walk = first->next; (walk); walk = walk->next) { walk->rec->exptext = strdup(first->rec->exptext); walk->rec->explen = first->rec->explen; walk->rec->expofs = 0; /* HACK - not used right now */ } } } else if (strncmp(l, "options ", 8) == 0) { if (first) { char *opt; first->rec->flags = 0; l = skipwhitespace(l+7); opt = strtok(l, ","); while (opt) { if (strcmp(opt, "ssl") == 0) first->rec->flags |= TCP_SSL; else if (strcmp(opt, "banner") == 0) first->rec->flags |= TCP_GET_BANNER; else if (strcmp(opt, "telnet") == 0) first->rec->flags |= TCP_TELNET; else errprintf("Unknown option: %s\n", opt); opt = strtok(NULL, ","); } for (walk = first->next; (walk); walk = walk->next) { walk->rec->flags = first->rec->flags; } } } else if (strncmp(l, "port ", 5) == 0) { if (first) { first->rec->port = atoi(skipwhitespace(l+4)); for (walk = first->next; (walk); walk = walk->next) { walk->rec->port = first->rec->port; } } } } if (fd) stackfclose(fd); freestrbuffer(inbuf); /* Copy from the svclist to svcinfo table */ svcinfo = (svcinfo_t *) malloc((svccount+1) * sizeof(svcinfo_t)); for (walk=head, i=0; (walk && (i < svccount)); walk = walk->next, i++) { svcinfo[i].svcname = walk->rec->svcname; svcinfo[i].sendtxt = walk->rec->sendtxt; svcinfo[i].sendlen = walk->rec->sendlen; svcinfo[i].exptext = walk->rec->exptext; svcinfo[i].explen = walk->rec->explen; svcinfo[i].expofs = walk->rec->expofs; svcinfo[i].flags = walk->rec->flags; svcinfo[i].port = walk->rec->port; } memset(&svcinfo[svccount], 0, sizeof(svcinfo_t)); /* This should not happen */ if (walk) { errprintf("Whoa - didn't copy all services! svccount=%d, next service '%s'\n", svccount, walk->rec->svcname); } /* Free the temp. svclist list */ while (head) { /* * Note: Don't free the strings inside the records, * as they are now owned by the svcinfo records. */ walk = head; head = head->next; xfree(walk); } searchstring = strdup(xgetenv("XYMONNETSVCS")); searchstring_buflen = strlen(searchstring) + 1; SBUF_MALLOC(xymonnetsvcs, strlen(xgetenv("XYMONNETSVCS")) + svcnamebytes + 1); strncpy(xymonnetsvcs, xgetenv("XYMONNETSVCS"), xymonnetsvcs_buflen); for (i=0; (svcinfo[i].svcname); i++) { char *p; strncpy(searchstring, xgetenv("XYMONNETSVCS"), searchstring_buflen); p = strtok(searchstring, " "); while (p && (strcmp(p, svcinfo[i].svcname) != 0)) p = strtok(NULL, " "); if (p == NULL) { char *eos = xymonnetsvcs + strlen(xymonnetsvcs); snprintf(eos, (xymonnetsvcs_buflen - (eos - xymonnetsvcs)), " %s", svcinfo[i].svcname); } } xfree(searchstring); if (debug) { dump_tcp_services(); dbgprintf("XYMONNETSVCS set to : %s\n", xymonnetsvcs); } MEMUNDEFINE(filename); return xymonnetsvcs; } void dump_tcp_services(void) { int i; dbgprintf("Service list dump\n"); for (i=0; (svcinfo[i].svcname); i++) { dbgprintf(" Name : %s\n", svcinfo[i].svcname); dbgprintf(" Sendtext: %s\n", binview(svcinfo[i].sendtxt, svcinfo[i].sendlen)); dbgprintf(" Sendlen : %d\n", svcinfo[i].sendlen); dbgprintf(" Exp.text: %s\n", binview(svcinfo[i].exptext, svcinfo[i].explen)); dbgprintf(" Exp.len : %d\n", svcinfo[i].explen); dbgprintf(" Exp.ofs : %d\n", svcinfo[i].expofs); dbgprintf(" Flags : %d\n", svcinfo[i].flags); dbgprintf(" Port : %d\n", svcinfo[i].port); } dbgprintf("\n"); } int default_tcp_port(char *svcname) { int svcidx; int result = 0; for (svcidx=0; (svcinfo[svcidx].svcname && (strcmp(svcname, svcinfo[svcidx].svcname) != 0)); svcidx++) ; if (svcinfo[svcidx].svcname) result = svcinfo[svcidx].port; return result; } svcinfo_t *find_tcp_service(char *svcname) { int svcidx; for (svcidx=0; (svcinfo[svcidx].svcname && (strcmp(svcname, svcinfo[svcidx].svcname) != 0)); svcidx++) ; if (svcinfo[svcidx].svcname) return &svcinfo[svcidx]; else return NULL; } xymon-4.3.30/lib/links.c0000664000076400007640000001321413515623702015242 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the host-, */ /* page-, and column-links present in www/notes and www/help. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: links.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" /* Info-link definitions. */ typedef struct link_t { char *key; char *filename; char *urlprefix; /* "/help", "/notes" etc. */ } link_t; static int linksloaded = 0; static void * linkstree; STATIC_SBUF_DEFINE(notesskin); STATIC_SBUF_DEFINE(helpskin); static char *columndocurl = NULL; static char *hostdocurl = NULL; char *link_docext(char *fn) { char *p = strrchr(fn, '.'); if (p == NULL) return NULL; if ( (strcasecmp(p, ".php") == 0) || (strcasecmp(p, ".php3") == 0) || (strcasecmp(p, ".asp") == 0) || (strcasecmp(p, ".pdf") == 0) || (strcasecmp(p, ".doc") == 0) || (strcasecmp(p, ".docx") == 0) || (strcasecmp(p, ".odt") == 0) || (strcasecmp(p, ".shtml") == 0) || (strcasecmp(p, ".phtml") == 0) || (strcasecmp(p, ".html") == 0) || (strcasecmp(p, ".htm") == 0)) { return p; } return NULL; } static link_t *init_link(char *filename, char *urlprefix) { char *p; link_t *newlink = NULL; dbgprintf("init_link(%s, %s)\n", textornull(filename), textornull(urlprefix)); newlink = (link_t *) malloc(sizeof(link_t)); newlink->filename = strdup(filename); newlink->urlprefix = urlprefix; /* Without extension, this time */ p = link_docext(filename); if (p) *p = '\0'; newlink->key = strdup(filename); return newlink; } static void load_links(char *directory, char *urlprefix) { DIR *linkdir; struct dirent *d; char fn[PATH_MAX]; dbgprintf("load_links(%s, %s)\n", textornull(directory), textornull(urlprefix)); linkdir = opendir(directory); if (!linkdir) { errprintf("Cannot read links in directory %s\n", directory); return; } MEMDEFINE(fn); while ((d = readdir(linkdir))) { link_t *newlink; if (*(d->d_name) == '.') continue; strncpy(fn, d->d_name, sizeof(fn)); newlink = init_link(fn, urlprefix); xtreeAdd(linkstree, newlink->key, newlink); } closedir(linkdir); MEMUNDEFINE(fn); } void load_all_links(void) { char dirname[PATH_MAX]; char *p; MEMDEFINE(dirname); dbgprintf("load_all_links()\n"); linkstree = xtreeNew(strcasecmp); if (notesskin) { xfree(notesskin); notesskin = NULL; } if (helpskin) { xfree(helpskin); helpskin = NULL; } if (columndocurl) { xfree(columndocurl); columndocurl = NULL; } if (hostdocurl) { xfree(hostdocurl); hostdocurl = NULL; } if (xgetenv("XYMONNOTESSKIN")) notesskin = strdup(xgetenv("XYMONNOTESSKIN")); else { SBUF_MALLOC(notesskin, strlen(xgetenv("XYMONWEB")) + strlen("/notes") + 1); snprintf(notesskin, notesskin_buflen, "%s/notes", xgetenv("XYMONWEB")); } if (xgetenv("XYMONHELPSKIN")) helpskin = strdup(xgetenv("XYMONHELPSKIN")); else { SBUF_MALLOC(helpskin, strlen(xgetenv("XYMONWEB")) + strlen("/help") + 1); snprintf(helpskin, helpskin_buflen, "%s/help", xgetenv("XYMONWEB")); } if (xgetenv("COLUMNDOCURL")) columndocurl = strdup(xgetenv("COLUMNDOCURL")); if (xgetenv("HOSTDOCURL")) hostdocurl = strdup(xgetenv("HOSTDOCURL")); if (!hostdocurl || (strlen(hostdocurl) == 0)) { strncpy(dirname, xgetenv("XYMONNOTESDIR"), sizeof(dirname)); load_links(dirname, notesskin); } /* Change xxx/xxx/xxx/notes into xxx/xxx/xxx/help */ strncpy(dirname, xgetenv("XYMONNOTESDIR"), sizeof(dirname)); p = strrchr(dirname, '/'); *p = '\0'; strncat(dirname, "/help", (sizeof(dirname) - strlen(dirname))); load_links(dirname, helpskin); linksloaded = 1; MEMUNDEFINE(dirname); } static link_t *find_link(char *key) { link_t *l = NULL; xtreePos_t handle; handle = xtreeFind(linkstree, key); if (handle != xtreeEnd(linkstree)) l = (link_t *)xtreeData(linkstree, handle); return l; } char *columnlink(char *colname) { STATIC_SBUF_DEFINE(linkurl); link_t *link; if (linkurl == NULL) SBUF_MALLOC(linkurl, PATH_MAX); if (!linksloaded) load_all_links(); link = find_link(colname); if (link) { snprintf(linkurl, linkurl_buflen, "%s/%s", link->urlprefix, link->filename); } else if (columndocurl) { snprintf(linkurl, linkurl_buflen, columndocurl, colname); } else { *linkurl = '\0'; } return linkurl; } char *hostlink(char *hostname) { STATIC_SBUF_DEFINE(linkurl); link_t *link; if (linkurl == NULL) SBUF_MALLOC(linkurl, PATH_MAX); if (!linksloaded) load_all_links(); if (hostdocurl && *hostdocurl) { snprintf(linkurl, linkurl_buflen, hostdocurl, hostname); return linkurl; } else { link = find_link(hostname); if (link) { snprintf(linkurl, linkurl_buflen, "%s/%s", link->urlprefix, link->filename); return linkurl; } } return NULL; } xymon-4.3.30/lib/headfoot.h0000664000076400007640000000430212277125340015715 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HEADFOOT_H__ #define __HEADFOOT_H__ #include extern void sethostenv(char *host, char *ip, char *svc, char *color, char *hikey); extern void sethostenv_report(time_t reportstart, time_t reportend, double repwarn, double reppanic); extern void sethostenv_snapshot(time_t snapshot); extern void sethostenv_histlog(char *histtime); extern void sethostenv_template(char *dir); extern void sethostenv_refresh(int n); extern void sethostenv_filter(char *hostptn, char *pageptn, char *ipptn, char *classptn); extern void sethostenv_clearlist(char *listname); extern void sethostenv_addtolist(char *listname, char *name, char *val, char *extra, int selected); extern void sethostenv_critack(int prio, char *ttgroup, char *ttextra, char *infourl, char *docurl); extern void sethostenv_critedit(char *updinfo, int prio, char *group, time_t starttime, time_t endtime, char *crittime, char *extra); extern void sethostenv_critclonelist_clear(void); extern void sethostenv_critclonelist_add(char *hostname); extern void sethostenv_pagepath(char *s); extern void sethostenv_backsecs(int seconds); extern void sethostenv_eventtime(time_t starttime, time_t endtime); extern void output_parsed(FILE *output, char *templatedata, int bgcolor, time_t selectedtime); extern void headfoot(FILE *output, char *template, char *pagepath, char *head_or_foot, int bgcolor); extern void showform(FILE *output, char *headertemplate, char *formtemplate, int color, time_t seltime, char *pretext, char *posttext); #endif xymon-4.3.30/lib/ripemd.h0000664000076400007640000001165411535462534015421 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was taken from the */ /* FreeBSD sources. It was originally written by Eric Young, and is NOT */ /* licensed under the GPL. Please adhere the original copyright notice below. */ /*----------------------------------------------------------------------------*/ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #ifndef HEADER_RIPEMD_H #define HEADER_RIPEMD_H /******************** Modifications for Xymon ***************************/ #include "config.h" #ifndef HAVE_UINT32_TYPEDEF typedef unsigned int u_int32_t; #endif #ifndef BYTE_ORDER #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifdef XYMON_LITTLE_ENDIAN #define BYTE_ORDER LITTLE_ENDIAN #else #define BYTE_ORDER BIG_ENDIAN #endif #endif /******************** End of modifications for Xymon ***************************/ #define RIPEMD160_CBLOCK 64 #define RIPEMD160_LBLOCK 16 #define RIPEMD160_BLOCK 16 #define RIPEMD160_LAST_BLOCK 56 #define RIPEMD160_LENGTH_BLOCK 8 #define RIPEMD160_DIGEST_LENGTH 20 typedef struct RIPEMD160state_st { u_int32_t A,B,C,D,E; u_int32_t Nl,Nh; u_int32_t data[RIPEMD160_LBLOCK]; int num; } RIPEMD160_CTX; #if 0 __BEGIN_DECLS void RIPEMD160_Init(RIPEMD160_CTX *c); void RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); void RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); char *RIPEMD160_End(RIPEMD160_CTX *, char *); char *RIPEMD160_File(const char *, char *); char *RIPEMD160_FileChunk(const char *, char *, off_t, off_t); char *RIPEMD160_Data(const void *, unsigned int, char *); __END_DECLS #endif #endif xymon-4.3.30/lib/htmllog.c0000664000076400007640000005246513532325276015607 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for generating HTML version of a status log. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: htmllog.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "version.h" #include "htmllog.h" static char *cgibinurl = NULL; static char *colfont = NULL; static char *ackfont = NULL; static char *rowfont = NULL; static char *documentationurl = NULL; static char *doctarget = NULL; #define HOSTPOPUP_COMMENT 1 #define HOSTPOPUP_DESCR 2 #define HOSTPOPUP_IP 4 static int hostpopup = (HOSTPOPUP_COMMENT | HOSTPOPUP_DESCR | HOSTPOPUP_IP); enum histbutton_t histlocation = HIST_BOTTOM; static void hostpopup_setup(void) { static int setup_done = 0; char *val, *p; if (setup_done) return; val = xgetenv("HOSTPOPUP"); if (val) { /* Clear the setting, since there is an explicit value for it */ hostpopup = 0; for (p = val; (*p); p++) { switch (*p) { case 'C': case 'c': hostpopup = (hostpopup | HOSTPOPUP_COMMENT); break; case 'D': case 'd': hostpopup = (hostpopup | HOSTPOPUP_DESCR); break; case 'I': case 'i': hostpopup = (hostpopup | HOSTPOPUP_IP); break; default: break; } } } setup_done = 1; } static void hostsvc_setup(void) { static int setup_done = 0; if (setup_done) return; hostpopup_setup(); getenv_default("NONHISTS", "info,trends,graphs", NULL); getenv_default("CGIBINURL", "/cgi-bin", &cgibinurl); getenv_default("XYMONPAGEACKFONT", "COLOR=\"#33ebf4\" SIZE=-1\"", &ackfont); getenv_default("XYMONPAGECOLFONT", "COLOR=\"#87a9e5\" SIZE=-1\"", &colfont); getenv_default("XYMONPAGEROWFONT", "SIZE=+1 COLOR=\"#FFFFCC\" FACE=\"Tahoma, Arial, Helvetica\"", &rowfont); getenv_default("XYMONWEB", "/xymon", NULL); { SBUF_DEFINE(dbuf); SBUF_MALLOC(dbuf, strlen(xgetenv("XYMONWEB")) + 6); snprintf(dbuf, dbuf_buflen, "%s/gifs", xgetenv("XYMONWEB")); getenv_default("XYMONSKIN", dbuf, NULL); xfree(dbuf); } setup_done = 1; } static void historybutton(char *cgibinurl, char *hostname, char *service, char *ip, char *displayname, char *btntxt, FILE *output) { SBUF_DEFINE(tmp1); SBUF_DEFINE(tmp2) SBUF_MALLOC(tmp2, strlen(service)+3); getenv_default("NONHISTS", "info,trends", NULL); SBUF_MALLOC(tmp1, strlen(xgetenv("NONHISTS"))+3); snprintf(tmp1, tmp1_buflen, ",%s,", xgetenv("NONHISTS")); snprintf(tmp2, tmp2_buflen, ",%s,", service); if (strstr(tmp1, tmp2) == NULL) { fprintf(output, "

", cgibinurl); fprintf(output, "", htmlquoted(btntxt)); fprintf(output, "", htmlquoted(service)); fprintf(output, ""); fprintf(output, "", htmlquoted(ip)); fprintf(output, "", htmlquoted(displayname)); fprintf(output, "
\n"); } xfree(tmp2); xfree(tmp1); } static void textwithcolorimg(char *msg, FILE *output) { char *p, *restofmsg; restofmsg = msg; do { int color, acked, recent; color = -1; acked = recent = 0; p = strchr(restofmsg, '&'); if (p) { *p = '\0'; fprintf(output, "%s", restofmsg); *p = '&'; if (strncmp(p, "&red", 4) == 0) color = COL_RED; else if (strncmp(p, "&yellow", 7) == 0) color = COL_YELLOW; else if (strncmp(p, "&green", 6) == 0) color = COL_GREEN; else if (strncmp(p, "&clear", 6) == 0) color = COL_CLEAR; else if (strncmp(p, "&blue", 5) == 0) color = COL_BLUE; else if (strncmp(p, "&purple", 7) == 0) color = COL_PURPLE; if (color == -1) { fprintf(output, "&"); restofmsg = p+1; } else { acked = (strncmp(p + 1 + strlen(colorname(color)), "-acked", 6) == 0); recent = (strncmp(p + 1 + strlen(colorname(color)), "-recent", 7) == 0); fprintf(output, "\"%s\"", xgetenv("XYMONSKIN"), dotgiffilename(color, acked, !recent), colorname(color), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); restofmsg = p+1+strlen(colorname(color)); if (acked) restofmsg += 6; if (recent) restofmsg += 7; } } else { fprintf(output, "%s", restofmsg); restofmsg = NULL; } } while (restofmsg); } void generate_html_log(char *hostname, char *displayname, char *service, char *ip, int color, int flapping, char *sender, char *flags, time_t logtime, char *timesincechange, char *firstline, char *restofmsg, char *modifiers, time_t acktime, char *ackmsg, char *acklist, time_t disabletime, char *dismsg, int is_history, int wantserviceid, int htmlfmt, int locatorbased, char *multigraphs, char *linktoclient, char *prio, char *ttgroup, char *ttextra, int graphtime, FILE *output) { int linecount = 0; xymonrrd_t *rrd = NULL; xymongraph_t *graph = NULL; char *tplfile = "hostsvc"; SBUF_DEFINE(graphs); char *graphsenv; char *graphsptr; time_t now = getcurrenttime(NULL); if (graphtime == 0) { if (getenv("TRENDSECONDS")) graphtime = atoi(getenv("TRENDSECONDS")); else graphtime = 48*60*60; } hostsvc_setup(); if (!displayname) displayname = hostname; sethostenv(displayname, ip, service, colorname(color), hostname); if (logtime) sethostenv_snapshot(logtime); if (is_history) tplfile = "histlog"; if (strcmp(service, xgetenv("INFOCOLUMN")) == 0) tplfile = "info"; else if (strcmp(service, xgetenv("TRENDSCOLUMN")) == 0) tplfile = "trends"; headfoot(output, tplfile, "", "header", color); if (strcmp(service, xgetenv("TRENDSCOLUMN")) == 0) { int formfile; char formfn[PATH_MAX]; snprintf(formfn, sizeof(formfn), "%s/web/trends_form", xgetenv("XYMONHOME")); formfile = open(formfn, O_RDONLY); if (formfile >= 0) { char *inbuf; struct stat st; int n; fstat(formfile, &st); inbuf = (char *) malloc(st.st_size + 1); *inbuf = '\0'; n = read(formfile, inbuf, st.st_size); if (n > 0) inbuf[n] = '\0'; close(formfile); sethostenv_backsecs(graphtime); output_parsed(output, inbuf, color, 0); xfree(inbuf); } } if (prio) { int formfile; char formfn[PATH_MAX]; snprintf(formfn, sizeof(formfn), "%s/web/critack_form", xgetenv("XYMONHOME")); formfile = open(formfn, O_RDONLY); if (formfile >= 0) { char *inbuf; struct stat st; int n; fstat(formfile, &st); inbuf = (char *) malloc(st.st_size + 1); *inbuf = '\0'; n = read(formfile, inbuf, st.st_size); if (n > 0) inbuf[st.st_size] = '\0'; close(formfile); sethostenv_critack(atoi(prio), ttgroup, ttextra, hostsvcurl(hostname, xgetenv("INFOCOLUMN"), 1), hostlink(hostname)); output_parsed(output, inbuf, color, 0); xfree(inbuf); } } if (acklist && *acklist) { /* received:validuntil:level:ackedby:msg */ time_t received, validuntil; int level; char *ackedby, *msg; char *bol, *eol, *tok; char receivedstr[200]; char untilstr[200]; fprintf(output, "\n"); fprintf(output, ""); fprintf(output, "", ackfont); fprintf(output, "\n"); fprintf(output, ""); fprintf(output, "", ackfont); fprintf(output, "", ackfont); fprintf(output, "", ackfont); fprintf(output, "", ackfont); fprintf(output, "\n"); nldecode(acklist); bol = acklist; do { eol = strchr(bol, '\n'); if (eol) *eol = '\0'; tok = strtok(bol, ":"); if (tok) { received = atoi(tok); tok = strtok(NULL, ":"); } else received = 0; if (tok) { validuntil = atoi(tok); tok = strtok(NULL, ":"); } else validuntil = 0; if (tok) { level = atoi(tok); tok = strtok(NULL, ":"); } else level = -1; if (tok) { ackedby = tok; tok = strtok(NULL, "\n"); } else ackedby = NULL; if (tok) msg = tok; else msg = NULL; if (received && validuntil && (level >= 0) && ackedby && msg) { strftime(receivedstr, sizeof(receivedstr)-1, "%Y-%m-%d %H:%M", localtime(&received)); strftime(untilstr, sizeof(untilstr)-1, "%Y-%m-%d %H:%M", localtime(&validuntil)); fprintf(output, ""); fprintf(output, "", ackfont, level); fprintf(output, "", ackfont, htmlquoted(ackedby)); fprintf(output, "", ackfont, receivedstr, untilstr); fprintf(output, "", ackfont, htmlquoted(msg)); fprintf(output, "\n"); } if (eol) { *eol = '\n'; bol = eol+1; } else bol = NULL; } while (bol); fprintf(output, "
Acknowledgments
LevelFromValidityMessage
%d%s%s - %s%s
\n"); } fprintf(output, "

 \n"); if (flapping) fprintf(output, "
WARNING: Flapping status
\n"); if (histlocation == HIST_TOP) { historybutton(cgibinurl, hostname, service, ip, displayname, (is_history ? "Full History" : "HISTORY"), output); } fprintf(output, "
\n"); if (wantserviceid) { fprintf(output, "\n"); } if (disabletime != 0) { fprintf(output, "\n", (disabletime == -1 ? "OK" : ctime(&disabletime))); fprintf(output, "\n", htmlquoted(dismsg)); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(dismsg)); fprintf(output, "\n"); } if (modifiers) { char *modtxt; nldecode(modifiers); fprintf(output, "
", rowfont); fprintf(output, "%s - ", htmlquoted(displayname)); fprintf(output, "%s", htmlquoted(service)); fprintf(output, "

Disabled until %s

%s


Current status message follows:

"); if (strlen(firstline)) { fprintf(output, "

"); textwithcolorimg(firstline, output); fprintf(output, "

"); /* Drop the color */ } fprintf(output, "\n"); } else { char *txt = skipword(firstline); if (dismsg) { fprintf(output, "

Planned downtime: %s



Current status message follows:

"); modtxt = strtok(modifiers, "\n"); while (modtxt) { fprintf(output, "

"); textwithcolorimg(modtxt, output); fprintf(output, "

"); modtxt = strtok(NULL, "\n"); if (modtxt) fprintf(output, "
"); } fprintf(output, "\n"); } fprintf(output, "
"); if (strlen(txt)) { fprintf(output, "

"); textwithcolorimg(txt, output); fprintf(output, "

"); /* Drop the color */ } fprintf(output, "\n"); } if (!htmlfmt) fprintf(output, "
\n");
	textwithcolorimg(restofmsg, output);
	if (!htmlfmt) fprintf(output, "\n
\n"); fprintf(output, "
\n"); fprintf(output, "

\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "
", colfont); if (strlen(timesincechange)) fprintf(output, "Status unchanged in %s
\n", timesincechange); if (sender) fprintf(output, "Status message received from %s
\n", sender); if (linktoclient) fprintf(output, "Client data available
\n", linktoclient); if (ackmsg) { char *ackedby; char ackuntil[200]; MEMDEFINE(ackuntil); strftime(ackuntil, sizeof(ackuntil)-1, xgetenv("ACKUNTILMSG"), localtime(&acktime)); ackuntil[sizeof(ackuntil)-1] = '\0'; ackedby = strstr(ackmsg, "\nAcked by:"); if (ackedby) { *ackedby = '\0'; fprintf(output, "Current acknowledgment: %s
%s
%s

\n", ackfont, htmlquoted(ackmsg), (ackedby+1), ackuntil); *ackedby = '\n'; } else { fprintf(output, "Current acknowledgment: %s
%s

\n", ackfont, htmlquoted(ackmsg), ackuntil); } MEMUNDEFINE(ackuntil); } fprintf(output, "
\n"); /* trends stuff here */ if (!is_history) { rrd = find_xymon_rrd(service, flags); if (rrd) { graph = find_xymon_graph(rrd->xymonrrdname); if (graph == NULL) { errprintf("Setup error: Service %s has a graph %s, but no graph-definition\n", service, rrd->xymonrrdname); } } } if (rrd && graph) { int may_have_rrd = 1; /* * See if there is already a linecount in the report. * If there is, this overrides the calculation here. * * From Francesco Duranti's hobbit-perl-client. */ char *lcstr = strstr(restofmsg, "\n", linecount); fprintf(output, " \n"); /* Get the GRAPHS_* environment setting */ SBUF_MALLOC(graphs, 7 + strlen(service) + 1); snprintf(graphs, graphs_buflen, "GRAPHS_%s", service); graphsenv=getenv(graphs); if (graphsenv) { fprintf(output, "\n", service, graphsenv); /* check for strtokens */ graphsptr = strtok(graphsenv,","); while (graphsptr != NULL) { // fprintf(output, "\n", graphsptr); graph->xymonrrdname = strdup(graphsptr); fprintf(output, "%s\n", xymon_graph_data(hostname, displayname, graphsptr, color, graph, linecount, HG_WITHOUT_STALE_RRDS, HG_PLAIN_LINK, locatorbased, now-graphtime, now)); // next token graphsptr = strtok(NULL,","); } } else { fprintf(output, "%s\n", xymon_graph_data(hostname, displayname, service, color, graph, linecount, HG_WITHOUT_STALE_RRDS, HG_PLAIN_LINK, locatorbased, now-graphtime, now)); } xfree(graphs); } } if (histlocation == HIST_BOTTOM) { historybutton(cgibinurl, hostname, service, ip, displayname, (is_history ? "Full History" : "HISTORY"), output); } fprintf(output,"
\n"); headfoot(output, tplfile, "", "footer", color); } char *alttag(char *columnname, int color, int acked, int propagate, char *age) { static char tag[1024]; size_t remain; remain = sizeof(tag) - 1; remain -= snprintf(tag, remain, "%s:%s:", columnname, colorname(color)); if (remain > 20) { if (acked) { strncat(tag, "acked:", remain); remain -= 6; } if (!propagate) { strncat(tag, "nopropagate:", remain); remain -= 12; } strncat(tag, age, remain); } tag[sizeof(tag)-1] = '\0'; return tag; } static char *nameandcomment(void *host, char *hostname, int usetooltip) { STATIC_SBUF_DEFINE(result); char *cmt, *disp, *hname; if (result) xfree(result); hostpopup_setup(); /* For summary "hosts", we have no hinfo record. */ if (!host) return hostname; hname = xmh_item(host, XMH_HOSTNAME); disp = xmh_item(host, XMH_DISPLAYNAME); cmt = NULL; if (!cmt && (hostpopup & HOSTPOPUP_COMMENT)) cmt = xmh_item(host, XMH_COMMENT); if (!cmt && usetooltip && (hostpopup & HOSTPOPUP_DESCR)) cmt = xmh_item(host, XMH_DESCRIPTION); if (!cmt && usetooltip && (hostpopup & HOSTPOPUP_IP)) cmt = xmh_item(host, XMH_IP); if (disp == NULL) disp = hname; if (cmt) { if (usetooltip) { /* Thanks to Marco Schoemaker for suggesting the use of */ SBUF_MALLOC(result, strlen(disp) + strlen(cmt) + 30); snprintf(result, result_buflen, "%s", cmt, disp); } else { SBUF_MALLOC(result, strlen(disp) + strlen(cmt) + 4); snprintf(result, result_buflen, "%s (%s)", disp, cmt); } return result; } else return disp; } static char *urldoclink(const char *docurl, const char *hostname) { /* * docurl is a user defined text string to build * a documentation url. It is expanded with the * hostname. */ static char linkurl[PATH_MAX]; if (docurl) { snprintf(linkurl, sizeof(linkurl), docurl, hostname); } else { linkurl[0] = '\0'; } return linkurl; } void setdocurl(char *url) { if (documentationurl) xfree(documentationurl); documentationurl = strdup(url); } void setdoctarget(char *target) { if (doctarget) xfree(doctarget); doctarget = strdup(target); } char *hostnamehtml(char *hostname, char *defaultlink, int usetooltip) { static char result[4096]; void *hinfo = hostinfo(hostname); char *hostlinkurl; if (!doctarget) doctarget = strdup(""); /* First the hostname and a notes-link. * * If a documentation CGI is defined, use that. * * else if a host has a direct notes-link, use that. * * else if no direct link and we are doing a nongreen/critical page, * provide a link to the main page with this host (there * may be links to documentation in some page-title). * * else just put the hostname there. */ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ if (documentationurl) { snprintf(result, sizeof(result), "%s", urldoclink(documentationurl, hostname), doctarget, xgetenv("XYMONPAGEROWFONT"), nameandcomment(hinfo, hostname, usetooltip)); } else if ((hostlinkurl = hostlink(hostname)) != NULL) { snprintf(result, sizeof(result), "%s", hostlinkurl, doctarget, xgetenv("XYMONPAGEROWFONT"), nameandcomment(hinfo, hostname, usetooltip)); } else if (defaultlink) { /* Provide a link to the page where this host lives */ snprintf(result, sizeof(result), "%s", xgetenv("XYMONWEB"), defaultlink, doctarget, xgetenv("XYMONPAGEROWFONT"), nameandcomment(hinfo, hostname, usetooltip)); } else { snprintf(result, sizeof(result), "%s", xgetenv("XYMONPAGEROWFONT"), nameandcomment(hinfo, hostname, usetooltip)); } #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ return result; } xymon-4.3.30/lib/ipaccess.c0000664000076400007640000000622712411754366015727 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, implementing IP-address based access */ /* controls. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: ipaccess.c 7476 2014-09-28 09:46:30Z storner $"; #include #include #include #include "libxymon.h" sender_t *getsenderlist(char *iplist) { char *ips, *p, *tok; sender_t *result; int count; dbgprintf("-> getsenderlist\n"); ips = strdup(iplist); count = 0; p = ips; do { count++; p = strchr(p, ','); if (p) p++; } while (p); result = (sender_t *) calloc(1, sizeof(sender_t) * (count+1)); tok = strtok(ips, ","); count = 0; while (tok) { int bits = 32; p = strchr(tok, '/'); if (p) *p = '\0'; result[count].ipval = ntohl(inet_addr(tok)); if (p) { *p = '/'; p++; bits = atoi(p); } if (bits < 32) result[count].ipmask = (0xFFFFFFFF << (32 - atoi(p))); else result[count].ipmask = 0xFFFFFFFF; tok = strtok(NULL, ","); count++; } xfree(ips); dbgprintf("<- getsenderlist\n"); return result; } int oksender(sender_t *oklist, char *targetip, struct in_addr sender, char *msgbuf) { int i; unsigned long int tg_ip; char *eoln = NULL; dbgprintf("-> oksender\n"); /* If oklist is empty, we're not doing any access checks - so return OK */ if (oklist == NULL) { dbgprintf("<- oksender(1-a)\n"); return 1; } /* If we know the target, it would be ok for the host to report on itself. */ if (targetip) { if (strcmp(targetip, "0.0.0.0") == 0) return 1; /* DHCP hosts can report from any address */ tg_ip = ntohl(inet_addr(targetip)); if (ntohl(sender.s_addr) == tg_ip) { dbgprintf("<- oksender(1-b)\n"); return 1; } } /* If sender is 0.0.0.0 (i.e. it arrived via backfeed channel), then OK */ if (sender.s_addr == INADDR_ANY) { dbgprintf("<- oksender(1-c)\n"); return 1; } /* It's someone else reporting about the host. Check the access list */ i = 0; do { if ((oklist[i].ipval & oklist[i].ipmask) == (ntohl(sender.s_addr) & oklist[i].ipmask)) { dbgprintf("<- oksender(1-c)\n"); return 1; } i++; } while (oklist[i].ipval != 0); /* Refuse and log the message */ if (msgbuf) { eoln = strchr(msgbuf, '\n'); if (eoln) *eoln = '\0'; } errprintf("Refused message from %s: %s\n", inet_ntoa(sender), (msgbuf ? msgbuf : "")); if (msgbuf && eoln) *eoln = '\n'; dbgprintf("<- oksender(0)\n"); return 0; } xymon-4.3.30/lib/md5.h0000664000076400007640000000215711615341300014606 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* API for the MD5 digest routines. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __MD5_H__ #define __MD5_H__ extern int myMD5_Size(void); extern void myMD5_Init(void *pms); extern void myMD5_Update(void *pms, unsigned char *data, int nbytes); extern void myMD5_Final(unsigned char digest[16], void *pms); #endif xymon-4.3.30/lib/locator.c0000664000076400007640000003055013515623702015567 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for communicating with the Xymon locator service. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: locator.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include const char *servicetype_names[] = { "rrd", "client", "alert", "history", "hostdata" }; static struct sockaddr_in myaddr; static socklen_t myaddrsz = 0; static int locatorsocket = -1; #define DEFAULT_CACHETIMEOUT (15*60) /* 15 minutes */ static void * locatorcache[ST_MAX]; static int havecache[ST_MAX] = {0,}; static int cachetimeout[ST_MAX] = {0,}; typedef struct cacheitm_t { char *key, *resp; time_t tstamp; } cacheitm_t; enum locator_servicetype_t get_servicetype(char *typestr) { enum locator_servicetype_t res = 0; while ((res < ST_MAX) && (strcmp(typestr, servicetype_names[res]))) res++; return res; } static int call_locator(char *buf, size_t bufsz) { int n, bytesleft; fd_set fds; struct timeval tmo; char *bufp; /* First, send the request */ bufp = buf; bytesleft = strlen(buf)+1; do { FD_ZERO(&fds); FD_SET(locatorsocket, &fds); tmo.tv_sec = 5; tmo.tv_usec = 0; n = select(locatorsocket+1, NULL, &fds, NULL, &tmo); if (n == 0) { errprintf("Send to locator failed: Timeout\n"); return -1; } else if (n == -1) { errprintf("Send to locator failed: %s\n", strerror(errno)); return -1; } n = send(locatorsocket, bufp, bytesleft, 0); if (n == -1) { errprintf("Send to locator failed: %s\n", strerror(errno)); return -1; } else { bytesleft -= n; bufp += n; } } while (bytesleft > 0); /* Then read the response */ FD_ZERO(&fds); FD_SET(locatorsocket, &fds); tmo.tv_sec = 5; tmo.tv_usec = 0; n = select(locatorsocket+1, &fds, NULL, NULL, &tmo); if (n > 0) { n = recv(locatorsocket, buf, bufsz-1, 0); if (n == -1) { errprintf("call_locator() recv() failed: %s\n", strerror(errno)); return -1; } buf[n] = '\0'; } else { errprintf("call_locator() comm failure: %s\n", (n == 0) ? "Timeout" : strerror(errno)); return -1; } return 0; } static char *locator_querycache(enum locator_servicetype_t svc, char *key) { xtreePos_t handle; cacheitm_t *itm; if (!havecache[svc]) return NULL; handle = xtreeFind(locatorcache[svc], key); if (handle == xtreeEnd(locatorcache[svc])) return NULL; itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); return (itm->tstamp + cachetimeout[svc]) > getcurrenttime(NULL) ? itm->resp : NULL; } static void locator_updatecache(enum locator_servicetype_t svc, char *key, char *resp) { xtreePos_t handle; cacheitm_t *newitm; if (!havecache[svc]) return; handle = xtreeFind(locatorcache[svc], key); if (handle == xtreeEnd(locatorcache[svc])) { newitm = (cacheitm_t *)calloc(1, sizeof(cacheitm_t)); newitm->key = strdup(key); newitm->resp = strdup(resp); if (xtreeAdd(locatorcache[svc], newitm->key, newitm) != XTREE_STATUS_OK) { xfree(newitm->key); xfree(newitm->resp); xfree(newitm); } } else { newitm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); if (newitm->resp) xfree(newitm->resp); newitm->resp = strdup(resp); newitm->tstamp = getcurrenttime(NULL); } } void locator_flushcache(enum locator_servicetype_t svc, char *key) { xtreePos_t handle; if (!havecache[svc]) return; if (key) { handle = xtreeFind(locatorcache[svc], key); if (handle != xtreeEnd(locatorcache[svc])) { cacheitm_t *itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); itm->tstamp = 0; } } else { for (handle = xtreeFirst(locatorcache[svc]); (handle != xtreeEnd(locatorcache[svc])); handle = xtreeNext(locatorcache[svc], handle)) { cacheitm_t *itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); itm->tstamp = 0; } } } void locator_prepcache(enum locator_servicetype_t svc, int timeout) { if (!havecache[svc]) { locatorcache[svc] = xtreeNew(strcasecmp); havecache[svc] = 1; } else { locator_flushcache(svc, NULL); } cachetimeout[svc] = ((timeout>0) ? timeout : DEFAULT_CACHETIMEOUT); } char *locator_cmd(char *cmd) { static char pingbuf[512]; int res; strncpy(pingbuf, cmd, sizeof(pingbuf)); res = call_locator(pingbuf, sizeof(pingbuf)); return (res == 0) ? pingbuf : NULL; } char *locator_ping(void) { return locator_cmd("p"); } int locator_init(char *ipport) { char *ip, *p; int portnum; if (locatorsocket >= 0) { close(locatorsocket); locatorsocket = -1; } locatorsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (locatorsocket == -1) { errprintf("Cannot get socket: %s\n", strerror(errno)); return -1; } ip = strdup(ipport); p = strchr(ip, ':'); if (p) { *p = '\0'; portnum = atoi(p+1); } else { portnum = atoi(xgetenv("XYMONDPORT")); } memset(&myaddr, 0, sizeof(myaddr)); inet_aton(ip, (struct in_addr *) &myaddr.sin_addr.s_addr); myaddr.sin_port = htons(portnum); myaddr.sin_family = AF_INET; myaddrsz = sizeof(myaddr); if (connect(locatorsocket, (struct sockaddr *)&myaddr, myaddrsz) == -1) { errprintf("Cannot set target address for locator: %s:%d (%s)\n", ip, portnum, strerror(errno)); close(locatorsocket); locatorsocket = -1; return -1; } fcntl(locatorsocket, F_SETFL, O_NONBLOCK); return (locator_ping() ? 0 : -1); } int locator_register_server(char *servername, enum locator_servicetype_t svctype, int weight, enum locator_sticky_t sticky, char *extras) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(servername) + 100; if (extras) bufsz += (strlen(extras) + 1); SBUF_MALLOC(buf, bufsz); if (sticky == LOC_SINGLESERVER) weight = -1; snprintf(buf, buf_buflen, "S|%s|%s|%d|%d|%s", servername, servicetype_names[svctype], weight, ((sticky == LOC_STICKY) ? 1 : 0), (extras ? extras : "")); res = call_locator(buf, bufsz); xfree(buf); return res; } int locator_register_host(char *hostname, enum locator_servicetype_t svctype, char *servername) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(servername) + strlen(hostname) + 100; SBUF_MALLOC(buf, bufsz); snprintf(buf, buf_buflen, "H|%s|%s|%s", hostname, servicetype_names[svctype], servername); res = call_locator(buf, bufsz); xfree(buf); return res; } int locator_rename_host(char *oldhostname, char *newhostname, enum locator_servicetype_t svctype) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(oldhostname) + strlen(newhostname) + 100; SBUF_MALLOC(buf, bufsz); snprintf(buf, buf_buflen, "M|%s|%s|%s", oldhostname, servicetype_names[svctype], newhostname); res = call_locator(buf, bufsz); xfree(buf); return res; } char *locator_query(char *hostname, enum locator_servicetype_t svctype, char **extras) { STATIC_SBUF_DEFINE(buf); static int bufsz = 0; int res, bufneeded; bufneeded = strlen(hostname) + 100; if (extras) bufneeded += 1024; if (!buf) { bufsz = bufneeded; SBUF_MALLOC(buf, bufsz); } else if (bufneeded > bufsz) { bufsz = bufneeded; SBUF_REALLOC(buf, bufsz); } if (havecache[svctype] && !extras) { char *cachedata = locator_querycache(svctype, hostname); if (cachedata) return cachedata; } snprintf(buf, buf_buflen, "Q|%s|%s", servicetype_names[svctype], hostname); if (extras) buf[0] = 'X'; res = call_locator(buf, bufsz); if (res == -1) return NULL; switch (*buf) { case '!': /* This host is fixed on an available server */ case '*': /* Roaming host */ if (extras) { *extras = strchr(buf+2, '|'); if (**extras == '|') { **extras = '\0'; (*extras)++; } } if (havecache[svctype] && !extras) locator_updatecache(svctype, hostname, buf+2); return ((strlen(buf) > 2) ? buf+2 : NULL); case '?': /* No available server to handle the request */ locator_flushcache(svctype, hostname); return NULL; } return NULL; } int locator_serverdown(char *servername, enum locator_servicetype_t svctype) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(servername) + 100; SBUF_MALLOC(buf, bufsz); snprintf(buf, buf_buflen, "D|%s|%s", servername, servicetype_names[svctype]); res = call_locator(buf, bufsz); locator_flushcache(svctype, NULL); xfree(buf); return res; } int locator_serverup(char *servername, enum locator_servicetype_t svctype) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(servername) + 100; SBUF_MALLOC(buf, bufsz); snprintf(buf, buf_buflen, "U|%s|%s", servername, servicetype_names[svctype]); res = call_locator(buf, bufsz); xfree(buf); return res; } int locator_serverforget(char *servername, enum locator_servicetype_t svctype) { SBUF_DEFINE(buf); int bufsz; int res; bufsz = strlen(servername) + 100; SBUF_MALLOC(buf, bufsz); snprintf(buf, buf_buflen, "F|%s|%s", servername, servicetype_names[svctype]); res = call_locator(buf, bufsz); locator_flushcache(svctype, NULL); xfree(buf); return res; } #ifdef STANDALONE int main(int argc, char *argv[]) { char buf[1024]; int done = 0; char *res; if (argc < 2) { printf("Usage: %s IP:PORT\n", argv[0]); return 1; } if (locator_init(argv[1]) == -1) { printf("Locator ping failed\n"); return 1; } else { printf("Locator is available\n"); } while (!done) { char *p, *p1, *p2, *p3, *p4, *p5, *p6, *p7; char *extras; printf("Commands:\n"); printf(" r(egister) s servername type weight sticky\n"); printf(" r(egister) h servername type hostname\n"); printf(" d(own) servername type\n"); printf(" u(p) servername type\n"); printf(" f(orget) servername type\n"); printf(" q(uery) hostname type\n"); printf(" x(query) hostname type\n"); printf(" p(ing)\n"); printf(" s(ave state)\n"); printf(">"); fflush(stdout); done = (fgets(buf, sizeof(buf), stdin) == NULL); if (done) continue; p = strchr(buf, '\n'); if (p) *p = '\0'; p1 = p2 = p3 = p4 = p5 = p6 = p7 = NULL; p1 = strtok(buf, " "); if (p1) p2 = strtok(NULL, " "); if (p2) p3 = strtok(NULL, " "); if (p3) p4 = strtok(NULL, " "); if (p4) p5 = strtok(NULL, " "); if (p5) p6 = strtok(NULL, " "); if (p6) p7 = strtok(NULL, "\r\n"); switch (*p1) { case 'R': case 'r': if (*p2 == 's') { enum locator_servicetype_t svc; enum locator_sticky_t sticky; int weight; svc = get_servicetype(p4); weight = (p5 ? atoi(p5) : 1); sticky = ((p6 && (atoi(p6) == 1)) ? LOC_STICKY : LOC_ROAMING); printf("%s\n", locator_register_server(p3, svc, weight, sticky, p7) ? "Failed" : "OK"); } else if (*p2 == 'h') { printf("%s\n", locator_register_host(p5, get_servicetype(p4), p3) ? "Failed" : "OK"); } break; case 'D': case 'd': printf("%s\n", locator_serverdown(p2, get_servicetype(p3)) ? "Failed" : "OK"); break; case 'U': case 'u': printf("%s\n", locator_serverup(p2, get_servicetype(p3)) ? "Failed" : "OK"); break; case 'F': case 'f': printf("%s\n", locator_serverforget(p2, get_servicetype(p3)) ? "Failed" : "OK"); break; case 'Q': case 'q': case 'X': case 'x': extras = NULL; res = locator_query(p2, get_servicetype(p3), (*p1 == 'x') ? &extras : NULL); if (res) { printf("Result: %s\n", res); if (extras) printf(" Extras gave: %s\n", extras); } else { printf("Failed\n"); } break; case 'P': case 'p': p = locator_cmd("p"); if (p == NULL) printf("Failed\n"); else printf("OK: %s\n", p); break; case 'S': case 's': p = locator_cmd("@"); if (p == NULL) printf("Failed\n"); else printf("OK: %s\n", p); break; } } return 0; } #endif xymon-4.3.30/lib/digest.c0000664000076400007640000001526513515623702015411 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is used to implement message digest functions (MD5, SHA1 etc.) */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: digest.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include "libxymon.h" char *md5hash(char *input) { /* We have a fast MD5 hash function, since that may be used a lot */ static struct digestctx_t *ctx = NULL; unsigned char md_value[16]; static char md_string[2*16+1]; int i; char *p; if (!ctx) { ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup("md5"); ctx->digesttype = D_MD5; ctx->mdctx = (void *)malloc(myMD5_Size()); } myMD5_Init(ctx->mdctx); myMD5_Update(ctx->mdctx, input, strlen(input)); myMD5_Final(md_value, ctx->mdctx); for(i = 0, p = md_string; (i < sizeof(md_value)); i++) p += snprintf(p, (sizeof(md_string) - (md_string - p)), "%02x", md_value[i]); *p = '\0'; return md_string; } digestctx_t *digest_init(char *digest) { struct digestctx_t *ctx = NULL; if (strcmp(digest, "md5") == 0) { /* Use the built in MD5 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_MD5; ctx->mdctx = (void *)malloc(myMD5_Size()); myMD5_Init(ctx->mdctx); } else if (strcmp(digest, "sha1") == 0) { /* Use the built in SHA1 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_SHA1; ctx->mdctx = (void *)malloc(mySHA1_Size()); mySHA1_Init(ctx->mdctx); } else if (strcmp(digest, "rmd160") == 0) { /* Use the built in RMD160 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_RMD160; ctx->mdctx = (void *)malloc(myRIPEMD160_Size()); myRIPEMD160_Init(ctx->mdctx); } else if (strcmp(digest, "sha512") == 0) { /* Use the built in SHA-512 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_SHA512; ctx->mdctx = (void *)malloc(mySHA512_Size()); mySHA512_Init(ctx->mdctx); } else if (strcmp(digest, "sha256") == 0) { /* Use the built in SHA-256 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_SHA256; ctx->mdctx = (void *)malloc(mySHA256_Size()); mySHA256_Init(ctx->mdctx); } else if (strcmp(digest, "sha224") == 0) { /* Use the built in SHA-224 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_SHA224; ctx->mdctx = (void *)malloc(mySHA224_Size()); mySHA224_Init(ctx->mdctx); } else if (strcmp(digest, "sha384") == 0) { /* Use the built in SHA-384 routines */ ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup(digest); ctx->digesttype = D_SHA384; ctx->mdctx = (void *)malloc(mySHA384_Size()); mySHA384_Init(ctx->mdctx); } else { errprintf("digest_init failure: Cannot handle digest %s\n", digest); return NULL; } return ctx; } int digest_data(digestctx_t *ctx, unsigned char *buf, int buflen) { switch (ctx->digesttype) { case D_MD5: myMD5_Update(ctx->mdctx, buf, buflen); break; case D_SHA1: mySHA1_Update(ctx->mdctx, buf, buflen); break; case D_RMD160: myRIPEMD160_Update(ctx->mdctx, buf, buflen); break; case D_SHA512: mySHA512_Update(ctx->mdctx, buf, buflen); break; case D_SHA256: mySHA256_Update(ctx->mdctx, buf, buflen); break; case D_SHA384: mySHA384_Update(ctx->mdctx, buf, buflen); break; case D_SHA224: mySHA224_Update(ctx->mdctx, buf, buflen); break; } return 0; } char *digest_done(digestctx_t *ctx) { unsigned int md_len = 0; unsigned char *md_value = NULL; SBUF_DEFINE(md_string); int i; char *p; switch (ctx->digesttype) { case D_MD5: /* Built in MD5 hash */ md_len = 16; md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); myMD5_Final(md_value, ctx->mdctx); break; case D_SHA1: /* Built in SHA1 hash */ md_len = 20; md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); mySHA1_Final(md_value, ctx->mdctx); break; case D_RMD160: /* Built in RMD160 hash */ md_len = 20; md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); myRIPEMD160_Final(md_value, ctx->mdctx); break; case D_SHA512: /* Built in SHA-512 hash */ md_len = (512/8); md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); mySHA512_Final(md_value, ctx->mdctx); break; case D_SHA256: /* Built in SHA-256 hash */ md_len = (256/8); md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); mySHA256_Final(md_value, ctx->mdctx); break; case D_SHA384: /* Built in SHA-384 hash */ md_len = (384/8); md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); mySHA384_Final(md_value, ctx->mdctx); break; case D_SHA224: /* Built in SHA-224 hash */ md_len = (224/8); md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char)); SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char)); mySHA224_Final(md_value, ctx->mdctx); break; } snprintf(md_string, md_string_buflen, "%s:", ctx->digestname); for(i = 0, p = md_string + strlen(md_string); (i < md_len); i++) p += snprintf(p, (md_string_buflen - (p - md_string)), "%02x", md_value[i]); *p = '\0'; xfree(md_value); xfree(ctx->digestname); xfree(ctx->mdctx); xfree(ctx); return md_string; } xymon-4.3.30/lib/holidays.c0000664000076400007640000004501613532325276015747 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for handling holidays. */ /* */ /* Copyright (C) 2006-2008 Michael Nagel */ /* Modifications for Xymon (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: holidays.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" static int holidays_like_weekday = -1; typedef struct holidayset_t { char *key; holiday_t *head; holiday_t *tail; } holidayset_t; static void * holidays; static int current_year = 0; static time_t mkday(int year, int month, int day) { struct tm t; memset(&t, 0, sizeof(t)); t.tm_year = year; t.tm_mon = month - 1; t.tm_mday = day; t.tm_isdst = -1; return mktime(&t); } /* * Algorithm for calculating the date of Easter Sunday * (Meeus/Jones/Butcher Gregorian algorithm) * For reference, see http://en.wikipedia.org/wiki/Computus */ static time_t getEasterDate(int year) { time_t day; int Y = year+1900; int a = Y % 19; int b = Y / 100; int c = Y % 100; int d = b / 4; int e = b % 4; int f = (b + 8) / 25; int g = (b - f + 1) / 3; int h = (19 * a + b - d - g + 15) % 30; int i = c / 4; int k = c % 4; int L = (32 + 2 * e + 2 * i - h - k) % 7; int m = (a + 11 * h + 22 * L) / 451; day = mkday(year, (h + L - 7 * m + 114) / 31, ((h + L - 7 * m + 114) % 31) + 1); return day; } /* Algorithm to compute the 4th Sunday in Advent (ie the last Sunday before Christmas Day) */ static time_t get4AdventDate(int year) { time_t day; struct tm *t; day = mkday(year, 12, 24); t = localtime(&day); day -= t->tm_wday * 86400; return day; } static int getnumberedweekday(int wkday, int daynum, int month, int year) { struct tm tm; /* First see what weekday the 1st of this month is */ memset(&tm, 0, sizeof(tm)); tm.tm_mon = (month - 1); tm.tm_year = year; tm.tm_mday = 1; tm.tm_isdst = -1; mktime(&tm); if (tm.tm_wday != wkday) { /* Skip forward so we reach the first of the wanted weekdays */ tm.tm_mday += (wkday - tm.tm_wday); if (tm.tm_mday < 1) tm.tm_mday += 7; tm.tm_isdst = -1; mktime(&tm); } /* t and tm now has the 1st wkday in this month. So skip to the one we want */ tm.tm_mday += 7*(daynum - 1); /* Check if we overflowed into next month (if daynum == 5) */ mktime(&tm); tm.tm_isdst = -1; if ((daynum == 5) && (tm.tm_mon != (month - 1))) { /* We drifted into the next month. Go back one week to return the last wkday of the month */ tm.tm_mday -= 7; tm.tm_isdst = -1; mktime(&tm); } return tm.tm_yday; } static int getweekdayafter(int wkday, int daynum, int month, int year) { struct tm tm; /* First see what weekday this date is */ memset(&tm, 0, sizeof(tm)); tm.tm_mon = (month - 1); tm.tm_year = year; tm.tm_mday = daynum; tm.tm_isdst = -1; mktime(&tm); if (tm.tm_wday != wkday) { /* Skip forward so we reach the wanted weekday */ tm.tm_mday += (wkday - tm.tm_wday); if (tm.tm_mday < daynum) tm.tm_mday += 7; tm.tm_isdst = -1; mktime(&tm); } return tm.tm_yday; } static void reset_holidays(void) { static int firsttime = 1; xtreePos_t handle; holidayset_t *hset; holiday_t *walk, *zombie; if (!firsttime) { for (handle = xtreeFirst(holidays); (handle != xtreeEnd(holidays)); handle = xtreeNext(holidays, handle)) { hset = (holidayset_t *)xtreeData(holidays, handle); xfree(hset->key); walk = hset->head; while (walk) { zombie = walk; walk = walk->next; xfree(zombie->desc); xfree(zombie); } } xtreeDestroy(holidays); } holidays_like_weekday = -1; firsttime = 0; holidays = xtreeNew(strcasecmp); } static void add_holiday(char *key, int year, holiday_t *newhol) { int isOK = 0; struct tm *t; time_t day; holiday_t *newitem; xtreePos_t handle; holidayset_t *hset; switch (newhol->holtype) { case HOL_ABSOLUTE: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <=31) && (!newhol->year || (newhol->year == year)) ); if (!isOK) break; day = mkday(year, newhol->month, newhol->day); t = localtime(&day); newhol->yday = t->tm_yday; break; case HOL_EASTER: isOK = (newhol->month == 0); if (!isOK) break; day = getEasterDate(year); t = localtime(&day); newhol->yday = t->tm_yday + newhol->day; break; case HOL_ADVENT: isOK = (newhol->month == 0); if (!isOK) break; day = get4AdventDate(year); t = localtime(&day); newhol->yday = t->tm_yday + newhol->day; break; case HOL_MON: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(1, newhol->day, newhol->month, year); break; case HOL_TUE: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(2, newhol->day, newhol->month, year); break; case HOL_WED: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(3, newhol->day, newhol->month, year); break; case HOL_THU: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(4, newhol->day, newhol->month, year); break; case HOL_FRI: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(5, newhol->day, newhol->month, year); break; case HOL_SAT: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(6, newhol->day, newhol->month, year); break; case HOL_SUN: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 5) ); if (!isOK) break; newhol->yday = getnumberedweekday(0, newhol->day, newhol->month, year); break; case HOL_MON_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(1, newhol->day, newhol->month, year); break; case HOL_TUE_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(2, newhol->day, newhol->month, year); break; case HOL_WED_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(3, newhol->day, newhol->month, year); break; case HOL_THU_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(4, newhol->day, newhol->month, year); break; case HOL_FRI_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(5, newhol->day, newhol->month, year); break; case HOL_SAT_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(6, newhol->day, newhol->month, year); break; case HOL_SUN_AFTER: isOK = ( (newhol->month >= 1 && newhol->month <=12) && (newhol->day >=1 && newhol->day <= 31) ); if (!isOK) break; newhol->yday = getweekdayafter(0, newhol->day, newhol->month, year); break; } if (!isOK) { errprintf("Error in holiday definition %s\n", newhol->desc); return; } newitem = (holiday_t *)calloc(1, sizeof(holiday_t)); newitem->holtype = newhol->holtype; newitem->day = newhol->day; newitem->month = newhol->month; newitem->desc = strdup(newhol->desc); newitem->yday = newhol->yday; handle = xtreeFind(holidays, key); if (handle == xtreeEnd(holidays)) { hset = (holidayset_t *)calloc(1, sizeof(holidayset_t)); hset->key = strdup(key); xtreeAdd(holidays, hset->key, hset); } else { hset = (holidayset_t *)xtreeData(holidays, handle); } if (hset->head == NULL) { hset->head = hset->tail = newitem; } else { hset->tail->next = newitem; hset->tail = hset->tail->next; } } static int record_compare(void **a, void **b) { holiday_t **reca = (holiday_t **)a; holiday_t **recb = (holiday_t **)b; return ((*reca)->yday < (*recb)->yday); } static void * record_getnext(void *a) { return ((holiday_t *)a)->next; } static void record_setnext(void *a, void *newval) { ((holiday_t *)a)->next = (holiday_t *)newval; } int load_holidays(int year) { static void *configholidays = NULL; char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf; holiday_t newholiday; xtreePos_t handle, commonhandle; char *setname = NULL; holidayset_t *commonhols; MEMDEFINE(fn); if (year == 0) { time_t tnow; struct tm *now; tnow = getcurrenttime(NULL); now = localtime(&tnow); year = now->tm_year; } else if (year > 1000) { year -= 1900; } snprintf(fn, sizeof(fn), "%s/etc/holidays.cfg", xgetenv("XYMONHOME")); /* First check if there were no modifications at all */ if (configholidays) { /* if the new year begins, the holidays have to be recalculated */ if (!stackfmodified(configholidays) && (year == current_year)){ dbgprintf("No files modified, skipping reload of %s\n", fn); MEMUNDEFINE(fn); return 0; } else { stackfclist(&configholidays); configholidays = NULL; } } reset_holidays(); fd = stackfopen(fn, "r", &configholidays); if (!fd) { errprintf("Cannot open configuration file %s\n", fn); MEMUNDEFINE(fn); return 0; } memset(&newholiday,0,sizeof(holiday_t)); inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *p, *delim, *arg1, *arg2; sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; p = STRBUF(inbuf); if (strncasecmp(p, "HOLIDAYLIKEWEEKDAY=", 19) == 0) { p+=19; holidays_like_weekday = atoi(p); if (holidays_like_weekday < -1 || holidays_like_weekday > 6) { holidays_like_weekday = -1; errprintf("Invalid HOLIDAYLIKEWEEKDAY in %s\n", fn); } continue; } if (*p == '[') { /* New set of holidays */ if (setname) xfree(setname); delim = strchr(p, ']'); if (delim) *delim = '\0'; setname = strdup(p+1); continue; } delim = strchr(p, ':'); if (delim) { memset(&newholiday,0,sizeof(holiday_t)); if (delim == p) { newholiday.desc = "untitled"; } else { *delim = '\0'; newholiday.desc = p; p=delim+1; } } arg1 = strtok(p, "="); while (arg1) { arg2=strtok(NULL," ,;\t\n\r"); if (!arg2) break; if (strncasecmp(arg1, "TYPE", 4) == 0) { if (strncasecmp(arg2, "STATIC", 6) == 0) newholiday.holtype = HOL_ABSOLUTE; else if (strncasecmp(arg2, "EASTER", 6) == 0) newholiday.holtype = HOL_EASTER; else if (strncasecmp(arg2, "4ADVENT", 7) == 0) newholiday.holtype = HOL_ADVENT; else if (strncasecmp(arg2, "MON", 3) == 0) newholiday.holtype = HOL_MON; else if (strncasecmp(arg2, "TUE", 3) == 0) newholiday.holtype = HOL_TUE; else if (strncasecmp(arg2, "WED", 3) == 0) newholiday.holtype = HOL_WED; else if (strncasecmp(arg2, "THU", 3) == 0) newholiday.holtype = HOL_THU; else if (strncasecmp(arg2, "FRI", 3) == 0) newholiday.holtype = HOL_FRI; else if (strncasecmp(arg2, "SAT", 3) == 0) newholiday.holtype = HOL_SAT; else if (strncasecmp(arg2, "SUN", 3) == 0) newholiday.holtype = HOL_SUN; else if (strncasecmp(arg2, "+MON", 4) == 0) newholiday.holtype = HOL_MON_AFTER; else if (strncasecmp(arg2, "+TUE", 4) == 0) newholiday.holtype = HOL_TUE_AFTER; else if (strncasecmp(arg2, "+WED", 4) == 0) newholiday.holtype = HOL_WED_AFTER; else if (strncasecmp(arg2, "+THU", 4) == 0) newholiday.holtype = HOL_THU_AFTER; else if (strncasecmp(arg2, "+FRI", 4) == 0) newholiday.holtype = HOL_FRI_AFTER; else if (strncasecmp(arg2, "+SAT", 4) == 0) newholiday.holtype = HOL_SAT_AFTER; else if (strncasecmp(arg2, "+SUN", 4) == 0) newholiday.holtype = HOL_SUN_AFTER; } else if (strncasecmp(arg1, "MONTH", 5) == 0) { newholiday.month=atoi(arg2); } else if (strncasecmp(arg1, "DAY", 3) == 0) { newholiday.day=atoi(arg2); } else if (strncasecmp(arg1, "OFFSET", 6) == 0) { newholiday.day=atoi(arg2); } else if (strncasecmp(arg1, "YEAR", 4) == 0) { newholiday.year=atoi(arg2); if (newholiday.year > 1000) { newholiday.year -= 1900; } } arg1 = strtok(NULL,"="); } add_holiday((setname ? setname : ""), year, &newholiday); } stackfclose(fd); freestrbuffer(inbuf); commonhandle = xtreeFind(holidays, ""); commonhols = (commonhandle != xtreeEnd(holidays)) ? (holidayset_t *)xtreeData(holidays, commonhandle) : NULL; for (handle = xtreeFirst(holidays); (handle != xtreeEnd(holidays)); handle = xtreeNext(holidays, handle)) { holidayset_t *oneset = (holidayset_t *)xtreeData(holidays, handle); if (commonhols && (oneset != commonhols)) { /* Add the common holidays to this set */ holiday_t *walk; for (walk = commonhols->head; (walk); walk = walk->next) add_holiday(oneset->key, year, walk); } oneset->head = msort(oneset->head, record_compare, record_getnext, record_setnext); } MEMUNDEFINE(fn); current_year = year; return 0; } static holiday_t *findholiday(char *key, int dayinyear) { xtreePos_t handle; holidayset_t *hset; holiday_t *p; if (key && *key) { handle = xtreeFind(holidays, key); if (handle == xtreeEnd(holidays)) { key = NULL; handle = xtreeFind(holidays, ""); } } else { key = NULL; handle = xtreeFind(holidays, ""); } if (handle != xtreeEnd(holidays)) hset = (holidayset_t *)xtreeData(holidays, handle); else return NULL; p = hset->head; while (p) { if (dayinyear == p->yday) { return p; } p = p->next; } return NULL; } int getweekdayorholiday(char *key, struct tm *t) { holiday_t *rec; if (holidays_like_weekday == -1) return t->tm_wday; rec = findholiday(key, t->tm_yday); if (rec) return holidays_like_weekday; return t->tm_wday; } char *isholiday(char *key, int dayinyear) { holiday_t *rec; rec = findholiday(key, dayinyear); if (rec) return rec->desc; return NULL; } void printholidays(char *key, strbuffer_t *buf, int mfirst, int mlast) { int day; char *fmt; char oneh[1024]; char dstr[1024]; fmt = xgetenv("HOLIDAYFORMAT"); for (day = 0; (day < 366); day++) { char *desc = isholiday(key, day); if (desc) { struct tm tm; time_t t; /* * mktime() ignores the tm_yday parameter, so to get the * actual date for the "yday'th" day of the year we just set * tm_mday to the yday value, and month to January. mktime() * will figure out that the 56th of January is really Feb 25. * * Note: tm_yday is zero-based, but tm_mday is 1-based! */ tm.tm_mon = 0; tm.tm_mday = day+1; tm.tm_year = current_year; tm.tm_hour = 12; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; t = mktime(&tm); if ((tm.tm_mon >= mfirst) && (tm.tm_mon <= mlast)) { strftime(dstr, sizeof(dstr), fmt, localtime(&t)); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ snprintf(oneh, sizeof(oneh), "%s%s\n", desc, dstr); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ addtobuffer(buf, oneh); } } } } #ifdef STANDALONE int main(int argc, char *argv[]) { char l[1024]; char *hset = NULL; char *p; strbuffer_t *sbuf = newstrbuffer(0); char *dayname[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; load_holidays(0); do { printf("$E year, $4 year, $W daynum wkday month year, Setname\n? "); fflush(stdout); if (!fgets(l, sizeof(l), stdin)) return 0; p = strchr(l, '\n'); if (p) *p = '\0'; if (hset) xfree(hset); hset = strdup(l); if (*hset == '$') { time_t t; struct tm *tm; int i; char *tok, *arg[5]; i = 0; tok = strtok(hset, " "); while (tok) { arg[i] = tok; i++; tok = strtok(NULL, " "); } if (arg[0][1] == 'E') { t = getEasterDate(atoi(arg[1]) - 1900); tm = localtime(&t); printf("Easter Sunday %04d is %02d/%02d/%04d\n", atoi(arg[1]), tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900); } else if (arg[0][1] == '4') { t = get4AdventDate(atoi(arg[1]) - 1900); tm = localtime(&t); printf("4Advent %04d is %02d/%02d/%04d\n", atoi(arg[1]), tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900); } else if (arg[0][1] == 'W') { struct tm wtm; memset(&wtm, 0, sizeof(wtm)); wtm.tm_mday = getnumberedweekday(atoi(arg[2]), atoi(arg[1]), atoi(arg[3]), atoi(arg[4])-1900) + 1; wtm.tm_mon = 0; wtm.tm_year = atoi(arg[4]) - 1900; wtm.tm_isdst = -1; mktime(&wtm); printf("The %d. %s in %02d/%04d is %02d/%02d/%04d\n", atoi(arg[1]), dayname[atoi(arg[2])], atoi(arg[3]), atoi(arg[4]), wtm.tm_mday, wtm.tm_mon+1, wtm.tm_year+1900); } else if (arg[0][1] == 'A') { struct tm wtm; memset(&wtm, 0, sizeof(wtm)); wtm.tm_mday = getweekdayafter(atoi(arg[2]), atoi(arg[1]), atoi(arg[3]), atoi(arg[4])-1900) + 1; wtm.tm_mon = 0; wtm.tm_year = atoi(arg[4]) - 1900; wtm.tm_isdst = -1; mktime(&wtm); printf("The %d. %s on or after %02d/%04d is %02d/%02d/%04d\n", atoi(arg[1]), dayname[atoi(arg[2])], atoi(arg[3]), atoi(arg[4]), wtm.tm_mday, wtm.tm_mon+1, wtm.tm_year+1900); } } else { char *set_tok, *y_tok; int year; set_tok = strtok(hset, " "); y_tok = strtok(NULL, " "); year = atoi(y_tok); load_holidays(year); printholidays(set_tok, sbuf, 0, 11); printf("Holidays year %d in set: %s\n", year, STRBUF(sbuf)); clearstrbuffer(sbuf); } } while (1); return 0; } #endif xymon-4.3.30/lib/loadcriticalconf.c0000664000076400007640000003134613515623702017430 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the */ /* critical.cfg file. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: loadcriticalconf.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" static void * rbconf; STATIC_SBUF_DEFINE(defaultfn); STATIC_SBUF_DEFINE(configfn); static void flushrec(void *k1, void *k2) { char *key; key = (char *)k1; if (*(key + strlen(key) - 1) == '=') { /* Clone record just holds a char string pointing to the origin record */ char *pointsto = (char *)k2; xfree(pointsto); } else { /* Full record */ critconf_t *rec = (critconf_t *)k2; if (rec->crittime) xfree(rec->crittime); if (rec->ttgroup) xfree(rec->ttgroup); if (rec->ttextra) xfree(rec->ttextra); } xfree(key); } int load_critconfig(char *fn) { static void *configfiles = NULL; static int firsttime = 1; FILE *fd; strbuffer_t *inbuf; /* Setup the default configuration filename */ if (!fn) { if (!defaultfn) { char *xymonhome = xgetenv("XYMONHOME"); SBUF_MALLOC(defaultfn, strlen(xymonhome) + strlen(DEFAULT_CRITCONFIGFN) + 2); snprintf(defaultfn, defaultfn_buflen, "%s/%s", xymonhome, DEFAULT_CRITCONFIGFN); } fn = defaultfn; } if (configfn && (strcmp(fn, configfn) != 0)) { /* Force full reload - it's a different config file */ if (configfiles) { stackfclist(&configfiles); configfiles = NULL; } } if (configfn) xfree(configfn); configfn = strdup(fn); /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", fn); return 0; } else { stackfclist(&configfiles); configfiles = NULL; } } if (!firsttime) { /* Clean up existing datatree */ xtreePos_t handle; for (handle = xtreeFirst(rbconf); (handle != xtreeEnd(rbconf)); handle = xtreeNext(rbconf, handle)) { flushrec(xtreeKey(rbconf, handle), xtreeData(rbconf, handle)); } xtreeDestroy(rbconf); } firsttime = 0; rbconf = xtreeNew(strcasecmp); fd = stackfopen(fn, "r", &configfiles); if (fd == NULL) return 1; inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { /* Full record : Host service START END TIMESPEC TTPrio TTGroup TTExtra */ /* Clone record: Host =HOST */ char *ehost, *eservice, *estart, *eend, *etime, *ttgroup, *ttextra, *updinfo; int ttprio = 0; critconf_t *newitem; xtreeStatus_t status; int idx = 0; ehost = gettok(STRBUF(inbuf), "|\n"); if (!ehost) continue; eservice = gettok(NULL, "|\n"); if (!eservice) continue; if (*eservice == '=') { SBUF_DEFINE(key); char *pointsto = strdup(eservice+1); SBUF_MALLOC(key, strlen(ehost) + 2); snprintf(key, key_buflen, "%s=", ehost); status = xtreeAdd(rbconf, key, pointsto); } else { unsigned int key_buflen; estart = gettok(NULL, "|\n"); if (!estart) continue; eend = gettok(NULL, "|\n"); if (!eend) continue; etime = gettok(NULL, "|\n"); if (!etime) continue; ttprio = atoi(gettok(NULL, "|\n")); if (ttprio == 0) continue; ttgroup = gettok(NULL, "|\n"); ttextra = gettok(NULL, "|\n"); updinfo = gettok(NULL, "|\n"); newitem = (critconf_t *)malloc(sizeof(critconf_t)); key_buflen = strlen(ehost) + strlen(eservice) + 15; newitem->key = (char *)malloc(key_buflen); snprintf(newitem->key, key_buflen, "%s|%s", ehost, eservice); newitem->starttime= ((estart && *estart) ? atoi(estart) : 0); newitem->endtime = ((eend && *eend) ? atoi(eend) : 0); newitem->crittime = ((etime && *etime) ? strdup(etime) : NULL); newitem->priority = ttprio; newitem->ttgroup = strdup(ttgroup); newitem->ttextra = strdup(ttextra); newitem->updinfo = strdup(updinfo); status = xtreeAdd(rbconf, newitem->key, newitem); while (status == XTREE_STATUS_DUPLICATE_KEY) { idx++; snprintf(newitem->key, key_buflen, "%s|%s|%d", ehost, eservice, idx); status = xtreeAdd(rbconf, newitem->key, newitem); } } } stackfclose(fd); freestrbuffer(inbuf); if (debug) { xtreePos_t handle; handle = xtreeFirst(rbconf); while (handle != xtreeEnd(rbconf)) { printf("%s\n", (char *)xtreeKey(rbconf, handle)); handle = xtreeNext(rbconf, handle); } } return 0; } static xtreePos_t findrec(char *key) { xtreePos_t handle; handle = xtreeFind(rbconf, key); if (handle == xtreeEnd(rbconf)) { /* Check if there's a clone pointer record */ SBUF_DEFINE(clonekey); char *p; clonekey = strdup(key); p = strchr(clonekey, '|'); if (p && *(p+1)) { *p = '='; *(p+1) = '\0'; } handle = xtreeFind(rbconf, clonekey); xfree(clonekey); if (handle != xtreeEnd(rbconf)) { char *pointsto; char *service; /* Get the origin record for this cloned record, using the same service name */ pointsto = (char *)xtreeData(rbconf, handle); service = strchr(key, '|'); if (service) { service++; SBUF_MALLOC(clonekey, strlen(pointsto) + strlen(service) + 2); snprintf(clonekey, clonekey_buflen, "%s|%s", pointsto, service); handle = xtreeFind(rbconf, clonekey); xfree(clonekey); } else handle = xtreeEnd(rbconf); } } return handle; } static int timecheck(time_t starttime, time_t endtime, char *crittime) { time_t now = getcurrenttime(NULL); if (starttime && (now < starttime)) return 0; if (endtime && (now > endtime)) return 0; if ((crittime == NULL) || within_sla(NULL, crittime, 0)) return 1; /* FIXME */ return 0; } critconf_t *get_critconfig(char *key, int flags, char **resultkey) { static xtreePos_t handle; static char *realkey = NULL; critconf_t *result = NULL; int isclone; if (resultkey) *resultkey = NULL; switch (flags) { case CRITCONF_TIMEFILTER: handle = findrec(key); /* We may have hit a cloned record, so use the real key for further searches */ if (handle != xtreeEnd(rbconf)) { realkey = (char *)xtreeKey(rbconf, handle); } while (handle != xtreeEnd(rbconf)) { result = (critconf_t *)xtreeData(rbconf, handle); if (timecheck(result->starttime, result->endtime, result->crittime)) return result; /* Go to the next */ handle = xtreeNext(rbconf, handle); if (handle != xtreeEnd(rbconf)) { critconf_t *rec = (critconf_t *)xtreeData(rbconf, handle); if (strncmp(realkey, rec->key, strlen(realkey)) != 0) handle=xtreeEnd(rbconf); } } realkey = NULL; break; case CRITCONF_FIRSTMATCH: handle = findrec(key); realkey = NULL; if (handle != xtreeEnd(rbconf)) { realkey = (char *)xtreeKey(rbconf, handle); } break; case CRITCONF_FIRST: realkey = NULL; handle = xtreeFirst(rbconf); if (handle == xtreeEnd(rbconf)) return NULL; do { realkey = (char *)xtreeKey(rbconf, handle); isclone = (*(realkey + strlen(realkey) - 1) == '='); if (isclone) handle = xtreeNext(rbconf, handle); } while (isclone && (handle != xtreeEnd(rbconf))); break; case CRITCONF_NEXT: if (!realkey || (handle == xtreeEnd(rbconf))) return NULL; isclone = 1; while (isclone && (handle != xtreeEnd(rbconf))) { handle = xtreeNext(rbconf, handle); if (handle) { realkey = (char *)xtreeKey(rbconf, handle); isclone = (*(realkey + strlen(realkey) - 1) == '='); } } break; case CRITCONF_RAW_FIRST: handle = xtreeFirst(rbconf); realkey = NULL; break; case CRITCONF_RAW_NEXT: handle = xtreeNext(rbconf, handle); realkey = NULL; break; case CRITCONF_FIRSTHOSTMATCH: do { int found = 0; char *delim; realkey = NULL; handle = xtreeFirst(rbconf); while (!found && (handle != xtreeEnd(rbconf))) { realkey = (char *)xtreeKey(rbconf, handle); delim = realkey + strlen(key); /* OK even if past end of realkey */ found = ((strncmp(realkey, key, strlen(key)) == 0) && ((*delim == '|') || (*delim == '='))); if (!found) { handle = xtreeNext(rbconf, handle); realkey = NULL; } } if ((handle != xtreeEnd(rbconf)) && (*(realkey + strlen(realkey) - 1) == '=')) { key = (char *)xtreeData(rbconf, handle); isclone = 1; } else isclone = 0; } while (isclone && (handle != xtreeEnd(rbconf))); break; } if (handle == xtreeEnd(rbconf)) { realkey = NULL; return NULL; } if (resultkey) *resultkey = (char *)xtreeKey(rbconf, handle); result = (critconf_t *)xtreeData(rbconf, handle); return result; } int update_critconfig(critconf_t *rec) { SBUF_DEFINE(bakfn); FILE *bakfd; unsigned char buf[8192]; int n; struct stat st; struct utimbuf ut; xtreePos_t handle; FILE *fd; int result = 0; /* First, copy the old file */ SBUF_MALLOC(bakfn, strlen(configfn) + 5); snprintf(bakfn, bakfn_buflen, "%s.bak", configfn); if (stat(configfn, &st) == 0) { ut.actime = st.st_atime; ut.modtime = st.st_mtime; } else ut.actime = ut.modtime = getcurrenttime(NULL); fd = fopen(configfn, "r"); if (fd) { bakfd = fopen(bakfn, "w"); if (bakfd) { while ((n = fread(buf, 1, sizeof(buf), fd)) > 0) fwrite(buf, 1, n, bakfd); fclose(bakfd); utime(bakfn, &ut); } fclose(fd); } xfree(bakfn); fd = fopen(configfn, "w"); if (fd == NULL) { errprintf("Cannot open output file %s\n", configfn); return 1; } if (rec) { handle = xtreeFind(rbconf, rec->key); if (handle == xtreeEnd(rbconf)) xtreeAdd(rbconf, rec->key, rec); } handle = xtreeFirst(rbconf); while (handle != xtreeEnd(rbconf)) { char *onekey; onekey = (char *)xtreeKey(rbconf, handle); if (*(onekey + strlen(onekey) - 1) == '=') { char *pointsto = (char *)xtreeData(rbconf, handle); char *hostname; hostname = strdup(onekey); *(hostname + strlen(hostname) - 1) = '\0'; fprintf(fd, "%s|=%s\n", hostname, pointsto); } else { critconf_t *onerec = (critconf_t *)xtreeData(rbconf, handle); char startstr[20], endstr[20]; *startstr = *endstr = '\0'; if (onerec->starttime > 0) snprintf(startstr, sizeof(startstr), "%d", (int)onerec->starttime); if (onerec->endtime > 0) snprintf(endstr, sizeof(endstr), "%d", (int)onerec->endtime); fprintf(fd, "%s|%s|%s|%s|%d|%s|%s|%s\n", onekey, startstr, endstr, (onerec->crittime ? onerec->crittime : ""), onerec->priority, (onerec->ttgroup ? onerec->ttgroup : ""), (onerec->ttextra ? onerec->ttextra : ""), (onerec->updinfo ? onerec->updinfo : "")); } handle = xtreeNext(rbconf, handle); } fclose(fd); return result; } void addclone_critconfig(char *origin, char *newclone) { SBUF_DEFINE(newkey); xtreePos_t handle; SBUF_MALLOC(newkey, strlen(newclone) + 2); snprintf(newkey, newkey_buflen, "%s=", newclone); handle = xtreeFind(rbconf, newkey); if (handle != xtreeEnd(rbconf)) dropclone_critconfig(newclone); xtreeAdd(rbconf, newkey, strdup(origin)); } void dropclone_critconfig(char *drop) { xtreePos_t handle; SBUF_DEFINE(key); char *dropkey, *dropsrc; SBUF_MALLOC(key, strlen(drop) + 2); snprintf(key, key_buflen, "%s=", drop); handle = xtreeFind(rbconf, key); if (handle == xtreeEnd(rbconf)) return; dropkey = (char *)xtreeKey(rbconf, handle); dropsrc = (char *)xtreeDelete(rbconf, key); xfree(dropkey); xfree(dropsrc); xfree(key); } int delete_critconfig(char *dropkey, int evenifcloned) { xtreePos_t handle; handle = xtreeFind(rbconf, dropkey); if (handle == xtreeEnd(rbconf)) return 0; if (!evenifcloned) { /* Check if this record has any clones attached to it */ char *hostname, *p; hostname = strdup(dropkey); p = strchr(hostname, '|'); if (p) *p = '\0'; handle = xtreeFirst(rbconf); while (handle != xtreeEnd(rbconf)) { char *key, *ptr; key = (char *)xtreeKey(rbconf, handle); ptr = (char *)xtreeData(rbconf, handle); if ((*(key + strlen(key) - 1) == '=') && (strcmp(hostname, ptr) == 0)) { xfree(hostname); return 1; } handle = xtreeNext(rbconf, handle); } xfree(hostname); } handle = xtreeFind(rbconf, dropkey); if (handle != xtreeEnd(rbconf)) { void *k1, *k2; k1 = xtreeKey(rbconf, handle); k2 = xtreeDelete(rbconf, dropkey); flushrec(k1, k2); } return 0; } xymon-4.3.30/lib/timing.c0000664000076400007640000001204413515623702015411 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for timing program execution. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: timing.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include // For POSIX timer definitions #include #include #include #include #include #include "libxymon.h" int timing = 0; typedef struct timestamp_t { char *eventtext; struct timespec eventtime; struct timestamp_t *prev; struct timestamp_t *next; } timestamp_t; static timestamp_t *stamphead = NULL; static timestamp_t *stamptail = NULL; time_t gettimer(void) { int res; struct timespec t; #if (_POSIX_TIMERS > 0) && defined(_POSIX_MONOTONIC_CLOCK) res = clock_gettime(CLOCK_MONOTONIC, &t); if(-1 == res) { res = clock_gettime(CLOCK_REALTIME, &t); if(-1 == res) { return time(NULL); } } return (time_t) t.tv_sec; #else return time(NULL); #endif } void getntimer(struct timespec *tp) { struct timeval t; struct timezone tz; int res; #if (_POSIX_TIMERS > 0) && defined(_POSIX_MONOTONIC_CLOCK) res = clock_gettime(CLOCK_MONOTONIC, tp); if(-1 == res) { res = clock_gettime(CLOCK_REALTIME, tp); if(-1 != res) return; /* Fall through to use gettimeofday() */ } #endif gettimeofday(&t, &tz); tp->tv_sec = t.tv_sec; tp->tv_nsec = 1000*t.tv_usec; } void add_timestamp(const char *msg) { if (timing) { timestamp_t *newstamp = (timestamp_t *) malloc(sizeof(timestamp_t)); getntimer(&newstamp->eventtime); newstamp->eventtext = strdup(msg); if (stamphead == NULL) { newstamp->next = newstamp->prev = NULL; stamphead = newstamp; } else { newstamp->prev = stamptail; newstamp->next = NULL; stamptail->next = newstamp; } stamptail = newstamp; } } int ntimerus(struct timespec *start, struct timespec *now) { struct timespec tdiff; /* See how long the query took */ if (now) { memcpy(&tdiff, now, sizeof(struct timespec)); } else { getntimer(&tdiff); } if (tdiff.tv_nsec < start->tv_nsec) { tdiff.tv_sec--; tdiff.tv_nsec += 1000000000; } tdiff.tv_sec -= start->tv_sec; tdiff.tv_nsec -= start->tv_nsec; return (tdiff.tv_sec*1000000 + tdiff.tv_nsec/1000); } void show_timestamps(char **buffer) { timestamp_t *s; struct timespec dif; SBUF_DEFINE(outbuf); char buf1[80]; if (!timing || (stamphead == NULL)) return; MEMDEFINE(buf1); SBUF_MALLOC(outbuf, 4096); strncpy(outbuf, "\n\nTIME SPENT\n", outbuf_buflen); strncat(outbuf, "Event ", (outbuf_buflen - strlen(outbuf))); strncat(outbuf, " Start time", (outbuf_buflen - strlen(outbuf))); strncat(outbuf, " Duration\n", (outbuf_buflen - strlen(outbuf))); for (s=stamphead; (s); s=s->next) { snprintf(buf1, sizeof(buf1), "%-40s ", s->eventtext); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); snprintf(buf1, sizeof(buf1), "%10u.%06u ", (unsigned int)s->eventtime.tv_sec, (unsigned int)s->eventtime.tv_nsec / 1000); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); if (s->prev) { tvdiff(&((timestamp_t *)s->prev)->eventtime, &s->eventtime, &dif); snprintf(buf1, sizeof(buf1), "%10u.%06u ", (unsigned int)dif.tv_sec, (unsigned int)dif.tv_nsec / 1000); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); } else strncat(outbuf, " -", (outbuf_buflen - strlen(outbuf))); strncat(outbuf, "\n", (outbuf_buflen - strlen(outbuf))); if ((outbuf_buflen - strlen(outbuf)) < 200) { SBUF_REALLOC(outbuf, outbuf_buflen + 4096); } } tvdiff(&stamphead->eventtime, &stamptail->eventtime, &dif); snprintf(buf1, sizeof(buf1), "%-40s ", "TIME TOTAL"); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); snprintf(buf1, sizeof(buf1), "%-18s", ""); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); snprintf(buf1, sizeof(buf1), "%10u.%06u ", (unsigned int)dif.tv_sec, (unsigned int)dif.tv_nsec / 1000); strncat(outbuf, buf1, (outbuf_buflen - strlen(outbuf))); strncat(outbuf, "\n", (outbuf_buflen - strlen(outbuf))); if (buffer == NULL) { printf("%s", outbuf); xfree(outbuf); } else *buffer = outbuf; MEMUNDEFINE(buf1); } long total_runtime(void) { if (timing) return (stamptail->eventtime.tv_sec - stamphead->eventtime.tv_sec); else return 0; } xymon-4.3.30/lib/acknowledgementslog.c0000664000076400007640000003265113515623702020164 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This displays the "acknowledgements" log. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* Host/test/color/start/end filtering code by Eric Schwimmer 2005 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: acknowledgementslog.c 7085 2012-07-16 11:08:37Z storner $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" typedef struct acknowledgements_t { void *host; struct htnames_t *service; time_t eventtime; time_t validity; char *recipient; char *message; struct acknowledgements_t *next; } acknowledgements_t; static time_t convert_time(char *timestamp) { time_t event = 0; unsigned int year,month,day,hour,min,sec,count; struct tm timeinfo; count = sscanf(timestamp, "%u/%u/%u@%u:%u:%u", &year, &month, &day, &hour, &min, &sec); if(count != 6) { return -1; } if(year < 1970) { return 0; } else { memset(&timeinfo, 0, sizeof(timeinfo)); timeinfo.tm_year = year - 1900; timeinfo.tm_mon = month - 1; timeinfo.tm_mday = day; timeinfo.tm_hour = hour; timeinfo.tm_min = min; timeinfo.tm_sec = sec; timeinfo.tm_isdst = -1; event = mktime(&timeinfo); } return event; } static htnames_t *namehead = NULL; static htnames_t *getname(char *name, int createit) { htnames_t *walk; for (walk = namehead; (walk && strcmp(walk->name, name)); walk = walk->next) ; if (walk || (!createit)) return walk; walk = (htnames_t *)malloc(sizeof(htnames_t)); walk->name = strdup(name); walk->next = namehead; namehead = walk; return walk; } void do_acknowledgementslog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pageregex, char *expageregex, char *hostregex, char *exhostregex, char *testregex, char *extestregex, char *rcptregex, char *exrcptregex) { FILE *acknowledgementslog; char acknowledgementslogfilename[PATH_MAX]; time_t firstevent = 0; time_t lastevent = getcurrenttime(NULL); acknowledgements_t *head, *walk; struct stat st; char l[MAX_LINE_LEN]; char title[200]; /* For the PCRE matching */ const char *errmsg = NULL; int errofs = 0; pcre *pageregexp = NULL; pcre *expageregexp = NULL; pcre *hostregexp = NULL; pcre *exhostregexp = NULL; pcre *testregexp = NULL; pcre *extestregexp = NULL; pcre *rcptregexp = NULL; pcre *exrcptregexp = NULL; if (maxminutes && (fromtime || totime)) { fprintf(output, "Only one time interval type is allowed!"); return; } if (fromtime) { firstevent = convert_time(fromtime); if(firstevent < 0) { fprintf(output,"Invalid 'from' time: %s", htmlquoted(fromtime)); return; } } else if (maxminutes) { firstevent = getcurrenttime(NULL) - maxminutes*60; } else { firstevent = getcurrenttime(NULL) - 86400; } if (totime) { lastevent = convert_time(totime); if (lastevent < 0) { fprintf(output,"Invalid 'to' time: %s", htmlquoted(totime)); return; } if (lastevent < firstevent) { fprintf(output,"'to' time must be after 'from' time."); return; } } if (!maxcount) maxcount = 100; if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (rcptregex && *rcptregex) rcptregexp = pcre_compile(rcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exrcptregex && *exrcptregex) exrcptregexp = pcre_compile(exrcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); snprintf(acknowledgementslogfilename, sizeof(acknowledgementslogfilename), "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS")); acknowledgementslog = fopen(acknowledgementslogfilename, "r"); if (acknowledgementslog && (stat(acknowledgementslogfilename, &st) == 0)) { time_t curtime; int done = 0; /* Find a spot in the acknowledgements log file close to where the firstevent time is */ fseeko(acknowledgementslog, 0, SEEK_END); do { /* Go back maxcount*80 bytes - one entry is ~80 bytes */ if (ftello(acknowledgementslog) > maxcount*80) { unsigned int uicurtime; fseeko(acknowledgementslog, -maxcount*80, SEEK_CUR); if (fgets(l, sizeof(l), acknowledgementslog) && /* Skip to start of line */ fgets(l, sizeof(l), acknowledgementslog)) { /* 2015-03-07 18:17:03 myserver disk andy 1 1425724570 1425752223 1425838623 testing message */ if ( sscanf(l, "%*u-%*u-%*u %*u:%*u:%*u %*s %*s %*s %*u %*u %u %*u %*s", &uicurtime) == 0 ) { /* that didnt work - try the old format 1430040985 630949 30 630949 np_filename_not_used myserver.procs red testing log format \nAcked by: andy (127.0.0.1) */ sscanf(l, "%u\t%*u\t%*u\t%*u\tnp_filename_not_used\t%*s\t%*s\t%*s", &uicurtime); } curtime = uicurtime; done = (curtime < firstevent); } else { fprintf(output, "Error reading logfile %s: %s\n", acknowledgementslogfilename, strerror(errno)); return; } } else { rewind(acknowledgementslog); done = 1; } } while (!done); } head = NULL; while (acknowledgementslog && (fgets(l, sizeof(l), acknowledgementslog))) { unsigned int etim; unsigned int valid; int duration; time_t eventtime; time_t validity; char host[MAX_LINE_LEN]; char svc[MAX_LINE_LEN]; char recipient[MAX_LINE_LEN]; char message[MAX_LINE_LEN]; char *hostname, *svcname, *p; int itemsfound, pagematch, hostmatch, testmatch, rcptmatch; acknowledgements_t *newrec; void *eventhost; struct htnames_t *eventcolumn; int ovector[30]; /* 2015-03-07 18:17:03 myserver disk andy 1 1425724570 1425752223 1425838623 testing message */ itemsfound = sscanf(l, "%*u-%*u-%*u %*u:%*u:%*u %s %s %s %*u %*u %u %u %[^\t\n]", host, svc, recipient, &etim, &valid, message); if (itemsfound != 6) { /* 1430040985 630949 30 630949 np_filename_not_used myserver.procs red testing log format \nAcked by: andy (127.0.0.1) */ itemsfound = sscanf(l, "%u\t%*u\t%d\t%*u\tnp_filename_not_used\t%s\t%*s\t%[^\n]", &etim, &duration, host, message); if (itemsfound != 4) continue; p = strrchr(host, '.'); if (p) { *p = '\0'; strncpy(svc,p+1, sizeof(svc)); } /* Xymon uses \n in the ack message, for the "acked by" data. Cut it off. */ p = strstr(message, "\\nAcked by:"); if (p) { strncpy(recipient,p+12, sizeof(recipient)); *(p-1) = '\0'; } else { strncpy(recipient,"UnknownUser", sizeof(recipient)); } p = strchr(recipient, '('); if (p) *(p-1) = '\0'; } eventtime = etim; if (eventtime < firstevent) continue; if (eventtime > lastevent) break; validity = duration ? (etim + duration * 60) : valid; hostname = host; svcname = svc; eventhost = hostinfo(hostname); if (!eventhost) continue; /* Dont report hosts that no longer exist */ eventcolumn = getname(svcname, 1); p = strchr(recipient, '['); if (p) *p = '\0'; if (pageregexp) { char *pagename; pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 1; if (!pagematch) continue; if (expageregexp) { char *pagename; pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 0; if (pagematch) continue; if (hostregexp) hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 1; if (!hostmatch) continue; if (exhostregexp) hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 0; if (hostmatch) continue; if (testregexp) testmatch = (pcre_exec(testregexp, NULL, svcname, strlen(svcname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 1; if (!testmatch) continue; if (extestregexp) testmatch = (pcre_exec(extestregexp, NULL, svcname, strlen(svcname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 0; if (testmatch) continue; if (rcptregexp) rcptmatch = (pcre_exec(rcptregexp, NULL, recipient, strlen(recipient), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else rcptmatch = 1; if (!rcptmatch) continue; if (exrcptregexp) rcptmatch = (pcre_exec(exrcptregexp, NULL, recipient, strlen(recipient), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else rcptmatch = 0; if (rcptmatch) continue; newrec = (acknowledgements_t *) malloc(sizeof(acknowledgements_t)); newrec->host = eventhost; newrec->service = eventcolumn; newrec->eventtime = eventtime; newrec->validity = validity; newrec->recipient = strdup(recipient); newrec->message = strdup(message); newrec->next = head; head = newrec; } if (head) { char *bgcolors[2] = { "#000000", "#000066" }; int bgcolor = 0; int count; struct acknowledgements_t *lasttoshow = head; count=0; walk=head; do { count++; lasttoshow = walk; walk = walk->next; } while (walk && (counteventtime) / 60)); } else { snprintf(title, sizeof(title), "%d events acknowledged.", count); } fprintf(output, "

\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); fprintf(output, "\n"); for (walk=head; (walk != lasttoshow->next); walk=walk->next) { char *hostname = xmh_item(walk->host, XMH_HOSTNAME); fprintf(output, "\n", bgcolors[bgcolor]); bgcolor = ((bgcolor + 1) % 2); fprintf(output, "\n", ctime(&walk->eventtime)); fprintf(output, "\n", ctime(&walk->validity)); fprintf(output, "\n", hostname); fprintf(output, "\n", walk->service->name); fprintf(output, "\n", walk->recipient); fprintf(output, "\n", walk->message); } fprintf(output, "
%s
TimeValid UntilHostServiceAcknowledged ByMessage
%s%s%s%s%s%s
\n"); /* Clean up */ walk = head; do { struct acknowledgements_t *tmp = walk; walk = walk->next; xfree(tmp->recipient); xfree(tmp->message); xfree(tmp); } while (walk); } else { /* No acknowledgements during the past maxminutes */ if (acknowledgementslog) snprintf(title, sizeof(title), "No events acknowledged in the last %d minutes", maxminutes); else strncpy(title, "No acknowledgements logged", sizeof(title)); fprintf(output, "

\n"); fprintf(output, "\n", title); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); fprintf(output, "\n"); fprintf(output, "
%s
\n"); fprintf(output, "
\n"); } if (acknowledgementslog) fclose(acknowledgementslog); if (pageregexp) pcre_free(pageregexp); if (expageregexp) pcre_free(expageregexp); if (hostregexp) pcre_free(hostregexp); if (exhostregexp) pcre_free(exhostregexp); if (testregexp) pcre_free(testregexp); if (extestregexp) pcre_free(extestregexp); if (rcptregexp) pcre_free(rcptregexp); if (exrcptregexp) pcre_free(exrcptregexp); } xymon-4.3.30/lib/readmib.c0000664000076400007640000001736613515623702015541 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor SNMP data collection tool */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: readmib.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include "libxymon.h" static void * mibdefs; /* Holds the list of MIB definitions */ static xtreePos_t nexthandle; int readmibs(char *cfgfn, int verbose) { STATIC_SBUF_DEFINE(fn); static void *cfgfiles = NULL; FILE *cfgfd; strbuffer_t *inbuf; mibdef_t *mib = NULL; /* Check if config was modified */ if (cfgfiles) { if (!stackfmodified(cfgfiles)) { dbgprintf("No files changed, skipping reload\n"); return 0; } else { xtreePos_t handle; errprintf("Re-loading MIBs\n"); /* Clear list of config files */ stackfclist(&cfgfiles); cfgfiles = NULL; /* Drop the current data */ for (handle = xtreeFirst(mibdefs); (handle != xtreeEnd(mibdefs)); handle = xtreeNext(mibdefs, handle)) { mibdef_t *mib = (mibdef_t *)xtreeData(mibdefs, handle); oidset_t *swalk, *szombie; mibidx_t *iwalk, *izombie; int i; swalk = mib->oidlisthead; while (swalk) { szombie = swalk; swalk = swalk->next; for (i=0; (i <= szombie->oidcount); i++) { xfree(szombie->oids[i].dsname); xfree(szombie->oids[i].oid); } xfree(szombie->oids); xfree(szombie); } iwalk = mib->idxlist; while (iwalk) { izombie = iwalk; iwalk = iwalk->next; if (izombie->keyoid) xfree(izombie->keyoid); if (izombie->rootoid) xfree(izombie->rootoid); xfree(izombie); } if (mib->mibfn) xfree(mib->mibfn); if (mib->mibname) xfree(mib->mibname); freestrbuffer(mib->resultbuf); xfree(mib); } xtreeDestroy(mibdefs); } } mibdefs = xtreeNew(strcasecmp); nexthandle = xtreeEnd(mibdefs); if (fn) xfree(fn); fn = cfgfn; if (!fn) { SBUF_MALLOC(fn, strlen(xgetenv("XYMONHOME")) + strlen("/etc/snmpmibs.cfg") + 1); snprintf(fn, fn_buflen, "%s/etc/snmpmibs.cfg", xgetenv("XYMONHOME")); } cfgfd = stackfopen(fn, "r", &cfgfiles); if (cfgfd == NULL) { errprintf("Cannot open configuration files %s\n", fn); return 0; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *bot, *p; sanitize_input(inbuf, 0, 0); bot = STRBUF(inbuf) + strspn(STRBUF(inbuf), " \t"); if ((*bot == '\0') || (*bot == '#')) continue; if (*bot == '[') { char *mibname; mibname = bot+1; p = strchr(mibname, ']'); if (p) *p = '\0'; mib = (mibdef_t *)calloc(1, sizeof(mibdef_t)); mib->mibname = strdup(mibname); mib->oidlisthead = mib->oidlisttail = (oidset_t *)calloc(1, sizeof(oidset_t)); mib->oidlisttail->oidsz = 10; mib->oidlisttail->oidcount = -1; mib->oidlisttail->oids = (oidds_t *)malloc(mib->oidlisttail->oidsz*sizeof(oidds_t)); mib->resultbuf = newstrbuffer(0); mib->tabular = 0; xtreeAdd(mibdefs, mib->mibname, mib); continue; } if (mib && (strncmp(bot, "mibfile", 7) == 0)) { p = bot + 7; p += strspn(p, " \t"); mib->mibfn = strdup(p); continue; } if (mib && (strncmp(bot, "extra", 5) == 0)) { /* Add an extra set of MIB objects to retrieve separately */ mib->oidlisttail->next = (oidset_t *)calloc(1, sizeof(oidset_t)); mib->oidlisttail = mib->oidlisttail->next; mib->oidlisttail->oidsz = 10; mib->oidlisttail->oidcount = -1; mib->oidlisttail->oids = (oidds_t *)malloc(mib->oidlisttail->oidsz*sizeof(oidds_t)); continue; } if (mib && (strncmp(bot, "table", 5) == 0)) { mib->tabular = 1; continue; } if (mib && ((strncmp(bot, "keyidx", 6) == 0) || (strncmp(bot, "validx", 6) == 0))) { /* * Define an index. Looks like: * keyidx (IF-MIB::ifDescr) * validx [IP-MIB::ipAdEntIfIndex] */ char endmarks[6]; mibidx_t *newidx = (mibidx_t *)calloc(1, sizeof(mibidx_t)); p = bot + 6; p += strspn(p, " \t"); newidx->marker = *p; p++; newidx->idxtype = (strncmp(bot, "keyidx", 6) == 0) ? MIB_INDEX_IN_OID : MIB_INDEX_IN_VALUE; newidx->keyoid = strdup(p); snprintf(endmarks, sizeof(endmarks), "%s%c", ")]}>", newidx->marker); p = newidx->keyoid + strcspn(newidx->keyoid, endmarks); *p = '\0'; newidx->next = mib->idxlist; mib->idxlist = newidx; mib->tabular = 1; continue; } if (mib) { /* icmpInMsgs = IP-MIB::icmpInMsgs.0 [/u32] [/rrd:TYPE] */ char *tok, *name, *oid = NULL; name = strtok(bot, " \t"); if (name) { tok = strtok(NULL, " \t"); if (tok && (*tok == '=')) oid = strtok(NULL, " \t"); else oid = tok; } if (name && oid) { mib->oidlisttail->oidcount++; if (mib->oidlisttail->oidcount == mib->oidlisttail->oidsz) { mib->oidlisttail->oidsz += 10; mib->oidlisttail->oids = (oidds_t *)realloc(mib->oidlisttail->oids, mib->oidlisttail->oidsz*sizeof(oidds_t)); } mib->oidlisttail->oids[mib->oidlisttail->oidcount].dsname = strdup(name); mib->oidlisttail->oids[mib->oidlisttail->oidcount].oid = strdup(oid); mib->oidlisttail->oids[mib->oidlisttail->oidcount].conversion = OID_CONVERT_NONE; mib->oidlisttail->oids[mib->oidlisttail->oidcount].rrdtype = RRD_NOTRACK; tok = strtok(NULL, " \t"); while (tok) { if (strcasecmp(tok, "/u32") == 0) { mib->oidlisttail->oids[mib->oidlisttail->oidcount].conversion = OID_CONVERT_U32; } else if (strncasecmp(tok, "/rrd:", 5) == 0) { char *rrdtype = tok+5; if (strcasecmp(rrdtype, "COUNTER") == 0) mib->oidlisttail->oids[mib->oidlisttail->oidcount].rrdtype = RRD_TRACK_COUNTER; else if (strcasecmp(rrdtype, "GAUGE") == 0) mib->oidlisttail->oids[mib->oidlisttail->oidcount].rrdtype = RRD_TRACK_GAUGE; else if (strcasecmp(rrdtype, "DERIVE") == 0) mib->oidlisttail->oids[mib->oidlisttail->oidcount].rrdtype = RRD_TRACK_DERIVE; else if (strcasecmp(rrdtype, "ABSOLUTE") == 0) mib->oidlisttail->oids[mib->oidlisttail->oidcount].rrdtype = RRD_TRACK_ABSOLUTE; } tok = strtok(NULL, " \t"); } } continue; } if (verbose) { errprintf("Unknown MIB definition line: '%s'\n", bot); } } stackfclose(cfgfd); freestrbuffer(inbuf); if (debug) { xtreePos_t handle; for (handle = xtreeFirst(mibdefs); (handle != xtreeEnd(mibdefs)); handle = xtreeNext(mibdefs, handle)) { mibdef_t *mib = (mibdef_t *)xtreeData(mibdefs, handle); oidset_t *swalk; int i; dbgprintf("[%s]\n", mib->mibname); for (swalk = mib->oidlisthead; (swalk); swalk = swalk->next) { dbgprintf("\t*** OID set, %d entries ***\n", swalk->oidcount); for (i=0; (i <= swalk->oidcount); i++) { dbgprintf("\t\t%s = %s\n", swalk->oids[i].dsname, swalk->oids[i].oid); } } } } return 1; } mibdef_t *first_mib(void) { nexthandle = xtreeFirst(mibdefs); if (nexthandle == xtreeEnd(mibdefs)) return NULL; else return (mibdef_t *)xtreeData(mibdefs, nexthandle); } mibdef_t *next_mib(void) { nexthandle = xtreeNext(mibdefs, nexthandle); if (nexthandle == xtreeEnd(mibdefs)) return NULL; else return (mibdef_t *)xtreeData(mibdefs, nexthandle); } mibdef_t *find_mib(char *mibname) { xtreePos_t handle; handle = xtreeFind(mibdefs, mibname); if (handle == xtreeEnd(mibdefs)) return NULL; else return (mibdef_t *)xtreeData(mibdefs, handle); } xymon-4.3.30/lib/rmd160c.h0000664000076400007640000000217711615341300015277 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* API for the RMD160 digest routines. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __RMD160C_H__ #define __RMD160C_H__ extern int myRIPEMD160_Size(void); extern void myRIPEMD160_Init(void *c); extern void myRIPEMD160_Update(void *c, const void *data, size_t len); extern void myRIPEMD160_Final(unsigned char *md, void *c); #endif xymon-4.3.30/lib/loadhosts.c0000664000076400007640000006412213515623702016126 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the hosts.cfg */ /* file and keeping track of what hosts are known, their aliases and planned */ /* downtime settings etc. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: loadhosts.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" typedef struct pagelist_t { char *pagepath; char *pagetitle; struct pagelist_t *next; } pagelist_t; typedef struct namelist_t { char ip[IP_ADDR_STRLEN]; char *hostname; /* Name for item 2 of hosts.cfg */ char *logname; /* Name of the host directory in XYMONHISTLOGS (underscores replaces dots). */ int preference; /* For host with multiple entries, mark if we have the preferred one */ pagelist_t *page; /* Host location in the page/subpage/subparent tree */ void *data; /* Misc. data supplied by the user of this library function */ struct namelist_t *defaulthost; /* Points to the latest ".default." host */ int pageindex; char *groupid, *dgname; char *classname; char *osname; struct namelist_t *next, *prev; char *allelems; /* Storage for data pointed to by elems */ char **elems; /* List of pointers to the elements of the entry */ /* * The following are pre-parsed elements. * These are pre-parsed because they are used by the xymon daemon, so * fast access to them is an optimization. */ char *clientname; /* CLIENT: tag - host alias */ char *downtime; /* DOWNTIME tag - when host has planned downtime. */ time_t notbefore, notafter; /* NOTBEFORE and NOTAFTER tags as time_t values */ } namelist_t; static pagelist_t *pghead = NULL; static namelist_t *namehead = NULL, *nametail = NULL; static namelist_t *defaulthost = NULL; static char *xmh_item_key[XMH_LAST]; static char *xmh_item_name[XMH_LAST]; static int xmh_item_isflag[XMH_LAST]; static int configloaded = 0; static void * rbhosts; static void * rbclients; static void xmh_item_list_setup(void) { static int setupdone = 0; int i; enum xmh_item_t bi; if (setupdone) return; /* Doing it this way makes sure the index matches the value */ setupdone = 1; memset(xmh_item_key, 0, sizeof(xmh_item_key)); memset(xmh_item_name, 0, sizeof(xmh_item_key)); memset(xmh_item_isflag, 0, sizeof(xmh_item_isflag)); xmh_item_key[XMH_NET] = "NET:"; xmh_item_name[XMH_NET] = "XMH_NET"; xmh_item_key[XMH_DISPLAYNAME] = "NAME:"; xmh_item_name[XMH_DISPLAYNAME] = "XMH_DISPLAYNAME"; xmh_item_key[XMH_CLIENTALIAS] = "CLIENT:"; xmh_item_name[XMH_CLIENTALIAS] = "XMH_CLIENTALIAS"; xmh_item_key[XMH_COMMENT] = "COMMENT:"; xmh_item_name[XMH_COMMENT] = "XMH_COMMENT"; xmh_item_key[XMH_DESCRIPTION] = "DESCR:"; xmh_item_name[XMH_DESCRIPTION] = "XMH_DESCRIPTION"; xmh_item_key[XMH_DOCURL] = "DOC:"; xmh_item_name[XMH_DOCURL] = "XMH_DOCURL"; xmh_item_key[XMH_NK] = "NK:"; xmh_item_name[XMH_NK] = "XMH_NK"; xmh_item_key[XMH_NKTIME] = "NKTIME="; xmh_item_name[XMH_NKTIME] = "XMH_NKTIME"; xmh_item_key[XMH_TRENDS] = "TRENDS:"; xmh_item_name[XMH_TRENDS] = "XMH_TRENDS"; xmh_item_key[XMH_WML] = "WML:"; xmh_item_name[XMH_WML] = "XMH_WML"; xmh_item_key[XMH_NOPROP] = "NOPROP:"; xmh_item_name[XMH_NOPROP] = "XMH_NOPROP"; xmh_item_key[XMH_NOPROPRED] = "NOPROPRED:"; xmh_item_name[XMH_NOPROPRED] = "XMH_NOPROPRED"; xmh_item_key[XMH_NOPROPYELLOW] = "NOPROPYELLOW:"; xmh_item_name[XMH_NOPROPYELLOW] = "XMH_NOPROPYELLOW"; xmh_item_key[XMH_NOPROPPURPLE] = "NOPROPPURPLE:"; xmh_item_name[XMH_NOPROPPURPLE] = "XMH_NOPROPPURPLE"; xmh_item_key[XMH_NOPROPACK] = "NOPROPACK:"; xmh_item_name[XMH_NOPROPACK] = "XMH_NOPROPACK"; xmh_item_key[XMH_REPORTTIME] = "REPORTTIME="; xmh_item_name[XMH_REPORTTIME] = "XMH_REPORTTIME"; xmh_item_key[XMH_WARNPCT] = "WARNPCT:"; xmh_item_name[XMH_WARNPCT] = "XMH_WARNPCT"; xmh_item_key[XMH_WARNSTOPS] = "WARNSTOPS:"; xmh_item_name[XMH_WARNSTOPS] = "XMH_WARNSTOPS"; xmh_item_key[XMH_DOWNTIME] = "DOWNTIME="; xmh_item_name[XMH_DOWNTIME] = "XMH_DOWNTIME"; xmh_item_key[XMH_SSLDAYS] = "ssldays="; xmh_item_name[XMH_SSLDAYS] = "XMH_SSLDAYS"; xmh_item_key[XMH_SSLMINBITS] = "sslbits="; xmh_item_name[XMH_SSLMINBITS] = "XMH_SSLMINBITS"; xmh_item_key[XMH_DEPENDS] = "depends="; xmh_item_name[XMH_DEPENDS] = "XMH_DEPENDS"; xmh_item_key[XMH_BROWSER] = "browser="; xmh_item_name[XMH_BROWSER] = "XMH_BROWSER"; xmh_item_key[XMH_HTTPHEADERS] = "httphdr="; xmh_item_name[XMH_HTTPHEADERS] = "XMH_HTTPHEADERS"; xmh_item_key[XMH_HOLIDAYS] = "holidays="; xmh_item_name[XMH_HOLIDAYS] = "XMH_HOLIDAYS"; xmh_item_key[XMH_DELAYRED] = "delayred="; xmh_item_name[XMH_DELAYRED] = "XMH_DELAYRED"; xmh_item_key[XMH_DELAYYELLOW] = "delayyellow="; xmh_item_name[XMH_DELAYYELLOW] = "XMH_DELAYYELLOW"; xmh_item_key[XMH_FLAG_NOINFO] = "noinfo"; xmh_item_name[XMH_FLAG_NOINFO] = "XMH_FLAG_NOINFO"; xmh_item_key[XMH_FLAG_NOTRENDS] = "notrends"; xmh_item_name[XMH_FLAG_NOTRENDS] = "XMH_FLAG_NOTRENDS"; xmh_item_key[XMH_FLAG_NOCLIENT] = "noclient"; xmh_item_name[XMH_FLAG_NOCLIENT] = "XMH_FLAG_NOCLIENT"; xmh_item_key[XMH_FLAG_NODISP] = "nodisp"; xmh_item_name[XMH_FLAG_NODISP] = "XMH_FLAG_NODISP"; xmh_item_key[XMH_FLAG_NONONGREEN] = "nonongreen"; xmh_item_name[XMH_FLAG_NONONGREEN] = "XMH_FLAG_NONONGREEN"; xmh_item_key[XMH_FLAG_NOBB2] = "nobb2"; xmh_item_name[XMH_FLAG_NOBB2] = "XMH_FLAG_NOBB2"; xmh_item_key[XMH_FLAG_PREFER] = "prefer"; xmh_item_name[XMH_FLAG_PREFER] = "XMH_FLAG_PREFER"; xmh_item_key[XMH_FLAG_NOSSLCERT] = "nosslcert"; xmh_item_name[XMH_FLAG_NOSSLCERT] = "XMH_FLAG_NOSSLCERT"; xmh_item_key[XMH_FLAG_TRACE] = "trace"; xmh_item_name[XMH_FLAG_TRACE] = "XMH_FLAG_TRACE"; xmh_item_key[XMH_FLAG_NOTRACE] = "notrace"; xmh_item_name[XMH_FLAG_NOTRACE] = "XMH_FLAG_NOTRACE"; xmh_item_key[XMH_FLAG_NOCONN] = "noconn"; xmh_item_name[XMH_FLAG_NOCONN] = "XMH_FLAG_NOCONN"; xmh_item_key[XMH_FLAG_NOPING] = "noping"; xmh_item_name[XMH_FLAG_NOPING] = "XMH_FLAG_NOPING"; xmh_item_key[XMH_FLAG_DIALUP] = "dialup"; xmh_item_name[XMH_FLAG_DIALUP] = "XMH_FLAG_DIALUP"; xmh_item_key[XMH_FLAG_TESTIP] = "testip"; xmh_item_name[XMH_FLAG_TESTIP] = "XMH_FLAG_TESTIP"; xmh_item_key[XMH_FLAG_LDAPFAILYELLOW] = "ldapyellowfail"; xmh_item_name[XMH_FLAG_LDAPFAILYELLOW] = "XMH_FLAG_LDAPFAILYELLOW"; xmh_item_key[XMH_FLAG_NOCLEAR] = "NOCLEAR"; xmh_item_name[XMH_FLAG_NOCLEAR] = "XMH_FLAG_NOCLEAR"; xmh_item_key[XMH_FLAG_HIDEHTTP] = "HIDEHTTP"; xmh_item_name[XMH_FLAG_HIDEHTTP] = "XMH_FLAG_HIDEHTTP"; xmh_item_key[XMH_PULLDATA] = "PULLDATA"; xmh_item_name[XMH_PULLDATA] = "XMH_PULLDATA"; xmh_item_key[XMH_NOFLAP] = "NOFLAP"; xmh_item_name[XMH_NOFLAP] = "XMH_NOFLAP"; xmh_item_key[XMH_FLAG_MULTIHOMED] = "MULTIHOMED"; xmh_item_name[XMH_FLAG_MULTIHOMED] = "XMH_MULTIHOMED"; xmh_item_key[XMH_FLAG_HTTP_HEADER_MATCH] = "headermatch"; xmh_item_name[XMH_FLAG_HTTP_HEADER_MATCH] = "XMH_FLAG_HTTP_HEADER_MATCH"; xmh_item_key[XMH_FLAG_SNI] = "sni"; // Enable SNI (Server name Indication) for TLS requests xmh_item_name[XMH_FLAG_SNI] = "XMH_FLAG_SNI"; xmh_item_key[XMH_FLAG_NOSNI] = "nosni"; // Disable SNI (Server name Indication) for TLS requests xmh_item_name[XMH_FLAG_NOSNI] = "XMH_FLAG_NOSNI"; xmh_item_key[XMH_LDAPLOGIN] = "ldaplogin="; xmh_item_name[XMH_LDAPLOGIN] = "XMH_LDAPLOGIN"; xmh_item_key[XMH_CLASS] = "CLASS:"; xmh_item_name[XMH_CLASS] = "XMH_CLASS"; xmh_item_key[XMH_OS] = "OS:"; xmh_item_name[XMH_OS] = "XMH_OS"; xmh_item_key[XMH_NOCOLUMNS] = "NOCOLUMNS:"; xmh_item_name[XMH_NOCOLUMNS] = "XMH_NOCOLUMNS"; xmh_item_key[XMH_NOTBEFORE] = "NOTBEFORE:"; xmh_item_name[XMH_NOTBEFORE] = "XMH_NOTBEFORE"; xmh_item_key[XMH_NOTAFTER] = "NOTAFTER:"; xmh_item_name[XMH_NOTAFTER] = "XMH_NOTAFTER"; xmh_item_key[XMH_COMPACT] = "COMPACT:"; xmh_item_name[XMH_COMPACT] = "XMH_COMPACT"; xmh_item_key[XMH_INTERFACES] = "INTERFACES:"; xmh_item_name[XMH_INTERFACES] = "XMH_INTERFACES"; xmh_item_key[XMH_ACCEPT_ONLY] = "ACCEPTONLY:"; xmh_item_name[XMH_ACCEPT_ONLY] = "XMH_ACCEPT_ONLY"; xmh_item_name[XMH_IP] = "XMH_IP"; xmh_item_name[XMH_CLIENTALIAS] = "XMH_CLIENTALIAS"; xmh_item_name[XMH_HOSTNAME] = "XMH_HOSTNAME"; xmh_item_name[XMH_PAGENAME] = "XMH_PAGENAME"; xmh_item_name[XMH_PAGEPATH] = "XMH_PAGEPATH"; xmh_item_name[XMH_PAGETITLE] = "XMH_PAGETITLE"; xmh_item_name[XMH_PAGEPATHTITLE] = "XMH_PAGEPATHTITLE"; xmh_item_name[XMH_ALLPAGEPATHS] = "XMH_ALLPAGEPATHS"; xmh_item_name[XMH_GROUPID] = "XMH_GROUPID"; xmh_item_name[XMH_DGNAME] = "XMH_DGNAME"; xmh_item_name[XMH_PAGEINDEX] = "XMH_PAGEINDEX"; xmh_item_name[XMH_RAW] = "XMH_RAW"; xmh_item_name[XMH_DATA] = "XMH_DATA"; i = 0; while (xmh_item_key[i]) i++; if (i != XMH_IP) { errprintf("ERROR: Setup failure in xmh_item_key position %d\n", i); } for (bi = 0; (bi < XMH_LAST); bi++) if (xmh_item_name[bi]) xmh_item_isflag[bi] = (strncmp(xmh_item_name[bi], "XMH_FLAG_", 9) == 0); } static char *xmh_find_item(namelist_t *host, enum xmh_item_t item) { int i; char *result; if (item == XMH_LAST) return NULL; /* Unknown item requested */ xmh_item_list_setup(); i = 0; while (host->elems[i] && strncasecmp(host->elems[i], xmh_item_key[item], strlen(xmh_item_key[item]))) i++; result = (host->elems[i] ? (host->elems[i] + strlen(xmh_item_key[item])) : NULL); /* Handle the LARRD: tag in Xymon 4.0.4 and earlier */ if (!result && (item == XMH_TRENDS)) { i = 0; while (host->elems[i] && strncasecmp(host->elems[i], "LARRD:", 6)) i++; result = (host->elems[i] ? (host->elems[i] + 6) : NULL); } if (result || !host->defaulthost || (strcasecmp(host->hostname, ".default.") == 0)) { if (xmh_item_isflag[item]) { return (result ? xmh_item_key[item] : NULL); } else return result; } else return xmh_find_item(host->defaulthost, item); } static void initialize_hostlist(void) { while (defaulthost) { namelist_t *walk = defaulthost; defaulthost = defaulthost->defaulthost; if (walk->hostname) xfree(walk->hostname); if (walk->groupid) xfree(walk->groupid); if (walk->dgname) xfree(walk->dgname); if (walk->classname) xfree(walk->classname); if (walk->osname) xfree(walk->osname); if (walk->logname) xfree(walk->logname); if (walk->allelems) xfree(walk->allelems); if (walk->elems) xfree(walk->elems); xfree(walk); } while (namehead) { namelist_t *walk = namehead; namehead = namehead->next; /* clientname should not be freed, since it's just a pointer into the elems-array */ if (walk->hostname) xfree(walk->hostname); if (walk->groupid) xfree(walk->groupid); if (walk->dgname) xfree(walk->dgname); if (walk->classname) xfree(walk->classname); if (walk->osname) xfree(walk->osname); if (walk->logname) xfree(walk->logname); if (walk->allelems) xfree(walk->allelems); if (walk->elems) xfree(walk->elems); xfree(walk); } nametail = NULL; while (pghead) { pagelist_t *walk = pghead; pghead = pghead->next; if (walk->pagepath) xfree(walk->pagepath); if (walk->pagetitle) xfree(walk->pagetitle); xfree(walk); } /* Setup the top-level page */ pghead = (pagelist_t *) malloc(sizeof(pagelist_t)); pghead->pagepath = strdup(""); pghead->pagetitle = strdup(""); pghead->next = NULL; } static void build_hosttree(void) { static int hosttree_exists = 0; namelist_t *walk; xtreeStatus_t status; char *tstr; if (hosttree_exists) { xtreeDestroy(rbhosts); xtreeDestroy(rbclients); } rbhosts = xtreeNew(strcasecmp); rbclients = xtreeNew(strcasecmp); hosttree_exists = 1; for (walk = namehead; (walk); walk = walk->next) { status = xtreeAdd(rbhosts, walk->hostname, walk); if (walk->clientname) xtreeAdd(rbclients, walk->clientname, walk); switch (status) { case XTREE_STATUS_OK: case XTREE_STATUS_DUPLICATE_KEY: break; case XTREE_STATUS_MEM_EXHAUSTED: errprintf("loadhosts:build_hosttree - insert into tree failed (out of memory)\n"); break; default: errprintf("loadhosts:build_hosttree - insert into tree failed code %d\n", status); break; } tstr = xmh_item(walk, XMH_NOTBEFORE); walk->notbefore = (tstr ? timestr2timet(tstr) : 0); if (walk->notbefore == -1) walk->notbefore = 0; tstr = xmh_item(walk, XMH_NOTAFTER); walk->notafter = (tstr ? timestr2timet(tstr) : INT_MAX); if (walk->notafter == -1) walk->notafter = INT_MAX; } } #include "loadhosts_file.c" #include "loadhosts_net.c" char *knownhost(char *hostname, char *hostip, enum ghosthandling_t ghosthandling) { /* * ghosthandling = GH_ALLOW : Default BB method (case-sensitive, no logging, keep ghosts) * ghosthandling = GH_IGNORE : Case-insensitive, no logging, drop ghosts * ghosthandling = GH_LOG : Case-insensitive, log ghosts, drop ghosts * ghosthandling = GH_MATCH : Like GH_LOG, but try to match unknown names against known hosts */ xtreePos_t hosthandle; namelist_t *walk = NULL; static char *result = NULL; time_t now = getcurrenttime(NULL); if (result) xfree(result); result = NULL; if (hivalhost) { *hostip = '\0'; if (!hivalbuf || (*hivalbuf == '\0')) return NULL; result = (strcasecmp(hivalhost, hostname) == 0) ? strdup(hivalhost) : NULL; if (!result && hivals[XMH_CLIENTALIAS]) { result = (strcasecmp(hivals[XMH_CLIENTALIAS], hostname) == 0) ? strdup(hivalhost) : NULL; } if (result && hivals[XMH_IP]) strcpy(hostip, hivals[XMH_IP]); return result; } /* Find the host in the normal hostname list */ hosthandle = xtreeFind(rbhosts, hostname); if (hosthandle != xtreeEnd(rbhosts)) { walk = (namelist_t *)xtreeData(rbhosts, hosthandle); } else { /* Not found - lookup in the client alias list */ hosthandle = xtreeFind(rbclients, hostname); if (hosthandle != xtreeEnd(rbclients)) { walk = (namelist_t *)xtreeData(rbclients, hosthandle); } } if (walk) { /* * Force our version of the hostname. Done here so CLIENT works always. */ strcpy(hostip, walk->ip); result = strdup(walk->hostname); } else { *hostip = '\0'; result = strdup(hostname); } /* If default method, just say yes */ if (ghosthandling == GH_ALLOW) return result; /* Allow all summaries */ if (strcmp(hostname, "summary") == 0) return result; if (walk && ( ((walk->notbefore > now) || (walk->notafter < now)) )) walk = NULL; return (walk ? result : NULL); } int knownloghost(char *logdir) { namelist_t *walk = NULL; if (hivalhost) { int result; char *hvh_logname, *p; hvh_logname = strdup(hivalhost); p = hvh_logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } result = (strcasecmp(hvh_logname, logdir) == 0); xfree(hvh_logname); return result; } /* Find the host */ /* Must do the linear string search, since the tree is indexed by the hostname, not logname */ for (walk = namehead; (walk && (strcasecmp(walk->logname, logdir) != 0)); walk = walk->next); return (walk != NULL); } void *hostinfo(char *hostname) { xtreePos_t hosthandle; namelist_t *result = NULL; time_t now = getcurrenttime(NULL); if (hivalhost) { return (strcasecmp(hostname, hivalhost) == 0) ? &hival_hostinfo : NULL; } if (!configloaded) { load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); configloaded = 1; } hosthandle = xtreeFind(rbhosts, hostname); if (hosthandle != xtreeEnd(rbhosts)) { result = (namelist_t *)xtreeData(rbhosts, hosthandle); if ((result->notbefore > now) || (result->notafter < now)) return NULL; } return result; } void *localhostinfo(char *hostname) { /* Returns a static fake hostrecord */ static namelist_t *result = NULL; if (!result) { initialize_hostlist(); result = (namelist_t *)calloc(1, sizeof(namelist_t)); } strncpy(result->ip, "127.0.0.1", sizeof(result->ip)); if (result->hostname) xfree(result->hostname); result->hostname = strdup(hostname); if (result->logname) xfree(result->logname); result->logname = strdup(hostname); { char *p = result->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } result->preference = 1; result->page = pghead; if (result->allelems) xfree(result->allelems); result->allelems = strdup(""); if (result->elems) xfree(result->elems); result->elems = (char **)malloc(sizeof(char *)); result->elems[0] = NULL; return result; } char *xmh_item(void *hostin, enum xmh_item_t item) { STATIC_SBUF_DEFINE(result); static char intbuf[15]; static char *inttxt = NULL; static strbuffer_t *rawtxt = NULL; char *p; namelist_t *host = (namelist_t *)hostin; namelist_t *hwalk; if (rawtxt == NULL) rawtxt = newstrbuffer(0); if (inttxt == NULL) inttxt = (char *)malloc(10); if (host == NULL) return NULL; if (host == &hival_hostinfo) return hivals[item]; switch (item) { case XMH_CLIENTALIAS: return host->clientname; case XMH_IP: return host->ip; case XMH_CLASS: if (host->classname) return host->classname; else return xmh_find_item(host, item); break; case XMH_OS: if (host->osname) return host->osname; else return xmh_find_item(host, item); break; case XMH_HOSTNAME: return host->hostname; case XMH_PAGENAME: p = strrchr(host->page->pagepath, '/'); if (p) return (p+1); else return host->page->pagepath; case XMH_PAGEPATH: return host->page->pagepath; case XMH_PAGETITLE: p = strrchr(host->page->pagetitle, '/'); if (p) return (p+1); /* else: Fall through */ case XMH_PAGEPATHTITLE: if (strlen(host->page->pagetitle)) return host->page->pagetitle; return "Top Page"; case XMH_PAGEINDEX: snprintf(intbuf, sizeof(intbuf), "%d", host->pageindex); return intbuf; case XMH_ALLPAGEPATHS: if (rawtxt) clearstrbuffer(rawtxt); hwalk = host; while (hwalk && (strcmp(hwalk->hostname, host->hostname) == 0)) { if (STRBUFLEN(rawtxt) > 0) addtobuffer(rawtxt, ","); addtobuffer(rawtxt, hwalk->page->pagepath); hwalk = hwalk->next; } return STRBUF(rawtxt); case XMH_GROUPID: return host->groupid; case XMH_DGNAME: return host->dgname; case XMH_DOCURL: p = xmh_find_item(host, item); if (p) { if (result) xfree(result); SBUF_MALLOC(result, strlen(p) + strlen(host->hostname) + 1); snprintf(result, result_buflen, p, host->hostname); return result; } else return NULL; case XMH_DOWNTIME: if (host->downtime) return host->downtime; else if (host->defaulthost) return host->defaulthost->downtime; else return NULL; case XMH_RAW: if (rawtxt) clearstrbuffer(rawtxt); p = xmh_item_walk(host); while (p) { addtobuffer(rawtxt, nlencode(p)); p = xmh_item_walk(NULL); if (p) addtobuffer(rawtxt, "|"); } return STRBUF(rawtxt); case XMH_HOLIDAYS: p = xmh_find_item(host, item); if (!p) p = getenv("HOLIDAYS"); return p; case XMH_DATA: return host->data; case XMH_FLAG_NONONGREEN: case XMH_FLAG_NOBB2: p = xmh_find_item(host, XMH_FLAG_NONONGREEN); if (p == NULL) p = xmh_find_item(host, XMH_FLAG_NOBB2); return p; case XMH_NOFLAP: /* special - can be 'noflap=test1,test2' or just 'noflap' */ p = xmh_find_item(host, XMH_NOFLAP); if ((p != NULL) && (*(p) == '\0')) p = xmh_item_key[XMH_NOFLAP]; /* mirror flag semantics */ return p; case XMH_PULLDATA: /* special - can be 'pulldata=IP:PORT' or just 'pulldata' */ p = xmh_find_item(host, XMH_PULLDATA); if ((p != NULL) && (*(p) == '\0')) p = xmh_item_key[XMH_PULLDATA]; /* mirror flag semantics */ return p; default: return xmh_find_item(host, item); } return NULL; } char *xmh_custom_item(void *hostin, char *key) { int i; namelist_t *host = (namelist_t *)hostin; i = 0; while (host->elems[i] && strncmp(host->elems[i], key, strlen(key))) i++; return host->elems[i]; } enum xmh_item_t xmh_key_idx(char *item) { enum xmh_item_t i; xmh_item_list_setup(); i = 0; while (xmh_item_name[i] && strcmp(xmh_item_name[i], item)) i++; return (xmh_item_name[i] ? i : XMH_LAST); } char *xmh_item_byname(void *hostin, char *item) { enum xmh_item_t i; namelist_t *host = (namelist_t *)hostin; i = xmh_key_idx(item); return ((i == -1) ? NULL : xmh_item(host, i)); } char *xmh_item_walk(void *hostin) { static int idx = -1; static namelist_t *curhost = NULL; char *result; namelist_t *host = (namelist_t *)hostin; if ((host == NULL) && (idx == -1)) return NULL; /* Programmer failure */ if (host != NULL) { idx = 0; curhost = host; } result = curhost->elems[idx]; if (result) idx++; else idx = -1; return result; } int xmh_item_idx(char *value) { int i; xmh_item_list_setup(); i = 0; while (xmh_item_key[i] && strncmp(xmh_item_key[i], value, strlen(xmh_item_key[i]))) i++; return (xmh_item_key[i] ? i : -1); } char *xmh_item_id(enum xmh_item_t idx) { if ((idx >= 0) && (idx < XMH_LAST)) return xmh_item_name[idx]; return NULL; } void *first_host(void) { return (hivalhost ? &hival_hostinfo : namehead); } void *next_host(void *currenthost, int wantclones) { namelist_t *walk; if (!currenthost || (currenthost == &hival_hostinfo)) return NULL; if (wantclones) return ((namelist_t *)currenthost)->next; /* Find the next non-clone record */ walk = (namelist_t *)currenthost; do { walk = walk->next; } while (walk && (strcmp(((namelist_t *)currenthost)->hostname, walk->hostname) == 0)); return walk; } void xmh_set_item(void *hostin, enum xmh_item_t item, void *value) { namelist_t *host = (namelist_t *)hostin; if (host == &hival_hostinfo) { switch (item) { case XMH_CLASS: case XMH_OS: case XMH_CLIENTALIAS: hivals[item] = strdup((char *)value); break; case XMH_DATA: hivals[item] = (char *)value; break; default: break; } return; } switch (item) { case XMH_CLASS: if (host->classname) xfree(host->classname); host->classname = strdup((char *)value); break; case XMH_OS: if (host->osname) xfree(host->osname); host->osname = strdup((char *)value); break; case XMH_DATA: host->data = value; break; case XMH_CLIENTALIAS: /* * FIXME: Small mem. leak here - we should run "rebuildhosttree", but that is heavy. * Doing this "free" kills the tree structure, since we free one of the keys. * * if (host->clientname && (host->hostname != host->clientname) && (host->clientname != xmh_find_item(host, XMH_CLIENTALIAS)) xfree(host->clientname); */ host->clientname = strdup((char *)value); xtreeAdd(rbclients, host->clientname, host); break; default: break; } } char *xmh_item_multi(void *hostin, enum xmh_item_t item) { namelist_t *host = (namelist_t *)hostin; static namelist_t *keyhost = NULL, *curhost = NULL; if (item == XMH_LAST) return NULL; if ((host == NULL) && (keyhost == NULL)) return NULL; /* Programmer failure */ if (host != NULL) curhost = keyhost = host; else { curhost = curhost->next; if (!curhost || (strcmp(curhost->hostname, keyhost->hostname) != 0)) curhost = keyhost = NULL; /* End of hostlist */ } return xmh_item(curhost, item); } #ifdef STANDALONE int main(int argc, char *argv[]) { int argi; namelist_t *h; char *val; if (strcmp(argv[1], "@") == 0) { load_hostinfo(argv[2]); } else { load_hostnames(argv[1], NULL, get_fqdn()); } for (argi = 2; (argi < argc); argi++) { char s[1024]; char *p; char *hname; char hostip[IP_ADDR_STRLEN]; handlehost: hname = knownhost(argv[argi], hostip, GH_IGNORE); if (hname == NULL) { printf("Unknown host '%s'\n", argv[argi]); continue; } if (strcmp(hname, argv[argi])) { printf("Using canonical name '%s'\n", hname); } h = hostinfo(hname); if (h == NULL) { printf("Host %s not found\n", argv[argi]); continue; } val = xmh_item_walk(h); printf("Entry for host %s\n", h->hostname); while (val) { printf("\t%s\n", val); val = xmh_item_walk(NULL); } do { *s = '\0'; printf("Pick item:"); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return 0; p = strchr(s, '\n'); if (p) *p = '\0'; if (*s == '!') { load_hostnames(argv[1], NULL, get_fqdn()); /* Must restart! The "h" handle is no longer valid. */ goto handlehost; } else if (*s == '>') { val = xmh_item_multi(h, XMH_PAGEPATH); while (val) { printf("\t%s value is: '%s'\n", s, val); val = xmh_item_multi(NULL, XMH_PAGEPATH); } } else if (strncmp(s, "set ", 4) == 0) { xmh_set_item(h, XMH_DATA, strdup(s+4)); } else if (*s) { val = xmh_item_byname(h, s); if (val) printf("\t%s value is: '%s'\n", s, val); else printf("\t%s not found\n", s); } } while (*s); } return 0; } #endif xymon-4.3.30/lib/tree.h0000664000076400007640000000347412275523176015103 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for tree-based record storage. */ /* */ /* Copyright (C) 2011-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __TREE_H__ #define __TREE_H__ typedef enum { XTREE_STATUS_OK, XTREE_STATUS_MEM_EXHAUSTED, XTREE_STATUS_DUPLICATE_KEY, XTREE_STATUS_KEY_NOT_FOUND, XTREE_STATUS_NOTREE } xtreeStatus_t; #ifdef HAVE_BINARY_TREE #define xtreeEnd(X) (NULL) typedef void *xtreePos_t; #else #define xtreeEnd(X) (-1) typedef int xtreePos_t; #endif extern void *xtreeNew(int(*xtreeCompare)(const char *a, const char *b)); extern void xtreeDestroy(void *treehandle); extern xtreeStatus_t xtreeAdd(void *treehandle, char *key, void *userdata); extern void *xtreeDelete(void *treehandle, char *key); extern xtreePos_t xtreeFind(void *treehandle, char *key); extern xtreePos_t xtreeFirst(void *treehandle); extern xtreePos_t xtreeNext(void *treehandle, xtreePos_t pos); extern char *xtreeKey(void *treehandle, xtreePos_t pos); extern void *xtreeData(void *treehandle, xtreePos_t pos); #endif xymon-4.3.30/lib/clientlocal.h0000664000076400007640000000167412275104151016421 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CLIENTLOCAL_H__ #define __CLIENTLOCAL_H__ extern void load_clientconfig(void); extern char *get_clientconfig(char *hostname, char *hostclass, char *hostos); extern void set_clientlocal_mergemode(int onoff); #endif xymon-4.3.30/lib/eventlog.c0000664000076400007640000006637413532325276015770 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This displays the "eventlog" found on the "All non-green status" page. */ /* It also implements a CGI tool to show an eventlog for a given period of */ /* time, as a reporting function. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* Host/test/color/start/end filtering code by Eric Schwimmer 2005 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: eventlog.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" char *eventignorecolumns = NULL; int havedoneeventlog = 0; static int wanted_eventcolumn(char *service) { char svc[100]; int result; if (!eventignorecolumns || (strlen(service) > (sizeof(svc)-3))) return 1; #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ snprintf(svc, sizeof(svc), ",%s,", service); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ result = (strstr(eventignorecolumns, svc) == NULL); return result; } int record_compare(void **a, void **b) { countlist_t **reca = (countlist_t **)a, **recb = (countlist_t **)b; /* Sort the countlist_t records in reverse */ if ( (*reca)->total > (*recb)->total ) return -1; else if ( (*reca)->total < (*recb)->total ) return 1; else return 0; } void * record_getnext(void *a) { return ((countlist_t *)a)->next; } void record_setnext(void *a, void *newval) { ((countlist_t *)a)->next = (countlist_t *)newval; } static htnames_t *namehead = NULL; static htnames_t *getname(char *name, int createit) { htnames_t *walk; for (walk = namehead; (walk && strcmp(walk->name, name)); walk = walk->next) ; if (walk || (!createit)) return walk; walk = (htnames_t *)malloc(sizeof(htnames_t)); walk->name = strdup(name); walk->next = namehead; namehead = walk; return walk; } static void count_events(countlist_t **hostcounthead, countlist_t **svccounthead) { void *hostwalk; for (hostwalk = first_host(); (hostwalk); hostwalk = next_host(hostwalk, 0)) { eventcount_t *swalk; countlist_t *hrec, *srec; swalk = (eventcount_t *)xmh_item(hostwalk, XMH_DATA); if (!swalk) continue; hrec = (countlist_t *)malloc(sizeof(countlist_t)); hrec->src = hostwalk; hrec->total = 0; hrec->next = *hostcounthead; *hostcounthead = hrec; for (swalk = (eventcount_t *)xmh_item(hostwalk, XMH_DATA); (swalk); swalk = swalk->next) { hrec->total += swalk->count; for (srec = *svccounthead; (srec && (srec->src != (void *)swalk->service)); srec = srec->next) ; if (!srec) { srec = (countlist_t *)malloc(sizeof(countlist_t)); srec->src = (void *)swalk->service; srec->total = 0; srec->next = *svccounthead; *svccounthead = srec; } srec->total += swalk->count; } } } typedef struct ed_t { event_t *event; struct ed_t *next; } ed_t; typedef struct elist_t { htnames_t *svc; ed_t *head, *tail; struct elist_t *next; } elist_t; static void dump_eventtree(void) { void *hwalk; elist_t *lwalk; ed_t *ewalk; for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { printf("%s\n", xmh_item(hwalk, XMH_HOSTNAME)); lwalk = (elist_t *)xmh_item(hwalk, XMH_DATA); while (lwalk) { printf("\t%s\n", lwalk->svc->name); ewalk = lwalk->head; while (ewalk) { printf("\t\t%ld->%ld = %6ld %s\n", (long) ewalk->event->changetime, (long) ewalk->event->eventtime, (long) ewalk->event->duration, colorname(ewalk->event->oldcolor)); ewalk = ewalk->next; } lwalk = lwalk->next; } } } void dump_countlists(countlist_t *hosthead, countlist_t *svchead) { countlist_t *cwalk; printf("Hosts\n"); for (cwalk = hosthead; (cwalk); cwalk = cwalk->next) { printf("\t%20s : %lu\n", xmh_item(cwalk->src, XMH_HOSTNAME), cwalk->total); } printf("\n"); printf("Services\n"); for (cwalk = svchead; (cwalk); cwalk = cwalk->next) { printf("\t%20s : %lu\n", ((htnames_t *)cwalk->src)->name, cwalk->total); } printf("\n"); } static int eventfilter(void *hinfo, char *testname, pcre *pageregexp, pcre *expageregexp, pcre *hostregexp, pcre *exhostregexp, pcre *testregexp, pcre *extestregexp, int ignoredialups, f_hostcheck hostcheck) { int pagematch, hostmatch, testmatch; char *hostname = xmh_item(hinfo, XMH_HOSTNAME); int ovector[30]; if (ignoredialups && xmh_item(hinfo, XMH_FLAG_DIALUP)) return 0; if (hostcheck && (hostcheck(hostname) == 0)) return 0; if (pageregexp) { char *pagename; pagename = xmh_item_multi(hinfo, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 1; if (!pagematch) return 0; if (expageregexp) { char *pagename; pagename = xmh_item_multi(hinfo, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 0; if (pagematch) return 0; if (hostregexp) hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 1; if (!hostmatch) return 0; if (exhostregexp) hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 0; if (hostmatch) return 0; if (testregexp) testmatch = (pcre_exec(testregexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 1; if (!testmatch) return 0; if (extestregexp) testmatch = (pcre_exec(extestregexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 0; if (testmatch) return 0; return 1; } static void count_duration(time_t fromtime, time_t totime, pcre *pageregexp, pcre *expageregexp, pcre *hostregexp, pcre *exhostregexp, pcre *testregexp, pcre *extestregexp, int ignoredialups, f_hostcheck hostcheck, event_t *eventhead, countlist_t **hostcounthead, countlist_t **svccounthead) { void *hwalk; elist_t *lwalk; event_t *ewalk; ed_t *ed; sendreturn_t *bdata; /* * Restructure the event-list so we have a tree instead: * * HostRecord * | *Data ----> EventList * | | *Service * | | *EventHead --> Event --> Event --> Event * | | *EventTail --------------------------^ * | | * | v * | * v * */ for (ewalk = eventhead; (ewalk); ewalk = ewalk->next) { lwalk = (elist_t *)xmh_item(ewalk->host, XMH_DATA); while (lwalk && (lwalk->svc != ewalk->service)) lwalk = lwalk->next; if (lwalk == NULL) { lwalk = (elist_t *)calloc(1, sizeof(elist_t)); lwalk->svc = ewalk->service; lwalk->next = (elist_t *)xmh_item(ewalk->host, XMH_DATA); xmh_set_item(ewalk->host, XMH_DATA, (void *)lwalk); } ed = (ed_t *)calloc(1, sizeof(ed_t)); ed->event = ewalk; ed->next = lwalk->head; if (lwalk->head == NULL) lwalk->tail = ed; lwalk->head = ed; } if (debug) { printf("\n\nEventtree before fixups\n\n"); dump_eventtree(); } /* * Next, we must add a pseudo record for the current state. * This is for those statuses that haven't changed since the * start of our data-collection period - they won't have any events * so we cannot tell what color they are. By grabbing the current * color we can add a pseudo-event that lets us determine what the * color has been since the start of the event-period. */ bdata = newsendreturnbuf(1, NULL); if (sendmessage("xymondboard fields=hostname,testname,color,lastchange", NULL, XYMON_TIMEOUT, bdata) == XYMONSEND_OK) { char *bol, *eol; char *hname, *tname; int color; time_t lastchange; void *hrec; htnames_t *srec; char *icname = xgetenv("INFOCOLUMN"); char *tcname = xgetenv("TRENDSCOLUMN"); bol = getsendreturnstr(bdata, 0); while (bol) { eol = strchr(bol, '\n'); if (eol) *eol = '\0'; hname = strtok(bol, "|"); tname = (hname ? strtok(NULL, "|") : NULL); color = (tname ? parse_color(strtok(NULL, "|")) : -1); lastchange = ((color != -1) ? atol(strtok(NULL, "\n")) : totime+1); if (hname && tname && (color != -1) && (strcmp(tname, icname) != 0) && (strcmp(tname, tcname) != 0)) { hrec = hostinfo(hname); srec = getname(tname, 1); if (eventfilter(hrec, tname, pageregexp, expageregexp, hostregexp, exhostregexp, testregexp, extestregexp, ignoredialups, hostcheck) == 0) goto nextrecord; lwalk = (elist_t *)xmh_item(hrec, XMH_DATA); while (lwalk && (lwalk->svc != srec)) lwalk = lwalk->next; if (lwalk == NULL) { lwalk = (elist_t *)calloc(1, sizeof(elist_t)); lwalk->svc = srec; lwalk->next = (elist_t *)xmh_item(hrec, XMH_DATA); xmh_set_item(hrec, XMH_DATA, (void *)lwalk); } /* See if we already have an event past the "totime" value */ if (lwalk->head) { ed = lwalk->head; while (ed && (ed->event->eventtime < totime)) ed = ed->next; if (ed) { ed->next = NULL; lwalk->tail = ed; } else { ed = (ed_t *)calloc(1, sizeof(ed_t)); ed->event = (event_t *)calloc(1, sizeof(event_t)); lwalk->tail->next = ed; ed->event->host = hrec; ed->event->service = srec; ed->event->eventtime = totime; ed->event->changetime = lwalk->tail->event->eventtime; ed->event->duration = (totime - lwalk->tail->event->eventtime); ed->event->newcolor = -1; ed->event->oldcolor = lwalk->tail->event->newcolor; ed->event->next = NULL; ed->next = NULL; lwalk->tail = ed; } } else if (lastchange < totime) { ed = (ed_t *)calloc(1, sizeof(ed_t)); ed->event = (event_t *)calloc(1, sizeof(event_t)); ed->event->host = hrec; ed->event->service = srec; ed->event->eventtime = totime; ed->event->changetime = (lwalk->tail ? lwalk->tail->event->eventtime : fromtime); ed->event->duration = (totime - ed->event->changetime); ed->event->newcolor = color; ed->event->oldcolor = (lwalk->tail ? lwalk->tail->event->newcolor : color); ed->event->next = NULL; ed->next = NULL; lwalk->head = lwalk->tail = ed; } } nextrecord: bol = (eol ? eol+1 : NULL); } freesendreturnbuf(bdata); } else { errprintf("Cannot get the current state\n"); freesendreturnbuf(bdata); return; } if (debug) { printf("\n\nEventtree after pseudo-events\n\n"); dump_eventtree(); } /* * Fixup the beginning-time (and duration) of the first events recorded. * This is to handle events that begin BEFORE our event-logging period. * Fixup the end-time (and duration) of the last events recorded. * This is to handle events that end AFTER our event-logging period. */ for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { elist_t *lwalk; event_t *erec; ed_t *ewalk; lwalk = (elist_t *)xmh_item(hwalk, XMH_DATA); while (lwalk) { if (lwalk->head) { erec = lwalk->head->event; if (erec->changetime > totime) { /* First event is after our start-time. Drop the events */ lwalk->head = lwalk->tail = NULL; } else if (erec->changetime < fromtime) { /* First event is before our start-time. Adjust to starttime. */ erec->changetime = fromtime; erec->duration = (erec->eventtime - fromtime); } ewalk = lwalk->head; while (ewalk && (ewalk->event->eventtime < totime)) ewalk = ewalk->next; if (ewalk) { lwalk->tail = ewalk; lwalk->tail->next = 0; } if (lwalk->tail) { erec = lwalk->tail->event; if (erec->eventtime > totime) { /* Last event is after our end-time. Adjust to end-time */ erec->eventtime = totime; erec->duration = (totime - erec->changetime); } } } lwalk = lwalk->next; } } if (debug) { printf("\n\nEventtree after fixups\n\n"); dump_eventtree(); } for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { countlist_t *hrec, *srec; hrec = (countlist_t *)malloc(sizeof(countlist_t)); hrec->src = hwalk; hrec->total = 0; hrec->next = *hostcounthead; *hostcounthead = hrec; lwalk = (elist_t *)xmh_item(hwalk, XMH_DATA); while (lwalk) { for (srec = *svccounthead; (srec && (srec->src != (void *)lwalk->svc)); srec = srec->next) ; if (!srec) { srec = (countlist_t *)malloc(sizeof(countlist_t)); srec->src = (void *)lwalk->svc; srec->total = 0; srec->next = *svccounthead; *svccounthead = srec; } if (lwalk->head) { ed_t *ewalk = lwalk->head; while (ewalk) { if (ewalk->event->oldcolor >= COL_YELLOW) { hrec->total += ewalk->event->duration; srec->total += ewalk->event->duration; } ewalk = ewalk->next; } } lwalk = lwalk->next; } } if (debug) dump_countlists(*hostcounthead, *svccounthead); } void do_eventlog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pageregex, char *expageregex, char *hostregex, char *exhostregex, char *testregex, char *extestregex, char *colrregex, int ignoredialups, f_hostcheck hostcheck, event_t **eventlist, countlist_t **hostcounts, countlist_t **servicecounts, countsummary_t counttype, eventsummary_t sumtype, char *periodstring) { FILE *eventlog; char eventlogfilename[PATH_MAX]; time_t firstevent = 0; time_t lastevent = getcurrenttime(NULL); event_t *eventhead = NULL; struct stat st; char l[MAX_LINE_LEN]; char title[200]; /* For the PCRE matching */ const char *errmsg = NULL; int errofs = 0; pcre *pageregexp = NULL; pcre *expageregexp = NULL; pcre *hostregexp = NULL; pcre *exhostregexp = NULL; pcre *testregexp = NULL; pcre *extestregexp = NULL; pcre *colrregexp = NULL; countlist_t *hostcounthead = NULL, *svccounthead = NULL; if (eventlist) *eventlist = NULL; if (hostcounts) *hostcounts = NULL; if (servicecounts) *servicecounts = NULL; havedoneeventlog = 1; if ((maxminutes > 0) && (fromtime || totime)) { fprintf(output, "Only one time interval type is allowed!"); return; } if (fromtime) { firstevent = eventreport_time(fromtime); if(firstevent < 0) { if (output) fprintf(output,"Invalid 'from' time: %s", htmlquoted(fromtime)); return; } } else if (maxminutes == -1) { /* Unlimited number of minutes */ firstevent = 0; } else if (maxminutes > 0) { firstevent = getcurrenttime(NULL) - maxminutes*60; } else { firstevent = getcurrenttime(NULL) - 86400; } if (totime) { lastevent = eventreport_time(totime); if (lastevent < 0) { if (output) fprintf(output,"Invalid 'to' time: %s", htmlquoted(totime)); return; } if (lastevent < firstevent) { if (output) fprintf(output,"'to' time must be after 'from' time."); return; } } if (!maxcount) maxcount = 100; if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colrregex && *colrregex) colrregexp = pcre_compile(colrregex, PCRE_CASELESS, &errmsg, &errofs, NULL); snprintf(eventlogfilename, sizeof(eventlogfilename), "%s/allevents", xgetenv("XYMONHISTDIR")); eventlog = fopen(eventlogfilename, "r"); if (eventlog && (stat(eventlogfilename, &st) == 0)) { time_t curtime; int done = 0; int unlimited = (maxcount == -1); if (unlimited) maxcount = 1000; do { /* Find a spot in the eventlog file close to where the firstevent time is */ fseeko(eventlog, 0, SEEK_END); do { /* Go back maxcount*80 bytes - one entry is ~80 bytes */ if (ftello(eventlog) > maxcount*80) { unsigned int uicurtime; fseeko(eventlog, -maxcount*80, SEEK_CUR); if (fgets(l, sizeof(l), eventlog) && /* Skip to start of line */ fgets(l, sizeof(l), eventlog)) { sscanf(l, "%*s %*s %u %*u %*u %*s %*s %*d", &uicurtime); curtime = uicurtime; done = (curtime < firstevent); if (unlimited && !done) maxcount += 1000; } else { if (output) fprintf(output,"Error reading eventlog file %s: %s\n", eventlogfilename, strerror(errno)); return; } } else { rewind(eventlog); curtime = 0; done = 1; } } while (!done); if (unlimited) unlimited = ((curtime > firstevent) && (ftello(eventlog) > 0)); } while (unlimited); } eventhead = NULL; while (eventlog && (fgets(l, sizeof(l), eventlog))) { time_t eventtime, changetime, duration; unsigned int uievt, uicht, uidur; char hostname[MAX_LINE_LEN], svcname[MAX_LINE_LEN], newcol[MAX_LINE_LEN], oldcol[MAX_LINE_LEN]; char *newcolname, *oldcolname; int state, itemsfound, colrmatch; event_t *newevent; void *eventhost; struct htnames_t *eventcolumn; int ovector[30]; eventcount_t *countrec; itemsfound = sscanf(l, "%s %s %u %u %u %s %s %d", hostname, svcname, &uievt, &uicht, &uidur, newcol, oldcol, &state); eventtime = uievt; changetime = uicht; duration = uidur; oldcolname = colorname(eventcolor(oldcol)); newcolname = colorname(eventcolor(newcol)); /* For DURATION counts, we must parse all events until now */ if ((counttype != XYMON_COUNT_DURATION) && (eventtime > lastevent)) break; eventhost = hostinfo(hostname); eventcolumn = getname(svcname, 1); if ( (itemsfound == 8) && (eventtime >= firstevent) && (eventhost && !xmh_item(eventhost, XMH_FLAG_NONONGREEN)) && (wanted_eventcolumn(svcname)) ) { if (eventfilter(eventhost, svcname, pageregexp, expageregexp, hostregexp, exhostregexp, testregexp, extestregexp, ignoredialups, hostcheck) == 0) continue; /* For duration counts, record all events. We'll filter out the colors later. */ if (colrregexp && (counttype != XYMON_COUNT_DURATION)) { colrmatch = ( (pcre_exec(colrregexp, NULL, newcolname, strlen(newcolname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0) || (pcre_exec(colrregexp, NULL, oldcolname, strlen(oldcolname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0) ); } else colrmatch = 1; if (!colrmatch) continue; newevent = (event_t *) malloc(sizeof(event_t)); newevent->host = eventhost; newevent->service = eventcolumn; newevent->eventtime = eventtime; newevent->changetime = changetime; newevent->duration = duration; newevent->newcolor = eventcolor(newcol); newevent->oldcolor = eventcolor(oldcol); newevent->next = eventhead; eventhead = newevent; if (counttype != XYMON_COUNT_DURATION) { countrec = (eventcount_t *)xmh_item(eventhost, XMH_DATA); while (countrec && (countrec->service != eventcolumn)) countrec = countrec->next; if (countrec == NULL) { countrec = (eventcount_t *)calloc(1, sizeof(eventcount_t)); countrec->service = eventcolumn; countrec->next = (eventcount_t *)xmh_item(eventhost, XMH_DATA); xmh_set_item(eventhost, XMH_DATA, (void *)countrec); } countrec->count++; } } } /* Count the state changes per host */ svccounthead = hostcounthead = NULL; switch (counttype) { case XYMON_COUNT_EVENTS: count_events(&hostcounthead, &svccounthead); break; case XYMON_COUNT_DURATION: count_duration(firstevent, lastevent, pageregexp, expageregexp, hostregexp, exhostregexp, testregexp, extestregexp, ignoredialups, hostcheck, eventhead, &hostcounthead, &svccounthead); break; default: break; } if (hostcounthead) hostcounthead = msort(hostcounthead, record_compare, record_getnext, record_setnext); if (svccounthead) svccounthead = msort(svccounthead, record_compare, record_getnext, record_setnext); if (eventhead && (output != NULL)) { char *bgcolors[2] = { "#000000", "#000033" }; int bgcolor = 0; struct event_t *ewalk, *lasttoshow = eventhead; countlist_t *cwalk; unsigned long totalcount = 0; if (periodstring) fprintf(output, "

%s

\n", htmlquoted(periodstring)); switch (sumtype) { case XYMON_S_HOST_BREAKDOWN: /* Request for a specific service, show breakdown by host */ for (cwalk = hostcounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total; fprintf(output, "\n"); fprintf(output, "\n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); fprintf(output, "\n"); for (cwalk = hostcounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) { fprintf(output, "\n", xmh_item(cwalk->src, XMH_HOSTNAME), cwalk->total, ((100.0 * cwalk->total) / totalcount)); } fprintf(output, "
Host%s

%s%lu(%6.2f %%)
\n"); break; case XYMON_S_SERVICE_BREAKDOWN: /* Request for a specific host, show breakdown by service */ for (cwalk = svccounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total; fprintf(output, "\n"); fprintf(output, "\n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); fprintf(output, "\n"); for (cwalk = svccounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) { fprintf(output, "\n", ((htnames_t *)cwalk->src)->name, cwalk->total, ((100.0 * cwalk->total) / totalcount)); } fprintf(output, "
Service%s

%s%lu(%6.2f %%)
\n"); break; case XYMON_S_NONE: break; } if (sumtype == XYMON_S_NONE) { int count; count=0; ewalk=eventhead; do { count++; lasttoshow = ewalk; ewalk = ewalk->next; } while (ewalk && (countnext = NULL; /* Terminate list if any items left */ if (maxminutes > 0) { snprintf(title, sizeof(title), "%d events received in the past %u minutes", count, (unsigned int)((getcurrenttime(NULL) - lasttoshow->eventtime) / 60)); } else { snprintf(title, sizeof(title), "%d events received.", count); } } else { strncpy(title, "Events in summary", sizeof(title)); } fprintf(output, "

\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); for (ewalk=eventhead; (ewalk); ewalk=ewalk->next) { char *hostname = xmh_item(ewalk->host, XMH_HOSTNAME); if ( (counttype == XYMON_COUNT_DURATION) && (ewalk->oldcolor < COL_YELLOW) && (ewalk->newcolor < COL_YELLOW) ) continue; if ( (counttype == XYMON_COUNT_DURATION) && (ewalk->eventtime >= lastevent) ) continue; fprintf(output, "\n", bgcolors[bgcolor]); bgcolor = ((bgcolor + 1) % 2); fprintf(output, "\n", ctime(&ewalk->eventtime)); if (ewalk->newcolor == COL_CLEAR) { fprintf(output, "\n", hostname); } else { fprintf(output, "\n", colorname(ewalk->newcolor), hostname); } fprintf(output, "\n", ewalk->service->name); fprintf(output, "\n", xgetenv("XYMONSKIN"), dotgiffilename(ewalk->newcolor, 0, 0), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), colorname(ewalk->newcolor), colorname(ewalk->newcolor)); fprintf(output, "\n"); } fprintf(output, "
%s
%s%s%s%s\n", histlogurl(hostname, ewalk->service->name, ewalk->changetime, NULL)); fprintf(output, "\"%s\"\n", xgetenv("XYMONSKIN"), dotgiffilename(ewalk->oldcolor, 0, 0), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), colorname(ewalk->oldcolor), colorname(ewalk->oldcolor)); fprintf(output, "\"From\n", xgetenv("XYMONSKIN"), xgetenv("IMAGEFILETYPE")); fprintf(output, "\n", histlogurl(hostname, ewalk->service->name, ewalk->eventtime, NULL)); fprintf(output, "\"%s\"
\n"); } else if (output != NULL) { /* No events during the past maxminutes */ if (eventlog) snprintf(title, sizeof(title), "No events received in the last %d minutes", maxminutes); else strncpy(title, "No events logged", sizeof(title)); fprintf(output, "

\n"); fprintf(output, "\n", title); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); fprintf(output, "\n"); fprintf(output, "
%s
\n"); fprintf(output, "
\n"); } if (eventlog) fclose(eventlog); if (pageregexp) pcre_free(pageregexp); if (hostregexp) pcre_free(hostregexp); if (testregexp) pcre_free(testregexp); if (colrregexp) pcre_free(colrregexp); /* Return the event- and count-lists, if wanted - or clean them up */ if (eventlist) { *eventlist = eventhead; } else { event_t *zombie, *ewalk = eventhead; while (ewalk) { zombie = ewalk; ewalk = ewalk->next; xfree(zombie); } } if (hostcounts) { *hostcounts = hostcounthead; } else { countlist_t *zombie, *hwalk = hostcounthead; while (hwalk) { zombie = hwalk; hwalk = hwalk->next; xfree(zombie); } } if (servicecounts) { *servicecounts = svccounthead; } else { countlist_t *zombie, *swalk = svccounthead; while (swalk) { zombie = swalk; swalk = swalk->next; xfree(zombie); } } } xymon-4.3.30/lib/misc.c0000664000076400007640000004440613532325276015070 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains miscellaneous routines. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: misc.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif #include #include #include "libxymon.h" #include "version.h" enum ostype_t get_ostype(char *osname) { char *nam; enum ostype_t result = OS_UNKNOWN; int n; if (!osname || (*osname == '\0')) return OS_UNKNOWN; n = strspn(osname, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-/_"); nam = (char *)malloc(n+1); strncpy(nam, osname, n); *(nam+n) = '\0'; if (strcasecmp(nam, "solaris") == 0) result = OS_SOLARIS; else if (strcasecmp(nam, "sunos") == 0) result = OS_SOLARIS; else if (strcasecmp(nam, "hpux") == 0) result = OS_HPUX; else if (strcasecmp(nam, "hp-ux") == 0) result = OS_HPUX; else if (strcasecmp(nam, "aix") == 0) result = OS_AIX; else if (strcasecmp(nam, "osf") == 0) result = OS_OSF; else if (strcasecmp(nam, "osf1") == 0) result = OS_OSF; else if (strcasecmp(nam, "win32") == 0) result = OS_WIN32; else if (strcasecmp(nam, "hmdc") == 0) result = OS_WIN32_HMDC; else if (strcasecmp(nam, "bbwin") == 0) result = OS_WIN32_BBWIN; else if (strcasecmp(nam, "powershell") == 0) result = OS_WIN_POWERSHELL; else if (strcasecmp(nam, "freebsd") == 0) result = OS_FREEBSD; else if (strcasecmp(nam, "netbsd") == 0) result = OS_NETBSD; else if (strcasecmp(nam, "openbsd") == 0) result = OS_OPENBSD; else if (strcasecmp(nam, "debian3") == 0) result = OS_LINUX22; else if (strcasecmp(nam, "linux22") == 0) result = OS_LINUX22; else if (strcasecmp(nam, "linux") == 0) result = OS_LINUX; else if (strcasecmp(nam, "redhat") == 0) result = OS_LINUX; else if (strcasecmp(nam, "debian") == 0) result = OS_LINUX; else if (strcasecmp(nam, "suse") == 0) result = OS_LINUX; else if (strcasecmp(nam, "mandrake") == 0) result = OS_LINUX; else if (strcasecmp(nam, "redhatAS") == 0) result = OS_LINUX; else if (strcasecmp(nam, "redhatES") == 0) result = OS_RHEL3; else if (strcasecmp(nam, "rhel3") == 0) result = OS_RHEL3; else if (strcasecmp(nam, "snmp") == 0) result = OS_SNMP; else if (strcasecmp(nam, "snmpnetstat") == 0) result = OS_SNMP; else if (strncasecmp(nam, "irix", 4) == 0) result = OS_IRIX; else if (strcasecmp(nam, "macosx") == 0) result = OS_DARWIN; else if (strcasecmp(nam, "darwin") == 0) result = OS_DARWIN; else if (strcasecmp(nam, "sco_sv") == 0) result = OS_SCO_SV; else if (strcasecmp(nam, "unixware") == 0) result = OS_SCO_SV; else if (strcasecmp(nam, "netware_snmp") == 0) result = OS_NETWARE_SNMP; else if (strcasecmp(nam, "zvm") == 0) result = OS_ZVM; else if (strcasecmp(nam, "zvse") == 0) result = OS_ZVSE; else if (strcasecmp(nam, "zos") == 0) result = OS_ZOS; else if (strcasecmp(nam, "snmpcollect") == 0) result = OS_SNMPCOLLECT; else if (strcasecmp(nam, "mqcollect") == 0) result = OS_MQCOLLECT; else if (strcasecmp(nam, "gnu/kfreebsd") == 0) result = OS_GNUKFREEBSD; if (result == OS_UNKNOWN) dbgprintf("Unknown OS: '%s'\n", osname); xfree(nam); return result; } char *osname(enum ostype_t os) { switch (os) { case OS_SOLARIS: return "solaris"; case OS_HPUX: return "hpux"; case OS_AIX: return "aix"; case OS_OSF: return "osf"; case OS_WIN32: return "win32"; case OS_WIN32_HMDC: return "hmdc"; case OS_WIN32_BBWIN: return "bbwin"; case OS_WIN_POWERSHELL: return "powershell"; case OS_FREEBSD: return "freebsd"; case OS_NETBSD: return "netbsd"; case OS_OPENBSD: return "openbsd"; case OS_LINUX22: return "linux22"; case OS_LINUX: return "linux"; case OS_RHEL3: return "rhel3"; case OS_SNMP: return "snmp"; case OS_IRIX: return "irix"; case OS_DARWIN: return "darwin"; case OS_SCO_SV: return "sco_sv"; case OS_NETWARE_SNMP: return "netware_snmp"; case OS_ZVM: return "zvm"; case OS_ZVSE: return "zvse"; case OS_ZOS: return "zos"; case OS_SNMPCOLLECT: return "snmpcollect"; case OS_MQCOLLECT: return "mqcollect"; case OS_GNUKFREEBSD: return "gnu/kfreebsd"; case OS_UNKNOWN: return "unknown"; } return "unknown"; } int hexvalue(unsigned char c) { switch (c) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': return 10; case 'A': return 10; case 'b': return 11; case 'B': return 11; case 'c': return 12; case 'C': return 12; case 'd': return 13; case 'D': return 13; case 'e': return 14; case 'E': return 14; case 'f': return 15; case 'F': return 15; } return -1; } char *commafy(char *hostname) { STATIC_SBUF_DEFINE(s); char *p; if (s == NULL) { SBUF_MALLOC(s, strlen(hostname)+1); strncpy(s, hostname, s_buflen); } else if (strlen(hostname) > strlen(s)) { xfree(s); SBUF_MALLOC(s, strlen(hostname)+1); strncpy(s, hostname, s_buflen); } else { strncpy(s, hostname, s_buflen); } for (p = strchr(s, '.'); (p); p = strchr(s, '.')) *p = ','; return s; } void uncommafy(char *hostname) { char *p; p = hostname; while ((p = strchr(p, ',')) != NULL) *p = '.'; } char *skipword(char *l) { return l + strcspn(l, " \t"); } char *skipwhitespace(char *l) { return l + strspn(l, " \t"); } char *stripnonwords(char *l) { /* Attempt to strip non-word data */ static char reduced[255]; char *inp; int outidx; reduced[0] = '\0'; if (!l) return (char *)reduced; /* Must be in the set [a-zA-Z0-9_] ... */ for (inp=l, outidx=0; (*inp && (outidx < 250)); inp++) { if ( ((*inp >= 'A') && (*inp <= 'Z')) || ((*inp >= 'a') && (*inp <= 'z')) || ((*inp >= '0') && (*inp <= '9')) ) { reduced[outidx++] = *inp; } /* Replace anything else with an underscore, */ /* compacting successive invalid chars into 1 */ else if ((outidx == 0) || (reduced[outidx - 1] != '_')) { reduced[outidx++] = '_'; } } /* strip a final invalid char */ if ((outidx > 0) && (reduced[outidx-1] == '_')) { reduced[outidx-1] = '\0'; } else { reduced[outidx] = '\0'; } return (char *)reduced; } int argnmatch(char *arg, char *match) { return (strncmp(arg, match, strlen(match)) == 0); } char *msg_data(char *msg, int stripcr) { /* Find the start position of the data following the "status host.test " message */ char *result; if (!msg || (*msg == '\0')) return msg; result = strchr(msg, '.'); /* Hits the '.' in "host.test" */ if (!result) { dbgprintf("Msg was not what I expected: '%s'\n", msg); return msg; } result += strcspn(result, " \t\n"); /* Skip anything until we see a space, TAB or NL */ result += strspn(result, " \t"); /* Skip all whitespace */ if (stripcr) { /* Replace with blanks */ char *cr = result; do { cr = strchr(cr, '\r'); if (cr) *cr = ' '; } while (cr); } return result; } char *gettok(char *s, char *delims) { /* * This works like strtok(), but can handle empty fields. */ static char *source = NULL; static char *whereat = NULL; int n; char *result; if ((delims == NULL) || (*delims == '\0')) return NULL; /* Sanity check */ if ((source == NULL) && (s == NULL)) return NULL; /* Programmer goofed and called us first time with NULL */ if (s) source = whereat = s; /* First call */ if (*whereat == '\0') { /* End of string ... clear local state and return NULL */ source = whereat = NULL; return NULL; } n = strcspn(whereat, delims); if (n == 0) { /* An empty token */ whereat++; result = ""; } else if (n == strlen(whereat)) { /* Last token */ result = whereat; whereat += n; } else { /* Mid-string token - null-teminate the token */ *(whereat + n) = '\0'; result = whereat; /* Move past this token and the delimiter */ whereat += (n+1); } return result; } char *wstok(char *s) { /* * This works like strtok(s, " \t"), but can handle quoted fields. */ static char *source = NULL; static char *whereat = NULL; int n; char *result; if ((source == NULL) && (s == NULL)) return NULL; if (s) source = whereat = s + strspn(s, " \t"); /* First call */ if (*whereat == '\0') { /* End of string ... clear local state and return NULL */ source = whereat = NULL; return NULL; } n = 0; do { n += strcspn(whereat+n, " \t\""); if (*(whereat+n) == '"') { char *p = strchr(whereat+n+1, '"'); if (!p) n = strlen(whereat); else n = (p - whereat) + 1; } } while (*(whereat+n) && (*(whereat+n) != ' ') && (*(whereat+n) != '\t')); if (n == strlen(whereat)) { /* Last token */ result = whereat; whereat += n; } else { /* Mid-string token - null-teminate the token */ *(whereat + n) = '\0'; result = whereat; /* Move past this token and the delimiter */ whereat += (n+1); whereat += strspn(whereat, " \t"); } /* Strip leading/trailing quote */ { char *p; if (*result == '"') result++; p = result + strlen(result) - 1; if (*p == '"') *p = '\0'; } return result; } void sanitize_input(strbuffer_t *l, int stripcomment, int unescape) { int i; /* * This routine sanitizes an input line, stripping off leading/trailing whitespace. * If requested, it also strips comments. * If requested, it also un-escapes \-escaped charactes. */ /* Kill comments */ if (stripcomment || unescape) { char *p, *commentstart = NULL; char *noquotemarkers = (unescape ? "\"'#\\" : "\"'#"); char *inquotemarkers = (unescape ? "\"'\\" : "\"'"); int inquote = 0; p = STRBUF(l) + strcspn(STRBUF(l), noquotemarkers); while (*p && (commentstart == NULL)) { switch (*p) { case '\\': if (inquote) p += 2+strcspn(p+2, inquotemarkers); else p += 2+strcspn(p+2, noquotemarkers); break; case '"': case '\'': inquote = (1 - inquote); if (inquote) p += 1+strcspn(p+1, inquotemarkers); else p += 1+strcspn(p+1, noquotemarkers); break; case '#': if (!inquote) commentstart = p; break; } } if (commentstart) strbufferchop(l, STRBUFLEN(l) - (commentstart - STRBUF(l))); } /* Kill a trailing CR/NL */ i = strcspn(STRBUF(l), "\r\n"); if (i != STRBUFLEN(l)) strbufferchop(l, STRBUFLEN(l)-i); /* Kill trailing whitespace */ i = STRBUFLEN(l); while ((i > 0) && isspace((int)(*(STRBUF(l)+i-1)))) i--; if (i != STRBUFLEN(l)) strbufferchop(l, STRBUFLEN(l)-i); /* Kill leading whitespace */ i = strspn(STRBUF(l), " \t"); if (i > 0) { memmove(STRBUF(l), STRBUF(l)+i, STRBUFLEN(l)-i); strbufferchop(l, i); } if (unescape) { char *p; p = STRBUF(l) + strcspn(STRBUF(l), "\\"); while (*p) { memmove(p, p+1, STRBUFLEN(l)-(p-STRBUF(l))); strbufferchop(l, 1); p = p + 1 + strcspn(p+1, "\\"); } } } unsigned int IPtou32(int ip1, int ip2, int ip3, int ip4) { return ((ip1 << 24) | (ip2 << 16) | (ip3 << 8) | (ip4)); } char *u32toIP(unsigned int ip32) { int ip1, ip2, ip3, ip4; STATIC_SBUF_DEFINE(result); if (result == NULL) SBUF_MALLOC(result, 16); ip1 = ((ip32 >> 24) & 0xFF); ip2 = ((ip32 >> 16) & 0xFF); ip3 = ((ip32 >> 8) & 0xFF); ip4 = (ip32 & 0xFF); snprintf(result, result_buflen, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); return result; } const char *textornull(const char *text) { return (text ? text : "(NULL)"); } int issimpleword(const char *text) { if (text == NULL) return 0; return (strlen(text) == strspn(text, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ._-")); } int get_fqdn(void) { /* Get FQDN setting */ getenv_default("FQDN", "TRUE", NULL); return (strcmp(xgetenv("FQDN"), "TRUE") == 0); } int generate_static(void) { getenv_default("XYMONLOGSTATUS", "STATIC", NULL); return (strcmp(xgetenv("XYMONLOGSTATUS"), "STATIC") == 0); } void do_extensions(FILE *output, char *extenv, char *family) { /* * Extension scripts. These are ad-hoc, and implemented as a * simple pipe. So we do a fork here ... */ char *exts, *p; FILE *inpipe; char extfn[PATH_MAX]; strbuffer_t *inbuf; p = xgetenv(extenv); if (p == NULL) { /* No extension */ return; } MEMDEFINE(extfn); exts = strdup(p); p = strtok(exts, "\t "); inbuf = newstrbuffer(0); while (p) { /* Don't redo the eventlog or acklog things */ if ((strcmp(p, "eventlog.sh") != 0) && (strcmp(p, "acklog.sh") != 0)) { snprintf(extfn, sizeof(extfn), "%s/ext/%s/%s", xgetenv("XYMONHOME"), family, p); inpipe = popen(extfn, "r"); if (inpipe) { initfgets(inpipe); while (unlimfgets(inbuf, inpipe)) fputs(STRBUF(inbuf), output); pclose(inpipe); freestrbuffer(inbuf); } } p = strtok(NULL, "\t "); } xfree(exts); MEMUNDEFINE(extfn); MEMUNDEFINE(buf); } static void clean_cmdarg(char *l) { /* * This routine sanitizes command-line argument, stripping off whitespace, * removing comments and un-escaping \-escapes and quotes. */ char *p, *outp; int inquote, inhyphen; /* Remove quotes, comments and leading whitespace */ p = l + strspn(l, " \t"); outp = l; inquote = inhyphen = 0; while (*p) { if (*p == '\\') { *outp = *(p+1); outp++; p += 2; } else if (*p == '"') { inquote = (1 - inquote); p++; } else if (*p == '\'') { inhyphen = (1 - inhyphen); p++; } else if ((*p == '#') && !inquote && !inhyphen) { *p = '\0'; } else { if (outp != p) *outp = *p; outp++; p++; } } /* Remove trailing whitespace */ while ((outp > l) && (isspace((int) *(outp-1)))) outp--; *outp = '\0'; } char **setup_commandargs(char *cmdline, char **cmd) { /* * Good grief - argument parsing is complex! * * This routine takes a command-line, picks out any environment settings * that are in the command line, and splits up the remainder into the * actual command to run, and the arguments. * * It handles quotes, hyphens and escapes. */ char **cmdargs; char *cmdcp, *barg, *earg, *eqchar, *envsetting; int argi, argsz; int argdone, inquote, inhyphen; char savech; argsz = 1; cmdargs = (char **) malloc((1+argsz)*sizeof(char *)); argi = 0; cmdcp = strdup(expand_env(cmdline)); /* Kill a trailing CR/NL */ barg = cmdcp + strcspn(cmdcp, "\r\n"); *barg = '\0'; barg = cmdcp; do { earg = barg; argdone = 0; inquote = inhyphen = 0; while (*earg && !argdone) { if (!inquote && !inhyphen) { argdone = isspace((int)*earg); } if ((*earg == '"') && !inhyphen) inquote = (1 - inquote); if ((*earg == '\'') && !inquote) inhyphen = (1 - inhyphen); if (!argdone) earg++; } savech = *earg; *earg = '\0'; clean_cmdarg(barg); eqchar = strchr(barg, '='); if (eqchar && (eqchar == (barg + strspn(barg, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")))) { /* It's an environment definition */ dbgprintf("Setting environment: %s\n", barg); envsetting = strdup(barg); putenv(envsetting); } else { if (argi == argsz) { argsz++; cmdargs = (char **) realloc(cmdargs, (1+argsz)*sizeof(char *)); } cmdargs[argi++] = strdup(barg); } *earg = savech; barg = earg + strspn(earg, " \t\n"); } while (*barg); cmdargs[argi] = NULL; xfree(cmdcp); *cmd = cmdargs[0]; return cmdargs; } long long str2ll(char *s, char **errptr) { #ifdef HAVE_STRTOLL return strtoll(s, errptr, 10); #else long long result = 0; int negative = 0; char *inp; inp = s + strspn(s, " \t"); if (*inp == '-') { negative = 1; inp++; } while (isdigit((int)*inp)) { result = 10*result + (*inp - '0'); inp++; } if (errptr && (*inp != '\0') && (!isspace((int)*inp))) *errptr = inp; if (negative) result = -result; return result; #endif } int checkalert(char *alertlist, char *testname) { SBUF_DEFINE(alist); SBUF_DEFINE(aname); int result; if (!alertlist) return 0; SBUF_MALLOC(alist, strlen(alertlist) + 3); snprintf(alist, alist_buflen, ",%s,", alertlist); SBUF_MALLOC(aname, strlen(testname) + 3); snprintf(aname, aname_buflen, ",%s,", testname); result = (strstr(alist, aname) != NULL); xfree(aname); xfree(alist); return result; } char *nextcolumn(char *s) { static char *ofs = NULL; char *result; if (s) ofs = s + strspn(s, " \t"); if (!s && !ofs) return NULL; result = ofs; ofs += strcspn(ofs, " \t"); if (*ofs) { *ofs = '\0'; ofs += 1 + strspn(ofs+1, " \t"); } else ofs = NULL; return result; } int selectcolumn(char *heading, char *wanted) { char *hdr; int result = 0; hdr = nextcolumn(heading); while (hdr && strcasecmp(hdr, wanted)) { result++; hdr = nextcolumn(NULL); } if (hdr) return result; else return -1; } char *getcolumn(char *s, int wanted) { char *result; int i; for (i=0, result=nextcolumn(s); (i < wanted); i++, result = nextcolumn(NULL)); return result; } int chkfreespace(char *path, int minblks, int mininodes) { /* Check there is least 'minblks' % free space on filesystem 'path' */ struct statvfs fs; int n; int avlblk, avlnod; n = statvfs(path, &fs); if (n == -1) { errprintf("Cannot stat filesystem %s: %s\n", path, strerror(errno)); return 0; } /* Not all filesystems report i-node data, so play it safe */ avlblk = ((fs.f_bavail > 0) && (fs.f_blocks > 0)) ? fs.f_bavail / (fs.f_blocks / 100) : 100; avlnod = ((fs.f_favail > 0) && (fs.f_files > 0)) ? fs.f_favail / (fs.f_files / 100) : 100; if ((avlblk >= minblks) && (avlnod >= mininodes)) return 0; return 1; } xymon-4.3.30/lib/clientlocal.c0000664000076400007640000001662513515623702016424 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the */ /* client-local.cfg file into memory and finding the proper host entry. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: clientlocal.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include "libxymon.h" typedef struct clientconfig_t { pcre *hostptn, *classptn, *osptn; strbuffer_t *config; struct clientconfig_t *next; } clientconfig_t; static clientconfig_t *cchead = NULL; typedef struct cctree_t { char *hostname; char *config; } cctree_t; static void *cctree = NULL; /* Feature flag: Set to 1 to merge all matching clientconfig entries into one */ static int ccmergemode = 0; void load_clientconfig(void) { static char *configfn = NULL; static void *clientconflist = NULL; FILE *fd; strbuffer_t *buf; clientconfig_t *cctail = NULL; if (!configfn) { unsigned int configfn_buflen = strlen(xgetenv("XYMONHOME"))+ strlen("/etc/client-local.cfg") + 1; configfn = (char *)malloc(configfn_buflen); snprintf(configfn, configfn_buflen, "%s/etc/client-local.cfg", xgetenv("XYMONHOME")); } /* First check if there were no modifications at all */ if (clientconflist) { if (!stackfmodified(clientconflist)){ dbgprintf("No files modified, skipping reload of %s\n", configfn); return; } else { stackfclist(&clientconflist); clientconflist = NULL; } } /* Must reload the config, clear out old cache data */ if (cchead) { clientconfig_t *walk, *zombie; walk = cchead; while (walk) { zombie = walk; walk = walk->next; if (zombie->hostptn) freeregex(zombie->hostptn); if (zombie->classptn) freeregex(zombie->classptn); if (zombie->osptn) freeregex(zombie->osptn); if (zombie->config) freestrbuffer(zombie->config); xfree(zombie); } cchead = NULL; } if (cctree) { xtreePos_t handle; cctree_t *rec; handle = xtreeFirst(cctree); while (handle != xtreeEnd(cctree)) { rec = xtreeData(cctree, handle); xfree(rec->hostname); xfree(rec->config); handle = xtreeNext(cctree, handle); } xtreeDestroy(cctree); cctree = NULL; } buf = newstrbuffer(0); fd = stackfopen(configfn, "r", &clientconflist); if (!fd) return; while (stackfgets(buf, NULL)) { static int insection = 0; char *p, *ptn; /* Ignore comments and blank lines */ p = STRBUF(buf); p += strspn(p, " \t\r\n"); if ((*p == '#') || (*p == '\0')) continue; if (insection) { if (*p != '[') { if (cctail) { if (!cctail->config) cctail->config = newstrbuffer(0); addtostrbuffer(cctail->config, buf); } } else { insection = 0; } } if (!insection) { if (*STRBUF(buf) == '[') { pcre *hostptn = NULL, *classptn = NULL, *osptn = NULL; clientconfig_t *newrec; p = STRBUF(buf) + strcspn(STRBUF(buf), "\r\n"); if (p == STRBUF(buf)) errprintf("Garbled block in client-local.cfg\n"); else if (*(p-1) == ']') { *(p-1) = '\0'; strbufferrecalc(buf); ptn = STRBUF(buf) + 1; if (strncasecmp(ptn, "host=", 5) == 0) { ptn += 5; if (*ptn == '%') ptn++; hostptn = compileregex((strcmp(ptn, "*") == 0) ? "." : ptn); if (!hostptn) errprintf("Invalid host pattern in client-local.cfg: %s\n", ptn); } else if (strncasecmp(ptn, "class=", 6) == 0) { ptn += 6; if (*ptn == '%') ptn++; classptn = compileregex((strcmp(ptn, "*") == 0) ? "." : ptn); if (!classptn) errprintf("Invalid class pattern in client-local.cfg: %s\n", ptn); } else if (strncasecmp(ptn, "os=", 3) == 0) { ptn += 3; if (*ptn == '%') ptn++; osptn = compileregex((strcmp(ptn, "*") == 0) ? "." : ptn); if (!osptn) errprintf("Invalid os pattern in client-local.cfg: %s\n", ptn); } else if (*(ptn + strlen(ptn) - 1) == '*') { /* It's a "blabla*" */ *(ptn-1) = '^'; /* Ok, we know there is a '[' first */ strbufferchop(buf, 1); hostptn = compileregex(ptn-1); } else { /* Old-style matching, must anchor it and match on all possible patterns */ *(ptn-1) = '^'; /* Ok, we know there is a '[' first */ addtobuffer(buf, "$"); /* Compile it three times, because we free each expression when reloading the config */ hostptn = compileregex(ptn-1); classptn = compileregex(ptn-1); osptn = compileregex(ptn-1); } if (hostptn || classptn || osptn) { newrec = (clientconfig_t *)calloc(1, sizeof(clientconfig_t)); newrec->hostptn = hostptn; newrec->classptn = classptn; newrec->osptn = osptn; newrec->next = NULL; if (!cchead) { cchead = cctail = newrec; } else { cctail->next = newrec; cctail = newrec; } insection = 1; } } } } } stackfclose(fd); freestrbuffer(buf); } char *get_clientconfig(char *hostname, char *hostclass, char *hostos) { xtreePos_t handle; cctree_t *rec = NULL; if (!cchead) return NULL; if (!cctree) cctree = xtreeNew(strcasecmp); handle = xtreeFind(cctree, hostname); if (handle == xtreeEnd(cctree)) { strbuffer_t *config = newstrbuffer(0); clientconfig_t *walk = cchead; if (!ccmergemode) { /* Old-style: Find the first match of hostname, classname or osname - in that priority */ clientconfig_t *hostmatch = NULL, *classmatch = NULL, *osmatch = NULL; while (walk && !hostmatch) { /* Can stop if we find a hostmatch, since those are priority 1 */ if (walk->hostptn && !hostmatch && matchregex(hostname, walk->hostptn)) hostmatch = walk; else if (walk->classptn && !classmatch && matchregex(hostclass, walk->classptn)) classmatch = walk; else if (walk->osptn && !osmatch && matchregex(hostos, walk->osptn)) osmatch = walk; walk = walk->next; } if (hostmatch && hostmatch->config) addtostrbuffer(config, hostmatch->config); else if (classmatch && classmatch->config) addtostrbuffer(config, classmatch->config); else if (osmatch && osmatch->config) addtostrbuffer(config, osmatch->config); } else { /* Merge mode: Merge all matching entries into one */ while (walk) { if ( (walk->hostptn && matchregex(hostname, walk->hostptn)) || (walk->classptn && matchregex(hostclass, walk->classptn)) || (walk->osptn && matchregex(hostos, walk->osptn)) ) { if (walk->config) addtostrbuffer(config, walk->config); } walk = walk->next; } } rec = (cctree_t *)calloc(1, sizeof(cctree_t)); rec->hostname = strdup(hostname); rec->config = grabstrbuffer(config); xtreeAdd(cctree, rec->hostname, rec); } else { rec = (cctree_t *)xtreeData(cctree, handle); } return (rec ? rec->config : NULL); } void set_clientlocal_mergemode(int onoff) { ccmergemode = (onoff != 0); } xymon-4.3.30/lib/tree.c0000664000076400007640000003244613532325276015075 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for tree-based record storage. */ /* */ /* Copyright (C) 2011-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: files.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include "config.h" #include "tree.h" #ifdef HAVE_BINARY_TREE #include typedef struct treerec_t { char *key; void *userdata; int (*compare)(const char *a, const char *b); struct treerec_t *link; } treerec_t; typedef struct xtree_t { void *root; int (*compare)(const char *a, const char *b); } xtree_t; static treerec_t *i_curr = NULL; static int xtree_i_compare(const void *pa, const void *pb) { const treerec_t *reca = pa, *recb = pb; return (reca->compare)(reca->key, recb->key); } void *xtreeNew(int(*xtreeCompare)(const char *a, const char *b)) { xtree_t *newtree; newtree = (xtree_t *)calloc(1, sizeof(xtree_t)); newtree->compare = xtreeCompare; newtree->root = NULL; return newtree; } void xtreeDestroy(void *treehandle) { free(treehandle); } xtreeStatus_t xtreeAdd(void *treehandle, char *key, void *userdata) { xtree_t *tree = treehandle; treerec_t *rec, **erec; if (!tree) return XTREE_STATUS_NOTREE; rec = (treerec_t *)calloc(1, sizeof(treerec_t)); rec->key = key; rec->userdata = userdata; rec->compare = tree->compare; erec = tsearch(rec, &tree->root, xtree_i_compare); if (erec == NULL) { free(rec); return XTREE_STATUS_MEM_EXHAUSTED; } if (*erec != rec) { /* Was already there */ free(rec); return XTREE_STATUS_DUPLICATE_KEY; } return XTREE_STATUS_OK; } void *xtreeDelete(void *treehandle, char *key) { xtree_t *tree = treehandle; treerec_t **result, *zombie, rec; void *userdata; if (!tree) return NULL; rec.key = key; rec.userdata = NULL; rec.compare = tree->compare; result = tfind(&rec, &tree->root, xtree_i_compare); if (result == NULL) { /* Not found */ return NULL; } userdata = (*result)->userdata; zombie = (*result); tdelete(&rec, &tree->root, xtree_i_compare); free(zombie); return userdata; } xtreePos_t xtreeFind(void *treehandle, char *key) { xtree_t *tree = treehandle; treerec_t **result, rec; if (!tree) return NULL; rec.key = key; rec.userdata = NULL; rec.compare = tree->compare; result = tfind(&rec, &tree->root, xtree_i_compare); return (result ? *result : NULL); } static void xtree_i_action(const void *nodep, const VISIT which, const int depth) { treerec_t *rec = NULL; switch (which) { case preorder: break; case postorder: rec = *(treerec_t **) nodep; break; case endorder: break; case leaf: rec = *(treerec_t **) nodep; break; } if (rec) { /* * Each time here, we have rec pointing to the next record in the tree, and i_curr is then * pointing to the previous record. So build a linked list of the records going backwards * as we move through the tree. * * R0 <- R1:link <- R2:link <- R3:link * ^ * i_curr * * becomes * * R0 <- R1:link <- R2:link <- R3:link <- rec:link * ^ * i_curr */ rec->link = i_curr; i_curr = rec; } } xtreePos_t xtreeFirst(void *treehandle) { xtree_t *tree = treehandle; treerec_t *walk, *right, *left; if (!tree) return NULL; i_curr = NULL; twalk(tree->root, xtree_i_action); if (!i_curr) return NULL; /* * We have walked the tree and created a reverse-linked list of the records. * Now reverse the list so we get the records in the right sequence. * i_curr points to the last entry. * * R1 <- R2 <- R3 <- R4 * ^ * i_curr * * must be reversed to * * R1 -> R2 -> R3 -> R4 */ walk = i_curr; right = NULL; while (walk->link) { left = walk->link; walk->link = right; right = walk; walk = left; } walk->link = right; i_curr = NULL; return walk; } xtreePos_t xtreeNext(void *treehandle, xtreePos_t pos) { return pos ? ((treerec_t *)pos)->link : NULL; } char *xtreeKey(void *treehandle, xtreePos_t pos) { return pos ? ((treerec_t *)pos)->key : NULL; } void *xtreeData(void *treehandle, xtreePos_t pos) { return pos ? ((treerec_t *)pos)->userdata : NULL; } #else typedef struct treerec_t { char *key; void *userdata; int deleted; } treerec_t; typedef struct xtree_t { treerec_t *entries; xtreePos_t treesz; int (*compare)(const char *a, const char *b); } xtree_t; static xtreePos_t binsearch(xtree_t *mytree, char *key) { xtreePos_t uplim, lowlim, n; if (!key) return -1; /* Do a binary search */ lowlim = 0; uplim = mytree->treesz-1; do { xtreePos_t res; n = (uplim + lowlim) / 2; res = mytree->compare(key, mytree->entries[n].key); if (res == 0) { /* Found it! */ uplim = -1; /* To exit loop */ } else if (res > 0) { /* Higher up */ lowlim = n+1; } else { /* Further down */ uplim = n-1; } } while ((uplim >= 0) && (lowlim <= uplim)); return n; } void *xtreeNew(int(*xtreeCompare)(const char *a, const char *b)) { xtree_t *newtree = (xtree_t *)calloc(1, sizeof(xtree_t)); newtree->compare = xtreeCompare; return newtree; } void xtreeDestroy(void *treehandle) { xtree_t *mytree = (xtree_t *)treehandle; xtreePos_t i; if (treehandle == NULL) return; /* Must delete our privately held keys in the deleted records */ for (i = 0; (i < mytree->treesz); i++) { if (mytree->entries[i].deleted) free(mytree->entries[i].key); } free(mytree->entries); free(mytree); } xtreePos_t xtreeFind(void *treehandle, char *key) { xtree_t *mytree = (xtree_t *)treehandle; xtreePos_t n; /* Does tree exist ? Is it empty? */ if ((treehandle == NULL) || (mytree->treesz == 0)) return -1; n = binsearch(mytree, key); if ((n >= 0) && (n < mytree->treesz) && (mytree->entries[n].deleted == 0) && (mytree->compare(key, mytree->entries[n].key) == 0)) return n; return -1; } xtreePos_t xtreeFirst(void *treehandle) { xtree_t *mytree = (xtree_t *)treehandle; /* Does tree exist ? Is it empty? */ if ((treehandle == NULL) || (mytree->treesz == 0)) return -1; return 0; } xtreePos_t xtreeNext(void *treehandle, xtreePos_t pos) { xtree_t *mytree = (xtree_t *)treehandle; /* Does tree exist ? Is it empty? */ if ((treehandle == NULL) || (mytree->treesz == 0) || (pos >= (mytree->treesz - 1)) || (pos < 0)) return -1; do { pos++; } while (mytree->entries[pos].deleted && (pos < mytree->treesz)); return (pos < mytree->treesz) ? pos : -1; } char *xtreeKey(void *treehandle, xtreePos_t pos) { xtree_t *mytree = (xtree_t *)treehandle; /* Does tree exist ? Is it empty? */ if ((treehandle == NULL) || (mytree->treesz == 0) || (pos >= mytree->treesz) || (pos < 0)) return NULL; return mytree->entries[pos].key; } void *xtreeData(void *treehandle, xtreePos_t pos) { xtree_t *mytree = (xtree_t *)treehandle; /* Does tree exist ? Is it empty? */ if ((treehandle == NULL) || (mytree->treesz == 0) || (pos >= mytree->treesz) || (pos < 0)) return NULL; return mytree->entries[pos].userdata; } xtreeStatus_t xtreeAdd(void *treehandle, char *key, void *userdata) { xtree_t *mytree = (xtree_t *)treehandle; xtreePos_t n; if (treehandle == NULL) return XTREE_STATUS_NOTREE; if (mytree->treesz == 0) { /* Empty tree, just add record */ mytree->entries = (treerec_t *)calloc(1, sizeof(treerec_t)); mytree->entries[0].key = key; mytree->entries[0].userdata = userdata; mytree->entries[0].deleted = 0; } else { n = binsearch(mytree, key); if ((n >= 0) && (n < mytree->treesz) && (mytree->compare(key, mytree->entries[n].key) == 0)) { /* Record already exists */ if (mytree->entries[n].deleted != 0) { /* Revive the old record. Note that we can now discard our privately held key */ free(mytree->entries[n].key); mytree->entries[n].key = key; mytree->entries[n].deleted = 0; mytree->entries[n].userdata = userdata; return XTREE_STATUS_OK; } else { /* Error */ return XTREE_STATUS_DUPLICATE_KEY; } } /* Must create new record */ if (mytree->compare(key, mytree->entries[mytree->treesz - 1].key) > 0) { /* Add after all the others */ mytree->entries = (treerec_t *)realloc(mytree->entries, (1 + mytree->treesz)*sizeof(treerec_t)); mytree->entries[mytree->treesz].key = key; mytree->entries[mytree->treesz].userdata = userdata; mytree->entries[mytree->treesz].deleted = 0; } else if (mytree->compare(key, mytree->entries[0].key) < 0) { /* Add before all the others */ treerec_t *newents = (treerec_t *)malloc((1 + mytree->treesz)*sizeof(treerec_t)); newents[0].key = key; newents[0].userdata = userdata; newents[0].deleted = 0; memcpy(&(newents[1]), &(mytree->entries[0]), (mytree->treesz * sizeof(treerec_t))); free(mytree->entries); mytree->entries = newents; } else { treerec_t *newents; n = binsearch(mytree, key); if (mytree->compare(mytree->entries[n].key, key) < 0) n++; /* * n now points to the record AFTER where we will insert data in the current list. * So in the new list, the new record will be in position n. * Check if this is a deleted record, if it is then we won't have to move anything. */ if (mytree->entries[n].deleted != 0) { /* Deleted record, let's re-use it. */ free(mytree->entries[n].key); mytree->entries[n].key = key; mytree->entries[n].userdata = userdata; mytree->entries[n].deleted = 0; return XTREE_STATUS_OK; } /* Ok, must create a new list and copy entries there */ newents = (treerec_t *)malloc((1 + mytree->treesz)*sizeof(treerec_t)); /* Copy record 0..(n-1), i.e. n records */ memcpy(&(newents[0]), &(mytree->entries[0]), n*sizeof(treerec_t)); /* New record is the n'th record */ newents[n].key = key; newents[n].userdata = userdata; newents[n].deleted = 0; /* Finally, copy records n..(treesz-1) from the old list to position (n+1) onwards in the new list */ memcpy(&(newents[n+1]), &(mytree->entries[n]), (mytree->treesz - n)*sizeof(treerec_t)); free(mytree->entries); mytree->entries = newents; } } mytree->treesz += 1; return XTREE_STATUS_OK; } void *xtreeDelete(void *treehandle, char *key) { xtree_t *mytree = (xtree_t *)treehandle; xtreePos_t n; if (treehandle == NULL) return NULL; if (mytree->treesz == 0) return NULL; /* Empty tree */ n = binsearch(mytree, key); if ((n >= 0) && (n < mytree->treesz) && (mytree->entries[n].deleted == 0) && (mytree->compare(key, mytree->entries[n].key) == 0)) { mytree->entries[n].key = strdup(mytree->entries[n].key); /* Must dup the key, since user may discard it */ mytree->entries[n].deleted = 1; return mytree->entries[n].userdata; } return NULL; } #endif #ifdef STANDALONE #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" #endif // __GNUC__ int main(int argc, char **argv) { char buf[1024], key[1024], data[1024]; void *th = NULL; xtreePos_t n; xtreeStatus_t stat; char *rec, *p; do { printf("New, Add, Find, Delete, dUmp, deStroy : "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) return 0; switch (*buf) { case 'N': case 'n': th = xtreeNew(strcasecmp); break; case 'A': case 'a': printf("Key:");fflush(stdout); fgets(key, sizeof(key), stdin); p = strchr(key, '\n'); if (p) *p = '\0'; printf("Data:");fflush(stdout); fgets(data, sizeof(data), stdin); p = strchr(data, '\n'); if (p) *p = '\0'; stat = xtreeAdd(th, strdup(key), strdup(data)); printf("Result: %d\n", stat); break; case 'D': case 'd': printf("Key:");fflush(stdout); fgets(key, sizeof(key), stdin); p = strchr(key, '\n'); if (p) *p = '\0'; rec = xtreeDelete(th, key); if (rec) { printf("Existing record deleted: Data was '%s'\n", rec); } else { printf("No record\n"); } break; case 'F': case 'f': printf("Key:");fflush(stdout); fgets(key, sizeof(key), stdin); p = strchr(key, '\n'); if (p) *p = '\0'; n = xtreeFind(th, key); if (n != xtreeEnd(th)) { printf("Found record: Data was '%s'\n", (char *)xtreeData(th, n)); } else { printf("No record\n"); } break; case 'U': case 'u': n = xtreeFirst(th); while (n != xtreeEnd(th)) { printf("Key '%s', data '%s'\n", (char *)xtreeKey(th, n), (char *)xtreeData(th, n)); n = xtreeNext(th, n); } break; case 'S': case 's': xtreeDestroy(th); th = NULL; break; } } while (1); return 0; } #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ #endif xymon-4.3.30/lib/loadalerts.c0000664000076400007640000012320213515623702016253 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the */ /* alerts.cfg file which holds information about the Xymon alert */ /* configuration. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: loadalerts.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" /* token's are the pre-processor macros we expand while parsing the config file */ typedef struct token_t { char *name; char *value; struct token_t *next; } token_t; static token_t *tokhead = NULL; /* This defines a rule. Some general criteria, and a list of recipients. */ typedef struct rule_t { int cfid; criteria_t *criteria; recip_t *recipients; struct rule_t *next; } rule_t; static rule_t *rulehead = NULL; static rule_t *ruletail = NULL; static int cfid = 0; static char cfline[256]; static int printmode = 0; static rule_t *printrule = NULL; static enum { P_NONE, P_RULE, P_RECIP } pstate = P_NONE; static int defaultcolors = 0; static int localalertmode = 0; static criteria_t *setup_criteria(rule_t **currule, recip_t **currcp) { criteria_t *crit = NULL; MEMDEFINE(cfline); switch (pstate) { case P_NONE: *currule = (rule_t *)calloc(1, sizeof(rule_t)); (*currule)->cfid = cfid; pstate = P_RULE; /* Fall through */ case P_RULE: if (!(*currule)->criteria) (*currule)->criteria = (criteria_t *)calloc(1, sizeof(criteria_t)); crit = (*currule)->criteria; crit->cfid = cfid; if (crit->cfline == NULL) crit->cfline = strdup(cfline); *currcp = NULL; break; case P_RECIP: if (!(*currcp)->criteria) { recip_t *rwalk; (*currcp)->criteria = (criteria_t *)calloc(1, sizeof(criteria_t)); /* Make sure other recipients on the same rule also get these criteria */ for (rwalk = (*currule)->recipients; (rwalk); rwalk = rwalk->next) { if (rwalk->cfid == cfid) rwalk->criteria = (*currcp)->criteria; } } crit = (*currcp)->criteria; crit->cfid = cfid; if (crit->cfline == NULL) crit->cfline = strdup(cfline); break; } MEMUNDEFINE(cfline); return crit; } void set_localalertmode(int localmode) { if (localmode) localalertmode = 1; } static char *preprocess(char *buf) { /* Expands config-file macros */ static strbuffer_t *result = NULL; char *inp; if (result == NULL) result = newstrbuffer(8192); clearstrbuffer(result); inp = buf; while (inp) { char *p; p = strchr(inp, '$'); if (p == NULL) { addtobuffer(result, inp); inp = NULL; } else { token_t *twalk; char savech; int n; *p = '\0'; addtobuffer(result, inp); p = (p+1); n = strcspn(p, "\t $.,|%!()[]{}+?/&@:;*"); savech = *(p+n); *(p+n) = '\0'; for (twalk = tokhead; (twalk && strcmp(p, twalk->name)); twalk = twalk->next) ; *(p+n) = savech; if (twalk) addtobuffer(result, twalk->value); inp = p+n; } } return STRBUF(result); } static void flush_rule(rule_t *currule) { if (currule == NULL) return; currule->next = NULL; if (rulehead == NULL) { rulehead = ruletail = currule; } else { ruletail->next = currule; ruletail = currule; } } static void free_criteria(criteria_t *crit) { if (crit->cfline) xfree(crit->cfline); if (crit->pagespec) xfree(crit->pagespec); if (crit->pagespecre) pcre_free(crit->pagespecre); if (crit->expagespec) xfree(crit->expagespec); if (crit->expagespecre) pcre_free(crit->expagespecre); if (crit->dgspec) xfree(crit->dgspec); if (crit->dgspecre) pcre_free(crit->dgspecre); if (crit->exdgspec) xfree(crit->exdgspec); if (crit->exdgspecre) pcre_free(crit->exdgspecre); if (crit->hostspec) xfree(crit->hostspec); if (crit->hostspecre) pcre_free(crit->hostspecre); if (crit->exhostspec) xfree(crit->exhostspec); if (crit->exhostspecre) pcre_free(crit->exhostspecre); if (crit->svcspec) xfree(crit->svcspec); if (crit->svcspecre) pcre_free(crit->svcspecre); if (crit->exsvcspec) xfree(crit->exsvcspec); if (crit->exsvcspecre) pcre_free(crit->exsvcspecre); if (crit->classspec) xfree(crit->classspec); if (crit->classspecre) pcre_free(crit->classspecre); if (crit->exclassspec) xfree(crit->exclassspec); if (crit->exclassspecre) pcre_free(crit->exclassspecre); if (crit->groupspec) xfree(crit->groupspec); if (crit->groupspecre) pcre_free(crit->groupspecre); if (crit->exgroupspec) xfree(crit->exgroupspec); if (crit->exgroupspecre) pcre_free(crit->exgroupspecre); if (crit->timespec) xfree(crit->timespec); if (crit->extimespec) xfree(crit->extimespec); } int load_alertconfig(char *configfn, int defcolors, int defaultinterval) { /* (Re)load the configuration file without leaking memory */ static void *configfiles = NULL; char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf; char *p; rule_t *currule = NULL; recip_t *currcp = NULL, *rcptail = NULL; MEMDEFINE(fn); if (configfn) strncpy(fn, configfn, sizeof(fn)); else snprintf(fn, sizeof(fn), "%s/etc/alerts.cfg", xgetenv("XYMONHOME")); /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", fn); MEMUNDEFINE(fn); return 0; } else { stackfclist(&configfiles); configfiles = NULL; } } fd = stackfopen(fn, "r", &configfiles); if (!fd) { errprintf("Cannot open configuration file %s: %s\n", fn, strerror(errno)); MEMUNDEFINE(fn); return 0; } /* First, clean out the old rule set */ while (rulehead) { rule_t *trule; if (rulehead->criteria) { free_criteria(rulehead->criteria); xfree(rulehead->criteria); } while (rulehead->recipients) { recip_t *trecip = rulehead->recipients; if (trecip->criteria) { recip_t *rwalk; /* Clear out the duplicate criteria that may exist, to avoid double-free'ing them */ for (rwalk = trecip->next; (rwalk); rwalk = rwalk->next) { if (rwalk->criteria == trecip->criteria) rwalk->criteria = NULL; } free_criteria(trecip->criteria); xfree(trecip->criteria); } if (trecip->recipient) xfree(trecip->recipient); if (trecip->scriptname) xfree(trecip->scriptname); rulehead->recipients = rulehead->recipients->next; xfree(trecip); } trule = rulehead; rulehead = rulehead->next; xfree(trule); } while (tokhead) { token_t *ttok; if (tokhead->name) xfree(tokhead->name); if (tokhead->value) xfree(tokhead->value); ttok = tokhead; tokhead = tokhead->next; xfree(ttok); } defaultcolors = defcolors; MEMDEFINE(cfline); cfid = 0; inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { int firsttoken = 1; int mailcmdactive = 0, scriptcmdactive = 0; recip_t *curlinerecips = NULL; cfid++; sanitize_input(inbuf, 1, 0); /* Skip empty lines */ if (STRBUFLEN(inbuf) == 0) continue; if ((*STRBUF(inbuf) == '$') && strchr(STRBUF(inbuf), '=')) { /* Define a macro */ token_t *newtok = (token_t *) malloc(sizeof(token_t)); char *delim; delim = strchr(STRBUF(inbuf), '='); *delim = '\0'; newtok->name = strdup(STRBUF(inbuf)+1); /* Skip the '$' */ newtok->value = strdup(preprocess(delim+1)); newtok->next = tokhead; tokhead = newtok; continue; } strncpy(cfline, STRBUF(inbuf), (sizeof(cfline)-1)); cfline[sizeof(cfline)-1] = '\0'; /* Expand macros inside the line before parsing */ p = strtok(preprocess(STRBUF(inbuf)), " \t"); while (p) { if ((strncasecmp(p, "PAGE=", 5) == 0) || (strncasecmp(p, "PAGES=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->pagespec = strdup(val); if (*(crit->pagespec) == '%') crit->pagespecre = compileregex(crit->pagespec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXPAGE=", 7) == 0) || (strncasecmp(p, "EXPAGES=", 8) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->expagespec = strdup(val); if (*(crit->expagespec) == '%') crit->expagespecre = compileregex(crit->expagespec+1); firsttoken = 0; } else if ((strncasecmp(p, "DISPLAYGROUP=", 13) == 0) || (strncasecmp(p, "DISPLAYGROUPS=", 14) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->dgspec = strdup(val); if (*(crit->dgspec) == '%') crit->dgspecre = compileregex(crit->dgspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXDISPLAYGROUP=", 15) == 0) || (strncasecmp(p, "EXDISPLAYGROUPS=", 16) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exdgspec = strdup(val); if (*(crit->exdgspec) == '%') crit->exdgspecre = compileregex(crit->exdgspec+1); firsttoken = 0; } else if ((strncasecmp(p, "HOST=", 5) == 0) || (strncasecmp(p, "HOSTS=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->hostspec = strdup(val); if (*(crit->hostspec) == '%') crit->hostspecre = compileregex(crit->hostspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXHOST=", 7) == 0) || (strncasecmp(p, "EXHOSTS=", 8) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exhostspec = strdup(val); if (*(crit->exhostspec) == '%') crit->exhostspecre = compileregex(crit->exhostspec+1); firsttoken = 0; } else if ((strncasecmp(p, "SERVICE=", 8) == 0) || (strncasecmp(p, "SERVICES=", 9) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->svcspec = strdup(val); if (*(crit->svcspec) == '%') crit->svcspecre = compileregex(crit->svcspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXSERVICE=", 10) == 0) || (strncasecmp(p, "EXSERVICES=", 11) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exsvcspec = strdup(val); if (*(crit->exsvcspec) == '%') crit->exsvcspecre = compileregex(crit->exsvcspec+1); firsttoken = 0; } else if (strncasecmp(p, "CLASS=", 6) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->classspec = strdup(val); if (*(crit->classspec) == '%') crit->classspecre = compileregex(crit->classspec+1); firsttoken = 0; } else if (strncasecmp(p, "EXCLASS=", 8) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exclassspec = strdup(val); if (*(crit->exclassspec) == '%') crit->exclassspecre = compileregex(crit->exclassspec+1); firsttoken = 0; } else if (strncasecmp(p, "GROUP=", 6) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->groupspec = strdup(val); if (*(crit->groupspec) == '%') crit->groupspecre = compileregex(crit->groupspec+1); firsttoken = 0; } else if (strncasecmp(p, "EXGROUP=", 8) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exgroupspec = strdup(val); if (*(crit->exgroupspec) == '%') crit->exgroupspecre = compileregex(crit->exgroupspec+1); firsttoken = 0; } else if ((strncasecmp(p, "COLOR=", 6) == 0) || (strncasecmp(p, "COLORS=", 7) == 0)) { criteria_t *crit; char *c1, *c2; int cval, reverse = 0; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); /* Put a value in crit->colors so we know there is an explicit color setting */ crit->colors = (1 << 30); c1 = strchr(p, '=')+1; /* * If the first colorspec is "!color", then apply the default colors and * subtract colors from that. */ if (*c1 == '!') crit->colors |= defaultcolors; do { c2 = strchr(c1, ','); if (c2) *c2 = '\0'; if (*c1 == '!') { reverse=1; c1++; } cval = (1 << parse_color(c1)); if (reverse) crit->colors &= (~cval); else crit->colors |= cval; if (c2) c1 = (c2+1); else c1 = NULL; } while (c1); firsttoken = 0; } else if ((strncasecmp(p, "TIME=", 5) == 0) || (strncasecmp(p, "TIMES=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->timespec = strdup(val); firsttoken = 0; } else if ((strncasecmp(p, "EXTIME=", 7) == 0) || (strncasecmp(p, "EXTIMES=", 8) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->extimespec = strdup(val); firsttoken = 0; } else if (strncasecmp(p, "DURATION", 8) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); if (*(p+8) == '>') { if (*(p+9) == '=') crit->minduration = 60*durationvalue(p+10); else crit->minduration = 60*durationvalue(p+9) + 1; } else if (*(p+8) == '<') { if (*(p+9) == '=') crit->maxduration = 60*durationvalue(p+10); else crit->maxduration = 60*durationvalue(p+9) - 1; } else errprintf("Ignoring invalid DURATION at line %d: %s\n",cfid, p); firsttoken = 0; } else if (strncasecmp(p, "RECOVERED", 9) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendrecovered = SR_WANTED; firsttoken = 0; } else if (strncasecmp(p, "NORECOVERED", 11) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendrecovered = SR_NOTWANTED; firsttoken = 0; } else if (strncasecmp(p, "NOTICE", 6) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendnotice = SR_WANTED; firsttoken = 0; } else if (strncasecmp(p, "NONOTICE", 8) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendnotice = SR_NOTWANTED; firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "FORMAT=", 7) == 0)) { if (!currcp) errprintf("FORMAT used without a recipient (line %d), ignored\n", cfid); else if (strcasecmp(p+7, "TEXT") == 0) currcp->format = ALERTFORM_TEXT; else if (strcasecmp(p+7, "PLAIN") == 0) currcp->format = ALERTFORM_PLAIN; else if (strcasecmp(p+7, "SMS") == 0) currcp->format = ALERTFORM_SMS; else if (strcasecmp(p+7, "PAGER") == 0) currcp->format = ALERTFORM_PAGER; else if (strcasecmp(p+7, "SCRIPT") == 0) currcp->format = ALERTFORM_SCRIPT; else errprintf("Unknown FORMAT setting '%s' ignored\n", p); firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "REPEAT=", 7) == 0)) { if (!currcp) errprintf("REPEAT used without a recipient (line %d), ignored\n", cfid); else currcp->interval = 60*durationvalue(p+7); firsttoken = 0; } else if ((pstate == P_RECIP) && (strcasecmp(p, "STOP") == 0)) { if (!currcp) errprintf("STOP used without a recipient (line %d), ignored\n", cfid); else currcp->stoprule = 1; firsttoken = 0; } else if ((pstate == P_RECIP) && (strcasecmp(p, "UNMATCHED") == 0)) { if (!currcp) errprintf("UNMATCHED used without a recipient (line %d), ignored\n", cfid); else currcp->unmatchedonly = 1; firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "NOALERT", 7) == 0)) { if (!currcp) errprintf("NOALERT used without a recipient (line %d), ignored\n", cfid); else currcp->noalerts = 1; firsttoken = 0; } else if (currule && ((strncasecmp(p, "MAIL", 4) == 0) || mailcmdactive) ) { recip_t *newrcp; mailcmdactive = 1; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_MAIL; newrcp->format = ALERTFORM_TEXT; if (strncasecmp(p, "MAIL=", 5) == 0) { p += 5; } else if (strcasecmp(p, "MAIL") == 0) { p = strtok(NULL, " \t"); } else { /* Second recipient on a rule - do nothing */ } if (p) { newrcp->recipient = strdup(p); newrcp->interval = defaultinterval; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } } else { errprintf("Ignoring MAIL with no recipient at line %d\n", cfid); xfree(newrcp); } firsttoken = 0; } else if (currule && ((strncasecmp(p, "SCRIPT", 6) == 0) || scriptcmdactive)) { recip_t *newrcp; scriptcmdactive = 1; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_SCRIPT; newrcp->format = ALERTFORM_SCRIPT; if (strncasecmp(p, "SCRIPT=", 7) == 0) { p += 7; newrcp->scriptname = strdup(p); p = strtok(NULL, " \t"); } else if (strcasecmp(p, "SCRIPT") == 0) { p = strtok(NULL, " \t"); if (p) { newrcp->scriptname = strdup(p); p = strtok(NULL, " \t"); } else { errprintf("Invalid SCRIPT command at line %d\n", cfid); } } else { /* A second recipient for the same script as the previous one */ newrcp->scriptname = strdup(currcp->scriptname); } if (p) { newrcp->recipient = strdup(p); newrcp->interval = defaultinterval; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } } else { errprintf("Ignoring SCRIPT with no recipient at line %d\n", cfid); if (newrcp->scriptname) xfree(newrcp->scriptname); xfree(newrcp); } firsttoken = 0; } else if (currule && (strncasecmp(p, "IGNORE", 6) == 0)) { recip_t *newrcp; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_IGNORE; newrcp->format = ALERTFORM_NONE; newrcp->interval = defaultinterval; newrcp->stoprule = 1; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } firsttoken = 0; } else { errprintf("Ignored unknown/unexpected token '%s' at line %d\n", p, cfid); } if (p) p = strtok(NULL, " \t"); } if (curlinerecips && currcp && (curlinerecips != currcp)) { /* We have multiple recipients on one line. Make sure criteria etc. get copied */ recip_t *rwalk; /* All criteria etc. have been set on the last recipient (currcp) */ for (rwalk = curlinerecips; (rwalk != currcp); rwalk = rwalk->next) { rwalk->format = currcp->format; rwalk->interval = currcp->interval; rwalk->criteria = currcp->criteria; rwalk->noalerts = currcp->noalerts; } } } flush_rule(currule); stackfclose(fd); freestrbuffer(inbuf); MEMUNDEFINE(cfline); MEMUNDEFINE(fn); return 1; } static void dump_criteria(criteria_t *crit, int isrecip) { if (crit->pagespec) printf("PAGE=%s ", crit->pagespec); if (crit->expagespec) printf("EXPAGE=%s ", crit->expagespec); if (crit->dgspec) printf("DISPLAYGROUP=%s ", crit->dgspec); if (crit->exdgspec) printf("EXDISPLAYGROUP=%s ", crit->exdgspec); if (crit->hostspec) printf("HOST=%s ", crit->hostspec); if (crit->exhostspec) printf("EXHOST=%s ", crit->exhostspec); if (crit->svcspec) printf("SERVICE=%s ", crit->svcspec); if (crit->exsvcspec) printf("EXSERVICE=%s ", crit->exsvcspec); if (crit->classspec) printf("CLASS=%s ", crit->classspec); if (crit->exclassspec) printf("EXCLASS=%s ", crit->exclassspec); if (crit->groupspec) printf("GROUP=%s ", crit->groupspec); if (crit->exgroupspec) printf("EXGROUP=%s ", crit->exgroupspec); if (crit->colors) { int i, first = 1; printf("COLOR="); for (i = 0; (i < COL_COUNT); i++) { if ((1 << i) & crit->colors) { dbgprintf("first=%d, i=%d\n", first, i); printf("%s%s", (first ? "" : ","), colorname(i)); first = 0; } } printf(" "); } if (crit->timespec) printf("TIME=%s ", crit->timespec); if (crit->extimespec) printf("EXTIME=%s ", crit->extimespec); if (crit->minduration) printf("DURATION>%d ", (crit->minduration / 60)); if (crit->maxduration) printf("DURATION<%d ", (crit->maxduration / 60)); if (isrecip) { switch (crit->sendrecovered) { case SR_UNKNOWN: break; case SR_WANTED: printf("RECOVERED "); break; case SR_NOTWANTED: printf("NORECOVERED "); break; } switch (crit->sendnotice) { case SR_UNKNOWN: break; case SR_WANTED: printf("NOTICE "); break; case SR_NOTWANTED: printf("NONOTICE "); break; } } } void dump_alertconfig(int showlines) { rule_t *rulewalk; recip_t *recipwalk; for (rulewalk = rulehead; (rulewalk); rulewalk = rulewalk->next) { if (showlines) printf("%5d\t", rulewalk->cfid); dump_criteria(rulewalk->criteria, 0); printf("\n"); for (recipwalk = rulewalk->recipients; (recipwalk); recipwalk = recipwalk->next) { printf("\t"); switch (recipwalk->method) { case M_MAIL : printf("MAIL %s ", recipwalk->recipient); break; case M_SCRIPT : printf("SCRIPT %s %s ", recipwalk->scriptname, recipwalk->recipient); break; case M_IGNORE : printf("IGNORE "); break; } switch (recipwalk->format) { case ALERTFORM_TEXT : printf("FORMAT=TEXT "); break; case ALERTFORM_PLAIN : printf("FORMAT=PLAIN "); break; case ALERTFORM_SMS : printf("FORMAT=SMS "); break; case ALERTFORM_PAGER : printf("FORMAT=PAGER "); break; case ALERTFORM_SCRIPT: printf("FORMAT=SCRIPT "); break; case ALERTFORM_NONE : break; } printf("REPEAT=%d ", (int)(recipwalk->interval / 60)); if (recipwalk->criteria) dump_criteria(recipwalk->criteria, 1); if (recipwalk->unmatchedonly) printf("UNMATCHED "); if (recipwalk->stoprule) printf("STOP "); if (recipwalk->noalerts) printf("NOALERT "); printf("\n"); } printf("\n"); } } int stoprulefound = 0; static int criteriamatch(activealerts_t *alert, criteria_t *crit, criteria_t *rulecrit, int *anymatch, time_t *nexttime) { /* * See if the "crit" matches the "alert". * Match on pagespec, dgspec, hostspec, svcspec, classspec, groupspec, colors, timespec, extimespec, minduration, maxduration, sendrecovered */ static char *pgnames = NULL; const char *dgname = NULL; int pgmatchres, pgexclres; time_t duration = (getcurrenttime(NULL) - alert->eventstart); int result, cfid = 0; char *pgtok, *cfline = NULL; void *hinfo = hostinfo(alert->hostname); if (!hinfo) { logprintf("Checking criteria for host '%s', which is not yet defined; some alerts may not immediately fire\n", alert->hostname); if (localalertmode) hinfo = localhostinfo(alert->hostname); }; /* The top-level page needs a name - cannot match against an empty string */ if (pgnames) xfree(pgnames); pgnames = strdup((*alert->location == '\0') ? "/" : alert->location); dgname = hinfo ? textornull(xmh_item(hinfo, XMH_DGNAME)) : strdup(""); if (crit) { cfid = crit->cfid; cfline = crit->cfline; } if (!cfid && rulecrit) cfid = rulecrit->cfid; if (!cfline && rulecrit) cfline = rulecrit->cfline; if (!cfline) cfline = ""; traceprintf("Matching host:service:dgroup:page '%s:%s:%s:%s' against rule line %d\n", alert->hostname, alert->testname, dgname, alert->location, cfid); if (alert->state == A_PAGING) { /* Check max-duration now - it's fast and easy. */ if (crit && crit->maxduration && (duration > crit->maxduration)) { traceprintf("Failed '%s' (max. duration %d>%d)\n", cfline, duration, crit->maxduration); if (!printmode) return 0; } } if (crit && crit->classspec && !namematch(alert->classname, crit->classspec, crit->classspecre)) { traceprintf("Failed '%s' (class not in include list)\n", cfline); return 0; } if (crit && crit->exclassspec && namematch(alert->classname, crit->exclassspec, crit->exclassspecre)) { traceprintf("Failed '%s' (class excluded)\n", cfline); return 0; } /* alert->groups is a comma-separated list of groups, so it needs some special handling */ /* * NB: Don't check groups when RECOVERED - the group list for recovery messages is always empty. * It doesn't matter if we match a recipient who was not in the group that originally * got the alert - we will later check who has received the alert, and only those that * have will get the recovery message. */ if (crit && (crit->groupspec || crit->exgroupspec) && (alert->state != A_RECOVERED)) { SBUF_DEFINE(grouplist); char *tokptr; if ((alert->groups && (*(alert->groups)))) { SBUF_MALLOC(grouplist, strlen(alert->groups)); strncpy(grouplist, alert->groups, grouplist_buflen); } if (crit->groupspec) { char *onegroup; int iswanted = 0; if (grouplist) { /* There is a group label on the alert, so it must match */ onegroup = strtok_r(grouplist, ",", &tokptr); while (onegroup && !iswanted) { iswanted = (namematch(onegroup, crit->groupspec, crit->groupspecre)); onegroup = strtok_r(NULL, ",", &tokptr); } } if (!iswanted) { /* * Either the alert had a group list that didn't match, or * there was no group list and the rule listed one. * In both cases, it's a failed match. */ traceprintf("Failed '%s' (group not in include list)\n", cfline); if (grouplist) xfree(grouplist); return 0; } } if (crit->exgroupspec && grouplist) { char *onegroup; /* Excluded groups are only handled when the alert does have a group list */ strncpy(grouplist, alert->groups, grouplist_buflen); /* Might have been used in the include list */ onegroup = strtok_r(grouplist, ",", &tokptr); while (onegroup) { if (namematch(onegroup, crit->exgroupspec, crit->exgroupspecre)) { traceprintf("Failed '%s' (group excluded)\n", cfline); xfree(grouplist); return 0; } onegroup = strtok_r(NULL, ",", &tokptr); } } if (grouplist) xfree(grouplist); } pgmatchres = pgexclres = -1; pgtok = strtok(pgnames, ","); while (pgtok) { if (crit && crit->pagespec && (pgmatchres != 1)) pgmatchres = (namematch(pgtok, crit->pagespec, crit->pagespecre) ? 1 : 0); if (crit && crit->expagespec && (pgexclres != 1)) pgexclres = (namematch(pgtok, crit->expagespec, crit->expagespecre) ? 1 : 0); pgtok = strtok(NULL, ","); } if (pgexclres == 1) { traceprintf("Failed '%s' (pagename excluded)\n", cfline); return 0; } if (pgmatchres == 0) { traceprintf("Failed '%s' (pagename not in include list)\n", cfline); return 0; } if (crit && crit->dgspec && !namematch(dgname, crit->dgspec, crit->dgspecre)) { traceprintf("Failed '%s' (displaygroup not in include list)\n", cfline); return 0; } if (crit && crit->exdgspec && namematch(dgname, crit->exdgspec, crit->exdgspecre)) { traceprintf("Failed '%s' (displaygroup excluded)\n", cfline); return 0; } if (crit && crit->hostspec && !namematch(alert->hostname, crit->hostspec, crit->hostspecre)) { traceprintf("Failed '%s' (hostname not in include list)\n", cfline); return 0; } if (crit && crit->exhostspec && namematch(alert->hostname, crit->exhostspec, crit->exhostspecre)) { traceprintf("Failed '%s' (hostname excluded)\n", cfline); return 0; } if (crit && crit->svcspec && !namematch(alert->testname, crit->svcspec, crit->svcspecre)) { traceprintf("Failed '%s' (service not in include list)\n", cfline); return 0; } if (crit && crit->exsvcspec && namematch(alert->testname, crit->exsvcspec, crit->exsvcspecre)) { traceprintf("Failed '%s' (service excluded)\n", cfline); return 0; } if (alert->state == A_NOTIFY) { /* * Don't do the check until we are checking individual recipients (rulecrit is set). * You don't need to have NOTICE on the top-level rule, it's enough if a recipient * has it set. However, we do want to allow there to be a default defined in the * rule; but it doesn't take effect until we start checking the recipients. */ if (rulecrit) { int n = (crit ? crit->sendnotice : -1); traceprintf("Checking NOTICE setting %d (rule:%d)\n", n, rulecrit->sendnotice); if (crit && (crit->sendnotice == SR_NOTWANTED)) result = 0; /* Explicit NONOTICE */ else if (crit && (crit->sendnotice == SR_WANTED)) result = 1; /* Explicit NOTICE */ else result = (rulecrit->sendnotice == SR_WANTED); /* Not set, but rule has NOTICE */ } else { result = 1; } if (!result) traceprintf("Failed '%s' (notice not wanted)\n", cfline); return result; } /* At this point, we know the configuration may result in an alert. */ if (anymatch) (*anymatch)++; /* * Duration checks should be done on real paging messages only. * Not on recovery- or notify-messages. */ if (alert->state == A_PAGING) { if (crit && crit->minduration && (duration < crit->minduration)) { if (nexttime) { time_t mynext = alert->eventstart + crit->minduration; if ((*nexttime == -1) || (*nexttime > mynext)) *nexttime = mynext; } traceprintf("Failed '%s' (min. duration %d<%d)\n", cfline, duration, crit->minduration); if (!printmode) return 0; } } /* * Time restrictions apply to ALL messages. * Before 4.2, these were only applied to ALERT messages, * not RECOVERED and NOTIFY messages. This caused some * unfortunate alerts in the middle of the night because * some random system recovered ... not good. So apply * this check to all messages. */ if (crit && ((!hinfo) || ( (crit->timespec && !timematch(xmh_item(hinfo, XMH_HOLIDAYS), crit->timespec)) || (crit->extimespec && timematch(xmh_item(hinfo, XMH_HOLIDAYS), crit->extimespec)) ) ) ) { /* Try again in a minute */ if (nexttime) *nexttime = getcurrenttime(NULL) + 60; traceprintf("Failed '%s' (time/extime criteria)\n", cfline); if (!printmode) return 0; } /* Check color. For RECOVERED messages, this holds the color of the alert, not the recovery state */ if (crit && crit->colors) { result = (((1 << alert->color) & crit->colors) != 0); if (printmode) return 1; } else { result = (((1 << alert->color) & defaultcolors) != 0); if (printmode) return 1; } if (!result) { traceprintf("Failed '%s' (color)\n", cfline); return result; } if ((alert->state == A_RECOVERED) || (alert->state == A_DISABLED)) { /* * Don't do the check until we are checking individual recipients (rulecrit is set). * You don't need to have RECOVERED on the top-level rule, it's enough if a recipient * has it set. However, we do want to allow there to be a default defined in the * rule; but it doesn't take effect until we start checking the recipients. */ if (rulecrit) { int n = (crit ? crit->sendrecovered : -1); traceprintf("Checking recovered setting %d (rule:%d)\n", n, rulecrit->sendrecovered); if (crit && (crit->sendrecovered == SR_NOTWANTED)) result = 0; /* Explicit NORECOVERED */ else if (crit && (crit->sendrecovered == SR_WANTED)) result = 1; /* Explicit RECOVERED */ else result = (rulecrit->sendrecovered == SR_WANTED); /* Not set, but rule has RECOVERED */ } else { result = 1; } if (printmode) return result; } if (result) { traceprintf("*** Match with '%s' ***\n", cfline); } return result; } recip_t *next_recipient(activealerts_t *alert, int *first, int *anymatch, time_t *nexttime) { static rule_t *rulewalk = NULL; static recip_t *recipwalk = NULL; if (anymatch) *anymatch = 0; do { if (*first) { /* Start at beginning of rules-list and find the first matching rule. */ *first = 0; rulewalk = rulehead; while (rulewalk && !criteriamatch(alert, rulewalk->criteria, NULL, NULL, NULL)) rulewalk = rulewalk->next; if (rulewalk) { /* Point recipwalk at the list of possible candidates */ dbgprintf("Found a first matching rule\n"); recipwalk = rulewalk->recipients; } else { /* No matching rules */ dbgprintf("Found no first matching rule\n"); recipwalk = NULL; } } else { if (!recipwalk) { /* Should not happen! */ } else if (recipwalk->next) { /* Check the next recipient in the current rule */ recipwalk = recipwalk->next; } else { /* End of recipients in current rule. Go to the next matching rule */ do { rulewalk = rulewalk->next; } while (rulewalk && !criteriamatch(alert, rulewalk->criteria, NULL, NULL, NULL)); if (rulewalk) { /* Point recipwalk at the list of possible candidates */ dbgprintf("Found a secondary matching rule\n"); recipwalk = rulewalk->recipients; } else { /* No matching rules */ dbgprintf("No more secondary matching rule\n"); recipwalk = NULL; } } } } while (rulewalk && recipwalk && !criteriamatch(alert, recipwalk->criteria, rulewalk->criteria, anymatch, nexttime)); stoprulefound = (recipwalk && recipwalk->stoprule); printrule = rulewalk; return recipwalk; } int have_recipient(activealerts_t *alert, int *anymatch) { int first = 1; return (next_recipient(alert, &first, anymatch, NULL) != NULL); } void alert_printmode(int on) { printmode = on; } void print_alert_recipients(activealerts_t *alert, strbuffer_t *buf) { char *normalfont = "COLOR=\"#FFFFCC\" FACE=\"Tahoma, Arial, Helvetica\""; char *stopfont = "COLOR=\"#33ebf4\" FACE=\"Tahoma, Arial, Helvetica\""; int first = 1; recip_t *recip; char l[4096]; int count = 0; char *p, *fontspec; char codes[25]; unsigned int codes_bytesleft; MEMDEFINE(l); MEMDEFINE(codes); if (printmode == 2) { /* For print-out usage - e.g. confreport.cgi */ normalfont = "COLOR=\"#000000\" FACE=\"Tahoma, Arial, Helvetica\""; stopfont = "COLOR=\"#FF0000\" FACE=\"Tahoma, Arial, Helvetica\""; } fontspec = normalfont; stoprulefound = 0; while ((recip = next_recipient(alert, &first, NULL, NULL)) != NULL) { int mindur = 0, maxdur = INT_MAX; char *timespec = NULL; char *extimespec = NULL; int colors = defaultcolors; int i, firstcolor = 1; int recovered = 0, notice = 0; count++; addtobuffer(buf, ""); if (count == 1) { snprintf(l, sizeof(l), "%s", alert->testname); addtobuffer(buf, l); } /* * The min/max duration of an alert can be controlled by both the actual rule, * and by the recipient specification. * The rule must be fulfilled before the recipient even gets into play, so * if there is a min/max duration on the rule then this becomes the default * and recipient-specific settings can only increase the minduration/decrease * the maxduration. * On the other hand, if there is no rule-setting then the recipient-specific * settings determine everything. */ if (printrule->criteria && printrule->criteria->minduration) mindur = printrule->criteria->minduration; if (recip->criteria && recip->criteria->minduration && (recip->criteria->minduration > mindur)) mindur = recip->criteria->minduration; if (printrule->criteria && printrule->criteria->maxduration) maxdur = printrule->criteria->maxduration; if (recip->criteria && recip->criteria->maxduration && (recip->criteria->maxduration < maxdur)) maxdur = recip->criteria->maxduration; if (printrule->criteria && printrule->criteria->timespec) timespec = printrule->criteria->timespec; if (printrule->criteria && printrule->criteria->extimespec) extimespec = printrule->criteria->extimespec; if (recip->criteria && recip->criteria->timespec) { if (timespec == NULL) timespec = recip->criteria->timespec; else errprintf("Cannot handle nested timespecs yet\n"); } if (recip->criteria && recip->criteria->extimespec) { if (extimespec == NULL) extimespec = recip->criteria->extimespec; else errprintf("Cannot handle nested extimespecs yet\n"); } if (printrule->criteria && printrule->criteria->colors) colors = (colors & printrule->criteria->colors); if (recip->criteria && recip->criteria->colors) colors = (colors & recip->criteria->colors); /* * Recoveries are sent if * - there are no recipient criteria, and the rule says yes; * - the recipient criteria does not have a RECOVERED setting, and the rule says yes; * - the recipient criteria says yes. */ if ( (!recip->criteria && printrule->criteria && (printrule->criteria->sendrecovered == SR_WANTED)) || (recip->criteria && (printrule->criteria->sendrecovered == SR_WANTED) && (recip->criteria->sendrecovered == SR_UNKNOWN)) || (recip->criteria && (recip->criteria->sendrecovered == SR_WANTED)) ) recovered = 1; if ( (!recip->criteria && printrule->criteria && (printrule->criteria->sendnotice == SR_WANTED)) || (recip->criteria && (printrule->criteria->sendnotice == SR_WANTED) && (recip->criteria->sendnotice == SR_UNKNOWN)) || (recip->criteria && (recip->criteria->sendnotice == SR_WANTED)) ) notice = 1; *codes = '\0'; codes_bytesleft = sizeof(codes); if (recip->method == M_IGNORE) { recip->recipient = "-- ignored --"; } if (recip->noalerts) { if (*codes) strncat(codes, ",A", codes_bytesleft); else strncat(codes, "-A", codes_bytesleft); codes_bytesleft -= 2; } if (recovered && !recip->noalerts) { if (*codes) strncat(codes, ",R", codes_bytesleft); else strncat(codes, "R", codes_bytesleft); codes_bytesleft -= 2; } if (notice) { if (*codes) strncat(codes, ",N", codes_bytesleft); else strncat(codes, "N", codes_bytesleft); codes_bytesleft -= 2; } if (recip->stoprule) { if (*codes) strncat(codes, ",S", codes_bytesleft); else strncat(codes, "S", codes_bytesleft); codes_bytesleft -= 2; } if (recip->unmatchedonly) { if (*codes) strncat(codes, ",U", codes_bytesleft); else strncat(codes, "U", codes_bytesleft); codes_bytesleft -= 2; } if (strlen(codes) == 0) snprintf(l, sizeof(l), "%s", fontspec, recip->recipient); else snprintf(l, sizeof(l), "%s (%s)", fontspec, recip->recipient, codes); addtobuffer(buf, l); snprintf(l, sizeof(l), "%s", durationstring(mindur)); addtobuffer(buf, l); /* maxdur=INT_MAX means "no max duration". So set it to 0 for durationstring() to do the right thing */ if (maxdur == INT_MAX) maxdur = 0; snprintf(l, sizeof(l), "%s", durationstring(maxdur)); addtobuffer(buf, l); snprintf(l, sizeof(l), "%s", durationstring(recip->interval)); addtobuffer(buf, l); if (timespec && extimespec) snprintf(l, sizeof(l), "%s, except %s", timespec, extimespec); else if (timespec) snprintf(l, sizeof(l), "%s", timespec); else if (extimespec) snprintf(l, sizeof(l), "all, except %s", extimespec); else strncpy(l, "-", sizeof(l)); addtobuffer(buf, l); addtobuffer(buf, ""); for (i = 0; (i < COL_COUNT); i++) { if ((1 << i) & colors) { snprintf(l, sizeof(l), "%s%s", (firstcolor ? "" : ","), colorname(i)); addtobuffer(buf, l); firstcolor = 0; } } addtobuffer(buf, ""); if (stoprulefound) fontspec = stopfont; addtobuffer(buf, "\n"); } /* This is hackish - patch up the "rowspan" value, so it matches the number of recipient lines */ snprintf(l, sizeof(l), "%d ", count); p = strstr(STRBUF(buf), "rowspan=###"); if (p) { p += strlen("rowspan="); memcpy(p, l, 3); } MEMUNDEFINE(l); MEMUNDEFINE(codes); } xymon-4.3.30/lib/loadhosts_file.c0000664000076400007640000003401513515623702017123 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the hosts.cfg */ /* file and keeping track of what hosts are known, their aliases and planned */ /* downtime settings etc. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid_file[] = "$Id: loadhosts_file.c 8069 2019-07-23 15:29:06Z jccleaver $"; static int get_page_name_title(char *buf, char *key, char **name, char **title) { *name = *title = NULL; *name = buf + strlen(key); *name += strspn(*name, " \t\r\n"); if (strlen(*name) > 0) { /* (*name) now points at the start of the name. Find end of name */ *title = *name; *title += strcspn(*title, " \t\r\n"); /* Null-terminate the name */ **title = '\0'; (*title)++; *title += strspn(*title, " \t\r\n"); return 0; } return 1; } static int pagematch(pagelist_t *pg, char *name) { char *p = strrchr(pg->pagepath, '/'); if (p) { return (strcmp(p+1, name) == 0); } else { return (strcmp(pg->pagepath, name) == 0); } } static strbuffer_t *contentbuffer = NULL; static int prepare_fromfile(char *hostsfn, char *extrainclude) { static void *hostfiles = NULL; FILE *hosts; strbuffer_t *inbuf; /* First check if there were no modifications at all */ if (hostfiles) { if (!stackfmodified(hostfiles)){ return 1; } else { stackfclist(&hostfiles); hostfiles = NULL; } } if (!contentbuffer) contentbuffer = newstrbuffer(0); clearstrbuffer(contentbuffer); hosts = stackfopen(hostsfn, "r", &hostfiles); if (hosts == NULL) return -1; inbuf = newstrbuffer(20480); while (stackfgets(inbuf, extrainclude)) { sanitize_input(inbuf, 0, 0); addtostrbuffer(contentbuffer, inbuf); addtobuffer(contentbuffer, "\n"); } stackfclose(hosts); freestrbuffer(inbuf); return 0; } static int prepare_fromnet(void) { static char contentmd5[33] = { '\0', }; sendreturn_t *sres; sendresult_t sendstat; char *fdata, *fhash; sres = newsendreturnbuf(1, NULL); sendstat = sendmessage("config hosts.cfg", NULL, XYMON_TIMEOUT, sres); if (sendstat != XYMONSEND_OK) { freesendreturnbuf(sres); errprintf("Cannot load hosts.cfg from xymond, code %d\n", sendstat); return -1; } fdata = getsendreturnstr(sres, 1); freesendreturnbuf(sres); fhash = md5hash(fdata); if (strcmp(contentmd5, fhash) == 0) { /* No changes */ xfree(fdata); return 1; } if (contentbuffer) freestrbuffer(contentbuffer); contentbuffer = convertstrbuffer(fdata, 0); strncpy(contentmd5, fhash, sizeof(contentmd5)); return 0; } char *hostscfg_content(void) { return strdup(STRBUF(contentbuffer)); } int load_hostnames(char *hostsfn, char *extrainclude, int fqdn) { /* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */ int prepresult; int ip1, ip2, ip3, ip4, groupid, pageidx; char hostname[4096]; SBUF_DEFINE(dgname); pagelist_t *curtoppage, *curpage, *pgtail; void * htree; char *cfgdata, *inbol, *ineol, insavchar = '\0'; load_hostinfo(NULL); if (*hostsfn == '!') prepresult = prepare_fromfile(hostsfn+1, extrainclude); else if (extrainclude) prepresult = prepare_fromfile(hostsfn, extrainclude); else if ((*hostsfn == '@') || (strcmp(hostsfn, xgetenv("HOSTSCFG")) == 0)) { prepresult = prepare_fromnet(); if (prepresult == -1) { errprintf("Failed to load from xymond, reverting to file-load\n"); prepresult = prepare_fromfile(xgetenv("HOSTSCFG"), extrainclude); } } else prepresult = prepare_fromfile(hostsfn, extrainclude); /* Did we get the data ? */ if (prepresult == -1) { errprintf("Cannot load host data\n"); return -1; } /* Any modifications at all ? */ if (prepresult == 1) { dbgprintf("No files modified, skipping reload of %s\n", hostsfn); return 1; } MEMDEFINE(hostname); MEMDEFINE(l); configloaded = 1; initialize_hostlist(); curpage = curtoppage = pgtail = pghead; pageidx = groupid = 0; dgname = NULL; htree = xtreeNew(strcasecmp); inbol = cfgdata = hostscfg_content(); while (inbol && *inbol) { inbol += strspn(inbol, " \t"); ineol = strchr(inbol, '\n'); if (ineol) { while ((ineol > inbol) && (isspace(*ineol) || (*ineol == '\n'))) ineol--; if (*ineol != '\n') ineol++; insavchar = *ineol; *ineol = '\0'; } /* Strip out initial "v" for vpage/vsubpage/vsubparent -- we don't care about the difference here */ if ((strncmp(inbol, "vpage", 5) == 0) || (strncmp(inbol, "vsubpage", 8) == 0) || (strncmp(inbol, "vsubparent", 10) == 0)) inbol++; if (strncmp(inbol, "page", 4) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; if (get_page_name_title(inbol, "page", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = strdup(name); newp->pagetitle = (title ? strdup(title) : NULL); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = curtoppage = newp; } } else if (strncmp(inbol, "subpage", 7) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; if (get_page_name_title(inbol, "subpage", &name, &title) == 0) { unsigned int sz; newp = (pagelist_t *)malloc(sizeof(pagelist_t)); sz = strlen(curtoppage->pagepath) + strlen(name) + 2; newp->pagepath = malloc(sz); snprintf(newp->pagepath, sz, "%s/%s", curtoppage->pagepath, name); sz = strlen(curtoppage->pagetitle) + strlen(title) + 2; newp->pagetitle = malloc(sz); snprintf(newp->pagetitle, sz, "%s/%s", curtoppage->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(inbol, "subparent", 9) == 0) { pagelist_t *newp, *parent; char *pname, *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; parent = NULL; if (get_page_name_title(inbol, "subparent", &pname, &title) == 0) { for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next); } if (parent && (get_page_name_title(title, "", &name, &title) == 0)) { unsigned int sz; newp = (pagelist_t *)malloc(sizeof(pagelist_t)); sz = strlen(parent->pagepath) + strlen(name) + 2; newp->pagepath = malloc(sz); snprintf(newp->pagepath, sz, "%s/%s", parent->pagepath, name); sz = strlen(parent->pagetitle) + strlen(title) + 2; newp->pagetitle = malloc(sz); snprintf(newp->pagetitle, sz, "%s/%s", parent->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(inbol, "group", 5) == 0) { char *tok; groupid++; if (dgname) xfree(dgname); dgname = NULL; tok = strtok(inbol, " \t"); if ((strcmp(tok, "group-only") == 0) || (strcmp(tok, "group-except") == 0)) { tok = strtok(NULL, " \t"); } if (tok) tok = strtok(NULL, "\r\n"); if (tok) { char *inp; /* Strip HTML tags from the string */ SBUF_MALLOC(dgname, strlen(tok) + 1); *dgname = '\0'; inp = tok; while (*inp) { char *tagstart, *tagend; tagstart = strchr(inp, '<'); if (tagstart) { tagend = strchr(tagstart, '>'); *tagstart = '\0'; if (*inp) strncat(dgname, inp, (dgname_buflen - strlen(dgname))); if (tagend) { inp = tagend+1; } else { /* Unmatched '<', keep all of the string */ *tagstart = '<'; strncat(dgname, tagstart, (dgname_buflen - strlen(dgname))); inp += strlen(inp); } } else { strncat(dgname, inp, (dgname_buflen - strlen(dgname))); inp += strlen(inp); } } } } else if (sscanf(inbol, "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { char *startoftags, *tag, *delim; int elemidx, elemsize; char groupidstr[15]; xtreePos_t handle; namelist_t *newitem; if ( (ip1 < 0) || (ip1 > 255) || (ip2 < 0) || (ip2 > 255) || (ip3 < 0) || (ip3 > 255) || (ip4 < 0) || (ip4 > 255)) { errprintf("Invalid IPv4-address for host %s (nibble outside 0-255 range): %d.%d.%d.%d\n", hostname, ip1, ip2, ip3, ip4); goto nextline; } newitem = calloc(1, sizeof(namelist_t)); /* Hostname beginning with '@' are "no-display" hosts. But we still want them. */ if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname)); if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } snprintf(newitem->ip, sizeof(newitem->ip), "%d.%d.%d.%d", ip1, ip2, ip3, ip4); snprintf(groupidstr, sizeof(groupidstr), "%d", groupid); newitem->groupid = strdup(groupidstr); newitem->dgname = (dgname ? strdup(dgname) : strdup("NONE")); newitem->pageindex = pageidx++; newitem->hostname = strdup(hostname); if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0; newitem->logname = strdup(newitem->hostname); { char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } newitem->page = curpage; newitem->defaulthost = defaulthost; startoftags = strchr(inbol, '#'); if (startoftags == NULL) startoftags = ""; else startoftags++; startoftags += strspn(startoftags, " \t\r\n"); newitem->allelems = strdup(startoftags); elemsize = 5; newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *)); tag = newitem->allelems; elemidx = 0; while (tag && *tag) { if (elemidx == elemsize) { elemsize += 5; newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *)); } newitem->elems[elemidx] = tag; /* Skip until we hit a whitespace or a quote */ tag += strcspn(tag, " \t\r\n\""); if (*tag == '"') { delim = tag; /* Hit a quote - skip until the next matching quote */ tag = strchr(tag+1, '"'); if (tag != NULL) { /* Found end-quote, NULL the item here and move on */ *tag = '\0'; tag++; } /* Now move quoted data one byte down (including the NUL) to kill quotechar */ memmove(delim, delim+1, strlen(delim)); } else if (*tag) { /* Normal end of item, NULL it and move on */ *tag = '\0'; tag++; } else { /* End of line - no more to do. */ tag = NULL; } /* * If we find a "noconn", drop preference value to 0. * If we find a "prefer", up reference value to 2. */ if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0)) newitem->preference = 0; else if (strcmp(newitem->elems[elemidx], "prefer") == 0) newitem->preference = 2; /* Skip whitespace until start of next tag */ if (tag) tag += strspn(tag, " \t\r\n"); elemidx++; } newitem->elems[elemidx] = NULL; /* See if this host is defined before */ handle = xtreeFind(htree, newitem->hostname); if (strcasecmp(newitem->hostname, ".default.") == 0) { /* The pseudo DEFAULT host */ newitem->next = newitem->prev = NULL; defaulthost = newitem; } else if (handle == xtreeEnd(htree)) { /* New item, so add to end of list */ newitem->prev = nametail; newitem->next = NULL; if (namehead == NULL) namehead = nametail = newitem; else { nametail->next = newitem; nametail = newitem; } xtreeAdd(htree, newitem->hostname, newitem); } else { namelist_t *existingrec = (namelist_t *)xtreeData(htree, handle); if (newitem->preference <= existingrec->preference) { /* Add after the existing (more preferred) entry */ newitem->next = existingrec->next; /* NB: existingrec may be the end of the list, so existingrec->next can be NULL */ if (newitem->next) newitem->next->prev = newitem; existingrec->next = newitem; newitem->prev = existingrec; if (newitem->next == NULL) nametail = newitem; } else { /* New item has higher preference, so add before the current item (i.e. after existingrec->prev) */ if (existingrec->prev == NULL) { newitem->next = namehead; namehead = newitem; } else { newitem->prev = existingrec->prev; newitem->next = existingrec; existingrec->prev = newitem; newitem->prev->next = newitem; } } } newitem->clientname = xmh_find_item(newitem, XMH_CLIENTALIAS); if (newitem->clientname == NULL) newitem->clientname = newitem->hostname; newitem->downtime = xmh_find_item(newitem, XMH_DOWNTIME); #ifdef DEBUG { namelist_t *walk; int err = 0; for (walk = namehead; (walk && !err); walk = walk->next) { // printf("%s %s %s\n", walk->hostname, (walk->next ? walk->next->hostname: ""), (walk->prev ? walk->prev->hostname : "")); if (walk->next && (walk->next->prev != walk)) { printf("*** ERROR: next->prev is not self\n"); err = 1; } if (!walk->next && (walk != nametail)) { printf("*** ERROR: No next element, but nametail is different\n"); err = 1; } if (!walk->prev && (walk != namehead)) { printf("*** ERROR: No prev element, but namehead is different\n"); err = 1; } } if (err) printf("Error\n"); } #endif } nextline: if (ineol) { *ineol = insavchar; if (*ineol != '\n') ineol = strchr(ineol, '\n'); inbol = (ineol ? ineol+1 : NULL); } else inbol = NULL; } xfree(cfgdata); if (dgname) xfree(dgname); xtreeDestroy(htree); MEMUNDEFINE(hostname); MEMUNDEFINE(l); build_hosttree(); return 0; } xymon-4.3.30/lib/netservices.h0000664000076400007640000000242611615341300016452 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __NETSERVICES_H__ #define __NETSERVICES_H__ /* * Flag bits for known TCP services */ #define TCP_GET_BANNER 0x0001 #define TCP_TELNET 0x0002 #define TCP_SSL 0x0004 #define TCP_HTTP 0x0008 typedef struct svcinfo_t { char *svcname; unsigned char *sendtxt; int sendlen; unsigned char *exptext; int expofs, explen; unsigned int flags; int port; } svcinfo_t; extern char *init_tcp_services(void); extern void dump_tcp_services(void); extern int default_tcp_port(char *svcname); extern svcinfo_t *find_tcp_service(char *svcname); #endif xymon-4.3.30/lib/eventlog.h0000664000076400007640000000413411615341300015741 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __EVENTLOG_H_ #define __EVENTLOG_H_ /* Format of records in the $XYMONHISTDIR/allevents file */ typedef struct event_t { void *host; struct htnames_t *service; time_t eventtime; time_t changetime; time_t duration; int newcolor; /* stored as "re", "ye", "gr" etc. */ int oldcolor; int state; /* 2=escalated, 1=recovered, 0=no change */ struct event_t *next; } event_t; typedef struct eventcount_t { struct htnames_t *service; unsigned long count; struct eventcount_t *next; } eventcount_t; typedef struct countlist_t { void *src; /* May be a pointer to a host or a service */ unsigned long total; struct countlist_t *next; } countlist_t; typedef enum { XYMON_S_NONE, XYMON_S_HOST_BREAKDOWN, XYMON_S_SERVICE_BREAKDOWN } eventsummary_t; typedef enum { XYMON_COUNT_NONE, XYMON_COUNT_EVENTS, XYMON_COUNT_DURATION } countsummary_t; typedef int (*f_hostcheck)(char *hostname); extern char *eventignorecolumns; extern int havedoneeventlog; extern void do_eventlog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pagematch, char *expagematch, char *hostmatch, char *exhostmatch, char *testmatch, char *extestmatch, char *colormatch, int ignoredialups, f_hostcheck hostcheck, event_t **eventlist, countlist_t **hostcounts, countlist_t **servicecounts, countsummary_t counttype, eventsummary_t sumtype, char *periodstring); #endif xymon-4.3.30/lib/headfoot.c0000664000076400007640000013717413515623702015727 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for handling header- and footer-files. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: headfoot.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "version.h" /* Stuff for headfoot - variables we can set dynamically */ static char *hostenv_hikey = NULL; static char *hostenv_host = NULL; static char *hostenv_ip = NULL; static char *hostenv_svc = NULL; static char *hostenv_color = NULL; static char *hostenv_pagepath = NULL; static time_t hostenv_reportstart = 0; static time_t hostenv_reportend = 0; static char *hostenv_repwarn = NULL; static char *hostenv_reppanic = NULL; static time_t hostenv_snapshot = 0; static char *hostenv_logtime = NULL; static char *hostenv_templatedir = NULL; static int hostenv_refresh = 60; static char *statusboard = NULL; static char *scheduleboard = NULL; static char *hostpattern_text = NULL; static pcre *hostpattern = NULL; static char *pagepattern_text = NULL; static pcre *pagepattern = NULL; static char *ippattern_text = NULL; static pcre *ippattern = NULL; static char *classpattern_text = NULL; static pcre *classpattern = NULL; static void * hostnames; static void * testnames; typedef struct treerec_t { char *name; int flag; } treerec_t; static int backdays = 0, backhours = 0, backmins = 0, backsecs = 0; static char hostenv_eventtimestart[20]; static char hostenv_eventtimeend[20]; typedef struct listrec_t { char *name, *val, *extra; int selected; struct listrec_t *next; } listrec_t; typedef struct listpool_t { char *name; struct listrec_t *listhead, *listtail; struct listpool_t *next; } listpool_t; static listpool_t *listpoolhead = NULL; typedef struct bodystorage_t { char *id; strbuffer_t *txt; } bodystorage_t; static void clearflags(void * tree) { xtreePos_t handle; treerec_t *rec; if (!tree) return; for (handle = xtreeFirst(tree); (handle != xtreeEnd(tree)); handle = xtreeNext(tree, handle)) { rec = (treerec_t *)xtreeData(tree, handle); rec->flag = 0; } } void sethostenv(char *host, char *ip, char *svc, char *color, char *hikey) { if (hostenv_hikey) xfree(hostenv_hikey); if (hostenv_host) xfree(hostenv_host); if (hostenv_ip) xfree(hostenv_ip); if (hostenv_svc) xfree(hostenv_svc); if (hostenv_color) xfree(hostenv_color); hostenv_hikey = (hikey ? strdup(htmlquoted(hikey)) : NULL); hostenv_host = strdup(htmlquoted(host)); hostenv_ip = strdup(htmlquoted(ip)); hostenv_svc = strdup(htmlquoted(svc)); hostenv_color = strdup(color); } void sethostenv_report(time_t reportstart, time_t reportend, double repwarn, double reppanic) { if (hostenv_repwarn == NULL) hostenv_repwarn = malloc(10); if (hostenv_reppanic == NULL) hostenv_reppanic = malloc(10); hostenv_reportstart = reportstart; hostenv_reportend = reportend; snprintf(hostenv_repwarn, 10, "%.2f", repwarn); snprintf(hostenv_reppanic, 10, "%.2f", reppanic); } void sethostenv_snapshot(time_t snapshot) { hostenv_snapshot = snapshot; } void sethostenv_histlog(char *histtime) { if (hostenv_logtime) xfree(hostenv_logtime); hostenv_logtime = strdup(histtime); } void sethostenv_template(char *dir) { if (hostenv_templatedir) xfree(hostenv_templatedir); hostenv_templatedir = strdup(dir); } void sethostenv_refresh(int n) { hostenv_refresh = n; } void sethostenv_pagepath(char *s) { if (!s) return; if (hostenv_pagepath) xfree(hostenv_pagepath); hostenv_pagepath = strdup(s); } void sethostenv_filter(char *hostptn, char *pageptn, char *ipptn, char *classptn) { const char *errmsg; int errofs; if (hostpattern_text) xfree(hostpattern_text); if (hostpattern) { pcre_free(hostpattern); hostpattern = NULL; } if (pagepattern_text) xfree(pagepattern_text); if (pagepattern) { pcre_free(pagepattern); pagepattern = NULL; } if (ippattern_text) xfree(ippattern_text); if (ippattern) { pcre_free(ippattern); ippattern = NULL; } if (classpattern_text) xfree(classpattern_text); if (classpattern) { pcre_free(classpattern); classpattern = NULL; } /* Setup the pattern to match names against */ if (hostptn) { hostpattern_text = strdup(hostptn); hostpattern = pcre_compile(hostptn, PCRE_CASELESS, &errmsg, &errofs, NULL); } if (pageptn) { pagepattern_text = strdup(pageptn); pagepattern = pcre_compile(pageptn, PCRE_CASELESS, &errmsg, &errofs, NULL); } if (ipptn) { ippattern_text = strdup(ipptn); ippattern = pcre_compile(ipptn, PCRE_CASELESS, &errmsg, &errofs, NULL); } if (classptn) { classpattern_text = strdup(classptn); classpattern = pcre_compile(classptn, PCRE_CASELESS, &errmsg, &errofs, NULL); } } static listpool_t *find_listpool(char *listname) { listpool_t *pool = NULL; if (!listname) listname = ""; for (pool = listpoolhead; (pool && strcmp(pool->name, listname)); pool = pool->next); if (!pool) { pool = (listpool_t *)calloc(1, sizeof(listpool_t)); pool->name = strdup(listname); pool->next = listpoolhead; listpoolhead = pool; } return pool; } void sethostenv_clearlist(char *listname) { listpool_t *pool = NULL; listrec_t *zombie; pool = find_listpool(listname); while (pool->listhead) { zombie = pool->listhead; pool->listhead = pool->listhead->next; xfree(zombie->name); xfree(zombie->val); xfree(zombie); } } void sethostenv_addtolist(char *listname, char *name, char *val, char *extra, int selected) { listpool_t *pool = NULL; listrec_t *newitem = (listrec_t *)calloc(1, sizeof(listrec_t)); pool = find_listpool(listname); newitem->name = strdup(name); newitem->val = strdup(val); newitem->extra = (extra ? strdup(extra) : NULL); newitem->selected = selected; if (pool->listtail) { pool->listtail->next = newitem; pool->listtail = newitem; } else { pool->listhead = pool->listtail = newitem; } } static int critackttprio = 0; static char *critackttgroup = NULL; static char *critackttextra = NULL; static char *ackinfourl = NULL; static char *critackdocurl = NULL; void sethostenv_critack(int prio, char *ttgroup, char *ttextra, char *infourl, char *docurl) { critackttprio = prio; if (critackttgroup) xfree(critackttgroup); critackttgroup = strdup((ttgroup && *ttgroup) ? ttgroup : " "); if (critackttextra) xfree(critackttextra); critackttextra = strdup((ttextra && *ttextra) ? ttextra : " "); if (ackinfourl) xfree(ackinfourl); ackinfourl = strdup(infourl); if (critackdocurl) xfree(critackdocurl); critackdocurl = strdup((docurl && *docurl) ? docurl : ""); } static char *criteditupdinfo = NULL; static int criteditprio = -1; static char *criteditgroup = NULL; static time_t criteditstarttime = 0; static time_t criteditendtime = 0; static char *criteditextra = NULL; static char *criteditslawkdays = NULL; static char *criteditslastart = NULL; static char *criteditslaend = NULL; static char **criteditclonelist = NULL; static int criteditclonesize = 0; void sethostenv_critedit(char *updinfo, int prio, char *group, time_t starttime, time_t endtime, char *crittime, char *extra) { char *p; if (criteditupdinfo) xfree(criteditupdinfo); criteditupdinfo = strdup(updinfo); criteditprio = prio; criteditstarttime = starttime; criteditendtime = endtime; if (criteditgroup) xfree(criteditgroup); criteditgroup = strdup(group ? group : ""); if (criteditextra) xfree(criteditextra); criteditextra = strdup(extra ? extra : ""); if (criteditslawkdays) xfree(criteditslawkdays); criteditslawkdays = criteditslastart = criteditslaend = NULL; if (crittime) { criteditslawkdays = strdup(crittime); p = strchr(criteditslawkdays, ':'); if (p) { *p = '\0'; criteditslastart = p+1; p = strchr(criteditslastart, ':'); if (p) { *p = '\0'; criteditslaend = p+1; } } if (criteditslawkdays && (!criteditslastart || !criteditslaend)) { xfree(criteditslawkdays); criteditslawkdays = criteditslastart = criteditslaend = NULL; } } } void sethostenv_critclonelist_clear(void) { int i; if (criteditclonelist) { for (i=0; (criteditclonelist[i]); i++) xfree(criteditclonelist[i]); xfree(criteditclonelist); } criteditclonelist = malloc(sizeof(char *)); criteditclonelist[0] = NULL; criteditclonesize = 0; } void sethostenv_critclonelist_add(char *hostname) { char *p; criteditclonelist = (char **)realloc(criteditclonelist, (criteditclonesize + 2)*sizeof(char *)); criteditclonelist[criteditclonesize] = strdup(hostname); p = criteditclonelist[criteditclonesize]; criteditclonelist[++criteditclonesize] = NULL; p += (strlen(p) - 1); if (*p == '=') *p = '\0'; } void sethostenv_backsecs(int seconds) { backdays = seconds / 86400; seconds -= backdays*86400; backhours = seconds / 3600; seconds -= backhours*3600; backmins = seconds / 60; seconds -= backmins*60; backsecs = seconds; } void sethostenv_eventtime(time_t starttime, time_t endtime) { *hostenv_eventtimestart = *hostenv_eventtimeend = '\0'; if (starttime) strftime(hostenv_eventtimestart, sizeof(hostenv_eventtimestart), "%Y/%m/%d@%H:%M:%S", localtime(&starttime)); if (endtime) strftime(hostenv_eventtimeend, sizeof(hostenv_eventtimeend), "%Y/%m/%d@%H:%M:%S", localtime(&endtime)); } char *wkdayselect(char wkday, char *valtxt, int isdefault) { static char result[100]; char *selstr; if (!criteditslawkdays) { if (isdefault) selstr = " selected"; else selstr = ""; } else { if (strchr(criteditslawkdays, wkday)) selstr = " selected"; else selstr = ""; } snprintf(result, sizeof(result), "\n", wkday, selstr, valtxt); return result; } static void *wanted_host(char *hostname) { void *hinfo = hostinfo(hostname); int result, ovector[30]; if (!hinfo) return NULL; if (hostpattern) { result = pcre_exec(hostpattern, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) return NULL; } if (pagepattern && hinfo) { char *pname = xmh_item(hinfo, XMH_PAGEPATH); result = pcre_exec(pagepattern, NULL, pname, strlen(pname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) return NULL; } if (ippattern && hinfo) { char *hostip = xmh_item(hinfo, XMH_IP); result = pcre_exec(ippattern, NULL, hostip, strlen(hostip), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) return NULL; } if (classpattern && hinfo) { char *hostclass = xmh_item(hinfo, XMH_CLASS); if (!hostclass) return NULL; result = pcre_exec(classpattern, NULL, hostclass, strlen(hostclass), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) return NULL; } return hinfo; } static void fetch_board(void) { static int haveboard = 0; char *walk, *eoln; sendreturn_t *sres; if (haveboard) return; sres = newsendreturnbuf(1, NULL); if (sendmessage("xymondboard fields=hostname,testname,disabletime,dismsg", NULL, XYMON_TIMEOUT, sres) != XYMONSEND_OK) { freesendreturnbuf(sres); return; } haveboard = 1; statusboard = getsendreturnstr(sres, 1); freesendreturnbuf(sres); hostnames = xtreeNew(strcasecmp); testnames = xtreeNew(strcasecmp); walk = statusboard; while (walk) { eoln = strchr(walk, '\n'); if (eoln) *eoln = '\0'; if (strlen(walk) && (strncmp(walk, "summary|", 8) != 0)) { char *buf, *hname = NULL, *tname = NULL; treerec_t *newrec; buf = strdup(walk); hname = gettok(buf, "|"); if (hname && wanted_host(hname) && hostinfo(hname)) { newrec = (treerec_t *)malloc(sizeof(treerec_t)); newrec->name = strdup(hname); newrec->flag = 0; xtreeAdd(hostnames, newrec->name, newrec); tname = gettok(NULL, "|"); if (tname) { newrec = (treerec_t *)malloc(sizeof(treerec_t)); newrec->name = strdup(tname); newrec->flag = 0; xtreeAdd(testnames, strdup(tname), newrec); } } xfree(buf); } if (eoln) { *eoln = '\n'; walk = eoln + 1; } else walk = NULL; } sres = newsendreturnbuf(1, NULL); if (sendmessage("schedule", NULL, XYMON_TIMEOUT, sres) != XYMONSEND_OK) { freesendreturnbuf(sres); return; } scheduleboard = getsendreturnstr(sres, 1); freesendreturnbuf(sres); } static char *eventreport_timestring(time_t timestamp) { static char result[20]; strftime(result, sizeof(result), "%Y/%m/%d@%H:%M:%S", localtime(×tamp)); return result; } static void build_pagepath_dropdown(FILE *output) { void * ptree; void *hwalk; xtreePos_t handle; ptree = xtreeNew(strcmp); for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { char *path = xmh_item(hwalk, XMH_PAGEPATH); char *ptext; handle = xtreeFind(ptree, path); if (handle != xtreeEnd(ptree)) continue; ptext = xmh_item(hwalk, XMH_PAGEPATHTITLE); xtreeAdd(ptree, ptext, path); } for (handle = xtreeFirst(ptree); (handle != xtreeEnd(ptree)); handle = xtreeNext(ptree, handle)) { fprintf(output, "\n", (char *)xtreeData(ptree, handle), xtreeKey(ptree, handle)); } xtreeDestroy(ptree); } char *xymonbody(char *id) { static void * bodystorage; static int firsttime = 1; xtreePos_t handle; bodystorage_t *bodyelement; strbuffer_t *rawdata, *parseddata; char *envstart, *envend, *outpos; char *idtag, *idval; int idtaglen; if (firsttime) { bodystorage = xtreeNew(strcmp); firsttime = 0; } idtaglen = strspn(id, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); idtag = (char *)malloc(idtaglen + 1); strncpy(idtag, id, idtaglen); *(idtag+idtaglen) = '\0'; handle = xtreeFind(bodystorage, idtag); if (handle != xtreeEnd(bodystorage)) { bodyelement = (bodystorage_t *)xtreeData(bodystorage, handle); xfree(idtag); return STRBUF(bodyelement->txt); } rawdata = newstrbuffer(0); idval = xgetenv(idtag); if (idval == NULL) return ""; if (strncmp(idval, "file:", 5) == 0) { FILE *fd; strbuffer_t *inbuf = newstrbuffer(0); fd = stackfopen(idval+5, "r", NULL); if (fd != NULL) { while (stackfgets(inbuf, NULL)) addtostrbuffer(rawdata, inbuf); stackfclose(fd); } freestrbuffer(inbuf); } else { addtobuffer(rawdata, idval); } /* Output the body data, but expand any environment variables along the way */ parseddata = newstrbuffer(0); outpos = STRBUF(rawdata); while (*outpos) { envstart = strchr(outpos, '$'); if (envstart) { char savechar; char *envval = NULL; *envstart = '\0'; addtobuffer(parseddata, outpos); envstart++; envend = envstart + strspn(envstart, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); savechar = *envend; *envend = '\0'; if (*envstart) envval = xgetenv(envstart); *envend = savechar; outpos = envend; if (envval) { addtobuffer(parseddata, envval); } else { addtobuffer(parseddata, "$"); addtobuffer(parseddata, envstart); } } else { addtobuffer(parseddata, outpos); outpos += strlen(outpos); } } freestrbuffer(rawdata); bodyelement = (bodystorage_t *)calloc(1, sizeof(bodystorage_t)); bodyelement->id = idtag; bodyelement->txt = parseddata; xtreeAdd(bodystorage, bodyelement->id, bodyelement); return STRBUF(bodyelement->txt); } typedef struct distest_t { char *name; char *cause; time_t until; struct distest_t *next; } distest_t; typedef struct dishost_t { char *name; struct distest_t *tests; struct dishost_t *next; } dishost_t; void output_parsed(FILE *output, char *templatedata, int bgcolor, time_t selectedtime) { char *t_start, *t_next; char savechar; time_t now = getcurrenttime(NULL); time_t yesterday = getcurrenttime(NULL) - 86400; struct tm *nowtm; for (t_start = templatedata, t_next = strchr(t_start, '&'); (t_next); ) { /* Copy from t_start to t_next unchanged */ *t_next = '\0'; t_next++; fprintf(output, "%s", t_start); /* Find token */ t_start = t_next; /* Don't include lower-case letters - reserve those for eg " " */ t_next += strspn(t_next, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"); savechar = *t_next; *t_next = '\0'; if ((strcmp(t_start, "XYMWEBDATE") == 0) || (strcmp(t_start, "BBDATE") == 0)) { char *datefmt = xgetenv("XYMONDATEFORMAT"); char datestr[100]; MEMDEFINE(datestr); /* * If no XYMONDATEFORMAT setting, use a format string that * produces output similar to that from ctime() */ if (datefmt == NULL) datefmt = "%a %b %d %H:%M:%S %Y\n"; if (hostenv_reportstart != 0) { char starttime[20], endtime[20]; MEMDEFINE(starttime); MEMDEFINE(endtime); strftime(starttime, sizeof(starttime), "%b %d %Y", localtime(&hostenv_reportstart)); strftime(endtime, sizeof(endtime), "%b %d %Y", localtime(&hostenv_reportend)); if (strcmp(starttime, endtime) == 0) fprintf(output, "%s", starttime); else fprintf(output, "%s - %s", starttime, endtime); MEMUNDEFINE(starttime); MEMUNDEFINE(endtime); } else if (hostenv_snapshot != 0) { strftime(datestr, sizeof(datestr), datefmt, localtime(&hostenv_snapshot)); fprintf(output, "%s", datestr); } else { strftime(datestr, sizeof(datestr), datefmt, localtime(&now)); fprintf(output, "%s", datestr); } MEMUNDEFINE(datestr); } else if ((strcmp(t_start, "XYMWEBBACKGROUND") == 0) || (strcmp(t_start, "BBBACKGROUND") == 0)) { fprintf(output, "%s", colorname(bgcolor)); } else if ((strcmp(t_start, "XYMWEBCOLOR") == 0) || (strcmp(t_start, "BBCOLOR") == 0)) fprintf(output, "%s", hostenv_color); else if ((strcmp(t_start, "XYMWEBSVC") == 0) || (strcmp(t_start, "BBSVC") == 0)) fprintf(output, "%s", hostenv_svc); else if ((strcmp(t_start, "XYMWEBHOST") == 0) || (strcmp(t_start, "BBHOST") == 0)) fprintf(output, "%s", hostenv_host); else if ((strcmp(t_start, "XYMWEBHIKEY") == 0) || (strcmp(t_start, "BBHIKEY") == 0)) fprintf(output, "%s", (hostenv_hikey ? hostenv_hikey : hostenv_host)); else if ((strcmp(t_start, "XYMWEBIP") == 0) || (strcmp(t_start, "BBIP") == 0)) fprintf(output, "%s", hostenv_ip); else if ((strcmp(t_start, "XYMWEBIPNAME") == 0) || (strcmp(t_start, "BBIPNAME") == 0)) { if (strcmp(hostenv_ip, "0.0.0.0") == 0) fprintf(output, "%s", hostenv_host); else fprintf(output, "%s", hostenv_ip); } else if ((strcmp(t_start, "XYMONREPWARN") == 0) || (strcmp(t_start, "BBREPWARN") == 0)) fprintf(output, "%s", hostenv_repwarn); else if ((strcmp(t_start, "XYMONREPPANIC") == 0) || (strcmp(t_start, "BBREPPANIC") == 0)) fprintf(output, "%s", hostenv_reppanic); else if (strcmp(t_start, "LOGTIME") == 0) fprintf(output, "%s", (hostenv_logtime ? hostenv_logtime : "")); else if ((strcmp(t_start, "XYMWEBREFRESH") == 0) || (strcmp(t_start, "BBREFRESH") == 0)) fprintf(output, "%d", hostenv_refresh); else if ((strcmp(t_start, "XYMWEBPAGEPATH") == 0) || (strcmp(t_start, "BBPAGEPATH") == 0)) fprintf(output, "%s", (hostenv_pagepath ? hostenv_pagepath : "")); else if (strcmp(t_start, "REPMONLIST") == 0) { int i; struct tm monthtm; char mname[20]; char *selstr; MEMDEFINE(mname); nowtm = localtime(&selectedtime); for (i=1; (i <= 12); i++) { if (i == (nowtm->tm_mon + 1)) selstr = " selected"; else selstr = ""; monthtm.tm_mon = (i-1); monthtm.tm_mday = 1; monthtm.tm_year = nowtm->tm_year; monthtm.tm_hour = monthtm.tm_min = monthtm.tm_sec = monthtm.tm_isdst = 0; strftime(mname, sizeof(mname)-1, "%B", &monthtm); fprintf(output, "\n", i, selstr, mname); } MEMUNDEFINE(mname); } else if (strcmp(t_start, "MONLIST") == 0) { int i; struct tm monthtm; char mname[20]; MEMDEFINE(mname); nowtm = localtime(&selectedtime); for (i=1; (i <= 12); i++) { monthtm.tm_mon = (i-1); monthtm.tm_mday = 1; monthtm.tm_year = nowtm->tm_year; monthtm.tm_hour = monthtm.tm_min = monthtm.tm_sec = monthtm.tm_isdst = 0; strftime(mname, sizeof(mname)-1, "%B", &monthtm); fprintf(output, "\n", i, mname); } MEMUNDEFINE(mname); } else if (strcmp(t_start, "REPWEEKLIST") == 0) { int i; char weekstr[5]; int weeknum; char *selstr; nowtm = localtime(&selectedtime); strftime(weekstr, sizeof(weekstr)-1, "%V", nowtm); weeknum = atoi(weekstr); for (i=1; (i <= 53); i++) { if (i == weeknum) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "REPDAYLIST") == 0) { int i; char *selstr; nowtm = localtime(&selectedtime); for (i=1; (i <= 31); i++) { if (i == nowtm->tm_mday) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "DAYLIST") == 0) { int i; nowtm = localtime(&selectedtime); for (i=1; (i <= 31); i++) { fprintf(output, "\n", i, i); } } else if (strcmp(t_start, "REPYEARLIST") == 0) { int i; char *selstr; int beginyear, endyear; nowtm = localtime(&selectedtime); beginyear = nowtm->tm_year + 1900 - 5; endyear = nowtm->tm_year + 1900; for (i=beginyear; (i <= endyear); i++) { if (i == (nowtm->tm_year + 1900)) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "FUTUREYEARLIST") == 0) { int i; char *selstr; int beginyear, endyear; nowtm = localtime(&selectedtime); beginyear = nowtm->tm_year + 1900; endyear = nowtm->tm_year + 1900 + 5; for (i=beginyear; (i <= endyear); i++) { if (i == (nowtm->tm_year + 1900)) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "YEARLIST") == 0) { int i; int beginyear, endyear; nowtm = localtime(&selectedtime); beginyear = nowtm->tm_year + 1900; endyear = nowtm->tm_year + 1900 + 5; for (i=beginyear; (i <= endyear); i++) { fprintf(output, "\n", i, i); } } else if (strcmp(t_start, "REPHOURLIST") == 0) { int i; struct tm *nowtm = localtime(&yesterday); char *selstr; for (i=0; (i <= 24); i++) { if (i == nowtm->tm_hour) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "HOURLIST") == 0) { int i; for (i=0; (i <= 24); i++) { fprintf(output, "\n", i, i); } } else if (strcmp(t_start, "REPMINLIST") == 0) { int i; struct tm *nowtm = localtime(&yesterday); char *selstr; for (i=0; (i <= 59); i++) { if (i == nowtm->tm_min) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "MINLIST") == 0) { int i; for (i=0; (i <= 59); i++) { fprintf(output, "\n", i, i); } } else if (strcmp(t_start, "REPSECLIST") == 0) { int i; char *selstr; for (i=0; (i <= 59); i++) { if (i == 0) selstr = " selected"; else selstr = ""; fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "HOSTFILTER") == 0) { if (hostpattern_text) fprintf(output, "%s", hostpattern_text); } else if (strcmp(t_start, "PAGEFILTER") == 0) { if (pagepattern_text) fprintf(output, "%s", pagepattern_text); } else if (strcmp(t_start, "IPFILTER") == 0) { if (ippattern_text) fprintf(output, "%s", ippattern_text); } else if (strcmp(t_start, "CLASSFILTER") == 0) { if (classpattern_text) fprintf(output, "%s", classpattern_text); } else if (strcmp(t_start, "HOSTLIST") == 0) { xtreePos_t handle; treerec_t *rec; fetch_board(); for (handle = xtreeFirst(hostnames); (handle != xtreeEnd(hostnames)); handle = xtreeNext(hostnames, handle)) { rec = (treerec_t *)xtreeData(hostnames, handle); if (wanted_host(rec->name)) { fprintf(output, "\n", rec->name, rec->name); } } } else if (strcmp(t_start, "JSHOSTLIST") == 0) { xtreePos_t handle; fetch_board(); clearflags(testnames); fprintf(output, "var hosts = new Array();\n"); fprintf(output, "hosts[\"ALL\"] = [ \"ALL\""); for (handle = xtreeFirst(testnames); (handle != xtreeEnd(testnames)); handle = xtreeNext(testnames, handle)) { treerec_t *rec = xtreeData(testnames, handle); fprintf(output, ", \"%s\"", rec->name); } fprintf(output, " ];\n"); for (handle = xtreeFirst(hostnames); (handle != xtreeEnd(hostnames)); handle = xtreeNext(hostnames, handle)) { treerec_t *hrec = xtreeData(hostnames, handle); if (wanted_host(hrec->name)) { xtreePos_t thandle; treerec_t *trec; char *bwalk, *tname, *p; SBUF_DEFINE(key); SBUF_MALLOC(key, strlen(hrec->name) + 3); /* Setup the search key and find the first occurrence. */ snprintf(key, key_buflen, "\n%s|", hrec->name); if (strncmp(statusboard, (key+1), strlen(key+1)) == 0) bwalk = statusboard; else { bwalk = strstr(statusboard, key); if (bwalk) bwalk++; } while (bwalk) { tname = bwalk + strlen(key+1); p = strchr(tname, '|'); if (p) *p = '\0'; if ( (strcmp(tname, xgetenv("INFOCOLUMN")) != 0) && (strcmp(tname, xgetenv("TRENDSCOLUMN")) != 0) ) { thandle = xtreeFind(testnames, tname); if (thandle != xtreeEnd(testnames)) { trec = (treerec_t *)xtreeData(testnames, thandle); trec->flag = 1; } } if (p) *p = '|'; bwalk = strstr(tname, key); if (bwalk) bwalk++; } fprintf(output, "hosts[\"%s\"] = [ \"ALL\"", hrec->name); for (thandle = xtreeFirst(testnames); (thandle != xtreeEnd(testnames)); thandle = xtreeNext(testnames, thandle)) { trec = (treerec_t *)xtreeData(testnames, thandle); if (trec->flag == 0) continue; trec->flag = 0; fprintf(output, ", \"%s\"", trec->name); } fprintf(output, " ];\n"); } } } else if (strcmp(t_start, "TESTLIST") == 0) { xtreePos_t handle; treerec_t *rec; fetch_board(); for (handle = xtreeFirst(testnames); (handle != xtreeEnd(testnames)); handle = xtreeNext(testnames, handle)) { rec = (treerec_t *)xtreeData(testnames, handle); fprintf(output, "\n", rec->name, rec->name); } } else if (strcmp(t_start, "DISABLELIST") == 0) { char *walk, *eoln; dishost_t *dhosts = NULL, *hwalk, *hprev; distest_t *twalk; fetch_board(); clearflags(testnames); walk = statusboard; while (walk) { eoln = strchr(walk, '\n'); if (eoln) *eoln = '\0'; if (*walk) { char *buf, *hname, *tname, *dismsg, *p; time_t distime; xtreePos_t thandle; treerec_t *rec; buf = strdup(walk); hname = tname = dismsg = NULL; distime = 0; hname = gettok(buf, "|"); if (hname) tname = gettok(NULL, "|"); if (tname) { p = gettok(NULL, "|"); if (p) distime = atol(p); } if (distime) dismsg = gettok(NULL, "|\n"); if (hname && tname && (distime != 0) && dismsg && wanted_host(hname)) { nldecode(dismsg); hwalk = dhosts; hprev = NULL; while (hwalk && (strcasecmp(hname, hwalk->name) > 0)) { hprev = hwalk; hwalk = hwalk->next; } if (!hwalk || (strcasecmp(hname, hwalk->name) != 0)) { dishost_t *newitem = (dishost_t *) malloc(sizeof(dishost_t)); newitem->name = strdup(hname); newitem->tests = NULL; newitem->next = hwalk; if (!hprev) dhosts = newitem; else hprev->next = newitem; hwalk = newitem; } twalk = (distest_t *) malloc(sizeof(distest_t)); twalk->name = strdup(tname); twalk->cause = strdup(dismsg); twalk->until = distime; twalk->next = hwalk->tests; hwalk->tests = twalk; thandle = xtreeFind(testnames, tname); if (thandle != xtreeEnd(testnames)) { rec = xtreeData(testnames, thandle); rec->flag = 1; } } xfree(buf); } if (eoln) { *eoln = '\n'; walk = eoln+1; } else { walk = NULL; } } if (dhosts) { /* Insert the "All hosts" record first. */ hwalk = (dishost_t *)calloc(1, sizeof(dishost_t)); hwalk->next = dhosts; dhosts = hwalk; for (hwalk = dhosts; (hwalk); hwalk = hwalk->next) { fprintf(output, ""); fprintf(output, ""); fprintf(output,"
\n", xgetenv("SECURECGIBINURL")); fprintf(output, "\n", (hwalk->name ? hwalk->name : "")); fprintf(output, "\n"); fprintf(output, "", (hwalk->name ? hwalk->name : "All hosts")); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "
%s
\n"); if (hwalk->name) { fprintf(output, "\n", hwalk->name); fprintf(output, "\n"); } else { dishost_t *hw2; fprintf(output, "\n"); } fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "
\n"); fprintf(output, "
\n"); fprintf(output, "\n"); fprintf(output, "\n"); } } else { fprintf(output, "No tests disabled\n"); } } else if (strcmp(t_start, "SCHEDULELIST") == 0) { char *walk, *eoln; int gotany = 0; fetch_board(); walk = scheduleboard; while (walk) { eoln = strchr(walk, '\n'); if (eoln) *eoln = '\0'; if (*walk) { int id = 0; time_t executiontime = 0; char *sender = NULL, *cmd = NULL, *buf, *p, *eoln; buf = strdup(walk); p = gettok(buf, "|"); if (p) { id = atoi(p); p = gettok(NULL, "|"); } if (p) { executiontime = atoi(p); p = gettok(NULL, "|"); } if (p) { sender = p; p = gettok(NULL, "|"); } if (p) { cmd = p; } if (id && executiontime && sender && cmd) { gotany = 1; nldecode(cmd); fprintf(output, "\n"); fprintf(output, "%s\n", ctime(&executiontime)); fprintf(output, ""); p = cmd; while ((eoln = strchr(p, '\n')) != NULL) { *eoln = '\0'; fprintf(output, "%s
", p); p = (eoln + 1); } fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "
\n", xgetenv("SECURECGIBINURL")); fprintf(output, "\n", id); fprintf(output, "\n"); fprintf(output, "
\n"); fprintf(output, "\n"); } xfree(buf); } if (eoln) { *eoln = '\n'; walk = eoln+1; } else { walk = NULL; } } if (!gotany) { fprintf(output, "No tasks scheduled\n"); } } else if (strncmp(t_start, "GENERICLIST", strlen("GENERICLIST")) == 0) { listpool_t *pool = find_listpool(t_start + strlen("GENERICLIST")); listrec_t *walk; for (walk = pool->listhead; (walk); walk = walk->next) fprintf(output, "\n", walk->val, (walk->selected ? " selected" : ""), (walk->extra ? walk->extra : ""), walk->name); } else if (strcmp(t_start, "CRITACKTTPRIO") == 0) fprintf(output, "%d", critackttprio); else if (strcmp(t_start, "CRITACKTTGROUP") == 0) fprintf(output, "%s", critackttgroup); else if (strcmp(t_start, "CRITACKTTEXTRA") == 0) fprintf(output, "%s", critackttextra); else if (strcmp(t_start, "CRITACKINFOURL") == 0) fprintf(output, "%s", ackinfourl); else if (strcmp(t_start, "CRITACKDOCURL") == 0) fprintf(output, "%s", critackdocurl); else if (strcmp(t_start, "CRITEDITUPDINFO") == 0) { fprintf(output, "%s", criteditupdinfo); } else if (strcmp(t_start, "CRITEDITPRIOLIST") == 0) { int i; char *selstr; for (i=1; (i <= 3); i++) { selstr = ((i == criteditprio) ? " selected" : ""); fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "CRITEDITCLONELIST") == 0) { int i; for (i=0; (criteditclonelist[i]); i++) fprintf(output, "\n", criteditclonelist[i], criteditclonelist[i]); } else if (strcmp(t_start, "CRITEDITGROUP") == 0) { fprintf(output, "%s", criteditgroup); } else if (strcmp(t_start, "CRITEDITEXTRA") == 0) { fprintf(output, "%s", criteditextra); } else if (strcmp(t_start, "CRITEDITWKDAYS") == 0) { fprintf(output, "%s", wkdayselect('*', "All days", 1)); fprintf(output, "%s", wkdayselect('W', "Mon-Fri", 0)); fprintf(output, "%s", wkdayselect('1', "Monday", 0)); fprintf(output, "%s", wkdayselect('2', "Tuesday", 0)); fprintf(output, "%s", wkdayselect('3', "Wednesday", 0)); fprintf(output, "%s", wkdayselect('4', "Thursday", 0)); fprintf(output, "%s", wkdayselect('5', "Friday", 0)); fprintf(output, "%s", wkdayselect('6', "Saturday", 0)); fprintf(output, "%s", wkdayselect('0', "Sunday", 0)); } else if (strcmp(t_start, "CRITEDITSTART") == 0) { int i, curr; char *selstr; curr = (criteditslastart ? (atoi(criteditslastart) / 100) : 0); for (i=0; (i <= 23); i++) { selstr = ((i == curr) ? " selected" : ""); fprintf(output, "\n", i, selstr, i); } } else if (strcmp(t_start, "CRITEDITEND") == 0) { int i, curr; char *selstr; curr = (criteditslaend ? (atoi(criteditslaend) / 100) : 24); for (i=1; (i <= 24); i++) { selstr = ((i == curr) ? " selected" : ""); fprintf(output, "\n", i, selstr, i); } } else if (strncmp(t_start, "CRITEDITDAYLIST", 13) == 0) { time_t t = ((*(t_start+13) == '1') ? criteditstarttime : criteditendtime); char *defstr = ((*(t_start+13) == '1') ? "Now" : "Never"); int i; char *selstr; struct tm *tm; tm = localtime(&t); selstr = ((t == 0) ? " selected" : ""); fprintf(output, "\n", selstr, defstr); for (i=1; (i <= 31); i++) { selstr = ( (t && (tm->tm_mday == i)) ? " selected" : ""); fprintf(output, "\n", i, selstr, i); } } else if (strncmp(t_start, "CRITEDITMONLIST", 13) == 0) { time_t t = ((*(t_start+13) == '1') ? criteditstarttime : criteditendtime); char *defstr = ((*(t_start+13) == '1') ? "Now" : "Never"); int i; char *selstr; struct tm tm; time_t now; struct tm nowtm; struct tm monthtm; char mname[20]; memcpy(&tm, localtime(&t), sizeof(tm)); now = getcurrenttime(NULL); memcpy(&nowtm, localtime(&now), sizeof(tm)); selstr = ((t == 0) ? " selected" : ""); fprintf(output, "\n", selstr, defstr); for (i=1; (i <= 12); i++) { selstr = ( (t && (tm.tm_mon == (i -1))) ? " selected" : ""); monthtm.tm_mon = (i-1); monthtm.tm_mday = 1; monthtm.tm_year = nowtm.tm_year; monthtm.tm_hour = monthtm.tm_min = monthtm.tm_sec = monthtm.tm_isdst = 0; strftime(mname, sizeof(mname)-1, "%B", &monthtm); fprintf(output, "\n", i, selstr, mname); } } else if (strncmp(t_start, "CRITEDITYEARLIST", 14) == 0) { time_t t = ((*(t_start+14) == '1') ? criteditstarttime : criteditendtime); char *defstr = ((*(t_start+14) == '1') ? "Now" : "Never"); int i; char *selstr; struct tm tm; time_t now; struct tm nowtm; int beginyear, endyear; memcpy(&tm, localtime(&t), sizeof(tm)); now = getcurrenttime(NULL); memcpy(&nowtm, localtime(&now), sizeof(tm)); beginyear = nowtm.tm_year + 1900; endyear = nowtm.tm_year + 1900 + 5; selstr = ((t == 0) ? " selected" : ""); fprintf(output, "\n", selstr, defstr); for (i=beginyear; (i <= endyear); i++) { selstr = ( (t && (tm.tm_year == (i - 1900))) ? " selected" : ""); fprintf(output, "\n", i, selstr, i); } } else if (hostenv_hikey && ( (strncmp(t_start, "XMH_", 4) == 0) || (strncmp(t_start, "BBH_", 4) == 0) )) { void *hinfo = hostinfo(hostenv_hikey); if (hinfo) { char *s; if (strncmp(t_start, "BBH_", 4) == 0) memmove(t_start, "XMH_", 4); /* For compatibility */ s = xmh_item_byname(hinfo, t_start); if (!s) { fprintf(output, "&%s", t_start); } else { fprintf(output, "%s", s); } } } else if (strncmp(t_start, "BACKDAYS", 8) == 0) { fprintf(output, "%d", backdays); } else if (strncmp(t_start, "BACKHOURS", 9) == 0) { fprintf(output, "%d", backhours); } else if (strncmp(t_start, "BACKMINS", 8) == 0) { fprintf(output, "%d", backmins); } else if (strncmp(t_start, "BACKSECS", 8) == 0) { fprintf(output, "%d", backsecs); } else if (strncmp(t_start, "EVENTLASTMONTHBEGIN", 19) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_mon -= 1; tm->tm_mday = 1; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTCURRMONTHBEGIN", 19) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_mday = 1; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTLASTWEEKBEGIN", 18) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); int weekstart = atoi(xgetenv("WEEKSTART")); if (tm->tm_wday == weekstart) { /* Do nothing */ } else if (tm->tm_wday > weekstart) tm->tm_mday -= (tm->tm_wday - weekstart); else tm->tm_mday += (weekstart - tm->tm_wday) - 7; tm->tm_mday -= 7; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTCURRWEEKBEGIN", 18) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); int weekstart = atoi(xgetenv("WEEKSTART")); if (tm->tm_wday == weekstart) { /* Do nothing */ } else if (tm->tm_wday > weekstart) tm->tm_mday -= (tm->tm_wday - weekstart); else tm->tm_mday += (weekstart - tm->tm_wday) - 7; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTLASTYEARBEGIN", 18) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_year -= 1; tm->tm_mon = 0; tm->tm_mday = 1; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTCURRYEARBEGIN", 18) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_mon = 0; tm->tm_mday = 1; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTYESTERDAY", 14) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_mday -= 1; tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTTODAY", 10) == 0) { time_t t = getcurrenttime(NULL); struct tm *tm = localtime(&t); tm->tm_hour = tm->tm_min = tm->tm_sec = 0; tm->tm_isdst = -1; t = mktime(tm); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "EVENTNOW", 8) == 0) { time_t t = getcurrenttime(NULL); fprintf(output, "%s", eventreport_timestring(t)); } else if (strncmp(t_start, "PAGEPATH_DROPDOWN", 17) == 0) { build_pagepath_dropdown(output); } else if (strncmp(t_start, "EVENTSTARTTIME", 8) == 0) { fprintf(output, "%s", hostenv_eventtimestart); } else if (strncmp(t_start, "EVENTENDTIME", 8) == 0) { fprintf(output, "%s", hostenv_eventtimeend); } else if (strncmp(t_start, "XYMONBODY", 9) == 0) { char *bodytext = xymonbody(t_start); fprintf(output, "%s", bodytext); } else if (*t_start && (savechar == ';')) { /* A "&xxx;" is probably an HTML escape - output unchanged. */ fprintf(output, "&%s", t_start); } else if (*t_start && (strncmp(t_start, "SELECT_", 7) == 0)) { /* * Special for getting the SELECTED tag into list boxes. * Cannot use xgetenv because it complains for undefined * environment variables. */ char *val = getenv(t_start); fprintf(output, "%s", (val ? val : "")); } else if (strlen(t_start) && xgetenv(t_start)) { fprintf(output, "%s", xgetenv(t_start)); } else fprintf(output, "&%s", t_start); /* No substitution - copy all unchanged. */ *t_next = savechar; t_start = t_next; t_next = strchr(t_start, '&'); } /* Remainder of file */ fprintf(output, "%s", t_start); } void headfoot(FILE *output, char *template, char *pagepath, char *head_or_foot, int bgcolor) { int fd; char filename[PATH_MAX]; SBUF_DEFINE(bulletinfile); struct stat st; char *templatedata; char *hfpath; int have_pagepath = (hostenv_pagepath != NULL); MEMDEFINE(filename); if (xgetenv("XYMONDREL") == NULL) { SBUF_DEFINE(xymondrel); SBUF_MALLOC(xymondrel, 12+strlen(VERSION)); snprintf(xymondrel, xymondrel_buflen, "XYMONDREL=%s", VERSION); putenv(xymondrel); } /* * "pagepath" is the relative path for this page, e.g. * - for the top-level page it is "" * - for a page, it is "pagename/" * - for a subpage, it is "pagename/subpagename/" * * We allow header/footer files named template_PAGE_header or template_PAGE_SUBPAGE_header * so we need to scan for an existing file - starting with the * most detailed one, and working up towards the standard "web/template_TYPE" file. */ hfpath = strdup(pagepath); /* Trim off excess trailing slashes */ if (*hfpath) { while (*(hfpath + strlen(hfpath) - 1) == '/') *(hfpath + strlen(hfpath) - 1) = '\0'; } fd = -1; if (!have_pagepath) hostenv_pagepath = strdup(hfpath); while ((fd == -1) && strlen(hfpath)) { char *p; char *elemstart; if (hostenv_templatedir) { snprintf(filename, sizeof(filename), "%s/", hostenv_templatedir); } else { snprintf(filename, sizeof(filename), "%s/web/", xgetenv("XYMONHOME")); } p = strchr(hfpath, '/'); elemstart = hfpath; while (p) { *p = '\0'; strncat(filename, elemstart, (sizeof(filename) - strlen(filename))); strncat(filename, "_", (sizeof(filename) - strlen(filename))); *p = '/'; p++; elemstart = p; p = strchr(elemstart, '/'); } strncat(filename, elemstart, (sizeof(filename) - strlen(filename))); strncat(filename, "_", (sizeof(filename) - strlen(filename))); strncat(filename, head_or_foot, (sizeof(filename) - strlen(filename))); dbgprintf("Trying header/footer file '%s'\n", filename); fd = open(filename, O_RDONLY); if (fd == -1) { p = strrchr(hfpath, '/'); if (p == NULL) p = hfpath; *p = '\0'; } } xfree(hfpath); if (fd == -1) { /* Fall back to default head/foot file. */ if (hostenv_templatedir) { snprintf(filename, sizeof(filename), "%s/%s_%s", hostenv_templatedir, template, head_or_foot); } else { snprintf(filename, sizeof(filename), "%s/web/%s_%s", xgetenv("XYMONHOME"), template, head_or_foot); } dbgprintf("Trying header/footer file '%s'\n", filename); fd = open(filename, O_RDONLY); } if (fd != -1) { int n; fstat(fd, &st); templatedata = (char *) malloc(st.st_size + 1); *templatedata = '\0'; n = read(fd, templatedata, st.st_size); if (n > 0) templatedata[n] = '\0'; close(fd); output_parsed(output, templatedata, bgcolor, getcurrenttime(NULL)); xfree(templatedata); } else { fprintf(output, " \n
\n
%s is either missing or invalid, please create this file with your custom header
\n
", htmlquoted(filename)); } /* Check for bulletin files */ SBUF_MALLOC(bulletinfile, strlen(xgetenv("XYMONHOME")) + strlen("/web/bulletin_") + strlen(head_or_foot)+1); snprintf(bulletinfile, bulletinfile_buflen, "%s/web/bulletin_%s", xgetenv("XYMONHOME"), head_or_foot); fd = open(bulletinfile, O_RDONLY); if (fd != -1) { int n; fstat(fd, &st); templatedata = (char *) malloc(st.st_size + 1); *templatedata = '\0'; n = read(fd, templatedata, st.st_size); templatedata[n] = '\0'; close(fd); output_parsed(output, templatedata, bgcolor, getcurrenttime(NULL)); xfree(templatedata); } if (!have_pagepath) { xfree(hostenv_pagepath); hostenv_pagepath = NULL; } xfree(bulletinfile); MEMUNDEFINE(filename); } void showform(FILE *output, char *headertemplate, char *formtemplate, int color, time_t seltime, char *pretext, char *posttext) { /* Present the query form */ int formfile; char formfn[PATH_MAX]; snprintf(formfn, sizeof(formfn), "%s/web/%s", xgetenv("XYMONHOME"), formtemplate); formfile = open(formfn, O_RDONLY); if (formfile >= 0) { char *inbuf; struct stat st; int n; fstat(formfile, &st); inbuf = (char *) malloc(st.st_size + 1); *inbuf = '\0'; n = read(formfile, inbuf, st.st_size); inbuf[n] = '\0'; close(formfile); if (headertemplate) headfoot(output, headertemplate, (hostenv_pagepath ? hostenv_pagepath : ""), "header", color); if (pretext) fprintf(output, "
%s
\n", pretext); output_parsed(output, inbuf, color, seltime); if (posttext) fprintf(output, "%s", posttext); if (headertemplate) headfoot(output, headertemplate, (hostenv_pagepath ? hostenv_pagepath : ""), "footer", color); xfree(inbuf); } } xymon-4.3.30/lib/test-endianness.c0000664000076400007640000000342011615341300017212 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Utility program to define endian-ness of the target system. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: test-endianness.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include int main(int argc, char **argv) { unsigned int c; unsigned char cbuf[sizeof(c)]; int i; int outform = 1; if ((argc > 1) && (strcmp(argv[1], "--configh") == 0)) outform = 0; for (i=0; (i < sizeof(c)); i++) { cbuf[i] = (i % 2); } memcpy(&c, cbuf, sizeof(c)); if (c == 65537) { /* Big endian */ if (outform == 0) printf("#ifndef XYMON_BIG_ENDIAN\n#define XYMON_BIG_ENDIAN\n#endif\n"); else printf(" -DXYMON_BIG_ENDIAN"); } else if (c == 16777472) { /* Little endian */ if (outform == 0) printf("#ifndef XYMON_LITTLE_ENDIAN\n#define XYMON_LITTLE_ENDIAN\n#endif\n"); else printf(" -DXYMON_LITTLE_ENDIAN"); } else { fprintf(stderr, "UNKNOWN ENDIANNESS! testvalue is %u\n", c); } fflush(stdout); return 0; } xymon-4.3.30/lib/msort.h0000664000076400007640000000202011615341300015252 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __MSORT_H__ #define __MSORT_H__ typedef int (msortcompare_fn_t)(void **, void **); typedef void * (msortgetnext_fn_t)(void *); typedef void (msortsetnext_fn_t)(void *, void *); extern void *msort(void *head, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext); #endif xymon-4.3.30/lib/acklog.h0000664000076400007640000000216111615341300015354 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef _ACKLOG_H_ #define _ACKLOG_H_ /* Format of records in $XYMONACKDIR/acklog file (TAB separated) */ typedef struct ack_t { time_t acktime; int acknum; int duration; /* Minutes */ int acknum2; char *ackedby; char *hostname; char *testname; int color; char *ackmsg; int ackvalid; } ack_t; extern int havedoneacklog; extern void do_acklog(FILE *output, int maxcount, int maxminutes); #endif xymon-4.3.30/lib/run.h0000664000076400007640000000155112000046362014721 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __RUN_H__ #define __RUN_H__ extern int run_command(char *cmd, char *errortext, strbuffer_t *banner, int showcmd, int timeout); #endif xymon-4.3.30/lib/crondate.h0000664000076400007640000000164611615341300015722 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CRONDATE_H__ #define __CRONDATE_H__ extern void * parse_cron_time(char * ch); extern void crondatefree(void *vcdate); extern void crongettime(void); extern int cronmatch(void *vcdate); #endif xymon-4.3.30/lib/notifylog.c0000664000076400007640000002674513515623702016151 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This displays the "notification" log. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* Host/test/color/start/end filtering code by Eric Schwimmer 2005 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: notifylog.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" typedef struct notification_t { void *host; struct htnames_t *service; time_t eventtime; char *recipient; struct notification_t *next; } notification_t; static time_t convert_time(char *timestamp) { time_t event = 0; unsigned int year,month,day,hour,min,sec,count; struct tm timeinfo; count = sscanf(timestamp, "%u/%u/%u@%u:%u:%u", &year, &month, &day, &hour, &min, &sec); if(count != 6) { return -1; } if(year < 1970) { return 0; } else { memset(&timeinfo, 0, sizeof(timeinfo)); timeinfo.tm_year = year - 1900; timeinfo.tm_mon = month - 1; timeinfo.tm_mday = day; timeinfo.tm_hour = hour; timeinfo.tm_min = min; timeinfo.tm_sec = sec; timeinfo.tm_isdst = -1; event = mktime(&timeinfo); } return event; } static htnames_t *namehead = NULL; static htnames_t *getname(char *name, int createit) { htnames_t *walk; for (walk = namehead; (walk && strcmp(walk->name, name)); walk = walk->next) ; if (walk || (!createit)) return walk; walk = (htnames_t *)malloc(sizeof(htnames_t)); walk->name = strdup(name); walk->next = namehead; namehead = walk; return walk; } void do_notifylog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pageregex, char *expageregex, char *hostregex, char *exhostregex, char *testregex, char *extestregex, char *rcptregex, char *exrcptregex) { FILE *notifylog; char notifylogfilename[PATH_MAX]; time_t firstevent = 0; time_t lastevent = getcurrenttime(NULL); notification_t *head, *walk; struct stat st; char l[MAX_LINE_LEN]; char title[200]; /* For the PCRE matching */ const char *errmsg = NULL; int errofs = 0; pcre *pageregexp = NULL; pcre *expageregexp = NULL; pcre *hostregexp = NULL; pcre *exhostregexp = NULL; pcre *testregexp = NULL; pcre *extestregexp = NULL; pcre *rcptregexp = NULL; pcre *exrcptregexp = NULL; if (maxminutes && (fromtime || totime)) { fprintf(output, "Only one time interval type is allowed!"); return; } if (fromtime) { firstevent = convert_time(fromtime); if(firstevent < 0) { fprintf(output,"Invalid 'from' time: %s", htmlquoted(fromtime)); return; } } else if (maxminutes) { firstevent = getcurrenttime(NULL) - maxminutes*60; } else { firstevent = getcurrenttime(NULL) - 86400; } if (totime) { lastevent = convert_time(totime); if (lastevent < 0) { fprintf(output,"Invalid 'to' time: %s", htmlquoted(totime)); return; } if (lastevent < firstevent) { fprintf(output,"'to' time must be after 'from' time."); return; } } if (!maxcount) maxcount = 100; if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (rcptregex && *rcptregex) rcptregexp = pcre_compile(rcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exrcptregex && *exrcptregex) exrcptregexp = pcre_compile(exrcptregex, PCRE_CASELESS, &errmsg, &errofs, NULL); snprintf(notifylogfilename, sizeof(notifylogfilename), "%s/notifications.log", xgetenv("XYMONSERVERLOGS")); notifylog = fopen(notifylogfilename, "r"); if (notifylog && (stat(notifylogfilename, &st) == 0)) { time_t curtime; int done = 0; /* Find a spot in the notification log file close to where the firstevent time is */ fseeko(notifylog, 0, SEEK_END); do { /* Go back maxcount*80 bytes - one entry is ~80 bytes */ if (ftello(notifylog) > maxcount*80) { unsigned int uicurtime; fseeko(notifylog, -maxcount*80, SEEK_CUR); if (fgets(l, sizeof(l), notifylog) && /* Skip to start of line */ fgets(l, sizeof(l), notifylog)) { /* Sun Jan 7 10:29:08 2007 myhost.disk (130.225.226.90) foo@test.com 1168162147 100 */ sscanf(l, "%*s %*s %*u %*u:%*u:%*u %*u %*s %*s %*s %u %*d", &uicurtime); curtime = uicurtime; done = (curtime < firstevent); } else { fprintf(output, "Error reading logfile %s: %s\n", notifylogfilename, strerror(errno)); return; } } else { rewind(notifylog); done = 1; } } while (!done); } head = NULL; while (notifylog && (fgets(l, sizeof(l), notifylog))) { unsigned int etim; time_t eventtime; char hostsvc[MAX_LINE_LEN]; char recipient[MAX_LINE_LEN]; char *hostname, *svcname, *p; int itemsfound, pagematch, hostmatch, testmatch, rcptmatch; notification_t *newrec; void *eventhost; struct htnames_t *eventcolumn; int ovector[30]; itemsfound = sscanf(l, "%*s %*s %*u %*u:%*u:%*u %*u %s %*s %s %u %*d", hostsvc, recipient, &etim); eventtime = etim; if (itemsfound != 3) continue; if (eventtime < firstevent) continue; if (eventtime > lastevent) break; hostname = hostsvc; svcname = strrchr(hostsvc, '.'); if (svcname) { *svcname = '\0'; svcname++; } else svcname = ""; eventhost = hostinfo(hostname); if (!eventhost) continue; /* Don't report hosts that no longer exist */ eventcolumn = getname(svcname, 1); p = strchr(recipient, '['); if (p) *p = '\0'; if (pageregexp) { char *pagename; pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 1; if (!pagematch) continue; if (expageregexp) { char *pagename; pagename = xmh_item_multi(eventhost, XMH_PAGEPATH); pagematch = 0; while (!pagematch && pagename) { pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); pagename = xmh_item_multi(NULL, XMH_PAGEPATH); } } else pagematch = 0; if (pagematch) continue; if (hostregexp) hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 1; if (!hostmatch) continue; if (exhostregexp) hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else hostmatch = 0; if (hostmatch) continue; if (testregexp) testmatch = (pcre_exec(testregexp, NULL, svcname, strlen(svcname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 1; if (!testmatch) continue; if (extestregexp) testmatch = (pcre_exec(extestregexp, NULL, svcname, strlen(svcname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else testmatch = 0; if (testmatch) continue; if (rcptregexp) rcptmatch = (pcre_exec(rcptregexp, NULL, recipient, strlen(recipient), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else rcptmatch = 1; if (!rcptmatch) continue; if (exrcptregexp) rcptmatch = (pcre_exec(exrcptregexp, NULL, recipient, strlen(recipient), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); else rcptmatch = 0; if (rcptmatch) continue; newrec = (notification_t *) malloc(sizeof(notification_t)); newrec->host = eventhost; newrec->service = eventcolumn; newrec->eventtime = eventtime; newrec->recipient = strdup(recipient); newrec->next = head; head = newrec; } if (head) { char *bgcolors[2] = { "#000000", "#000066" }; int bgcolor = 0; int count; struct notification_t *lasttoshow = head; count=0; walk=head; do { count++; lasttoshow = walk; walk = walk->next; } while (walk && (counteventtime) / 60)); } else { snprintf(title, sizeof(title), "%d notifications sent.", count); } fprintf(output, "

\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); fprintf(output, "\n"); for (walk=head; (walk != lasttoshow->next); walk=walk->next) { char *hostname = xmh_item(walk->host, XMH_HOSTNAME); fprintf(output, "\n", bgcolors[bgcolor]); bgcolor = ((bgcolor + 1) % 2); fprintf(output, "\n", ctime(&walk->eventtime)); fprintf(output, "\n", hostname); fprintf(output, "\n", walk->service->name); fprintf(output, "\n", walk->recipient); } fprintf(output, "
%s
TimeHostServiceRecipient
%s%s%s%s
\n"); /* Clean up */ walk = head; do { struct notification_t *tmp = walk; walk = walk->next; xfree(tmp->recipient); xfree(tmp); } while (walk); } else { /* No notifications during the past maxminutes */ if (notifylog) snprintf(title, sizeof(title), "No notifications sent in the last %d minutes", maxminutes); else strncpy(title, "No notifications logged", sizeof(title)); fprintf(output, "

\n"); fprintf(output, "\n", title); fprintf(output, "\n"); fprintf(output, "\n", htmlquoted(title)); fprintf(output, "\n"); fprintf(output, "
%s
\n"); fprintf(output, "
\n"); } if (notifylog) fclose(notifylog); if (pageregexp) pcre_free(pageregexp); if (expageregexp) pcre_free(expageregexp); if (hostregexp) pcre_free(hostregexp); if (exhostregexp) pcre_free(exhostregexp); if (testregexp) pcre_free(testregexp); if (extestregexp) pcre_free(extestregexp); if (rcptregexp) pcre_free(rcptregexp); if (exrcptregexp) pcre_free(exrcptregexp); } xymon-4.3.30/lib/stackio.c0000664000076400007640000004016413532325276015567 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for reading configuration files with "include"s. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: stackio.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include #include "libxymon.h" typedef struct filelist_t { char *filename; time_t mtime; size_t fsize; struct filelist_t *next; } filelist_t; typedef struct fgetsbuf_t { FILE *fd; char inbuf[4096+1]; char *inbufp; int moretoread; struct fgetsbuf_t *next; } fgetsbuf_t; static fgetsbuf_t *fgetshead = NULL; typedef struct stackfd_t { FILE *fd; filelist_t **listhead; struct stackfd_t *next; } stackfd_t; static stackfd_t *fdhead = NULL; static char *stackfd_base = NULL; static char *stackfd_mode = NULL; static htnames_t *fnlist = NULL; /* * initfgets() and unlimfgets() implements a fgets() style * input routine that can handle arbitrarily long input lines. * Buffer space for the input is dynamically allocated and * expanded, until the input hits a newline character. * Simultaneously, lines ending with a '\' character are * merged into one line, allowing for transparent handling * of very long lines. * * This interface is also used by the stackfgets() routine. * * If you open a file directly, after getting the FILE * descriptor call initfgets(FILE). Then use unlimfgets() * to read data one line at a time. You must read until * unlimfgets() returns NULL (at which point you should not * call unlimfgets() again with this fd). */ int initfgets(FILE *fd) { fgetsbuf_t *newitem; newitem = (fgetsbuf_t *)malloc(sizeof(fgetsbuf_t)); *(newitem->inbuf) = '\0'; newitem->inbufp = newitem->inbuf; newitem->moretoread = 1; newitem->fd = fd; newitem->next = fgetshead; fgetshead = newitem; return 0; } char *unlimfgets(strbuffer_t *buffer, FILE *fd) { fgetsbuf_t *fg; size_t n; char *eoln = NULL; for (fg = fgetshead; (fg && (fg->fd != fd)); fg = fg->next) ; if (!fg) { errprintf("umlimfgets() called with bad input FD\n"); return NULL; } /* End of file ? */ if (!(fg->moretoread) && (*(fg->inbufp) == '\0')) { if (fg == fgetshead) { fgetshead = fgetshead->next; free(fg); } else { fgetsbuf_t *prev; for (prev = fgetshead; (prev->next != fg); prev = prev->next) ; prev->next = fg->next; free(fg); } return NULL; } /* Make sure the output buffer is empty */ clearstrbuffer(buffer); while (!eoln && (fg->moretoread || *(fg->inbufp))) { int continued = 0; if (*(fg->inbufp)) { /* Have some data in the buffer */ eoln = strchr(fg->inbufp, '\n'); if (eoln) { /* See if there's a continuation character just before the eoln */ char *contchar = eoln-1; while ((contchar > fg->inbufp) && isspace((int)*contchar) && (*contchar != '\\')) contchar--; continued = (*contchar == '\\'); if (continued) { *contchar = '\0'; addtobuffer(buffer, fg->inbufp); fg->inbufp = eoln+1; eoln = NULL; } else { char savech = *(eoln+1); *(eoln+1) = '\0'; addtobuffer(buffer, fg->inbufp); *(eoln+1) = savech; fg->inbufp = eoln+1; } } else { /* No newline in buffer, so add all of it to the output buffer */ addtobuffer(buffer, fg->inbufp); /* Input buffer is now empty */ *(fg->inbuf) = '\0'; fg->inbufp = fg->inbuf; } } if (!eoln && !continued) { /* Get data for the input buffer */ char *inpos = fg->inbuf; size_t insize = sizeof(fg->inbuf); /* If the last byte we read was a continuation char, we must do special stuff. * * Mike Romaniw discovered that if we hit an input with a newline exactly at * the point of a buffer refill, then strlen(*buffer) is 0, and contchar then * points before the start of the buffer. Bad. But this can only happen when * the previous char WAS a newline, and hence it is not a continuation line. * So the simple fix is to only do the cont-char stuff if **buffer is not NUL. * Hence the test for both *buffer and **buffer. */ if (STRBUF(buffer) && *STRBUF(buffer)) { char *contchar = STRBUF(buffer) + STRBUFLEN(buffer) - 1; while ((contchar > STRBUF(buffer)) && isspace((int)*contchar) && (*contchar != '\\')) contchar--; if (*contchar == '\\') { /* * Remove the cont. char from the output buffer, and stuff it into * the input buffer again - so we can check if there's a new-line coming. */ strbufferchop(buffer, 1); *(fg->inbuf) = '\\'; inpos++; insize--; } } n = fread(inpos, 1, insize-1, fd); *(inpos + n) = '\0'; fg->inbufp = fg->inbuf; if (n < insize-1) fg->moretoread = 0; } } return STRBUF(buffer); } FILE *stackfopen(char *filename, char *mode, void **v_listhead) { FILE *newfd; stackfd_t *newitem; char stackfd_filename[PATH_MAX]; filelist_t **listhead = (filelist_t **)v_listhead; MEMDEFINE(stackfd_filename); if (fdhead == NULL) { char *p; stackfd_base = strdup(filename); p = strrchr(stackfd_base, '/'); if (p) *(p+1) = '\0'; stackfd_mode = strdup(mode); strncpy(stackfd_filename, filename, sizeof(stackfd_filename)); } else { if (*filename == '/') strncpy(stackfd_filename, filename, sizeof(stackfd_filename)); else snprintf(stackfd_filename, sizeof(stackfd_filename), "%s/%s", stackfd_base, filename); } dbgprintf("Opening file %s\n", stackfd_filename); newfd = fopen(stackfd_filename, stackfd_mode); if (newfd != NULL) { newitem = (stackfd_t *) malloc(sizeof(stackfd_t)); newitem->fd = newfd; newitem->listhead = listhead; newitem->next = fdhead; fdhead = newitem; initfgets(newfd); if (listhead) { struct filelist_t *newlistitem; struct stat st; fstat(fileno(newfd), &st); newlistitem = (filelist_t *)malloc(sizeof(filelist_t)); newlistitem->filename = strdup(stackfd_filename); newlistitem->mtime = st.st_mtime; newlistitem->fsize = st.st_size; newlistitem->next = *listhead; *listhead = newlistitem; } } MEMUNDEFINE(stackfd_filename); return newfd; } int stackfclose(FILE *fd) { int result; stackfd_t *olditem; if (fd != NULL) { /* Close all */ while (fdhead != NULL) { olditem = fdhead; fdhead = fdhead->next; fclose(olditem->fd); xfree(olditem); } xfree(stackfd_base); xfree(stackfd_mode); while (fnlist) { htnames_t *tmp = fnlist; fnlist = fnlist->next; xfree(tmp->name); xfree(tmp); } result = 0; } else { olditem = fdhead; fdhead = fdhead->next; result = fclose(olditem->fd); xfree(olditem); } return result; } int stackfmodified(void *v_listhead) { /* Walk the list of filenames, and see if any have changed */ filelist_t *walk; struct stat st; for (walk=(filelist_t *)v_listhead; (walk); walk = walk->next) { if (stat(walk->filename, &st) == -1) { dbgprintf("File %s no longer exists\n", walk->filename); return 1; /* File has disappeared */ } if (st.st_mtime != walk->mtime) { dbgprintf("File %s new timestamp\n", walk->filename); return 1; /* Timestamp has changed */ } if (S_ISREG(st.st_mode) && (st.st_size != walk->fsize)) { dbgprintf("File %s new size\n", walk->filename); return 1; /* Size has changed */ } } return 0; } void stackfclist(void **v_listhead) { /* Free the list of filenames */ filelist_t *tmp; if ((v_listhead == NULL) || (*v_listhead == NULL)) return; while (*v_listhead) { tmp = (filelist_t *) *v_listhead; *v_listhead = ((filelist_t *) *v_listhead)->next; xfree(tmp->filename); xfree(tmp); } *v_listhead = NULL; } static int namecompare(const void *v1, const void *v2) { char **n1 = (char **)v1; char **n2 = (char **)v2; /* Sort in reverse order, so when we add them to the list in LIFO, it will be alpha-sorted */ return -strcmp(*n1, *n2); } static void addtofnlist(char *dirname, int is_optional, void **v_listhead) { filelist_t **listhead = (filelist_t **)v_listhead; DIR *dirfd; struct dirent *d; struct stat st; char dirfn[PATH_MAX], fn[PATH_MAX]; char **fnames = NULL; int fnsz = 0; int i; if (*dirname == '/') strncpy(dirfn, dirname, sizeof(dirfn)); else snprintf(dirfn, sizeof(dirfn), "%s/%s", stackfd_base, dirname); if ((dirfd = opendir(dirfn)) == NULL) { if (!is_optional) errprintf("WARNING: Cannot open directory %s\n", dirfn); else dbgprintf("addtofnlist(): Cannot open directory %s\n", dirfn); return; } /* Add the directory itself to the list of files we watch for modifications */ if (listhead) { filelist_t *newlistitem; stat(dirfn, &st); newlistitem = (filelist_t *)malloc(sizeof(filelist_t)); newlistitem->filename = strdup(dirfn); newlistitem->mtime = st.st_mtime; newlistitem->fsize = 0; /* We don't check sizes of directories */ newlistitem->next = *listhead; *listhead = newlistitem; } while ((d = readdir(dirfd)) != NULL) { int fnlen = strlen(d->d_name); /* Skip all dot-files */ if (*(d->d_name) == '.') continue; /* Skip editor backups - file ending with '~' */ if (*(d->d_name + fnlen - 1) == '~') continue; /* Skip RCS files - they end with ",v" */ if ((fnlen >= 2) && (strcmp(d->d_name + fnlen - 2, ",v") == 0)) continue; /* Skip any documentation file starting with README */ if (strncmp(d->d_name, "README", 6) == 0) continue; /* Skip Debian installer left-overs - they end with ".dpkg-new" or .dpkg-orig */ if ((fnlen >= 9) && (strcmp(d->d_name + fnlen - 9, ".dpkg-new") == 0)) continue; if ((fnlen >= 10) && (strcmp(d->d_name + fnlen - 10, ".dpkg-orig") == 0)) continue; /* Skip RPM package debris - they end with ".rpmsave", .rpmnew, or .rpmorig */ if ((fnlen >= 8) && ((strcmp(d->d_name + fnlen - 8, ".rpmsave") == 0) || (strcmp(d->d_name + fnlen - 8, ".rpmorig") == 0) ) ) continue; if ((fnlen >= 7) && (strcmp(d->d_name + fnlen - 7, ".rpmnew") == 0)) continue; #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ snprintf(fn, sizeof(fn), "%s/%s", dirfn, d->d_name); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ if (stat(fn, &st) == -1) continue; if (S_ISDIR(st.st_mode)) { /* Skip RCS sub-directories */ if (strcmp(d->d_name, "RCS") == 0) continue; addtofnlist(fn, 0, v_listhead); /* this directory is optional, but opening up files that do exist isn't */ } /* Skip everything that isn't a regular file */ if (!S_ISREG(st.st_mode)) continue; if (fnsz == 0) fnames = (char **)malloc(2*sizeof(char **)); else fnames = (char **)realloc(fnames, (fnsz+2)*sizeof(char **)); fnames[fnsz] = strdup(fn); fnsz++; } closedir(dirfd); if (fnsz) { qsort(fnames, fnsz, sizeof(char *), namecompare); for (i=0; (iname = fnames[i]; newitem->next = fnlist; fnlist = newitem; } xfree(fnames); } } char *stackfgets(strbuffer_t *buffer, char *extraincl) { char *result; int optional = 0; result = unlimfgets(buffer, fdhead->fd); if (result) { char *bufpastwhitespace = STRBUF(buffer) + strspn(STRBUF(buffer), " \t"); if (strncmp(bufpastwhitespace, "optional", 8) == 0) { optional = 1; bufpastwhitespace += 8 + strspn(bufpastwhitespace+8, " \t"); } if ( (strncmp(bufpastwhitespace, "include ", 8) == 0) || (strncmp(bufpastwhitespace, "include\t", 8) == 0) || (extraincl && (strncmp(bufpastwhitespace, extraincl, strlen(extraincl)) == 0)) ) { char *newfn, *eol, eolchar = '\0'; eol = bufpastwhitespace + strcspn(bufpastwhitespace, "\r\n"); if (eol) { eolchar = *eol; *eol = '\0'; } newfn = bufpastwhitespace + strcspn(bufpastwhitespace, " \t"); newfn += strspn(newfn, " \t"); while (*newfn && isspace(*(newfn + strlen(newfn) - 1))) *(newfn + strlen(newfn) -1) = '\0'; if (*newfn && (stackfopen(newfn, "r", (void **)fdhead->listhead) != NULL)) return stackfgets(buffer, extraincl); else { if (!optional) errprintf("WARNING: Cannot open include file '%s', line was: %s\n", newfn, STRBUF(buffer)); else dbgprintf("stackfgets(): Cannot open include file '%s', line was: %s\n", newfn, STRBUF(buffer)); if (eol) *eol = eolchar; return result; } } else if ((strncmp(bufpastwhitespace, "directory ", 10) == 0) || (strncmp(bufpastwhitespace, "directory\t", 10) == 0)) { char *dirfn, *eol, eolchar = '\0'; eol = bufpastwhitespace + strcspn(bufpastwhitespace, "\r\n"); if (eol) { eolchar = *eol; *eol = '\0'; } dirfn = bufpastwhitespace + 9; dirfn += strspn(dirfn, " \t"); while (*dirfn && isspace(*(dirfn + strlen(dirfn) - 1))) *(dirfn + strlen(dirfn) -1) = '\0'; if (*dirfn) addtofnlist(dirfn, optional, (void **)fdhead->listhead); if (fnlist && (stackfopen(fnlist->name, "r", (void **)fdhead->listhead) != NULL)) { htnames_t *tmp = fnlist; fnlist = fnlist->next; xfree(tmp->name); xfree(tmp); return stackfgets(buffer, extraincl); } else if (fnlist) { htnames_t *tmp = fnlist; if (!optional) errprintf("WARNING: Cannot open include file '%s', line was: %s\n", fnlist->name, buffer); else dbgprintf("stackfgets(): Cannot open include file '%s', line was: %s\n", fnlist->name, buffer); fnlist = fnlist->next; xfree(tmp->name); xfree(tmp); if (eol) *eol = eolchar; return result; } else { /* Empty directory include - return a blank line */ dbgprintf("stackfgets(): Directory %s was empty\n", dirfn); *result = '\0'; return result; } } } else if (result == NULL) { /* end-of-file on read */ stackfclose(NULL); if (fnlist) { if (stackfopen(fnlist->name, "r", (void **)fdhead->listhead) != NULL) { htnames_t *tmp = fnlist; fnlist = fnlist->next; xfree(tmp->name); xfree(tmp); return stackfgets(buffer, extraincl); } else { htnames_t *tmp = fnlist; if (!optional) errprintf("WARNING: Cannot open include file '%s', line was: %s\n", fnlist->name, buffer); else dbgprintf("stackfgets(): Cannot open include file '%s', line was: %s\n", fnlist->name, buffer); fnlist = fnlist->next; xfree(tmp->name); xfree(tmp); return result; } } else if (fdhead != NULL) return stackfgets(buffer, extraincl); else return NULL; } return result; } #ifdef STANDALONE int main(int argc, char *argv[]) { char *fn, *p; char cmd[1024]; FILE *fd; strbuffer_t *inbuf = newstrbuffer(0); void *listhead = NULL; int done, linenum; fn = strdup(argv[1]); strncpy(cmd, "!", sizeof(cmd)); done = 0; while (!done) { if (*cmd == '!') { fd = stackfopen(fn, "r", &listhead); linenum = 1; if (!fd) { errprintf("Cannot open file %s\n", fn); continue; } while (stackfgets(inbuf, NULL)) { linenum++; printf("%s", STRBUF(inbuf)); } stackfclose(fd); } else if (*cmd == '?') { filelist_t *walk = (filelist_t *)listhead; while (walk) { printf("%s %lu\n", walk->filename, (unsigned long)walk->fsize); walk = walk->next; } if (stackfmodified(listhead)) printf("File(s) have been modified\n"); else printf("No changes\n"); } else if (*cmd == '.') { done = 1; continue; } else { xfree(fn); fn = strdup(cmd); stackfclist(&listhead); strncpy(cmd, "!", sizeof(cmd)); continue; } printf("\nCmd: "); fflush(stdout); if (fgets(cmd, sizeof(cmd), stdin)) { p = strchr(cmd, '\n'); if (p) *p = '\0'; } else done = 1; } xfree(fn); stackfclist(&listhead); return 0; } #endif xymon-4.3.30/lib/htmllog.h0000664000076400007640000000331111615341300015560 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HTMLLOG_H__ #define __HTMLLOG_H__ #include enum histbutton_t { HIST_TOP, HIST_BOTTOM, HIST_NONE }; extern enum histbutton_t histlocation; extern void generate_html_log(char *hostname, char *displayname, char *service, char *ip, int color, int flapping, char *sender, char *flags, time_t logtime, char *timesincechange, char *firstline, char *restofmsg, char *modifiers, time_t acktime, char *ackmsg, char *acklist, time_t disabletime, char *dismsg, int is_history, int wantserviceid, int htmlfmt, int locatorbased, char *multigraphs, char *linktoclient, char *nkprio, char *nkttgroup, char *nkttextra, int graphtime, FILE *output); extern char *alttag(char *columnname, int color, int acked, int propagate, char *age); extern void setdocurl(char *url); extern void setdoctarget(char *target); extern char *hostnamehtml(char *hostname, char *defaultlink, int usetooltip); #endif xymon-4.3.30/lib/xymonrrd.h0000664000076400007640000000350611630612042016003 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __XYMONRRD_H__ #define __XYMONRRD_H__ #include /* This is for mapping a service -> an RRD file */ typedef struct { char *svcname; char *xymonrrdname; } xymonrrd_t; /* This is for displaying an RRD file. */ typedef struct { char *xymonrrdname; char *xymonpartname; int maxgraphs; } xymongraph_t; typedef enum { HG_WITHOUT_STALE_RRDS, HG_WITH_STALE_RRDS } hg_stale_rrds_t; typedef enum { HG_PLAIN_LINK, HG_META_LINK } hg_link_t; typedef struct rrdtpldata_t { char *template; void *dsnames; /* Tree of tplnames_t records */ } rrdtpldata_t; typedef struct rrdtplnames_t { char *dsnam; int idx; } rrdtplnames_t; extern xymonrrd_t *xymonrrds; extern xymongraph_t *xymongraphs; extern xymonrrd_t *find_xymon_rrd(char *service, char *flags); extern xymongraph_t *find_xymon_graph(char *rrdname); extern char *xymon_graph_data(char *hostname, char *dispname, char *service, int bgcolor, xymongraph_t *graphdef, int itemcount, hg_stale_rrds_t nostale, hg_link_t wantmeta, int locatorbased, time_t starttime, time_t endtime); extern rrdtpldata_t *setup_template(char *params[]); #endif xymon-4.3.30/lib/cgi.c0000664000076400007640000002467713211516034014673 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for handling CGI requests. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: cgi.c 8015 2017-12-05 13:16:12Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" #define MAX_REQ_SIZE (1024*1024) enum cgi_method_t cgi_method = CGI_OTHER; static char *cgi_error_text = NULL; static void lcgi_error(char *msg) { cgi_error_text = msg; } char *cgi_error(void) { char *result = cgi_error_text; cgi_error_text = NULL; return result; } int cgi_ispost() { char *method = getenv("REQUEST_METHOD"); if (method && (strcasecmp(method, "POST") == 0)) { cgi_method = CGI_POST; /* might as well set here */ return 1; } return 0; } cgidata_t *cgi_request(void) { char *method = NULL; char *reqdata = NULL; char *conttype = NULL; char *token; cgidata_t *head = NULL, *tail = NULL; cgi_error_text = NULL; cgi_method = CGI_OTHER; method = getenv("REQUEST_METHOD"); if (!method) { lcgi_error("CGI violation - no REQUEST_METHOD\n"); return NULL; } conttype = getenv("CONTENT_TYPE"); if (strcasecmp(method, "POST") == 0) { char *contlen = getenv("CONTENT_LENGTH"); int postsize = 0; cgi_method = CGI_POST; if (contlen) { postsize = atoi(contlen); } else { lcgi_error("CGI violation - no CONTENT_LENGTH\n"); return NULL; } if (postsize < MAX_REQ_SIZE) { size_t n; reqdata = (char *)malloc(postsize+1); n = fread(reqdata, 1, postsize, stdin); if (n < postsize) { lcgi_error("Error reading POST data\n"); return NULL; } reqdata[n] = '\0'; } else { lcgi_error("Request too large\n"); return NULL; } } else if (strcasecmp(method, "GET") == 0) { char *q = getenv("QUERY_STRING"); cgi_method = CGI_GET; if (q) { if (strlen(q) < MAX_REQ_SIZE) { reqdata = strdup(q); } else { lcgi_error("Request too large\n"); return NULL; } } else { /* This is OK - we may not have any query */ return NULL; } } dbgprintf("CGI: Request method='%s', data='%s'\n", method, textornull(reqdata)); if ((cgi_method == CGI_GET) || (conttype && (strcasecmp(conttype, "application/x-www-form-urlencoded") == 0))) { token = strtok(reqdata, "&"); while (token) { cgidata_t *newitem = (cgidata_t *)calloc(1, sizeof(cgidata_t)); char *val; val = strchr(token, '='); if (val) { *val = '\0'; val = urlunescape(val+1); } newitem->name = strdup(token); newitem->value = strdup(val ? val : ""); if (!tail) { head = newitem; } else { tail->next = newitem; } tail = newitem; token = strtok(NULL, "&"); } } else if ((cgi_method == CGI_POST) && (conttype && (strcasecmp(conttype, "multipart/form-data") == 0))) { char *bol, *eoln, *delim; char eolnchar = '\n'; char *currelembegin = NULL, *currelemend = NULL; cgidata_t *newitem = NULL; delim = reqdata; eoln = strchr(delim, '\n'); if (!eoln) return NULL; *eoln = '\0'; delim = strdup(reqdata); *eoln = '\n'; if (*(delim + strlen(delim) - 1) == '\r') { eolnchar = '\r'; *(delim + strlen(delim) - 1) = '\0'; } bol = reqdata; do { eoln = strchr(bol, eolnchar); if (eoln) *eoln = '\0'; if (strncmp(bol, delim, strlen(delim)) == 0) { if (newitem && currelembegin && (currelemend >= currelembegin)) { /* Finish off the current item */ char savech; savech = *currelemend; *currelemend = '\0'; newitem->value = strdup(currelembegin); *currelemend = savech; currelembegin = currelemend = NULL; } if (strcmp(bol+strlen(delim), "--") != 0) { /* New element */ newitem = (cgidata_t *)calloc(1, sizeof(cgidata_t)); if (!tail) head = newitem; else tail->next = newitem; tail = newitem; } else { /* No more elements, end of input */ newitem = NULL; bol = NULL; continue; } } else if (newitem && (strncasecmp(bol, "Content-Disposition:", 20) == 0)) { char *tok; tok = strtok(bol, ";\t "); while (tok) { if (strncasecmp(tok, "name=", 5) == 0) { char *name; name = tok+5; if (*name == '\"') { name++; *(name + strlen(name) - 1) = '\0'; } newitem->name = strdup(name); } else if (strncasecmp(tok, "filename=", 9) == 0) { char *filename; filename = tok+9; if (*filename == '\"') { filename++; *(filename + strlen(filename) - 1) = '\0'; } newitem->filename = strdup(filename); } tok = strtok(NULL, ";\t "); } } else if (newitem && (strncasecmp(bol, "Content-Type:", 12) == 0)) { } else if (newitem && !currelembegin && (*bol == '\0')) { /* End of headers for one element */ if (eoln) { currelembegin = eoln+1; if ((eolnchar == '\r') && (*currelembegin == '\n')) currelembegin++; } currelemend = currelembegin; } else if (newitem && currelembegin) { currelemend = (eoln ? eoln+1 : bol + strlen(bol)); } if (eoln) { bol = eoln+1; if ((eolnchar == '\r') && (*bol == '\n')) bol++; } else { bol = NULL; } } while (bol && (*bol)); if (newitem) { if (!newitem->name) newitem->name = ""; if (!newitem->value) newitem->value = ""; } } else { /* Raw data - return a single record to caller */ head = (cgidata_t *)calloc(1, sizeof(cgidata_t)); head->name = strdup(""); head->value = reqdata ? strdup(reqdata) : NULL; } if (reqdata) xfree(reqdata); return head; } char *csp_header(const char *str) { char *csppol = NULL; char *returnstr = NULL; if (getenv("XYMON_NOCSPHEADER")) return NULL; if (strncmp(str, "enadis", 6) == 0) csppol = strdup("script-src 'self' 'unsafe-inline'; connect-src 'self'; form-action 'self'; sandbox allow-forms allow-scripts allow-same-origin allow-modals allow-popups;"); else if (strncmp(str, "useradm", 7) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "chpasswd", 8) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "ackinfo", 7) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "acknowledge", 11) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "criticaleditor", 14) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self';"); else if (strncmp(str, "svcstatus-trends", 16) == 0) csppol = strdup("script-src 'self' 'unsafe-inline'; connect-src 'self'; form-action 'self'; sandbox allow-forms allow-scripts allow-same-origin;"); else if (strncmp(str, "svcstatus-info", 14) == 0) csppol = strdup("script-src 'self' 'unsafe-inline'; connect-src 'self'; form-action 'self'; sandbox allow-forms allow-same-origin allow-scripts allow-modals allow-popups;"); else if (strncmp(str, "svcstatus", 9) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self'; sandbox allow-forms allow-same-origin;"); else if (strncmp(str, "historylog", 10) == 0) csppol = strdup("script-src 'self'; connect-src 'self'; form-action 'self'; sandbox allow-forms;"); else { errprintf(" csp_header: page %s not listed, no CSP returned\n", str); } if ((!csppol) || (*csppol == '\0')) return NULL; returnstr = (char *)malloc(3 * strlen(csppol) + 512); snprintf(returnstr, (3 * strlen(csppol) + 512), "Content-Security-Policy: %s\nX-Content-Security-Policy: %s\nX-Webkit-CSP: %s\n", csppol, csppol, csppol); dbgprintf("CSP return is %s", returnstr); return returnstr; } int cgi_refererok(char *expected) { static char cgi_checkstr[1024]; int isok = 0; char *p, *httphost; p = getenv("HTTP_REFERER"); dbgprintf(" - checking if referer is OK (http_referer: %s, http_host: %s, xymonwebhost: %s, checkstr: %s\n", textornull(p), textornull(getenv("HTTP_HOST")), textornull(xgetenv("XYMONWEBHOST")), textornull(expected)); if (!p) return 0; /* If passed NULL, just check that there _is_ a REFERER */ if (!expected) return 1; httphost = getenv("HTTP_HOST"); if (!httphost) { if (strcmp(xgetenv("XYMONWEBHOST"), "http://localhost") != 0) { /* If XYMONWEBHOST is set by the admin, use that */ snprintf(cgi_checkstr, sizeof(cgi_checkstr), "%s%s", getenv("XYMONWEBHOST"), expected); if (strncmp(p, cgi_checkstr, strlen(cgi_checkstr)) == 0) isok = 1; } else { errprintf("Disallowed request due to missing HTTP_HOST variable\n"); return 0; } } else { /* skip the protocol specifier, which HTTP_REFERER has but HTTP_HOST doesn't */ p += (strncasecmp(p, "https://", 8) == 0) ? 8 : (strncasecmp(p, "http://", 7) == 0) ? 7 : 0; if (*p == '\0') { errprintf("Disallowed request due to unexpected referer '%s'\n", getenv("HTTP_REFERER")); return 0; } snprintf(cgi_checkstr, sizeof(cgi_checkstr), "%s%s", httphost, expected); if (strncmp(p, cgi_checkstr, strlen(cgi_checkstr)) == 0) isok = 1; } if (!isok) dbgprintf("Disallowed request due to unexpected referer '%s', wanted '%s' (originally '%s')\n", p, cgi_checkstr, expected); return isok; } char *get_cookie(char *cookiename) { static char *ckdata = NULL; char *tok, *p; int n; /* If no cookie, just return NULL */ p = getenv("HTTP_COOKIE"); if (!p) return NULL; if (ckdata) xfree(ckdata); n = strlen(cookiename); /* Split the cookie variable into elements, separated by ";" and possible space. */ ckdata = strdup(p); tok = strtok(ckdata, "; "); while (tok) { if ((strncmp(cookiename, tok, n) == 0) && (*(tok+n) == '=')) { /* Got it */ return (tok+n+1); } tok = strtok(NULL, "; "); } xfree(ckdata); ckdata = NULL; return NULL; } xymon-4.3.30/lib/sig.c0000664000076400007640000000763613515623702014717 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for handling of signals and crashes. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: sig.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" /* Data used while crashing - cannot depend on the stack being usable */ static char signal_xymoncmd[PATH_MAX]; static char signal_xymondserver[1024]; static char signal_msg[1024]; static char signal_tmpdir[PATH_MAX]; static void sigsegv_handler(int signum) { /* * This is a signal handler. Only a very limited number of * library routines can be safely used here, according to * Posix: http://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_04.html#tag_02_04_03 * Do not use string, stdio etc. - just basic system calls. * That is why we need to setup all of the strings in advance. */ signal(signum, SIG_DFL); /* * Try to fork a child to send in an alarm message. * If the fork fails, then just attempt to exec() the XYMON command */ if (fork() <= 0) { execl(signal_xymoncmd, "xymon-signal", signal_xymondserver, signal_msg, NULL); } /* Dump core and abort */ if (chdir(signal_tmpdir) == 0) {}; /* Cannot chdir? Well, abort anyway */ abort(); } static void sigusr2_handler(int signum) { /* SIGUSR2 toggles debugging */ if (debug) { dbgprintf("Debug OFF\n"); debug = 0; } else { debug = 1; dbgprintf("Debug ON\n"); } } void setup_signalhandler(char *programname) { struct rlimit lim; struct sigaction sa; MEMDEFINE(signal_xymoncmd); MEMDEFINE(signal_xymondserver); MEMDEFINE(signal_tmpdir); MEMDEFINE(signal_msg); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigsegv_handler; /* * Try to allow ourselves to generate core files */ getrlimit(RLIMIT_CORE, &lim); lim.rlim_cur = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &lim); if (xgetenv("XYMON") == NULL) return; if (xgetenv("XYMSRV") == NULL) return; /* * Used inside signal-handler. Must be setup in * advance. */ strncpy(signal_xymoncmd, xgetenv("XYMON"), sizeof(signal_xymoncmd)); strncpy(signal_xymondserver, xgetenv("XYMSRV"), sizeof(signal_xymondserver)); strncpy(signal_tmpdir, xgetenv("XYMONTMP"), sizeof(signal_tmpdir)); snprintf(signal_msg, sizeof(signal_msg), "status %s.%s red - Program crashed\n\nFatal signal caught!\n", (xgetenv("MACHINE") ? xgetenv("MACHINE") : "XYMSERVERS"), programname); sigaction(SIGSEGV, &sa, NULL); sigaction(SIGILL, &sa, NULL); #ifdef SIGBUS sigaction(SIGBUS, &sa, NULL); #endif /* * After lengthy debugging and perusing of mail archives: * Need to ignore SIGPIPE since FreeBSD (and others?) can throw this * on a write() instead of simply returning -EPIPE like any sane * OS would. */ signal(SIGPIPE, SIG_IGN); /* Ignore SIGUSR1 unless explicitly set by main program */ signal (SIGUSR1, SIG_IGN); /* SIGUSR2 toggles debugging */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigusr2_handler; sigaction(SIGUSR2, &sa, NULL); } xymon-4.3.30/lib/errormsg.c0000664000076400007640000001125013515623702015760 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for error- and debug-message display. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: errormsg.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" SBUF_DEFINE(errbuf); static char msg[4096]; static char timestr[20]; static size_t timesize = sizeof(timestr); static struct timeval now; static time_t then = 0; int save_errbuf = 1; static char *errappname = NULL; int debug = 0; static FILE *tracefd = NULL; static FILE *debugfd = NULL; void errprintf(const char *fmt, ...) { va_list args; gettimeofday(&now, NULL); if (now.tv_sec != then) { strftime(timestr, timesize, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec)); then = now.tv_sec; } fprintf(stderr, "%s.%06d ", timestr, (int) now.tv_usec); if (errappname) fprintf(stderr, "%s ", errappname); va_start(args, fmt); vsnprintf(msg, sizeof(msg), fmt, args); va_end(args); fprintf(stderr, "%s", msg); fflush(stderr); if (save_errbuf) { if (errbuf == NULL) { SBUF_MALLOC(errbuf, 8192); *errbuf = '\0'; } else if ((strlen(errbuf) + strlen(msg)) > errbuf_buflen) { SBUF_REALLOC(errbuf, errbuf_buflen+8192); } strncat(errbuf, msg, (errbuf_buflen - strlen(errbuf))); } } void real_dbgprintf(const char *fmt, ...) { va_list args; gettimeofday(&now, NULL); if (!debugfd) debugfd = stdout; if (now.tv_sec != then) { strftime(timestr, timesize, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec)); then = now.tv_sec; } fprintf(debugfd, "%lu %s.%06d ", (unsigned long)getpid(), timestr, (int) now.tv_usec); va_start(args, fmt); vfprintf(debugfd, fmt, args); va_end(args); fflush(debugfd); } void flush_errbuf(void) { if (errbuf) xfree(errbuf); errbuf = NULL; } void set_debugfile(char *fn, int appendtofile) { /* Always close and reopen when re-setting */ if (debugfd && (debugfd != stdout) && (debugfd != stderr)) fclose(debugfd); if (fn) { if (strcasecmp(fn, "stderr") == 0) debugfd = stderr; else if (strcasecmp(fn, "stdout") == 0) debugfd = stdout; else { debugfd = fopen(fn, (appendtofile ? "a" : "w")); if (debugfd == NULL) errprintf("Cannot open debug log '%s': %s\n", fn, strerror(errno)); } } if (!debugfd) debugfd = stdout; } void starttrace(const char *fn) { if (tracefd) fclose(tracefd); if (fn) { tracefd = fopen(fn, "a"); if (tracefd == NULL) errprintf("Cannot open tracefile %s\n", fn); } else tracefd = stdout; } void stoptrace(void) { if (tracefd) fclose(tracefd); tracefd = NULL; } void traceprintf(const char *fmt, ...) { va_list args; if (tracefd) { char timestr[40]; time_t now = getcurrenttime(NULL); MEMDEFINE(timestr); strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now)); fprintf(tracefd, "%08lu %s ", (unsigned long)getpid(), timestr); va_start(args, fmt); vfprintf(tracefd, fmt, args); va_end(args); fflush(tracefd); MEMUNDEFINE(timestr); } } void reopen_file(char *fn, char *mode, FILE *fd) { FILE *testfd; testfd = fopen(fn, mode); if (!testfd) { fprintf(stderr, "reopen_file: Cannot open new file: %s\n", strerror(errno)); return; } fclose(testfd); if (freopen(fn, mode, fd) == NULL) { /* Ugh ... lost the filedescriptor :-(( */ } } void redirect_cgilog(char *cginame) { char logfn[PATH_MAX]; char *cgilogdir; FILE *fd; cgilogdir = getenv("XYMONCGILOGDIR"); if (!cgilogdir) return; if (cginame) errappname = strdup(cginame); snprintf(logfn, sizeof(logfn), "%s/cgierror.log", cgilogdir); reopen_file(logfn, "a", stderr); /* If debugging, setup the debug logfile */ if (debug) { snprintf(logfn, sizeof(logfn), "%s/%s.dbg", cgilogdir, (errappname ? errappname : "cgi")); set_debugfile(logfn, 1); } } xymon-4.3.30/lib/environ.c0000664000076400007640000003303013515623702015600 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains environment variable handling routines. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: environ.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include "libxymon.h" const static struct { char *name; char *val; } xymonenv[] = { { "XYMONDREL", VERSION }, { "XYMONSERVERROOT", XYMONTOPDIR }, { "XYMONSERVERLOGS", XYMONLOGDIR }, { "XYMONSERVERHOSTNAME", XYMONHOSTNAME }, { "XYMONSERVERIP", XYMONHOSTIP }, { "XYMONSERVEROS", XYMONHOSTOS }, { "XYMONSERVERWWWNAME", XYMONHOSTNAME }, { "XYMONSERVERWWWURL", "/xymon" }, { "XYMONSERVERCGIURL", "/xymon-cgi" }, { "XYMONSERVERSECURECGIURL", "/xymon-seccgi" }, { "XYMONNETWORK", "" }, { "BBLOCATION", "" }, { "PATH", "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:"XYMONHOME"/bin" }, { "DELAYRED", "" }, { "DELAYYELLOW", "" }, { "XYMONDPORT", "1984" }, { "XYMSRV", "$XYMONSERVERIP" }, { "XYMSERVERS", "" }, { "FQDN", "TRUE" }, { "PAGELEVELS", "red yellow purple" }, { "PURPLEDELAY", "30" }, { "XYMONLOGSTATUS", "DYNAMIC" }, { "PINGCOLUMN", "conn" }, { "INFOCOLUMN", "info" }, { "TRENDSCOLUMN", "trends" }, { "CLIENTCOLUMN", "clientlog" }, { "DOCOMBO", "TRUE" }, { "MAXMSGSPERCOMBO", "100" }, { "SLEEPBETWEENMSGS", "0" }, { "SERVEROSTYPE", "$XYMONSERVEROS" }, { "MACHINEDOTS", "$XYMONSERVERHOSTNAME" }, { "MACHINEADDR", "$XYMONSERVERIP" }, { "XYMONWEBHOST", "http://$XYMONSERVERWWWNAME" }, { "XYMONWEBHOSTURL", "$XYMONWEBHOST$XYMONSERVERWWWURL" }, { "XYMONWEBHTMLLOGS", "$XYMONWEBHOSTURL/html" }, { "XYMONWEB", "$XYMONSERVERWWWURL" }, { "XYMONSKIN", "$XYMONSERVERWWWURL/gifs" }, { "XYMONHELPSKIN", "$XYMONSERVERWWWURL/help" }, { "XYMONNOTESSKIN", "$XYMONSERVERWWWURL/notes" }, { "XYMONMENUSKIN", "$XYMONSERVERWWWURL/menu" }, { "XYMONREPURL", "$XYMONSERVERWWWURL/rep" }, { "XYMONSNAPURL", "$XYMONSERVERWWWURL/snap" }, { "XYMONWAP", "$XYMONSERVERWWWURL/wml" }, { "CGIBINURL", "$XYMONSERVERCGIURL" }, { "XYMONHOME", XYMONHOME }, { "XYMONTMP", "$XYMONHOME/tmp" }, { "HOSTSCFG", "$XYMONHOME/etc/hosts.cfg" }, { "XYMON", "$XYMONHOME/bin/xymon" }, { "XYMONGEN", "$XYMONHOME/bin/xymongen" }, { "XYMONVAR", "$XYMONSERVERROOT/data" }, { "XYMONACKDIR", "$XYMONVAR/acks" }, { "XYMONDATADIR", "$XYMONVAR/data" }, { "XYMONDISABLEDDIR", "$XYMONVAR/disabled" }, { "XYMONHISTDIR", "$XYMONVAR/hist" }, { "XYMONHISTLOGS", "$XYMONVAR/histlogs" }, { "XYMONRAWSTATUSDIR", "$XYMONVAR/logs" }, { "XYMONWWWDIR", "$XYMONHOME/www" }, { "XYMONHTMLSTATUSDIR", "$XYMONWWWDIR/html" }, { "XYMONNOTESDIR", "$XYMONWWWDIR/notes" }, { "XYMONREPDIR", "$XYMONWWWDIR/rep" }, { "XYMONSNAPDIR", "$XYMONWWWDIR/snap" }, { "XYMONALLHISTLOG", "TRUE" }, { "XYMONHOSTHISTLOG", "TRUE" }, { "SAVESTATUSLOG", "TRUE" }, { "CLIENTLOGS", "$XYMONVAR/hostdata" }, { "DU", "du -k" }, { "MAILC", "mail" }, { "MAIL", "$MAILC -s" }, { "SVCCODES", "disk:100,cpu:200,procs:300,svcs:350,msgs:400,conn:500,http:600,dns:800,smtp:725,telnet:723,ftp:721,pop:810,pop3:810,pop-3:810,ssh:722,imap:843,ssh1:722,ssh2:722,imap2:843,imap3:843,imap4:843,pop2:809,pop-2:809,nntp:819,test:901" }, { "ALERTCOLORS", "red,yellow,purple" }, { "OKCOLORS", "green,blue,clear" }, { "ALERTREPEAT", "30" }, { "XYMWEBREFRESH", "60" }, { "MAXMSG_ALERTSCRIPT", "8164" }, { "CONNTEST", "TRUE" }, { "IPTEST_2_CLEAR_ON_FAILED_CONN", "TRUE" }, { "NONETPAGE", "" }, { "FPING", "xymonping" }, { "FPINGOPTS", "-Ae" }, { "SNTP", "sntp" }, { "SNTPOPTS", "-u" }, { "NTPDATE", "ntpdate" }, { "NTPDATEOPTS", "-u -q -p 1" }, { "TRACEROUTE", "traceroute" }, { "TRACEROUTEOPTS", "-n -q 2 -w 2 -m 15" }, { "RPCINFO", "rpcinfo" }, { "XYMONROUTERTEXT", "router" }, { "NETFAILTEXT", "not OK" }, { "XYMONRRDS", "$XYMONVAR/rrd" }, { "TEST2RRD", "cpu=la,disk,memory,$PINGCOLUMN=tcp,http=tcp,dns=tcp,dig=tcp,time=ntpstat,vmstat,iostat,netstat,temperature,apache,bind,sendmail,nmailq,socks,bea,iishealth,citrix,xymongen,xymonnet,xymonproxy,xymond" }, { "GRAPHS", "la,disk:disk_part:5,memory,users,vmstat,iostat,tcp.http,tcp,netstat,temperature,ntpstat,apache,bind,sendmail,nmailq,socks,bea,iishealth,citrix,xymongen,xymonnet,xymonproxy,xymond" }, { "SUMMARY_SET_BKG", "FALSE" }, { "XYMONNONGREENEXT", "eventlog.sh acklog.sh" }, { "DOTHEIGHT", "16" }, { "DOTWIDTH", "16" }, { "IMAGEFILETYPE", "gif" }, { "RRDHEIGHT", "120" }, { "RRDWIDTH", "576" }, { "COLUMNDOCURL", "$CGIBINURL/columndoc.sh?%s" }, { "HOSTDOCURL", "" }, { "XYMONLOGO", "Xymon" }, { "XYMONPAGELOCAL", "Pages Hosted Locally" }, { "XYMONPAGEREMOTE", "Remote Status Display" }, { "XYMONPAGESUBLOCAL", "Subpages Hosted Locally" }, { "XYMONPAGEACKFONT", "COLOR=\"#33ebf4\" SIZE=\"-1\"" }, { "XYMONPAGECOLFONT", "COLOR=\"#87a9e5\" SIZE=\"-1\"" }, { "XYMONPAGEROWFONT", "SIZE=\"+1\" COLOR=\"#FFFFCC\" FACE=\"Tahoma, Arial, Helvetica\"" }, { "XYMONPAGETITLE", "COLOR=\"ivory\" SIZE=\"+1\"" }, { "XYMONDATEFORMAT", "%a %b %d %H:%M:%S %Y" }, { "XYMONRSSTITLE", "Xymon Alerts" }, { "ACKUNTILMSG", "Next update at: %H:%M %Y-%m-%d" }, { "WMLMAXCHARS", "1500" }, { "XYMONREPWARN", "97" }, { "XYMONGENREPOPTS", "--recentgifs --subpagecolumns=2" }, { "XYMONGENSNAPOPTS", "--recentgifs --subpagecolumns=2" }, { "XYMONSTDEXT", "" }, { "XYMONHISTEXT", "" }, { "TASKSLEEP", "300" }, { "XYMONPAGECOLREPEAT", "0" }, { "ALLOWALLCONFIGFILES", "" }, { "XYMONHTACCESS", "" }, { "XYMONPAGEHTACCESS", "" }, { "XYMONSUBPAGEHTACCESS", "" }, { "XYMONNETSVCS", "smtp telnet ftp pop pop3 pop-3 ssh imap ssh1 ssh2 imap2 imap3 imap4 pop2 pop-2 nntp" }, { "HTMLCONTENTTYPE", "text/html" }, { "HOLIDAYFORMAT", "%d/%m" }, { "WEEKSTART", "1" }, { "XYMONBODYCSS", "$XYMONSKIN/xymonbody.css" }, { "XYMONBODYMENUCSS", "$XYMONMENUSKIN/xymonmenu.css" }, { "XYMONBODYHEADER", "file:$XYMONHOME/etc/xymonmenu.cfg" }, { "XYMONBODYFOOTER", "" }, { "LOGFETCHSKIPTEXT", "<...SKIPPED...>" }, { "LOGFETCHCURRENTTEXT", "<...CURRENT...>" }, { "XYMONALLOKTEXT", "

All Monitored Systems OK


" }, { "HOSTPOPUP", "CDI" }, { "STATUSLIFETIME", "30" }, { "ACK_COOKIE_EXPIRATION", "86400" }, { NULL, NULL } }; char *xgetenv(const char *name) { char *result; SBUF_DEFINE(newstr); int i; result = getenv(name); if ((result == NULL) && (strcmp(name, "MACHINE") == 0) && xgetenv("MACHINEDOTS")) { /* If MACHINE is undefined, but MACHINEDOTS is there, create MACHINE */ SBUF_DEFINE(oneenv); char *p; #ifdef HAVE_SETENV oneenv = strdup(xgetenv("MACHINEDOTS")); p = oneenv; while ((p = strchr(p, '.')) != NULL) *p = ','; setenv(name, oneenv, 1); xfree(oneenv); #else SBUF_MALLOC(10 + strlen(xgetenv("MACHINEDOTS"))); snprintf(oneenv, oneenv_buflen, "%s=%s", name, xgetenv("MACHINEDOTS")); p = oneenv; while ((p = strchr(p, '.')) != NULL) *p = ','; putenv(oneenv); #endif result = getenv(name); } if (result == NULL) { for (i=0; (xymonenv[i].name && (strcmp(xymonenv[i].name, name) != 0)); i++) ; if (xymonenv[i].name) result = expand_env(xymonenv[i].val); if (result == NULL) { errprintf("xgetenv: Cannot find value for variable %s\n", name); return NULL; } /* * If we got a result, put it into the environment so it will stay there. * Allocate memory for this new environment string - this stays allocated. */ #ifdef HAVE_SETENV setenv(name, result, 1); #else SBUF_MALLOC(newstr, strlen(name) + strlen(result) + 2); snprintf(newstr, newstr_buflen, "%s=%s", name, result); putenv(newstr); #endif /* * Return pointer to the environment string. */ result = getenv(name); } return result; } void envcheck(char *envvars[]) { int i; int ok = 1; for (i = 0; (envvars[i]); i++) { if (xgetenv(envvars[i]) == NULL) { errprintf("Environment variable %s not defined\n", envvars[i]); ok = 0; } } if (!ok) { errprintf("Aborting\n"); exit (1); } } void loadenv(char *envfile, char *area) { FILE *fd; strbuffer_t *inbuf; char *p, *marker; SBUF_DEFINE(oneenv); MEMDEFINE(l); inbuf = newstrbuffer(0); fd = stackfopen(envfile, "r", NULL); if (fd) { while (stackfgets(inbuf, NULL)) { char *equalpos; int appendto = 0; sanitize_input(inbuf, 1, 1); if ((STRBUFLEN(inbuf) == 0) || ((equalpos = strchr(STRBUF(inbuf), '=')) == NULL)) continue; appendto = ((equalpos > STRBUF(inbuf)) && (*(equalpos-1) == '+')); /* * Do the environment "area" stuff: If the input * is of the form AREA/NAME=VALUE, then setup the variable * only if we're called with the correct AREA setting. */ oneenv = NULL; p = STRBUF(inbuf); /* Skip ahead for anyone who thinks this is a shell include */ if ((strncmp(p, "export ", 7) == 0) || (strncmp(p, "export\t", 7) == 0)) { p += 6; p += strspn(p, " \t"); } marker = p + strcspn(p, "=/"); if (*marker == '/') { if (area) { *marker = '\0'; if (strcasecmp(p, area) == 0) { oneenv = strdup(expand_env(marker+1)); oneenv_buflen = strlen(oneenv)+1; } } } else { oneenv = strdup(expand_env(p)); oneenv_buflen = strlen(oneenv)+1; } if (oneenv) { p = strchr(oneenv, '='); if (*(p+1) == '"') { /* Move string over the first '"' */ memmove(p+1, p+2, strlen(p+2)+1); /* Kill a trailing '"' */ if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0'; } if (appendto) { char *oldval, *addstring, *p; addstring = strchr(oneenv, '='); if (addstring) { *addstring = '\0'; addstring++; } p = strchr(oneenv, '+'); if (p) *p = '\0'; oldval = getenv(oneenv); if (oldval) { SBUF_DEFINE(combinedenv); SBUF_MALLOC(combinedenv, strlen(oneenv) + strlen(oldval) + strlen(addstring) + 2); snprintf(combinedenv, combinedenv_buflen, "%s=%s%s", oneenv, oldval, (addstring)); xfree(oneenv); oneenv = combinedenv; } else { /* oneenv is now VARxxVALUE, so fix it to be a normal env. variable format */ strncat(oneenv, "=", oneenv_buflen-strlen(oneenv)); memmove(oneenv+strlen(oneenv), addstring, strlen(addstring) + 1); } } putenv(oneenv); } } stackfclose(fd); } else { errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno)); } freestrbuffer(inbuf); MEMUNDEFINE(l); } char *getenv_default(char *envname, char *envdefault, char **buf) { static char *val; val = getenv(envname); /* Don't use xgetenv() here! */ if (!val) { unsigned int val_buflen = strlen(envname) + strlen(envdefault) + 2; val = (char *)malloc(val_buflen); snprintf(val, val_buflen, "%s=%s", envname, envdefault); putenv(val); /* Don't free the string - it must be kept for the environment to work */ val = xgetenv(envname); /* OK to use xgetenv here */ } if (buf) *buf = val; return val; } typedef struct envxp_t { char *result; int resultlen; struct envxp_t *next; } envxp_t; static envxp_t *xps = NULL; char *expand_env(char *s) { static char *res = NULL; static int depth = 0; char *sCopy, *bot, *tstart, *tend, *envval; char savech; envxp_t *myxp; if ((depth == 0) && res) xfree(res); depth++; myxp = (envxp_t *)malloc(sizeof(envxp_t)); myxp->next = xps; xps = myxp; myxp->resultlen = 4096; myxp->result = (char *)malloc(myxp->resultlen); *(myxp->result) = '\0'; sCopy = strdup(s); bot = sCopy; do { tstart = strchr(bot, '$'); if (tstart) *tstart = '\0'; if ((strlen(myxp->result) + strlen(bot) + 1) > myxp->resultlen) { myxp->resultlen += strlen(bot) + 4096; myxp->result = (char *)realloc(myxp->result, myxp->resultlen); } strncat(myxp->result, bot, (myxp->resultlen - strlen(myxp->result))); if (tstart) { tstart++; envval = NULL; if (*tstart == '{') { tstart++; tend = strchr(tstart, '}'); if (tend) { *tend = '\0'; envval = xgetenv(tstart); bot = tend+1; } else { envval = xgetenv(tstart); bot = NULL; } } else { tend = tstart + strspn(tstart, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"); savech = *tend; *tend = '\0'; envval = xgetenv(tstart); *tend = savech; bot = tend; } if (envval) { if ((strlen(myxp->result) + strlen(envval) + 1) > myxp->resultlen) { myxp->resultlen += strlen(envval) + 4096; myxp->result = (char *)realloc(myxp->result, myxp->resultlen); } strncat(myxp->result, envval, (myxp->resultlen - strlen(myxp->result))); } } else { bot = NULL; } } while (bot); xfree(sCopy); depth--; if (depth == 0) { envxp_t *tmp; /* Free all xps except the last one (which is myxp) */ while (xps->next) { tmp = xps; xps = xps->next; xfree(tmp->result); xfree(tmp); } if (xps != myxp) { errprintf("Assertion failed: xps != myxp\n"); abort(); } /* We KNOW that xps == myxp */ res = myxp->result; xfree(myxp); xps = NULL; return res; } else return myxp->result; } xymon-4.3.30/lib/cgi.h0000664000076400007640000000226612666146167014711 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CGI_H__ #define __CGI_H__ typedef struct cgidata_t { char *name; char *value; char *filename; struct cgidata_t *next; } cgidata_t; enum cgi_method_t { CGI_OTHER, CGI_GET, CGI_POST }; extern enum cgi_method_t cgi_method; extern char *cgi_error(void); extern int cgi_ispost(void); extern cgidata_t *cgi_request(void); extern char *csp_header(const char *pagename); extern int cgi_refererok(char *expected); extern char *get_cookie(char *cookiename); #endif xymon-4.3.30/lib/encoding.h0000664000076400007640000000203011615341300015675 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __ENCODING_H__ #define __ENCODING_H__ extern char *base64encode(unsigned char *buf); extern char *base64decode(unsigned char *buf); extern void getescapestring(char *msg, unsigned char **buf, int *buflen); extern unsigned char *nlencode(unsigned char *msg); extern void nldecode(unsigned char *msg); #endif xymon-4.3.30/lib/availability.h0000664000076400007640000000350513531275564016612 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __AVAILABILITY_H__ #define __AVAILABILITY_H__ #include "color.h" typedef struct reportinfo_t { char *fstate; time_t reportstart; int count[COL_COUNT]; double fullavailability; int fullstops; double fullpct[COL_COUNT]; unsigned long fullduration[COL_COUNT]; int withreport; double reportavailability; int reportstops; double reportpct[COL_COUNT]; unsigned long reportduration[COL_COUNT]; } reportinfo_t; typedef struct replog_t { time_t starttime; time_t duration; int color; int affectssla; char *cause; char *timespec; struct replog_t *next; } replog_t; extern replog_t *reploghead; #define MAXDURSIZE 30 extern char *durationstr(time_t duration); extern int parse_historyfile(FILE *fd, reportinfo_t *repinfo, char *hostname, char *servicename, time_t fromtime, time_t totime, int for_history, double warnlevel, double greenlevel, int warnstops, char *reporttime); extern replog_t *save_replogs(void); extern void restore_replogs(replog_t *head); extern int history_color(FILE *fd, time_t snapshot, time_t *starttime, char **histlogname); #endif xymon-4.3.30/lib/sha1.h0000664000076400007640000000220411615341300014746 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* API for the SHA1 digest routines. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __SHA1_H__ #define __SHA1_H__ extern int mySHA1_Size(void); extern void mySHA1_Init(void *context); extern void mySHA1_Update(void *context, const unsigned char *data, int len); extern void mySHA1_Final(unsigned char digest[20], void *context); #endif xymon-4.3.30/lib/loadhosts_net.c0000664000076400007640000000604513515623702016774 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the host */ /* configuration from xymond, for either a single host or all hosts. */ /* */ /* Copyright (C) 2011-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid_net[] = "$Id: loadhosts_file.c 6745 2011-09-04 06:01:06Z storner $"; static char *hivalhost = NULL; static char *hivals[XMH_LAST] = { NULL, }; static char *hivalbuf = NULL; static namelist_t hival_hostinfo; /* Used as token for userspace. Also holds raw data in "elems" */ int load_hostinfo(char *targethost) { sendreturn_t *sres; sendresult_t sendstat; SBUF_DEFINE(msg); char *bol, *eoln, *key, *val; int elemsize = 0; xmh_item_list_setup(); if (hivalhost) { xfree(hivalhost); hivalhost = NULL; } if (hivalbuf) { xfree(hivalbuf); hivalbuf = NULL; xfree(hival_hostinfo.elems); } if (!targethost) return -1; SBUF_MALLOC(msg, 200 + strlen(targethost)); snprintf(msg, msg_buflen, "hostinfo clone=%s", targethost); sres = newsendreturnbuf(1, NULL); sendstat = sendmessage(msg, NULL, XYMON_TIMEOUT, sres); xfree(msg); if (sendstat != XYMONSEND_OK) { errprintf("Cannot load hostinfo\n"); return -1; } hivalbuf = getsendreturnstr(sres, 1); if (strlen(hivalbuf) == 0) { errprintf("No such host\n"); return -2; } hivalhost = strdup(targethost); memset(hivals, 0, sizeof(hivals)); memset(&hival_hostinfo, 0, sizeof(hival_hostinfo)); hival_hostinfo.elems = (char **)calloc(1, sizeof(char *)); bol = hivalbuf; while (bol && *bol) { int idx; /* * The "clone" output is multiline: * Lines beginning with XMH_ are the item-values, * all others are elem entries. */ eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; key = bol; if (strncmp(key, "XMH_", 4) == 0) { val = strchr(bol, ':'); if (val) { *val = '\0'; val++; } idx = xmh_key_idx(key); if ((idx >= 0) && (idx < XMH_LAST)) hivals[idx] = val; } else { elemsize++; hival_hostinfo.elems = (char **)realloc(hival_hostinfo.elems, (elemsize+1)*sizeof(char *)); hival_hostinfo.elems[elemsize-1] = bol; } bol = (eoln ? eoln+1 : NULL); } hival_hostinfo.elems[elemsize] = NULL; hival_hostinfo.hostname = hivals[XMH_HOSTNAME]; if (hivals[XMH_IP]) strncpy(hival_hostinfo.ip, hivals[XMH_IP], sizeof(hival_hostinfo.ip)); else *(hival_hostinfo.ip) = '\0'; return 0; } xymon-4.3.30/lib/timefunc.c0000664000076400007640000003516613532325276015752 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for timehandling. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: timefunc.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" #ifdef time #undef time #endif time_t fakestarttime = 0; time_t getcurrenttime(time_t *retparm) { static time_t firsttime = 0; if (fakestarttime != 0) { time_t result; if (firsttime == 0) firsttime = time(NULL); result = fakestarttime + (time(NULL) - firsttime); if (retparm) *retparm = result; return result; } else return time(retparm); } char *timestamp = NULL; void init_timestamp(void) { time_t now; if (timestamp == NULL) timestamp = (char *)malloc(30); now = getcurrenttime(NULL); strncpy(timestamp, ctime(&now), 30); timestamp[strlen(timestamp)-1] = '\0'; } char *timespec_text(char *spec) { static char *daynames[7] = { NULL, }; STATIC_SBUF_DEFINE(wkdays); static strbuffer_t *result = NULL; char *sCopy; char *p; if (result == NULL) result = newstrbuffer(0); clearstrbuffer(result); if (!daynames[0]) { /* Use strftime to get the locale-specific weekday names */ time_t now; int i; now = time(NULL); for (i=0; (i<7); i++) { char dtext[10]; struct tm *tm = localtime(&now); strftime(dtext, sizeof(dtext), "%a", tm); daynames[tm->tm_wday] = strdup(dtext); now -= 86400; } SBUF_MALLOC(wkdays, strlen(daynames[1]) + strlen(daynames[5]) + 2); snprintf(wkdays, wkdays_buflen, "%s-%s", daynames[1], daynames[5]); } p = sCopy = strdup(spec); do { char *s1, *s2, *s3, *s4, *s5; char *days = NULL, *starttime = NULL, *endtime = NULL, *columns = NULL; unsigned char *cause = NULL; char *oneday, *dtext; int daysdone = 0, firstday = 1, causelen; /* Its either DAYS:START:END or SERVICE:DAYS:START:END:CAUSE */ s1 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s2 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s3 = p; p += strcspn(p, ":;,"); if ((*p == ',') || (*p == ';') || (*p == '\0')) { if (*p != '\0') { *p = '\0'; p++; } days = s1; starttime = s2; endtime = s3; columns = "*"; cause = strdup("Planned downtime"); } else if (*p == ':') { *p = '\0'; p++; s4 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s5 = p; p += strcspn(p, ",;"); if (*p != '\0') { *p = '\0'; p++; } days = s2; starttime = s3; endtime = s4; columns = s1; getescapestring(s5, &cause, &causelen); } if (!days) return ""; oneday = days; if (STRBUFLEN(result) > 0) addtobuffer(result, "
"); while (!daysdone) { switch (*oneday) { case '*': dtext = "All days"; break; case 'W': dtext = wkdays; break; case '0': dtext = daynames[0]; break; case '1': dtext = daynames[1]; break; case '2': dtext = daynames[2]; break; case '3': dtext = daynames[3]; break; case '4': dtext = daynames[4]; break; case '5': dtext = daynames[5]; break; case '6': dtext = daynames[6]; break; default : dtext = oneday; daysdone = firstday = 1; break; } if (!firstday) addtobuffer(result, "/"); addtobuffer(result, dtext); oneday++; firstday = 0; } addtobuffer(result, ":"); addtobuffer(result, starttime); addtobuffer(result, ":"); addtobuffer(result, endtime); addtobuffer(result, " (status:"); if (strcmp(columns, "*") == 0) addtobuffer(result, "All"); else addtobuffer(result, columns); addtobuffer(result, ")"); if (cause) { addtobuffer(result, " (cause:"); addtobuffer(result, cause); addtobuffer(result, ")"); xfree(cause); } } while (*p); xfree(sCopy); return STRBUF(result); } struct timespec *tvdiff(struct timespec *tstart, struct timespec *tend, struct timespec *result) { static struct timespec resbuf; if (result == NULL) result = &resbuf; result->tv_sec = tend->tv_sec; result->tv_nsec = tend->tv_nsec; if (result->tv_nsec < tstart->tv_nsec) { result->tv_sec--; result->tv_nsec += 1000000000; } result->tv_sec -= tstart->tv_sec; result->tv_nsec -= tstart->tv_nsec; return result; } static int minutes(char *p) { /* Converts string HHMM to number indicating minutes since midnight (0-1440) */ if (isdigit((int)*(p+0)) && isdigit((int)*(p+1)) && isdigit((int)*(p+2)) && isdigit((int)*(p+3))) { return (10*(*(p+0)-'0')+(*(p+1)-'0'))*60 + (10*(*(p+2)-'0')+(*(p+3)-'0')); } else { errprintf("Invalid timespec - expected 4 digits, got: '%s'\n", p); return 0; } } int within_sla(char *holidaykey, char *timespec, int defresult) { /* * timespec is of the form W:HHMM:HHMM[,W:HHMM:HHMM]* * "W" = weekday : '*' = all, 'W' = Monday-Friday, '0'..'6' = Sunday ..Saturday */ int found = 0; time_t tnow; struct tm *now; int curtime; int newwday; char *onesla; if (!timespec) return defresult; tnow = getcurrenttime(NULL); now = localtime(&tnow); curtime = now->tm_hour*60+now->tm_min; newwday = getweekdayorholiday(holidaykey, now); onesla = timespec; while (!found && onesla) { char *wday; int validday, wdaymatch = 0; char *endsla, *starttimep, *endtimep; int starttime, endtime; endsla = strchr(onesla, ','); if (endsla) *endsla = '\0'; for (wday = onesla, validday=1; (validday && !wdaymatch); wday++) { switch (*wday) { case '*': wdaymatch = 1; break; case 'W': case 'w': if ((newwday >= 1) && (newwday <=5)) wdaymatch = 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': if (*wday == (newwday+'0')) wdaymatch = 1; break; case ':': /* End of weekday spec. is OK */ validday = 0; break; default: errprintf("Bad timespec (missing colon or wrong weekdays): %s\n", onesla); validday = 0; break; } } if (wdaymatch) { /* Weekday matches */ starttimep = strchr(onesla, ':'); if (starttimep) { starttime = minutes(starttimep+1); endtimep = strchr(starttimep+1, ':'); if (endtimep) { endtime = minutes(endtimep+1); if (endtime > starttime) { /* *:0200:0400 */ found = ((curtime >= starttime) && (curtime <= endtime)); } else { /* The period crosses over midnight: *:2330:0400 */ found = ((curtime >= starttime) || (curtime <= endtime)); } dbgprintf("\tstart,end,current time = %d, %d, %d - found=%d\n", starttime,endtime,curtime,found); } else errprintf("Bad timespec (missing colon or no endtime): %s\n", onesla); } else errprintf("Bad timespec (missing colon or no starttime): %s\n", onesla); } else { dbgprintf("\tWeekday does not match\n"); } /* Go to next SLA spec. */ if (endsla) *endsla = ','; onesla = (endsla ? (endsla + 1) : NULL); } return found; } int periodcoversnow(char *tag) { /* * Tag format: "-DAY-HHMM-HHMM:" * DAY = 0-6 (Sun .. Mon), or W (1..5) */ time_t tnow; struct tm *now; int result = 1; SBUF_DEFINE(dayspec); SBUF_DEFINE(starttime); SBUF_DEFINE(endtime); unsigned int istart, iend, inow; char *p; if ((tag == NULL) || (*tag != '-')) return 1; SBUF_MALLOC(dayspec, strlen(tag)+1+12); /* Leave room for expanding 'W' and '*' */ SBUF_MALLOC(starttime, strlen(tag)+1); SBUF_MALLOC(endtime, strlen(tag)+1); strncpy(dayspec, (tag+1), dayspec_buflen); for (p=dayspec; ((*p == 'W') || (*p == '*') || ((*p >= '0') && (*p <= '6'))); p++) ; if (*p != '-') { xfree(endtime); xfree(starttime); xfree(dayspec); return 1; } *p = '\0'; p++; strncpy(starttime, p, starttime_buflen); p = starttime; if ( (strlen(starttime) < 4) || !isdigit((int) *p) || !isdigit((int) *(p+1)) || !isdigit((int) *(p+2)) || !isdigit((int) *(p+3)) || !(*(p+4) == '-') ) goto out; else *(starttime+4) = '\0'; p+=5; strncpy(endtime, p, endtime_buflen); p = endtime; if ( (strlen(endtime) < 4) || !isdigit((int) *p) || !isdigit((int) *(p+1)) || !isdigit((int) *(p+2)) || !isdigit((int) *(p+3)) || !(*(p+4) == ':') ) goto out; else *(endtime+4) = '\0'; tnow = getcurrenttime(NULL); now = localtime(&tnow); /* We have a timespec. So default to "not included" */ result = 0; /* Check day-spec */ if (strchr(dayspec, 'W')) strncat(dayspec, "12345", (dayspec_buflen - strlen(dayspec))); if (strchr(dayspec, '*')) strncat(dayspec, "0123456", (dayspec_buflen - strlen(dayspec))); if (strchr(dayspec, ('0' + now->tm_wday)) == NULL) goto out; /* Calculate minutes since midnight for start, end and now */ istart = (600 * (starttime[0]-'0')) + (60 * (starttime[1]-'0')) + (10 * (starttime[2]-'0')) + (1 * (starttime[3]-'0')); iend = (600 * (endtime[0]-'0')) + (60 * (endtime[1]-'0')) + (10 * (endtime[2]-'0')) + (1 * (endtime[3]-'0')); inow = 60*now->tm_hour + now->tm_min; if ((inow < istart) || (inow > iend)) goto out; result = 1; out: xfree(endtime); xfree(starttime); xfree(dayspec); return result; } char *histlogtime(time_t histtime) { STATIC_SBUF_DEFINE(result); char d1[40],d2[3],d3[40]; if (result == NULL) SBUF_MALLOC(result, 30); MEMDEFINE(d1); MEMDEFINE(d2); MEMDEFINE(d3); /* * Historical logs use a filename like "Fri_Nov_7_16:01:08_2002 * But apparently there is no simple way to generate a day-of-month * with no leading 0. */ strftime(d1, sizeof(d1), "%a_%b_", localtime(&histtime)); strftime(d2, sizeof(d2), "%d", localtime(&histtime)); if (d2[0] == '0') { d2[0] = d2[1]; d2[1] = '\0'; } strftime(d3, sizeof(d3), "_%H:%M:%S_%Y", localtime(&histtime)); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ snprintf(result, result_buflen, "%s%s%s", d1, d2, d3); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ MEMUNDEFINE(d1); MEMUNDEFINE(d2); MEMUNDEFINE(d3); return result; } int durationvalue(char *dur) { /* * Calculate a duration, taking special modifiers into consideration. * Return the duration as number of minutes. */ int result = 0; char *startofval; char *endpos; char savedelim; /* Make sure we only process the first token, don't go past whitespace or some other delimiter */ endpos = dur + strspn(dur, "01234567890mhdw"); savedelim = *endpos; *endpos = '\0'; startofval = dur; while (startofval && (isdigit((int)*startofval))) { char *p; char modifier; int oneval = 0; p = startofval + strspn(startofval, "0123456789"); modifier = *p; *p = '\0'; oneval = atoi(startofval); *p = modifier; switch (modifier) { case '\0': break; /* No delimiter = minutes */ case 'm' : break; /* minutes */ case 'h' : oneval *= 60; break; /* hours */ case 'd' : oneval *= 1440; break; /* days */ case 'w' : oneval *= 10080; break; /* weeks */ } result += oneval; startofval = ((*p) ? p+1 : NULL); } /* Restore the saved delimiter */ *endpos = savedelim; return result; } char *durationstring(time_t secs) { #define ONE_WEEK (7*24*60*60) #define ONE_DAY (24*60*60) #define ONE_HOUR (60*60) #define ONE_MINUTE (60) static char result[50]; char *p = result; time_t v = secs; int n; if (secs == 0) return "-"; *result = '\0'; if (v >= ONE_WEEK) { n = (int) (v / ONE_WEEK); p += snprintf(p, (sizeof(result) - (p - result)), "%dw ", n); v -= (n * ONE_WEEK); } if (v >= ONE_DAY) { n = (int) (v / ONE_DAY); p += snprintf(p, (sizeof(result) - (p - result)), "%dd ", n); v -= (n * ONE_DAY); } if (v >= ONE_HOUR) { n = (int) (v / ONE_HOUR); p += snprintf(p, (sizeof(result) - (p - result)), "%dh ", n); v -= (n * ONE_HOUR); } if (v >= ONE_MINUTE) { n = (int) (v / ONE_MINUTE); p += snprintf(p, (sizeof(result) - (p - result)), "%dm ", n); v -= (n * ONE_MINUTE); } if (v > 0) { p += snprintf(p, (sizeof(result) - (p - result)), "%ds ", (int)v); } return result; } char *agestring(time_t secs) { static char result[128]; char *p; time_t left = secs; *result = '\0'; p = result; if (left > 86400) { p += snprintf(p, (sizeof(result) - (p - result)), "%ldd", (left / 86400)); left = (left % 86400); } if ((left > 3600) || *result) { p += snprintf(p, (sizeof(result) - (p - result)), (*result ? "%02ldh" : "%ldh"), (left / 3600)); left = (left % 3600); } if ((left > 60) || *result) { p += snprintf(p, (sizeof(result) - (p - result)), (*result ? "%02ldm" : "%ldm"), (left / 60)); left = (left % 60); } /* Only show seconds if no other info */ if (*result == '\0') { p += snprintf(p, (sizeof(result) - (p - result)), "%02lds", left); } *p = '\0'; return result; } time_t timestr2timet(char *s) { /* Convert a string "YYYYMMDDHHMM" to time_t value */ struct tm tm; if (strlen(s) != 12) { errprintf("Invalid timestring: '%s'\n", s); return -1; } tm.tm_min = atoi(s+10); *(s+10) = '\0'; tm.tm_hour = atoi(s+8); *(s+8) = '\0'; tm.tm_mday = atoi(s+6); *(s+6) = '\0'; tm.tm_mon = atoi(s+4) - 1; *(s+4) = '\0'; tm.tm_year = atoi(s) - 1900; *(s+4) = '\0'; tm.tm_isdst = -1; return mktime(&tm); } time_t eventreport_time(char *timestamp) { time_t event = 0; unsigned int year,month,day,hour,min,sec,count; struct tm timeinfo; if ((*timestamp) && (*(timestamp + strspn(timestamp, "0123456789")) == '\0')) return (time_t) atol(timestamp); count = sscanf(timestamp, "%u/%u/%u@%u:%u:%u", &year, &month, &day, &hour, &min, &sec); if(count != 6) { return -1; } if(year < 1970) { return 0; } else { memset(&timeinfo, 0, sizeof(timeinfo)); timeinfo.tm_year = year - 1900; timeinfo.tm_mon = month - 1; timeinfo.tm_mday = day; timeinfo.tm_hour = hour; timeinfo.tm_min = min; timeinfo.tm_sec = sec; timeinfo.tm_isdst = -1; event = mktime(&timeinfo); } return event; } xymon-4.3.30/lib/loadcriticalconf.h0000664000076400007640000000343711630612042017424 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module for Xymon, responsible for loading the */ /* critical.cfg file. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOADCRITICALCONF_H__ #define __LOADCRITICALCONF_H__ #include typedef struct critconf_t { char *key; int priority; time_t starttime, endtime; char *crittime; char *ttgroup; char *ttextra; char *updinfo; } critconf_t; #define CRITCONF_TIMEFILTER 1 #define CRITCONF_FIRSTMATCH 2 #define CRITCONF_FIRST 3 #define CRITCONF_NEXT 4 #define CRITCONF_RAW_FIRST 5 #define CRITCONF_RAW_NEXT 6 #define CRITCONF_FIRSTHOSTMATCH 7 #define DEFAULT_CRITCONFIGFN "etc/critical.cfg" extern int load_critconfig(char *fn); extern critconf_t *get_critconfig(char *key, int flags, char **resultkey); extern int update_critconfig(critconf_t *rec); extern void addclone_critconfig(char *origin, char *newclone); extern void dropclone_critconfig(char *drop); extern int delete_critconfig(char *dropkey, int evenifcloned); #endif xymon-4.3.30/lib/color.h0000664000076400007640000000230611615341300015233 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __COLOR_H__ #define __COLOR_H__ #define COL_GREEN 0 #define COL_CLEAR 1 #define COL_BLUE 2 #define COL_PURPLE 3 #define COL_YELLOW 4 #define COL_RED 5 #define COL_CLIENT 99 #define COL_COUNT (COL_RED+1) extern int use_recentgifs; extern char *colorname(int color); extern int parse_color(char *colortext); extern int eventcolor(char *colortext); extern char *dotgiffilename(int color, int acked, int oldage); extern int colorset(char *colspec, int excludeset); #endif xymon-4.3.30/lib/encoding.c0000664000076400007640000001357711615341300015712 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for Base64 encoding and decoding. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: encoding.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include "libxymon.h" static char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char *base64encode(unsigned char *buf) { unsigned char c0, c1, c2; unsigned int n0, n1, n2, n3; unsigned char *inp, *outp; unsigned char *result; result = malloc(4*(strlen(buf)/3 + 1) + 1); inp = buf; outp=result; while (strlen(inp) >= 3) { c0 = *inp; c1 = *(inp+1); c2 = *(inp+2); n0 = (c0 >> 2); /* 6 bits from c0 */ n1 = ((c0 & 3) << 4) + (c1 >> 4); /* 2 bits from c0, 4 bits from c1 */ n2 = ((c1 & 15) << 2) + (c2 >> 6); /* 4 bits from c1, 2 bits from c2 */ n3 = (c2 & 63); /* 6 bits from c2 */ *outp = b64chars[n0]; outp++; *outp = b64chars[n1]; outp++; *outp = b64chars[n2]; outp++; *outp = b64chars[n3]; outp++; inp += 3; } if (strlen(inp) == 1) { c0 = *inp; c1 = 0; n0 = (c0 >> 2); /* 6 bits from c0 */ n1 = ((c0 & 3) << 4) + (c1 >> 4); /* 2 bits from c0, 4 bits from c1 */ *outp = b64chars[n0]; outp++; *outp = b64chars[n1]; outp++; *outp = '='; outp++; *outp = '='; outp++; } else if (strlen(inp) == 2) { c0 = *inp; c1 = *(inp+1); c2 = 0; n0 = (c0 >> 2); /* 6 bits from c0 */ n1 = ((c0 & 3) << 4) + (c1 >> 4); /* 2 bits from c0, 4 bits from c1 */ n2 = ((c1 & 15) << 2) + (c2 >> 6); /* 4 bits from c1, 2 bits from c2 */ *outp = b64chars[n0]; outp++; *outp = b64chars[n1]; outp++; *outp = b64chars[n2]; outp++; *outp = '='; outp++; } *outp = '\0'; return result; } char *base64decode(unsigned char *buf) { static short bval[128] = { 0, }; static short bvalinit = 0; int n0, n1, n2, n3; unsigned char *inp, *outp; unsigned char *result; int bytesleft = strlen(buf); if (!bvalinit) { int i; bvalinit = 1; for (i=0; (i < strlen(b64chars)); i++) bval[(int)b64chars[i]] = i; } result = malloc(3*(bytesleft/4 + 1) + 1); inp = buf; outp=result; while (bytesleft >= 4) { n0 = bval[*(inp+0)]; n1 = bval[*(inp+1)]; n2 = bval[*(inp+2)]; n3 = bval[*(inp+3)]; *(outp+0) = (n0 << 2) + (n1 >> 4); /* 6 bits from n0, 2 from n1 */ *(outp+1) = ((n1 & 0x0F) << 4) + (n2 >> 2); /* 4 bits from n1, 4 from n2 */ *(outp+2) = ((n2 & 0x03) << 6) + (n3); /* 2 bits from n2, 6 from n3 */ inp += 4; bytesleft -= 4; outp += 3; } *outp = '\0'; return result; } void getescapestring(char *msg, unsigned char **buf, int *buflen) { char *inp, *outp; int outlen = 0; inp = msg; if (*inp == '\"') inp++; /* Skip the quote */ outp = *buf = malloc(strlen(msg)+1); while (*inp && (*inp != '\"')) { if (*inp == '\\') { inp++; if (*inp == 'r') { *outp = '\r'; outlen++; inp++; outp++; } else if (*inp == 'n') { *outp = '\n'; outlen++; inp++; outp++; } else if (*inp == 't') { *outp = '\t'; outlen++; inp++; outp++; } else if (*inp == '\\') { *outp = '\\'; outlen++; inp++; outp++; } else if (*inp == 'x') { inp++; if (isxdigit((int) *inp)) { *outp = hexvalue(*inp); inp++; if (isxdigit((int) *inp)) { *outp *= 16; *outp += hexvalue(*inp); inp++; } } else { errprintf("Invalid hex escape in '%s'\n", msg); } outlen++; outp++; } else { errprintf("Unknown escape sequence \\%c in '%s'\n", *inp, msg); } } else { *outp = *inp; outlen++; inp++; outp++; } } *outp = '\0'; if (buflen) *buflen = outlen; } unsigned char *nlencode(unsigned char *msg) { static unsigned char *buf = NULL; static int bufsz = 0; int maxneeded; unsigned char *inp, *outp; int n; if (msg == NULL) msg = ""; maxneeded = 2*strlen(msg)+1; if (buf == NULL) { bufsz = maxneeded; buf = (char *)malloc(bufsz); } else if (bufsz < maxneeded) { bufsz = maxneeded; buf = (char *)realloc(buf, bufsz); } inp = msg; outp = buf; while (*inp) { n = strcspn(inp, "|\n\r\t\\"); if (n > 0) { memcpy(outp, inp, n); outp += n; inp += n; } if (*inp) { *outp = '\\'; outp++; switch (*inp) { case '|' : *outp = 'p'; outp++; break; case '\n': *outp = 'n'; outp++; break; case '\r': *outp = 'r'; outp++; break; case '\t': *outp = 't'; outp++; break; case '\\': *outp = '\\'; outp++; break; } inp++; } } *outp = '\0'; return buf; } void nldecode(unsigned char *msg) { unsigned char *inp = msg; unsigned char *outp = msg; int n; if ((msg == NULL) || (*msg == '\0')) return; while (*inp) { n = strcspn(inp, "\\"); if (n > 0) { if (inp != outp) memmove(outp, inp, n); inp += n; outp += n; } /* *inp is either a backslash or a \0 */ if (*inp == '\\') { inp++; switch (*inp) { case 'p': *outp = '|'; outp++; inp++; break; case 'r': *outp = '\r'; outp++; inp++; break; case 'n': *outp = '\n'; outp++; inp++; break; case 't': *outp = '\t'; outp++; inp++; break; case '\\': *outp = '\\'; outp++; inp++; break; } } } *outp = '\0'; } xymon-4.3.30/lib/timing.h0000664000076400007640000000205112000046362015400 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __TIMING_H__ #define __TIMING_H__ extern int timing; extern void add_timestamp(const char *msg); extern void show_timestamps(char **buffer); extern long total_runtime(void); extern time_t gettimer(void); extern void getntimer(struct timespec *tp); extern int ntimerus(struct timespec *start, struct timespec *now); #endif xymon-4.3.30/lib/calc.h0000664000076400007640000000147711615341300015027 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CALC_H__ #define __CALC_H__ 1 extern long compute(char *expression, int *error); #endif xymon-4.3.30/lib/webaccess.h0000664000076400007640000000201111664526142016062 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __WEBACCESS_H__ #define __WEBACCESS_H__ typedef enum { WEB_ACCESS_VIEW, WEB_ACCESS_CONTROL, WEB_ACCESS_ADMIN } web_access_type_t; extern void *load_web_access_config(char *accessfn); extern int web_access_allowed(char *username, char *hostname, char *testname, web_access_type_t acc); #endif xymon-4.3.30/lib/ipaccess.h0000664000076400007640000000227711615341300015716 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __IPACCESS_H__ #define __IPACCESS_H__ #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif typedef struct sender_t { unsigned long int ipval; int ipmask; } sender_t; extern sender_t *getsenderlist(char *iplist); extern int oksender(sender_t *oklist, char *targetip, struct in_addr sender, char *msgbuf); #endif xymon-4.3.30/lib/matching.h0000664000076400007640000000345212621055261015720 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __MATCHING_H__ #define __MATCHING_H__ /* The clients probably don't have the pcre headers */ #if defined(LOCALCLIENT) || !defined(CLIENTONLY) #include #include extern pcre *compileregex(const char *pattern); extern pcre *compileregex_opts(const char *pattern, int flags); #ifdef PCRE_FIRSTLINE #define firstlineregex(P) compileregex_opts(P, PCRE_FIRSTLINE); #define firstlineregexnocase(P) compileregex_opts(P, PCRE_CASELESS|PCRE_FIRSTLINE); #else #define firstlineregex(P) compileregex_opts(P, 0); #define firstlineregexnocase(P) compileregex_opts(P, PCRE_CASELESS); #endif extern pcre *multilineregex(const char *pattern); extern int matchregex(const char *needle, pcre *pcrecode); extern void freeregex(pcre *pcrecode); extern int namematch(const char *needle, char *haystack, pcre *pcrecode); extern int patternmatch(char *datatosearch, char *pattern, pcre *pcrecode); extern pcre **compile_exprs(char *id, const char **patterns, int count); extern int pickdata(char *buf, pcre *expr, int dupok, ...); extern int timematch(char *holidaykey, char *tspec); #endif #endif xymon-4.3.30/lib/strfunc.c0000664000076400007640000001474012501343647015614 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains string handling routines. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: strfunc.c 7600 2015-03-15 17:55:51Z jccleaver $"; #include "config.h" #include #include #include #include #include #include "libxymon.h" #include "version.h" #define BUFSZINCREMENT 4096 strbuffer_t *newstrbuffer(int initialsize) { strbuffer_t *newbuf; newbuf = calloc(1, sizeof(strbuffer_t)); if (!initialsize) initialsize = 4096; newbuf->s = (char *)malloc(initialsize); if (newbuf->s == NULL) { errprintf("newstrbuffer: Attempt to allocate failed (initialsize=%d): %s\n", initialsize, strerror(errno)); xfree(newbuf); return NULL; } *(newbuf->s) = '\0'; newbuf->sz = initialsize; return newbuf; } strbuffer_t *convertstrbuffer(char *buffer, int bufsz) { strbuffer_t *newbuf; newbuf = calloc(1, sizeof(strbuffer_t)); newbuf->s = buffer; newbuf->used = strlen(buffer); newbuf->sz = (bufsz ? bufsz : newbuf->used+1); return newbuf; } void freestrbuffer(strbuffer_t *buf) { if (buf == NULL) return; if (buf->s) xfree(buf->s); xfree(buf); } void clearstrbuffer(strbuffer_t *buf) { if (buf == NULL) return; if (buf->s) { *(buf->s) = '\0'; buf->used = 0; } } char *grabstrbuffer(strbuffer_t *buf) { char *result; if (buf == NULL) return NULL; result = buf->s; xfree(buf); return result; } strbuffer_t *dupstrbuffer(char *src) { strbuffer_t *newbuf; int len = 0; newbuf = newstrbuffer(0); if (src) { newbuf->s = strdup(src); len = strlen(src); newbuf->used = newbuf->sz = len; } return newbuf; } static void strbuf_addtobuffer(strbuffer_t *buf, char *newtext, int newlen) { if (buf->s == NULL) { buf->used = 0; buf->sz = newlen + BUFSZINCREMENT; buf->s = (char *) malloc(buf->sz); *(buf->s) = '\0'; } else if ((buf->used + newlen + 1) > buf->sz) { buf->sz += (newlen + BUFSZINCREMENT); buf->s = (char *) realloc(buf->s, buf->sz); } if (newtext) { memcpy(buf->s+buf->used, newtext, newlen); buf->used += newlen; /* Make sure result buffer is NUL-terminated; newtext might not be. */ *(buf->s + buf->used) = '\0'; } } void addtobuffer(strbuffer_t *buf, char *newtext) { if (newtext) strbuf_addtobuffer(buf, newtext, strlen(newtext)); } void addtobuffer_many(strbuffer_t *buf, ...) { va_list ap; char *newtext; va_start(ap, buf); newtext = va_arg(ap, char *); while (newtext) { strbuf_addtobuffer(buf, newtext, strlen(newtext)); newtext = va_arg(ap, char *); } va_end(ap); } void addtostrbuffer(strbuffer_t *buf, strbuffer_t *newtext) { strbuf_addtobuffer(buf, STRBUF(newtext), STRBUFLEN(newtext)); } void addtobufferraw(strbuffer_t *buf, char *newdata, int bytes) { /* Add binary data to the buffer */ strbuf_addtobuffer(buf, newdata, bytes); } void strbufferchop(strbuffer_t *buf, int count) { /* Remove COUNT characters from end of buffer */ if ((buf == NULL) || (buf->s == NULL)) return; if (count >= buf->used) count = buf->used; buf->used -= count; *(buf->s+buf->used) = '\0'; } void strbufferrecalc(strbuffer_t *buf) { if (buf == NULL) return; if (buf->s == NULL) { buf->used = 0; return; } buf->used = strlen(buf->s); } void strbuffergrow(strbuffer_t *buf, int bytes) { if (buf == NULL) return; buf->sz += bytes; buf->s = (char *) realloc(buf->s, buf->sz); } void strbufferuse(strbuffer_t *buf, int bytes) { if (buf == NULL) return; if ((buf->used + bytes) < buf->sz) { buf->used += bytes; } else { errprintf("strbuffer: Attempt to use more than allocated (sz=%d, used=%d, growbytes=%d\n", buf->sz, buf->used, bytes); } *(buf->s+buf->used) = '\0'; } char *htmlquoted(char *s) { /* * This routine converts a plain string into an html-quoted string */ static strbuffer_t *result = NULL; char *inp, *endp; char c; if (!s) return NULL; if (!result) result = newstrbuffer(4096); clearstrbuffer(result); inp = s; do { endp = inp + strcspn(inp, "\"&<> "); c = *endp; if (endp > inp) addtobufferraw(result, inp, endp-inp); switch (c) { case '"': addtobuffer(result, """); break; case '&': addtobuffer(result, "&"); break; case '<': addtobuffer(result, "<"); break; case '>': addtobuffer(result, ">"); break; case ' ': addtobuffer(result, " "); break; default: break; } inp = (c == '\0') ? NULL : endp+1; } while (inp); return STRBUF(result); } char *prehtmlquoted(char *s) { /* * This routine converts a string which may contain html to a string * safe to include in a PRE block. It's similar to above, but escapes * only the minmum characters for efficiency. */ static strbuffer_t *result = NULL; char *inp, *endp; char c; if (!s) return NULL; if (!result) result = newstrbuffer(4096); clearstrbuffer(result); inp = s; do { endp = inp + strcspn(inp, "&<>"); c = *endp; if (endp > inp) addtobufferraw(result, inp, endp-inp); switch (c) { case '&': addtobuffer(result, "&"); break; case '<': addtobuffer(result, "<"); break; case '>': addtobuffer(result, ">"); break; // this is not, strictly speaking, needed, but unbalanced encoding might confuse automated readers default: break; } inp = (c == '\0') ? NULL : endp+1; } while (inp); return STRBUF(result); } strbuffer_t *replacetext(char *original, char *oldtext, char *newtext) { strbuffer_t *result = newstrbuffer(0); char *pos = original, *start; do { start = pos; pos = strstr(pos, oldtext); if (pos) { if (pos > start) strbuf_addtobuffer(result, start, (pos - start)); addtobuffer(result, newtext); pos += strlen(oldtext); } else addtobuffer(result, start); } while (pos); return result; } xymon-4.3.30/lib/xymond_buffer.h0000664000076400007640000000173112174246230016774 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __XYMOND_BUFFER_H__ #define __XYMOND_BUFFER_H__ enum msgchannels_t { C_STATUS=1, C_STACHG, C_PAGE, C_DATA, C_NOTES, C_ENADIS, C_CLIENT, C_CLICHG, C_USER, C_FEEDBACK_QUEUE, C_LAST }; extern unsigned int shbufsz(enum msgchannels_t chnid); #endif xymon-4.3.30/lib/timefunc.h0000664000076400007640000000266212000046362015733 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __TIMEFUNC_H__ #define __TIMEFUNC_H__ extern time_t fakestarttime; extern char *timestamp; extern time_t getcurrenttime(time_t *retparm); #define time(X) getcurrenttime(X) extern void init_timestamp(void); extern char *timespec_text(char *spec); extern struct timespec *tvdiff(struct timespec *tstart, struct timespec *tend, struct timespec *result); extern int within_sla(char *holidaykey, char *timespec, int defresult); extern int periodcoversnow(char *tag); extern char *histlogtime(time_t histtime); extern int durationvalue(char *dur); extern char *durationstring(time_t secs); extern char *agestring(time_t secs); extern time_t timestr2timet(char *s); extern time_t eventreport_time(char *timestamp); #endif xymon-4.3.30/lib/rmd160c.c0000664000076400007640000003516213515623702015304 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was taken from the */ /* FreeBSD sources. It was originally written by Eric Young, and is NOT */ /* licensed under the GPL. Please adhere the original copyright notice below. */ /*----------------------------------------------------------------------------*/ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #include #include #include #include "rmd_locl.h" /* * The assembly-language code is not position-independent, so don't * try to use it in a shared library. */ #ifdef PIC #undef RMD160_ASM #endif // static char *RMD160_version="RIPEMD160 part of SSLeay 0.9.0b 11-Oct-1998"; #ifdef RMD160_ASM static void ripemd160_block_x86(RIPEMD160_CTX *c, const u_int32_t *p,int num); #define ripemd160_block ripemd160_block_x86 #else static void ripemd160_block(RIPEMD160_CTX *c, const u_int32_t *p,int num); #endif static void RIPEMD160_Init(c) RIPEMD160_CTX *c; { c->A=RIPEMD160_A; c->B=RIPEMD160_B; c->C=RIPEMD160_C; c->D=RIPEMD160_D; c->E=RIPEMD160_E; c->Nl=0; c->Nh=0; c->num=0; } static void RIPEMD160_Update(c, in, len) RIPEMD160_CTX *c; const void *in; size_t len; { u_int32_t *p; int sw,sc; u_int32_t l; const unsigned char *data = in; if (len == 0) return; l=(c->Nl+(len<<3))&0xffffffffL; if (l < c->Nl) /* overflow */ c->Nh++; c->Nh+=(len>>29); c->Nl=l; if (c->num != 0) { p=c->data; sw=c->num>>2; sc=c->num&0x03; if ((c->num+len) >= RIPEMD160_CBLOCK) { l= p[sw]; p_c2l(data,l,sc); p[sw++]=l; for (; swnum); ripemd160_block(c,p,64); c->num=0; /* drop through and do the rest */ } else { int ew,ec; c->num+=(int)len; if ((sc+len) < 4) /* ugly, add char's to a word */ { l= p[sw]; p_c2l_p(data,l,sc,len); p[sw]=l; } else { ew=(c->num>>2); ec=(c->num&0x03); l= p[sw]; p_c2l(data,l,sc); p[sw++]=l; for (; sw < ew; sw++) { c2l(data,l); p[sw]=l; } if (ec) { c2l_p(data,l,ec); p[sw]=l; } } return; } } /* we now can process the input data in blocks of RIPEMD160_CBLOCK * chars and save the leftovers to c->data. */ #if BYTE_ORDER == LITTLE_ENDIAN if ((((unsigned long)data)%sizeof(u_int32_t)) == 0) { sw=(int)len/RIPEMD160_CBLOCK; if (sw > 0) { sw*=RIPEMD160_CBLOCK; ripemd160_block(c,(u_int32_t *)data,sw); data+=sw; len-=sw; } } #endif p=c->data; while (len >= RIPEMD160_CBLOCK) { #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == BIG_ENDIAN if (p != (u_int32_t *)data) memcpy(p,data,RIPEMD160_CBLOCK); data+=RIPEMD160_CBLOCK; #if BYTE_ORDER == BIG_ENDIAN for (sw=(RIPEMD160_LBLOCK/4); sw; sw--) { Endian_Reverse32(p[0]); Endian_Reverse32(p[1]); Endian_Reverse32(p[2]); Endian_Reverse32(p[3]); p+=4; } #endif #else for (sw=(RIPEMD160_LBLOCK/4); sw; sw--) { c2l(data,l); *(p++)=l; c2l(data,l); *(p++)=l; c2l(data,l); *(p++)=l; c2l(data,l); *(p++)=l; } #endif p=c->data; ripemd160_block(c,p,64); len-=RIPEMD160_CBLOCK; } sc=(int)len; c->num=sc; if (sc) { sw=sc>>2; /* words to copy */ #if BYTE_ORDER == LITTLE_ENDIAN p[sw]=0; memcpy(p,data,sc); #else sc&=0x03; for ( ; sw; sw--) { c2l(data,l); *(p++)=l; } c2l_p(data,l,sc); *p=l; #endif } } #ifndef RMD160_ASM static void ripemd160_block(ctx, X, num) RIPEMD160_CTX *ctx; const u_int32_t *X; int num; { u_int32_t A,B,C,D,E; u_int32_t a,b,c,d,e; for (;;) { A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E; RIP1(A,B,C,D,E,WL00,SL00); RIP1(E,A,B,C,D,WL01,SL01); RIP1(D,E,A,B,C,WL02,SL02); RIP1(C,D,E,A,B,WL03,SL03); RIP1(B,C,D,E,A,WL04,SL04); RIP1(A,B,C,D,E,WL05,SL05); RIP1(E,A,B,C,D,WL06,SL06); RIP1(D,E,A,B,C,WL07,SL07); RIP1(C,D,E,A,B,WL08,SL08); RIP1(B,C,D,E,A,WL09,SL09); RIP1(A,B,C,D,E,WL10,SL10); RIP1(E,A,B,C,D,WL11,SL11); RIP1(D,E,A,B,C,WL12,SL12); RIP1(C,D,E,A,B,WL13,SL13); RIP1(B,C,D,E,A,WL14,SL14); RIP1(A,B,C,D,E,WL15,SL15); RIP2(E,A,B,C,D,WL16,SL16,KL1); RIP2(D,E,A,B,C,WL17,SL17,KL1); RIP2(C,D,E,A,B,WL18,SL18,KL1); RIP2(B,C,D,E,A,WL19,SL19,KL1); RIP2(A,B,C,D,E,WL20,SL20,KL1); RIP2(E,A,B,C,D,WL21,SL21,KL1); RIP2(D,E,A,B,C,WL22,SL22,KL1); RIP2(C,D,E,A,B,WL23,SL23,KL1); RIP2(B,C,D,E,A,WL24,SL24,KL1); RIP2(A,B,C,D,E,WL25,SL25,KL1); RIP2(E,A,B,C,D,WL26,SL26,KL1); RIP2(D,E,A,B,C,WL27,SL27,KL1); RIP2(C,D,E,A,B,WL28,SL28,KL1); RIP2(B,C,D,E,A,WL29,SL29,KL1); RIP2(A,B,C,D,E,WL30,SL30,KL1); RIP2(E,A,B,C,D,WL31,SL31,KL1); RIP3(D,E,A,B,C,WL32,SL32,KL2); RIP3(C,D,E,A,B,WL33,SL33,KL2); RIP3(B,C,D,E,A,WL34,SL34,KL2); RIP3(A,B,C,D,E,WL35,SL35,KL2); RIP3(E,A,B,C,D,WL36,SL36,KL2); RIP3(D,E,A,B,C,WL37,SL37,KL2); RIP3(C,D,E,A,B,WL38,SL38,KL2); RIP3(B,C,D,E,A,WL39,SL39,KL2); RIP3(A,B,C,D,E,WL40,SL40,KL2); RIP3(E,A,B,C,D,WL41,SL41,KL2); RIP3(D,E,A,B,C,WL42,SL42,KL2); RIP3(C,D,E,A,B,WL43,SL43,KL2); RIP3(B,C,D,E,A,WL44,SL44,KL2); RIP3(A,B,C,D,E,WL45,SL45,KL2); RIP3(E,A,B,C,D,WL46,SL46,KL2); RIP3(D,E,A,B,C,WL47,SL47,KL2); RIP4(C,D,E,A,B,WL48,SL48,KL3); RIP4(B,C,D,E,A,WL49,SL49,KL3); RIP4(A,B,C,D,E,WL50,SL50,KL3); RIP4(E,A,B,C,D,WL51,SL51,KL3); RIP4(D,E,A,B,C,WL52,SL52,KL3); RIP4(C,D,E,A,B,WL53,SL53,KL3); RIP4(B,C,D,E,A,WL54,SL54,KL3); RIP4(A,B,C,D,E,WL55,SL55,KL3); RIP4(E,A,B,C,D,WL56,SL56,KL3); RIP4(D,E,A,B,C,WL57,SL57,KL3); RIP4(C,D,E,A,B,WL58,SL58,KL3); RIP4(B,C,D,E,A,WL59,SL59,KL3); RIP4(A,B,C,D,E,WL60,SL60,KL3); RIP4(E,A,B,C,D,WL61,SL61,KL3); RIP4(D,E,A,B,C,WL62,SL62,KL3); RIP4(C,D,E,A,B,WL63,SL63,KL3); RIP5(B,C,D,E,A,WL64,SL64,KL4); RIP5(A,B,C,D,E,WL65,SL65,KL4); RIP5(E,A,B,C,D,WL66,SL66,KL4); RIP5(D,E,A,B,C,WL67,SL67,KL4); RIP5(C,D,E,A,B,WL68,SL68,KL4); RIP5(B,C,D,E,A,WL69,SL69,KL4); RIP5(A,B,C,D,E,WL70,SL70,KL4); RIP5(E,A,B,C,D,WL71,SL71,KL4); RIP5(D,E,A,B,C,WL72,SL72,KL4); RIP5(C,D,E,A,B,WL73,SL73,KL4); RIP5(B,C,D,E,A,WL74,SL74,KL4); RIP5(A,B,C,D,E,WL75,SL75,KL4); RIP5(E,A,B,C,D,WL76,SL76,KL4); RIP5(D,E,A,B,C,WL77,SL77,KL4); RIP5(C,D,E,A,B,WL78,SL78,KL4); RIP5(B,C,D,E,A,WL79,SL79,KL4); a=A; b=B; c=C; d=D; e=E; /* Do other half */ A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E; RIP5(A,B,C,D,E,WR00,SR00,KR0); RIP5(E,A,B,C,D,WR01,SR01,KR0); RIP5(D,E,A,B,C,WR02,SR02,KR0); RIP5(C,D,E,A,B,WR03,SR03,KR0); RIP5(B,C,D,E,A,WR04,SR04,KR0); RIP5(A,B,C,D,E,WR05,SR05,KR0); RIP5(E,A,B,C,D,WR06,SR06,KR0); RIP5(D,E,A,B,C,WR07,SR07,KR0); RIP5(C,D,E,A,B,WR08,SR08,KR0); RIP5(B,C,D,E,A,WR09,SR09,KR0); RIP5(A,B,C,D,E,WR10,SR10,KR0); RIP5(E,A,B,C,D,WR11,SR11,KR0); RIP5(D,E,A,B,C,WR12,SR12,KR0); RIP5(C,D,E,A,B,WR13,SR13,KR0); RIP5(B,C,D,E,A,WR14,SR14,KR0); RIP5(A,B,C,D,E,WR15,SR15,KR0); RIP4(E,A,B,C,D,WR16,SR16,KR1); RIP4(D,E,A,B,C,WR17,SR17,KR1); RIP4(C,D,E,A,B,WR18,SR18,KR1); RIP4(B,C,D,E,A,WR19,SR19,KR1); RIP4(A,B,C,D,E,WR20,SR20,KR1); RIP4(E,A,B,C,D,WR21,SR21,KR1); RIP4(D,E,A,B,C,WR22,SR22,KR1); RIP4(C,D,E,A,B,WR23,SR23,KR1); RIP4(B,C,D,E,A,WR24,SR24,KR1); RIP4(A,B,C,D,E,WR25,SR25,KR1); RIP4(E,A,B,C,D,WR26,SR26,KR1); RIP4(D,E,A,B,C,WR27,SR27,KR1); RIP4(C,D,E,A,B,WR28,SR28,KR1); RIP4(B,C,D,E,A,WR29,SR29,KR1); RIP4(A,B,C,D,E,WR30,SR30,KR1); RIP4(E,A,B,C,D,WR31,SR31,KR1); RIP3(D,E,A,B,C,WR32,SR32,KR2); RIP3(C,D,E,A,B,WR33,SR33,KR2); RIP3(B,C,D,E,A,WR34,SR34,KR2); RIP3(A,B,C,D,E,WR35,SR35,KR2); RIP3(E,A,B,C,D,WR36,SR36,KR2); RIP3(D,E,A,B,C,WR37,SR37,KR2); RIP3(C,D,E,A,B,WR38,SR38,KR2); RIP3(B,C,D,E,A,WR39,SR39,KR2); RIP3(A,B,C,D,E,WR40,SR40,KR2); RIP3(E,A,B,C,D,WR41,SR41,KR2); RIP3(D,E,A,B,C,WR42,SR42,KR2); RIP3(C,D,E,A,B,WR43,SR43,KR2); RIP3(B,C,D,E,A,WR44,SR44,KR2); RIP3(A,B,C,D,E,WR45,SR45,KR2); RIP3(E,A,B,C,D,WR46,SR46,KR2); RIP3(D,E,A,B,C,WR47,SR47,KR2); RIP2(C,D,E,A,B,WR48,SR48,KR3); RIP2(B,C,D,E,A,WR49,SR49,KR3); RIP2(A,B,C,D,E,WR50,SR50,KR3); RIP2(E,A,B,C,D,WR51,SR51,KR3); RIP2(D,E,A,B,C,WR52,SR52,KR3); RIP2(C,D,E,A,B,WR53,SR53,KR3); RIP2(B,C,D,E,A,WR54,SR54,KR3); RIP2(A,B,C,D,E,WR55,SR55,KR3); RIP2(E,A,B,C,D,WR56,SR56,KR3); RIP2(D,E,A,B,C,WR57,SR57,KR3); RIP2(C,D,E,A,B,WR58,SR58,KR3); RIP2(B,C,D,E,A,WR59,SR59,KR3); RIP2(A,B,C,D,E,WR60,SR60,KR3); RIP2(E,A,B,C,D,WR61,SR61,KR3); RIP2(D,E,A,B,C,WR62,SR62,KR3); RIP2(C,D,E,A,B,WR63,SR63,KR3); RIP1(B,C,D,E,A,WR64,SR64); RIP1(A,B,C,D,E,WR65,SR65); RIP1(E,A,B,C,D,WR66,SR66); RIP1(D,E,A,B,C,WR67,SR67); RIP1(C,D,E,A,B,WR68,SR68); RIP1(B,C,D,E,A,WR69,SR69); RIP1(A,B,C,D,E,WR70,SR70); RIP1(E,A,B,C,D,WR71,SR71); RIP1(D,E,A,B,C,WR72,SR72); RIP1(C,D,E,A,B,WR73,SR73); RIP1(B,C,D,E,A,WR74,SR74); RIP1(A,B,C,D,E,WR75,SR75); RIP1(E,A,B,C,D,WR76,SR76); RIP1(D,E,A,B,C,WR77,SR77); RIP1(C,D,E,A,B,WR78,SR78); RIP1(B,C,D,E,A,WR79,SR79); D =ctx->B+c+D; ctx->B=ctx->C+d+E; ctx->C=ctx->D+e+A; ctx->D=ctx->E+a+B; ctx->E=ctx->A+b+C; ctx->A=D; X+=16; num-=64; if (num <= 0) break; } } #endif static void RIPEMD160_Final(md, c) unsigned char *md; RIPEMD160_CTX *c; { int i,j; u_int32_t l; u_int32_t *p; static unsigned char end[4]={0x80,0x00,0x00,0x00}; unsigned char *cp=end; /* c->num should definitly have room for at least one more byte. */ p=c->data; j=c->num; i=j>>2; /* purify often complains about the following line as an * Uninitialized Memory Read. While this can be true, the * following p_c2l macro will reset l when that case is true. * This is because j&0x03 contains the number of 'valid' bytes * already in p[i]. If and only if j&0x03 == 0, the UMR will * occur but this is also the only time p_c2l will do * l= *(cp++) instead of l|= *(cp++) * Many thanks to Alex Tang for pickup this * 'potential bug' */ #ifdef PURIFY if ((j&0x03) == 0) p[i]=0; #endif l=p[i]; p_c2l(cp,l,j&0x03); p[i]=l; i++; /* i is the next 'undefined word' */ if (c->num >= RIPEMD160_LAST_BLOCK) { for (; iNl; p[RIPEMD160_LBLOCK-1]=c->Nh; ripemd160_block(c,p,64); cp=md; l=c->A; l2c(l,cp); l=c->B; l2c(l,cp); l=c->C; l2c(l,cp); l=c->D; l2c(l,cp); l=c->E; l2c(l,cp); /* clear stuff, ripemd160_block may be leaving some stuff on the stack * but I'm not worried :-) */ c->num=0; /* memset((char *)&c,0,sizeof(c));*/ } #ifdef undef int printit(l) unsigned long *l; { int i,ii; for (i=0; i<2; i++) { for (ii=0; ii<8; ii++) { fprintf(stderr,"%08lx ",l[i*8+ii]); } fprintf(stderr,"\n"); } } #endif /* Added for Xymon - not part of the original file */ int myRIPEMD160_Size(void) { return sizeof(RIPEMD160_CTX); } void myRIPEMD160_Init(void *c) { RIPEMD160_Init((RIPEMD160_CTX *)c); } void myRIPEMD160_Update(void *c, unsigned char *in, int len) {RIPEMD160_Update((RIPEMD160_CTX *)c, in, len); } void myRIPEMD160_Final(char md[20], void *c) { RIPEMD160_Final(md, (RIPEMD160_CTX *)c); } #ifdef STANDALONE #include #include int main(int argc, char *argv[]) { FILE *fd; unsigned char buf[8192]; int buflen, i; unsigned char md[20]; char md_string[41]; char *p; void *c; fd = fopen(argv[1], "r"); if (fd == NULL) return 1; c = (void *)malloc(myRIPEMD160_Size()); myRIPEMD160_Init(c); while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) myRIPEMD160_Update(c, buf, buflen); fclose(fd); myRIPEMD160_Final(md, c); for(i = 0, p = md_string; (i < sizeof(md)); i++) p += snprintf(p, (sizeof(md_string) - (p - md_string)), "%02x", md[i]); *p = '\0'; printf("%s\n", md_string); return 0; } #endif xymon-4.3.30/lib/webaccess.c0000664000076400007640000000642213515623702016064 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for web access control. */ /* */ /* Copyright (C) 2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: misc.c 6712 2011-07-31 21:01:52Z storner $"; #include #include "config.h" #include "libxymon.h" void *acctree = NULL; void *load_web_access_config(char *accessfn) { FILE *fd; strbuffer_t *buf; if (acctree) return 0; acctree = xtreeNew(strcasecmp); fd = stackfopen(accessfn, "r", NULL); if (fd == NULL) return NULL; buf = newstrbuffer(0); while (stackfgets(buf, NULL)) { char *group, *member; SBUF_DEFINE(key); group = strtok(STRBUF(buf), ": \n"); if (!group) continue; member = strtok(NULL, ", \n"); while (member) { SBUF_MALLOC(key, strlen(group) + strlen(member) + 2); snprintf(key, key_buflen, "%s %s", group, member); xtreeAdd(acctree, key, NULL); member = strtok(NULL, ", \n"); } } stackfclose(fd); return acctree; } int web_access_allowed(char *username, char *hostname, char *testname, web_access_type_t acc) { void *hinfo; char *pages, *onepg; SBUF_DEFINE(key); hinfo = hostinfo(hostname); if (!hinfo || !acctree || !username) return 0; /* Check for "root" access first */ SBUF_MALLOC(key, strlen(username) + 6); snprintf(key, key_buflen, "root %s", username); if (xtreeFind(acctree, key) != xtreeEnd(acctree)) { xfree(key); return 1; } xfree(key); pages = strdup(xmh_item(hinfo, XMH_ALLPAGEPATHS)); onepg = strtok(pages, ","); while (onepg) { char *p; p = strchr(onepg, '/'); if (p) *p = '\0'; /* Will only look at the top-level path element */ SBUF_MALLOC(key, strlen(onepg) + strlen(username) + 2); snprintf(key, key_buflen, "%s %s", onepg, username); if (xtreeFind(acctree, key) != xtreeEnd(acctree)) { xfree(key); xfree(pages); return 1; } xfree(key); onepg = strtok(NULL, ","); } xfree(pages); if (hostname) { /* See if user is a member of a group named by the hostname */ SBUF_MALLOC(key, strlen(hostname) + strlen(username) + 2); snprintf(key, key_buflen, "%s %s", hostname, username); if (xtreeFind(acctree, key) != xtreeEnd(acctree)) { xfree(key); return 1; } xfree(key); } if (testname) { /* See if user is a member of a group named by the testname */ SBUF_MALLOC(key, strlen(testname) + strlen(username) + 2); snprintf(key, key_buflen, "%s %s", testname, username); if (xtreeFind(acctree, key) != xtreeEnd(acctree)) { xfree(key); return 1; } xfree(key); } return 0; } xymon-4.3.30/lib/misc.h0000664000076400007640000000447212656201271015066 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __MISC_H__ #define __MISC_H__ #include enum ostype_t { OS_UNKNOWN, OS_SOLARIS, OS_OSF, OS_AIX, OS_HPUX, OS_WIN32, OS_FREEBSD, OS_NETBSD, OS_OPENBSD, OS_LINUX22, OS_LINUX, OS_RHEL3, OS_SNMP, OS_IRIX, OS_DARWIN, OS_SCO_SV, OS_NETWARE_SNMP, OS_WIN32_HMDC, OS_WIN32_BBWIN, OS_WIN_POWERSHELL, OS_ZVM, OS_ZVSE, OS_ZOS, OS_SNMPCOLLECT, OS_MQCOLLECT, OS_GNUKFREEBSD } ; extern enum ostype_t get_ostype(char *osname); extern char *osname(enum ostype_t os); extern int hexvalue(unsigned char c); extern char *commafy(char *hostname); extern void uncommafy(char *hostname); extern char *skipword(char *l); extern char *skipwhitespace(char *l); extern char *stripnonwords(char *l); extern int argnmatch(char *arg, char *match); extern char *msg_data(char *msg, int stripcr); extern char *gettok(char *s, char *delims); extern char *wstok(char *s); extern void sanitize_input(strbuffer_t *l, int stripcomment, int unescape); extern unsigned int IPtou32(int ip1, int ip2, int ip3, int ip4); extern char *u32toIP(unsigned int ip32); extern const char *textornull(const char *text); extern int issimpleword(const char *text); extern int get_fqdn(void); extern int generate_static(void); extern void do_extensions(FILE *output, char *extenv, char *family); extern char **setup_commandargs(char *cmdline, char **cmd); extern int checkalert(char *alertlist, char *test); extern long long str2ll(char *s, char **errptr); extern char *nextcolumn(char *s); extern int selectcolumn(char *heading, char *wanted); extern char *getcolumn(char *s, int wanted); extern int chkfreespace(char *path, int minblks, int mininodes); #endif xymon-4.3.30/lib/links.h0000664000076400007640000000164011622212202015231 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LINKS_H__ #define __LINKS_H__ extern char *link_docext(char *fn); extern void load_all_links(void); extern char *columnlink(char *colname); extern char *hostlink(char *hostname); #endif xymon-4.3.30/lib/suid.h0000664000076400007640000000156311615341300015065 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __SUID_H__ #define __SUID_H__ extern void drop_root(void); extern void get_root(void); extern void drop_root_and_removesuid(char *fn); #endif xymon-4.3.30/lib/sendmsg.c0000664000076400007640000005675513515623702015603 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for communicating with the Xymon daemon */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: sendmsg.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #define SENDRETRIES 2 /* These commands go to all Xymon servers */ static char *multircptcmds[] = { "status", "combo", "extcombo", "meta", "data", "notify", "enable", "disable", "drop", "rename", "client", NULL }; static char errordetails[1024]; /* Stuff for combo message handling */ int xymonmsgcount = 0; /* Number of messages transmitted */ int xymonstatuscount = 0; /* Number of status items reported */ int xymonnocombocount = 0; /* Number of status items reported outside combo msgs */ static int xymonmsgqueued; /* Anything in the buffer ? */ static strbuffer_t *xymonmsg = NULL; /* Complete combo message buffer */ static strbuffer_t *msgbuf = NULL; /* message buffer for one status message */ static int msgcolor; /* color of status message in msgbuf */ static int combo_is_local = 0; static int maxmsgspercombo = 100; /* 0 = no limit. 100 is a reasonable default. */ static int sleepbetweenmsgs = 0; static int xymondportnumber = 0; static char *xymonproxyhost = NULL; static int xymonproxyport = 0; static char *proxysetting = NULL; static char *comboofsstr = NULL; static int comboofssz = 0; static int *combooffsets = NULL; static int xymonmetaqueued; /* Anything in the buffer ? */ static strbuffer_t *metamsg = NULL; /* Complete meta message buffer */ static strbuffer_t *metabuf = NULL; /* message buffer for one meta message */ static int backfeedqueue = -1; static int max_backfeedsz = 16384; int dontsendmessages = 0; void setproxy(char *proxy) { if (proxysetting) xfree(proxysetting); proxysetting = strdup(proxy); } static void setup_transport(char *recipient) { static int transport_is_setup = 0; int default_port; if (transport_is_setup) return; transport_is_setup = 1; if (strncmp(recipient, "http://", 7) == 0) { /* * Send messages via http. This requires e.g. a CGI on the webserver to * receive the POST we do here. */ default_port = 80; if (proxysetting == NULL) proxysetting = getenv("http_proxy"); if (proxysetting) { char *p; xymonproxyhost = strdup(proxysetting); if (strncmp(xymonproxyhost, "http://", 7) == 0) xymonproxyhost += strlen("http://"); p = strchr(xymonproxyhost, ':'); if (p) { *p = '\0'; p++; xymonproxyport = atoi(p); } else { xymonproxyport = 8080; } } } else { /* * Non-HTTP transport - lookup portnumber in both XYMONDPORT env. * and the "xymond" entry from /etc/services. */ default_port = 1984; if (xgetenv("XYMONDPORT")) xymondportnumber = atoi(xgetenv("XYMONDPORT")); /* Next is /etc/services "bbd" entry */ if ((xymondportnumber <= 0) || (xymondportnumber > 65535)) { struct servent *svcinfo; svcinfo = getservbyname("bbd", NULL); if (!svcinfo) svcinfo = getservbyname("bb", NULL); if (svcinfo) xymondportnumber = ntohs(svcinfo->s_port); } } /* Last resort: The default value */ if ((xymondportnumber <= 0) || (xymondportnumber > 65535)) { xymondportnumber = default_port; } dbgprintf("Transport setup is:\n"); dbgprintf("xymondportnumber = %d\n", xymondportnumber); dbgprintf("xymonproxyhost = %s\n", (xymonproxyhost ? xymonproxyhost : "NONE")); dbgprintf("xymonproxyport = %d\n", xymonproxyport); } static int sendtoxymond(char *recipient, char *message, FILE *respfd, char **respstr, int fullresponse, int timeout) { struct in_addr addr; struct sockaddr_in saddr; int sockfd = -1; fd_set readfds; fd_set writefds; int res, isconnected, wdone, rdone; struct timeval tmo; char *msgptr = message; char *p; char *rcptip = NULL; int rcptport = 0; int connretries = SENDRETRIES; SBUF_DEFINE(httpmessage); char recvbuf[32768]; int haveseenhttphdrs = 1; int respstrsz = 0; int respstrlen = 0; int result = XYMONSEND_OK; if (dontsendmessages && !respfd && !respstr) { fprintf(stdout, "%s\n", message); fflush(stdout); return XYMONSEND_OK; } setup_transport(recipient); dbgprintf("Recipient listed as '%s'\n", recipient); if (strncmp(recipient, "http://", strlen("http://")) != 0) { /* Standard communications, directly to Xymon daemon */ rcptip = strdup(recipient); rcptport = xymondportnumber; p = strchr(rcptip, ':'); if (p) { *p = '\0'; p++; rcptport = atoi(p); } dbgprintf("Standard protocol on port %d\n", rcptport); } else { char *posturl = NULL; char *posthost = NULL; if (xymonproxyhost == NULL) { char *p; /* * No proxy. "recipient" is "http://host[:port]/url/for/post" * Strip off "http://", and point "posturl" to the part after the hostname. * If a portnumber is present, strip it off and update rcptport. */ rcptip = strdup(recipient+strlen("http://")); rcptport = xymondportnumber; p = strchr(rcptip, '/'); if (p) { posturl = strdup(p); *p = '\0'; } p = strchr(rcptip, ':'); if (p) { *p = '\0'; p++; rcptport = atoi(p); } posthost = strdup(rcptip); dbgprintf("HTTP protocol directly to host %s\n", posthost); } else { char *p; /* * With proxy. The full "recipient" must be in the POST request. */ rcptip = strdup(xymonproxyhost); rcptport = xymonproxyport; posturl = strdup(recipient); p = strchr(recipient + strlen("http://"), '/'); if (p) { *p = '\0'; posthost = strdup(recipient + strlen("http://")); *p = '/'; p = strchr(posthost, ':'); if (p) *p = '\0'; } dbgprintf("HTTP protocol via proxy to host %s\n", posthost); } if ((posturl == NULL) || (posthost == NULL)) { snprintf(errordetails + strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "Unable to parse HTTP recipient"); if (posturl) xfree(posturl); if (posthost) xfree(posthost); if (rcptip) xfree(rcptip); return XYMONSEND_EBADURL; } SBUF_MALLOC(httpmessage, strlen(message)+strlen(posthost)+1024); msgptr = httpmessage; snprintf(httpmessage, httpmessage_buflen, "POST %s HTTP/1.0\nMIME-version: 1.0\nContent-Type: application/octet-stream\nContent-Length: %d\nHost: %s\n\n%s", posturl, (int)strlen(message), posthost, message); if (posturl) xfree(posturl); if (posthost) xfree(posthost); haveseenhttphdrs = 0; dbgprintf("HTTP message is:\n%s\n", httpmessage); } if (inet_aton(rcptip, &addr) == 0) { /* recipient is not an IP - do DNS lookup */ struct hostent *hent; char hostip[IP_ADDR_STRLEN]; hent = gethostbyname(rcptip); if (hent) { memcpy(&addr, *(hent->h_addr_list), sizeof(struct in_addr)); strncpy(hostip, inet_ntoa(addr), sizeof(hostip)); if (inet_aton(hostip, &addr) == 0) { result = XYMONSEND_EBADIP; goto done; } } else { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "Cannot determine IP address of message recipient %s", rcptip); result = XYMONSEND_EIPUNKNOWN; goto done; } } retry_connect: dbgprintf("Will connect to address %s port %d\n", rcptip, rcptport); memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = addr.s_addr; saddr.sin_port = htons(rcptport); /* Get a non-blocking socket */ sockfd = socket(PF_INET, SOCK_STREAM, 0); if (sockfd == -1) { result = XYMONSEND_ENOSOCKET; goto done; } res = fcntl(sockfd, F_SETFL, O_NONBLOCK); if (res != 0) { result = XYMONSEND_ECANNOTDONONBLOCK; goto done; } res = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)); if ((res == -1) && (errno != EINPROGRESS)) { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "connect to Xymon daemon@%s:%d failed (%s)", rcptip, rcptport, strerror(errno)); result = XYMONSEND_ECONNFAILED; goto done; } rdone = ((respfd == NULL) && (respstr == NULL)); isconnected = wdone = 0; while (!wdone || !rdone) { FD_ZERO(&writefds); FD_ZERO(&readfds); if (!rdone) FD_SET(sockfd, &readfds); if (!wdone) FD_SET(sockfd, &writefds); tmo.tv_sec = timeout; tmo.tv_usec = 0; res = select(sockfd+1, &readfds, &writefds, NULL, (timeout ? &tmo : NULL)); if (res == -1) { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "Select failure while sending to Xymon daemon@%s:%d", rcptip, rcptport); result = XYMONSEND_ESELFAILED; goto done; } else if (res == 0) { /* Timeout! */ shutdown(sockfd, SHUT_RDWR); close(sockfd); if (!isconnected && (connretries > 0)) { dbgprintf("Timeout while talking to Xymon daemon@%s:%d - retrying\n", rcptip, rcptport); connretries--; sleep(1); goto retry_connect; /* Yuck! */ } result = XYMONSEND_ETIMEOUT; goto done; } else { if (!isconnected) { /* Havent seen our connect() status yet - must be now */ int connres; socklen_t connressize = sizeof(connres); res = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &connres, &connressize); dbgprintf("Connect status is %d\n", connres); isconnected = (connres == 0); if (!isconnected) { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "Could not connect to Xymon daemon@%s:%d (%s)", rcptip, rcptport, strerror(connres)); result = XYMONSEND_ECONNFAILED; goto done; } } if (!rdone && FD_ISSET(sockfd, &readfds)) { char *outp; int n; n = recv(sockfd, recvbuf, sizeof(recvbuf)-1, 0); if (n > 0) { dbgprintf("Read %d bytes\n", n); recvbuf[n] = '\0'; /* * When running over a HTTP transport, we must strip * off the HTTP headers we get back, so the response * is consistent with what we get from the normal Xymon daemon * transport. * (Non-http transport sets "haveseenhttphdrs" to 1) */ if (!haveseenhttphdrs) { outp = strstr(recvbuf, "\r\n\r\n"); if (outp) { outp += 4; n -= (outp - recvbuf); haveseenhttphdrs = 1; } else n = 0; } else outp = recvbuf; if (n > 0) { if (respfd) { fwrite(outp, n, 1, respfd); } else if (respstr) { char *respend; if (respstrsz == 0) { respstrsz = (n+sizeof(recvbuf)); *respstr = (char *)malloc(respstrsz); } else if ((n+respstrlen) >= respstrsz) { respstrsz += (n+sizeof(recvbuf)); *respstr = (char *)realloc(*respstr, respstrsz); } respend = (*respstr) + respstrlen; memcpy(respend, outp, n); *(respend + n) = '\0'; respstrlen += n; } if (!fullresponse) { rdone = (strchr(outp, '\n') == NULL); } } } else rdone = 1; if (rdone) shutdown(sockfd, SHUT_RD); } if (!wdone && FD_ISSET(sockfd, &writefds)) { /* Send some data */ res = write(sockfd, msgptr, strlen(msgptr)); if (res == -1) { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "Write error while sending message to Xymon daemon@%s:%d", rcptip, rcptport); result = XYMONSEND_EWRITEERROR; goto done; } else { dbgprintf("Sent %d bytes\n", res); msgptr += res; wdone = (strlen(msgptr) == 0); if (wdone) shutdown(sockfd, SHUT_WR); } } } } done: dbgprintf("Closing connection\n"); shutdown(sockfd, SHUT_RDWR); if (sockfd > 0) close(sockfd); xfree(rcptip); if (httpmessage) xfree(httpmessage); return result; } static int sendtomany(char *onercpt, char *morercpts, char *msg, int timeout, sendreturn_t *response) { int allservers = 1, first = 1, result = XYMONSEND_OK; char *xymondlist, *rcpt; /* * Even though this is the "sendtomany" routine, we need to decide if the * request should go to all servers, or just a single server. The default * is to send to all servers - but commands that trigger a response can * only go to a single server. * * "schedule" is special - when scheduling an action there is no response, but * when it is the blank "schedule" command there will be a response. So a * schedule action goes to all Xymon servers, the blank "schedule" goes to a single * server. */ // errprintf("sendtomany: onercpt=%s\n", onercpt); if (strcmp(onercpt, "0.0.0.0") != 0) allservers = 0; else if (strncmp(msg, "schedule", 8) == 0) /* See if it's just a blank "schedule" command */ allservers = (strcmp(msg, "schedule") != 0); else { char *msgcmd; int i; /* See if this is a multi-recipient command */ i = strspn(msg, "abcdefghijklmnopqrstuvwxyz"); msgcmd = (char *)malloc(i+1); strncpy(msgcmd, msg, i); *(msgcmd+i) = '\0'; // errprintf("sendtomany: msgcmd=%s\n", msgcmd); for (i = 0; (multircptcmds[i] && strcmp(multircptcmds[i], msgcmd)); i++) ; xfree(msgcmd); allservers = (multircptcmds[i] != NULL); } // errprintf("sendtomany: allservers=%d\n", allservers); if (allservers && !morercpts) { snprintf(errordetails+strlen(errordetails), (sizeof(errordetails) - strlen(errordetails)), "No recipients listed! XYMSRV was %s, XYMSERVERS %s", onercpt, textornull(morercpts)); return XYMONSEND_EBADIP; } if (strcmp(onercpt, "0.0.0.0") != 0) xymondlist = strdup(onercpt); else xymondlist = strdup(morercpts); rcpt = strtok(xymondlist, " \t"); while (rcpt) { int oneres; if (first) { /* We grab the result from the first server */ char *respstr = NULL; if (response) { oneres = sendtoxymond(rcpt, msg, response->respfd, (response->respstr ? &respstr : NULL), (response->respfd || response->respstr), timeout); } else { oneres = sendtoxymond(rcpt, msg, NULL, NULL, 0, timeout); } if (oneres == XYMONSEND_OK) { if (respstr && response && response->respstr) { addtobuffer(response->respstr, respstr); xfree(respstr); } first = 0; } } else { /* Secondary servers do not yield a response */ oneres = sendtoxymond(rcpt, msg, NULL, NULL, 0, timeout); } /* Save any error results */ if (result == XYMONSEND_OK) result = oneres; /* * Handle more servers IF we're doing all servers, OR * we are still at the first one (because the previous * ones failed). */ if (allservers || first) rcpt = strtok(NULL, " \t"); else rcpt = NULL; } xfree(xymondlist); return result; } sendreturn_t *newsendreturnbuf(int fullresponse, FILE *respfd) { sendreturn_t *result; result = (sendreturn_t *)calloc(1, sizeof(sendreturn_t)); result->fullresponse = fullresponse; result->respfd = respfd; if (!respfd) { /* No response file, so return it in a strbuf */ result->respstr = newstrbuffer(0); } result->haveseenhttphdrs = 1; return result; } void freesendreturnbuf(sendreturn_t *s) { if (!s) return; if (s->respstr) freestrbuffer(s->respstr); xfree(s); } char *getsendreturnstr(sendreturn_t *s, int takeover) { char *result = NULL; if (!s) return NULL; if (!s->respstr) return NULL; result = STRBUF(s->respstr); if (takeover) { /* * We cannot leave respstr as NULL, because later calls * to sendmessage() might re-use this sendreturn_t struct * and expect to get the data back. So allocate a new * responsebuffer for future use - if it isn't used, it * will be freed by freesendreturnbuf(). */ s->respstr = newstrbuffer(0); } return result; } int sendmessage_init_local(void) { backfeedqueue = setup_feedback_queue(CHAN_CLIENT); if (backfeedqueue == -1) return -1; max_backfeedsz = 1024*shbufsz(C_FEEDBACK_QUEUE)-1; return max_backfeedsz; } void sendmessage_finish_local(void) { close_feedback_queue(backfeedqueue, CHAN_CLIENT); } sendresult_t sendmessage_local(char *msg) { int n, done = 0; #if defined(__OpenBSD__) || defined(__dietlibc__) unsigned long msglen; #else msglen_t msglen; #endif if (backfeedqueue == -1) { return sendmessage(msg, NULL, XYMON_TIMEOUT, NULL); } /* Make sure we dont overflow the message buffer */ msglen = strlen(msg); if (msglen > max_backfeedsz) { errprintf("Truncating backfeed channel message from %d to %d\n", msglen, max_backfeedsz); *(msg+max_backfeedsz) = '\0'; msglen = max_backfeedsz; } /* This will block if queue is full, but that is OK */ do { n = msgsnd(backfeedqueue, msg, msglen+1, 0); if ((n == 0) || ((n == -1) && (errno != EINTR))) done = 1; } while (!done); if (n == -1) { errprintf("Sending via backfeed channel failed: %s\n", strerror(errno)); return XYMONSEND_ECONNFAILED; } return XYMONSEND_OK; } sendresult_t sendmessage(char *msg, char *recipient, int timeout, sendreturn_t *response) { static char *xymsrv = NULL; int res = 0; *errordetails = '\0'; if ((xymsrv == NULL) && xgetenv("XYMSRV")) xymsrv = strdup(xgetenv("XYMSRV")); if (recipient == NULL) recipient = xymsrv; if ((recipient == NULL) && xgetenv("XYMSERVERS")) { recipient = "0.0.0.0"; } else if (recipient == NULL) { errprintf("No recipient for message\n"); return XYMONSEND_EBADIP; } res = sendtomany(recipient, xgetenv("XYMSERVERS"), msg, timeout, response); if (res != XYMONSEND_OK) { char *statustext = ""; char *eoln; switch (res) { case XYMONSEND_OK : statustext = "OK"; break; case XYMONSEND_EBADIP : statustext = "Bad IP address"; break; case XYMONSEND_EIPUNKNOWN : statustext = "Cannot resolve hostname"; break; case XYMONSEND_ENOSOCKET : statustext = "Cannot get a socket"; break; case XYMONSEND_ECANNOTDONONBLOCK : statustext = "Non-blocking I/O failed"; break; case XYMONSEND_ECONNFAILED : statustext = "Connection failed"; break; case XYMONSEND_ESELFAILED : statustext = "select(2) failed"; break; case XYMONSEND_ETIMEOUT : statustext = "timeout"; break; case XYMONSEND_EWRITEERROR : statustext = "write error"; break; case XYMONSEND_EREADERROR : statustext = "read error"; break; case XYMONSEND_EBADURL : statustext = "Bad URL"; break; default: statustext = "Unknown error"; break; }; eoln = strchr(msg, '\n'); if (eoln) *eoln = '\0'; if (strcmp(recipient, "0.0.0.0") == 0) recipient = xgetenv("XYMSERVERS"); errprintf("Whoops ! Failed to send message (%s)\n", statustext); errprintf("-> %s\n", errordetails); errprintf("-> Recipient '%s', timeout %d\n", recipient, timeout); errprintf("-> 1st line: '%s'\n", msg); if (eoln) *eoln = '\n'; } /* Give it a break */ if (sleepbetweenmsgs) usleep(sleepbetweenmsgs); xymonmsgcount++; return res; } /* Routines for handling combo message transmission */ static void combo_params(void) { static int issetup = 0; if (issetup) return; issetup = 1; if (xgetenv("MAXMSGSPERCOMBO")) maxmsgspercombo = atoi(xgetenv("MAXMSGSPERCOMBO")); if (maxmsgspercombo == 0) { /* Force it to 100 */ dbgprintf("MAXMSGSPERCOMBO is 0, setting it to 100\n"); maxmsgspercombo = 100; } if (xgetenv("SLEEPBETWEENMSGS")) sleepbetweenmsgs = atoi(xgetenv("SLEEPBETWEENMSGS")); comboofssz = 10*maxmsgspercombo; comboofsstr = (char *)malloc(comboofssz+1); combooffsets = (int *)malloc((maxmsgspercombo+1)*sizeof(int)); } void combo_start(void) { int n; combo_params(); memset(comboofsstr, ' ', comboofssz); memcpy(comboofsstr, "extcombo", 8); *(comboofsstr + comboofssz) = '\0'; memset(combooffsets, 0, maxmsgspercombo*sizeof(int)); combooffsets[0] = comboofssz; if (xymonmsg == NULL) xymonmsg = newstrbuffer(0); clearstrbuffer(xymonmsg); addtobufferraw(xymonmsg, comboofsstr, comboofssz); xymonmsgqueued = 0; combo_is_local = 0; } void combo_start_local(void) { combo_start(); combo_is_local = 1; } void meta_start(void) { if (metamsg == NULL) metamsg = newstrbuffer(0); clearstrbuffer(metamsg); xymonmetaqueued = 0; } static void combo_flush(void) { int i; char *outp; if (!xymonmsgqueued) { dbgprintf("Flush, but xymonmsg is empty\n"); return; } outp = strchr(STRBUF(xymonmsg), ' '); for (i = 0; (i <= xymonmsgqueued); i++) { outp += snprintf(outp, (STRBUFSZ(xymonmsg) - (outp - STRBUF(xymonmsg))), " %d", combooffsets[i]); } *outp = '\n'; if (debug) { char *p1, *p2; dbgprintf("Flushing combo message\n"); p1 = p2 = STRBUF(xymonmsg); do { p2++; p1 = strstr(p2, "\nstatus "); if (p1) { p1++; /* Skip the newline */ p2 = strchr(p1, '\n'); if (p2) *p2='\0'; printf(" %s\n", p1); if (p2) *p2='\n'; } } while (p1 && p2); } if (combo_is_local) { sendmessage_local(STRBUF(xymonmsg)); combo_start_local(); } else { sendmessage(STRBUF(xymonmsg), NULL, XYMON_TIMEOUT, NULL); combo_start(); } } static void meta_flush(void) { if (!xymonmetaqueued) { dbgprintf("Flush, but xymonmeta is empty\n"); return; } sendmessage(STRBUF(metamsg), NULL, XYMON_TIMEOUT, NULL); meta_start(); /* Get ready for the next */ } void combo_add(strbuffer_t *buf) { if (combo_is_local) { /* Check if message fits into the backfeed message buffer */ if ( (STRBUFLEN(xymonmsg) + STRBUFLEN(buf)) >= max_backfeedsz) { combo_flush(); } } else { /* Check if there is room for the message + 2 newlines */ if (maxmsgspercombo && (xymonmsgqueued >= maxmsgspercombo)) { combo_flush(); } } addtostrbuffer(xymonmsg, buf); combooffsets[++xymonmsgqueued] = STRBUFLEN(xymonmsg); } static void meta_add(strbuffer_t *buf) { /* Check if there is room for the message + 2 newlines */ if (maxmsgspercombo && (xymonmetaqueued >= maxmsgspercombo)) { /* Nope ... flush buffer */ meta_flush(); } else { /* Yep ... add delimiter before new status (but not before the first!) */ if (xymonmetaqueued) addtobuffer(metamsg, "\n\n"); } addtostrbuffer(metamsg, buf); xymonmetaqueued++; } void combo_end(void) { combo_flush(); combo_is_local = 0; dbgprintf("%d status messages merged into %d transmissions\n", xymonstatuscount, xymonmsgcount); } void meta_end(void) { meta_flush(); } void init_status(int color) { if (msgbuf == NULL) msgbuf = newstrbuffer(0); clearstrbuffer(msgbuf); msgcolor = color; xymonstatuscount++; } void init_meta(char *metaname) { if (metabuf == NULL) metabuf = newstrbuffer(0); clearstrbuffer(metabuf); } void addtostatus(char *p) { addtobuffer(msgbuf, p); } void addtostrstatus(strbuffer_t *p) { addtostrbuffer(msgbuf, p); } void addtometa(char *p) { addtobuffer(metabuf, p); } void finish_status(void) { if (debug) { char *p = strchr(STRBUF(msgbuf), '\n'); if (p) *p = '\0'; dbgprintf("Adding to combo msg: %s\n", STRBUF(msgbuf)); if (p) *p = '\n'; } combo_add(msgbuf); } void finish_meta(void) { meta_add(metabuf); } xymon-4.3.30/lib/matching.c0000664000076400007640000001124112621055261015706 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for matching names and expressions */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: matching.c 7733 2015-11-12 09:24:01Z jccleaver $"; #include #include #include #include #include #include "libxymon.h" pcre *compileregex_opts(const char *pattern, int flags) { pcre *result; const char *errmsg; int errofs; dbgprintf("Compiling regex %s\n", pattern); result = pcre_compile(pattern, flags, &errmsg, &errofs, NULL); if (result == NULL) { errprintf("pcre compile '%s' failed (offset %d): %s\n", pattern, errofs, errmsg); return NULL; } return result; } pcre *compileregex(const char *pattern) { return compileregex_opts(pattern, PCRE_CASELESS); } pcre *multilineregex(const char *pattern) { return compileregex_opts(pattern, PCRE_CASELESS|PCRE_MULTILINE); } int matchregex(const char *needle, pcre *pcrecode) { int ovector[30]; int result; if (!needle || !pcrecode) return 0; result = pcre_exec(pcrecode, NULL, needle, strlen(needle), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); return (result >= 0); } void freeregex(pcre *pcrecode) { if (!pcrecode) return; pcre_free(pcrecode); } int namematch(const char *needle, char *haystack, pcre *pcrecode) { char *xhay; char *tokbuf = NULL, *tok; int found = 0; int result = 0; int allneg = 1; if ((needle == NULL) || (*needle == '\0')) return 0; if (pcrecode) { /* Do regex matching. The regex has already been compiled for us. */ return matchregex(needle, pcrecode); } if (strcmp(haystack, "*") == 0) { /* Match anything */ return 1; } /* Implement a simple, no-wildcard match */ xhay = strdup(haystack); tok = strtok_r(xhay, ",", &tokbuf); while (tok) { allneg = (allneg && (*tok == '!')); if (!found) { if (*tok == '!') { found = (strcmp(tok+1, needle) == 0); if (found) result = 0; } else { found = (strcmp(tok, needle) == 0); if (found) result = 1; } } /* We must check all of the items in the haystack to see if they are all negative matches */ tok = strtok_r(NULL, ",", &tokbuf); } xfree(xhay); /* * If we didn't find it, and the list is exclusively negative matches, * we must return a positive result for "no match". */ if (!found && allneg) result = 1; return result; } int patternmatch(char *datatosearch, char *pattern, pcre *pcrecode) { if (pcrecode) { /* Do regex matching. The regex has already been compiled for us. */ return matchregex(datatosearch, pcrecode); } if (strcmp(pattern, "*") == 0) { /* Match anything */ return 1; } return (strstr(datatosearch, pattern) != NULL); } pcre **compile_exprs(char *id, const char **patterns, int count) { pcre **result = NULL; int i; result = (pcre **)calloc(count, sizeof(pcre *)); for (i=0; (i < count); i++) { result[i] = compileregex(patterns[i]); if (!result[i]) { errprintf("Internal error: %s pickdata PCRE-compile failed\n", id); for (i=0; (i < count); i++) if (result[i]) pcre_free(result[i]); xfree(result); return NULL; } } return result; } int pickdata(char *buf, pcre *expr, int dupok, ...) { int res, i; int ovector[30]; va_list ap; char **ptr; char w[100]; if (!expr) return 0; res = pcre_exec(expr, NULL, buf, strlen(buf), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res < 0) return 0; va_start(ap, dupok); for (i=1; (i < res); i++) { *w = '\0'; pcre_copy_substring(buf, ovector, res, i, w, sizeof(w)); ptr = va_arg(ap, char **); if (dupok) { if (*ptr) xfree(*ptr); *ptr = strdup(w); } else { if (*ptr == NULL) { *ptr = strdup(w); } else { dbgprintf("Internal error: Duplicate match ignored\n"); } } } va_end(ap); return 1; } int timematch(char *holidaykey, char *tspec) { int result; result = within_sla(holidaykey, tspec, 0); return result; } xymon-4.3.30/lib/url.c0000664000076400007640000004156513515623702014736 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for URL parsing and mangling. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: url.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" int obeybbproxysyntax = 0; /* Big Brother can put proxy-spec in a URL, with "http://proxy/bla;http://target/foo" */ /* This is used for loading a .netrc file with hostnames and authentication tokens. */ typedef struct loginlist_t { char *host; char *auth; struct loginlist_t *next; } loginlist_t; static loginlist_t *loginhead = NULL; /* * Convert a URL with "%XX" hexadecimal escaped style bytes into normal form. * Result length will always be <= source length. */ char *urlunescape(char *url) { static char *result = NULL; char *pin, *pout; pin = url; if (result) xfree(result); pout = result = (char *) malloc(strlen(url) + 1); while (*pin) { if (*pin == '+') { *pout = ' '; pin++; } else if (*pin == '%') { pin++; if ((strlen(pin) >= 2) && isxdigit((int)*pin) && isxdigit((int)*(pin+1))) { *pout = 16*hexvalue(*pin) + hexvalue(*(pin+1)); pin += 2; } else { *pout = '%'; pin++; } } else { *pout = *pin; pin++; } pout++; } *pout = '\0'; return result; } /* * Get an environment variable (eg: QUERY_STRING) and do CGI decoding of it. */ char *urldecode(char *envvar) { if (xgetenv(envvar) == NULL) return NULL; return urlunescape(xgetenv(envvar)); } /* * Do a CGI encoding of a URL, i.e. unusual chars are converted to %XX. */ char *urlencode(char *s) { STATIC_SBUF_DEFINE(result); char *inp, *outp; if (result == NULL) { SBUF_MALLOC(result, 1024); } outp = result; for (inp = s; (*inp); inp++) { if ((outp - result) > (result_buflen - 5)) { int offset = (outp - result); SBUF_REALLOC(result, result_buflen + 1024); outp = result + offset; } if ( ( (*inp >= 'a') && (*inp <= 'z') ) || ( (*inp >= 'A') && (*inp <= 'Z') ) || ( (*inp >= '0') && (*inp <= '9') ) ) { *outp = *inp; outp++; } else { snprintf(outp, (result_buflen - (outp - result)), "%%%0x", *inp); outp += 3; } } *outp = '\0'; return result; } /* * Check if a URL contains only safe characters. * This is not really needed any more, since there are no more CGI * shell-scripts that directly process the QUERY_STRING parameter. */ int urlvalidate(char *query, char *validchars) { #if 0 static int valid; char *p; if (validchars == NULL) validchars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-:&_%=*+/ "; for (p=query, valid=1; (valid && *p); p++) { valid = (strchr(validchars, *p) != NULL); } return valid; #else return 1; #endif } /* * Load the $HOME/.netrc file with authentication tokens for HTTP tests. */ static void load_netrc(void) { #define WANT_TOKEN 0 #define MACHINEVAL 1 #define LOGINVAL 2 #define PASSVAL 3 #define OTHERVAL 4 static int loaded = 0; char netrcfn[MAXPATHLEN]; FILE *fd; strbuffer_t *inbuf; char *host, *login, *password, *p; int state = WANT_TOKEN; if (loaded) return; loaded = 1; MEMDEFINE(netrcfn); /* Look for $XYMONHOME/etc/netrc first, then the default ~/.netrc */ snprintf(netrcfn, sizeof(netrcfn), "%s/etc/netrc", xgetenv("XYMONHOME")); fd = fopen(netrcfn, "r"); /* Can HOME be undefined ? Yes, on Solaris when started during boot */ if ((fd == NULL) && getenv("HOME")) { snprintf(netrcfn, sizeof(netrcfn), "%s/.netrc", xgetenv("HOME")); fd = fopen(netrcfn, "r"); } if (fd == NULL) { MEMUNDEFINE(netrcfn); return; } host = login = password = NULL; initfgets(fd); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, fd)) { sanitize_input(inbuf, 0, 0); if (STRBUFLEN(inbuf) != 0) { p = strtok(STRBUF(inbuf), " \t"); while (p) { switch (state) { case WANT_TOKEN: if (strcmp(p, "machine") == 0) state = MACHINEVAL; else if (strcmp(p, "login") == 0) state = LOGINVAL; else if (strcmp(p, "password") == 0) state = PASSVAL; else if (strcmp(p, "account") == 0) state = OTHERVAL; else if (strcmp(p, "macdef") == 0) state = OTHERVAL; else if (strcmp(p, "default") == 0) { host = ""; state = WANT_TOKEN; } else state = WANT_TOKEN; break; case MACHINEVAL: host = strdup(p); state = WANT_TOKEN; break; case LOGINVAL: login = strdup(p); state = WANT_TOKEN; break; case PASSVAL: password = strdup(p); state = WANT_TOKEN; break; case OTHERVAL: state = WANT_TOKEN; break; } if (host && login && password) { loginlist_t *item = (loginlist_t *) malloc(sizeof(loginlist_t)); unsigned int login_len = strlen(login) + strlen(password) + 1; item->host = host; item->auth = (char *) malloc(login_len + 1); snprintf(item->auth, login_len, "%s:%s", login, password); item->next = loginhead; loginhead = item; host = login = password = NULL; } p = strtok(NULL, " \t"); } } } fclose(fd); freestrbuffer(inbuf); MEMUNDEFINE(netrcfn); } /* * Clean a URL of double-slashes. */ char *cleanurl(char *url) { static char *cleaned = NULL; char *pin, *pout; int lastwasslash = 0; if (cleaned == NULL) cleaned = (char *)malloc(strlen(url)+1); else { cleaned = (char *)realloc(cleaned, strlen(url)+1); } for (pin=url, pout=cleaned, lastwasslash=0; (*pin); pin++) { if (*pin == '/') { if (!lastwasslash) { *pout = *pin; pout++; } lastwasslash = 1; } else { *pout = *pin; pout++; lastwasslash = 0; } } *pout = '\0'; return cleaned; } /* * Parse a URL into components, following the guidelines in RFC 1808. * This fills out a urlelem_t struct with the elements, and also * constructs a canonical form of the URL. */ void parse_url(char *inputurl, urlelem_t *url) { char *tempurl; char *fragment = NULL; char *netloc; char *startp, *p; int haveportspec = 0; char *canonurl; int canonurllen; memset(url, 0, sizeof(urlelem_t)); url->scheme = url->host = url->relurl = ""; /* Get a temp. buffer we can molest */ tempurl = strdup(inputurl); /* First cut off any fragment specifier */ fragment = strchr(tempurl, '#'); if (fragment) *fragment = '\0'; /* Get the scheme (protocol) */ startp = tempurl; p = strchr(startp, ':'); if (p) { *p = '\0'; if (strncasecmp(startp, "https", 5) == 0) { url->scheme = "https"; url->port = 443; if (strlen(startp) > 5) url->schemeopts = strdup(startp+5); } else if (strncasecmp(startp, "http", 4) == 0) { url->scheme = "http"; url->port = 80; if (strlen(startp) > 4) url->schemeopts = strdup(startp+4); } else if (strncasecmp(startp, "ftps", 4) == 0) { url->scheme = "ftps"; url->port = 990; } else if (strncasecmp(startp, "ftp", 3) == 0) { url->scheme = "ftp"; url->port = 21; } else if (strncasecmp(startp, "ldaps", 5) == 0) { url->scheme = "ldaps"; url->port = 389; /* ldaps:// URL's are non-standard, and must use port 389+STARTTLS */ } else if (strncasecmp(startp, "ldap", 4) == 0) { url->scheme = "ldap"; url->port = 389; } else { /* Unknown scheme! */ errprintf("Unknown URL scheme '%s' in URL '%s'\n", startp, inputurl); url->scheme = strdup(startp); url->port = 0; } startp = (p+1); } else { errprintf("Malformed URL - no 'scheme:' in '%s'\n", inputurl); url->parseerror = 1; xfree(tempurl); return; } if (strncmp(startp, "//", 2) == 0) { startp += 2; netloc = startp; p = strchr(startp, '/'); if (p) { *p = '\0'; startp = (p+1); } else startp += strlen(startp); } else { errprintf("Malformed URL missing '//' in '%s'\n", inputurl); url->parseerror = 2; xfree(tempurl); return; } /* netloc is [username:password@]hostname[:port][=forcedIP] */ p = strchr(netloc, '@'); if (p) { *p = '\0'; url->auth = strdup(urlunescape(netloc)); netloc = (p+1); } p = strchr(netloc, '='); if (p) { url->ip = strdup(p+1); *p = '\0'; } p = strchr(netloc, ':'); if (p) { haveportspec = 1; *p = '\0'; url->port = atoi(p+1); } url->host = strdup(netloc); if (url->port == 0) { struct servent *svc = getservbyname(url->scheme, NULL); if (svc) url->port = ntohs(svc->s_port); else { errprintf("Unknown scheme (no port) '%s'\n", url->scheme); url->parseerror = 3; xfree(tempurl); return; } } if (fragment) *fragment = '#'; url->relurl = malloc(strlen(startp) + 2); snprintf(url->relurl, (strlen(startp)+2), "/%s", startp); if (url->auth == NULL) { /* See if we have it in the .netrc list */ loginlist_t *walk; load_netrc(); for (walk = loginhead; (walk && (strcmp(walk->host, url->host) != 0)); walk = walk->next) ; if (walk) url->auth = strdup(walk->auth); } /* Build the canonical form of this URL, free from all config artefacts */ canonurllen = 1; canonurllen += strlen(url->scheme)+3; /* Add room for the "://" */ canonurllen += strlen(url->host); canonurllen += 6; /* Max. length of a port spec. */ canonurllen += strlen(url->relurl); p = canonurl = (char *)malloc(canonurllen); p += snprintf(p, (canonurllen - (p - canonurl)), "%s://", url->scheme); /* * Don't include authentication here, since it * may show up in clear text on the info page. * And it is not used in URLs to access the site. */ p += snprintf(p, (canonurllen - (p - canonurl)), "%s", url->host); if (haveportspec) p += snprintf(p, (canonurllen - (p - canonurl)), ":%d", url->port); p += snprintf(p, (canonurllen - (p - canonurl)), "%s", url->relurl); url->origform = canonurl; xfree(tempurl); return; } /* * If a column name is column=NAME, pick out NAME. */ static char *gethttpcolumn(char *inp, char **name) { char *nstart, *nend; nstart = inp; nend = strchr(nstart, ';'); if (nend == NULL) { *name = NULL; return inp; } *nend = '\0'; *name = strdup(nstart); *nend = ';'; return nend+1; } /* * Split a test-specification with a URL and optional * post-data/expect-data/expect-type data into the URL itself * and the other elements. * Un-escape data in the post- and expect-data. * Parse the URL. */ char *decode_url(char *testspec, weburl_t *weburl) { static weburl_t weburlbuf; static urlelem_t desturlbuf, proxyurlbuf; char *inp, *p; char *urlstart, *poststart, *postcontenttype, *expstart, *proxystart, *okstart, *notokstart; urlstart = poststart = postcontenttype = expstart = proxystart = okstart = notokstart = NULL; /* If called with no buffer, use our own static one */ if (weburl == NULL) { memset(&weburlbuf, 0, sizeof(weburl_t)); memset(&desturlbuf, 0, sizeof(urlelem_t)); memset(&proxyurlbuf, 0, sizeof(urlelem_t)); weburl = &weburlbuf; weburl->desturl = &desturlbuf; weburl->proxyurl = NULL; } else { memset(weburl, 0, sizeof(weburl_t)); weburl->desturl = (urlelem_t*) calloc(1, sizeof(urlelem_t)); weburl->proxyurl = NULL; } inp = strdup(testspec); if (strncmp(inp, "content=", 8) == 0) { weburl->testtype = WEBTEST_CONTENT; urlstart = inp+8; } else if (strncmp(inp, "cont;", 5) == 0) { weburl->testtype = WEBTEST_CONT; urlstart = inp+5; } else if (strncmp(inp, "cont=", 5) == 0) { weburl->testtype = WEBTEST_CONT; urlstart = gethttpcolumn(inp+5, &weburl->columnname); } else if (strncmp(inp, "nocont;", 7) == 0) { weburl->testtype = WEBTEST_NOCONT; urlstart = inp+7; } else if (strncmp(inp, "nocont=", 7) == 0) { weburl->testtype = WEBTEST_NOCONT; urlstart = gethttpcolumn(inp+7, &weburl->columnname); } else if (strncmp(inp, "post;", 5) == 0) { weburl->testtype = WEBTEST_POST; urlstart = inp+5; } else if (strncmp(inp, "post=", 5) == 0) { weburl->testtype = WEBTEST_POST; urlstart = gethttpcolumn(inp+5, &weburl->columnname); } else if (strncmp(inp, "nopost;", 7) == 0) { weburl->testtype = WEBTEST_NOPOST; urlstart = inp+7; } else if (strncmp(inp, "nopost=", 7) == 0) { weburl->testtype = WEBTEST_NOPOST; urlstart = gethttpcolumn(inp+7, &weburl->columnname); } else if (strncmp(inp, "soap;", 5) == 0) { weburl->testtype = WEBTEST_SOAP; urlstart = inp+5; } else if (strncmp(inp, "soap=", 5) == 0) { weburl->testtype = WEBTEST_SOAP; urlstart = gethttpcolumn(inp+5, &weburl->columnname); } else if (strncmp(inp, "nosoap;", 7) == 0) { weburl->testtype = WEBTEST_NOSOAP; urlstart = inp+7; } else if (strncmp(inp, "nosoap=", 7) == 0) { weburl->testtype = WEBTEST_NOSOAP; urlstart = gethttpcolumn(inp+7, &weburl->columnname); } else if (strncmp(inp, "type;", 5) == 0) { weburl->testtype = WEBTEST_TYPE; urlstart = inp+5; } else if (strncmp(inp, "type=", 5) == 0) { weburl->testtype = WEBTEST_TYPE; urlstart = gethttpcolumn(inp+5, &weburl->columnname); } else if (strncmp(inp, "httpstatus;", 11) == 0) { weburl->testtype = WEBTEST_STATUS; urlstart = strchr(inp, ';') + 1; } else if (strncmp(inp, "httpstatus=", 11) == 0) { weburl->testtype = WEBTEST_STATUS; urlstart = gethttpcolumn(inp+11, &weburl->columnname); } else if (strncmp(inp, "httphead;", 9) == 0) { weburl->testtype = WEBTEST_HEAD; urlstart = strchr(inp, ';') + 1; } else if (strncmp(inp, "httphead=", 9) == 0) { weburl->testtype = WEBTEST_HEAD; urlstart = gethttpcolumn(inp+9, &weburl->columnname); } else if (strncmp(inp, "http=", 5) == 0) { /* Plain URL test, but in separate column */ weburl->testtype = WEBTEST_PLAIN; urlstart = gethttpcolumn(inp+5, &weburl->columnname); } else { /* Plain URL test */ weburl->testtype = WEBTEST_PLAIN; urlstart = inp; } switch (weburl->testtype) { case WEBTEST_PLAIN: case WEBTEST_HEAD: break; case WEBTEST_CONT: case WEBTEST_NOCONT: case WEBTEST_TYPE: expstart = strchr(urlstart, ';'); if (expstart) { *expstart = '\0'; expstart++; } else { errprintf("content-check, but no content-data in '%s'\n", testspec); weburl->testtype = WEBTEST_PLAIN; } break; case WEBTEST_POST: case WEBTEST_NOPOST: case WEBTEST_SOAP: poststart = strchr(urlstart, ';'); if (poststart) { *poststart = '\0'; poststart++; /* See if "poststart" points to a content-type */ if (strncasecmp(poststart, "(content-type=", 14) == 0) { postcontenttype = poststart+14; poststart = strchr(postcontenttype, ')'); if (poststart) { *poststart = '\0'; poststart++; } } if (poststart) { expstart = strchr(poststart, ';'); if (expstart) { *expstart = '\0'; expstart++; } } if ((weburl->testtype == WEBTEST_NOPOST) && (!expstart)) { errprintf("content-check, but no content-data in '%s'\n", testspec); weburl->testtype = WEBTEST_PLAIN; } } else { errprintf("post-check, but no post-data in '%s'\n", testspec); weburl->testtype = WEBTEST_PLAIN; } break; case WEBTEST_STATUS: okstart = strchr(urlstart, ';'); if (okstart) { *okstart = '\0'; okstart++; notokstart = strchr(okstart, ';'); if (notokstart) { *notokstart = '\0'; notokstart++; } } if (okstart && (strlen(okstart) == 0)) okstart = NULL; if (notokstart && (strlen(notokstart) == 0)) notokstart = NULL; if (!okstart && !notokstart) { errprintf("HTTP status check, but no OK/not-OK status codes in '%s'\n", testspec); weburl->testtype = WEBTEST_PLAIN; } if (okstart) weburl->okcodes = strdup(okstart); if (notokstart) weburl->badcodes = strdup(notokstart); } if (poststart) getescapestring(poststart, &weburl->postdata, NULL); if (postcontenttype) getescapestring(postcontenttype, &weburl->postcontenttype, NULL); if (expstart) getescapestring(expstart, &weburl->expdata, NULL); if (obeybbproxysyntax) { /* * Ye olde Big Brother syntax for using a proxy on per-URL basis. */ p = strstr(urlstart, "/http://"); if (!p) p = strstr(urlstart, "/https://"); if (p) { proxystart = urlstart; urlstart = (p+1); *p = '\0'; } } parse_url(urlstart, weburl->desturl); if (proxystart) { if (weburl == &weburlbuf) { /* We use our own static buffers */ weburl->proxyurl = &proxyurlbuf; } else { /* User allocated buffers */ weburl->proxyurl = (urlelem_t *)malloc(sizeof(urlelem_t)); } parse_url(proxystart, weburl->proxyurl); } xfree(inp); return weburl->desturl->origform; } xymon-4.3.30/lib/acklog.c0000664000076400007640000001706713532325276015400 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file contains code to build the acknowledgement log shown on the */ /* "all non-green" page. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: acklog.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" int havedoneacklog = 0; void do_acklog(FILE *output, int maxcount, int maxminutes) { FILE *acklog; char acklogfilename[PATH_MAX]; time_t cutoff; struct stat st; char l[MAX_LINE_LEN]; char title[200]; ack_t *acks; int num, ackintime_count; havedoneacklog = 1; cutoff = ( (maxminutes) ? (getcurrenttime(NULL) - maxminutes*60) : 0); if ((!maxcount) || (maxcount > 100)) maxcount = 100; snprintf(acklogfilename, sizeof(acklogfilename), "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS")); acklog = fopen(acklogfilename, "r"); if (!acklog) { /* BB compatible naming */ snprintf(acklogfilename, sizeof(acklogfilename), "%s/acklog", xgetenv("XYMONACKDIR")); acklog = fopen(acklogfilename, "r"); } if (!acklog) { /* If no acklog, that is OK - some people don't use acks */ dbgprintf("Cannot open acklog\n"); return; } /* HACK ALERT! */ if (stat(acklogfilename, &st) == 0) { if (st.st_size != 0) { /* Assume a log entry is max 150 bytes */ if (150*maxcount < st.st_size) { fseeko(acklog, -150*maxcount, SEEK_END); if ((fgets(l, sizeof(l), acklog) == NULL) || (strchr(l, '\n') == NULL)) { errprintf("Oops - couldnt find a newline in acklog\n"); } } } } acks = (ack_t *) calloc(maxcount, sizeof(ack_t)); ackintime_count = num = 0; while (fgets(l, sizeof(l), acklog)) { char ackedby[MAX_LINE_LEN], hosttest[MAX_LINE_LEN], color[10], ackmsg[MAX_LINE_LEN]; char ackfn[PATH_MAX]; char *testname; void *hinfo; int ok; if (atol(l) >= cutoff) { int c_used; char *p, *p1, *xymondacker = NULL; unsigned int atim; sscanf(l, "%u\t%d\t%d\t%d\t%s\t%s\t%s\t%n", &atim, &acks[num].acknum, &acks[num].duration, &acks[num].acknum2, ackedby, hosttest, color, &c_used); acks[num].acktime = atim; p1 = ackmsg; for (p=l+c_used, p1=ackmsg; (*p); ) { /* * Need to de-code the ackmsg - it may have been entered * via a web page that did "%asciival" encoding. */ if ((*p == '%') && (strlen(p) >= 3) && isxdigit((int)*(p+1)) && isxdigit((int)*(p+2))) { char hexnum[3]; hexnum[0] = *(p+1); hexnum[1] = *(p+2); hexnum[2] = '\0'; *p1 = (char) strtol(hexnum, NULL, 16); p1++; p += 3; } else { *p1 = *p; p1++; p++; } } *p1 = '\0'; /* Xymon uses \n in the ack message, for the "acked by" data. Cut it off. */ nldecode(ackmsg); p = strchr(ackmsg, '\n'); if (p) { if (strncmp(p, "\nAcked by:", 10) == 0) xymondacker = p+10; *p = '\0'; } /* Show only the first 30 characters in message */ if (strlen(ackmsg) > 30) ackmsg[30] = '\0'; #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ snprintf(ackfn, sizeof(ackfn), "%s/ack.%s", xgetenv("XYMONACKDIR"), hosttest); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ testname = strrchr(hosttest, '.'); if (testname) { *testname = '\0'; testname++; } else testname = "unknown"; ok = 1; /* Ack occurred within wanted timerange ? */ if (ok && (acks[num].acktime < cutoff)) ok = 0; /* Unknown host ? */ hinfo = hostinfo(hosttest); if (!hinfo) ok = 0; if (hinfo && xmh_item(hinfo, XMH_FLAG_NONONGREEN)) ok = 0; if (ok) { char *ackerp; /* If ack has expired or tag file is gone, the ack is no longer valid */ acks[num].ackvalid = 1; if ((acks[num].acktime + 60*acks[num].duration) < getcurrenttime(NULL)) acks[num].ackvalid = 0; if (acks[num].ackvalid && (stat(ackfn, &st) != 0)) acks[num].ackvalid = 0; if (strcmp(ackedby, "np_filename_not_used") != 0) { ackerp = ackedby; if (strncmp(ackerp, "np_", 3) == 0) ackerp += 3; p = strrchr(ackerp, '_'); if (p > ackerp) *p = '\0'; acks[num].ackedby = strdup(ackerp); } else if (xymondacker) { acks[num].ackedby = strdup(xymondacker); } else { acks[num].ackedby = ""; } acks[num].hostname = strdup(hosttest); acks[num].testname = strdup(testname); strncat(color, " ", (sizeof(color) - strlen(color))); acks[num].color = parse_color(color); acks[num].ackmsg = strdup(ackmsg); ackintime_count++; num = (num + 1) % maxcount; } } } if (ackintime_count > 0) { int firstack, lastack; int period = maxminutes; if (ackintime_count <= maxcount) { firstack = 0; lastack = ackintime_count-1; period = maxminutes; } else { firstack = num; lastack = ( (num == 0) ? maxcount : (num-1)); ackintime_count = maxcount; period = ((getcurrenttime(NULL)-acks[firstack].acktime) / 60); } snprintf(title, sizeof(title), "%d events acknowledged in the past %u minutes", ackintime_count, period); fprintf(output, "

\n"); fprintf(output, "\n", title); fprintf(output, "\n"); fprintf(output, "\n", title); for (num = lastack; (ackintime_count); ackintime_count--, num = ((num == 0) ? (maxcount-1) : (num - 1)) ) { fprintf(output, "\n"); fprintf(output, "\n", ctime(&acks[num].acktime)); fprintf(output, "\n", colorname(acks[num].color), acks[num].hostname); fprintf(output, "\n", acks[num].testname); if (acks[num].color != -1) { fprintf(output, "\n", xgetenv("XYMONSKIN"), dotgiffilename(acks[num].color, acks[num].ackvalid, 1)); } else fprintf(output, "\n"); fprintf(output, "\n", acks[num].ackedby); fprintf(output, "\n", acks[num].ackmsg); } } else { snprintf(title, sizeof(title), "No events acknowledged in the last %u minutes", maxminutes); fprintf(output, "

\n"); fprintf(output, "
%s
%s%s%s %s%s
\n", title); fprintf(output, "\n"); fprintf(output, "\n", title); } fprintf(output, "
%s
\n"); fclose(acklog); } xymon-4.3.30/lib/files.h0000664000076400007640000000150411615341300015216 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __FILES_H__ #define __FILES_H__ extern void dropdirectory(char *dirfn, int background); #endif xymon-4.3.30/lib/msort.c0000664000076400007640000001372613515623702015276 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains a "mergesort" implementation for sorting linked lists. */ /* */ /* Based on http://en.wikipedia.org/wiki/Merge_sort pseudo code, adapted for */ /* use in a generic library routine. */ /* */ /* Copyright (C) 2009-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: msort.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include "libxymon.h" #if 0 static void *merge(void *left, void *right, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext) { void *head, *tail; head = tail = NULL; while (left && right) { if (comparefn(left, right) < 0) { /* Add the left item to the resultlist */ if (tail) { setnext(tail, left); } else { head = left; } tail = left; left = getnext(left); } else { /* Add the right item to the resultlist */ if (tail) { setnext(tail, right); } else { head = right; } tail = right; right = getnext(right); } } /* One or both lists have ended. Add whatever elements may remain */ if (left) { if (tail) setnext(tail, left); else head = tail = left; } if (right) { if (tail) setnext(tail, right); else head = tail = right; } return head; } void *msort(void *head, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext) { void *left, *right, *middle, *walk, *walknext; /* First check if list is empty or has only one element */ if ((head == NULL) || (getnext(head) == NULL)) return head; /* * Find the middle element of the list. * We do this by walking the list until we reach the end. * "middle" takes one step at a time, whereas "walk" takes two. */ middle = head; walk = getnext(middle); /* "walk" must be ahead of "middle" */ while (walk && (walknext = getnext(walk))) { middle = getnext(middle); walk = getnext(walknext); } /* Split the list in two halves, and sort each of them. */ left = head; right = getnext(middle); setnext(middle, NULL); left = msort(left, comparefn, getnext, setnext); right = msort(right, comparefn, getnext, setnext); /* We have sorted the two halves, now we must merge them together */ return merge(left, right, comparefn, getnext, setnext); } #endif void *msort(void *head, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext) { void *walk; int len, i; void **plist; for (walk = head, len=0; (walk); walk = getnext(walk)) len++; plist = malloc((len+1) * sizeof(void *)); for (walk = head, i=0; (walk); walk = getnext(walk)) plist[i++] = walk; plist[len] = NULL; /* This bizarre cast is to quelch compiler warnings */ qsort(plist, len, sizeof(plist[0]), (int(*)(const void *, const void *))comparefn); for (i=0, head = plist[0]; (i < len); i++) setnext(plist[i], plist[i+1]); xfree(plist); return head; } #ifdef STANDALONE typedef struct rec_t { struct rec_t *next; char *key; char *val; } rec_t; void dumplist(rec_t *head) { rec_t *walk; walk = head; while (walk) { printf("%p : %-15s:%3s\n", walk, walk->key, walk->val); walk = walk->next; } printf("\n"); printf("\n"); } int record_compare(void **a, void **b) { rec_t **reca = (rec_t **)a; rec_t **recb = (rec_t **)b; return strcasecmp((*reca)->key, (*recb)->key); } void * record_getnext(void *a) { return ((rec_t *)a)->next; } void record_setnext(void *a, void *newval) { ((rec_t *)a)->next = (rec_t *)newval; } /* 50 most popular US babynames in 2006: http://www.ssa.gov/OACT/babynames/ */ char *tdata[] = { "Jacob", "Emily", "Michael", "Emma", "Joshua", "Madison", "Ethan", "Isabella", "Matthew", "Ava", "Daniel", "Abigail", "Christopher", "Olivia", "Andrew", "Hannah", "Anthony", "Sophia", "William", "Samantha", "Joseph", "Elizabeth", "Alexander", "Ashley", "David", "Mia", "Ryan", "Alexis", "Noah", "Sarah", "James", "Natalie", "Nicholas", "Grace", "Tyler", "Chloe", "Logan", "Alyssa", "John", "Brianna", "Christian", "Ella", "Jonathan", "Taylor", "Nathan", "Anna", "Benjamin", "Lauren", "Samuel", "Hailey", "Dylan", "Kayla", "Brandon", "Addison", "Gabriel", "Victoria", "Elijah", "Jasmine", "Aiden", "Savannah", "Angel", "Julia", "Jose", "Jessica", "Zachary", "Lily", "Caleb", "Sydney", "Jack", "Morgan", "Jackson", "Katherine", "Kevin", "Destiny", "Gavin", "Lillian", "Mason", "Alexa", "Isaiah", "Alexandra", "Austin", "Kaitlyn", "Evan", "Kaylee", "Luke", "Nevaeh", "Aidan", "Brooke", "Justin", "Makayla", "Jordan", "Allison", "Robert", "Maria", "Isaac", "Angelina", "Landon", "Rachel", "Jayden", "Gabriella", NULL }; int main(int argc, char *argv[]) { int i; rec_t *head, *newrec, *tail; head = tail = NULL; for (i=0; (tdata[i]); i++) { char numstr[10]; newrec = (rec_t *)calloc(1, sizeof(rec_t)); newrec->key = strdup(tdata[i]); snprintf(numstr, sizeof(numstr), "%d", i+1); newrec->val = strdup(numstr); if (tail) { tail->next = newrec; tail = newrec; } else { head = tail = newrec; } } dumplist(head); head = msort(head, record_compare, record_getnext, record_setnext); dumplist(head); return 0; } #endif xymon-4.3.30/lib/reportlog.h0000664000076400007640000000231611615341300016133 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __REPORTLOG_H__ #define __REPORTLOG_H__ #include #include "availability.h" #define STYLE_CRIT 0 #define STYLE_NONGR 1 #define STYLE_OTHER 2 extern char *stylenames[]; extern void generate_replog(FILE *htmlrep, FILE *textrep, char *textrepurl, char *hostname, char *service, int color, int style, char *ip, char *displayname, time_t st, time_t end, double reportwarnlevel, double reportgreenlevel, int reportwarnstops, reportinfo_t *repinfo); #endif xymon-4.3.30/lib/cgiurls.h0000664000076400007640000000242511615341300015567 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CGIURLS_H__ #define __CGIURLS_H__ #include #include "availability.h" extern char *hostsvcurl(char *hostname, char *service, int htmlformat); extern char *hostsvcclienturl(char *hostname, char *section); extern char *histcgiurl(char *hostname, char *service); extern char *histlogurl(char *hostname, char *service, time_t histtime, char *histtime_txt); extern char *replogurl(char *hostname, char *service, int color, char *style, int recentgifs, reportinfo_t *repinfo, char *reportstart, time_t reportend, float reportwarnlevel); #endif xymon-4.3.30/lib/reportlog.c0000664000076400007640000003434011615341300016130 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This tool generates the report status log for a single status, with the */ /* availability percentages etc needed for a report-mode view. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: reportlog.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include "libxymon.h" char *stylenames[3] = { "crit", "nongr", "all" }; void generate_replog(FILE *htmlrep, FILE *textrep, char *textrepurl, char *hostname, char *service, int color, int style, char *ip, char *displayname, time_t st, time_t end, double reportwarnlevel, double reportgreenlevel, int reportwarnstops, reportinfo_t *repinfo) { replog_t *walk; char *bgcols[2] = { "\"#000000\"", "\"#000033\"" }; int curbg = 0; if (!displayname) displayname = hostname; sethostenv(displayname, ip, service, colorname(color), hostname); sethostenv_report(st, end, reportwarnlevel, reportgreenlevel); headfoot(htmlrep, "replog", "", "header", color); fprintf(htmlrep, "\n"); fprintf(htmlrep, "
\n"); fprintf(htmlrep, "
", xgetenv("XYMONPAGEROWFONT")); fprintf(htmlrep, "%s - ", htmlquoted(displayname)); fprintf(htmlrep, "%s\n", htmlquoted(service)); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); if (repinfo->withreport) { fprintf(htmlrep, "\n", repinfo->fullavailability); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", repinfo->reportavailability); } else { fprintf(htmlrep, "\n", repinfo->fullavailability); } fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_GREEN, 0, 1), colorname(COL_GREEN), colorname(COL_GREEN), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_YELLOW, 0, 1), colorname(COL_YELLOW), colorname(COL_YELLOW), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_RED, 0, 1), colorname(COL_RED), colorname(COL_RED), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_PURPLE, 0, 1), colorname(COL_PURPLE), colorname(COL_PURPLE), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_CLEAR, 0, 1), colorname(COL_CLEAR), colorname(COL_CLEAR), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n", xgetenv("XYMONSKIN"), dotgiffilename(COL_BLUE, 0, 1), colorname(COL_BLUE), colorname(COL_BLUE), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", repinfo->fullpct[COL_GREEN]); fprintf(htmlrep, "\n", repinfo->fullpct[COL_YELLOW]); fprintf(htmlrep, "\n", repinfo->fullpct[COL_RED]); fprintf(htmlrep, "\n", repinfo->fullpct[COL_PURPLE]); fprintf(htmlrep, "\n", repinfo->fullpct[COL_CLEAR]); fprintf(htmlrep, "\n", repinfo->fullpct[COL_BLUE]); fprintf(htmlrep, "\n"); if (repinfo->withreport) { fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", reportwarnlevel); fprintf(htmlrep, "\n", repinfo->reportpct[COL_GREEN]); fprintf(htmlrep, "\n", repinfo->reportpct[COL_YELLOW]); fprintf(htmlrep, "\n", repinfo->reportpct[COL_RED]); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", repinfo->reportpct[COL_CLEAR]); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); } fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", repinfo->count[COL_YELLOW]); fprintf(htmlrep, "\n", repinfo->count[COL_RED]); fprintf(htmlrep, "\n", repinfo->count[COL_PURPLE]); fprintf(htmlrep, "\n", repinfo->count[COL_CLEAR]); fprintf(htmlrep, "\n", repinfo->count[COL_BLUE]); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); if (strcmp(repinfo->fstate, "NOTOK") == 0) { fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); } fprintf(htmlrep, "

Availability (24x7): %.2f%%
 
Availability (SLA): %.2f%%

Availability: %.2f%%
 \"%s\"\"%s\"\"%s\"\"%s\"\"%s\"\"%s\"
24x7%.2f%%%.2f%%%.2f%%%.2f%%%.2f%%%.2f%%
SLA (%.2f)%.2f%%%.2f%%%.2f%%-%.2f%%-
Event count%d%d%d%d%d
\n"); fprintf(htmlrep, "[Total may not equal 100%%]
\n"); fprintf(htmlrep, "[History file contains invalid entries]
\n"); fprintf(htmlrep, "
\n"); /* Text-based report start */ if (textrep) { char text_starttime[20], text_endtime[20]; fprintf(textrep, "Availability Report\n"); strftime(text_starttime, sizeof(text_starttime), "%b %d %Y", localtime(&st)); strftime(text_endtime, sizeof(text_endtime), "%b %d %Y", localtime(&end)); if (strcmp(text_starttime, text_endtime) == 0) fprintf(textrep, "%s\n", text_starttime); else fprintf(textrep, "%s - %s\n", text_starttime, text_endtime); fprintf(textrep, "\n"); fprintf(textrep, "\n"); fprintf(textrep, " %s - %s\n", displayname, service); fprintf(textrep, "\n"); if (repinfo->withreport) { fprintf(textrep, " Availability (24x7) : %.2f%%\n", repinfo->fullavailability); fprintf(textrep, " Availability (SLA) : %.2f%%\n", repinfo->reportavailability); } else { fprintf(textrep, " Availability: %.2f%%\n", repinfo->fullavailability); } fprintf(textrep, " Green Yellow Red Purple Clear Blue\n"); fprintf(textrep, " 24x7 %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%%\n", repinfo->fullpct[COL_GREEN], repinfo->fullpct[COL_YELLOW], repinfo->fullpct[COL_RED], repinfo->fullpct[COL_PURPLE], repinfo->fullpct[COL_CLEAR], repinfo->fullpct[COL_BLUE]); if (repinfo->withreport) { fprintf(textrep, " SLA %.2f%% %.2f%% %.2f%% - %.2f%% - \n", repinfo->reportpct[COL_GREEN], repinfo->reportpct[COL_YELLOW], repinfo->reportpct[COL_RED], repinfo->reportpct[COL_CLEAR]); } fprintf(textrep, " Events %d %d %d %d %d %d\n", repinfo->count[COL_GREEN], repinfo->count[COL_YELLOW], repinfo->count[COL_RED], repinfo->count[COL_PURPLE], repinfo->count[COL_CLEAR], repinfo->count[COL_BLUE]); fprintf(textrep, "\n"); fprintf(textrep, "\n"); fprintf(textrep, " Event logs for the given period\n"); fprintf(textrep, "\n"); fprintf(textrep, "Event Start Event End Status Duration (Seconds) Cause\n"); fprintf(textrep, "\n"); fprintf(textrep, "\n"); } fprintf(htmlrep, "

\n"); fprintf(htmlrep, "
\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); fprintf(htmlrep, "\n", xgetenv("XYMONPAGECOLFONT")); fprintf(htmlrep, "\n"); for (walk = reploghead; (walk); walk = walk->next) { int wanted = 0; switch (style) { case STYLE_CRIT: wanted = (walk->color == COL_RED); break; case STYLE_NONGR: wanted = (walk->color != COL_GREEN); break; case STYLE_OTHER: wanted = 1; } if (wanted) { char start[30]; char end[30]; time_t endtime; int angrygif = (repinfo->withreport && walk->affectssla); strftime(start, sizeof(start), "%a %b %d %H:%M:%S %Y", localtime(&walk->starttime)); endtime = walk->starttime + walk->duration; strftime(end, sizeof(end), "%a %b %d %H:%M:%S %Y", localtime(&endtime)); fprintf(htmlrep, "\n", bgcols[curbg]); curbg = (1-curbg); fprintf(htmlrep, "\n", start); fprintf(htmlrep, "\n", end); fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", durationstr(walk->duration)); fprintf(htmlrep, "\n", walk->cause); fprintf(htmlrep, "\n\n"); /* And the text-report */ if (textrep) { fprintf(textrep, "%s %s %s %s %u ", start, end, colorname(walk->color), durationstr(walk->duration), (unsigned int)walk->duration); if (walk->cause) { char *p; for (p=walk->cause; (p && *p); ) { if (*p == '<') { p = strchr(p, '>'); if (p) p++; } else if (*p != '\n') { fprintf(textrep, "%c", *p); p++; } else p++; } fprintf(textrep, "\n"); } } } } fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", durationstr(repinfo->fullduration[COL_RED])); if (style != STYLE_CRIT) { fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", durationstr(repinfo->fullduration[COL_YELLOW] + repinfo->fullduration[COL_PURPLE] + repinfo->fullduration[COL_CLEAR] + repinfo->fullduration[COL_BLUE])); } if (repinfo->withreport) { fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", durationstr(repinfo->reportduration[COL_RED])); if (style != STYLE_CRIT) { fprintf(htmlrep, "\n"); fprintf(htmlrep, "\n", durationstr(repinfo->reportduration[COL_YELLOW])); } } /* And the text report ... */ if (textrep) { fprintf(textrep, "\n"); fprintf(textrep, "\n"); fprintf(textrep, " %s %s (%lu secs)\n", "Time Critical/Offline (24x7):", durationstr(repinfo->fullduration[COL_RED]), repinfo->fullduration[COL_RED]); if (style != STYLE_CRIT) { fprintf(textrep, " %s %s (%lu secs)\n", "Time Non-Critical (24x7):", durationstr(repinfo->fullduration[COL_YELLOW] + repinfo->fullduration[COL_PURPLE] + repinfo->fullduration[COL_CLEAR] + repinfo->fullduration[COL_BLUE]), (repinfo->fullduration[COL_YELLOW] + repinfo->fullduration[COL_PURPLE] + repinfo->fullduration[COL_CLEAR] + repinfo->fullduration[COL_BLUE])); } if (repinfo->withreport) { fprintf(textrep, "\n"); fprintf(textrep, "\n"); fprintf(textrep, " %s %s (%lu secs)\n", "Time Critical/Offline (SLA) :", durationstr(repinfo->reportduration[COL_RED]), repinfo->reportduration[COL_RED]); if (style != STYLE_CRIT) { fprintf(textrep, " %s %s (%lu secs)\n", "Time Non-Critical (SLA) :", durationstr(repinfo->reportduration[COL_YELLOW]), repinfo->fullduration[COL_YELLOW]); } } } fprintf(htmlrep, "
Event logs for the given period
Event StartEvent EndStatusDurationCause
%s%s"); fprintf(htmlrep, "", histlogurl(hostname, service, 0, walk->timespec)); fprintf(htmlrep, "\"%s\"", xgetenv("XYMONSKIN"), dotgiffilename(walk->color, 0, !angrygif), colorname(walk->color), colorname(walk->color), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); fprintf(htmlrep, "%s%s
\n"); fprintf(htmlrep, "Time Critical/Offline (24x7):%s
\n"); fprintf(htmlrep, "Time Non-Critical (24x7):%s
\n"); fprintf(htmlrep, "Time Critical/Offline (SLA):%s
\n"); fprintf(htmlrep, "Time Non-Critical (SLA):%s
\n"); fprintf(htmlrep, "

\n"); fprintf(htmlrep, "

\n"); fprintf(htmlrep, "Click here for text-based availability report\n", textrepurl); fprintf(htmlrep, "


\n"); /* XYMONREPEXT extensions */ do_extensions(htmlrep, "XYMONREPEXT", "rep"); fprintf(htmlrep, "
\n"); headfoot(htmlrep, "replog", "", "footer", color); } xymon-4.3.30/lib/sendmsg.h0000664000076400007640000000442313033575046015573 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __SENDMSG_H_ #define __SENDMSG_H_ #define XYMON_TIMEOUT 15 /* Default timeout for a request going to Xymon server */ #define PAGELEVELSDEFAULT "red purple" typedef enum { XYMONSEND_OK, XYMONSEND_EBADIP, XYMONSEND_EIPUNKNOWN, XYMONSEND_ENOSOCKET, XYMONSEND_ECANNOTDONONBLOCK, XYMONSEND_ECONNFAILED, XYMONSEND_ESELFAILED, XYMONSEND_ETIMEOUT, XYMONSEND_EWRITEERROR, XYMONSEND_EREADERROR, XYMONSEND_EBADURL } sendresult_t; typedef struct sendreturn_t { FILE *respfd; strbuffer_t *respstr; int fullresponse; int haveseenhttphdrs; } sendreturn_t; extern int xymonmsgcount; extern int xymonstatuscount; extern int xymonnocombocount; extern int dontsendmessages; extern void setproxy(char *proxy); extern sendresult_t sendmessage(char *msg, char *recipient, int timeout, sendreturn_t *response); extern sendreturn_t *newsendreturnbuf(int fullresponse, FILE *respfd); extern void freesendreturnbuf(sendreturn_t *s); extern char *getsendreturnstr(sendreturn_t *s, int takeover); extern void combo_start(void); extern void combo_end(void); extern void combo_add(strbuffer_t *msg); extern void combo_start_local(void); extern int sendmessage_init_local(void); extern void sendmessage_finish_local(void); extern sendresult_t sendmessage_local(char *msg); extern void init_status(int color); extern void addtostatus(char *p); extern void addtostrstatus(strbuffer_t *p); extern void finish_status(void); extern void meta_start(void); extern void meta_end(void); extern void init_meta(char *metaname); extern void addtometa(char *p); extern void finish_meta(void); #endif xymon-4.3.30/lib/run.c0000664000076400007640000001024113515623702014723 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains miscellaneous routines. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: run.c 6893 2012-01-21 12:52:53Z storner $"; #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" int run_command(char *cmd, char *errortext, strbuffer_t *banner, int showcmd, int timeout) { int result; char l[1024]; int pfd[2]; pid_t childpid; MEMDEFINE(l); result = 0; if (banner && showcmd) { snprintf(l, sizeof(l), "Command: %s\n\n", cmd); addtobuffer(banner, l); } /* Adapted from Stevens' popen()/pclose() example */ if (pipe(pfd) > 0) { errprintf("Could not create pipe: %s\n", strerror(errno)); MEMUNDEFINE(l); return -1; } if ((childpid = fork()) < 0) { errprintf("Could not fork child process: %s\n", strerror(errno)); MEMUNDEFINE(l); return -1; } if (childpid == 0) { /* The child runs here */ close(pfd[0]); if (pfd[1] != STDOUT_FILENO) { dup2(pfd[1], STDOUT_FILENO); dup2(pfd[1], STDERR_FILENO); close(pfd[1]); } if (strchr(cmd, ' ') == NULL) execlp(cmd, cmd, NULL); else { char *shell = getenv("SHELL"); if (!shell) shell = "/bin/sh"; execl(shell, "sh", "-c", cmd, NULL); } exit(127); } else { /* The parent runs here */ int done = 0, didterm = 0, n; struct timespec tmo, timestamp, cutoff; close(pfd[1]); /* Make our reads non-blocking */ if (fcntl(pfd[0], F_SETFL, O_NONBLOCK) == -1) { /* Failed .. but lets try and run this anyway */ errprintf("Could not set non-blocking reads on pipe: %s\n", strerror(errno)); } getntimer(&cutoff); cutoff.tv_sec += timeout; while (!done) { fd_set readfds; getntimer(×tamp); tvdiff(×tamp, &cutoff, &tmo); if ((tmo.tv_sec < 0) || (tmo.tv_nsec < 0)) { /* Timeout already happened */ n = 0; } else { struct timeval selecttmo; selecttmo.tv_sec = tmo.tv_sec; selecttmo.tv_usec = tmo.tv_nsec / 1000; FD_ZERO(&readfds); FD_SET(pfd[0], &readfds); n = select(pfd[0]+1, &readfds, NULL, NULL, &selecttmo); } if (n == -1) { errprintf("select() error: %s\n", strerror(errno)); result = -1; done = 1; } else if (n == 0) { /* Timeout */ errprintf("Timeout waiting for data from child, killing it\n"); kill(childpid, (didterm ? SIGKILL : SIGTERM)); if (!didterm) didterm = 1; else { done = 1; result = -1; } } else if (FD_ISSET(pfd[0], &readfds)) { n = read(pfd[0], l, sizeof(l)-1); l[n] = '\0'; if (n == 0) { done = 1; } else { if (banner && *l) addtobuffer(banner, l); if (errortext && (strstr(l, errortext) != NULL)) result = 1; } } } close(pfd[0]); result = 0; while ((result == 0) && (waitpid(childpid, &result, 0) < 0)) { if (errno != EINTR) { errprintf("Error picking up child exit status: %s\n", strerror(errno)); result = -1; } } if (WIFEXITED(result)) { result = WEXITSTATUS(result); } else if (WIFSIGNALED(result)) { errprintf("Child process terminated with signal %d\n", WTERMSIG(result)); result = -1; } } MEMUNDEFINE(l); return result; } xymon-4.3.30/lib/rmd_locl.h0000664000076400007640000001705111535462534015731 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was taken from the */ /* FreeBSD sources. It was originally written by Eric Young, and is NOT */ /* licensed under the GPL. Please adhere the original copyright notice below. */ /*----------------------------------------------------------------------------*/ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #include "ripemd.h" #undef c2nl #define c2nl(c,l) (l =(((u_int32_t)(*((c)++)))<<24), \ l|=(((u_int32_t)(*((c)++)))<<16), \ l|=(((u_int32_t)(*((c)++)))<< 8), \ l|=(((u_int32_t)(*((c)++))) )) #undef p_c2nl #define p_c2nl(c,l,n) { \ switch (n) { \ case 0: l =((u_int32_t)(*((c)++)))<<24; \ case 1: l|=((u_int32_t)(*((c)++)))<<16; \ case 2: l|=((u_int32_t)(*((c)++)))<< 8; \ case 3: l|=((u_int32_t)(*((c)++))); \ } \ } #undef c2nl_p /* NOTE the pointer is not incremented at the end of this */ #define c2nl_p(c,l,n) { \ l=0; \ (c)+=n; \ switch (n) { \ case 3: l =((u_int32_t)(*(--(c))))<< 8; \ case 2: l|=((u_int32_t)(*(--(c))))<<16; \ case 1: l|=((u_int32_t)(*(--(c))))<<24; \ } \ } #undef p_c2nl_p #define p_c2nl_p(c,l,sc,len) { \ switch (sc) \ { \ case 0: l =((u_int32_t)(*((c)++)))<<24; \ if (--len == 0) break; \ case 1: l|=((u_int32_t)(*((c)++)))<<16; \ if (--len == 0) break; \ case 2: l|=((u_int32_t)(*((c)++)))<< 8; \ } \ } #undef nl2c #define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l) )&0xff)) #undef c2l #define c2l(c,l) (l =(((u_int32_t)(*((c)++))) ), \ l|=(((u_int32_t)(*((c)++)))<< 8), \ l|=(((u_int32_t)(*((c)++)))<<16), \ l|=(((u_int32_t)(*((c)++)))<<24)) #undef p_c2l #define p_c2l(c,l,n) { \ switch (n) { \ case 0: l =((u_int32_t)(*((c)++))); \ case 1: l|=((u_int32_t)(*((c)++)))<< 8; \ case 2: l|=((u_int32_t)(*((c)++)))<<16; \ case 3: l|=((u_int32_t)(*((c)++)))<<24; \ } \ } #undef c2l_p /* NOTE the pointer is not incremented at the end of this */ #define c2l_p(c,l,n) { \ l=0; \ (c)+=n; \ switch (n) { \ case 3: l =((u_int32_t)(*(--(c))))<<16; \ case 2: l|=((u_int32_t)(*(--(c))))<< 8; \ case 1: l|=((u_int32_t)(*(--(c)))); \ } \ } #undef p_c2l_p #define p_c2l_p(c,l,sc,len) { \ switch (sc) \ { \ case 0: l =((u_int32_t)(*((c)++))); \ if (--len == 0) break; \ case 1: l|=((u_int32_t)(*((c)++)))<< 8; \ if (--len == 0) break; \ case 2: l|=((u_int32_t)(*((c)++)))<<16; \ } \ } #undef l2c #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>>24)&0xff)) #undef ROTATE #if defined(WIN32) #define ROTATE(a,n) _lrotl(a,n) #else #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) #endif /* A nice byte order reversal from Wei Dai */ #if defined(WIN32) /* 5 instructions with rotate instruction, else 9 */ #define Endian_Reverse32(a) \ { \ u_int32_t l=(a); \ (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ } #else /* 6 instructions with rotate instruction, else 8 */ #define Endian_Reverse32(a) \ { \ u_int32_t l=(a); \ l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ (a)=ROTATE(l,16L); \ } #endif #define F1(x,y,z) ((x)^(y)^(z)) #define F2(x,y,z) (((x)&(y))|((~x)&z)) #define F3(x,y,z) (((x)|(~y))^(z)) #define F4(x,y,z) (((x)&(z))|((y)&(~(z)))) #define F5(x,y,z) ((x)^((y)|(~(z)))) #define RIPEMD160_A 0x67452301L #define RIPEMD160_B 0xEFCDAB89L #define RIPEMD160_C 0x98BADCFEL #define RIPEMD160_D 0x10325476L #define RIPEMD160_E 0xC3D2E1F0L #include "rmdconst.h" #define RIP1(a,b,c,d,e,w,s) { \ a+=F1(b,c,d)+X[w]; \ a=ROTATE(a,s)+e; \ c=ROTATE(c,10); } #define RIP2(a,b,c,d,e,w,s,K) { \ a+=F2(b,c,d)+X[w]+K; \ a=ROTATE(a,s)+e; \ c=ROTATE(c,10); } #define RIP3(a,b,c,d,e,w,s,K) { \ a+=F3(b,c,d)+X[w]+K; \ a=ROTATE(a,s)+e; \ c=ROTATE(c,10); } #define RIP4(a,b,c,d,e,w,s,K) { \ a+=F4(b,c,d)+X[w]+K; \ a=ROTATE(a,s)+e; \ c=ROTATE(c,10); } #define RIP5(a,b,c,d,e,w,s,K) { \ a+=F5(b,c,d)+X[w]+K; \ a=ROTATE(a,s)+e; \ c=ROTATE(c,10); } xymon-4.3.30/lib/Makefile0000664000076400007640000001067412503132277015423 0ustar rpmbuildrpmbuild# Xymon library Makefile # XYMONLIBOBJS = osdefs.o acklog.o availability.o calc.o cgi.o cgiurls.o clientlocal.o color.o crondate.o digest.o encoding.o environ.o errormsg.o eventlog.o files.o headfoot.o xymonrrd.o holidays.o htmllog.o ipaccess.o loadalerts.o loadcriticalconf.o links.o matching.o md5.o memory.o misc.o msort.o netservices.o notifylog.o acknowledgementslog.o readmib.o reportlog.o rmd160c.o sha1.o sha2.o sig.o stackio.o strfunc.o suid.o timefunc.o tree.o url.o webaccess.o XYMONCOMMLIBOBJS = $(XYMONLIBOBJS) loadhosts.o locator.o sendmsg.o xymond_ipc.o xymond_buffer.o XYMONTIMELIBOBJS = run.o timing.o CLIENTLIBOBJS = osdefs.o cgiurls.o color-client.o crondate.o digest.o encoding.o environ-client.o errormsg.o holidays.o ipaccess.o md5.o memory.o misc.o msort.o rmd160c.o sha1.o sha2.o sig.o stackio.o strfunc.o suid.o timefunc-client.o tree.o ifeq ($(LOCALCLIENT),yes) CLIENTLIBOBJS += matching.o endif XYMONCLIENTCOMMLIBOBJS = locator.o loadhosts.o sendmsg.o xymond_ipc.o xymond_buffer.o XYMONCLIENTLIB = libxymonclient.a XYMONCLIENTLIBS = $(XYMONCLIENTLIB) XYMONCLIENTCOMMLIB = libxymonclientcomm.a XYMONCLIENTCOMMLIBS = $(XYMONCLIENTCOMMLIB) $(ZLIBLIBS) $(XYMONCLIENTLIB) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONLIB = libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(ZLIBLIBS) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) CFLAGS += -I../include all: test-endianness $(XYMONLIB) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) loadhosts stackio availability md5 sha1 rmd160 locator tree client: test-endianness $(XYMONCLIENTLIB) $(XYMONCLIENTCOMMLIB) $(XYMONTIMELIB) test-endianness: test-endianness.c $(CC) $(CFLAGS) -o $@ $< $(XYMONLIB): $(XYMONLIBOBJS) ar cr $(XYMONLIB) $(XYMONLIBOBJS) ranlib $(XYMONLIB) || echo "" $(XYMONCOMMLIB): $(XYMONCOMMLIBOBJS) ar cr $(XYMONCOMMLIB) $(XYMONCOMMLIBOBJS) ranlib $(XYMONCOMMLIB) || echo "" $(XYMONTIMELIB): $(XYMONTIMELIBOBJS) ar cr $(XYMONTIMELIB) $(XYMONTIMELIBOBJS) ranlib $(XYMONTIMELIB) || echo "" $(XYMONCLIENTLIB): $(CLIENTLIBOBJS) ar cr $(XYMONCLIENTLIB) $(CLIENTLIBOBJS) ranlib $(XYMONCLIENTLIB) || echo "" $(XYMONCLIENTCOMMLIB): $(XYMONCLIENTCOMMLIBOBJS) ar cr $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTCOMMLIBOBJS) ranlib $(XYMONCLIENTCOMMLIB) || echo "" loadhosts.o: loadhosts.c loadhosts_file.c loadhosts_net.c $(CC) $(CFLAGS) -c -o $@ loadhosts.c eventlog.o: eventlog.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< notifylog.o: notifylog.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< acknowledgementslog.o: acknowledgementslog.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< headfoot.o: headfoot.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< loadalerts.o: loadalerts.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< matching.o: matching.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< sha1.o: sha1.c $(CC) $(CFLAGS) `./test-endianness` -c -o $@ $< rmd160c.o: rmd160c.c $(CC) $(CFLAGS) `./test-endianness` -c -o $@ $< environ.o: environ.c $(CC) $(CFLAGS) -DXYMONTOPDIR=\"$(XYMONTOPDIR)\" -DXYMONLOGDIR=\"$(XYMONLOGDIR)\" -DXYMONHOSTNAME=\"$(XYMONHOSTNAME)\" -DXYMONHOSTIP=\"$(XYMONHOSTIP)\" -DXYMONHOSTOS=\"$(XYMONHOSTOS)\" -DXYMONHOME=\"$(XYMONHOME)\" -c -o $@ environ.c environ-client.o: environ.c $(CC) $(CFLAGS) -DXYMONTOPDIR=\"$(XYMONTOPDIR)\" -DXYMONLOGDIR=\"$(XYMONLOGDIR)\" -DXYMONHOSTNAME=\"$(XYMONHOSTNAME)\" -DXYMONHOSTIP=\"$(XYMONHOSTIP)\" -DXYMONHOSTOS=\"$(XYMONHOSTOS)\" -DXYMONHOME=\"$(XYMONCLIENTHOME)\" -c -o $@ environ.c color-client.o: color.c $(CC) $(CFLAGS) -DCLIENTONLY -c -o $@ $< timefunc-client.o: timefunc.c $(CC) $(CFLAGS) -DCLIENTONLY -c -o $@ $< loadhosts: loadhosts.c loadhosts_file.c loadhosts_net.c $(XYMONCOMMLIB) $(CC) $(CFLAGS) -DSTANDALONE -o $@ loadhosts.c $(XYMONCOMMLIBS) stackio: stackio.c libxymon.a $(CC) $(CFLAGS) -DSTANDALONE -o $@ stackio.c $(XYMONLIBS) availability: availability.c libxymon.a $(CC) $(CFLAGS) -DSTANDALONE -o $@ availability.c $(XYMONLIBS) md5: md5.c $(CC) $(CFLAGS) -DSTANDALONE `./test-endianness` -o $@ md5.c sha1: sha1.c $(CC) $(CFLAGS) -DSTANDALONE `./test-endianness` -o $@ sha1.c rmd160: rmd160c.c $(CC) $(CFLAGS) -DSTANDALONE `./test-endianness` -o $@ rmd160c.c locator: locator.c $(CC) $(CFLAGS) -DSTANDALONE -o $@ locator.c $(XYMONCOMMLIBS) $(XYMONLIBS) tree: tree.c $(CC) $(CFLAGS) -DSTANDALONE -o $@ tree.c clean: rm -f *.o *.a *~ loadhosts stackio availability test-endianness md5 sha1 rmd160 locator tree xymon-4.3.30/lib/locator.h0000664000076400007640000000355111615341300015563 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOCATOR_H__ #define __LOCATOR_H__ enum locator_servicetype_t { ST_RRD, ST_CLIENT, ST_ALERT, ST_HISTORY, ST_HOSTDATA, ST_MAX } ; extern const char *servicetype_names[]; enum locator_sticky_t { LOC_ROAMING, LOC_STICKY, LOC_SINGLESERVER } ; extern enum locator_servicetype_t get_servicetype(char *typestr); extern int locator_init(char *ipport); extern void locator_prepcache(enum locator_servicetype_t svc, int timeout); extern void locator_flushcache(enum locator_servicetype_t svc, char *key); extern char *locator_ping(void); extern int locator_register_server(char *servername, enum locator_servicetype_t svctype, int weight, enum locator_sticky_t sticky, char *extras); extern int locator_register_host(char *hostname, enum locator_servicetype_t svctype, char *servername); extern int locator_rename_host(char *oldhostname, char *newhostname, enum locator_servicetype_t svctype); extern char *locator_query(char *hostname, enum locator_servicetype_t svctype, char **extras); extern int locator_serverup(char *servername, enum locator_servicetype_t svctype); extern int locator_serverdown(char *servername, enum locator_servicetype_t svctype); #endif xymon-4.3.30/lib/md5.c0000664000076400007640000003411011535462534014611 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This file is part of the Xymon monitor library, but was written by */ /* Peter Deutsch and released under the GNU GPL. */ /*----------------------------------------------------------------------------*/ /* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.c 6650 2011-03-08 17:20:28Z storner $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ /************ XYMON SPECIFIC MODIFICATION *****************/ /* For Xymon: Moved these definitions from md5.h into here */ typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t abcd[4]; /* digest buffer */ md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; /************ END XYMON SPECIFIC MODIFICATION *****************/ #include #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else # define BYTE_ORDER 0 #endif #define T_MASK ((md5_word_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ md5_word_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; #endif { #if BYTE_ORDER == 0 /* * Determine dynamically whether this is a big-endian or * little-endian machine, since we can use a more efficient * algorithm on the latter. */ static const int w = 1; if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ #endif #if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const md5_byte_t *)0) & 3)) { /* data are properly aligned */ X = (const md5_word_t *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } } #endif #if BYTE_ORDER == 0 else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const md5_byte_t *xp = data; int i; # if BYTE_ORDER == 0 X = xbuf; /* (dynamic only) */ # else # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #endif } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } static void md5_init(md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } static void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { const md5_byte_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } static void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } /* Added for use with Xymon */ int myMD5_Size(void) { return sizeof(md5_state_t); } void myMD5_Init(void *pms) { md5_init((md5_state_t *)pms); } void myMD5_Update(void *pms, unsigned char *data, int nbytes) { md5_append((md5_state_t *)pms, (md5_byte_t *)data, nbytes); } void myMD5_Final(unsigned char digest[16], void *pms) { md5_finish((md5_state_t *)pms, (md5_byte_t *)digest); } #ifdef STANDALONE #include #include #include int main(int argc, char *argv[]) { FILE *fd; int n; unsigned char buf[8192]; void *context; unsigned char digest[16]; int i; fd = fopen(argv[1], "r"); if (fd == NULL) return 1; context = (void *)malloc(myMD5_Size()); myMD5_Init(context); while ((n = fread(buf, 1, sizeof(buf), fd)) > 0) myMD5_Update(context, buf, n); fclose(fd); myMD5_Final(digest, context); for (i=0; (i < sizeof(digest)); i++) printf("%02x", digest[i]); printf("\n"); return 0; } #endif xymon-4.3.30/lib/loadalerts.h0000664000076400007640000000670312654212423016263 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOADALERTS_H__ #define __LOADALERTS_H__ #include #include /* The clients probably don't have the pcre headers */ #if defined(LOCALCLIENT) || !defined(CLIENTONLY) #include typedef enum { A_PAGING, A_NORECIP, A_ACKED, A_RECOVERED, A_DISABLED, A_NOTIFY, A_DEAD } astate_t; typedef struct activealerts_t { /* Identification of the alert */ char *hostname; char *testname; char *location; char *osname; char *classname; char *groups; char ip[IP_ADDR_STRLEN]; /* Alert status */ int color, maxcolor; unsigned char *pagemessage; unsigned char *ackmessage; time_t eventstart; time_t nextalerttime; astate_t state; int cookie; struct activealerts_t *next; } activealerts_t; /* These are the criteria we use when matching an alert. Used both generally for a rule, and for recipients */ enum method_t { M_MAIL, M_SCRIPT, M_IGNORE }; enum msgformat_t { ALERTFORM_TEXT, ALERTFORM_PLAIN, ALERTFORM_SMS, ALERTFORM_PAGER, ALERTFORM_SCRIPT, ALERTFORM_NONE }; enum recovermsg_t { SR_UNKNOWN, SR_NOTWANTED, SR_WANTED }; typedef struct criteria_t { int cfid; char *cfline; char *pagespec; /* Pages to include */ pcre *pagespecre; char *expagespec; /* Pages to exclude */ pcre *expagespecre; char *dgspec; /* Display groups to include */ pcre *dgspecre; char *exdgspec; /* Display groups to exclude */ pcre *exdgspecre; char *hostspec; /* Hosts to include */ pcre *hostspecre; char *exhostspec; /* Hosts to exclude */ pcre *exhostspecre; char *svcspec; /* Services to include */ pcre *svcspecre; char *exsvcspec; /* Services to exclude */ pcre *exsvcspecre; char *classspec; pcre *classspecre; char *exclassspec; pcre *exclassspecre; char *groupspec; pcre *groupspecre; char *exgroupspec; pcre *exgroupspecre; int colors; char *timespec; char *extimespec; int minduration, maxduration; /* In seconds */ enum recovermsg_t sendrecovered, sendnotice; } criteria_t; /* This defines a recipient. There may be some criteria, and then how we send alerts to him */ typedef struct recip_t { int cfid; criteria_t *criteria; enum method_t method; char *recipient; char *scriptname; enum msgformat_t format; time_t interval; /* In seconds */ int stoprule, unmatchedonly, noalerts; struct recip_t *next; } recip_t; extern int load_alertconfig(char *configfn, int alertcolors, int alertinterval); extern void dump_alertconfig(int showlinenumbers); extern void set_localalertmode(int localmode); extern int stoprulefound; extern recip_t *next_recipient(activealerts_t *alert, int *first, int *anymatch, time_t *nexttime); extern int have_recipient(activealerts_t *alert, int *anymatch); extern void alert_printmode(int on); extern void print_alert_recipients(activealerts_t *alert, strbuffer_t *buf); #endif #endif xymon-4.3.30/lib/suid.c0000664000076400007640000000356413515623702015075 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for handling UID changes. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: suid.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include "libxymon.h" int havemyuid = 0; static uid_t myuid; #ifdef HPUX void drop_root(void) { if (!havemyuid) { myuid = getuid(); havemyuid = 1; } setresuid(-1, myuid, -1); } void get_root(void) { setresuid(-1, 0, -1); } #else void drop_root(void) { if (!havemyuid) { myuid = getuid(); havemyuid = 1; } if (seteuid(myuid) != 0) { perror("Failed to drop root privileges\n"); abort(); } } void get_root(void) { if (seteuid(0) != 0) { perror("Failed to get root privileges\n"); abort(); } } #endif void drop_root_and_removesuid(char *fn) { struct stat st; if ( (stat(fn, &st) == 0) && (st.st_mode & S_ISUID) && (st.st_uid == 0) ) { /* We now know that fn is suid-root */ chmod(fn, (st.st_mode & (~S_ISUID))); } drop_root(); } xymon-4.3.30/lib/crondate.c0000664000076400007640000003767511615341300015730 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for time-specs in CRON format. */ /* */ /* Copyright (C) 2010-2011 Henrik Storner */ /* Copyright (C) 2010 Milan Kocian */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2 (see the file "COPYING" for details), except as listed below. */ /* */ /*----------------------------------------------------------------------------*/ /* * A large part of this file was adapted from the "cron" sources by Paul * Vixie. It contains this copyright notice: * ------------------------------------------------------------------------ * Copyright 1988,1990,1993,1994 by Paul Vixie * All rights reserved * * Distribute freely, except: don't remove my name from the source or * documentation (don't take credit for my work), mark your changes (don't * get me blamed for your possible bugs), don't alter or remove this * notice. May be sold if buildable source is provided to buyer. No * warrantee of any kind, express or implied, is included with this * software; use at your own risk, responsibility for damages (if any) to * anyone resulting from the use of this software rests entirely with the * user. * ------------------------------------------------------------------------ * Adjusted by Milan Kocian so don't tease original autor * for my bugs. * * Major change is that functions operate on string instead on file. * And it's used only time part of cronline (no user, cmd, etc.) * Also, the file "bitstring.h" was used from the cron sources. This file * carries the following copyright notice: * ------------------------------------------------------------------------ * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Vixie. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#)bitstring.h 5.2 (Berkeley) 4/4/90 * ------------------------------------------------------------------------ * */ static char rcsid[] = "$Id: crondate.c 6712 2011-07-31 21:01:52Z storner $"; /* -------------------- bitstring.h begins -----------------------------*/ #include #include #include #include #include typedef unsigned char bitstr_t; /* internal macros */ /* byte of the bitstring bit is in */ #define _bit_byte(bit) \ ((bit) >> 3) /* mask for the bit within its byte */ #define _bit_mask(bit) \ (1 << ((bit)&0x7)) /* external macros */ /* bytes in a bitstring of nbits bits */ #define bitstr_size(nbits) \ ((((nbits) - 1) >> 3) + 1) /* allocate a bitstring */ #define bit_alloc(nbits) \ (bitstr_t *)malloc(1, \ (unsigned int)bitstr_size(nbits) * sizeof(bitstr_t)) /* allocate a bitstring on the stack */ #define bit_decl(name, nbits) \ (name)[bitstr_size(nbits)] /* is bit N of bitstring name set? */ #define bit_test(name, bit) \ ((name)[_bit_byte(bit)] & _bit_mask(bit)) /* set bit N of bitstring name */ #define bit_set(name, bit) \ (name)[_bit_byte(bit)] |= _bit_mask(bit) /* clear bit N of bitstring name */ #define bit_clear(name, bit) \ (name)[_bit_byte(bit)] &= ~_bit_mask(bit) /* clear bits start ... stop in bitstring */ #define bit_nclear(name, start, stop) { \ register bitstr_t *_name = name; \ register int _start = start, _stop = stop; \ register int _startbyte = _bit_byte(_start); \ register int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ (0xff << ((_stop&0x7) + 1))); \ } else { \ _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ while (++_startbyte < _stopbyte) \ _name[_startbyte] = 0; \ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ } \ } /* set bits start ... stop in bitstring */ #define bit_nset(name, start, stop) { \ register bitstr_t *_name = name; \ register int _start = start, _stop = stop; \ register int _startbyte = _bit_byte(_start); \ register int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] |= ((0xff << (_start&0x7)) & \ (0xff >> (7 - (_stop&0x7)))); \ } else { \ _name[_startbyte] |= 0xff << ((_start)&0x7); \ while (++_startbyte < _stopbyte) \ _name[_startbyte] = 0xff; \ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ } \ } /* find first bit clear in name */ #define bit_ffc(name, nbits, value) { \ register bitstr_t *_name = name; \ register int _byte, _nbits = nbits; \ register int _stopbyte = _bit_byte(_nbits), _value = -1; \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte] != 0xff) { \ _value = _byte << 3; \ for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ ++_value, _stopbyte >>= 1); \ break; \ } \ *(value) = _value; \ } /* find first bit set in name */ #define bit_ffs(name, nbits, value) { \ register bitstr_t *_name = name; \ register int _byte, _nbits = nbits; \ register int _stopbyte = _bit_byte(_nbits), _value = -1; \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte]) { \ _value = _byte << 3; \ for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ ++_value, _stopbyte >>= 1); \ break; \ } \ *(value) = _value; \ } /* -------------------- end of bitstring.h ------------------------------- */ /* --------------------- crondate from Paul Vixie cron ------------------ */ #define TRUE 1 #define FALSE 0 #define MAX_TEMPSTR 1000 #define Skip_Blanks(c) \ while (*c == '\t' || *c == ' ') \ c++; #define Skip_Nonblanks(c) \ while (*c!='\t' && *c!=' ' && *c!='\n' && *c!='\0') \ c++; #define SECONDS_PER_MINUTE 60 #define FIRST_MINUTE 0 #define LAST_MINUTE 59 #define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1) #define FIRST_HOUR 0 #define LAST_HOUR 23 #define HOUR_COUNT (LAST_HOUR - FIRST_HOUR + 1) #define FIRST_DOM 1 #define LAST_DOM 31 #define DOM_COUNT (LAST_DOM - FIRST_DOM + 1) #define FIRST_MONTH 1 #define LAST_MONTH 12 #define MONTH_COUNT (LAST_MONTH - FIRST_MONTH + 1) /* note on DOW: 0 and 7 are both Sunday, for compatibility reasons. */ #define FIRST_DOW 0 #define LAST_DOW 7 #define DOW_COUNT (LAST_DOW - FIRST_DOW + 1) typedef struct { bitstr_t bit_decl(minute, MINUTE_COUNT); bitstr_t bit_decl(hour, HOUR_COUNT); bitstr_t bit_decl(dom, DOM_COUNT); bitstr_t bit_decl(month, MONTH_COUNT); bitstr_t bit_decl(dow, DOW_COUNT); int flags; #define DOM_STAR 0x01 #define DOW_STAR 0x02 #define WHEN_REBOOT 0x04 #define MIN_STAR 0x08 #define HR_STAR 0x10 } c_bits_t; #define PPC_NULL ((char **)NULL) static char *MonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; static char *DowNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", NULL }; static char * get_number(numptr, low, names, ch) int *numptr; /* where does the result go? */ int low; /* offset applied to result if symbolic enum used */ char *names[]; /* symbolic names, if any, for enums */ char *ch; /* current character */ { char temp[MAX_TEMPSTR], *pc; int len, i, all_digits; /* collect alphanumerics into our fixed-size temp array */ pc = temp; len = 0; all_digits = TRUE; while (isalnum((int)*ch)) { if (++len >= MAX_TEMPSTR) return(NULL); *pc++ = *ch; if (!isdigit((int)*ch)) all_digits = FALSE; ch++; } *pc = '\0'; if (len == 0) { return(NULL); } /* try to find the name in the name list */ if (names) { for (i = 0; names[i] != NULL; i++) { if (!strcasecmp(names[i], temp)) { *numptr = i+low; return ch; } } } /* no name list specified, or there is one and our string isn't * in it. either way: if it's all digits, use its magnitude. * otherwise, it's an error. */ if (all_digits) { *numptr = atoi(temp); return ch; } return(NULL) ; } static int set_element(bits, low, high, number) bitstr_t *bits; /* one bit per flag, default=FALSE */ int low; int high; int number; { if (number < low || number > high) return(-1); bit_set(bits, (number-low)); return(0); } static char * get_range(bits, low, high, names, ch, last) bitstr_t *bits; /* one bit per flag, default=FALSE */ int low, high; /* bounds, impl. offset for bitstr */ char *names[]; /* NULL or names of elements */ char *ch; /* current character being processed */ int last; /* processing last value */ { /* range = number | number "-" number [ "/" number ] */ register int i; auto int num1, num2, num3; if (*ch == '*') { /* '*' means "first-last" but can still be modified by /step */ num1 = low; num2 = high; ch++; if (!*ch) { if (!last) /* string is too short (if not last)*/ return(NULL); } } else { ch = get_number(&num1, low, names, ch); if (!ch) return (NULL); if (*ch != '-') { /* not a range, it's a single number. */ if (set_element(bits, low, high, num1)) return(NULL); return ch; } else { /* eat the dash */ ch++; if (!*ch) return(NULL); /* get the number following the dash */ ch = get_number(&num2, low, names, ch); if (!ch) return(NULL); } } /* check for step size */ if (*ch == '/') { /* eat the slash */ ch++; if (!*ch) return(NULL); /* get the step size -- note: we don't pass the * names here, because the number is not an * element id, it's a step size. 'low' is * sent as a 0 since there is no offset either. */ ch = get_number(&num3, 0, PPC_NULL, ch); if (!ch || num3 <= 0) return(NULL) ; } else { /* no step. default==1. */ num3 = 1; } /* Explicitly check for sane values. Certain combinations of ranges and * steps which should return EOF don't get picked up by the code below, * eg: * 5-64/30 * * * * touch /dev/null * * Code adapted from set_elements() where this error was probably intended * to be catched. */ if (num1 < low || num1 > high || num2 < low || num2 > high) return(NULL); /* range. set all elements from num1 to num2, stepping * by num3. (the step is a downward-compatible extension * proposed conceptually by bob@acornrc, syntactically * designed then implmented by paul vixie). */ for (i = num1; i <= num2; i += num3) if (set_element(bits, low, high, i)) return(NULL); return ch; } static char * get_list(bits, low, high, names, ch, last) bitstr_t *bits; /* one bit per flag, default=FALSE */ int low, high; /* bounds, impl. offset for bitstr */ char *names[]; /* NULL or *[] of names for these elements */ char *ch; /* current character being processed */ int last; /* processing last value */ { register int done; /* we know that we point to a non-blank character here; * must do a Skip_Blanks before we exit, so that the * next call (or the code that picks up the cmd) can * assume the same thing. */ /* clear the bit string, since the default is 'off'. */ bit_nclear(bits, 0, (high-low+1)); /* process all ranges */ done = FALSE; while (!done) { ch = get_range(bits, low, high, names, ch, last); if (ch && *ch == ',') ch++; else done = TRUE; } /* exiting. skip to some blanks, then skip over the blanks. */ if (ch) { Skip_Nonblanks(ch) Skip_Blanks(ch) } return ch; } /* parse cron time */ void * parse_cron_time(char * ch) { c_bits_t *e; e = (c_bits_t *) calloc(1, sizeof(c_bits_t)); if (!e) return(NULL); if (ch[0] == '@') { if (!strcmp("yearly", ch + 1) || !strcmp("annually", ch + 1)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_set(e->dom, 0); bit_set(e->month, 0); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOW_STAR; } else if (!strcmp("monthly", ch + 1)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_set(e->dom, 0); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOW_STAR; } else if (!strcmp("weekly", ch + 1)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); e->flags |= DOM_STAR; bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0,0); } else if (!strcmp("daily", ch + 1) || !strcmp("midnight", ch + 1)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); } else if (!strcmp("hourly", ch + 1)) { bit_set(e->minute, 0); bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1)); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= HR_STAR; } else { free(e); return(NULL); } } else { /* end of '@' and begin for * * .. */ if (*ch == '*') e->flags |= MIN_STAR; ch = get_list(e->minute, FIRST_MINUTE, LAST_MINUTE, PPC_NULL, ch, 0); if (!ch) { free(e); return(NULL); } /* hours */ if (*ch == '*') e->flags |= HR_STAR; ch = get_list(e->hour, FIRST_HOUR, LAST_HOUR, PPC_NULL, ch, 0); if (!ch) { free(e); return(NULL); } /* DOM (days of month) */ if (*ch == '*') e->flags |= DOM_STAR; ch = get_list(e->dom, FIRST_DOM, LAST_DOM, PPC_NULL, ch, 0); if (!ch) { free(e); return(NULL); } /* month */ ch = get_list(e->month, FIRST_MONTH, LAST_MONTH, MonthNames, ch, 0); if (!ch) { free(e); return(NULL); } /* DOW (days of week) */ if (*ch == '*') e->flags |= DOW_STAR; ch = get_list(e->dow, FIRST_DOW, LAST_DOW, DowNames, ch, 1); if (!ch) { free(e); return(NULL); } } /* make sundays equivilent */ if (bit_test(e->dow, 0) || bit_test(e->dow, 7)) { bit_set(e->dow, 0); bit_set(e->dow, 7); } /* end of * * ... parse */ return e; } /* END of cron date-time parser */ /*----------------- End of code from Paul Vixie's cron sources ----------------*/ void crondatefree(void *vcdate) { c_bits_t *cdate = (c_bits_t *)vcdate; free(cdate); } static int minute=-1, hour=-1, dom=-1, month=-1, dow=-1; void crongettime(void) { time_t now; struct tm tt; now = time(NULL); /* we need real clock, not monotonic from gettimer */ localtime_r(&now, &tt); minute = tt.tm_min -FIRST_MINUTE; hour = tt.tm_hour -FIRST_HOUR; dom = tt.tm_mday -FIRST_DOM; month = tt.tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH; dow = tt.tm_wday -FIRST_DOW; } int cronmatch(void *vcdate) { c_bits_t *cdate = (c_bits_t *)vcdate; if (minute == -1) crongettime(); return cdate && bit_test(cdate->minute, minute) && bit_test(cdate->hour, hour) && bit_test(cdate->month, month) && ( ((cdate->flags & DOM_STAR) || (cdate->flags & DOW_STAR)) ? (bit_test(cdate->dow,dow) && bit_test(cdate->dom,dom)) : (bit_test(cdate->dow,dow) || bit_test(cdate->dom,dom))); } xymon-4.3.30/lib/sig.h0000664000076400007640000000147411615341300014704 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __SIG_H__ #define __SIG_H__ extern void setup_signalhandler(char *programname); #endif xymon-4.3.30/lib/sha2.c0000664000076400007640000010273613515623702014767 0ustar rpmbuildrpmbuild/* * FIPS 180-2 SHA-224/256/384/512 implementation * Last update: 02/02/2007 * Issue date: 04/30/2005 * * Copyright (C) 2005, 2007 Olivier Gay * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #define UNROLL_LOOPS /* Enable loops unrolling */ #endif #include #include "sha2.h" #define SHFR(x, n) (x >> n) #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) #define CH(x, y, z) ((x & y) ^ (~x & z)) #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) #define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) #define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7)) #define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6)) #define UNPACK32(x, str) \ { \ *((str) + 3) = (uint8) ((x) ); \ *((str) + 2) = (uint8) ((x) >> 8); \ *((str) + 1) = (uint8) ((x) >> 16); \ *((str) + 0) = (uint8) ((x) >> 24); \ } #define PACK32(str, x) \ { \ *(x) = ((uint32) *((str) + 3) ) \ | ((uint32) *((str) + 2) << 8) \ | ((uint32) *((str) + 1) << 16) \ | ((uint32) *((str) + 0) << 24); \ } #define UNPACK64(x, str) \ { \ *((str) + 7) = (uint8) ((x) ); \ *((str) + 6) = (uint8) ((x) >> 8); \ *((str) + 5) = (uint8) ((x) >> 16); \ *((str) + 4) = (uint8) ((x) >> 24); \ *((str) + 3) = (uint8) ((x) >> 32); \ *((str) + 2) = (uint8) ((x) >> 40); \ *((str) + 1) = (uint8) ((x) >> 48); \ *((str) + 0) = (uint8) ((x) >> 56); \ } #define PACK64(str, x) \ { \ *(x) = ((uint64) *((str) + 7) ) \ | ((uint64) *((str) + 6) << 8) \ | ((uint64) *((str) + 5) << 16) \ | ((uint64) *((str) + 4) << 24) \ | ((uint64) *((str) + 3) << 32) \ | ((uint64) *((str) + 2) << 40) \ | ((uint64) *((str) + 1) << 48) \ | ((uint64) *((str) + 0) << 56); \ } /* Macros used for loops unrolling */ #define SHA256_SCR(i) \ { \ w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ + SHA256_F3(w[i - 15]) + w[i - 16]; \ } #define SHA512_SCR(i) \ { \ w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \ + SHA512_F3(w[i - 15]) + w[i - 16]; \ } #define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ { \ t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ + sha256_k[j] + w[j]; \ t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ wv[d] += t1; \ wv[h] = t1 + t2; \ } #define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \ { \ t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ + sha512_k[j] + w[j]; \ t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ wv[d] += t1; \ wv[h] = t1 + t2; \ } uint32 sha224_h0[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; uint32 sha256_h0[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; uint64 sha384_h0[8] = {0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL}; uint64 sha512_h0[8] = {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL}; uint32 sha256_k[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; uint64 sha512_k[80] = {0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL}; /* SHA-256 functions */ void sha256_transf(sha256_ctx *ctx, const unsigned char *message, unsigned int block_nb) { uint32 w[64]; uint32 wv[8]; uint32 t1, t2; const unsigned char *sub_block; int i; #ifndef UNROLL_LOOPS int j; #endif for (i = 0; i < (int) block_nb; i++) { sub_block = message + (i << 6); #ifndef UNROLL_LOOPS for (j = 0; j < 16; j++) { PACK32(&sub_block[j << 2], &w[j]); } for (j = 16; j < 64; j++) { SHA256_SCR(j); } for (j = 0; j < 8; j++) { wv[j] = ctx->h[j]; } for (j = 0; j < 64; j++) { t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j]; t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); wv[7] = wv[6]; wv[6] = wv[5]; wv[5] = wv[4]; wv[4] = wv[3] + t1; wv[3] = wv[2]; wv[2] = wv[1]; wv[1] = wv[0]; wv[0] = t1 + t2; } for (j = 0; j < 8; j++) { ctx->h[j] += wv[j]; } #else PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]); PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]); PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]); PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]); PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]); PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]); PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]); PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]); SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19); SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23); SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27); SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31); SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35); SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39); SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43); SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47); SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51); SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55); SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59); SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63); wv[0] = ctx->h[0]; wv[1] = ctx->h[1]; wv[2] = ctx->h[2]; wv[3] = ctx->h[3]; wv[4] = ctx->h[4]; wv[5] = ctx->h[5]; wv[6] = ctx->h[6]; wv[7] = ctx->h[7]; SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1); SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3); SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5); SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7); SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9); SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11); SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13); SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15); SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17); SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19); SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21); SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23); SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25); SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27); SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29); SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31); SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33); SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35); SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37); SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39); SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41); SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43); SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45); SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47); SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49); SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51); SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53); SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55); SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57); SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59); SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61); SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63); ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; #endif /* !UNROLL_LOOPS */ } } void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) { sha256_ctx ctx; sha256_init(&ctx); sha256_update(&ctx, message, len); sha256_final(&ctx, digest); } void sha256_init(sha256_ctx *ctx) { #ifndef UNROLL_LOOPS int i; for (i = 0; i < 8; i++) { ctx->h[i] = sha256_h0[i]; } #else ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1]; ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3]; ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5]; ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7]; #endif /* !UNROLL_LOOPS */ ctx->len = 0; ctx->tot_len = 0; } void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len) { unsigned int block_nb; unsigned int new_len, rem_len, tmp_len; const unsigned char *shifted_message; tmp_len = SHA256_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], message, rem_len); if (ctx->len + len < SHA256_BLOCK_SIZE) { ctx->len += len; return; } new_len = len - rem_len; block_nb = new_len / SHA256_BLOCK_SIZE; shifted_message = message + rem_len; sha256_transf(ctx, ctx->block, 1); sha256_transf(ctx, shifted_message, block_nb); rem_len = new_len % SHA256_BLOCK_SIZE; memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 6; } void sha256_final(sha256_ctx *ctx, unsigned char *digest) { unsigned int block_nb; unsigned int pm_len; unsigned int len_b; #ifndef UNROLL_LOOPS int i; #endif block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); len_b = (ctx->tot_len + ctx->len) << 3; pm_len = block_nb << 6; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK32(len_b, ctx->block + pm_len - 4); sha256_transf(ctx, ctx->block, block_nb); #ifndef UNROLL_LOOPS for (i = 0 ; i < 8; i++) { UNPACK32(ctx->h[i], &digest[i << 2]); } #else UNPACK32(ctx->h[0], &digest[ 0]); UNPACK32(ctx->h[1], &digest[ 4]); UNPACK32(ctx->h[2], &digest[ 8]); UNPACK32(ctx->h[3], &digest[12]); UNPACK32(ctx->h[4], &digest[16]); UNPACK32(ctx->h[5], &digest[20]); UNPACK32(ctx->h[6], &digest[24]); UNPACK32(ctx->h[7], &digest[28]); #endif /* !UNROLL_LOOPS */ } /* SHA-512 functions */ void sha512_transf(sha512_ctx *ctx, const unsigned char *message, unsigned int block_nb) { uint64 w[80]; uint64 wv[8]; uint64 t1, t2; const unsigned char *sub_block; int i, j; for (i = 0; i < (int) block_nb; i++) { sub_block = message + (i << 7); #ifndef UNROLL_LOOPS for (j = 0; j < 16; j++) { PACK64(&sub_block[j << 3], &w[j]); } for (j = 16; j < 80; j++) { SHA512_SCR(j); } for (j = 0; j < 8; j++) { wv[j] = ctx->h[j]; } for (j = 0; j < 80; j++) { t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha512_k[j] + w[j]; t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); wv[7] = wv[6]; wv[6] = wv[5]; wv[5] = wv[4]; wv[4] = wv[3] + t1; wv[3] = wv[2]; wv[2] = wv[1]; wv[1] = wv[0]; wv[0] = t1 + t2; } for (j = 0; j < 8; j++) { ctx->h[j] += wv[j]; } #else PACK64(&sub_block[ 0], &w[ 0]); PACK64(&sub_block[ 8], &w[ 1]); PACK64(&sub_block[ 16], &w[ 2]); PACK64(&sub_block[ 24], &w[ 3]); PACK64(&sub_block[ 32], &w[ 4]); PACK64(&sub_block[ 40], &w[ 5]); PACK64(&sub_block[ 48], &w[ 6]); PACK64(&sub_block[ 56], &w[ 7]); PACK64(&sub_block[ 64], &w[ 8]); PACK64(&sub_block[ 72], &w[ 9]); PACK64(&sub_block[ 80], &w[10]); PACK64(&sub_block[ 88], &w[11]); PACK64(&sub_block[ 96], &w[12]); PACK64(&sub_block[104], &w[13]); PACK64(&sub_block[112], &w[14]); PACK64(&sub_block[120], &w[15]); SHA512_SCR(16); SHA512_SCR(17); SHA512_SCR(18); SHA512_SCR(19); SHA512_SCR(20); SHA512_SCR(21); SHA512_SCR(22); SHA512_SCR(23); SHA512_SCR(24); SHA512_SCR(25); SHA512_SCR(26); SHA512_SCR(27); SHA512_SCR(28); SHA512_SCR(29); SHA512_SCR(30); SHA512_SCR(31); SHA512_SCR(32); SHA512_SCR(33); SHA512_SCR(34); SHA512_SCR(35); SHA512_SCR(36); SHA512_SCR(37); SHA512_SCR(38); SHA512_SCR(39); SHA512_SCR(40); SHA512_SCR(41); SHA512_SCR(42); SHA512_SCR(43); SHA512_SCR(44); SHA512_SCR(45); SHA512_SCR(46); SHA512_SCR(47); SHA512_SCR(48); SHA512_SCR(49); SHA512_SCR(50); SHA512_SCR(51); SHA512_SCR(52); SHA512_SCR(53); SHA512_SCR(54); SHA512_SCR(55); SHA512_SCR(56); SHA512_SCR(57); SHA512_SCR(58); SHA512_SCR(59); SHA512_SCR(60); SHA512_SCR(61); SHA512_SCR(62); SHA512_SCR(63); SHA512_SCR(64); SHA512_SCR(65); SHA512_SCR(66); SHA512_SCR(67); SHA512_SCR(68); SHA512_SCR(69); SHA512_SCR(70); SHA512_SCR(71); SHA512_SCR(72); SHA512_SCR(73); SHA512_SCR(74); SHA512_SCR(75); SHA512_SCR(76); SHA512_SCR(77); SHA512_SCR(78); SHA512_SCR(79); wv[0] = ctx->h[0]; wv[1] = ctx->h[1]; wv[2] = ctx->h[2]; wv[3] = ctx->h[3]; wv[4] = ctx->h[4]; wv[5] = ctx->h[5]; wv[6] = ctx->h[6]; wv[7] = ctx->h[7]; j = 0; do { SHA512_EXP(0,1,2,3,4,5,6,7,j); j++; SHA512_EXP(7,0,1,2,3,4,5,6,j); j++; SHA512_EXP(6,7,0,1,2,3,4,5,j); j++; SHA512_EXP(5,6,7,0,1,2,3,4,j); j++; SHA512_EXP(4,5,6,7,0,1,2,3,j); j++; SHA512_EXP(3,4,5,6,7,0,1,2,j); j++; SHA512_EXP(2,3,4,5,6,7,0,1,j); j++; SHA512_EXP(1,2,3,4,5,6,7,0,j); j++; } while (j < 80); ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; #endif /* !UNROLL_LOOPS */ } } void sha512(const unsigned char *message, unsigned int len, unsigned char *digest) { sha512_ctx ctx; sha512_init(&ctx); sha512_update(&ctx, message, len); sha512_final(&ctx, digest); } void sha512_init(sha512_ctx *ctx) { #ifndef UNROLL_LOOPS int i; for (i = 0; i < 8; i++) { ctx->h[i] = sha512_h0[i]; } #else ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1]; ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3]; ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5]; ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7]; #endif /* !UNROLL_LOOPS */ ctx->len = 0; ctx->tot_len = 0; } void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len) { unsigned int block_nb; unsigned int new_len, rem_len, tmp_len; const unsigned char *shifted_message; tmp_len = SHA512_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], message, rem_len); if (ctx->len + len < SHA512_BLOCK_SIZE) { ctx->len += len; return; } new_len = len - rem_len; block_nb = new_len / SHA512_BLOCK_SIZE; shifted_message = message + rem_len; sha512_transf(ctx, ctx->block, 1); sha512_transf(ctx, shifted_message, block_nb); rem_len = new_len % SHA512_BLOCK_SIZE; memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 7; } void sha512_final(sha512_ctx *ctx, unsigned char *digest) { unsigned int block_nb; unsigned int pm_len; unsigned int len_b; #ifndef UNROLL_LOOPS int i; #endif block_nb = 1 + ((SHA512_BLOCK_SIZE - 17) < (ctx->len % SHA512_BLOCK_SIZE)); len_b = (ctx->tot_len + ctx->len) << 3; pm_len = block_nb << 7; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK32(len_b, ctx->block + pm_len - 4); sha512_transf(ctx, ctx->block, block_nb); #ifndef UNROLL_LOOPS for (i = 0 ; i < 8; i++) { UNPACK64(ctx->h[i], &digest[i << 3]); } #else UNPACK64(ctx->h[0], &digest[ 0]); UNPACK64(ctx->h[1], &digest[ 8]); UNPACK64(ctx->h[2], &digest[16]); UNPACK64(ctx->h[3], &digest[24]); UNPACK64(ctx->h[4], &digest[32]); UNPACK64(ctx->h[5], &digest[40]); UNPACK64(ctx->h[6], &digest[48]); UNPACK64(ctx->h[7], &digest[56]); #endif /* !UNROLL_LOOPS */ } /* SHA-384 functions */ void sha384(const unsigned char *message, unsigned int len, unsigned char *digest) { sha384_ctx ctx; sha384_init(&ctx); sha384_update(&ctx, message, len); sha384_final(&ctx, digest); } void sha384_init(sha384_ctx *ctx) { #ifndef UNROLL_LOOPS int i; for (i = 0; i < 8; i++) { ctx->h[i] = sha384_h0[i]; } #else ctx->h[0] = sha384_h0[0]; ctx->h[1] = sha384_h0[1]; ctx->h[2] = sha384_h0[2]; ctx->h[3] = sha384_h0[3]; ctx->h[4] = sha384_h0[4]; ctx->h[5] = sha384_h0[5]; ctx->h[6] = sha384_h0[6]; ctx->h[7] = sha384_h0[7]; #endif /* !UNROLL_LOOPS */ ctx->len = 0; ctx->tot_len = 0; } void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len) { unsigned int block_nb; unsigned int new_len, rem_len, tmp_len; const unsigned char *shifted_message; tmp_len = SHA384_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], message, rem_len); if (ctx->len + len < SHA384_BLOCK_SIZE) { ctx->len += len; return; } new_len = len - rem_len; block_nb = new_len / SHA384_BLOCK_SIZE; shifted_message = message + rem_len; sha512_transf(ctx, ctx->block, 1); sha512_transf(ctx, shifted_message, block_nb); rem_len = new_len % SHA384_BLOCK_SIZE; memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 7; } void sha384_final(sha384_ctx *ctx, unsigned char *digest) { unsigned int block_nb; unsigned int pm_len; unsigned int len_b; #ifndef UNROLL_LOOPS int i; #endif block_nb = (1 + ((SHA384_BLOCK_SIZE - 17) < (ctx->len % SHA384_BLOCK_SIZE))); len_b = (ctx->tot_len + ctx->len) << 3; pm_len = block_nb << 7; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK32(len_b, ctx->block + pm_len - 4); sha512_transf(ctx, ctx->block, block_nb); #ifndef UNROLL_LOOPS for (i = 0 ; i < 6; i++) { UNPACK64(ctx->h[i], &digest[i << 3]); } #else UNPACK64(ctx->h[0], &digest[ 0]); UNPACK64(ctx->h[1], &digest[ 8]); UNPACK64(ctx->h[2], &digest[16]); UNPACK64(ctx->h[3], &digest[24]); UNPACK64(ctx->h[4], &digest[32]); UNPACK64(ctx->h[5], &digest[40]); #endif /* !UNROLL_LOOPS */ } /* SHA-224 functions */ void sha224(const unsigned char *message, unsigned int len, unsigned char *digest) { sha224_ctx ctx; sha224_init(&ctx); sha224_update(&ctx, message, len); sha224_final(&ctx, digest); } void sha224_init(sha224_ctx *ctx) { #ifndef UNROLL_LOOPS int i; for (i = 0; i < 8; i++) { ctx->h[i] = sha224_h0[i]; } #else ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1]; ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3]; ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5]; ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7]; #endif /* !UNROLL_LOOPS */ ctx->len = 0; ctx->tot_len = 0; } void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len) { unsigned int block_nb; unsigned int new_len, rem_len, tmp_len; const unsigned char *shifted_message; tmp_len = SHA224_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; memcpy(&ctx->block[ctx->len], message, rem_len); if (ctx->len + len < SHA224_BLOCK_SIZE) { ctx->len += len; return; } new_len = len - rem_len; block_nb = new_len / SHA224_BLOCK_SIZE; shifted_message = message + rem_len; sha256_transf(ctx, ctx->block, 1); sha256_transf(ctx, shifted_message, block_nb); rem_len = new_len % SHA224_BLOCK_SIZE; memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len); ctx->len = rem_len; ctx->tot_len += (block_nb + 1) << 6; } void sha224_final(sha224_ctx *ctx, unsigned char *digest) { unsigned int block_nb; unsigned int pm_len; unsigned int len_b; #ifndef UNROLL_LOOPS int i; #endif block_nb = (1 + ((SHA224_BLOCK_SIZE - 9) < (ctx->len % SHA224_BLOCK_SIZE))); len_b = (ctx->tot_len + ctx->len) << 3; pm_len = block_nb << 6; memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; UNPACK32(len_b, ctx->block + pm_len - 4); sha256_transf(ctx, ctx->block, block_nb); #ifndef UNROLL_LOOPS for (i = 0 ; i < 7; i++) { UNPACK32(ctx->h[i], &digest[i << 2]); } #else UNPACK32(ctx->h[0], &digest[ 0]); UNPACK32(ctx->h[1], &digest[ 4]); UNPACK32(ctx->h[2], &digest[ 8]); UNPACK32(ctx->h[3], &digest[12]); UNPACK32(ctx->h[4], &digest[16]); UNPACK32(ctx->h[5], &digest[20]); UNPACK32(ctx->h[6], &digest[24]); #endif /* !UNROLL_LOOPS */ } #ifdef TEST_VECTORS /* FIPS 180-2 Validation tests */ #include #include void test(const char *vector, unsigned char *digest, unsigned int digest_size) { char output[2 * SHA512_DIGEST_SIZE + 1]; int i; output[2 * digest_size] = '\0'; for (i = 0; i < (int) digest_size ; i++) { snprintf(output+2*i, (sizeof(output) - strlen(output)), "%02x", digest[i]); } printf("H: %s\n", output); if (strcmp(vector, output)) { fprintf(stderr, "Test failed.\n"); exit(EXIT_FAILURE); } } int main(void) { static const char *vectors[4][3] = { /* SHA-224 */ { "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", }, /* SHA-256 */ { "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", }, /* SHA-384 */ { "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed" "8086072ba1e7cc2358baeca134c825a7", "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712" "fcc7c71a557e2db966c3e9fa91746039", "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b" "07b8b3dc38ecc4ebae97ddd87f3d8985", }, /* SHA-512 */ { "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909", "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb" "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" } }; static const char message1[] = "abc"; static const char message2a[] = "abcdbcdecdefdefgefghfghighijhi" "jkijkljklmklmnlmnomnopnopq"; static const char message2b[] = "abcdefghbcdefghicdefghijdefghijkefghij" "klfghijklmghijklmnhijklmnoijklmnopjklm" "nopqklmnopqrlmnopqrsmnopqrstnopqrstu"; unsigned char *message3; unsigned int message3_len = 1000000; unsigned char digest[SHA512_DIGEST_SIZE]; message3 = malloc(message3_len); if (message3 == NULL) { fprintf(stderr, "Can't allocate memory\n"); return -1; } memset(message3, 'a', message3_len); printf("SHA-2 FIPS 180-2 Validation tests\n\n"); printf("SHA-224 Test vectors\n"); sha224((const unsigned char *) message1, strlen(message1), digest); test(vectors[0][0], digest, SHA224_DIGEST_SIZE); sha224((const unsigned char *) message2a, strlen(message2a), digest); test(vectors[0][1], digest, SHA224_DIGEST_SIZE); sha224(message3, message3_len, digest); test(vectors[0][2], digest, SHA224_DIGEST_SIZE); printf("\n"); printf("SHA-256 Test vectors\n"); sha256((const unsigned char *) message1, strlen(message1), digest); test(vectors[1][0], digest, SHA256_DIGEST_SIZE); sha256((const unsigned char *) message2a, strlen(message2a), digest); test(vectors[1][1], digest, SHA256_DIGEST_SIZE); sha256(message3, message3_len, digest); test(vectors[1][2], digest, SHA256_DIGEST_SIZE); printf("\n"); printf("SHA-384 Test vectors\n"); sha384((const unsigned char *) message1, strlen(message1), digest); test(vectors[2][0], digest, SHA384_DIGEST_SIZE); sha384((const unsigned char *)message2b, strlen(message2b), digest); test(vectors[2][1], digest, SHA384_DIGEST_SIZE); sha384(message3, message3_len, digest); test(vectors[2][2], digest, SHA384_DIGEST_SIZE); printf("\n"); printf("SHA-512 Test vectors\n"); sha512((const unsigned char *) message1, strlen(message1), digest); test(vectors[3][0], digest, SHA512_DIGEST_SIZE); sha512((const unsigned char *) message2b, strlen(message2b), digest); test(vectors[3][1], digest, SHA512_DIGEST_SIZE); sha512(message3, message3_len, digest); test(vectors[3][2], digest, SHA512_DIGEST_SIZE); printf("\n"); printf("All tests passed.\n"); return 0; } #endif /* TEST_VECTORS */ /* Added for Xymon - not part of the original file */ int mySHA224_Size(void) { return sizeof(sha224_ctx); } void mySHA224_Init(void *c) { sha224_init((sha224_ctx *)c); } void mySHA224_Update(void *c, unsigned char *in, int len) {sha224_update((sha224_ctx *)c, in, len); } void mySHA224_Final(char md[20], void *c) { sha224_final((sha224_ctx *)c, md); } int mySHA256_Size(void) { return sizeof(sha256_ctx); } void mySHA256_Init(void *c) { sha256_init((sha256_ctx *)c); } void mySHA256_Update(void *c, unsigned char *in, int len) {sha256_update((sha256_ctx *)c, in, len); } void mySHA256_Final(char md[20], void *c) { sha256_final((sha256_ctx *)c, md); } int mySHA384_Size(void) { return sizeof(sha384_ctx); } void mySHA384_Init(void *c) { sha384_init((sha384_ctx *)c); } void mySHA384_Update(void *c, unsigned char *in, int len) {sha384_update((sha384_ctx *)c, in, len); } void mySHA384_Final(char md[20], void *c) { sha384_final((sha384_ctx *)c, md); } int mySHA512_Size(void) { return sizeof(sha512_ctx); } void mySHA512_Init(void *c) { sha512_init((sha512_ctx *)c); } void mySHA512_Update(void *c, unsigned char *in, int len) {sha512_update((sha512_ctx *)c, in, len); } void mySHA512_Final(char md[20], void *c) { sha512_final((sha512_ctx *)c, md); } /* end of xymon adds */ xymon-4.3.30/lib/files.c0000664000076400007640000000446213515623702015231 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* This is a library module, part of libxymon. */ /* It contains routines for file- and directory manipulation. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: files.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include "libxymon.h" void dropdirectory(char *dirfn, int background) { DIR *dirfd; struct dirent *de; char fn[PATH_MAX]; struct stat st; pid_t childpid = 0; if (background) { /* Caller wants us to run as a background task. */ childpid = fork(); } MEMDEFINE(fn); if (childpid == 0) { dbgprintf("Starting to remove directory %s\n", dirfn); dirfd = opendir(dirfn); if (dirfd) { while ( (de = readdir(dirfd)) != NULL ) { snprintf(fn, sizeof(fn), "%s/%s", dirfn, de->d_name); if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..") && (stat(fn, &st) == 0)) { if (S_ISREG(st.st_mode)) { dbgprintf("Removing file %s\n", fn); unlink(fn); } else if (S_ISDIR(st.st_mode)) { dbgprintf("Recurse into %s\n", fn); dropdirectory(fn, 0); /* Don't background the recursive calls! */ } } } closedir(dirfd); } dbgprintf("Removing directory %s\n", dirfn); rmdir(dirfn); if (background) { /* Background task just exits */ exit(0); } } else if (childpid < 0) { errprintf("Could not fork child to remove directory %s\n", dirfn); } MEMUNDEFINE(fn); } xymon-4.3.30/lib/acknowledgementslog.h0000664000076400007640000000206612503132277020164 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __ACKNOWLEDGEMENTSLOG_H_ #define __ACKNOWLEDGEMENTSLOG_H_ extern void do_acknowledgementslog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, char *pagematch, char *expagematch, char *hostmatch, char *exhostmatch, char *testmatch, char *extestmatch, char *rcptmatch, char *exrcptmatch); #endif xymon-4.3.30/web/0000775000076400007640000000000013534041775013771 5ustar rpmbuildrpmbuildxymon-4.3.30/web/eventlog.cgi.10000664000076400007640000000137713534041733016441 0ustar rpmbuildrpmbuild.TH EVENTLOG.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME eventlog.cgi \- CGI program to report the Xymon eventlog .SH SYNOPSIS .B "eventlog.cgi" .SH DESCRIPTION \fBeventlog.cgi\fR is invoked as a CGI script via the eventlog.sh CGI wrapper. Based on the parameters it receives, it generates the Xymon event log for a period. This log shows all status changes that have occurred for all hosts and services. eventlog.cgi is passed a QUERY_STRING environment variable with the following parameters: MAXTIME (maximum minutes to go back in the log) MAXCOUNT (maximum number of events to report) .SH OPTIONS .IP "--env=FILENAME" Loads the environment defined in FILENAME before executing the CGI script. .SH "SEE ALSO" hosts.cfg(5), xymonserver.cfg(5) xymon-4.3.30/web/svcstatus.cgi.10000664000076400007640000000751213534041733016652 0ustar rpmbuildrpmbuild.TH SVCSTATUS.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME svcstatus.cgi \- CGI program to view Xymon status logs .SH SYNOPSIS .B "svcstatus.cgi [\-\-historical] [\-\-history={top|bottom}]" .SH DESCRIPTION \fBsvcstatus.cgi\fR is a CGI program to present a Xymon status log in HTML form (ie, as a web page). It can be used both for the logs showing the current status, and for historical logs from the "histlogs" directory. It is normally invoked as a CGI program, and therefore receives most of the input parameters via the CGI QUERY_STRING environment variable. Unless the "\-\-historical" option is present, the current status log is used. This assumes a QUERY_STRING environment variable of the form .br HOSTSVC=hostname.servicename .br where "hostname" is the name of the host with commas instead of dots, and "servicename" is the name of the service (the column name in Xymon). Such links are automatically generated by the .I xymongen(1) tool when the environment contains "XYMONLOGSTATUS=dynamic". With the "\-\-historical" option present, a historical logfile is used. This assumes a QUERY_STRING environment variable of the form .br HOST=hostname&SERVICE=servicename&TIMEBUF=timestamp .br where "hostname" is the name of the host with commas instead of dots, "servicename" is the name of the service, and "timestamp" is the time of the log. This is automatically generated by the .I history.cgi(1) tool. .SH OPTIONS .IP "\-\-historical" Use a historical logfile instead of the current logfile. .IP "\-\-history={top|bottom|none}" When showing the current logfile, provide a "HISTORY" button at the top or the bottom of the webpage, or not at all. The default is to put the HISTORY button at the bottom of the page. .IP "\-\-env=FILENAME" Load the environment from FILENAME before executing the CGI. .IP "\-\-templates=DIRECTORY" Where to look for the HTML header- and footer-templates used when generating the webpages. Default: $XYMONHOME/web/ .IP "\-\-no\-svcid" Do not include the HTML tags to identify the hostname/service on the generated web page. Useful is this already happens in the hostsvc_header template file, for instance. .IP "\-\-multigraphs=TEST1[,TEST2]" This causes svcstatus.cgi to generate links to service graphs that are split up into multiple images, with at most 5 graphs per image. This option only works in Xymon mode. If not specified, only the "disk" status is split up this way. .IP "\-\-no\-disable" By default, the info-column page includes a form allowing users to disable and re-enable tests. If your setup uses the default separation of administration tools into a separate, password- protected area, then use of the disable- and enable-functions requires access to the administration tools. If you prefer to do this only via the dedicated administration page, this option will remove the disable-function from the info page. .IP "\-\-no\-jsvalidation" The disable-function on the info-column page by default uses JavaScript to validate the form before submitting the input to the Xymon server. However, some browsers cannot handle the Javascript code correctly so the form does not work. This option disables the use of Javascript for form-validation, allowing these browsers to use the disable-function. .IP "\-\-nkconfig=FILENAME" Use FILENAME as the configuration file for the Critical Systems information. The default is to load this from $XYMONHOME/etc/critical.cfg .SH FILES .IP "$XYMONHOME/web/hostsvc_header" HTML template header .IP "$XYMONHOME/web/hostsvc_footer" HTML template footer .SH ENVIRONMENT .IP "NONHISTS=info,trends,graphs" A comma-separated list of services that does not have meaningful history, e.g. the "info" and "trends" columns. Services listed here do not get a "History" button. .IP "TEST2RRD=test,test" A comma-separated list of the tests that have an RRD graph. .SH "SEE ALSO" xymon(7), xymond(1) xymon-4.3.30/web/datepage.cgi.10000664000076400007640000000532413534041733016364 0ustar rpmbuildrpmbuild.TH DATEPAGE.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME datepage.cgi \- Xymon CGI script to view pre-built reports by date .SH SYNOPSIS .B "datepage.cgi?type={day,week,month} \-\-url=URLPREFIX [options] .SH DESCRIPTION \fBdatepage.cgi\fR is invoked as a CGI script via the datepage.sh CGI wrapper. datepage.cgi is passed a QUERY_STRING environment variable with the type of time-selection that is desired: Either "day", "week" or "month" can be requested. It will then generate a web form with appropriate day/week/month selection boxes, and based on the users' selection a resulting url is built from the URLPREFIX and the time selection. The browser is then redirected to this URL. The URL is constructed from the URLPREFIX, the type-parameter, the value of the "pagepath" or "host" cookie, and the users' selection as follows: .IP type=day The final URL is \fBURLPREFIX/daily/YEAR/MONTH/DAY/PAGEPATH\fR. .IP type=week The final URL is \fBURLPREFIX/weekly/YEAR/WEEK/PAGEPATH\fR. .IP type=month The final URL is \fBURLPREFIX/monthly/YEAR/MONTH/PAGEPATH\fR. YEAR is the full year (4 digits, including century). MONTH is the two-digit number of the month (01..12). DAY is the number of the day in the month (01..31). WEEK is the ISO 8601:1988 week-number (01..53). PAGEPATH is the current value of the "pagepath" cookie if set; if it is not set but the "host" cookie is set, then this host is looked up in the hosts.cfg file and the page where this host is found is used for PAGEPATH. These two cookies are set by the default web-header templates supplied with Xymon. .SH OPTIONS .IP "\-\-url=URLPREFIX" This specifies the initial part of the final URL. This option is required. .IP "\-\-hffile=FILENAME" Specifies the template files (from $XYMONHOME/web/) to use. The default is "\-\-hffile=report". .IP "\-\-color=COLOR" Sets the background color of the generated webpage. The default is blue. .IP "\-\-env=FILENAME" Loads the environment defined in FILENAME before executing the CGI script. .IP "\-\-debug" Enables debugging output. .IP "$XYMONHOME/web/report_form_daily" HTML form template for the date selection form when type=daily. .IP "$XYMONHOME/web/report_form_weekly" HTML form template for the date selection form when type=weekly. .IP "$XYMONHOME/web/report_form_monthly" HTML form template for the date selection form when type=monthly. .IP "$XYMONHOME/web/report_header" HTML header file for the generated web page .IP "$XYMONHOME/web/report_footer" HTML footer file for the generated web page .SH "ENVIRONMENT VARIABLES" .IP XYMONHOME Used to locate the template files for the generated web pages. .IP QUERY_STRING Contains the parameters for the CGI script. .SH "SEE ALSO" xymongen(1), hosts.cfg(5), xymonserver.cfg(5) xymon-4.3.30/web/csvinfo.c0000664000076400007640000001250013515623702015575 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon general CSV info viewer. */ /* */ /* This is a CGI script for a generic presentation of information stored in */ /* a comma-separated file (CSV), e.g. via an export from a spreadsheet or DB. */ /* It is also used for the Xymon column-name links, to provide information */ /* about what each column header means and what kind of test is run. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: csvinfo.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" #define MAXCOLUMNS 80 char *srcdb = "hostinfo.csv"; char *wantedname = ""; int keycolumn = 0; char delimiter = ';'; cgidata_t *cgidata = NULL; void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } void parse_query(void) { cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "key") == 0) { wantedname = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "db") == 0) { char *val, *p; /* Don't allow any slashes in the db-name */ val = cwalk->value; p = strrchr(val, '/'); if (p) val = (p+1); srcdb = strdup(val); } else if (strcasecmp(cwalk->name, "column") == 0) { keycolumn = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "delimiter") == 0) { delimiter = *(cwalk->value); } cwalk = cwalk->next; } } int main(int argc, char *argv[]) { FILE *db; char dbfn[PATH_MAX]; strbuffer_t *inbuf; char *hffile = "info"; int bgcolor = COL_BLUE; char *envarea = NULL; char *headers[MAXCOLUMNS]; char *items[MAXCOLUMNS]; int i, found; int argi; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--hffile=")) { char *p = strchr(argv[argi], '='); hffile = strdup(p+1); } else if (argnmatch(argv[argi], "--color=")) { char *p = strchr(argv[argi], '='); bgcolor = parse_color(p+1); } } redirect_cgilog("csvinfo"); cgidata = cgi_request(); parse_query(); if (strlen(wantedname) == 0) { errormsg("Invalid request"); return 1; } snprintf(dbfn, sizeof(dbfn), "%s/etc/%s", xgetenv("XYMONHOME"), srcdb); db = fopen(dbfn, "r"); if (db == NULL) { SBUF_DEFINE(msg); SBUF_MALLOC(msg, 30+strlen(htmlquoted(dbfn))); snprintf(msg, msg_buflen, "Cannot open sourcedb %s\n", htmlquoted(dbfn)); errormsg(msg); return 1; } /* First, load the headers from line 1 of the sourcedb */ memset(headers, 0, sizeof(headers)); initfgets(db); inbuf = newstrbuffer(0); if (unlimfgets(inbuf, db)) { char *p1, *p2; for (i=0, p1=STRBUF(inbuf), p2=strchr(STRBUF(inbuf), delimiter); (p1 && p2 && strlen(p1)); i++,p1=p2+1,p2=strchr(p1, delimiter)) { *p2 = '\0'; headers[i] = strdup(p1); } } /* * Pre-allocate the buffer space for the items - we weill be stuffing data * into these while scanning for the right item. */ for (i=0; i\n"); for (i=0; (headers[i]); i++) { printf("\n"); printf(" %s%s\n", headers[i], items[i]); printf("\n"); } printf("\n"); headfoot(stdout, hffile, "", "footer", bgcolor); return 0; } xymon-4.3.30/web/showgraph.cgi.10000664000076400007640000000556513534041733016623 0ustar rpmbuildrpmbuild.TH SHOWGRAPH.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME showgraph.cgi \- CGI to generate Xymon trend graphs .SH SYNOPSIS .B "showgraph [options]" .SH DESCRIPTION \fBshowgraph.cgi\fR is invoked as a CGI script via the showgraph.sh CGI wrapper. showgraph.cgi is passed a QUERY_STRING environment variable with the following parameters: .sp .BR host Name of the host to generate a graph for .sp .BR service Name of the service to generate a graph for .sp .BR disp Display-name of the host, used on the generated graphs instead of hostname. .sp .BR graph Can be "hourly", "daily", "weekly" or "monthly" to select the time period that the graph covers. .sp .BR first Used to split multi-graphs into multiple graphs. This causes showgraph.cgi to generate only the graphs starting with the "first'th" graph and continuing for "count". .sp .BR count Number of graphs in a multi-graph. .sp .BR upper Set the upper limit of the graph. See .I rrdgraph(1) for a description of the "\-u" option. .sp .BR lower Set the lower limit of the graph. See .I rrdgraph(1) for a description of the "\-l" option. .sp .BR graph_start Set the starttime of the graph. This is used in zoom-mode. .sp .BR graph_end Set the end-time of the graph. This is used in zoom-mode. .sp .BR action=menu Generate an HTML page with links to 4 graphs, representing the hourly, weekly, monthly and yearly graphs. Doesn't actually generate any graphs, only the HTML that links to the graphs. .sp .BR action=selzoom Generate an HTML page with link to single graph, and with JavaScript code that lets the user select part of the graph for a zoom-operation. The JavaScript invokes showgraph.cgi with "action=showzoom" to generate the zoomed graph webpage. .sp .BR action=showzoom Generate HTML with a link to the zoomed graph image. This link goes to an "action=view" invocation of showgraph.cgi. .sp .BR action=view Generate a single graph image. .SH OPTIONS .IP "\-\-config=FILENAME" Loads the graph configuration file from FILENAME. If not specified, the file $XYMONHOME/etc/graphs.cfg is used. See the .I graphs.cfg(5) for details about this file. .IP "\-\-env=FILENAME" Loads the environment settings defined in FILENAME before executing the CGI. .IP "\-\-rrddir=DIRECTORY" The top-level directory for the RRD files. If not specified, the directory given by the XYMONRRDS environment is used. .IP "\-\-save=FILENAME" Instead of returning the image via the CGI interface (i.e. on stdout), save the generated image to FILENAME. .IP "\-\-debug" Enable debugging output. .SH ENVIRONMENT .sp .BR QUERY_STRING Provided by the webserver CGI interface, this decides what graph to generate. .sp .BR RRDGRAPHOPTS RRD-specific options for the graph. This is usually set in the .I xymonserver.cfg(5) file. .SH FILES .sp .BR graphs.cfg: The configuration file determining how graphs are generated from RRD files. .SH "SEE ALSO" graphs.cfg(5), xymon(7), rrdtool(1) xymon-4.3.30/web/statusreport.cgi.10000664000076400007640000000572613534041733017377 0ustar rpmbuildrpmbuild.TH STATUSREPORT.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME statusreport.cgi \- CGI program to report a status for a group of servers .SH SYNOPSIS .B "statusreport.cgi \-\-column=COLUMNNAME [options]" .SH DESCRIPTION \fBstatusreport.cgi\fR is a CGI tool to generate a simple HTML report showing the current status of a single column for a group of Xymon hosts. E.g. You can use this report to get an overview of all of the SSL certificates that are about to expire. The generated webpage is a simple HTML table, suitable for copying into other documents or e-mail. statusreport.cgi runs as a CGI program, invoked by your webserver. It is normally run via a wrapper shell-script in the CGI directory for Xymon. .SH EXAMPLES The Xymon installation includes two web report scripts using this CGI tool: The \fBcertreport.sh\fR script generates a list of SSL server certificates that are yellow or red (i.e. they will expire soon); and the \fBnongreen.sh\fR script generates a report of all statuses that are currently non-green. These can be accessed from a web browser through a URL referencing the script in the Xymon CGI directory (e.g. "/xymon\-cgi/xymon\-nongreen.sh"). .SH OPTIONS .IP "\-\-column=COLUMNNAME" Report the status of the COLUMNNAME column. .IP "\-\-all" Report the status for all hosts known to Xymon. By default, this tool reports only on the hosts found on the current page from where the CGI was invoked (by looking at the "pagepath" cookie). .IP "\-\-filter=CRITERIA" Only report on statuses that match the CRITERIA setting. See the .I xymon(1) man-page - in the "xymondboard" command description - for details about specifying filters. .IP "\-\-heading=HTML" Defines the webpage heading - i.e. the "title" tag in the generated HTML code. .IP "\-\-show\-column" Include the column name in the display. .IP "\-\-show\-colors" Show the status color on the generated webpage. The default is to not show the status color. .IP "\-\-no\-colors" Do not include text showing the current color of each status in the report. This is the default. .IP "\-\-show\-summary" Show only a summary of the important lines in the status message. By default, the entire status message appears in the generated HTML code. This option causes the first non-blank line of the status message to be shown, and also any lines beginning with "&COLOR" which is used by many status messages to point out lines of interest (non-green lines only, though). .IP "\-\-show\-message" Show the entire message on the webpage. This is the default. .IP "\-\-link" Include HTML links to the host "info" page, and the status page. .IP "\-\-embedded" Only generate the HTML table, not a full webpage. This can be used to embed the status report into an external webpage. .IP "\-\-env=FILENAME" Load the environment from FILENAME before executing the CGI. .IP "\-\-area=NAME" Load environment variables for a specific area. NB: if used, this option must appear before any \-\-env=FILENAME option. .SH "SEE ALSO" xymon(7) xymon-4.3.30/web/appfeed.cgi.10000664000076400007640000000403613534041733016215 0ustar rpmbuildrpmbuild.TH APPFEED.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME appfeed.cgi \- Xymon CGI feeder for Smartphone apps .SH SYNOPSIS .B "appfeed.cgi [options]" .SH DESCRIPTION \fBappfeed.cgi\fR is invoked as a CGI script via the appfeed.sh CGI wrapper. appfeed.cgi is optionally passed a QUERY_STRING environment variable with the "filter=FILTER" parameter. FILTER is a filter for the "xymondboard" command sent to .I xymond(8) daemon. These filters are described in detail in the .I xymon(1) manual. Typically, the filter will specify hosts found on a specific (sub)page to be returned, e.g. "filter=page=webservers" will cause appfeed.cgi to only return hosts that are present on the "webservers" page in Xymon. If no filter is specified, appfeed.cgi returns data for all red, yellow or purple statuses (equivalent to the data present on the "All non-green" page), or if invoked with the "\-\-critical" option it returns data from the "Critical systems" page. The output is an XML document with the current status of the selected hosts/services. .SH OPTIONS .IP "\-\-env=FILENAME Loads the environment from FILENAME before executing the CGI. .IP "\-\-critical[=FILENAME]" FILENAME specifies the "Critical Systems" configuration file (default: critical.cfg). appfeed.cgi will only return the statuses currently on the "Critical Systems" view. .IP "\-\-access=FILENAME" In addition to the filtering done by the "filter" parameter or the "\-\-critical" option, this option limits the output to hosts that the user has access to as defined in the Apache-compatible group-definitions in FILENAME. See .I xymon\-webaccess(5) for more details of this. .BR Note: Use of this option requires that access to the appfeed.cgi tool is password-protected by whatever means your webserver software provides, and that the login userid is available via the REMOTE_USER environment variable (this is standard CGI behaviour, so all webservers should provide it if you use the webserver's built-in authentication mechanisms). .SH "SEE ALSO" xymon(1), critical.cfg(5), xymon\-webaccess(5) xymon-4.3.30/web/chpasswd.c0000664000076400007640000001616713515623702015757 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: chpasswd.c 6588 2010-11-14 17:21:19Z storner $"; #include #include #include #include #include #include "libxymon.h" static void errormsg(int status, char *msg) { printf("Status: %d\n", status); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } static int idcompare(const void *p1, const void *p2) { return strcmp(* (char * const *) p1, * (char * const *) p2); } #define ACT_NONE 0 #define ACT_DELETE 2 #define ACT_UPDATE 3 char *adduser_name = NULL; char *adduser_password = NULL; char *adduser_password1 = NULL; char *adduser_password2 = NULL; char *deluser_name = NULL; int parse_query(void) { cgidata_t *cgidata, *cwalk; int returnval = ACT_NONE; cgidata = cgi_request(); if (cgi_method != CGI_POST) return ACT_NONE; if (cgidata == NULL) errormsg(400, cgi_error()); cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcmp(cwalk->name, "USERNAME") == 0) { adduser_name = cwalk->value; } else if (strcmp(cwalk->name, "PASSWORD") == 0) { adduser_password = cwalk->value; } else if (strcmp(cwalk->name, "PASSWORD1") == 0) { adduser_password1 = cwalk->value; } else if (strcmp(cwalk->name, "PASSWORD2") == 0) { adduser_password2 = cwalk->value; } else if (strcmp(cwalk->name, "USERLIST") == 0) { deluser_name = cwalk->value; } else if (strcmp(cwalk->name, "SendDelete") == 0) { returnval = ACT_DELETE; } else if (strcmp(cwalk->name, "SendUpdate") == 0) { returnval = ACT_UPDATE; } cwalk = cwalk->next; } /* We only want to accept posts from certain pages */ if (returnval != ACT_NONE) { char cgisource[1024]; char *p; p = csp_header("chpasswd"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "chpasswd"); if (!cgi_refererok(cgisource)) { fprintf(stdout, "Location: %s.sh?\n\n", cgisource); return 0; } } return returnval; } int main(int argc, char *argv[]) { int argi, event; char *envarea = NULL; char *hffile = "chpasswd"; SBUF_DEFINE(passfile); FILE *fd; char *infomsg = NULL; char *loggedinuser = NULL; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--passwdfile=")) { char *p = strchr(argv[argi], '='); passfile = strdup(p+1); } } if (passfile == NULL) { SBUF_MALLOC(passfile, strlen(xgetenv("XYMONHOME")) + 20); snprintf(passfile, passfile_buflen, "%s/etc/xymonpasswd", xgetenv("XYMONHOME")); } loggedinuser = getenv("REMOTE_USER"); if (!loggedinuser) errormsg(401, "User authentication must be enabled and you must be logged in to use this CGI"); event = parse_query(); if (adduser_name && !issimpleword(adduser_name)) { event = ACT_NONE; adduser_name = strdup(""); infomsg = "Invalid USERNAME. Letters, numbers, dashes, and periods only.\n"; } switch (event) { case ACT_NONE: /* Show the form */ break; case ACT_UPDATE: /* Change a user password*/ { char *cmd; int n, ret; if ( (strlen(loggedinuser) == 0) || (strlen(loggedinuser) != strlen(adduser_name)) || (strcmp(loggedinuser, adduser_name) != 0) ) { infomsg = "Username mismatch! You may only change your own password."; break; } if ( (strlen(adduser_name) == 0)) { infomsg = "User not logged in"; } else if ( (strlen(adduser_password1) == 0) || (strlen(adduser_password2) == 0)) { infomsg = "New password cannot be blank"; } else if (strcmp(adduser_password1, adduser_password2) != 0) { infomsg = "New passwords don't match"; } else if (strlen(adduser_name) != strspn(adduser_name,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.,@/=^") ) { infomsg = "Username has invalid characters!"; } else if (strlen(adduser_password1) != strspn(adduser_password1,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.,@/=^") ) { infomsg = "Password has invalid characters! Use alphanumerics and/or _ - . , @ / = ^"; } else { pid_t childpid; int n, ret; childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (childpid == 0) { /* child */ char *cmd; char **cmdargs; cmdargs = (char **) calloc(4 + 2, sizeof(char *)); cmdargs[0] = cmd = strdup("htpasswd"); cmdargs[1] = "-bv"; cmdargs[2] = strdup(passfile); cmdargs[3] = strdup(adduser_name); cmdargs[4] = strdup(adduser_password); cmdargs[5] = '\0'; execvp(cmd, cmdargs); exit(127); } /* parent waits for htpasswd to finish */ if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { infomsg = "Existing Password incorrect"; break; } childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (childpid == 0) { /* child */ char *cmd; char **cmdargs; cmdargs = (char **) calloc(4 + 2, sizeof(char *)); cmdargs[0] = cmd = strdup("htpasswd"); cmdargs[1] = "-b"; cmdargs[2] = strdup(passfile); cmdargs[3] = strdup(adduser_name); cmdargs[4] = strdup(adduser_password1); cmdargs[5] = '\0'; execvp(cmd, cmdargs); exit(127); } /* parent waits for htpasswd to finish */ if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { infomsg = "Update FAILED"; } else { infomsg = "Password changed\n"; } } } break; } fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, hffile, "chpasswd_form", COL_BLUE, getcurrenttime(NULL), infomsg, NULL); return 0; } xymon-4.3.30/web/showgraph.c0000664000076400007640000011422513524336224016137 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD graph generator. */ /* */ /* This is a CGI script for generating graphs from the data stored in the */ /* RRD databases. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: showgraph.c 8076 2019-08-12 19:23:00Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #define HOUR_GRAPH "e-48h" #define DAY_GRAPH "e-12d" #define WEEK_GRAPH "e-48d" #define MONTH_GRAPH "e-576d" /* RRDtool 1.0.x handles graphs with no DS definitions just fine. 1.2.x does not. */ #ifdef RRDTOOL12 #ifndef HIDE_EMPTYGRAPH #define HIDE_EMPTYGRAPH 1 #endif #endif #ifdef HIDE_EMPTYGRAPH unsigned char blankimg[] = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x12\x00\x00\x0b\x12\x01\xd2\xdd\x7e\xfc\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd1\x01\x14\x12\x21\x14\x7e\x4a\x3a\xd2\x00\x00\x00\x0d\x49\x44\x41\x54\x78\xda\x63\x60\x60\x60\x60\x00\x00\x00\x05\x00\x01\x7a\xa8\x57\x50\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; #endif char *hostname = NULL; char **hostlist = NULL; int hostlistsize = 0; char *displayname = NULL; char *service = NULL; char *period = NULL; time_t persecs = 0; char *gtype = NULL; char *glegend = NULL; enum {ACT_MENU, ACT_SELZOOM, ACT_VIEW} action = ACT_VIEW; time_t graphstart = 0; time_t graphend = 0; double upperlimit = 0.0; int haveupperlimit = 0; double lowerlimit = 0.0; int havelowerlimit = 0; int graphwidth = 0; int graphheight = 0; int ignorestalerrds = 0; int bgcolor = COL_GREEN; int coloridx = 0; char *colorlist[] = { "0000FF", "FF0000", "00CC00", "FF00FF", "555555", "880000", "000088", "008800", "008888", "888888", "880088", "FFFF00", "888800", "00FFFF", "00FF00", "AA8800", "AAAAAA", "DD8833", "DDCC33", "8888FF", "5555AA", "B428D3", "FF5555", "DDDDDD", "AAFFAA", "AAFFFF", "FFAAFF", "FFAA55", "55AAFF", "AA55FF", NULL }; typedef struct gdef_t { char *name; char *fnpat; char *exfnpat; char *title; char *yaxis; char *graphopts; int novzoom; char **defs; struct gdef_t *next; } gdef_t; gdef_t *gdefs = NULL; typedef struct rrddb_t { char *key; char *rrdfn; char *rrdparam; } rrddb_t; rrddb_t *rrddbs = NULL; int rrddbcount = 0; int rrddbsize = 0; int rrdidx = 0; int paramlen = 0; int firstidx = -1; int idxcount = -1; int lastidx = 0; void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } void request_cacheflush(char *hostname) { /* Build a cache-flush request, and send it to all of the $XYMONTMP/rrdctl.* sockets */ SBUF_DEFINE(req); char *bufp; int bytesleft; DIR *dir; struct dirent *d; int ctlsocket = -1; ctlsocket = socket(AF_UNIX, SOCK_DGRAM, 0); if (ctlsocket == -1) { errprintf("Cannot get socket: %s\n", strerror(errno)); return; } fcntl(ctlsocket, F_SETFL, O_NONBLOCK); dir = opendir(xgetenv("XYMONTMP")); if (!dir) { errprintf("Cannot access $XYMONTMP directory: %s\n", strerror(errno)); return; } SBUF_MALLOC(req, strlen(hostname)+3); snprintf(req, req_buflen, "/%s/", hostname); while ((d = readdir(dir)) != NULL) { if (strncmp(d->d_name, "rrdctl.", 7) == 0) { struct sockaddr_un myaddr; socklen_t myaddrsz = 0; int n, sendfailed = 0; SBUF_DEFINE(fnam); memset(&myaddr, 0, sizeof(myaddr)); myaddr.sun_family = AF_UNIX; SBUF_MALLOC(fnam, strlen(xgetenv("XYMONTMP"))+ strlen(d->d_name) + 2); snprintf(fnam, fnam_buflen, "%s/%s", xgetenv("XYMONTMP"), d->d_name); if (strlen(fnam) > sizeof(myaddr.sun_path)) { errprintf("rrdctl files located in XYMONTMP with too long pathname - max %d characters\n", sizeof(myaddr.sun_path)); return; } strncpy(myaddr.sun_path, fnam, sizeof(myaddr.sun_path)); xfree(fnam); myaddrsz = sizeof(myaddr); bufp = req; bytesleft = strlen(req); do { n = sendto(ctlsocket, bufp, bytesleft, 0, (struct sockaddr *)&myaddr, myaddrsz); if (n == -1) { if (errno == EDESTADDRREQ) { /* Probably a left-over rrdctl file, ignore it */ } else if (errno == EAGAIN) { /* Harmless */ } else { errprintf("Sendto failed: %s\n", strerror(errno)); } sendfailed = 1; } else { bytesleft -= n; bufp += n; } } while ((!sendfailed) && (bytesleft > 0)); } } closedir(dir); xfree(req); /* * Sleep 0.3 secs to allow the cache flush to happen. * Note: It isn't guaranteed to happen in this time, but * there's a good chance that it will. */ usleep(300000); } void parse_query(void) { cgidata_t *cgidata = NULL, *cwalk; char *stp = NULL; cgidata = cgi_request(); cwalk = cgidata; while (cwalk) { if (strcmp(cwalk->name, "host") == 0) { char *hnames = strdup(cwalk->value); hostname = strtok_r(cwalk->value, ",", &stp); while (hostname) { if (hostlist == NULL) { hostlistsize = 1; hostlist = (char **)malloc(sizeof(char *)); hostlist[0] = strdup(hostname); } else { hostlistsize++; hostlist = (char **)realloc(hostlist, (hostlistsize * sizeof(char *))); hostlist[hostlistsize-1] = strdup(hostname); } hostname = strtok_r(NULL, ",", &stp); } xfree(hnames); if (hostlist) hostname = hostlist[0]; } else if (strcmp(cwalk->name, "service") == 0) { service = strdup(cwalk->value); } else if (strcmp(cwalk->name, "disp") == 0) { displayname = strdup(cwalk->value); } else if (strcmp(cwalk->name, "graph") == 0) { if (strcmp(cwalk->value, "hourly") == 0) { period = HOUR_GRAPH; persecs = 48*60*60; gtype = strdup(cwalk->value); glegend = "Last 48 Hours"; } else if (strcmp(cwalk->value, "daily") == 0) { period = DAY_GRAPH; persecs = 12*24*60*60; gtype = strdup(cwalk->value); glegend = "Last 12 Days"; } else if (strcmp(cwalk->value, "weekly") == 0) { period = WEEK_GRAPH; persecs = 48*24*60*60; gtype = strdup(cwalk->value); glegend = "Last 48 Days"; } else if (strcmp(cwalk->value, "monthly") == 0) { period = MONTH_GRAPH; persecs = 576*24*60*60; gtype = strdup(cwalk->value); glegend = "Last 576 Days"; } else if (strcmp(cwalk->value, "custom") == 0) { period = NULL; persecs = 0; gtype = strdup(cwalk->value); glegend = ""; } } else if (strcmp(cwalk->name, "first") == 0) { firstidx = atoi(cwalk->value) - 1; } else if (strcmp(cwalk->name, "count") == 0) { idxcount = atoi(cwalk->value); lastidx = firstidx + idxcount - 1; } else if (strcmp(cwalk->name, "action") == 0) { if (cwalk->value) { if (strcmp(cwalk->value, "menu") == 0) action = ACT_MENU; else if (strcmp(cwalk->value, "selzoom") == 0) action = ACT_SELZOOM; else if (strcmp(cwalk->value, "view") == 0) action = ACT_VIEW; } } else if (strcmp(cwalk->name, "graph_start") == 0) { if (cwalk->value) graphstart = atoi(cwalk->value); } else if (strcmp(cwalk->name, "graph_end") == 0) { if (cwalk->value) graphend = atoi(cwalk->value); } else if (strcmp(cwalk->name, "upper") == 0) { if (cwalk->value) { upperlimit = atof(cwalk->value); haveupperlimit = 1; } } else if (strcmp(cwalk->name, "lower") == 0) { if (cwalk->value) { lowerlimit = atof(cwalk->value); havelowerlimit = 1; } } else if (strcmp(cwalk->name, "graph_width") == 0) { if (cwalk->value) graphwidth = atoi(cwalk->value); } else if (strcmp(cwalk->name, "graph_height") == 0) { if (cwalk->value) graphheight = atoi(cwalk->value); } else if (strcmp(cwalk->name, "nostale") == 0) { ignorestalerrds = 1; } else if (strcmp(cwalk->name, "color") == 0) { int color = parse_color(cwalk->value); if (color != -1) bgcolor = color; } cwalk = cwalk->next; } if (hostlistsize == 1) { xfree(hostlist); hostlist = NULL; } else { displayname = hostname = strdup(""); } if ((hostname == NULL) || (service == NULL)) errormsg("Invalid request - no host or service"); if (displayname == NULL) displayname = hostname; if (graphstart && graphend) { char t1[15], t2[15]; persecs = (graphend - graphstart); strftime(t1, sizeof(t1), "%d/%b/%Y", localtime(&graphstart)); strftime(t2, sizeof(t2), "%d/%b/%Y", localtime(&graphend)); glegend = (char *)malloc(40); snprintf(glegend, 40, "%s - %s", t1, t2); } } void load_gdefs(char *fn) { FILE *fd; strbuffer_t *inbuf; char *p; gdef_t *newitem = NULL; char **alldefs = NULL; int alldefcount = 0, alldefidx = 0; inbuf = newstrbuffer(0); fd = stackfopen(fn, "r", NULL); if (fd == NULL) errormsg("Cannot load graph definitions"); while (stackfgets(inbuf, NULL)) { p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; p = STRBUF(inbuf); p += strspn(p, " \t"); if ((strlen(p) == 0) || (*p == '#')) continue; if (*p == '[') { char *delim; if (newitem) { /* Save the current one, and start on the next item */ alldefs[alldefidx] = NULL; newitem->defs = alldefs; newitem->next = gdefs; gdefs = newitem; } newitem = calloc(1, sizeof(gdef_t)); delim = strchr(p, ']'); if (delim) *delim = '\0'; newitem->name = strdup(p+1); alldefcount = 10; alldefs = (char **)malloc((alldefcount+1) * sizeof(char *)); alldefidx = 0; } else if (strncasecmp(p, "FNPATTERN", 9) == 0) { p += 9; p += strspn(p, " \t"); newitem->fnpat = strdup(p); } else if (strncasecmp(p, "EXFNPATTERN", 11) == 0) { p += 11; p += strspn(p, " \t"); newitem->exfnpat = strdup(p); } else if (strncasecmp(p, "TITLE", 5) == 0) { p += 5; p += strspn(p, " \t"); newitem->title = strdup(p); } else if (strncasecmp(p, "YAXIS", 5) == 0) { p += 5; p += strspn(p, " \t"); newitem->yaxis = strdup(p); } else if (strncasecmp(p, "NOVZOOM", 7) == 0) { newitem->novzoom = 1; } else if (strncasecmp(p, "GRAPHOPTIONS", 12) == 0) { p += 12; p += strspn(p, " \t"); newitem->graphopts = strdup(p); } else if (haveupperlimit && (strncmp(p, "-u ", 3) == 0)) { continue; } else if (haveupperlimit && (strncmp(p, "-upper ", 7) == 0)) { continue; } else if (havelowerlimit && (strncmp(p, "-l ", 3) == 0)) { continue; } else if (havelowerlimit && (strncmp(p, "-lower ", 7) == 0)) { continue; } else { if (alldefidx == alldefcount) { /* Must expand alldefs */ alldefcount += 5; alldefs = (char **)realloc(alldefs, (alldefcount+1) * sizeof(char *)); } alldefs[alldefidx++] = strdup(p); } } /* Pick up the last item */ if (newitem) { /* Save the current one, and start on the next item */ alldefs[alldefidx] = NULL; newitem->defs = alldefs; newitem->next = gdefs; gdefs = newitem; } stackfclose(fd); freestrbuffer(inbuf); } char *lookup_meta(char *keybuf, char *rrdfn) { FILE *fd; SBUF_DEFINE(metafn); char *p; int servicelen = strlen(service); int keylen = strlen(keybuf); int found; static char buf[1024]; /* Must be static since it is returned to caller */ SBUF_MALLOC(metafn, PATH_MAX); p = strrchr(rrdfn, '/'); if (!p) { strncpy(metafn, "rrd.meta", metafn_buflen); } else { metafn = (char *)malloc(strlen(rrdfn) + 10); *p = '\0'; snprintf(metafn, metafn_buflen, "%s/rrd.meta", rrdfn); *p = '/'; } fd = fopen(metafn, "r"); xfree(metafn); if (!fd) return NULL; /* Find the first line that has our key and then whitespace */ found = 0; while (!found && fgets(buf, sizeof(buf), fd)) { found = ( (strncmp(buf, service, servicelen) == 0) && (*(buf+servicelen) == ':') && (strncmp(buf+servicelen+1, keybuf, keylen) == 0) && isspace(*(buf+servicelen+1+keylen)) ); } fclose(fd); if (found) { char *eoln, *val; val = buf + servicelen + 1 + keylen; val += strspn(val, " \t"); eoln = strchr(val, '\n'); if (eoln) *eoln = '\0'; if (strlen(val) > 0) return val; } return NULL; } char *colon_escape(char *buf) { /* Change all colons to "\:" */ static char *result = NULL; int count = 0; char *p, *inp, *outp; p = buf; while ((p = strchr(p, ':')) != NULL) { count++; p++; } if (count == 0) return buf; if (result) xfree(result); result = (char *) malloc(strlen(buf) + count + 1); /* Add one backslash per colon */ *result = '\0'; inp = buf; outp = result; while (*inp) { p = strchr(inp, ':'); if (p == NULL) { strcat(outp, inp); inp += strlen(inp); outp += strlen(outp); } else { *p = '\0'; strcat(outp, inp); strcat(outp, "\\:"); *p = ':'; inp = p+1; outp = outp + strlen(outp); } } *outp = '\0'; return result; } char *expand_tokens(char *tpl) { static strbuffer_t *result = NULL; char *inp, *p; if (strchr(tpl, '@') == NULL) return tpl; if (!result) result = newstrbuffer(2048); else clearstrbuffer(result); inp = tpl; while (*inp) { p = strchr(inp, '@'); if (p == NULL) { addtobuffer(result, inp); inp += strlen(inp); continue; } *p = '\0'; if (strlen(inp)) { addtobuffer(result, inp); inp = p; } *p = '@'; if (strncmp(inp, "@RRDFN@", 7) == 0) { addtobuffer(result, colon_escape(rrddbs[rrdidx].rrdfn)); inp += 7; } else if (strncmp(inp, "@RRDPARAM@", 10) == 0) { /* * We do a colon-escape first, then change all commas to slashes as * this is a common mangling used by multiple backends (disk, http, iostat...) */ if (rrddbs[rrdidx].rrdparam) { char *val, *p; int vallen; SBUF_DEFINE(resultstr); val = colon_escape(rrddbs[rrdidx].rrdparam); p = val; while ((p = strchr(p, ',')) != NULL) *p = '/'; /* rrdparam strings may be very long. */ if (strlen(val) > 100) *(val+100) = '\0'; /* * "paramlen" holds the longest string of the any of the matching files' rrdparam. * However, because this goes through colon_escape(), the actual string length * passed to librrd functions may be longer (since ":" must be escaped as "\:"). */ vallen = strlen(val); if (vallen < paramlen) vallen = paramlen; SBUF_MALLOC(resultstr, vallen + 1); snprintf(resultstr, resultstr_buflen, "%-*s", paramlen, val); addtobuffer(result, resultstr); xfree(resultstr); } inp += 10; } else if (strncmp(inp, "@RRDMETA@", 9) == 0) { /* * We do a colon-escape first, then change all commas to slashes as * this is a common mangling used by multiple backends (disk, http, iostat...) */ if (rrddbs[rrdidx].rrdparam) { char *val, *p, *metaval; val = colon_escape(rrddbs[rrdidx].rrdparam); p = val; while ((p = strchr(p, ',')) != NULL) *p = '/'; metaval = lookup_meta(val, rrddbs[rrdidx].rrdfn); if (metaval) addtobuffer(result, metaval); } inp += 9; } else if (strncmp(inp, "@RRDIDX@", 8) == 0) { char numstr[10]; snprintf(numstr, sizeof(numstr), "%d", rrdidx); addtobuffer(result, numstr); inp += 8; } else if (strncmp(inp, "@STACKIT@", 9) == 0) { /* Contributed by Gildas Le Nadan */ /* the STACK behavior changed between rrdtool 1.0.x * and 1.2.x, hence the ifdef: * - in 1.0.x, you replace the graph type (AREA|LINE) * for the graph you want to stack with the STACK * keyword * - in 1.2.x, you add the STACK keyword at the end * of the definition * * Please note that in both cases the first entry * mustn't contain the keyword STACK at all, so * we need a different treatment for the first rrdidx * * examples of graphs.cfg entries: * * - rrdtool 1.0.x * @STACKIT@:la@RRDIDX@#@COLOR@:@RRDPARAM@ * * - rrdtool 1.2.x * AREA::la@RRDIDX@#@COLOR@:@RRDPARAM@:@STACKIT@ */ char numstr[10]; if (rrdidx == 0) { #ifdef RRDTOOL12 strncpy(numstr, "", sizeof(numstr)); #else snprintf(numstr, sizeof(numstr), "AREA"); #endif } else { snprintf(numstr, sizeof(numstr), "STACK"); } addtobuffer(result, numstr); inp += 9; } else if (strncmp(inp, "@SERVICE@", 9) == 0) { addtobuffer(result, service); inp += 9; } else if (strncmp(inp, "@COLOR@", 7) == 0) { addtobuffer(result, colorlist[coloridx]); inp += 7; coloridx++; if (colorlist[coloridx] == NULL) coloridx = 0; } else { addtobuffer(result, "@"); inp += 1; } } return STRBUF(result); } int rrd_name_compare(const void *v1, const void *v2) { rrddb_t *r1 = (rrddb_t *)v1; rrddb_t *r2 = (rrddb_t *)v2; char *endptr; long numkey1, numkey2; int key1isnumber, key2isnumber; /* See if the keys are all numeric; if yes, then do a numeric sort */ numkey1 = strtol(r1->key, &endptr, 10); key1isnumber = (*endptr == '\0'); numkey2 = strtol(r2->key, &endptr, 10); key2isnumber = (*endptr == '\0'); if (key1isnumber && key2isnumber) { if (numkey1 < numkey2) return -1; else if (numkey1 > numkey2) return 1; else return 0; } return strcmp(r1->key, r2->key); } void graph_link(FILE *output, char *uri, char *grtype, time_t seconds) { time_t gstart, gend; char *grtype_s; fprintf(output, "\n"); grtype_s = htmlquoted(grtype); switch (action) { case ACT_MENU: fprintf(output, " \"%s\n", uri, grtype_s, grtype_s); fprintf(output, " \"Zoom \n", uri, grtype_s, colorname(bgcolor), xgetenv("XYMONSKIN"), xgetenv("IMAGEFILETYPE")); break; case ACT_SELZOOM: if (graphend == 0) gend = getcurrenttime(NULL); else gend = graphend; if (graphstart == 0) gstart = gend - persecs; else gstart = graphstart; fprintf(output, " \"Zoom\n"); break; case ACT_VIEW: break; } fprintf(output, "\n"); } char *build_selfURI(void) { strbuffer_t *result = newstrbuffer(2048); char numbuf[40]; addtobuffer(result, xgetenv("SCRIPT_NAME")); addtobuffer(result, "?host="); if (hostlist) { int i; addtobuffer(result, urlencode(hostlist[0])); for (i = 1; (i < hostlistsize); i++) { addtobuffer(result, ","); addtobuffer(result, urlencode(hostlist[i])); } } else { addtobuffer(result, urlencode(hostname)); } addtobuffer(result, "&color="); addtobuffer(result, colorname(bgcolor)); if (service) { addtobuffer(result, "&service="); addtobuffer(result, urlencode(service)); } if (haveupperlimit) { snprintf(numbuf, sizeof(numbuf)-1, "%f", upperlimit); addtobuffer(result, "&upper="); addtobuffer(result, urlencode(numbuf)); } if (graphheight) { snprintf(numbuf, sizeof(numbuf)-1, "%d", graphheight); addtobuffer(result, "&graph_height="); addtobuffer(result, urlencode(numbuf)); } if (graphwidth) { snprintf(numbuf, sizeof(numbuf)-1, "%d", graphwidth); addtobuffer(result, "&graph_width="); addtobuffer(result, urlencode(numbuf)); } if (displayname && (displayname != hostname)) { addtobuffer(result, "&disp="); addtobuffer(result, urlencode(displayname)); } if (firstidx != -1) { snprintf(numbuf, sizeof(numbuf)-1, "&first=%d", firstidx+1); addtobuffer(result, numbuf); } if (idxcount != -1) { snprintf(numbuf, sizeof(numbuf)-1, "&count=%d", idxcount); addtobuffer(result, numbuf); } if (ignorestalerrds) addtobuffer(result, "&nostale"); return STRBUF(result); } void build_menu_page(char *selfURI, int backsecs) { /* This is special-handled, because we just want to generate an HTML link page */ fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); sethostenv(displayname, "", service, colorname(bgcolor), hostname); sethostenv_backsecs(backsecs); headfoot(stdout, "graphs", "", "header", bgcolor); fprintf(stdout, "\n"); graph_link(stdout, selfURI, "hourly", 48*60*60); graph_link(stdout, selfURI, "daily", 12*24*60*60); graph_link(stdout, selfURI, "weekly", 48*24*60*60); graph_link(stdout, selfURI, "monthly", 576*24*60*60); fprintf(stdout, "
\n"); headfoot(stdout, "graphs", "", "footer", bgcolor); } void generate_graph(char *gdeffn, char *rrddir, char *graphfn) { gdef_t *gdef = NULL, *gdefuser = NULL; int wantsingle = 0; DIR *dir; time_t now = getcurrenttime(NULL); int argi, pcount; /* Options for rrd_graph() */ int rrdargcount; char **rrdargs = NULL; /* The full argv[] table of string pointers to arguments */ char heightopt[30]; /* -h HEIGHT */ char widthopt[30]; /* -w WIDTH */ char upperopt[30]; /* -u MAX */ char loweropt[30]; /* -l MIN */ char startopt[30]; /* -s STARTTIME */ char endopt[30]; /* -e ENDTIME */ char graphtitle[1024]; /* --title TEXT */ char timestamp[50]; /* COMMENT with timestamp graph was generated */ /* Return variables from rrd_graph() */ int result; char **calcpr = NULL; int xsize, ysize; double ymin, ymax; char *useroptval = NULL; char **useropts = NULL; int useroptcount = 0, useroptidx; /* Find the graphs.cfg file and load it */ if (gdeffn == NULL) { char fnam[PATH_MAX]; snprintf(fnam, sizeof(fnam), "%s/etc/graphs.cfg", xgetenv("XYMONHOME")); gdeffn = strdup(fnam); } load_gdefs(gdeffn); /* Determine the real service name. It might be a multi-service graph */ if (strchr(service, ':') || strchr(service, '.')) { /* * service is "tcp:foo" - so use the "tcp" graph definition, but for a * single service (as if service was set to just "foo"). */ char *delim = service + strcspn(service, ":."); char *realservice; *delim = '\0'; realservice = strdup(delim+1); /* The requested gdef only acts as a fall-back solution so don't set gdef here. */ for (gdefuser = gdefs; (gdefuser && strcmp(service, gdefuser->name)); gdefuser = gdefuser->next) ; strcpy(service, realservice); wantsingle = 1; xfree(realservice); } /* * Lookup which RRD file corresponds to the service-name, and how we handle this graph. * We first lookup the service name in the graph definition list. * If that fails, then we try mapping it via the servicename -> RRD map. */ for (gdef = gdefs; (gdef && strcmp(service, gdef->name)); gdef = gdef->next) ; if (gdef == NULL) { if (gdefuser) { gdef = gdefuser; } else { xymonrrd_t *ldef = find_xymon_rrd(service, NULL); if (ldef) { for (gdef = gdefs; (gdef && strcmp(ldef->xymonrrdname, gdef->name)); gdef = gdef->next) ; wantsingle = 1; } } } if (gdef == NULL) errormsg("Unknown graph requested"); if (hostlist && (gdef->fnpat == NULL)) { SBUF_DEFINE(multiname); SBUF_MALLOC(multiname, strlen(gdef->name) + 7); snprintf(multiname, multiname_buflen, "%s-multi", gdef->name); for (gdef = gdefs; (gdef && strcmp(multiname, gdef->name)); gdef = gdef->next) ; if (gdef == NULL) errormsg("Unknown multi-graph requested"); xfree(multiname); } /* * If we're here only to collect the min/max values for the graph but it doesn't * allow vertical zoom, then there's no reason to waste anymore time. */ if ((action == ACT_SELZOOM) && gdef->novzoom) { haveupperlimit = havelowerlimit = 0; return; } /* Determine the directory with the host RRD files, and go there. */ if (rrddir == NULL) { char dnam[PATH_MAX]; if (hostlist) snprintf(dnam, sizeof(dnam), "%s", xgetenv("XYMONRRDS")); else snprintf(dnam, sizeof(dnam), "%s/%s", xgetenv("XYMONRRDS"), hostname); rrddir = strdup(dnam); } if (chdir(rrddir)) errormsg("Cannot access RRD directory"); /* Request an RRD cache flush from the xymond_rrd update daemon */ if (hostlist) { int i; for (i=0; (i < hostlistsize); i++) request_cacheflush(hostlist[i]); } else if (hostname) request_cacheflush(hostname); /* What RRD files do we have matching this request? */ if (hostlist || (gdef->fnpat == NULL)) { /* * No pattern, just a single file. It doesnt matter if it exists, because * these types of graphs usually have a hard-coded value for the RRD filename * in the graph definition. */ rrddbcount = rrddbsize = (hostlist ? hostlistsize : 1); rrddbs = (rrddb_t *)malloc((rrddbsize + 1) * sizeof(rrddb_t)); if (!hostlist) { size_t buflen = strlen(gdef->name) + strlen(".rrd") + 1; rrddbs[0].key = strdup(service); rrddbs[0].rrdfn = (char *)malloc(buflen); snprintf(rrddbs[0].rrdfn, buflen, "%s.rrd", gdef->name); rrddbs[0].rrdparam = NULL; } else { int i, maxlen; char paramfmt[20]; for (i=0, maxlen=0; (i < hostlistsize); i++) { if (strlen(hostlist[i]) > maxlen) maxlen = strlen(hostlist[i]); } snprintf(paramfmt, sizeof(paramfmt), "%%-%ds", maxlen+1); for (i=0; (i < hostlistsize); i++) { size_t buflen; rrddbs[i].key = strdup(service); buflen = strlen(hostlist[i]) + strlen(gdef->fnpat) + 2; rrddbs[i].rrdfn = (char *)malloc(buflen); snprintf(rrddbs[i].rrdfn, buflen, "%s/%s", hostlist[i], gdef->fnpat); buflen = maxlen + 2; rrddbs[i].rrdparam = (char *)malloc(buflen); snprintf(rrddbs[i].rrdparam, buflen, paramfmt, hostlist[i]); } } } else { struct dirent *d; pcre *pat, *expat = NULL; const char *errmsg; int errofs, result; int ovector[30]; struct stat st; time_t now = getcurrenttime(NULL); /* Scan the directory to see what RRD files are there that match */ dir = opendir("."); if (dir == NULL) errormsg("Unexpected error while accessing RRD directory"); /* Setup the pattern to match filenames against */ pat = pcre_compile(gdef->fnpat, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!pat) { char msg[8192]; snprintf(msg, sizeof(msg), "graphs.cfg error, PCRE pattern %s invalid: %s, offset %d\n", htmlquoted(gdef->fnpat), errmsg, errofs); errormsg(msg); } if (gdef->exfnpat) { expat = pcre_compile(gdef->exfnpat, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!expat) { char msg[8192]; snprintf(msg, sizeof(msg), "graphs.cfg error, PCRE pattern %s invalid: %s, offset %d\n", htmlquoted(gdef->exfnpat), errmsg, errofs); errormsg(msg); } } /* Allocate an initial filename table */ rrddbsize = 5; rrddbs = (rrddb_t *) malloc((rrddbsize+1) * sizeof(rrddb_t)); while ((d = readdir(dir)) != NULL) { char *ext; char param[PATH_MAX]; /* Ignore dot-files and files with names shorter than ".rrd" */ if (*(d->d_name) == '.') continue; ext = d->d_name + strlen(d->d_name) - strlen(".rrd"); if ((ext <= d->d_name) || (strcmp(ext, ".rrd") != 0)) continue; /* First check the exclude pattern. */ if (expat) { result = pcre_exec(expat, NULL, d->d_name, strlen(d->d_name), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result >= 0) continue; } /* Then see if the include pattern matches. */ result = pcre_exec(pat, NULL, d->d_name, strlen(d->d_name), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) continue; if (wantsingle) { /* "Single" graph, i.e. a graph for a service normally included in a bundle (tcp) */ if (strstr(d->d_name, service) == NULL) continue; } /* * Has it been updated recently (within the past 24 hours) ? * We don't want old graphs to mess up multi-displays. */ if (ignorestalerrds && (stat(d->d_name, &st) == 0) && ((now - st.st_mtime) > 86400)) { continue; } /* We have a matching file! */ rrddbs[rrddbcount].rrdfn = strdup(d->d_name); if (pcre_copy_substring(d->d_name, ovector, result, 1, param, sizeof(param)) > 0) { /* * This is ugly, but I cannot find a pretty way of un-mangling * the disk- and http-data that has been molested by the back-end. */ if ((strcmp(param, ",root") == 0) && ((strncmp(gdef->name, "disk", 4) == 0) || (strncmp(gdef->name, "inode", 5) == 0)) ) { rrddbs[rrddbcount].rrdparam = strdup(","); } else if ((strcmp(gdef->name, "http") == 0) && (strncmp(param, "http", 4) != 0)) { size_t buflen = strlen("http://")+strlen(param)+1; rrddbs[rrddbcount].rrdparam = (char *)malloc(buflen); snprintf(rrddbs[rrddbcount].rrdparam, buflen, "http://%s", param); } else { rrddbs[rrddbcount].rrdparam = strdup(param); } if (strlen(rrddbs[rrddbcount].rrdparam) > paramlen) { /* * "paramlen" holds the longest string of the any of the matching files' rrdparam. */ paramlen = strlen(rrddbs[rrddbcount].rrdparam); } rrddbs[rrddbcount].key = strdup(rrddbs[rrddbcount].rrdparam); } else { rrddbs[rrddbcount].key = strdup(d->d_name); rrddbs[rrddbcount].rrdparam = NULL; } rrddbcount++; if (rrddbcount == rrddbsize) { rrddbsize += 5; rrddbs = (rrddb_t *)realloc(rrddbs, (rrddbsize+1) * sizeof(rrddb_t)); } } pcre_free(pat); if (expat) pcre_free(expat); closedir(dir); } rrddbs[rrddbcount].key = rrddbs[rrddbcount].rrdfn = rrddbs[rrddbcount].rrdparam = NULL; /* Sort them so the display looks prettier */ qsort(&rrddbs[0], rrddbcount, sizeof(rrddb_t), rrd_name_compare); /* Setup the title */ if (!gdef->title) gdef->title = strdup(""); if (strncmp(gdef->title, "exec:", 5) == 0) { char *pcmd; int i, pcmdlen = 7; FILE *pfd; char *p; char *param_str = "%s \"%s\" %s \"%s\""; pcmdlen += (strlen(gdef->title+5) + strlen(displayname) + strlen(service) + strlen(glegend)); for (i=0; (ititle+5, displayname, service, glegend); for (i=0; (i= firstidx) && (i <= lastidx))) { p += snprintf(p, (pcmdlen - (p - pcmd) + 1), " \"%s\"", rrddbs[i].rrdfn); } } pfd = popen(pcmd, "r"); if (pfd) { if (fgets(graphtitle, sizeof(graphtitle), pfd) == NULL) *graphtitle = '\0'; pclose(pfd); } /* Drop any newline at end of the title */ p = strchr(graphtitle, '\n'); if (p) *p = '\0'; } else { snprintf(graphtitle, sizeof(graphtitle), "%s %s %s", displayname, gdef->title, glegend); } snprintf(heightopt, sizeof(heightopt), "-h%d", graphheight); snprintf(widthopt, sizeof(widthopt), "-w%d", graphwidth); /* * Grab user-provided additional rrd_graph options from RRDGRAPHOPTS */ useroptcount = 0; useroptval = gdef->graphopts; if (!useroptval) useroptval = getenv("RRDGRAPHOPTS"); if (useroptval) { char *tok; useropts = (char **)calloc(1, sizeof(char *)); useroptval = strdup(useroptval); tok = strtok(useroptval, " "); while (tok) { useroptcount++; useropts = (char **)realloc(useropts, (useroptcount+1)*sizeof(char *)); useropts[useroptcount-1] = tok; useropts[useroptcount] = NULL; tok = strtok(NULL, " "); } } /* * Setup the arguments for calling rrd_graph. * There's up to 16 standard arguments, plus the * graph-specific ones (which may be repeated if * there are multiple RRD-files to handle). */ for (pcount = 0; (gdef->defs[pcount]); pcount++) ; rrdargs = (char **) calloc(16 + pcount*rrddbcount + useroptcount + 1, sizeof(char *)); argi = 0; rrdargs[argi++] = "rrdgraph"; rrdargs[argi++] = (action == ACT_VIEW) ? graphfn : "/dev/null"; rrdargs[argi++] = "--title"; rrdargs[argi++] = graphtitle; rrdargs[argi++] = widthopt; rrdargs[argi++] = heightopt; rrdargs[argi++] = "-v"; rrdargs[argi++] = gdef->yaxis; rrdargs[argi++] = "-a"; rrdargs[argi++] = "PNG"; if (haveupperlimit) { snprintf(upperopt, sizeof(upperopt), "-u %f", upperlimit); rrdargs[argi++] = upperopt; } if (havelowerlimit) { snprintf(loweropt, sizeof(loweropt), "-l %f", lowerlimit); rrdargs[argi++] = loweropt; } if (haveupperlimit || havelowerlimit) rrdargs[argi++] = "--rigid"; if (graphstart) snprintf(startopt, sizeof(startopt), "-s %u", (unsigned int) graphstart); else snprintf(startopt, sizeof(startopt), "-s %s", period); rrdargs[argi++] = startopt; if (graphend) { snprintf(endopt, sizeof(endopt), "-e %u", (unsigned int) graphend); rrdargs[argi++] = endopt; } for (useroptidx=0; (useroptidx < useroptcount); useroptidx++) { rrdargs[argi++] = useropts[useroptidx]; } for (rrdidx=0; (rrdidx < rrddbcount); rrdidx++) { if ((firstidx == -1) || ((rrdidx >= firstidx) && (rrdidx <= lastidx))) { int i; for (i=0; (gdef->defs[i]); i++) { rrdargs[argi++] = strdup(expand_tokens(gdef->defs[i])); } } } #ifdef RRDTOOL12 strftime(timestamp, sizeof(timestamp), "COMMENT:Updated\\: %d-%b-%Y %H\\:%M\\:%S", localtime(&now)); #else strftime(timestamp, sizeof(timestamp), "COMMENT:Updated: %d-%b-%Y %H:%M:%S", localtime(&now)); #endif rrdargs[argi++] = strdup(timestamp); rrdargcount = argi; rrdargs[argi++] = NULL; if (debug) { for (argi=0; (argi < rrdargcount); argi++) dbgprintf("%s\n", rrdargs[argi]); } /* If sending to stdout, print the HTTP header first. */ if ((action == ACT_VIEW) && (strcmp(graphfn, "-") == 0)) { time_t expiretime = now + 300; char expirehdr[100]; printf("Content-type: image/png\n"); strftime(expirehdr, sizeof(expirehdr), "Expires: %a, %d %b %Y %H:%M:%S GMT", gmtime(&expiretime)); printf("%s\n", expirehdr); printf("\n"); #ifdef HIDE_EMPTYGRAPH /* It works, but we still get the "zoom" magnifying glass which looks odd */ if (rrddbcount == 0) { /* No graph */ fwrite(blankimg, 1, sizeof(blankimg), stdout); return; } #endif } /* All set - generate the graph */ rrd_clear_error(); #ifdef RRDTOOL12 result = rrd_graph(rrdargcount, rrdargs, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax); /* * If we have neither the upper- nor lower-limits of the graph, AND we allow vertical * zooming of this graph, then save the upper/lower limit values and flag that we have * them. The values are then used for the zoom URL we construct later on. */ if (!haveupperlimit && !havelowerlimit) { upperlimit = ymax; haveupperlimit = 1; lowerlimit = ymin; havelowerlimit = 1; } #else result = rrd_graph(rrdargcount, rrdargs, &calcpr, &xsize, &ysize); #endif /* Was it OK ? */ if (rrd_test_error() || (result != 0)) { if (calcpr) { int i; for (i=0; (calcpr[i]); i++) xfree(calcpr[i]); calcpr = NULL; } errormsg(rrd_get_error()); } if (useroptval) xfree(useroptval); if (useropts) xfree(useropts); } void generate_zoompage(char *selfURI) { fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); sethostenv(displayname, "", service, colorname(bgcolor), hostname); headfoot(stdout, "graphs", "", "header", bgcolor); fprintf(stdout, "
\n"); fprintf(stdout, "
\n"); fprintf(stdout, "\n"); graph_link(stdout, selfURI, gtype, 0); fprintf(stdout, "
\n"); { char zoomjsfn[PATH_MAX]; struct stat st; snprintf(zoomjsfn, sizeof(zoomjsfn), "%s/web/zoom.js", xgetenv("XYMONHOME")); if (stat(zoomjsfn, &st) == 0) { FILE *fd; char *buf; size_t n; char *zoomrightoffsetmarker = "var cZoomBoxRightOffset = -"; char *zoomrightoffsetp; fd = fopen(zoomjsfn, "r"); if (fd) { buf = (char *)malloc(st.st_size+1); n = fread(buf, 1, st.st_size, fd); fclose(fd); #ifdef RRDTOOL12 zoomrightoffsetp = strstr(buf, zoomrightoffsetmarker); if (zoomrightoffsetp) { zoomrightoffsetp += strlen(zoomrightoffsetmarker); memcpy(zoomrightoffsetp, "30", 2); } #endif fwrite(buf, 1, n, stdout); } } } headfoot(stdout, "graphs", "", "footer", bgcolor); } int main(int argc, char *argv[]) { /* Command line settings */ int argi; char *envarea = NULL; char *rrddir = NULL; /* RRD files top-level directory */ char *gdeffn = NULL; /* graphs.cfg file */ char *graphfn = "-"; /* Output filename, default is stdout */ char *selfURI; /* Setup defaults */ graphwidth = atoi(xgetenv("RRDWIDTH")); graphheight = atoi(xgetenv("RRDHEIGHT")); /* See what we want to do - i.e. get hostname, service and graph-type */ parse_query(); /* Handle any command-line args */ for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (argnmatch(argv[argi], "--rrddir=")) { char *p = strchr(argv[argi], '='); rrddir = strdup(p+1); } else if (argnmatch(argv[argi], "--config=")) { char *p = strchr(argv[argi], '='); gdeffn = strdup(p+1); } else if (strcmp(argv[argi], "--save=") == 0) { char *p = strchr(argv[argi], '='); graphfn = strdup(p+1); } } redirect_cgilog("showgraph"); selfURI = build_selfURI(); if (action == ACT_MENU) { build_menu_page(selfURI, graphend-graphstart); return 0; } if ((action == ACT_VIEW) || !(haveupperlimit && havelowerlimit)) { generate_graph(gdeffn, rrddir, graphfn); } if (action == ACT_SELZOOM) { generate_zoompage(selfURI); } return 0; } xymon-4.3.30/web/cgiwrap.c0000664000076400007640000002027313515623702015570 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon CGI wrapper tool */ /* */ /* This is a wrapper for running the Xymon CGI programs */ /* */ /* Copyright (C) 2014 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: $"; #include #include #include #include #include #include #include #include "libxymon.h" static char **options = NULL; static int optcount = 0; static int haveenvopt = 0; void addopt(char *opt) { options = (char **)realloc(options, (++optcount)*sizeof(char *)); options[optcount-1] = strdup(opt); if (strncmp(opt, "--env=", 6) == 0) haveenvopt = 1; } void addoptl(char *ename) { char *optlist, *opt; if (getenv(ename) == NULL) return; optlist = strdup(getenv(ename)); opt = strtok(optlist, " \t"); while (opt) { addopt(opt); opt = strtok(NULL, " \t"); } free(optlist); } void addoptdone(void) { options = (char **)realloc(options, (++optcount)*sizeof(char *)); options[optcount-1] = NULL; } int main(int argc, char **argv) { char *cgifile = XYMONHOME "/etc/cgioptions.cfg"; char *pgm = strdup(argv[0]); SBUF_DEFINE(cgipgm); char executable[PATH_MAX]; char xymoncmd[PATH_MAX]; if (getenv("CGIDEBUG")) debug = 1; set_debugfile("stderr", 1); loadenv(cgifile, NULL); SBUF_MALLOC(cgipgm, strlen(pgm) + 5); strncpy(cgipgm, basename(pgm), cgipgm_buflen); if (strstr(cgipgm, ".sh")) { char *p = strstr(cgipgm, ".sh"); strncpy(p, ".cgi", (cgipgm_buflen - (p - cgipgm))); } if (strcmp(cgipgm, "cgiwrap") == 0) { printf("\ncgiwrap is an executable wrapper program for xymon CGI scripts. It sets the environment according to the configuration specified in %s and then launches the CGI to response to the request.\n\nCGI scripts in the xymon-cgi or xymon-seccgi directories should be symlinked or hardlinked to this file. cgiwrap will do nothing if called directly.\n", cgifile); return 1; } addopt(""); // Reserve one for the program name if (strcmp(cgipgm, "ackinfo.cgi") == 0) { addoptl("CGI_ACKINFO_OPTS"); } else if (strcmp(cgipgm, "acknowledge.cgi") == 0) { addoptl("CGI_ACK_OPTS"); } else if (strcmp(cgipgm, "appfeed-critical.cgi") == 0) { cgipgm = "appfeed.cgi"; addoptl("CGI_APPFEED_OPTS"); addopt("--critical=/etc/xymon/critical.cfg"); } else if (strcmp(cgipgm, "appfeed.cgi") == 0) { addoptl("CGI_APPFEED_OPTS"); } else if (strcmp(cgipgm, "certreport.cgi") == 0) { cgipgm = "statusreport.cgi"; addopt("--column=sslcert"); addopt("--filter=color=red,yellow"); addopt("--all"); addopt("--no-colors"); } else if (strcmp(cgipgm, "columndoc.cgi") == 0) { cgipgm = "csvinfo.cgi"; addoptl("CGI_COLUMNDOC_OPTS"); if (getenv("QUERY_STRING")) { SBUF_DEFINE(t); SBUF_MALLOC(t, strlen(getenv("QUERY_STRING")) + 35); snprintf(t, t_buflen, "QUERY_STRING=db=columndoc.csv&key=%s", getenv("QUERY_STRING")); putenv(t); } } else if (strcmp(cgipgm, "confreport-critical.cgi") == 0) { cgipgm = "confreport.cgi"; addoptl("CGI_CONFREPORT_OPTS"); addopt("--critical"); } else if (strcmp(cgipgm, "confreport.cgi") == 0) { addoptl("CGI_CONFREPORT_OPTS"); } else if (strcmp(cgipgm, "criticaleditor.cgi") == 0) { addoptl("CGI_CRITEDIT_OPTS"); } else if (strcmp(cgipgm, "criticalview.cgi") == 0) { addoptl("CGI_CRITVIEW_OPTS"); } else if (strcmp(cgipgm, "csvinfo.cgi") == 0) { addoptl("CGI_CSVINFO_OPTS"); } else if (strcmp(cgipgm, "datepage.cgi") == 0) { addoptl("CGI_DATEPAGE_OPTS"); } else if (strcmp(cgipgm, "enadis.cgi") == 0) { addoptl("CGI_ENADIS_OPTS"); } else if (strcmp(cgipgm, "eventlog.cgi") == 0) { addoptl("CGI_EVENTLOG_OPTS"); } else if (strcmp(cgipgm, "findhost.cgi") == 0) { addoptl("CGI_FINDHOST_OPTS"); } else if (strcmp(cgipgm, "ghostlist.cgi") == 0) { addoptl("CGI_GHOSTS_OPTS"); } else if (strcmp(cgipgm, "history.cgi") == 0) { addoptl("CGI_HIST_OPTS"); } else if (strcmp(cgipgm, "historylog.cgi") == 0) { cgipgm = "svcstatus.cgi"; addoptl("CGI_SVCHIST_OPTS"); addopt("--historical"); } else if (strcmp(cgipgm, "hostgraphs.cgi") == 0) { addoptl("CGI_HOSTGRAPHS_OPTS"); } else if (strcmp(cgipgm, "hostlist.cgi") == 0) { addoptl("CGI_HOSTLIST_OPTS"); } else if (strcmp(cgipgm, "nongreen.cgi") == 0) { cgipgm = "statusreport.cgi"; addopt("--filter=\"color=red,yellow\""); addopt("--all"); addopt("--heading=\"All non-green systems\""); addopt("--show-column"); addopt("--show-summary"); addopt("--link"); } else if (strcmp(cgipgm, "notifications.cgi") == 0) { addoptl("CGI_NOTIFYLOG_OPTS"); } else if (strcmp(cgipgm, "acknowledgements.cgi") == 0) { addoptl("CGI_ACKNOWLEDGEMENTSLOG_OPTS"); } else if (strcmp(cgipgm, "perfdata.cgi") == 0) { addoptl("CGI_PERFDATA_OPTS"); } else if (strcmp(cgipgm, "reportlog.cgi") == 0) { addoptl("CGI_REPLOG_OPTS"); } else if (strcmp(cgipgm, "report.cgi") == 0) { addoptl("CGI_REP_OPTS"); addoptl("XYMONGENREPOPTS"); } else if (strcmp(cgipgm, "showgraph.cgi") == 0) { addoptl("CGI_SHOWGRAPH_OPTS"); } else if (strcmp(cgipgm, "snapshot.cgi") == 0) { addoptl("CGI_SNAPSHOT_OPTS"); addopt("XYMONGENSNAPOPTS"); } else if (strcmp(cgipgm, "svcstatus-hist.cgi") == 0) { cgipgm = "svcstatus.cgi"; addoptl("CGI_SVCHIST_OPTS"); addopt("--historical"); } else if (strcmp(cgipgm, "svcstatus.cgi") == 0) { addoptl("CGI_SVC_OPTS"); } else if (strcmp(cgipgm, "svcstatus2.cgi") == 0) { cgipgm = "svcstatus.cgi"; addoptl("CGI_SVC_OPTS"); } else if (strcmp(cgipgm, "topchanges.cgi") == 0) { cgipgm = "eventlog.cgi"; addoptl("CGI_TOPCHANGE_OPTS"); } else if (strcmp(cgipgm, "useradm.cgi") == 0) { addoptl("CGI_USERADM_OPTS"); } else if (strcmp(cgipgm, "chpasswd.cgi") == 0) { addoptl("CGI_CHPASSWD_OPTS"); } else { /* Make sure we're being called as a CGI */ if ((strlen(cgipgm) <= 4) || (strcmp(cgipgm+strlen(cgipgm)-4, ".cgi") != 0)) { fprintf(stderr, "ERROR: cgiwrap was called as an unexpected CGI name: %s\n", cgipgm); printf("Status: 403\nContent-type: text/plain\n\nUnexpected CGI name: %s\n", cgipgm); return 1; } dbgprintf("called as an unexpected CGI name: %s", cgipgm); } addoptdone(); if (!haveenvopt && getenv("XYMONENV")) loadenv(getenv("XYMONENV"), NULL); snprintf(executable, sizeof(executable), "%s/bin/%s", xgetenv("XYMONHOME"), cgipgm); options[0] = executable; execv(executable, options); printf("Status: 500\nContent-type: text/plain\n\nExec failed for %s: %s\n", executable, strerror(errno)); errprintf("Exec failed for %s: %s\n", executable, strerror(errno)); return 1; } xymon-4.3.30/web/csvinfo.cgi.10000664000076400007640000000322513534041733016257 0ustar rpmbuildrpmbuild.TH CSVINFO.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME csvinfo.cgi \- CGI program to show host information from a CSV file .SH SYNOPSIS .B "csvinfo.cgi" .SH DESCRIPTION \fBcsvinfo.cgi\fR is invoked as a CGI script via the csvinfo.sh CGI wrapper. Based on the parameters it receives, it searches a comma- separated file for the matching host, and presents the information found as a table. csvinfo.cgi is passed a QUERY_STRING environment variable with the following parameters: key (string to search for, typically hostname) column (columnnumber to search - default 0) db (name of the CSV database file in $XYMONHOME/etc/, default hostinfo.csv) delimiter (delimiter character for columns, default semi-colon) CSV files are easily created from e.g. spreadsheets, by exporting them in CSV format. You should have one host per line, with the first line containing the column headings. Despite their name, the default delimiter for CSV files is the semi-colon - if you need a different delimiter, invoke csvinfo.cgi with the "delimiter=" in the query string. .SH Example usage This example shows how you can use the csvinfo CGI. It assumes you have a CSV-formatted file with information about the hosts stored as $XYMONHOME/etc/hostinfo.csv, and the hostname is in the first column of the file. .IP "Use with the xymongen \-\-docurl" The \-\-docurl option to .I xymongen(1) sets up all of the hostnames on your Xymon webpages to act as links to a CGI script. To invoke the csvinfo CGI script, run xymongen with the option .sp \-\-docurl=/cgi\-bin/csvinfo.sh?db=hostinfo.csv&key=%s .SH "SEE ALSO" hosts.cfg(5), xymonserver.cfg(5), xymongen(1) xymon-4.3.30/web/report.c0000664000076400007640000002551213515623702015450 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon report generation front-end. */ /* */ /* This is a front-end CGI that lets the user select reporting parameters, */ /* and then invokes xymongen to generate the report. When the report is */ /* ready, the user's browser is sent off to view the report. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: report.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" char *reqenv[] = { "XYMONHOME", "XYMONREPDIR", "XYMONREPURL", NULL }; char *style = ""; time_t starttime = 0; time_t endtime = 0; char *suburl = ""; int csvoutput = 0; char csvdelim = ','; cgidata_t *cgidata = NULL; char *monthnames[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } void parse_query(void) { cgidata_t *cwalk; int startday, startmon, startyear; int endday, endmon, endyear; struct tm tmbuf; startday = startmon = startyear = endday = endmon = endyear = -1; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "start-day") == 0) { startday = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "start-mon") == 0) { char *errptr; startmon = strtol(cwalk->value, &errptr, 10) - 1; if (errptr == cwalk->value) { for (startmon=0; (monthnames[startmon] && strcmp(cwalk->value, monthnames[startmon])); startmon++) ; if (startmon >= 12) startmon = -1; } } else if (strcasecmp(cwalk->name, "start-yr") == 0) { startyear = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "end-day") == 0) { endday = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "end-mon") == 0) { char *errptr; endmon = strtol(cwalk->value, &errptr, 10) - 1; if (errptr == cwalk->value) { for (endmon=0; (monthnames[endmon] && strcmp(cwalk->value, monthnames[endmon])); endmon++) ; if (endmon > 12) endmon = -1; } } else if (strcasecmp(cwalk->name, "end-yr") == 0) { endyear = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "style") == 0) { char *p = cwalk->value + strspn(cwalk->value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); *p = '\0'; style = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "suburl") == 0) { suburl = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "DoReport") == 0) { csvoutput = 0; } else if (strcasecmp(cwalk->name, "DoCSV") == 0) { csvoutput = 1; } else if (strcasecmp(cwalk->name, "csvdelim") == 0) { csvdelim = *cwalk->value; } cwalk = cwalk->next; } memset(&tmbuf, 0, sizeof(tmbuf)); tmbuf.tm_mday = startday; tmbuf.tm_mon = startmon; tmbuf.tm_year = startyear - 1900; tmbuf.tm_hour = 0; tmbuf.tm_min = 0; tmbuf.tm_sec = 0; tmbuf.tm_isdst = -1; /* Important! Or we mishandle DST periods */ starttime = mktime(&tmbuf); memset(&tmbuf, 0, sizeof(tmbuf)); tmbuf.tm_mday = endday; tmbuf.tm_mon = endmon; tmbuf.tm_year = endyear - 1900; tmbuf.tm_hour = 23; tmbuf.tm_min = 59; tmbuf.tm_sec = 59; tmbuf.tm_isdst = -1; /* Important! Or we mishandle DST periods */ endtime = mktime(&tmbuf); if ((starttime == -1) || (endtime == -1) || (starttime > getcurrenttime(NULL))) errormsg("Invalid parameters"); if (endtime > getcurrenttime(NULL)) endtime = getcurrenttime(NULL); if (starttime > endtime) { /* Swap start and end times */ time_t tmp; tmp = endtime; endtime = starttime; starttime = tmp; } } void cleandir(char *dirname) { DIR *dir; struct dirent *d; struct stat st; char fn[PATH_MAX]; time_t killtime = getcurrenttime(NULL)-86400; dir = opendir(dirname); if (dir == NULL) return; while ((d = readdir(dir))) { if (d->d_name[0] != '.') { snprintf(fn, sizeof(fn), "%s/%s", dirname, d->d_name); if ((stat(fn, &st) == 0) && (st.st_mtime < killtime)) { if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { dbgprintf("rm %s\n", fn); unlink(fn); } else if (S_ISDIR(st.st_mode)) { dbgprintf("Cleaning directory %s\n", fn); cleandir(fn); dbgprintf("rmdir %s\n", fn); rmdir(fn); } else { /* Ignore file */ }; } } } } int main(int argc, char *argv[]) { char dirid[PATH_MAX]; SBUF_DEFINE(outdir); SBUF_DEFINE(xymonwebenv); SBUF_DEFINE(xymongencmd); char xymongentimeopt[100]; char csvdelimopt[100]; char *xymongen_argv[20]; pid_t childpid; int childstat; char htmldelim[100]; char startstr[30], endstr[30]; int cleanupoldreps = 1; int argi, newargi; char *envarea = NULL; char *useragent = NULL; int usemultipart = 1; SBUF_MALLOC(outdir, PATH_MAX+1024); SBUF_MALLOC(xymonwebenv, PATH_MAX+1024); SBUF_MALLOC(xymongencmd, PATH_MAX+1024); newargi = 0; xymongen_argv[newargi++] = xymongencmd; xymongen_argv[newargi++] = xymongentimeopt; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[1], "--noclean") == 0) { cleanupoldreps = 0; } else { xymongen_argv[newargi++] = argv[argi]; } } redirect_cgilog("report"); cgidata = cgi_request(); if (cgidata == NULL) { /* Present the query form */ sethostenv("", "", "", colorname(COL_BLUE), NULL); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "report", "report_form", COL_BLUE, getcurrenttime(NULL)-86400, NULL, NULL); return 0; } useragent = getenv("HTTP_USER_AGENT"); if (useragent && strstr(useragent, "KHTML")) { /* KHTML (Konqueror, Safari) cannot handle multipart documents. */ usemultipart = 0; } envcheck(reqenv); parse_query(); /* * We need to set these variables up AFTER we have put them into the xymongen_argv[] array. * We cannot do it before, because we need the environment that the command-line options * might provide. */ if (xgetenv("XYMONGEN")) snprintf(xymongencmd, xymongencmd_buflen, "%s", xgetenv("XYMONGEN")); else snprintf(xymongencmd, xymongencmd_buflen, "%s/bin/xymongen", xgetenv("XYMONHOME")); snprintf(xymongentimeopt, sizeof(xymongentimeopt)-1,"--reportopts=%u:%u:1:%s", (unsigned int)starttime, (unsigned int)endtime, style); snprintf(dirid, sizeof(dirid), "%lu-%u", (unsigned long)getpid(), (unsigned int)getcurrenttime(NULL)); if (!csvoutput) { snprintf(outdir, outdir_buflen, "%s/%s", xgetenv("XYMONREPDIR"), dirid); mkdir(outdir, 0755); xymongen_argv[newargi++] = outdir; snprintf(xymonwebenv, xymonwebenv_buflen, "XYMONWEB=%s/%s", xgetenv("XYMONREPURL"), dirid); putenv(xymonwebenv); } else { snprintf(outdir, outdir_buflen, "--csv=%s/%s.csv", xgetenv("XYMONREPDIR"), dirid); xymongen_argv[newargi++] = outdir; snprintf(csvdelimopt, sizeof(csvdelimopt), "--csvdelim=%c", csvdelim); xymongen_argv[newargi++] = csvdelimopt; } xymongen_argv[newargi++] = NULL; if (usemultipart) { /* Output the "please wait for report ... " thing */ snprintf(htmldelim, sizeof(htmldelim)-1, "xymonrep-%lu-%u", (unsigned long)getpid(), (unsigned int)getcurrenttime(NULL)); printf("Content-type: multipart/mixed;boundary=%s\n", htmldelim); printf("\n"); printf("--%s\n", htmldelim); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); /* It's ok with these hardcoded values, as they are not used for this page */ sethostenv("", "", "", colorname(COL_BLUE), NULL); sethostenv_report(starttime, endtime, 97.0, 99.995); headfoot(stdout, "repnormal", "", "header", COL_BLUE); strftime(startstr, sizeof(startstr), "%b %d %Y", localtime(&starttime)); strftime(endstr, sizeof(endstr), "%b %d %Y", localtime(&endtime)); printf("
 \n"); printf("



\n"); printf("

Generating report for the period: %s", htmlquoted(startstr)); printf(" - %s ", htmlquoted(endstr)); printf("(%s)
\n", htmlquoted(style)); printf("

\n"); fflush(stdout); } /* Go do the report */ childpid = fork(); if (childpid == 0) { execv(xymongencmd, xymongen_argv); } else if (childpid > 0) { wait(&childstat); /* Ignore SIGHUP so we don't get killed during cleanup of XYMONREPDIR */ signal(SIGHUP, SIG_IGN); if (WIFEXITED(childstat) && (WEXITSTATUS(childstat) != 0) ) { char msg[4096]; if (usemultipart) printf("--%s\n\n", htmldelim); snprintf(msg, sizeof(msg), "Could not generate report.
\nCheck that the %s/www/rep/ directory has permissions '-rwxrwxr-x' (775)
\n and that is is set to group %d", xgetenv("XYMONHOME"), (int)getgid()); errormsg(msg); } else { /* Send the browser off to the report */ if (usemultipart) { printf("Done...Report is here.

\n", xgetenv("XYMONREPURL"), dirid, suburl); fflush(stdout); printf("--%s\n\n", htmldelim); } printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("\n"); if (!csvoutput) { printf("Report is available here\n", xgetenv("XYMONREPURL"), dirid, suburl); } else { printf("Report is available here\n", xgetenv("XYMONREPURL"), dirid); } if (usemultipart) printf("\n--%s\n", htmldelim); fflush(stdout); } if (cleanupoldreps) cleandir(xgetenv("XYMONREPDIR")); } else { if (usemultipart) printf("--%s\n\n", htmldelim); printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); errormsg("Fork failed"); } return 0; } xymon-4.3.30/web/boilerplate.c0000664000076400007640000000423712277125340016437 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: boilerplate.c 7435 2014-02-13 11:22:08Z storner $"; #include #include #include #include "libxymon.h" static void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } void parse_query(void) { cgidata_t *cgidata, *cwalk; cgidata = cgi_request(); if (cgidata == NULL) errormsg(cgi_error()); cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ cwalk = cwalk->next; } } int main(int argc, char *argv[]) { int argi; char *envarea = NULL; char *hffile = "boilerplate"; int bgcolor = COL_BLUE; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--hffile=")) { char *p = strchr(argv[argi], '='); hffile = strdup(p+1); } } parse_query(); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); headfoot(stdout, hffile, "", "header", bgcolor); headfoot(stdout, hffile, "", "footer", bgcolor); return 0; } xymon-4.3.30/web/confreport.cgi.10000664000076400007640000000344113534041733016771 0ustar rpmbuildrpmbuild.TH CONFREPORT.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME confreport.cgi \- Xymon Configuration report .SH SYNOPSIS .B "confreport.cgi" .SH DESCRIPTION \fBconfreport.cgi\fR is invoked as a CGI script via the confreport.sh CGI wrapper. \fBconfreport.cgi\fR provides a plain HTML (Web) report of the Xymon configuration for a group of hosts; which hosts are included is determined by the hosts available on the webpage from where the CGI script is invoked. The configuration report include the hostnames, a list of the statuses monitored for each host, and if applicable any configuration settings affecting these. Alerts that may be triggered by status changes are also included. The report is plain HTML without any images included, and therefore suitable for inclusion into e-mails or other documents that may be accessed outside the Xymon system. .SH OPTIONS .IP "\-\-critical" Report only on the statuses that are configured to show up on the \fBCritical Systems\fR view. .IP "\-\-old\-nk\-config" Use the deprecated \fBNK\fR tag in hosts.cfg to determine if tests appear on the Critical Systems view. .IP "\-\-env=FILENAME" Loads the environment defined in FILENAME before executing the CGI script. .IP "\-\-area=NAME" Load environment variables for a specific area. NB: if used, this option must appear before any \-\-env=FILENAME option. .IP "\-\-debug" Enables debugging output. .IP "\-\-nkconfig=FILENAME" Use FILENAME as the configuration file for the Critical Systems information. The default is to load this from $XYMONHOME/etc/critical.cfg .SH BUGS Client-side configuration done in the .I analysis.cfg(5) is not currently reflected in the report. Critical Systems view configuration is not reflected in the report. .SH "SEE ALSO" hosts.cfg(5), alerts.cfg(5), analysis.cfg(5), xymon(7) xymon-4.3.30/web/criticaleditor.c0000664000076400007640000003110613515623702017132 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon CGI for administering the critical.cfg file */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: criticaleditor.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" static char *operator = NULL; static enum { CRITEDIT_FIND, CRITEDIT_NEXT, CRITEDIT_UPDATE, CRITEDIT_DELETE, CRITEDIT_ADDCLONE, CRITEDIT_DROPCLONE } editaction = CRITEDIT_FIND; static char *rq_hostname = NULL; static char *rq_service = NULL; static int rq_priority = 0; static char *rq_group = NULL; static char *rq_extra = NULL; STATIC_SBUF_DEFINE(rq_crittime); static time_t rq_start = 0; static time_t rq_end = 0; static char *rq_clonestoadd = NULL; static char *rq_clonestodrop = NULL; static int rq_dropevenifcloned = 0; static void parse_query(void) { cgidata_t *cgidata = cgi_request(); cgidata_t *cwalk; char *rq_critwkdays = NULL; char *rq_critslastart = NULL; char *rq_critslaend = NULL; int rq_startday = 0; int rq_startmon = 0; int rq_startyear = 0; int rq_endday = 0; int rq_endmon = 0; int rq_endyear = 0; cwalk = cgidata; while (cwalk) { if (strcasecmp(cwalk->name, "Find") == 0) { editaction = CRITEDIT_FIND; } else if (strcasecmp(cwalk->name, "Next") == 0) { editaction = CRITEDIT_NEXT; } else if (strcasecmp(cwalk->name, "Update") == 0) { editaction = CRITEDIT_UPDATE; } else if (strcasecmp(cwalk->name, "Drop") == 0) { editaction = CRITEDIT_DELETE; } else if (strcasecmp(cwalk->name, "Clone") == 0) { /* The "clone" button does both things */ editaction = CRITEDIT_ADDCLONE; } else if (strcasecmp(cwalk->name, "HOSTNAME") == 0) { if (*cwalk->value) rq_hostname = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "SERVICE") == 0) { if (*cwalk->value) rq_service = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "PRIORITY") == 0) { rq_priority = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "GROUP") == 0) { if (*cwalk->value) rq_group = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CRITWKDAYS") == 0) { if (*cwalk->value) { if (!rq_critwkdays) rq_critwkdays = strdup(cwalk->value); else { rq_critwkdays = (char *)realloc(rq_critwkdays, strlen(rq_critwkdays) + strlen(cwalk->value) + 1); strcat(rq_critwkdays, cwalk->value); } } } else if (strcasecmp(cwalk->name, "CRITSTARTHOUR") == 0) { if (*cwalk->value) rq_critslastart = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CRITENDHOUR") == 0) { if (*cwalk->value) rq_critslaend = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "start-day") == 0) { rq_startday = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "start-mon") == 0) { rq_startmon = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "start-yr") == 0) { rq_startyear = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "end-day") == 0) { rq_endday = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "end-mon") == 0) { rq_endmon = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "end-yr") == 0) { rq_endyear = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "EXTRA") == 0) { if (*cwalk->value) rq_extra = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "DROPEVENIFCLONED") == 0) { rq_dropevenifcloned = 1; } else if (strcasecmp(cwalk->name, "CRITEDITADDCLONES") == 0) { if (*cwalk->value) rq_clonestoadd = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CRITEDITCLONELIST") == 0) { if (rq_clonestodrop) { rq_clonestodrop = (char *)realloc(rq_clonestodrop, strlen(rq_clonestodrop) + strlen(cwalk->value) + 2); strcat(rq_clonestodrop, " "); strcat(rq_clonestodrop, cwalk->value); } else { if (*cwalk->value) rq_clonestodrop = strdup(cwalk->value); } } cwalk = cwalk->next; } if (editaction == CRITEDIT_UPDATE) { struct tm tm; if ((rq_startday == 0) || (rq_startmon == 0) || (rq_startyear == 0)) rq_start = -1; else { memset(&tm, 0, sizeof(tm)); tm.tm_mday = rq_startday; tm.tm_mon = rq_startmon - 1; tm.tm_year = rq_startyear - 1900; tm.tm_isdst = -1; rq_start = mktime(&tm); } if ((rq_endday == 0) || (rq_endmon == 0) || (rq_endyear == 0)) rq_end = -1; else { memset(&tm, 0, sizeof(tm)); tm.tm_mday = rq_endday; tm.tm_mon = rq_endmon - 1; tm.tm_year = rq_endyear - 1900; tm.tm_isdst = -1; rq_end = mktime(&tm); } SBUF_MALLOC(rq_crittime,strlen(rq_critwkdays) + strlen(rq_critslastart) + strlen(rq_critslaend) + 3); snprintf(rq_crittime, rq_crittime_buflen, "%s:%s:%s", rq_critwkdays, rq_critslastart, rq_critslaend); } else if (editaction == CRITEDIT_ADDCLONE) { if (!rq_clonestoadd && rq_clonestodrop) editaction = CRITEDIT_DROPCLONE; } } void findrecord(char *hostname, char *service, char *nodatawarning, char *isclonewarning, char *hascloneswarning) { critconf_t *rec = NULL; int isaclone = 0; int hasclones = 0; char warnmsg[4096]; /* Setup the list of cloned records */ sethostenv_critclonelist_clear(); if (hostname && *hostname) { SBUF_DEFINE(key); char *realkey, *clonekey; critconf_t *clonerec; if (service && *service) { /* First check if the host+service is really a clone of something else */ SBUF_MALLOC(key, strlen(hostname) + strlen(service) + 2); snprintf(key, key_buflen, "%s|%s", hostname, service); rec = get_critconfig(key, CRITCONF_FIRSTMATCH, &realkey); } else { key = strdup(hostname); rec = get_critconfig(key, CRITCONF_FIRSTHOSTMATCH, &realkey); } if (rec && realkey && (strcmp(key, realkey) != 0)) { char *p; xfree(key); key = strdup(realkey); hostname = realkey; p = strchr(realkey, '|'); if (p) { *p = '\0'; service = p+1; } isaclone = 1; } xfree(key); /* Next, see what hosts are clones of this one */ clonerec = get_critconfig(NULL, CRITCONF_RAW_FIRST, &clonekey); while (clonerec) { if ((*(clonekey + strlen(clonekey) -1) == '=') && (strcmp(hostname, (char *)clonerec) == 0)) { sethostenv_critclonelist_add(clonekey); hasclones = 1; } clonerec = get_critconfig(NULL, CRITCONF_RAW_NEXT, &clonekey); } } else { hostname = ""; } if (!service || !(*service)) service=""; if (rec) sethostenv_critedit(rec->updinfo, rec->priority, rec->ttgroup, rec->starttime, rec->endtime, rec->crittime, rec->ttextra); else sethostenv_critedit("", 0, NULL, 0, 0, NULL, NULL); sethostenv(hostname, "", service, colorname(COL_BLUE), NULL); *warnmsg = '\0'; if (!rec && nodatawarning) snprintf(warnmsg, sizeof(warnmsg), "%s", nodatawarning); if (isaclone && isclonewarning) snprintf(warnmsg, sizeof(warnmsg), "%s", isclonewarning); if (hasclones && hascloneswarning) snprintf(warnmsg, sizeof(warnmsg), "%s", hascloneswarning); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "critedit", "critedit_form", COL_BLUE, getcurrenttime(NULL), warnmsg, NULL); } void nextrecord(char *hostname, char *service, char *isclonewarning, char *hascloneswarning) { critconf_t *rec; char *nexthost, *nextservice; /* First check if the host+service is really a clone of something else */ if (hostname && service) { SBUF_DEFINE(key); SBUF_MALLOC(key, strlen(hostname) + strlen(service) + 2); snprintf(key, key_buflen, "%s|%s", hostname, service); rec = get_critconfig(key, CRITCONF_FIRSTMATCH, NULL); if (rec) rec = get_critconfig(NULL, CRITCONF_NEXT, NULL); xfree(key); } else { rec = get_critconfig(NULL, CRITCONF_FIRST, NULL); } if (rec) { nexthost = strdup(rec->key); nextservice = strchr(nexthost, '|'); if (nextservice) { *nextservice = '\0'; nextservice++; } } else { nexthost = strdup(""); nextservice = ""; } findrecord(nexthost, nextservice, NULL, isclonewarning, hascloneswarning); xfree(nexthost); } void updaterecord(char *hostname, char *service) { critconf_t *rec = NULL; if (hostname && service) { SBUF_DEFINE(key); char *realkey; char datestr[20]; time_t now = getcurrenttime(NULL); size_t upd_buflen; SBUF_MALLOC(key, strlen(hostname) + strlen(service) + 2); strftime(datestr, sizeof(datestr), "%Y-%m-%d %H:%M:%S", localtime(&now)); snprintf(key, key_buflen, "%s|%s", hostname, service); rec = get_critconfig(key, CRITCONF_FIRSTMATCH, &realkey); if (rec == NULL) { rec = (critconf_t *)calloc(1, sizeof(critconf_t)); rec->key = strdup(key); } rec->priority = rq_priority; rec->starttime = (rq_start > 0) ? rq_start : 0; rec->endtime = (rq_end > 0) ? rq_end : 0; if (rec->crittime) { xfree(rec->crittime); rec->crittime = NULL; } if (rq_crittime) { rec->crittime = (strcmp(rq_crittime, "*:0000:2400") == 0) ? NULL : strdup(rq_crittime); } if (rec->ttgroup) xfree(rec->ttgroup); rec->ttgroup = (rq_group ? strdup(rq_group) : NULL); if (rec->ttextra) xfree(rec->ttextra); rec->ttextra = (rq_extra ? strdup(rq_extra) : NULL); if (rec->updinfo) xfree(rec->updinfo); upd_buflen = strlen(operator) + strlen(datestr) + 2; rec->updinfo = (char *)malloc(upd_buflen); snprintf(rec->updinfo, upd_buflen, "%s %s", operator, datestr); update_critconfig(rec); xfree(key); } findrecord(hostname, service, NULL, NULL, NULL); } void addclone(char *origin, char *newhosts, char *service) { char *newclone; newclone = strtok(newhosts, " "); while (newclone) { addclone_critconfig(origin, newclone); newclone = strtok(NULL, " "); } update_critconfig(NULL); findrecord(origin, service, NULL, NULL, NULL); } void dropclone(char *origin, char *drops, char *service) { char *drop; drop = strtok(drops, " "); while (drop) { dropclone_critconfig(drop); drop = strtok(NULL, " "); } update_critconfig(NULL); findrecord(origin, service, NULL, NULL, NULL); } void deleterecord(char *hostname, char *service, int evenifcloned) { SBUF_DEFINE(key); SBUF_MALLOC(key, strlen(hostname) + strlen(service) + 2); snprintf(key, key_buflen, "%s|%s", hostname, service); if (delete_critconfig(key, evenifcloned) == 0) { update_critconfig(NULL); } findrecord(hostname, service, NULL, NULL, (evenifcloned ? "Warning: Orphans will be ignored" : "Will not delete record that is cloned")); } int main(int argc, char *argv[]) { int argi; char *envarea = NULL; char *configfn = NULL; operator = getenv("REMOTE_USER"); if (!operator) operator = "Anonymous"; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (argnmatch(argv[argi], "--config=")) { char *p = strchr(argv[argi], '='); configfn = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } } redirect_cgilog("criticaleditor"); /* We only want to accept posts from certain pages */ if (cgi_ispost()) { char cgisource[1024]; char *p; p = csp_header("criticaleditor"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "criticaleditor"); if (!cgi_refererok(cgisource)) { fprintf(stdout, "Location: %s.sh?\n\n", cgisource); return 0; } } parse_query(); load_critconfig(configfn); switch (editaction) { case CRITEDIT_FIND: findrecord(rq_hostname, rq_service, ((rq_hostname && rq_service) ? "No record for this host/service" : NULL), "Cloned - showing master record", NULL); break; case CRITEDIT_NEXT: nextrecord(rq_hostname, rq_service, "Cloned - showing master record", NULL); break; case CRITEDIT_UPDATE: updaterecord(rq_hostname, rq_service); break; case CRITEDIT_DELETE: deleterecord(rq_hostname, rq_service, rq_dropevenifcloned); break; case CRITEDIT_ADDCLONE: addclone(rq_hostname, rq_clonestoadd, rq_service); break; case CRITEDIT_DROPCLONE: dropclone(rq_hostname, rq_clonestodrop, rq_service); break; } return 0; } xymon-4.3.30/web/acknowledgements.c0000664000076400007640000001041212503132277017456 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon acknowledgements log viewer */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: acknowledgements.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" int maxcount = 100; /* Default: Include last 100 events */ int maxminutes = 1440; /* Default: for the past 24 hours */ char *totime = NULL; char *fromtime = NULL; char *pageregex = NULL; char *expageregex = NULL; char *hostregex = NULL; char *exhostregex = NULL; char *testregex = NULL; char *extestregex = NULL; char *rcptregex = NULL; char *exrcptregex = NULL; cgidata_t *cgidata = NULL; static void parse_query(void) { cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "MAXCOUNT") == 0) { maxcount = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "MAXTIME") == 0) { maxminutes = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "FROMTIME") == 0) { if (*(cwalk->value)) fromtime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "TOTIME") == 0) { if (*(cwalk->value)) totime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "HOSTMATCH") == 0) { if (*(cwalk->value)) hostregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXHOSTMATCH") == 0) { if (*(cwalk->value)) exhostregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "TESTMATCH") == 0) { if (*(cwalk->value)) testregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXTESTMATCH") == 0) { if (*(cwalk->value)) extestregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "PAGEMATCH") == 0) { if (*(cwalk->value)) pageregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXPAGEMATCH") == 0) { if (*(cwalk->value)) expageregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "RCPTMATCH") == 0) { if (*(cwalk->value)) rcptregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXRCPTMATCH") == 0) { if (*(cwalk->value)) exrcptregex = strdup(cwalk->value); } cwalk = cwalk->next; } } int main(int argc, char *argv[]) { int argi; char *envarea = NULL; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } } redirect_cgilog("acknowledgements"); load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); cgidata = cgi_request(); if (cgidata == NULL) { /* Present the query form */ sethostenv("", "", "", colorname(COL_BLUE), NULL); showform(stdout, "acknowledgements", "acknowledgements_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } parse_query(); /* Now generate the webpage */ headfoot(stdout, "acknowledgements", "", "header", COL_GREEN); fprintf(stdout, "
\n"); do_acknowledgementslog(stdout, maxcount, maxminutes, fromtime, totime, pageregex, expageregex, hostregex, exhostregex, testregex, extestregex, rcptregex, exrcptregex); fprintf(stdout, "
\n"); headfoot(stdout, "acknowledgements", "", "footer", COL_GREEN); return 0; } xymon-4.3.30/web/svcstatus-info.h0000664000076400007640000000165311615341300017120 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __SVCSTATUS_INFO_H__ #define __SVCSTATUS_INFO_H__ extern int showenadis; extern int usejsvalidation; extern int newcritconfig; extern char *generate_info(char *hostname, char *critconfigfn); #endif xymon-4.3.30/web/critical.cfg.50000664000076400007640000000171513534041733016405 0ustar rpmbuildrpmbuild.TH CRITICAL.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME critical.cfg \- Configuration of the showgraph CGI .SH SYNOPSIS .B $XYMONHOME/etc/critical.cfg .SH DESCRIPTION .I critical.cgi(1) uses the configuration file $XYMONHOME/etc/critical.cfg to determine which of the statuses currently in a red or yellow state should appear on the Critical Systems view. This file should not be edited manually. It is maintained by the .I criticaleditor.cgi(1) utility via a web-based frontend. .SH FILE PERMISSIONS Since the file is maintained by a web front-end tool, the userid running Web CGI scripts must have write-permission to the file. Typically, this means it must have a group-ownership matching your webserver userid, and group-write permissions (mode 664). When editing the file with the web front-end, a backup file is created. Therefore the critical.cfg.bak file should have identical permissions. .SH "SEE ALSO" criticalview.cgi(1), criticaleditor.cgi(1) xymon-4.3.30/web/eventlog.c0000664000076400007640000003375711615341300015760 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon eventlog generator tool. */ /* */ /* This displays the "eventlog" found on the "All non-green status" page. */ /* It also implements a CGI tool to show an eventlog for a given period of */ /* time, as a reporting function. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* Host/test/color/start/end filtering code by Eric Schwimmer 2005 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: eventlog.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" int maxcount = 100; /* Default: Include last 100 events */ int maxminutes = 240; /* Default: for the past 4 hours */ char *totime = NULL; char *fromtime = NULL; char *hostregex = NULL; char *exhostregex = NULL; char *testregex = NULL; char *extestregex = NULL; char *pageregex = NULL; char *expageregex = NULL; char *colorregex = NULL; int ignoredialups = 0; int topcount = 0; eventsummary_t summarybar = XYMON_S_NONE; countsummary_t counttype = XYMON_COUNT_NONE; char *webfile_hf = "event"; char *webfile_form = "event_form"; cgidata_t *cgidata = NULL; char *periodstring = NULL; static void parse_query(void) { cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "MAXCOUNT") == 0) { maxcount = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "MAXTIME") == 0) { maxminutes = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "FROMTIME") == 0) { if (*(cwalk->value)) fromtime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "TOTIME") == 0) { if (*(cwalk->value)) totime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "HOSTMATCH") == 0) { if (*(cwalk->value)) hostregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXHOSTMATCH") == 0) { if (*(cwalk->value)) exhostregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "TESTMATCH") == 0) { if (*(cwalk->value)) testregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXTESTMATCH") == 0) { if (*(cwalk->value)) extestregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "PAGEMATCH") == 0) { if (*(cwalk->value)) pageregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXPAGEMATCH") == 0) { if (*(cwalk->value)) expageregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "COLORMATCH") == 0) { if (*(cwalk->value)) colorregex = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "NODIALUPS") == 0) { ignoredialups = 1; } else if (strcasecmp(cwalk->name, "TOP") == 0) { if (*(cwalk->value)) topcount = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "SUMMARY") == 0) { if (strcasecmp(cwalk->value, "hosts") == 0) summarybar = XYMON_S_HOST_BREAKDOWN; else if (strcasecmp(cwalk->value, "services") == 0) summarybar = XYMON_S_SERVICE_BREAKDOWN; else summarybar = XYMON_S_NONE; } else if (strcasecmp(cwalk->name, "COUNTTYPE") == 0) { if (strcasecmp(cwalk->value, "events") == 0) counttype = XYMON_COUNT_EVENTS; else if (strcasecmp(cwalk->value, "duration") == 0) counttype = XYMON_COUNT_DURATION; else counttype = XYMON_COUNT_NONE; } else if (strcasecmp(cwalk->name, "TIMETXT") == 0) { if (*(cwalk->value)) periodstring = strdup(cwalk->value); } cwalk = cwalk->next; } } void show_topchanges(FILE *output, countlist_t *hostcounthead, countlist_t *svccounthead, event_t *eventhead, int topcount, time_t firstevent, time_t lastevent) { fprintf(output, "

%s

\n", (periodstring ? periodstring : "")); fprintf(output, "\n"); fprintf(output, "\n"); if (hostcounthead && (output != NULL)) { countlist_t *cwalk; int i; unsigned long others = 0, totalcount = 0; strbuffer_t *s = newstrbuffer(0); strbuffer_t *othercriteria = newstrbuffer(0); if (hostregex) { addtobuffer(othercriteria, "&HOSTMATCH="); addtobuffer(othercriteria, hostregex); } if (exhostregex) addtobuffer(s, exhostregex); if (testregex) { addtobuffer(othercriteria, "&TESTMATCH="); addtobuffer(othercriteria, testregex); } if (extestregex) { addtobuffer(othercriteria, "&EXTESTMATCH="); addtobuffer(othercriteria, extestregex); } if (pageregex) { addtobuffer(othercriteria, "&PAGEMATCH="); addtobuffer(othercriteria, pageregex); } if (expageregex) { addtobuffer(othercriteria, "&EXPAGEMATCH="); addtobuffer(othercriteria, expageregex); } if (colorregex) { addtobuffer(othercriteria, "&COLORMATCH="); addtobuffer(othercriteria, colorregex); } if (ignoredialups) { addtobuffer(othercriteria, "&NODIALUPS=on"); } addtobuffer(othercriteria, "&SUMMARY=services"); addtobuffer(othercriteria, "&TIMETXT="); addtobuffer(othercriteria, periodstring); if (counttype == XYMON_COUNT_EVENTS) addtobuffer(othercriteria, "&COUNTTYPE=events"); else if (counttype == XYMON_COUNT_DURATION) addtobuffer(othercriteria, "&COUNTTYPE=duration"); fprintf(output, "\n"); freestrbuffer(s); freestrbuffer(othercriteria); } if (svccounthead && (output != NULL)) { countlist_t *cwalk; int i; unsigned long others = 0, totalcount = 0; strbuffer_t *s = newstrbuffer(0); strbuffer_t *othercriteria = newstrbuffer(0); if (hostregex) { addtobuffer(othercriteria, "&HOSTMATCH="); addtobuffer(othercriteria, hostregex); } if (exhostregex) { addtobuffer(othercriteria, "&EXHOSTMATCH="); addtobuffer(othercriteria, exhostregex); } if (testregex) { addtobuffer(othercriteria, "&TESTMATCH="); addtobuffer(othercriteria, testregex); } if (extestregex) addtobuffer(s, extestregex); if (pageregex) { addtobuffer(othercriteria, "&PAGEMATCH="); addtobuffer(othercriteria, pageregex); } if (expageregex) { addtobuffer(othercriteria, "&EXPAGEMATCH="); addtobuffer(othercriteria, expageregex); } if (colorregex) { addtobuffer(othercriteria, "&COLORMATCH="); addtobuffer(othercriteria, colorregex); } if (ignoredialups) { addtobuffer(othercriteria, "&NODIALUPS=on"); } addtobuffer(othercriteria, "&SUMMARY=hosts"); addtobuffer(othercriteria, "&TIMETXT="); addtobuffer(othercriteria, periodstring); if (counttype == XYMON_COUNT_EVENTS) addtobuffer(othercriteria, "&COUNTTYPE=events"); else if (counttype == XYMON_COUNT_DURATION) addtobuffer(othercriteria, "&COUNTTYPE=duration"); fprintf(output, "\n"); freestrbuffer(s); freestrbuffer(othercriteria); } fprintf(output, "\n"); fprintf(output, "
\n"); fprintf(output, " \n", topcount); fprintf(output, " \n", topcount); fprintf(output, " \n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); /* Compute the total count */ for (i=0, cwalk=hostcounthead; (cwalk); i++, cwalk=cwalk->next) totalcount += cwalk->total; for (i=0, cwalk=hostcounthead; (cwalk && (cwalk->total > 0)); i++, cwalk=cwalk->next) { if (i < topcount) { fprintf(output, " \n", xmh_item(cwalk->src, XMH_HOSTNAME), (unsigned long)firstevent, (unsigned long)lastevent, STRBUF(othercriteria), xmh_item(cwalk->src, XMH_HOSTNAME), cwalk->total, ((100.0 * cwalk->total) / totalcount)); if (STRBUFLEN(s) > 0) addtobuffer(s, "|"); addtobuffer(s, "^"); addtobuffer(s, xmh_item(cwalk->src, XMH_HOSTNAME)); addtobuffer(s, "$"); } else { others += cwalk->total; } } fprintf(output, " \n", STRBUF(s), (unsigned long)firstevent, (unsigned long)lastevent, STRBUF(othercriteria), "Other hosts", others, ((100.0 * others) / totalcount)); fprintf(output, " \n"); fprintf(output, " \n", totalcount); fprintf(output, "
Top %d hosts
Host%s
%s%lu(%6.2f %%)
%s%lu(%6.2f %%)

Total%lu 
\n"); fprintf(output, "
\n"); fprintf(output, " \n", topcount); fprintf(output, " \n", topcount); fprintf(output, " \n", (counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow"); /* Compute the total count */ for (i=0, cwalk=svccounthead; (cwalk); i++, cwalk=cwalk->next) totalcount += cwalk->total; for (i=0, cwalk=svccounthead; (cwalk && (cwalk->total > 0)); i++, cwalk=cwalk->next) { if (i < topcount) { fprintf(output, " \n", ((htnames_t *)cwalk->src)->name, (unsigned long)firstevent, (unsigned long)lastevent, STRBUF(othercriteria), ((htnames_t *)cwalk->src)->name, cwalk->total, ((100.0 * cwalk->total) / totalcount)); if (STRBUFLEN(s) > 0) addtobuffer(s, "|"); addtobuffer(s, "^"); addtobuffer(s, ((htnames_t *)cwalk->src)->name); addtobuffer(s, "$"); } else { others += cwalk->total; } } fprintf(output, " \n", STRBUF(s), (unsigned long)firstevent, (unsigned long)lastevent, STRBUF(othercriteria), "Other services", others, ((100.0 * others) / totalcount)); fprintf(output, " \n"); fprintf(output, " \n", totalcount); fprintf(output, "
Top %d services
Service%s
%s%lu(%6.2f %%)
%s%lu(%6.2f %%)

Total%lu 
\n"); fprintf(output, "
\n"); } int main(int argc, char *argv[]) { int argi; char *envarea = NULL; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (argnmatch(argv[argi], "--top")) { topcount = 10; webfile_hf = "topchanges"; webfile_form = "topchanges_form"; maxminutes = -1; maxcount = -1; } else if (strcmp(argv[argi], "--debug=")) { debug = 1; } } redirect_cgilog("eventlog"); load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); cgidata = cgi_request(); if (cgidata == NULL) { /* Present the query form */ sethostenv("", "", "", colorname(COL_BLUE), NULL); showform(stdout, webfile_hf, webfile_form, COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } parse_query(); if (periodstring && (fromtime || totime)) { strbuffer_t *pstr = newstrbuffer(1024); if (fromtime && totime) { addtobuffer(pstr, "Events between "); addtobuffer(pstr, htmlquoted(fromtime)); addtobuffer(pstr, "- "); addtobuffer(pstr, htmlquoted(totime)); } else if (fromtime) { addtobuffer(pstr, "Events since "); addtobuffer(pstr, htmlquoted(fromtime)); } else if (totime) { addtobuffer(pstr, "Events until "); addtobuffer(pstr, htmlquoted(totime)); } xfree(periodstring); periodstring = grabstrbuffer(pstr); } /* Now generate the webpage */ headfoot(stdout, webfile_hf, "", "header", COL_GREEN); fprintf(stdout, "
\n"); if (topcount == 0) { do_eventlog(stdout, maxcount, maxminutes, fromtime, totime, pageregex, expageregex, hostregex, exhostregex, testregex, extestregex, colorregex, ignoredialups, NULL, NULL, NULL, NULL, counttype, summarybar, periodstring); } else { countlist_t *hcounts, *scounts; event_t *events; time_t firstevent, lastevent; do_eventlog(NULL, -1, -1, fromtime, totime, pageregex, expageregex, hostregex, exhostregex, testregex, extestregex, colorregex, ignoredialups, NULL, &events, &hcounts, &scounts, counttype, XYMON_S_NONE, NULL); lastevent = (totime ? eventreport_time(totime) : getcurrenttime(NULL)); if (fromtime) { firstevent = eventreport_time(fromtime); } else if (events) { event_t *ewalk; ewalk = events; while (ewalk->next) ewalk = ewalk->next; firstevent = ewalk->eventtime; } else firstevent = 0; show_topchanges(stdout, hcounts, scounts, events, topcount, firstevent, lastevent); } fprintf(stdout, "
\n"); headfoot(stdout, webfile_hf, "", "footer", COL_GREEN); return 0; } xymon-4.3.30/web/xymonpage.c0000664000076400007640000000443711615341300016135 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* This is a generic webpage generator, that allows scripts to output a */ /* standard Xymon-like webpage without having to deal with headers and */ /* footers. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonpage.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include "libxymon.h" #include "version.h" char *reqenv[] = { "XYMONHOME", NULL }; int main(int argc, char *argv[]) { int argi; char *hffile = "stdnormal"; int bgcolor = COL_BLUE; char inbuf[8192]; int n; char *envarea = NULL; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--hffile=")) { char *p = strchr(argv[argi], '='); hffile = strdup(p+1); } else if (argnmatch(argv[argi], "--color=")) { char *p = strchr(argv[argi], '='); bgcolor = parse_color(p+1); } } envcheck(reqenv); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); headfoot(stdout, hffile, "", "header", bgcolor); do { n = fread(inbuf, 1, sizeof(inbuf), stdin); if (n > 0) fwrite(inbuf, 1, n, stdout); } while (n == sizeof(inbuf)); headfoot(stdout, hffile, "", "footer", bgcolor); return 0; } xymon-4.3.30/web/criticaleditor.cgi.10000664000076400007640000000240213534041733017605 0ustar rpmbuildrpmbuild.TH CRITICALEDITOR.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME criticaleditor.cgi \- Xymon Critical Systems View Editor CGI .SH SYNOPSIS .B "criticaleditor.cgi" .SH DESCRIPTION \fBcriticaleditor.cgi\fR is invoked as a CGI script via the criticaleditor.sh CGI wrapper. criticaleditor.cgi is a web-based editor for the .I critical.cfg(5) file, which is used to configure the Xymon "Critical Systems" view. A detailed description of how to use the editor is provided in the Xymon Web documentation, available from the "Help" \-> "Critical Systems" link on the Xymon website. .SH SECURITY Access to this CGI script should be restricted through access controls in your webserver. Editing the Critical Systems View configuration will impact the monitoring of your site. .SH OPTIONS .IP "\-\-config=FILENAME" Name of the Critical Systems View configuration file. The default is critical.cfg in the $XYMONHOME/etc/ directory. .IP "\-\-env=FILENAME" Loads the environment defined in FILENAME before executing the CGI script. .IP "\-\-area=NAME" Load environment variables for a specific area. NB: if used, this option must appear before any \-\-env=FILENAME option. .IP "\-\-debug" Enables debugging output. .SH "SEE ALSO" criticalview.cgi(1), critical.cfg(5), xymon(7) xymon-4.3.30/web/svcstatus.c0000664000076400007640000005654613515623702016207 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon status-log viewer CGI. */ /* */ /* This CGI tool shows an HTML version of a status log. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: svcstatus.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "version.h" #include "svcstatus-info.h" #include "svcstatus-trends.h" /* Command-line params */ static enum { SRC_XYMOND, SRC_HISTLOGS, SRC_CLIENTLOGS } source = SRC_XYMOND; static int wantserviceid = 1; SBUF_DEFINE(multigraphs); static int locatorbased = 0; static char *critconfigfn = NULL; static char *accessfn = NULL; /* CGI params */ static char *hostname = NULL; static char *service = NULL; static char *tstamp = NULL; static char *nkprio = NULL, *nkttgroup = NULL, *nkttextra = NULL; static enum { FRM_STATUS, FRM_CLIENT } outform = FRM_STATUS; STATIC_SBUF_DEFINE(clienturi); static int backsecs = 0; static time_t fromtime = 0, endtime = 0; static char errortxt[1000]; STATIC_SBUF_DEFINE(hostdatadir); static void errormsg(int status, char *msg) { snprintf(errortxt, sizeof(errortxt), "Status: %d\nRefresh: 30\nContent-type: %s\n\nInvalid request\n%s\n", status, xgetenv("HTMLCONTENTTYPE"), msg); errortxt[sizeof(errortxt)-1] = '\0'; } static int parse_query(void) { cgidata_t *cgidata = cgi_request(); cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { if (strcasecmp(cwalk->name, "HOST") == 0) { hostname = strdup(basename(cwalk->value)); } else if (strcasecmp(cwalk->name, "SERVICE") == 0) { service = strdup(basename(cwalk->value)); } else if (strcasecmp(cwalk->name, "HOSTSVC") == 0) { /* For backwards compatibility */ char *p = strrchr(cwalk->value, '.'); if (p) { *p = '\0'; hostname = strdup(basename(cwalk->value)); service = strdup(p+1); for (p=strchr(hostname, ','); (p); p = strchr(p, ',')) *p = '.'; } } else if (strcasecmp(cwalk->name, "TIMEBUF") == 0) { /* Only for the historical logs */ tstamp = strdup(basename(cwalk->value)); } else if (strcasecmp(cwalk->name, "CLIENT") == 0) { char *p; hostname = strdup(cwalk->value); p = hostname; while ((p = strchr(p, ',')) != NULL) *p = '.'; service = strdup(""); outform = FRM_CLIENT; } else if (strcasecmp(cwalk->name, "SECTION") == 0) { service = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "NKPRIO") == 0) { nkprio = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "NKTTGROUP") == 0) { nkttgroup = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "NKTTEXTRA") == 0) { nkttextra = strdup(cwalk->value); } else if ((strcmp(cwalk->name, "backsecs") == 0) && cwalk->value && strlen(cwalk->value)) { backsecs += atoi(cwalk->value); } else if ((strcmp(cwalk->name, "backmins") == 0) && cwalk->value && strlen(cwalk->value)) { backsecs += 60*atoi(cwalk->value); } else if ((strcmp(cwalk->name, "backhours") == 0) && cwalk->value && strlen(cwalk->value)) { backsecs += 60*60*atoi(cwalk->value); } else if ((strcmp(cwalk->name, "backdays") == 0) && cwalk->value && strlen(cwalk->value)) { backsecs += 24*60*60*atoi(cwalk->value); } else if ((strcmp(cwalk->name, "FROMTIME") == 0) && cwalk->value && strlen(cwalk->value)) { fromtime = eventreport_time(cwalk->value); } else if ((strcmp(cwalk->name, "TOTIME") == 0) && cwalk->value && strlen(cwalk->value)) { endtime = eventreport_time(cwalk->value); } cwalk = cwalk->next; } if (backsecs == 0) { if (getenv("TRENDSECONDS")) backsecs = atoi(getenv("TRENDSECONDS")); else backsecs = 48*60*60; } if (!hostname || !service || ((source == SRC_HISTLOGS) && !tstamp) ) { errormsg(403, "Invalid request"); return 1; } if (strcmp(service, xgetenv("CLIENTCOLUMN")) == 0) { /* Make this a client request */ char *p = strdup(basename(hostname)); xfree(hostname); hostname = p; /* no need to convert to dots, since we'll already have them */ xfree(service); /* service does double-duty as the 'section' param */ outform = FRM_CLIENT; } if (outform == FRM_STATUS) { char *p, *req; char *hostquoted = htmlquoted(hostname); req = getenv("SCRIPT_NAME"); SBUF_MALLOC(clienturi, strlen(req) + 10 + strlen(hostquoted)); strncpy(clienturi, req, clienturi_buflen); p = strchr(clienturi, '?'); if (p) *p = '\0'; else p = clienturi + strlen(clienturi); snprintf(p, (clienturi_buflen - (clienturi - p)), "?CLIENT=%s", hostquoted); } return 0; } int loadhostdata(char *hostname, char **ip, char **displayname, char **compacts, int full) { void *hinfo = NULL; int loadres; if (full) { loadres = load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); } else { loadres = load_hostinfo(hostname); } if ((loadres != 0) && (loadres != -2)) { errormsg(500, "Cannot load host configuration"); return 1; } if ((loadres == -2) || (hinfo = hostinfo(hostname)) == NULL) { errormsg(403, "No such host"); return 1; } *ip = xmh_item(hinfo, XMH_IP); *displayname = xmh_item(hinfo, XMH_DISPLAYNAME); if (!(*displayname)) *displayname = hostname; *compacts = xmh_item(hinfo, XMH_COMPACT); return 0; } int do_request(void) { int color = 0, flapping = 0; char timesincechange[100]; time_t logtime = 0, acktime = 0, disabletime = 0; SBUF_DEFINE(firstline); char *log = NULL, *sender = NULL, *clientid = NULL, *flags = NULL; /* These are free'd */ char *restofmsg = NULL, *ackmsg = NULL, *dismsg = NULL, *acklist=NULL, *modifiers = NULL; /* These are just used */ int ishtmlformatted = 0; int clientavail = 0; char *ip = NULL, *displayname = NULL, *compacts; if (parse_query() != 0) return 1; { char *p = NULL; if (!service || !strlen(service)) p = csp_header("svcstatus"); else { if (strcasecmp(service, xgetenv("INFOCOLUMN")) == 0) p = csp_header("svcstatus-info"); else if (strcasecmp(service, xgetenv("TRENDSCOLUMN")) == 0) p = csp_header("svcstatus-trends"); else { int d = atoi(xgetenv("XYMWEBREFRESH")); fprintf(stdout, "Refresh: %d\n", ((d > 0) ? d : 60) ); p = csp_header("svcstatus"); } } if (p) fprintf(stdout, "%s", p); } /* Load the host data (for access control) */ if (accessfn) { load_hostinfo(hostname); load_web_access_config(accessfn); if (!web_access_allowed(getenv("REMOTE_USER"), hostname, service, WEB_ACCESS_VIEW)) { errormsg(403, "Not available (restricted)."); return 1; } } { char *s; s = xgetenv("CLIENTLOGS"); if (s) { SBUF_MALLOC(hostdatadir, strlen(s) + strlen(hostname) + 12); snprintf(hostdatadir, hostdatadir_buflen, "%s/%s", s, hostname); } else { s = xgetenv("XYMONVAR"); SBUF_MALLOC(hostdatadir, strlen(s) + strlen(hostname) + 12); snprintf(hostdatadir, hostdatadir_buflen, "%s/hostdata/%s", s, hostname); } } if (outform == FRM_CLIENT) { if (source == SRC_XYMOND) { SBUF_DEFINE(xymondreq); int xymondresult; sendreturn_t *sres = newsendreturnbuf(1, NULL); SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + (service ? strlen(service) : 0)); snprintf(xymondreq, xymondreq_buflen, "clientlog %s", hostname); if (service && *service) snprintf(xymondreq + strlen(xymondreq), (xymondreq_buflen - strlen(xymondreq)), " section=%s", service); xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres); if (xymondresult != XYMONSEND_OK) { SBUF_DEFINE(errtxt); SBUF_MALLOC(errtxt, 1024 + MAX_HTMLQUOTE_FACTOR*strlen(xymondreq)); snprintf(errtxt, errtxt_buflen, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult); errormsg(500, errtxt); return 1; } else { log = getsendreturnstr(sres, 1); } freesendreturnbuf(sres); } else if (source == SRC_HISTLOGS) { char logfn[PATH_MAX]; FILE *fd; snprintf(logfn, sizeof(logfn), "%s/%s", hostdatadir, tstamp); fd = fopen(logfn, "r"); if (fd) { struct stat st; int n; fstat(fileno(fd), &st); if (S_ISREG(st.st_mode)) { log = (char *)malloc(st.st_size + 1); n = fread(log, 1, st.st_size, fd); if (n >= 0) *(log+n) = '\0'; else *log = '\0'; } fclose(fd); } } restofmsg = (log ? log : strdup("\n")); } else if ((strcmp(service, xgetenv("TRENDSCOLUMN")) == 0) || (strcmp(service, xgetenv("INFOCOLUMN")) == 0)) { int fullload = (strcmp(service, xgetenv("INFOCOLUMN")) == 0); if (loadhostdata(hostname, &ip, &displayname, &compacts, fullload) != 0) return 1; ishtmlformatted = 1; sethostenv(displayname, ip, service, colorname(COL_GREEN), hostname); sethostenv_refresh(600); color = COL_GREEN; logtime = getcurrenttime(NULL); strncpy(timesincechange, "0 minutes", sizeof(timesincechange)); if (strcmp(service, xgetenv("TRENDSCOLUMN")) == 0) { if (locatorbased) { char *cgiurl, *qres; qres = locator_query(hostname, ST_RRD, &cgiurl); if (!qres) { errprintf("Cannot find RRD files for host %s\n", hostname); } else { /* Redirect browser to the real server */ fprintf(stdout, "Location: %s/svcstatus.sh?HOST=%s&SERVICE=%s\n\n", cgiurl, hostname, service); return 0; } } else { if (endtime == 0) endtime = getcurrenttime(NULL); if (fromtime == 0) { fromtime = endtime - backsecs; sethostenv_backsecs(backsecs); } else { sethostenv_eventtime(fromtime, endtime); } log = restofmsg = generate_trends(hostname, fromtime, endtime); } } else if (strcmp(service, xgetenv("INFOCOLUMN")) == 0) { log = restofmsg = generate_info(hostname, critconfigfn); } } else if (source == SRC_XYMOND) { SBUF_DEFINE(xymondreq); int xymondresult; char *items[25]; int icount; time_t logage, clntstamp; char *sumline, *msg, *compitem, *complist; sendreturn_t *sres; if (loadhostdata(hostname, &ip, &displayname, &compacts, 0) != 0) return 1; complist = NULL; if (compacts && *compacts) { char *p; compitem = strtok(compacts, ","); while (compitem && !complist) { p = strchr(compitem, '='); if (p) *p = '\0'; if (strcmp(service, compitem) == 0) complist = p+1; compitem = strtok(NULL, ","); } } /* We need not check that hostname is valid, has already been done with loadhostdata() */ if (!complist) { pcre *dummy = NULL; /* Check service as a pcre pattern. And no spaces in servicenames */ if (strchr(service, ' ') == NULL) dummy = compileregex(service); if (dummy == NULL) { errormsg(500, "Invalid testname pattern"); return 1; } freeregex(dummy); SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + strlen(service)); snprintf(xymondreq, xymondreq_buflen, "xymondlog host=%s test=%s fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,ackmsg,dismsg,client,acklist,XMH_IP,XMH_DISPLAYNAME,clntstamp,flapinfo,modifiers", hostname, service); } else { pcre *dummy = NULL; SBUF_DEFINE(re); SBUF_MALLOC(re, 5 + strlen(complist)); snprintf(re, re_buflen, "^(%s)$", complist); dummy = compileregex(re); if (dummy == NULL) { errormsg(500, "Invalid testname pattern"); return 1; } freeregex(dummy); SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + strlen(re)); snprintf(xymondreq, xymondreq_buflen, "xymondboard host=^%s$ test=%s fields=testname,color,lastchange", hostname, re); } sres = newsendreturnbuf(1, NULL); xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres); if (xymondresult == XYMONSEND_OK) log = getsendreturnstr(sres, 1); freesendreturnbuf(sres); if ((xymondresult != XYMONSEND_OK) || (log == NULL) || (strlen(log) == 0)) { errormsg(404, "Status not available\n"); return 1; } if (!complist) { char *p; sumline = log; p = strchr(log, '\n'); *p = '\0'; msg = (p+1); p = strchr(msg, '\n'); if (!p) { firstline = strdup(msg); restofmsg = NULL; } else { *p = '\0'; firstline = strdup(msg); restofmsg = (p+1); *p = '\n'; } memset(items, 0, sizeof(items)); p = gettok(sumline, "|"); icount = 0; while (p && (icount < 20)) { items[icount++] = p; p = gettok(NULL, "|"); } /* * hostname, [0] * testname, [1] * color, [2] * flags, [3] * lastchange, [4] * logtime, [5] * validtime, [6] * acktime, [7] * disabletime, [8] * sender, [9] * cookie, [10] * ackmsg, [11] * dismsg, [12] * client, [13] * acklist [14] * XMH_IP [15] * XMH_DISPLAYNAME [16] * clienttstamp [17] * flapping [18] * modifiers [19] */ color = parse_color(items[2]); flags = strdup(items[3]); logage = getcurrenttime(NULL) - atoi(items[4]); timesincechange[0] = '\0'; p = timesincechange; { int days = (int) (logage / 86400); int hours = (int) ((logage % 86400) / 3600); int minutes = (int) ((logage % 3600) / 60); if (days > 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d days, ", days); else if (days == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 day, "); if (hours == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 hour, "); else p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d hours, ", hours); if (minutes == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 minute"); else p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d minutes", minutes); } logtime = atoi(items[5]); if (items[7] && strlen(items[7])) acktime = atoi(items[7]); if (items[8] && strlen(items[8])) disabletime = atoi(items[8]); sender = strdup(items[9]); if (items[11] && strlen(items[11])) ackmsg = items[11]; if (ackmsg) nldecode(ackmsg); if (items[12] && strlen(items[12])) dismsg = items[12]; if (dismsg) nldecode(dismsg); if (items[13]) clientavail = (*items[13] == 'Y'); acklist = ((items[14] && *items[14]) ? strdup(items[14]) : NULL); ip = (items[15] ? items[15] : ""); displayname = ((items[16] && *items[16]) ? items[16] : hostname); clntstamp = ((items[17] && *items[17]) ? atol(items[17]) : 0); flapping = (items[18] ? (*items[18] == '1') : 0); modifiers = (items[19] && *(items[19])) ? items[19] : NULL; sethostenv(displayname, ip, service, colorname(COL_GREEN), hostname); sethostenv_refresh(60); } else { /* Compressed status display */ strbuffer_t *cmsg; char *row, *p_row, *p_fld; SBUF_DEFINE(nonhistenv); color = COL_GREEN; cmsg = newstrbuffer(0); addtobuffer(cmsg, "\n"); row = strtok_r(log, "\n", &p_row); while (row) { /* testname,color,lastchange */ char *testname, *itmcolor, *chgs; time_t lastchange; int icolor; testname = strtok_r(row, "|", &p_fld); itmcolor = strtok_r(NULL, "|", &p_fld); chgs = strtok_r(NULL, "|", &p_fld); lastchange = atoi(chgs); icolor = parse_color(itmcolor); if (icolor > color) color = icolor; addtobuffer(cmsg, "\n"); row = strtok_r(NULL, "\n", &p_row); } addtobuffer(cmsg, "
&"); addtobuffer(cmsg, itmcolor); addtobuffer(cmsg, " "); addtobuffer(cmsg, htmlquoted(testname)); addtobuffer(cmsg, "
\n"); ishtmlformatted = 1; sethostenv(displayname, ip, service, colorname(color), hostname); sethostenv_refresh(60); logtime = getcurrenttime(NULL); strncpy(timesincechange, "0 minutes", sizeof(timesincechange)); log = restofmsg = grabstrbuffer(cmsg); SBUF_MALLOC(firstline, 1024); snprintf(firstline, firstline_buflen, "%s Compressed status display\n", colorname(color)); SBUF_MALLOC(nonhistenv, 10 + strlen(service)); snprintf(nonhistenv, nonhistenv_buflen, "NONHISTS=%s", service); putenv(nonhistenv); } } else if (source == SRC_HISTLOGS) { char logfn[PATH_MAX]; struct stat st; FILE *fd; /* * Some clients (Unix disk reports) don't have a newline before the * "Status unchanged in ..." text. Most do, but at least Solaris and * AIX do not. So just look for the text, not the newline. */ char *statusunchangedtext = "Status unchanged in "; char *receivedfromtext = "Message received from "; char *clientidtext = "Client data ID "; char *p, *unchangedstr, *receivedfromstr, *clientidstr, *hostnamedash; int n; if (!tstamp) { errormsg(500, "Invalid request"); return 1; } if (loadhostdata(hostname, &ip, &displayname, &compacts, 0) != 0) return 1; hostnamedash = strdup(hostname); p = hostnamedash; while ((p = strchr(p, '.')) != NULL) *p = '_'; p = hostnamedash; while ((p = strchr(p, ',')) != NULL) *p = '_'; snprintf(logfn, sizeof(logfn), "%s/%s/%s/%s", xgetenv("XYMONHISTLOGS"), hostnamedash, service, tstamp); xfree(hostnamedash); p = tstamp; while ((p = strchr(p, '_')) != NULL) *p = ' '; sethostenv_histlog(tstamp); if ((stat(logfn, &st) == -1) || (st.st_size < 10) || (!S_ISREG(st.st_mode))) { errormsg(404, "Historical status log not available\n"); return 1; } fd = fopen(logfn, "r"); if (!fd) { errormsg(404, "Unable to access historical logfile\n"); return 1; } log = (char *)malloc(st.st_size+1); n = fread(log, 1, st.st_size, fd); if (n >= 0) *(log+n) = '\0'; else *log = '\0'; fclose(fd); p = strchr(log, '\n'); if (!p) { firstline = strdup(log); restofmsg = NULL; } else { *p = '\0'; firstline = strdup(log); restofmsg = (p+1); *p = '\n'; } color = parse_color(log); p = strstr(log, "\n", cmd); if (obeycookies && !gotfilter && ((hostname = get_cookie("host")) != NULL)) { if (*hostname) { pcre *dummy; SBUF_DEFINE(re); SBUF_MALLOC(re, 3+strlen(hostname)); snprintf(re, re_buflen, "^%s$", hostname); dummy = compileregex(re); if (dummy) { /* Valid expression */ freeregex(dummy); SBUF_REALLOC(cmd, 1024 + strlen(cmd) + strlen(re)); snprintf(cmd + strlen(cmd), cmd_buflen - strlen(cmd), " host=%s", re); gotfilter = 1; } else { filtererror = 1; printf("

Invalid hostname filter

\n"); } } } if (obeycookies && !gotfilter && ((pagename = get_cookie("pagepath")) != NULL)) { if (*pagename) { pcre *dummy; SBUF_DEFINE(re); SBUF_MALLOC(re, 8 + strlen(pagename)*2); snprintf(re, re_buflen, "%s$|^%s/.+", pagename, pagename); dummy = compileregex(re); if (dummy) { /* Valid expression */ freeregex(dummy); SBUF_REALLOC(cmd, 1024 + strlen(cmd) + strlen(re)); snprintf(cmd + strlen(cmd), cmd_buflen - strlen(cmd), " page=%s", re); gotfilter = 1; } else { filtererror = 1; printf("

Invalid pagename filter

\n"); } } } sres = newsendreturnbuf(1, NULL); if (!filtererror && (sendmessage(cmd, NULL, XYMON_TIMEOUT, sres) == XYMONSEND_OK)) { char *bol, *eoln; int first = 1; respbuf = getsendreturnstr(sres, 1); bol = respbuf; while (bol) { char *hname, *tname, *ackcode; eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; hname = tname = ackcode = NULL; hname = strtok(bol, "|"); if (hname) tname = strtok(NULL, "|"); if (tname) ackcode = strtok(NULL, "|"); if (hname && tname && ackcode && (strcmp(hname, "summary") != 0)) { if (first) { fprintf(stdout, "
\n", getenv("SCRIPT_NAME")); fprintf(stdout, "
\n"); fprintf(stdout, "\n"); first = 0; } generate_ackline(stdout, hname, tname, ackcode); } if (eoln) bol = eoln+1; else bol = NULL; } if (first) { fprintf(stdout, "
No active alerts
\n"); } else { generate_ackline(stdout, NULL, NULL, NULL); fprintf(stdout, "
HostTestDurationCauseAckAck Multiple
\n"); fprintf(stdout, "
\n"); } } freesendreturnbuf(sres); headfoot(stdout, "acknowledge", "", "footer", COL_RED); } } else if ( (nopin && (cgi_method == CGI_POST)) || (!nopin && (cgidata != NULL)) ) { SBUF_DEFINE(xymonmsg); SBUF_DEFINE(acking_user); acklist_t *awalk; strbuffer_t *response = newstrbuffer(0); int count = 0; acking_user = ""; /* We only want to accept posts from certain pages */ { char cgisource[1024]; char *p; p = csp_header("acknowledge"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "acknowledge"); if (!cgi_refererok(cgisource)) { fprintf(stdout, "Location: %s.sh?\n\n", cgisource); return 0; } } parse_query(); if (getenv("REMOTE_USER")) { char *remaddr = getenv("REMOTE_ADDR"); SBUF_MALLOC(acking_user, 1024 + strlen(getenv("REMOTE_USER")) + (remaddr ? strlen(remaddr) : 0)); snprintf(acking_user, acking_user_buflen, "\nAcked by: %s", getenv("REMOTE_USER")); if (remaddr) snprintf(acking_user + strlen(acking_user), acking_user_buflen - strlen(acking_user), " (%s)", remaddr); } /* Load the host data (for access control) */ if (accessfn) { load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_web_access_config(accessfn); } addtobuffer(response, "
\n"); for (awalk = ackhead; (awalk); awalk = awalk->next) { SBUF_DEFINE(msgline); SBUF_MALLOC(msgline, 1024 + (awalk->hostname ? MAX_HTMLQUOTE_FACTOR*strlen(awalk->hostname) : 0) + (awalk->testname ? MAX_HTMLQUOTE_FACTOR*strlen(awalk->testname) : 0)); if (!awalk->checked) continue; if (accessfn && (!web_access_allowed(getenv("REMOTE_USER"), awalk->hostname, awalk->testname, WEB_ACCESS_CONTROL))) continue; if ((reqtype == ACK_ONE) && (awalk->id != sendnum)) continue; if (reqtype == ACK_MANY) { if (!awalk->ackmsg) awalk->ackmsg = ackmsgall; if (!awalk->validity && validityall) awalk->validity = durationvalue(validityall); if (periodall) awalk->period = periodall; } if (strncmp(awalk->period, "hour", 4) == 0) awalk->validity *= 60; else if (strncmp(awalk->period, "day", 4) == 0) awalk->validity *= 60*24; count++; if (!awalk->ackmsg || !awalk->validity || !awalk->acknum) { if (awalk->hostname && awalk->testname) { snprintf(msgline, msgline_buflen, "NO ACK sent for host %s / test %s", htmlquoted(awalk->hostname), htmlquoted(awalk->testname)); } else { snprintf(msgline, msgline_buflen, "NO ACK sent for item %d", awalk->id); } addtobuffer(response, msgline); addtobuffer(response, ": Duration or message not set
\n"); continue; } SBUF_MALLOC(xymonmsg, 1024 + strlen(awalk->ackmsg) + strlen(acking_user)); snprintf(xymonmsg, xymonmsg_buflen, "xymondack %d %d %s %s", awalk->acknum, awalk->validity, awalk->ackmsg, acking_user); if (sendmessage(xymonmsg, NULL, XYMON_TIMEOUT, NULL) == XYMONSEND_OK) { if (awalk->hostname && awalk->testname) { snprintf(msgline, msgline_buflen, "Acknowledge sent for host %s / test %s
\n", htmlquoted(awalk->hostname), htmlquoted(awalk->testname)); } else { snprintf(msgline, msgline_buflen, "Acknowledge sent for code %d
\n", awalk->acknum); } } else { if (awalk->hostname && awalk->testname) { snprintf(msgline, msgline_buflen, "Failed to send acknowledge for host %s / test %s
\n", htmlquoted(awalk->hostname), htmlquoted(awalk->testname)); } else { snprintf(msgline, msgline_buflen, "Failed to send acknowledge for code %d
\n", awalk->acknum); } } addtobuffer(response, msgline); xfree(xymonmsg); } if (count == 0) addtobuffer(response, "No acks requested\n"); addtobuffer(response, "
\n"); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); headfoot(stdout, "acknowledge", "", "header", COL_RED); fprintf(stdout, "%s", STRBUF(response)); headfoot(stdout, "acknowledge", "", "footer", COL_RED); } return 0; } xymon-4.3.30/web/perfdata.c0000664000076400007640000002717613515623702015733 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon CGI for reporting performance statisticsc from the RRD data */ /* */ /* Copyright (C) 2008-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: perfdata.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" enum { O_NONE, O_XML, O_CSV } outform = O_NONE; char csvdelim = ','; char *hostpattern = NULL; char *exhostpattern = NULL; char *pagepattern = NULL; char *expagepattern = NULL; char *starttime = NULL; char *starttimedate = NULL, *starttimehm = NULL; char *endtime = NULL; char *endtimedate = NULL, *endtimehm = NULL; char *customrrd = NULL; char *customds = NULL; static void parse_query(void) { cgidata_t *cgidata = cgi_request(); cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { if (strcasecmp(cwalk->name, "HOST") == 0) { if (*(cwalk->value)) hostpattern = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXHOST") == 0) { if (*(cwalk->value)) hostpattern = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "PAGEMATCH") == 0) { if (*(cwalk->value)) pagepattern = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "EXPAGEMATCH") == 0) { if (*(cwalk->value)) expagepattern = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "STARTTIME") == 0) { if (*(cwalk->value)) starttime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "ENDTIME") == 0) { if (*(cwalk->value)) endtime = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CUSTOMRRD") == 0) { if (*(cwalk->value)) customrrd = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CUSTOMDS") == 0) { if (*(cwalk->value)) customds = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "CSV") == 0) { outform = O_CSV; if (*(cwalk->value)) csvdelim = *(cwalk->value); } else if (strcasecmp(cwalk->name, "FORMAT") == 0) { if (strcmp(cwalk->value, "XML") == 0) outform = O_XML; else { outform = O_CSV; csvdelim = *(cwalk->value); } } cwalk = cwalk->next; } } int oneset(char *hostname, char *rrdname, char *starttime, char *endtime, char *colname, double subfrom, char *dsdescr) { static int firsttime = 1; time_t start, end, t; unsigned long step; unsigned long dscount; char **dsnames; rrd_value_t *data; int columnindex; char tstamp[30]; int dataindex, rowcount, havemin, havemax, missingdata; double sum, min = 0.0, max = 0.0, val; char *rrdargs[10]; int result; rrdargs[0] = "rrdfetch"; rrdargs[1] = rrdname; rrdargs[2] = "AVERAGE"; rrdargs[3] = "-s"; rrdargs[4] = starttimedate; rrdargs[5] = starttimehm; rrdargs[6] = "-e"; rrdargs[7] = endtimedate; rrdargs[8] = endtimehm; rrdargs[9] = NULL; optind = opterr = 0; rrd_clear_error(); result = rrd_fetch(9, rrdargs, &start, &end, &step, &dscount, &dsnames, &data); if (result != 0) { errprintf("RRD error: %s\n", rrd_get_error()); return 1; } for (columnindex=0; ((columnindex < dscount) && strcmp(dsnames[columnindex], colname)); columnindex++) ; if (columnindex == dscount) { errprintf("RRD error: Cannot find column %s\n", colname); return 1; } sum = 0.0; havemin = havemax = 0; rowcount = 0; switch (outform) { case O_XML: printf(" \n"); printf(" %s\n", hostname); printf(" %s\n", rrdname); printf(" %s\n", colname); printf(" %s\n", (dsdescr ? dsdescr : colname)); printf(" \n"); break; case O_CSV: if (firsttime) { printf("\"hostname\"%c\"datasource\"%c\"rrdcolumn\"%c\"measurement\"%c\"time\"%c\"value\"\n", csvdelim, csvdelim, csvdelim, csvdelim, csvdelim); firsttime = 0; } break; default: break; } for (t=start+step, dataindex=columnindex, missingdata=0; (t <= end); t += step, dataindex += dscount) { if (isnan(data[dataindex]) || isnan(-data[dataindex])) { missingdata++; continue; } val = (subfrom != 0) ? subfrom - data[dataindex] : data[dataindex]; strftime(tstamp, sizeof(tstamp), "%Y%m%d%H%M%S", localtime(&t)); switch (outform) { case O_XML: printf(" \n"); printf(" \n", tstamp); printf(" %f\n", val); printf(" \n"); break; case O_CSV: printf("\"%s\"%c\"%s\"%c\"%s\"%c\"%s\"%c\"%s\"%c%f\n", hostname, csvdelim, rrdname, csvdelim, colname, csvdelim, (dsdescr ? dsdescr : colname), csvdelim, tstamp, csvdelim, val); break; default: break; } if (!havemax || (val > max)) { max = val; havemax = 1; } if (!havemin || (val < min)) { min = val; havemin = 1; } sum += val; rowcount++; } if (outform == O_XML) { printf(" \n"); printf(" \n"); if (havemin) printf(" %f\n", min); if (havemax) printf(" %f\n", max); if (rowcount) printf(" %f\n", (sum / rowcount)); printf(" %d\n", missingdata); printf(" \n"); printf(" \n"); } return 0; } int onehost(char *hostname, char *starttime, char *endtime) { struct stat st; DIR *d; struct dirent *de; if ((chdir(xgetenv("XYMONRRDS")) == -1) || (chdir(hostname) == -1)) { errprintf("Cannot cd to %s/%s\n", xgetenv("XYMONRRDS"), hostname); return 1; } if (customrrd && customds) { if (stat(customrrd, &st) != 0) return 1; oneset(hostname, customrrd, starttime, endtime, customds, 0, customds); return 0; } /* * CPU busy data - use vmstat.rrd if it is there, * if not then assume it's a Windows box and report the la.rrd data. */ if (stat("vmstat.rrd", &st) == 0) { oneset(hostname, "vmstat.rrd", starttime, endtime, "cpu_idl", 100, "pctbusy"); } else { /* No vmstat data, so use the la.rrd file */ oneset(hostname, "la.rrd", starttime, endtime, "la", 0, "pctbusy"); } /* * Report all memory data - it depends on the OS of the host which one * really is interesting (memory.actual.rrd for Linux, memory.real.rrd for * most of the other systems). */ if (stat("memory.actual.rrd", &st) == 0) { oneset(hostname, "memory.actual.rrd", starttime, endtime, "realmempct", 0, "Virtual"); } if (stat("memory.real.rrd", &st) == 0) { oneset(hostname, "memory.real.rrd", starttime, endtime, "realmempct", 0, "RAM"); } if (stat("memory.swap.rrd", &st) == 0) { oneset(hostname, "memory.swap.rrd", starttime, endtime, "realmempct", 0, "Swap"); } /* * Report data for all filesystems. */ d = opendir("."); while ((de = readdir(d)) != NULL) { if (strncmp(de->d_name, "disk,", 5) != 0) continue; stat(de->d_name, &st); if (!S_ISREG(st.st_mode)) continue; if (strcmp(de->d_name, "disk,root.rrd") == 0) { oneset(hostname, de->d_name, starttime, endtime, "pct", 0, "/"); } else { char *fsnam = strdup(de->d_name+4); char *p; while ((p = strchr(fsnam, ',')) != NULL) *p = '/'; p = fsnam + strlen(fsnam) - 4; *p = '\0'; dbgprintf("Processing set %s for host %s from %s\n", de->d_name, hostname, fsnam); oneset(hostname, de->d_name, starttime, endtime, "pct", 0, fsnam); xfree(fsnam); } } closedir(d); return 0; } void format_rrdtime(char *t, char **tday, char **thm) { int year, month, day, hour, min,sec; int n; time_t now = getcurrenttime(NULL); struct tm *nowtm = localtime(&now); if (t == NULL) return; /* Input is YYYY/MM/DD@HH:MM:SS or YYYYMMDD or MMDD */ n = sscanf(t, "%d/%d/%d@%d:%d:%d", &year, &month, &day, &hour, &min, &sec); switch (n) { case 6: break; /* Got all */ case 5: sec = 0; break; case 4: min = sec = 0; break; case 3: hour = min = sec = 0; break; default: break; } hour = min = sec = 0; n = sscanf(t, "%d/%d/%d", &year, &month, &day); switch (n) { case 3: break; /* Got all */ case 2: day = month; month = year; year = nowtm->tm_year + 1900; default: break; } if (year < 100) year += 2000; *tday = (char *)malloc(10); snprintf(*tday, 10, "%4d%02d%02d", year, month, day); *thm = (char *)malloc(20); snprintf(*thm, 20, "%02d:%02d:%02d", hour, min, sec); } int main(int argc, char **argv) { pcre *hostptn, *exhostptn, *pageptn, *expageptn; void *hwalk; char *hostname, *pagename; hostptn = exhostptn = pageptn = expageptn = NULL; if (getenv("QUERY_STRING") == NULL) { /* Not invoked through the CGI */ if (argc < 4) { errprintf("Usage:\n%s HOSTNAME-PATTERN STARTTIME ENDTIME", argv[0]); return 1; } hostpattern = argv[1]; if (strncmp(hostpattern, "--page=", 7) == 0) { pagepattern = strchr(argv[1], '=') + 1; hostpattern = NULL; } starttimedate = argv[2]; starttimehm = "00:00:00"; endtimedate = argv[3]; endtimehm = "00:00:00"; if (argc > 4) { if (strncmp(argv[4], "--csv", 5) == 0) { char *p; outform = O_CSV; if ((p = strchr(argv[4], '=')) != NULL) csvdelim = *(p+1); } } } else { char *envarea = NULL; int argi; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } } /* Parse CGI parameters */ parse_query(); format_rrdtime(starttime, &starttimedate, &starttimehm); format_rrdtime(endtime, &endtimedate, &endtimehm); switch (outform) { case O_XML: printf("Content-type: application/xml\n\n"); break; case O_CSV: printf("Content-type: text/csv\n\n"); break; case O_NONE: load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "perfdata", "perfdata_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } } load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); if (hostpattern) hostptn = compileregex(hostpattern); if (exhostpattern) exhostptn = compileregex(exhostpattern); if (pagepattern) pageptn = compileregex(pagepattern); if (expagepattern) expageptn = compileregex(expagepattern); switch (outform) { case O_XML: printf("\n"); printf("\n"); break; default: break; } dbgprintf("Got hosts, it is %s\n", (first_host() == NULL) ? "empty" : "not empty"); for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { hostname = xmh_item(hwalk, XMH_HOSTNAME); pagename = xmh_item(hwalk, XMH_PAGEPATH); dbgprintf("Processing host %s\n", hostname); if (hostpattern && !matchregex(hostname, hostptn)) continue; if (exhostpattern && matchregex(hostname, exhostptn)) continue; if (pagepattern && !matchregex(pagename, pageptn)) continue; if (expagepattern && matchregex(pagename, expageptn)) continue; onehost(hostname, starttime, endtime); } switch (outform) { case O_XML: printf("\n"); break; default: break; } return 0; } xymon-4.3.30/web/ackinfo.c0000664000076400007640000001123613515623702015545 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon CGI for sending in an "ackinfo" message. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: ackinfo.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" static char *hostname = NULL; static char *testname = NULL; static int level = -1; static int validity = -1; static char *ackedby = NULL; static char *ackmsg = NULL; static void parse_query(void) { cgidata_t *cgidata = cgi_request(); cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { if (strcasecmp(cwalk->name, "HOST") == 0) { hostname = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "SERVICE") == 0) { testname = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "ALLTESTS") == 0) { if (strcasecmp(cwalk->value, "on") == 0) testname = strdup("*"); } else if (strcasecmp(cwalk->name, "NOTE") == 0) { ackmsg = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "LEVEL") == 0) { /* Command line may override this */ if (level == -1) level = atoi(cwalk->value); } else if (strcasecmp(cwalk->name, "VALIDITY") == 0) { /* Command line may override this */ if (validity == -1) validity = atoi(cwalk->value); } cwalk = cwalk->next; } } int main(int argc, char *argv[]) { int argi; char *envarea = NULL; SBUF_DEFINE(xymonmsg); for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--level=")) { char *p = strchr(argv[argi], '='); level = atoi(p+1); } else if (argnmatch(argv[argi], "--validity=")) { char *p = strchr(argv[argi], '='); validity = atoi(p+1); } else if (argnmatch(argv[argi], "--sender=")) { char *p = strchr(argv[argi], '='); ackedby = strdup(p+1); } } redirect_cgilog("ackinfo"); /* We only want to accept posts from certain pages */ { char cgisource[1024]; char *p; p = csp_header("ackinfo"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("CGIBINURL"), "svcstatus"); if (!cgi_refererok(cgisource)) { snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("CGIBINURL"), "criticalview"); if (!cgi_refererok(cgisource)) { errprintf("ackinfo POST that is not coming from criticalview or svcstatus (referer=%s). Ignoring.\n", textornull(getenv("HTTP_REFERER")) ); fprintf(stdout, "Location: %s.sh?\n\n", cgisource); return 0; } } } parse_query(); if (hostname && *hostname && testname && *testname && ((level == 0) || (validity>0)) && ackmsg && *ackmsg) { char *p; /* Get the login username */ if (!ackedby) ackedby = getenv("REMOTE_USER"); if (!ackedby) ackedby = "UnknownUser"; if (validity == -1) validity = 30; /* 30 minutes */ validity = validity*60; p = strchr(ackmsg, '\n'); if (p) *p = '\0'; /* ackinfo HOST.TEST\nlevel\nvaliduntil\nackedby\nmsg */ SBUF_MALLOC(xymonmsg, 1024 + strlen(hostname) + strlen(testname) + strlen(ackedby) + strlen(ackmsg)); snprintf(xymonmsg, xymonmsg_buflen, "ackinfo %s.%s\n%d\n%d\n%s\n%s\n", hostname, testname, level, validity, ackedby, ackmsg); sendmessage(xymonmsg, NULL, XYMON_TIMEOUT, NULL); } else { xymonmsg = (char *)malloc(1024 + (hostname ? strlen(hostname) : 9) + (testname ? strlen(testname) : 9) + (ackmsg ? strlen(ackmsg) : 9)); snprintf(xymonmsg, xymonmsg_buflen, "error in input params: hostname=%s, testname=%s, ackmsg=%s, validity=%d\n", (hostname ? hostname : ""), (testname ? testname : ""), (ackmsg ? ackmsg : ""), validity); } fprintf(stdout, "Content-type: %s\n", xgetenv("HTMLCONTENTTYPE")); fprintf(stdout, "Location: %s\n", getenv("HTTP_REFERER")); fprintf(stdout, "\n"); fprintf(stdout, "Sent to xymond:\n%s\n", htmlquoted(xymonmsg)); return 0; } xymon-4.3.30/web/svcstatus-trends.c0000664000076400007640000002164013515623702017467 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD graph overview generator. */ /* */ /* This is a standalone tool for generating data for the trends column. */ /* All of the data stored in RRD files for a host end up as graphs. Some of */ /* these are displayed together with the corresponding status display, but */ /* others (e.g. from "data" messages) are not. This generates a "trends" */ /* column that contains all of the graphs for a host. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: svcstatus-trends.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" typedef struct graph_t { xymongraph_t *gdef; int count; struct graph_t *next; } graph_t; typedef struct dirstack_t { char *dirname; DIR *rrddir; struct dirstack_t *next; } dirstack_t; dirstack_t *dirs = NULL; static dirstack_t *stack_opendir(char *dirname) { dirstack_t *newdir; DIR *d; d = opendir(dirname); if (d == NULL) return NULL; newdir = (dirstack_t *)malloc(sizeof(dirstack_t)); newdir->dirname = strdup(dirname); newdir->rrddir = d; newdir->next = NULL; if (dirs == NULL) { dirs = newdir; } else { newdir->next = dirs; dirs = newdir; } return newdir; } static void stack_closedir(void) { dirstack_t *tmp = dirs; if (dirs && dirs->rrddir) { dirs = dirs->next; closedir(tmp->rrddir); xfree(tmp->dirname); xfree(tmp); } } static char *stack_readdir(void) { static char fname[PATH_MAX]; struct dirent *d; struct stat st; if (dirs == NULL) return NULL; do { d = readdir(dirs->rrddir); if (d == NULL) { stack_closedir(); } else if (*(d->d_name) == '.') { d = NULL; } else { snprintf(fname, sizeof(fname), "%s/%s", dirs->dirname, d->d_name); if ((stat(fname, &st) == 0) && (S_ISDIR(st.st_mode))) { stack_opendir(fname); d = NULL; } } } while (dirs && (d == NULL)); if (d == NULL) return NULL; if (strncmp(fname, "./", 2) == 0) return (fname + 2); else return fname; } static char *rrdlink_text(void *host, graph_t *rrd, hg_link_t wantmeta, time_t starttime, time_t endtime) { STATIC_SBUF_DEFINE(rrdlink); char *graphdef, *p; char *hostdisplayname, *hostrrdgraphs; hostdisplayname = xmh_item(host, XMH_DISPLAYNAME); hostrrdgraphs = xmh_item(host, XMH_TRENDS); dbgprintf("rrdlink_text: host %s, rrd %s\n", xmh_item(host, XMH_HOSTNAME), rrd->gdef->xymonrrdname); /* If no rrdgraphs definition, include all with default links */ if (hostrrdgraphs == NULL) { dbgprintf("rrdlink_text: Standard URL (no rrdgraphs)\n"); return xymon_graph_data(xmh_item(host, XMH_HOSTNAME), hostdisplayname, NULL, -1, rrd->gdef, rrd->count, HG_WITH_STALE_RRDS, wantmeta, 0, starttime, endtime); } /* Find this rrd definition in the rrdgraphs */ graphdef = strstr(hostrrdgraphs, rrd->gdef->xymonrrdname); if (graphdef) { char *endp; int namelength; namelength = strlen(rrd->gdef->xymonrrdname); while (graphdef) { /* * Search for string, but eliminate partial matches. * Must start and bol or after a comma or !, * and end with colon, comma, or eol. */ endp = graphdef + namelength; if (((*endp == '\0') || (*endp == ':') || (*endp == ',')) && ((graphdef == hostrrdgraphs) || (*(graphdef-1) == ',') || (*(graphdef-1) == '!') )) break; /* no match, keep looking */ graphdef = strstr(endp, rrd->gdef->xymonrrdname); } } /* If not found ... */ if (graphdef == NULL) { dbgprintf("rrdlink_text: NULL graphdef\n"); /* Do we include all by default ? */ if (*(hostrrdgraphs) == '*') { dbgprintf("rrdlink_text: Default URL included\n"); /* Yes, return default link for this RRD */ return xymon_graph_data(xmh_item(host, XMH_HOSTNAME), hostdisplayname, NULL, -1, rrd->gdef, rrd->count, HG_WITH_STALE_RRDS, wantmeta, 0, starttime, endtime); } else { dbgprintf("rrdlink_text: Default URL NOT included\n"); /* No, return empty string */ return ""; } } /* We now know that rrdgraphs explicitly define what to do with this RRD */ /* Does he want to explicitly exclude this RRD ? */ if ((graphdef > hostrrdgraphs) && (*(graphdef-1) == '!')) { dbgprintf("rrdlink_text: This graph is explicitly excluded\n"); return ""; } /* It must be included. */ if (rrdlink == NULL) { SBUF_MALLOC(rrdlink, 4096); } *rrdlink = '\0'; p = graphdef + strlen(rrd->gdef->xymonrrdname); if (*p == ':') { /* There is an explicit list of graphs to add for this RRD. */ char savechar; char *enddef; graph_t *myrrd; char *partlink; myrrd = (graph_t *) malloc(sizeof(graph_t)); myrrd->gdef = (xymongraph_t *) calloc(1, sizeof(xymongraph_t)); /* First, null-terminate this graph definition so we only look at the active RRD */ enddef = strchr(graphdef, ','); if (enddef) *enddef = '\0'; graphdef = (p+1); do { p = strchr(graphdef, '|'); /* Ends at '|' ? */ if (p == NULL) p = graphdef + strlen(graphdef); /* Ends at end of string */ savechar = *p; *p = '\0'; myrrd->gdef->xymonrrdname = graphdef; myrrd->gdef->xymonpartname = NULL; myrrd->gdef->maxgraphs = 0; myrrd->count = rrd->count; myrrd->next = NULL; partlink = xymon_graph_data(xmh_item(host, XMH_HOSTNAME), hostdisplayname, NULL, -1, myrrd->gdef, myrrd->count, HG_WITH_STALE_RRDS, wantmeta, 0, starttime, endtime); if ((strlen(rrdlink) + strlen(partlink) + 1) >= rrdlink_buflen) { SBUF_REALLOC(rrdlink, rrdlink_buflen + strlen(partlink) + 4096); } strncat(rrdlink, partlink, (rrdlink_buflen - strlen(rrdlink))); *p = savechar; graphdef = p; if (*graphdef != '\0') graphdef++; } while (*graphdef); if (enddef) *enddef = ','; xfree(myrrd->gdef); xfree(myrrd); return rrdlink; } else { /* It is included with the default graph */ return xymon_graph_data(xmh_item(host, XMH_HOSTNAME), hostdisplayname, NULL, -1, rrd->gdef, rrd->count, HG_WITH_STALE_RRDS, wantmeta, 0, starttime, endtime); } return ""; } char *generate_trends(char *hostname, time_t starttime, time_t endtime) { void *myhost; char hostrrddir[PATH_MAX]; char *fn; int anyrrds = 0; xymongraph_t *graph; graph_t *rwalk; SBUF_DEFINE(allrrdlinks); char *allrrdlinksend; myhost = hostinfo(hostname); if (!myhost) return NULL; snprintf(hostrrddir, sizeof(hostrrddir), "%s/%s", xgetenv("XYMONRRDS"), hostname); if (chdir(hostrrddir) != 0) { errprintf("Cannot chdir to %s: %s\n", hostrrddir, strerror(errno)); return NULL; } stack_opendir("."); while ((fn = stack_readdir())) { /* Check if the filename ends in ".rrd", and we know how to handle this RRD */ if ((strlen(fn) <= 4) || (strcmp(fn+strlen(fn)-4, ".rrd") != 0)) continue; graph = find_xymon_graph(fn); if (!graph) continue; dbgprintf("Got RRD %s\n", fn); anyrrds++; for (rwalk = (graph_t *)xmh_item(myhost, XMH_DATA); (rwalk && (rwalk->gdef != graph)); rwalk = rwalk->next) ; if (rwalk == NULL) { graph_t *newrrd = (graph_t *) malloc(sizeof(graph_t)); newrrd->gdef = graph; newrrd->count = 1; newrrd->next = (graph_t *)xmh_item(myhost, XMH_DATA); xmh_set_item(myhost, XMH_DATA, newrrd); rwalk = newrrd; dbgprintf("New rrd for host:%s, rrd:%s\n", hostname, graph->xymonrrdname); } else { rwalk->count++; dbgprintf("Extra RRD for host %s, rrd %s count:%d\n", hostname, rwalk->gdef->xymonrrdname, rwalk->count); } } stack_closedir(); if (!anyrrds) return NULL; SBUF_MALLOC(allrrdlinks, 16384); *allrrdlinks = '\0'; allrrdlinksend = allrrdlinks; graph = xymongraphs; while (graph->xymonrrdname) { for (rwalk = (graph_t *)xmh_item(myhost, XMH_DATA); (rwalk && (rwalk->gdef->xymonrrdname != graph->xymonrrdname)); rwalk = rwalk->next) ; if (rwalk) { int buflen; char *onelink; buflen = (allrrdlinksend - allrrdlinks); onelink = rrdlink_text(myhost, rwalk, 0, starttime, endtime); if ((buflen + strlen(onelink)) >= allrrdlinks_buflen) { SBUF_REALLOC(allrrdlinks, allrrdlinks_buflen+4096); allrrdlinksend = allrrdlinks + buflen; } allrrdlinksend += snprintf(allrrdlinksend, (allrrdlinks_buflen - (allrrdlinksend - allrrdlinks)), "%s", onelink); } graph++; } return allrrdlinks; } xymon-4.3.30/web/enadis.c0000664000076400007640000003750413515623702015404 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon backend script for disabling/enabling tests. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: enadis.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" enum { ACT_NONE, ACT_FILTER, ACT_ENABLE, ACT_DISABLE, ACT_SCHED_DISABLE, ACT_SCHED_CANCEL } action = ACT_NONE; enum { DISABLE_FOR, DISABLE_UNTIL } disableend = DISABLE_FOR; /* disable until a date OR disable for a duration */ int hostcount = 0; char **hostnames = NULL; int disablecount = 0; char **disabletest = NULL; int enablecount = 0; char **enabletest = NULL; int duration = 0; int scale = 1; char *disablemsg = "No reason given"; time_t schedtime = 0; time_t endtime = 0; time_t nowtime = 0; time_t starttime = 0; int cancelid = 0; int preview = 0; char *hostpattern = NULL; char *pagepattern = NULL; char *ippattern = NULL; char *classpattern = NULL; void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } void parse_cgi(void) { cgidata_t *postdata, *pwalk; struct tm schedtm; struct tm endtm; struct tm nowtm; memset(&schedtm, 0, sizeof(schedtm)); memset(&endtm, 0, sizeof(endtm)); postdata = cgi_request(); if (cgi_method == CGI_GET) return; /* We only want to accept posts from certain pages: svcstatus (for info), and ourselves */ /* At some point in the future, moving info lookups to their own page would be a good idea */ { char cgisource[1024]; char *p; p = csp_header("enadis"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "enadis"); if (!cgi_refererok(cgisource)) { snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("CGIBINURL"), "svcstatus"); if (!cgi_refererok(cgisource)) { errprintf("Enadis POST that is not coming from self or svcstatus (referer=%s). Ignoring.\n", textornull(getenv("HTTP_REFERER")) ); return; /* Just display, don't do anything */ } } } if (!postdata) { errormsg(cgi_error()); } pwalk = postdata; while (pwalk) { /* * When handling the "go", the "Disable now" and "Schedule disable" * radio buttons mess things up. So ignore the "go" if we have seen a * "filter" request already. */ if ((strcmp(pwalk->name, "go") == 0) && (action != ACT_FILTER)) { if (strcasecmp(pwalk->value, "enable") == 0) action = ACT_ENABLE; else if (strcasecmp(pwalk->value, "disable now") == 0) action = ACT_DISABLE; else if (strcasecmp(pwalk->value, "schedule disable") == 0) action = ACT_SCHED_DISABLE; else if (strcasecmp(pwalk->value, "cancel") == 0) action = ACT_SCHED_CANCEL; else if (strcasecmp(pwalk->value, "apply filters") == 0) action = ACT_FILTER; } else if ((strcmp(pwalk->name, "go2") == 0) && (action != ACT_FILTER)) { if (strcasecmp(pwalk->value, "Disable until") == 0) disableend = DISABLE_UNTIL; } else if (strcmp(pwalk->name, "duration") == 0) { duration = atoi(pwalk->value); } else if (strcmp(pwalk->name, "untilok") == 0) { if (strcasecmp(pwalk->value, "on") == 0) { duration = -1; scale = 1; } } else if (strcmp(pwalk->name, "scale") == 0) { scale = atoi(pwalk->value); } else if (strcmp(pwalk->name, "cause") == 0) { disablemsg = strdup(pwalk->value); } else if (strcmp(pwalk->name, "hostname") == 0) { if (hostnames == NULL) { hostnames = (char **)malloc(2 * sizeof(char *)); hostnames[0] = strdup(pwalk->value); hostnames[1] = NULL; hostcount = 1; } else { hostnames = (char **)realloc(hostnames, (hostcount + 2) * sizeof(char *)); hostnames[hostcount] = strdup(pwalk->value); hostnames[hostcount+1] = NULL; hostcount++; } } else if (strcmp(pwalk->name, "enabletest") == 0) { char *val = pwalk->value; if (strcmp(val, "ALL") == 0) val = "*"; if (enabletest == NULL) { enabletest = (char **)malloc(2 * sizeof(char *)); enabletest[0] = strdup(val); enabletest[1] = NULL; enablecount = 1; } else { enabletest = (char **)realloc(enabletest, (enablecount + 2) * sizeof(char *)); enabletest[enablecount] = strdup(val); enabletest[enablecount+1] = NULL; enablecount++; } } else if (strcmp(pwalk->name, "disabletest") == 0) { char *val = pwalk->value; if (strcmp(val, "ALL") == 0) val = "*"; if (disabletest == NULL) { disabletest = (char **)malloc(2 * sizeof(char *)); disabletest[0] = strdup(val); disabletest[1] = NULL; disablecount = 1; } else { disabletest = (char **)realloc(disabletest, (disablecount + 2) * sizeof(char *)); disabletest[disablecount] = strdup(val); disabletest[disablecount+1] = NULL; disablecount++; } } else if (strcmp(pwalk->name, "year") == 0) { schedtm.tm_year = atoi(pwalk->value) - 1900; } else if (strcmp(pwalk->name, "month") == 0) { schedtm.tm_mon = atoi(pwalk->value) - 1; } else if (strcmp(pwalk->name, "day") == 0) { schedtm.tm_mday = atoi(pwalk->value); } else if (strcmp(pwalk->name, "hour") == 0) { schedtm.tm_hour = atoi(pwalk->value); } else if (strcmp(pwalk->name, "minute") == 0) { schedtm.tm_min = atoi(pwalk->value); } /* Until start */ else if (strcmp(pwalk->name, "endyear") == 0) { endtm.tm_year = atoi(pwalk->value) - 1900; } else if (strcmp(pwalk->name, "endmonth") == 0) { endtm.tm_mon = atoi(pwalk->value) - 1; } else if (strcmp(pwalk->name, "endday") == 0) { endtm.tm_mday = atoi(pwalk->value); } else if (strcmp(pwalk->name, "endhour") == 0) { endtm.tm_hour = atoi(pwalk->value); } else if (strcmp(pwalk->name, "endminute") == 0) { endtm.tm_min = atoi(pwalk->value); } /* Until end */ else if (strcmp(pwalk->name, "canceljob") == 0) { cancelid = atoi(pwalk->value); } else if (strcmp(pwalk->name, "preview") == 0) { preview = (strcasecmp(pwalk->value, "on") == 0); } else if ((strcmp(pwalk->name, "hostpattern") == 0) && pwalk->value && strlen(pwalk->value)) { hostpattern = strdup(pwalk->value); } else if ((strcmp(pwalk->name, "pagepattern") == 0) && pwalk->value && strlen(pwalk->value)) { pagepattern = strdup(pwalk->value); } else if ((strcmp(pwalk->name, "ippattern") == 0) && pwalk->value && strlen(pwalk->value)) { ippattern = strdup(pwalk->value); } else if ((strcmp(pwalk->name, "classpattern") == 0) && pwalk->value && strlen(pwalk->value)) { classpattern = strdup(pwalk->value); } pwalk = pwalk->next; } schedtm.tm_isdst = -1; schedtime = mktime(&schedtm); endtm.tm_isdst = -1; endtime = mktime(&endtm); } void do_one_host(char *hostname, char *fullmsg, char *username) { SBUF_DEFINE(xymoncmd); int i, result; if (disableend == DISABLE_UNTIL) { nowtime = time(NULL); starttime = nowtime; if (action == ACT_SCHED_DISABLE) starttime = schedtime; if (duration > 0) { /* Convert to minutes unless "until OK" */ duration = (int) difftime (endtime, starttime) / 60; } scale = 1; } SBUF_MALLOC(xymoncmd, 1024); switch (action) { case ACT_ENABLE: for (i=0; (i < enablecount); i++) { if (preview) result = 0; else { SBUF_REALLOC(xymoncmd, 1024 + 2*strlen(hostname) + 2*strlen(enabletest[i]) + strlen(username)); snprintf(xymoncmd, xymoncmd_buflen, "enable %s.%s", commafy(hostname), enabletest[i]); result = sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL); snprintf(xymoncmd, xymoncmd_buflen, "notify %s.%s\nMonitoring of %s:%s has been ENABLED by %s\n", commafy(hostname), enabletest[i], hostname, enabletest[i], username); sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL); } if (preview) { printf("Enabling host %s", htmlquoted(hostname)); printf(" test %s", htmlquoted(enabletest[i])); printf(": %s\n", ((result == XYMONSEND_OK) ? "OK" : "Failed")); } } break; case ACT_DISABLE: for (i=0; (i < disablecount); i++) { if (preview) result = 0; else { SBUF_REALLOC(xymoncmd, 1024 + 2*strlen(hostname) + 2*strlen(disabletest[i]) + strlen(fullmsg) + strlen(username)); snprintf(xymoncmd, xymoncmd_buflen, "disable %s.%s %d %s", commafy(hostname), disabletest[i], duration*scale, fullmsg); result = sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL); snprintf(xymoncmd, xymoncmd_buflen, "notify %s.%s\nMonitoring of %s:%s has been DISABLED by %s for %d minutes\n%s", commafy(hostname), disabletest[i], hostname, disabletest[i], username, duration*scale, fullmsg); result = sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL); } if (preview) { printf("Disabling host %s", htmlquoted(hostname)); printf(" test %s", htmlquoted(disabletest[i])); printf(": %s\n", ((result == XYMONSEND_OK) ? "OK" : "Failed")); } } break; case ACT_SCHED_DISABLE: for (i=0; (i < disablecount); i++) { SBUF_REALLOC(xymoncmd, 1024 + 2*strlen(hostname) + strlen(disabletest[i]) + strlen(fullmsg)); snprintf(xymoncmd, xymoncmd_buflen, "schedule %d disable %s.%s %d %s", (int) schedtime, commafy(hostname), disabletest[i], duration*scale, fullmsg); result = (preview ? 0 : sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL)); if (preview) { printf("Scheduling disable of host %s", htmlquoted(hostname)); printf("test %s", htmlquoted(disabletest[i])); printf(" at %s: %s\n", ctime(&schedtime), ((result == XYMONSEND_OK) ? "OK" : "Failed")); } } break; case ACT_SCHED_CANCEL: snprintf(xymoncmd, xymoncmd_buflen, "schedule cancel %d", cancelid); result = (preview ? 0 : sendmessage(xymoncmd, NULL, XYMON_TIMEOUT, NULL)); if (preview) { printf("Canceling job %d : %s\n", cancelid, ((result == XYMONSEND_OK) ? "OK" : "Failed")); } break; default: errprintf("No action\n"); break; } xfree(xymoncmd); } int main(int argc, char *argv[]) { int argi, i; char *username = getenv("REMOTE_USER"); char *userhost = getenv("REMOTE_HOST"); char *userip = getenv("REMOTE_ADDR"); SBUF_DEFINE(fullmsg); char *envarea = NULL; int obeycookies = 1; char *accessfn = NULL; SBUF_MALLOC(fullmsg, 1024); strncpy(fullmsg, "No cause specified", fullmsg_buflen); if ((username == NULL) || (strlen(username) == 0)) username = "unknown"; if ((userhost == NULL) || (strlen(userhost) == 0)) userhost = userip; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--no-cookies") == 0) { obeycookies = 0; } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--access=")) { char *p = strchr(argv[argi], '='); accessfn = strdup(p+1); } } redirect_cgilog("enadis"); parse_cgi(); if (debug) preview = 1; if (cgi_method == CGI_GET) { /* * It's a GET, so the initial request. * If we have a pagepath cookie, use that as the initial * host-name filter. */ char *pagepath; action = ACT_FILTER; pagepath = get_cookie("pagepath"); if (obeycookies && pagepath && *pagepath) pagepattern = strdup(pagepath); } if (action == ACT_FILTER) { /* Present the query form */ load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); sethostenv("", "", "", colorname(COL_BLUE), NULL); sethostenv_filter(hostpattern, pagepattern, ippattern, classpattern); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "maint", "maint_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } SBUF_REALLOC(fullmsg, 1024 + strlen(username) + strlen(userhost) + strlen(disablemsg)); snprintf(fullmsg, fullmsg_buflen, "\nDisabled by: %s @ %s\nReason: %s\n", username, userhost, disablemsg); /* * Ready ... go build the webpage. */ printf("Content-Type: %s\n", xgetenv("HTMLCONTENTTYPE")); if (!preview) { SBUF_DEFINE(returl); // dbgprintf("Not a preview: sending to %s\n", textornull(getenv("HTTP_REFERER"))); /* We're done -- figure out where to send them */ if (getenv("HTTP_REFERER")) printf("Location: %s\n\n", getenv("HTTP_REFERER")); else { SBUF_MALLOC(returl, strlen( xgetenv("SECURECGIBINURL") ) + 11); snprintf(returl, returl_buflen, "%s/%s", xgetenv("SECURECGIBINURL"), "enadis.sh"); printf("Location: %s?\n\n", returl); } } else { printf("\n"); } /* It's ok with these hardcoded values, as they are not used for this page */ sethostenv("", "", "", colorname(COL_BLUE), NULL); if (preview) headfoot(stdout, "maintact", "", "header", COL_BLUE); if (debug) { printf("
\n");
		switch (action) {
		  case ACT_NONE   : dbgprintf("Action = none\n"); break;

		  case ACT_FILTER : dbgprintf("Action = filter\n"); break;

		  case ACT_ENABLE : dbgprintf("Action = enable\n"); 
				    dbgprintf("Tests = ");
				    for (i=0; (i < enablecount); i++) printf("%s ", enabletest[i]);
				    printf("\n");
				    break;

		  case ACT_DISABLE: dbgprintf("Action = disable\n"); 
				    dbgprintf("Tests = ");
				    for (i=0; (i < disablecount); i++) printf("%s ", disabletest[i]);
				    printf("\n");
				    if (disableend == DISABLE_UNTIL) {
				    	dbgprintf("Disable until: endtime = %d, duration = %d, scale = %d\n", endtime, duration, scale);
				     }	
			            else {
				    	dbgprintf("Duration = %d, scale = %d\n", duration, scale);
				    }
				    dbgprintf("Cause = %s\n", textornull(disablemsg));
				    break;

		  case ACT_SCHED_DISABLE:
				    dbgprintf("Action = schedule\n");
				    dbgprintf("Time = %s\n", ctime(&schedtime));
				    dbgprintf("Tests = ");
				    for (i=0; (i < disablecount); i++) printf("%s ", disabletest[i]);
				    printf("\n");
				    if (disableend == DISABLE_UNTIL) {
						  dbgprintf("Disable until: endtime = %d, duration = %d, scale = %d\n", endtime, duration, scale);
					  }	
			            else {
				    		  dbgprintf("Duration = %d, scale = %d\n", duration, scale);
				    }
				    dbgprintf("Cause = %s\n", textornull(disablemsg));
				    break;

		  case ACT_SCHED_CANCEL:
				    dbgprintf("Action = cancel\n");
				    dbgprintf("ID = %d\n", cancelid);
				    break;
		}
		printf("
\n"); } if (preview) printf("\n"); if (action == ACT_SCHED_CANCEL) { do_one_host(NULL, NULL, username); } else { /* Load the host data (for access control) */ if (accessfn) { load_web_access_config(accessfn); for (i = 0; (i < hostcount); i++) { if (web_access_allowed(getenv("REMOTE_USER"), hostnames[i], NULL, WEB_ACCESS_CONTROL)) { do_one_host(hostnames[i], fullmsg, username); } } } else { for (i = 0; (i < hostcount); i++) do_one_host(hostnames[i], fullmsg, username); } } if (preview) { printf("\n", xgetenv("HTTP_REFERER")); printf("


\n"); headfoot(stdout, "maintact", "", "footer", COL_BLUE); } return 0; } xymon-4.3.30/web/report.cgi.10000664000076400007640000000552313534041733016126 0ustar rpmbuildrpmbuild.TH REPORT.CGI 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME report.cgi \- CGI front-end to xymongen reporting .SH SYNOPSIS .B "report.cgi [\-\-noclean] [xymongen-options]" .SH DESCRIPTION \fBreport.cgi\fR is invoked as a CGI script via the report.sh CGI wrapper. It triggers the generation of a Xymon availability report for the timeperiod specified by the CGI parameters. report.cgi is passed a QUERY_STRING environment variable with the following parameters: start\-mon (Start month of the report) start\-day (Start day-of-month of the report) start\-yr (Start year of the report) end\-mon (End month of the report) end\-day (End day-of-month of the report) end\-yr (End year of the report) style (Report style) The following non-standard parameters are handled by the xymongen version of report.cgi: suburl (Page in report to go to, if not the top page) The "month" parameters must be specified as the three-letter english month name abbreviation: Jan, Feb, Mar ... Start- and end-days are in the range 1..31; the start- and end-year must be specified including century (e.g. "2003"). End-times beyond the current time are silently replaced with the current time. The generated report will include data for the start- and end-days, i.e. the report will begin at 00:00:00 of the start-day, and end at 23:59:59 of the end-day. The "style" parameter is passed directly to .I xymongen(1) and should be "crit", "non\-crit" or "all". Other values result in undefined behaviour. All of the processing involved in generating the report is done by invoking .I xymongen(1) with the proper "\-\-reportopts" option. .SH OPTIONS .IP \-\-noclean Do not clean the XYMONREPDIR directory of old reports. Makes the report-tool go a bit faster - instead, you can clean up the XYMONREPDIR directory e.g. via a cron-job. .IP "\-\-env=FILENAME" Load the environment from FILENAME before executing the CGI. .IP xymongen-options All other options passed to report.cgi are passed on to the .I xymongen(1) program building the report files. .SH FILES .IP $XYMONHOME/web/report_header HTML template header for the report request form .IP $XYMONHOME/web/report_footer HTML template footer for the report request form .IP $XYMONHOME/web/report_form HTML template report request form .SH "ENVIRONMENT VARIABLES" .IP XYMONGENREPOPTS xymongen options passed by default to the report.cgi. This happens in the report.sh wrapper. .IP XYMONHOME Home directory of the Xymon server installation .IP XYMONREPDIR Directory where generated reports are stored. This directory must be writable by the userid executing the CGI script, typically "www", "apache" or "nobody". Default: $XYMONHOME/www/rep/ .IP XYMONREPURL The URL prefix to use when accessing the reports via a browser. Default: $XYMONWEB/rep .SH "SEE ALSO" xymongen(1), hosts.cfg(5), xymonserver.cfg(5) xymon-4.3.30/web/hostlist.c0000664000076400007640000000760713515623702016013 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon hostlist report generator. */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: hostlist.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include "libxymon.h" cgidata_t *cgidata = NULL; char *pagefilter = NULL; char *testfilter = "cpu"; enum { SORT_IP, SORT_HOSTNAME } sortkey = SORT_HOSTNAME; char *fields = NULL; char csvchar = ','; void parse_query(void) { cgidata_t *cwalk; fields = strdup("XMH_HOSTNAME,XMH_IP"); cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "page") == 0) { pagefilter = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "filter") == 0) { testfilter = strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "sort") == 0) { if (strcasecmp(cwalk->value, "hostname") == 0) sortkey = SORT_HOSTNAME; else if (strcasecmp(cwalk->value, "ip") == 0) sortkey = SORT_IP; } else if (strncasecmp(cwalk->name, "XMH_", 4) == 0) { if (strcasecmp(cwalk->value, "on") == 0) { fields = (char *)realloc(fields, strlen(fields) + strlen(cwalk->name) + 2); strcat(fields, ","); strcat(fields, cwalk->name); } } else if (strcasecmp(cwalk->name, "csvdelim") == 0) { csvchar = *(cwalk->value); } cwalk = cwalk->next; } } int main(int argc, char *argv[]) { char *envarea = NULL; SBUF_DEFINE(req); char *board, *l; int argi, res; sendreturn_t *sres; char *cookie; pcre *dummy; init_timestamp(); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } } cookie = get_cookie("pagepath"); if (cookie) sethostenv_pagepath(cookie); cgidata = cgi_request(); if (cgidata == NULL) { /* Present the query form */ sethostenv("", "", "", colorname(COL_BLUE), NULL); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "hostlist", "hostlist_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } parse_query(); dummy = (testfilter ? compileregex(testfilter) : NULL); if (dummy == NULL) return 1; else freeregex(dummy); dummy = (pagefilter ? compileregex(pagefilter) : NULL); if (dummy == NULL) return 1; else freeregex(dummy); sres = newsendreturnbuf(1, NULL); SBUF_MALLOC(req, 1024 + strlen(fields) + strlen(testfilter) + strlen(pagefilter)); snprintf(req, req_buflen, "xymondboard fields=%s test=%s page=%s", fields, testfilter, pagefilter); res = sendmessage(req, NULL, XYMON_TIMEOUT, sres); if (res != XYMONSEND_OK) return 1; board = getsendreturnstr(sres, 1); freesendreturnbuf(sres); printf("Content-type: text/csv\n\n"); l = strtok(fields, ","); while (l) { printf("%s;", l); l = strtok(NULL, ",\n"); } printf("\n"); l = board; while (l && *l) { char *p; char *eoln = strchr(l, '\n'); if (eoln) *eoln = '\0'; do { p = strchr(l, '|'); if (p) *p = csvchar; } while (p); printf("%s\n", l); if (eoln) l = eoln+1; else l = NULL; } return 0; } xymon-4.3.30/web/xymonpage.cgi.10000664000076400007640000000161213534041733016615 0ustar rpmbuildrpmbuild.TH XYMONPAGE 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonpage \- Utility to show a webpage using header and footer .SH SYNOPSIS .B "xymonpage [options]" .SH DESCRIPTION \fBxymonpage\fR is a tool to generate a webpage in the Xymon style, with a standard header- and footer as well as a Xymon background. The data to present on the webpage, apart from the header and footer, are passed to xymonpage in stdin. The generated webpage is printed to stdout. .SH OPTIONS .IP "--env=FILENAME" Loads the environment defined in FILENAME before executing the CGI script. .IP "--hffile=PREFIX" Use the header- and footer-files in $XYMONHOME/web/PREFIX_header and PREFIX_footer. If not specified, stdnormal_header and stdnormal_footer are used. .IP "--color=COLOR" Set the background color of the generated webpage to COLOR. Default: Blue .IP "--debug" Enable debugging output. .SH "SEE ALSO" xymon(7) xymon-4.3.30/web/appfeed.c0000664000076400007640000001627613515623702015550 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon status-log viewer CGI. */ /* */ /* This CGI provides an XML interface to the xymondboard status. Intended for */ /* use by external user interfaces, e.g. smartphones. */ /* */ /* Copyright (C) 2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: svcstatus.c 6765 2011-10-13 11:55:08Z storner $"; #include #include #include #include "libxymon.h" static char *queryfilter = NULL; static char *boardcmd = "xymondboard"; static char *fieldlist = "fields=hostname,testname,color,lastchange,logtime,cookie,acktime,ackmsg,disabletime,dismsg,line1"; static char *colorlist = "color=red,yellow,purple"; static void errormsg(char *msg) { fprintf(stderr, "Refresh: 30\nContent-type: %s\n\nInvalid request\n%s\n", xgetenv("HTMLCONTENTTYPE"), msg); } static int parse_query(void) { cgidata_t *cgidata = cgi_request(); cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { if (strcasecmp(cwalk->name, "filter") == 0) { queryfilter = strdup(cwalk->value); } cwalk = cwalk->next; } if (!queryfilter) queryfilter = ""; /* See if the query includes a color filter - this overrides our default */ if ((strncmp(queryfilter, "color=", 6) == 0) || (strstr(queryfilter, " color=") != NULL)) colorlist = ""; return 0; } char *extractline(char *ptn, char **src) { char *pos = strstr(*src, ptn); char *eoln; if (pos == NULL) return NULL; eoln = strchr(pos, '\n'); if (eoln) *eoln = '\0'; if (pos == *src) *src = eoln+1; else *(pos-1) = '\0'; if (pos) pos += strlen(ptn); return pos; } int main(int argc, char **argv) { int argi; char *criticalconfig = NULL; char *envarea = NULL; char *accessfn = NULL; char *userid = getenv("REMOTE_USER"); FILE *output = stdout; SBUF_DEFINE(xymondreq); sendreturn_t *sres; int xymondresult; char *log, *bol, *eoln, *endkey; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--hobbit") == 0) { boardcmd = "hobbitdboard"; } else if (argnmatch(argv[argi], "--critical=")) { char *p = strchr(argv[argi], '='); criticalconfig = strdup(p+1); } else if (argnmatch(argv[argi], "--access=")) { char *p = strchr(argv[argi], '='); accessfn = strdup(p+1); } } /* Setup the query for xymond */ parse_query(); SBUF_MALLOC(xymondreq, strlen(boardcmd) + strlen(fieldlist) + strlen(colorlist) + strlen(queryfilter) + 5); snprintf(xymondreq, xymondreq_buflen, "%s %s %s %s", boardcmd, fieldlist, colorlist, queryfilter); /* Get the current status */ sres = newsendreturnbuf(1, NULL); xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres); if (xymondresult != XYMONSEND_OK) { SBUF_DEFINE(errtxt); SBUF_MALLOC(errtxt, 1024 + MAX_HTMLQUOTE_FACTOR*strlen(xymondreq)); snprintf(errtxt, errtxt_buflen, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult); errormsg(errtxt); return 1; } else { log = getsendreturnstr(sres, 1); } freesendreturnbuf(sres); /* Load the host data (for access control) */ if (accessfn) { load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_web_access_config(accessfn); } /* Load the critical config */ if (criticalconfig) load_critconfig(criticalconfig); fprintf(output, "Content-type: text/xml\n\n"); fprintf(output, "\n"); fprintf(output, "\n"); /* Step through the status board, one line at a time */ bol = log; while (bol && *bol) { int useit = 1; char *hostname, *testname, *color, *txt, *lastchange, *logtime, *cookie, *acktime, *ackmsg, *distime, *dismsg; eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; if (criticalconfig) { critconf_t *cfg; /* The key for looking up items in the critical config is "hostname|testname", which we already have */ endkey = strchr(bol, '|'); if (endkey) endkey = strchr(endkey+1, '|'); *endkey = '\0'; cfg = get_critconfig(bol, CRITCONF_TIMEFILTER, NULL); *endkey = '|'; if (!cfg) useit = 0; } if (useit) { hostname = gettok(bol, "|"); testname = (hostname ? gettok(NULL, "|") : NULL); if (accessfn) useit = web_access_allowed(userid, hostname, testname, WEB_ACCESS_VIEW); } if (useit) { color = (testname ? gettok(NULL, "|") : NULL); lastchange = (color ? gettok(NULL, "|") : NULL); logtime = (lastchange ? gettok(NULL, "|") : NULL); cookie = (logtime ? gettok(NULL, "|") : NULL); acktime = (cookie ? gettok(NULL, "|") : NULL); ackmsg = (acktime ? gettok(NULL, "|") : NULL); distime = (ackmsg ? gettok(NULL, "|") : NULL); dismsg = (distime ? gettok(NULL, "|") : NULL); txt = (dismsg ? gettok(NULL, "|") : NULL); if (txt) { /* We have all data */ fprintf(output, "\n"); fprintf(output, " %s\n", hostname); fprintf(output, " %s\n", testname); fprintf(output, " %s\n", color); fprintf(output, " %s\n", lastchange); fprintf(output, " %s\n", logtime); fprintf(output, " %s\n", cookie); if (atoi(acktime) != 0) { char *ackedby; nldecode(ackmsg); ackedby = extractline("Acked by: ", &ackmsg); fprintf(output, " %s\n", acktime); fprintf(output, " \n", ackmsg); if (ackedby) fprintf(output, " \n", ackedby); } if (atoi(distime) != 0) { char *disabledby; nldecode(dismsg); disabledby = extractline("Disabled by: ", &dismsg); if (strncmp(dismsg, "Reason: ", 8) == 0) dismsg += 8; fprintf(output, " %s\n", distime); fprintf(output, " \n", dismsg); if (disabledby) fprintf(output, " \n", disabledby); } fprintf(output, " \n", txt); fprintf(output, " \n", hostsvcurl(hostname, testname, 0)); fprintf(output, "\n"); } } if (eoln) { *eoln = '\n'; bol = eoln+1; } else bol = NULL; } fprintf(output, "\n"); xfree(log); return 0; } xymon-4.3.30/web/findhost.c0000664000076400007640000002106513515623702015752 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon host finder. */ /* */ /* This is a CGI script to find hosts in the Xymon webpages without knowing */ /* their full name. When you have 1200+ hosts split on 60+ pages, it can be */ /* tiresome to do a manual search to find a host ... */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /* 2004/09/08 - Werner Michels [wm] */ /* Added support regular expression on the host search. */ /* Minor changes on errormsg() and error messagess. */ /* The parse_query was rewritten to meet the new needs. */ /* */ /*----------------------------------------------------------------------------*/ /* * [wm] - Functionality change * Now the search is done using only Extended POSIX pattern match. * If you don't know how Regex works, look at "man 7 regex". * If you want search for multiple hosts use "name1|name2|name3" insted * of separating them by spaces. You can now search for host (displayname) * with spaces. * Emtpy search string will list all the hosts. * * * * [wm] - TODO * - Move the new global vars to local vars and use function parameters * - Verify the security implication of removing the urlvalidate() call * - Move to POST instead of GET to receive the FORM data * - Add the posibility to choose where to search (hostname, description * host comment, host displayname, host clientname...) * */ static char rcsid[] = "$Id: findhost.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include /*[wm] For the POSIX regex support*/ #include #include "libxymon.h" /* Global vars */ /* * [wm] To support regex searching */ char *pSearchPat = NULL; /* What're searching for (now its regex, not a hostlist) */ int re_flag = REG_EXTENDED|REG_NOSUB|REG_ICASE; /* default regcomp flags see man 3 regcomp */ /* You must remove REG_ICASE for case sensitive */ cgidata_t *cgidata = NULL; int dojump = 0; /* If set and there is only one page, go directly to it */ void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Xymon FindHost Error\n"); printf("


%s\n", msg); exit(1); } void parse_query(void) { cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "host") == 0) { pSearchPat = (char *)strdup(cwalk->value); } else if (strcasecmp(cwalk->name, "case_sensitive") == 0 ) { /* remove the ignore case flag */ re_flag ^= REG_ICASE; } else if (strcasecmp(cwalk->name, "jump") == 0 ) { dojump = 1; } cwalk = cwalk->next; } } void print_header(void) { /* It's ok with these hardcoded values, as they are not used for this page */ sethostenv("", "", "", colorname(COL_BLUE), NULL); printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); headfoot(stdout, "findhost", "", "header", COL_BLUE); printf("

\n"); printf("\n"); } void print_footer(void) { printf("
Hostname (DisplayName)IPLocation (Group Name)
\n"); headfoot(stdout, "findhost", "", "footer", COL_BLUE); } int main(int argc, char *argv[]) { void *hostwalk, *clonewalk; int argi; char *envarea = NULL; strbuffer_t *outbuf; SBUF_DEFINE(oneurl); int gotany = 0; enum { OP_INITIAL, OP_YES, OP_NO } gotonepage = OP_INITIAL; /* Tracks if all matches are on one page */ char *onepage = NULL; /* If gotonepage==OP_YES, then this is the page */ /*[wm] regex support */ #define BUFSIZE 256 regex_t re; char re_errstr[BUFSIZE]; int re_status; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } } redirect_cgilog("findhost"); cgidata = cgi_request(); if (cgidata == NULL) { /* Present the query form */ sethostenv("", "", "", colorname(COL_BLUE), NULL); printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, "findhost", "findhost_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL); return 0; } parse_query(); if ( (re_status = regcomp(&re, pSearchPat, re_flag)) != 0 ) { regerror(re_status, &re, re_errstr, BUFSIZE); print_header(); printf("%s\n", htmlquoted(pSearchPat)); printf("%s\n", re_errstr); print_footer(); return 0; } outbuf = newstrbuffer(0); load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); hostwalk = first_host(); while (hostwalk) { /* * [wm] - Allow the search to be done on the hostname * also on the "displayname" and the host comment * Maybe this should be implemented by changing the HTML form, but until than.. * we're supposing that hostname will NEVER be null */ char *hostname, *displayname, *comment, *ip; hostname = xmh_item(hostwalk, XMH_HOSTNAME); displayname = xmh_item(hostwalk, XMH_DISPLAYNAME); comment = xmh_item(hostwalk, XMH_COMMENT); ip = xmh_item(hostwalk, XMH_IP); if ( regexec (&re, hostname, (size_t)0, NULL, 0) == 0 || (regexec(&re, ip, (size_t)0, NULL, 0) == 0) || (displayname && regexec (&re, displayname, (size_t)0, NULL, 0) == 0) || (comment && regexec (&re, comment, (size_t)0, NULL, 0) == 0) ) { /* match */ addtobuffer_many(outbuf, "\n", " ", (displayname ? displayname : hostname), " \n", " ", ip, " \n", NULL); SBUF_MALLOC(oneurl, 4 + strlen(xgetenv("XYMONWEB")) + strlen(xmh_item(hostwalk, XMH_PAGEPATH)) + strlen(hostname)); snprintf(oneurl, oneurl_buflen, "%s/%s/#%s", xgetenv("XYMONWEB"), xmh_item(hostwalk, XMH_PAGEPATH), hostname); addtobuffer_many(outbuf, " ", xmh_item(hostwalk, XMH_PAGEPATHTITLE), "\n", NULL); gotany++; /* See if all of the matches so far are on one page */ switch (gotonepage) { case OP_INITIAL: gotonepage = OP_YES; onepage = xmh_item(hostwalk, XMH_PAGEPATH); break; case OP_YES: if (strcmp(onepage, xmh_item(hostwalk, XMH_PAGEPATH)) != 0) gotonepage = OP_NO; break; case OP_NO: break; } clonewalk = next_host(hostwalk, 1); while (clonewalk && (strcmp(xmh_item(hostwalk, XMH_HOSTNAME), xmh_item(clonewalk, XMH_HOSTNAME)) == 0)) { addtobuffer_many(outbuf, "
", xmh_item(clonewalk, XMH_PAGEPATHTITLE), "\n", NULL); clonewalk = next_host(clonewalk, 1); gotany++; } addtobuffer(outbuf, "\n\n"); hostwalk = clonewalk; } else { hostwalk = next_host(hostwalk, 0); } } regfree (&re); /*[wm] - free regex compiled patern */ if (dojump) { if (gotany == 1) { printf("Location: %s\n\n", oneurl); return 0; } else if ((gotany > 1) && (gotonepage == OP_YES)) { printf("Location: %s/%s/\n\n", xgetenv("XYMONWEB"), onepage); return 0; } } print_header(); if (!gotany) { printf("%sNot found\n", htmlquoted(pSearchPat)); } else { printf("%s", grabstrbuffer(outbuf)); } print_footer(); /* [wm] - Free the strdup allocated memory */ if (pSearchPat) xfree(pSearchPat); return 0; } xymon-4.3.30/web/useradm.c0000664000076400007640000001424613515623702015577 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: useradm.c 6588 2010-11-14 17:21:19Z storner $"; #include #include #include #include #include #include "libxymon.h" static void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } static int idcompare(const void *p1, const void *p2) { return strcmp(* (char * const *) p1, * (char * const *) p2); } #define ACT_NONE 0 #define ACT_CREATE 1 #define ACT_DELETE 2 char *adduser_name = NULL; char *adduser_password = NULL; char *deluser_name = NULL; int parse_query(void) { cgidata_t *cgidata, *cwalk; int returnval = ACT_NONE; cgidata = cgi_request(); if (cgi_method != CGI_POST) return ACT_NONE; if (cgidata == NULL) errormsg(cgi_error()); cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcmp(cwalk->name, "USERNAME") == 0) { adduser_name = cwalk->value; } else if (strcmp(cwalk->name, "PASSWORD") == 0) { adduser_password = cwalk->value; } else if (strcmp(cwalk->name, "USERLIST") == 0) { deluser_name = cwalk->value; } else if (strcmp(cwalk->name, "SendCreate") == 0) { returnval = ACT_CREATE; } else if (strcmp(cwalk->name, "SendDelete") == 0) { returnval = ACT_DELETE; } cwalk = cwalk->next; } /* We only want to accept posts from certain pages */ if (returnval != ACT_NONE) { char cgisource[1024]; char *p; p = csp_header("useradm"); if (p) fprintf(stdout, "%s", p); snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "useradm"); if (!cgi_refererok(cgisource)) { fprintf(stdout, "Location: %s.sh?\n\n", cgisource); return 0; } } return returnval; } int main(int argc, char *argv[]) { int argi, event; char *envarea = NULL; char *hffile = "useradm"; SBUF_DEFINE(passfile); FILE *fd; char *infomsg = NULL; for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--passwdfile=")) { char *p = strchr(argv[argi], '='); passfile = strdup(p+1); } } if (passfile == NULL) { SBUF_MALLOC(passfile, strlen(xgetenv("XYMONHOME")) + 20); snprintf(passfile, passfile_buflen, "%s/etc/xymonpasswd", xgetenv("XYMONHOME")); } event = parse_query(); if (adduser_name && !issimpleword(adduser_name)) { event = ACT_NONE; adduser_name = strdup(""); infomsg = "Invalid USERNAME. Letters, numbers, dashes, and periods only.\n"; } switch (event) { case ACT_NONE: /* Show the form */ break; case ACT_CREATE: /* Add a user */ { pid_t childpid; int n, ret; childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (childpid == 0) { /* child */ char *cmd; char **cmdargs; cmdargs = (char **) calloc(4 + 2, sizeof(char *)); cmdargs[0] = cmd = strdup("htpasswd"); cmdargs[1] = "-b"; cmdargs[2] = strdup(passfile); cmdargs[3] = strdup(adduser_name); cmdargs[4] = strdup(adduser_password); cmdargs[5] = '\0'; execvp(cmd, cmdargs); exit(127); } /* parent waits for htpasswd to finish */ if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { infomsg = "Update FAILED"; } else { infomsg = "User added/updated"; } } break; case ACT_DELETE: /* Delete a user */ { pid_t childpid; int n, ret; childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (childpid == 0) { /* child */ char *cmd; char **cmdargs; cmdargs = (char **) calloc(3 + 2, sizeof(char *)); cmdargs[0] = cmd = strdup("htpasswd"); cmdargs[1] = "-D"; cmdargs[2] = strdup(passfile); cmdargs[3] = strdup(deluser_name); cmdargs[4] = '\0'; execvp(cmd, cmdargs); exit(127); } /* parent waits for htpasswd to finish */ if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { infomsg = "Update delete FAILED"; } else { infomsg = "User deleted"; } } break; } sethostenv_clearlist(NULL); sethostenv_addtolist(NULL, "", "", NULL, 1); /* Have a blank entry first so we won't delete one by accident */ fd = fopen(passfile, "r"); if (fd != NULL) { char l[1024]; char *id, *delim; int usercount; char **userlist; int i; usercount = 0; userlist = (char **)calloc(usercount+1, sizeof(char *)); while (fgets(l, sizeof(l), fd)) { id = l; delim = strchr(l, ':'); if (delim) { *delim = '\0'; usercount++; userlist = (char **)realloc(userlist, (usercount+1)*sizeof(char *)); userlist[usercount-1] = strdup(id); userlist[usercount] = NULL; } } fclose(fd); qsort(&userlist[0], usercount, sizeof(char *), idcompare); for (i=0; (userlist[i]); i++) sethostenv_addtolist(NULL, userlist[i], userlist[i], NULL, 0); } fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); showform(stdout, hffile, "useradm_form", COL_BLUE, getcurrenttime(NULL), infomsg, NULL); return 0; } xymon-4.3.30/web/enadis.cgi.80000664000076400007640000000335313534041733016064 0ustar rpmbuildrpmbuild.TH ENADIS.CGI 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME enadis.cgi \- CGI program to enable/disable Xymon tests .SH SYNOPSIS .B "enadis.cgi (invoked via CGI from webserver)" .SH DESCRIPTION \fBenadis.cgi\fR is a CGI tool for disabling and enabling hosts and tests monitored by Xymon. You can disable monitoring of a single test, all tests for a host, or multiple hosts - immediately or at a future point in time. enadis.cgi runs as a CGI program, invoked by your webserver. It is normally run via a wrapper shell-script in the secured CGI directory for Xymon. enadis.cgi is the back-end script for the enable/disable form present on the "info" status-pages. It can also run in "stand-alone" mode, in which case it displays a web form allowing users to select what to enable or disable. .SH OPTIONS .IP "\-\-no\-cookies" Normally, enadis.cgi uses a cookie sent by the browser to initially filter the list of hosts presented. If this is not desired, you can turn off this behaviour by calling acknowledge.cgi with the \-\-no\-cookies option. This would normally be placed in the CGI_ENADIS_OPTS setting in .I cgioptions.cfg(5) .IP "\-\-env=FILENAME" Load the environment from FILENAME before executing the CGI. .IP "\-\-area=NAME" Load environment variables for a specific area. NB: if used, this option must appear before any \-\-env=FILENAME option. .SH FILES .IP "$XYMONHOME/web/maint_{header,form,footer}" HTML template header .SH BUGS When using alternate pagesets, hosts will only show up on the Enable/Disable page if this is accessed from the primary page in which they are defined. So if you have hosts on multiple pages, they will only be visible for disabling from their main page which is not what you would expect. .SH "SEE ALSO" xymon(7) xymon-4.3.30/web/reportlog.c0000664000076400007640000001351713522107743016154 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon report-mode statuslog viewer. */ /* */ /* This tool generates the report status log for a single status, with the */ /* availability percentages etc needed for a report-mode view. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: reportlog.c 8072 2019-08-05 20:21:55Z jccleaver $"; #include #include #include #include #include #include #include "libxymon.h" char *hostname = NULL; char *displayname = NULL; char *ip = NULL; SBUF_DEFINE(reporttime); char *service = NULL; time_t st, end; int style; int color; double reportgreenlevel = 99.995; double reportwarnlevel = 98.0; int reportwarnstops = -1; cgidata_t *cgidata = NULL; static void errormsg(char *msg) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("Invalid request\n"); printf("%s\n", msg); exit(1); } static void parse_query(void) { cgidata_t *cwalk; cwalk = cgidata; while (cwalk) { /* * cwalk->name points to the name of the setting. * cwalk->value points to the value (may be an empty string). */ if (strcasecmp(cwalk->name, "HOSTSVC") == 0) { char *p = cwalk->value + strspn(cwalk->value, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:,.\\/_-"); *p = '\0'; p = strrchr(cwalk->value, '.'); if (p) { *p = '\0'; service = strdup(p+1); } hostname = strdup(basename(cwalk->value)); while ((p = strchr(hostname, ','))) *p = '.'; } else if (strcasecmp(cwalk->name, "HOST") == 0) { char *p = cwalk->value + strspn(cwalk->value, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:,._-"); *p = '\0'; hostname = strdup(basename(cwalk->value)); } else if (strcasecmp(cwalk->name, "SERVICE") == 0) { char *p = cwalk->value + strspn(cwalk->value, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:\\/_-"); *p = '\0'; service = strdup(basename(cwalk->value)); } else if (strcasecmp(cwalk->name, "REPORTTIME") == 0) { SBUF_MALLOC(reporttime, strlen(cwalk->value)+strlen("REPORTTIME=")+1); snprintf(reporttime, reporttime_buflen, "REPORTTIME=%s", cwalk->value); } else if (strcasecmp(cwalk->name, "WARNPCT") == 0) { reportwarnlevel = atof(cwalk->value); } else if (strcasecmp(cwalk->name, "STYLE") == 0) { if (strcmp(cwalk->value, "crit") == 0) style = STYLE_CRIT; else if (strcmp(cwalk->value, "nongr") == 0) style = STYLE_NONGR; else style = STYLE_OTHER; } else if (strcasecmp(cwalk->name, "ST") == 0) { /* Must be after "STYLE" */ st = atol(cwalk->value); } else if (strcasecmp(cwalk->name, "END") == 0) { end = atol(cwalk->value); } else if (strcasecmp(cwalk->name, "COLOR") == 0) { SBUF_DEFINE(colstr); SBUF_MALLOC(colstr, strlen(cwalk->value)+2); snprintf(colstr, colstr_buflen, "%s ", cwalk->value); color = parse_color(colstr); xfree(colstr); } else if (strcasecmp(cwalk->name, "RECENTGIFS") == 0) { use_recentgifs = atoi(cwalk->value); } cwalk = cwalk->next; } } int main(int argc, char *argv[]) { SBUF_DEFINE(histlogfn); FILE *fd; SBUF_DEFINE(textrepfn); SBUF_DEFINE(textrepfullfn); SBUF_DEFINE(textrepurl); FILE *textrep; reportinfo_t repinfo; int argi; char *envarea = NULL; void *hinfo; SBUF_MALLOC(histlogfn, PATH_MAX); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } } redirect_cgilog("reportlog"); cgidata = cgi_request(); parse_query(); load_hostinfo(hostname); if ((hinfo = hostinfo(hostname)) == NULL) { errormsg("No such host"); return 1; } ip = xmh_item(hinfo, XMH_IP); displayname = xmh_item(hinfo, XMH_DISPLAYNAME); if (!displayname) displayname = hostname; snprintf(histlogfn, histlogfn_buflen, "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service); fd = fopen(histlogfn, "r"); if (fd == NULL) { errormsg("Cannot open history file"); } color = parse_historyfile(fd, &repinfo, hostname, service, st, end, 0, reportwarnlevel, reportgreenlevel, reportwarnstops, reporttime); fclose(fd); SBUF_MALLOC(textrepfn, 1024 + strlen(hostname) + strlen(service)); snprintf(textrepfn, textrepfn_buflen, "avail-%s-%s-%u-%lu.txt", hostname, service, (unsigned int)getcurrenttime(NULL), (unsigned long)getpid()); SBUF_MALLOC(textrepfullfn, 1024 + strlen(xgetenv("XYMONREPDIR")) + strlen(textrepfn)); snprintf(textrepfullfn, textrepfullfn_buflen, "%s/%s", xgetenv("XYMONREPDIR"), textrepfn); SBUF_MALLOC(textrepurl, 1024 + strlen(xgetenv("XYMONREPURL")) + strlen(textrepfn)); snprintf(textrepurl, textrepurl_buflen, "%s/%s", xgetenv("XYMONREPURL"), textrepfn); textrep = fopen(textrepfullfn, "w"); /* Now generate the webpage */ printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); generate_replog(stdout, textrep, textrepurl, hostname, service, color, style, ip, displayname, st, end, reportwarnlevel, reportgreenlevel, reportwarnstops, &repinfo); if (textrep) fclose(textrep); return 0; } xymon-4.3.30/web/Makefile0000664000076400007640000001714612615453444015441 0ustar rpmbuildrpmbuildXYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) PROGRAMS = history.cgi eventlog.cgi report.cgi reportlog.cgi snapshot.cgi findhost.cgi csvinfo.cgi acknowledge.cgi xymonpage datepage.cgi svcstatus.cgi enadis.cgi confreport.cgi criticalview.cgi criticaleditor.cgi ackinfo.cgi statusreport.cgi boilerplate.cgi hostgraphs.cgi ghostlist.cgi notifications.cgi acknowledgements.cgi hostlist.cgi useradm.cgi chpasswd.cgi appfeed.cgi cgiwrap CGISCRIPTS = history.sh eventlog.sh report.sh reportlog.sh snapshot.sh findhost.sh csvinfo.sh columndoc.sh datepage.sh svcstatus.sh historylog.sh confreport.sh confreport-critical.sh criticalview.sh certreport.sh nongreen.sh hostgraphs.sh ghostlist.sh notifications.sh acknowledgements.sh hostlist.sh topchanges.sh appfeed.sh appfeed-critical.sh SECCGISCRIPTS = acknowledge.sh enadis.sh criticaleditor.sh ackinfo.sh useradm.sh chpasswd.sh ifeq ($(DORRD),yes) PROGRAMS += showgraph.cgi perfdata.cgi CGISCRIPTS += showgraph.sh perfdata.sh endif CGIWRAPOBJS = cgiwrap.o HISTOBJS = history.o EVENTLOGOBJS = eventlog.o REPOBJS = report.o REPLOGOBJS = reportlog.o SNAPOBJS = snapshot.o FINDHOSTOBJS = findhost.o CSVINFOOBJS = csvinfo.o ACKCGIOBJS = acknowledge.o WEBPAGEOBJS = xymonpage.o DATEPAGEOBJS = datepage.o APPFEEDOBJS = appfeed.o SHOWGRAPHOBJS = showgraph.o SVCSTATUSOBJS = svcstatus.o svcstatus-info.o svcstatus-trends.o ENADISOBJS = enadis.o CRITVIEWOBJS = criticalview.o CRITEDITOBJS = criticaleditor.o ACKINFOOBJS = ackinfo.o CONFREPOBJS = confreport.o STATUSREPOBJS = statusreport.o MAILACKOBJS = xymon-mailack.o GHOSTOBJS = ghostlist.o NOTIFYOBJS = notifications.o ACKNOWLEDGEOBJS = acknowledgements.o HOSTLISTOBJS = hostlist.o PERFDATAOBJS = perfdata.o USERADMOBJS = useradm.o CHPASSWDOBJS = chpasswd.o HOSTGRAPHSOBJS = hostgraphs.o BOILERPLATEOBJS = boilerplate.o IDTOOL := $(shell if test `uname -s` = "SunOS"; then echo /usr/xpg4/bin/id; else echo id; fi) all: $(PROGRAMS) cgiwrap.o: cgiwrap.c $(CC) $(CFLAGS) -DXYMONHOME=\"$(XYMONHOME)\" -c -o $@ $< cgiwrap: $(CGIWRAPOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(CGIWRAPOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) history.cgi: $(HISTOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(HISTOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) eventlog.cgi: $(EVENTLOGOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(EVENTLOGOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) report.cgi: $(REPOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(REPOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) reportlog.cgi: $(REPLOGOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(REPLOGOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) snapshot.cgi: $(SNAPOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(SNAPOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) findhost.cgi: $(FINDHOSTOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(FINDHOSTOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) csvinfo.cgi: $(CSVINFOOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(CSVINFOOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) acknowledge.cgi: $(ACKCGIOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(ACKCGIOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) xymonpage: $(WEBPAGEOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(WEBPAGEOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) datepage.cgi: $(DATEPAGEOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(DATEPAGEOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) showgraph.o: showgraph.c $(CC) $(CFLAGS) $(PCREINCDIR) $(RRDDEF) $(RRDINCDIR) -c -o $@ $< # Need NETLIBS on Solaris for getservbyname(), called by parse_url() showgraph.cgi: $(SHOWGRAPHOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(SHOWGRAPHOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) $(RRDLIBS) svcstatus.cgi: $(SVCSTATUSOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(SVCSTATUSOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) enadis.cgi: $(ENADISOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(ENADISOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) statusreport.cgi: $(STATUSREPOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(STATUSREPOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) confreport.cgi: $(CONFREPOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(CONFREPOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) criticalview.cgi: $(CRITVIEWOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(CRITVIEWOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) criticalview.o: criticalview.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< criticaleditor.cgi: $(CRITEDITOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(CRITEDITOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) ackinfo.cgi: $(ACKINFOOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(ACKINFOOBJS) $(XYMONCOMMLIBS) boilerplate.cgi: $(BOILERPLATEOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(BOILERPLATEOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) hostgraphs.cgi: $(HOSTGRAPHSOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(HOSTGRAPHSOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) ghostlist.cgi: $(GHOSTOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(GHOSTOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) notifications.cgi: $(NOTIFYOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(NOTIFYOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) acknowledgements.cgi: $(ACKNOWLEDGEOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(ACKNOWLEDGEOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) hostlist.cgi: $(HOSTLISTOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(HOSTLISTOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) perfdata.o: perfdata.c $(CC) $(CFLAGS) $(PCREINCDIR) $(RRDDEF) $(RRDINCDIR) -c -o $@ $< # Need -lm on perfdata because it refers to isnan() perfdata.cgi: $(PERFDATAOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(PERFDATAOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) $(RRDLIBS) -lm useradm.cgi: $(USERADMOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(USERADMOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) chpasswd.cgi: $(CHPASSWDOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(CHPASSWDOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) appfeed.cgi: $(APPFEEDOBJS) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(APPFEEDOBJS) $(XYMONCOMMLIBS) $(XYMONLIBS) $(PCRELIBS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(PROGRAMS) *.o *~ install: install-bin install-cgi install-man install-bin: ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ install-cgi: mkdir -p $(INSTALLROOT)$(CGIDIR) mkdir -p $(INSTALLROOT)$(SECURECGIDIR) ifndef PKGBUILD for F in $(CGISCRIPTS); do ln -f $(INSTALLROOT)$(INSTALLBINDIR)/cgiwrap $(INSTALLROOT)$(CGIDIR)/$$F; done for F in $(SECCGISCRIPTS); do ln -f $(INSTALLROOT)$(INSTALLBINDIR)/cgiwrap $(INSTALLROOT)$(SECURECGIDIR)/$$F; done else for F in $(CGISCRIPTS); do ln -f $(INSTALLROOT)$(INSTALLBINDIR)/cgiwrap $(INSTALLROOT)$(CGIDIR)/$$F; done for F in $(SECCGISCRIPTS); do ln -f $(INSTALLROOT)$(INSTALLBINDIR)/cgiwrap $(INSTALLROOT)$(SECURECGIDIR)/$$F; done endif install-man: ifndef PKGBUILD chown $(XYMONUSER) *.1 *.5 *.8 chgrp `$(IDTOOL) -g $(XYMONUSER)` *.1 *.5 *.8 chmod 644 *.1 *.5 *.8 endif mkdir -p $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 chmod 755 $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 endif cp -fp *.1 $(INSTALLROOT)$(MANROOT)/man1/ cp -fp *.5 $(INSTALLROOT)$(MANROOT)/man5/ cp -fp *.8 $(INSTALLROOT)$(MANROOT)/man8/ xymon-4.3.30/web/statusreport.c0000664000076400007640000001515413515623702016715 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon status report generator. */ /* */ /* This is a CGI program to generate a simple HTML table with a summary of */ /* all FOO statuses for a group of hosts. */ /* */ /* E.g. this can generate a report of all SSL certificates that are about */ /* to expire. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: statusreport.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { char *envarea = NULL; char *server = NULL; char *cookie; SBUF_DEFINE(pagefilter); SBUF_DEFINE(filter); SBUF_DEFINE(heading); int showcolors = 1; int showcolumn = 0; int addlink = 0; int allhosts = 0; int summary = 0; int embedded = 0; SBUF_DEFINE(req); char *board, *l; int argi, res; sendreturn_t *sres; pagefilter = filter = ""; init_timestamp(); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if ( argnmatch(argv[argi], "--column=") || argnmatch(argv[argi], "--test=")) { char *p = strchr(argv[argi], '='); int needed, curlen = (filter ? strlen(filter) : 0); needed = 10 + strlen(p); if (filter) needed += curlen; if (filter) { SBUF_REALLOC(filter, needed); } else { SBUF_CALLOC(filter, 1, needed); } snprintf(filter + curlen, filter_buflen - curlen, " test=%s", p+1); if (!heading) { SBUF_MALLOC(heading, 1024 + strlen(p) + strlen(timestamp)); snprintf(heading, heading_buflen, "%s report on %s", p+1, timestamp); } } else if (argnmatch(argv[argi], "--filter=")) { char *p = strchr(argv[argi], '='); int needed, curlen = (filter ? strlen(filter) : 0); needed = 10 + strlen(p); if (filter) needed += curlen; if (filter) { SBUF_REALLOC(filter, needed); } else { SBUF_CALLOC(filter, 1, needed); } snprintf(filter + curlen, filter_buflen - curlen, " %s", p+1); } else if (argnmatch(argv[argi], "--heading=")) { char *p = strchr(argv[argi], '='); heading = strdup(p+1); } else if (strcmp(argv[argi], "--show-column") == 0) { showcolumn = 1; } else if (strcmp(argv[argi], "--show-test") == 0) { showcolumn = 1; } else if (strcmp(argv[argi], "--show-colors") == 0) { showcolors = 1; } else if (strcmp(argv[argi], "--show-summary") == 0) { summary = 1; } else if (strcmp(argv[argi], "--show-message") == 0) { summary = 0; } else if (strcmp(argv[argi], "--link") == 0) { addlink = 1; } else if (strcmp(argv[argi], "--no-colors") == 0) { showcolors = 0; } else if (strcmp(argv[argi], "--all") == 0) { allhosts = 1; } else if (strcmp(argv[argi], "--embedded") == 0) { embedded = 1; } } if (!filter) allhosts = 1; if (!allhosts) { /* Setup the filter we use for the report */ cookie = get_cookie("pagepath"); if (cookie && *cookie) { pcre *dummy; SBUF_DEFINE(re); SBUF_MALLOC(re, 8 + 2*strlen(cookie)); snprintf(re, re_buflen, "^%s$|^%s/.+", cookie, cookie); dummy = compileregex(re); if (dummy) { freeregex(dummy); SBUF_MALLOC(pagefilter, 10 + strlen(re)); snprintf(pagefilter, pagefilter_buflen, "page=%s", re); } xfree(re); } } sres = newsendreturnbuf(1, NULL); SBUF_MALLOC(req, 1024 + strlen(pagefilter) + strlen(filter)); snprintf(req, req_buflen, "xymondboard fields=hostname,testname,color,msg %s %s", pagefilter, filter); res = sendmessage(req, server, XYMON_TIMEOUT, sres); board = getsendreturnstr(sres, 1); freesendreturnbuf(sres); if (res != XYMONSEND_OK) return 1; if (!embedded) { printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); printf("%s\n", htmlquoted(heading)); printf(""); printf("\n", (showcolumn ? "Host/Column" : "Host")); } l = board; while (l && *l) { char *hostname, *testname = NULL, *colorstr = NULL, *msg = NULL, *p; char *eoln = strchr(l, '\n'); if (eoln) *eoln = '\0'; hostname = l; p = strchr(l, '|'); if (p) { *p = '\0'; l = testname = p+1; } p = strchr(l, '|'); if (p) { *p = '\0'; l = colorstr = p+1; } p = strchr(l, '|'); if (p) { *p = '\0'; l = msg = p+1; } if (hostname && testname && colorstr && msg) { char *msgeol; nldecode(msg); msgeol = strchr(msg, '\n'); if (msgeol) { /* Skip the first status line */ msg = msgeol + 1; } printf("\n"); printf("\n"); } if (eoln) l = eoln+1; else l = NULL; } if (!embedded) printf("
%sStatus
"); if (addlink) printf("%s", hostsvcurl(hostname, xgetenv("INFOCOLUMN"), 1), htmlquoted(hostname)); else printf("%s", htmlquoted(hostname)); if (showcolumn) { printf("
"); if (addlink) printf("%s", hostsvcurl(hostname, testname, 1), htmlquoted(testname)); else printf("%s", htmlquoted(testname)); } if (showcolors) printf(" - %s", colorstr); printf("
\n");

			if (summary) {
				int firstline = 1;
				char *bol, *eol;

				bol = msg;
				while (bol) {
					eol = strchr(bol, '\n'); if (eol) *eol = '\0';

					if (firstline) {
						if (!isspace((int)*bol)) {
							printf("%s\n", bol);
							firstline = 0;
						}
					}
					else if ((*bol == '&') && (strncmp(bol, "&green", 6) != 0)) {
						printf("%s\n", bol);
					}

					bol = (eol ? eol+1 : NULL);
				}
			}
			else {
				printf("%s", msg);
			}

			printf("
\n"); return 0; } xymon-4.3.30/web/graphs.cfg.50000664000076400007640000000777313534041733016111 0ustar rpmbuildrpmbuild.TH GRAPHS.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME graphs.cfg \- Configuration of the showgraph CGI .SH SYNOPSIS .B $XYMONHOME/etc/graphs.cfg .SH DESCRIPTION .I showgraph.cgi(1) uses the configuration file $XYMONHOME/etc/graphs.cfg to build graphs from the RRD files collected by Xymon. .SH FILE FORMAT Each definition of a graph type begins with a "[SERVICE]" indicator, this is the name passed as the "service" parameter to .I showgraph.cgi(1). If the service name passed to showgraph.cgi is not found, it will attempt to match the service name to a graph via the TEST2RRD environment variable. So calling showgraph.cgi with "service=cpu" or "service=la" will end up producing the same graph. A graph definition needs to have a TITLE and a YAXIS setting. These are texts shown as the title of the graph, and the YAXIS heading respectively. (The X-axis is always time-based). If a fixed set of RRD files are used for the graph, you just write those in the RRDtool definitions. Note that Xymon keeps all RRD files for a host in a separate directory per host, so you need not worry about the hostname being part of the RRD filename. For graphs that use multiple RRD files as input, you specify a filename pattern in the FNPATTERN statement, and optionally a pattern of files to exclude from the graph with EXFNPATTERN (see "[tcp]" for an example). When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each file in the set. "@RRDPARAM@" contains the first word extracted from the pattern of files (see e.g. "[memory]" how this is used). "@COLOR@" picks a new color for each graph automatically. The remainder of the lines in each definition are passed directly to the RRDtool rrd_graph() routine. The following is an example of how the "la" (cpu) graph is defined. This is a simple definition that uses a single RRD-file, la.rrd: .sp [la] .br TITLE CPU Load .br YAXIS Load .br DEF:avg=la.rrd:la:AVERAGE .br CDEF:la=avg,100,/ .br AREA:la#00CC00:CPU Load Average .br GPRINT:la:LAST: \: %5.1lf (cur) .br GPRINT:la:MAX: \: %5.1lf (max) .br GPRINT:la:MIN: \: %5.1lf (min) .br GPRINT:la:AVERAGE: \: %5.1lf (avg)\\n .sp Here is an example of a graph that uses multiple RRD-files, determined automatically at run-time via the FNPATTERN setting. Note how it uses the @RRDIDX@ to define a unique RRD parameter per input-file, and the @COLOR@ and @RRDPARAM@ items to pick unique colors and a matching text for the graph legend: .sp [disk] .br FNPATTERN disk(.*).rrd .br TITLE Disk Utilization .br YAXIS % Full .br DEF:p@RRDIDX@=@RRDFN@:pct:AVERAGE .br LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ .br \-u 100 .br \-l 0 .br GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) .br GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) .br GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) .br GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\\n .SH ADVANCED GRAPH TITLES Normally the title of a graph is a static text defined in the graphs.cfg file. However, there may be situations where you want to use different titles for the same type of graph, e.g. if you are incorporating RRD files from MRTG into Xymon. In that case you can setup the TITLE definition so that it runs a custom script to determine the graph title. Like this: .sp TITLE exec:/usr/local/bin/graphitle .sp The \fB/usr/local/bin/graphtitle\fR command is then called with the hostname, the graphtype, the period string, and all of the RRD files used as parameters. The script must generate one line of output, which is then used as the title of the graph. Each of the RRD pathname parameters will be enclosed in double quotes. .SH ENVIRONMENT .BR TEST2RRD Maps service names to graph definitions. .SH NOTES Most of the RRD graph definitions shipped with Xymon have been ported from the definitions in the \fBlarrd\-grapher.cgi\fR CGI from LARRD 0.43c. .SH "SEE ALSO" xymonserver.cfg(5), rrdtool(1), rrdgraph(1) xymon-4.3.30/docs/0000775000076400007640000000000013534041774014143 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/mainview.jpg0000664000076400007640000013671411070452713016470 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀº"ÿÄ ÿÄ] !1A"Q“Ó2TUW’•ÑSV–ÒÔ#3Baq$%45Rbst…‘²Á 7‚„¡±ðCDdu³µÂ&Erƒá´ÿÄÿÄ<Q!1S‘ÑA3RaqÒð"¡±Á2BCáñ#’ÂbcrÿÚ ?ôôùrÓ:BS)ä¤Q‡b+˜ørÙž–ÿxaQÿIÿJ¯üÌT4ª/Ò¾*ªy„꼞¿ûé=ì³bå _²O']òß2hޱŸ›çfK9œQê›Ö+*zKíÈq´´ê–FQÜCObê‘¡Ç“Iïr¶Ã¶Ã–Ìô·ûúñUº©b£œ'S©8¿“µ‹XQªQÐËvIð¶„ßyï;žÑð,WŽ!á\EQyú–DáY•H’êÙtIih6ÅçhóþЕl©#Qæ°ïå³=-þðÖÌô·ûÃ|?¡ ·S¬È«IZó©×Zi²EÈ‹"ÚSd‘™fÌ­§uËl@É÷å³=-þðÖÌô·ûÃ~ÇGåÖ4‹Vc PŸ8õ6Iuå:|åNAS¡šœaÕÕ«#7‰ÔÜîYOø·x¿ãbJùaæª FC Œ–NL9)[(t×!rK¤ƒ5 M‘d3ºŽé!‚ܬ׊G›W¨Ô_bîIîe«#hI©J²ngb#;«e¾ì†˜©©×#8M>”?˜ÚY¥+$¨ˆú§•iU‚ˆ÷ cLµ¬ü/¤¦Ï&%œ¨¨©hÓ-ÄJÍkRÒkë©Å4ŒŠI›;æÚCyXÄUÅV*t†ªÜÞÛ¸­ŠKSI–ÍPØU1™&IÌ“I©NšF²V×Ka؈hrÙž–ÿxaËfz[ýáŠRN.ÅiÕx Ö$ÖÞo"ŠÔè¬ÄCì±ÈZxȵ†† Ífd]{3,ìŸ56=cÊE¤?R—H•#¹N\—Û„ôµÄ*{Ò?h–MÆPîd‘­±)Q¦Ê4˜÷-™éo÷†¶g¥¿ÞÄӌCe‡d»)ÆÛJû¤’[¦EcZ‰”Ü÷žR"Û°ˆ¶•bŸ­I—KžÑ=[+aäñ!Ddeþã&Ç–Ìô·ûÃ(•eËiNÅ©ªCiqmš1УBÓr=éRT“.FG´…ZSæ×©0ty=õ;U)K‡[sr—>E-ÓÿN…°Ÿÿ½VóGÂmsˤE~B^©º¥i¹I§$Í6£Îq¦ui’Zµ6„&Ëþ#êm¹Æ {–Ìô·ûÃ[3Òßï ið¼æê˜j—SjW+n\6_Kú­^´–‚Q/'ðÞ÷· Øl@~[3Òßï s8çHLaOÎ ªÈÖ²ô•òc#Ô°ÎMkªÌ´Ý)Ö#bs(ï±'cTJ=#³ˆçÕh´Jþ%‰U’×'¬¿‘KÆLeVG ”›#J:ÊQ™žÓ2Ób³á·#D¨¦´Ô6"Óåq*Èã¯ÔD¢,¦›£*úŠ3WX¬éËfz[ýá}sF¢C“*©YTfãCzk„n©KÔ2Dn¸H+©DœÉ½ˆüä–ó!_cJŒ¬Oôe©Ö”êáȨá%Îs“’NƸºÅ6YÉ]U\Ò|lgc#±––äTéøV©@rµ*§ü_’ûÒ[dœ}ÆÊ16£6„–T¼âH’DFFW¹•Àÿ-™éo÷†¶g¥¿ÞøÁ“ïËfz[ýá‡-™éo÷†<Ý‚¨‹¦`­Öƒ°¥/®J¬Ód™Ô_Öjˆ‰hÔ7}i™%ÂÖ.ÉZÏ­kŽëÊ:÷+ç¿( '•ËÌZ†²j¹V£6lºÝnOî‹æË—øm´dÁkòÙž–ÿxaËfz[ýáŠz«ˆ±“[o”2<^Å™ù3ƒc—¡ƒ+©&æ±m]Ëæ±!{[_Ëõlx}üFÆ/ZTx¥ÚK0—OaQÒªª„“U’N)hI’ˆÉdG”ˆÈÎæ`\|¶g¥¿ÞrÙž–ÿxb®¨ÖëmìKK¨âYsQ%6LY®AaR©RcTIA6Ù™©”’¢²MË«1'o"Æ&Ҹ¡‡Ú“‹Í¸Ñ%¢S4>W¬Q™).ž´šSI"AåA%ÂÖcI @_ü¶g¥¿ÞÅ£WбG…W§T_~èíÉŽîe§;kI)*²¬er2;ŠÿÔ1>!ÆÑ&´ªTF0ý*¥& 4Gy.H}É:ÄkM+»fL’O!í"#J‹iŸ%¢|U\F‹Û”fQœÃØI‡aÐõdnOJb%H’¥™\УNT¥³+ÉFjê¤ ß–Ìô·ûÃ[3Òßï RŠñÄ<+ˆª/?RÈœ+2©]C›.‰- Â#8¼íc?Ú­•$j<Ö¾ƒPÛ©ÖdU¤­yÔë­4Ù"äE‘ m)²È̳fVÓºe€ÜrÙž–ÿxaËfz[ýဪ)T_¥|UTò+ Õy=~/÷Ò{ÙfÅË¿džN»å¾dþÑc?7Î0-î[3Òßï 9lÏK¼1X9‹§·ƒS)Ê«)©+sJn–ÉFÏ<êuYm¿“q¶ku¯}£-W7MòìNóÌ-r”TÓ†Á2q•VT$‘¨‘¬Î”™(”EÕ"23¹˜*¼UX«“¢ûÍ"CÑ”¬ËMœeÕ4âlvÜ´(¯¸ír¹XÇÕú²Øv;OÔÔÓ’\6˜JßÊn¬’¥šRF}cÊ…*ÅÁ&{ˆÅ9£Êb£Y¨a‚ª;‡c5T­=ÖÚmoÔŒê2‰FÙ¸…!)hÌ®›Œò™‘#ÏÉÑ”Š#GÚ(ŠŠÔ©UM†ßKí³û6y¥÷I„šM’—A‘×°ÈÔe°oòÙž–ÿxaËfz[ýኣb:ô™>§3ôâ}o)¥êJiöanþÌÒ’_ìÔ‚eyÔ«©eæî< UÅ…KÑÝf¯‰Þª–'i¶æE\6i£\d¥mšJ%]›Ôi<ÆdIØD·Ëfz[ýá‡-™éo÷†)Íb¼iZªÐª3ãÔ‘O«›Å)©J§"4c&Ö´¦>­Ó¥¥H$).FdŒ¶V‡\®ÏÀTjýHªË«S"ÊR–šdÖÙ(òh#¹æ,ÙŒÊåÕ$–ÀsËfz[ýá‡-™éo÷†>¾›#1¥úß“ôªMC5™®åÕ'"dþè¨eË‘‡s_­{嵋}öa¿V[ÇiúššrK†Ó [ùMÕ’T³JHϬyP¥X¸$ÏqúòÙž–ÿxb¡Ã5Zôli)™­D"£ù4øñ_9-)²Ãèu)'Úç4Ò®IIÜŒ¶•ïÌÕ±Æ17èhõLI&vFMqä¶ÒÙ4š‰ÈˆqÒq³5R\ Ô_´";¯*Tõ:¼Pe@*¢ûnÔ$h©Ì³Ö8M8é¦å»¨ÒÎçbêÛy‘W-™éo÷†*:túìÚžj¾Ô”H‰‹_a¥K\S’¶¹¢ZÈÞ(ËSI]Ö¢±Z䔫)fâûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞrÙž–ÿxcà¿-™éo÷†¶g¥¿ÞøïËfz[ýá‡-™éo÷†>ûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞrÙž–ÿxcà¿-™éo÷†¶g¥¿ÞøïËfz[ýá‡-™éo÷†>ûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞrÙž–ÿxcà¿-™éo÷†¶g¥¿ÞøïËfz[ýá‡-™éo÷†>ûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞrÙž–ÿxcà¿-™éo÷†¶g¥¿ÞøïËfz[ýá‡-™éo÷†>ûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞrÙž–ÿxcà¿-™éo÷†¶g¥¿ÞøïËfz[ýá‡-™éo÷†>ûòÙž–ÿxaËfz[ýá€>ü¶g¥¿ÞÇ•Yr:É·'?¬Q¥áš•nüχh‘§ÿ÷ïï‡'ÿá{—þŽá”`ψœ’†µ’ßaÇLÉ(S¦w·>ÎÛrRÿ¤"L—ë=·¤:âQ¥+Y™$ÍM\Êû¯bÿqPW²kÔjyuÿe›}¿•ö^û¯üí´ycéûŸž0~·.~I'6]×ÌÝíü†Wzæ«S¦·T–Û•ˆZ^Y)*y$dd£Ø{Gí¾q2“j”þ[ ßu¨è¥’sX’[UÔ«!(A”¥eBHÌì73tw£¶æ>Ú4wƒ )qDEÌ6ú1òèûG¾Ï0gáøžÀ3#¯ G}Ç]—Q®È´iRuË'±–ìë"R¿ÊQÌaD¥à(ˆœˆ”ì55)¹©i†RR¢2R\±uÈÈÎäw½Äô}£ßg˜3ðüO :>Ñï³Ìø~'†M¿;R½g ¿OÌ9Ú•ë8]ú~cQÑö}ž`ÏÃñ<0èûG¾Ï0gáøžS&ˆË“ªci.¥ ßSÏ2Ãt¼†f’Iš¢š•d%#Y¨ò¥$fvÑð;‘©mÔ Tž¥°Û1dÊb1¸Ù ˆˆÓ•$”n½I"àD[Û£íû<ÁŸ‡âxaÑö}ž`ÏÃñ<0Ö``zԔʬBÕÐÒ™K²ÚeÕ¥µ’F¢3ÊdgrÜw1üb8Ô¥£‰tœž´¸ú¤ÇjCO-$‚#u³2Öu[J6™ˆ¬eb·õÑö}ž`ÏÃñ<0èûG¾Ï0gáøžY„(f‹‡gR&Ì¡T¨È9Dv™Š£È†Ò„1uP”6„‘«Í¹™™Í>>§F‹žÍÝ7£4ÂZm,8iR h"Ø•V¤Ü¶ÙF\L|z>Ñï³Ìø~'†h÷Ùæ ü?ÃmùÚ•ë8]ú~cå6£N~Ì5\b#Ž6¤%öžhÖÑ™X–’Y)7-嘌¶m#-ƒ[Ñö}ž`ÏÃñ<0èûG¾Ï0gáøžBÞaº“µ&ô£VDç›KNÉK‚uÄ&攩\’æEs±ì¹ýFŸªQ£ LŒ‡—!,¾Ó.!.­Fµ¸I22%)JRŒ÷™™™í1h÷Ùæ ü?ô{ìó~‰á€6ÍÕ) ¡(EF P’"JRòˆ» hžv¥zÎ~Ÿ˜Ôt}£ßg˜3ðüO :>Ñï³Ìø~'†äëX …[–ÔºÎ<‘RÑY·eÁ£<´ò5C3!Ò7GÂD€ÝrE'Ê~O6¤ÌE<޵Ë.D%)¶Â,©-„W¹íh÷Ùæ ü?ô{ìó~‰áƒ=‰uŠr)¬?Jj l“Œ…¶M%²,¤‚Il$‘lµ­mƒ < žšs°ëP‘èÉŽ†™Kieã%:Ù$ŠÄ…™©;”dW¸ù?€ôrÃ>î°b[m&µ“ñÄEsÿÙŽ'Ÿ¾¿a¢ß…ÂðÀÉhsµ+Öp»ôüÇÊmFœü7˜j¸ÄGmHKí<Ñ­£2±-$²Rn[Ë1lÚF[iÏßFß°ÑoÂáxaÏßFß°ÑoÂáx`­FxR9éÀ©ÒÑ|ŦQq7ße&ë“àî|çÝE²äåÙåmkk<ë[e®8~ú6ý†‹~ Ã~ú6ý†‹~ Ãn«˜^‰WÆŒ×dUðêYnCTH€ÉMZ™4©9Yï«Î„¯.[ì¶kl^|1Éy.z?'å§UvòkµºÝe·gÖuóoÍÖß´W\ýômû ü.†ýômû ü.†±&+ Ìå<¬èÒ9[)bN´Û^¹¤š(]üä‘­fD{ 2»LkÝ¢èõÚ[§)8YtøË7Ѝì-(÷©(µ’̈q|ýômû ü.†ýômû ü.†²X•‡˜© H¥´òÚC*q l”m ÔhA™mÊ“Zì[‹2­¼ÇłŒ*˜*+G“b£TžLÙ‘Fíæ&ÉIX¬V"ìç?}~ÃE¿ …á‡?}~ÃE¿ …á€;ˆ”¼‘†£¦ …75-0ÂJJTFJK–.¹ÜŽ÷¸Üsµ+Öp»ôüÅ_ÏßFß°ÑoÂáxaÏßFß°ÑoÂáx` C©^³…ß§æ>LM °ì‡X—MiÉ.¯©!&êÉ)A)F^qåBSsà’-ÄB´çï£oØh·áp¼0çï£oØh·áp¼0kØ ‚õYUwqãîT–¤-RÕŠo¢R ×Èó]*JL¶ì4‘–áÜg×’ç£ò~QÊuWo&»[­Ö[v}g_6üÝmûEuÏßFß°ÑoÂáxaÏßFß°ÑoÂáx` Ë YI•ÒÄ•Kd¿efßR”¥:žÅš–³5Ó5ñ1ò§ÅÁ”ì¥O@‰–R¦¡ ¢Ï©…;³øÍi5o23+Øp<ýômû ü.†ýômû ü.†ïàÇÁÐ*’j°X Å¨Kÿ”ÊC¯m¿]eµ[{L}š^eˆ,4º;mSíÈ›I¶Ide«/ತì·UF[ŒW\ýômû ü.†ýômû ü.†ïcDÁqk.Ö£FÃìU#'f¶Û)}Ëï̲ëõ1 m6a×M†ÒÓ,´â†Ð’²R”–Â""""-´çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóÍV™]vMZ‘'RœÛm)¸‰¦™|©Ììu¸dF¥ªÊQØÖ«XŽÃ•çï£oØh·áp¼0çï£oØh·áp¼0ò‰Óê²1âªMŘ¹î7-¨H[²2ã%yØm­Í8dy‰fy±¤’d­ã¼Âg%Švi5ðÒC IãûK_úÜpüýômû ü.†ýômû ü.†ïéì`êth±©ìÐb1 Óv3L%¤%…šTƒR¶%F•©7-¶Q—¬@ÁøB‹N‹ ÊÔcSØ…"¢ÓM2ô¢i´§2ÌŒÏn[ØÌíÚc•çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóv¥zÎ~Ÿ˜«ùûèÛö-ø\/ 9ûèÛö-ø\/ hsµ+Öp»ôüé^³…ß§æ*þ~ú6ý†‹~ Ã~ú6ý†‹~ ÃZíJõœ.ý?0çjW¬áwéùŠ¿Ÿ¾¿a¢ß…Âðß¾¿a¢ß…ÂðÀ‡;R½g ¿OÌ9Ú•ë8]ú~b¯çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóv¥zÎ~Ÿ˜«ùûèÛö-ø\/ 9ûèÛö-ø\/ hsµ+Öp»ôüé^³…ß§æ*þ~ú6ý†‹~ Ã~ú6ý†‹~ ÃZíJõœ.ý?0çjW¬áwéùŠ¿Ÿ¾¿a¢ß…Âðß¾¿a¢ß…ÂðÀ‡;R½g ¿OÌ9Ú•ë8]ú~b¯çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóv¥zÎ~Ÿ˜«ùûèÛö-ø\/ n0œmbÊ¢©˜kèê­1 )åµ f†Ób5ªÍõRFdW;Ì‹y¸çjW¬áwéù‡;R½g ¿OÌkú3À^Ïð/ÁàþAƒ[ÁZ1¢ÄnUKàVvK1[2¡ÃY©×œKM¤‰-™Ö´–ëÓ;’Àßsµ+Öp»ôüé^³…ß§æ5h÷Ùæ ü?ô{ìó~‰á€6üíJõœ.ý?0çjW¬áwéùGGÚ=öyƒ?Äðãíû<ÁŸ‡âx` ¿;R½g ¿OÌ9Ú•ë8]ú~cQÑö}ž`ÏÃñ<0èûG¾Ï0gáøžoÎÔ¯YÂïÓóv¥zÎ~Ÿ˜Ôt}£ßg˜3ðüO :>Ñï³Ìø~'†Ûóµ+Öp»ôüé^³…ß§æ4¯à=°Ã»£ì–ÛI­GäüC±\ÿöc‰çï£oØh·áp¼0¡ÎÔ¯YÂïÓóv¥zÎ~Ÿ˜«ùûèÛö-ø\/ 9ûèÛö-ø\/ hsµ+Öp»ôüé^³…ß§æ*þ~ú6ý†‹~ Ã~ú6ý†‹~ ÃZíJõœ.ý?0çjW¬áwéùŠ¿Ÿ¾¿a¢ß…Âðß¾¿a¢ß…ÂðÀ‡;R½g ¿OÌ9Ú•ë8]ú~b¯çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóv¥zÎ~Ÿ˜«ùûèÛö-ø\/ 9ûèÛö-ø\/ hsµ+Öp»ôüé^³…ß§æ*þ~ú6ý†‹~ Ã~ú6ý†‹~ ÃZíJõœ.ý?0çjW¬áwéùŠ¿Ÿ¾¿a¢ß…Âðß¾¿a¢ß…ÂðÀ‡;R½g ¿OÌ9Ú•ë8]ú~b¯çï£oØh·áp¼0çï£oØh·áp¼0¡ÎÔ¯YÂïÓóò¥P¤,œr¡ X’2JÊBII¿Û¼¸v ߟ¾¿a¢ß…Âðß¾¿a¢ß…ÂðÀ¡FCZÊœ'ÜhÌÒµ>’µø_wí¹.}>dG“XÂNF}§Qä‘©µ’ˆ3{6 Æ„þ€kµV)TZ>ê3ß¾ª8 ¦Ó›ŠäÉ3]-®<û†¥-\ms;aþ's=A5Ú”j=]RY™1•:»o2"Ü_Ì÷ ê‹*U—Z}ªü˜¤óš¶ÐÌ4¦2œû4­ÖO9ßgžY¸n.·H J Áˆô¤Æ‹*Y¢J”MË®±*Id$ïn‘«F•gÓ"«„%töTóq•ë)f¦Ò–>Ù}›v}/„aaäù’‚“o×N“V½þ+qó¾+Š~r¤ª8Y~Wø¾?¡Ôa*nF%©BªÌ‹!¤BŽû aƒl‘™o!W¹™Üõdg´È·iõcŒÑd¦œõZKYdÊVBQ<ã™™J%ffeµFG²ù¯b˜äx–ÆfJš²V^ž‰'Ãâu° ¦^>c»{ïów4²¦N™%Æ)¤é$³V­)5¯)ÙGeì#Ùºæ{¶oÆn¥P©‘P×.3é5'X”šKz“”‹wa–ÒÚ_ÏøaÒ¥Wü–qM-×YCJ¶sRÌÒwÿ'­c¶Ò>G·Ì:ä–^Dgš˜¶TÓˆQÝ ;XÚE¶çý7™í©bÙב‘‘m#Ü1*ÓÛ§ÆKŠBœqÇÓ-'a¸â¼ÔÜööžá’ÁYBOa’HýÃ_‰â36Œäy1ŽTsq¥¼ÑoZâT¢-¥¶Äb9)IZ.ÌÊiofŽ»P©A†Ns²Ês·KM¥- Uö™æFlˆ¹\ÍEägbÙa êêÑœ9´±T‹b’ÒHÉ*#ó\EöäUŽÝ†F[Èkê,¦ƒ£Š® ¢ËntÍkME~mß$6n6“E”wØJ^ÃÜw¹oXrdz¬ÚuL݉"rè1ycŒl—•sq;<Ó¹Óü‹°VÀà«a¨¿>£œï½ú|‘½ZÑ©/Á/ÔÛW¿ÄsÿÕœÿ„ÇÇGØ8sèñ€$¢7-&‡J‰!9ß}Èí‘ŒÉ NgRR£CM¸¼ªÊd>Õïñÿõg?á1ÎRéÕþ:,­Òã=5ú>™=qlÔã쪞¨Îå"ëÜ…ºII)K6‰ +¬Œ·ÅT«KRtcµ5ÒÕ¤ì¿6k¥$›²9IÏLSX¢Õ)•H›]ŠÍR•6©U OFo<†#²±LŽ·‰.uJB’ê %[:Òt…„Ñ6Ldê2Ó ’ÁY$ão4—Z}Ì¥%µ¥FV3<«mÔ—«Î¯=S“L¢µ6³…êØˆã¶•¤§SêTç#3MKm2”0ëí“kºbFJÒáço’,ÍβNMÏôw 3êøŠq(râÁ¦QZUÏ]"\4HJ”f£BÕ!hMˬ–’á)Iq&8Þã”üC¡‡Œ­fåµk+lÛÕÙÞû½w¾¿_¨ÐÚžçºß~þZ–:ï(ÇL3Érò l9Ü£Y}g(vR2e¶Ì¼š÷¹ß>â¶ÜÆj®J¢6þiñ#3)ö²+¨ÓÊu-ªö±ÝL:V#¹eÛk•ø:Æ¢b/Weâ|:ÝNaÚcW)“S:ÎQP72_«¬I)³¹uK+fÛÉhË SœÄôiø×ªµgR#»6m O+•¡‰Hš‰›fM-M-¦ÔNšs‘6Û(úSš]4*¤ ån–ÿ(PŒÜ¨®äRu8’Re]&Gc">Ñš<Ù‡iš)ÑEv šÒ"×Xf¿Mjˆë.É–ÝQ>á·ŽQ]$jZIdâRdF­¤,M…TQ# ÕÓ‡]Å¡R“ÆžŠÑ=Væ¤Í*i¤JKšL‹+dwMº ⩊¨4Îwå³õ|Ϲ¬ÊÕªC™²y©<Ê<‡ÕMÕ»gX¯º´oïÿ$þ/+ñ’æ/ýBŸû³ÿø/‘±³ÿˆþf1¹•ß+¯äÍ[Ë+9O>r'5\×ʳååVÉ«ä±Ôæ¾}¹?ˆyŒœ“<‡¢= ×ZJ×ãA¸É™\УB”“Qn<ªQ\¶–ÑNáŠ1Ótع(2&ªMFkÓ*3hOG“ KŠI”üÚ©,(C63JTƒ; |´7‚z¡‡gâ|2µ?JÀxm˜§>!Ú<¶ŽZœ"%•’ûg«ÿ=‹vm \ðrLòˆô7]i+\wã&esB RME¸ò©ErØf[F³W|¤1P伫[R&³%¹L¶cç½ÍÖæ·¶¹^åAÎÃrã`Œ)ü1:«Z‰ƒ©Ñ¤ÏÃÏÊhŸC}d6ûf“§È¹ÙN®ÄDHÿ$íji‡1 ì,Š=VB ¥AóÍ2¢iÆWToZHZNù›C*Zíl‰R}»°@SX‹Á§½ètŠ4êN•J¤IC4Šq­¥É)RµùYM‰Ë¶Üru´õ”ƒµŒÔWÒˆé¸F%k a$B¨B«I ¨ïSÛ~<¨Èl¤r7 × L)i;V»k€/ð{›ƒñJ™*\§Õ§7B™E¡C’¤/Y2!U˜yé$´í2äéeæ©—LÏ«³¼¢Râ`,WŒäPðĦ( Ð`Ïj*VD¤®v¹,6VJžR%c36ïç€:üw]ò_×±7%å|ÑM‘;“ë2kuM)y3Xòß-¯cµ÷aêï;Õñ?’êy’¤ˆ9õ™µÙ¢G‘žÖ,¿ám·Ì½öØ©];PYŸH­Õ°mn¿[O4áyP©®ÉԵɓi Œ™2|žR’f“q+""]ò¬Úa:VÄUjå"¡UÁÎbP޵Yþo€†æ)²#9,¥hR,W&ÖƒU”i3l "±Œ AÅôŒ2Â9TÙ³“I©%+‰.B|¶YŸ$Rr‘‘‘(”| ]0¤ 3ŒäÑ+3éŽTiÕŒu.d”äR›(lS¦D`ܶÂiz¦ŽÇÕQ½c¾kÔðÉÓ"Õé Ãs\Á±›O=I‰ kmÚr©Œš‰¦_´d¦/:›AG Çc «ˆk¼ÑWÔþK®çº’àçÖeÔå‰"F{Xóƒå¶Ï>÷Ùcbï4Uðå?’ë¹î¤¸9õ™u9bH‘žÖ<ßàùm³Ï½öXéZ­¥Ñh†þ ­¿ƒÑŽW.-!çTäjw6>Ùš£gC' ÜV¨ÒWK‰F^±$ÕJ *¢PÍì[£®\ZB)®›‘©üØûfjŒE œƒqZ£I].%zÄ“ýó=ˆóéyÓBÖÙ ’ÁdR³¯2ˆÍ7I'ªJ;­;2æQjüª ùÖ1åÿÞ7¡"sru+º™ZIHQ#.{™(¬›f¹Úר*Ú&TµÐ## Ëk ;Œe»™2 ’ˆÔåÑe2¢q•—ìš[êrÈY<„Ø®D10-2ŸF<Àpðúè“$O†Uè륮œzt?!ÕfBuÄ·e³u9’¼öÌv;o`Úï”T‡ê—’êªSàäÖg¿&–ô|÷±yÚ¬Öáš×;\Ø6»å!ú‡%亪”ø95™ïÉ¥½=ì^v«5¸fµÎ×:W ÐYn¶¢…ƒ+p±‡—3%ó»´×PÙÓΦëŽ)2É©\sZI¬Ýe,–I;’ƒ ÐYn¶¢…ƒ+p±‡—3%ó»´×PÙÓΦëŽ)2É©\sZI¬Ýe,–I;’€V!®óE_Sù.»žêKƒŸY—S–$‰ícÍþ–Û<ûße2£TO™M‰1ýSÕ9'r(õŽ“.:ÀqêtÝ1WœÃOÊÄêÞÃòJ:Ôú\n‘T¸†[IZä©9›Ú¥#)ß-‹úÒ†fEÁ˜m暪`*ë u¬æK"ŒQ‰Ã"3qõäe5]jº÷ØÀx0*¿Çþ¨÷ÿˆÏ_ãÿT{ÿÄa‚µ­ãLCœp+X²ƒL–”’‰u™pˆ÷U(ŽÆ9}%Ö)Ì+@ŸDªA©ÄêMIiN«+hJKjÖ£þ‘m3+•úÀâ'ÕBÅ&ì¢4Æ›U…PiÞ &”ºÑùi&3’w™,í{¨x…iÒ¥xj“z-J#^thíGUw¢quJ 䢮üI± Ô²ó­E\g¢¬Ìˆµ)J2+™í#MÊåk™weÆ… é³$53 ›Ž¼ê‰(B®j3=„D\Eg¤*Ëøó"ŸÌ´¸ÍR9FÚË*œyDv$ ŒÔE´ˆíc32!Øi&2©„dF§ÇåO·"4¢˜“Ê̆ÝS7=t Ñ·g[nÁ‡V•M´åµ÷>ÿ‚¿…âg[Ì[[QOs×^„Ññ­Pj G§%çï¨94Ù1ÐýˆÔzµ¸ÚR½„gÕ3ØFcY…q*Ÿê”º¥“S#ëõ/r7[É‘ÒK_µQšÖ¶fçìȵyrªæc5ê¥gÐE‰WFpÌæpÏ4­É·X&pü¦]mã$Hœë†™e¬K}rI‘ªÇ˜®D®Ž±u»Q„Õb5!oZl˜îÉe¬§Öm¥6•ªö±XÞl¬gsͲö;kʼábº} Êk¬*d9Ò‰Ç\MÒQža¢ê¤ÔFNä²;‘‘¤ŒÌ“Íã*-!Í,aZõO ¢ –áIˆ‰i¥œ¥G’oÅ\e)IB²NWÌœ;%•´³ð°52¥Ó‘O–ËHò§;Ž2¤¥:ê».5s2ÙjOùI#2¹;ú÷øŽú³Ÿð˜Ó` ºéº*ѹH®»G¦#·2[ÈKGµ¦a%77®¯ao3/ä75ïñÿõg?á1Áª‡SÄšÀÔj5Ž¡#G_Üè5XœRJš¼—=l¹vìÛ´\ðúP«]B£´]îôÜ÷þE|[’¤Üxÿ¹Ü17H’騫‰8¡­³u¥OŒÌå§i§ö\Е(¬d•8V¹²™‹Ϊ»^›¢üå¡4ÈSÔÄ2N°·W –…I$µI.;oc1Ï5¥œ;3 œØµJ%:¶‚"~‘]ŸÈ]Žá[;k#I®å´ˆÉ&G°r¨Ó–ÃX…5LwXòz¡X SŸLS¦º¦Òg!Òë“VVy)3I–‡v4q8Z”ödᲮקž¦øXÒ[w“nÛ®ýn¿‹—¨Œ -̓c)y->Ò]B^el¸D¢¹²%![v¥DFG°ÈŒ}„$€[ÿOý¿þ’dž?éÿa/õi?ñ6=Ï[ÿOý¿þ’dž?éÿa/õi?ñ65õ3è{ £þ0“þ•_ù˜Ä’Ã2XSC­,¬¤-7#þÒŠn'~C»¤¼\kqFµeäI+™ÜìEÅý„*t¥TÌz¬wŽmÃ3p|1Äðÿ¡âNK Kfײá{ÛöeÌF Xx§ZI^ö»Óî{ JHIY$V"ž hí")¼4Ýåf{­´%´’JKqþ‡„JZ_áŽåÿVÚðÇðzRÓ w'ú¶×†#ËV÷Y¾b—¼{²\H²ÐH•·’Gr%¤ŽÆ>q)Ðb,×#M(÷šk ”´Ïýý[oÃÏJZkûöçv߆6ÊV÷Lf){ǽÀx#¥-5ýûs»oÔ´×÷íÎí¿ 2•½Ñ™¥ïær…GrIÉ]::ž3¹¬Ñ¶ÿú"¬°Ë?ºiá°‡ƒ:RÓ_ß·;¶ü0éKM~ÜîÛðÃ+Yú Å-OvÕšqúT¶NgahI^×3I‘ †ÉÌ5£Ì7‡&= Ù4ªLX/8ÓŽ¶™Ji»dv3IÚäCÀ])i¯ïÛÛ~t¥¦¿¿nwmø`°µ—øŒÅ-O~M¡`i¸‰8ŽfÃkIu·“Qv$–݉ 'M¬Ù“•6;ܲ•·ƒžšícß_äœ})i¯ïÛÛ~t¥¦¿¿nwmøc9jþèÌRÔý离X÷×ùžšícß_äœ})i¯ïÛÛ~t¥¦¿¿nwmøa–¯îŒÅ-OÐú‹Ôº„Êl¹Œ°ëÔÉ'*µÎ–­ÓeÆMV$Øÿfó‰±Üº×ÞDe›ÏMv±ï¯òÎ>”´×÷íÎí¿ :RÓ_ß·;¶ü0ËW÷Fb–§è|EÑbr>IM¥Gä,ªüô×kúÿ üãéKM~ÜîÛðÃ¥-5ýûs»oà µtf)j~ŽsÓ]¬{ëüÏMv±ï¯òÎ>”´×÷íÎí¿ :RÓ_ß·;¶ü0ËW÷Fb–§èç=5ÚǾ¿È>O§¹5™ÎF‚¹L!m´ú‰FãiY¤Ö”«Wr%r-ùJûˆ~ut¥¦¿¿nwmøaÒ–šþý¹Ý·á†Z¿º3µ?G9é®Ö=õþ@离X÷×ùçJZkûöçv߆)i¯ïÛÛ~e«û£1KSôsžšícß_äzkµ}~qô¥¦¿¿nwmøaÒ–šþý¹Ý·á†Z¿º3µ?G9é®Ö=õþ@离X÷×ùçJZkûöçv߆)i¯ïÛÛ~e«û£1KSôsžšícß_äzkµ}~qô¥¦¿¿nwmøaÒ–šþý¹Ý·á†Z¿º3µ?G9é®Ö=õþ@离X÷×ùçJZkûöçv߆)i¯ïÛÛ~e«û£1KSôsžšícß_äzkµ}~qô¥¦¿¿nwmøaÒ–šþý¹Ý·á†Z¿º3µ?G9é®Ö=õþ@离X÷×ùçJZkûöçv߆)i¯ïÛÛ~e«û£1KSôsžšícß_äzkµ}~lÔôæZ|t¼ö9}IR²‘!¦Œïc>-ÿ!®éçKŸ}¦÷,þAá8;H’3Œ•ÑúoÏMv±ï¯ò=5ÚǾ¿È?2:yÒçßi½Ë?:yÒçßY½Ë?k¼ÛqúoÏMv±ï¯ò=5ÚǾ¿È?2:yÒçßi½Ë?:yÒçßi½Ë?7Çé¿=5ÚǾ¿È5xš¼¸Ô‰s!Ó^ªÉDu6Ô(Ž%.<¥šKbž6ÐD[ÌÍ[ˆìFv#üÜéçKŸ}¦÷,þ@éçKŸ}f÷,þ@Þ7Úò¿{'¯üNú¦ÅRñ–)Mžz9«Ó[f¹O˜ì—êV†ÛfSn,Ìù¨ú©Vâ3áaãîžt¹÷ÚorÏäžt¹÷ÖorÏäÙbçèþ$2̈ë%–Ÿa²Úu´(¿šOaÏžt¹÷ÚorÏäžt¹÷ÖorÏä –™úM§S©)še6 ÖwR"FC)Qÿ2AÆHüíéçKŸ}f÷,þ@éçKŸ}f÷,þA… +# («#ôHçoO:\ûí7¹gòO:\ûí7¹gò ì³7?D€~vôó¥Ï¾³{– tó¥Ï¾³{– l±sô"¬ÓÒ¥°Òs8ã BJö¹šLˆF ¢Ä¦`L'E«8Ó• Šqȇ:K$f–›K™T„¤Í&¦’{{ aÏŽžt¹÷ÚorÏäžt¹÷ÖorÏä —ÀÄ£+I\ýä´ŸI¨ünwÌ`ÍÃX6}^™V©R˜©N¤È)T÷§Ì‘$ã:De™ÂV]ä{7© «ÎmŸÎþžt¹÷ÚorÏäžt¹÷ÖorÏäTÒwIÆœ!¾*Çé¿=5ÚǾ¿Èô×kúÿ üÈéçKŸ}¦÷,þ@éçKŸ}f÷,þA¶ó}Çé¿=5ÚǾ¿Èô×kúÿ üÈéçKŸ}f÷,þ@éçKŸ}f÷,þ@Þ7¦üô×kúÿ sÓ]¬{ëüƒó#§.}õ›Ü³ù§.}õ›Ü³ùxÜ~›óÓ]¬{ëüÏMv±ï¯òÌŽžt¹÷ÖorÏäžt¹÷ÖorÏä ãqúoÏMv±ï¯ò=5ÚǾ¿È?2:yÒçßY½Ë?:yÒçßY½Ë?7Çé¿=5ÚǾ¿Èô×kúÿ üÈéçKŸ}¦÷,þ@éçKŸ}¦÷,þ@Þ7¦üô×kúÿ sÓ]¬{ëüƒó#§.}õ›Ü³ù§.}õ›Ü³ùxÜ~›óÓ]¬{ëüÏMv±ï¯òÌŽžt¹÷ÚorÏäžt¹÷ÚorÏä ãqúa:¤Ì†M&¶SbQ–SY™™¡I"Ú’í&ÿ¤ üy„¿Õ¤ÿÄØª:yÒçßY½Ë?sßb¼läG1MaÚšâÉ…8Úh%[1uH¯æ–ð³¸=ßÚ<“M¥rê%V Ü‹=NKN©Œž{J^­KÍ}™V¦ŠÖÛŸy[o­»G”0]N.µš¨™ ¦ÉaسÂINjÜA§2IFDjIåY™ÒCã?éï‹·ÿ_þçOúªÛ/ÿËÿSa#M*kÄåæ9ȉÆPÒ *SoºÚMF¼×Õ4•ß.[)Y9K>¾F­²Ëœf]e×$ÝbSN ÛJÒ…) 2Q¤Ö›¤ŒÌˆîem£® é5>¡\ž¸ RêUVä4Ñ´Û³£MŽhÊ»¥F”ÊFT©&“Èd{7ÿ31Å-Uº*ä™ÔXÊ™­5E‡L55% iâCQú¦¼‰Øµ(ö’v&Û}Sj¥ø!h[‰Ì¹‚±Csyé“f3ék:s)2 ÎR¿YJ5¤²–ÒÛr,§l AEŸB˜ˆ•‹¬[zÄœymHA¦æŸ=¥)7ºLŒ¯r¶ÑØÕô‰Îñ©ª’SbOn®r¥JŠi%¥„¼·YKW?= ý¯°¬×fÍjÔŠÅZ4ŠC+"n)7&Bá5Rε¦ËFhAåRS°Îù3Ó1´\ï½’·Ø Àßàšu~‘LzErT9õj”ŠtQO'YÎÓl,ÖëºÔ›i=zJä…X’fcŸ¦aªÕJ"%CŠ…¡ÓY2•Hm>i+¨›B”JpËüÒ=»7ŽƒcÙ4,E\ÅF\ù®ÕaëM LŽû1›JÇç–©Ó%uMI2¾ÒŒ?¤ e.›MŒÃÏÇ] N=ß'©òž}&úÞBç³.:ÈÜ2êë¬FE{Þæ®J”ÉÌÁ–%/œ_„ÂYä­ÌÈSXSÆÃˆJÒé4K7 T“5e±m½¬vþ›Àx¥Ç!4Õ=—™!˜í°‰Œ)ÖÜuD–Òê y™ÌfDFá$¶Ž›ÖðÅ>¢ÝVù³ªÎaˆ”åGC œT)ÊSqœ=q8j5 ”¢4jÊËMŒö š>?ÃTÌnö/CugeÕªqåÔ¢œfÒÜd"k2Ü&W¬3pÍL’S™(±ÜÆ6çk¤gfÞÎZ&¨¿ƒêØ…Si6K ®3•ÉZ‰Æ]tÌ®ár$$‰²#R”kIfÖE«Ä˜j±‡TÊ*ì2ÂÝ5$›D¦Z›fC‰BŒÛYf+¥dFWÜ2èuJR0erƒR\Ö\•"4Ø®Çe.‘ºÃrM¬”´åJµþqf2ËæÆv‘ñ¼ˆæKšÚž\ª„ÈlÇ}òVLˆ^©FNš2¬õª²•Ÿiˆnœ¶­èjÔvnqà$#éð~^!£V*¼¢ª ÜÍYŽS¤Û®›dw,¿³eþݹJÝbÀï°Ž=¦áªM +8jMøsœŸ%éª}&—TiI%½SÉJ“«Bx“+©EkßI¹[ð›A+ï0tkæâ¬CFfF©Š\Ú‹1qS˜aå¶§— ”¸¬Î(ˆÏÍJ¶ðà>hÑÎ/\F¥•>)4äv¥]UÉ6Øu Zp˶ْ“×YHÎÆd{ÿb¬᪤ү¡¼34Žã2£“3! qJp²,µŠ#I‰V"ÌãQQÅ”é<û‘™eÎj›IjéOUè܇:•Öó’¹c+žÔÜŠçm6§µ¸Þбó-b…FY¢ž®PÃ’[ì!–Ûl¢þÐ7l¢>Vљؓ•IQ)E›'ðb3Cò#\’y„4mHaÈÎ6ãrÖkÉ̹H£8yŠè"Jó)’%t5Ý!Qgài46cT%ÚcQ Km3¥ª: Ìó^×§?Ãø›ÙµYŠ&=¤ÅÂTj*Þ«Á‘ ™K²£FiÛTR¬…¬‰i2œÒM*±(‰Â;l¾6ªlÞÆviÞÆ´UN¬ÖŸ›Iit©l0¶§õ©q—^5¡ZÞ¿U Ê”’ÌÊËsBˆ`/WÛÄoaé ÓãTÙÎN3"©’Já¶h5-ÂN|ÄvMˆ&F{šÎ#Âõ8–œÌi´øóŸ…2Ç„ÑߎÃÍ«;d´¥¤º§”³Èj$n"Q Æñ†{âúôÊ{Ùªµ7&Sžv›bšmN¸µ6¦žV­*Q)~¾\‡b;ŒíOïò1³ŒêïSiÞ~;ON­»Hv IÊšZa¾«Ky*ZÍo(—)%*Q’VJÿ’•ÞdçŽJÏ&Õk²r¦µú¯´ÔfÖäÿ?.[m½‡vxÿ ÈÅìפ"®ÑAÆÒ1 f›ŒÚõÌ>ôu) 3p²-)bålÄf«\‹¬4~TвóÕª<ùÌœÏÉ5ä¹y#Öës澯­“'üVRŸ¨q‡¡ªÄ8P#Ìz©†¹ º©m·5‡]Žy²‘­´,Ô”š¶Œ‰'r±ÈsC´­bÊtÜC¤:ƒLËKX—[ÈÒ¤§3yê É-g[gQ¥ÌÝc.K‹AɯÄi$“ÜnjÕ1„5º@ á>q·;óg÷N§÷\±¦\ósu²k­¼³e¾ËìÖ' V•LçŠV ää9 “ÆÑÂk6sFóÍ–Ö#=ÛGoLÒÍj5ÃS#â JÆ¥·JjE9©‹Jˆì°‡Ò–‰y –¦Ü2#¶lÛms'´ƒì6M’Î-E4„ÒµMP (Ö‚ÉóÕ¾œÈÞ›í2%$­hvªhKhjaâýWi¸Ž«—.Ó™›-ªy¿:9H”ÓdÍ-æ%8²6•rJo²ö±à…ÍŒqŽ‘аþ8feMsâ»*¡žˆÍ):´É 6úõ·iVZLÒH_UDd{n)‘šR“_ˆÅE÷‘€ÆOºŸ˜yMìdû©ùŽD=Tdéw”ð>ÆOºŸ˜yMìdû©ùŽD=Tdéw”Ð>ÆOºŸ˜yMìdû©ùŽK´@gªŒ#®òšØÉ÷Só) }ŒŸu?1È€gªŒ#®òžØÉ÷Só)à}ŒŸu?1È€gªŒ#®òžØÉ÷Só)à}ŒŸu?1È€gªŒ#®òžØÉ÷Só) }ŒŸu?1Èz¨ÉÒ:ï) }ŒŸu?0òžØÉ÷Sóˆz¨ÉÒ:ï) }ŒŸu?0òžØÉ÷S󗞪2tŽ»Êhc'ÝOÌ<¦ö2}ÔüÇ"žª2tŽ»Êhc'ÝOÌ<§ö2}ÔüÇ%Ø 3ÕFN‘×yMìdû©ù‡”ð>ÆOºŸ˜äˆ@gªŒ#®òšØÉ÷Só)à}ŒŸu?1È€gªŒ#®òšØÉ÷Só) }ŒŸu?1Ép õQ“¤o1b5Be·’¤¸J3Y¬eÀÿ˜Ñ õ*J¤¶¤ON𦬉$@ŒÜž OH@’žð````D  0íÐôO´ièP[´ß&içõ$LçI¥F•ÚÆ{¶Øn;F‚™RO‹YC’Ëï3f $«š‰*µŒ·m2!ý;*Qǧ[ûlïÿ/_Óâ}Þ1Màí7_º?šV~¸íZœÉ/’š£©yi2Bîde{áÏÁÂ*7æÕY‚äóË¥6j7…Ìeö¼†Î_J(µ¨õZ‹î8ücDdº¥¹uVFE¾ÛÓØ?˜ÕÊÈ47*’Þ‰"Ž¢2m,šÉâN[XËwšÿÏûGØÑŽ­:j>‰î“Iÿvûµmö»_ÉÆ¨ñ0”¯¯¢øz^þ¼L\!‡ZLlYNªÇ‡Êc0”¡çJ&LÒç\ŒÊä[Žå·a}Ì$Ý:µ†§µ1е&¡9–õš“Ië èRU}†Wߨw!ÑÓ1eD¼U"¬ó‘[©´†ÚB[5-I$- Äv2ÞdW1ª©bJ 8¸V‰Ošä˜tÚƒräÊ[*E¬³3²wÿeøoéÇ åFÍn½÷ÿ~믊ø¤ëm»§¾ß.Èǘ%OVΉP‚ÌÈÌ¡ôR™Ži² ´‘í+$ŒÎçb#ÞWµÆº…†éó°^ z©ÍMDY&\Z)Êå.už³ky+º’£I'Í,·Iß«·/àên(­âÈ9§ÈˆQÙÉ–”­D”u‰F[º©#½aÚ÷!ʳ‹¨q4w„)ç)NO¥VÑ6Lt´«“iuÕ\”e”ÎÊNÂ>?Ú/¥‡U•·ß×wn«Ð­ÿse-þŸ±ÏéâA£cY¢Êi*2I?¸Êm1,ÓyzDZyîjÙ»ŽÑZ¾,-5Ô(¬Zåv…VTâš”›Íe·¨4!"º­šö3Ù¸W¯ŒT·›+p¿¡˜ße\Ãtb;Äeº1â'ŒGF+»Œe:1]Übìdb;æ˜Çâ2óLcñãÀ…ƒ$Ä Œ| >Oh‚Ú€=¢öˆ ©ñ0&Šte†+ø‡GÅU¬HÑÉJ%um5•*±’¢+%Ä ÌÌö‘ÐUè=ÒN–(t}¼ýš£*i*!›QÝCJrÈA¨¯|¦“"2I\®3ðæ3Ѷ2Ñõ i5ê•2M¸s¢$ÔN5b"IÙ*2Ø”‘–_á##-¤>-ãíP´Ï†*øN†¨4 ;kbD”¶¢vN±µ6nLîyIW¹õoò ‚‰¢Žséûÿªò+]ÿ¹æåš½ù嫾£üï;ùmÉÄÚ'¥aÝQñ]K²Ë•zaL‰TõgqÓi$¢Y•ºÆF³""Ù°ï³»F3Ñm"›¥#¦bÉSfb¸ïºÊ\§<Ú5Ž!ü­$ò™Ü”áÝJ$•”žÃ1Âé¯áìE€4qJ£TyTº5,ب7©q—5QÓk©$JÚ…•Òf[?™>ÚQÐÜ,ûäc6ªU©º’NM=M¹ Öî¬úÙÔ”‘lµÏ­´¬V¸Ë¨hms&2§ÏÅTØE6]–› ÈŽÉtÎÊ=¥b±yɽ®B4ù¤*cL8{áY¥SJW6œhÖ¤8æ[-${;mm¢ÁÄnÃò2·H•èèr2y6GŽ—{)æ}Ö–“IžÓÚfW;ì ]@Ñ6fŒèØê¯Ž"ÑaÔe)‡ü/UgAe4ªë36Èíd‘™™õvØ:)ÐÍ…¦*žůî*=)©ñ×D‡Ð§r)ÕÍ$h4åÈy¯¬¹y¢¾Ä¸»Lú3á|¡ž¹¨¹bê\,š¤™sNCýâ6™íþF- :bÀM} XÄíÕÜ~Œææ×%"#¥ª{”›»Ri%X‹iùÅüì›1L*M>»&µÏtöòêgrUGÖÝ$jýš¶¦Ê3NÝö¿ë0¦ Ð)%‡´MÐdDC’*Œ¸Ë’ÎûÔ”,³,̶Ù*Ií²ÃÉx’-.rTZ-TêÔöÔDÄÃŽ¦MÒ±žEmNÛ–ÞÁè-c= QاV W1.”©thïÈv4— ÎÌJ%’ˆÏwY;; ðцÑz¤º–ªD!6´Gj§ K~ŒÑ²³SÆ’Q’ÔK%‘&æ²ÔÒ5h¶ƒ‰å›-é#g"k±©­1OrCï¶…åKδ•^:U°ËYÀvXgJX2¥‰´šu™/Ð`bبþJ§µd–\hÔ¤"ç˜ó’íº÷+ñ cíá\ Í5ªìÚeJ`äÊ~%=Fíj;n(ÛA«ø¤šÉFVÊeüFËѶŠ0Å2’iؾl7ªtf ¾Pqu0\u¸™I+Ùj23<¤Y’ml>± ÏèÞ%Eð1ä IÎpçÕ]‚Ã|„ÙÌÚúRõÍfe˜™#Êi#,ö¾Í¶ª´“£Ù8ãIH‘‰Õ/Ó#±z ¼²eH޶TJA¤”gÖÌ[,}¤9˜Ø›G] ÂÀuÌG:èugd°¶)ëZ§µ¬tÓ”· Ô—LºÆV2âÆ¨h kZW‹!b6d”®szc‘ ½SzÕ6i$Õ˜îIâ^wò†’°5 ÓâΣcjm}:¦^ŽMòiqÖWóØRiOTÊæEô…Ÿt‡€ëZu¥â(øª·–Å1¹Â”Úšq§Éç•Iu³5#*¶‘$ïrì2¤5› Q!SªiÄX†;Æ©U¢¦œ3[VQf“"¹íNíS2µì¥H8D ž OH@’¿>‰ÔÜ3&Ž*˜š‰L©±LAÈ­½«I%õ/.r;\’W·avBÚ;¡R´‘Šââ:4ñJªtºcS#¡Ô~íÉ9‰*#+ê¿ç­ô)‹°öÀF¥Öj–ef–Qà7©qzç5Rk¥&IÚâ6¨È¶ÿ#å;L8YìG£‰S*™¸,>þ {“8ÝG“ Ì‰&k=–ºo±EØ`)Í3_ÅØö³&« az%bS.IäÆâQg”Im¶‘m„F’±[zHˆÇÉZœÞ’èUÊë ¦×ã¹"Y† iqiN~ìÔ[v'fmÊ#¹îê^?ÁuHEÁ•ꬊu'רÀª5n‘fy*Nfȉ{um­ÄÈì6HÒ® N•p q¦>ÖÂp_‰Î0¼ÎšãD¬‰#Uº–ëÜÏa—«èI–(Xªm#@«NÃ*pçÃn"Ñ‘ Ìw5™Û6T¨Í$FDdiͰSÆ/L/°œ.š9U[Wå/)æîwO”çåYw'©}j<ü»ÿ‘Ûж Ã8s7/Ñ¢Õi2¶CñQ ™322p¢23#M¶m±» ¿ Ѩïý±}iêT*‘ë ¶ÌÕÇA¾Ú q.”¸e˜‹¬­„Ä}¦>U sv™hš:ò›[ÎU/—r j¬O]^³oîwæ/;vÍ»]!cQtCPÀ<™P©"«92ŸvCjI3e!FWRRgû¤$ˆˆö\Ìï¿°I:*ªéK if%›dJr¢;›RXQ¡Ó̵‘m/Ú©6A*æi=„F®iº‹#bªÔÜgÖߥ¼·à¨Ðâ[dnÝ+3#2^Ä*æDWÛrçt»£•à.f”ÅiŠÍ2³äC”Û&Ѩˆ’gt™ŠËA‘ßÛ×qö“¢m%PØ«f¨V±KÓéìòwK\Ÿad¼Æ›'ª…”d{7n-6bì=ˆðŽitj‡*™F¥zƒz—©sU6º’D­­¯jLËgó ËCtš #D£I5j >¹" Æ¡Æ9­c)#SD³Ê{ Ï\[xeÙ¼ÇOWÑžƒô§¥Ñ؃7âó«±I)”¤‰Â4eVÃI­°öYVݰqZ"ÅøU8ÄZ<ÆéPjr–ÔÖã©âJ’¦ÍI4§nÝR-³·w®‘q–Ò&™Ž¡ˆ^«ÅÃ-ÅL6$ÄJIâÊf¢Z’¤«ªjRö^ÆGÚ@çéGªÆj‘SVÁph¯­îC3 2ICä£M’ò‹b”D–+m]¯Â>ޏv:1Åušdj¢0å)RX‰%9™[†‡F¤ÿY£+ù_Ø?+âì-ÑŽÑÆ¨¿Y‹K¹OT]Œ¦3¨ÍÃ$¥*ÛÿµUÿ°·ðÃÐ>3¡áÔbl?‰z%+Ó•Ém4n Ê´’%´ÊÎ+w@;le…°#xëFxŽ£LK¡âxi~t8É4²—uhRH’^jMN¶“"àF}£?é‡pÕ'GuêX^‹‡ë%WS4¦4H9Q I²Ý˲æƒY÷'´hëúUÂÑt‰€LCõL?„bmzÙȧM“fâP­¥”’…í´¿°Ç÷¥|ÞÑÍa꼪ôºýmUC[ÑVÒ`”…Ö[m“)[‚•»ˆíWa؂֌sN–šþ¬êDÑ"ô‚V«6²Î̵‹ó‰»?é`éwàjwÑâƒVÁÐÒê­›\ç!””©)IHBŒÕk’ M‘’vˆ¶\VÚ‰@ÃaZÌéõIsV™ƒ$F{#g•m¦å˜Ü-†¯4¶öõ˜›aéŸFŒ/ƒ£T3× ÕW"L]K…‘³T“#ÎiȼFÂ3=¿ÈÀïчGøq.¡ì]M‰P«Ui뛸éu ÃKˆN¹IQ–¥–]žjNÛÌRØ' ÑëÔ GR©bÈ4Y˜ºø‘$3Ô‘ÅjÑ™i;Ý -„¯<¶vܺ'ÓÕ:F3“?S0Í ³§›H¨@¥»Ê¢[yZ5$Ö¬™HÎÖ·U"®…'b”âÊæ*u¬9T(¨UFŠmDuä´²Êi$/)ÙÔ›šÔwìÆÐ&aíIª³JÁ³ëµ*±F€œFÒ\k"sJ ÎÌgŸbwÚç°‡GÁŽÌÒ. ‘Œ`±E¤Qrei¸¨ÈÓDj3DvJÿÆfIAù»Kpûè…Z.„ª]{âÅ&»J¨7(Ù(ÚøòPÚ³%(ÈœÉ3²HÍGm‡Û³e_Óœ¹¼@qp¦¨Òª•––kMõFÒ.D²OšÙ㱩[v€?¿¥ÕBÒE:•™TvœSQ#¥¤)ZçˆÔd’"3±_~ÂMV°½2¸o`Äâ|Y>KlÓ—/DJLÒFJIªùŽêÛcÜÅqÐ}(t‡±¥V L4Ý2t6˜mÅÔù Ë' N‘±dGª²’¬¶¶c½ø o£gárª×«øª]|ШԳvžô”Ç%'¬ñ’ Æg|¶ÌGbWwÅ£\?éBí&— ”U ”ôþé/æ$’-Á6[kË»m·læ7´ e‚´‹éTH4ëÕ’¤ÊfžÑ6Ñ’Þq Q'qjÏoÛwÕàle‡4¦’¯§ÈÅ´ú”E¢¥Q(Gq8¼ÇÔYÝV4!FeÁFDW+ëi Ò0И&sõˆ¸v§Î‹–ìu0N8N)hA%[w;voàyp~¨Ñt‰‡)¸Z™L{Â*Øíå}ÌÌ)å‹Þ½‰2Û}÷Þ'èö3a‡!`ü-ˆ¦Ö©îMšU‰:©fBVÛq*²™¶ˆ¶o#;–›iOU0íFdºÎ1‹3°œˆ¦ÊPÑ´£RϪ®ª•æ™í· ¢0”ð?3`ºž$©ÍƒWÁ±¤FjQâf¥Æ‰¤åQlI’RŸ:ÛoÃhϵ†Éª¼Æ“ È)CëIFqf¥3ePÌÈ®eºöà1ÇU·‰j•¥4M*|Ç¥dw$kj·ô¸×?DûGUýòÇ{Ú8ÕÒêu9•62i·lü…9–÷µò‘Úö?÷ÏØDÝV‘è›q…äìs7 lî{âÅÌ3X?û“Ÿ!‚öÆ*.®¬ýÍ!ô¢×sjW¤ÿÉu8ÙŒjäñÃØ*ö•ƒÿº/ä0_ÑÎÏëâ~b:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+P_@ºaöX÷ótÃìþ±î'æü/6=Wq³- ЗÐ.˜}ŸÖ=ÄüÄt ¦gõq?0Ïáy±ê»™hV ,®tÃìþ±î'æ' ]0û?¬{‰ù† ÍUÜlËB´eô ¦gõq?1é‡ÙýcÜOÌ3ø^lz®ãfZ¨ + ]0û?¬{‰ù‡@ºaöX÷ó þ›«¸Ù–…jB{E•Ð.˜}ŸÖ=Äüà]0û?¬{‰ù† ÍUÜlËB´eô ¦gõq?0èL>Ïëâ~aŸÂócÕw2ЭY]é‡ÙýcÜOÌO@ºaöX÷ó þ›«¸Ù–…kÚ Y}é‡ÙýcÜOÌ:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+@_@ºaöX÷ótÃìþ±î'æü/6=Wq³- ЕÐ.˜}ŸÖ=Äüà]0û?¬{‰ù† ÍUÜlËBµet ¦gõq?0èL>Ïëâ~aŸÂócÕw2Э@…•Ð.˜}ŸÖ=ÄüÄô ¦gõq?0Ïáy±ê»™hV€,¾tÃìþ±î'æ# ]0û?¬{‰ù† ÍUÜlËB¶à Y}é‡ÙýcÜOÌG@ºaöX÷ó þ›«¸Ù–…jËèL>Ïëâ~aÐ.˜}ŸÖ=ÄüÃ?…æÇªî6e¡Zö_@ºaöX÷óÐ.˜}ŸÖ=ÄüÃ?…æÇªî6e¡[e–tÃìþ±î'æ# ]0û?¬{‰ù† ÍUÜlËBµeô ¦gõq?1é‡ÙýcÜOÌ3ø^lz®ãfZ±et ¦gõq?0èL>Ïëâ~aŸÂócÕw2ЭY]é‡ÙýcÜOÌO@ºaöX÷ó þ›«¸Ù–…j Y}é‡ÙýcÜOÌG@ºaöX÷ó þ›«¸Ù–…mÀA‹/ ]0û?¬{‰ù‡@ºaöX÷ó þ›«¸Ù–…hËèL>Ïëâ~b:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+b,²Ð.˜}ŸÖ=ÄüÄt ¦gõq?0Ïáy±ê»™hVÜ / ]0û?¬{‰ùˆèL>Ïëâ~aŸÂócÕw2Э@Y]é‡ÙýcÜOÌ:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+S_@ºaöX÷ótÃìþ±î'æü/6=Wq³- ЕÐ.˜}ŸÖ=Äüà]0û?¬{‰ù† ÍUÜlËBµeô ¦gõq?1é‡ÙýcÜOÌ3ø^lz®ãfZ¨ / ]0û?¬{‰ùˆèL>Ïëâ~aŸÂócÕw2Э„ / ]0û?¬{‰ùˆèL>Ïëâ~aŸÂócÕw2Э@Y]é‡ÙýcÜOÌ:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+PW@ºaöX÷ótÃìþ±î'æü/6=Wq³- Ô•Ð.˜}ŸÖ=Äüà]0û?¬{‰ù† ÍUÜlËBµet ¦gõq?0èL>Ïëâ~aŸÂócÕw2Э@Y}é‡ÙýcÜOÌ:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+@W@ºaöX÷ótÃìþ±î'æü/6=Wq³- ØÃ´Y]é‡ÙýcÜOÌ:Ó³úǸŸ˜gð¼Øõ]ÆÌ´+@l]‡+XN¿"ˆ .N:[SÑÖ¤©H'K‰¾S2¹¥i;o+Øìdd5"Ôd¤®¸Ÿ¢}£‚ªþùc½íW÷ËŸ°¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1LXßFÇßgLtvÚyÆÐú$6êR£"q:…«*‹‰fJNÇÅ$|Ô¡æMCWcIËf.ZÉð-\D§Ç™„1Ž“RˆGФÈjCÉ5«6U’hJl• Ô“Iß}®d2± ¥b¬G‹eS™|,Hˆ²NJÒ¶å2”Ù)I#NUp3UËnÁ2ÂÉÆëû\ÎIÙ• ¡ø´ÊNŒ´£‡©NÕÍ2d&\)o¥h[…'"œBR’$fÈDe´ì”í=ÅKˆëRòí¿v¿ƒxOnàи´ÌC£ýRëîÕrsÓaGy‡ÒFÍä!´š³¥Y’’$$­°·•ˆ‡ÊLhTÍ J£b'j¢Òñ«°ÐQ$edï”Ö•SsZ¬E´Ï…ÌĹ_[îµÿDÿ’?;áëþÅ8ÐÅZ:£a(µ¹µy“ç1®Ý2*"­ ¯®Á=¬^dªöJˆ²•®d{Hl+:0 ÄÅXª$gç*Ÿ‡#Ä5¢EF;Iuò#/Û8„¶ÒHŽÛIFf[¬DXÊT[ŸßÌÏŸ¿Ë¹O€´©ø »X®ÅURLØððê«L. ö6T‚ëÇtÒ•%j#=é4ì-Ýb·1¤¬9M£ª˜ì•EªÑãÔ‰ JœkZJº I"%[.ûñ¤ðó„v™´jÆNÈåYz|ËËX¯½  ¹…¦-öšW—)­¸ÔD¥‘îÌ}¦:}ÑbÒ4…k´93ÙˆcÎK‘_x”´›(Y)*RR’Z D…Ò[RGÀ†ô°®¦ËOé¾ßɬëlßw×(ÒÚ- !…ðÔ•á\K‰ÏA{µI— c­¯X³$©+/ÙÛ!߬ƒ#¹]9¶Ü.a*.#ÒÎ(¦ÁeÚ]>”S¤Èk”´’^©ÕV”hBAÝ$D¬Ä‚#33-ØËI¤×©Ÿ9\¬Z0p&‘]§2þ&‹‰_tâ^3Î5! "K*ÙdK%‰YxXÌnè8KÑk¸žSÕ)Œ#"vI’ã¾IQ+jØq-Z朙\±L–F•\­˜á&ø˜uâŠLÒQ°©.ª3n4Á¬Í¤8²Z’›ì#QŽÜHŠý…¸nôw‡c:nå%¥¸¢S¶¾T¥&µX¸’vþb¼bå%Å’¶’»4=¢‡…0ŽÆ5ˆtê+µšrܨgNfW’¦µN¸k%¥ JfŒ‰s<×#<¦>Ô|†jñ¨5ˆœîÕ6}|¨’#»%³|”´‘¡Ô,›µ‹5Í&“Ýkí¹L°Ó’ºûû¹«Ä­€Xø×áÚ5 Uf ꮳOÄîÑd²óíæyI¯2MõÄe´•·m¸ Ž4u‡hÑq‘R¤ÕMü4¸&g%ÖÖ‡“$‹e’„™Lï{ÿ+qxY«ü;7ü0«Gwßß§u RS€¥c ÑÍÂ*)§3¨if³oXkRÔ•Ù$[²í>Á æìå%‘eCÂXAXwVªûÍÑSö :S¨’Iê)*hÌ&j,äf•’ˆ­çeôw@)UTrŠššòKÊ:rµÈ%7ÕýÓ¥óí2Úœ» vÝ“efþþ}<è•Pë´‡ix~M T“šLU(‘êJD§RâÛS¦»¤””$Œˆ’\;°r$ œ%²Íã%%t^Ú¢S°ÆðkE&¦ºj’¹î)·’˜Ú§pÒÒ‘–ê¶BUÍVÌ”ìâ\u6—^†é²_©KƒÌVˆró›kadÌß"$ÈÉE”ÖeÕ3ã²ÆU¨Þû÷þ–îGç+Úß{ûßìkS°Ž1ÂÕ:ªn5#ƦÍM™¤2¥-'«BTÚÔFE”ÍDi5•Ìiô¹…bRyïT™&UR»50݉)³ŒÊIÕlx²ë7õIE²÷±¤È%„œbÛô ¼[KR«V‚4–6ŒóÏ”'0¬ÇiµØ•—)­¸ÔD¥‘îÌ}¦!¥OÌšÉ'-˜Ü­» EÝQοÚ™=•aRÄŽ6¥!R Nì¥YI&w·[.î Ñ5#Hx»D“9š~!9+Šûħ©BÉIR’I%¤Ô”(º¥µ%³`šI¹(½”¯ú‘ʼRº(ò-\ D§Ç™„1Ž“RˆJÅ Òd5!äšÕ|ª5$ДÙ*A©&“¾û\È1ΠÔgcŒDÉT’õ»ýÞÒßA&J´™4y.ÚˆÈ÷çÙ¶Ü2ÒÙÚ¿üZãÎW±U¾dÑh¬iSHð«QäVÎ\–žl¥e•†L̬ÖT¹Ö"JÈ‹)Ü•{•}B£R#á8å÷jì¶Ýe0iìÄ”„¼ÂòkIÅ9“¬i+[)&æ[ÓÃ3¸»__ÐF²k†Ÿ©ÄpÒ7þ¹«ß÷ÿçhW¼5aåÎPÑØ’ÚŠ–¤½qÍ-‡O‘P•Q:¼-±VLƒt”‡uf£Q,ŒJRGÖÌVþwŽ4‹‡XÐæ—Žã5ˆšG%6F¥!ô’Û7™Âß³B;]\fžÂîû’¿ê—òGÊVÜW"—¥øØZ‘üЇ"/( Â”ö¦KhÖ4¬ù‰VgkÇb»§°ÿÈاGXj&!Ÿz•"®™”g9%ùO6¶ÝA!µ)³JP“#²ö*ÿÊÛ.xxi]¤ïn×þ ªÊɲ§à Äðb±(ÝáLÈÑ7–™z"à›ˆJÛ6_JÞ²II4ÈÒd£ºVW¹\¶mèj;ˆç7»YfIàòÄëä6â·kGfÒjÙÇe­¸ïb±4¤“Z_õkø"uRveHBÔ‰$ÆŠð„©´Ù•s!>âd£Tá­ä2âžF¯ö„iR²mI ­µFWÆ%Át6i®EêŠÂóš‰(帅&Q-Å7™”¤Ñe&ö3VÎ#3Ã4®÷_ô¿ìb5“ã÷¾Å{À@ž­Ñ¥â¼y UÎb˜‡I.Eu(SjB²3Ì…•’em›Èï²Ç ç%Å’JJ)¶r -Ì7£¬+[,%©“Ydñ33RÎgZ=C‘³]jêu’«T¬e8Æ· `,œ-C­Vê:„Vd<Ù9Îq¢¦m¬n)/užÛs4¢ÆD[îeyò•>ÿ.èÓÎßçÙ•©‹O`L+.ƒ Té57¤;Š‹©ØRÚ6%Òò.ÙØ¬e²ê½·–mŸÎŽ©e£¥N˜™HÅg†ÞT“I¶µ[c©$‘Kù«ûH2µ-qçFö+ =sáØðq4¨ ª«Éj‹1g%÷Û.X…º¦ÌÚ2oöGt¯Ÿa‘íÜ>ØÓèï ã¹øn¡å3íÇ62¾Ô¦S—:[R³´w²T¥–ó"M‹Îxi%vÕ¿ç³ ª{—ßÝÊÈ‹¤ÜDÂLÔ TÍNJmªCËšÚÛέ+qÓ"h®E™V2ڽ痭]êStå³.&𚚺-Ì'£¼+\‚ÉOVcÌĬÎI¨¤4¶Ùr1ZÚ²3J'Õ½ÊåÖÙsÕ·‚ð³Å‚*Ö%Òé8„å"K’ÜA›ÂòÜ”I""Yض‘å¾Ó1.Vv¿ß§tiçFöûõìÊà@·¦hÆ’ÍD’ó5h‘#Ó&Uu3ؔܶY$e(î%´ÙFj<Ĥ‹-¯q‚Þ Á/S°Lçj:TlDü®Pü¹-)Ê9Jͦæ¥K9™oË·aá*.?|;˜óâUà;})a8xY4Ò {'+Z­s“™—öË)%M8ÚwڬĤìºm¼qtå²É#%%tZÌ„_¢àY2 ¸™¡çb/W)£C!Ôµ¬"6®i5ò^ö?;fÜy¸; ÑðLºÍYUgåÓñ´WÑKimü‰5gFfÌѲÛóß/ ÝYrÓµþø_öfžtJÜ—MÁxYæpô‡^¬­ŒQT~%0ÒãITVé6…Î1.§[“l–¥C‰)¨’ÙeµšR²aä–¥$³e3E¯m÷Ò¥SIËÔÚï`ǧèúu)w¨ùB¨Å)6‡ \˜Ôž±¶jÕË·}ª#<Å{ÎNÁ4Ì„qQ…i­r„Êf<–nK„…-¦øÌ}¤Y¶\ö˾7ô¿ðkæ­=lW€-8º8¢7J¤R²Ì95ZQT1ú¬V`ÔJ6Û6zՑ؈֓"#=Çc¶NÑÞ®SðYµ˜ó1+3’j) ©¶]ŒGÖ¶¬ŒÒ£Iõor¹u¶\öXJÛïÓº0ëÁoûûÜT†¢ÔÑ­D“€ñ‰53¨Vêêj7$y-¡”6ò[Q8YLÖKÌddFž©žýÇžœEÅ¿¼ìµÉ¬7ˆd¶Õ)ªƒQq­bŒÜJœBÉg}™l[¶žá˜á%(¦¸¾×²L¦ÀgbÌïT!Æj[,1)ÆÛnQ<„¥FDNeÙœˆ¶Ûeî0Ef¬ìLÏÑ>ÑÁU|±ÞöŽ «ûåϘ_hÏF²FŽFá­“¸l¤nÙ;‡~‰B¡­‘¸Æ®O´‘¸Æ®OÕ Q™¬•¼kdo1²•¼kdo1Õ¢S™®|a¾3oŽ•2´Œ7F#¼F[£Þ"ì$b:1]Üc)ÑŠîã`C#ß4Æ?ïšcˆ·,ét{‰šÂug*©1sI#»æmß?ïXt®eb¹e2,Å´”cš1HMÂJQâk(©+2Åé œRiÒ ™[%S7â §Ã&ÐéïpÑȲ©|s¨WÛ{íÍ_H4ú«.52!Êì’”é³UŠÊxŽäµ©¸dj2¾Ë™Û…¬+Óà K™«k\ÓɆ…TÒ[shõjyBª}É Ý“ iudG•k"„•)Dv<Ä¢VÂë‘W J•gS|Í£ÃeDÒdH)ÐcÓ«-Ǧ¥I„’›ì^×ROÜ–{óù×3;ÜÎÿ:~‘iði(¥1L¬œ4I9z·gBw;ÇÚ,×ÍjÛ½Fv±[qZ¹&j®¦žL4-9ÂyêŽVŒÛTçRû„™0ç%×Jýs'XI6¢Ùe'oöX‡ñ\ÒU~/ªâ&hµ¦©%-Hi58êaÖÒ”¥$¦œŠ´žÄ‘ØÍV;íˆ æªÚ×ûûcÉ…îXð4Oƒ*\˜ÔªºW.1Du*™hÔm»IB šPƒ334¤ˆ‰ç±¶&kƤÇj<Æ‘LÉZ9O0ꉤ’I%6ÃJ2MÎ5o;Zç~d’ÄT”v[ÜeRŠwHë°.…¢ÏJ"T&r —ž&;wdËÌý¬gTW;™šTWêìê‘ÜM%C‰YWO­µ.#)¦|,‘Ð{ɶùDí¹¤ˆÌŒÊö3°q"’O€t¡'vŽún8¤Ìäí;  =Ê#%Š´VR‡nG¬²!‘)w"ëÏùŒ‰F„ýUº¢¡bJlÝ2SU8¥F嵆´&%f«cQìWÜ+’Ú3™«¨òa¡b3¤*[/©Ö¨õT¥qÕL¸<ŸV¥%J-O!ÕÜÔ„ž[žRÚ!C‚šÊªå¥Cä>ˆmr}ÚQÂÉ“üܶØj®¦<˜hlñ=M5ŠäŠŠ!´:H$¡÷µ$’‚IЄ&ÅkHˆ¬\.' TcRk Ô$7QR˜ë°¨3Ä8FVVe6²µ¯²Üwð=X¶ÞÖש&ʵ‹^;¥È™YÓ«ì=ãÒ¢Õ"dz§½Ã&ᤔ£ÿ(îcê­!Ó•> Þl­%È)øÈDèIi·O{š²…×Ç1‘™Þä+¾Ñ\Í]M<˜hXótN™LitŠ«ÌJžš‹Í.TJ¤‘$µ–ä6#2I­±WUï™WW4–ФjÒ\…USõˆÈbRÝ“ IwVJÕ)iL$™šM[ *Ø›(²¤Ê¸—ŠªýLy0п bºu ’ä%Óê²A’¤·Ëc*3¦FyU©z+„FEb½Ìÿ³qr"„åx›Ê*J̶°Þpd $nTPªiM©ÌïÅ’…êŒÔ‚5-¤¥$£Q¥Dm¬‰6±pvñý=×ke ×£œWª´U6¦L­«Õœ<™,EÕµ…zWЍÒWàh¨ÃyÔãìXX¡4ÒÔLAÀdã¡RaÅjÊÙRJi†ŽÅcó³yÇk\ïËg9MíK‰$b¢¬‹&‹¤¨´dBM>}³‚•"+‹©CqƫݵÂ5eÚ}[ÛùlÌ]#S¢Ó𧯤UXŠÌò¨´Ûr '$’^rpŒ ÜŒfÍ™z¾nÁ\›5Un¹“ $ô‘߆òiuvù“–ÃmK‚†’ù•µ¦Ú`’²-Ê23-†V1ð®i æÐªôر'³ÎΛòyCinRRÍ ˆƒÌdéRL•Öß{×Ü 9¤±‡ÓAn›_äK¨m ªERÛK¿¼J8yÐJÛrI•ï´p &xª¯‹#ò`½ ÌoB¨SbÑ*q66Ûq”¤Tb)äÇB‰D‚W$J–”™\k"¹íão¤Ý&P± ª¢©+í¢¥(yKv+RJÉAåen-¾ªTi7JæjØ[ÅN 3Uv\oÄy0½Éà Äðb¹)Ùaœ_O¤a9˜}ÚmEÖjáú©1R—¬}OÞEqiÊV2ëìUÔV3ÕiM…IDƒ¦Õs¢©ÄE"žI8ª4™²iäMR²L¬[mkëÇV*É‘ºPnííCQgÑi´iŠß#¥žhIj£¥²|L–ˆD«™í;ŸXÈŒîeqðŸ݊íø%°Ûޏ—V·'F4º²þ7I¸­©ÕZäF¥\Œï·qñD aâ*4ÓaRŠô'€ét{‰šÂug*©1sI#»æmß?ïXt®eb¹e2,Å´”cšà G ¸IJrT¼Æé-0‰D»®FVOWÍØ+£ Õ[ZãɆ…‡RÒ6¢„·6™\uôHq'P†Dû‰óTñ/ÛúL׸‡áœQ]MSR±¯¬ÛÒ¨ÄBͲæ”DA-D[ ç{Ȉ­ÃÃÄT–æîeRŠàvúAÅz»|:ú‘Kˆˆ›=£ý™*æki-o±šv/q'²ÇÄêTuÙ´b¢¬‹.“bÁjÔ:ue„ѳóy¢l63 Ò»!¹æ%kß1ÙGs"1üGÒDñ)q¥U’Í%.&y\ÕˆR-°zIJQæÍ|Ç´îdF+pæªë÷ö‘§“ 6Ÿ¤•¨'3Š Ç†Ó5ÈfB44…‘š’˜å ¨”vÌGkïÛb!›^Òn[´Fé4ªâ›¢¢J"¾äˆŒ)E#c‰S%Ʋåê‘[‡SXº©ZÿhÇ‘ 68Äíb$@mˆóc3 +Clºû i£#ýša¤£mÌöön¶ÞdA9¹»Ë‰,b¢¬‹}ZHÂü@¥PàâTJ¤ë ×"CtÍkR]S.d«bT”6v3¹–á먮á…á·i·)‹rTÚª1 jxÎæá¹È³çá›5òõwl ¥Š¨ý~jŒßÑ1Õ*‹ éÔì@Û-8n²KªÅtØY•Mšá™¶£íI‘…3R©ÐÎ$zn [:ã”ȪEVéïqä5þrlc€…‰¨¸?ØÏ• ‘ Á†ÄhÔúê9:C/F¤6N)J^Wް®kQ•ÄÅr4YÎÛO´að;¬3éô*"i‘ ÖÉâd9jŒcIH$åÖ¶Kˆ³i]†J¹Þ\eBªP)ô)´ZÊéôëòFÑP†Ùµ:ËL"QæÞ«™æ;ÜÊã…¶b¥¶o¸×ÊïbÀ‰)qiñàµM¯Q’hŒ·*qìtžòmÕB5 ¶ÿ ŠÃ.“bÁjÔ:ue„ѳóy¢l63 Ð»!¹æ%kß1ÙGs"1ZÙbª® ãèX´Í!Ó©©JaS+m!¹g-”òøjK™ÜÔÑ#&Èûb¶ËX}Ѥèˆì„Òªš×fãYÉ€f™”¤ÝAœ¢Œ›šms+ï31Zv‚ÅU[®<˜hdU$òÚœ©—|õï-Û¾é8çYF}eemÚv+žÛÆÛ¾òSôO´pU_ß,w½£‚ªþùcóîÚ3ѣ쑣‘¸kdî)†¶NáߢP¨kdn1«“Äm$n1«“Äuhfk%oÙÌl¥oÙÌuh”ækŸoŒÇÆã¥L­# шï–èÄwˆ» ŽŒWwÊtb»¸ÅØÈÄwÍ1Äd;æ˜Çâ-Ç ;Ú&ÀieÏÒÝ6—-ÖÉOCz‹5Ű®)56Ù¥Ví#ˆU§)ÿlœ~VþS زÏh×ÛuàGÚ5öÝGøG±ð!ËTæË¤~“7Z_Ú5öÝGøGÂ!´kíºð „+@ µNlºGéZ_Ú5öÝGøGÂä6}·QþQð…j–©Í—Hý"ëBÊòF¾Û¨ÿ¨øB|†Ñ¯¶ê?À*>­2Õ9²é¤]hY~Ch×ÛuàGÚ5öÝGøG¨Z§6]#ô‹­ +Èmûn£ü£áÚ5öÝGøG¨Z§6]#ô‹­ /Èmûn£ü£áÚ5öÝGøG¡ í µNlºGéZWÚ5öÝGøGÂ!´kíºð „+@ µNlºGéZWÚ5öÝGøGÂä6}·QþQð…h–©Í—Hý"ëBËòF¾Û¨ÿ¨øAä6}·QþQð…kÚ 2Õ9²é¤]hY~Ch×Ûuà<†Ñ¯¶ê?À*>­2Õ9²é¤]hY^Ch×Ûuà<†Ñ¯¶ê?À*>­@2Õ9²é¤]hY^Ch×Ûuà<†Ñ¯¶ê?À*>­@2Õ9²é¤]hY^Ch×ÛuàOÚ5öÝGøG eªseÒ?HºÐ²ü†Ñ¯¶ê?À*>!´kíºð „+P µNlºGéZ_Ú5öÝGøGÂä6}·QþQð…mÀ@eªseÒ?HºÐ²ü†Ñ¯¶ê?À*>y £_mÔ€T|!ZeªseÒ?HºÐ²ü†Ñ¯¶ê?À*>!´kíºð „+nÁ–©Í—Hý"ëBË, £_mÔ€T|!Ch×ÛuàVÄ 2Õ9²é¤]hY~Ch×ÛuàGÚ5öÝGøG¨Z§6]#ô‹­ /Èmûn£ü£áÚ5öÝGøG©ËTæË¤~‘u¡dù £_mÔ€T|!>Ch×ÛuàV€jœÙtÒ.´,¿!´kíºð „#Èmûn£ü£á Ø@eªseÒ?HºÐ²ü†Ñ¯¶ê?À*>y £_mÔ€T|!Zða–©Í—Hý"ëBËòF¾Û¨ÿ¨øB<†Ñ¯¶ê?À*>­@2Õ9²é¤]hYe´kíºð „#Èmûn£ü£á Ø„Z§6]#ô‹­ /Èmûn£ü£áòF¾Û¨ÿ¨øB¶à 2Õ9²é¤]hY^Ch×Ûuà<†Ñ¯¶ê?À*>­@2Õ9²é¤]hY~Ch×Ûuà<†Ñ¯¶ê?À*>­ 2Õ9²é¤]hY^Ch×Ûuà<†Ñ¯¶ê?À*>­@2Õ9²é¤]hY~Ch×ÛuàGÚ5öÝGøG¨Z§6]#ô‹­ /Èmûn£ü£áòF¾Û¨ÿ¨øBµËTæË¤~‘u¡eù £_mÔ€T|!Ch×ÛuàVÂ-S›.‘úEÖ…•ä6}·QþQðƒÈmûn£ü£á Ô-S›.‘úEÖ…•ä6}·QþQðƒÈmûn£ü£á Ô-S›.‘úEÖ…•ä6}·QþQðƒÈmûn£ü£á Ô-S›.‘úEÖ…•ä6}·QþQðƒÈmûn£ü£á Ô-S›.‘úEÖ…—ä6}·QþQðƒÈmûn£ü£á Ð-S›.‘úEÖ…•ä6}·QþQðƒÈmûn£ü£á Ô-S›.‘úEÖ…—ä6}·QþQðƒÈmûn£ü£á Ôô2Õ9²é¤]he×#Á‰[—Qç8 Éq¸³5*g”´•!ÌŠÚŒÄD¬§´¯c`Ò5?DûGUýòÇ{Ú8*¯ï–??a}£=>É9†¶NáÕaY‘Œèqä4‡™v£6´’’´›‰###ØdeÀmë8u[WæG‘G¢Òš«HŒÃ³¤v”¢qVmD{ŠÅºÜ8¤Ãє㵙Z¬c+2¬‘¸Æ®Oa7£œM#KÃëf>0ße?DX²mjµM˜º]º#‰n|Ꜳf+JVÔ{ó‘•‹q•íròt9Œ‹3†šs†ü%On¢‰dpŽ*|çõ¿ä™ì¾ÒÙ´…úd2’*÷F#¼G ôW¡Hnéj…KÄõ¬)_¡Mb[¶¦Ö´ÊSM‘HR2«X•:Úòìê¡gs±§t‡…¼’¬5MòWõ±Òÿ)¢Íå,"êRr)V+,²Ü˱Ií)É7b ;œ›£ÝÆ2®î1zR1óLcñù¦1ø‹qàBÁˆbÆ >™ íÁŵU1øÑhÝʶŽBP질õe¶éEŒ³+~Û'mÍ;í6àZ—2»…ݧFTsQȄˈCkm7ë¶E°”D[R[ ·u¼î[ñj¼®û¥½ú'¥þíûs߉QXœ¾ûú¿Eð)PC èíè» Q0t©X©ú]F±5¢BÙSèZ! Ì®”ï;V[·$íu*™Ò6,-X&£Mjl •Ô¸•,ˆ­t¬‹rŠå·qÞåm¤\¼‹PÆTœ)ßð»_Ñëo½þ‡? âTqU%_sµýÈåÀu€„ŽçDÔÈÒ9æªì(Õ ce‰K:Æ–òÒ³I¨ŒÈŽÙ-c#.½îF’1bâdH®ëcÕ#"\~TIJ×´Ò×'¹¬¶ìV³«ráÈââ¼f8|C£³t¸»ÛG¹zñÕ=ñøáqN†ÅÒâïmåmûž¨ }çÇ8“ŸŠjÎlº¦óZ×±™\|e4ÕÑô’’º2džÑ{G£t¢ì-DÁÒ¥b§éuÄÖ‰ eO¡h†ƒ2ºPd¼íYnÜ“µÔ®ˆx•,bçväÒIqÿ…êRÆã©àã=í»$¾ý8€ê4…K V ¨ÓZ›FeFu.%K"+]+"Ü¢¹mÜw¹[i..Ó©‘SZ§8ÔŠ”x0spüО¨ ЕŠqlšd©#)p`:ꆤìqÂ3±¬Èö$üÛÜúÞe{¥|M)ôyŒ?J’æT6O—v3È{n¤ØŽÊþV=¶5rðþ-Cˆ_ðî¿£~©}ï9ô|Jjò£O_F·PèëaÜ=€ôtª‹SÕ Ìª8zS‹"¡Q“ÊTd¥+þë$d§#P¬è¹%Z²7”J­_ R6ÖÔ¯kî[“nïÑn$§MÍî<‘À@ôÇÒ{ àšŒ|EŠpLÖç@¦¢Τ‰îT9T‡y§Ú9.8µ)IACVSQä"+u†gæqšˆÖs¬ž—²|wz4mZŒ©Zþªë«_À`„žÁ{$„ ÃFsáHj¢C޹’©oH~Y³gœuiBÚg6k’6ØÈŒˆòº¦g~JÔ¦Þ‰2¬¨í´ûRIu)ë>ƒCdf­»L–¥ûýGB®#ÊÙ²nÉßpô¿Ïó´?¨a[äìZ-´÷½öám×ôß{zxÙôDpæ„ôm@f„¬S‹dÓ%H‘KƒOuÔ- !IØã„gcY‘ìIù·¹õ¼Ê#â4°¼Ê—wÜ’âßßSÆãiàéíÏä’âÙBÖ•°lL;53èó~•%yPÙâËÄ"ï™+;^ü~6_±ðÓ;uú Ó±.‘i´Š³kvÑ!ç[JÍ:ÍS:H3-¤“4ŒŽÆv2;È»ÏR޼íÈŒ Ü„gº¼Š¤"É5m3"2±Üä‹j>¯:µþ˜è4ì5¤Z•"’ÚÚ„„Gy¦Ô³V¯ZÃnšÏi¤fEs3±ÌÎæ`rËÐv`âÚŠª˜‚|h´HŽå[G!(vS„Dz²Ût¢ÆY•¿m“¶æþ›p- K™]ÂîÓ£*9¨äBeÄ!µ¶›õÛ"ØJ"-©-†[ºÞw-øµ ÞW}ÒÞýÒÿvý¹ïĨ¬N_}ý_¢ø±‡hvŽ¡Ð ¢}£‚ªþùc½íW÷ËŸp¾Ñždžy˜øÎ‡"C¨e–ª1Öã‹Q%(I8“33=„D\Gi‹Ê‹ ¹L‰é¹4ºÅAÂ9¯äfKO>k'²¹(øþ ÎFá­“¸}6¾Ä-tÎV"ŽÔ”¯f‹v£ˆpÍeUœÝ~Ñü€ …ð í®ÇÓh®Òê-9-´#û‘De™62²gü=‡´ËuŒ­n+´@Ž­(UV’48ÍZHÌ«ÔeU'.dÇ38­„Eæ ¸$‹ëxä’²7àdvÆÐ™rŸ5.H§-*Ê”ØÖÊŒjoÀÏyRâG¤ÄU©U¹Ç"Aåm7&š#ê¶_ó>Óãý–"ÖŠ4a¹¥½šFœc'$·°BSp/=iî^´ü=U]Y®lCDŸ ľ£efŸÙ-‡!š æÛ—êYTƒq.Q€9þ%áx_¤©bct×ÁðýŸÈšyÑ•â[ZbÓ ¬cAF¦.­Ì­I'ÒíIô.BÒI"CJ4] ;ÜS«Q’T¥Ü…J'€¾ÃðþEQÃÆÑãó~­üX¯^uåµ0é =‚öv{» ˜Ä NNl£’‰§ã-*Q¤ÌºŠC„i2.¼ˆˆŠ×;âb¬Rõ^)BmRTƳX·Ygpíb,©"JH»¶™_}Ç6B8à(F§š£¿‰B>†o9Gñqüþÿ á|’AÀ®ÀøÍú.Óæ¥Éå¥YR›ÙQ‘íMÏqžòþ¥Ä‘ZQ«™-Æ“„f­#gˆ«R«s¹DƒÊÚnM4GÕl¿æ}§Çû,E¬ o¨«#d­¹ÀA‰à ÆLÒà\Y+ ÍÊ¢SÔ÷UwØ#ÚGþZ{ÿ–ÃàeÍÒ¥8Ô‹Œ–ãYÂ3ŽÌ¸ÜYˆ_®J±fjgû&¯¿üå?ü·v™è„˜ÅAYI%dOxÜ᳇êôê&½2&ªW×rµˆ=n©d‡:¤y“eXŠü.9÷Ç êUKÐ>ŒäâÜ77/ûêQbµ8âµnTYÔµ¤wó,E³Î¿³…¢œ'I›M¢Ë¬·/ Á­ÑðÒê|™oò…,–qžk6H#ß~·~ÅiOSË®ŒGx‹ê¯„°œÙ8Ú–ÖªaŠÄ 8š”Xsf8꣺Óßµ6Õr'¶”‹f#Ú•Xg;£,˜ý=SiŠA5öNK„NTá4“w¬•’F·š²HȺ»·‹pšDRg›®î1è¬YCç¼S­L­ax ººÃ¬2ÙºJÎòHŒÔ§ ÉWEÒ‚"Mˆ®b®ú@a8K•ü+Lu×!Buµ0nÔHq¤:I3ãlö¿ t¦¤ìE#ˆ£ÒçVë0h´¶9Dú„–âÅk:S¬uÅP›¨ÈŠædW3"í g€ñ^‹ ^#¥rfÉ—:¹CNgv+º™ ²fY\êÜìG¼®[G¡)tèÏLØ?G¯àÉõÜZÅN–r«««®:#Êum8[)I¥hNt•c=×â;0`H¸« Ò±e2^ÃØ^³‹gT¢ÂÛ*RN¬¬­6[ÈŒÒy—¹ #>Á&fÒ[·?÷#hñ)ˆµÙPçUåK§ÒÙ¥DuÓS0Ùun!„ðI)Ã5*ݦ{–á„.š| >iˆ)PišŽE‰iU½flü…¹)ÕZÖͯe½÷;e¾ã½¶\ PØPiñ*SÄÊå>ŒÚ[5“óPú£¹R&[qWÚg´ˆ¶ÛØkM±1æ’Ô¦ÛqHK퉑‰I%’UcÞYˆnÒ#Øø€ íCmR¥A‹H9ŒKJŸ!ì¹à°Ü’y‹¤Ì󛌥³Ê}Sʵm=—-  HžÑ¶ÃØn»ˆšå˜üÔAk[ Û"²gb-»Ô{l’ºŽÇb;ÔöOàœY† èé¨V«„V7¹o)Û§1»ÕÚ½…~¶^®QËñLm|,aäSÚri|õoO»ÐÇâ«PŒ|˜m6íð_=ý/€ìô¹2‡;*E*'&”¬Ç8²SjrûËaY{óp3·×ãB”ÝH)5k—)ÉÊ)µ`CpaA§Ä©L[+”ú3ilÖOÍCêBŽäYH™mÅ_ižÒ"Ø{obûË&Úi´š–µØ’D[LÌöÎÄ”*¶ª¹K­B\9m‘¡FJ##âJI™(¶\Œö‘–ò1eý+jU“"U;•b¹Dq×I)CYzÚ²Ê}së\÷åØ[3ßs¦¼ACªÑ䢫MË+Xâ ­¸‡ øuv£vbÝkqÊ8ïÄ1ï#Êü qº»oE~ ï†þkÆWÍùJŸà^·_¦þ:(ô ;G`éÑ>ÑÁU|±ÞöŽ «ûåϸ_hÏF²F™N-—Pëj4­ %$Ë–Ò1Ô»¤—Ѥ_+¹©³oSªä:î­­;/Ú~Óvÿ÷ŽNFá­“¸}¬áý¯âskÓŒø£k„±”¼5.¯),·*PÖÉš——V騔‡·Í*+ÛgöÕÌÆ£dàÊ’BgòžUŸi¶D«5–Û³©J½÷žá¬‘¸Æ®OÔ¡RVµÊU!ÞÆöµjp¦¢3˜v‚òžL¢]Ôñ’ÍM\¬VÉ™d[OÎà01Ž9gé>>/™B`á0ôesJœ%´¦YÈFÉ™¦ÙU”ïtŸœ{ sÒ·læ:”dÙNQHé´›Žã⺠€Õ=&]EöÓĤd•#\M¥$„’I²²JÛí{'pÙ?¥L;=T–ñ&Ž¢Ö£Ó¨PiH%ÔœeâTmgíPãi#A/Yµ|Ôí³ã ñІò¼¢‹1Í5KV–©øÙÜ?P`SN–Õ$¤¨Ò¨šµ¤›[ª#5Öj32ÛbÅ;I•8xa·â¦K¸•ô¾©†îUGQ¸KzɱæÖPG´­—ˆãŽñ!A$tzOÆžYù3ýíä<Ň¢Q¬×ê3þ×Í,¹³y»mmæ7X»JÔÌG¤ŒgŒjx"Ÿ(¨ª§F‹"B]æç–šD¤-MmZuFebIõ¬J-ç[º1]ÜbÜ!)Kzy¡¿T¡â|A¢ÊUcR•5eU'š×“œª6RYu¶NÅžk)‘F»}!krkj­@¤ó<ºR¯9Y¥ëÛ–ÝB_(S NDõ]CÚy¼âÊdBœwÍ1ÄX z6Íþ«:þ,›XÃØtðì)JÖsyJס¥Ÿ‘Yd™í$Ûfâ;X‹ŸbéYXÔ“à Ið2'´A í@žÑ™KªÔi‰˜ÜŽ™Èé$üâáý†\ ¶•ÎÇ´aöˆi5fa¤ø€2€Ox=‚öIBI à—I©N¥JåTù aÓI ÌˆŒ'¼Œa—öñ">MY˜i=ÌþœZÝqN8µ-k3R”£¹™žó3È‘&Ià Äð`ȧ̕OšÔØO)™ +2äó.[Œ†8 4š³ _s>Ó$¿2S’¥:§^pî¥+þ»ÄIJÀžð````D ûeÇu2â›q %!i;L¶‘‘ð1‘U¨ÍªÌTÉòûÊ+Œˆ¬]„E°¿ Ä‹+ÜÅ•îI‡hvŒ™ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£]Eú|‡Í†¡¬×kòˆm?k_v±*¶þ¿ô!ÙvŽ «ûåÏØFÕVÑ蛤®Å5D–ÆhåþƉá ±…i%ÕnŽ_ìX~Á‘¸kdîAJMñg6¥ KüWCdö8¯¦ö*9±!øCý bTß*¨åþÃ…á LÆ5rxŽ•§ÅçJ#vþ‘ñR|×(åþÂ…àŒ'´Ÿ‹Ò{£—û‚9é[ƶFó*4©¾1] “„t:wt«ºMà|Šî–±ÂwK£ü‚9Æã¡O Eÿ‚èŠòHì\Òþ;-Óhÿ‡àx#Í1ãâ½§QÿSüÅ:1â.C CÜ] ŽáÍ4i·T(ÿ‡©þÇsMšD+Ú£Gü;OðèÅwq‹PÁaŸúq舤ÙÞ¯NG"ÙS£þ§xãÓž’¯þ4£þ§x½wÍ1ÄZŽ oeˆ‰ÉêYG§=%zÒøràéÓI^´£þ§x¶1l†•‹±©jYg§=%zÒøràéÓI^´£þ§x¶>!…åG¢ì6¥©eô餯ZQÿS¼éÓI^´£þ§x´ÈayQè» ©jY}:i+Ö”ÔïGNšJõ¥ðå;À¨C ÊEØmKRÊéÓI^´£þ§xztÒW­(ÿ‡)Þ­2^Tz.ÃjZ–_NšJõ¥ðå;ÀÓ¦’½iGü9NðjÂò£ÑvRÔ²ºtÒW­(ÿ‡)Þt餯ZQÿS¼Z€d0¼¨ô]†Ôµ,¾4•ëJ?áÊw€:i+Ö”ÔïV„'´2^Tz.ÃjZ–WNšJõ¥ðå;À4•ëJ?áÊw€+@ †•‹°Ú–¥•Ó¦’½iGü9Nðô餯ZQÿS¼Zd0¼¨ô]†Ôµ,¾4•ëJ?áÊw€:i+Ö”ÔïV½¢!…åG¢ì6¥©eô餯ZQÿS¼éÓI^´£þ§x´ÈayQè» ©jY]:i+Ö”Ôï:tÒW­(ÿ‡)Þ­@2^Tz.ÃjZ–WNšJõ¥ðå;À4•ëJ?áÊw€+P †•‹°Ú–¥•Ó¦’½iGü9Nðô餯ZQÿS¼ZC ÊEØmKRËéÓI^´£þ§x:tÒW­(ÿ‡)Þ­@2^Tz.ÃjZ–_NšJõ¥ðå;ÀÓ¦’½iGü9NðmÀ@d0¼¨ô]†Ôµ,¾4•ëJ?áÊw€:i+Ö”ÔïV€ /*=aµ-K/§=%zÒøràéÓI^´£þ§x¶ì /*=aµ-K,´é¤¯ZQÿS¼:i+Ö”ÔïVÄ 2^Tz.ÃjZ–_NšJõ¥ðå;ÀÓ¦’½iGü9NðjÂò£ÑvRÔ²útÒW­(ÿ‡)Þt餯ZQÿS¼Zp †•‹°Ú–¥“Ó¦’½iGü9Nðô餯ZQÿS¼Zd0¼¨ô]†Ôµ,¾4•ëJ?áÊw€#§M%zÒørà Ø@d0¼¨ô]†Ôµ,¾4•ëJ?áÊw€:i+Ö”ÔïV¼d0¼¨ô]†Ôµ,¾4•ëJ?áÊw€#§M%zÒørà Ô!…åG¢ì6¥©e–4•ëJ?áÊw€#§M%zÒørà Ø„C ÊEØmKRËéÓI^´£þ§x:tÒW­(ÿ‡)Þ­¸ †•‹°Ú–¥•Ó¦’½iGü9Nð§M%zÒørà Ô!…åG¢ì6¥©eô餯ZQÿS¼éÓI^´£þ§x´00ÈayQè» ©jY]:i+Ö”Ôï:tÒW­(ÿ‡)Þ­@2^Tz.ÃjZ–_NšJõ¥ðå;ÀÓ¦’½iGü9NðjÂò£ÑvRÔ²útÒW­(ÿ‡)ÞŽ4•ëJ?áÊw€+P †•‹°Ú–¥—Ó¦’½iGü9Nðt餯ZQÿS¼[ †•‹°Ú–¥•Ó¦’½iGü9Nð§M%zÒørà Ô!…åG¢ì6¥©et餯ZQÿS¼éÓI^´£þ§xµÈayQè» ©jY]:i+Ö”Ôï:tÒW­(ÿ‡)Þ­@2^Tz.ÃjZ–WNšJõ¥ðå;À4•ëJ?áÊw€+P †•‹°Ú–¥—Ó¦’½iGü9Nð§M%zÒørà Ð!…åG¢ì6¥©et餯ZQÿS¼éÓI^´£þ§xµÈayQè» ©jY}:i+Ö”Ôï:tÒW­(ÿ‡)Þ­L;C!…åG¢ì6¥©µÅØŠ¯Šëò+Õé(“P–Ðãˆa¶S•¶ÒÚÚR”‘! -„[†¤ZŒTU—SôO´pU_ß,w½£‚ªþùcóöÚ3ѣ쑣‘¸kdî)†¶NáߢP¨kdn1«“Äm$n1«“Äuhfk%oÙÌl¥oÙÌuh”ækŸoŒÇÆã¥L­# шï–èÄwˆ» ŽŒWwÊtb»¸ÅØÈÄwÍ1Äd;æ˜Çâ-Ç  Iˆ$ø|žÑ'´{D í@xÀ@ ì'°@H@’H8D ž OH@’žð````êtA,í,àøSc3*,Šì&žeäÐêú IROa‘‘™Ã#°ëAÔ§('k¦Œ§f\ÔLƒ«x*”ª1×+jn]YÝKpƒQ¨-´SI1›²ß#$“Ët¼ã¶²È¹Ü÷lè·ɡŦ:°óh¯ÊfEV:Ù#¥6¸p>Z¬‡ -n$Șœ±‘¨ˆüü™/Ä7º³õ|5¾-×ÓçºÉo¶´= Fô*…s MU&§HKìa«M4GT Î>ˆmºÓm-£I½gò³šÉYW™23«ôO£FÁ˜ ¡H£Ì†äêCÊ›%ÙãrD·Ð«Y´ÙDI#µÎÈ[IÞ“Zø að)I9T½¾|,Õ¸üo¿…·rOÐô–¸FN8Á5©ªYɃL¨STÒ2M•24U6êѹF¢~BÎå´âüí¼®ÑNª1‡yJ«Œ³Qv”Jª“ÍrIŠ–û-»9dº^hY™š—µ•Ý$FW¦cá•áýµŸ¸iÅþ_$ÖvÖ…« àç°KÓØ­&Øy©$ÈŽ·\6&ÒÉJmÝAês¢i‘eI©&›–•)*ék0Ã5 w‰ÚL®B‚Þ"“¹<†õ4hÉJV‰¯ænçyÍH"4Y2㱪…$¼>µÛV¸þ¶·¯¥¸úü®ž6Ö‡Q¤JM‡*—O¥"¢rWIƒ6k²_Bз$Deû6”¡&”¤ÜQm5ììÛÜiCŧèûÃÃñ¨Õ)œï.ž¹t©ÑåÈ©¼¶¢-6&V¥¨‰Å:„¦×JM¼Ä•:Y©ð¼-KÒjÛ{ßÕµm~/SK~âà“‡ê艙uì) sQ ŸQf‚â[„Ùº‚TÙ3Ú–¢p®’hwÖ\’›!*È›€¨’ôiF©”)¿Üô ƒë¯ÂÊŠ{ޱ6n¨JÚ'·‰(m£Bˆµe”ò™&— ÀU·á©oŵ¹|-n?Ÿ?Tgmhz,´Q¨V[yºÎ"90g·¶ómÏZ`>êeÅÂ&J…½Öq Ì¢A¥|ŠtYOVŠŠfª<”D‹-2äK\ˆ6ô†Y5en-’I'‰J$ºêÓ—)¢÷µDHxv" ?=·ºû´në•ïnö¶\Ö…Á‡pýQUª/áHÕŠqæ³}>‚ãÎKu&¢)Š”¶óÇe£²¬fŒÄŒ¦«Qu°õ4«R™†© Efªóx8ùm&«¡K[9”D\¥*yzË5]N©7Úd<îSÃ'97æZ÷ôÖß:¿TÚÜ­bš^‡¢(¸v#ËS³(,ÅÆ‡O„©´ØØa‰ªdÔüĸ£‚£CmþÉj"#A8fDF¡ª•‡ãF ÍiJŠ p+ ªÕbEKǨ´ô”Åm© »¤òDÈŒÝtºfd«™•UáU›ó7|¸n¶íþœW=FÚÐô~!´VkQ9:˜í%$·CDªqU9EBâoÏ—2§PÉ-Nó-V%~ƒ“M˜.*ÁÔ÷jU6â1U¥ª:b³S³VÚVät¤’GÉõK6¬’Ì¢3+]'H˜vŒCÂf¢ã*·Ü× ?]ÆïV“¸ó>ퟢ}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ ¢}£‚ªþùc½íW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž#i#q\ž#«@£3Y+xÖÈÞce+xÖÈÞc«D§3\øÃ|f>0ß*einŒGxŒ·F#¼EØHÄtb»¸ÆS£ÝÆ.À†F#¾iŒ~#!ß4Æ?n<X1L@ØÁ'À@“à „öˆ!= Ú Oh€ À@žO`=‚B€AÀ8  H€ðbx0B€ð'€€ H€I‡hv€ úÁÔ|iŠhˬÆÅH *tÈí°å Ç””±%ÖHÍe%$fdÝüÒÞ2]Ñn)uFnbê™ïÿôûÿ¬ƒ?êñüÚ«ÿÜd. L¼C.|ªN1âkufФítÕN$"\†ÐžLr·%)KdZŠ"2ØY‡-xNoT!ÿŠìZÎb-o1õf´EˆU¿Pý‚ÿëGÉZ®+ÎÅÿaHýhùUô¥‰#M¥¢ ´ÙÌU¤œv× Uj7QNgmä–Y¥•µ›$Ü•±$£-ûȨ̈ÑãÄ…=Bm}t³“P¥JŠÓ¬¦²5í°é¥Òó 9ĽҲ%m%‹Ã°‹…(ÿ⻼Ugþo«9¹ú›ó'bÜ73 ©×žv!m +©JQα™žá*ÐeE^v" ûOëFÃJÕlY;cøQÞ¡òZ5!Øur3‰r[«„—\[_´2e$—“•*Ö™‹xßKÄ•+UŠ]"&=BV'j–Ä—VCþö3%O>IQ‹$%H+nIm7+\n°Xuœz#}_yõ8ÅhZ¼êýÿز¿\>jú>¼­õÚÿ±¥~¸Yú?¬Vêob(Uþn9TН!CP´!Ôrh¥(ÍãÙ}› m®}HÙa¨®]¯›=YA+èìjß[ |_ë‡ð¯£ŠU¾³@ø<¿×@ÙQ¦¿Åt1·-O>ѱ“ßW |"gëÇòFˆÇ¾­@øDÏ×B€ÛËŽ†6ž§ÏèÉ ÷Õ( ™úñüÑ‚ï©Ð>7õãÑ`3dŒ]žr?¢Ý4÷Ôh ›úñüýV)^° |.oëÇ£ÀmpyÃê±Jõ…ás^#ê±Jõ…ás^= v8}V)^° |.oëÄ}V)^° |.oëǤ.ÁæÿªÅ+Ö…Íýx}V)^° |.oëǤ.ÁæÿªÅ+Ö…Íýx}V)^° |.oëǤ.ÁæÿªÅ+Ö…Íýx}V)^° |.oëǤ.ÁæÿªÅ+Ö…Íýx}V)^° |.oëǤ.ÁæÿªÅ+Ö…Íýx}V)^° |.oëǤ.ÁæÿªÅ+Ö…ÍýxŸªÅ+Ö…ÍýxôxØ<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<áõX¥zÂ𹿯õX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»œ>«¯XP>7õâ>«¯XP>7õãÒ`óÕb•ë Âæþ¼>«¯XP>7õãÒ`ó‡Õb•ë Âæþ¼GÕb•ë Âæþ¼z@ìpú¬R½a@ø\ß׈ú¬R½a@ø\ß×H]ƒÍÿUŠW¬( ›úðú¬R½a@ø\ß×H]ƒÎUŠW¬( ›úðú¬R½a@ø\ß×G€]ƒÍÿUŠW¬( ›úðú¬R½a@ø\ß×H]ƒÎUŠW¬( ›úñUŠW¬( ›úñé °yÃê±Jõ…ás^#ê±Jõ…ás^= v7ýV)^° |.oëÃê±Jõ…ás^= v8}V)^° |.oëÄ}V)^° |.oëǤ.ÁçªÅ+Ö…ÍýxªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<ßõX¥zÂ𹿯ªÅ+Ö…Íýxô€Ø<áõX¥zÂ𹿯õX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»›þ«¯XP>7õáõX¥zÂ𹿯»˜býðÕo⸔–éTè4ZÊ©¬¢Ty’]p’Ã.gRÓ-²¿ímbOýLú6aØŽ)·j´5-%u%ª5AÃOö’g¿¨¸p¬…C«iRZLbi&û®˜1OþC.§6DJœZlµ¶n”vRJÒŸUˆŠåÅJQÎ×;Úö1G‹ (+¶s±øÙaì¡¶R”ߣV¨¥j‡XÃΚËO5NJ‘Ù™'<Œ¿©Ó}0 ü·Êd5;.¯“óqI‰“ÎÍ›<‡s_«keµ}öoë*†ñ… =Å;)‡X‰=üê2ã«J]Øg±$j¹n4¹°—þóÿcþbƳª·ñ[™>»«u½neS Ïú¼Gÿ6ªÿ÷#­¥S¡R¢®4u-.CÒTœÆ«¸óªuÅ\Ì÷­j;n+جV!Ó`ŠU26¥"=6)\T<¢m„¤”µ–u¬ì[T¥)J3Þffg´Æç‘CôF;²X²Tôw„cÇ\vé¯j$–©Ï¨£(”DÅÖz‹þË.âì!°§áZÂ&c>µÂ˜©¬ºü·žs^¦VÉ­KZK=ZÔž±žËv¬þEÑîÈ9?Dc»!›¤Å âg¤»Y§:ùËd˜”†æ<Ê$ ˆÈµˆmiJÍ7<¦¢3NËX„âŒ+ u"¨ˆtèÏL-©Ë×Êy’SèCm’ÉÖÏ;*Õ´”’‘¸Êö;í®EÑîÈ9?Dc» °)ýag°½.¢™)a¹5*‚ç<Ó} ¨Ûm²-k½w+I5-DFj5‡X;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝÅÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝXXÓ‘CôF;²EÑîÈ,,iÈ¡ú#Ù"‡èŒwd´äPýŽìƒ‘CôF;² ‹Úr(~ˆÇvAÈ¡ú#ÙÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝXXÓ‘CôF;²EÑîÈ,,iÈ¡ú#Ù"‡èŒwd´äPýŽìƒ‘CôF;² ‹Úr(~ˆÇvAÈ¡ú#ÙÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝXXÓ‘CôF;²EÑîÈ,,iÈ¡ú#Ù"‡èŒwd´äPýŽìƒ‘CôF;² ‹Úr(~ˆÇvAÈ¡ú#ÙÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝXXÓ‘CôF;²EÑîÈ,,iÈ¡ú#Ù"‡èŒwd´äPýŽìƒ‘CôF;² ‹Úr(~ˆÇvAÈ¡ú#ÙÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °8°§"‡èŒwdŠ¢1ÝXXÓ‘CôF;²EÑîÈ,,iÈ¡ú#Ù"‡èŒwd´äPýŽìƒ‘CôF;² ‹Úr(~ˆÇvAÈ¡ú#ÙÅ€í9?Dc» äPýŽì‚ÀâÀvœŠ¢1Ýr(~ˆÇvA`q`;NEÑîÈ9?Dc» °)ŒÚÄúKiԒмXòT“Üdp¢\„FoáIêU žu†­È7PFeÃ9-I,ÅþQÛpÜ- )L¦¢,é§ÄKÒªRÝá2’S«'”‚RŽ×QåBsà’-ÄCqÈ¡ú#ÙêQK7ÅÕ¡¶oŠàÊ' á«ÕÔW1%£iÃu¨ùÉk[§~»†WNË™‘žÛÊÖ;ƒ ï?ö?æ6ÜŠ¢1Ýú2Ë,ßTÓmß~T‘\f(ÒV‰šT£J;1?ÿÙxymon-4.3.30/docs/editor-main.jpg0000664000076400007640000022262611070452713017057 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀª"ÿÄ ÿÄi  !1QV“Ó"ATU”•²ÑÒ2357RSqu‚’£Ô#a¡¥³BDWƒ–¢Â$46r‘¤±%Cbst´ „8dv…¦µÁÄðEceáãÿÄÿÄ: !1Q24ARSq’Ñða‘"B¡3ÁáCbr±ÂñÿÚ ?ééòå¦t„¦SÉI:¢"'ÄW1cvÌð·ùà ÂóUÿS†•AÝúWÅUN²°Ws×âÿÚ“ÞË6.X•ú$îuß-ó'ôˆîŒýϺ>ilæqDgªlSX¬©é/·!ÆÒÓªYGq !¦4ËQªÏÂúJlñ1RbQéÊŠˆ–2ÐìD¬Öµ-&¾íN)¤dRH”Ùß6ÒÊÆ"®*±S¤5VÞöÝÅlRZšL¶j†Â©ŒÉ2NdšMJtÔ‚5’¶º[Ä@6†í™áoó†¶g…¿ÎÒ’qv(ƒN«Àf±&¶óx¹V§Ef"eÂÓÆE¬40nk3"ëÙ™gdû”lzÆ7•‹H~¥.‘*F'rœ¹/· ékˆT÷¤~‘,›Œ¡ÜÉ"+[bR£M”i0ÛÛ¶g…¿ÎnÙžÿ8cÇ §†ËÉvS¶”)÷I$·LŠÆµ )¹ðžR"Û°ˆ¶ UŠ|Jµ&].{DôIl­‡ÊBˆÈËþ dwlÏ œ1j%YrÚS±jjÚ\[F¦ŸÌD´(д܅*J’eÞ22=¤5iO›^¤ÁÑä÷ÔíT¥.mÎ.|Š[§ÿž…°ŸíÕor,M®bùtˆ¯Â¨KÕ7T­7)4â„™¦ÔyÎ4έ2KV¦Ð„ÙÊ>ãmÌîConÙžÿ8a»fx[üáŒ>œÝS RêmJÝmˆËéU«Ö’ÐJ%äþMï{w¯a‘vÌð·ùÜs¤&0†çßUdkYzJ÷1‘êXg&µÕfZn”ë±9”wØ“±ˆTJ=#³ˆçÕh´Jþ%‰U’Ö笿‘KÆLeVG ”›#J;¥(ÌÏi™a± YŒG‡ðÛ‘¢T S@‡ZjiòŽ8•dq×ê "QSMÑ•}ÂŒÕ݃znÙžÿ8c\ŨäʪVU¸ÐÞšáªRõ ‘® êQ'2ob?t’á2ûTeb~¦ZiN®ŠŽ\ç79$ìk‹¬Seœ•ܪæ“ïØÎÆGc/–äTéøV©@rµ*§ü_’ûÒ[dœ}ÆÊ16£6„–T¼âH’DFFW¹•ÀmýÛ3Âßç 7lÏ œ1`%vÌð·ùà Û3Âßç sv ¢.™‚´sXN”D¾ºA*³M’gQYª"%£PÝõ¦d— X»%k>ê×®¸ëÛ¯~úà,to.ñjɪÝZŒÙ²ëu¹?Ò/›._äÛh”6¾í™áoó†¶g…¿ÎÓÕ\Eˆ¬šÛx´¡‘âö(»Ï¹˜4½ ]I75‹jî_5‰ ؒآ¥úŽ6<>þ#c­*äb5¦•ݳ&I'ö‘¥E´Î%¢|U\F‹Û”fQœÃØI‡aÐõdnOJb%H’¥™\УNT¥³+ÉFjîRßvÌð·ùà Û3Âßç iÅxâÄUŸ©dN™T‰.¡½—D–Fƒaœ^v1Ÿé VÊ’5k ¯‡àÔ A6êu™i+^u:ëM6H¹dB[Jl‚23,Ù•´î£Ù`ÌnÙžÿ8a»fx[üá‹TR¨;¿Jøª©ÖVªîzü_ûR{ÙfÅË¿Dλå¾dþ‘ÑŸ¹÷F{vÌð·ùà Û3Âßç k1töðje9Ue5%c-éMÒÙ(ÙßN«-¸w7~Ù­Ý^ûGŽ-W7MëìNóÌ-r”TÓ†Á2q•VT$‘¨‘¬Î”™(”EÜ‘ÜÌ6*¼UX«“¢ûÍ"CÑ”¬ËMœeÕ4âlvàZWà;\®V1uú²Øv;OÔÔÓ’\6˜JßÊn¬’¥šRF}ÑåB•bï$Ï€ŒiÍTëÍC QÜ;ª¥ièζÓk~¤gQ”J6ÍÄ) KFetØÔg”̉ïÓ£):F´Q©Sª› ¾—ÛgôlïKî“ 46›%.2ƒ#;¯a‘¨Ë` ¿»fx[üá†í™áoó†5F Äué20}Nf )éÄúÝÓKÔ4”ÓìÂÝý¥$¿Ñ©Êó©WRËÜð x«‹ —£ºÍ_½U,NÓmÌŠ¸l4ÓF¸ÉJÛ4 ”J»6;¨ÒyŒÈ“°ˆ6Þí™áoó†¶g…¿ÎÓš6ÅxÒµU¡TgÇ©"ŸW7ŠSR•NDhÆM­iL}[§!KJHR\#;ŒÉl%Zr»?Q«õüA"«.­L‹)HTvZi“[d£ÈM Žç˜³f3+—rI-€';¶g…¿ÎnÙžÿ8bÀ×ÓdbF4¿[ë~•I¨f S5Ûº¤äLŸé ¹r0îk÷W¾[X¸o°6õe°ìvŸ©©§$¸m0•¿”ÝY%K4¤Œû£Ê…*ÅÞIŸ»»fx[üáC†jµèØÒS3Z‰EGîiñâ¾rZSe‡ÐêRN-´+Ý4Ò®IIÜŒ¶•ï«cŒboÐ$ÑꘒL*쌚ã‡Im¥²i5‘ã¤ãfj$¤·A¨¿HDw^T¨7ÔêñA•4ª‹í»Pq¢§2ÏXá4㦛—pÒÎçbîmÂdGêݳ<-þpÆ£§O®Í©á«íIDˆ˜µöTµÅ9+kz%¬âŒµ4•Ýj+®IJ²–agFxJ§à*G•uXš1”È»™†ÓIŒ§MÄjÒJ,«A6²Q¨³8V$ì ‹vÌð·ùà Û3Âßç X _ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÇžUeÈë&Üœþ±Df”†jU»ÅúϽÆ?Fÿëßö†çÿ꼫ÿá÷øÂø‰É(kY-ötÌ’…:g{wÈø»ßMÈr—ÿ‰2_¬`öÞëˆDyF”­fd“55s+ð^ÅÿA^ɬcQ©Ý×ýn~«ì½ø/úí´rÇWî}øÁúܹ÷$œÙx/™»Ûõ Ž£®jµ:kuIm¹Pˆ…¥å’’§’FFJ=‡´BÝ£7¾3¦CÒmRŸ»dîµ²NkKj¢š•d%#R”¬¨I†fnŽôvÜÇÛFŽða%.(ˆ·‚&Â#ÿË»h÷ú<ÁŸÝø쎼1ô?tv]F»"Ðm¥I×,œvÆ\ÖD¥|¥ÜÇŠ%/DDäD§a¨é¨!MÍKL0’’•’’å‹»##;‘Þ÷½´{ý`ÏîüNŒ;h÷ú<ÁŸÝø%—ßjWŒáséõ†ûR¼g ŸO¬b;h÷ú<ÁŸÝøv>Ñïôyƒ?»ñ:0™4F\P“Iu(Hžúžy–¥ä34’HŒÕÔ«!(AÍG•)#3°È&ÜKn Í¤õ-†Ù‹&SÆÉDFœ©$£‚öA$‹¼D[îÇÚ=þ0g÷~'F´{ý`ÏîüNŒíf­ILªÄ,9Q} )”»-¦]Z[Q)j#<¦Fw.¹Š1j R‹Q€ÄºNOZ\}Rcµ!§–’AºÙ™k;–Ò¦Gb+X­WcíÿG˜3û¿£ÇÚ=þ0g÷~'F„(f‹‡gR&Ì¡T¨È9Dv™Š£È†Ò„1uP”6„‘«ÜÜÌÌÆfŸS£E‹Ofƒ ˆn›Ñša-6–4©´lJ+Rn[l£.ù‹=´{ý`ÏîüNŒ;h÷ú<ÁŸÝø ¾ûR¼g ŸO¬Z›Q§? æ®1ÇRûO4kh̬KI,”›— f#-›HË`Æö>Ñïôyƒ?»ñ:0ì}£ßèówât`0-ᦩ;RoJ5dNy´´ì”±H'\BniJ•¹.dW;žË˜ÏÔiø¥ê0°äÈÈyrËí2âêÔk[„“#"R”¥(Ï„ÌÌÏiÎÇÚ=þ0g÷~'F´{ý`ÏîüNŒYº¥!´%¨ÁJDIJ^Am»íJñœ.}>±ˆì}£ßèówâtaØûG¿Ñæ þïÄèÀDëX …[–ÔºÎ<‘RÑY·eÁ£<´ê5C3!$n„‰ºäŠN!•ûžmI˜ŠyÕË.D%)¶Â,©-„W¹íŽÇÚ=þ0g÷~'F´{ý`ÏîüNŒ÷±#±NE5‡éMAm’a¶É¤¶E”I-„’-–µ­°x£ÀÀñéé§1 µ ÞŒ˜èi”¶–^2S­’H¬HY‘“À£"½Å§ðŽXaÇÝÑö Km¤Ö£ë~!؈®÷b¿ÝM¿1¢ß5ÂèÁ-¡¾Ô¯ÂçÓë¦ÔiÏÃy†«ŒDqÆÔ„¾ÓÍÚ3+ÒK%&åÂYˆËfÒ2Ø5¦ÿu6üÆ‹|× £ þêmùù®FíFxR9éÀ©ÒÑ|ŦQq7ᲓŒ„ësàíüßÝE}²äÝÙÝmkk=Õ­²× þêmùù®FýÔÛó-ó\.Œj¹…è•|hÍvE_¥–ä1%Dˆ ”Õ©“Jƒ•žú¼èJòå¾Ëf¶Á+φ7.åÏGÜû£tê®ÞMv·[¬·}gw›‡7uôk­þêmùù®FýÔÛó-ó\.Œʬ/3tî³£HÝl¥‰:Ómzæ’j4¡w÷I#Z̈öeq˜Ç»EÑë´¶)NRp²éñ–n1QØ6ZQð©(µ’¬ˆB÷û©·æ4[æ¸]o÷SoÌh·Ípº0%‰Xy‰ ÄŠ[O-¤2§¶ÉFÚ F„–Ü©5®ÅÀY•nX,(¡)‚¢´p6!š5IÜÍ™dnÞá6JJÅb±×›ýÔÛó-ó\.Œ7û©·æ4[æ¸] ÄJ^ˆ‰È‰NÃQÓPB›š–˜a%%*#%%ËvFFw#½î3íJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖ-16‚òb]5§$¸N¾¤8„›«$¥¥{£Ê„¦çÞIÖ›ýÔÛó-ó\.Œ7û©·æ4[æ¸]kØ ‚õYUwqãîT–¤-RÕŠo¢R ׸ó]*JL¶ì4‘—œg×rç£î}ѺuWo&»[­Ö[ƒ>³»ÍÛºáÚ5Öÿu6üÆ‹|× £ þêmùù®Fa™aCK)2¢šX’©l—è¬ÛêR”§SijRÖf¢Úf£>ù‹Tø¸2”©ñ¨2ÊTÂÔ!”Yõ Чv,Ðf“W ‘™^¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ŸÁƒ U$Õ`±A‹P—þ±)”4‡^Û~íeµ[xÌ^ixa– °ÒèíµO¶âm&Ù&5m–¬¿‘d)IÙnåF\5Öÿu6üÆ‹|× £ þêmùù®F{& ‹Yvµ6b¨ñ;5¶ÙKî_‡2˺?ë1î…6ƒ 0á˦ƌÃii–ZqChIY)JKaÖ›ýÔÛó-ó\.Œ7û©·æ4[æ¸] ¡¾Ô¯ÂçÓëš­2<ºìš´="N¥9!¶ÚSqM2$"ùS™ØëpÈKU”£±­V±„Wº›~cE¾k…цÿu6üÆ‹|× £œ…‡"GÄtú¬Œxª“qf.{Ëj샌¸É^vk§ 1,Ï#v4’L•œb—€˜Lä±NÃM&¡þºHa‚)=ÿÒX»¿ë¸ƒï÷SoÌh·Ípº0ßî¦ß˜Ñošát`'ôö0u:4XÔöh1†é»¦ÒÂÍ*A©[£JÔ›–Û(˾c€(?QiÑa¹B:Œj{¤TZi¦^”M6”æY‘™íË{¸ÌEwû©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖíJñœ.}>±«÷û©·æ4[æ¸]Ìa8ÚÅ•ES0ÖÑÕZbSËj-Í ¦ÄkU›îRFdW;Ì‹„Èã}©^3…ϧÖíJñœ.}>±ìg€¿£ü æx>ÀðÖðVŒh±•RÀø†’ÌV̨pÖjuçÓi"Kfgu­%ÁbÚgb#2`g·Ú•ã8\ú}a¾Ô¯ÂçÓëŽÇÚ=þ0g÷~'F´{ý`ÏîüNŒ_}©^3…ϧÖíJñœ.}>±ˆì}£ßèówâtaØûG¿Ñæ þïÄèÀe÷Ú•ã8\ú}a¾Ô¯ÂçÓëŽÇÚ=þ0g÷~'F´{ý`ÏîüNŒ_}©^3…ϧÖíJñœ.}>±ˆì}£ßèówâtaØûG¿Ñæ þïÄèÀe÷Ú•ã8\ú}a¾Ô¯ÂçÓëWðŽXaÇÝÑö Km¤Ö£ë~!؈®÷b¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXoµ+Æp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xÎ>ŸXóÊ•B²qÊ„-bHÉ+) %&ýòÛÂ]î!­÷û©·æ4[æ¸]o÷SoÌh·Ípº0У!­eNî4fiZŸIZýâ+ðwþ›˜åί™äÖ0“‘Ÿiäy$jmd¢#ÌÞ̓xПРvªÅ*‹GѽF{÷ÕGF†ã‹²MJ2I7{HÌϼDf{hN®Š% ‡U¬P°ýŽÛŒI[…N§3Xy›"Í«If·z÷µÎÜ&&:¡Ú5„$ÿæ«þ¦"ÕzµB\)‡‡R•nv´“FryÔ¤ìÓI/vyŠÆ®à,Çr)%z:%9>+†¤¡ãqµNÆDw#±÷Œk¼KP›‡`)š“Dl°É”wÙI!·’”ìEˆ¬ÚöpZÇžúK/ÊwïY·›qË×=™^VÔÞÓÚÝDrõÏoÎé|zÜE=;è—ù*ÈÙ= æÒ¥’MF’R’E{%GÃÞ1¤Ð+g[§Ny–Q©%!gºgbmÄdOÎ_‡¼'Sc·.Ñ]S©mæÔÚ§TÒÈŒ¬f• ÉI=»“#.21èÒ\½rŒÞ§—§CzýÛsUúvÎz~Ë£ÏP™S“)JKd´#¹B–f¥(’’"I™š”E°»â7£\î§K'âI"L…9ºjó–ú›lŒõm¥&f”Ù'Ý(ˆj¹‹*S˜Å0¥T(Êb¨ä%öA8£JOVêµÈŽ×$Û€Ç{³U4LÓÎqÉè½UTÛªª#38ø¼“ê5'§±½M¸Û(eźSaºËn¯3d„gRK)™†FD|JÃ%I©G¨¶æ¬–Óì«#ñÝ+8ʸl¢ý¤e°ÊÆFd5ü÷æPdÆQŽ˜ç! S&Óæñ¬Òh#I'"LÌó•­ÄbM† T¨¦µPNçQ0l4ÁXÔM™ß»Wò•~÷v‘p™žNUª¹¨ªšéÄzÿf.ƒ[«½¨ª‹”c¿íËþ{$à1ø’”Ýr….’äÚ„Éo!I)Qä2|$´8¤ddGß#à223#Çh÷ ;…0´jDšõZ½-=Ü™õ)+yל2+™gR²#e‰v"áºJ=–û)]©F£ÑåÕ%™“YS«· ‘~³àê‹*U—Z}ªü˜¤óš¶ÐÌ4¦2œù´­ÖO9ßg»,Ýâ.–éIT1”˜ÑeK4IR‰£#BYuÂ#Ö%I"Ì„íÞ´i QÆ}2*±ØBWOeO7QÞ±’–jm(Ùcï_eömÙô¾HÒÑú?©UTÌúûtåÎxäùß*ê§õ¢Ô\š1,þó×ü%J£[‘‰jPª³"Èi£¾ÂX`Û$f[ÈUîfw=Yí2.ã9X†h² ÓNz­%¬²e+!(žqÌÌ¥G’Ƴ32Ú£#Ù|×± ˜Èò–Î&¨·ˆÄz½Q=?v¶‚.pôþ¤ægž~3–TÉÓ$¸Å4"d–jÕ¥&µå;(ì¢=„{8.gÁ³‡ÌÝJ¡S"¡®\gÒjN±(#4— “”‹ƒˆËim/×C•*¸§ä°óŠinºÊU³š–f“¿Éî¬vÚGÞ2=¾\C0ë’YyžjbÙSN!Gt(íb4_iÛŸõp™íòaëKÈÈÈŒ¶‘ð%Z{tøÉqHSŽ8âZe¤ì7W¹MÏa}'À=,¥”$ö$ˆÿà1øž#3hÎG“åG7[Í З¥m-¶#ꊪŒS8”ÄÄs–»P©A†No²Ês·KM¥- Uö™æFlˆ¹\ÍEÔgbÉa êêÑœ9´±T‹b’ÒHÉ*#÷."ûr*Çn##.ú‹) è⫈(²Û3ZÓQ_›wÉ ›¤Ñeö—°ø÷.êÓ#ÕfÓªfìI—A‹»`“d¼«›‰ÙîNäWOê.!æÐè¯i¬ÏëÜšëÏ9õ|!{·©¹WôSˆÿ,µ{à9ÿúg=ü)‹â`ž¦\ZÆê|ðý.<8„é!R\vÉ)¾Ó$¤³-fD£KhqYU–Ã!^øþ™ÏDƽÆ^µ‰:‘0øy—åThÔšeEo3’Q¸M—‹d¡õ¸DD£Q¶I"3Q =ë¿E7gÌÆg´gœ¼×ê®›uM™ÄãâÖލŒpª’ª±Ý·e Š;;‰ëp%(RW ÛY%WR^3>ìФ‘'¤zŸ4£J9sjúÈ‹*nM’ÊéZGÜ©ü— ÒhèªÍ1M\±Œs•u?ç›ÉZE˵Es3¿«üCxC®îŒqTÃ;—.à¦Ãº5—Ön‡e#&[l˹¯{óð¶ûª@z¹*ˆÛù§ÄŒÌ§ÚȮ᧔ê[Uícº˜t¬Gr˶×+À뉊t½]—‰ðëu8‡iŒE\¦MLë7E@ÜÉ~çX’SgrîK+fÛÑ–§9‰èÓñ® 9UjΤGvlÚžVëC‘56ÌšZš[M¨4ç"$m¶Qðmöé¡U W(p+t·÷D „fåEw"“¬iÄ’«(ˆÊé2;ñhæÈôl;LÑNŠ(³°LÖ‘ºÃ5úkTGYvL¶èò‰÷ ¼„rŠé#RÒK'“"5m!°pe6|!QDŒ/WNwD~…JLgz+DôM[š“4©¦‘).>i2,­‘Ý6î@N*˜ªƒLß}Û?W¼ñÛ‘:Ì­Z¤9›'¹IæQä>å7WÎ诚Z7ý¿¹?•×~2\Åÿè)þöî/q±³ÿ¬~³måw®ëõ³Vëß®ÍÓ¿›‰ÍVõî¬ùwU²j÷èu9¯ŸnOåÞBÌœ“<‡¢= ×ZJ×ãA¸É™\УB”“QpU(®[ ËhÓ¸bŒtÝ6.DJ ‰ª“QšôÊŒÚÑäÄB’â’e?6ªK£J͌ҕ ÎÆƒ´7‚z¡‡gâ|2µ?JÀxm˜§>!Ú<¶ŽZœ"%•’ûg«ÿÆŒÅÁ›hnx9& yDz®´•®;ƃq“2¹¡F…)&¢à<ªQ\¶–ÑŒÆUÞ·i T7.êÖÔ AɬÉmÓ-˜ùïc÷:ÜÖïåµÊ÷-; Ë‚0§ðÄê­j&§Dn“??)¢} ÷HmöÍ'O‘s²]ˆˆ‘òNÛSLl9ˆhoadQê²U* ‡ži•N2º£zÒBÒwÌÚR×kdJ«íØšÄX& =ìoC¤Q§RpäªU"J¤Sm.IJ•¯ÊÊlN]¶ã“­§ºRÖ3Q_ #¦á•¬-„‘ ¡ ­&$B£½Omøò£!²‘¸Ü3\t&A0¥¤ìYXZìY®€ç¹¸?T©’¨õÊ}Zst)”Z9*Bõ“"Y‡ž’KNÓ-ΘÙÖ^åLºf}ÎÉå—b¼g"‡†%1@fƒ{P)P»™’¹Úä°ÙY*yHDr4•ŒÌÛ¿º#/ÇuÞµð={n]×½Ù·>³&·TÒ—“5-òÚö;_€ÃWwÞ¯ˆéû—S¼•$AϬͮÍ<Œö±eÿXËm¾â÷ÛbÒºv ³>6‘[«`ÚÝ~·:žiÂò¡S]“©kr%&ÒA2dù<¥$Í&âVDD»åY´*Ât­ˆªÕÊEB«ƒœÄ,, 3j³ûß ÌSdFrYJФX®M­«(ÒfØlŠÆ2Ò0ËÝSfÎLY$F¤”T®$¹]òÙf{‘IÊFFD¢Q÷‰Ra¤ 3ŒäÑ+3éŽTiÕŒu.d”äR›(lS¦D`ܶÂiz¦ŽÇܨޱß5ö§†N™¯HNšæ …ŒÚyêLHk[nÓ•LdÔM0’ý#%1yÔÚÈò8V;Ú¸†»½|9Oܺíû©.}f]NX’$gµ7ú¾[l÷w¾Ë×w¢¯‡)û—]¿u%ÁϬ˩ËDŒö±æÿWËmžî÷ÙcÒµZ K¢Ñ ü[£®\ZB)ΩÈÔíì}³5F"ΆNA¸­Q¤®—Œ½Ñ$ÕJ *¢PÍì[£®\ZB)®›‘©ûØûfjŒE œƒqZ£I].%{¢I†ýó=ˆóéyÓBÖÙ ’ÁdR³¯2ˆÍ7I'¹%Ö™s(¬Pª+”8º[û¢B3r¢»‘IÖ4âIHU”Det™ŒˆøÆ ¢aÅK]20̶°£¸Æ[±)“ ©(N]S*'Y~‰¥¾§,…‘ÈMŠäC-¡š,ún†(4|# Ÿ„«ÙŽÍdªXmâKÒ‘ }y lªR‰?§%-*Êes=© ¬Kâª1±¦¦ªÑh2+$ÔaœºËܬ’[JÝQB‰ 6‚%-L¯jÔK+Ye|+Xo”×.¢“j«×6êbs8RSòt] o‰H&΢ͩµ ­ÝY U” è ·ÓiÑqü÷+˜b¦æ,UVk­Ö•Å4p”§ „”«d&É“m½Nk’Êù?”0Ø.Œó8±™‡j”Ý$ª%‰õ‡á¸ÒdÏ4ØœÝ*"CùîÐi5dM˸à0ܳÞr4ˆôÇZiKDvMãÆErBMjJIGÀY”’¹í2-¢?1” 6ôHfÕP•&iŒF¤Ù§æÇˆnš²™UHJ‰'cVS"à3-ˆ)4'äÖ `œZ£È‘£JûFv–ôw$ÉQÃ$ ¤‘¼íö‰%g3M”«lšãZK˜ÂN-”˜’f0Uú`”jÜñ§Ç~K„iÚ’%>ñ)Ek73"MÀn†ÆUÞ·i T7.êÖÔ AɬÉmÓ-˜ùïc÷:ÜÖïåµÊ÷-c‰pƒÔgñ'áçáPäSè²W šÑ²Ü›L“»ÐÉ&ÉÖ®3hJ‰63Ì‹íQàñ™G§ àÊÜ\*ýB€¨ô†)ÎÃuçZ¨!sf:‰ m&Ö¨VI]µ«‚꺱•w­ÚC ˺µµ(rk2[tËf>{Øýη5»ùmr½Ë'5çe+j#Ò”n¶ƒCF‚Q–I5žu$²¤ŒÔ{odžRR¬“ÐXŠ‚ÌŒ%Š“…ðen.~¡@S†)®ÃuçZ¨!sf:‰ m&Ö¨VI]µªöº†Eº).5YXC Ô©8iÊær,S‰úvjm®[莤¥M·ªÔæVT‘ê–® ¨ÃrѪ+Ü—N^Ër_Š¥dRlë-—SerãkMø×+‘‘hÕ:$ÃŒÐh8š…¨Tü-_Mfb—*Fp£=Sä9ƃh¤%1ÔII!ÏÑ܈ȽÉÞ“€éø›J5YÖ‡´Ú0Å*:$9 IйüóyM%JQ%iÌÙ—t¥¶K.뺹„ÞwtcЦܹw6íѬ¾³t;)2Ûf]Í{Ü­·29Æ% L*%N·K­O¤§áäbZn¥h•PZ7qºÝÌ®â›RÒ§#ìRÉdGÑw´“†ë3±^BXS Èj/[2›Áòê`!, ²°óo¶ˆk'‰Å:”‘ܳ)Eܤ7~;®õ¯ëØ›rî½è¦È¹õ™5º¦”¼™¬yo–×±Úü/H­Å‰Q{oDvlã…Ü"Re¬£ªAš2²¤Û¥úL‡v•b± Õ£ôíAf|m"·VÁµºýnu<Ó…åB¦»'RÖäJM¤:‚2dÉòyJIšMĬˆ‰wÊ=¸Û Såã9•¼MƒZ¥ÅÇ%!Ò]sÔ¨‹Ã̰jCIBÔã{¥,‘åI–fˆÏj6ölC]ÞŠ¾§î]výÔ—>³.§,I3ÚÇ›ý_-¶{»ße¥D·[ÃUÜ6ì:ëm·•ʉßCÄ© »IAÞ˨»­ÓmÂ"¹¬ˆkê&*Ý' R§`Ö£ÑXÆ/:ãQ©Óã¿©RHŸ\G Õµ:¢lЫ%g¶ß¤±†åÄ•êf‚‰•G$t™iâ;%×dg• ´•-Gd¨öì#>ðóQqn¬»Nj™Q) ©F‘**I¥¤ÔÛ6Ó×¹E!n¡&•YW3+w*´6‘M™…°¦“aP`O¥Å‡)÷h,Á§ë´23Ÿè¬¥.¤ÖlŒ’kÌ›–ÛSUÁXÇXFŸ‡*•Ú 4:¹;P„Û/­N;&òº¹ :“[Š'\32%¨Ð£½‰@'“1Ê”I•c9K„Ôù¦íІ#¸n¥)fYlfýû–]¶¹_Á†ñ¾Ä5§Ó¥ÊL½Q¾†&@~"ÝhŒˆÜlžB Ä™]H¹ËnÒ潃±2k˜Á:µŠªn’õ£µº·-B[îÃB™i¦ŒÍEc+–¸³Œ­%:“˜Ëai4Ê%nj$‡æM•R¦»ĸβQÒN¥&ášJÌÑt¨»«™ÌBÒ6›PfiòÜ'Þ&•½²J®²’Q$ÛÔ¨Í[ Ë;žÂ)ºMÂÕ âh‘™ÄÛ½Z£SNáj“Z´º¥%µ¸kŽDÚ HYgQ’{…mîNм<õF‹>HÁ‡Ž›ŒÔ¶#»B¬ÑpÇœ‰Ì’Í¢¶­¼Æ‚KîšR’##¹NéQ%#L8Žrã<˜aúK->m™6µ¢EDÖ‚W©$â ȶ‘-7á éXï Õ0Øê]/áæ"»-ÙdË„hi´š–£lÓœŒ’FvËs+XŽä=xƒP(:U6¯PLiuwµ›6Ö­bî”í4‘’K2ЛªÅ™i+ÜÈIÕ0Ö!¡õ6²å"‡Q‘*«¥VhíFYÉ)'O&Zy-[6±*³N&×4XÏÞˆŽKаn/ǘƒNT§Ðá)’£SÊ£Fy÷Ò–”NªS*'Ú$¿cIšVFQÚQlØa²Šh)Æ…ƒUPIWNTJ)¶²¼sZK%Û)žd¨²ß6Ã;[hÆT4ƒ Ê®Äzªë’(.Cj¢ÌxO¾¶Ü–¼‘Д¶ƒ7µ÷6Fc#Øv)¯bg1ST“¤bHtZ+±Ž{N3åµ"¤‰qÍd“3B›uEr#î]iv;¦ølEƒkU¶I‡ä*6“2©M§®C®ÊEnL‰2ZõŠF}fL‹Ê“EÒeb0ÝxcÓ±èÞøÕ¦w>\ûãF—ù¯l»¡¤g÷'|·¶ËÚå|ÈÖt„̯aŠä*}oâ)*ÜùÄ,HÃY;³3ÕI —v‘«)/Ü¥'”–w`œ)‰i¸ž$Ú…sÆo>w;#V*yn…£Hi-9´È»£,¾è¶‘•LÆØn&%ëué¯@œm— ¸O8Ë.8Dm¡Ç’ƒmµ¨”›%j#<ÅbÚCÓ‰ñ= ¦>úÈ|”¥&­'ÇbŸ‹]Tz´,?ž§¸Ž™) y؄äƒ7œ6Žì—riVTܲ“àÔñ54ÌOŽ_S¥×ªÏ¡7\4o\´ìmØm·ª5-(Φ”F§M$¬Ö$„öƒðÍr\xtê‚Õ&F»#Eu‡¦rk´¸”š’u‘DJ2UÈŒ®cÓ\Å4%B5>§<˜“'UªlšZÌõ’Ž‹å#$æuæÒW· ŸTe­ãáŠí6›ˆ†çÕ1%²Šô«í’UWÌÉ Û3Id³e ŠiAk±f"Ôi•Jæ•‹^¤Ô>¯‰hŠØËKñiÑj‘Ͷ̳#¹'¤(Œ‹)8w¶]°ÓŠènbƒÃLI~EILxo:ÔsÉœ’ë©I¶Ò;H–¤™Ü¬Gr¿²«ü¿ý#ßå,!Ú^¥…ªtª¢%K¬N{p]v,–žuÇÒj} 46¤%DÖW &fÙotÞ[Uþ_þ‘ïòˆ‘­kxÓPç Ö, Ó%¥$£b]E¦\">Ê¥ØÄ_IuŠEs Ð'Ñ*jqRO×›5ænY’fW!wLz%Ã:N«ìYpÝI·.98mf#[G~2½¾Ií.ù­$RiÔ,…èôˆÃƒQša–ÊÄ„”Ö¿â}ó3Úgs1E›Eñ%~{uRè­4§Û6ŠCî¤Ô–”ê²¶„¤¶­j?ä܈‹i™\¯(Dú¨X¤Ý”F˜Ój°ª ;ÞY4l¥ÖˆþZIŒäž%¯c·ƒÊ«µk4wˆ™íÞ(ß®ÍÔ÷ŒÏh âê”ÉE]ø“b©eçZЏÏEY™kR”dW2#ÚF›•Ê×2œM—'¦ÌÔxÌ6n:óª$¡"¹¨ÌöwƳÒeüyˆO‡Hf ‡Ú\f‹)£me•N<¢;Fj"ÚDv±™™˜i&2©„dF§ÇÝO·"4¢˜“º̆ÝS7=ÚPhÛ³ºÛ°sòuê®o‰«u1<§¦þ<þKÔ×{õ#vêbyO~ÿÃöŒèjƒPb=9/?}AɦɎ‡ìF£Õ­ÆÒ•ì#>äÏaŒfĪ~7ªRê”mÍL¯Ô½¸Ýo&GI-~•FhZÙ›Ÿ£"ÕåÊ«™*kÕJÎ7 .Šx¢,"uh«Á›F8ñRÑ0ù’õ®²JSšíBlÛ†› ˆ>‰WFpÌæpÎô­É·X&pü¦]mã$Hœë†™e¬K}Ù$ÈÕcÌW"VžÍÖíFUˆÔ…½i²c»%–²ŸtÛJm+Uíb±¼ÙXÎç›eìvÇ•yÂÅtú”×XTÈs¥ޏ›¤£<ÃEܤÔFNä²;‘‘¤ŒÌ“ÆTZCšXµêžEA-“ÓK9J$ߊ¸ÊR’…dœ¯™8vJ3+if;ø°52¥Ó‘O–ËHë§;Ž2¤¥:ê».5s2ÙjOÊI•Èþ½ðÿý3ž‰Œ6«®›¢­”Šë´zb0;s%¼„´{ZfSsq ï:½…Âf_¨fkßÏÿÓ9蘪‡SÄšÀÔj5Ž¡#G_èè5XœRJš¼—=Ö\»vmÚ=žOµEÛñEÉÅ3œÏnSÏäóêæ¨µ3O_ûN›¤ItÔUáDœPÖÙºˆÒ§ÆfrÓ´Óú-ÈhJ”V2Jœ+\‰YLŒ„‹Ϊ»^›¢üå¡4ÈSÔÄ2N°·W –…I$µI.þÛØÌGšÒΙ…ÎlZ¥[A?H®ÏÜ.Çp­µ‘¤×rÚDd“#Ø"¨Ó–ÃX…5LwXëz¡X SŸLS¦º¦Òg!ÒîÉŒ«+<”™¤ÎËC‰;Eu:[–öÕ4mŒÌužß¼Ïò¾–›Q¿5LÎ9f}yøËz€³Ks`ǘÊ^KO´—P—™[.(®D¤,‰HVÝ©Q‘ì2#‡@x+êÉûÂXáþ _a/ý4ŸI±Üõ¿õdý¿á,pÇÿ/‡0—þšO¤Ø¯­>§aT~“ÿš¯ú˜òIa™,)‰ !Ö–VR›‘ý$8Ž¡¥}(-nÉ^<ª›Ž(Ö«3%s;žÂhˆ¾‚#Ò––ûØîo6ÏF>›Yþ×è馫óM1Vqšºã¯«÷q¯QnžU;± JHIY$V"£„{)iw—s9¶º1ùÙKKÜ»™ÍµÑŒéò-èþúŸúWеÝÝà8?²–—ùw/›k£”´Ã˹\Û]¤ù"ôu?Êx«]ÝÖüXϺۯ0ÛŽ5}Z”›šoÃcýv/ø Ã{)i—ry¶º0=)i“½Žäsmtcœù.ôzãù8›]Ýäƒ;)i——oómtcó²–™¹vÿ6ßF+>N½¿”ñ6»»ª¥NƒRK)¹ aÒy¢Y\’²#"WÓc1Ž<)‡Ìí½äM|Á:²g›¾OØ8›²–™ùv÷6ßF?;)i£—osmôbôØÕÛŒSV>çUzjç5b~Nóm m„$’’à" 쥦ž]»Í·ÑÎÊZjåÛ¼Û}á:+Ý8›]Ýá.$Yh$JŽÛÉ#¹ÒGcâS ÄY®4FšQðškŽ쥦®]¹Í·ÑÎÊZkåÛœÛ}¯ {Ù8›^Ó½ÀpGe-5òíÎm¾Œ;)i¯—nsmôaÂ^öN&×´îg(Tw$œ•Ó£©ã;šÍoÿðˆ{Ya–}é¤#½°‡vRÓ_.ÜæÛèò–šùvç6ßF-éõE®îí«4ãô©l4œÎ8ÂÐ’½®f“" “˜kG˜oLz²iT˜°^q§4-m2”(ÓvÈìf“µÈ‡vRÓ_.ÜæÛèò–šùvç6ßF¥½Úq»»òe MÄ)Äs0–“ZK­ºš‹°¹$¶ìHQ:mfÌœ©±Þå”­À$ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}žÿ²q»¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ù8‹]ßCê/Rê)²æ2ïS$œ¨j×:Z·M—5X“cýÎ&Çrî¯ÂDeíߦ¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿ìœE®ï¡ñE‰¸÷%6•p²¨ñ5Mšw;JË™¶ìßr“È‹‘X»”ñöïÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_öN"×wÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û'k»èæý5ÆÇß_°ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ý“ˆµÝôs~šãcï¯Ø úk¾¿`|ã쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþÉÄZîú9¿Mq±÷×ìý5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿdâ-w}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿ²q»¾ŠÀŸO ˜0#A‹„l°É) ¶’+R’nÄD]â÷é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û'k»èæý5ÆÇß_°ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ý“ˆµÝôs~šãcï¯Ø úk¾¿`|ã쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþÉÄZîú9¿Mq±÷×ìý5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿdâ-w}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿ²q»»÷ Ò0ΜüÚTBD—ÛK&ãóäÈRI™“MëIZ¶ÈÎä„Y?¨f!ϧÂmmÃ2êÞZZ% ”âÔjZ̉½ªRŒÌÏ„ÌÌÌ|ê쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþÉÄZîú9¿Mq±÷×ìý5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿdâ-w}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿ²q»¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ù8‹]ßG7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿ìœE®ï£›ô×}~ÀoÓ\l}õûæÍOL:e§ÇKÏc—Ô•+)hÎö3ï·ú†;³Î—9k7™gØ«¢º':S]5Faôß~šãcï¯Ø úk¾¿`|Èìó¥ÎZÍæYö³Î—9k7™gØæ·'Ó}úk¾¿`7é®6>úýó#³Î—9k7™gØÏ:\å¬ÞeŸ`9œŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ær}7ߦ¸Øûëö~šãcï¯Ø2;<és–³y–}€ìó¥ÎZÍæYö™Éôß~šãcï¯Ø úk¾¿`|Èìó¥ÎZÍæYö³Î—9k7™gØg'Ó}úk¾¿`7é®6>úýó#³Î—9k7™gØÏ:\å¬ÞeŸ`9œŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ær}7ߦ¸Øûëö~šãcï¯Ø2;<és–³y–}€ìó¥ÎZÍæYö™Éôß~šãcï¯Ø úk¾¿`|Èìó¥ÎZÍæYö³Î—9k7™gØg'Ó}úk¾¿`7é®6>úýó#³Î—9k7™gØÏ:\å¬ÞeŸ`9œŸM÷é®6>úý‹ÄÕ寤K™šõVJ#©¶¡Dq)qå,Ò[ñ¶‚"á35pØŒìGós³Î—9k7™gØÏ:\å¬ÞeŸ`9œµ×~2þ‰ëþs§~`a±T¼eŠSG§žŽjôÖÙ®Sæ;%ú„¡¶Ù”Û‹3$>j>å*à#>õ‡vyÒç-fó,ûÙçKœµ›Ì³ìÛ&_D…fDuÇ’ËO°áYm:‚Z_­'°ÇÏÏ:\å¬ÞeŸ`;<és–³y–}€Û$â_Bi´êu1¥3L¦Á€ÚÎêDHÈe*?ÖH"¸ô½žt¹ËY¼Ë>ÀvyÒç-fó,û"ŒF!LbD€|íìó¥ÎZÍæYö³Î—9k7™gضS—Ñ ;{<és–³y–}€ìó¥ÎZÍæYöl™}«4ãô©l4œÎ8ÂÐ’½®f“"˜2‹™0¬ãNT(Tf)Ç"é,‘šZm.eR“4ššIíâ-„>|vyÒç-fó,ûÙçKœµ›Ì³ìÙ芩¦¨ÅQ—ÑíËIðšžçzdžnÁ³êôʵJ”ÅJu&AJ§½>d‰'Ò#,ÈÖ²ð‘ìáRWºmŸýžt¹ËY¼Ë>ÀvyÒç-fó,û"ÜDæ"¦Ýs¦0úo¿Mq±÷×ìý5ÆÇß_°>dvyÒç-fó,ûÙçKœµ›Ì³ì s_“é¾ý5ÆÇß_°ô×}~Àù‘ÙçKœµ›Ì³ìg.rÖo2ϰÎO¦ûô×}~ÀoÓ\l}õûæGg.rÖo2ϰžt¹ËY¼Ë>Às9>›ïÓ\l}õû¿Mq±÷×왞t¹ËY¼Ë>ÀvyÒç-fó,ûÌäúo¿Mq±÷×ìý5ÆÇß_°>dvyÒç-fó,ûÙçKœµ›Ì³ì3“é¾ý5ÆÇß_°ô×}~Àù‘ÙçKœµ›Ì³ìg.rÖo2ϰÎO¦ûô×}~ÀoÓ\l}õûæGg.rÖo2ϰžt¹ËY¼Ë>Às9>›ïÓ\l}õû¿Mq±÷×왞t¹ËY¼Ë>ÀÙNxßIZMÒ!áš®‘kÜ/I'£1ÖFÝŽÖR,de~.ðs9;¢uI™ šMl¦Ä£,¦³33B’Eµ%Æ8›ÿˆØKÿM'Òlo®Ç8úgÆo‡ìˆ‹ú¢i/Õpö3ÆØÂ®¬=$ˆòo9ÞRŸ%#)2«‘tÌøT{ ×8Ž£—'{¾’¦Ò·u«PnEž§%§TÆOvÒ—«Ró_fU©¢µ¶çá+mÆÎ÷…}3‚êp©u¬ÕDÈ]6KŘ–JsVâ 9’J2#RO*ȌȮ’Ú?×Yý6?÷ÿðÉÔã|e‘‚¦•5‡bn‰sÜDã(i†•)·Ým&£^kêšJï—-”¬Æœ¥Ÿ# VÙeÇÎ3.²ˆë’n±)§Pm¥iBŒ”…(ÒkMÒFfDw2¶Ñ. é5>¡\ž¸ RêUVä4Ñ´Û³£MŽhÊ»¥F”ÊFT©&“Èd{8i™Ž)j­ÑP§$΢ÆT„Íiª,:a©©(KOÜšò'bÔ£ÚIØ›mþsºæz8âŒuF\ÁX¡¹»‰t‡ŠI³ôµ9”™‚g)_ºRi,¥´¶Ü‹)ÛÁˆ(³èS Qu‹oX“-©4ÜÓîÚR“{¤ÈÊ÷+m¾‘7Þ55RJlIíÕÎT©QM$´°—–ë)jçîЩÚû ÍqlÀé­H¬U£H¤2²&â“rd.Q)ÜëQºl´f„U%; ï“1í3¦kÏ8EQN9#`:9€&ø7Ó«ôŠcÒ+’¡Ï«T¤S ²Šy:Îv›af·]Ö¤ÛIëÒW$*Ä“3úf­T¢"T8¨Z5“)T†Ðãæ’º‰´)D§ ¿ð‘íÙÂ$sÉ¡`Èxz*æ*2çÍv«ZhbdwÙŒÚPv?vZ§L”eÜš’e}¤3HÊ]6›‡ŸŽºœ*{½oSå<úMõ¼…Ïf\u‘¸eÜë¬FE{ߌÍq—XŠ%™‚1,J^ø¿ „³¹[™¦°§‡•¥Òh–n2©&jËbÛ{XíSx¸ä&š§²ãÓ$3¶1…:ÛŽ¨’Ú]A/39ŒÈˆÜ$–Ñ&Äu¼1O¨·U…>l곘b%9QÐÃg r”Üg\NH%(²²Óc=ƒÓGÇøj™ÞÅèn¬ìºµN<º”SŒÚ[Œ„Mf[„Êõ†n©’Js%#;˜õã1 ÛFyÊ-T_ÁõlB©´ÆŽ›%†WÊ„d­Dã.ºfWp9DÙ©J5¤‹3k"ÅâL5Xêevanš’M¢SN­ M³!Ä¡Fm¬³Ò²#+ð]©JF ®PjKšË’¤F›Øì¥Ò7XnB µ’–œ©V¿Ýc,¾äî=ÚGÄzò ™.kjyrª!³÷ÉY2!z¥:hʳ֪ÊV}¤V!xš·cÔ¬Å;r‡€èæ“àü"¼CF¬T7yETÿÑš6³§I·]6ÈîYFˇ}»r•»¢>Â8ö›†©4(¬á¨U7áÎr|—¦©ôš]Q¥$–õO%*N­ ÷Ä™]J+XÎô®jÇô­DFy¼:5ÀóqV!£3#TÅ.mE˜Î¸©Ì0òÛS‰K†Ê\VgDgîR­½îð¶âõÄjYSâ“NGjUÕQŒ“m‡P•¡×Ü»m™)=ÚÈ’Fv3#Ø3øs`˜x‡ U&•} ᙤp˜•˜é˜¹SŠS…‘e¬QH”J±dðŒEGS¤ïîFe–øaªm%«¥=ËÑ·u+º÷¹\±•ÏjnEsµ7W»’ø£ e£ŒP¨Ë4SÕºqâ’K}„2Ûm”_Ò¦í”GºÚ3;r©*%(³d¡:>Äf‡ÜF¹$óhÚÑœmÆä9¬×“™r‘FpóÐD•æR $J×t…EŸ¤ÐÙPL—iD%-´dΖ¨è33Í{^œÿ{ùMìÚ¬´Q1í&.£QVõ^ ˆdÊ]•3Nغ¢•d-dKI”æ’iU‰DNÛeãu͹ÂvÛÎBÑýU8^³Z~m%¥Ò¥°ÂØ:œSÖ¥Æ]xÖ…k{¾å Ê”’ÌÊËsBˆxƒ+íâ7°ô†éñªlç'‘TŒÉ%HpÛ4–á'>b;&÷QYDF“#<Ígáz„KNf4Ú|yÏ™ãÂh‰oÇaæÕ²ZRÒ]SÊYä58”CØÞ0ÂÏc<_^™O{5V¦äÊsÎÓcÌSM©×¦ÔÓÊÕ¥J%#»îòä;ÜNêÿ>HÛCÉFuw©´‰o?§§Vݤ;¤ÆÝM-0ßrÒÞJ–³[Ê#AåÊIJ”d•’„­JîòoÆågsjµÙ7SZýWÎj3krãË–Ûoa;<†dbökÒWh ãi†3MÆmzæz:”…™¸Y”±r¶b3U®EÝ ]4,»õjŽþo&óîMB7.]ǸõºÜù¯«î²d÷_ʰˆª¿Y4Ñêb±Åóª@a­Âîª[mÍa×cžl¤km 5%&­„£"Iܬgr¡4­bÊtÜC¤:ƒLËKX—[¸Ò¤§3yê É-gu³¸iE³7teÞÚP±Ò‰ªcú”ª"'ê€TÆÖ郄÷ÆÛ⦅é:ŸzÝ2ç¹ÍÝd×[„³e¾ËìÆ' V•LߊV ää9 “ÆÑÂk6sG æËkŸÑ7¦ifµá©‘ñ%cÒÛ¥5"œÔÅ¥ DvXCéKD¼†KSnÛ6m¶¹‹Oi+Øl›%œZŠi ¥jš @Q­sæ9ª#}9‘›í2%$­n;®vuÅÞ<_£*í7ÕcRâ¥Ús3eµO7çG)šbC¬™¥¼Ä§FÒ®IMö^Ö2!¹±Ž1Â1VÇ Ì©®|WeT#SÑ¥"çV™!¦ß^¶í*ËIšI îTFG¶ãL‰µUSÔ‹‘LO W0ü×þyz*.Ƶÿž^Š„Dbë¿ÝkhÿÚy o®¡/Cúšg¢CBÝÔ[L‰YÓ ÔÙû§s=F•¬(òÝŒ³"$ªÚÆ”•‘¬vQ\®Gr3!:н£ìmPÒ”\kI;Š<2Õ1J*Q­A™gBÏ\YV#5XŽä›[)Z_£/޼yõMÒœ1Œ0G‹ªÿÞZ§æEÝ R)´=,ãšu)‡ÙŽŠUVzt‰J35Î3<︵ÐFE³‚æfu„¸fw¼+è©0_ÈsþëéÞð¯ FÜ᤼«ä?”,[›Ñ?Ó3ŒO|}™—©Š«æÊo¬ïü Ö?­¿ïü Ö1(Pùßéý"”EŠ%™:¼bþCßð/Xü:ÌRÿ»{þëE jw|“§§¤Oò¼i¨gN¹¿îßû¥ë‡]ˆ_÷oýÒõˆú… ·tv©è· m"ßø4ÿÝ/Xüë‚ÍHû¥ë³ð\·M=[i7\0¾jGÝ/XüëŠÍHû¥ëƒ%uLtO m(ëŽÍHû©õ‡\°~jOÝO¬ELR|#Ë]úã¢xKi_\Ð>jOÝO¬~uÏædýÔúÄLÅ#ËV¶ì'ƒ´—uÏædýÔúîx3'î§Ö" #Žºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv’î¹à|ÌŸºŸXuÏædýÔúÄDŽºpv™ÜAXP„†Ymä©.ŒÖDEkwõŒóܹUÊ·TïnÜ[Œ@šàß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ'ºÑ1ÇÑÕH…P¨”"žo´…-·–Û䜊_¸3Q'mË€¸„ w¼+èÝ c NÂXæ<Ê£*5 E4ÛC™Ôò[|ŠÊAC%-32áýCôoú’‹Õù&bÄNíÔãö©íÏëû<<¿WšM4eRÃÚ>ÇÒ±ž„‡÷©NSQ!m© >jR &£A‘šû8 ˆD°ÎˆŠ£B£Ô+X¦EufšLW#©ÕH;\®ddH¾Ëpû¤÷ÎÃߣ­#¥¼Ži¸¿ÔeJ¨SMŠcrÜzFe›O%D“î‰5"æv.-™J.7Àuª{Õ¦Rª8=I40ˆŠu2ÉŒ¤•'b}é¶ÝòïÜ|&¦¯)Ù»vjÏ:£3M31ærÛžYÄL÷ÏGJvÌCóD˜;04@İieQ§CCMK”Ê\LU)§ÌBŒŒÒVÊ«•ŽÄ]òÄèÝŠ'À•ˆÕX˜“VªÑš'·1¡*=jIM­µßa‘(¶ñ(ŒˆJ0¾“°•B«¤©ø–KôÖ1v˜ŠÊSŽ­´2ëV,¤i%e4{£"¹ðØŒÆ:©Ž0}2£Ü%D«?P¦Pë,ÔgÔ\ж­gMGdf;kv+ðÆ]ʵ¿­Vb«Œró9âj¹r—HÆí(è’ŸYÆØœð½^•¡3R› FˆmÙ¢ig˜¬”©J#<¤Gî’fe˜x°–¥T´m£¹5­ãbK”w\n¢š÷w'+NHK—RV¤=ÊræIß¸Û ™¤}Ò1Þ'Ò"»2}Vm=0ãÂÜ.!,ßvKQ“vÐFJ"2Ê£+Ü„F>Ã0tC£úIÍ[µJ$n£2"^d²—Ÿ]ÉFDƒ;-;ûÿ¨ÆdΦmSLç–:Ç?6sêõN9­Ë,TžÃ8{H/GÃÓYJÔH)¶¡©¤Á³-dîÏc™îj;pï´Æ­1²: ê˜cã·q.®*¢šŠPo²¨Ž3¹ ¶ÙÖEžùLöÁ­ÌZÞFÙÎ=g­IŠEF)[„)1IðŠŒR|#Ãq*LR*1Hð×Õ`mn§|@¯ËIJ¹4l7u½&e­U–¢½Œ®DM¬ír¹Û½r<ž0ÆZ!Ř¢„`Ôajüs-íÜ $õÜFµ%)M¶XÉW2¹\G4©ø.­S‡^†ìÊ n)ÄžÛ^ì‹iˆ®W+)DerØ«—ŽC‹gh2…êP0|y˜†³Q"KRg¶²8[xHÍ(µ¶Û)Î×3 ÜO¢zVÑíÔ±»,¹W¦ÈUOVw6á2J%™[º25™͇}›¦™£|0þœÝ§â(XnBãáÖ¥F§S¨ª‡ËÉq*uIÖ-&¤Y)îº' gqsÓkÅø{` Ò¨ÕÕ.K6* ê\F¥ÍTtÚêI¶¡et™–ÏÖChIÓkªŒNÝ]ÇèÎa­írR":Z§·I»µ&’Q•ˆ¶‘º/×`/ RchÕ(u:rŸ ªËLÔ ©©Îf܆¢mÕ9v’JpÓ”Ðw²¶÷{<’t#¸©q™©ã:d M.žºƒ4w™RHÛI™)ã<©UˆøJ×#ÚdFcÒX“Q´Œ°%;Jdª³oÀQÁy£’ÑS5mI’-«p¬£¿súÈeqö.ÑF>8»ÔjiªÅ¤7hŒÆZM׋1¥Ix»”¤”µÛÜ­rØda ц)˜Â,ULÆ‘)“f¼¦¢Áb"æ>v2,Î¥Z”Üö)v+mଣøx~¦:. §Ó*s蔤.,—#¥ÃhÕC‰[f¢º Ë!ìÛr.!gCúBÀ¸oF°a½T™B­D©¦]CrB7ª´…©Ig?RdiIÜËÜžÎèÆ^«¤¬ª¶–å1ˆRê1-;4ÛC|ÇQÖ”ƒº )æ4í;t[vƒKè‚—C­i*‡KÄŽ“t¹2½uä%S4 ϼJQ%?Ö:IT|-I§U¡W4(ìJ#-¬¢Ö¨ia׊ܬ‹"›"áîŒË¼c˜°|ª, ¤ÔdáìK‰k ‘HA˜§\ŽÁŸRn'¹.ñžul¿ %Šô½:9øÚV:œ*º—Qµgò/{3̬ÛR²½‹Ü–Í¢\Þe»Œ(¸Q‘‚ªK¥N¢ÚâØ ·t§)Yg¬Q©F_É÷7ï‰Rt¨µª5s bªz‘ Ök-:²ý6´™‘Ÿx*NÝò%ñ˜‡Ó1í*³§J†/Ä5ºíêZbJ¥©$ë +%´­*J³#!YDI;™ßŒªŒpŒ,s…#¯Ó+4Ê…QeÆÜêfZsÊÒãçÖ!.):¼çl¹ÈÏ`Ìi3E4ªÞœ:ÖÁ5‘Þq²rt†¶š¥´†Y²³ð:nfÍÜðØÏmÇ£IzIÁ2æà‰±ê=rV¨õv&O¬·M8‹q†×›W”È®gÜðlºO‚ö©OÁ4=?¯RëÕ©õ¨{– Ò!8ÚáPÊRežÚË›Dgn¿ˆ»Ç/GÁªÅøkDÄÔv%œ9nµL)‡v¹QÓs"½ÿ”“+‘ÜLêO4øxÂ6sHÐÓROÂaTÕ“Žšs®D³JRD›’W>êÉîvÚÓ’ U0Š ]"Ö1\‰¯¤Öƒ¤±3M%iYîÉ8¥‘¤¶¥DGß±l<Ö&Òn™Õ/…ñ„jÞzRãÉ•¹^,Žd‘CFs÷Äm"2ÛúŒ*n…TÞÄSábúmB¯†Ðk«S˜ayX"%(È;”D•l$Úé2¸¿HМ3ÂTjæ#Ç”ì>ºÓøH~*”Ų’ÒN>jJ3I–Ãú æF2X[a8]š7U[W×.éÞôwOtçÝYxÜ_Zw—‡õ³z%Ò¡a*l:¦7¬*"#)NœRÙufž–ÿFŒ×2J”ddv;p€çŠŒS…P“ ßaóaÕ4n°á-µå3,ÈQlRN×#.‚œs{©3ñ•>*©B9‘h댵]FvS¤vIì;•ܪױKˆ$A—^¨J¦E8^”둘?û¦FiGõ‘PéÅiÊW‹ªî>¬aÅ5$Ú4J;O8óå~í·œmiI¬|$EîNà4ÖÑsÕºf!¬b ã8n—AtØ—!èê|õÄv4Rd{Äv¹ÝEb1¸ëhz•K§a…=.,¥Jr”™¦©¸m±Ä Ý¹æRMJ##UøÈà#áz¶ Æø?ÕfR™¯ÔRb~æ×¨5¥fKKi"½ÛAì$¤î¯s°L_ÒfŽ™Åú*‘ºñÓ0äqæ-èoØ%DCM’ˆ’yŒÍ6<™ˆ¸í´ èû¹£wR­T©Ôé¬â)dTؤ8h¦d”„¥¦™%r¢Êe”û’{)™ä1Âz*–¢T«ØºN!^Z<7#)ÕH;\³(Œ‰ÙntžùØHãcŒ WÁšGÂuLBí-¼G"§aAuäºÒmhîH®Fz¢÷V¶oÕar´y]ÃØìSX›G©à¥$Ѹky3 Œ¤•'boªlÏ5¿”]û€‹`Ý Î¬T1:³]b‰' ¥ñª9ºÓ¤¤¸¢VlÄiNVÈïc;+ƒe†¸ÄÐé´úä˜tz¹V ¶e©šQÔθ$fyfi±™–Þ!»)WÕév¥T’ªkø–¥GS+ZœÉæ’Fh#$žÖïs"º¸v 7çRm7 ɣ㊦&¢S*lS#ÇG2+ojÒI¥åÎGk’Jöâ.!#жŽèT­$b¸¸Ž|Rª.˜ÔÈèuöäœÄ••õHFßüF5¾…1vøHôºÍCr̬Ҋ==½K‹×9ª›])2N×µFE·õžS´Ã…žÄz8•2¡¹›‚Ãïâ·3‡þ”p÷: È’f³Ùk¦û\F振âì{Y“U…†0½±)—$îcq(³Ê$¶ÛH¶Â#IX­Â’"1iZœÞ’èUÊë ¦×ã¹"Y† iqiN{Ù¨¶ìNÌÜ #¹ð õ/຤ "àÊõVE:“ˆkÔ`UŠ·H³<•'3dD½º¶ÎÖIUÁ©Ò®n4ÇÚÃN ñ7Áæ™Ó\ch•‘$j·pÙp^æ{€EêúeŠ)™HÆÐ*Ó°Êœ9ðÛˆ´dBsÍfvÍ•*3I‘slxoL-°œ.ͪ­“®]Ó½èîžéϺ²ð'¸¾µï/ê;@t+ˆ0ÎÆíËÅôhµZCÌ-‡üTH&LÌŒœ$(ŒŒÈÓm›lgn# ~£QßêNÅõ§©P\ªG¬6Û3Wûh5ĺRá–b.é[ÿ”|f-Vt%½Úe¢hë®mnúAT½Ý¸-ª±ÂÉy6Or…”d{88 M˜»b<£š]¡º¦Q©G Þ¥Äj\ÕGM®¤‘+kkÚ“2ÙúÈKCtš #D£I5j >¹" Æ¡Æ9­c)#SD³Ê{ Ï\[{Ùvp˜“Õôg‡àõSÒèìAŒŠñwÕØŽ$”ÊRDá2«a¤Ö‚Ø{,«pl­bü*bc ƒô¨59 ËjkqÔñ%ISf¤šS·n©;qðwîé`m"i˜ê…ê¼\2ÜTÃbLD¤ž,¦j%©*J»“R—°Šö2>2OT=«ªEMXÁ¢¾·· Ì4É%’Œ¬—”[¢$ì±[jí~÷çS®£N‡Œq]f™¨Œ9JT–"INfVá¡Å©?Ê+4ecù_@£Jø» v1ú8ÂUë1ir)ꋱ”Æu¸d”¥[ïU ¸{ÞMã:F&Ãø‘÷¢R±9Q–ÓFá°¬«I(Ò[L¬â¸;öþ ØíaJÖ‘ôc=ÈôÊn,‚r¦Bú6s¶Ê^4¤‹Ü’³¥6+Äî-i‡ Pjz2ÄØ†‡æaœ@å9¥CcTR£ÐÙ)eÀ£3p7þÖ#zDǸV©Š°=2›R«Âñ›¾Q©j"BMÖÒ²;[Vƒ±•ÎÆ\F2šcÒ&¡£ù˜R•Šê8±ê”ä¾äÉPÊ1FŽŒ¦†r’RJVd‘š‰$Gs> ú«ƒ0ìÁkF9§KMVu"h‘zA+U›YgæZÅû¢G½Ÿõl.áÜ Nêx Õ°t4º‡ëfÖùÈe%*JRR£5ZäƒSdd…b-—ÃAÀÑ(qì+Y>©".jÓ2dˆÏdlò Í´Ü³…°ÕîKo³bì=3©£ àèÕ õÈ5UÈ“RádlÕ$Èóšr¾#ažßÔ`6†Ñì*nÃBÁø[M­SÜ›4«uRÌ„­¶ãUe2%m;lá#;–Ž á:5f6/›PÄ0»ôd-Øt¹jJÝ”«:z„©KAš’hJnIQÝE³¼{[éOï6 ©âJœØ5|Df¡µN&j\hšNUÄ™%)÷VÛ~öѬ ½‚13Øßbʤê]VB™F‹&¤>ûšÕ›k2mV"V¬¸QÂ{xƒfh“aŠ6‹ðµz«†é•¹x«·KZ§2NjRÜo¸#Ø•¶g~¿¨„j¡XMU̇ð†Äºk Âjµåj iΔ ÍE”¬í”g}ˆ#>’ÑN?Á}¨8oÔäÒžÃUÄU¡­¸«y2I*ZɾæùO3ŠáÙÁúícé Lê‹©éIU6›qPÆê‰YRËddÙ(Èõyˆ¿ÀÕ53£CÃtJ%ôvMÈIމH5$’[r¢Û.fdjQ}8íÖ°½2¸o`Äâ|Y>KlÓ—/DJLÒFJIªùŽêÛcàNÒ+ˆn{ÕZÔ꤅ž™!ÇÜ3ï©j5í1µzœë8 ï­z¿ˆÚ¥×͵F¥›´÷¤¦9)=ÓÆH+òÛ1‰]ã>-àyýT.ÐáB`ép©EP™OO½%üÄ’E»É²Û^^ ¶àØ#˜ß Ð1– Ñþ/¥Q ЯVJ“)š{DÛFKyÄ%Dž2ÕžÞþm¼1xaÍ餫éŲ1m>¥h©TJ‘ÜCŽ/1÷ ;ªÆ„(Ì»Ê2"¹XUŽ´ƒ†igáL9úÄ\;SßEËv:˜''´ ’­¿Ë]ÎÜ\=àžc܃ª4m"aÊn¦SÁ°cJ‡6;y_s3 yDâøW±&[oÃ~û4{ ›€0ð~ÄSkT÷&Í*ÄT‡³!+m¸Ç•YL‰[NÄ[8HÎå†ÇZSÀ‡AÆ•L;Q™.³ŒbÇŒì'")²†”4m(Ô³îUÜ©^äÏm»ÛE8Jxy°UOTæÁ«àØÒ#5 ¨Šq3RãDÒr¨¶$É)Oº¶Û÷¶€çêÃdÕ^cI†ä¡õ¤£8³R™²¸32+™p^Ýá»ú„¾=êiž‰ -Š*‡[ĵJÒš&•>cÒ²;’5‹5[ú®7OP—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ aàÒêu#p©´é“uvÖnvæKÞ×ÊGkØÿà?R_˜±”|X6=uæhd•£r¶Út­F¥$ÖIÎdf£¹Ûm¸XHzÈÆ<—¬yýAÖF1ä½cÈ×ê ×{šþ™ûéîõ‘Œy/Xò5úƒ¬ŒcÉzÇ‘¯Ô®÷5ý3ö7ÓÝ!ë#ò^±äkõYÇ’õ#_¨<+]îkúgìo§º<CÖF1ä½cÈ×ê²1%ëF¿PxV»Ü×ôÏØßOtx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ð­w¹¯éŸ±¾žèð YÇ’õ#_¨:ÈÆ<—¬yýAáZïs_Ó?c}=Ñà²1%ëF¿Pu‘Œy/Xò5úƒÂµÞ濦~Æú{£À$=dcKÖ<~ ë#ò^±äkõ…k½ÍLýô÷G€HzÈÆ<—¬yýAÖF1ä½cÈ×ê ×{šþ™ûéîõ‘Œy/Xò5úƒ¬ŒcÉzÇ‘¯Ô®÷5ý3ö7ÓÝ!ë#ò^±äkõYÇ’õ#_¨<+]îkúgìo§º<CÖF1ä½cÈ×ê²1%ëF¿PxV»Ü×ôÏØßOtx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ð­w¹¯éŸ±¾žèð YÇ’õ#_¨:ÈÆ<—¬yýAáZïs_Ó?c}=Ñà²1%ëF¿Pu‘Œy/Xò5úƒÂµÞ濦~Æú{£À$=dcKÖ<~ ë#ò^±äkõ…k½ÍLýô÷G€HzÈÆ<—¬yýAÖF1ä½cÈ×ê ×{šþ™ûéîõ‘Œy/Xò5úƒ¬ŒcÉzÇ‘¯Ô®÷5ý3ö7ÓÝ!ë#ò^±äkõYÇ’õ#_¨<+]îkúgìo§º<CÖF1ä½cÈ×ê²1%ëF¿PxV»Ü×ôÏØßOtx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ð­w¹¯éŸ±¾žèð YÇ’õ#_¨:ÈÆ<—¬yýAáZïs_Ó?c}=Ñà²1%ëF¿Pu‘Œy/Xò5úƒÂµÞ濦~Æú{£À$=dcKÖ<~ ë#ò^±äkõ…k½ÍLýô÷G€HzÈÆ<—¬yýAÖF1ä½cÈ×ê ×{šþ™ûéîõ‘Œy/Xò5úƒ¬ŒcÉzÇ‘¯Ô®÷5ý3ö7ÓÝ!ë#ò^±äkõYÇ’õ#_¨<+]îkúgìo§º<CÖF1ä½cÈ×ê²1%ëF¿PxV»Ü×ôÏØßOtx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ð­w¹¯éŸ±¾žèðß]B_‡õ4ÏD†«ÓgR'®J2ãJBP¥´¿t’RII¿ÙE³„¸hÝýB_‡õ4ÏD‡†ºj¢f𣠸ÆF_xóêš7¥8g†F_xóêš7¥8r„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L)1IðŠŒR|#Ãq*LR*1Hð×Õ`úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄ“Ÿ¨Å'Â<7¤Å"£ }VPo®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L)1IðŠŒR|#Ãq*LR*1Hð×Õ`úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄžøiW¨¸HV9Ñb›‘™&p²hWüÕ¯‹ö‹à"|Ÿn}sùòFùXÕ¯‹ö†­|_´_k¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹ãnõ=èçãŠF-«bú•VŸ €Ã2ä%¤¬Ù¥å8¥¶³U‰¢2$•øxvwtvmQ5Õ3ÏÙ1TËMê×ÅûCV¾/Ú7&¨…ƒçIÁxÚ¿R¯#W¹cIeIm˸’]Ì㣣÷E´‹‡€Ú#Ð~$ÄÕêŒIDªÂÂõ2qG::ÛK„JÖÚ¬y)R’’#Rly¶påúx¢kªf><¿àÌå¦õkâý¡«_í¦N‰â=AÅê£Òñ$ê…3®‰M’R¡¦ÿ¤2Òñ)ItÜ=gºJIRx•o?T†¥èÏ{æÃvEBŒóm²ì÷TÚ/-Fé›il1'"îw.½à¦Î–ª¢Ó™ø©§µkâý¡«_íSBÚ1‰ŒàÕ±#­• QÈ·\¢IÖ£+äMöŠ×; Hˆï³'¥m`zf´}ŒÎ¯MTÎäyªJ_5^Æh,¨Q™•Òi½ŽüfÆš.~žg?ã=³ƒ3Œ´Æ­|_´5kâý£i§B˜ö“W§õÏ…æ±LvtHòdcqDóÄÙ%³5šs™ì+ì#25XŽâqKêy:ÕKnk”ö(Í¥šT9ÏE\™2Õ.êÜ[k6Ò’RÚÚ[ .Ò4ªÕªÖ’ž{ÿÌ~zÓšœé«_í Zø¿hÚËG‰Ãš*§W¦Qëñ«K«=N˜ó²b.­µÈBÚ[Q»œ’+¨²žUØìi¾*½¢­!P°Ñb:¶™™•*SªR M‘ðÐJ5 ¶—º")Óiªþï^:Â7J «_í Zø¿hŸáéÐS]¢áy2©ë#6Ý7[oXE°Í)Z‰J-â1™¢èâ—'©ÿcÙÎÔØ­Ñª©‚ˆÙ’–H³ÇJ³¤Ñ›1k—ü¢à-œ7U¦ÓG-ÓÖ#¬u“2Ôúµñ~ÐÕ¯‹ö… Í’±Òh Ÿ¸cµr¤ºI̽ZM)²Höf3ZKo\öÚÂgŽ4q¢4áz¬ì¤u.«K#7 UÖ†U Ëi¡²ZQªÄv±*çbïÜV½>žŠöLÎ:ò38ËEj×ÅûCV¾/Ú$øÇâl#R‰NĵE“1”¿(y·‰Ô(̈ҦԢ=¥Á{ðqÍöÒ9âƒÃ)Ã.¹ULdÊ[(’ʉ¶ÔfI5¬—‘2;Œõ“¤ÓDg/Œ¥¯ukâý¡«_íwh;Ô´bj|ª"É’$¶á%„l̃%e]Ö¤#¹32Ïs+Œv.Ñ/¦é:V ¥Q%ÌufäŠykZœ‡­ZyjIåEòíÍ–ÇÞ+¤XÒÍ[wú³Ö:©¬õkâý¡«_íëeÊö‰ºÒ¤6'>þ™«‚WxÐëK3,¤®à’£76ò3m¹p‘´étÑëëûÁº¦´Õ¯‹ö†­|_´Mq^ŒñÞ¡3\Än\ {ÆIK«4S>ZRf¤ÿâ"âÐÖ“OõÁÖŒÝÁ©×fÖ7¬ÉkßU›YÁ·Ü‡ ¦Æwÿ˜7K]j×ÅûCV¾/Ú/€ëáÖ»ÏçÉåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾V5kâý¡«_íÀ<:×yüùåcV¾/Úµñ~Ñ|íwŸÏ‘¾^sBˆ®e°R/»ïf, ýUšl×ÓÙjg 2Àß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½>2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜~ űÜ~ç/Ö"ÕÊi§œ¢¨TbxŒ~kSÄbó©µܲ¸Þµ¹\qFµ2´oÇv.€ôÐÓÍ)¥8yd•»•Iˆ¤ŸÐi22ýF9KZž# jxŒR-Zß¾nzâzvœ÷38èØO©uzM„˜ØÍ8FY¶²9qÒók^ÏÑ-*RSeøO„ˆ­s!Ò`‚µhƒ=¥¥aêmÇ=ã™MJÒûŽØòlY\ŒÕ–äƒ2¶kì!ÅzÔñkSÄc­øµväWú˜ÇíÏù#1í´0ÕI˜ V+ò›DÍLVëSŸ÷‘’Ù­£?ÔF†ø~i|b?¡Üg‰ñŽ“1åRšÍ£²Ùôj¤ÅGv\t’ÐÛl¨’¢Ì”Uf±weô–¶N–!St]'a\"ÅÚ“ 5W©żäÃJH”d•d%w]É‘”D[n5–µN¾™…º¢´l[ý=”®,­m¡T9H¤©qm R))FI"#±ä+l°üÑÓ á1éRƒ_‹5,FOL¤0äâcv2·d6N¤ÌÛR󧃺+Û`ä-jxŒ5©â1iµjiÄÜõcüçóÿ´f{:ÓKrŸ+EJ^¤á×#bˆOF€Ý}uqÚ×YI]Û"$™©&G¬WˆòÉpt¹NõhãXÎHuLµ@i-¶j<©,°Õ°¾•¨þÑñŽ&Ö§ˆÃZž#6,Í3úÄÇó9Ï9Ng³¡°¼¹3ú‹±Ü™¹!åWУ[Š5ÍÈj3¹ñšŒÿ¬ÆÛT Ž%Ãʬ㠄;¬Q®Ö2Ãçmh%_T´ Ïowc%'„ˆÒ{kSÄa­O‰¹jÕS3"9ç§|}¿é3Ùp½jxŒ5©â1£ÅYö•Û+€-ëSÄa­O‡gÚ6Êà zÔñkSÄaÅYö²¸ÞµŒí«5ÊæW²LûÂU¼üEzÄk ü;íz&'#'QTÅ\–†/­úG‚~"ýcó­ê?‚~"ýc*Ì–+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTFñ ›Žüˆñ²8œ¹UGk¨‹¾b"'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>zÐó¤JÕé”úTèÔU8Ç!¶Ù'34’Zd¼ÈI_:žäÕî ø ŒÕª1Ó)ô©‡Q‡(ªqŽCm²Nfi$µ Éy’¾t-=É«ÜðÆF,€eBœü(”é.©µ"¡ä4I3ºRN¸Õ•³‡3J=—ØeôŒ\è7E87höR©OFéÊÛfm²×uú&Õs̃335Û‰Ï`=x¹–:1ƒ@w—`=x¹–:0ì£ÏW2ÇF$phòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF9O”jvÒÅfJŽˆðã&96„‘\ã¶¥‹eÌÌÏg( „ü ˆ;ằ~o{¦)]ÄÃÕ¼zË'd}¾ôæÒ¹w<;Jñºå9ú=ju&J›[ð¤¹Å6fi5!F“23";\¸ˆDU<`ÙC§?X­A¤ÆSh~l–ã¶§ É$¥¨’FfDgkŸ‰0!Ѽxòñ¤ò˜iöW¬ÌÛˆ%$ìÚŒ®G³„€G€w—`=x¹–:0ì£ÏW2ÇFƒ@w—`=x¹–:0ì£ÏW2ÇFƒ@w—`=x¹–:0ì£ÏW2ÇFƒ@w—`=x¹–:0ì£ÏW2ÇFƒ@w—`=x¹–:0ì£ÏW2ÇFƒ@w—`=x¹–:1̽T¸^„t•CŠ˜ñΖ‡Wd¤k7ž,Ç”ˆ¯d¤¶p N½¥`¬Óêm8 ™¸i,ñº-u‚9 …¼Òϲ+¹8ppñë;r y¥Ÿd:ÎÁ†ÂÞigÙ ÐaÁÀ;ǬìÈl-æ–}ë;r y¥Ÿd7A‡îjUG•X«“agšD‡£)[ÎÒlã.©§cIp- +ð®W+õõ‚9 …¼Òϲ Ãƒ€ln¨†aGÒ"اÒéÔØí±‘,BŒ†î\p®d’+¨í´Ïoõu„¬Ú}M§ás"· %ž/÷DäÂ@wYØ#Ø[Í,û!Övä6óK>ÈÐaÁÀ;ǬìÈl-æ–}ë;r y¥Ÿd7A‡ï³°G!°·šYöG9uSC¥ÀÄ蔪%&”Ëip0a¡ašZUÖi"Ì{N×àïpæ'&l ¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<éÒ©Tƒ áF¤áÊ]MgKqDì§$¥I-Û+¹-S¨M¶_‚ûOo²ITJg¸Šd8äª$•F†Þu´o¥ù¦Ê,┥ft‘°Ìîj·ÁŸUªT#E>¥2[«ŒÛÏ©ie6"Ê‚3²JÉIX¸‹ˆ~Í«Ug1<ÚœÙ,ÃNH­¼ú––b+ Œì’²S°­À\B›Dê5ŠÎ®¹ˆäÊ–ˆ‰kq»(ÍJjA¼’Õ Ïi¶n™ ¶wvØ$8ÖUEú^%…¯”Â"jÊU{¤S¿L‚-ÈâTi±“À›¡J>ê×î©Y«ÕRÒj•YÓ‰¢³e&BÜÈ_«1‡ìêÝft& Î«Ï•Ÿzaé+[húgbþ Ú%8‚¯‰ßÂxj©Xv莛ñÚᶤ7*Id‘ØÒ–Ò’Û°’’ïÕ} §{õtW©W„Ù«Xµ«uÛ¾œÄVJ»Ä[6lš¬UÙ¥¹Jj©9º{‡uÅL…“J>3EìðyRåKÕn©/?©hškXá«" )¿K¼E°LFvu-|SCÿyÀhmAªz˜–˜ú&§ë‰H' AšNÊN¥¢¹q•ÈËúŒlýÙç?ÂbEð7dœÿ †ìóŸá1"ø ²?΄ÃvGùÏð˜ à,nÈÿ9þ Ùç?Â`/€±»#üçøL7dœÿ €¾ÆìóŸá0Ý‘þsü&ø ²?΄ÃvGùÏð˜ à,nÈÿ9þ Ùç?Â`/€±»#üçøL7dœÿ €¾ÆìóŸá0Ý‘þsü&ø ²?΄ÃvGùÏð˜ à,nÈÿ9þ Ùç?Â`/€±»#üçøL7dœÿ €¾ÆìóŸá0Ý‘þsü&øà>©ÿ±»#üçøL7dœÿ ‹ à,nÈÿ9þ Ùç?Â`/€±»#üçøL7dœÿ €¾ÆìóŸá0Ý‘þsü&ø ²?΄ÃvGùÏð˜ ã‹:¶>6`ýNßñß™»#üçøLq—V±’´¯Dw#£6eϾ¨jë‹þ¯ú×úL¡ªµR£$“B©I|ΉXxÐÄÛêÿI±+º›µŠèY´øÆ%¼MC‹U~;ÓÒN6¢JÉ(RˆŽÅr¹•Ëö r§k±J-mŠ}R:O152¼‚>;)Wýk!ob'(ØI4ü-Ar!XŒ©SX¦¾Ã茳cZjŒ§Ô†HŒ‰´(’Dµ¨²¶µ“1…U«"¯¤ºÞ÷CÕµOz£%Ƹ’¢C‡§}ÞÕl4¢ùHÖV“&£E:"cÓÓK4ä8EɃMïm^L¶¿zÂÆ·Gż;ÛHÞ›æÜ;Ø[ž÷½õy2ðþ B#FÅ®²Ì ;U™´ù)ÅÎÑäK}ˆnIS ¦¹(ÉdÖv ÂUŠèÙÜÓî’$ÔÉU‰Xº£ ü\ìF(R!Å(î15@–ÓK7<„dkSŠm:¬„JAì?r=Ð'`zD´Ø‰eí{DÅ?!!ÝV«9Y«î.[r÷<S*XmR5Vcù5›#Jv­æÜY¢éþ£  9ˆ(Ô5×£b·±¤¨gK8ÌêTÓõ·#¬Íyu™ÈÜ5‘’ȶe=¦{|F7ïn]Ëþ‰¹÷FéÕn5d×kuºËe¶}gw›‡7uôzúîÃÞ0ü=±Õñ’ÿþZ¿Œè캇úâÿ«þ„8êæäio²¬Í¸É­k\× Œu½oPâÕ_Žôô“¨’²J¢#±\®Derý‚g …é“"«¤Ü2p$”Z”:-RT•|¨y/À"%‘p¡IR¢ù*;XìeªãIMT1~!¥D[U&(”X¯Æ^C\7•:sN³©(<„³Y””*䓸؋ĘUs˜© *KM­¦Þ8Ë5¡ 4š’JËr#4 Ì»ùSÄBÊk8-2¦ÊJa”‰èJ&:P<„¤Œ’—-ÖDFdDw±ñˆ(˜ƒÀ¢bêRgG:b#J„ur‚¹Íf´ª2Ñ K"JÍ)$(’•š—b%å2<|ÙU¼]?Ô¥WjzAâY•NŠÔs]9I§Ë±,Ýiy2.pi{¹#î&t·ôuKe,Ó)ô˜-%â”G¦êÒN‘È’‚î¬fWáÚbº¬ÝÕš}ª¬:döäš ôɧkIÓEò‰H<Ùnv¿ö—Ž]ê±ÿk!ý¿á²:®ì=ãÁsÙåÕE.<üC\G5Œ¯Y•YL¯d4G°öðšz’Ó .€b±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>zÐó¤ìj•Tz”õYªlÇ)Ì/Vì´°£eµlîT»e#Ͼ\cÆ$>.+?[Óÿƒ0c(1:³*!;;;¥š;NâKjˆ”ddžäº22.àž£ÄkŠè‘›ÂÎÕÓL¤Ó^b{1‰ºuY3âCªºÈpТ6¸n’<ÇbØ=ž•Cf…R~›Feømj÷¾« iº³ºÒ_éMšÏVjFn&ʱm#¸ð ΰû-²ã¬¸ÚF±¥)&Dâss$ûå™*+—|Œ»Âؙ⊔"ÂX^1áúb]D™&äcfS$¤Í%­És25Òeu¬V"Ä`¨ÐæT¦F› ¹(:\ç5-i6œn3Ž¡iÊ¢¹’Ee\ŒŒöp3Ë#947p Bb¡¶S#U"´‰$¥æ6ÝjA©Y²Úí$Èòßií2±w½…iÕxÓ„ÙÔɃD•"[ùÚSÑÛqDÅÖdDYög%í¿zĹàA‡¢l°u¶ˆÛ¡”¾Î¹£F±µ{•¦åµ'c±–ÉԚ~fk³à³Y}i4ÖóŽ!¤“3¬Éµ%Fg¬M»¢"²¸{×ñêr°S4ÚT‡Xv˜j8H~Ê2)²Ä“†G”¶*Ê2;Ó½Œ7@¹!‡ã¸MÈeÆVhK„•¤Òf•$”•XûÆ“##ï‘‘‰Ž+¢Fo ;WM2“My‰ìÆ&éÕdÌKˆqªë"uÃBˆÚáºHó‹`öb•C¯bê=š. ÓãRZLÆ× ÖÙ9‚"²4eI(‹job+™ÌÛ†¾Štµ)§C‘2S—ÈË ‹UˆÌì’#3±ŸÐBqR¡R× Ù@ SšŽÃŽÅ”Ö#aùÔIqò‰f²,¶Bew®B?£OŒ|3õ¼Oã$7f3>W4*Þí¦Ã¢"؈ü˜ÒÓ!Å:½KjpÉÒR™(Qw)MŒË½°dèÐh“XÃÕ5aø%Ne¹X=t‹¸¦S™Fg­îLФrå#ZŒ¶–Àš° 2S¦=Nv¢Ì†ãK\ÃJ)´³KlšnK'gr#îr™™÷î1¢À1X³à ?cÓ!ÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½>2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ19Ÿ=hyÒÎQq tê,ŠKô ]I‰Q!j”©¬ÈJ’‚#mÔˆœ_{nc½ìVô«¾Ö÷¦F¥S™„ä‡ –Içö½´6é/ZâÌÈЂMˆËaŸ|F€FØ Ø2(RèÌaú<(Ò^ió8äöt8Þr%–âŒîKQYW"#ØD{EÊæ/™Ujy®›L‹&¤e»åGmirM–KîˆÖiMÖ”¨ò%72° °3mâ' ŠÕ5êU2JØaÈñå<ÚÔë-­JY’K6KæZÌ”i5žÃ+¼4J”ŠEMª„RmN6JI¥ÄæBÒ¤šT•|*2?ÔcĈ Ø äPeQ¡ÒaÃóR ,%ìÍ:‚QgJ”á™Ý+RL•˜ˆ¸hÎb¬O =J÷3B­*%:,N8ï’˜[L¡ ,«È•÷hR‹:VQºP0¶bˆ$GnC3aÄ«Gö½Æ¦ç2Ö÷ÖJB’²3¾Û*Dz÷±t¼g=ù”©i§S#¹MŽäFɦTHr:Íwii5lâÓr"Q’Žægc¶‚v'LŠº3~ 4—š|Î9=7œ‰D¥¸£;’ÔVUȈöÑL¬Q!øM7½´ææ¶Ó •A(^èÈÉ$›"3Q¥&D„–d¤ŒÈ¬g´ïÛ@þ)yq¤¦="•T¶ÔÜ™‘ÚY:âUÖhFnÈ”ì3.°Çẫ”:ô*Ã1cÉzÉy¦ßÍ“:v¤Ï*’{ÇkÚå¶år2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢cfÒ0æ!«ÆTšM©Pa+4)رu$¢"3IšHÊö2;~²Ë ü;íz&76‡n­µ&­˜„Õ (ž’—T“=TÎäµHYßmö•¶Þ ãêç/ÌèràJ\YÑ_Šú=ÓO6hZ~’=¤? Å~tæ!EoY"C‰i¤\‹2”v"¹ì-§ßªcôzž$ÁøjCÝp°‰ûžKï­¥M¾´$›AÝ.eGt¢3·t³Ùn&“†*¸–‹EV’EY†Tú¦HÎã 3mIYȳ]IQ)9H±‘™.ïØB€HiSiØeºÜÚcUG¥Lr+,¾ëˆi²m ©jV­IQ™ëREÝ•ÃÞÌÒ©T×¢¼ý,ݦԨRç¦9¾²\e´ÛçÜ,Œ®yã³’‹*¶‘žÑ3V.Wæ<¦£7imÇL®EÜ¡µÞ$¤Ïú…*aôÆD•2á0âÔÚ4žU)$“RHø È”“2ïf.2Ú$Œ?Z}P‹ BˆãtÚ‹«u¹r™HŒ§ZY%N”•4wÚiQ,û„b¢©B£;oaúdÕNz ÇÜJ#ÕÅ<ýé+ÙD\²²ùMÂ}FƒD𯩫Á*s-È*Áë¤]Å2œÊ3=orf… Ó—)Ôe´¶œÆéS¨³!¸Ò×0ÒŠcm,ÒÛ&›’ÉÅ܈ûœ¦f}û„U‘!‡:šÚ®Ñ˜ªÄ«- ?›*]D¢Ê£IÞÍp‘÷Ç7£z#ø¼¦küe‹ Ú¨çŽSå?ÿÄZ‘Ô·¨I)ÊÒI<{«gðF÷Ñ”Š¾ïÅôнvmoz+h‹LƘCº¥@†þUjme¼å-ìdG{ $ÿP?ÿò#˜;Yãøý¯,.„Et¡ŠnÂ5Ê»UÔÊ•Jn:ÖÃok,o<”$•ú4Ûa¨øo°¶XÈÆÊÄ:IÇ´Ý(±¢h·wnÌÎé`ÑqÒdJyjÔ¯&d’Ó´ÈÔ’,ÙÐjòi—ý‰Òÿt"Rå`@1X³à ?cÓ!ÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½>2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢cfƬ›be{¡­¤·!RTnk¦ÉD’M–H±Ü-©?v|I¶²ÂÿÆû^‰‰ÈÈÕFkZ 7Ur‡^…Xf,y/By/4Ûù²gNÔ™åROaØí{\¶Ü®Gè¦WSMÅqq*==¥Ey3ï)„­$YOk†³²ˆ•c]¯ú¶ 86ÌÀ¯œTÉŽºE:U=÷ò„þ´Ûe{lhQ,œ+ÛÝÈŠ÷±D,Y%Šâê¯S)Òï ÈMÆq.!–YZ ³J µ¤Ë¸RÊægîŒýÖÑÄ Å ºšEfMEš==ô¾Ëì”gíSHu&…r¸K÷ RHÔ£;øle]9O¦¢´ªeA¶Ÿ\ˆç1µ¯RâÒ„¨È‰D•\›FÅ’‹¹àá@ @”ËŸ “ƒ£RkG=Ue0üÔ¥…¶Qò"ú£Ì]Ñëw4ÜŒ›I÷ìX-ßÿbo^â…þ³º7V«ôþç.¯=ýÇ~ÖáÚ<`>èâò™ý¯ñ–>r ‡MšM ¨pñ"Ya¤åBOb.oiþ¾ø‘Úø/¿†«5Zšñ† ¬ªªé?)™íÃ&Ôñ6ÓDéjc¶¢Q6Âb<¶¹šMGqìǵZ}†©•)HŒÎbA)W3RŒËam3ØgbïŸ#ìï¥nU~ïчg}+r«÷|nŒ@鮿ð—¿åÝöFºÒ…B%SGZMŸítww«"òšogG°È„Œj®ÎúVåWîøÝÆâ,éP¤Pë•ý×O“—\Îãa²¨–žé(#.é${¼"# ÊÈ+|'ìzd B{‹>“ö=2 ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##Sç­:@¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<éºK‘Z«3LжóÙ²©Ã2IY&£½ˆÏ€¸†Áì¤?«ÉßèÄ[E¿íÝ;û_á,N°Õ)jŠ™~QÄŠË+~L^}ShMÌòÜ®fvIÊæ¢!ÚÍŸÔÏË Ø'H~+W“¿Ñ‡`!ø­^NÿF=ôªV¨Ú\ƒÝBžÔ‘šÒ’Í‘K?te°’“3>— •ÈY«SeÒ䥉dÎe –…2úB“s+’Ðf“ÚF[¼'ƒŒãr¼\õÚóv ÒŠÕäïôaØ'H~+W“¿ÑŠ@Oÿ·ø8ÏýÊ®Á:CñZ¼þŒbŸÑn!aå°üªkN¶£Bз%%Dv224l21ÐÔŒgMÀº ¤â ÍAÈcCYåBì§Vo9•+íQðí±˜á~ÇéDNrífÿêÌÆÇØÊ¹áô®y~ÀÃãœ#YÁµ6)Õ¶’ԇ㔄$³ä5­IDFGt+a—÷ÇEâ-(ÀÒGSN-­Ñ§Ii{Ñ!™Öù›‘Öm™n™Øø é"ƒõk|kÀú™¿ã¾<ñ/CF€”‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Ñãã,ëžzÙŠ+1B‡Íê§¢… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&'" …þö½{áv«x^©Sb¢´O‚êˆg/’›qÎåÌ×%YtòåÛd‘™ìÇÕN*^ ü†ÕŠq ÖPXZ—d›yɼëJÜÜ®fµ%6¿~ýãø”©•:‹ÑhP§ÔÉ&£A5ÍÓAÅ)5eÙk•Ì‹ŒÇŸ0<=ŒÒªH“šlLjڒÚQ©”'Ý)dEt‘\®gÀ?j”zµ(š:¥.tx³5ºc©¼åÆYˆ¯ýA‘â&§a…O?CN«G“ž¹/0ô5ÉZ#ë &‚±’Vå’“=¶q&v<[´ ëUTÒ]¢Ô›¨-9“QVO(¸É¹—õèÐôÑ+*«•4ŠÔŽö†Q—®;ϸ¶n3àà!î¥ázãÒiîÉõç Êy)J£BY©äØÔ¢h̬¥dJŒ¾ƒ>0Ì | -f ÂIŸ-—Üèq˜ËZTî\ÙȬj˶Ü6Ú<óaLƒ1p¦Ä‘J ‰L¼Ù¡i3ïOi Ȱ,þÄŒ”þ«4IaRk„âlÒm™Ã¹{’¹]\rá*3ø‹ÓhqÍÄ®l”2kCFá¶“>éyK„’›¨ö–Â=¤#1ÔbÀgS†+q$ºÝ[WXJ"= ÒP–•¥)IÙÃ%ÆÉfŒÊïŸ~ÃËWæ²Ãðèu9-HJÖÊÚˆµ¥Ä ì³I‘m$™‘—ð†`c{¥U§7R~›1¨N+#rV‰¥+ˆ”ec=‡³õ áÑk`;>&|˜ŒßZûQÖ¶ÑnÊ"±XdxH 6‹Ûºwö¿ÂXØ´@TJ$Æ`²ÒçÍu yRb4ûDÂ{¬„— DfkÊgrÙ«Miu¢ßöîý¯ð–;kö5ø¿᪎ ¦nŠþ¼£>ŠSÃFÑ´›:£±§2Þm ±Ô¢#¶ÁÞÍØ·œÆrázÔ׌Kž§â¨µ TÅKaiªJ¥&žâ™ŽÛl«W%—VTØ“fÛ4X“ü”q¼3ñg¤yª S{-;b3-q¸”ª×">;\t›'£W´–îkR×Rfšºƒ•)΂JÚI´jáÖYö—l¶Ê²;í°öÓãh†¡¡:\JjT©ï°ˆ«n)$ŒÔn¨¶ ˆˆÌóZÄF;ƪˆõ8Κ¹õ¹¿}ðœ:QÀŠÍZ{OUâÎ}¹HCi6[K¤¦®•¨ÍG¬¶m—â+mÈÌ®³W§7CÂѦ?U]M‰‘ŠæÇ~„¢StU\“*5 ©¿ Y%7 ˜Ï)…mزI¤öÇbÈØ>‡\¦Ñ!豚ôú„i2Õ:êÚaL¥jQÈq¢÷R""3>!M=“ÃUÝ¡16!†Ö6i0VäîeÀ$¬”û„zçJîT“Qå$™ØÛJJåÂ0Æ¡M©TYzšÁ¡(`ó§¸Ú÷3(ÍÍSfhFÃIXŒï–ü&:‘Èš.ŠôuŠ.£U&¡ƒn›9¸h’KxÍ-·”ŒÉJ5%i,†¢R¢IªÃßBÂØ2¥CQëS ¯uFmüУ3":³$•vÝÕ§X½Êò–b±Ø¯a1ª¦=H5SëqÚë'rFæÖ}ë'rFæÖ}‘n6žÊðuwq(ß2»‰âàšj^ªµhÍÄ2L´T 2‡LÜYžTºúWb½®¤–Ò;\¬g¸ºÉÁœ‘ yµŸdG °Ìh)–Ùa©2ÐÛm¤’”$¥¼D’"ØDE²ÃÍ©¿b"!Þʼn·33-M¦jÞ.™¢lUnŽjtèë¥HÖJr¯MZZ"AžcJdƒ$f}â3Ø Zßð>¦oøïçï‰LaõKþ‰=Õ­ñ¯êfÿŽøóRôËF€²ŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½§ ¦­ G•JäòR˜•Ê{©’–ŒÐ…!¹;MV¶Ãq²?÷Ò_Ê+él/ðìoµè˜œŒ}Tf¥á³pÔÊdœy…éØU‡”ÜÊÌj”æÑÝ¥%dz’ãm¤ë›‰FgîF 2¯3¹D¥B–ºœz£ª¨ÁmµkÍ$„%»·îŒ¢xgrjÛkˆx6Ñ´(lÕ]Ætö¢5&Urš™ŠŽ“uÄ=¨’MšoÝVÃïY<;jj”Öf*<§¢³Y†­vE)3jA8y¸ j™#ýjEøHE6•*Ÿ>&‘؇.˜òdabe–hз:9´I"=¦zÂ4[å— U.‡[‡E¬PÊñë²Ê3¨‰Á!ÈÄn“ä÷YZ¥d2Ìd›ÚÛD(m3 è7‰ôIõV#Uõ®0i5:ÄRq¥%+.å4¾»NûÆ'·ˆËJ”J]Eª¢e*µT¨!d¼ÉY/X´Û’ G˜ËbLÏ€B@6‰•:nŒ±1î)ñÛMZyfl­$œˆ’KBÎÛ,µ4FGÀjI ³MK…3Ï©4ôU?Cˆ²¤¤Ð~²QGVelîsÇQy&ƒà°Öâì7Õ[2P†œS.%ÂC­’У#½”“Ø¢ã#Øa4‰Í6“‰iX3a‰ã¿•Rn“ye2?é“Ú¢"3#Qlî‹nÑÑÛ­±¤ 8ûÎ%¶›ªÅZÖ£±$‰Ô™™Ÿ¦£ˆŽDá£Ó)MÉ˺N"\Ìñæ$™¸µeNb#²lW"â!„8œ‰Ö Âx–!q©49í¼õ"§‘“dÍÓ-Èâò{¢#[ˆI•”j±\ÅË^FŒ°ú¡D¨rkÒ•4Òì뺸Ék)‘mQ©.’mÂiQˆ`'#hâXU©“Ji\)î6³-J-¤¦²¦ÏƒajIj#ù£-—DaºŠh3i4,E-áGBeÁ«6Ìx®¥%­5‘°­Oé3¨ÍJÛ|ÜCV‰J&“òŲi´zc´Â–…9 ¬µCA¼­Y2£Ê¬ª÷&yv‘È„\Z#H“h·ý»§kü%ŽãÒ& bÈâVÕ8°ýNæ!IÏK’ 9iIÍI8ëYˆÛ+™\¯Ãš-ÿnéßÚÿ cè=_Ðiއj5Ç©ÖõÛÜÊ›Y“Ú’I¹ÝeM‰i÷FW½Šæ\Ô4g]'ŽÍH¤Í©aÌA¡ZÈLÞ|×!j•«%)II!•%$Y²¥”‘í#Âø£бÅÁ%‡N¨PcC9QvÈy(Õ%ÚÍ)i½Z’“pЦWr’¸ÚIÅ4cCÁ©¨%UÒ€uŠM¬í–”ÍvÊG™I,·Í´ŽÖÚ3 !u.ùcú<Ê;;×Oc Ôi«— -%Q–·arJFG”›|Ót)%c#.êÇ­`)U\e†U«b ”m"¦ÌŠ›u3§ÉSÏ? M!gØÌœºV$åýM]ÕŒö0ÃL®î|qKÃ;—6ï¦Ìº5–Õîwb£&[mͺo{•²pö…†OÒ…J´pÔ¸iÔÚd)¾o¼fÓÓTê kQ¸gg3Rº3#¹™½š'¥Ï¡è³ Q*Œnyôú$(²šÎ•jÝm„%iºLÈì¢2¹—“^ô¿ýdßýãâx4­cWk9“ÙÒ-rse“0âîrm´”—HíxËQÝYjŒö÷ŠÄU©0óiûâS}Rÿ¢cOuk|kÀú™¿ã¾'úGÀ®ÀÀ5é¸J8®m!š{Ë™ÔódƒÌ„‘Å"Ì|´¶™m.êÖø×õ3Ç|)%£@J‰C©VTá@m“KF’[Ém†Òj¾R5¸¤¦çc±^çcâè†4¢§ M6¥*5­T¨¯-—‘˜••i3JŠår;ÒØ<à:Óõ£ÒdT¦O^¥„æQ!‡J3;éxLÌ‹m‹nÓ"”áÊÀ&:hÃ0–’ª˜z™›rÄKs™™©†Ö£ÚfvÌ£Ùs°‡ @Ðä)-ÓY¨­«E}çmy‹º[d…,­ÂV'·ƒnÎpÓz!ÐfƘ"jB÷3ÊBáYÅæV© 5lpˆ®jà°—v°a? ü'z`l²{X0Ÿ†þ½0v°a? ü'z`l²{X0Ÿ†þ½0v°a? ü'z`l®åu9à¸Î›nͲ¿òžéG–^€° HJ‘QÈË-©Ç¨|ì’+™Ø¿ÊpäàNXZ…kÔhô2t£O£³<õ—½ÜqËl5*ÝÊRV¹í#üJ¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<é›E¿íÝ;û_á,v¶”ð¬ÜOèíÄK±ÖÆ©ª-CVfÜI¥*šìe)DV#ÌÊ/ ’…—Çhòl*v1§Ë¨ILX¨RÉÇ”…(JB’Fd’5\Ë€ŒvwlFŠyIÿ#'¢Œ™ƒñ”ZÔŠ‹DƒÅul3ˆVô膳k«§¦#)uI+PÊI9ˆŒõkU‹m°ÕJ wð®0k`ºÝ Ø¥|G©G\Ú‚ÛNç$¡I#}ä‘>Ju$¬ÚÄ–ew¥±)å'üŒžˆ;b4SÊOù= q z_ÎŽ©;ÒýGUÚ\˜è4!ÉéTBˆ·œàS×[æKQæ2Îw;£tjU2>.Tü£œAOmœUbKOC~œR¦)Èf†u¦I=z²,ô™š¸IjÈydݱ)å'üŒžˆ;b4SÊOù=v²+8²e èi£Ðê¸vRe½OÂr¨­·5Æ6£}Åk_Fg—2¢öQ‘®Ç’¡…ÖqBzüÄ̲‰ªŒTÈ hîÞ©µYùâ'ÞNbÿûm³úÆ¿§×i)5 I'rÈ"K¥£¬ÈŒŽÄãHJÈŽÖ2#+•ÈîFd=4ù¡ú|ð!W[3Ie–[$’ÚVJHµ[ˆˆ€mð›¶#E<¤ÿ‘“ÑlFŠyIÿ#'¢¶F¦ÆÐ1K N…«‡D¬n©ª‹(ØmÔf)o÷+JÒ¢Ê|dW.â7lFŠyIÿ#'¢ú»Žô_S©¿13c[N8·D%–³­KQ'<%(î¥(û¥íµìDE——ӱ̦¬X½!WÊ­[‘J}džm¸¥ìÚM´'1ñ™ßnÂØW8V·Æ¼©›þ;âCY¬è–±I—J©éÃJ…-•2û+ŒÕ–…Œ¿Ô8¸„ªaüi¤ul7?vÄn˜†æ¥Æìá:ê6ZHø¶¶ÑU }«*+Ha¨+#«B/ÓÁeãîÙ•}«AŸò Çü›ªÖÌ«ÄR~¥‹*ŒÆã8R—¬y.ÁeÕ²šIDµ Ô“"R¬de—2Œ¬fbjŒÂYuâ£R°œ–(T ;M7$œšcN&A"Sí¤–Yxr¶Dk+-]õ±.kt9ÊTZ-6lg¡Å}ý|D8ì¥<ÚV¢' ³¢Æ£Ad4Û/Ƨ_©TiPé’÷£BA7$[q ,Ç—X”Ì®¥(ÈÌî£5Ïh½NÅ5Ê|6¢Å–Ù!›“ \f–ë;þÅ$ÖÞÓ3îL¶Åv‰Û›ѱLx°éÓUMÄ,Ƈ&L6žRRi”J;©'˜Œ™Gr«¤iÑꚸ+²h¨¢ÒØ‹&€uêâ§X™NÝY»fBI{2’mÞ–kU¨Rhˆ\s…)ä¾ñ*3jqKO¹2pÓœ­s-Š/t¯”«ûúò¯oÎûë)û¯qî,Û×&§.L¹5y}Çq{_/s|»m”£à:!ß”ª¬ÊSÍF¹OI.e:“P—&›‘¸Þµi+wö‘ 5vUOG¥RÞzåVµŸÔ«¾3/ý.&§Vâ3™ä'5ʺdwd–Ñ3Ñ^æsGö$j–…¥ä­µØÉDn®äd|$d=8gá,9ºw®ée1ÜÝ3“fS|¬§Zµdh³›M’Wà,+ü7¤:m=z­W‡T È›%U ÎJ2}‡£!. Ög«' Bî„Ù£+$¶È•ÌI‰×CĵéT‰T¼/kª¡Îz39õÈCΤîJq¶Î:r¡Ë¦ÎwI3Ü'„°¶u稱ÔËŽ¶†MoMvBÒ.iiêÕ«l®vBl’â)Ú=Àó)4ªSÔóLJTÓ⡚ƒíE$¥:…© %:Ý›¡ÃQ¶‘€†Ð¥Tô‚tÝø®Uh¹0]6°[ß1q?Òå뵎/!–roP›!WGvwIìGY•íaºåA‰•LYrI±Ž2•¨­ÞÚf<Ø›á,G¹·Ò+s²¨èÜÓvUl̯T´çhìWmWNÎ!eQYe ²¦[m $¡ 2"IÂ".ñÖzX^0f6Fn’ýiœ®5¤ÚÍ© $íl”•£"Ïe”fi¹XìG™:âGHU T*úBI¥Ë•¨\XãºÛ¬7¬N׳¸«-[!H»®èÍ)ÙX‹)ŠÔ–ØŽZ[Q']ž£mfDWÊfer½ÊüÞ¹XÄ_UgV°Ìºd\)‰óÙ2©Êr‰%e¥G{Ÿq ,箩ÿê÷±$¯d¤‹ò\Öèr)”¨´ZlØÏCŠûúøˆqÙJy´­DNgEF‚Èi¶^;Œ%Öhñ·=>KM œ7PkŒÛŠiÃ"#[jZLÛU‰;Rd{ ˆ…tìS\§Ãj,Ym’¹0µÆin±s¿èÜRMmí3>äËiÜShóbˆ,S1-R›Ãuˆ“aµ™ß2P³Iõ‘ p™™™™™žÓ3xåÔµñMýä¡~‹ãé*<7ˆ1P ›r½:¤ä˜ÖSJÕ²HQêÛXm¯+II% Vb,è¿›©uÆÑ¢xd¥¥'tl3·ýÃBG„ty„0¤–^¡;YŒ–V㈎¼G9èæ¥æÎjeÇÔÚŒÍFw4žÓ¿Ð÷G:C¦bÍ5ÓçDÇåF«Òªh‰Ebª•¥”2ô=Î¥°JÙ!hÝNí,äƒ4žÆÔ&‰ºÝcáü+]¨»4¦êÓ:4Ç¢©ä0û(ˆÙº“K„­L‚ZÉ&DklítìW Òž®E­¸–Õ>$g¢°î´û†žSJq6½Žêa£¹•Ë.Ë\`¼%6˜Ý=Ø«m¦¦ÈžÓ‘ç¼ÃÍ>ûŽ8òÐëkK‰Î§\¹ˆ¬«ZÄD A•SÄë¸b«\ª¦ïî¾TI‹‹"nàšˆ¬fu£Jû¤,Ü<¦Y;v\„ãDÓæÔ0C+¨Krcñ¦Î‚R\±­ôG–ó ¸£.) ¥F}ó;‹• „¦ÐéÔeÃ(ñ)–Ü;Žc±]ÜšO#­-.&äfGewW;ÜfhðétzTj]1¨ñaElše–̉(Ipÿï¾'¤TÖÕ aaÇiíUµ&q=¥®9¬”ge’•Xø.G²÷²­”õ&«i^¹ƒñ,í#Q¨”6‹&Ÿ)šŒf[\’y¦ßRŠÍ6²<Æ”Øö™jÕ|·,Þ8XpÞŠRäÖitøÎ¸¦ã9%N–èÊv3A% Q&ÿÊQ$»Ü$vnƒ!„§É‘WŒôÈŸ¤¶—¤"CŠ,ÍÒƒZ”šTEÃu‹)(^sJ]VDZΪ¡椬Ù7T´!RPÙäÌÚr8•ÉV<Žl½ÎѺ`™A[Ž™-üCDŒÕM‚v)º·ˆÔyÔ… È›3I¥I25‘Ä£˜vk³çÅ”ìzziË4LzJŒ›eD¬¹O)(ÔfddD’3;ð˜Ð0à3µÌ4å*‰°ujdÈÓ$-˜Ån)NdJMk²YHi+*ʹìM¶ŒDäH÷P)r+Ufi‘VÒ{6U8fI+$Ôw±ðØ=‚t‡âµy;ý‹h·ý»§kü%ŽôÒV0{³Duš+Õmñ©GeÌ®4Òc?!ÇRœ§¬RQVl¬j3±öq§`!ø­^NÿF‚t‡âµy;ýíG±tâ*E=¥GvŸR£L«¦¢R›CL.*Hø,iQJÍšåbG~÷/%;IX2|wä3Tyd™Z·D )M¼á6Û¨Kˆ#[FµkF‚á3"Ú»éÅjòwú1ø­é%uSEúØ£Å+Pã-Ä;QlÖÕAšk‰AÔ‰.’ ™$ŒÈÌœAñÌȈÌzëi€á‘™™} p`ÜâïÁ£z–†qÅ>™2£*$w$º¥!Ô‘!´ÕµH"½’}ý¼£ñ¶š0. ®ª‰‰ñ$ªlô¶—IµÁ”¢RÀ¤©-šT[ ®“;p‘‘yqÍEʃX‘Ýl£Ž¼ 1æ›…¶¤g½îÚÈ”…nFDeb#-‚"S‡u—"µVf™m!ç³eS†d’²MG{Ÿq“h·ý»§kü%‹!)ì¤?«ÉßèðNüV¯'£—¤¬`öfˆë4WªÛãR8Ž6Ë™\i¤Æ~CŽ¥9OX¤¢:¬ÙXÔgb;ì?Kغq"žÒ£»O©Q¦UÓQ)M¡¦$|4¨¥fÍr±#¿{q_`!ø­^NÿF‚t‡âµy;ýìšv’°døïÈf¨òÉ2µnˆR›yÂm·P—F¶j"Ö$ÂfE´f%bJe¸‡j-šÚ¨3Mq(#Z‘%ÒA¡³$‘™“ˆ>"#¹™€áîÁ:CñZ¼þŒ;éÅjòwú1Þà‚;éÅjòwú0ì¤?«ÉßèÇ{€ì¤?«ÉßèðNüV¯'£î8ô¤;8Èÿ[ôaØ7ø»ð_èÇjc›µÊ5H&Úmn,˜mn-D”‘Ù(A–|IIŸ˜ÖX'MWSDÃ’UJz›S¦Ú ÊI% áR”¦É)-¤WQ•ÌȸLˆë”¹Û–p,jyUñf ŒÔ­cqŠœ”Ø›$\²¨ÒdVZm²Ü}÷Vë®*¨µ­j5)J7Û333á3>øÒÂÈmÙ{Åuú2Ä/›K4)²©ÊRÊÄ“3²o³º-¢GÖVŸùGŠ<¶w²%½C~ûTÿuïÿn7¢f‘kXF]1P“ JbÁšofD×J+\nÖ,‹J$$É7<Ä•™{“"Ëýeiÿ”x£Ëg{!ÖVŸùGŠ<¶w²:~6‘(­ÐÓR«%ø‹v­P¦Ç‹‡f>ùÄ”ó Z[e³#&s’d’UŒÏ„ò1ñÆ‘ Ù­VãœVi¥Tqó%%´Å3Yk3[a¶¢4û¤ÛiÊáÉýeiÿ”x£Ëg{ x+OäWŸXÅè­æŸÓ6;u‡Pëj¤Ñ¬¤(Œ»ß!ìy€9 †<ÒDz6‡pî ï®ñP©”­~§]¸¢6γ.|¹²^×;_‚æ) |ùï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLmŠ zC”ä¾XTZÃRd§›tÙSYS”Ò¦¥¥d¬÷¹XÈÓÁc¾§ÂÿÆû^‰‰ÈÇÕFk^—+ÔDZlWäÔMûR$À—SS*-{βûdêŠÙ̈BL̳"ö¹ØY¡u»K9‘Û­ÒŸœ¶ÚS3æSz#v5ë$-µ(ÌËVdµ7ÞQX¶Ãy¶ºÅÌeªN×é¦Õ/!OqŠ{‘Ðѵ)Ç»–ÛhŠÊJÈ“”®gsQ&æb)‡äCÃøî•5s™ŸøòüT¹•iJÒµe'•\¬e´‹iqm §%[ƒM‚–S¶ÅQÅæ7 †B-™v¸”™™í¹e±X¶öd:sø‹~¡·-5I.¾ÊÛzì6êBV£&Í&E©Q™$ÔvRlFw"€œ í^uM{H2Ú¯C6ªˆZ ²ÿúA®[R2—èû“$¶i<ÙK1•ŒÓu:B¨· T¦×OScÇ•㸷U©m-‘´iI ó% >éI±™÷¶ˆ˜Šp%õ:´®ÄóŸ4ú•q™íÁ4:k4HÍe2pÈ+]E± ÿÛÝID^Ñô·kÐɪZ©æL¾{œÑ-ÙOô}Ñš\$–\Å˜ŽæI²Ž´I¨ÛÔº^*¹&²|i Ë[/)§RÒd!YI(5‘žµ&Y’[ïcd ¯Nƒ Uöà).ÆBåEvÒY7–êVDÙ/*ÿH¢4ªÅ°»£@ ¢tÅFT•‰IÊÌz[2iqiЕ1§ŒÝ&\e¨šBò÷ÌÏõ¬ˆ¯´Ë …]€Ý7.§#ÒiÉf3n!ÕË) ;b4!D[2ºŒŠêOzæQð ¢Iˆ*™…#G­CZÙ‚qåž­â(ªT—]ºîßtD—ˆ&m¨U¯Üš³uiêå{C‹?Y}@ª­TŠòÚi)[–Ö§&t¦Ò &yNÊ"á#¸€E>tÚt¤Ê§Ì‘B}ˬ:hY}GpšDŸŇaø±fîÃ9ÓžS¤Ò›Bó"2IH%‘(ÑÜ\È®iVÍ‚ =5*„úœ£—R›&l…Ù©Å™}*31æˆ$Ú-ÿnéßÚÿ cè*¢Jª×pœèî2–¨Õw&È' ÉJB ÊŽD‹ÝYßAí±X•¶ö#ùÝ„jíбJ«±U)¶¬Ì¥ÝY¬&“"U•cÛÃcÛi#‘½K µjº-/Tâ³Q ÌÃÕjlvK6è†ìõÆ7 l¦Éj²,ÄdnH²‘[Ó#b|PäÇqÑ!(°üª,dÒÞqÒYÈ6”·ÔkB5fFÃyPY²Ý]Ñ쇶ÒG"?z—@¶’9ûÔºGhÊ»MÅ4ZåR¥õ(Ü©W›g=žªèÈÜrsë =ªIXÒ||=ë²CÔ7ïµO÷^ÿöãw¹Ü˜¬`S%!…Uë,Ôé’c™›°ÜnFPæÒ"%“‘ÔvÚF“"=ŠRGèGKE£6åå *¦ìƒU•»I’JU’äe«Uϸ-·.øÙ¶’9ûÔºSà¼oD‡D¬4xvn"‡"´©qW%æ¢:ÝBnê3Cº¥-*A¡²Úƒ¹Êü ¥h¢|¸v¹Ðm2f/6HQ"S2e”Õ²ÑXîz‹*ߢSó±ëÛIˆýê]vÚHäGïRèoaJž£Mbµ=š„ù¯º5fi 1˜ÌˆóêšB•ÞÎ¥Ú÷¹Ì÷¥ÿºc•ûm$r#÷©tðú¬äØÿ•.„åÅôJN#¦ÔhuÈ-N§LÌÛì:[W¹Ëi’ŠÆFDdddF08®4hMáHpãµ3¸m2ËH$!´&䔥%°ˆˆˆˆ‹€hgôǃŸ}ÇßÑrÝuÅÖµâ'Ô¥(Îæff¦gßÁÓ>…5‰‘´[«}‡ëJß÷O*’w#±·cÚ]ñ]©k+|hâÏ®æb42X®«¿¸¦­\Ôn}ñšô½N|Ú½bÍysX¯kÚö+Œh²¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëùÿöæ!-Ñ×óÿìÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰ŸI¡ªlŸ*¥—Zl¡éfá“‹"#4¥-¡j;’fv±f-»F°ÂÿÆû^‰»Izd\,—ª&êtMq ­KRÌŒçÊ´Òf_º#IÛa‘ÛUç/ R°œö*LÃ)P_Kô÷ª,HeÓSN²ÒZŒŽ×#ý Óc";–ÛpŒØxu•áüXÔŠª”Ô0ìé)iNš_d÷4Œ¨R’IÍÝ´…¤ìWîÄv:tüFtJµ}ÙU'«„˜ÆÄÇÖµ¾ˆfn“Ž6µm"%¥´æ. ÆWÚc˺D ÌÃ3jâ}Õ§H}5‰5}Sš.¿Üi)RÏ…YO¢çÂ’±Üˆc¢T1EêÝ3®B©ñ`É[‘ÝMš†êPzZx»º´[\”e´Œ7 &‹~>’°Ó‘Þq•R;f¤(Òf•8”©7.ñ¤ÌŒ»äfC-WWêSŽ òeE©ÄjÉ;.#n7$Ö†L¶¶“Õ ¬›‹õ˜™™±$gV-ªT#4•ÕºÞ‰:)df©.1n¸IùD•¼»÷Œ¯ÂC:§W™ƒÛ­UfË]N=Q¤Ó§8âµæ’BÔåœ÷FHQ2e·¹5lµÂ*ñym°PZu2sHS‹JÙÈe‘$I4«7æ3Q[½—õÙ•ÊÝN~’1…L¥®—j¹”;þ„”ÓO¸…’8 yЕfá3¾Ý¢+.tÖô}†Ýnd„9¯?r­.™DE–C¿sÝ«g|ÌøLDU20uÊsôzÔêL•6·áIr;ŠlÌÒjB&dfDv¹qñ¥Z•[«ib¬ÅJEB£O‰Tœ˜,IZÝŒ™—Ž3D•]=Ò’’$÷ËgF±Yµ×1™RÑ-n7e©MH7’Z´í"6ÍÓ4ÎàŽÛ*ázcl4òSNèA¶Úy 6Q I±ü•¦ýû_¾&øãbXõBŽÍbJ—C„Ü´æ¹IÖÁkX§/îÔyº;™l±•ˆdªOoI.ÍT§]yü(K’n¨ÖRy‰Ë9vF´¥FJ½ÌˆÃtõȶeV£[Ñüéy¯ÎzR#qÝ}fµ¶‡’kAí$™´ƒ·Á. T1d¦Ði‹t6êLîhd›Ç8„²4=—Ü™š,¼ü7Û{„Õ©\’ûò¤»&KÎ>ûË7qÅ”µÜÔf{LÌöÜ[&ÑoûwNþ×øKÕQÁº;¦ª*j1âC9’1?=Æõï(ŒÒÚ.²Ì³$™’KiØø‡ è·ý»§kü%ŽßÓ& v«€©&ز± Èp‰F•ý“P2RL¶¥DdFJ-¤dF[H@È/à4Nj à2™o4·š`æ¸N-4’ÖIÏsJMÄ™l#ZoÂB÷c¬âù—½±®ªµœRÆ:Þt6©x‡‚«ÇÍQe¨»O8¯‘p]jA¥Iï- "îr™â°Ø“*¥ƒ‹á*Fóœ[8²eUäÔu¥²§‰ØíT«»CŒÜ‰D«’¡8k±Ö ñ?üËÞØv:Á¾'ÿ™{Ûò½‹1*ÂÌk„Ü,Hq G­[yVãÍ. ê²¡g™–ÏVJ$-HSoY'{ŸS«ÌÁõ¶)عÀíkÇŠõI«»OTšjAn·šA÷H4–ªëËu܉+$›nv:Á¾'ÿ™{Û)xK ±!Mol¶ÛºÝ.÷ûÂyD¦Ç¤S§Evk¬µ›*åÌvS§u3Ž©KVÓ;\ÎÅb+ s¥Œ4î+£M¤F¯U¨2Õ•q§Ód­—Yp“°Ï"“lh3±—”IQVS n1¦áŠ&™Sc¡×YI¹ŽåÌ¥HÎÊÚDg{l½­ráÁÕ!4 3×aÃe,°Òc%Oækþ'úûãu@Áµ|¡ª„|EŠjØ’µ'PäÉ3':ûM¨œM›e.åA\û«–{NÅ•)ÓSÿx‹ÿ–ÿÚ´’Ö£µúž0¥»£(ê°7CèKm¥Zå¦É&[;Y*"á3P;Ë©kâšûÈþBPÌFÃ1“‡ÏÆ:sÔd²·Î ÝMJŒM¢ù—¬'2å+Îö+Èö:Á¾'ÿ™{ÛBKkÂJ9„(è5ü†å¶’¹Cœºq%wñåB¸œÈ¯å¬ÆcJÕÌQHèå\§QžŽQÏÜM*\-J¥&QÜDÛ¼n!I3R¬’I%©ÀÚýްo‰ÿæ^öÃ±Ö ñ?üËÞØ‰VjU¨ø†££Fê3ÊejreÓ¦“ËÖ±MtÔ¹Y\½Ò¦”‡[A‘÷øä\"¬×1:´¤¸òë”ú}Q›PÔ98šR]v›¯È”¢˜QÍ¥’ز‰ìçee-$F’`m~ÇX7Äÿó/{aØëøŸþeïlbt=OuæjøŠu^³:cÕÊÌVÛ“Qyl0Ãu'ІÐÉ«VYI¤‘+.b+¤Œ“Ü‚NÇX7Äÿó/{aØëøŸþeïlJÀ0"ްo‰ÿæ^öÇž¡£üÄe:š>Ô‘ŸúË»vþ!3:ÏÁîÿºô15÷[OÄ?ónúÄ;Hpû4üKK‡Bi“g ΜO-÷<ù„‘ŽÅnèïcÛkZÛ|Qц Å8¶™W éaÈjp‘V‰¤òPãIIÙl$••·ēٗn{fI“žÌi¸‡‰â´§TÛ8 [i7]S«2,ÄF¥¬ÍJ=›T£3>31XYÇBM¢ßöîý¯ð–#"M¢ßöîý¯ð–/*»ª£ƒtwMTTÔcĆs$&,b~{ëÞQ¥´]e™fI3$–Ó±ñ «À¸ š‚¸ ¦[Í-æ˜9®‹B $µ’sÜÒ“qf[Ö›ðÇ銓»UÀTŠ“FìYX…ä8D£J‹þɨ)&[R¢2#%Ò2#-¤"ZÎ)co:T¼aCÁUãˆæ¨²Ô ݧœWȸ.µ Ò¤÷–…‘w9LØ±Ö ñ?üËÞØv:Á¾'ÿ™{Û—½‰1ªPh8¾¤o9ÉÕ³‹&U^MA§Z[*xŽÑEJ»´8ÍÈ”J± ‰*zö,ÄX«W1®rth±!Æ6µmå[4ºƒªÊ…žf[=Y(µ!M½dìl ‡ØëøŸþeïl;`ßÿ̽íGO©Õæ`úÛì\Æàvµ‡ãÅzŠ$ÕÝŠ§ªM5 ·[Í û¤KUuåºîD•’O}Ñ)±éÆiÑ]šë-fʹs”éÝF£ÌãªRÕ´Î×3±XŠÄDA—„°›ÖñæËm»­Òï¼0xÆ›†(˜jeMŒ:‡]e$HJæ;—2”I#;+ií²öµË„d´±†Åti´ˆÕêµZ²®4úl•²ë.väRs£mv2ಉ*-qÕðv†ªñ)«bJÔC“$Ìœëí6¢q6m”¸g•sî¬JYí;T¦‹4¯T„HÐ4Ï]‡ ”²ÃIŒ”!<[™¯øŸëïx6WTÿÇž"ÿå¿ö­ j.¨1X³à ?cÓ!ÜYðŸ±éÝ=F¿ëú­ÿIK ÓÔkñ¾¿ªßô"zìá-Ñ×óÿìÿÌ"B[£¯çÿÙÿ˜R:¦_9§{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½“Y¬RµRjÓéæ¿tq¤-¬ßNS+q…þö½‘‘©óÖ‡«|jå¾{¾Vî%çÝ:åksqæ½ïúî/*¹[UTªÊ¬TQ-…,ä¯\]ïw{þÑæÂYÊ!z&1‰*ç2¬ìI(’¢\£'R2HÜQ+eȯ³i\¶p—š«[¨Îd ª¥Sr˜ÒÌãD“1N¥”ÿ$»É¹Ë’Kè.ŒÄE:tÚlÆæÓ¦H‡)»äy‡Mµ¦ädvQ\ŒËè1èr¹Zr¨NV* ‹1ã~S*’³C֛ÙJ¹ÜöÜ‹ˆcÀNB}nµ> ÕBu^¡*c$IjCÒV·DfdIQÊÆf{8Ì~K­ÖfTY¨Ë«Ï‘5ƒJšì•©ÖÍ'r4¨ÎåcÚVˆF±!fªõYªõQº‹èÕ»-2Ü'œNÎåK¾c.å; ûÅÄ<îÕjR™¤»R˜å9…눧Ôl¶­½ÒQ|¤}Ò¶‘wÏŒxÀ1Ý>³X¨2Ã3êÓåµczBÖ–¿Ý#>çú‚©Y«ÕRÒj•YÓ‰¢³e&BÜÈ_«1‡„2Šåj³ªßŠÅB£©¾«uI[¹/kåÌgkدn"Žº±Fùo—\•Ý©ÔnÜæ·W|Ù3f¾[íµí}£ˆƪµFiORZ©LnœúõŽÄKê&\VÎéH¾S>å;L»ÅÄ$ô¼pšm:Q"Uô2Bšk}Ü8ZäXÉÓŽi>ë1¬K$ß½m‚4Ä€ $Ñ“¬³Ži«‘!ˆíæZMÇÝKhI›j"º”dDW2Úf;˲†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í è·e r×ùÑl;(hó–¸wÎŒ{cçHú-ÙCGœµÃ¾tcÛ æ7nEZC´ìk£vâ¬ÑH¬fs)®¬¦Esµì\µÏ„ø `uÝ~¸uªCôÉXóFˆeì¹”Ý^Ê+(”V¹™p—нQu]2WgÓ'FÝÏ«~3©qµÚ;DvRLÈìdeô‘|€¥Ôïð}F0bUqM…ªv¢Ê’&›NԚOaâÐ>‹vPÑç-pïöò†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í è·e r×ùÑl;(hó–¸wÎŒ{cçHú-ÙCGœµÃ¾tcÛÊ<å®ó£ØùÒ>‹vPÑç-pïöǃé+?GÝ/aELRLš)5vRÙìº*3±^ö"Ûk\¸KçÀ쮼dòçEþv?ha±jœí#TêxÓH}ü12xôê¢V·¤š’D•ÌÌî[‹`äà„äM:Ë8æš¹ŽÞe¤Ü}Ô¶„™¶¢+©FDEs-¦b6Pú-ÙCGœµÃ¾tcÛÊ<å®ó£ØùÒ>‹vPÑç-pïöò†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í µë˜Ý¹iÓ±®Ûˆj³E"±™Ì¤Vº²™Î×±p^×>Á×ë‡Z¤?L•4h†^Ë™MÕ좲‰Ek™— qDN[ª.¡«¦JìúdèÓ¢;¹õoÆu.6»GhŽÊI™ŒŒ¾’1¯€ ¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëùÿöæ!-Ñ×óÿìÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|õ çH‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'¡ÎÝ?þÏüÂ$%º:þýŸù…#ªeóšw¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ1´hØj©V¦»QˆtôÅeâaÅÉ©G•j#RJÎ-'´‰V>þU[€í«°¿Ã±¾×¢crá–énàÚjÓ&Dc} W*_Q«U3a¥N ˆ­}·ïÍ»1õsŠ—†·F©Qiº„ro\Œí8‡Pën&öºVƒ4¨¯³a˜Ç‰ìª}.i`ê4 /»C•PZU5â$:N¸¶PêT‚¹#*RÙ‘fQwW¾Û¢kt‰ÌTâ*~[,Æyر鴹I’›I©%¬8é5seŠ2"3=†C˸k ´Ã] QaS©’hºÇ©ò¢j'¡ÍFc”‡q7ý)$—cF̶Ú0g-4 =Fv>!Ú‹.?!épÛ‘î^[dÑg#$‘ WM•Ýð𠊆2dÊ|éñÐÚØ€„9&ï!*JT²A(g™E™I#4‘Û1^×!ã©PãAs5­CNP¢H&HÌÉ“vDÞݽɬӷnÁí!¹u*^,vHÞøÔ×W5„Ó#¥•:Í’mš LÜRÙ;Ú宨eb´nà†PcaúmG|°¬)•Mt™EP¥­ã÷å ÚPÂÛmH½“•]×x‰#ñ´S)s±ŠbÓàLŒÕ.<¸äü5ZuOF+·®I8H-rȈìKN\Ä¢°nøF½Wr°ôwž…NжX&OqDDt»e)YÔ”'7uk‘ÄOšÝ Úm*%›2;У>ù¿;%O6•¨‰Ã,豨ÐY >çŽâÙà&¤üX¸¯I½—„Kܬœ‰ s™e³AK-’³¹Åÿ+0ıV)”Y¸…Ú=w@(КKTöÐÑ“†òÔúÚ"Õ©e•(¹¦ÖQl¹ŠÅBaa²‹;ળôÚrŸW83Üêl–ÉgÕd+“ÊNÂ"#EÊÇ´GðËd¼7‹ìV&©ìº‡ÂT¶œ)l +2Ì‹¥k#"2¹ÛØ­;„tâ¯XU3 agcQhºé4Õœ‰ÓY½’Kí¤Œ6ÌIBn²"YÜ®g°cq:CPjKSiÈ ÈŠÌcIêd:ËnkÏ·V“Z’ÊØA †…°å;ãvhµ6ó2ú”ÔY§PœÝÉ‘‰G²ã¤ûX0Ÿ†þ½0нL_4ÿ÷›þ;C½ÄÚÁ„ü7ð郵ƒ øoá;Ó úF‚í`Â~øNôÁÚÁ„ü7ðé†ý µƒ øoá;ÓkðßÂw¦ôh.Ö 'á¿„ïL¬Oà ޘoР»X0Ÿ†þ½0v°a? ü'za¿@‚í`Â~øNôÁÚÁ„ü7ðé†ý µƒ øoá;ÓkðßÂw¦ôh.Ö 'á¿„ïL¬Oà ޘoР»X0Ÿ†þ½0v°a? ü'za¿@_S&d‰×d©ÆÒ¢Ì”¥Ä™•ö‘´ì®Æ8Ü}?Ÿþ¨¿êÿ©˜1X³à ?cÓ!ÜYðŸ±éÝ=F¿ëú­ÿIK ÓÔkñ¾¿ªßô"zìá-Ñ×óÿìÿÌ"B[£¯çÿÙÿ˜R:¦_9§{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½%ŠÌö(2hmª>á’ò^u'¥,Ö‰2pÓœ¬FdDFEe+å*úÛ ü;íz&'##Sç­tz´æ)Ò›q³ˆû‰uH[(Z’²àRdjA챚L®[ä=³qUv\'¢=-¬–WÜDfóå{ÙÇR’Zö‘tgq„æÄ%›sל¦&œ¹ˆSIŽQ‰{™­q2Ebo[—Y’Û2æµ¶p 4ŒEV¥Å8±^aLg7܈­>”,ȈԂq*È­…µ6=…Ä1@•ˆjÑÑTIHiÓ« Ñ5r#¶òÝ,Ù½ÒÒjIæ²®“#ºR|)#+ Õª,Ñ_£7)I!Ô¼ë6+)ià;ÚåôØìWà+x@1+HÄJ\sØëg9­-ɈԄ¡Gb5$œJ‰*Ø[Jǰ¸…ت· MBB!Ú•ŠZ¦CfIºD¬Ö=jbÌDv.úSòJØP @ ¦Ä´ètX‘äÔ*Í?7rˆŸ;ŒìË˳‘öòsmº‹†Â1‘!Q$ÒOE)-,ˆøK2[#°Ìõ•§þQâ-쉟®gç[ûÄæ~u¿¼CŒ:ÊÓÿ(ñG–ÎöC¬­?òylïd2;?\Ïη÷ˆ5Ìüëx‡u•§þQâ-ì‡YZå(òÙÞÈdv~¹Ÿoïk™ùÖþñ0ë+Oü£Å[;Ù²´ÿÊë®IJ²MH+$”›™¨½ÑX½‘§á(ÒkÅN]d›"šôø3 9šKhZÌ–YˆÐ_¢q&ešÊNÂ2Ú<ÐçPÝ¥¹C¨¿QD6&9&¶#!NwiJTKhÜ"Ïbû“#÷Wn ¡¦ºÑÈ:Œj\:<šl][yåk›u&µ‘­]Óî.ÄgÀIÿÄS9CT£S‘C:½"¨üÖZ’ˆÒüBahZÒµ ÊËY)&M¯mÈöpmê­.}/rîæ5;®2%1Ý¥YÚ]ò«a¯cØ{FBê[x¥Kué…Q‘:<†’˜é6r´‡Se/9(ŒõÊ=‰?p_+¹ÇÕw«ýz÷oú²7VéËïûsäËüŽ _o ÄÆGsu-|SCÿyÀhmAªú–¾)¡ÿ¼à46 ´±?ýQÕÿR0Óùÿê‹þ¯úù€‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'¡ÎÝ?þÏüÂ$%º:þýŸù…#ªeóšw¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<é÷ѧT:°V‹Ag ªY´IÎñÔ‰µ›’u'b²KeϾ$½¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:s¶ÒG"?z—@¶’9ûÔºÌ`§;m$r#÷©tÛi#‘½K Æ:iΫœA¡xé>ßRèG2€ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰èC³„·G_Ïÿ³ÿ0‰ nŽ¿ŸÿgþaHê™|æï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##Sç­:@î¢Ñêõ¹J‰F¥N©HB Å5:ÞY ŒˆÔd’3µÌŠÿ¬€x@I{cÞDb_5?ì‡cì{ÈŒKæ§ý ^ÇØ÷‘—ÍOû!Øûò#ù©ÿdh—±ö=äF%óSþÈv>ǼˆÄ¾jÙ%ì}y‰|Ôÿ²±ï"1/šŸö@F€I{cÞDb_5?ì‡cì{ÈŒKæ§ý ^ÇØ÷‘—ÍOû!Øûò#ù©ÿdh—±ö=äF%óSþȵ/ãX‘]—/âñÙBœu×i¯%  Šæ¥¦ÄDEs3ŠÅŸIû™žâÏ€$ýL„éê5øß_ÕoúHXnž£_õýVÿ¤Їg nŽ¿ŸÿgþaÝ?þÏü‘Õ2ùÍ;ÞôÛœ"I;ÞôÛœ#õ-ïGŒ³®yëf(P¬Å 7¨ZžŠ-¨\P¶¡…¨u…µ +P¡Cúð Å+1AŒ›«B“ŠŒR3®&/ðìoµè˜œˆ6øv7ÚôLNFF§ÏZt€vu™–’ªÆGc*Ö?í˜LnΣŒš¿ÔO:^÷Ï9÷Œy)U†j±W&ÇiŒ¥wI³Œº¦œMŽÜ BŠük•ÊÆ/y@­¹„áÔè³èùJ«P•qÓ}©(‘)×Û³¨I¶ƒ³¤“ΤØÈûÛEO(Õ†kxUztÇ…:;rc»Ý';kI)*²¬er2;^½ïžsïçÖ(4z]n-ayõÙì G†„„ä¢jB-'l„zµ™¤òºv$Ù]Òo·?R¤¼—)ÐjX‰HÃqc°qb®V¦¤œû¡WA©ÅÝœ¯R,Šî‹¾7×ÞÄXB‹ˆ29|éìLÔëMz­ki^\Ö+Û5¯b½¸zÚ¬2íbM!9±£µ%æ»®å·TâP«ðÍ— Äw,»mr¾ˆ“Hœ¼!ƒiU&‡VÆ‚Ñ9;J©š$yVÊ[C¦+‰²LÜY¤Ï1Ë&É(í1ŒhµÌE†]ßÚ†¥T]¤©N75¶ä¢u쇩pЦyÍ&¢"NÛ‹^÷Ï9÷Œ5ï|óŸxÆŒÑm· QÞª‘±X`Þ߇™ÃRTÃSk#×N[êiäk2­9RgrIPW"œc3i#bŽŠ•.="¥¬Kìë#ëTì,‰Ye32' ’®†d]ÍÈ'z÷¾yϼa¯{çœûÆ4cT Ùirg‘µRëƒt31¬5!çÕ ]t·»Éòe jl…!I+wVB•e§ÀƒMr±‡j ÄÊ©Kqº±ÃqME)fÊJE² £m«ß9_/ò-•¯{çœûÆ÷¾yϼcLèöäjæ6pýN!‹®ëª¢ôGD˲´ªï(²ÈÌù¶´e5eJOÜð 4l ‘¢<Nág”Ú›€æ(ˆÜ5.T¦Óe‘ÖÈµŽ“o-m™’•&Û ­B¯½SªW¡dq­è¨"}i«[š3测/¿å¶ßs{í±F4÷"Gc:š5îå[N%iÎvQj–v>=¤GýD,èb 0“‹u›"½®ƒTe°fÖ㊜ÈBˆ(Ì•&Å–ÙlF“"ýÓçŵCÿ-Ïิ¸ÈE@ŠÅŸIû™žâÏ€$ýL„éê5øß_ÕoúHXnž£_õýVÿ¤Їg nŽ¿ŸÿgþaÝ?þÏü‘Õ2ùÍ;ÞôÛœ"I;ÞôÛœ#õ-ïGŒ³®yëf(P¬Å 7¨ZžŠ-¨\P¶¡…¨u…µ +P¡Cúð Å+1AŒ›«B“ŠŒR3®&/ðìoµè˜œˆ6øv7ÚôLNFF§ÏZt€eõ;c . ŵZµmå6Ó´‡c²ImJ5º§Z2OrGb²Tw>.ùØZ¬ìý„ø¿‹Ñgì'Åü^ˆr˜ í„åÔ-i³5X“WC›&;Qžw;ÝÓm)Å!6ÕØ¬o8w"¹æÛ{½}Ÿ°Ÿñz!Ê``Ë«;?a>/âôAÙû ñ¢¦¶ º³³öâþ/DŸ°Ÿñz!Ê``Ë«;?a>/âôAÙû ñ¢¦¶ º³³öâþ/DŸ°Ÿñz!Ê``Ë«;?a>/âôB7¤/aŒM„&Ò£»ªym9«î\<Ê6Ô’-¨"-ªá¸çp¶ €%ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰èC³„·G_Ïÿ³ÿ0‰ nŽ¿ŸÿgþaHê™|æï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##Sç­:@¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëùÿöæ!-Ñ×óÿìÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|õ çH;ÚV Àí>¦Óð¹‘[†’Ïû£‚GÑ:‡úâÿ«þ„+Raë;r y¥Ÿd:ÎÁ†ÂÞigÙÜgC¢Wô§†¡×©ú¤fè•WRÔØÈy Y?O"QˆÈŽÆe~¦#sf?DÜt-d•:á(ÒÙíQå#U‹‡añ‹`,„ìTuÇÖï]ø}7fâÔd™ïÙòe͹òû­—½¿X‡‹§G¨ãÌO‡¡a*ZªU £°ãKC®“ÚÓ–“%~‘Å6F¬¦“ÊH¶sÚEtž? ®±‰0ÁaHÕ $¨S[•£yDÚZ‰¯nåJBÿQ‡ß1Hªq™Jh·ˆš¬MÄ•çk†¤E8ñ©ò˜`¥Ibg#Qgqƒ3&ó,•{¸,ÌWL–gð M‰µ‡æHª%µÔ&GDgd²n¶›!Õ©eÝ8“Z­˜.ܧfÿØj±z l=9†¥IÜÑÖâRëÙ z´™ØÕ”¶‹m‹„JáVêuÌ5‰£Tå.Dh°[“…èã/u°ßè“À‚ÈâÊɱXÇ‹E¿IXiÈï8ÊΩ³Ri3JœJT›—xÒfF]ò3!9å(xhTEÕ‘)ÚŒlHëm§$K5ä%¹˜Ð›!*U̳à±NæCÎä#×ÕM•Q¹Ú”l;6=Þk)/)º‹XÖ›wEnf¯NÑ¥iº}Vt4ZM,H[dd¶eg+ÿ+"/Ç•7à!äÑcïÇÒVr;Î2³ªGlÔ…LÒ§•&åÞ4™‘—|ŒÈ3<ÆšsîÑeU’¦ÉˆÒYŽ´™žcS©uI2+ZÖeWÛß.¶óÆmIi§n:²Jp”ilŒö¨ò‘ªÅðŒøˆÄ» Vk´ÝÖGªÔ¡¨ªðr”Y lû¶¥­”ËÝ¿Tñ‰ÎL¤M}’òe%Åäñ8K¿ušûs^÷¾Û‰‰ç"õrœýµ:“%M­øR\Žâ›34š£I™‘®\DâHà%çBU›„ÎûvŒVreÓ—×bžŠ£«y†)tÔ¾nÙfÙ¥ÅæÚ™¨¬w±fÛX«—1³ʉˆ1ÁB**$jÆçEJ˜”›ËZù!¬¹’zµ’všL¬m¤¶ÜˆâzEÝ}wJTåÅqõ4ÂÈíIp”Vh=©ZˆÉJ/”jfD|d¥8æz¶‰QͶ&7Æ;­jMÄ-h_¹Êi=ZËÝ^å´¬dbK ¡\¤Q0â°³Ò™\Âstnb;¿$žZI¥ÛÝ‘6MC¹wfvÚbÍMÇÝíÙQãF}xŠ"f5µM¨Ñ:éEŒË)±žËm0Ü"6~ë©öFëo;Ýjë²îK£o}½ÿ/¹¾¯»Öpßmî0­âÕ3F”TÓêr¢­5YèmÖ4¸Ú ¸ªÈ…Ô¤Ôµ(ÒV#=¦#tˆP —¡«TgHS¬ËgbÚG ×äPê¨B&GKjq)32"Z´ð‘ì¢Øe°b†ÊêŸøóÄ_ü·þÕ¡­D€ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰èC³„·G_Ïÿ³ÿ0‰ nŽ¿ŸÿgþaHê™|æï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##Sç­:@ßu¼MC‹U~;ÓÒN6¢JÉ(RˆŽÅr¹•Ëö³ˆ$hïˆ)ôš¾çͨÝÔÝ~«5³e΃µò¦öá±qC5lÍ9ªk-Ân+CGD&¤,–…%$›¥I%—‘m!ÃÀ#jríÚÕCV̓­F§T·:³±ºéæö©\ĩ±ì-¤1sØÀ•L[.½Y:}Q.‰˜òé†é0¦½bMI=§º-°ŠÙ8Nû8Øi—tÌĘVl7¡L̘¯¶¦žeØËZBŠÊJ’i±‘‘™±Y«àšÔƒYD*”E(Ø—Ýl̸*’d8ti—mÌ—£é”v¨ÒáRäS¶®´ìì"ÜA£)[è ¬½UZŠÕR.spÌŽ2dÓµ„Á•­”ƒËÀ\C‰6™wJ1&DÇ&"C)’ëhiÇŠ2ÉkB F„š²ÜÈk2.öeq˜ÇÇ‘£¸õeUãÓé,Ԗ鼩h¦åyNT“Y¬‘›6U¨¯{ÙF]óL´Ë»úîÃÞ0ü=‘ÆÚRÿnê?Ù 2b0ägß‹%©1žq‡ÙY8Û¨Ò¤(Žä¢2ÚFG¶âØ BAׯ5å† ó“ÞÐÂÄ•*¦ìI/GqHSf¦–i3JˆÉI¹wŒŒÈ˾F,€ŒD ð&L)àJ~$„{‡Ypдý[Hz·ö·¾é¬oÍG|’FI™ºW®+‘‘ÙwÍÀf\<1À' Ír´ÎïÔÖ* ï÷vY+-Õ{ßY·»¾e{«û£ãzté´ÙͧL‘SwÈó›kMÈÈì¢22¹—ÐcΔoâãLŒÝz¨†&­nKm2Ü$ÈRÊËRÊöQ¨¶ïß:té´ÙͧL‘SwÈó›kMÈÈì¢22¹—ÐcÎ1!»[…:DèuŠŒyrLÍ÷Ú’´8é™ÜÍJ#º®{v#2d±1ër[pCÈY’Ò²;’‰E´Žûn-œ £X³Uz¬Õz¨ÝEôjÝ–™nÎ'gr¥ß1—r†}ââ Vë0!» ^¡+×ֲ̕¡ ¾Îé$v?ëˆFñ!n¦íQºõQÞ"K²“-ÂuÂ"""Rïs±Óï sï;!õ¾û«u×jZÖ£R”gÂfgÂb€ m6±V¦4óTÚ¤èM¾Vu1ä)²p¸”I2¿õƪµF©ORZ©LnœúõŽÄKê&\VÎéH¾S>å;L»ÅÄ<`ýú¬ïVôï´ýïð]нO ýÅíûÕjR™¤»R˜å9…눧Ôl¶­½ÒQ|¤}Ò¶‘wÏŒxÀ0=óëuš„öªêóåÌd‰-H~JÖâŒÌˆ”gr±™žÎ3Ôëj¤†äÔª“¦¾ÙYH§Ÿ Ôfd<@îªÖjõmVúÕgOÕ›Ý2æBâ,ÆvyRåKÕn©/?©hškXá«" )¿K¼E°Y8\+ˆªø^¬š­RcLBr¥Å2‡HŠä~åde{‘í²ÂkÙßJܪýߣÔd±Ez«‰«²+•É[®¡'.¹íZQ›*I îRDEܤ‹aw†4b±gÀ~ǦB'¸³à ?cÓ!½z‡c5/MÆËÙõgI”£ÈdGÜ’UÂd|CE óÔ,´7§¸â’„&‹4Ô¥ˆˆ[LDíÝí¥üÜÎ}>Àµ£Ú®³Hx§2Æ®%:ŸN…­yœZÞT¢Ü‹)H±Z÷Í´îDZƽ¢Vt¥Ë~Èh³¿ F¢Käe‘Õ•øKmËG”Ï€óNtVóO雺èuµRhÖRFGÝÎï¬%¢ð–…ÙÅ”EÕÙ—Dƒs¦Gn;”éO))fK¬‘šÊbÌÉ»ìIpyõ3Å>­Í?>6vƒ>/õµWÿÌdŒ. L¼C.|ªN1âkufФítÕN$"\†ÐÌr¸”¥²-FÅl,ÃOÇ|§1‰Ô×þu}Õš)ŸRÚËÆ´4Ìüøüíd‡ãJšf~|gjúRÄ‘¦ÒÑÚlæ*ÒN;k†ª5¸S™Ûy%–iemEfÉw%lI(Ë>Æ2ų)ôxñ!EP›_],äÔ)R¢´ë)†ì{l:it½Á')™‘šVD­¤¢ç>V×Ï[õýS÷NÚ{5ìÞ¦ÚT(oÌ›\Ãq£0Úyçi“†Ð’º”¥û™™ð ½¬P|g@óLßωV•ªØ²vÇð£½CÜ´jC°êägä·W .¸¶¿HdÊI/'*U¬3225ÏKÄ•+UŠ]"&=BV'j–Ä—VCÿ³’§Ÿ$¨Å’¤7$¶›•®)>QÖO[µ}S÷6Çf¶í`ã:šfþ|~Rý?ÆT5MüøÜZ?¬Vêob(Uýî9TŠ®áCP´!Ônh¥(ÍãÙ}› m®r‘Îuº™ër¯æSˆsŸjõ;ÆT5Müøüí\§xÊæ©¿Ÿ“©½=kŸæLCœ»W)¾1 yªoçÇçjÝ3Æ45Müøèà›×'û§ù0çh½LPb¾—Ø©ÐâocÞ™§k•»óÇ»µá~; yš_ç†ûIª©ë#Bv¼/Çt3Küðv¼/Çt3Küðß`#2–„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘Ïòúœ*:£È¬ÐÚ­™;Ï,¯c¿zpÇö¬R¼a@ó\ßÏŽÌŽoíX¥xÂæ¹¿ŸÕŠWŒ(k›ùñÒ‘Íý«¯P<×7óáÚ±Jñ…Ís>:@29¿µb•ã šæþ|;V)^0 y®oçÇHfG7ö¬R¼a@ó\ßχjÅ+Æ5Íüøé ÈæþÕŠWŒ(k›ùðíX¥xÂæ¹¿Ÿ ™Ã©ß Öñ>+‰In•NƒE¬ªšÊ%G™%× ,2æu-2Û+þ–Ö$÷†b‡ ê~%Ø5<(ã¯1¨ÔŒ+"¢Y©+"SnKq$y“#±͇Â6^¨um*KA©ŒM!Äß‚éƒÿý®§6DJœZlµ¶n”vRJÒŸUˆŠåßR”EsµÎö½Œxuººìb(§3,í~¶­>"Šs2ƒÓtfU­PßÑc¦ƒ²ÓØâ:TŽ,É7ˆËúÈlÍ`Y˜}oP ÂÝŸö{ F¦gËŸßv¹¬¶nçƒ-ÕÛdN²¨øoQ ÓÜS²˜uˆ“ßΣ):´¥Ý†{F«‘¤†æÂ_Î~Çÿ¨ôiïMØœõŽR樂7iœÇ8å-S Ï‹Ä}mUÿó"[J§B¥E\h êZ\‡¤©9WqçT늹™ð­j;pìV+“`ŠU26¥"=6)\T<¢m„¤”µ–u¬ì[T¥)J3á333Úc3¸¡ø#ÙØzZ‚>ŽðŒxëŽÝ5íQ¤’Ò9õb%ˆ˜ºÏQc"?Ñeà." ~¡ÁL"f3ë\)ŠšË¯Ëyç5êelšÔµ¨Ô³Õ­IîŒö[ˆ­³÷?c› ÜPüŽl„àjLQ€°®&zKµšs¯œ¶I‰HncÌ¢BŒ‹X†Ö”¬ÓsÊj#4챕ˆ~âŒ+ u"¨ˆtèÏL-©Ë×Êy’SèCm’ÉÖÏ;*Õ´”’‘Àe{ÎûkqCðF9² ÅÁæÈ04þŒ0³Ø^—QL”°Üš•Asži‰>†Ôm¶ÙµÞíÃÊÒMKQšGa,MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#ÙÀ…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A¦0hwé-§RKBñcÉRO€ÈáD¹ÈÍã<)=J¡3¾°ÕÀƒuf]ìäµ$³Ê#Ûn÷ÚR™MDYÒOˆ—¥T¥»!Âe$§VO)¥®£Ê„&çÞIÌn(~Ç6CË4ÜÄÏXq»b›¸™ë%¢pžª½]EsZ6œ7Zœ–µºwîÜ2ºv\̈ŒöØîV±î %üçìúŒ¶â‡àŒsd.2Ë,ßTÓm߇*H®&ͪmF)M«TÚ§m/ÿÙxymon-4.3.30/docs/critview-disk.jpg0000664000076400007640000013560511070452713017433 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀÙý"ÿÄ ÿÄe  !1AQUÓ"2S“•Ô37TVWu’–²ÑÒ#Ba”¥45q $%Rbt‚…‘±³rsvƒ¡£¦´Á6CDdw„ðEHµÂĆÿÄÿÄ91Q‘!RÑ3ASa±ð"q¡2BCÁáb’ÂñcÿÚ ?ôôùrÓ:BS)ä¤Q‡b+˜øqÙŸÒT¬$ÿΫýæ*Uæ¾*ª{ŠÂu^/_‹þžö™±tÀ„¯Ñ'‹®úo©?¤GŒgäùG­+9œQê›Ö+*zKíÈq´´ê–FQÜCO¢ñHÐã‰I¤Î÷¹[aÛaÇf|mÿHb—^#ª·U,@´r„êu'ñv´p…¥ ·d‘~«hM÷žó¹íÅxâÄUŸ©hN™T‰.¡É—D–Fƒaœ^¶QŸé VÒ’5«»øìÏ¿é 8ìÏ¿é iðü„&ÝN³"­%kÖ§]i¦É"-KiMFFe«R¶Ô{-±¾üvgÆßô†vgÆßô†<ýŽ(ˬf-YŒ-B|ãÔÙ%×”éò•9N†jq„WWFn©¹Ü´Ÿënñ~/Æ Ä•òÃÍTŒ†,.œ˜rR¶Pé®Bä:—Ij4›""ÐguÒD-ÊÍx¨ôyµzEö!AŽä™êZ´6„š”«&æv"3±˜ú±V[îÈiŠšr3„ÓéCú¥šR²JˆÅ=+J¬|Ê#Üd)Œå¨Õgá|Êlñ1RbQéÊŠˆ F™hv"VkZ–“_ާÒ4)$Jlï«i åcWX©Ò«r{nâ¶)-M&[5CaTÆd™'RM&¥:jAÉ[]-‡b ‡™ñ·ý!‡™ñ·ý!ŠRN.ÅiÕx Ö$ÖÞo"ŠÔè¬ÄCì±ÄZxȸCCç ©^ÍK;'É@ÍXÆò£QiÔ¥Ò%HÄîS—%öá=-q žôÒ%“q”;©$EklJTi²&÷™ñ·ý!‡™ñ·ý!Œ8M8Ä6XvK²œm´¡OºI%ºdV5¨IMÏyé"-»‹`ùV)ñ*Ô™t¹íÑ%²¶Aþ²FF_ì0KcÇf|mÿHc嬹m)ص5Hm.-£SOê"ZhZnG½*J’eÌdd{HU¥>mz“/'¾§j¥)pënnRáÇÐ¥ºóè[ ÿ¯U¼‘ð›\Åòé_…P—Á7T­7)4â„™¦ÔyÎ4Ï™%Á©´!6_뉶æw!oqÙŸÒqÙŸÒÓáyÍÕ0Õ.¦Ô®6ܸl¾—ø.…% ”KÑú·½íÍ{ ˆ¿™ñ·ý!ŽgæC‹ò‚ª²8V^’¾,d| èá]V¥¦éO‰Ô£¾ÄŒqQ(ôŒBÎ#ŸU¢Ñ+ø–%VK\^²þ„Da/1¥Z6Rlhp(ñ”£3=¦e¦Ä5f1ÃnF‰P.´Ô6"Óåq*Ðã¯ÔD¢-&›£JüE«Æ+éÇf|mÿHc_\ŨäʪVU¸ÐÞšáªRøH× u(“©7±”’Þd+ìiQ•‰û™ju¥:¸r*8Isœâ䓱®/¦ËY+ÅUÍ'Ïc;Œ°snENŸ…j”+RªqŸÁù/½%¶IÇÜl£j3iIiKÎ$‰$Dde{™\¿Çf|mÿHaÇf|mÿHcàûñÙŸÒqÙŸÒóv ¢.™‚²æ°œ…(‰}t‚Uf›$΢ÿ ÁÑÀ7~Ì’áp‹²V³ñ­qÝ{£¯q¾[÷@Z=Ôr/!p hà¸×«Vž…Ñýñ}Ztþ­¶‰B×ã³>6ÿ¤0ã³>6ÿ¤1OUq"²kmâÒ†G‹Ø¢ò?`Ðlqô0eu$ÜáÕܾ«±%±Eü¿QÆÇ‡ßÄlbõ¥GŠ]¤³ tö,*ª¨I5Y$â–„™(Œ–DzHŒŒîf™ñ·ý!‡™ñ·ý!Šº£[¬a·±-.£‰eÍDH”Ù1f¹…HJ¥HyŽ’‚m³3S)$)Ed›—V¢NÞEŒM˜Nã †jN/6âCD–‰LÐøß£2R]>šSI"AéA%Âá Q¤ ¿øìÏ¿é bÑ«ÅX£Â«Óª/¿ tväÇwRÓ­µ¤”•YV2¹ŒˆÅ‡jŸãè“ZU*#~•R“#¼—$>äž)¥wlÉ’Iè=¤DiQm3䲟W•íÊ3(Îaì$ðè|“Ò˜‰R$©fW4(Ó¥)lÊÇrQš¼T…ïÇf|mÿHaÇf|mÿHb,WŽ!á\EQyú–„áY•H’ê™tIih6Åëhõþ•m)#Qê°µðü„&ÝN³"­%kÖ§]i¦É"-KiMFFe«R¶Ô{,Ž;3ãoúC;3ãoúCTR¨<5ñUSÜVªñzü_ð¤÷´Í‹¦%~‰<]wÓ}Iý"ÏÄìýö^üÞ`ϳñ;0KoÊÔ®³…éÓø‡+RºÎ§Oâ5ï²÷æó}Ÿ‰Ù‡{ì½ù¼ÁŸgâv`52hŒ¹:¡&6eÔ¡"{êyæXn— ÌÒI"3TSR¬„¡k5”¤ŒÎÃ`š>r5-ºƒ4 “Ô¶f,™LF7$t¤’ײ $\ÄE°}»ßeïÍæ û?³÷Ù{óyƒ>ÏÄìÀMf­ILªÄ,9Q} )”»-¦]Z[Q)j#=&Fw-ÇsÆ#AªQj0—@iÉëKªLv¤4òÒH"7[3.Åm(Údv"±•Šß×{ì½ù¼ÁŸgâvaÞû/~o0gÙø˜ f aš.H›2…Pn£ äLiÚf*BJÅÔIBPÚDf¯&æff74øø:,Z{4lCtÞŒÓ i´°á¥H5 ‹bTiZ“rÛes˜ø÷¾Ëß›Ìö~'fï²÷æó}Ÿ‰Ù€Ûòµ+¬áztþ#å6£N~Ì5\b#Ž6¤%öžhÖÑ™X–’Y)7-娌¶m#-ƒ[Þû/~o0gÙø˜w¾Ëß›Ìö~'fBÞaº“µ&óF¬‰Ï6–’–)ëˆMÍ)R¸¥ÌŠçb3Ùsú?T¢"F™.BY}¦\B]Zkp’ddJR”¥ï333Úb;ßeïÍæ û?³÷Ù{óyƒ>ÏÄìÀm›ªRBPŠŒ¡$D”¥ätÑ<­Jë8^?ˆÔw¾Ëß›Ìö~'fï²÷æó}Ÿ‰Ù€äëX …[–ÔºÎ<‘RÑY·eÁ£<´ì5C3!Ò7GÂD€ÝrE'Ê~/6¤ÌE<å§B”Ûa”–Â+ÜöŒŽ÷Ù{óyƒ>ÏÄìýö^üÞ`ϳñ;0C=‰uŠr)¬?Jj l“Œ…¶M%²-$‚Il$‘lµ­mƒ < žšs°ëP‘èÉŽ†™Kieã%:Ù$ŠÄ…™©;”dW¸ù?€òå†}ܾÁ‰m´šÔ~ç∊çÿ»O/w6ùŒ­õ\.Ì´9Z•Öp½:ò›Q§? æ®1ÇRûO4kh̬KI,”›–òÔF[6‘–ÁZr÷so˜ÊßUÂì×»›|ÆVú®fëGË<)Fœ‰ôŒ`Téh¾‡âÓ(8›ï²“Œ‡uÅðw.rïAåm:8ö†¸Æ›ZÜ'•klµÇËÝ;c+}W ³^îmó[ê¸]˜ Õs Ñ*øÑšìоK-ÈbJ‰)«S&•!+]ø=hJôé¾Ëj¶ÁÕëÃWŠë£ñ~1Æx+·£†áx^Ûµðž>­ú¼mûEuËÝ;c+}W ³^îmó[ê¸]˜ b°¼Î3ÆÎ#²–$ð¦Úøf’j4¡wò’Fµ™ì-Jé1¯v‹—®ÒØ¥9IÂ˧ÆY¸ÄUG`ÙiG½IE¬“ý¤C‹åîæß1•¾«…Ù‡/w6ùŒ­õ\.Ì’Ĭ<Ä…HbE-§–ÒSˆ[d£m£B Ën”š×bÜZ•mæ>,aP”ÁQZ8 ›Íx³fDZ·›%%b±X‹ Wœ½ÜÛæ2·Õp»0åîæß1•¾«…Ù€î"RðDNDJvŽš‚ÜÔ´Ã ))Q).X¼r23¹ïq¸åjWYÂôéüE_ËÝ;c+}W ³^îmó[ê¸]˜ C•©]g Ó§ñ&&ÐXvC¬K¦´ä— ×Ô‡“ud” ”£/(ô¡)¹ó$‹q­9{¹·ÌeoªávaËÝ;c+}W ³šö ½VU]Üxû•%© Tµ@¢›Æ¤(”ƒ5ñ=WJ’“-» $e¸wðÇâºèü_Œqž íèá¸^„¶í|'«~¯~Ñ]r÷so˜ÊßUÂì×»›|ÆVú®fÃ2†–ReE4±%RÙ/ÑY·Ô¥)N§¡f¥¬ÍE´ÍF|æ>Tø¸2¤©ñ¨4ÊTÂàÊ,úhS»?\Ðf“Vó#2½‡ËÝ;c+}W ³^îmó[ê¸]˜þ |©&«Š Z„¿é™CHuí·ñÖ[U·¤ÇÙ¥á†X‚ÃK£¶Õ>ÜI´›d˜ÖA¶\~¥¥'e¼Un1]r÷so˜ÊßUÂì×»›|ÆVú®f½Ŭ»Z±TxŒšÛl¥÷/¿RËÆ?Þc:Ú (lÇ.›3 ¥¦YiÄ! ¡%d¥)-„DDDD[…iËÝ;c+}W ³^îmó[ê¸]˜ C•©]g Ó§ñÍV™]vMZbN¥9!¶ÚSqM2$"úS©ØëpÈKU”£±­V±‡+ËÝ;c+}W ³^îmó[ê¸]˜ ä,9>#§ÕdcÅT›‹1sÜn[P·deÆJõ°Û[špÈõÌô7cI$É[Æ)x „ÎKì4ÒjÓI 0E'Ÿô–/÷Üpü½ÜÛæ2·Õp»0åîæß1•¾«…Ù€ïéì`êth±©ìÐb1 Óv3L%¤%…šTƒR¶%F•©7-¶Q—9V `ü!E§E†åê1©ìB‘Qi¦™zQ4ÚS©fFg·Mìfvé1Êò÷so˜ÊßUÂì×»›|ÆVú®fÐåjWYÂôéüC•©]g Ó§ñ/w6ùŒ­õ\.Ì9{¹·Ìeoªáv`-V¥uœ/NŸÄ9Z•Öp½:Wò÷so˜ÊßUÂì×»›|ÆVú®fÐåjWYÂôéüC•©]g Ó§ñ/w6ùŒ­õ\.Ì9{¹·Ìeoªáv`-V¥uœ/NŸÄ9Z•Öp½:Wò÷so˜ÊßUÂì×»›|ÆVú®fÐåjWYÂôéüC•©]g Ó§ñ/w6ùŒ­õ\.Ì9{¹·Ìeoªáv`-V¥uœ/NŸÄ9Z•Öp½:Wò÷so˜ÊßUÂì×»›|ÆVú®fÐåjWYÂôéüC•©]g Ó§ñ/w6ùŒ­õ\.Ìn0œlŽÅ•ES0Ö˪´Ä4§–ÔZ45šMˆÖ«7⤌Ȯv+™ó Ç+RºÎ§Oâ­Jë8^?ˆ×÷³À_7øÔð Á­à¬±¢ÄnUKàVvK1[2¡ÃY©×œKM¤‰-™Ö´–ëÓ;“}ÊÔ®³…éÓø‡+RºÎ§Oâ5ï²÷æó}Ÿ‰Ù‡{ì½ù¼ÁŸgâv`6ü­Jë8^?ˆrµ+¬áztþ#QÞû/~o0gÙø˜w¾Ëß›Ìö~'foÊÔ®³…éÓø‡+RºÎ§Oâ5ï²÷æó}Ÿ‰Ù‡{ì½ù¼ÁŸgâv`6ü­Jë8^?ˆrµ+¬áztþ#QÞû/~o0gÙø˜w¾Ëß›Ìö~'foÊÔ®³…éÓø‡+RºÎ§Oâ4¯à<¹a‡w/°b[m&µ¹ø‡b"¹ÿîÇËÝ;c+}W ³hrµ+¬áztþ!ÊÔ®³…éÓøŠ¿—»›|ÆVú®f½ÜÛæ2·Õp»0‡+RºÎ§Oâ­Jë8^?ˆ«ù{¹·ÌeoªávaËÝ;c+}W ³hrµ+¬áztþ!ÊÔ®³…éÓøŠ¿—»›|ÆVú®f½ÜÛæ2·Õp»0‡+RºÎ§Oâ­Jë8^?ˆ«ù{¹·ÌeoªávaËÝ;c+}W ³hrµ+¬áztþ!ÊÔ®³…éÓøŠ¿—»›|ÆVú®f½ÜÛæ2·Õp»0‡+RºÎ§Oâ­Jë8^?ˆ«ù{¹·ÌeoªávaËÝ;c+}W ³hrµ+¬áztþ!ÊÔ®³…éÓøŠ¿—»›|ÆVú®f½ÜÛæ2·Õp»0‡+RºÎ§Oâ­Jë8^?ˆ«ù{¹·ÌeoªávaËÝ;c+}W ³hrµ+¬áztþ#Tª…“ŽT!p‰#$¬¤$”›ó–ÝåÍÐ+~^îmó[ê¸]˜r÷so˜ÊßUÂìÀX… p•8O¸Ñ™¥j}%kó_w?öÜÇ—;¾dG“XÂNF}§Qä‘©µ’ˆS{6 Æ„þ@×j¬R¨´|·¨Ï~üxÔhn8»$Ô£$“w±$ŒÌùˆŒÏa »¢‰B¡Õp«,?E£¶ãVáS©ÌÆáSdZ¸4–«s^ö¹Ûy‰Žh{F£ýa'þu_ï1ËUêÕ p¦JUÅÚvÒMÉçR“³M$¼³ÔV5n-ŨîEÒW£¢S“â¸jJ7Q¤ìdGr;1ŠïÔ&áØ f¤Ñ,2eöRHmä¥;b+6½›­cÞžt—/ÄïÞ³o6ãËë=¯âopöµQ_YéûêëãÖâ)è±ßD¸ïÉV†Éèo6•,’j4’”’+Ù*=üÃf8 M¶uºtç™eÚ’R|hÖv&ÜA„ùËïæÔØíˆôWTê[yµ6£iÕ4²#+¥h2ROnÅ$ÈËy±Â\½rŒÞ§•žõû¶æ«ôéœòüQñ—%˜Œï¨Ò‚RS±&£3Q‘Ó¹™ær×»ƒ©ÒãÉÅ8‡H“!Nqš¼å¾¦Û#> ´¤ÌÒ›$üe­W3±iJwÕè¯Ì¦)˜Ú8Rq·KQ‘‡«\ˆíäô k¬IµK”×JÒÚ[Zœ)ÖÚV« ’J"±™¶•÷m!°§Ífkj6õ!ÆÏK­,¬¶ÕÐeÿ®ãÞCŒœR©O0̶’Ù¼•|¦á¨Òi#+i#¿Œ[†ûÁ•ÆJ£/ôJàÍ´4V3$Þþ1óŸý…ÍÎg3¾ðŸ3!»O>É8›pŒ¸hZO˜ÈËqÿøw!ð¡ÀU6œÜW&IšémqçÜ5)jçµÌì]_öÌñ]©F£ÑåÕ%™“YS«¶ó"-ÅûOp®©Ø²¥Yu§Ú¯ÉŠO9Á¶†a¥1”ç›JÝdõöye«˜‹qu¹€¤ª JLh²¥š$©DÑ‘¡,ºáð‰RHµ!'{sF­BTqŸLЬv•ÓÙSÍÆTw¬d¥š›J6Xù¯²û6ìú_áhø?ª"©™úôååÎò|ïŠñSñ¢Ô\š1–çýF¨ÖäbZ”*¬È²D(ï°–6É–ò{™Ïƒ#=¦E¸ºO«fVAZiÏU¤µ¦L¥h%Î9©”¨ôXÖff[Td{/ªö!ÙŽG‰hÜÕã§Ò"'—âëpsoOÄœÌùçúÎZYS'L’ãÒt‰’Y«ƒJMkÒvQÙD{ön¹ží›ñ›©T p2*2ã>“RxD ŒÒ[Ô$[º ¶–Òý¿Ã•*¸§ä°óŠinºÊUµš–f“¿ø¾5ŽÛHùŒn.!˜uÉ,¼ˆÏ51l©§£ºv±/´‹mÏ÷o3ÛS n¼ŒŒˆËiá‰VžÝ>2\RãŽ8–™i; Çä¦ç°¿´÷ –ÒÊ{ ’DìüO™´g#ÉŒr£›-æ‹zЗ¥m-¶#ꊪŒS8”ÄÄyËG]¨T Ã'9Ye9Û¥¦Ò–‰„ªûLõ#V„\®f¢¿ì3±l°…uuhÎFœÚXªE±Ii$d•ù."ût*Çnƒ#-ä5õSAËŠ® ¢ËntΦ¢¿6ï’7I¢Ê;ì%/aî;Ü·Œ¬92=Vm:¦nÄ‘9t¼qÆ 6Kʹ¸žIÜŠéý…Ð+p<îÌü{“]yóŸ§ô†woSr¯ä§ýÛj÷õÿóg>éŽ_báÎçŒ%¸ìé4:TH1 ÍûîGlˆŒìfHJu8â’•mÅéV“!ö¯QÏÿ6sî˜ç)tê‹ýÏ9Y[¥Æzkô }2zâ2Ù©ÇÙU=QÒEãÜ…ºII)K6‰ +¬Œ³â®]µÃÜ®Í:«Šfb:ÌDâ?9cDEUDL⤌gœSX¢Õ)•H›]ŠÍR•7ˆ*†§£7®CÙ X¦G[ˆD—˜åFXÇRæIN…)²†Å:dF Ël&—Á4v?FõŽú¬sSÃ'L‹W¤' ÍsBÆm<õ&$5­·iʦ2j&˜I~‘’˜½jmdz+Œ€Z¸†»É|9Oâ¼7-Ô—_ §ÓDv±êþ¦Û<»ßeˆk¼‘WÔþ+ÃrÝIpuðšx1$H×k¯èúm³Ë½öXéZ­¥Ñh†þ ­¿ƒÑŽW.-!çTäjw&>Ùš£kC' ÜWi+¥Ä£OŒI5R‚ʨ”3{VßÁèÇ+—Šk¦äj&>Ùš£kC' ÜWi+¥Ä£OŒI0¿d<ãOFB"<ú^tе¶h$°Z­kÔ¢3MÒIñIGu§fJ/… ©¹C[¥¿Æ T#7*+ºž§JB¬¢#+¤ÈìdGÒ* &TµÐ## Ëk ;Œe»™2 ’ˆÔåÑe2¢q•—èš[êrÈY<„Ø®D6Ù3EŸMÉŠ §á*Ä6c³Y*–x’ô¤GB_^‚[ꔢOéÉKJ´™\ÏjBÖV¿M§'6ê2ñ>©Õ'=6"ðíA¨>Ô6ÓD¤“É-1Ìž'–½FiYäŽ#ÓiѪÍ.±…ªŽbÕãØ¦³Ä\6• Uf”Áq›h6ÒÁ¶ßªä´êѳP Ú]n$ŒÈª¶õ?ŒN(,¡Ô’ÔãŠtÛlÈ›5x«Ø¢½Œ’«¬’d¢/Ž®û¨ÀôMÅx§+ÓcÎâü&¾ …i+ѪŪڭ{í¸…oƒâJ‘Šh4 ‘ž`©õ¼GˆmÖÍeTdµÌzV™+q'¸ÉeÌ0rÓ±†è?R§a·©õ•2Ë÷Ê:Ó#‚U*B”‰&e¨’—ÒÉ/bTHI[a»Æ›W}Ô`z&â¼S•é±çq~_´•èÕbÕmV½ŠöÜB¦Ë*+±q60ÍZŸ‰âpþìjÂq¦ç]‡«¾¢$É× ÚqMz“/p×dM˜òéºN ­Ð+piäœQ*m5ØÜ3\QI&–êȉåæÊ’5iA‘’-¤Õ+¾ê0=q^)ÊôØó¸¿ ¯‚áZJôj±j¶«^Å{n!ö¥VâΜºb›z%Q˜1æÊ‚ñ¹›‰A)H56jÔË©= Q£}&t~DÐY.›¤àÊÝ·žIŦÓ]Ã5Å’in¬ˆžQ¾l© #Q¶”"ÚFnJaj}ayõœ¸õy‰<õѥǖÃQ%.Î L6|"’j$¥}$°Óbï$Uðå?ŠðÜ·R\|&žLI5ÚÇ«ú>›lòï}–>/azÍuìNÆŸˆXF%qùgO¦;:#•2a$BžwÅ7 )35U­(2Ûãrbxﮇb»Cj7qÚBÓE$uáåëS~)¥¶Õ!×PK"4¥Åù&e¤Âü<â§;â<–Ò™hàÜ5ˆÐDJÕ©:HÎé"²Óc3ÔI§£3# Á¦â¬‚k Èv;Ôš­%Ö¹Iºœa÷W´Ý"ZTýÔF™ YªÉ;`ÖðN$¥Sñ]&€™OIsÑìÞFS*„÷§ÚÊF·‡Vf„­'úd•Ó¨ŒêÏ´*ú^¬WèôÙ&“6ŸS…J§a)4fÍÆ”âeßuk[®0µ Í$”™’-¨ÍC¡Ëj.0oSéøµ©RZ£0ýY–“6œ•4‘©¤+q›KTäéÞ–ÖÏH „i°õw•êøŽŸÅxD©"¾W ª$yíbÓý#M¶ù¾ÛG›N¹>“‹#áJ¥F|ª+ ‰Fªáפ¥-|<Ò‹“å²JÝYج§¤ÇÛ`V*3ƒ« ½+¥å¿‡¤ñu©ôºÕ"'¸»/«†J“vö©HÒwÓb ¼`U_üÑïÿ¨Ï_×ÿ4{ÿê"Ek[Ƙ:‡8àV±e™-)%ê-2áî=*QŒrù—X¤W0­}©§ñU!ü9 y³QNfå©&er\ãÊ\3™Ñ •`‹.©6åÇ"' ­Dkh,¯oñOis‘ü³"“N¡`¼/G¤Dn˜’ŒÓ ¶V$$¦µþÓç3=¦w32X×ĕùíÔK¢´ÒŸlÚ)º“RZSªÒÚ’Úµ¨ÿVäD[LÊå~ p8‰õP±I»(1¦ÕaTw™dѲ—Z#ÿ$ƲNó%¯cµ½]«Y£¬DÏHê¡â7ë³gU=c3Ò8º¥rQW~$؆êYyÖ¢®3ÑVfD\#JRŒŠæD{HÓr¹Zæ]ÄÙq¡BzlÉ GŒÃfã¯:¢J‚+šŒÏa8¬ó ²þ<ħä3Cí.3E¤ŽQ¶²Ò§Q‰#5m";XÌ̈v“N™TÂ2#Sãñ§Û‘QFÔIã fCn©›žÏ(4mÙãmØ5øuê®k‰«U1>SË?üWð¾&»ß5j¦'Êzõìš>3 Uª Aˆôä¼ýø“M“ØGÁ­ÆÒ•ì#?ÏafĪ~7ªRê”n-LÃð/q7[Ñ¡ÒK_¥Qšá[3sôd\*¹˜ÅMz©YÆôÑOE„N­x3hÇ*Z&2_ ë$¥9Ãp ³nl[·˜áðÃK`0+Ñ“þŸü% t úó ›IûÍsÖÿ£'ý?øKþèõæÿ6“÷›ýSô{ £ýa'þu_ï1‰%†d°¦$4‡ZYYHZnGý¤* ÜNü‡w2ñq­ÅÕ§‰$®gs±{ö¨]Í*¦£à±Þ9·6¦àöc‰áþ7cĦ¨áiª­8Î#–sÒW8Ž ®˜›ÕDg8Ìôçú½€„¥$$¬’+ 7ViWÿWã/ÞÜ>Ì|•šX›õqÞ.ýíÄìÇR&ôÿ¥WeIª×ÜŽïf€ñr³K~®;Å?½¸˜ù+4±·êã¼IûÛ‹ÙŒâ›Óþ•]˜üK^¸{IÖuh[!JEô¨Ëi_}‡Ðx‘Y¥¿W×ÿ{q»1òVif/êãºßïn?f3‹w§ý9ì‹k×pðÚ³K3?WÕÿ{lvcøVifê㺧ïmŽÌeðoz%תÝ©S Ô’ÊgEnBXtžh–W$¬ˆÈ•ý¶3ã˜|ÎÜžDט'VLú;èÿ°xÀóK5¹±ÝC÷¶Ïf?ƒÍ,ÚæÇs¿{löc}ÅѧT5W<5sš±/u¶„¶‚BIIn"Ððæ–oóc¹½¶»1üig6;“ûÛk³ö×½2ÏqkÔ÷d¸‘e ‘*;o$ŽäKIŒ|âS ÄY®4FšQï4&×<ÒÎ~lv÷ïm¾Ì=ô³¯åÛž¾Ìe´½éFâשïpï¥.ÜômöaßK:þ]¹èÛìÃi{Ònmzžær…GrIÉ]::ž3¹¬Ñ¶ÿþ ÖXeŸziæØCÁô³¯åÛž¾Ì;ég_Ë·=}˜moOÐÜZê÷mY§¥Ka¤êqÆ„•ís4™Øe¹9†²ó áÉBvM*“ Î4ㆅ­¦R…nÙŒÒv¹ð},ëùvç£o³úY×òíÏFßfÂÞò›‹]^ü›BÀÓqqÌ#†$Ö’ëo&¢ì.I-»N›Zµ'Jlw¹i+n-5ÒÇ×_äœ}ô³¯åÛž¾Ì;ég_Ë·=}˜µÿI¸µÕú9ËMt±õ×ù–šécë¯òÎ>úY×òíÏFßfô³¯åÛž¾Ì6×ý&â×Wè}Eê]Be6\ÆXuêd“• \3¥Áºl¸ÉªÄ›èÞq6;—}äFY¼´×K]~q÷Òο—nz6û0ï¥.Üômöa¶¿é7º¿Câ.‹‰ñJm*?eQâpMšx»JÓ©¶ìߊ“Ћ‘X¼TôÍ妺Xúëüƒó¾–uü»sÑ·Ù‡},ëùvç£o³ µÿI¸µÕú9ËMt±õ×ù–šécë¯òÎ>úY×òíÏFßfô³¯åÛž¾Ì6×ý&â×Wèç-5ÒÇ×_äZk¥®¿È?8ûég_Ë·=}˜wÒο—nz6û0Û_ô›‹]_£œ´×K]9i®–>ºÿ üãï¥.ÜômöaßK:þ]¹èÛìÃmÒn-u~ŽrÓ],}uþ@妺Xúëüƒó¾–uü»sÑ·Ù‡},ëùvç£o³ µÿI¸µÕú9ËMt±õ×ù–šécë¯òÎ>úY×òíÏFßfô³¯åÛž¾Ì6×ý&â×Wè¬ ôø™ƒ4±XA6Ë ’Ûi"±%)&ìDEÌCïËMt±õ×ùç},ëùvç£o³úY×òíÏFßfkþ“qk«ôs–šécë¯ò-5ÒÇ×_äœ}ô³¯åÛž¾Ì;ég_Ë·=}˜m¯úMÅ®¯ÑÎZk¥®¿È´×K]~q÷Òο—nz6û0ï¥.Üômöa¶¿é7º¿G9i®–>ºÿ ÐK¤a™x™¬G&!;=§ò Sä›êS¡.ðà¸BMˆ—§Q݃À]ô³¯åÛž¾Ì;ég_Ë·=}˜m¯úMÅ®¯ÑTϧ¦s“Ó Kq¤²·È•Â)´š(5pw4‘­FE¸GÒcïËMt±õ×ùç},ëùvç£o³úY×òíÏFßfkþ“qk«ôs–šécë¯ò-5ÒÇ×_äœ}ô³¯åÛž¾Ì;ég_Ë·=}˜m¯úMÅ®¯ÑÎZk¥®¿È´×K]~q÷Òο—nz6û0ï¥.Üômöa¶¿é7º¿G9i®–>ºÿ rÓ],}uþAùÇßK:þ]¹èÛìþ–uü»sÑ·Ù†Úÿ¤ÜZêý妺XúëüËMt±õ×ùç},ëùvç£o³úY×òíÏFßfkþ“qk«ôs–šécë¯ò-5ÒÇ×_äœ}ô³¯åÛž¾Ì;ég_Ë·=}˜m¯úMÅ®¯ÑÎZk¥®¿È´×K]~lÔó‡9iñÒóØåõ%JÒD†š3½ŒùÛýƒ]ßç7>[Mô,þAªº+¢qSe5ÓTf¦ü´×K]jñ5yq©æC¦½U’ˆêm¨QJ\yK4–Å[Mô,þ@ïó›Ÿ-fú ÇÍ—“Û^ëñ—Í=ÖtïhlU/b”Ñéç—5zkl×)ó’ýB ÐÛlÊmÅ™’5Š•n#>kwùÍÏ–Ó} ?;üæçËi¾…ŸÈ#L™~‰âC,ÈŽ¸òYiö+-§PKB‹ö¤öüðïó›Ÿ-¦ú wùÍÏ–³} ?4É8—èM6N¦4¦i”Ø0YÝH‰ ¥GûIW#ó·¿În|¶›èYüßç7>ZÍô,þAF#ˆˆ¦1Ñ ½þsså´ßBÏäÿ9¹òÖo¡gò Ó)ËôHçoœÜùk7гù¿În|µ›èYü¦L¿B*Í8ý*[ 'SŽ0´$¯k™¤È„`Ê,JfÂtZ³9P¡Q˜§ˆs¤²Fii´¹¥HJLÒji'· ¶üøïó›Ÿ-¦ú wùÍÏ–Ó} ?4Ï$UM5F*Œ¿G¸­'ã5]ÎüF Ü5ƒgÕé•j•)Š”êL‚•Oz|ÉN3¤FZ‘´ï#Ù½Hm^Sh4þw÷ùÍÏ–³} ?;üæçËY¾…ŸÈ"-ÄNb!6è£Î˜Ãôß–šécë¯ò-5ÒÇ×_ä™þsså´ßBÏäÿ9¹òÖo¡gò ¼Ùù?Mùi®–>ºÿ rÓ],}uþAù‘ßç7>[Mô,þ@ïó›Ÿ-fú yžOÓ~Zk¥®¿È´×K]~dwùÍÏ–Ó} ?;üæçËY¾…ŸÈg“ôß–šécë¯ò-5ÒÇ×_ä™þsså¬ßBÏäÿ9¹òÖo¡gò™äý7妺XúëüËMt±õ×ùæGœÜùk7гù¿În|µ›èYüæy?Mùi®–>ºÿ rÓ],}uþAù‘ßç7>ZÍô,þ@ïó›Ÿ-fú yžOÓ~Zk¥®¿È´×K]~dwùÍÏ–³} ?;üæçËY¾…ŸÈg“ôß–šécë¯ò-5ÒÇ×_ä™þsså´ßBÏäGsž7̬ÍÌ3Ã5\Ŭ@cˆ½$žŒÄsYv;YH±‘•ú9ƒÌò{¢uI™ šMl¦Ä£-&³33B’Eµ%Òq™u”G\“u‰M:ƒm+Jd¤(ÉF“Zn’32#¹•¶Žºƒ˜ñ©õ äõÀZ—Rª·!¦¦Üm˜ÅlsF•Ý*4¦R4¥I4žƒ#Ù¿ù™Ž)j­ÑP§$΢ÆT„Íiª,:a©©(KOâšô'bÔ£ÚIØ›mõMW3Éò£ܢ+77‰.ñI6c>–µ§R“ ÐLé+øÊQ­%¤¶–Û‘i;`b ,úÄD¨^mð‰8òÚƒMÍ>[JRot™^åm£±«æ'+ƦªIM‰=º¹Ê•*)¤––òÝe-\ü´*Cö¾Â³]49ƒV¤V*ѤRYqI¹2 ¨Š”Ý6Z3BJ’†wѨö™Œ©šóçª)Ç“›±¬ÛàÜN¯Ò)H®J‡>­R‘N‚Ê)äë:Úm…šÝw…I¶“áÒW$*Ä“3ý3 VªQ*T-šÉ”ªChqóI]DÚ¢S†_ä‘íÙ¼tsÉ¡`Èxz*æ*2çÍv«…412;ìÆm(;–\¦J2ñMI2¾ÒŒ?˜Ê]6›‡ŸŽºœ*{¾ç©òž}&úÞBçµ.:ÈÜ2ñxB+‘^÷Ó3\e¶"‰rs0F%‰Kåá0–x«s4Öñ°â´ºMÍÃF•$ÍZl[ok¿¦ð)qÈM5OeǦHf;l"c u·Q%´º‚^¦u‘¸I-£¦Äu¼1O¨·U…>l곘b%9QÐÃg r”Üg†' F¤”FŽ ¬´ØÏ`É£ãü5LÆïbô7Vv]Z§]J)Æm-ÆB&³-Âe|!›†jd’IEˆÎæ#]xÌBtÑŸ9rÑ05EüVÄ*›Lhé²Xeqœ¨FJÔN2ë¦ewõ‘!$M‘”£ZHµ6²-^$ÃUŒ:¦QWa–é©$Ú%4êФÛRJfÚËQ]+"2¾á—CªR‘ƒ+”’æ²ä©¦Åv;)tÖ‚md¥§JUÃùE¨ËO’wÙˆ(õä@82\ÖÔòåT&Cf;ï’´hBø%:hÒ³áUe+^Ò+Î&­Xú1˜§N\x `Ÿáâ5b¡ÇÊ* ·ýìѵ¨å:Mºé¶GrÓú6\;íÛ¤­ãæ}„qí7 RhQYÃPªoÜäù/MSé4º£JI-ðO%*O„ûâL®¥¬g|+š±ü¬¨ˆÏ›-p<ÜUˆhÌÈà˜¥Í¨³×9†[jq)pÙKŠÔ∌ü”«o70ù£.qzâ5,©ñI§#µ*ê¨ÆI¶Ã¨JÐë„n]¶Ì”ŸdI#;‘ìü9аL5Mdã2*‘™$©fƒRÜ$ëÔGdÞê+(ˆÒdg¹¬âõÇeÏ'W£†¶òÕ¦û/³Xœ5ZU3” *8.äè9 “ÆÑÂkV³FóÕ¦Ö#=ÛGoLÍšÔ k†¦GÄ•Œ;Kn”ÔŠsS”-Ùa¥-ô-M¸dGmZ¶Úæ>Of W°Ù6K8µÒJàš @Q­‹ê9ª#}:‘½63ÚdJIZÚu\èÛŠ:°ñ~YWi¸Ž«—.Ó™›-ªy¿:9H”ÓdÍ-ê%8²6•rJo²ö±à…ÍŒqŽ‘аþ8feMsâ»*¡žˆÍ):´É 6úø[´«-&i$/ÅQÛŠdMªª˜þd\Šb|€ZÀåú3TLã^Fã¹<ã¾ÂØ]ªÕ>¼© –™”önÃ-ØNYÏDdg½$V+s ¸Z£R©u¸Dn|–ÛÔ•$ÌÒ¥’OI•Êåݳ`êYá.Å×)÷ÇŸO5*ïQªiÏœ8É[ƶFó>?Ëú­&¡Qz—O™"Iñ‡“Q–„©Gb±™™í"±[öŤàDV°þ‘-U¹uIçÉ+qƒŒM‘ºk4'Q9©)lÏÆ±•oHêZánÓ\Ñ1çøSªíNr¬_oŽó6°Tœ\&]9òþôâÐjxÒ„›wM”«m"ýûÇø»Mi«œ4ÍQTfnŒGyÆ[£Þqj†š˜ŽŒWwÊtb»¸ÅÚjb;ä˜Ççù&1ùźy4Èb˜’|Ÿ0€!="OH>WàÉøóEðCá)ÇŸZnL´Ÿ)Vçæ".s2ݼ0úŸ”™cQ¤VÂ9†¹ÊCJ\„ÌRf–%RDF{5”DfWÌ#ˆaàØXÆM?Esç4®³ÖáÈËA+Y{Úö™lý¤GÒ w]èó ÝW¹sÿá~#Çø¿cÞ8N^­z|­–½ÿe„ÇÊÆ‘*\V°ËÊ‘3RŸgŒ2KCnkÐzMw3> ~)xÛ6–ÒÂì)ùeŽªšv…‡Ÿ~§OÓÆÛK­ègQ]$§5h#2=…«§ ÇÀò÷'±ƒœ¡>ÕrBT¦b¸âÂ$’¥’³Q ÊÉVÛÛa–ð°Ö·•9…E¢J¬ÔðĨðb-H}Ó[jÑ¥ZMZIF£MÿX‹I–ÛÛhêsO$ªØ/Rq8y+àuÖÉki(„µICi"Qšüu­&¤ê-„{B¹É¼½{0+Òc¹=Ú\8Äù‹+ðhæ"#2+iì"#>kaŒ2Ë.žÀuM€1Êê ¥™¦'©(á¡JæDf[ªÆD`)`!Ú?•˜õœ4ŒHæYRW”$¤²ià4¥ZŒ‰w#²ˆÉ&Zn͇kB—pjÙ’í¶q%–Ô¹*¨½Ù uÇ\B“eJI%Imgs#24ËÆH=€³je"‰–øŽ©ˆ(•ØõÊD棩ƥDT’²Ž¢'–n©F—· Œ¼dßr­£c,1óØWÝ;Xfb©\ O]»_Y7}f›m½­m»€qüÂ[ƒ2ÛãÏÔ¦Åmf…‹‘Bâ\ÍÁ;¥ð¾0[×CƒJ\y2¸«Å¡ÃL’"ÐhÔ~ø¤F[aŠ/0çĪãüET€ï eVL†ÒiÖÚÝR’v2#+‘–Ã+€ôç{¼Ëê}ÌÓxrÜ¥ÊÜ÷ßáx-\&û_ÆÓ»šÖØ8¼„¬=•’j¬Ò°lúíJ¬Q '´—Є\Ò‚òµëØö¹ì!¸<åÁáãò3ÝW¹ÞHä®*­‘­Ã®,Zä–É&¶Y'JÜfIY•ÆË¤pU_~XðßâçƒââôFf"¼L»ï¯Ø‹ü/Ùç?¤Äºšm~es×øÛl#€ˆ­<L¯© ½îgÐC#NU)ØZM2CIbœ´œÒá :-¦æeûl¯¬8)†¶Náõö|nºâ˜»¦#9ÄÏój§—OÅȹÀSLΉǟOà 6!Š•K»NÛhu†ÒÛÚ´¤”M¸“]ú.FwýãQQIÓix‡PqµU«2ê’K%šáÅræñ’_èþÁ[ÈÜcW'œ_·âš©ÄÓççõòó«W,~Jµp˜ž~^_Ú0¼ä2í+bLIT–Ï"rrZR â;/JA¦÷#±(˧Y[xãá<Ô|§Ëù¸–Úk´µ­GbJIçÌÌÿe…S+xÖÈÞc¡OªsóÏ׬Äôüg‡ÄsýÄ;NèšlÈÙ‡*¦ói(•¶¨ÎÈõ’m*ØGrÛÒ*çÆcã ñ¶kŠëš£êÇià шï8Ëtb;Î,ÐÕSÑŠîãNŒWw»CMLG|“üã!ß$Æ?8·O&™ @“2BO˜@“æ'¤A éÑîbÅ”¼#š ʬ>ˆÐæÄrß^Ä´jR•(ùŠè"3æ½Ï`«€õPÈj=VÄ«ÁjˆÛK]9ÈfKvAïEÉV#=Å¥&w¾òШ’1·rޤQdÂ9ª»ŽÏ7䡤Ço\ƒ5(Ôeb$º…fë;€sÿû§ÿþ#ÿ÷ S¹Æ|³ËÌݨ‡NQRIâtÔz‰|µ^ý7Ú(N‘=Üã6—RÊlU…MfµX‘)/•-u„¹¬él‰)t¶– 3-ÛHŽÄ¡×MÉÿ–Ô‰Tê\ tØS¶"U—9ÆqTHmÕ©´ÙE¥_¬³;™™î3ò@õ•&R;¢%÷Ke(KQ™$‰3VýÈIbK s¹íO“XÈ̶®ÓI©4úM),Mu§ôN)¸è$Ú÷3Ô…ض[m….>æjí:±V­Ô¦7‰©ÜU™n™Pá%Ä‘žÂ3'LÊö¹¦Û̇Óä­;`z•gbø|£b*TX¬¤*û/¨‰G~{’W;žáL ãº2CíåRÇC«KNQ‰KI‰FQãþå+ý¦.‰2£Fî«am¥HÁœ$µk_5i.“²Tvý†<>а¨•,9Ü£èµv <èµÖ’ód´¬’f¨F[RfG°ËqŽŸ3iõŒMV£cÜ‹!Ñ0Ô|:ãJƦ:¼s6¾¥„fFŽ’"?)€LäysCÅ%ŠÄˆ•rã,Ôª#PØ'n:Ûf¢I8dIQ9¬ºý]e‡Y¯çÚÜiHCÔ®6fV%§ˆ>“2éñ’¢þÒ1ãÎa:¸$ž9¤jÄ'‡¾ ML›×Å•úª25$­{ÜìDg}ƒ×•82]ÃRÍšŽ¬aÔEQÄ©2ѵ%gÌ­'t¥VÝÁïkCdDHŸ–«ËÊÃä—èu&j{Î2—úTÖp¿µÄô ªN9¬×û¦§JÂóhM1"鱩¾¦™}„-:’Ú•)K#Zvn/Üu¾Ìظ3ʧÐ0« b‘Ü"¸©‹RÍ Y™ijÖI‘KaØÍ$fF+p ÌŠ]7Ôòê ü©˜uÅb(ÎÈÃŽÕŽLH¨K¦j}}("é+œÜ[FäŒ3Ýi2»_Tx´üAN&iRœyTâZŽGÏâù I^×¹[xò9élãuêLThð+7> —c°¼JäùN9Â%Jy 6ÏÅQ$ïu¦×3µÎÇØc)RKºÿÄ'Ü(üŠò¸=G¦æ‰w;~Ý ú¥Ð9¯ræ4Ûn«ÚÛoaýãLŠ0l¶"âZCÔ÷I©JJÒáû)i3+•Ê÷+—Hôž^âÚV9Tà“k‡„¸°ž"Úñ¥Ô]ÏßÂ8EþM† j¡’ÙDõdøW׋[mÅ;´Í£’ù,ŽüÖ$ؘÄ9mŽpþn¿YÃ’áÓ\ÓúešLÑ«v´‘š‘{‘xÄ[NÁ…2ÛbªC•j•6 fdo‚Q–òI(È×oòo´zS-R*ír”¨ŒÒa©„¬üT¯‰-EoôÉ?¼(Ppä¼?”´ U[‘R£?ÄåÓê Œq(èqåø†Z”£3-»7ÜŽæÈ/6ã.­§P¦ÜB+BŠÆ“-†F\Æ/~á/‡CúgÝ!Mã(OSquf&Zæ={ì9!j3SÊKŠI¬Ì÷™™_÷‹“¸KáÐþ†™÷HD÷Ðå—Ã^<ú&÷§ ðÐå—Ã^<ú&÷§ !.O¤pU_~XïzGU÷åá~d½Ÿ• Ã['pÙHÜ5²wý• lÆ5ryÆÒFã¹<ã«aF¶²Vñ­‘¼ÆÊVñ­‘¼ÇVÊmsã ñ˜øÃ|t­«TÃtb;Î2ÝŽó‹´4TÄtb»¸ÆS£ÝÆ.ÐÓSß$Æ?8ÈwÉ1Î-ÓɦC$Ä “æ$ù„ éBz@@ é'¤@žay„ è' @ !H@’` æD y„ža$„ !'˜@ža````D »ËœÏªàzF…‡êêKÕ+”b­Óq:lM™ÒF‚Úv2?(Ç;efM]ŒoÑ)4=2< 1J…ÀÇu7Q™­=Fd«ßq&Ö2¸ùãüÈÄ8Ítòšˆ4èÔã5D‹NdÙi¥™ÜÖEs=Fe¾ÿÙk˜ã@‹s—â\2ý qSD´¡3¥F‹ÁȘHòIÅ^Ç»˜‹£vÁ?91†ìÑ`¦™! eD¸¼#ð‰wÕÁ*åkÜ÷‘ônØ+ ô’ó²d9!÷ëάÖâÔw5(Îæf}&böîøt?¡¦}Ò(¾»„¾èiŸt„IqY|5ãÏ¢hßzpß Y|5ãÏ¢hßzpÂäúG¶éŽH”¦KŒEm^*^Õ¾÷Ôâ-ÍÓÏ»Ÿ²éWß–< „œ]—¡iÕf#8„­ãV+Ÿº–×´ £à«xÕŒAû©lû@Á‘¸kdîAjb~Ÿ¯»r×ýÒÙ=íÕXÄ¿º–Ç´ ãåÞÝUŒUû©qý jdn1«“Î:Vi‰ÿì©×Gã-ÛñòÏõ«¿÷Rãû@Âz>V_Ƭc?ÝKíž•¼kdo1Óµn'ë=åRºNì|¥ýjÆ7ýÔ¸¾Ð1]”­XÇ_º—Ú"øÃ|_¢Äužò¯T;#äß=cþê\OhîGÉ}·¬fî¥ÃöÅ:1ç(áãÕ=妧pä|’ç¬fî¥ÃöŽä|ŽÛzÆbþê\/h#£ÝÆ-QÂǪ®òÕT»ÕÇÈ«m¬fGªá{@øñ|†¿õÆez®´ õß$Æ?8µO º»ËTÔ²Ž>CuÆez®´âù וê¸^Ð+c2ÚG®®òK,ãä7\fWªá{@Ž/Ýq™^«…í¶>a´]]äÔ²ø¾CuÆez®´Èn¸Ì¯UÂöZm#×Wy5,¾/Ýq™^«…í8¾CuÆez®´ Ôiº»É©eq|†ëŒÊõ\/hÅò®3+Õp½ V€HõÕÞMK/‹ä7\fWªá{@Ž/Ýq™^«…íµÚG®®òjY\_!ºã2½W Ú‹ä7\fWªá{@­@6‘뫼š–_Èn¸Ì¯UÂö€âù וê¸^Ð+BÒHõÕÞMK+‹ä7\fWªá{@q|†ëŒÊõ\/h Ò=uw“RÊâù וê¸^Ð'‹ä7\fWªá{@­6‘뫼š–_Èn¸Ì¯UÂö€âù וê¸^Ð+^‘´]]äÔ²ø¾CuÆez®´Èn¸Ì¯UÂöZm#×Wy5,®/Ýq™^«…íÅò®3+Õp½ V HõÕÞMK+‹ä7\fWªá{@q|†ëŒÊõ\/h¨Ò=uw“RÊâù וê¸^Ð'‹ä7\fWªá{@­ƒiº»É©eñ|†ëŒÊõ\/hÅò®3+Õp½ V HõÕÞMK/‹ä7\fWªá{@Ž/Ýq™^«…í¶æHõÕÞMK/‹ä7\fWªá{@q|†ëŒÊõ\/h Ò=uw“RËâù וê¸^Ð#‹ä7\fWªá{@­ºÒ=uw“RË(ù וê¸^Ð#‹ä7\fWªá{@­ˆ@m#×Wy5,¾/Ýq™^«…í8¾CuÆez®´ Ôiº»É©eñ|†ëŒÊõ\/h/Ýq™^«…íµ æ ¤zêï&¥“Åò®3+Õp½ OÈn¸Ì¯UÂöZm#×Wy5,¾/Ýq™^«…í8¾CuÆez®´ Ø@m#×Wy5,¾/Ýq™^«…íÅò®3+Õp½ V¼Â 6‘뫼š–_Èn¸Ì¯UÂö_!ºã2½W Új´]]äÔ²Ê>CuÆez®´âù וê¸^Ð+bHõÕÞMK/‹ä7\fWªá{@Ž/Ýq™^«…í¶æHõÕÞMK+‹ä7\fWªá{@q|†ëŒÊõ\/h¨Ò=uw“RËâù וê¸^Ð_!ºã2½W Úh`a´]]äÔ²¸¾CuÆez®´Èn¸Ì¯UÂöZ€m#×Wy5,¾/Ýq™^«…í8¾CuÆez®´ Ôiº»É©eñ|†ëŒÊõ\/hÅò®3+Õp½ V HõÕÞMK/‹ä7\fWªá{@Ž/Ýq™^«…í¶HõÕÞMK+‹ä7\fWªá{@q|†ëŒÊõ\/h¨Ò=uw“RÊâù וê¸^Ð_!ºã2½W Új´]]äÔ²¸¾CuÆez®´Èn¸Ì¯UÂöZ€m#×Wy5,®/Ýq™^«…íÅò®3+Õp½ V HõÕÞMM¶.,8U÷Ë .¬º1%²aUD6™*WžÔM™¤‹^»øºnfw'p—áý 3î¡EõÜ%ðèCLû¤,Äb0‡¸Æ‡,¾ñçÑ4o½8o†‡,¾ñçÑ4o½8c“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÄ 1$$ù„ >aBzDžzD é@'˜@žaz èH@’$ƒ˜9€@‘Dža'˜A€ !H@ æ'˜@‘D ë¸KáÐþ†™÷HP¢úîøt?¡¦}Ò$=Æ49eð×>‰£}éÃ|49eð×>‰£}éÃK“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÄ 1$$ù„ >aBzDžzD é@'˜@žaz èH@’$ƒ˜t8 ÍÄÕˆ‘Š=E¸IDggG„o¡…,É)5mI\Ó{¨¬Fg·qäU°sÔöq;ÊzcŒÑ'œ&ßM=ÃfB’î…jp®†ŒˆÒvQõÙ«šucÉŒ×LN¨ ÉaªÛ©Ôhµ˜´ƒ4³JÍ B”E¨ZRg´¬F¢#3"¹\m±¦«P±u^ƒLbmm´´·äÇ„«!+hœº‰&­%´Êæªf ¼g¿ÜéÎ2äD 5²O0ƒÌ À$ óÌ H"õÜ%ðèCLû¤(Q}w |:ÐÓ>é’ã²økÇŸDѾôá¾²økÇŸDѾôá„%ÉôŽ «ïËïHાü±à+5ŨÑÿ-š¡Qª 'ɶ´­©$lìBtj¹x¤F“±™(y¬SÇDç4óÿŸtGŒyòÿdˆ PYO0ƒÌ À$ óÌ H"õÜ%ðèCLû¤(Q}w |:ÐÓ>é’ã²økÇŸDѾôá¾²økÇŸDѾôá„%ÉôŽ «ïËïHાü±àé’ã²økÇŸDѾôá¾²økÇŸDѾôá„%ÉôŽ «ïËïHાü±àé’ã²økÇŸDѾôá¾²økÇŸDѾôá„%ÉôŽ «ïËïHાü±à®¼AŒ3¶¼ìdÅr¥ëÓÂw4n8ÚÍ%ýš­û†¨¿\ÄÌcËðÿ”áXвã×q¤üGÃÒ§VéÏ8ÄÈì© &ÚÍ ÔåôŠÚµXùŒÄf\ã|¾’Ä|a‡¥RŽAµ©.6å·’\AšLÊår#¹\XXRLÊgqæ'›BqÆ&ÌÅŒD«:É™/‰}H%m$›¦eûneÎ2LÊr>`ǬºëÐ)•Zk”NÌɹ+pÒú[3Ýú3#2/ñŒùÆß‰VsôÎ…K…è5ŒO^B SÞ¨Ô¥¨ÒÄvJê]’j?ÜI#3>b#N?ÉìÊÀT¤Uq^•O€µ8Á:ÓÈJq(ÛR´ßü«.Ù”ùE*·âHJT’u‡ "RM*+–ÛLÈúHÌ…êÒèï÷)âBÀ3ª„–_¦/±XA­Õ*È8ŠB´“|1ÈӬȓsÙcÎåUS1ŽD(!ÓbT¡à\-Œ%Ȇ¸›ñ&ÚZÖø³¤ÚøB4‘ÌÊÖ5lßmÙµÀxr…^É|«ˆ©ü©aüU[:v£IL[ÚÒÑÛmŒÕ{sÛmÊä"õχ‰ýò’#/%ô•Îü6{ø3àÚ¥¿I„™T(Ç©æÉ&… ÌÈÖ‹ëÕ¿vâ½ôÙ½Z¢MÅÕŒœÂ¹U†)ëf¨ŠE& Û*MC†D„£ZÞ3ý!9c++q,Žça{3§S YuÌ—Å4Œ +IŸF\ÔJ]im¶ó†é±Pum²’#l‹Yg¨¯b+XÕ¸za¼WÁ˜ï ÔØËEb¬=‡æT6 ?ØoG"35JZÌœ"Y’MDgØcaZªS¨¹>©U¡F®Å—1J%Å!§UÆ¥5švšIF•[Ma5qS8Ó_déx„zÇa|˜{Wª:…†%+;EžÕ “ŠÄ¸è‚¹v4‘™’BQª÷Ú{v•¹šmO fÆÇô•e¦®áÊ$ŠÅ*u.1²ú …$¸ ¿éT²;\È·ËØËnãÏåÍyÐnqN®áŽJåȉ£}éÃ|49eð×>‰£}éÃK“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÄ 1$$ù„ >ag„ëR°Þ)¤â(-²äº\Öf°‡ˆÍµ-¥’ÒJ"23MÒW±‘ÛœƒÖ¥bLSVÄS›e¹uI¯M} ‘“i[«5¨’Ffd›¨ís3·9a éˆÎGkZÌìQQ®á:ã.ǦÔp­*-.œô4©'ÁGÕ¡KÔ¥jQê2Vä™lÓkŽÖÝZ¥Ôk•¹u—*¼§9I×).©O¡Ä¡.4fo{Úô”$Ôj;\Å( µDùL'.ûæ¾$ÂX–¹V¢Â¢· ¸âÕ>ˆä"]5Ä)f¢l™3Ø„ê2IÜ‹eíp̬×Ęꕉ&‰C„á¼Å&‹¢ÅK¦FFá ŒÌÕc2Ú{.vµÌp 'áÑXó2Ý`ŒKP¢&!¥µ éQu’[–Á<ˉZÚÒ´Ã#JÔ_¼u¹œX‹a‚ãa¬7ESå!øTqDnK¥¹nm3Q—ö‘^Çm…jç¤@MÌê˜óFAxa<Ô¤Ñ(,l]^¦ÊÂmKàx¾eä¸rÖN>Óª]@‰Öõ”ž„¶™ÚÔxtE|̯¼wš¸[Ñ£Ñcâ –¦3-3N.ÀÑ¡¡Ù ò]]ª&f¢Þ[H¯cµÈ­°ÄÙÙ‡ëÔí+r#UÔ¸î=]‹€"7Q}L8‡[5»Ê6ضÐ{E²Û‡kÛÓûÂrô½[>píB=q¾:˜k¯RäSªr"eüfŸ’O$’§–áTµ„WµÏNÓºOe´µÌ×ÂÕ| +ÉÄU”@“D¥ÑVãx=²t˜§º·QÔ̵™¸zŽÖ2µ‰;Å=1ËýŒ®|;0®Áp°½b˜mAÄ)Ä1æ# 1Æ%,ð$W:ŽƒoNôšvžó¶Á¿Æ¹É†±6¨PÓZ—Bjª¤ª«"€¢Æ~¡c¿é—Ê&j¹í;ZûyŒÈyäLئg>ÞÆ^ŠÄÓ†jØz§Jn¦ºLмuF©Õ)¹}‰³W–‡*Œ•Ïb!ÎcœÍÃÕŒ£c&O-K§Æf%:}C°ÄÆXmĨ›L¤ÍpÛI$Œ¶6z‹aï50)ƒ)æ'˜@Ü€O@=IBȦÏLšÜêlÙ0¥7~ øî©·r±ÙI22¹—öÇ æU1TLLy&&bs ʽZ©X”™Uz”ÊŒ„ NÊ}N¬’FfIºŒÎ×3ÙûLa¦šh4Æ ª©ªs2‘D ža'˜A€ !H@ æ'˜@‘D ë¸KáÐþ†™÷HP¢úîøt?¡¦}Ò$=Æ49eð×>‰£}éÃ|49eð×>‰£}éÃK“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÄ 1$$ù„ >aBzDžzD é@'˜@žaz èH@’$ƒ˜9€@‘Dža'˜A€ !H@ æ'˜@‘D ë¸KáÐþ†™÷HP¢úîøt?¡¦}Ò$=Æ49eð×>‰£}éÃ|49eð×>‰£}éÃK“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÄ 1$$ù„ >aBzDžzD é@'˜@žaz èH@’$ƒ˜9€@‘Dža'˜A€ !H@ æ'˜@‘D ë¸KáÐþ†™÷HP¢úîøt?¡¦}Ò$=Æ49eð×>‰£}éÃ|49eð×>‰£}éÃK“éWß–;Þ‘ÁU}ùcÀx_™/E§åCG#pÖÉÜ6R7 lÿeBã[#q\žq´‘¸Æ®O8êØQ­¬•¼kdo1²•¼kdo1Õ²§[\øÃ|f>0ß+jÕ0ÝŽóŒ·F#¼âí 1®î1”èÅwq‹´4ÔÄwÉ1Î2òLcó‹tòiÅË’eÔ20Ü¥aªun·Nrœå0œ¢19ô¯)/Im©J#B7É63"#31MïðF)Ôœ¦Æø^¢åTªX‡Šñsb#ke¾,áºj7R¯Fi;$ô‘jñ¯¤¢¸Ì!Û×ð}&³IÁ´ìS Æ•zÑ@[4ÈhÔqV-¼ôT­)m\)¥;4ž“3²Œ¬8\Uƒðv¬V¨³qÄÇj4©œ¡Š.¦ß"x½ 7ŠÎ%¥šTD“4IgrPÑåÅRBÇÔåYRÊ6{3(¬¥ÇÁ(–I$©I/ÒEs=„fv;Xþ˜ò§E¯æUbµúƒtšMÉf·"£Œ4‡W­eÁ“†•u(‹Ç-V#3MìQ18Ê]Î>Ëys3×áv$ÒaǦDLéÒ¢Á8Ñ£ÇDfÜZÒÉ)f^Q‰G©G}—ÙÊT0lðdüW…ër*irb¢Ü¨%æ8[“k"'JfF›ê##¶ÁÚb|Ø JÎzþ/¦Ãª?EÄ”•RêQd4Û/¶ÚÙCJàÍ+ZL˃BÈÎ×¹¦ÅmGÊ¿Špý/+XG *«4ëÒ#¹>]B3qô6ÂM¶†Ðã—=J¹¨Ô[­a«ù ¶&Ë|†åaÎXÌ ŒC¯Ó©0êhZÜŽÛ·27—ö¹Ðk32Q[aácå}ϹUW#PcÑÞãÑg_}.§C«òµÒvÓbÚ«ìc|S‡*ÙM‚0½9ʩ԰÷ãüFÐËœeÂuZN©^"ˆ’WIj#ÕâÛIÌjòÈësû `ùñ6ŠÕNNiÉ1ZÌZ#% ÒúM^1¤ÔZmK;¨ÒD®v»–´ª?ÄXn«ˆ*ŒD Á9R'!³5ÐI$·Æ´¯„A%Z®f¢#Im2ûæs fn8•[£5],E\\Hñà<Û FeâKmÞ7 ÖFI±]-ØÕs;k8ŽR²÷ Ñ«·©ø±èˆf´o‘¥åÇŒµ¦6´žÒ5jRŽö3ЃÚZLc¢"0r!="OHY@ƒrâ´Ó`Ô+X’T¢ŽäÖûQ#ÇQ!D––F…-K;ÝDv"±o íi¸¦•QÀ‘0f)DäF§JrM6|&Ðë±øKp­)¥©$´(È•å$ÈúHì1¨}&W!c ; ‚œ/Ng»Ue¸³iÐÛŠ‰ ­+I´´7¥¸ChÈÉ;¯´­ãlÓ•ðebІ ¥b…MÅpPö¨œžhŒó¬¤ÔãM=ÂE¥DZ›I§xÕHÅ hm`Úk«z—QEMÊ¥E†Ó&CÈ4èA%® ¤é¾j¹Ìöéaæ¤æG2¨ñëg_–r_bžû-hÒ_B’µ›Ä³S‰-k2O“Ý´c9ŽIa¿ ÝË UM§•EŒbp‘1Dƒ`â)Î NIK-j3ñŒù‹rH‹æy_.(§àº®(T,W9 éˆTó\f]y$¦Úuî”J2Ro¥µ·Œ?u8s¼¸~«Ë\½Ë¸£|[Þ¸ _ «ÈñõhßâÚÞ0ÞKÌ<%WÌJveV#ÖÊ¿ã>ý=†Z8ÒdGBR…“ƲSi=3O£-»D4rŒ1–Ѫ8[Õ«Ê,¼'!¦gÅ\*%¸mÙ+'õêBËI¦×Óã(Í<Ž(‡A‡"'¹êäš´w£*D*ãëQFk#±U©*2ñí¼ŒvôŒyEwæ<ë•2­ã LÊAņÚã¶¶žSå©Ju*²Ö³IÙ'¤ˆÆ¾’¬FTç3”3 <Âó<*ª"11!Ìä„§9mÇdœ#IšÖ‡ÔoXŒì“JÎÚ®WI¢j‘V€Ü„s0 H€Ì;Œ©U*Šü¬iˆ)1ªÔê[0Ü)-’Û’ûª2Òi=‡¥¤¼¿Ø¤£¤püþ^3§Ñð=‰†M¾…®EMl= Cj»©¥ºnž’JR‚-)¾“QùZK¹`ms,ä=žMáL*†U¾´M£¹äµÅ^I¸JØ^B–]6@æjøw ·KªÈ£c>;.›¤ÕTŒRÈÜKfqÕÂ,ܶ¢U”H=$gm†,J~rÒ§àªä¦&?‹ð»Ž ‰šdxÐäEpÍÅÛYhÒÙž•V¾Í;MB¶¯»…;­K•)eÀöPÊ`£V£±¶â¸e›¨’DFg¦ö2Æ\¥+C1pD íK ÕeŒ9F, §Z©Sé--¾á¹ã)¦Í´šÖ«$‰;wX¬[+èX2"…PÅnWêð¼YmÁfJéi9rd©Í `ž4”‘™™º[-Îv+ Ìè¢ÅÄAº|ºô¬3N 7C­SfÓÚàå´„ØÜKdù§RÊÅ´ËN‚Ú²3!¨ƒ˜øb‰G«á<+WÆ”JÙé©Ã™(jd7tšÂ’—ÈžhÐHÚkAÝ%r;\ñQ›NWÔê‡ ÓðôÖêPñJºdÇ6v!F—‰Ä]ZTÞ•‘ŠÖ±˜ìr§àÅRó<:¤|B¨xVséLúm©·›M‘";†§DWW›35 ìv-:™ªý#áŒA¡ˆqÐÜuk‘\˜µ; I!Ä%µ¥’Ѱ¬j33¹™‘VÅye…\ÅDرÔW販m¨àG¼$½nnô¶±«£Éµ¼k”ΩQ€Ú€ÀÀÀÀˆ _]Â_‡ô4ϺB…×p—áý 3î‰!î1¡Ë/†¼yôMïNá¡Ë/†¼yôMïNB\ŸHાü±ÞôŽ «ïËÂüÉz-?*9†¶NᲑ¸kdîû*ÙŒjäó¤Æ5ryÇVÂmd­ã[#y”­ã[#yŽ­•:ÚçÆã1ñ†øé[V©†èÄwœeº1çhh©ˆèþ`Cv¡R•!.Éy  ÖfI%)DE{smÓ£3í…é?â$]¶ÓS¼k¹Û3%Gmøô£u—RKmÄG¤­&W##&¬deÎ?ŸÌÓ¿õ2ÿ…“Ù|ª¿+ dý¥žÍB[ŒÒ¡1é'µ.K¬GI©ÂBÍ)#t”vJŽÅ¸Ì6é%YkB‹‡Ÿ¤'\iK›mËuL°¤¬šBöº…$ÈÐZlG{ÅÈŒ4åàoÌÓêeÿ '²àÙš}L¿ádöCô&69¡,êS¤U$Tæ&ºÌÚdˆ°…»!²q|)$Ì–l%‚Wˆguˆ´wÇÁÉÃók¯Õ‹†cÌ)P_aæyhCD¶V‚q$¥8‹¦Ö;ÞÄfR‡çǃfiõ2ÿ…“ÙðlÍ>¦_ð²{!îüMš”š,c¨!ª”Ö–í-¢§•kRØL¹ŽÇáÖFÙ¨Ò|ÍàÒjSDD¥í¶ŸŠ(sŠi·-lªf¥KD¸îF[ 8Ù¸…­.¥&’ÒJ½Ëa¥I;)&Dœ~ ™§ÔËþOd ™§ÔËþOd?I™¨C"«DmU&!H„‰&¸ÉtÔH%™ ÖÙÊ÷Ašo䙕†»/«ò±.å9ÔöiòÛ6ñÙ’rJãJv:.jI›F¢ºRv=À?:¼3O©—ü,žÈ<3O©—ü,žÈ~Žaêï+Õñ?Šð<‰RD|&®THò5ÚŧúF›mò/}¶-%cb=^:ªxV;496©ÍJEP—(Öë¤ÓnroOjROc†¢IÜÒV2 üþðlÍ>¦_ð²{ ðlÍ>¦_ð²{!ú9ˆk¼‘WÔþ+ÃrÝIpuðšx1$H×k¯èúm³Ë½öXãNÄq8³xv¨ãšǪ̃ñFY"µ®¢mÅ™ÎÄH2ñNæ[.œž ™§ÔËþOd?“îoÍ;$ÈÿÍäöCôsâbŒ3²ˆªŠn8ó.4nÉ.4êÚ^•–ŧRiQyI±óaWâa¨3+U)2cÓá´nÈ[,¸é¡£º ‘¨È·™‘l"3;ˆ™Â_ŸþŸÕ'ü<žÈqØÏ.1.Åt¬5\i˜Óê¶ìr3Q%n­¤šˆÒJOŒ…sn±í¸÷…6ð®7£WšÁ¸Šléiî<ëÄ’ÊYñOO鄤”fGb½ÏJŒ‹Å;yúá§+¿èå#ÿ2èDŽ:?s–gHa¹é|3.¤–Ûˆ%IZL®FFMXÈËœ~ ™§ÔËþOd=ôªü¬5“ô ”{5 n3J„Äw¤œvÔ¹.±&§ 4¤ÒQÙ*;áö¢ã¥"F ‰‹áÓèr(1Ø•-ÈÕ—‚{„Ñe›m«]ÚUÐh#Ú‹_Q CóÿÁ³4ú™ÂÉìƒÁ³4ú™ÂÉì‡è„w…¥ÑjUr¨¹-0ˆæ”ØEu‚2ºMM:„¹ã“âøÜ׬ň SåI]2ŸI¦¸˜ò`¹Ö$:ìÞRB\-Hmƒ"QZÄF^Q™‡<3O©—ü,žÈ<3O©—ü,žÈ~Žaêï+Õñ?Šð<‰RD|&®THò5ÚŧúF›mò/}¶- 7¹5Ú]54m5É5GàMÆoÄÒÇŒëæ½24)•'ajáÚ/UÈ<àÙš}L¿ádöAàÙš}L¿ádöCôF‹Ž°µb¶tzuEnÊ3pšR¢<†dgg —”‚mãIï&Ô«m¸âòÃΑIf«‹k-”&ð-±%å´„H“Ç8w¦_ð²{ ðlÍ>¦_ð²{!úIǘZ§Á&4÷ÛuÙ©ƒÀI‚üwò›SˆJÛq Z IIšT¢"=„FfdC`Ö$¡»" Ô[yÉòŸ‰š#Y-Ö5ðÉ3"²t›k#3±\­{™‡æú»›³E>U!Eý±¤öB<3?ªOøy=ý%Ä*R š£J‹q‘Ø÷¦ªùá€i8¥Ü/PÄU«MH(Ç©sTêœQ–”¤’ÑëÕrÒi¹(ŒŒ®FC”¼UŒ2?a\/?V !š|¡O­Hue¸†ÓmhIêZvÞ×>cø'1ž5¡·WÃÑš–Âït¡-mÙJOŒHmDW4*Ûy‡ª{¥d>þRæÉ>óŽ“i¢¡Ôg¥„S« 3ÓOuÆ¢GrGÝu¶Í-¤Ýqã%:¢ç+Ù6)CÂ^ ™§ÔËþOd ™§ÔËþOd?D+˜ï ÑkEG©T–Ô¢àøSLWœf?vo†u(6ÙÔ{¸E&üÃ>&$¡Êq¦Ù¨·Â;=êshY¹ ÍÆÈ”DfdM­WÜdW#223ÎÌÓêeÿ '²ÌÓêeÿ '²¤P«ôytkÌÏl©Œ“Æä—ÛBÊ”—f¢/ ñ·ÈÌŒŒq˜Ó1©îåÞ3—†gL‹[¤áù•å2˜ôe‘¡•šB$6’u²-¤JNâ=à¦_ð²{ ðlÍ>¦_ð²{!új?2¼3O©—ü,žÈ<3O©—ü,žÈ~š€Ì•w7æŠNʤ(öÆ“ÙðpÌþ©?áäöCô{-m¶ƒBÔ“¹Òvé #<0 [µ…éøŠ íiÙ¡.j]K‰3Ô•š-lzV$‘ˆŒc2—‡³ (q¦ÃÍ×q 41 rÑ&iq 7…¬¬KBnVmW2½¶_y |ºÊüS¡½'2ÔƒeÅ!m][…bIš¬„+ÅñÒWé‰î»yé-ÇÝqÕ÷ÁRu-F£²b:DW>b""/ØC#ûœ~ÿYÿ’ÿûã B™ðlÍ>¦_ð²{ ðlÍ>¦_ð²{!úFÇh™˜µ¬#.˜¨I…%1`Í7µ"k¥‰.7k…¥d›ž¢J̼“"ˆÙ‰En†š•Y/Ä[µj…6æE.>«.š†ã@ˆô·Ô¶ÞAm6¥¯j›"¾”ˆÏiعdz±¶t`\]UâITÙém.“kƒ)D¤+r’¤¶iQl2ºLìde¼Œ‹[™µ*Ldï (ã¯.ê4Ü„-µ#ZN÷mdJBŒ‰7#"2±–Á)ÃÄ97–•ÜÔÄÒ°þ™L‰&4%ÍZ纴7Á¥hA‘£½Ü.kXhµü3å. þ:G`Üûø_¯Ñ™ùˆÃÚ3âÿÌÇùK‚Ž‘Øæcü¥Á?ÇH쨪xÕ0±Ü|;ÉÊr”Óª<5“CÉqL´h¶ÝDÙ\îV7+­ŸyØû B®J£I©:‰qm‰V†òšŽ·…·Â:HàÐJ'cRˆŒÌÊ÷#"RaåoÌÇùK‚Ž‘Øæcü¥Á?ÇHìªgcì) ¹*&¤ê%Äy¶%ZÊj:ÜJßé#ƒA(œMJ"33+ÜŒ‹ã‡ñ*WŒ1¥7ô‰¬qZcfÕ‹BiñZ5XÏS®/Æ;™^Û±ªL<¹ày˜ÿ)pOñÒ;Êf§sÖ+Ëœ&ö#®â,*û-© Lxrž[îš–”ø©S)+¢332"þÓ"?wÓjpj.LD'øc‡ ã>d…%Â"3I••mDFer#¹o#"£{·~ Qûÿã0&$ÃÄ2BD /®á/‡CúgÝ!B‹ë¸KáÐþ†™÷HD÷Ðå—Ã^<ú&÷§ ðÐå—Ã^<ú&÷§ !.O¤pU_~XïzGU÷åá~d½Ÿ• Ã['pÙHÜ5²wý• lÆ5ryÆÒFã¹<ã«aF¶²Vñ­‘¼ÆÊVñ­‘¼ÇVÊmsã ñ˜øÃ|t­«TÃtb;Î2ÝŽó‹´4TÄtfaý°£} ÇüDŒ7DÒ¦òubCƒáx¬†ÞѪڴ¨•kó^Âí¶šŸ§ðÛØ³&°õ—¸EF’êÊCŒ(šbDgÜÐã~:hmD“I‘’Œ¶§y}êùuNoªlÑ%úÍ.|¹5 ¯ÊuôEšÃêJuKqG¡¥HÎÄgm„fcÌt¾íJ¤Ä¦ÇË…©˜Œ!†ÍuÒ5P’I^Ñ÷؇ÛÑëüÿxr=óküð½œG‡#ß6ŸÏKÙÄGcœZ«×kUjkÔýr#ÐNRZ OSª/ËR\4¡ZP²ZJ"Q—ŒzvôxΜÞ2ÌŠ%‰‘™¨7ÛÆq!?ô˜£y\Y¥'u¸vN¤¥JiÇIjw‡#ß6¿Ï ÙÄxr=óiüô½œ²ç*Sp_T~RZQ°ÓΛM­vñR¥’TiIˆÔIQ‘m±î.µUaJ®Ì ;†eÀ•R—9,5)SÚ{ŒMzQ¡ÆÞŽÙ§D~6£N«&ÄCÍÞ|Ú­WÄØš©˜T|1*fŸN†šc*TÖ‹‹;%Ãá8VKñžBˆô•Œ­o”¯8ør=óiüð½œ<9ù´þx^ÎÑx?(°]×*êÁxI*z®ÔÚ:Ù¥²NBB"ÆAOApj'šuÂÐvºõ_Q·ôÜ1Å3>µ‹x8¤ÜúT(šo“­¹ ÝR¶ZÊB£ÈÌÏ‚"2-)¿•|9ù´þz^Î|Ú…ZͦÊ"I®vBÚNôš×ÅÙÃð-UUÌãúòÄÆ9þ9óå$MQ?G¤°¾Â2qÆ­H¥RÎHôeB𦑢l©‘¢©·VÊ5òw-§ïåmåpÆTáú£wŒª¸Ë5iDª©<ט©o²Û±c–‹¥æ‰Õ™™©{Y]ÒDez\š|2ýá½<¢9tÏãøÏåý"buÇE« àç°KÓØ­&Øy©$ÈŽ·\6&ÒÉJmÞøhšdZRjI¦Æ¥¥JJºZÆXaš†;ÄíG¦W!AoI‚\^C| 2R•¢kú›¹Ç^³RB µ¬ìj¡@l«Ãïff›³ÿ¾1õúcŸ×úf&5ÇGS˜tš%U.ŸJED䮓l×d¾…¡nHˆËöm)BM)I¸¢Új3ÙÑ··Í Ÿ—Ø>F©LåytõË¥N.EMåµi±2µ-DN)Ô%6ºRmê$©ÒÕO€ß<-ÌÚ˜¯ü9Î~³1Ž¿ŒõF¨óò\°ýQ¼¢f]{ F§BœÔB§ÔY ¸–á6n •6LÄ6¥¨œ+¤š#]øK’Sd%Yp^ZQªe o÷½ úë𴢞ã¬M›Á©[Dâ–ñ%  ÔhQZOI’iLðqü·1üÚ¼£ðÆ9þ|ñ?XN¸èôYeF UYmæë8ˆäÁžÜFØSÍ·=i€û¨y—›¾¦É(B÷Œâ©DƒJùåe=YP¼S0åQä¢$Yi—"ZäDy·¤2É«Kql’I]&sñÎ9O鉚ã¢àØ~¨ÆXUª/áHÕŠqæ³}>‚ãÎKu&²)Š”¶õÇe£²¬fD&«Quðõ4«R™†© Efªóx8ø“m&«¡K[:”D\e*y|eš®§T›í2w¹á•×TÏÄÆsôëÇŸYúÄÌyF0Šâ>DQpìG–§fPY‹Ÿ Si±°ÃTÉ©ù‰qGF†Ûý!ÔDF‚p̈CU+ÆAšÒ(”)àVUªÄŠ—Qié)ŠÛRwI艡¼tºfd«™•ð«‘TÏÄòþœ¼±åçôçñ=MqÑèüC…h¬Ö¢q*u1ÚJ&In†‰T&âªrŠ…Ä&Þ%ŸeN¡’Zœ+êZ¬K2ý-&.v`¸«SÝ©TÛˆÅV–¨éŠÌyNÍ[i[‘Ò’Ià–mY%©DfVºNxMqLÓUÜùLrÄýzOã™ë1“â~½û†Yeüðàßlœo’%(ÒfdFdI2ÝcÞD(v÷Õét,ß~«Z¨Å§@b/…‘%Òm´\’”‘¨ö\ÔdD\ædE´ÇfZÞÌ™Œ²âMt¹•ü-{npKŒíY(u+ÿÐnÜöXm2ò§!ìÐÅÔd¥¶`A¦ÒÝa¤ìqÕÌÖ£3333$ ­{’±™™Õu*Þ@Ôqü,s/a·+pÚ6Ûxæ'IžÍ+RwÒW$«šÿ±6í2>½EÄ™±ŽêT ¬:œ3¦QÑÃFt–’Q*uÒf[vÏÚCKŽÀN~)ë­JÇ’ŽTg2LEL2i´3-æE®:•ä¡;Ô{n7 ÊFw^7Äê?ÚÕ<ÿÿ(ØägÁâ>–ªÿüŒ‘ ÊªøresÜVþ¿¬ÿ‡8oð—ôÙHòx¿úýä}QZ8KÊˆí ¿çª{²'¡žüe‰þ¢ìƒù<š§žü_ˆÿ¶§{ äjØã›ô 4z¦$“ »#G pé-´¶M&¢r"tœlÍD”—5éŽëÒ•tìÖ1¬¨ÔJKÕ”‰R13”ç$ÈnÒשïHý"Y7Cš’DV·’•l£Iå¶µåŽÐ‹_ª_ÖTaúEm^¥Œ«ìƒÉ2]âtåhm 5)V(fgb#;휛ÃÒ]Ó8°ó‘œ&ŸJ#Óm,Ò•’TEÅ=+J¬|Ê#Üd5¹³2²þ ÌHc!±C¥2ŽóïP'!¥JuÓÐFJqN)´ðzJAì?$tUŒE\Ub§Hj­Éí»ŠØ¤µ4™lÕ …S’dI4š”é©k%mt¶ˆ„ü ~˜ì‰WVäu ÷âJÙÿl*g²äò+žüCX?þÆ™ìƒ¦Ë •NkتJ¸U¢¥×y<h> ¢ÆY¥\MD·J;o¾Â+vB~ôŽÈ×WUJy ‡}z¬ý…/ØÇòy †}rªêú_±‹pè§¡ªzªÈ.{ë5?WRýŒA÷?áSßW©z¶—ìbß:c¢3*|ûŸ0™ïªÔ}[Jö1üŸsÖ=õIþ¬¥{¸€N Êœ>çŒ{êS½WJö1Ø7¬&ú®•ìbä߃¶ ë ¾«¥{x;`Þ°›êºW±‹äS~Ø7¬&ú®•ìaàíƒzÂoªé^Æ.@ ŠoÁÛõ„ßUÒ½Œ<°oXMõ]+ØÅÈ‘Mø;`Þ°›êºW±‡ƒ¶ ë ¾«¥{¹2)¿lÖ}WJö0ðvÁ½a7Õt¯c E7àíƒzÂoªé^ÆØ7¬&ú®•ìbäȦü°oXMõ]+ØÃÁÛõ„ßUÒ½Œ\€߃¶ ë ¾«¥{x;`Þ°›êºW±‹"›ðvÁ½a7Õt¯clÖ}WJö1rdS~Ø7¬&ú®•ìaàíƒzÂoªé^Æ.@ ŠoÁÛõ„ßUÒ½Œ<°oXMõ]+ØÅÈ‘Mø;`Þ°›êºW±‡ƒ¶ ë ¾«¥{¹2)¿lÖ}WJö0ðvÁ½a7Õt¯c E7àíƒzÂoªé^ÆØ7¬&ú®•ìbäȦü°oXMõ]+ØÃÁÛõ„ßUÒ½Œ\€߃¶ ë ¾«¥{x;`Þ°›êºW±‹"›ðvÁ½a7Õt¯clÖ}WJö1rdS~Ø7¬&ú®•ìaàíƒzÂoªé^Æ.@ ŠoÁÛõ„ßUÒ½Œ<°oXMõ]+ØÅÈ‘Mø;`Þ°›êºW±‡ƒ¶ ë ¾«¥{¹2)¿lÖ}WJö0ðvÁ½a7Õt¯c E7àíƒzÂoªé^ÆØ7¬&ú®•ìbäȦü°oXMõ]+ØÃÁÛõ„ßUÒ½Œ\€߃¶ ë ¾«¥{x;`Þ°›êºW±‹"›ðvÁ½a7Õt¯clÖ}WJö1rdS~Ø7¬&ú®•ìaàíƒzÂoªé^Æ.@ ŠoÁÛõ„ßUÒ½Œ<°oXMõ]+ØÅÈ‘Mø;`Þ°›êºW±‡ƒ¶ ë ¾«¥{¹2)¿lÖ}WJö0ðvÁ½a7Õt¯c E7àíƒzÂoªé^ÆØ7¬&ú®•ìbäȦü°oXMõ]+ØÃÁÛõ„ßUÒ½Œ\€߃¶ ë ¾«¥{x;`Þ°›êºW±‹"›ðvÁ½a7Õt¯clÖ}WJö1rdS~Ø7¬&ú®•ìaàíƒzÂoªé^Æ.@ ŠoÁÛõ„ßUÒ½Œ<°oXMõ]+ØÅÈ‘Mø;`Þ°›êºW±‡ƒ¶ ë ¾«¥{¹2)¿lÖ}WJö0ðvÁ½a7Õt¯c E7àíƒzÂoªé^ÆØ7¬&ú®•ìbäÈ¡é¹3„1-Æ“-Ò¢Ò«Ë4*]<ІŠ;m7c­fzVÓW@ÛQò¶…g½7 âLxj})"\…)d‡–³/(ÏR¯~‹‹§ ñ?èê,p×fäN®qäßÂߪí3«œy*œŒøzŠŸ=#QR4QEEP윶Ø9ø.Ù#¡Y ä„éš‹”Û/šŽŠRLµfRB9n’¾rá"?Œ»ã¤.˜æexê6ç.DÏ"ª#‘‡“ È9KžY…—©¦M…¨LYAx\wS[j%w@ÑšŠ¶2æ]Lòä(†’æïø¦È:ãÃÆÜ3™€ž»¢b‘‰8G$pgÈ¥A"޵ ò€o/Ÿ}©Zô £„ˆZXÛe´”Yà 6‹¥R,tô69²Q3ÈCQ3Þæ ·F͵d0Ó…ÒÂÒïtŠ2j1)ŒÉ¹@t'¤º€4ê(¹‰²óÐf )¡w`Üœ]ÍlDÂK¶›os'´Žv %)ŒcD˜¦Ï1ÝæóW]Ù‚þ-€›‘€»YO¸·Ï¦a¢mŒ‘›nÌÚDD@ùd9ò|SyÀB€ROšœ1&Ìm(iËŽüŽ·Ï4†Ý‘jc!–9AEÄÅ"b%Ü?؈ h,Œ?°•À+ŠJnmŠ’“®f’fw@ÇBɤH ?|)ÃHë&[—È~(Ð} ( (Šua¾³)l»Žä¸£ZbE²ˆrÔÊÔJ¡DÅ1·€j/ ¢€Žc•l.KB@v "šÙf ä'ÀrÒ"<‚4¢µ˜ŸkFY׈™Ü$šv2|d›lÒA_:e6¡Ö!¿1È2äåÌ'@QE Oš j|ÔQE@Q@PÔ…@Ô…QEQ^ž±í fgàÉCÀÆ~U'¨´{à‰øA—LîU m2ÕñPÓËÉ»’Œ?´-”>³JHÀÆ9àó‰o ]¢gY"ªEÁ)Ä5 GPd;„s Ì4SnÓÁ€’·á$§næP.n !Ù¨ØÊ™Àå˜j03Ý—/Æ/œr¯¡‚²ï¯(ùyÆð®írÊíWQT0O¨„É0ZDr6ynÈ@TPÅÄl2JÙ²¡ï‹™¼ü4š¢VM±©‘‡-& á¿!Ì9)tEz.ëø{•Ž ÁF¢Æ ÄÜ:Ê;z݉êœWQÀ¢Q8ˆ·ˆÿ8Gûp0˜Qã>1¿Ëû.m¿ÌõxfÏoÿœ6yì?ó|oͼÔÓ¥®ÆŒu òGÇÎÝ3¶EHãûeC2ä|Œ^Ba€ë Yâ°îͼdm§Ë&²ì”Љç¤å1@å6CÉ™L—š€¡¢½MaYött6ÛrV´dš×“.ž=pž¥ÓÒV(&~Rn8ì¹3å¬Ö ÙQìb Û—‰wâ¨áŸ)L×mµ1DÇÏ“»xêÈ9h?Q[e‹™ˆÄ'í§!¢!Ý06‰KfÓF€("ù€Úsüڳ˒›Io[Ø_kOJÛq“nî«8³™ò ¦ÁDü€Å0 b9òïüÁ@yÚŠô}™cÚ18Í}Ûf‰g)$ͶÚÝ~Ð9Œ–×A³Ü9jL¹˜yG—}g1âݵ {Zè%lJ¾I\l@+F&PS `r.jä 3=“¢˜‘ílKVm<ã†p HQMfAMʆL† Ãh%”L`Õ¼K¿ÎÄÅûB ËK ›»r>Ø»&äˆÝËXÄ´ VçPH9ypÍ>Mù‰¼ÙPw¢½M~ÙötŒ6"[‘¶´dbÖkΙ½nž•ÔÔ–0(~Sî(†üùså¤,¯Ó âî¤nÆ.e:2 B ·l@@6Gd;2Žòñ¿“02tW¢fí,;ø:ÝÏ­qNmÛÈ6<ÊèY”[‰¶ÊDòSNáß¿x†CTYœ~ÖÚqeØîb£QQÔ”¬„@,਄éA6Bo+Is Àƒ¦€ITÖƒåâç¯yIXH¦ÑQ«*Õ«tŠ™™JÒP6Bç0ÓŸÔ°îCÂÙÌìïÍà‹+qIÈ·)Ž˜òvV KH¢‹½Sù×y¢Nn!ÊÑœ¨Ý«ç‡]%HL™€C2òÿ4¿þ¼•ø5× [®±ÉÒðƒ¦lÌ"—= 9n/›Î5Ž_ÏUŽ+¿cö­µ废³¼—oe^§*ÒN ûßñR¦ÖVã¶£¢®sÅ>]۹Ø»# $Ê:€M˜ò€ë0‡Ÿx€o¡k†ÊxÒÎ3é¥Ðq’j¤j¡Š')SÌ‚9â o Ãpü 4·uUn¹+¥eö£üª˜oƸâTŽZ_ñPb·¾¡\›]=pfªL´X&dŒaSJJ&P(w“”rßYüCž·.:¶ÑBQD¥ašƒs23cýðD)‡_ÅO?ÏŸš±j¹=^‚j8áºûõ¯ÌÑ”)Õ;Ž%¹+‰Zí[’¸•­Öf¸ŽUk‘_=u«\Šùê홢#•^ZäSÏ]jò×"žz¹fjˆå?ƨ©?ƨ«(ÔEOš¢§Í@EQ@EEQE@Q@PQ@QE?%EOÉQ@EETùê*|ôTEHÐEPQ@9øÂav$C'€â~à,’ì…% B*àáå‰tŽzÉÈ">WæÙ+ŠXowNâtD¤ƒ¹éXÂ4NFf&Å@£)ñD>öLòË!åÏw™¨ öÕbÜ.ǯ9—PG‰‘ðÆîhuʹÇ0—"ï}ôá¿py#¿xWÓ .Ì5·¯[µdü*£´( %Û‹¥X“M¤G1C—qrÞ")JšÓîñRÂuxa¬¹®‡+%o‘óy]³[nmm¶dXÚJ mf ä"!¬3Ë~Y9ËúÓs„ø•„¶¹ «¥gñèø:¡¶@Ë p>¡.EòHaÈ»“’‘u!Ë@?¥qZÚŽSdcžEkiÛÊ DNC%­º)NSå2ÈD3/.ðý\ö@À_«Z’ïfdïc˜TAFgD¬Šp>°1ñ‡ïªiÏù¡æÎ¼ý@PÂ\C°à­(Ör—¼Á𑱉#'ÑTâ^DTþöMYˆÆ‡.ZÏÚ—‚÷ ï[&BIki)Yƒ¿þw"ZÒ1È™ï ˆs ù豈Tù¨ Ë è²îÖW,Z-VxÏ^ÌŽJc&:Ó10(€ò|ü¹W~(_“‡p!54Ù‹w5+R•¡R s˜@Æ0ç™ÇÏòVN€ = ~aäÝ»‡KÜóOb¥,ç —Á’duJ¹ )O¨»€¡³!‡”ÛŒQÌ»¤16ÈVk'7šWSvñFðU¿„(VJ&`øžFG0fÈ7çɾ¼ßEèü%Ä; ÒŽg){Ì¡’0qÀíN%ä@åOïdÕ˜LaÈråªë`m /º“€pF..½ŠQ¹Î c ÀQ }ìªxç»wš#EÂÇ©+Fv÷ŽÑ}¶JM®õ¸ tÌÝÇ!ÀusÜ9”G~¯ÍKÚšŠ¢Š(j|ÕSæ "Š(  Š€¤*¤(¢Š(½¹‰–ì&áäbb3·…¿l)™‰ÜëZtŽdT7ˆù\›†®Å;1eqIIƒvR0¨Æ[镪¹*TÛ®M _ 5¨jÓñ¿0ל( =aäí½`­tÌ=‡“²ŒQ#tÙb¼4L]ÅÏd˜Ž¬¿œ|ëçŠöä‰ñvJUÉ£W¹cÈ„[s"s™M ÖH "@(ïO<Ä3rî¤ ^滭矋^Ïm!®qŒ©Ü9k±P4&&r :ĺøÂnßù†¿893†Fµf-\CdV¢íPY´Â-Gî.d)À†9w2Ô`]ꪀô<Ö.Y­±6Á< ¢^x[ŠCv:zòënº¨•Hå“&ÑB/¥"Ž‘ÀÊf021~AóuÒé¿­7¼Kø,¶Óƒ^ ãàꇃhð]\¥òòÙâjäüážçân|Yšœƒwáqîv¶f&­(&Cy&ÈÅÞjÂMèÛì@‚²å.)­&læŽ$É6†PÒŠ%8y%òJ_Œ!¿?6úZÛ‡ÃÛªNrNùœ–€”xøîÐYº;vâ>£Å)Dú·›!Ìx|™ ðƒ¾ߨ„yh´”#íˆÑ¹Ô.“*R˜Æˆy³Ž_˜“’¶XSÙ|_@Ûw|›˜¥­©ÂK3:mN±\Ls‚~NzGR†åÝÉùòDÑ@>mlW¶^߸€ò|\Ųºšø+gäDTQ¡ ™“.e.ýåˆåžò‡öÕ>.]–UÕ9cÀ¶~íhHTQe!0(5VHE2œå(€›É) `Ìy‡pùÓÔP XЈ¼Y]»¡ž²D…".eX¦DâÌ Ö\² Û÷äê/ÌCµâí[.×´¸ž rL²^0p‘Õ¤ç1R7•——îË"——Ì’¢€ôuõŠv ÀÞ’–ì‹Çs7‹Ví•d£C& ÊD…# Ž>I¼“âˆïË;“²lldðÎ-û —ÊÞ :1_°9`’9«‘Š;0 ò¿ž?w|™:(½³w[Ìþ EœæCDãéB8l×b ëL ØDutñgÜ"»ó…~0òì·m̽c¼a²¹¦LFÈ·T;$ut†åÜ"»û)WESö˛è¬ež"…¿3.¤Ë¢Ã9p¦BÄJÒ"9æl¾5 ªh&]SK6ìÃK†uta_? ¥Óds E ¼R Ì]@‘~Yˆ&ûþ;¡~èq»¶N|Aâÿm6|Ùj×´ÓË–Ó~\º|Ùî¯>|•¦ýÄ j"׳-KúÒí­é/Ú­Ì€@PÇ!¦ß»hlÇ/“,üÚkÇ,1‚½¥á$<˜¼Y ÕHåZ˜€ËB&HDN>I¼“ù";À?´<áE!ËEËEîÙöÎ^K³6ë9\ÿ$SœÙ1ÈxîÕUkÚ7Q„tÛSýÉOuwÝ_†›ûþYW<¦¯ ‘»÷j§ M+KîëTø“µk*ï7%±0?ÜÔ÷W ÖênKV`ºÝUËùê±ÅvlºÈÕ¦+/òZ¯‡wѾ-¥0?ÝMî®ðÏ ñlùþìj¥uUn¹+§b¢îÌÊq¨ñý¿É _ 1ß͘îã\já.%<¬¹ÿ`5™sUËùë¥d­{šËü•¢©¬S18Cu“1õ5̦ âòXóSÿûXõ¹+‰Z½g ·2ÉúU0[G’Řú ÷×:˜%‹ÉbL}P{ë­r+ç«pC1̼¯ÔiˆÝ±lGu…1õaï®sàV/yX3@¾úÁ«Ë\ŠyêÔLóÃå~£TTÀlaÝ`L}ûê8…Ææ>}ô¶?ƨ«&¹áò¿Y¯„dñ Œ=Ì}ûêx…Æ¿'ó@¾úZTù©rkž+õŽ“Ä.0ô1ô ï©âz?˜ú÷ÒÒŠ\šç‡Êýc„eñ Œ=Ì}ûèâz?˜ú÷ÒÐ(¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8F_¸ÃÑüÇÐ/¾Ž!q‡£ù _}-( \šç‡Êýc„eq Œ=Ì}ûèâz?˜ú÷ÒÖŠ\šç‡Êýc„eq Œ=Ì}ûèâz?˜ú÷ÒÖŠ\šç‡Êýc„eñ Œ=Ì}ûèâz?˜ú÷Ò×䨥ɮx|¯Ö8F_¸ÃÑüÇÐ/¾£ˆ\aèþcèßKP¢—&¹áò¿Xá\BãGó@¾úž!q‡?ÉüÇÐ/¾–•>z\šç‡Êýc„dñ Œ=Ì}ûêx…Ææ>}ô´©\šç‡Êýc„eq Œ=Ì}ûê8…Ææ>}ôµ¢—&¹áò¿Xá\BãGó@¾ú8…Ææ>}ôµ¢—&¹áò¿Xá\BãGó@¾ú8…Ææ>}ôµ¢—&¹áò¿Xá\BãGó@¾úž!q‡£ù _}-*irkž+õŽ“Ä.0ô1ô ï© Ææ>}ô´©Z\šç‡Êýc„dñ Œ=Ì}ûêx…Ææ>}ô´ )rkž+õŽ—Ä.0ô1ô \aèþcèßK@©óRä×<>Wë#+ˆ\aèþcèßG¸ÃÑüÇÐ/¾–”.MsÃå~±Â2ø…Ææ>}õBãGó@¾úZÑK“\ðù_¬pŒ¾!q‡£ù _}BãGó@¾úZ ¹5Ï•úÇËâz?˜ú÷Ôq Œ=Ì}ûémQK“\ðù_¬pŒ¾!q‡£ù _}BãGó@¾úZQK“\ðù_¬pŒ¾!q‡£ù _}BãGó@¾úZ Oš—&¹áò¿Xá\BãGó@¾ú8…Ææ>}ô´¢—&¹áò¿Xá\BãGó@¾úž!q‡£ù _}-( \šç‡Êýc„eñ Œ=Ì}ûè Ææ>}ô´¥É®x|¯Ö8FO¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾§ˆ\aèþcèßKJ)rkž+õŽ—Ä.0ô1ô ï¨âz?˜ú÷ÒÖŠ\šç‡Êýc„eq Œ=Ì}ûêx…Ææ>}ô´ )rkž+õŽ•Ä.0ô1ô \aèþcèßKZ)rkž+õŽ—Ä.0ô1ô \aèþcèßKA©¥É®x|¯Ö8FO¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾Ž!q‡£ù _}-h¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾§ˆ\aèþcèßKJ)rkž+õŽ—Ä.0ô1ô ï¨âz?˜ú÷ÒÖŠ\šç‡Êýc„eq Œ=Ì}ûêx…Ææ>}ô´©¥É®x|¯Ö8FW¸ÃÑüÇÐ/¾£ˆ\aèþcèßKo’¢—&¹áò¿Xá\BãGó@¾úý¡€Ʋé¢KT s@O …Ëy„ÀœG ¥•¹5Ï•ú‡ !ËEËE[1=Ñu~oìøe\òšµWWá¦þÀÿ€VUÏ)«Âd¿¡‰1ýL­_ÏUŽ*Í=V8®Ý‰Í´+U[®J´uUn¹+«bQŒ­sUËùêÅÍW/ç®­‰V3‰nJâV»Vä®%jý™Z#•ZäWÏ]j×"¾z»fhˆåW–¹ó×Z¼µÈ§ž®Yš¢9Oñª*Oñª*Ê5S権óPEPQ@Q@QEPPEPQ@OÉQSòTPQ@Q@>zŠŸ=#QR4QEEPQ@54T‡-EHrÐ@Q@PTùª§Í@EE@QE  ÔTÔPQ@S樟5QEPP5!P5!@EQ@QEQE@Q@PQ@SP54QEEPQ@QEQEEPMEM|•?%EQE‡--¼&¹‘™ðF…!•1þZ…L R“Q„LaãæªwÔˆˆÿ †öËNÖ´éþ1¸ý÷÷E+äÂ9eû+Ã$T*Æÿ‡ßMGÞ¸a¡Ð½­&?çP~ÛgÚÕröœ ÿ@ûy—k\ëª`ó身×r 5©'º»OûÿƒÞt>îlùaäwoþ»mUÎlÉ Ï-Ï×q0í«àåâÁÈFÿ­º~ê®s ¸äÚ~¶‰}šéظ»—ïþ qß:Y#þ{mu–?·®¬Y±Ïøu±ÖxîÞ¿-•–xFQÑéø?ø^ÊmÙÕ¸Æ 7¡¦#½L;ŸþP´zÝÞ+˜øspoÿ(YýoŠï5ðm'8ôWð(Æ.v™u¶P­Ï³L¿æÉ=Å Ã1Á_ÈÜ>)2ñnßÁ¼/ÄMö;m:¶zöZuéß§<òßV s8C›ÐÕ©ðÞáÏùFÎëŒWy¨âÞáùÆÎëŒWyªƒÜ’9þ ìfG d}ØÍ;:±Y¬!Íèká-ø·¸~q³ºãÞjx·¸rþQ³ºãÞj›„²> ìfO drüØÍ;:Vkszß‹{‡ç;®1]æ§‹{‡ç;®1]橸K#èÐÞÆiÙÑÂYF†ö3NΕšÂÞƒ„¹âÞáùÆÎëŒWy£‹{‡ç;®1]æ»0ÞDóϘÈÇÃ,€ÀL*–Å8×*&`1Sä)€@sª©Ùg®›4hÒ$©=™ü¸¶ÊLfɘÂ&2b""cæ#ç¬>öbÿÝÑV•ï¥?iÑŽÃó×®óG÷Î6w\b»ÍSð–GÑ¡½ŒÓ³£„²> ìfgY¬!Íè8Kž-îœlî¸Åwš8·¸~q³ºãÞj›„²> ìf%‘ôhoc4ìéY¬!Íè8KŽ-îœlî¸Åwš8·¸~q³ºãÞjŸ„²> ìf%‘ôhoc4ìéY¬!Íè8KŽ-îœlî¸Åwš8·¸~q³ºãÞjŸ„²> ìf%‘ôhoc4ìéY¬!Íè8Kž-îœlî¸Åwš8·¸~q³ºãÞjŸ„²> ìfG d}ØÍ;:Vkszç‹{‡ç;®1]棋{‡ç;®1]æ¬T·qM" ŠaÜPÌLk=0íØVaKŠM3˜‡iS”D SB´ùïU )§ÝoAÂ[qopüãguÆ+¼Ôñopçü£guÆ+¼Õ7 d}ØÍ;:žÈçø47±švu5šÂÞƒ„·âÞáùÆÎëŒWy©7¸~q³ºãÞj›„²> ìfXÁ9ºçÞœ¾ÚUÉL‹+uºÇ)@ÂR$"˜€gù•šÂÞƒ„èâÞáùÆÎëŒWy¨âÞáùÆÎëŒWyª~Èú47±švtp–GÑ¡½ŒÓ³¥f°‡7 á.8·¸~q³ºãÞhâÞáùÆÎëŒWyª~Èú47±švtp–GÑ¡½ŒÓ³¥f°‡7 á.8·¸~q³ºãÞhâÞáùÆÎëŒWyª~Èú47±švtp–GÑ¡½ŒÓ³¥f°‡7 á.8·¸~q³ºãÞjx·¸~q³ºãÞj›„²> ìfO d}ØÍ;:Vkszß‹{‡ç;®1]æ¤0ÞáÏùFÎëŒWyªnÈú47±švu!rÈçø47±švt¬Öæô%¿÷Î6w\b»ÍO÷Î6w\b»ÍSp–GÑ¡½ŒÓ³£„²> ìf+5„9½ sŽÃó×®óG÷_Ê6w\b»ÍSp–GÑ¡½ŒÓ³©á,Ž_ƒC{§gJÍaoAÂ\qopüãguÆ+¼ÑŽÃó×®óTÜ%‘ôhoc4ìèá,£C{§gJÍaoAÂ\ñopüãguÆ+¼ÔqopüãguÆ+¼Õ? d}ØÍ;:8K#èÐÞÆiÙÒ³XC›Ðp—<[Ü?8ÙÝqŠï4qopüãguÆ+¼Õ7 d}ØÍ;:8K#èÐÞÆiÙÒ³XC›Ðp—<[Ü?8ÙÝqŠï5[Ü?8ÙÝqŠï5QÂYF†ö3NΣ„²> ìf+5„9½ sŽÃó×®óG÷Î6w\b»Í^b‹UÛÖ±(ª£ tâ-@Ä- ª% JQ9ü¡È1¬W d}ØÍ;: Y‹JÝKu1Á?¨¢EÏ÷Î6w\b»Í[Ü9(ÙÝqŠï5MÂYF†ö3NΧ„²9~ ìfgY¬!Íè8KŽ-îœlî¸Åwš8·¸~q³ºãÞj›„²> ìf%‘ôhoc4ìéY¬!Íè8KŽ-îœlî¸Åwšž-îœlî¸Åwš¦á,£C{§gG d}ØÍ;:Vkszç‹{‡ç;®1]æ€Ã{‡ç;®1]橸K#èÐÞÆiÙÔ…Ë#èÐÞÆiÙÒ³XC›Ðp–ü[Ü?8ÙÝqŠï4qopüãguÆ+¼Õ? d}ØÍ;:ÐDFb,¼rR16Bò •Ïfá­¨’©!ŽF*"€‡ö€ÑÅ4»¡Íè8N~-îœlî¸Åwšž-îœlî¸Åwšâ—¹"‹9hVQî@3]@6Hàü¦H¸øK#èÐÞÆiÙÒ³XC›Ðp—<[Ü?8ÙÝqŠï5[Ü?8ÙÝqŠï5OÂYF†ö3NÎŽÈú47±švt¬Öæô%Ç÷Î6w\b»ÍO÷Î6w\b»ÍSp–GÑ¡½ŒÓ³£„²> ìf+5„9½ qŽÃó×®óG÷Î6w\b»ÍSð–GÑ¡½ŒÓ³£„²> ìf+5„9½ sŽÃó×®óG÷Î6w\b»ÍSp–GÑ¡½ŒÓ³©á,£C{§gJÍaoAÂ[ñopüãguÆ+¼ÑŽÃó×®ó\R2WoƒxÆ‹? nW-öð “Û"lô¨LÒ D‡#áʹ8K#èÐÞÆiÙÒ³XC›Ðp—[Ü?8ÙÝqŠï4qopüãguÆ+¼×i+‰Ô{ÉÐìWdËG…¸N±“o¬t“Y,‹¨wyf<•øB^yÃ'/PŠŽU«]>± ›ˆê‹¬À–EÌw|£JÍaoAÂXqopüãguÆ+¼ÑŽÃó×®óTü%‘ôhoc4ìèá,£C{§gJÍaoAÂ\qopüãguÆ+¼ÑŽÃó×®óTü%‘ôhoc4ìèá,£C{§gJÍaoAÂ\qopüãguÆ+¼ÔñopüãguÆ+¼Õ7 d}ØÍ;:8K#èÐÞÆiÙÒ³XC›Ðp—<[Ü?8ÙÝqŠï5[Ü?8ÙÝqŠï5OÂYF†ö3NÎŽÈú47±švt¬Öæô%Ç÷Î6w\b»ÍO÷Î6w\b»ÍSp–GÑ¡½ŒÓ³©á,£C{§gJÍaoAÂ\qopüãguÆ+¼ÔqopüãguÆ+¼ÕG d}ØÍ;:ŽÈú47±švt¬Öæô%Ç÷Î6w\b»Í|_aýÀÑ’îÌæÚpD2§#Kš9ʺJ˜JšK˜æÈDt€î5Vð–GÑ¡½ŒÓ³­«3¦óàåg“ÕÜmÔY³$1Ó$kC¦Ù”º€¢¢‚òj–°´µ˜³…Å]øá^$ÅrÑ@rÑWŒO§øÆãôsßÝ¥û®Q¦Œn?G=ýÑJ_ºåðÉ?Á‡õú}1ýÃø}JÅüõXâ¬×óÕcŠìX”í ÇUVë’­U[®JêØ”c;pÿò‰m~—kÿ8µµVbÏÄ›ªaõÈY*íñÕ„1Îpаœ¥ Ds6ðÝ.¡e„e0‹fîVf±VI5õhÖQÌ¢:LQÜ9/›~a˜U}Õ(¤äóé…›7l³ÅŒ²©¡«F³o0†£wŽc–yf;² ‚»6Ò¥Hk­žkjÃᥗpÔjêFPÉNíÁRPP ¨@ˆd>Hsy9dÅ>ŒCÌ Vn>,ñ¹Ýçnšzº„*BÜÊ SHc” Rk€‰HïÎ’â»KÚ0ÖÚ±qÈ7‡×àË#µÚŽÐsSV¥£¨Ù|ÈCÉÈ7W"·sž/xâ¨ßðßðŸ¿xFß-:óÚhøžFZrË~Z¼ª½Ev™°•¶­8\SÃWP ÷l£V®¥|)R¸Û.R´À ³”T €Ä6àÞ5ÁkÛQö~&v9G¶£äjäŽHÇ®dD¦ŸH“2ü]YÞWÅÒå“xÎMh¸‡Sl’*M¥—EC8 4Dà™ŒPË#‚;ƒ}UEߣmKŠÞ4dsÔîï9…q1RbQ*€PœDá™G1Õ¨7U¨ M3U†ç·n2^`Ú×JÍ,§ŽYÉ;È˦?UÞC„&}`"‘Gvbù”bËচŽm¸©"’󌛥”ªY‰¶£²Xƒ¬tdÒ™DÙ˜qv%èêΈ‹ñ³ǹðݶæçþ0…Ù¨Lµd\Çx†ÈC~|ð7˸«MkUÌ4DÄAß„‰P|E~öà £YE%?vC˜~j³ 53J· sà‹Y[^ÕgÂF2¨ÇJ˜‹¹:‡*¢ŠÅ(ª$.³yò~0Ž(V'‚Åãkr1›ö†ðbø*«‹˜‚ e³Tç6Fò Àºwg˜Ž¾Å¼ÛÙÑ“× ‰§Œç#×AXdcÔKÁœaÙ¨A쀄/–Q _çR®¬@L>jŠŸ5l Š(¢€Ù`÷ãkßõrsü)ÝS^?ÊÈ~cû¢5sƒß¯ÕÉÏð§uMxÿ+!ú5îˆÕGýÒÿåüÑ—å)¨¢Š¶bQEEPòTTü•¤®X&n¬&Ó°µÞšÏ‰M0.s>F!ŠMžñ€  aÉÉ4ͼþ×ү㔎iÕÌ‚ÌU]6¹›„ÒeDt&>G1óÈDsZY_÷ÓÛÅHS¸ˆ‹‹43ãÚ†Ü`Ÿñd6ÑSç§3d`ÈGPæ#»+9lW¸_Þi]àÆ%¬¸¶¯UE‰$SbUÈs˜¦Ì¡éþÐ ´¨"D–7E³|?’™Q^j= ݜ]Ä“à~‰ÄJ|‰á œAÒaÛ³KL4´M$ÕݯkÛ×Õ®“tÕtvÓ«„¹‹¤6†ÙÄL žDÓ¿pf;‘R×`ºŠq ÝØ”]ƒ¬&\ :ŠSe P0´”@3 Á–™Î0J Òêëµ­ˆ«…È)ªIš.B™B‰Nrë00€•£=ùÔ¸bîäÐжÛWT„y÷÷—`šnœ,š-‘nr¦ ‰Èa9Œ"9‰²ÝL\,µãmŸ„ý„¤>Ô‘óp£.‚ ŸYÛ‚Ì—Í17ó²ŽB;òÏå¤Ô5è핺»#;‚æpÙ¼Uþ¡€ÂC$¡ lƒ2ˆ‰DC<³«XÆj[j)5\ÙQФèª9Ú4(‰Çd˜ ÂA frœÙ|¡„-í<.·^\ñøpµ€Œœy&1Sz´’N<UŽDðP.í[1ÞŒaË5Œ¾!¾—ƒa'íÌ|YbZHª‚†p“b€J´Ùj0äq& åÈjñ¦5Ï¡z´½Mo[KÜh%²RAVë ÜÈRÌå@€:œB”weɘ7bJˆ¸? Ñžâ¡ÜAÇÈ•"Nr9:åÀÎD¥)öj@ & "QÌèLVÙÍ£dðC$¼ZVn8ŽU¿ƒ;rR«9쌘ª$P„Ž‘8À&0‰„rË1lß. Z\¨BD9‡Ÿü25À.(€&  !Ѝ*DwœGåå®ÆØŽéµµrÛèÛ6êlî-ˆ:Ù¢ºb"±ÀªCAƒ^f Œ"'ç•dáu`¹¸¢­[2ÏBFÛF}ÌäB2ï\.ítÅ$Ö1€©¢ ¥¥Þ'æ#É–êÔÄaͧ ‰Ø™iÎFŒÓ¬–*$ºbB&r†é[!ÔSd €0³ @|”l[)HHIÁˆ.ˆå¤TTlMZ€³P r„D  <¹7WE»‰ó‘Sw$ÓÆ“oî6ª3V@ÌQSøÂP€P6E” ïÎ1Ââ…·ä°=­÷„+ô®#C®‹eÖQ%ˆ-öÅ>JœâMÃü”¶­_ ÝqaÅÿ‰¢¼ÃücáðŸËN¼öš?‹ò2Ñ–[òÕåVR³…5Ú@QE (¢€*j*h䨩ù*(™P¿’«ôÏþÆ–´Ê…ü•[ÿ¤nð¶5RwðŸÁü™”=¢Ø9h 9h«f'¿Óücqú9ïîŠVMŠyƒrµe7(Ùg¡$^„.c˜ä9ñ­bŒn?G=ýÑJ_ºåðÙ&ÕŒ4ëô>òj»O©Øµãtô–õI(ú× ×µÐÒk“õK(\¿ž«W^É·Þó(Gcî-W¾î‚ÿJ.ŸÕ2 é\+âÐ_éMÛú§ý*•ÕUºä®Œ ã›)Çg|EºúUy~«@ÿú׸“tö®öýWŸf³.j¹=t¬¬axæÊÑBb˜›t~6__ªåSìW2˜¡tô²ýýW:Ÿb±ërWµzÎ^Íã›ÔÑ6ªbÐÒÛÿõ]*}ŠçSn€þ—bêºÔìë­r+ç«pJÙ`ózšbfèø±tþ7b/[Tìëœø·tö¿úÞ§gX5yk‘O=Z‚NÅ÷<Þ¦¨›Åë£?Ç Jë‚•G×G<1+® vT¶?ƨ« Ž7©®ó¨âµÞ²k(Ó‰êm1.åD. .£%¸5¡˜ùÌ篟×G<1+®*vUœ´X3{j^‹(¤‚NØÅ åAÈ /›$tÖOH‰Àv¤8dbé2`"Ì2¼w‡Qpvœ„“{e&ãÔ|A±Èåt ©DQe0¢&· yCg˜gDáºÞúno–ö8¼ûq½tsúâ§eG×G<1+®*vUeb·°îLnø’®d-ƧA³ØÇåd²bIíÎtÎd”ÀpÈÁÈ]eÈDàbÕ\Žâ$¼î¿Ö¸fdî…T³ÄQ:MQ0µLê¨dL ©š(€™èÔ&ÌÛµBìb¨lÛ‡uçVÚQnUì§{kàNúvŸ¾7®ŽxbW\Tì¨ãzèç†%uÅNʱפ)mû‰xÔœ‹¦û$\6XI TAdˆ²Fæ:DH¡DC1Ès Æ©ªíœ¤½¤*8S£ßÚõ1q42¸Þº9á‰]qS²£ë£ž•×;*ZÑYì68<Þ¢ó\o]ðÄ®¸©ÙQÆõÑÏ J늕-h¦ÃcƒÍê/1•ÆõÑÏ J늕O×G<1+®*vT´¢› Ž7¨¼Æ_×G<1+®*vUo]ðÄ®¸©ÙRÖŠl68<Þ¢ó\o]ðÄ®¸©ÙTñ½tsúâ§eKJšl68<Þ¢ó\o]ðÄ®¸©ÙTq½tsúâ§eKo’¢› Ž7¨¼ÆW×G<1+®*vUa)(þã¶a.9û¢MU >È™—3â¢T£Ð>¤ÄJ]a\@ܹè/ÉJZeBþJ­ÿÒ7?ø[Ñ1-gefÜ+¹÷¼)¶Å°rÑ@rÑ]#ßéþ1¸ý÷÷E)~ë”i€ŸãÑÏtR—î¹F¼2Oðaý~‡ßLpþR±=V8«5üõXâ»%;B±ÕUºä«GUVë’º¶%Ê×5\¿ž¬\ÕrþzêØ•c8–ä®%kµnJâV¯Ù•¢-íIR0#†ˆCD»“xªDjîKfdš”ÚÃJ¿zò„Iåq@£òæX¢ÄYÇÂûHĦeV,‰•ª¨æPK!KïF8+¨SÝ–à5Á¥®,_4¸Q‘MeL™š=dR¨d4êÖS$c”§j.ý@! 2åø]r‘jÃFÁCűUuÅòŠ*¢ ˜È)Œ(EÈ5x˜sß•]³4EÚeUå®E<õÖ¯-r)ç«–f¨ŽSüjŠ“üjвDTùª*|ÔQEË¿^ÿ«“ŸáNêšñþVCôkÝ«œüm{þ®N…;ªkÇùYѬtFª?î—ÿ/挿)MEU³ ( (Š(  (¢€Ÿ’¢§ä¨ ¢€¢€û3p£GˆºH©DT*…R*¤Ì5à%0nÞS€òV¯8År“Höé°›]&ÍÓb‰[ˆª%!v ]™ƒ"`%[ÄÙˆŽxêßÊKØS——DÀÜ)½t·…=A²&Ee„u)¥qP B˜Ùñfç–ü³¬_mAcuÛqx‰¼Š(@;YTQm@@[&ì­´&bNtô€uŽzŒQò‡-9oòk.ÊiãÈ9 ·Qc°*nP:[1T6[Q)„ © _¾y–»™\ñM~HN¬ù¹5jESÚ™Ún‡YŒ¡D¥Ô‰K¸ 9Gù¹•YqÅ«ÉTÞ¶—réè•‚fLˆ®T"™¶À'9A¹GHDâƒNf…TIq;i ö὚¯p=tFIºµJ0€"¢ ,QCHî1…2¼36š æ.ÝU‹&Òî^ÉŠy&ʳ* ÅQû΢¨}f ùî.À>V¢—M3vÚĹ®Û¾ ÄÙgädTseؤB4"ÇÖ¡ÄÅX †£”¦(qŒ<ÍøþYãih“½îÒʤ«2"‰\äΈ•CfSPˆ!ä ‡IPÔ+z6ØtÇm7s/àëŠI „h¸— ¢† LÄCÉÖo$|žLúѳŬ¤ò ˆG4t,Þ®Š;s™}g!SH™” aÙ¨;ÌPÈ‚9òÞ[7ËHÛN>5½Ãv[Ž›rAé!$DÊàubÀLĪ r€ü® ªÚ—ºo,2ÁpÉ„škdÁÓe€Ê¹¥´œT™k.` lÃâÒ®¤vGÀ#‡öz­Ÿ¦á’²Ò)(ù´ÒxT VfЩÁ´9ELP2† ŽÜYl;‚c+rFò2‹ÛJœdL1‚R XÔíN¦³¦Q C3n8€jªùé;)ÅŸoF¸žOÀ%\.åÊÌ’Y%ÈL¡H y'.ÀÌ@Ùæ*’»¦.{QõÁ‰$s6DîTÎ1Åô³)Îí'B ýÿÉ2@˜ uæd7’|mû]º•fµ¸œ&ÖmVëÆIx¸¦U#ŠæD‚t ¦Ÿ%dÄ5˜2 ÃWÅ»jÚ…‘³ä.;Äqcß·lº` „Y5LC$;Bê>hŸ2HoÖ#äÕÔ=Ïj1¸0ÞDîfδ™D¡–f9ªè/¿ù@&TS6Œ€ l„G@R§#n7°' Òy*£×2í20L©¹T6ØD‡080é8Pê̳¼|«0UŒ€ÈGÉ3Œ×:˜›C¦`95I€é¢a Ù€ïª@å­%á' þÔi¼‚Žc#Ñà9jD‰¬Î_4ÌU & ×1w~ ^VE͇-d»"€¢€©>j€©óP@Q@PQ@EE55/[ôu­þ ´¦^*þ ·èë[ü)iU%;"ø¯úÂe Oš j|ÕlÄŠ(¢€( ( ¨ "Š(  (¢€û2E7Pn³¤Z&ª…!Ü,$9 Ì)Œ £¤¢9àÝLÌCaf\“­ä"¯Ër1£š2œ©$äÆðtM¨±É€fDɘeñµylŒÔP;ÔVY©T(¬š*‚g93òŠS‰L ÀJ`ßòV¢à­ÜRšƒhÞIXx©U˜Š» ¸Xˆ¨$8í )DÚL!ä0e˜Ò·³QÛÃHši:R”íUí¯C$÷ )g¶b÷Hȱ¼-”âÜB¶‡ñy5Œá$M"˜$rz ’œ<‘ÈäÞQЦ5’Äc@ÝvrQM$Ñ’tÒOÆoEú‰î)L¢˜Ç. nPùˆæe.Û(Üh\¶½¤ÑÉÙÃ=]¸ªýâA ˆ©²2ª¬ šd)Œ†yj)s0ï‡6uÈÞy¤!£¶hÛbºj¤²ažjRS1I³0Hi6b sì¥eœÒÙ­ÉѵÙNõNåÞû1Üfâx œ,·–¸ÛvýínÅǨü¯ÔMÛ™Wz)@*_äòdÉCf¨ÆÈ¹˜t…~.D,9¨”Ì­Ùk–x³b/ŒâTQ)$šE1ð9“H¥1Î]æ(BI«.à‡^19¦”¢‚›'D‘n£UL)Mü ‡ƒH˜º„L\ó‚¬qbÈVËºåØ¤í‚ñÍäÜ4i¢Y«—;2(`(ªšG¦m ê!rà Õ•œ¼ºŽ`¶uukzßF«¾›û·:öt!· ´ØYðw<{ëòÜx´ÔqY"ª*I"VúWM}F(ÇTòÑKp |ažfí>ÊÕ´YïŠplü àøL‰…Ù‹˜Sÿ&Äu,¨{@n(‰°å±3p±¨7‰Ag¢ÕÄÙé(ª±Š@0ä9<Ç!È7Uíóe«îÓŽŒ’,¤ÌQYšª•ÁŒã—CïBB3‚%9CÊÜŒ`ÈG(ì,a¶£¶Šóuí‡s»JµMÜ=:ö„Ý; úïðåíÑ}KH]ovüfèIH&vºœ¦éLŽ1&æªDÓ䆒æ¨D ‘¬E`˜Å]µ*XÝeb³E圉œâqHùÇ(&³ÁÀ'7•¼2Â\tü~ý³SµÚ&Y£ä%@Š '6ÌÂ9Ùä;· u%‡×j°ËJ§™ÑA ½Yxˆ¹M¾[c7×µôˆP“,‡<ò¬!“–‚Kv“¥8—jTTtí¦çNÞñyà|ñ%Âon•_%5*UÒ&“F&àˆ7! ³M þA@ Âeåç–j´èX7Zðg˜J53·#Aztâ>VÀ…ao¯k³ÓåkÓ§-ùåYŠêKÅgråœU»»»è`ëÚŠ(«Q@QEQESQS@%EOÉQ@Ê…ü•[ÿ¤nð¶4µ¦T/äªßý#sÿ…±ª“¿„þäÌ¡íÁËEËE[1=þŸãÑÏtR—î¹F˜ þ1¸ý÷÷E+&‹x”Ïde\sÖDcˆ©~ìŒ+Gv^`ÿÖ¼6IVÆ×è}äÔJvÞS0¿ž«VÉf¸ÿ¥§ÿT2cÿ¸®¢íqÿJÜŸª 1ÿÜ×^Ê‹½fŠÛ@ûÌCª«uÉ[Åá­s¥.ŸÕo¦?ûªá^×7úNíýVâcÿº®Œp®ôSŽÒ~æ«—óÓ {r×ôåú­”Çÿw\jÛ¸çþP½¿U¬Ÿ{®••½šüÈ­H]­É\JÓKR×þP¾¿U¦Ÿ|®e-\ÏïßÕh§ß*õœÍ’üÈѸV¹óÓ)K:×óëÿõYé÷ÚçR˵Çüû¿UšŸ}«pMØó#LHY«Ë\Šyéž{"×ü7z˜Ÿ}®sØÖ¸çü3ú”Ÿ~«PNØ/ÌQ&+ñª)–k×ÏðÌJêB}ú£€v¿¦bWRïÕcn—çF»¬ZTù©“À;_Ó1+© ÷êžÚù~‰]HO¿Sn—çBë”S+€v¿¦bWRïÕ<µý3ºŸ~¦Ý/Î…ÖS`÷ãkßõrsü)ÝS^?ÊÈ~cû¢4Ä·``m·/¤˜§ˆ’ ÉëZ$A3Ë5›”L ;8” *‡"˜rJàRÔ†•I«¹Bâ  Ñº ÚÑ#„Êd’"y•C; ˜F{ȹy³ªînÇïÔw•(×è,h¦WíLÄ®¤'ߨà¯é˜•Ô„ûõXÛ¥ùÑXµ )—À;_Ó1+© ÷ê8kúf%u!>ýMº_ ¬ZQL®Úþ™‰]HO¿QÀ;_Ó1+© ÷êmÒüè]bÖŠep×ôÌJêB}úŽÚþ™‰]HO¿Sn—çBëß%E2økúf%u!>ýGíLÄ®¤'ß©·Kó¡u‹@¢™|µý3ºŸ~¨à¯é˜•Ô„ûõ6é~t.±kSç¦OíLÄ®¤'ߪxkçøf%u!>ýMº_ ¬ZT2xkúf%u!>ýSÀ;_Ó1+© ÷êmÒüè]bÒŠeð×ôÌJêB}ú£€v¿¦bWRïÔÛ¥ùкŭÊà¯é˜•Ô„ûõµý3ºŸ~¦Ý/Î…Ö-h¦WíLÄ®¤'ߨà¯é˜•Ô„ûõ6é~t.±kSLžÚþ™‰]HO¿Tð×ôÌJêB}ú›t¿:X´©Zdð×ôÌJêB}ú¤,;_Ó1+© ÷êmÒüè]bÒ€¦WíLÄ®¤'ߪxkúf%u!>ýMº_ ¬ZOš™\µý3ºŸ~£€v¿¦bWRïÔÛ¥ùкťL¾Úþ™‰]HO¿QÀ;_Ó1+© ÷êmÒüè]bÒŠeð×ôÌJêB}ú£€v¿¦bWRïÔÛ¥ùкŨÑL¾Úþ™‰]HO¿QÀ;_Ó1+© ÷êmÒüè]bÖ¢™|µý3ºŸ~¨à¯é˜•Ô„ûõ6é~t.²qWðU¿GZßà¡KJp\,˜Oʾlæ6ûeà‘(µr´UWP̘ƒSkH\¤f ”>[ƒÏº«€v¿¦bWRïÕ^^nÆ ¨¢]ßõD¸[ƒSæ¦WíLÄ®¤'ߨà¯é˜•Ô„ûõXÛ¥ùÑX´¢™|µý3ºŸ~£€v¿¦bWRïÔÛ¥ùкťL®Úþ™‰]HO¿Tð×ôÌJêB}ú›t¿:X´¦WíLÄ®¤'ߨ ×ôÌJêB}ú›t¿:X´¢™\µý3ºŸ~£€v¿¦bWRïÔÛ¥ùкŭÊà¯é˜•Ô„ûõOíLÄ®¤'ß©·Kó¡u‹¦M”xõˆ™¨º…L†Yb$@@&9Ä @ß¼Æ â ØÄü@Äbõà ‰2þâeo™¥Ì ÌQQt¨UvD ÅÏ1&ð6"Ï kÅÂÉ%' ;ŠÑ¯‘Ïd奜T•&`%&+ðÌ@rA­n^”1çØJÔkŸ5mekk |1$šß‹§G”)¤S^¦e-xbm¾Öj‹ËÜE”v2(ø+¤J£ƒlü ³(˜®(À) G#Uð·×o îÔ¶†æ‚BA™åríC‘Û–åLŒÔ9GAˆ}‘ŠcÂRƒó ÐxÖåéC}„§ýFܽ(cϰ”ÿ¨Õ5ý/CJbûnݯôöS»þã#Š)Æ7‰…lÓÅìž‚®Tw/áìPÕ²ª™¶Š¦‘aÉ"g–àÖ4Ƥ­åq]m¦àݲ—›rá’Md]s¢ªŠ(U BŠ@%*šM™ƒ"ŽB!ºñ­ËÒ†<û Oú5¹zPÇŸa)ÿQ­ÖVñY¸ŠÕüÏ}Z}ðôë»2¨½„A;‹P·YÈÆ³’c,»Ó$ýêMå%RD€ ¢¦)3LQ7’&Wv{òÖ¾s+‡ÆsrE½A+iôC‡•pª¯Šb”DàT¼%#´ä`.dU¯n^”1çØJÔhñ­ËÒ†<û Oúak´tqCw{¥_æM=÷zÕå%n0aKJιÉKÃ;q0ÝŒÛGȤìs+”–Ì)À@¤$0‡kÉ–yX^-¹nKéÝ"W.&Ýñá¶å01nS‚¥ Ž)Æ&€0€˜2ÖxÖåéC}„§ýFܽ(cϰ”ÿ¨Ö_{ë÷¡«­w¾ÇNë¿ñX÷þ‘B­sF+k‘ü”½¾¸’ÚLGÉx4¡ðM™X¬ÔT€?ÁÄû0OÊåäÒjŸ>5¹zPÇŸa)ÿQ¬³ë6óÕÞ½”ÅNœ(eVYk,‡:§0æcÂû1â#V$mà±½~5¿ßÑSôÝ‚DD«Ø+è¦WíLÄ®¤'ߨà¯é˜•Ô„ûõ_Û¥ùÑÖ-h¦WíLÄ®¤'ߨà¯é˜•Ô„ûõ6é~t.±kE2¸kúf%u!>ýSÀ;_Ó1+© ÷êmÒüè]bÒŠeð×ôÌJêB}ú£€v¿¦bWRïÔÛ¥ùкŭM2xkúf%u!>ýSÀ;_Ó1+© ÷êmÒüè]b×䨦_íLÄ®¤'ߪ8kúf%u!>ýMº_ ¬ZÓ*òUoþ‘¹ÿÂØÑÀ;_Ó1+© ÷ê°”nÂ*Ù„Žot I}Ø»™…,yT2±èf˜Êë‚ &Ã-¡wo­6V¶n"«£ù2RiŠ`墀墺F¿Óücqú9ïîŠRý×(Ó?Æ7£žþè¥/ÝrxdŸàÃúý¾˜þáü>¥bþz¬qVkùê±Åv,Jv…cª«uÉVŽª­×%ulJ1•®j¹=X¹ªåüõÕ±*Æq-É\J×jܕĭ_³+Dr«\Šùë­ZäWÏWlͪò×"žzëW–¹óÕË3TG)þ5EIþ5EYF¢*|Õ>j(¢Š ( (Š(  Š€(¢Š¢Š( ù**~JŠ ( (§ÏQSç 5e·mèã‘¥Ïq½9 s Î0€STò6B P>Yä;À@>mäé+k•¼Â2lùºÌ‘ÖÝâJª‚f8˜ ™Ê. ™t›yNQˆo±¼-‹‚ï»$îkfÜ´l«“½*­ ßj:Å5D?ЉGV\™†` #6µ»&„6$6j—Ê "¸pÀ¦YÚ(`ÖäTÕAŽ`(gXW¨21öíÁ!¼¤|£¶ óÛ:A¢‡I<ƒ1Ôp ƒõ|àá&§\¼$D„¢Ä.£¦Í±Ö1Kòˆ@)¼Å²Rĵ䠭›µúqñÍ#øÙÔ›´d±Ha8 Sì>û´0‰Ïåg«@*¦. ´Â„\]Á4ÑÌâÅ45¶üš u"±ÄÈœNO¾¤0¤\´œGNyT_$[4…˜våãf‘/Ü.Å#¬í4›œÆn™#œà™JQÌG =~æà'`Áš…’ŒÔ…µ:;@ùK¨0Þ”äzQÞ"qÔ!˜ikz¯æò›s @$b² ™@¹Q $7“•!Š éºíЋº†‰]Ô©\6hå©…®ÍeÃtÖ)E2˜ù@.@co ®š…˜ƒvV“q/ãº'ΉĿ.F©«1+{¿U£¨Ù×¶Tj@à‚‚‚°4fEJA6^P‘7)|¢lÉ˺«!Û)lÃÂ1Än·;7I1zASfP?…˜S7”R4y@5h³Èj[ŒB˼W#3¡iÏ*W¹ø ’9SŒŠ&ò2/•䀎ì÷h¬ì9ñ•ª…Õ>æn& w*"WÍ ”z’DONµ•9t$} !¨DÄ8eähm8KíÅtKM Â3y1·zªŸx‘Í’â]‘óÒ¶ð†œòˆòfd`æ°2ň4rSrJ¨ìQ!›Êa>Y Èrç¼Å0r€Ô^ouI8šÚi-sÈA=,Ä#¶pË=Ø>bQ]~¢g(˜‚™ ¡M&ÈÓ2Žb!I oÏÎsBÁÉÉ‚šÂÍ¡ÖÙ‡Êm 9~ºlpjããoÀ|A+á|þ#ÀÔÚ x?ÅË?ã¾õÿÏäòîªë}«IËÜgkÝ3ª±Û™á!%€"àËœAEðuL)l@ä\ƒ!(Òð°ð“3OLÆ!ü‹¢”Ld6:ª(‰J9W+¶ÎYºQ«¶ê·p‘´¨’¤ƒòðr»™¹›Ñ£HfšxázÊ*Wm#·"G.E Ž•À´Úäžg(†àRÿ< /Ǥu*´¢©¤Ù1]r+tÊ )£p¨˜&aß™ˆ"9ˆÔ¨ªèA\0oOªu*éTšÁ„QxPÈR  ¨pPNSgÊ@åΡí­s²ZEå¹0Ù’ ™œ*ÉB&š…6“ÆÈ Þº´o æœ`õ¨«x‰“wqH¤ØÄlsÇQ&D!H P˜É*Påμ£–ÒEÏ)ð‹Äÿ•v±ÚÎ[•a@[/àÞHzD†0‰‰–ñ ^$H k.[r"9¼Š,$^³(9|é6'Ø2QbB¤u2êТFò¾eçÛ×ãÐW®ÓICç–‚ ƒY‡ósÕZô% ~_LJ ®5Lx´„r.ˆ‰›3óŠz‘ÿ6¥º2 s»ZæfvwnL74fÄd¡EÐd÷¼ÃËÜbü\ùC寓ëz}ŒÂ0Ï`äÚÉ®b•k49PÆŠ †¡Áo`±AŒCsöHè[±FeŒJà“™  ªTN 9mEUÕÒa‰ƒHç•~ñÛ~L<µciÜŒã·ÌÊÖAo pUM ¤—ŠbA8í© uë0fº/o¡& ݧt³s&îÚ™nŪ‚“‡*±T©"p>)Î%È¢òrÏ=ܵy!c¶c$ªÓ øÉ„)ƒµa ÂÉdcí3)ŠWŸâŽy˜N@&Ó_ñ7<§Â&bÝ’<«g¦ÔHvúÒ*ÌAÐè>C"‚z€w‡‘˜rW*.$/³qGÆ»Y¢‘`rìP1Š‚A Ôé”Dv”Q8ïþjfBŽQyƒÂݸ$#”a(íƒ|öÎh¡ÒO-ã¨àëùBBÌN:3HH—òn ]b“6çXà_—"€ŽTÂsuË?¶f­ºñ[ædEâ'É则AÀªŠŽk§YfÞD»cÜÐólpý›‡D5ÎñÒ¬Y&"ªŒÌðCeòŒBd· ažY…Mâô¤$ÌR ÜJD?b‹ƒ(DrØé•S&m*DÀa)·\ƒ¸j¾·øÄ”¢ ,”&—Ÿ¥nlÕ*1r|ð‚9”R€CÌ%JÀVIÕ ( *@ HT HPEPQ@QEPPEPÔÔ MQEQEEPQ@QEQESQS@%EOÉQ@Ê…ü•[ÿ¤nð¶4µ¦T/äªßý#sÿ…±ª“¿„þäÌ¡íÁËEËE[1=þŸãÑÏtR²IF2pÜZáŒfsgš+&àN]ùoБ‹ù÷òÖµ?Æ7£žþè¥UaŤ7Àâ+Æ"ÃdÔÎ6€–Ó<ŒBå–¢ÿâÏ<üÕã?aÉZN¨,¬é]ýµ§vÚý§n¬-oï‰^0¦aþÉçaUËÁEôÒ?ؽîôóÏúZRÖ¿ð(ÿK–õCvµõ°¦æáï‡7¡Å‹í8?±çç6üHòßøj/»µW9·aÄ7ß–àjûµz@~„[½Çêl~Ú¿#ðxHyo©;j·Øspòæô4E=Çö<ÂâÛ†þÐ- ÿa!Ýk…kfsÿ¼K`?»È÷ZõHüQé‹ß«W·¯Èü›ôÅÿÑ[·«P}—5.oÒjsP¼O&+kÁåùGµƒû¼—t®EmX.’­Pþï%Ý+×£ðol?Ó)ÿ·¯ÈüZôÊKö¸ïb•†~ÓS·…ž;RÔé2ÓîÒ}ιT´à:N´ƒû´§s¯fÁ­ ÿLå>›Žñ_‘ø4³霯Ö9ïºi•†~Ói °ï¼Ò“3ödžøot«gz¬¯r©à}½Ò­ê²½Ê½Ç÷1°ç¬Ï¬;ï4}Ìl9ë3ëûÍ)1Ó?hÜxsö÷J¶wªÊ÷*8ot«gz¬¯r¯qýÌl9ë3ëûÍszÌúþóJLtÏÚ7à}½Ò­ê²½ÊŽÛÝ*ÙÞ«+ܫܟszÌúþóGÜÆÃž³>°ï¼Ò“3öLJ8ot«gz¬¯r£ö÷J¶wªÊ÷*ö±~vѧ \Iv2ÅCÂLÄ$x@#˜i³ð­Z3 Ye˜€WÝÿÁºƒß¾¿¤Ú´l‘–]u¹"i¡™Žc œŠPÀJLtÏÚ7!à}½Ò­ê²½ÊŽÛÝ*ÙÞ«+ܫܟszÌúþóGÜÆÃž³>°ï¼Ò“3ödžøot«gz¬¯r£ö÷J¶wªÊ÷*÷'ÜÆÃž³>°ï¼Ñ÷1°ç¬Ï¬;ï4¤ÇLý£qáÎÛÝ*ÙÞ«+ܨà}½Ò­ê²½Ê½ºãàÝ Ùfȸ¿¤ÑUÒ¢‹r(íÉL±À†8€.|£h!ÍoȦ@û}Ìl9ë3ëûÍ)1Ó?hÜxsö÷J¶wªÊ÷*ŽÛÝ*ÙÞ«+ܫܟszÌúþó_ ƒ„,sŸH_òM AQe×x䉦På1Œ.r”iIŽ™ûFãÄ\·ºU³½VW¹Tð>ÞÏò«gz¬¯r¯n°ø7C?bÝóúMÓG)dE㓦© ”å09ÈÅÜ 5öû˜ØsÖgÖ÷šRc¦~Ѹðßíî•lïU•îU#gÛÝ*ÙÞ«+Ü«ÜszÌúþó_ègìP|Æþ“tÑÊEYÑväéªCe1Lr1D7 )1Ó?hÜx‹ö÷J¶wªÊ÷*ŽÛÝ*ÙÞ«+ܫܟszÌúþóGÜÆÃž³>°ï¼Ò“3ödžøot«gz¬¯r£ö÷J¶wªÊ÷*öóƒt3•œ¢Þþ“YVª‚.›Ç&2'àC€9òM ä6C¿#y+í÷1°ç¬Ï¬;ï4¤ÇLý£qá¾ÛÝ*ÙÞ«+ܨà}½Ò­ê²½Ê½É÷1°ç¬Ï¬;ï4}Ìl9ë3ëûÍ)1Ó?hÜxÚó·îiTd ˆ}dš ÐdÚlH$E0M1«cŽ`B¼»ô€å˜ˆ/íî•lïU•îUî?¹‡=f}aßy£îcaÏYŸXwÞj˜_ûí ð>ÞéVÎõY^åR}½ŸåVÎõY^å^ãû˜ØsÖgÖ÷š>æ6õ™õ‡}榓3öÇ‘ž+ªü ñÂ觯:±ŽšMC¦pÈå)¨¤˜3Ù»„CpÖWö÷J¶wªÊ÷*÷ÜÆÃž³>°ï¼Ñ÷1°ç¬Ï¬;ï5 …ÿ¾Ñ¸ðçíî•lïU•îTp>ÞËò«gz¬¯r¯qýÌl9ë3ëûÍszÌúþóSIŽ™ûFãÜ·ºU³½VW¹QÀû{¥[;Õe{•{îcaÏYŸXwÞhû˜ØsÖgÖ÷šRc¦~Ѹðçíî•lïU•îU·ºU³½VW¹W¹>æ6õ™õ‡}湇=f}aßy¥&:gí2¶¢X¹,q~Ôj¸ÅF\†1D¦ Á–y D@~P øð>ÞéVÎõY^å^¥øBàÊ8{ƒó×[¶qgŒÊÜ^9 ÇrŠb#©c†“›v\¢žêò îžrÌúò¿j”˜éŸ´n.xot«gz¬¯r¨à}½Ò­ê²½Ê¾ä•ópÎ4…Џe|ñ@IºjË s!u(r—1äÞ"ˆ€WÒ!Ýù-t%mGÜO—’YÀ¶H6šŠˆi*¢ &lÄ2(²0ˆsÌ3÷3öÇSj%‹rÇíF«LPQeÈ`J`Ìg”Då¯íî•lïU•îUXò㻼¯Ú©¤ÇLý£qsÀû{¥[;Õe{•[Û±VÄJN‘s{á´Ât “~Æg2 sÈH¢mH¡>0æ`ݘA–jjõ˜˜g?2»×®Ùº^09u¨sJ\ÄÀ˜ˆb Ë»§/ÆYŸ^WíTRa៴n5wL<ã´V_ìVÉ7D¶lÙ”±RA !@Yˆå™Œ""""&¬à}½Ò­ê²½Ê©¸Wtó–gוûTp®éç,ϯ+öªi1Ó?hÜ\p>ÞéVÎõY^åSÀû{¥[;Õe{•sAÉ_3JºJ:á”QF­x©O,)ŽÉ"‰ÔÎÄ m%ÌÙˆ@5_»§œ³>¼¯Ú¥&:g틞ÛÝ*ÙÞ«+ܨ >ÞéVÎõY^åUŒ®+ÁëÔ5¸fT]Â…I"xz¨Æ€3dÇÏZ®c¥Lû`½¥)1Ó?hÜSð>ÞéVÎõY^åGíî•lïU•îUû¹¸Ê¶Ðj¼ÜœãD™B q‘1Ês 'œw€™‡þ`ªNÝ<å™õå~Õ)1Ó?hÜ\p>ÞéVÎõY^åSÀû{¥[;Õe{•uá”ÄÜÍï%=2»U¶»Düb±sÉ#˜7”À< í¹‡=f}aßy¥&:gíp>ÞéVÎõY^åQÀû{¥[;Õe{•{“îcaÏYŸXwÞkâËàÝ õ,Îþ“r‘UQ'ŽNP:g‚ çãå1D9@J ;”˜éŸ´nÞéVÎõY^å^ãû˜ØsÖgÖ÷š>æ6õ™õ‡}攘韴n<7Àû{¥[;Õe{•·ºU³½VW¹W¹>æ6õ™õ‡}æ¸ÞüâÚ(Võ™ ùÂïÿùž”˜éŸ´ne™ë4mO÷3öÇøot«gz¬¯r£ö÷J¶wªÊ÷*÷Ǹqó,ÏY¤{jø¯…ø^‚­Ò^6Q%¨) SÝ2N1Ä¥_Ê$1²1Dyi[ãöŠ#Á¼·ºU³½VW¹Tð>ÞéVÎõY^å^÷â—>e™ë4mG¸qó,ÏY¤{jVߦ~ÑDx#ö÷J¶wªÊ÷*ŽÛÝ*ÙÞ«+Ü«ßRáÇ̳=f‘í«â¾áz ·IxÙD”r ¤OtÈU8Ç”(tÆÈ<Åä¥mÿÚ(ð>ÞéVÎõY^åSÀû{¥[;Õe{•{ߊ\8ù–g¬Ò=µ|WÂü/AVé/(’ŽT)î™Ч˜âR€¯å’Ù˜¢<€4­¿ñûEàîÛÝ*ÙÞ«+ܪ8ot«gz¬¯r¯|qK‡2ÌõšG¶£Š\8ù–g¬Ò=µ+oÓ?h¢<Àû{¥[;Õe{•h hFœ5»sÆÏ;n¥ÀõÁØ"艤E£Û‘0]ÄL"‚œ€ ¿}{cŠ\8ù–g¬Ò=µy_ntZ&É›2JFâ+fê¼UÈ¢A‡6¢¦1ÇyŒ;Ç,Är Á¢cï~íßì£ïèÿâ¾dªTóørÑ@rÑ]3ßéþ1¸ý÷÷E*ÏàÛøüûôaÿæ¥U‰þ1¸ý÷÷E*ÏàÞ`-üøL âÃòÿz•yoú3ûˆ>|‘õowþŸ3d­Í<Îä¹b£EWÒ’1QçªÝ‘8]pË\p™`»g ±W<[˜ò¼ ‡*ÄAÈm_/H€‰ƒQ ˆo¬¬eïz óò[ÆáZÐÕzá¼á0ÎffbR6uá®7q±ÅðUPÖ<ÂÍT9–PE1È%!@¢šdÑ™òS ѶmëQ³ÆðMŹ:Ž…GJ,u–1PÆPÆ0˜J™3÷ˆŽñrY–©[M4fQ¤Ú†UóU^*¢9Œc˜ÄLÇ$cæ0Š`Qd#˜€ÏeÌÏ«rLÛ)㾎nÕÙÇ tU±JQLç8”å2 gåˆ GvyV~×’ºY\8Ÿ!+pD8‰‹’?‚·r‚¨¾QÌÖ&¥ÅU4@§`T·œN e«f+ZܶRrH”Õ)Ýp»—Šº]aÒ]j¬cÀäÉ•|–´í¥¥%¤Vle™l-¤Q3µE»’ A¡«d'ÐB“^ZCNyn ÷ý+1d_–Üš‰<#›"ZA³”­çñe($‘Hb Àvä:c»!Ì¡™sÖ/‰’£cÍ_G7´\§ÀȪ£ß3’·¸"y˜žYÃï ©oFШᅈ˜<ÖÁÓ“=ŒqºŽåÝ89™¯£hˆELb”t,„4ïÓ–cÃËR×vîUˈä<ºF@¢¡7 _ŠcHœ å« Ï €¥ÂÛ¦r}̳)–kˆ2N„€À=ŠIÀ)¯4Á~^¢ 7‰L`990¯³y«¢^ø•ahfñohðŽ‘Pî褹̙Êp*`R,L³)õ Ho«{bÜ„·< cÙ”q¤UäŠîÕ0=%Ö±Î`(j6EÈ3ÛëäþÒ¶Ÿ\i\+¶P$H)‰Ž‹ÕR"˜昪™TJ;ˬ¦ËÍ•†—ÄÉXûÅàáƒØÃN#£voÔ…WnSC/”Ç(™!(d:ˆg*ß·{>à¼_£«’îâ#˜µbà먡dÅ’*¨bœÂ!»ÊL‰‰ÊQ ôVÎY%¼f³Œ°HL©xÉÀ7#²ª ‚Å@ÙâpÔ&€›3g˜s¸ vÞ&b‚‘¯p»†êNSu޲¦Þ"!šŠÛ¹wedÝ3“îe™L³\A"t$ìRNMy¦»òõI¼JcÉÈ9…V^7µÑµÝ+”7‰lýÝÊJËÜ›¦å]‘Êp*Y&©@¹úŒO-l-‹rÜðŒfQÆUW’+»TÀ\ô—ZÇ9€¡¨Ù Ìwo®9Ë"Ñšš ‰&«¡Ùí@¯M1Í=²E8&¶‘äÚÙPbÞx¸‰ÉE¬ÃǤL¨¥t×x½‰“ûè¬`•3ièÞ}G(@dîõ.¥¬ì| IÆO"Z¶~ƒV¥f©TC8vÊ ¡–1@€SŽ¢R‚uJÐHèøÈ÷’NÙ¦T–“ržh#´TM6B9ÞÑL¹AäçÊ"#S#fZò§vÙcøù™ÙJ$Wë‘)™2¦a2E8ÐR“h†@l¨ Eõt]Öü-ÄÆèikËk>Va³tÙ+°(µ*@vË”ên™¼ ¨6y€4†aVÓW}ˉ%ˆvFQp‡vÙ»E]E¹T¯ö MY;LÛ$¬Æ!SP¢'†Bƒ-UÇm[××Ç ëkê,ÿ93jçg·OÉ0|m’~WÆ ;„3ùä,ëaýÂIçmÖQáMÆŸX™TòÙ¨dû#ºK‘ŒQÒ\‡pPØ5pE¸¶#í°ŒsSÀê?Hê&’`ÍÊâp) Q ³Þ†až Ì…Ñ<ÒBV“k|“®®–ðàü4SÄíݨådÁA1ÇINB—h¤©Mäê$Œ|dƒÈ×o*«F9LÍ´Ùª(¨ˆ› ‡ïk(\‡0ò³å »í(ÉY‚0Žd»ù©H)á—nr™HU’Ql‘!@Ɇá ò͘ ÙY»Ú^à…Žpkx&á¯ãÇ7]4ÆL`XU:b ˜M’çpäêÜ'‰‰ìB¸íød'!#¤c®õ➬œrçlôG‰R% L…19¾øR 4›K†˜~ΙœË¢ÓÆ&œVi$Û½Yr5\í|øÕ°Š:µ@òŒs „/¦,Ë^T‹¦ËGr’QfÏ×n°9+r·¢g)Ó‰ O @3ÌPæ]ñ.x]ä¢n·:Z Um"‰ÎR’˜ Îo+É!wœÚJæ ›žï¹®›}ý¾/&ò>rÜX]¹¶2Mt\É2Z¹Pªy*#™Œ1NMD &1÷ \LüBñ2è‘Ë5ô‰É´e0¦)Š b˜¦)Lªì<²ØÒˆ±]Už*Ég+9’páUŽÍa]±Œu1Œ$PsÞ;Ã"Že 'lÎ^ùñFv霚·Ü_i²Ôœc5òHNáPM1)÷½#š†1õ­5–(]è[w<‹¨°\ñöËÉ–ÎmIG6AtH ”@]¾­@ b @‡òK¸iš•·”üŒÙ?…I¥²zAv¨·pJMG@M²é!K¯N­!§<·U[l;³Ž‘ŽnUi ÅXåÑ^QÊÅ+e#¢AØ@rzyä òÙ%ÀXóäs³Ã©¬¥`Üé&‰ïb'9…Cêòü€ò-øƒäã•­[rÝPˆ£ß|™À®›‚ 9夲ynÌM˜Ža“GhŸõ…ýµq‡6Bí# z©#Á8ÖåBEÂ:š2" ‰ ²`ÍSPo”s)iÞX‡x0°¦µØk>"uÁݳ]P<#RD)V.”þðDD»óçäØB^·Eàák£ gÛç^2MEÀÀïi³@šM9l”Ô êË2ùl-ËjÞ·v^'hV»(Ö±dûùÏ“VÛM‚~Q‡âíTò¾0êÞ#eZ㬵ãâX z‰!ÈŒ‚×DÀØ R‚'1U<Š•A0œ1 0’7u·'‹W49¡  &Wî›:AS®èˆbuC”å*^AC# TÌGxbéª7¶Õ¼ò>árЧmqëñ±6çÔÜͼ ™3I2ÉË“>Q«­¢ÖöЪ+ó´OúÂþÚ6‰ÿX_Û@~¨¯ÎÑ?ë ûhÚ'ýamú¢¿;Dÿ¬/í£hŸõ…ý´êŠüíþ°¿¶¢ÖöЪ+ó´OúÂþÚ6‰ÿX_Û@~¨¯ÎÑ?ë ûhÚ'ýamú¢¿;Dÿ¬/í£hŸõ…ý´[á½ÿÕ¦éþéûâüÒ¯égÃpÅ7Á¦éÒ`Á9ÿÆ!_Í:Wƒ¿•Û7ôóÞ Z\){am2³¶®T\ŒÛ0EEgÐP„>ÜšDÅeY€3äÌ9knLÈ[Ó&¢”I'ÌÔ[¨£tÖ9 ¥B˜¹‡(†áÈ@¾‘ ¤MЕËfˆI"à\¤pdˆ¦š‚":ŠS.B9”¹@¹dbá¨/a—NÂF}¤|s¹²‹³2Y¦èÓI$N ¨&gM¼@Gï[²ßZ&MàÓ”m8â9›$-¿8]2Žsáb€,¢ Sd‘ÊMÁ¤Å)—&EË ¬ô¢èRäBå‘D¦a ãTâÂÞxØ,"ËÙªgc$Ý‚ ­&L„6çT„c˜ s(—#fr‰†­ñr·¸UŸ+¶ª?U©™ˆ¯ÝTÊ‹ S"G ¦B‰3.E(y"`ä0€ó½º¦^Û -§b1ŒÎ'@…ŽnEaËPíJ@PDr ó6üƒ<ò ]u¨>vGã¬éÿó _Ö[ñßýÛþQkùõXéF²†UªäX€p(˜¦yy³ ô+†.&1bÝ‹XE6íÒ*IÁ’3Žà¬Á¹ÿé0þ>ÃÿxÿÁ­xâ™Xߌ÷N/ @ܬaÚŒVÛaà (M[]ž­ZÔ>ylË–Yr--h † ~R¢ÛÉ=K±‘üú°Q6êj™ÔÔ¹X¨dx1Š ²ÆÉ]&Àv Q8LaÒ´×óG?)Q?í¿äž¿ª×TTôi£å µ@LS€‘s$¢g(æS‘B†ä1D>Z=„Ž 1R±Ž‘nö.HÍ]·y*¤ˆ$ ¢’  ¸PE(C†½à'0d&Ι»­øUeЊ[Ê_/ãÌÔPWÂÌgVCj ëÐ]**FÌs)sÔ9NÚ„†·#F>!-Š&PË(e:Ê*¡¾1΢†1ÎaÝåDwÉ_ [Þ(ñO‚À¼eãMžÜÿ…x_†m3ÕŸñþ^œôù²Óº€ÇðÚèðŸl¡¸5ÂOxÉO ÏÃ< oµ×£øï+g³ø›õ纻ö” Ç›^ÂïhÐmø¬µg¯cågžZ÷å—“W´xKÂð ÓáŠø>ßN·ƒëÙmrÿâhÕùë™ÞÙ¦|j¼z¦_ÃÓ’ÂEÁ[•Ù*…\6@¦²€‰€¹›x`"}­Óˆ®í{‚âfÎÚm$ßGÇÇ·d±×1P‘3o9¶¾V”ÓP‰Jq(i9sÒŒ3župA¸pùû'Ž[;3u Þ9Ã@„6•®"¢G \‚#™D¦ò²Ó[vù Áx6–\¬íTÈåB›lªæps”àme6ÔÆ8 D4ŽZr ¾¶Ä-¶ÅV‘:dYa]ut£…VP@ 'QULcœÙ¡™„w€·¢¿;Dÿ¬/í£hŸõ…ý´ê²÷©\3š©"äS8"¢© „!ô†‘1@ÅY€¹òfµ¦Ú'ýamb±dX=n’0ó2Bb‰„X³2¥ nÌÛƒ1Èwˆîß–aœ>ÂP©Âéli”»dÚßPÖÌT4j‚ŽÙ¢ ßœJS c* ä%0œÅÿÉ– >„/Â÷òg…ïùÈת¸Nã™÷g³Gß^\øe4tÇp¹«ÖË6\ž7֒Ŭ€†`;Ãp€Ô z ÿ$ú³û¹+“g„³–GrY  Á˜¶n¢êêg©B¦˜ Œ)¦@9&5q+Ç l$^É3j ÚñÆ,¹H"†yònÙ]îŸÚ.¤ÙI8–‹QÓSÁŽ/‹’zÀçVB9Yˆf"–cž/´›fò^6ЙbŒŸ>‹‘A£Ì¢áºË"ír‘²ŠíŠU¥2†LÆÌÛ{ó¯Þ%LÊÚÍ-9«œI*Ê}e?ÉmŒ(O=̇9´d"9˜N%†¡ À52ű%œ.¼‹Ø‡pÐY-©ér:"mZDÙFÞÊ\Ç! ƾ ØL“fD¥ª,Ý™â's.uÔŒ‰Ñê(cïg1r0ˆdƒ 8™¾”—€†n½²“©H÷¯×_ÁÖ]&äIFÀ™I’…Úî\@M™w¹i› ¶æ˜J)"Ì:<™]8]n@bä($LCœæ(€ ü’çžyoµ†o`øl¼køÆæjšè·‘̈¦¹Ó:„!DâR”L’bȺr.@#ŸÅôvŽ#B2wY¿ZE+ðÈŽ*„9þ6üʲ¤wddzÀÄ9Ë’b%CE®h¹rœä)`_!à$Ù™DÌ£¥ ±T ù|£—H˜7×+i‹’~k g¤$‘2²j»hÝŽW Êhׂ™T8œJ ‰ :„ M& ·çiãaül°I²’f’Å9Κ~79›¤cæ2h ‚™u1)@wË_0˜jÊm¬ËgŒíšÊ.×9s™&çP‡!öi š ˜ "–`p@Ý÷c×vd‹’Á„-Ô¹öh&Š€åªBÑw €œN%9‡f]C¤ ]áæ ç.Iˆ• ¹¢åÊs¥|‡€“fe2Ž”.ÅP0 äiòŽ]"`ß\‘pñŒ×Œ-¶Qñnœ¹i°›UcU"‰é“rä©„Û1FŽEä­Dc ?– 6RLÒX§9ÓOÆç3tŒ|ÀÆMPS Ž£f%(ñùh xs?kúFáÿޝgðŠßùö/ÖÓ÷׌13ðF¿¤nðXê­7øOàþLÉvˆ`墀墮˜ÿOñÇè翺)X¶ÒÒ±fWÅ’oXí2Úx:æO^\™éÏ,ÇöÖÑ?Æ7£žþè¥/Ýrxt„qAc …Ó·è}äÌ*)†žS¡{¾ìK¢l?¿«öª¹{ÎðK®t?Þ ýªå_ÏUŽ+¹c1kÌóe+K80Gk›ÞôK¾àì’[íUs›îøÝy\Aý’k}ªàuUn¹+§cmiÌó)G8N/ûð9/k”?Þ«ýªá[ïðÏ+æç÷²ÿjª\ÕrþzêYZG‰V8VÚ¸ˆ@¯» ?ÞëýºäWq9/Û«Úî>ÝQ-É\JÕë8âįF…LKÄ`ä¿î¿l8ûuʦ&âHrb Ûí—n³Ê×"¾z¹OLI51?ÀwbÝí§n¹ŠXšÿÞ-ßí§?n³jò×"žz¹4ÄiŠ˜ŸŸåðöÛŸ·QƦ'ôxûmÏÛ¬þ5EXF³aƦ'ôxûmÏÛ£LOËòxûmÏÛ¬uOš€Øq©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·XࢀØñ©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·Xê€Øñ©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·Xê( ˜ŸÒ=ãí·?nŽ51?¤{ÇÛn~ÝcþJŠcƦ'ôxûmÏÛ£LOéñöÛŸ·XࢀØñ©‰ý#Þ>ÛsöèãSóü£Þ>ÛsöëSç 6jbH÷¶Üýº1?¤{ÇÛn~ÝcªF€Øq©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·Xê( ˜ŸÒ=ãí·?nŽ51?¤{ÇÛn~Ýc¨ 6Ûsöë@P51?¤{ÇÛn~Ýjb~_”{ÇÛn~Ýc‚§Í@l8ÔÄþ‘ïm¹ûtq©‰ý#Þ>Ûsöë@P51?¤{ÇÛn~ÝjbH÷¶ÜýºÇQ@if¯ûòn5h¹›Úä’`¶[VÎåY%4˜ ˆcB!˜r€ f¨( ¨©¨  (¢€§ÍP5>j(¢Š ( (jB jB€Š(¢€é‹ ŒŒ[×,^ mh¸l©“Q3|¥1Dó…j8ÔÄþ‘ïm¹ûuŽ¢€Øñ©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·Xê€Øñ©‰ý#Þ>ÛsöèãSúG¼}¶çíÖ:ŠcƦ'ôxûmÏÛ£LOéñöÛŸ·Xá© 6jbH÷¶Üýº8ÔÄþ‘ïm¹ûuŽ¢€Øñ©‰ý#Þ>Ûsöêšåº®‹›ÁøIrLMx6­‡Œ(ãe«-Zu˜t礹åË|•OEpUÎ ¦˜\sD“"I—ÔȄ!@¤(­Å)@(áUÏÎ9]SíU=Ç ®~qÌzêŸjŽ\üã˜õÕ>ÕSÑ@\pªççÇ®©ö¨áUÏÎ9]SíU=Ç ®~qÌzêŸjŽ\üã˜õÕ>ÕSÑ@\pªççÇ®©öªxUsóŽc×TûUMS@\pªççÇ®©öª8UsóŽc×TûUQòTP*¹ùÇ1ëª}ªÜ1téîA:zåg+žFæÖªÇœÙE1ÌGxî WÓ*òUoþ‘¹ÿÂØÕIßÂòfPö‹`墀墭˜žùpå“«*àúfNRÈG3¹ÈPÝò˜À®³(É1A¹RZ-ÙËžk,£9·ùô*RîäÜÉV·Wá¦þÀÿ€VUÏ)«ÂäbjÎzÕ’Š7YÚ´ÄWžÕ€ýj¾í«…iˆ=«mþµd;j®_ÏUŽ+³dÛïùhs#²êËUæ!<ö­­úÕ’ÿÑjá^bÏjÚ_­YOýªWUVë’ºv0·ßòЧMóïžÕ³Z²Ýµq«1moÎÕ²Z³µf\ÕrþzéYY·ùŸí¡Z(Mb“Æ[í[õ«3ÛW2“·žÕ°¿Z³]µcÖä®%jõ‹ç¶†ˆª“§žÕ°?Z³µs©1iyí\=ýjÎöÕˆV¹óÕ¸%ß;ý´4Än1hçø«‡_[=ÛW9æ,ýÿöW>¶¶¬¼µÈ§ž­A,üH¿m Q1€i‹7?Å\5úÛƒ¶¨ñÅ›Í\5úÛƒ¶¥±þ5EXÙ_‰kC]îƒ'Ço5p×ënÚ§Çn_Џkõ·mKJŸ56WâEšÐ^è2|qfóW ~¶àíª|qfóW ~¶àí©iE6WâEšÐ^è2üqfóW ~¶àí¨ñÅ›Í\5úÛƒ¶¥ QM•ø‘f´º ¯Y¼ÕÃ_­¸;j8³y«†¿[pvÕ>8³y«†¿[pvÔ´ )²¿,Ö‚÷A—ã‹7š¸kõ·mGŽ,Þjá¯Öܵ-§ÍM•ø‘f´º ¯Y¼ÕÃ_­¸;j8³y«†¿[pvÔ´ )²¿,Ö‚÷A—ã‹7š¸kõ·m@LY¼ÕÃ_­¸;jZ HSe~$Y­îƒ'Ço5p×ënÚY¼ÕÃ_­¸;jZÑM•ø‘f´º ¯Y¼ÕÃ_­¸;jŸY¼ÕÃ_­¸;jZQM•ø‘f´º ¿Y¼ÕÃ_­¸;jY¼ÕÃ_­¸;jZÑM•ø‘f´º ¯Y¼ÕÃ_­¸;jŸY¼ÕÃ_­¸;jZPÙ_‰kA{ ÊñÅ›Í\5úÛƒ¶£Ço5p×ënÚ–´Se~$Y­îƒ/Ço5p×ënÚY¼ÕÃ_­¸;jZ M6WâEšÐ^è2|qfóW ~¶àí¨ñÅ›Í\5úÛƒ¶¥­Ù_‰kA{ ÊñÅ›Í\5úÛƒ¶£Ço5p×ënÚ–´Se~$Y­îƒ+Ço5p×ënÚY¼ÕÃ_­¸;jZÑM•ø‘f´º ¯Y¼ÕÃ_­¸;jzZQQåG_¶‚÷BC–Š–ЏbÿÙxymon-4.3.30/docs/critview-detail.jpg0000664000076400007640000026723611070452713017751 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀ©A"ÿÄ ÿÄk  !1A"QTVW“–ÓÔ#27SUu‘’”•ÑÒ3B¥²á46aq$%5Fv³´&CRstƒ„µÁÕ '8DEbr‚…¡¤±Ä9Gcd£ðÂÿÄÿÄ?‘!1QR3ASaÑq’¡áð"BÁ24C±²bÂ#cr¢ñÿÚ ?ý=>\´Î”Êy)'TDDáà‹&<9lÎûÊTÊãUÿÜÇ!¥Py~ÕYVW“×âÿ'½¦l]0!+Ü“É×9ÔŸtGlgï}ñó$éÌÝž©±Mb²§¤¾Ü‡KN©deÄ4ñj.Ô8”šLóœ–86¶g}¿å quÜuVê¥p-PN¤Ýü­[ÂRކ[ÂH¿U´'<çÎy>#À®»â«qT^~¥¡6¬Ê¤Iu¦eZA „FqzÚ=F~èJÆ”‘¨õ`ÛùlÎûÊrÙöÿ”1§·àÔ A6êu™i+^µ:ëM6HÉhB[Jp‚23-Z•Äò£áˆ{òÙöÿ”0å³;íÿ(cóõñD~]chµf-jç¦É.¼§OªTä:©ÆMe[²3pˆNO%¤ÿ[wwÝ÷‚®Jù[ÍTŒ†,.œ˜rR¶Pé®Bä:—Ij4›""Ðg•RB¹Y¯6¯Q¨¾Ä(1Ü“!ÝKV†Ð“R•„äÏFx"3¬U–û²b¦§\Œá4úPþ£if”¬’¢#íOJÒ¬BˆùŒ‡Û-F«>×ÚSgs&%œ¨¨¹hÓ-ÄJÍkRÒkíÔâšF…$‰Mžuq!¼¬\UÅV*t†ªÝOmÛ­ŠKSI–ÍPØU1™&IÔ“I©NšF²WKàˆÔ9lÎûÊrÙöÿ”1Å$Ý×Du^5‰5·›»‘EjtVb!öXä-é$–é‘`Ö¢A%9>sÒD\xåX§Ä«ReÒç´OD–ÊØyúÈQ}›[3¾ßò†<¢U—-¥;¦© ¥Å´jiýDKB NHùÒ¤©&]FGć-)ókÔ˜;<žúª”¥Ã­¹Ì¥Ã¡Ktÿãжÿ>¬{Ñá6¹wˤE~B^麥i¹I§$Í6£Îq¦wi’[µ6„' ýcí8äÏ"½ËfwÛþPÖÌï·ü¡=¯9º¥µK©µ+•·./¥ýÖïzKA(—£õsœã£8¿-™ßoùC›çhLZŸª ªÈÞ²ô•òc#ܰÎëªÔ´å)Þ#‚u(óÁ'ƒ¨”zEÂÍÇ>«E¢WîX•Y-rzËú„¼dÆ•hpÙI±¡Â4£¶RŒÌø™–šá«1qÛöÛ‘¢T s@‡ZjiòŽ8•hq×ê "Q“NQ¥}¢ŒÕÛg}¿å kë—Dj$92ª••Fn47¦¸FꔽÃ$Fë„‚Ê”IÔœàß$¹Ì‡>½*2®c-N´§WEFÒ\ç99$ðk‹¼Se¬•Ú«&“éÁž X;[‘S§ÚµJ•©U8ÏÙù/½%¶IÇÜl£j3iIiKÎ$‰$Ddeœ™d×ùlÎûÊrÙöÿ”1à =ùlÎûÊrÙöÿ”1ùºÊ¢.™elæ°›:Ô¢%õÒ Ušl“:‹ûÍÑ-†ó½3$¸[Åá+YöØÈ½uÇ^å}[뀴uÑÔ^¡nѺå[Z´ïwº?Â3«NŸÕÇ$_–Ìï·ü¡‡-™ßoùCz«q\XMm»´¡‘ÝìQzɘ4½ eI77‹k.gV à’à¢þ_¨ÞÇo¿q±w­*;¥ÚK0—OaQÒªª„“VN)hI’ˆÉdG¤ˆÈÏ&`v>[3¾ßò†¶g}¿å rên±m½rÒê7,¹¨‰›&,× °© T©1º$ ›lÌÔÊI Qa&æU¨“Æ¢ÅÍ´'o …¾Ô›¼Û‰ Z%3Cå{Å’’éïI¥4’$”\-áj4‘ Ôå³;íÿ(c^*Å^Q}øS£·&;º–m­$¤« Á–HÈðdF9ý»P¹îÂ:$Ö•JˆÅ¿J©Iƒ ÞK’rNñÓJòÙ“$“Ð|HˆÒ¢âgRÙ=Õ\FËÛ”fQœ·­&‡CÝ‘¹=)ˆ•"J–e“B:R–̰y%«µHß–Ìï·ü¡‡-™ßoùC@®»â«qT^~¥¡6¬Ê¤Iu¦eZA „FqzÚ=F~èJÆ”‘¨õ`u{~ Bn§Y‘V’µëS®´ÓdŒ‘„%´§##2Õ©\O*>qËfwÛþPÖÌï·ü¡Ê)T_µ{ª©ÖU§Uäõø¿ãIïi›LJ÷$òuçNu'ÝÛûß|`uî[3¾ßò†¶g}¿å s.éíÙ©”åU”Ô•yu%9Kd£g«;ÖœsònœjÇmœñqj·ctÞ¹Þ¹Þy‚»\¥4á°LœeU• $j$o5¥&FJ%v¤FFy3¨Ò«ÅUй0*/¼Ò$=JÔ´áÆ]SN'Že¡EžcÆK%ƒ¯Õ–ñÚ~¦¦œ’á´ÂVþ“ud•,Ò’3íJ¬BLùˆÇÙåN±Q¬Ô-‚ª;nÆj©Zz3­´Úß©Ôe³q BRÑ™e85é3"G¿ÉÙ”Š#gÛ(ŠŠÔ©UM†ßKí³îlõ%÷I„šN—A‘žWÀÈÔeÀ×ùlÎûÊrÙöÿ”1Ê,ËŽ½&EŸS™pôÜûÞSKÜ4”ÓðÂÝ÷3JI~æ¤+Ö¥eK/{Ì<ìJ­ØT½Öj÷;ÕR¹Úm¹‘W †šh×Ù)[f„‰Yg•OQ™xÖùlÎûÊrÙöÿ”1Ç6muÞ•ª­ £>=Iú¹¼Rš”ªr#F2mkJcîÝ9 ZT‚B’áàÔfHÓjØë•Ùö¿_¸$UeÕ©‘e) ŽËM2kl”z ´äõ­Fe’íI%Àyå³;íÿ(aËfwÛþPÇ€çÓd\Œm~·Öý*“PÕ@¦o¹uIÈš?Â*tèaÝYí³8Ásç€ ú²Øv;OÔÔÓ’\6˜JßÒn¬’¥šRF}±éB•‚èIŸ1õå³;íÿ(cÛ5ZôkÒS3Z‰EF÷äÓãÅ|ä´¦ÊßC©I8¶Ð¯|ÓJÉ%'’2âYÍf­|^&ýM©rI…]‘£|pé-´¶M&¢r"tœlÍD”—(5ºW¥*½N¯P#J¨¾Ûµ *u,÷ŽN:iÉsv,òx.׿Dy\¶g}¿å r:túìÚ¢Õ}©(‘í}†•-qNJÚêDµ‘¼Q–¦’¼­E‚ÆI)V’Ô"–í¾¨Î™iµJ-oºÔtRÉ:°I.*ŠjV” JR´¡$fx™»;ÙÛsm;³ )qDEÔœþ,yv>Ùï‹Ë3ÍøžŒs$ÌŽ»b;è~:èìºö… ÛJ“¾Y8î ¹µ¬‰Jÿ„¢#<˜Â‰K°¢"r"S­¨é¨!MÍKL0’’•’’æ ·##<‘ç9Øûg¾/,Ï7âz0ì}³ß–g›ñ=mú­JùN—OâV¥|§ ˧ñŽÇÛ=ñyfy¿чcížø¼³<߉èÀ™4F\P“iu(Hžúžy–¥è34’HŒÕÔ¬!(AÍG¥)#3ÀØ&c¹–ÝAšIê[ ³L¦#’ˆ:RIG6p‚IApݶ{âòÌó~'£ÇÛ=ñyfy¿Ñ€&³Ç­ILªÄ+r¢úS)v[Lº´¶¢2RÔFzLŒò\Ç“ÅǃT¢Ô`1.€Ó“Ö—T˜íHiå¤Dn¶f[ÎÕ´£‰‘à‹X,]¶{âòÌó~'£ÇÛ=ñyfy¿Ñ€5–…Ù¢Û³©fPª Ôd‰";LÅQèCiBʉ(JBHŒÕïrffcsOgS£E‹Ofƒ ˆn›Ñša-6–4©´pJ+Rr\p£.“=¶{âòÌó~'£ÇÛ=ñyfy¿Ñ€6ýV¥|§ ˧ñSj4çá¼ÃUÆ"8ãjB_iæm– i%’“’ç-DeÉpÞÇÛ=ñyfy¿чcížø¼³<߉èÀí¦©;Roj5dNy´´ì”±H'\BriJ•É2dY<Ÿ ˜ßÔiö5J"!Ôa[“#!åÈK/´ËˆK«Q­nLŒ‰JR”£>s33>&#±öÏ|^YžoÄôaØûg¾/,Ï7âz0Ùº¥!´%¨ÁJDIJ^Ap¸‰êµ+å8^]?ˆÔv>Ùï‹Ë3ÍøžŒ;l÷Å噿üOF©Ö¬*n[Rë7䊔†‹ ». å ¿°Õ Ì…‘º= ôH ×$RnP3ÉæÔ™ˆ§‘Ûd´èBRœp"Ò’àEœŸ‘Øûg¾/,Ï7âz0ì}³ß–g›ñ=g±"ÝbœŠkÒš‚Û$Â#!m“Il‹I ’\ $\1Œc€ÂÇOM9ˆVëP‘èÉŽ†™Kieã%:Ù$‹…™©<Ê2,äy?aìå†}ÝŸY‰m´šÔ}oÄ<OýìRz½ìmø–ý× Ñ'Pêµ+å8^]?ˆò›Q§? æ®1ÇRûO4kh̰KI,”œ—9j#.HË€æ^ö6üFË~ë…èÃ«ÞÆßˆÙoÝp½Ö³;R9éS¥£:‹L¢4âsÏ…& ×'³º¹ÕÝŪÚtrí r8Æ7žûጊW½¿²ßºáz0ê÷±·â6[÷\/FÝW-z%^ôf»"¯n¥–ä1%Dˆ ”Õ©“Jƒ•¯;½hJôéÏ jÇk×lr^K®ÉùG)Ýe½íî÷yŽm{ÎßW>®ÛŸˆç]^ö6üFË~ë…èÃ«ÞÆßˆÙoÝp½¢LU¯3”ò³£Hål¥‰;Óm{æ’j4¡y÷É#Z̈ø¥wLkÝ¢ìõÚ[§)6²éñ–n1QØ6ZQó©(ÆÚD)}^ö6üFË~ë…èÃ«ÞÆßˆÙoÝp½¤±*ÞbB¤1"–ÓËi ©Ä-²Q¶ƒQ¡eÇJMkÁs¥cœÇ‹j0¨J`¨­MˆfÒy3fDZǼN’Á`°EÜó«ÞÆßˆÙoÝp½u{ØÛñ-û®£^"Rì(ˆœˆ”ëj:jSsRÓ $¤¥Dd¤¹‚íÈÈÏ$yÎFãªÔ¯”áytþ#—õ{ØÛñ-û®£¯{~#e¿uÂô`¡ÕjWÊp¼ºäÄÚ Èu‰tÖœ’á:úân¬’””eïJœŸBH¹ˆ‡4ê÷±·â6[÷\/F^ö6üFË~ë…èÀ¯XTªÊ«»~>åIjBÕ-P(¦ñ© % Í|VR¤¤ËIs Æ»c’ò]t~OÊ9Në-èßow»ÌskÞvú¹õvÜüG:ê÷±·â6[÷\/F^ö6üFË~ë…èÀ ÊÔ4²“*)¥‰*–É{–}JR”ê{‹5-fj.&j3é1åO‹fS´•>5&™J˜[„2Œ>¤ï×4¤ÕÎdfYÀ õ{ØÛñ-û®£¯{~#e¿uÂô` üöt ¤š¬(1jÿ¤Je !׸ç·YqWéf—l2Ä]¶©øäM¤Û$ÆÂ ²Ý—êa RxcµQ—1ŽuÕïcoÄl·î¸^Œ:½ìmø–ý× Ñ€/±¢Yqk.Ö£F·ØªÙï‹Ë3ÍøžŒ·êµ+å8^]?ˆuZ•òœ/.ŸÄj;l÷Å噿üOF¶{âòÌó~'£mú­JùN—OâV¥|§ ˧ñŽÇÛ=ñyfy¿чcížø¼³<߉èÀ~«R¾S…åÓø‡U©_)ÂòéüF£±öÏ|^YžoÄôb¿tÃØ¬û,\væÏiN>“[%*‰ ½áàñ–øãþÒî€.ýV¥|§ ˧ñ«R¾S…åÓøŽ_ÕïcoÄl·î¸^Œ:½ìmø–ý× Ñ€:‡U©_)ÂòéüCªÔ¯”áytþ#—õ{ØÛñ-û®£¯{~#e¿uÂô`¡ÕjWÊp¼ºêµ+å8^]?ˆåý^ö6üFË~ë…èÃ«ÞÆßˆÙoÝp½¨uZ•òœ/.ŸÄ:­JùN—Oâ9W½¿²ßºáz0ê÷±·â6[÷\/FêV¥|§ ˧ñ«R¾S…åÓøŽ_ÕïcoÄl·î¸^Œ:½ìmø–ý× Ñ€:‡U©_)ÂòéüCªÔ¯”áytþ#—õ{ØÛñ-û®£¯{~#e¿uÂô`¡ÕjWÊp¼ºêµ+å8^]?ˆåý^ö6üFË~ë…èÃ«ÞÆßˆÙoÝp½¨uZ•òœ/.ŸÄ:­JùN—Oâ9W½¿²ßºáz0ê÷±·â6[÷\/FêV¥|§ ˧ñª¥!I4ª£I2Á‘¾“#/¤s¯{~#e¿uÂôaÕïcoÄl·î¸^Œ~Zh[öÕV#mµœ¶O¤ÉYçç>žcçÉpÕB]š ØÑ&Ã-L8IB_IšŒÒÛ“1Ïú½ìmø–ý× Ñ‹kseµ‹Uêå˱æDS.ª<¦møŠmfDf“ÝáDJI— –HË Áƒæø…O¬•ò„ŸøÕ÷1V«ÕªáL;u)W'iÜI4k'JO 4’÷稰jæ.bÔy"²W£¢S“â¸jJ7Q¤ðdG’<AŽwrÔ&Û°ÍI¢6XdÊ;ì¤ÛÉJx#Xm|9±ƒçOJKÈözÔiÞšÝÞù_µ´šÚ=,P[»ß/¾e¾=n"ž‹ôKŽü•hlž†óiRÉ&£I)I"Σçè1@¤Ð+g[§Ny–Q©%!gÊg‚mÄhOÆgŸ ^¦Çn\7¢º§RÛÍ©µN©¥‘`Í+A’’|x)&F\ädcF‰RµH^´lîiÐkW«Mʼp»ðò=GŒ¹,Ä`ß}F”’ž 5šŒˆˆˆ¸žLÈ…gf¶k¶u:\y7MÃrH“!Nrš¼å¾¦Û#=ÛiI™¥8IöÊ"#Z²g‚Ò”ï«Ñ_™LS1´oIÆÜI-FDzJ±’#ǽî fÓmFRå5È´¶–Ö§ Du¶•«($§Rˆ°fF®%žn$6ù¬ÍmFÞ¤8Ùéu¥–Ú»†_öó9 dâ•Jy†e´–Íä¨Ûݺn&’2Æ’<öÅÌ7Öü\¤ª2ýÉ[³m  É9Ïl}'ÿȺ:LåØàã&d7c)çÙ'ã.“è22æ?ÿÓÉ SiÍÅrd™®—}ÃR–®œdÏÜ"ÿæy3¨&»RG£ËªK3&"²§WŽs".bþÓæêvT«.´ûUù1Iç7m¡˜iLe9ñi[¬ž³Ï~Zº¹ŠÛ´%P`ÄzRcE•,Ñ%J&Œ e×x•$‹RyÇ@¨Õ£HJŽ3é‘UŽÂº{*y¸ÊŽö ”³SiG Fxg‡¥öF‹ N²PRm÷òá¹5kßÍn?;í])ë•%QÂËô¿›ãò-•F·"å©BªÌ‹!¤BŽû aƒl‘©o!YÉ™ä÷dgÄȹ‹ºv±LÙd¦œõZKZdÊV‚Q<ãš™JF ffeÅFGÃ:³‚1ä{KÓ%MY+.îä“áæzÚ©³ÇXîÞûûÝÍ,©“¦IqŠi:DÉ,Õ»JMkÒxQáD|øsdÏ›‡>3u*„ ÌŠ†ùqŸI©;Ä ŒÒ\êN’.ná—â_Ûü0éR«Š~K8¦–묡¥cY©fi<ÿÁí°xâGÐd|qn‡\’ËÈŒóSÊšq <¡GŒ£I"? kîxŒÍ£9Lc•Üio4\ëB\J”EĸàŒs’”•¢ìÉM-ìÑ×j(0ÉΫ,§;”´ÚRÑ0•g‰ž¤jÐŒ–LÔYþÃ<ÊЮ®­ÈÓ›KH¸)-$Œ’¢?zâ3ÇB°xîs×ÔYMg[‚‹-¹Ó7­5ù¹|Ù¸ÚMQç)|˜ó’çVäÈõY´ê™»DåÐbòÇ$á/+&âx{ÓÉSý…Ü´ ¶Eëê9Îûßw¹«Z5%ø#eó6Õïòÿù3ŸÂcÇg×mÏcÅ%¹lé4:TH1 ÍûîGlˆŒðfHJu8â’•mÅéV“!í^ÿ!Ïÿ“9ü&+”ºuEÿcÎË+t¸ÏM~O¦O\F[58û*§ª3ºH»cR·I)%)fÑ!%•‘•ôª•ihõ'F8¦¢Ú\ÚNËõe`”¤“vEREç¶)¬Qj”ÊŠ$M®Åf©J‡tˆ*†§£7®CÙ `¦G[ˆD—;R¤º‚B ]gbBNЭ4M“0ꌴÂä°XI8ÛÍ%ÖŸB5)ImiQ– ÏJÛu¥îõ«óÕ94Ê+Sk6½Zâ8í¥i)Ôú•9ÈÌÓRÛL¥ :ûdÚò˜‘’´¸zÛä‹3s¶IÉìþÇz1¯qS£®%\X4Ê+JÉï¡ÄK†‰ RŒÔhZ¤- ÉvÉi.”—cÆöw·)ûCKPÑã+Y¹bµ•°Û½ÙÞû»÷¾ß_CThbžçºÞ|þýÜÎ…»Ê/Š¥³Étò l9Ü£yç(vR4iÇ <›9Éç_1cŽc5HW%QTø‘™”ûZÚ4òKjÎ0yS–òZxã%šbÅ¢];^®Ë¹íÖêp ݦ1r™53¼åsF{]âIMžK¶A,°e«KfVµ9Ëž>õ²ŽUZ³cR#»6m O+•¡‰Hš‰›fM-M-¦ÔNšu‘8ãHý)榅T\¡À­Òßå*›•Ý Nñ§JB°¢#,¤ÈðdGÝ£ódz5»LÙNÊ(³¬™­"-u†kô֍޲ì™mÑåîzåRF¥¤–N%&DjâC Ù”ØQí Š$ZõtۮݡR“ÆžŠÑ=væäÍ*i¤JKšL‹KdyN;Pâ©uPiWå³÷}GŽÜ‰ØejÝ!ÍZ=êORAö©Ê¹¸vÅÐâÑ¿Çü“õºï¼—1ò èÏÿa|ŽÿcûLcuÞ»³ÖÍ[¯~»9OW9›®¥ò­zyV4nù¸îug_¬îCÆÎIƒCцë­%kŽñ Üd̲hQ¡JI¨¹J”Y.eÄqÛbŒtݶ.DJ ‰ª“QšôÊŒÚÑäÄB’â’e?VêK£JÎ Ò• σ[²z¡nϹ합úU‡m³çÄFO ux""GüÇTÛ\47­dQê²U* ‡ži•N2º£{ÒBÒyÔÚR׌hJ¬ñàAÆ®+& =ëÞ‡H£N¤Û’©T‰(f‘N5´¹%*VÿK)Á9–ÛŽN¶žÙH<`ÍE,(6щZµ­$B¨B«I ¨ïSÛ~<¨Èl¤r7 × L)i<–¼¬€;øÏslû‚¥L•G®SêÓ›¡L¢Ð¡ÉR¼™ªÌ<ô’Zx™rtÆÖ²÷ªeÓ3íx_(”¸–×yȡۘ 3Aƒ=¨¨]¬‰I\íòXl°•<¤"9Kfmç߀-÷Ýw­{½sr^WÔŠl‰ÜŸy£{ºiKÑ«§:qœ3ÌaoWz¯W¸éü—sÔJ’ ëÞjßj‰F¼`´ÿHÓŽ>ó9ã‚â»v ³>6Ñ[«Yµºýnu<ÓkÊ…MvNå®H”›HudÉ“äò”“4›‰Yó¤mfЫ ÚµÅV®R*[9Ë……”c­X©ðÜÅ6Dg%”­ F $ÚÐjÂ&mÒ+”7}"ÙaªlÙÉ‹$ˆÔ’Еė! Μ,Ï’):HÈÈ”J>‚U˜q·™¼äÑ+3éŽTiÕ‹ê\É)Ð¥6PاLˆÁ¹ŽÒ÷MµQ½ƒÎ¬Ô퓦E«ÒmÍrÌ…y´óԘֶݧ*˜É¨ša%ÅëSh##Ðá`ðdê· w©{rŸÉwÝ[©.½æÎ˜’$kÆWô}8áïóž5Ã]êE^ܧò]÷VêKƒ¯y§s¦$‰ñƒÕýN8{ü熊Õh-.‹D7ìÚÛöz/•Ë‹HE9Õ9ÔÇÛ3Tb-hdäŠÝK)q(ÓÛMT ²ª% Þ³+oÙè¾W.-!×MÈÔþ¦>Ùš£kC' ÜVèÒYK‰FžØ’`wÙ8Óш>—4-mš ,…+Zõ(ŒÓ”’{RQåiá§R‹Â…T\¡À­Òßå*›•Ý Nñ§JB°¢#,¤ÈðdGÝ‚‰n*Zè‘lËjÔvñ–ìJdÈ*J#S—E”ʉÆV^äÒßS˜BȈ‰ä'’!¶ØÍ}7c=£ ŸiV!³šÉT­·‰/JDt%õè%°n©J$û¹)iV“,™ñHX-~›NNÖê2î{b§TœôØ‹·j @qö¡°–š%$žIiŽdñ<µê4ëJÈ»z)}6¬ÒëµQ˵wìSYä.J„ª³J`¹N4i`Ûos«$´êÑÃP»K­Ä™VÞ§ò‰Å”:’ZœqN›m™f®Õ|YÁ’U•’L”EãbWzè±è77%äW¦ÇÉ÷š÷[Ö’½°Z±«ÁgÄ9½ŸT‹¦ƒ@™æ Ÿ[¸î›u³AáU-E3#çJÓ%n$ùŒF]»°š 0#ìéºM™[ VàÓÉ7D©´×cošäŠI4·VDO(ß6T„‘¨ÛJ Œ‘ ÕbWzè±è77%äW¦ÇÉ÷š÷[Ö’½°Z±«ÁgÄ w©{rŸÉwÝ[©.½æÎ˜’$kÆWô}8áïóž>+°š 0#ìéºM™[ VàÓÉ7D©´×cošäŠI4·VDO(ß6T„‘¨ÛJ Œ‘"ízZõšëÖU:ðê}ÂÂ.W–túc±£¢9S&IÔ)ç{SpÒ“3Q%ZÒƒ.=°4©Û'L‹W¤&Ûšå™ óiç©1!­m»NU1“Q4ÂKÝ)‹Ö¦ÐFG¡ÂÁàÈcͶڕ³Ù*“V§Û¥srº=1Ê ³Ü^LH4?O,:l)ýòÒÑMMEÀÒõR5È´GÓ>\g¥0Ö…ví2¦’ⳌûEƒ<ž®Áã4p»zÞ¦õͳ»‚àÙÛ )˜5M›4'(oœèË„æƒJ×Rû‰ÖdLo“Rx‰ƒjD{j•[oU"Õ¤ÔT™:„ôy˜u·xý[©,(ÔM¡’#R¤àÐx¹€ã-So›Š“6–fF«ÚÔyi“$ ÛLê¢Ûq–¦!GÀÈš$«Qp#’âyÐx°X.Úô Z³S¶¬Zý0áÂKÓ!õ%ÖdÍu´-F„%xåðÁ¸Y%š’ZÕŽta¦³k½qR¨r^Kº©Oƒ£y¯<š[Ñõçï·Z±Ñ«[ÖF먂é99&ŽI¿ç÷óF÷tÒ—£VNtã8r2è§f;³¬ ¦©pÒqÉ2ÖežíŠ FE©¶ÏûO=±ñÓ‚î™ód›=–ÿ—6þ”+ýŠ ¶Vj1é4¹j2e„Õ¤²gÜ".“>b.“=–ÿ—6þ”+ýŠ °Þ0äηÞn[ù ºÌ¦ÙÉ{©²êÝñáÛhÓǺ9Õ”£â®ìR¬¥IÅ]¤Ê¼ÚýÒ“\‡_§ÒЗI­Ã°œy pÒ•k|–”¥zV“Á¹Ï¬±Úî­Åy/°QæÅY7!¤«RḦÉIW I222<pÈŒŒŠ½I¾X§ÛµØÌÓYª*tå8g(‹“6Þå–ÌžIžujBˆÛ2/zy2á™ÙɉՅ‘”ihe˜Ç§ê7n$¿àºiOtF\0gâè:UJ•¢±âº»Vþ_¾Gƒ éÕ*i‚ž+¦ÚéýKzì¡Ñf¦ Çå;1M“¼š应™Ô†P¥%&de“"#Á÷ªïºjµ!Ömyr$ÊÝ8÷Sß”qÛ"^¥vÍ.¨÷ˆKf’Á¤Ôf|d0¥Ézܹ.uN‰\K·~N—N\Õ±ˆÍ²mš‡ *J›7 Z ¼éâB­_Evu­Anä£;W×&£®UV€íGvÑH>K½ƒv[ų¤õšKF•àÖcÞ?Buª™³(Tùu(|†sñ[rLmZ·.)$jFzt™™gûñM«ÆªS)uJZ›¦ÚfBHim›ˆqIY¥X>Õ8"5ee’"ÔeXÙ$o칊]ÉOWlìØÎD™ГÊ^Ch6–¥á³kAMK-8í”\N¯³º+Pm]™Â§Ûr)’)µ$•iK\lIM"KN<³4,”³BwÅ”¨Ìˆ”gÀÒlÚÏ\V…àäÜ—ªtö&nuëÝo[JôêÁg±œqÌC‰ÿ”]+ý¨¶B{'&Ë-(s#»KHm<˨4-µ¥„’¤Ÿ2222>aéDÿÊ.•þˆÔ?Û!â ŠEÅ_¨B¡À¦UêUJìÊKæ§1X –Ù«äë4êW¤’¥ ñ‚3/j­Bü¦Q«oÔ—:3Ð)OÎb\i$ÄqhI™4­QÛp•Ã8ÓŒ~¶E[gõfìZä*Ê¥D Ü¶õ%1*Žg“Ç}†4©‡UÌÞ¢^¤š°ž âg’+÷hð&Á¹hÌÍ Ê¡d‡j”ùnÎTdéC^ìÓ ,ÓÛ=«$jÂqG‚IWÚ:f¦V½îÿ[o¶çºÖî1è 7ZNÍ««¾ôÞv`mšínÀÚ<épìºÛÕWa´NÉQS¤´ÛDg„‘­ÆÒ’QñÂs“$¨ÈŒ’x¼8ÖF¾?ɳ¿äÏÿ‚ò(×Çù6wü™ÿâpV\ GÊ úÉQÿ(IÿWÿs’XfK bCHu¥–…§$ÞCH¦ÜïÈq÷v—wÜQ­ZyK&y<GÁqBîÔªšu}ß8èÔÜF üH­©_ß«}×ÿkq½òVÔ¶‹ú·Ýoö·Ñ‹ªuŸöÞDkiu£÷ÃjÚ–Ó?Vû«þÖØôcøVÔ¶£ú·ÝSö¶Ç£ÔÖèdk©u#öíJ¤–S:+räóD²É%dFD¯ïÁ˜×©o™ã©äM|A:²gÉçGÿ!øÀö¥µn‹î¡û[gÑàö¥µ®‹îwímŸF;ÁipVŽ$r›Ñ¦ï+3÷[hKh$!$”—1þ‡áÚ–×ú/¹µ¶½þj[cè¾äþÖÚôcžÍ[¥—Ú)u»%Ä‹-‰QÛy$y"ZHðcÎ%: EšãDi¥9¡8Èü({RÛ?Eö÷ím¿F?žÊ[kðíÏ&ߣÙ+t‘´Rê?{€üÙKm~¹äÛôaÙKm~¹äÛôa²VéM.£÷3”*;’NJéÑÔñžMfŽ9ÿý"¬°Ë?¢ièàCðge-µøvç“oчe-µøvç“oцËY÷ ¢—3÷mY§¥Ka¤êqÆ„–q“4™ØlÜœ¶¶ymÛ“„ìšU&,œiÇ [L¥ 4å²<¤ñ’!ø ²–Úü;sÉ·èò–Úü;sÉ·èÁhµ—åE.gïÉ´+mÄ›Že£lI­%ÖÞMEØ\’[x$,6µjN”àó’ÒXæ­5Ýcë¯òœ}”¶×áÛžM¿F”¶×áÛžM¿F'f¯Ò6Š\Ï£ZkºÇ×_ä­5Ýcë¯òœ}”¶×áÛžM¿F”¶×áÛžM¿F5~‘´Ræ}¨½K¨L¦Ë˜Ë½L’r¡«|énÝ6\dÕ‚NÜÞq8<—mžr#,Þ­5Ýcë¯òœ}”¶×áÛžM¿F”¶×áÛžM¿F5~‘´Ræ}ˆº,NGÉ)´¨ü…•G‰ºlÓÉÚVM·†ûTž„d‹Ú§¸C7«MwXúëüƒçe-µøvç“oчe-µøvç“oцÍ_¤m¹ŸG:´×u®¿ÈZkºÇ×_ä8û)m¯Ã·<›~Œ;)m¯Ã·<›~Œ6jý#h¥Ìú9Õ¦»¬}uþ@êÓ]Ö>ºÿ ùÇÙKm~¹äÛôaÙKm~¹äÛôa³WéE.gÑέ5Ýcë¯òVšî±õ×ùÎ>Ê[kðíÏ&ߣÊ[kðíÏ&ߣ š¿HÚ)s>Žui®ë]:´×u®¿È>qöRÛ_‡ny6ývRÛ_‡ny6ýlÕúFÑK™ôs«MwXúëüÕ¦»¬}uþAó²–Úü;sÉ·èò–Úü;sÉ·èÃf¯Ò6Š\Ï¢°'ÓàBf ÐbÅaÛ,2JCm¤‹”¤›ÁA~­5Ýcë¯òœ}”¶×áÛžM¿F”¶×áÛžM¿F5~‘´Ræ}êÓ]Ö>ºÿ ui®ë]|ã쥶¿Üòmú0쥶¿Üòmú0Ù«ô¢—3èçVšî±õ×ù«MwXúëüƒçe-µøvç“oчe-µøvç“oцÍ_¤m¹ŸG:´×u®¿È4éÌ»™«ŽLBv{N%ä§É6 Ô§B]Ücu¼$à‰zuqà?vRÛ_‡ny6ývRÛ_‡ny6ýlÕúFÑK™ôU3ééœäôÆ‚RÜi,­ò%oÚMF”·y4‘­FEÌF£î˜÷êÓ]Ö>ºÿ ùÇÙKm~¹äÛôaÙKm~¹äÛôa³WéE.gÑέ5Ýcë¯òVšî±õ×ùÎ>Ê[kðíÏ&ߣÊ[kðíÏ&ߣ š¿HÚ)s>Žui®ë]:´×u®¿È>qöRÛ_‡ny6ývRÛ_‡ny6ýlÕúFÑK™ôs«MwXúëüÕ¦»¬}uþAó²–Úü;sÉ·èò–Úü;sÉ·èÃf¯Ò6Š\Ï£ZkºÇ×_ä­5Ýcë¯òœ}”¶×áÛžM¿F”¶×áÛžM¿F5~‘´Ræ}êÓ]Ö>ºÿ ui®ë]|ã쥶¿Üòmú0쥶¿Üòmú0Ù«ô¢—3èçVšî±õ×ù«MwXúëüƒæÍOl;e§ÇKÏ_/©*V’$4ÑžpgÒßö wg®xm7ȳù)Âpv‘Ò3Œ•Ñôß«MwXúëüÕ¦»¬}uþAó#³Î×<6›äYüÙçkžÍò,þA]å·Mú´×u®¿ÈZkºÇ×_ä2;<ísÃi¾EŸÈžv¹á´ß"Ïä ãqôß«MwXúëüÕ¦»¬}uþAó#³Î×<6›äYüÙçkžÍò,þ@Þ7Mú´×u®¿ÈZkºÇ×_ä2;<ísÃi¾EŸÈžv¹á¬ß"Ïä ãqôß«MwXúëüÕ¦»¬}uþAó#³Î×<6›äYüÙçkžÍò,þ@Þ7½/;¦¿®ˆt‹³Z;mòÖ&Ci·UŒž”ºòW‚Î2¤§‰Ëz^»ï/õÿ¼éÞ°?öyÚ熳|‹?;<ísÃY¾EŸÈ# ?nìªe…]5 ÕEÊ­qSŒû̸²o’Ço&m-i÷ͯ§<3‚Ⱥ½žv¹á´ß"ÏäÏ;\ðÚo‘gò.}™G£Í˜™³hÔÉR“/¿ ·,saJIŸÿ1œffy3Éžv¹á¬ß"ÏäÏ;\ðÖo‘gòP·ŠÞ‘ôHÎÞÏ;\ðÚo‘gòg®xk7ȳùádÜú$çog®xm7ȳù³Î×<5›äYü…‹ŸD†¦›L”ÎÖ"]FädÂB“ORVµÔ㯰áH’|˜Vs|œgŽ?öyÚç†Ó|‹?;<ísÃY¾EŸÈX¹ôj-:…3Q¢®k 4‚Cm·Yš”¡$X""#Á íp© A¥RjX2Áâ¹8é#à>qvyÚ熳|‹?;<ísÃY¾EŸÈ*éEñHå4¢î¢²>YôûZÏ¥»KµèÔºD'd»)Æb’Е:â²¥cG÷2R”¤°”‘ç«MwXúëüƒæGg®xk7ȳù³Î×<5›äYü‚ûλ¦ýZkºÇ×_ä­5Ýcë¯ò™žv¹á¬ß"ÏäÏ;\ðÖo‘gòñ¸úoÕ¦»¬}uþ@êÓ]Ö>ºÿ ù‘ÙçkžÍò,þ@ìóµÏ fù o¦ýZkºÇ×_ä­5Ýcë¯ò™žv¹á´ß"ÏäÏ;\ðÚo‘gòñ¸úoÕ¦»¬}uþ@êÓ]Ö>ºÿ ù‘ÙçkžÍò,þ@ìóµÏ fù o¦ýZkºÇ×_ä­5Ýcë¯ò™žv¹á´ß"ÏäÏ;\ðÚo‘gòñ¸úoÕ¦»¬}uþ@êÓ]Ö>ºÿ ù‘ÙçkžÍò,þ@ìóµÏ fù o¦ýZkºÇ×_ä­5Ýcë¯ò™žv¹á¬ß"ÏäÏ;\ðÚo‘gòñ¸úoÕ¦»¬}uþAX¼]CÔ™ªBÒ¯ðWŒôçfkV8‘wHr šÚ÷mÓ³Ë~曵ۦ+õH(’¶Y‡hAžHÈŒÐGŒ‘ÿ1ýí Ö¸-‹·p»µ«¾rið]‘ÉŽ4Æ”™’ ZgÀÏ‚>cæwdŸ€~ûö–ì·åûË푽\îTÜwGäšm+—Q*µäaêrZuLh÷í){µ/VxiZš,c޾rÇÖÝÑùB˩¥ֵU!tÙ,;bXI)ÍÛˆ4êI(ÈI=+"3"ÊH~/ÿLo}.ßüùž§ñU°P¿ý¿ñ6,©¥MaØœ¢\Ç98ÊA!¥Jm÷[I¨×«;¦’¼éÓ…+Q§Ik×ȵ«l²ãç—YDuÉ7X”Ó¨6Ò´¡FJBŒ”i5§)#3"<™cˆ·PvŸP®O\©u*«rhÚmÆÙŒQ¦Ç4i^R£Je#JT“Iè2>ÿÌËâ–ªÝ rLê,eHLÖš¢Ã¦š’„´ñ!¨ý©¯Bx-J>$ž Ǫb©~ä- q+.YWCsyé“f3ékZu)2 Î’Ïl¥ÒZK‰qÉ“ÆÁEŸB˜ˆ•‹¼[{ÄœymHA§&Ÿ~Ò”œå&FYÉcˆ¸Õö‰ÕxÔÕI)±'·W9R¥E4’ÒÂ^[¬¥¬Ÿ¿B¤?Œð,5Üá¡Ú Z‘X«F‘HedMÅ&äÈ\&¢*SºÖ£tÙhÍ=*JxçF£âf-;ïDIFۊ؇0ïfÙ4êý"˜ôŠä¨sêÕ)è,¢žN³­¦ØY­×w©6Ò{ô–I Á$ÌÅ~™mVªQ*T-šÉ”ªChqóIeDÚ¢S†_ú¤|xs‹¹~É¡Yí諘¨ËŸ5Ú¬=顉‘ßf3iAàýùn2Q—jjI–xÜ[û@¦Ré´ØÌ<üuÐÔáSÝëzŸ)çÒo­ä(Þ{Rã¬Ã.×xE‚2,ç<[š¹Õ(2§2ȹbRú¢ü&Ï%nf‚šÂž6BV—I¢Y¸hÒ¤™«N ŽqƒÇô݇t¸ä&š§²ãÓ$3¶1…:ÛŽ¨’Ú]A/S:ŒÈˆÜ$—f¸ëvÅ>¢ÝVù³ªÎ[)ÊŽ†8¨S”¦ã8{âpÔjA)DhÝ–œð4{þÚ¦^ï]èn¬ìºµN<º”SŒÚ[Œ„Mf[„Ê÷†n©’Ju%#<˜ŒsµÒ' /½•h–5Eû>­pªm1£¦Éa•Ær¡+Q8Ë®™–\#ÖD„‘6DjRi"ÔÚȵw%µX·TÊ*ì2ÂÝ5$›D¦ZœjC‰BŒÛYj,¥dFYæt:¥)erƒR\Ö\•"4Ø®Çe.‘ºÃrM¬”´éJ·þøµi÷§‘´{‚^D€s%ÍmO.UBd6c¾ù+F„/t£'MV{ÕaJ×Ä‹.œ±[¸«QÃrž¡ÌÏgÚ+¸hÕŠ‡/(ª‚ßø3FÖ£”é6ë¦ÙKO¹²áç%ŽØ…`_­ö›mRhQY¶¡T߇9Éò^š§ÒiuF”’[Ý<”©;´'ô‰2Ê”XÁži7+~ÐJûÌšØón«†ŒÌÓ¹µc:â§0ÃËmN%.)qZœQŸ½J¸ôt4læï\F¥•>)4äv¥eUÉ6Øu Zp̶ْ“Û¬‰$gƒ2>n]VL;†ÚªM*ú¶f‘Âb)ÉOÅ<[‹Ú<ËgB£,ÑOW(aÇŠI-öËm¶Q}Ð7p¢>VÑ™à“¥IQ)E«GðŸ\f‡äF¹$óhÚÑœmÆä9¼ß“št‘FpõPD•êR $J°×v…EŸcI¡³ ™.ÓˆJ[hÑ­-QÐfg«8Í9þÖo‡iþ(—í&-¥F¢­ê¼É”»*4fÁ!uE+ZÈ–“)Í$Ò¬ˆœ#Ç Æ*˜obpÓ½!lþª›^³Z~m%¥Ò¥°ÂØ:œSÞ¥Æ]xÖ…o{~Õ Ò”’ÍJÓ“Bˆ`.̯·q½oHnŸ¦Î²q™HÌ’T‡ ³A©nuê#Âs•Di23ÜÖn;^¡å§3m><çáL„qá4D·ã°ójÖÙ-)i.©å,ô‰ÄJ!˜Ýák=yÝõé”÷µUjnL§<í6<Å4ÚqjmM<­ÚT¢R;~ßNƒÁDâŸßèFvgWz›H–óñÚzumÚC°JLnTÒÐã ö­-ä©k5¼¢4$”©FIY(WúÔ®õ«•žMºßhåMo÷_¸Õ½Ñÿ¯§N8çöwý³"ïf½!vŠ í"áŒÓq›^ù‡ÞŽ¥!fn…¥,d±¨ŒÕŒ‘vÃG×M OV±QêçQ:É7äºy#ÞïuêÎï¶Ñ£ß~¶)O¼8øÕ\6%Ñ@1ê¤ä.ÜÖv9êÒF¶Ð³RRjàJ2$žKy!ZJÕÙN›pí Ó2ÒÕ˽äiRS©½ud–ó¶áÚ4¢á«¶2èâT±ÒM~"’I=ÀÊ€Z˜´7»@ Ú}QÇUú™þ¹ý,i—=î®ÛFûå«Nxg†±6ÕiTΨTn·'AÈlž6ˆðnZµš9ÏVœ`Œù¸‹½3k5¨­µ2=Ár±nÒÛ¥5"œÔÅ¥ DvXCéKD½KSnãV®8É'¶ƒël›%œZŠi ¥nš @Q­“ê9ª#}:‘Μñ2%$±Ž8ªr:ÚÌ;¿fUÚmÇUKŠ—iÌÍ–Õ<ߤJi‰²f–õœYJÉ%9áœ`ÈP‡f¼oBEÕoß Ì©®|WeT#SÑ¥#'V™!¦ß^÷-+ IšI íTFGÇ#Œ‰¥)5øˆ¨¢žà©ÌÑÞä¶¿ãËøT*"Ýyÿ’Úÿ/áP¨NíO[Cì‰$@Èj' A‰è`$„ ! è' @€ $@$úС–*µ\ö2Z4ª |¨$Ño—múÚA©z´´áF\ÊÏŽ82ÓÜv¥rËö5]–ýbê;¸Ô§Ê#ë†l¸ÓzÜÔ{Åë"èæÁpâXÆÃcÖ%±ZØõ™RªGª¿%Ú3:éì!$F¤‘%¶ŸJ\3Ú¤²ff|LÌymšÁ´i;&ºª0©õ2Å*B›7. “‰#Ðe“B¤UÏÌ¢2>’2à(Xý&Jœº?5HÙµu…W.œf]Çùé^è¡UL±ñáÿné~ÊE£5ø­{«ð½¿Ë?m¦{2†JëþÛõ·¡ÇWbUÑÏ&×_å ³ªh./Ãúêü£¦ÈæÙ<ÃöTÿŒ½§.-dx³þÐ×ó9êíyèçz7ÖWà<¡KG;Œ~Åà.ò9ŒjäôÔ¿Š½¡.-de—±4UÜó*®S$#m~Ã?Àx.+ˆç4ý#}+œkds˜ßOøM—²3ËÙ2îyšÕ‘§œy-Ô§œŒ{>0ß!íÍ-÷¬Ž2öeÏ2U1¤ó¥AáUΗ>‚üF+£Þ‘¦>×Ò_zÈå/gQFÁUxÅ·~‚üGðªäBçmÿª_ˆÓº1]æ1¢>Ó®ùÞƒIå\Pˆ¸µ#ê—â<úæñ2~ªZwÞ˜Çé#§Vg7¡Ò-½s@ø™?U?ˆuÏâdýTþ"¤b¶ê¤lt‹w\Ð>&OÕOâsÀø™?U?ˆ©@€ÛªŽ‘nëšÄÉú©üC®h'ê§ñ º¨Øéî¹ |LŸªŸÄ:çñ2~ªQÛªŽ‘nëžÄÉú©üC®h'ê§ñ º¨Øéî¹ |LŸªŸÄ:çñ2~ªQÛªŽ‘nëžÄÉú©üC®x'ê§ñ º¨Øéî¹ |LŸªŸÄ:æñ2~ªQ!=ÐÛªŽ‘mëšÄÉú©üC®h'ê§ñ º¨Øéî¹à|LŸªŸÄ:æñ2~ªQÛªŽ‘nëšÄÉú©üC®h'ê§ñ.è€ÛªŽ‘nëšÄÉú©üC®h'ê§ñ º¨Øéî¹à|LŸªŸÄ:çñ2~ªQÛªŽ‘nëžÄÉú©üC®x'ê§ñ º¨Øéî¹à|LŸªŸÄ:æñ2~ªQ º¨Øéî¹ |LŸªŸÄ:çñ2~ªQÛªŽ‘nëšÄÉú©üC®x'ê§ñ.·U"Ý×4‰“õSø‡\Ð>&OÕOâ* uQ±Ò-Ýs@ø™?U?ˆuÏâdýTþ"¥ÜuQ±Ò-Ýs@ø™?U?ˆuÏâdýTþ"¤Bnª6:E»®h'ê§ñ¹à|LŸªŸÄT@6ê£c¤[ºæñ2~ªëšÄÉú©üEHƒ 6ê£c¤o. Äj„$2Ëo%Ip”f²",`Ë ÿ´h€z•%RX¤w§MSVDˆ s.O@ƒÐ ÀIBÐ O@€ H€I‡t ; Jv ðc|Ìßñ,yíûàRðù¥ÿá1é°_€»æfÿ‰cÏoß—‡Í/ÿ Ž}åŽÚÅNÝzçE­7ÉšyýÉ:ÒFiQ¥xÁŸ7 Çth)•(ôøµ”9!L¾ó8`ÒJɨ’¬`Ë›‰ø—ðì©GON·òÙÞÿý_?—™û½1Mèv‡¯òæ•n¿ ƒ\v­Nd—ÉMQÔ½ 4™!y22ΘWàÚ*7æÕY‚äóÓ¥6j7£&GÃ<>’:5}(¢Ö£Õj/¸ãñ’ê–æTiY>9ÓÜÌjåd•IoD‘GQ6–Mdñ'N0eÍïSÏý¿Þ?cF:ZtÔ{“Ý&“þm÷jÛív¿sƨô˜JWçܼ»¯~þ&-¡n´˜×e:«)ŒÂR‡žA(™3K¹–H¹%Ç û–“têÕµ=©ŒU©5 Ì·¼ÜšHÏxYB’¬ð2Ï?pòBÇL»(²%ÝR*Ï9º›Hm¤%³RÔ’BÑÐX#Á—9‘dƪ¥rPaŵh”ù®I‡M¨7.L¥²¤c 3<'Ÿõ”|3ÑÎ7ÓŽ‹ªšÝ{;ïþ}×^kÈÍ'[º{íîáêEù`D©Ü•³¢T ³23(}¦cšp‚m$|K #3ÉàˆùË8È×P­º|ë.Íz©Ô¦¢N¬“.-år—;g°ÚÞJò¤¨ÒI÷¥§)<ö¼wòï:›tVîÈ9§ÈˆQÙÉ–”­D”vÄ£.nÕ$yÁðŸïÒÑÕG%m÷ïÝÅ[5ÜfÿÜ–þïðWöñF Ñ¯Y¢Êi*2I?¸Êm10Óz{cà½y5pæéâ9«ã¡m®¡@­]®WhUeN)©I¼ÑÆ[{ƒB‚,«³ƒ>Þ¾"¥µ²· ÷áW0ÝŽôŒ·F#½#¼r1®óÊtb»Ìcl21÷¦1úFC¾ôÆ?H× @“,A'Ð Iô!=Ñ'º€=Ñ{¢¢öá³6îºÒ-KB›L£´õ_6#¥–›I<ñ)Å%Y> Oöö¥ÍÍùÐ~™¯ížÐ‡·ú}×M–íJŠº S%¼Ôu¡M(ß[™$¬’gŒ#8è3ÆL°å÷ÞË¢Ú »­Ë¢%ÍFfQÄ–óQÔʘtRfyNL‹9ýd™d#o'b<Š™šçLsJ§® ÍæT’6ÒFfJxÏJU‚>rÆHø™˜ö¼.Û"±éÛ=²ªÒ«½V¨òÉЦÊ HQ ‰\M^ä‚ɶ>mïÛ»eñÀ»®:M5X´ƒ†í˜ËI¸ñj4©/j”’–£ãœ–2\ Œ ^Ì6iL¼"ÅTËÒ%2l×”ÌX,D\ÇÏN¥[”äø)x,qæ« gðíú6Øè·>™SŸD¥!qd¹.F¨òJÛ5PfZ‡‘wŽÇö…bÛ{5ƒ ê¤Êj%M2ê’¸íU¤-JK&¾d¤ÈÒ“É—½?øF6õ]¥XŠ«mnS ]EËGŽÍ7ß#qÔDu¥ ò‚ÒzHJW…aYçÁc*Èn½•ƺ,ý™ª‘™BŠt%L®U“JLGV·L´ëQ™¬Ë'Ò£ÉL~x­±O‹V••=Ê„&Ü4³)lnMÔ—ëhÔ­$}sŽç0ý'KÛ]«O£XñÔQ.ŽTsr2¨Ž{‰“ !<é툔NèÎK?Ø?8Üñéqn ñ蓹}1¨¢HФgµ3%8KœŒ­ˆ = O@ƒ$ IO@=ú›Ù7aÐ^¥CiÛôÊ}J$¸¤úaDC:Ú”·F­Y÷Fˆ‹=Ó–Gꊦ٬^ÌŽUÑSåÔmö™RŽ#ÅþÌ•¼ÑiR Y,ðV0F¢ãÀÀ~ÈKJÚgeTm;~šÔõWÑJ'ãÅm¾¶ÊC*J–DFz–ÞO'ÏÎ)•‚Hié”û¾ŸPºiÐÓ2U¸ëNeœ%Ó<(ù°X.rÎ2CÚ£´ÚGaË6;sÊUÍJ¹º¯.!´âKƒÒ\γN“ɸŽc3í¿°Å©í©lÞ•wWvHªT%ת´ÄDnŽä5 ™p‰©N{Ó/sG1ž0|ùà= lŽ›3ft[ê¯|E¢Ã¨ÊS!ø*^ë8‚ÒiVVfm‘ã "#33íxÖv½aÌÙÕÝÔsZš•ÇL–B ÛQ©ãaT+†ÛZ3…¹Æôé[Šm¯&„«¶4žuqÁž}-­¬Z5[Çi*¸dI¤S.ØhŒÄÂSIm•²Z’Œž£Jõt–KR){(å¶%tuw×-mºO'äyäÚÝu½æ­}¾7YÓ„óóðãgwØøÊî Å·O¿ K®@Œ™MÁ8+BœlҜըɩXÁ¸Lñœ Œ›ãgtëg¶åâ‘/¨7Li²Öü[Q0‡^SŽàˆËY$ŒÕƒ.#vÎÓlˆ~É{¢ð“[ÑCJDxÒ¹+Ç­ÂLb2ÐHÖ\[_".Ú@iRÊ·uR(¦³AOœÌSQs§xâSŸþcô•ûgÙÕ6Ñ-Êm­L¦=fÁ*Øíé}ÍL)å‹ç_™qÏ>yÇæ›r¦åá§VA-Èš’„™ã&…’ˆ¿ùý}mNÄ: éT·j3%Öo±ã; ÈŠl¡¥ J5,ûUvªW½3㎎ Í›Z kd6úèví…W¸êg"c\ %Ç\i'„¥¢÷ÆxÒ|L’YãŒÍRã½S±d´¦ŸefÛˆQ`Ò¢<ö‘ŽÇ±ê¶Éí94‹ÍúýqŠõ=—ŠM-ÈÛÔHqMš=ÉiISÛöçÒ\ØÉò‹š¨ºÝÉS­8Ñ4¹ó”¤ä’n,Ôd_ÝêŽÇvoV;u³Mßõ­Õ.«nÿÂùN÷u«yÏ]¶žnŒc€­ûmËj«³š|Šm¯E¸+ «¥šñÔÚ%œX¦¥emjá’A Ëægܶk#xwùN™×W[½HêW%Vîóy¼ÞûÝ:¿·8èÏ]Ù=ÿc³³ª½pUåÐ%Ð+iªoŠ·S<’¥¨f‚…K‡ 4–£”Ú”5$–Ü$-Z4Ÿ 'îFiæíÏ£€§û!èõXÍR*j·ì¸4WÖ÷!™m2ICä£,%å(‰<0Xâ¼g£K2.Ï]Ú9*½|Uî*DæéuhUæä©gÁHt”jNŒÌ‹õ‹ÆCmµ{ºÖìcnìâÒ¨¿Y‹K¹OT]Œ¦5¨ÍÃ$¥*ãþú¬ÿqsô««ØÖuiÊûCƒP¡?ReÕ¡¡ K&’t÷DIZÈÖ{´‘qϺé´{$¨v­"ÌÙÜ«R’Ô(³à¼þðÚIH}&ˆêA¼¢â¥³ç>=Ë^Úîëzâ°6sK£T9TÊ5,ãÔܸ˛¨éÆT’%qm|Rf\?´€j½³˜Õ´õaÛ7qè¤ü¥½/uVuìž·Z=*2Acv¹3Ág?ÊÔÆš”S¨¥åB'r œo ¼–¢NxgÆzGéX›f²9Rv€üé½s&ÝêJ¨ü•F…¹¼Þo7ž÷N¯íÎ:3À~j¦µúŒf&J(‘œyyóA¬šA™—¤¸ž '‚âx~ˆ”Ýwìžó­Ä²a[ÔjK ¦‰?““rž‘£¶BÔFzýÐОsÉ/mµ…gÙÔê6Îíº•­L©½yA•*dÙ ê}½,%ä“kçG‘pÇ6yÅck5œW,˜vý·´‚…J£CQä"‰$Îd„¤ÌÇOIeGÃ&X#RŒó‘°±¶§b˪\U ±+6tIš„ÜE8S mI4¬»Tö©O¾2㞎 m‘jÐ,Û*ÿ»ê´H÷è5“¤Æf Ñ8Ñm Q§˜Ì÷¥Ç£Osé;"¶Wì˜ê2`'¨IêÉÀJŒg¯u».<kí±ÍÑÌ)Ö&Ðmš½±yÚ—¼çèñ®ŸU-¨ê|ḅ­”ñÿ{NÞnÂößG/d?]éfJ¨ƒ©Zô{¦ëV½æŸøÎ8çÓý¼?d%píê çl«f”© YJÞ•ª3ØÏ¹)‚"Ypí²¬éV ¸Èë»[»í3Ù…½³»F¥"±›)ÉnÏv2™É©NPIW÷Õdù¸ìä@¥;ø ±¾foø–<öýð)x|Òÿð˜ôØ/À]ó3ıç·ïKÃæ—ÿ„Ç>òÇmb§îŠWôËÞ覮—S©È|©´é“M¼käì)Í9Î3¤Áýà"n«Hú&8Šrv+9†¶O0·=gÝŠ.Í`ÿèN~ë"ñQv¶½`ÿèküè)E®(ójW¤ÿ2Ì¦Èæ1«“Ò/X7²³‹R°ôEþýœßŠÎ›J°ôU~Ò£$¸³êÚ(R¹Æ¶G9Ž€þÌv‚¯{gÖþŒ¡„öÊ¶Ž£áfVþŽcÒ£Všã%™’s3¾0ßÝ‘í-\ÖUcÈ Wv=´õsY"= zMùÖhÏ&ŽrèÄw¤t‡65µ#æ±ëGùŒw6+µSÎ,ZÇ’/Äl†—C­fŽ29££Þc5͈ídù¬JÇ“/Äc¹°Ý®qaV<™~#T4Ýr9£”“9{¾ôÆ?Hê ØN×̸X5¨ŸÄxöÛ~ëQ?ˆÕ?E·kÑÉÅò9©ˆ,ö ¶õ¨ŸÄG`]°ø¿¬}Dþ"Û~‹âÇ5êFr9±ô,ö ¶õ¨ŸÄG`]°ø¿¬}Dþ!·è¾,s^£ ¹ÔKì ¶õ¨ŸÄ;í‡Åýcê'ñ ¿EñcšõeÈæ€:_`]°ø¿¬}Dþ";í‡Åýcê'ñ ¿EñcšõeÈæ :W`]°ø¿¬}Dþ"{í‡Åýcê'ñ ¿EñcšõeÈæ€:_`]°ø¿¬}Dþ";í‡Åýcê'ñ ¿EñcšõeÈæ :W`]°ø¿¬}Dþ!Øl>/ëQ?ˆmú/‹רÃ.G5!=ÑÒ»í‡Åýcê'ñÀ»añXú‰üCoÑ|Xæ½Fr9 —Øl>/ëQ?ˆvÛ‹úÇÔOâ~‹âÇ5ê0Ë‘Ít®À»añXú‰üDöÛ‹úÇÔOâ~‹âÇ5ê0Ë‘Í{¢Kì ¶õ¨ŸÄ;í‡Åýcê'ñ ¿EñcšõeÈæ€:_`]°ø¿¬}Dþ!Øl>/ëQ?ˆmú/‹רÃ.G4Ò»í‡Åýcê'ñÀ»añXú‰üCoÑ|Xæ½Fr9¨•Øl>/ëQ?ˆvÛ‹úÇÔOâ~‹âÇ5ê0Ë‘Í@‡Jì ¶õ¨ŸÄO`]°ø¿¬}Dþ!·è¾,s^£ ¹ÐKì ¶õ¨ŸÄG`]°ø¿¬}Dþ!·è¾,s^£ ¹Û @é}vÃâþ±õøˆì ¶õ¨ŸÄ6ýÅŽkÔa—#š€é}vÃâþ±õø‡`]°ø¿¬}Dþ!·è¾,s^£ ¹׸ t¾À»añXú‰üDvÛ‹úÇÔOâ~‹âÇ5ê0ˑ͈@ée°]°ø¿¬}Dþ";í‡Åýcê'ñ ¿EñcšõeÈæ :_`]°ø¿¬}Dþ";í‡Åýcê'ñ ¿EñcšõeÈæÄ¥vÛ‹úÇÔOâvÃâþ±õø†ß¢ø±ÍzŒ2äs@+°.Ø|_Ö>¢=vÃâþ±õø†ß¢ø±ÍzŒ2äsQ¥öÛ‹úÇÔOâ#°.Ø|_Ö>¢Ûô_9¯Q†\ŽmÐ ÇKì ¶õ¨ŸÄ;í‡Åýcê'ñ ¿EñcšõeÈæ€:_`]°ø¿¬}Dþ";í‡Åýcê'ñ ¿Eñcšõe龀 t²Ø.Ø|_Ö>¢vÃâþ±õø†ß¢ø±ÍzŒ2äsn¥öÛ‹úÇÔOâ#°.Ø|_Ö>¢Ûô_9¯Q†\Žj¥vÛ‹úÇÔOâvÃâþ±õø†ß¢ø±ÍzŒ2äsS/°.Ø|_Ö>¢ì ¶õ¨ŸÄ6ýÅŽkÔa—#šé]vÃâþ±õø‡`]°ø¿¬}Dþ!·è¾,s^£ ¹ÔKì ¶õ¨ŸÄG`]°ø¿¬}Dþ!·è¾,s^£ ¹ÔKì ¶õ¨ŸÄG`]°ø¿¬}Dþ!·è¾,s^£ ¹Ø@é}vÃâþ±õøˆì ¶õ¨ŸÄ6ýÅŽkÔa—#š€é]vÃâþ±õø‡`]°ø¿¬}Dþ!·è¾,s^£ ¹ÔJì ¶õ¨ŸÄ;í‡Åýcê'ñ ¿EñcšõeÈæ :W`]°ø¿¬}Dþ!Øl>/ëQ?ˆmú/‹רÃ.G5Ò»í‡Åýcê'ñÀ»añXú‰üCoÑ|Xæ½Fr9¨—Øl>/ëQ?ˆvÛ‹úÇÔOâ~‹âÇ5ê0Ë‘Ít®À»añXú‰üC°.Ø|_Ö>¢Ûô_9¯Q†\ŽlaÝ+°.Ø|_Ö>¢ì ¶õ¨ŸÄ6ýÅŽkÔa—#šé]vÃâþ±õø‡`]°ø¿¬}Dþ!·è¾,s^£ ¹ÔîäØþÒíºÚýzПN¦BJ"Cæ„¥§Ú[&f¥¤°Y>9æ#2¢ôêÓª±S’kÉ܆šâ})Ø/À]ó3ıç·ïKÃæ—ÿ„ǦÁ~ìo™›þ%=¿| ^4¿ü&ä´Šœº(U_Ó,_{¢…Uý2Çóþ‹Ú3èÑì‘£‘Ì5²y†ÊG0ÖÉæýC[#˜Æ®OHÚHæ1«“Ò=ZšÉ\ã[#œÆÊW8ÖÈç1êÑ1Ì×>0ߌ7Ç¥LÍ# шïHËtb;Ò6Àá#ÑŠï1Œ§F+¼Æ6Àã#ßzc¤d;ïLcôqàq`Ä 1Ä}Ÿ@€ÝB{ Ý'º €ôÐ ÷ îIBI@t  H€ô1= $ =ô0000"ˆ˜w@ú€ô§`¿v7ÌÍÿÇžß¾/š_þ›ø ±¾foø–<öýð)x|Òÿð˜çÞXí ,TàÑBªþ™bûÝR&ÔyKѹ2ZeIC‹~SL$”¢Q¤²âˆŒÏJ¹»ƒà"n«Hú"’ÙU‘Ì5²y…±ûf¤eý&‹÷ÔOJ5ò-j™—ôªßý(ýK‘çÔ©eFG1\ž‘r~ÒªžÂèBô£]"Ï«ÂíïÛpÁôÃÔ¢š1NqæRåslŽsY6]`Ï„ËsöÜp=0׿dVLÏü6Ùó–ŸéÇ©Gq’rE%ñ†øº=bÖÏÿ>µüç§zqˆõ…\?üúÖó¦›éÇ£NK™šM§F#½"êí]?üþÔóª™ëÍŸW?áöŸ”ÏX!8ó8Ȥ:1]æ1xsg•óÿÒ—´¿XÎlêà2?ñ…¡çu/ÖÈT‡4q‘EwÞ˜Çé‡6qp™”lÿ<)^²<;Ü9ÿ(ÙÞxÒ½djZvþdri”ã.G³{‡å;ÏW¬ˆìopü£gyãJõ‘mm>¥™e<ú ‘ìÞáùFÎóÆ•ë";Ü?(ÙÞxÒ½d5´ú–b̧¹v7¸~Q³¼ñ¥zÈv7¸~Q³¼ñ¥zÈkiõ,Å™Mrìopü£gyãJõ‘î”l菱³) .=î”l菱³) .]î”l菱³) .=î”l菱³)â˱½Ãòç+ÖDv7¸~Q³¼ñ¥zÈkiõ,Å™Nqìopü£gyãJõìopü£gyãJõÖÓêY‹2œãØÞáùFÎóÆ•ë!ØÞáùFÎóÆ•ë!­§Ô³e8DZ½Ãòç+ÖC±½Ãòç+ÖC[O©f,Êp c{‡å;ÏW¬‡c{‡å;ÏW¬†¶ŸRÌY”à.Æ÷Ê6wž4¯YÆ÷Ê6wž4¯Y m>¥˜³) .=î”lïÔÉ95v¸ÒE‡q1F›ì{z½M¤®—›ÑÈíGD÷ÝBYTu8’RV³B–’RQ¼$¤Í(,ñ33Ó BɤÙDªÔniGê…" >TÂdÇßУ#|ʳ¥Äjk¶Aàð¢àxÞ¹j9þFûš'£sÙ Z¦¶Í„…ÚTWÛ>—! [²ÈÚoRÏpœ>E»Ár¢5áGÛçK®Õ³Ù¹-Ëž•jAM.‚íUöÎT¥”Út¸ÊÖodœ'M´$Òi,¸œ’°cLhP¶ø,‘ɶr3¹j=íFûš'£×-G½¨ßsDôcY5Öß–óíFj+n8¥¥†F†ˆÌÌ’“Y©X.bÔf|8™Ÿâ:ì´:HŒLÝËQïj7ÜÑ=޹j=íFûš'£sè-…’™¹ë–£ÞÔo¹¢z1u²ÔÅnÑqú•6’ã­]ÔHè[tÖVéÖ癡”¨ÛFR|Iw1/eßÔ©_é­¿þ®¢3itiÓ£)B)?$Z-¶Szå¨÷µîhžŒ:å¨÷µîhžŒi€iÙht,‘\LÜõËQïj7ÜÑ=uËQïj7ÜÑ=Ól´:Hbfç®Z{Q¾æ‰èîZ{Q¾æ‰èƘe¡Ð²C7=rÔ{Ú÷4OFrÔ{Ú÷4OF4À-…’™¹ë–£ÞÔo¹¢z1=rÔ{Ú÷4OF4¤'º-…’™c¤T®*ÅAªu&¡5ìîãÅ FuÅàG„¥£3ÁŸ‚1µ«Sv‰H„¹µ[!øQïÞ“j´ÒýêS$D0v;ð»füýý¡¼Ù´èÔ­³íävE¬7j²%Û0’ñ;-·ÛpB¢A¨Œôø§†rYç:bÿ‘d‰»?:uËQïj7ÜÑ=uËQïj7ÜÑ=¼lòʃ+f ÚL*URJjè¥Å‡S«"dû–õn-ju£YàÒIJVGïEÃbvvÏz÷²N¯X¥RéutºU¨pk-KE=ÖòI-ò½-¹îfF¥§*í¸pFвBìæýrÔ{Ú÷4OF#®Z{Q¾æ‰èÇYÚ‰…³êåYË"Þr>¦›¦×-ểM°½ò2O%ÇŒŒ”DJ$ðQ¤°Y#/­©fÐ6¿KÙT»u3·ÎC‡2±ËLü„ ÷$•º$$Ü,%HVIj(t,»9w\µö£}Íч\µö£}ÍÑŽ«*Ò·ŽÍ¦Þ”›^ÝuÙ|–VàäLBŒÂÉ´’w’[q×TyR•­INKµ"2!ïeX¶4¯d Ø6©ÕÊjšrŒÕPßänâš'£¸D¥!mx™‘¡\ÆxPjt~…’g#ë–£ÞÔo¹¢z0ë–£ÞÔo¹¢z1•_¬[RèëK´X§ID´­šMyn­‚JÈÛu Q¶j34+RŒi2Ɔïfvå"e¥x^5¨§PbÜÚ½Si}ÙîÒkR •¡832I‘Ÿ$,ôz _ÉvVºå¨÷µîhžŒ:å¨÷µîhžŒtIÑ,Õì«æ%‘Of¬«¡ש’ÔÁ4–wÆ”'}’%i$ž¥)XRðdzM>Ûs‹aYJ¸-:]ŠÃÑÚŠ”4óµ);ÈϹ*Cöø4¥KJ+%j<–HŒˆ¡P Ýµk$Mß3šõËQïj7ÜÑ=uËQïj7ÜÑ=êu[RÍ mz—²©–êgoœ‡ec–<™;ùAïI+tHI¸XJ¬‘q1«‰fQ"ìëjíΧ±&±iÔbG…RK®¥X\³eÂ4÷fœ6fYNKZ¸Ÿ 5:H]”¹j8þFûš'£×-G½¨ßsDôbå{ÑíúfË6etàDnmS—uIûæÜÎNúN¢72E[³G4ðÅÊú·vyKöA£f‘,¶Û§J—¥•BIÈao¶ÞÑ›†Œ¸G…¥y=\H°DÔPèY.áwÌã}rÔ{Ú÷4OFrÔ{Ú÷4OFFM ¦ëä’ FKr4•èQµ…i>ŒàùÇ@¸¬ÛJ~Ì.ªý!Ë}º·&!(¨²g:ÚÛyÓkK§)$F¬–IM’.÷ÚV >Ç]—6åµJ©êí6ãŽI%FRd%&ê4¼DkQöæK%'W2RžÔ5; ²Bï™Í_«×£Â5úU9¨²µrw—BŒ”=¤ð­ 6°¬Ç1Œ~¹j=íFûš'£"¿m­lûc,CB H¯J›ãåO:ÊTRšdœKn-IAžMj$i#QŸ,eÒ­K6¿µê¦Ê¡Û©ƒ¹rd8uŽXò¤ïã¡g¼u&­Ñ¡FÙå)BpJàa¨¡Ð²BìårÔ{Ú÷4OFrÔ{Ú÷4OF/´Šu¥Øò‹Æu§}i›”éIqrä¡6q÷Þê”8DxÉ‘hÑïSœöÚµn·(öýVÝ“CЍQk¶ì:¹Å7Tâc­âV¤%J3Q¤9,™Ÿ*…ídˆ»æVzå¨÷µîhžŒ:å¨÷µîhžŒi€[e¡Ð²C7=rÔ{Ú÷4OFrÔ{Ú÷4OF4À-…’™¹ë–£ÞÔo¹¢z0ë–£ÞÔo¹¢z1¦Ùht,ÄÍÑܵö£}Íч\µö£}ÍÑ1‡t6Z $13q×-G½¨ßsDôa×-G½¨ßsDôcL²ÐèY!‰j Çf4¾M4T½Û¶ã°–n9HÞ8¢J’F¥©J<31ÎJÚ¯ôW¾nµ¿êRÔsÑ8KÞ¿Ö$ÈúS°_€»æfÿ‰cÏoß—‡Í/ÿ M‚üØß37üK{~ø¼>iøLwïmb§îŠÌŸêWçŸêä‹7tVeTê¿8ÄÿW$| Aí_»ögïëMúþè¦HæÙ<ÂÜõÝtY+Ÿ² áÚ0^¼®‚/ë5Áû*ný£Þ¥‡Ïïõ1TNŸ™M‘ÌcW'¤^½î‚Ïû§¹eYÂ/ß—AgýÔ]_²´áØ=*/’/Så.E W8͵n™ÁÔù=2Ÿ7ª0× þU½àÊýúKBÓ\2|å‚Á—Ø_Ú ÐŸó¦ïý•× þÁ„öÑ®‚?ëUçû. ÿù ’‹º‹ùz˜çv¬Ñ@CˆfKN¸Ãr…’”Ó†¢C„G“Ié2V˜ðd}Ã!›´;¢]ãq½_¨B…cèB^䤲C†’ÒJ2Z•ƒÒI..Ô¸g&vgv•tù×{þËÏÊ1]ÚmÐ_çeõû.W? ô)Õ©k`/S„Mô:ÅF¯A«E…O¤M Æn,a¹&›ýN8²Q'*þÓÔz³Ãú•ñ1Ê}J:H£Q:'½· ÉÕ¨ÑÛ­D„™àÍ($‘ãÜõͨÝþvß¿²èsò w6§tÝnÐ?eÒç£ãZ¯CÍzœ$ŠÝÍyI­Y”+YÚE2Æû|{Ã˺N)'­XQö¥ƒ,'Id†3·¤®Æ‡aõ"—ÈywT9W»rŽQ:ó¼Ñï;LhÆ8ãWl,®mZè/ó»h²ësÑŒw6³tÝ~ÑeÚ磡V¯†ó^§)$hk[A›V¡Á§Ôè4)r`RÊ• ë)ö£$Œ’’-æëQ 4j.r2>#gtÝqi[*ìuD¹š¯Âvª¹…!¸Ž°mGÂM-(œ"258ZÍ)Ô’4—l¬ðþ׵ˠ‹úß´;ÜôCDzõÑŸë†Ò¼ñsÑ ©WÂy£›K™ÍL@égµë£Ã ¥yâç¢ÙzèðÃi^x¹è‡M}o 戲æscè:YízèðÃi^x¹è„v^º<0ÚWž.z ×ÖðžhYs9¨é{.þ¥JÿMmÿõuì½txa´¯<\ôCdÕb©|ÚíJ©]wÃüŽè¥Dm©÷¥¶žP‰fn ”‚Ðêw$IW•ÀpÒjT))à çtÉŠW9—ÙzèðÃi^x¹è„v^º<0ÚWž.z!ß_[Ây¢,¹œÔJì½txa´¯<\ôB{/]m+Ï=këxO4,¹œÐKì½txa´¯<\ôB;/]m+Ï=këxO4,¹œÔJì½txa´¯<\ôAÙzèðÃi^x¹èƒ_[Ây¡eÌæ¤'º:Weë£Ã ¥yâç¢Ë×G†JóÅÏDúÞÍ .e*Ю;m\ôÛ‚<8“$SŸL–Z•¯vn$ò……%G¥XV3ƒ2,ä²G½ƒ´ZÍ?jNí¦ì—$»´¸q–§ÉÒ4©f¬,Ô£2ÕÀφˆ‹qÙzèðÃi^x¹èƒ²õÑá†Ò¼ñsÑuk?í<ר²æhà_r¡·T€š ÊMäHzŽâ8­º’Á-³ÞoP®'Äœæ<¦`“ilÐLêyIá«RJ3#"Áð,R6—yN¿n×îj>Ÿt–ЇÊ8HpÐ’I(Ék^I%< ‹µ.É“²õÑá†Ò¼ñsÑ ì½txa´¯<\ôBJËûO4,¹˜ö£YDØUgé4I•ø ¡˜µ™ ¸©-’ JdK&–¤–”´(øWk_Z5¸®G‡W…]BSR‹P'‰•ëJÍHZVJ%™(¹Å²õÑá†Ò¼ñsÑì½txa´¯<\ôA­«á|ר²æk.[î]ßo[ö¥B@¤Á¤<´Ã–ËO§“6ê²²Y—©Ú™™!Kí ‰™«UëlÛU¥»µ¹7EŸÝ«/vÊéõeÃ’™T–É&JBÍ ©iQ)IR¼“džYì½txa´¯<\ôB;/]m+Ï=e_ æ…—3œÉ}éR]“!Õºó«5¸âÏ*RŒòfgÒfcÌt¾Ë×G†JóÅÏD—® 6•狞ˆ__[Ây¡eÌæ½Á¥ö^º<0ÚWž.z!—® 6•狞ˆ5õ¼'š\ÎlBK-¯]m+Ï=ŽË×G†JóÅÏDúÞÍ .g5Òû/]m+Ï=ŽË×G†JóÅÏDúÞÍ .g6 è+²õÑá†Ò¼ñsÑeë£Ã ¥yâç¢ }o æ…—3K°ß†»ý#§ÿ´¶4÷ù"ÜùµírMÙþÐî;–ü·íÇï}¦Çj«T n¢ïpÔÚ]u(5\L‰Yª%çY´­ªTJuÉzÃj[ ”lÓ.Ãa ß8ßÉÄɲ3<ñ3'R£œdá¾ëu×)’±ÏÄ—ÙzèðÃi^x¹è„v^º<0ÚWž.z!ß_[Ây¢,¹œÛ AŽ—ÙzèðÃi^x¹èƒ²õÑá†Ò¼ñsѾ·„óBË™Ít¾Ë×G†JóÅÏD#²õÑá†Ò¼ñsѾ·„óB˙͈@éeµë£Ã ¥yâç¢ÙzèðÃi^x¹èƒ_[Ây¡eÌæÝKì½txa´¯<\ôB;/]m+Ï=këxO4,¹˜õý¨uutÇ*v¥!t¸ Sá¹i“QÚ΄iå:UGÅDf}&cK>þºeÝðn£¨îjTâB`îKmEB=ëm¶E¥("ÉiÆ'œäÅ‹²õÑá†Ò¼ñsÑeë£Ã ¥yâç¢Uj¯í|ר²æiª@œí6© —D¢Pήéí:NIF­FƒÞ8¢BMDFil’GŒsp»@œTŠe:©D¢Vú’“E9ù츧c#V¢Ahq)ZHòd— dYÆ1Àn»/]m+Ï=v^º<0ÚWž.z ÖÕðžkÔYs4íûY¤}…X‹p‘V4ô¬Ñ!d³q+3mHQ(”fdd¢çW6ÑeÜ6õ½A¨[”ƒ@yk††PûymjÔ¶W‡x¡XI‹ íHõäÔg´ì½txa´¯<\ôAÙzèðÃi^x¹èƒ[V÷Õ|ר²æ{HÛMbMÙp\Ò-kiÙ×3©u4Ë$8Á¤’¢"'ËI©)m&d|7iÆ Ôj¯Vïê…Nж­´Òé¶ÖµÓåÅ7ÊA)jÔá¨Ôê’f¥‘,ð’Á‘iÒY!¼ì½txa´¯<\ôB;/]m+Ï=*•WöžkÔYs5³¶“P—Rr¶»~€ÝÂîTºÃl:™á– ÒFórNtê&ÈÈø–ˆÂëÞWcÇýF¥r_ÕWîü§”cN¼ï4~´ÆŒcŽ5vÂÁÙzèðÃi^x¹è‡¢¶­w¦+r•tí<£¸µ6‡NîwB”’I©${¬‘-&eѨ»¤Ú«û_5ê,¹š{Ÿi5ZÝjÙ¬7I¤R¥Û,1ž¨ixÈšaD¦R¢uÅêÐyÁð3ÔzŒøc+²½]‹Á«¶•A·©U”Ï\÷äÆŽâ•!Õ¥iY(Üqf”¨œ^R$fyÆHŒ²»/]m+Ï=ŽË×G†JóÅÏDʾÍz‹.f v–û6ÕÅn´­˜TÛ-ò¶ØnIVÚHZo‘¥FFI34p.×¢\S|¤–­NN©&jYÏ ,%’²6£Y\Ùµf)4H•ùì­™U˜ì8™.Ó¥j"5›HR‹$jB|OÙzèðÃi^x¹èƒ²õÑá†Ò¼ñsѶ¯…ó^¢Ë™ ëÞWcÇýF¥r_ÕWîü§”cN¼ï4~´ÆŒcŽ5vÁ´;ÞUéÔ~WF¥Sº‘è܇Æ:?F…o\^tåX>z&|1¿ì½txa´¯<\ôAÙzèðÃi^x¹è„ëkqÕ<ר²æsP+²õÑá†Ò¼ñsÑeë£Ã ¥yâ碯­á<вæsP/²õÑá†Ò¼ñsÑeë£Ã ¥yâç¢ }o æ…—3šé]—® 6•狞ˆ;/]m+Ï=këxO4,¹œØÃº:Weë£Ã ¥yâç¢Ë×G†JóÅÏDúÞÍ .g4Ò»/]m+Ï=v^º<0ÚWž.z ×ÖðžhYsUþŠ÷ÍÖ·ýJCšŽµ$:ET}úZ¦ìÄÐ&®ERYÉ’¥?LSÆ•8dZ‰&æ’áïR’èà4N÷¯õˆ‘ô§`¿v7ÌÍÿÇžß¾/š_þ›ø ±¾foø–<öýð)x|Òÿð˜ïÞÚÅNÝ™?Õ:¯Î1?ÕÉnè¬Éþ©Õ~q‰þ®HøƒÚ¿wìÏß×þ—ïš)’9†¶O0ÙHæÙ<ÃÜ¢g¨kdsÕÉéIÆ5rzG«@Ã3Y+œkds˜ÙJçÙæ=Z&9šçÆã1ñ†øô©™¤aº1én‹e­P•6,*kG–ÒræU¹"•)Jpñƒ•Á8J’’K}±é5tðÛ„ÎzèÅw˜Å«i1¡Ã¼ª!DäˆdЇ$- KÄÚwº¾Ø‘¼Öi#ã¤ÈU]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$ú¥ì»ú•+ý5·ÿÕÔG4/eßÔ©_é­¿þ®¢2ißÓÏÜZZJ‰St‘6 2KjÏ6¢K©Q’ÛAç\ÆdpÝ*Ñá²7’ÍÓ0ÕŸ-%D©ºH›™H%µ ç›Q%Ô©$d¶ÐyÇA—1™Óí‹pìºmÍU¹¦ÄnTÉ0ŒÍ-/:—KK#F^I-—““3A¤ø+œ³8æ›l*zUi ×ÛPe·)˜dâe2¨ IRT¢6ÉÈêQj-F•pýbR¬z}fŸD™F«Ôf"K»ªÇø¹´,É:”¥¿…'I-DµnÒiIñ#%%1‰ŒaqƥîK‹E©»T§´½,Ìr7'7ˆ‹Š·z•¤³œdòeƒ2#<ö ³B©SÖÝ2ævUiºs“×éÊDr&š7lž5ê7„¯ýì’f“"QäŒæà©³Ó­ê;THu;Ž»&šU j„ÌX%kBTh7—HF´©%ƒRŒÐ®×›6»¢Ö¦Vö¯.ŽºœYu½z$A§¥1uº[R\V„hÝ¡z\V¤¤ÌŒË´âxŒH´^NѵJ\rñ–ŠDÙCBÎ\¡¶H5êo}§vIu³ÖK3틵ÎqàŽ&˜ÍýM~¦¸ó¨Œ2Xn2\jR=––ᨳ' ¥z‰&Fiéb@¦€¼.ÒµbÒ­ú…Jï™5¸\¡´"N)…¥ç^ó݈·d¦JË*Qg(N0u[†—&‡_¨Ñfhå4ùNÅ{Aå:ÛY¥XþÌ‘‰M0atÐ Hžà=Á !H@ è€Ãa¿ v/úGOÿiliîòE¹ójÿÚä ÆÃ~ì_ôŽŸþÒØÓÜ?ä‹sæÕÿµÈ*vÑ÷þÒ,¸qD eIèbz !H@z èbë°‰R¡í²Êz$—£¸ªì6”¶–i3BÞJœ—B’¥$˘ÈÌŠQ‹~ÇeÒ©{E¤W+áÄI’‰è).¾Ú^u¥¥HoS,>¢í°g”`Ò•¤™‘ŒºrrѪ$¯t÷sÜZˆ«ÚÙ¸ m Ôm»k“eVC«K/)ä“®òë=J2à”‘$’DDD9Î¥zŠQ’•œZàûÖëÙqç¹oüÖÜJIÂâ~Ý}ÖNÝ¥Uií’Oz™õ&åš Òha­%ý†GûæT*S;=µjî•YÖݬO>/.I6²i0Ök`·g¹Zñ Í[Î-¤ù»RÝÜÖþÏ%¦3võãmRÙ­O.TЬ·^5c’§¶”¥8<'=±åJáŒõB°Þ±èV܋ބ§)õWçJ’ÜšŠJBKHq´ 釻=1ÚÂK"=fi2QvËIXiá„÷7ui^Ö’ãï·{+n'ÅgXÌÞw]—HràUFŒU'#Ï‘!£eÎF‡]SJh›%gCJNð—ÅDG ˆðY6­ãÖ>ǨÕKqUêezMj …̇Sm¶[-ÃR7Í Þ´Dö £V5ofd²Jve6Ãsj·é*í¡.-i¹åÈ[›QBÙ\Æ–ÛªÞ,ÉDDó¦’ÐFFhÉ«IêÓÈ…a¿³X6ÂïzT¡M“1¹å&£¹5¿¸JÈØêf¬qÐEî„zJ32ÂKåV0§^” wO¥{óIÚë‡$Ëp»FYöŸ^ŽõÖºæå=Oåûö¹'.ÎÎçF½ÎÓy¼ÏëiýQÍGmê…™ÕnººìµzîÎó—ïê¼›”cúO'ê~­î{Òi×ÇN819–ãÍ~;2™–ÛN)É,éà–’ZR¢#ç-I#Áñ">Óö}J“mMIn\Sã¾íyp²ù"“K¸ñé”$úÐ¥mWú+ß7Zßõ)j:VÕ¢½óu­ÿRæ£&‰Â^õþ±-#éNÁ~ìo™›þ%=¿| ^4¿ü&=6 ðc|Ìßñ,yíûàRðù¥ÿá1ß¼´Šœº+2ªu_œb«’,ÝÑY“ýSªüãý\‘ð-µ~ïÙŸ¿¯ý/ß4S$s lža²‘Ì5²y‡¹DÏPÖÈæ1«“Ò6’9ŒjäôV†f²W8ÖÈç1²•Î5²9Ìz´Ls5ÏŒ7Æcã ñéS3HÃtnØU&‹ ¹ç[¦Ô˜JÓ%È‘Ñ%¹yZ”•an Û2I’xj#ÒGŒ™çHèÄw¤mÂFeëWj·_v{Öæc²…¯ZɶšCH5 *4 ŒÏæb¼ï1Œ§F+¼Æ6Àã#ßzc¤d;ïLcôqàq`Ä 1Ä}Ÿ@€t½—R¥¦¶ÿúºˆæƒ¥ì»ú•+ý5·ÿÕÔFM;úyû‹G‰Ík*ÝB{ nlÊËt‰Š‹ñ•*6íèòYJô)Æ^im8’VhZ°x<˜ïÖ%NͷبK È¯T*2¡? „͆Ôv£%än(Ô‡VníKIpGÏFB§Ewf´z+Ô­§.[è\T&>‡ÛeIpœ5—'IñAgxežÔU®èKë–Ëëûª¼ºàêo[=I×Ô¶wÛî§rZ9F}×:óžÓ®1(WU¿oSèði ¨8ÔÃÅÒr ·þÙà†Èí›$šðFm™¬’¼‘’Iüa@ί&ŠÄ”Пœý7Vc®k)ií8. JT¤ä%’>8Î 8.°ÞÓhnΚ·î;Þ-&¡\3¡Gi³ƒžŽãI$#~”º„ÈÉ&–Ï«%ÇŒ€8§Äȵ;j«@¦SîGªÐߤ¶ãž·ÉæTêÝФ­Äh2[Ž¢5d”E§‡—U”þÐU\%סS¶Ž—¹L&Ÿu—ŽŸÈpFo –‚OºkíLÌ´è,êÌ-nTmɆìÊ«sbÕäÊši€Ú›C/¥„¶­ñÖ’Ž“Òd‚3Y–¢Ó•në=©:àÚEEkhnåmgNIÓÚÊV¹mJ2wÝûR%4M‘§^IF¬–ƒç A„»’£nTi–t&&USÔØ¤µÀl´j’ëæ¦Hž=æ7ëI·yÐG’ÔdœM¤U)ÕÛþ½\¤ªY©Ozce)”¶âwª5šM)R‹µ5d‰ 8*ø HÐ O@ {‚÷$„ !$ƒ : †ü5Ø¿é?ý¥±§¸ÉçÍ«ÿk7 øk±Ò:ûKcOpÿ’-Ï›Wþ× d©ÛGßûH²àiÄ 5•' A‰è`$„ ! è' @‹NÌit*ÅÅ*Á¤üVéS¦  ËDuëÉF¥´á(š4sdD¬ž'V1{Øbä1}=2%V*CjžâTŠ“P´<ä'šgCŽ-KÞ¸Þ0y/}À’fYté8èÕ$šOË}·kvaK¡V.)0îõ'â·J1Z#¯\xÎH"5-§ÉDÒ‘Í’5²ztž-½gWë°NtÑQxm!és˜Š‡\"#46o-;Åe)É–K‡™Þ×ÅÃZ©Rë{@©=O~…TiÆk7ê;«rÍ4“ߺHQ›®7‚ç/}À’fZC§¢í³í¸ôÚ½$ŠZ$¡£32Ðn#(R°D}¢”XQqÎH®UZkWLŠ-zŸqÑiÑ#S!E”Rª ²ô%Çe -IeFN9¨Ðn–é+μsä†ÊÕ䡤¬ûìíúYßvü¼Õ\VD´í.çµ­Ö—"=£)‚zSí´–Ùiãm+yÕGê‘™é,™s‘ ENÕ¯Óë1)Ó”äɤ“†˜Î"B$’”i#imš’áˆË)3,‘—@èת¡U¯ §[ñkTt?W¸“T§Ë:‹<–S)rB·{òVí&¤ÈBûe´i<(°1)5]¶vÕ»Q«AzCW)3"¼R„sb¦;E¼o$½Ú’n™ ÔE¯†O$2RÓkà]îÜ,îÿïî¾î{Ë8¢£U°nºl8“¦µ&4¹i„˰&11'!E”²fÊ×¥Ã"< ð|€ò¸ì«ŽKER£9ÁSü˜äEœÄ¤!ì·K6–­ ÁéVðà7ôj[ö´úÊ¿iô×®Ä|‘O”ÝA˜©mG‰®“K4joYéAöÆF¿{úÙ›Jj›Óq9 @©¿TmgÞ¬r¨SZKnÿ„-¢qdÊÒj"I¤ðêÈœzGL«­Œnš}é?Ý÷sX¼ì†c™õŽ`˜w@ú€t­ªÿE{æë[þ¥!ÍGJÚ¯ôW¾nµ¿êRÔdÑ8KÞ¿Ö%¤})Ø/À]ó3ıç·ïKÃæ—ÿ„ǦÁ~ìo™›þ%=¿| ^4¿ü&;÷ƒ¶€±S€wEfWõN«óŒOõrE›º+2ªu_œb«’> ö¯Ýû3÷õ¿¦ýtj‡k™•럲Ùÿùêu®eþV¸?e³ÿòF Ža­“Ì=êRò_?SHO«älž¤ÚçŸñ­Ëû(MŸÿ’0_¢ZçŸñ¥Õû-æÏÿÊ™Æ5rzG¥Gu¾ÿSã.fíû~×Wþ’»ÿe¶ÙÿùC ën×3ÿ(Þ²Ølÿü±^•Î5²9Ìzt”ûšËêdš|Ë;¶µ®úB÷ý–«~¸1]´ísÿÏï¯Ùi·ë‚¢øÃ|o„*õ,¾¦y"âå¡kŸþ~þËE¿\îY¶¹çü;h²Ïo×E)шïHÙVëY}N2/YV¹ÿç»Cý–k~º1ܲ-sÏønÑe–ß®Š#£Þc¡N¿ZËêr•‹êì[\ËúfÒ<ÉoׇXv¾¦m+̆ýxs×}éŒ~‘ª4´|?S“k‘Ҏõûói^d7ëÂ:õûói^d7ëÛmV‘â/‡êE×#¥‡k÷æÒ¼Èoׄu‡k÷æÒ¼Èoׇ6>ªÒ–ÅR} ©Œne?Ä4æx–•™`ÿa†¯HñÃõ\‹·Xv¿~m+̆ýx:õûói^d7ë“ݸ&R¬D¡ÔäSXÎö[Q¶[Ç>¥‘i/ÚaK·.¬fåS(UIÌ;#’¶ìxŽ8…½§^ì$dkÓÛiçÇ`Õé"Ëê.¹n°í~üÚW™ úðu‡k÷æÒ¼Èoׇ>©ÓçÒç9§ LmbCJmÄ?¨ˆÈ]M¨õ#«O—ÔÞQɹfå[ö[½xÓ¯O9Î8‰Õi"ø~¢ë‘ë×ïÍ¥y߯ ë×ïÍ¥y߯ KVÕÆõB 9ªUɵå&tÃpÜ’É‘¨œm8ÊÐd•¢É`¸"}»pSéŒU'Ъ‘ HÆæSñCNd²ZVeƒáÜ1½#ÄY}E×"ï֯ߛJó!¿^֯ߛJó!¿^ ‹ä¼èöô©ÎÁn§-¸…!¸äñ¶·¥ ÖŒ–£N{n“"3,‹X®J8”JLúœ„§Yµ:ÞY'»„‘žW¤x‹áú‹®Eó¬;_¿6•æC~¼#¬;_¿6•æC~¼9ÿSçõK©œ†O.Þn¹6é[ÝyÆÎsÑŒ…JÓº©¬Êz£mV¡µ -®RäAu´°—iA¬Ô’ÒJ22,ó™`ƒW¤x‹áú‹®EǬ;_¿6•æC~¼aÚýù´¯2õὓ¹Kn UÖnâªÉDw‘M‹n8®T•è[¬²ñ«‹í²¥­Dmàµ$Ï$(ñ豞±fÜIœéI‡S ȧ´iå¥Âs^rFÂÈÓ£¥'¨ø‘B…wýÅðýFîEì;_¿6•æC~¼#¬;_¿6•æC~¼)=nÜDêçPªJÎ9w$sqÏÒcO?ö…:ݸ*T×êTêRdù'¤±ÇoORˆŒ‹ö˜^‘â,¾¢ë‘w+×ïÍ¥y߯ë×ïÍ¥y߯lC{T¶jÍÖeÓaÛõäH ¹3£I†¢~9H7\ZH²†‰J3%(‹µRsÄÃW¤x‹áú‹®E·¬;_¿6•æC~¼#¬;_¿6•æC~¼(õªv†Lj‹R¦„š™åqVÎð»©ÔE’â\ÁkÒ$\%6‡ðýBSq›iøLzlà.Æù™¿âXóÛ÷À¥áóKÿÂc¿x;h 8tVdÿTê¿8ÄÿW$Y»¢³+ú§UùÆ'ú¹#àZjýß³?Y_FýtS$s lžal~‹M2þ¶ÑKþj_ ù:a—õƆ_ó3=\{Ô`þÙ’¤×ÚeFG1\ž‘r~ƒJ<ÿ»ZÌÍõq®‘oÒO?îæÞ/ïbw«RŠ1NH¥ÊçÙæ.²mÊ9ŸöÜ/ïb« {öÕÌÿñƒl—üÅCÕG©DÉ6R_o‹£ÖÅÿýŵËþQõAˆõ­C?ÿr-bÿ£Ô½Pz4äŒÒe)шïHº»jмeZ…ÿG©ú ÆrÔ ñÿÆe¦_ôjŸ©šûG‡F+¼Æ/ZTö—Ùªž¦1œ´müþ4m³U=Ll…Eç“8È¢»ïLcô‹Ã–…½…;?ìÕ_RgÛÙøU³¾ËUõ!ª5»òg&Šqˆ#³íï¶wÙj¾¤#¬û{Æ­öZ¯© kcç“ô"Å<ú ‘Ùö÷[;ìµ_RÖ}½ãVÎû-WÔƒ[<Ÿ ±Nrë>Þñ«g}–«êAÖ}½ãVÎû-WÔƒ[<Ÿ ±Mrë>Þñ«g}–«êB:Ï·¼jÙßeªúkcç“ô)À.=gÛÞ5lï²Õ}HOYö÷[;ìµ_R l|ò~‚Å4ˬû{Æ­öZ¯©ë>Þñ«g}–«êA­žOÐX§¸õŸoxÕ³¾ËUõ ë>Þñ«g}–«êA­žOÐX§žè¸õŸoxÕ³¾ËUõ ë>Þñ«g}–«êA­žOÐX¦€¹uŸoxÕ³¾ËUõ ë>Þñ«g}–«êA­žOÐX¦€¸õŸoxÕ³¾ËUõ!=gÛÞ5lï²Õ}H5±óÉú ížO‰OºšrsÉb<ˆÒ¡-åážQÆ ÃÇ$Ü%8ðlêì#SÓiЧSPF¥Õ%˜D’,êKÅ”¹ž‚F£W"31ëÖ}½ãVÎû-WÔƒ¬û{Æ­öZ¯©Ö/<˜±»¡D(6&ÏëUÚdž·ÓwËrKËŽ­ÓŒš`‘–qƒÉ2ñtÛY~©ã}Sˆ¨±îzÌÛ^æŽÌè2RíJ«q6ì‹QìÛ4ÄO(VóBHW:HÌÒ’3*7Yö÷[;ìµ_R³íï¶wÙj¾¤+‰yäÁÒ6]mîn+ þ¥Ýµ¸{Ø‹EMšš¦Dß-+uÒø–´­ÄÕ¨ˆ‹QÑé4ûŽ›±«ÍENªEeêtYê6‚Fí¹„ãn;SJÖÉ(˜Ö‚?|Y×uŸoxÕ³¾ËUõ ë>Þñ«g}–«êA‰yäÁï´¸5V-›uJÆJM¾¢CÏ´¤“¤™²M8Q—m†”É—þª|ÆCù³i• öÎî*5õ —U)Ó: o-–Û˜…©(.*Ò§›Îñ«#ˬû{Æ­öZ¯©Yö÷[;ìµ_RZÛòbÅÖE©Qi"tU¶Z㵯Fð«¶õ h'©<é3"< < UÓI‘qÖnÔÊ*Lêl´;-õ™±Qym«“›J>‚#3àC>›F¯T,­Ê%:{•˜•§•W¦²Ò¹JM¶–u4]²‰µ¦AÔÖYÆFYö÷[;ìµ_RÖ}½ãVÎû-WÔ„¹«÷äÅ‹a¸ÿTº’rS×Z\‡y¾-ç,å:·ZóúNGî8ÎsÚsðÊ¥&æ¢lB¥áb\õÇÈðe嵘óu/v®Ù)Vƒ2,èÙ:›RK¶÷¥Eë>Þáÿ[;ìµ_RÖ}½ãVÎû-WÔ…n­ß“<‡o‡Cº¡í™”E¢UÚ©1c%ƘŽ©Rh;‚2,g$ùnÿöû_}ÀPJÏ·¼jÙßeªú޳íï¶wÙj¾¤,æŸ<˜±“M‡W™± †z¢N‘=Á\ ÛRšlÍ™ItõsG%j›Ï:sç²ñ{µë©]©Qi/-…ý—ñœi¦²ÿ‹1çÖ}½ãVÎû-WÔ‡³VÕ%¨oÃkkö¢#HRTó)f®HpÓ&¤ò,–£Æy²}ÐÆ¼òbÆÆÁ»A‰2¨M¸Í úåKmfDoAV\KEý›ôš?¾Q[N›.å Uë²"Ý7$ªQJŸM¢L&M&’%¦CÄmºj#S®OF¥}±gFV}½ãVÎû-WÔƒ¬û{ ¶wÙj¾¤מLÊE}vuúE"°RNÎT¸Æ’9Û'7ˆI¦ožâH‰N ‰àS6xíZ’õÁSª¹5®µàJS1¤©EÉçH4Æ.Ñ^õÍJÔ|ýÇ0ÖõŸoxÕ³¾ËUõ!îÕµIjðÚÚý¨ˆÒ…<ÊY«’4çI©<‹e¨ñžlŸtF%nü˜6´eÅÙýj»M“Öúnùk’ó‘Õº[&˜$eœ`òL¼EÝ6Ö_ªxôJºé3®jÍÞ™]JN˜‡¦<¼±Qym¨£›K÷¯aãie§8$™ð"³íï¶wÙj¾¤#¬û{Æ­öZ¯© Ƽò`ÞÏ¥]5iÝfÒL£¥A¦Äm©l,ÉŠsÈm% Ý_3&o«=XÉ(‰®m‹ávòùúwûBÅ®ŽÍ³O§EŒíײ¹ïD38òäÓkDêLÔjí´FJÁŸ âWÃÌDCEQ¶¨õ „‰óv·h?*Kªyç«•­Ff¥ø9™™‚š¿~LX£¹uŸoxÕ³¾ËUõ!gÛÞ5lï²Õ}H[[<Ÿ ±O!äV}½ãVÎû-WÔ„uŸoxÕ³¾ËUõ ÖÇÏ'è,Sú —Yöö>lï²Õ}HGYö÷[;ìµ_R l|ò~‚Å8Ǭû{Æ­öZ¯©Yö÷[;ìµ_R l|ò~‚Å8ÀÅˬû{Æ­öZ¯©Yö÷[;ìµ_R l|ò~‚Å4Ǭû{Æ­öZ¯©Yö÷[;ìµ_R l|ò~‚Å8ˬû{Æ­öZ¯©ë>Þñ«g}–«êA­žOÐX§¹uŸoxÕ³¾ËUõ!gÛÞ5lï²Õ}H5±óÉú ñåÖ}½ãVÎû-WÔ„uŸoxÕ³¾ËUõ ÖÇÏ'è,S€\zÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,S€\zÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,S€\zÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,S€\zÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,S€\ºÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,S@\zÏ·¼jÙßeªúuŸoxÕ³¾ËUõ ÖÇÏ'è,SÌ;¢âv}½ãVÎû-WÔƒ¬û{Æ­öZ¯©¶>y?AbšãÖ}½ãVÎû-WÔƒ¬û{Æ­öZ¯©¶>y?Acsµ_è¯|ÝkÔ¤9¨è›KMŸ¢ºMIš”HíÛðŠS-¸†Ý\zb™pÒN%+Ó­µjI‘gŽ&å/zÿX“#éNÁ~ìo™›þ%=¿| ^4¿ü&=6 ðc|Ìßñ,yíûàRðù¥ÿá1ß¼´Šœº+2ªu_œb«’,ÝÑY“ýSªüãý\‘ð-µ~ïÙŸ¿¯ý/ß4mök³3½(/Õ:º¨©J»äÆæp”+9ÖŸø\ØècØÎ×>Ä~”o}ÔI¿9¹þ©¡ÔGÛ4oghnŒ¥ ò®^ãñkTSkâpóö?¤ÿÎç¾È¿J?ƒö=¶ç|ŸÙÏL;˜ÿñÚ'……zõµ:™ÂØîÑóÞÿc.úaüŸ±Ñƒÿ{XàxkYûD¿Yk k?h—ë#ôËC¡d†&~|ö±ÀðÖ³ö‰~²Ö8Ö~Ñ/ÖGè0 –‡BÉ Lüùícá­gíýd=¬p<5¬ý¢_¬Ð`-…’™ùóÚÇÃZÏÚ%úÈ{XàxkYûD¿Y À6Z $13ó絎†µŸ´Kõö±ÀðÖ³ö‰~²?A€l´:HbgçÏk k?h—ë!ícá­gíýd~ƒÙht,ÄÏÏžÖ8Ö~Ñ/ÖCÚÇÃZÏÚ%úÈý²ÐèY!‰ŸŸ=¬p<5¬ý¢_¬‡µŽ†µŸ´Kõ‘ú e¡Ð²C?>{XàxkYûD¿Yk k?h—ë#ôËC¡d†&~|ö±ÀðÖ³ö‰~²Ö8Ö~Ñ/ÖGè0 –‡BÉ Lüùícá­gíýd=¬p<5¬ý¢_¬Ð`-…’™ùóÚÇÃZÏÚ%úÈ{XàxkYûD¿Y À6Z $13ó絎†µŸ´Kõö±ÀðÖ³ö‰~²?A€l´:HbgçÏk k?h—ë!ícá­gíýd~ƒÙht,ÄÏÏžÖ8Ö~Ñ/ÖCÚÇÃZÏÚ%úÈý²ÐèY!‰ŸŸ=¬p<5¬ý¢_¬Žì¾²¤l™»tK¦¸ëµ5L7ÖsŸ$él˜ÐD•8¬\^O¢Íµ.C…nÑê1$SáI•Ê`!禭öâÒ—L·é5›e»Rq£<ù1]žBÉ ¾e[®»§ÂZÏÛüÃ* jõ›|˜µúËSã”™Jê‚ËvÙº†‰X5qíÝA`²|sÌFey§À£Ð$Õ©P\¡5&=Å.2î g(‹PŽÑ¡)ekKKNMJ>ÐðêQ`³…@©J ÍÚ¢"QiÔÃj!™SåDbrbj‘LåÔ(”I%¨¹°£JTe”¤É³Ñî‚ÉvRzëºqýe¬ý¹ßÌ#®»§ÂZÏÛüÃÔãÆ­ÆZŸqPi³ JQ@äO2§°’2Ý¥† ”µ"5#‰p\O¢Æ£GÜTmzÔ›™4ú,Õ9M‡Oxê ÉÇu*NäÈÜÖÞV“{G¾"Ip!/G ¿"Évs^ºîŸ k?nwó ‚jWÊíÇ.Ü5ESš–ˆn,ªÆkC«B–’6õë"4¡xV'¥Eœ‘ÙG¨"Õ·í™hÔz‹µV•1Sà7+^™.2L'Y‚$´JÊ4«Ý9ù±g±iôš¤[¬§·ÚˆÍ×O}ªl³%iY"¡»…—PiÎLju:H‰F¢áƒ‡£Ñ_‘d‰»æsrºîŸ k?nwó ½>þ¸&®"·Y’ú7TŽ©)IžT².uÁ¾ªª7D×*4xi 8¦•â">•i¡ ,™seYQ㉘èÞÿ†ú_þÓ?í, l´zH‹³KÖöØ;ê³÷Â} ¯\;òUv•X¬×"Li(ZÚ\÷ É+BVƒÉ(ÈÈÒ¤™pÈ}p2=šùK]Ÿô?ö6ì´:H]œß®»§ÂZÏÛüñûh³v•uK¡Ön*ÉgFéî_#ÜûG–}ª\Ns ‹‰ð ~–ÿÁ÷ð¦÷þïú‰!²ÐèY!‰ÿÚÇÃZÏÚ%úÈ{XàxkYûD¿YjÑéhm©³ë*&¼ŽMK¦Ò*ŽÅ\‰=±–„¶iÖ®ûÓ$¡¶’Ê–¥œ%$Dff|ˆ{{XàxkYûD¿Y+lòâÏØé: –eD“kOy‡Ùp–Û¨TUšV•$ÈÈÈË‘mNóº­sºîj=”Ûu ë(¦0ë+k‘›;ÆkZ÷™ß£ "G½<§‰ËC¡d†&Qý¬p<5¬ý¢_¬‡µŽ†µŸ´Kõ‘l¸okÚԤ׺›zlö­Iõúz¡0êmÈ©F¦]%8£q9y¼-&DKíSÀmö±{Õ-3šTÖ!=¸´kU´ïÐ¥eø|—t“Ò¢í~½EÎx,qËe¡Ð²C9絎†µŸ´Kõö±ÀðÖ³ö‰~².÷mh¶ô*j¥u%i’·œ™:dæ %)ovÊ™ií놣7Lß-)"Ae‘~·¦õNN©oâ¿Êâ´þö*L¯R Z›3âh<äŒú0-…’™Â½¬p<5¬ý¢_¬‡µŽ†µŸ´Kõ‘ú e¡Ð²C?5»ìz¤4á¶åëY%9r‰ž°0+›·(ô™)—½srÂu(ôÃRŒÏEþÎfd\p\x™ê;X]àÍl‹ºKõ¦t¸Ôj“k6¤$“ŲRV >Q™§%ƒÁ¤óˆ¡V65P«í &—.Váq`CŽën°Þñ<^Öâ°µp=Di"í»c4¦›5…’&ìüûyÒd[þÊú~ÎÛ¯W$Q±JŠûk©>FêLstµõ$ŒÜ^0y"2ãÃ#õsÛ"ÙÃn­¾£VOJŒ³×5GŽ?ç‡æm¯ÿú€BÿHèêâÚ?¥½ÿ¯þâ^G¡d…ÙFìK³‘k>sT}0v%ÙÇȵŸ9ª>˜i¶ÇY’íN ±O¨WiîòggÈ•Iƒ*K%HŒ…”t)D…;©g’‰…$ùð3¡ÞU{† ²Í¾Ü( Ä9¤ª£Ç ã©¶ÞdÚ%!Fá:é'¤ãJŒóŒ ìÔzH]ž¨Ù~Ë×1Èi¦Õ%¦Ð댕ÓP5¡ 5TißäˆÍ ">*îöìK³‘k>sT}0®Uî*¥#kOÒ˜ 땊)†ÞtÔP™u.Ô³R¸)]:,)xç"%(²ë×]é»Î§è ¦Ú‹#q¥Åw}1 „Ä—H”NéhýÑZLÉ}eÀÔ©Ù¨ô,»7‰vqò-gÎj¦Ä»8ù³ç5GÓ ¦î¸ ½sÔ©­Òº“kiå¬HmÅH—†!ÍÚÉd–ðÛ‰$å+Ô¢2à&FЧ\mÑ*Q7SYv,—ZÊS)¥£aÓÉŸT¨¨3æÊ–|4à›5…’gº6_²õÌriµEIi´:ã%tÔ hBÍD•wù"3BȧJ»†=»ìãäZÏœÕL)ѯIðž¯^R ¡ÉR­ê"ã0ÓN(´ÈŸ= e Ôµ%ÆÍD’33%`‹$Csü¸C¬9*œoÉŒô& Ëz2—÷%˜VUX¹(Û*¦t™ÕB¦P¢D\v–à Só&4ÚœB–µ$’·{b%RœðÎ 2©{]ÚîxÕÆ©U©‘)ŽC]>#èÞ¹2C̶‰N/ RÚ£RŒˆÌ²j"&ÍG¡d…ÙºìK³‘k>sT}0Ô^;:ÙíÚ™SbVuÖRD„®æ¨éÔ¥HÏñ"3Î8gÉsÖÎn:ÅnEN%Z+ÆQ •³4è²é­¾NkÊ ©=¶¤8™(ÈÉiæ<ÊÚ§õ¥ÿ5þµ³QèY!v~Úã®ÈD§ßunºä ]kZÔjR”tb333ç3>‘ÌGJÚ¯ôW¾nµ¿êRÔWCVRý?Ö"GÒ‚üØß37üK{~ø¼>iøLzlà.Æù™¿âXóÛ÷À¥áóKÿÂcGx;h 8tVdÿTê¿8ÄÿW$Y»¢³'ú§UùÆ'ú¹#àZjýß³?_ú_¾hë>Æ¥¥6,ÒR’GÕ79Ïÿâhu 㟤~6fá¯ÀŠˆ°k•8¬#:fZЄäòx"<3ý£Eáv‘pºk…ÿOwó¨hÿÅ•8ÇV÷$¸£óu}“7&ñ#ö–ñ¿ŒOÒÆþ1?Hü:ýéx–qvW‹ÿˆ»ù†¶Eñz–qx\ýÕ'¿0Ûâ*rüŒÌý›%ùÞ›Æþ1?HoøÄý#çÔ›òù#áyÜeýÕG¿0Àhéâö¹KÿŠ¿ù†˜{fü¬äô).óè¦ñ¿ŒOÒÆþ1?Hù¸öÑ6€\×ÍÎ_üYÿÌ1Ú6ЋšüºKÿ‹¿ùƈûF/òœÞŒ×yô»x߯'é 㟤|Çwi;E.kúêûâGçÎm/håœmëûâGç––ŸqGE®óêñ¿ŒOÒÆþ1?HùhæÓ¶’\ÛB»~ù‘ùÆ3›PÚYãh—wßR?8ê«'ÜQÂÇÕM㟤7üb~‘ò‰Í©m8‹†Ñ®ÿ¾äþqÙSiùøG¼~û“ùÇTîTú˼oãô†ñ¿ŒOÒ>MÕ6ŸãñûîOçÊ›Oñxý÷'ó‰ ú˼oãô†ñ¿ŒOÒ>MÕ6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6ŸãñûîOçÊ›Oñxý÷'ó€>²ïøÄý!¼oãô“]•6Ÿ„{Çï¹?œ;*m?Æ=ã÷ÜŸÎú˼oãô†ñ¿ŒOÒ>MvTÚŒ{Çï¹?œ;*m?Æ=ã÷ÜŸÎú˼oãô†ñ¿ŒOÒ>MvTÚücÞ?}ÉüáÙSiþ1ï¾äþpÖ]㟤7üb~‘òh¶©´ÿ÷ßr8vTÚŒ{Çï¹?œõ—x߯'éŒ?ð—™ö‘‘—øÇ›û¢Í=•6ŸãñûîOçk–êº.nO×%ÉX­rm[ލNrFëV5iÖ£Ó)Î9ð]À †Ö‰pÔèÔê¤ ˆ˜õXåa= —”¶ÈõR§jGlIVPdz’ƒçJLµD ¥áªQ©õH1ê±Ê4Âz/)m‘ê$¥N ÔŽØ’¬ Èõ%Δ™fÒok–•Of)Í%¸ù(Î9—^“3=Ë«A¸×3íž&gÎ+ "È åpÑ)ë§Á–¢)ó’MJ†Ì”¡ã"#qê¡x"-IÁð.<5&ä¬Ó*²ªqå!É3¤Ê9L7% J%¨œC©RW•+¶#âD|ä5"ȵº¤úÕMÚ•Iýü§t’”HJ‰)$¥$”‘RI"""""""!d´»Å‡IäO‚·Í¥0ëÎÒ¢¸ì†ÔƒBòÔÙ©äšLÈÉÃQ~Ò!OèadÁ¾·®û‚ƒ£Se²–’áºÑ=—͇khÜJ¥ ¶FqàCÎ-ÑYC—EC±‡2Z&H'à°óŽ|pâF+ M¬Ò¾Üý©ü‹hý–O¬´ëΩ´â¡wÖX‡|ýÖõ¸ˆRZ-ÛHl´’”£æAg&|sý·Р¥¿ð~ÔŸ32"íyÿâ$Í#kn\·´û¯Û•ú­×’Hup&9KIH”h2Ég ÀUîkÖ¸®. ‰Õª1â5" rd%%£V£NuÄø™ã'‚Ï1cm:‹HŸjȶ'’éra*í¿-Ÿë*A¡D§M[Å(Òg•šµsœñ+»*m?Æ=ã÷ܟΕ6ŸãñûîOç}X¯Sé•Êú%Q´ÈPŒäYMo ;ÆœI¥iÊLŒ²“2ÉpyϤQ§Õ©LŒËòY†ü$)j3Náõ4§PiΕ–ùÈϵÁc'Ÿ•}•6ŸãñûîOçÊ›Oñxý÷'ó€>žÐ¬;:ŒÌơӷˆ™‘¼S&;+ü‰n¾Z´5ÄýÍ8Oö û/°ÙD´>Kü²–ý!åJ«J}G íÆ N:f”„à’e§ŽœdóóC²¦ÓücÞ?}ÉüáÙSiþ1ï¾äþpÔ«¦Ú¡\©`ª¼«TrY6äJƒñ$«’kehQ¤ô§)32<K€ÙÓc@¦Ó£S 4Äh‘ZC,2Þ -¶’$¥$]DDCåeM§øÇ¼~û“ùò¦ÓücÞ?}Éü଻Æþ1?HoøÄý#ä×eM§øÇ¼~û“ùò¦ÓücÞ?}Éüà£7Äã©,5m\’ÒÚ‰;èôåk2"Γ3,–rYæ>Œ– UïJBµl˦E´®t<ö*rœ¢IaiQçgÌ]Áø;²¦ÓücÞ?}ÉüáÙSiþ1ï¾äþq\$Üì;_ÿõ…þ‘ÐÿÕįê5ê5 ,½Y§6âRV…JALŒÈÈË< |À™pW¦\ ¸fVêR+)q·SPvR×$–Œ¼3Õ©:SƒÎKŽaí×UÏácí®~a-\\úM}£¥6¢ÅZ–™s¡Ãœ“5èN”—`ˆ‹< “3ç33ÔϦìòj—gÁmJ˜¹¤ìz²˜u,ˆ–¤-· HÔEÄ’dG“3#31ó¿®«ŸÂ:ÇÛ\üÁ×UÏácí®~aEÏ¢’¡lòTyäI¤8܈Qà¸G<¿B–¦I=¿j¤)Õ™-8VL< ®µb;K¬Ó¨Óœ‹[I¦¢•Ô²§ÈØDsÊzˆÍ¦Ðœ‘‘ðÏ9™ŸÎnº®ëmsó]W?„u¶¹ùƒ¹ôF±NÙÝ^­ÕIóiÎH=Þô“T44þƒÊ7­%d‡tŸ6´«ûªÁÙÝQú³óäQÞv¯ 0§(笧V”ðWje¨ûdàù¸ö¥}u\þÖ>Úçæº®ëmsósèÓíØ/ò²z]ÄÌ„ÌЩ‰4©†Ãmu`´›®`øóð,cE§ìú=2u8êPåGž‚nO-¬.RÖ”çJuºâ”Dœ™‘– òX1ó»®«ŸÂ:ÇÛ\üÁ×UÏácí®~`Â.}Mg±)µ¦`L¥½"­ I]B®äþïYµ¼RÜ5ö¦áñ#%cÚ§»"…nÃrà~¿>€eZeˆÎÄMiÉäm³¼4©o¿‡³7UÐZI("æÈüwUÏácí®~`ëªçðޱö×?0a>ÛÝeÐwçO­Æ5¿¤œrUarœQ':S­×¢Ij< 'Àam&µG—eO­÷—»ÒÛr¥Iž<Ä>xuÕsøGXûkŸ˜:ê¹ü#¬}µÏÌEË–Õ¢½óu­ÿR棥mWú+ß7Zßõ)j3hœ%ï_ëd})Ø/À]ó3ıç·ïKÃæ—ÿ„ǦÁ~ìo™›þ%=¿| ^4¿ü&;÷ƒ¶€±S€wEfOõN«óŒOõrE›º*se0‹~£ KÃîÍŽêƒâ”!òQç›­?O÷€è]«÷~ÌúTÞeÏЩHæÙ<ÂÜõb™Ž6­ö»3Ó «œqµmÿÚìïL=úI.ÿóèa©Wþ¬¦Èæ1«“Ò/V(ÜsjÛ_µÚ‡¦/Ö(|sjÚ¿µÚ—¦•%ÿñ˜ç?&P¥slŽsúÅ¿ÓjÚµÚ§ý '«æxÚ¶gív­é‡§J¢]Ï&dœ¼ŽvøÃ|tGk×M«d~×k˜b»X¶:m[ö»YôÃ|+®O&g“9Ë£Þ‘Ò¬Z½6­…û]­úaŽåbÔã›WgÿµÚç¦!¤.—“8ÈæŽŒWyŒt×+—‚»<ý®×}0Çr±hqÿr»:ý®×½0Õ )tË&r’9{¾ôÆ?Hê ¬YØþªìßö»_ôÃÇ«nª»5ò·¦£¥®‰dÎN'51¥bÍðWf¾VàôÂ:±fø+³_+pzam­tK&F›@Òαfø+³_+pzaX³|Ù¯•¸=0mk¢Y1„æ :_V,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ€:_V,ßvkånL#«o‚»5ò·¦ ­tK&0œÔJêÅ›à®Í|­Áé„õbÍðWf¾VàôÁµ®‰dÆšé}X³|Ù¯•¸=0ެY¾ ì×Êܘ6µÑ,˜ÂsP+«o‚»5ò·¦¬Y¾ ì×Êܘ6µÑ,˜ÂsRÝ+«o‚»5ò·¦¬Y¾ ì×Êܘ6µÑ,˜Âs@/«o‚»5ò·¦¬Y¾ ì×Êܘ6µÑ,˜Âs@+«o‚»5ò·¦Õ‹7Á]šù[ƒÓÖº%“NkÝ:_V,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ€:_V,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ€:WV,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ :WV,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ C¥ubÍðWf¾VàôÂz±fø+³_+pz`Ú×D²c Ít¾¬Y¾ ì×ÊܘGV,ßvkånLZè–La9·@Òú±fø+³_+pzaX³|Ù¯•¸=0mk¢Y1„æ :_V,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ½Á¥õbÍðWf¾VàôÂ:±fø+³_+pz`Ú×D²c ͈@éeX³|Ù¯•¸=0ެY¾ ì×Êܘ6µÑ,˜ÂsP/«o‚»5ò·¦Õ‹7Á]šù[ƒÓÖº%“NlAÐ:WV,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ€:WV,ßvkånL'«o‚»5ò·¦ ­tK&0œÔ@é}X³|Ù¯•¸=0ެY¾ ì×Êܘ6µÑ,˜Âsn:_V,ßvkånLX³|Ù¯•¸=0mk¢Y1„æ€:_V,ßvkånL#«o‚»5ò·¦ ­tK&0œØ„–U‹7Á]šù[ƒÓêÅ›à®Í|­Áéƒk]ÉŒ'6è:_V,ßvkånL#«o‚»5ò·¦ ­tK&0œÔJêÅ›à®Í|­Á郫o‚»5ò·¦ ­tK&0œÔÀÇKêÅ›à®Í|­Á郫o‚»5ò·¦ ­tK&0œÐJêÅ›à®Í|­Á郫o‚»5ò·¦ ­tK&0œÔKêÅ›à®Í|­Áé„ubÍðWf¾VàôÁµ®‰dÆš€é}X³|Ù¯•¸=0ެY¾ ì×Êܘ6µÑ,˜Âsa¥õbÍðWf¾VàôÂ:±fø+³_+pz`Ú×D²c Í@t®¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c Í@t®¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c Í@t®¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c Í@t®¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c Í@t¾¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c Ít®¬Y¾ ì×Êܘ:±fø+³_+pz`Ú×D²c ÍŒ;£¥ubÍðWf¾VàôÁÕ‹7Á]šù[ƒÓÖº%“Nh¥ubÍðWf¾VàôÁÕ‹7Á]šù[ƒÓÖº%“FÕ¢½óu­ÿRæ¢ñ~×¢ÖbM“ÊèÜ¢C´æ™‡LnQ4Ã"®:K2 Qö¤ß:”fy1G ødÚ¶õÇwåHHúS°_€»æfÿ‰cÏoß—‡Í/ÿ M‚üØß37üK{~ø¼>iøLwïmb§îŠWôËÞè¡UL±üÿ¢öŒú4{$häs lža²‘Ì5²y‡¿DÁPÖÈæ1«“Ò6’9ŒjäôV†f²W8ÖÈç1²•Î5²9Ìz´Ls5ÏŒ7Æcã ñéS3HÃtb;Ò2ÝŽô°8HÄtb»Ìc)ÑŠï1°8ÈÄwÞ˜ÇéûÓý#\xX1L@±Ÿ@'Ð „÷Džè÷D îˆ =ô=Á{‚B€AЈ = O@ƒ$ IO@= H"&Ð0î€ })Ø/À]ó3ıç·ïKÃæ—ÿ„ǦÁ~ìo™›þ%=¿| ^4¿ü&9÷–;h 8tPª¿¦X¾÷E «úeçý´gÑ£Ù#G#˜kdó ”Ža­“Ì=ú& †¶G1\ž‘´‘ÌcW'¤z´ 35’¹Æ¶G9”®q­‘ÎcÕ¢c™®|a¾3oJ™šF£Þ‘–èÄw¤mÂF#£ÞcNŒWyŒmÆF#¾ôÆ?HÈwÞ˜ÇéãÀâÁˆbˆ$ú >'º „÷@'º Ot@ è' @ îÜ’$„’€ è@$@‘ èbz !H@z è````D  0î‡téNÁ~ìo™›þ%=¿| ^4¿ü&=6 ðc|Ìßñ,yíûàRðù¥ÿá1ϼ±Û@X©À;¢…Uý2Å÷º(U_Ó,?è½£>É9Ã['˜l¤s lžaïÑ0T5²9Œjäô¤Žc¹=#Õ a™¬•Î5²9Ìl¥slŽs­Ísã ñ˜øÃ|zTÌÒ0ÝŽôŒ·F#½#l1®óÊtb»Ìcl21÷¦1úFC¾ôÆ?H× @“,A'Ð Iô!=Ñ'º€=Ñ{¢€O@=Op@žà€$ t@"ˆO@ƒÐ ÀIBÐ O@€ H€I‡t ; Jv ðc|Ìßñ,yíûàRðù¥ÿá1é°_€»æfÿ‰cÏoß—‡Í/ÿ Ž}åŽÚÅNÝ*¯é–/½ÑBªþ™cùÿEíôhöHÑÈæÙ<Ãe#˜kdó~‰‚¡­‘ÌcW'¤m$sÕÉé­ Íd®q­‘Îce+œkds˜õh˜ækŸoŒÇÆãÒ¦f‘†èÄw¤eº1é`p‘ˆèÅw˜ÆS£Þc`q‘ˆï½1Ò2÷¦1úF¸ð8°b˜b >O @ îˆ!=Ð îˆÝ@z è{‚÷$„ !$ƒ : $@zžH@’žz‘DL; aÝ@úS°_€»æfÿ‰cÏoß—‡Í/ÿ M‚üØß37üK{~ø¼>iøLsï,vÐ*pè¡UL±}îŠWôËÏú/hÏ£G²FŽG0ÖÉæ)Ã['˜{ôL lŽc¹=#i#˜Æ®OHõhfk%slŽs)\ã[#œÇ«DÇ3\øÃ|f>0ß•34Œ7F#½#-шïHÛ„ŒGF+¼Æ2®óÛŒŒG}éŒ~‘ï½1Ò5ÇŃ$Ä Iô}OtA î€ Ot@žè€ íc–ŶWtl>Û¹.KKª5YÜ«~ÿTdµ«D—PžÕK JK0¿û^¶à”EÑ6>xtD=¯[ð÷ÄÏJ×­‡øûâg¥ HXùÞ臵ëaþ~ø™éCÚõ°ÿ?|Lô¡‰ <;‚ÑkÖÃüýñ3Ò‡µëaþ~ø™éC>xôCÚõ°ÿ?|Lô£’{)¶a³ 'fî˵ì´@©º¤š%ª¥)Ói$ëd¢$-ÃI™’ñ“#Ág†pdº?%’ è€D ž' A€’$„' @ž$@‘“èw@>”ìà.Æù™¿âXóÛ÷À¥áóKÿÂcÓ`¿v7ÌÍÿÇžß¾/š_þûË´Šœº(U_Ó,_{¢…Uý2Çóþ‹Ú3èÑì‘£‘Ì5²y†ÊG0ÖÉæýC[#˜Æ®OHÚHæ1«“Ò=ZšÉ\ã[#œÆÊW8ÖÈç1êÑ1Ì×>0ߌ7Ç¥LÍ# шïHËtb;Ò6Àá#ÑŠï1Œ§F+¼Æ6Àã#ßzc¤d;ïLcôqàq`Ä 1Ä}Ÿ@€ÝB{ Ý'º €ôCØÿ“M›ÿNÿlxXv¯>m2Ñne<¥®Bjô´“Q\$:òUPŽ•4F¥%=ºLÑ…(’d£#<Ч±r£Oìi²¹|è±wœ¿Fùä£V&;œdøó—Ò/5Z¥UŠˆÓêô·šD†d¥<µ)ÃŒº—[VIEÌ´$ñÌxÁä²B‰%r©rVåÝÖl7m‹†ƒú»©yÙR"O¤©òÔM1!Ål”¯9ArD+ÔFnZ­gUg3rW)[Vâ)U“‰+•›zœyÕ­)ÝDhǺ *ÊOVGDQ´§J&U^–ã´ù&*¹jKvá´ãF¬¸öެ°y.Û<äFZ7h»9\J|VêlÄnŸ ¸1ŽyØË&,!µ-·R¥¤‹>øÏœû¦ +–:§bÒkTúÝׯªÐ)ƵVeÆtª£l>ÓˆmhI­$·Z5™ûRíŒÈŒnHDËÇ­«W#R)´¦¦6†êòJD§}ä¨×#^ùIl›,¼{©ð$‘mP›8ÔFæÒOŠû2eR’K<—¬’²g¼I(òg¨óœäóüÜMØõõÇv£U…¿ŽJ&dFªª3í’±©$ãKJÉ'‚Ég‚Ï0Q«“j†ˆ=pÖ˜…x9N.§TŽ,ɬ-é…ÇôâÅ@:I@t  H€ô1= $ =ô0000"ˆ˜w@ú€ô§`¿v7ÌÍÿÇžß¾/š_þ›ø ±¾foø–<öýð)x|Òÿð˜çÞXí ,TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$úžè‚Ý@žè=Ñ@ ¬k–â ˆq«õVcGI¡–[˜âPÒMF£$¤F¥)X.•ôﮫŸÂ:ÇÛ\üÃN Ï]W>?¬u¶¹ù„uÕsøGXûkŸ˜j:7u\þÖ>Úçæº®ëmsó 87=tÜü?Ýcí®~au\þÖ>ÚçæŽà€䮫ŸÂ:ÇÛ\üÃÂm~»62âÍ­T¤°¼kiéKZƒÉdŒð|HŒkˆ@ è€D ž' A€’$„' @ž$@‘“èw@>”ìà.Æù™¿âXóÛ÷À¥áóKÿÂcÓ`¿v7ÌÍÿÇžß¾/š_þûË´Šœº(U_Ó,_{¢…Uý2Çóþ‹Ú3èÑì‘£‘Ì5²y†ÊG0ÖÉæýC[#˜Æ®OHÚHæ1«“Ò=ZšÉ\ã[#œÆÊW8ÖÈç1êÑ1Ì×>0ߌ7Ç¥LÍ# шïHËtb;Ò6Àá#ÑŠï1Œ§F+¼Æ6Àã#ßzc¤d;ïLTš•FQj£I¨K§Íg;¹^SN#$i<)&FY#2þã1®<,Å1õÆÒˆ¶·³Ëæ“‚vå±ëó\ŒEÅnE'œÂKÿq&œKHîŒ?a›MЮs¡iê…J†º´Ó2íšozÊc7ý†hZÜ>é:Žà¦·ð·acò¡ôJ¯vm5{¢mL•ª•f¯)jJ8R•/ ZÕ‚""I(ù‹¸<®-ŸÕéV›lI”êÕ×Î9ϧ­f†Ýÿ€´¸„-ýéÇî–o‰p ¨é·Æêvý2ƒUªÝö¤zmy²v £zN•$Ò…$Í;dFK#Μëxf±´›"»³û™výÂÛ)”M%æÖÊõ¶ëj3"ROxÉq"<‘‚’|YvØ]J£MÚå­Ôꄸ|ª¯4ÃÊo|ʤ7©µàËR”ŸÀ¿û$#UîÿdÔ›8ë›–—",jr'<ê£GqèÌö©JR­פŒÉ8É‘«“(r´¬¢±²û›^eë«Q­´Ù--ÇŽ;ǹKÚR¢hÌA™öÉ"íL³œfl×îÛê¿fSêÔF*ÔGCé’ã扷wKSjKJàJÓï´™ê,ñÄãˆ9È ô}–V¦Ú•«†W¡Õ›¡'UR4GÜ7£ ÌÏSiBȉ*<¡J#Òx3)§ÀçgÛN—G´-b“´¹ÚJ3­Heº 3eõÌ}D·\pÈÒ“BÚ÷šñŽb=¾Rï VÓêMß3ŸXy-¸©6”"Cd‚B”¥)"íPIÆ ŠOŸœê¤Û³„÷G\ö$ÚT»»k­1YŒÜ¨”ènOTwS©©*BJ.’%8GŽcÇѰIÕ ­×îÛJî˜íJªCÒá¢Aê(/%Ô% c?¢"Þs'dX2ÀJv¿‘6?=ý°Öß±êø›C6é?+i«º˜‰&²ÖZnJÍ)B°NäµöéþÁ‰ì°û R£!êÃÔTõR¨Â LMt’ÙdOjê‰[Ã3#> OöSüV8@¥W´n]‡ÝíÇM¥TW.,‡"2N­¡ÝÑ d¤àÔÚBñƒ#2"%t•ïØãY©^ŒÞ¶9êÅ¥”§¤;QVñ1ÔZMµ+ôg§xdIÇ–:¹Ù]p?9÷D£±‹ívUµq+©ûz|¹°M+Lnk¯2„J'”8d‚–ÑäÔ“îg˜m=e|Uí»^ë­Ý­Ývì´»Ôɉ€ÜE²â±¼mÆÐ\îð”]¡ãûXž+q k·f75±`ÐïZ™Bê]kG'&žÔê5 ÖiÆ RHÏž:p|]¥Ö^­û o‰D… ¦kL³4FI¶™lœ„d’éWš”f£3É™ƒ¸ó`Óìe À~™~^r£3&M³DrD<‚Zú›uIsIð3NèñžîyȆÇg…/i›Ú7]sªÏ·£µQ§M”³qöCªZ³ã¡DÖ4çsŒƒ™68(ïÛw7ö>͹dY*“)tÄΪT➉RÝRÔŒ¥Û%hQ’HÈ»a.Vip!vªm&½VµcS*n*MZM©Ð«†¼Md…‘·½"Ö¢Ô¤,ŒÕ’4tðÓÞ¶×>ú‘²í•L·îçi’dQ Ùï;r7O\¥›Œ”¥:ê ÓɬÌûljã\jæÓI’~OúSeuKl´{_jwÔS`õB2¥+”'•Ì ÍÖñN- B *Ðdx5eEï’Eý^vnÛm¨Uùw‹êƒ*Ÿ%¥âI<˜ÚÛQ!öÛZu6m™’ðÙc 2Éfû šºûìk¿.šÞÜ­JKõª“t†árB¦¢c¼”ÒÅ=HIîZrfÙ,ø{ã3M®ß—O^ÛB¶æVêSéRêRb",©Ž¸Ôd·5. ÛA«JL·D’áÁ*2!lO¬AË@lmz‹‹–—V•ºƒ¦3!ØŽ$% %g’2ˆ°y#çæ1ܽŽWm×{miÊmÁ%UKjLi.Ô II.v‰iÒÙö‘/Bxp12“Џ?>÷ý±[vÜUoj—u9†&Dµ¡Ëz†N¤œBL÷êeÜ+$£$´XÎ}öyð<öxRö™±]£u×1ê¬ûz;UtÙK7`ô:¥¡+>:McNqÇ8È«¨MŽ BzÚKٞŶs֤ǩSîîÔj3b¬Û}óÐÊ…,»m 'q§8áœdXî­Ñn­¢ìŽ¢ìV£¦ð¦&UY¦M¥å²ÂqXN4šÉXÆ{RìMN•K­Ožh“U¹«mÔæG¸nÐÚð´èI’ 9mXQ‘‘ªÒ è-öþÏêµ;EÛºdêm‚‰ª p’ë§úˆKhZÔeƒâIÇãÀñ“7f7 â‹jÔ$Ó¢®¸M2y¸µÄ’—x6iR¥aJ2Oð5ž ˆœHpk°Ú»¦­jĬےë´ÈÉ”äe;¼q¥L&¦É<ëIaF“âGŒ×j›2­ÄÙû×ÄZ"©I‹+’L8O-KŒîRXQ) #,©%”ˆõ ˈ)Å÷‚Ž`bñJÙ^U„ÕóRªÒ(”)4gç-Ó7Ü#Qa)iµ« ,™½1Zº(“mÚÛ´™êao6†Ý%°é8Û¸Ú\miQs’´Ÿí¤˜5€:g±¶êjí!¹­I˜tö Î™6/©–LBâR²æV #ÁžEÓm[>§¿L¶M“>áÑYI’ÌC4;Nx&âI%ÚûÚ¹ÚV`üþô}‹D{j;v¤Ò®úœúµ.—mSêj‹*RÜJÔ¨0õã'Ã[‹J—}ƒÏ8æ}­^nÜOÍ¥Ö¦Ó‰ã8Ô¸äH„ÛD}«fÁ…òGžSor?úm†›¨—½ŽÙÛê¾­ä›È‚ê™8‹%Ƶ2h24j- 2.5wFêñ»®¶=‡v]u‹ž¶ÕZMmÆŸœ‰î”‡PK™„©ÂV¥hžª]¬ܸ“có(·»î ÷EmUŠšÔäÅÆŒÃ®)jZ6Xm­jRŒÌÔ¢l”f|æf6V]‰[ºiµ:¼eăG¥ •:£5ÃC ç™=©)JQ÷“>%Ý,Þö[È*À-÷Ïêô«M‹¶$Êuj€ëççÓÖ³CnÿÀZ\Bƒþôã‰wK=«ÙLª^vÄ`”µ;>£HZ•(Üs¶6")n¸¤’•Žu)X>“>“sI¡có0 ­ÏIF©(Õê]h’G­úvøÚJˆÌ9q´jæÎRF“#,P¸$úÐ¥;ø ±¾foø–<öýð)x|Òÿð˜ôØ/À]ó3ıç·ïKÃæ—ÿ„Ç>òÇmb§îŠWôËÞè¡UL±üÿ¢öŒú4{$häs lža²‘Ì5²y‡¿DÁPÖÈæ1«“Ò6’9ŒjäôV†f²W8ÖÈç1²•Î5²9Ìz´Ls5ÏŒ7Æcã ñéS3HÃtb;Ò2ÝŽô°8HÄtb»Ìc)ÑŠï1°8ÈÄwÞ˜þ©1X›Qj,š”JcKΩR’ê›ofY&µñ2ÇŸ,à²eü»ïLcôqàqga…´¶l»Öï[vlK’—W‘-çXdÞŽKiçV´¶³u¢4­'¡Fd•Aäñ¹ö8íÞ¢í6»~Þ÷,*zª1žŒQKŽ©ÆV“I6ÒM‘ ÒE«%¤‹N0c‚˜šjÂçd³.Ëf²Ë»eZìt±S}©p«qc¾¸Æán”hZTÚ]$外tëp2ÁŸŒûÊÝ·v7f”Šš+Õ µL¦Ë–÷:m%êRµ(÷)ýR.*ý¼ˆúEÎá·[’Ϻ,MšÐ¨—u>LšDÓê 8²Ð„šañ™#Si6Uœ¾)ÂOŽ1}–·u­|_TÊí«[j¥ÄÄu%æ–ÒÐë‹É“ˆI8XÁŸ½VH¸gŒ€*i[È›—-ÖÖÖ,W]ŠûmÉ­Cu…)³"u ’I5$Ïß) ,—JLº ^¶óZDö[J¸•>Í6§N”â2ʉ¦XR’_ÛÚ™{nmî·¢DJ©´Ò!käkv9Y™«t·¥7“33ÒeÄÌW*%Ô'?>|—dÊá¸óάԷg“Q™ó™˜anWd£›½¶n~ÉÖ¶¤»Ñ¢¥º×ôr§J7™s‘î0²ÝãOtš&\1“,]ßV=³ì…¾/­Õz)äN¢$¥)þQ!ºÊtM*ÕŽØËN¢â?:Rµ‰¹Ü6rYöÅ‹´ªnî§Æ“_ˆª|”YkBÍ->‚xÍ,™¥µÉÆK_e%Ã<<YFͲ ûtœÔ¦Qæ7vµD†Q#&«D9.>O¥ 'ÔÉ¡+B‰j%(µ)8ÕŒÈöDí&Ò6ŠºÝ:3¬@âïH‰kBT¥jQ6Tµpî`s€ ;î öÁ/älçhÑkòXqø+iqf6Ö5›KÁ™§< ÉIJ±ÓŒpÎE£g×M©²Ù7Ez‰qµ]¨T 9“Üt!XJ[CX5iâ¥+w¬Ï˜ºHÛfȼ¬]ŸP©{@¢3&Û¦IŠ‘ ”8½ÓËf˜ÆfYi\äžráÜà€B®Ó¸:L:Lsj罫Ô%C~;S¡3)Æ e¢’óm-E¡24–²$èÁ‘¸lfþ£l®-jD›á+ÂSP¨Ð˜”MÙ#K‹7ÛBPDDdzud”|ø"ÂêÌ\é~ÆÚÅ¿líFtÜu蔸TÝî¤8Ãî8öñ‡[-Ój.ÔÔœê4ð>â+û[~—7hÕÚµ±« §>Dæœa·‘»K¯-D…“¨Aë"23Áxð3㊯@8Á@f"»OW˜¸T×d¶‰rPƒZ™dÖDµ’HŒÌÉ9<p;ÍmÍ“.„åµlm•åÒ.Q‹^bߘeÓ!ã2S=©PYà’ž%÷ƒ¯ìöûµ­;Êû¢3¾M™r·.2…­qÙ58–Ò¾ÝDHY‘‘öÜsÎX?*ÙA°v[v[”zãê½Ï»Ž·bÇy¶#GI,•¨ÞB¥¨œQ`“‚ÎsÐ97p@Œn¹vPoí–Úvåb¸Å¯l‘Ðì¨ï8Ęê$t›(Z’´“i,pxÎz erí’$m¡X³­Ö_“F³!· “u;µËNì›yd\tjAs'Ü.&BV…ÎñjÝ nö¨«¬äÄqùsX¥" å0Ü}+#mFi&ˆ‹x®$áç8ÍÕV]zçª×e,®£5éjm'’A¸³Y‘vF´¨¤îÁ³¯d5écYÐmjM2ß~-æír˜yN·áäÒêKgÐ\09@t QKzt´+Öd_c=~À™{Ò£Ö«3ÚœÙ*$Õ6ÂsF‡˜çÛ–åeÚ’“œ`̸Žk²Ú«/ë]úÅ_Ñé•vªÛÕ¶Ö•!NP„¨õ¬šBrIâdŒ™dª€!B×óè¾¾¬mßd^º¢u½É÷»þI+^®GÉ·Z7Zµêí³:[Wj0¬Í§ZööѶšÃõ¤Qo¾¨ÕFà©æÙ5›ªFñ‡PF´‘ÐÚB‹VæV8§œ¹Ç!©¥À\ï£Ûv:VZ„:+Ôª³²i’+´„TY‘KuIK„L¹¡Ò'O*&ú0FDfC¡}ÒêWþΣxØVÔ†ž—9tÄF†ÒPâºŒË %Ý$–’‚ÖGÛpBrc‹t«Bçê»ki{:§û%î›þE㨵*C1£`Ë7 Ì0•$ӹ᧓™™çqÉê$Ñ-ë’Ϧ{îÛ ëºžån¡ST¸­·Y¡Ä6¶0Z’"5“ 4çý'¨“ÃÀF©¹ß¶9µ¢´ìº] ‹žÜd)Ó¨@¯Sä:†ÍN©YŒ¸èQé4šLÒç2µ…Ù pY—.Ñ©ØÔ䦜t!ÓLre/¼F£S„ŽŒ‘¤¸‘šLúG;01* ;‘rá²³¤1X2¯qSèíõ2tFÊKRn®D7ÙI§rÒðIRÒjÕŽÀ”|ïcM²ûªC(y‹vK¦ÌøÍ’·RG§zÙ8I2V8–¢,‘áD]и§Ä²^Ôè¶§²6Eéf´S-ÎMc¡ gTdÅe³BIdFF•6XÉ`ÍÐy*½ g³®'çÓ¯Ö Ñ_xÝ(²)²NkQçvIB ¥sï€à‹·-¡E¾j”¨thoB·èP“šÓæFé ˆˆÖ¼p#2JKž !p»ëÖd¯c=À‡{Ò¤V¨ÓÝœá&$Ô¶ús%D†Ô¨åÛžùÛSœäȸŽn\…É_f—½½Ž][2¯ÊU,ªï¢\JŽåN¶‡m¡ÂAÉ'¹O’¹ÕûÊ 5pué÷•»nìnÍ)4Wªj™M—-†nÅnLÈì¬è­™%Ç &e­|x˜ñÛ½FžþÆnæ˜×I C©3>ÐúÅ3d–mŸVÙ…³PªZ”)ó¦1¼‘&žÓŽ/",©I3<q´v<°<¶>écòŽeÐ@,TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ láPks©ÎÔaÒ¦H†Îw¶Ê”„`²y2àX.#X"5#&Ô]íÄ—$›\I>O @¹P îˆ!=Ð îˆÝ@z è{‚÷$„ !$ƒ : $@zžH@’žz‘DL; aÝ@ú °ÿ‚WæÆ„\…7aÿ6¯ÍŒÿ¹E޶åNÝ*¯é–/½ÑBªþ™cùÿEíôhöHÑÈæÙ<Ãe#˜kdó~‰‚¡­‘ÌcW'¤m$sÕÉé­ Íd®q­‘Îce+œkds˜õh˜ækŸoŒÇÆãÒ¦f‘†èÄw¤eº1é`p‘ˆèÅw˜ÆS£Þc`q‘ˆï½1Ò2÷¦1úF¸ð8³õ¶Ájæ¶-Ý—ÂßêYŽÙGÛw8ƒ“$™—M<ƳÇÒ:‡zØ4‹ E"µk*eIdæ^"#'2]¯lg”w8sc<æ9ZÌfi,ŸîÍû ÙóÑtÍ.¤¢Òœ®¯k>/u›çä{>ÓÒã_G¡Ó»¯åÇw>µ¯[õ*+QšÖ)”8JJU„)HJɵ‘½ mf’3Á8œàÏíe±Lr¸‰5§*|&Õ)öVá$ä’8¥”ô™­ZSÉš¹’bï³;Âד*ºÖÒSÊX©JD¦Ü6MdÛ®š˜yiIàÒÓêt¸pSÇ"?Ò6Ñâ”-Ûöd¼Å ¨ëQXD‰ DG–ZZu!Å™j•$ÉD£àeÄ‚•n\5X‹—K¡U'ÆF½oFˆãˆN‚I¯*I’ZLû„¢Ï9›G¾¨sjìVgÕ:’šeÈõY0w./–E6ÙCQh#IRÉ·ÛšS¥ÓãÎGHU¨û8£R)õ9 M\™=ÖÚRÑ£S1Ëš‹†¢6ÞÆ%ƒæÉf`Â¸í¹”©Jm„¿5†©Ðg>ú2K%&;O(Ë$DFé ŒÌ²eÑœ èÛDº¨õë^.Ÿ £.œNY& â °Ë†¼—éR”™á“Q§ÅÎr&-µ¼EÚR×"ƒOˆñ=T«Gå*Ž¢$&;j34œ3Ç$Ü32"JL'Ç Ù\¦Sˆ‡tÛÒbG޹&¡×ɨˆJЃÖJhœ<©Ô$´!D£W àñ¾‹qAw[wJg2„?BêkúI.®ˆ†¨ZÔ×9‘!Ò,aDfE“#"ÝE¼)M.;;Æ=f´˜2ÙMrT7äFNõlL¼‡[Þ<„¥·Ï¶mD•:œ’E[‘%^NË«MPδÕV* ±ß“Æ]tùsL Öú›Ëe§AäœÐfddDf(†F\ Œ‡fkh”Ø÷D(nU#H¦»OKI,0û0]}éµ¢1i$²Flê4´K#'‚IŸo´)TÉ·„ùt‰.Ɉé¡[×âõ¹»NðÒnû¡£^­:ûm:sÇ"bÝ÷jÑM¨¹¹ÑO–­üw$³†T{Æ[×­Äðâ„îÜÊ‹hVyŒ{½@®³En¶õ¤Ý-ÓÒÜÕÅY0³î†ZOé»z³l•‘6myfS-šµ àœgT·^}3TÒ‰II |©)É«$eİf¢ñ­W(Söz¤M©Á•Z("Eä¬ÊfJI¥6FÜ‚3äëi(A’M9Y©(3ÇÄî <ê5bŸ©ô©Ñ#ÍN¸Ž½hCéáÅe…âYçz½¡6‡E¤Ôn§ÒÕ>¡"+‘ß„¤:Óm":÷¤•uj)‚à]§?çÚ ºõrX†ÕqrD¬È‡‰§)(kV[uO¸l–­8d´« >Ô’I{ÖU2]¯oÛÔ멪춪õÜ}hu–ÛD‚ŠHÊžJH²m¸j>b=\q…I»§uQÝ \3i¼‡ù3šPò y³â‡ýŠI¥Eý†3íÛJ©_·ª*Di“åD›)B‹O8á<Ü…šû\™y>1ƒÎ®rÇÚLØ“oGôɉ˜ð}<Ï&; °Nö+w«öî[nÎët¶fºÄùujt†ÐDki–åë=Eõ[Œž ó“#.cÄï°50hu©ÌÌz ¡)¨)Õ-lÆZÓ»«2.Ô¸>9‡õ]“Fzµ‹Rz˜Á™;1¸«S ŸqK"Ò_´Çd¶®û­¡Ô+Óª‘Î?^2j ´Î47I¥Øí2iNðÈ•¯|^ôZUƒIÔ(Uʶ}È«u8.?Ÿ.<[fSsØqÃqIJ\AîÊ”¼¯yÇ ZH¸ˆÄùsžèÚI·.´²ªÉ Õ§«F%9IJzÒJGneŽÙ*#.¿F‡q.l§ê”Ç}¤º‚}¦”J25% [DD­&xI‘È—õ°‹‚¹*;ÔTîîɵ˜R*1§)/2餛ݢ:ÐF¢$hñLœ2Ê{b3“@æV•£U¸•-f³McîN(ª[$¶"¸ù4kà’R·zyòZ³ƒæ:èê6ÅAfÛ„¹WÓÞnÕéK§nQÊvB$©µ‘¥&&o6“Ôddm'†8—.›l‚öÎË.¸õ›Vv—P¤F¸¥³2_‚éU¹!l’%’Ky„„ŒñA¤òYáV™A®Â•,Ú-J3óR•Eiè«Bß%h#,¨Œù±œ‹µ·Z G©ìƳ&´Ã'oËaŠŒU0ñºÛi¨?$ß#$‚C„X%kÏ2L¸‰²ï*m>-¶å^AË“§W\’y.«v‰Q#´Û¦i4¨Èœ'Vd…ËI™`ÌŒâò$ UiÕ Lç U`J-¬o’Ê›q,–R¢#.kH´kuŠKU \tË'–“eµ{¢ 3(yÅžpXо334™c8ÎnÓj°êu:kP¤¹=1PtÆ¥%’"qÅàŽRÕkç<pIFv •ß°lûVjTFº™Õb-„i3#Œj%ÉãŒq&A‘žLœ>rÎ%·k¢ ?gÕÉÕ ¤îÂ7i”dUß3qDJmL¶é6ž×‹¸p‹O6R¬‘dÿªMƒ&¥ŒãWª…i¥;N¦:§Ó!ò'œd’JÝn‰J[K"#p³Ã›"ú«úÅ£Ýuz”FçÕcH®ÆTdG|ãBŠÖ„o7Œ«ZÖdh-*÷>&žÔ³~R¨S-zM9øsèÐbȇ2Ri¨LÆÐ¹ÒÔN2úÛ'¢eÆÜI%DDgƒ,ê![È’­PÙírªk½EQ¡®´ËˆqF‚iU)M¨ôðt›Iv¼ÙRxàò=ßÙêùm· ×oÔd\o´Ô0™iíVúØ'Vn0’J ÆÔ“.*é$™q^Vªjªtš¿)…Ü&iÒ%Ìê2`¸Ñ$ÒJJ\VžØÈ‹,§Ž#_m±G¸¶eQMãJ¨5o¿ªE0”„•Aù*t·Œ#R $°]¶¬á&\CUE_\Ùð›(«~ Išs„Ná+S¨}ĺ•wZ#­F³2ài>lãSpÑØ¥n5z“WCºˆÕNûš“Œ’‰Ä!]%ƒ"4ŸàÇG¶¯«q«;5Y/&°ä–©ÓRÛ*R• 0§FL‚?zkBf%rFdÒ´Ê¡x9BbÓ¡Ñ©Õ*]VlI3~l( cS.;¦ÜZÛBÜRT—¶Õ¤–DJÇ”Ý÷aYt:uyu²jráÍb™‘Ü4ºÛۈ­fâM¼“X#$¯Š¸‘c޲›G«ÔãÊ‘M¥ÎšÌ4o%9:ÜKÿ„³I$¸î ®ÎgÁ§\ûÊ”’‹D Дù¡K&ŽDGXJÌ’F£I)Â3Áàbç³›¦…oÑÓNzUr©u§g±.cÖÜ”BM¤°¦õ¹¨ô¾’#'0fžØŽ[hѺeIÄ4¶éòÖ—XrCf–Td¶‘«[…ÊS¡yW1i<óþÝ£ÕÚ£µYv—9ºcË6Ú˜¨ë&²ÎRKÆ“>À \h·=&6ɪ4ÇÞYWЧ"ANì̹,…2·OV0ZM…'y>P®|pØÜwunÏŽ,#£3-úLsÌ›3U31Í£5dÜä©I›jV¤§Wnde•)B1>@¨^T:uiTšœº„*¬˜ÚåCLg‰0i4%Ç “<’¹”\Wúžä•M¨Y–ÂØ©3Ëi‘§È‚¦Ü'xÊ’ù:JÓ»4aä§µgõqÄV:.'bÿŽ*×n |¤ÓZ›S~cOqÖµ´Ù²DÒZÔ•¾„™é"É+ ²xP-4Í—QÜÜ”R¥ÓɽõY|¡1N{Ô%&ÖôÔg¨±»ýE1dXªÕc=§U«Ô{åVÙV›9ț簓yIqqÝ62â4«Qi>(IãJ Ç@«ÆzŒýÅ3tÁ’õrTt¸ê““q²mKQrRœ©³ÔlöÄZ….É+·Í«Ô:Фéì0ÑH6uJqqâe2ztjY‘m¨ÈÈôãˆÑD¢«Z¡XfQ›ôù "DSoM9’'IYã…‘$Ëiây'º „÷@'º Ot@ è' @ îÜ’$„’€ è@$@‘ èbz !H@z è````D  0î‡tè.Ãþm_›þr݇üÚ¿63ü"ä9:Ø •8tPª¿¦X¾÷E «úeçý´gÑ£Ù#G#˜kdó ”Ža­“Ì=ú& †¶G1\ž‘´‘ÌcW'¤z´ 35’¹Æ¶G9”®q­‘ÎcÕ¢c™®|a¾3oJ™šF£Þ‘–èÄw¤mÂF#£ÞcNŒWyŒmÆF#¾ôÆ÷ft×%àÕ&TZ„¶ÕcåÉ2[1]y  Í Á©M¥>õ\ü #Dï½1›kV:‡Tzo'åÈ!è×§¢3¬jÎÞï5c§Ég%©pÜqeÕ62_»¨4žµê¶‹³¤nîzBÙ¨¹¼m)aÄVÖœšð£Î0¢íxÍfìRç̪S*Tx“w”‰òYã%È®1 ÷¤hZRyZ’ZTX.ÉçgµÊuµwSî 2]K©Ò•–&&>^mÄ­&µne©‘¤ˆŒóï‹f‹]¥ÑnåU)Ô™‡K\w¢®‰É[ÆÓÑÔË¥¾KI-FN,Ò{¾2JÇŸKZͨ\0“&<Ú|S~AĂԗ•ÍI%MiI–¬)TiNV’ÎLBlù)µcܪԸh–Ó¯CŒú'd!µ)*4™ Û#Ô…%KJòYÝZ;FzÚ¦J¤À+‚58ç92#pk«ˆ´š’”è}M ·ÉÒÚ9‰³É‘§QÄ·/†è¶„Ú#Pj;.+ñœ#ª+‘,œ#-âã Ä‘–•’DiIà̸¿5³-”ZSõ7_‰Éƒa8KV'Õ¥ §µâ²2s$x/r^ ðYȹ¬§mÙÍÁ©ÜTJ))1”›æ¨J<åK-×n’ÁåMo ‡ ™–vw…kFËmK_ éÞKqßK¦–kTvÜ4™‘-;Ù Ò|S½"2#É kºønµiÇ·£Á¨4ËRS$ŽmQS ƒJÜrRÚlõdÒf³3J8ðä{¦Ãê¦Pè šæSãËtòò 1*Rujq¤4d¥­8Ô¢B{b%p8¡ì±Z¸:“N«Ñ]K:,ÃuÔ±) ˆÈJ ÛÔJ7–HÂÒœp?†/ÄĹ(w%>*-R@–âg™%öÑ1RmiA)•îˆò­J파±ŒÒ›µG!^Ep.^¦I„•R´¹Oá‰ìLâê‘ÌfÉ ‰)I­X3ΨüV$£ÝY6ýiÊ\§£¾´6ÓÉv:M¸Û­¥Ä)&dGƒBÒ|H¹Æ°mnªÇW*lÍäüŸw=õg“ÆiYÁ{íÞ¬tg‰H(êAÊŒÁ¶¦½F~ì¥j' ˜‹O9žòÒ³(Õ8”(3 ®º­Â…9øÊAG†“¨­É4¬”úM&d¤i%'ßàj,Úý¹G¢Ö Õ¨UZƒµXåÇbÕ[Œ”2O2ñ%QÜíõ²]±ž4¨ËI“nÞ±)i+“DTºµyÔ™e/vÛ:–§¼oAï48µ-8R8Ÿ£¿p"…Gµ«t‰¬Äf¸Ìø4·g?=çÚä©[hÕ»6‰’J^J·†f¥'µã‚õ«ÙÐ)[1MnT™=_å± Ø„iÝ3K2֢ƭᓾ|O Ÿ«¶×vÆm³mV!)¶‰O¹²ÚZ—(’dOºƒŒjQŸ÷„I,‘šŽ+»J®W­zµ±–ûõ)±¥91ª\V÷$ºFFm´•)J7ÛêÉT’àâˆ?&¿fTh•û©TɤÖítÚ‹¨S®hCÂyÆÖ¥$­ QôpâFY!º²­ÈTý¨[TJÜ*MÇJ¯?¦žCÒÒÙyòlÝlÒ¦–KI¥Äáe‚2<¤ðCUE¾*݈¯Ü¯Ï¹V˜ ©g­K6žaÖ´“ŠÔdE¾R°_ÛÍœƒ·ŠXºíÊÅ"˜qbÛ›ŽA÷÷Ê2mõ>{Å’S¨ÔâÖg„§à‹€;`Ú¶Ëõæ¥H::—*šmÉS–´·¼pÕ»l´%G©Z|Ø"I™™ ¨ÖMCDÕUj4Ê!Dšå?ü=Õ–öK~ý¤èJ¸§)Ê•„–¤åE‘ïL¹mØkªS×mM‘@œüyH†º¡Í<ÊVI3x™Â’{×HÓ  .9-Gèõ鬉éºh‹©rš¬Š³'g&6ŸNô•Ú/SjÐßҮׂ‹!øýU-]B¯E& Æ:*äΓ!ÅézG.–Óm ¸åÅ!¤‘%$E„©C_Z³äÒ(qê3jÔ´H~32ÑOÔéH6]$šFh&ÕÁI3JVj"3É2¯gfYtëN\#vÚi&ÿ¼’rx¤#µíOnÔž:’žr=&Ÿg¯†û½j± E!¶Pç(ª)è­kJ÷Œ°h÷'iÁ«Y–¢"">Ä X €@ºÑ-*tÛ‹gtç^––®mÏ-4©:›×P~1îû^£I>:»c>ŽJ[võMfƒ&] éukwü•%·L§­ôoZݨÜÒãŠ>ÕhÉäVWî¾µhI¤P˜¨Í«RÑ!øÌËE?S¥ Ùt’hY ›VII3JVj"3É5=ŸV¡¹;R N˜äö©¯ÄŒâÈ’Ü#42u•jj"4(ŒÈÈ{={·ØùëUˆ5) ²‡9EQOEhÛZW¼eƒG¹8£N Z̰¥ðÙÜ{X«ÕçS*Šr°ª„:›53LÊò!¥öÌÌ·1̈šI™™ã*2. 4–HãñWyZð(6McéÕ9rª•—×ÚÓq4£ JpiSŽñ$ñ%äËI=‹Gb½vÓ©rÝq˜n»ª[ãSl n¬³Ã$„¨ø÷uÛrR*” m‹@v“ÉrýÖw(SŠ},$Ë:‚Nàˆ¿°ËeB4F$Kv±XSí¡ÆÚ70•©M­*K„m›‰ÒeŽß=9W°6µ«RnÔ*#¥*4)¬7.+ÝžbJ½ÁÌcJo<Ü\Nú1éVLš•RM.=r†SQ5pb0© ×9äž0Ñ£2Ò§4ŒðG’2-å'jr¡]m\nÑ¢½/©(€úÐÃn8Ñ’£¼”!”n͸æH"ǹs–xFË6œ»4vÑOžòØ©”ãTJ¢¢’ÂÙ|’…¨"AšK$DkVIDxø¬I[*JÀvàje*N'±ö“Ê \E-2 <¤™RM)FdkQiG½Êˆò®)olæÝ«E£Ä§Í\ù°d¸Ã+”¥–a©+Y8µ//8g ’ž<Å€¦WíÈöërE ªôÙ’”¹ˆª¶†Òó)} 4qÌôH=IוK O0ÁMn–9[²éï8üy®Ìƒ)¹$„¶§RÊKˆ4ð,#R0y>%ÀNûY-§.ëe3jšÍ.U~6¤Ô+VåO9ú%,‰$z’—0¶”¤ö§… -B‹Ö¬Š}RJh—->Bl’‡ŸäêuD¶Öi6œÔhWjzO)25ñ¹ÏÛ2¤¿Lp¨Ó¨5ø5¤Æz®§hãï2Äv÷d–Vð°E¨ËO_ Q®šü•2ŸI¤ÒWL ×äîÜ•¿RŸ{vN+V”á8i²$à̉ŒÚkgäÇ7Ô…)&”ÌuVxž…;‚àZ•ž}<ú¡&«ö­š”X$n.Tvªé75jM­L™6„ŸVfFdjæ2ϬÞPÚ³Wí"¥U*³±eML‚SûóxÉ*KhÒŒàˆŒŒËÛxNò {6œ©«œTZ” Â"?‚\Ry;ã|ô¤Ð—B°KÂQ'Š‹#ÈÓÕá:«.ž© H8¯­“yƒ3mÃJŒµ$̈Í'Œ–H¸t öÍëÔÚ ^温m7œÝ,ÛuA·¤•) `Ñ„ Ü4<Ú\É# JH”y25sq)»ƒ°X{)¤\1¬iÏT'7­¬«jB‘˜º¥»6ï)á¼SzxêâF|Ü ‹>˨÷°¹Ôå­¸ÌË‘,äÇŽñ¤šudiÑ¥ZÑÀ”fZÓ’,ŒÊù.•P´e‡ù5½¸7ã"Q¥·Sž–DE„àÞ4–IXÆzpQR½#Ë·†Š2šªÌ§Å¦Lœrµ6ähæÙ¶IkIi_¸2F­FG£LGâ¹">Ï+O\ShI•O)0î(öóŠ7 ä¼·•‘éÎì…äñž)íOŽ1§Yå TÇd\´2§Ï[ìòôî2ì¥&ãk$´k5¶ø¡*Ië##ÆL¬ÊÚ…=5¤Ö"ÚËjc×4+Šz•QÔO<Á¼¥6‚Ý–í 7”eFžec·Qc Hƒ2Îd½>\)5$0å6°ý:¨igYFCM8á¼]±j#KðíGÏdž’ͧC{ªг;êe.9¸ãf£I>ò»VYÉl®'ƒ#Ð…™sî‘xÕi1.°Z†Ó5öM©(&pM¨Ï- Z:KJÔC Mc]¯ƒ6á¦ä.L—5ää:e¥e‚Á!¸ñRÏ=¶ w‚å|ÚÔg!?Q¦TÌê}»GŸ*žˆ$†´;#jY8Jâá¸òV¢ÑÇYž£<ö¬Yôj=¡X¦U©5x×-:9ç y÷SIÔ¡I5­Æõ$³„‘¨Ú÷§„æ£*í¨Éê–¶bTi)/a*íYÉ´)=·Ÿ%o&y.*ÁK‰[L­<–œj›H‹15Xµ‡¦4Ê÷²e°N\sRÍ'âDI"3âDYVkiXÝÕg·e9F«TéõYÔÙÊ} ‰S‚å1å­¤£9N¥·—[2RTF¢%jeÃÿ§Ó£R(s›£3B©ÎC®¿NeçV„1ÚnêRÐkË©¨òIJ‹¢ç´Gù}òµ­¾MI™&k0”Ëëe×_CiQ¹©ÓZðm!E•p>S„––𸛹&òåP©ôéKZÜôgå:¹ V8¬ßyÎ%ƒæÇ9ç<1*ýàѸB{¢OtÙ3gôG§MaúÑ-Ú|˜§á).Tb¹-–ïn£mDh{y–Ò’F4«9LZ%^o.'%…@¡SZqæÞ˜˜ÑÖe0ЭIK„µ¨‰âhF”Ÿ ’o€/ɵ¨p’u»¾Ì‹jC‹1ÈhbSÓV̳r$¥ÇqÂJÔñ¤že²5µ„¨”x.ÔÆº‹G£=´«U¹Ý­P·«Ó¦¤é²ªƒQ¾Ù:²7]KÈy)q%…v¸ROIç"§&òZù,xöí %2;ªyTæÚuL>â’h58kqN’LȰ²Ó“4é3È̦m ú}n•PlPÅÓ‘N‰$à m¬ßÉ=¼ZýÉÛ­IÁcb¸dI‹³v)sæÕ)•*¨ó ÕšÜRÉn©I3Q‘öŠI¡&’#,ž]3iS Ìšÿ[tÑ" 2ÊŠKe :ue¶VÛÉZIzQš”jÉäø«<í"M‡Sè _R-ª5¡¼ãŽ£Zž©=»Š[¤èBÛRS¥·7¥½Y©:RFeÀÌ÷ìÛQ†¢3K*=qúÔ‰GKn£6K/¾Â$ºÃI`™"B]VèÏSǤÍI"IàÅN™±O¦T©‘ì{d¡ÔœJßoy9'¥)ID´É%›z‹^•(ËQç¡$œz]÷*šl¹ƒE'á:·)O­)tÝK5’Z3s $©F¤ïIÃ#3<äÂÒò¯N¶ªv¶îÒ‡kH–Å&<‰Xv¢š’Û\µéuEXY;Á®Ó&EÃ%¾©lö†ºùÙôƨϿ§Ÿ>k¤*s¹ °§–…G6ÍKÁ%R h%HóÏcÝÎE¤.$ Ç"7jL´áH[JF…– fÙ“”©IA(ÈÏ'ÄÆL U–Ó®ELR’¶œ™SŒÛ…&R›q.$שf‚=â³Ð”êRHÏ!†]Àȹ¡Ðªc×"ˆÅâTZŠM³1oï™y/šá-j4:“Œ¼ãI-&I"Á X®k²En AE&•JŒ©'-öà6´“ï™cx­kV0F¬%:RZYÑxÜ‚õ³ ,2µ1ÚM:§6Ç&ªOT(d…šÉjS¤ãe¼É ’“ZrF³ÁéÀµË³i1$N*5–«‰æê blUJ|“Lk“°³ZT…$÷jqÇÉ/9©ZIžudù½µq¹F‡2ÔªuZŸ5m¸ôIÉsA¸Þ²BÉM­ JˆœYpV ”y#"¿$.¤íNU»oK›­µEuèΓm¡¶Ð„’É*BRÚ’á,¸iæ;‚ÅI ÛìÞµK6e¸Ô˜T©²YªW\˜ò]ŒÃn©ä’TM' $á*Jõ«^øˆ²úÑ¢u¡Ê:…“u½Õ¨uI}Så;_Ñ5þ‡{ÚêÝcwÛ눛Ap­²¡ÔmjUµJ\¹Érb”ò”g­ÓfB fY2NKgLÌüüœtí×Q¨åPêS:©ºs”òmÖçG¿Ýþ‹ÜõhÕ§§¤-"K•Vض.«‘š}’Å®š:ëL°©4çj<µˆ¯>L¶§Q-Z ²ãz´ž¤²Dx= öíWíÞºµ I¸Ç ª“Š)M<܃lÝ3R”‡¨Æj$èÔ• $d¡©]ó1¨ëEG¡HyÆÜ‘*žÓ‰qãmiqzÖ¤ ‰hB´¶”–R\8Êoh’©Â–ݯm%ˆó9Ø\Ó.A¤ÒN:“s=®£4¥&”™ö¸3#Yƒ~åÝM%7BÚb¸´·ª/ÐÚ”þéÆÍøÌÆqZ–n –§Ö£N¼š[I‘‘,ŒTö‰KƒM*e>+Pš©Àå*ŠÌûL¸‡ÞadÛ†¥j`Ô“Ô® .'Î2e_®=[vªÝµEeÙhuºŠ Ù& ‡ ŒÉÓyõ«¤”FƒI‘ñÏÆŠå­È®ÍjCÑãDi†4XÉ4´ÃIÎFjç5šŒÌÍFfg‘1LƒTà‘D2é2˜…PjTšlJ›HΨ²”ê[s$dY6–…ð3Ï,ä²GÐ)Ô{~/².M¦ý$ú+×2©(Œûï–ᓘM’¦ÜJiG5‹ŽLŒÇ?¤ÊbA©Ri±*m#:¢ÊS©mÌ‘‘dÚZÀÏ<\H³’ɯ² û#uõÖ¥¿Õ.QË7Z¥îy^û{Ê1¿Õ¯W :·xýN‘Y& ®Ìmš ÇhÔ™v Ÿ­Ým‡¿I’¢äédÓîF£w^´¹•1»#P ×)ÏR*òi’ ÍèË6ÜËN6z‹œ´¸”¨¿÷ˆûÆŸr®™uz—H§BI!mòË¡mN'+qNaIR²zòF®X,b\õ©WiÚ¬¶ØiÇÛim’2Chm´¶„'Q™à„–LÌÏ33â ;ƒ:ͧC{ªг;êe.9¸ãf£I>ò»VYÉl®'ƒ#Ð…™s ðÛI¬kµâPcÆÜ4Ûë“%Íy9™iA™`°HG.É9Ã['˜l¤s lžaïÑ0T5²9Œjäô¤Žc¹=#Õ a™¬•Î5²9Ìl¥slŽs­Ísã ñ˜øÃ|zTÌÒ0ÝŽôŒ·F#½#l1®óÊtb»Ìcl21÷¦<•-Ä¡ 5)FDDE“3îw}ék~¨ýµ­¦‘{ÆIäš’•‘v«ÁdÒxQtd‹$e’=qàqeÙú ¹S)3ÙqqíZYɪ*܉rÖûM-²uIQP·Œ™(ˆšZˆ»c:Í¥D®\õŒ§žêd ]; 9T‰Ou{êsF•)Ù甡¥ ‹*3,`²eÊh•Ê¢º…>BRûˆSnïšCÈu*÷ÉZ%%d}Å–H lÎú¹×Z•Wz{2%Ke¦dˆL:Ó©i CzšZ ³4¥ ÁéÉc9É™ˆqd‡GžýOGeÅ¢UŸf¡&+ˆ6Ý„†]q´x2ʹ;¤Jʈõ·‚î×ìÈÑ£C©\Õí?œÙ5—JCòÝ%I4ŸH–á‘ð=Þß ·5v*+ b¢â ¶Ù·QíR{ôšÉgœ—س’Áó—1™ yui2(phÚj,7t‰²27s–³3âzR„–0DI.33›0t+ö•B©B›)®¨¢³Jµ¨s\ZAÇq Ù#N¢Qo­Z±ÀËO1že^Ü¢A¶kv-5—¥G¼)”Ù«Â9%¹È5°‚$c*5‘!J<á=·Ýûвÿ,ÞÌÕË`1N‘îH-qØÜî‘ÍÃO'g‰`ÏO<žvRïû¶TXÑ«a1¥15µ·¦Ü9 ¥ImÕ8”’–²%jQ™Ÿ çŠáv$Ý^vô+9ª%Á#"Kò£ªÚ„j’ã)k¶R£áïé=Ú‹)4öÚˆË>{Oíû~¦ÃÔIòd¹)·êx\’+š7ZZÝhlÉÄk33ݧ$â9ñ‘§~]€ëÓc':ó±[fvšmO%)wÜЂA’É É±ç_q\Ujÿ'MEæ7Q‰Dâµ–µ-´” ŒðY2,ž <ÂR{®A©p„÷Džè¦í³*nË',÷›¨Ò*ôé2jÒéZÐâÜnNñ´©ÄW (È2<¡K>9%$qa–ÕFcT‰”=ˆR_jKÍé.ÙÆ’âP¬ã%‚yÂÁWà±Y&ÁÖér™žý«I¯Q­ç'KnM^CQ¢ELV ;œœÝ&Pm§IÈZLÏR43Àÿ¹;bN‰T©õ |Š„YQ¬Q­¨ÏÆC¨~"É'BYFñ-ïHÖhIâB1«c—Í\+”®4ÏRj„e‡’„‘iѧI:;]8Ó§†1Àg¹~ÜÎKjB¤ÀÒËKi“KŒQI+4©DqɽÑäÒ“34äÍ)î®IzM¢S£U/JÅBœûR‘éµo0i$:rP¥¡’q*ˆ¤™(Íæ3#a`Ät‰½N¨53’D–mäÉ©Mï322#4ó óƒá’,‘–Hñ]"£2“Pj|I© gJ Y`ÈÒdiQ(ŒŒÈÈÈÈÈÌt éuýLµmÏ¡Óí›’±Q\¨¥&ŸFIEqi6M ¦2›BMä&¦ˆ/'™j,Z­JŸí‹9ÙÐ箫T¦&Ld¤ÝR‰¦Ûˆ"4›HQ¡³-i3I’LÌô16‘wD¨&li°R#; ¦•£¡§ ÂK½Ù´‘’reÀÏ:/šò%¹!¢#x„!ÆQB„–¤ÔiQ²MnÍe­X^XÕF\ÆUNlªl:sïê‰ _'l’DH5«+>“32.'“ÁsX«[FºëÓŸ¥¤›F‰lÑa³%³lÒmèy¶’âtéI•Ç7./¸-¤±OvÌzc­Š«ÌVèTↈ­nžéÒÐá¬ÒF•axÝ/·<Ž^7×Ý^¯ÄLJŒ˜Ü.ïͨЙŒ—Æ7‹&kÁ™jVO‰ñâcB&*È‚ã²Ç’ºV˜ô:|˜Ò¨µ'WÊ`²òж`Hqµ6µ¤ÔÑ’È(4çœà†ÆÄ¸-Ø–³4‰/ƧUUPyÕË‘kCª6ãKC)m*[Æn6HR3$%_¤Î ÅbÔºjöò¤=.HlÚqRi±åƒJ¤¤ÞB´’’µ%Dœj#Á䇽.ô¯Óú¡9Oo}%R°ª\e“.«S$¦Ì™>ú=8Ác˜„8¶ Ô6`8ÌMš°ô }̤R%öÌ9-Ê–r^"2š¬¾ƒ4©¶ÉDžÔÐFF\ãÞ›bM¦ìr¹%ûF\És¨UÑTU=kDVÊ\m ´îœ…<놓÷†DxÒ¡@…|\Ðáª3ÚÉï1!q\¤o ÍzR ÔdÔ£=*.*>èÓA¨Ì…|h¯nÚ¨G(Ò“¤xÙ:‡I92áÛ´ƒÉ`øc˜ÌŽ0²N†ÜyuûT£Ô(48Rë1Ø qä8êžJT½dDµ³§Z5:¥ejN ô«]§PUgZ¶Ô–¬³aÚ¤ø+™R¥-¾¨â2óšÈI7BšJ¸iF0xY -Í~Üw#µY:<ƒuBžEO’Q$N¡¢ZH‰$\\8spºmÅX§1 ˆ’É Aüˆè6¢JÞBw$¢=D¤6„šU’Á'–¶Í2ÙzšÅÍT‘oÏ8P&H\ú]+w ×üF›hâég[­”…/ B­m’ŒÈ”cm-”•F›PaÈOD¨À)1žMDq뙸ÃfhBÉm­'§’Høç'âíós9>4ÎY³ŒÚÚj;0n1!~ý&ÂPM+œ¤ó‚ÎpCW_­T«³ŠmMôºê[KHKm!¦ÛBy„ ‰(Iqà’"â}Ñ1‹Lƒ\à‘D,û/§Sjw¤V+¾BÓ¥¼NjТb;U§¶4™¶Dd\pgŽ#¡S£RêDwK·Ü€˜|»y˜A}§"‘œˆÍkC©ÒúPƒ"qF§Ë$zp\~™>e2 ÅBë)…ëmÄó¤ÿí/ì>7Ê¿nž^Ô´ÍŒÞé•ÇLv©ñÑÛY‘­'(&”J2IžRy4‘Ÿ1 J-°uÒ¦ÚÕ*[4žA@]J¥Luî©E†ÃQ§¬ÒâPë)V—b¥ƒiF£KhJ”…ï7iâ8uÓIr‡^“Kpž#dÓƒu(#ZT’RUÚ)i2QT¢2223ÈËzï¸]¸#×U963[–4Fi-6Ñ’’m“$’ld¥£N“Ô¬‘äÆº·TZ©»R©?¾’î’R‰ A%$”¥)IR’IHˆˆˆˆ‹‹L›.4hÐêW5B;OƧ6MGeäü·IDÒM'ÁD’%¸d|wƒ÷ÂÕVÙiS©Sn×_w­^D¹PœÞ—(Q­¦Ž:WÚéâãéIà²{—¸' Ui2(p¨Új,7t‰²27s–³3âzR„–0DI.33Ê•v\R­ÆíÙGœ¥4–ˆæIÁjuh,ã'…>éóô—üâZw†þ´è”j}W©NÔNU®ŠDõIq nKŠCǽh’’4$•ÂÒf®“Ï@´Ó(?k«JÜUY3¡³[§òšœ¦I‡P% Ìð”îô¨“Û™eG£Ú¿vWëÐX…Uœ—ÙeD²$°Ûjqd’I-Å!$n¯IcRÍGŽ‘àåÅYráŸp.fjUUÊžÝ#Ý9J‡»\i-IqeÀ‹áŒŒ.À÷½é”ú-Âý¥¸¨>á%ÙIÞ¾“2ZŒ¥àD¬™‘dñ%£u*ŒÊ“Œ¹5í󌲆³I´ °’3"ʰX"3Éàˆ¹ˆˆb H $@$úР»ø!µ~lgøEÈSvðCjüØÏð‹äXë`.TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$úžè‚Ý@žè=Ñ@' @ž'¸ Op@H@’H:ƒ ‘D' A‰è`$„ ! è' @€ $@$úР»ø!µ~lgøEÈSvðCjüØÏð‹äXë`.TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$úžè‚Ý@žè=Ñ@' @ž'¸ Op@H@’H:ƒ ‘D' A‰è`$„ ! è' @€ $@$úР»ø!µ~lgøEÈSvðCjüØÏð‹äXë`.TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$úžè‚Ý@žè=Ñ@' @ž'¸ Op@H@’H:ƒ ‘D' A‰è`$„ ! è' @€ $@$úР»ø!µ~lgøEÈSvðCjüØÏð‹äXë`.TàÑBªþ™bûÝ*¯é–?Ÿô^ÑŸFdŽa­“Ì6R9†¶O0÷è˜*ÙÆ5rzFÒG1\ž‘êÐ0ÌÖJçÙæ6R¹Æ¶G9V‰Žf¹ñ†øÌ|a¾=*finŒGzF[£Þ‘¶ ŽŒWyŒe:1]æ1¶ŽûÓý#!ßzc¤k‹ Iˆ “è$úžè‚Ý@¦Îr›$ëàÓi iˆ²4R%Sy$øzQë'‰n)¬jQ)yQ%]©tt§O÷””°œÏº tZÕ"Ý©]Q!SèÕ(¬·K‡*ZÓ>9 ›T6”Ff¶ÛCfkZ N)FFj5iÉ’G±P-Ê,Z˳©ò'0ý©ÑÐÍR;ªþ†I} ­ VSïÒE„šÒe•e=6ww¿rýŠëV㚺µoÐ$»L³Si©ÖìÊŠR©hYµ!ŽSŒ™4Z›>OïpFZý÷>* »@ªp6[éŽËŽÈjK+m·i%¶ã8'$™šIfj%µp¦¦V¹mb½Šˆ õ6-ËJEZK3\‘«‡Ü„¥.°ëo(ÒDh3JÈÙନ»o{ÃŽö}¿kR—ròôV^M¾Tæ÷2›IºÊ·äYËg…–àÌϘóŒ'œ#Iµ¾ÿ@æ–âˆåS·¨–ûóδu¬³X•Le1C*÷ :œQ©*#Îñ8Ig¶âXz©J¶e¾ûˆy%Ä;o%£A'&DFƒÔj2ÔŸ{Ìb©eĉ:¥2<´:fT¹¯2¤0—Œã„j%!Z‹2á¤ÈÌ”J#!“VWâN>&Œá›zÛ‘J§EUn¡:…&¢JT†ÔÒŽr57df•”sÁd9.+{1¦ ªõc3)Êu<ä0ËÈÖ…8n´ÞT“à¢I8¥`øv¼rY SM}ùŒhÐw %Ìmη)ÅD‹d‡äÇx£0–Pâ[&”—4$‰$g½R{R"=Ü‹¨Ð+¶ý¸ÅEê‹•4[2ÞŒöø´"3Ó”(ŒJ#Kf‚Á§IyËJ¥vÒl9Ù\ç„ ] [´%Ô©vì…TŽ­Sf:Û”‡PQÚ[èJÛI¶i5(ˆ–’Rµ–8ð-«“ûÎZýùãŽæ¡@¶j÷˜…O•OD:$)Ï“•Hí!ä®É9Ã['˜l¤s lžaïÑ0T5²9Œjäô¤Žc¹=#Õ a™¬•Î5²9Ìl¥slŽs­Ísã ñ˜øÃ|zTÌÒ0ÝŽôŒ·F#½#l1®óÊtb»Ìcl21÷¦1úFC¾ôÆ?H× @“,A'Ð Iô!=Ñ'º€‚uåqNaöåMikÙ¶ü‚ˆÊd:“,Vñ œQp<¨óÒ+âÛhG¢=HQ¹‘2¬©*I±T˜äfÉ)ÒhRT„ê5k#Ô¾Nòc¥-2qÑ!Mo#ºµ$•¾I) Z ÉX3$¡YÖ¬a½b©‹i5׫¢3M0ü·G[l¥·„4âÔ’uĚ˵íHðfJ2,ŽÎ5—ó)ŠŸ/‘¯‹|\ÑRg´êO©øl¼¥Ú·©3Z Í 5¨ÍÚ™žqž#]ÍZ•H*[ò¨Û¤2fQÛ'Ú1¡ p“­IN”á&fE¤»„,7µn³Y»Û¢Ôg èŽ­eØI&É%),îùJ=;ÄáFœ¨ˆóƒË4Wªs™f©>Dhñ¡Éo“ÓIÉN"C$é(Ù'x%dJ2R±’àyᯆÿ?¾AJŸ|¾ù•ª=n§HjKPB’IÞ¥l¡Â3Nt¨‰dzTY<(°e“ÁŒùWzW-å.SåÓ›'U.1ï^G½QûŸ÷ä¹ZòG­Yñ·è±*—¬Kyu%!‰SJsŽkÉ©Z½ 4“3Nsƒ"3àfXšeŸH¨•/“\nŸU%ªŸ01™IÝäÝ85î­öüý·¼àb°UZ´^ïß2ÒpOzùüî©L¨.LW˜é>ù. AºEá Ñ¥+î©$Ffffy0‰yÜ1JêTU. ÅÍa×`0ã„úýó†µ Ô¥ÊŒø¥ú‰ÆÚÚÙÕJ·D‡=–êŠ]C_$äôŽ´¨ÑîÏ‘7•$Ë™X.'‚<#²£•2™%ÊÊÙ\þO¡×a(¡åÓIJA(ËZ Fk%%8Ңɞ3l5í{¼ÊÞŸ_ô¸`©•Å“µ0ù¿]OŽgF½fM™£ÜÓ¨Ìô' â|8„Kν‘rg)ÍrŽM¦—·O/ß(½Ïû°\Å¡"Мl%YM7qB¤5.­¼|œ7[vŒéHA!9%%´‰Ä¯™&Jç÷ÚKˆŠŽºuYMT%M…ä˜Ü”5½Ü‘® 70DZ°ddyÀa®»Þï2oO—È͵ïXt†"M[ó¹|i+•ÉQ1°§ f¢&Üà¸è>Ô”„$Èð|Äx*Í*æ­Rá”XR›Bj6Ô¨í­ÆM\æÚÔ“Sfú†BÃÃb õ=4Šœú‚$Ó©®óNÎu Ý#CM´Êm´äÏ B’’É™ð"âceó¯Eä[—)ÅÈ¡¹ T¸ÊÒÊýúO-ž¬åY5dÏZøöêÎÎ5ŽÜ·©°#NÕI²d â;O"42ƽn—¥(ô Š-Õ]OLf6M¡³i·;jy´r„:iÞ%:[“^³Þ6HÐáš°fj#<‘qàC:±iÂ…¢¸µµJ‘ $yæÑÄЕFxÚ$+V£Âýݳ4`ȳïfq(µ Ú—O®Æ~LYRšŽ–Z^‚Z–êÛ(¸’H”£áÄ̈¸g%U‘’…í2[‹X­sMV©ÍªHKÓ]JÍ ÐÚPÚ[CiÉž”¡$IIdÌðDE“1¶‹y×¢ò-Ë”âäP× T¸ÊÒÊýúO-ž¬åY5dÏZøöêÏ…µ&ŽÄy)™CUb¤ë7 •­Ä²Dzµš‰µ%jVtHUž‚=Á¢‹ç“F§[Q*ò%ÈŒÔTJ”ñ¢;ŠFh¥ ×îª$’ŒÏ‚:udL¿™K¼JÜ5Ñ/:ô^E¹rœ\Š˜ÕKŒ­,¯ß¤òÙêÎU“VLõ¯n¬Ä[ν‘n\§"†ä&5Rã+K+÷é<¶z³•dÕ“=kãÛ«8·‘ÒŽèžš$vا¡Óm„¶µ©&I-&¢5©JÂŒX3×'œgˆþ›¼®&ã13›Ü°” qZ2q)A¡)w)÷R$™¤‰zˆ‹»4:•v|T +ÌFf3Ž- ©n“ªÔ³A¥FDL¨°F\T\x`üîØp˜U6}=ƒ¥¥}f²eDë)$gÄËSFeœž ¸Ÿ8­ê(ßßmÚÇ¢/+…/ºï*Ž´º” Ù\&ÂI´ihÐhNjÆ”–5+ºcI.Còå½.S«y÷œSޏ³Ê–¥LÌû¦f7õè”TY4*…23è’ì©Qæ<òòn© Æ_—¥&êȺL¸Ÿ> ¶+QÊö“¹hÛŠD$ s,O@= H"&Ð0î€ }ØÁ «óc?Â.B›°ÿ‚WæÆ„\‡"Ç[r§îŠWôËÞè¡UL±üÿ¢öŒú4{$häs lža²‘Ì5²y‡¿DÁPÖÈæ1«“Ò6’9ŒjäôV†f²W8ÖÈç1²•Î5²9Ìz´Ls5ÏŒ7Æcã ñéS3HÃtb;Ò2ÝŽô°8HÄtb»Ìc)ÑŠï1°8ÈÄwÞ˜ÇéûÓý#\xX1L@±Ÿ@'Ð „÷DžèÊMƨt~¤J¤S*“!R[D´¸FÛŠJR£J›Zƒ$'$feÀ¸  FN<i>%™«ÊqIšìªm*j%-…“Q´Ê˜B›dÒ’Q’P£N•jI—9õ›{È˜Š¡È¡ÑÕ"«Ù›$’ñ8éëC„çé4¥D´%XIOReÀU{¢µÓµ®Wy¹7¼™3äËz‡EW-C©žÞéÂ)ŠqhqJqD½yÖÚTD•%$dx"Éæ¼Ü~ S¤[Ô7œÜGk‹n§Â46´©.zpFI2AéNS’Ȫ€tßxÕÄÜÓ®)‘/î§#Å™9n‡’¢lÞÔj%!I> 툈ñÀ³’É 6óU?©\–Ý£'©u'*1²rO¯O÷n)N†°\þ䜙åzª !U’àÉpL°1s›lK¡Qä&¾G¿mÇ9"V£V„¯ I)FdNø™÷Lqîé1©¥5"ŽÑ©,¡÷J9™ÉKJJ—j6ÏŠ“ÐF®93Éæ¸:/P¶uGº\´n¹wiqŸ8³êñœmQ⾞ÕeÉ·f·…dDá‘d“Ð8VÓmÙð[ì¸ÿžíýÈ•M3J›âbˆÌÑéMS‰—Z\“Û§ Å6¥äÍÃYdÚlûUžÄó™Hº#Ï“4æh´ˆ± ; Ti1!µ=½&^Òµ-)%)J% µd‹9ç,ëbÕ¦\Ô;LB§Ô*·êSò×!ô¢Ja­”¨É.“k5HSd¤·¤²“Q CKC±ªZd9i©Ò¢É¨ëê\ 8R'éQ¤÷zPh,­*AkR5)&E“µ ®äímÛü›]Ýß…¿woŠî2.;¢:*0Z¦3T8´Î§¾Ñ2â#HI¾·$J2sI)iÂŒÉFh%sŠÍfzj2’ò B€ÚHC14¡$Yç5©GÇFgý¸"¢ÙÌÕСÕ#Ü4 ›Gv¯|Ÿq–MÒ}$Jh’Kopær¢%i=±çµ Jj͈Í.èVßA…!l4‰ê è<¥åÆFíJYšŒÔI4’ˆ”JÄÈÓ«SVž÷~çºÛ¿N^û÷’©aW5•¦L«‚=iŠt.±¸»– Å4ãHotIQ8µå¼ ø–H»¦fbºÔ„ª-)²¦^ˆÛNr£#2qJY¸|R“.Ü´™§E®Æ±¢“s¯½D’óöÔú‹4×$>™‘‰0Ý~<’Ñ¥³34 ô)J3BÌÍÁ•j›g?Q·Î§·Er_&~Zii¥K6YÔn,ÈhN…«J–•KQ$ÈÈδ©¹I_…·Ûvûúo|«q⛜Éç’t*9ÓÝBªy6âYÊ5i^¤¬œ5–µöƳ<(ÈøpÌ«•OÑj4³£RšDéMI7mÆÔÉ´“J‚%èÁ%nl“3Öffgƒ+%á³úE2ã§R©w½â—$—U%r& ÈMÈ[Š[Œ!;µ”hJu8d¤$Ó¯$*—Eú ˜È\ÈsãLŽRbLˆk6¤5­HÔiJË BÒd¤‘‘¤ø QÓáYG â®®­¹û׿çb4Œ‰×e^m}ŠÜ…²©-0LiÝö‹FƒJÉEÓ¯RÍ]ÓZ†Gô‹¥LÉ%E¡Q£D6VÃÐÛiÃnBi3%©K7ŠReÛ–“IcG”+uÙ”ŽZÅN˜·÷.È($êŽA¶Þ£ZŒ‰:S‚J•¥J%K$FX“lÕÄEAÅÜu· 3Ih)_C¸Ð–ÌÚ,¨ò’±ï¹ûUéÚµ¯yOÁÀÀ¸ëë­Ç§0ºe>i쩆y*\,¶n)d•jZˆôšÕƒç=G¨Ô|FÆ樮Ûï·nÑŽEG%uG'+Òµ¸ZË}ƒ÷G Î\p^÷µÛ®·FUIš2Zše·äFŽê–ìvÖiJT¾×G¾ZHÈ”f“Q‘ ³Ô0#ÜÐÞj4ÇbÒ!O‰1·]=&ã‘x§$ŽÕH}ªÐfžGÀÌåk/‹ïïq­÷÷¼ÓS+ª‚ìÔ2ð&¬–ä‰Ãd&f&K'Ó¨È^pfFg“Š»ä-Š“Ri‹jlÀm]Jb2— Â&‰.á%fkÔfeÇ$j#Æ~Ýuº2ªLÔé’ÔÓ-¿"4wT·c¶³JR¥öº=òÒFD£4šˆŒˆn®Ë]…ÊTºC”Ⱥ©qjKmçTêP¨­¸ê’kÔX#5«I¬Õ¤³ŒUÝ÷{†ásmæ©]QÍ»Fk—ÓX§/AÉ÷6™Ñ»4åãí‹tÏÉì¸q^­U«Z;~·®Ý:çã-.°™Fæ–ÜJ’¤¬‰µ¤ÌÈ˘ÌˉäŒo+Öìi5·ß†ª}˜Ü|‡Tó)–œ‘·4'ôŽšfEÇGÇ+5hÒê“ ÜoJBµ%iQ’¤ŸJM&FGÜ2=dewÜLpµdmé;4º„Ùq­ª6%6M¥¥.N#§VíDñ,]&j3âdX#2åpºÕ}U˜4Út7–™Ž…“LûŽëZr£V¼vÚ”ff®Øò4 9ë%À¶fĨrz\è<ŠܯwîÖt(ÏÜÕž×<ÇÝ!µ—vÌ‘ôœ {s¤³¸“PBÊFŒ*ÐFdX5%$£ã“<žkÂ)É+ â™`+¡Þ¨Î’ª= âNJ úrYR#‚-&’B‰I2ÁžR¢>Ù]d<ê7#ó£Ìaêu0ûl´É¥ƒÌ6Û32K&g”‘äõäÕ“ÉçˆÒt1:És½™q7"×A*)”GZnJ#|N(›'ÅÓFTM Œ´à¸é$‰Iˉ)%À’$„ ’O@= H"&Ð0î€ }ØÁ «óc?Â.B›°ÿ‚WæÆ„\‡"Ç[r§îŠWôËÞè¡UL±üÿ¢öŒú4{$häs lža²‘Ì5²y‡¿DÁPÖÈæ1«“Ò6’9ŒjäôV†f²W8ÖÈç1²•Î6Võ‹u\ð\ŸC¥ò¸íºl©|¡¤adDfXRˆù”_HõôhJnÑW1Ti+²”øÃ|t—v;´es[¿ýlH1ØÆÒ•ÍmÿõÑý õiЪ¿+ÈË)Ç™ÌÝŽôŽœæÄöœ|ÖÏÿ]Ò w6µÎ-þ¾7¤!N|™ÂR3—:1]æ1ÔÜØ^ÕšÖýáÒ w6µsÎ-_Þ} ÕÉw¤ÑÊ]÷¦1úGV^Àö´eÂÓýãÒkþ×3ýRýãÒQàrg/1¨Ÿ±ÿkž ~ñ‹éD{_ö¹à—ï¾”Xƒ˜@ÔOØÿµÏ¿xÅô¢=¯û\ðK÷Œ_Jåà:‡µÿkž ~ñ‹éCÚÿµÏ¿xÅô ^¨{_ö¹à—ï¾”=¯û\ðK÷Œ_Jåà:‡µÿkž ~ñ‹éCÚÿµÏ¿xÅô ^¨{_ö¹à—ï¾”=¯û\ðK÷Œ_Jåà:‡µÿkž ~ñ‹éCÚÿµÏ¿xÅô ^B{£§û_ö¹à—ï¾”=¯û\ðK÷Œ_Jåà:‡µÿkž ~ñ‹éCÚÿµÏ¿xÅô ^¨{_ö¹à—ï¾”=¯û\ðK÷Œ_JæÑ¨{_ö¹à—ï¾”=¯û\ðK÷Œ_Jåà:‡µÿkž ~ñ‹éCÚÿµÏ¿xÅô ^¨{_ö¹à—ï¾”=¯û\ðK÷Œ_Jæ°YnDÖ#½)˜ºâP¹Í ž j$%J2.sÒ“<3à; ®ØR¦¹_©\v|Û‘Â59!×*j„ëÆX7œŒtã5,϶2Þ \éÁékþ×<ýãÒ‡µÿkž ~ñ‹éFM'DZCMÉ«rÝûR±¿³fØtVz»hRå[•×kJqj-"JÖMaƒ¥¨ÐDq£žu(̉Âá­&…»vÒh”F(ðö¢Ëéêy4Èñ+µ¨­N8· 2RÕ=;å–¬­ÑŸ7""¨{_ö¹à—ï¾”=¯û\ðK÷Œ_J1Tö-*—Å9;ïâ¹·ËÍæYTh²ÒgìæP7÷E!î¥[Óh®è©T¿å[ýn–i'£ªFz¹ÚÉž…o4W|k*¿L…¦òµ#V4‰êr¬´-¸Ñ“ CE‰’„F³3Ii4‘™?µÿkž ~ñ‹éCÚÿµÏ¿xÅô¢ðöT!=djJþõ;\ßÝ‘wV±d¡Tìò#Ô*÷-·>¦š;”Wä12¦ÂWQ*Jš½.¥£Ju©'§Þdò[ZåmA¢Æ¥I¿`*R\¤Ëƒ ¯Uæ×L¥©ŠI·Z7&+ ×îËNHÖFI. ‘+×ÚÿµÏ¿xÅô¡íÚç‚_¼búQÖ‡²iQ¬«)IµÍù[—"ÛV5ô­¢7šÄ Õ•©ë",j¹³Ä)•4n;µ9Ûj5¨Y]6œòÛ‘ aI(îè3I™Ôœ—9ˆÈñÄŒ¸ •‡wìǰ=­hÞ7;Ú M̃&RIiJJ"Qg)<T\ÇÅ&]4÷eò`5û2̺(ŠÍ-ô2Ê&!NÈtÒyRõ–¯À‹ ‡2Çë*~i°-9÷MººÔ«âä†ã•Ì“S šm Ëy¤kŽ¥{Ô'GÇ#p½’0³Êï{Gý­SÏÿņ|#çj¯ýc$h6UAÿL®u•iÿ—ë?ãÍ÷øËúl¤{ÞOÿ¹úoyõFU¢P\ ²GmuN§™”{†|÷•ÈóïTÉìjž|÷}Äôjwª Zø¼Múš=Rä“ »#FøáÒ[ilšMDäD8é8Ùš‰).Pj/t"<¯JUgf±zÊD¤½Q™H•"ærœä™ ÂzZâ•=éè–MÆP椑1ïR£Ni;lÔ—åY"5³êgkeý"6¯R¼«ìƒÉ2]ätåhm 5)X(fg‚#<íÛÒ]Ó7…aç#8M>”G¦(ÚY¥+$¨Š'jzV•`úGÌd5»Y™Y~ËÚ$G¯!±C¥2ŽóóP'!¥JuÓÐFJqN)´îô$”ƒà~ôX«qUŠ!ª·SÛvëb’ÔÒe³T6LfI’u$ÒjS¦¤¬•ÅÒàx"¨§Ò²#Y.fì:†|÷%lÿ¾3Õ΋²õÑSTm ]ÔÖÖ£R‘0%ã&d˜¥Ç}6;0©Tæ½uB©W ´TºáÂ'tÚvQc,Ò­ÙMD·JÔ¨ÍIazÚu$´+ºF0è>ѧ¥Jp‹MÆÏw)%(¼žÿ;«P•8©5¹ßäìË_P |uOïI>Ô©df8Ý©íº1R ¶·)$jydjÔóËyEÂS†EÛüã>#«ˆÒš‹Oµ8·M-$’Fµ¨Öµ`ºT¥)F}&fgÄǸ4¬Pèl&rX´èm&¡ý4‘ ²)=>é‚íÿnFE>>,j}½JˆÄ7MØÍ1K 4©¤pJ+Rr\p£.“ j+4ŠEjJeV-z-Eô4¦R츺´¶¢2RÔFzLŒò\Ç“•81ª0¦C“H€¶g:‡f!QÛZd)$‚÷BQ/)m)É‘ž’"#,6`@ÒZtˆöØ¥Cm¦¦K9KA%Bv†É(J )JI  ˆ±ÑÄÌø×/™Þíý?ÌH#—ÌïvþŸæ¾g{·ôÿ1 @Ž_3½Ûú˜rùîßÓüÄ€Y9|Î÷oéþaËæw»Oódåó;Ý¿§ù‡/™Þíý?ÌH#—ÌïvþŸæ¾g{·ôÿ1 @Ž_3½Ûú˜rùîßÓüÄ€Y9|Î÷oéþaËæw»Oódåó;Ý¿§ù‡/™Þíý?ÌH#—ÌïvþŸæ=¡I—&kͦÐN¸”¹ôäñœdy ªGùVüz?ˆ‚ÈÕZä>ÌJ´º†ádÛŽSè’¥´J4¥Zwg…$ðGÃx§¶27·?ôHüƪôþ¬NÿØ/â!_¶ÿ­þoWÿt´t5RŒªßçé{£¤Ó¡†ø»î]ù|Î÷oéþaËæw»Oó‘èËæw»Oó_3½Ûú˜ G/™Þíý?Ì9|Î÷oéþb@,¾g{·ôÿ0åó;Ý¿§ù‰²rùîßÓü×ÌïvþŸæ$ÈËæw»Oó_3½Ûú˜ G/™Þíý?Ì9|Î÷oéþb@,¾g{·ôÿ0åó;Ý¿§ù‰²rùîßÓü×ÌïvþŸæ$ÈËæw»Oó_3½Ûú˜ G/™Þíý?Ì9|Î÷oéþb@,¾g{·ôÿ0åó;Ý¿§ù‰²rùîßÓü×ÌïvþŸæ$ÈËæw»Oó_3½Ûú˜ G/™Þíý?Ì9|Î÷oéþb@,¾g{·ôÿ0åó;Ý¿§ù‰²rùîßÓü×ÌïvþŸæ$ÈËæw»Oó_3½Ûú˜ G/™Þíý?Ì9|Î÷oéþb@,«¹b*¿Ocjm¸õµK"Q¹ÒqyÏjf\KŸÆC&I½!õ:ó£6ɲN® ,äñýæIÏþÉ °t–“MÒ«ÅñEáRTä¥fE*œÕ6«2¥*•"fï{¼yKIh#$éIžÎyÆ3Ò6ž“r ¶Iyå=£%¥¬j$ÿa«*ãž*>Œ{€ã£û?FÑž*0IÙ/ÑnKô-R½JŸÎîmzî¬wœO ÿ0 P §#ÿÙxymon-4.3.30/docs/TODO0000664000076400007640000001702111535462534014634 0ustar rpmbuildrpmbuildBugfixes -------- * From: Date: Mon, 10 Jan 2005 15:06:36 -0500 Subject: {bb} Bbgen depends not working for conn tests 10.0.0.1 host1.domain.com # depends=(conn:host2.domain.com/conn) 10.0.0.2 host2.domain.com # Both hosts have red connectivity. My understanding is that since host2 can't be pinged, host1's conn test should be clear, not red. Is this right? Analysis: "depends" is not evaluated for "conn" tests, only the "router" setting is. Simple fix would be to change "conn" dependencies into router tags on the fly, or implement "depends" throughout and treat "route" as a special-case of depends. * SMTP network check violates the SMTP protocol by sending commands before the banner has appeared. Some servers recognize this as a spam-client, and refuses with a status 554, causing a red status. The correct fix would be to implement a full expect-send engine for the TCP tests (would help with other things also). * Make a common vmstat RRD layout, to allow for systems that grow more advanced. Use this to add Solaris I/O wait data. AIX also needs it. Will break compatibility with existing RRD files, unless we look at what datasets exist and drop data that cannot be stored. For AIX (bug-report Nov.10-14-16 2006 from Andy France): > There's a mix of "cpu_w" and "cpu_wait" definitions in the Xymon RRD > module, depending on what operating system the vmstat data comes from. > But all of the graph definitions in graphs.cfg use the cpu_wait > definition. Also, postponed from the 4.2 release: o vmstat columns on HP-UX 11.0 are different from 11.11i. Marco Avvissano March 10. o vmstat columns differ between various Red Hat Enterprise versions. o sar data parsing for IRIX client instead of vmstat data. * A host cannot be configured to appear on multiple pages of an alternate pageset. Configuring this will cause it to appear twice on each page. Fixing this requires a complete re-design of how alternate pagesets are built, and probably also quite a bit of work on the internal datastructures in xymongen. Things I must remember to look at --------------------------------- * IIS6Check: Log performance data in graphs. * Scott Walters suggest larger RRA's for graphs: "I think 3 RRAs is good. A month of 5m samples, 2 years of 1 hour samples, and 7 years of one day samples. This doesn't address keeping the MAXs, but is worth considering as a blanket change for all RRDs. You could then generate *real* 9AM-5PM Load avareage reports for the last year Monday - Friday." It will require re-generating all of the RRD's. * configuration file for NCV. - filter out unwanted lines - more flexible DS configuration than the env settings * Create a new xymond worker module off the stachg channel. This will dynamically receive status updates, and therefore it can have the full status of each PAGE without having to load the xymond board (should do so regularly just in case). This can be used to switch the overview pages to a CGI tool instead of generating the static pages. NB: Must be able to handle multiple page setups - or should we just have one worker per setup with different config files ? * "cpu" status determined by the non-idle time reported by vmstat, instead of the rather meaningless load average. * xymond_client process/disk alarms to different people depending on *which* process/disk is in error. * process checks that relate to a group of host (process "foo" must exist on at least X of these Y nodes: HostA, HostB, HostC. * Configuration of which graph(s) to show by default, including limiting it to e.g. one of the 7 disk graphs. Ref. mail from Charles Jones 15-feb-2005. What we really want to do is customize on a per host/test basis which graphs appear for which tests. So this means some way of customizing svcstatus.cgi to include specific graphs. * Something similar to larrd-graphs.cgi for picking out a bunch of graphs to show on one page. * Move all of the xymonnet "badFOO" etc. stuff away from xymonnet and into xymond. * On Fri, Aug 05, 2005 at 09:39:15AM +0200, Thomas Bergauer wrote: 2. the NOPROP(RED|YELLOW|..) command in the hosts.cfg file works as announced, but I am looking for a possibility to tell NOPROP a "level" of propagation. This means that an alarm should propagate to its sub-page, but not further up to the main page. * Dialog-style network tests. Currently when we connect, we immediately blast all of the SEND string to the remote end, which in many cases is a protocol violation (e.g. SMTP servers may refuse us because we send data before seeing their "220" greeting). Should do this right and also cater for multiple http exchanges to follow redirects. * Better dependencies between tests. If you have multiple http tests for one host, be able to make them depend on each other - also such that one http test depends on another on the same host. And direct alerts for one URL to one group, and for another URL to a different group (like GROUP in client handling). See http://www.xymon.com/archive/2006/06/msg00210.html * Better selection of which graphs go with what statuses. * Easy way of grouping hosts for multi-graphs. Improvements ------------ * showgraph.cgi change to make zoom work in two dimensions. Requires RRDtool 1.2.x. * More reports: Check out bb-reports on deadcat * Multi-line macros in alerts.cfg * Allow for regex's in the TCP response match code. * Merging of alerts based on some criteria, e.g. merge all purple alerts for a host into one message. * Implement "--follow" in the new HTTP tester. * https proxying (proxy CONNECT protocol) * Optionally hide the URL and content output from HTTP/content checks for "security reasons". Marco Avvisano, 20-sep-2004. * Set a "BASE" URL in the content status message, so the web page we show will link back to the original page for images etc. * Provide a way of sending http status-messages with individual test (column) names for each URL - apparently, Big Sister does this. Suggested by Darshan Purandare. Repeated by Scott Walker. * Provide a way for a "cont" check to NOT be included in the "http" column. Suggested by Kim Scarborough. * Allow for enable/disable of TCP response check per host/service. * Use the "acked" gif for subpage/page/etc. links when there are only acked tests on the page. Marco Avvisano. * Handle "summary" pages for alternate pagesets. Need to find a way of detecting what color a page has when it was NOT generated by the current pageset (allowing for summaries across pagesets). * Improve the history colorbars in cases where there are many shortlived statuses. They should not automatically be given 1 pixel each, as that will cause the history graph to be *very* wide. * Display-only tags should work on duplicate host-entries in hosts.cfg, e.g. you should be able to put a "NAME:foo" tag on a host and have it show up with different names for the same host. Various ideas that have appeared on the mailing lists ----------------------------------------------------- * A report generater capable of displaying for a certain time frame: 1) List of the top XX "host.service" state changes. This is to help us understand what is barking the most in our environment and focus efforts on fixing chronic issues rather than band aiding. 2) List of lowest XX "Availablity" for host.service. And since I am throwing things out, how about embedding a 13 week rolling availability into the status/history page? Scott Walters, "Reporting based on history", Sep 9 2004 xymon-4.3.30/docs/critview-green.jpg0000664000076400007640000013572711070452713017606 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀº"ÿÄ ÿÄe  !A1Q“•"2TUVÒÓÔ3SWa’”Ñ#Bq–¤ $%457Rbst…‘²Cr‚¡±³Áð6DEdu¢´µ'cfƒ„Âw†äÿÄÿÄ9 !1Rb‘AQ3a"2q¡±ÑðBCÁá’ñcÂÿÚ ?ìôùrÓ:BS)ä¤Q‡&>lÏ;´0¨ÿ„$ÿ¥Wý¦8†•AÛô¯uU>EZu]ž¿û©=ì³bå _²Nμrã™?´GŒgäùG­.NfèŒõMŠk•=%öä8ÚZuK#(î!§‹1x¤hqĤÒgŽ8– †Û3Îßí pºî:«uR¸ŽPN¤Ýû;Yµ…¥ ·‚H¿u´'“éR§ ©ÐÍN0‚kjÈÍÂ"u8ž%”ÿ{wwÝ÷‚®Jù[ÍTŒ†,.œ˜rR¶Pé®Bä:—Ij4›""ÈgŠ‘\¬×ŠG›W¨Ô_bîIîe«#hI©JÁ8™àDg˜ú±V[îÈiŠšr3„ÓéCù¥šR²JˆÅ<«J°> #è21¦ZV}¯¤¦Îæ*LJ=9QQRѦZˆ•šÖ¥¤×ã©Å4ŒŠI›«E¢WîX•Y-lõ—ò"# xÉŒªÈᲓc#„iGŒ¥™ï3-5ÃVbã·í·#D¨¦´Ô6"Óåq*Èã¯ÔD¢,¦œQ•~"ŒÕãΛlÏ;´1¯®]¨äʪVU¸ÐÞšáªRõ ‘® (“™8àGå$ºL‡^•W?ƒ-N´§WEFÒ\ç6rIàk‹¬Seœ•â«IñÀÏ#ÀËKr*tûV©@rµ*§û"¿%÷¤¶É8û”bmFm! ,©yÄ‘$ˆŒŒ±ÄË¿¶Ìó·ûC ¶g¿Úø„¾ûlÏ;´0ÛfyÛý¡Ž·YTEÓ,­ÖgZ”D¾ºA*³M’gQYª"%£PÞ:Ó2K…¬^ ZÏÆÃzùG^ÚùoådùQȼ…¨k&«jÔfÍ—[­Éý±Žl¹w âPå}¶g¿Úm³<íþÐÇUn+‹ÖÛ»JÞÅ‘öf ÆÞ† ±RMÍbÚÅÌs`H^ä–ååúìvû÷zÒ£º]¤³ tö,*ª¨I5`’qKBL”FK"<¤FFx™‡1í³<íþÐÃm™çoö†8º£[¬[o\´ºË.j"D¦É‹5È,*BU*CÌj‰(&Û352’B”X$ÜÅY‰;ê,\ÚBvð¨[íI»Í¸Ñ%¢S4=¯X£2R]=i4¦’DƒÊ‚K…¬,Æ’4ƒŸöÙžvÿhc^*Å^Q}øS£·&;¹–œí­$¤«`e‰DcíÚ…ÏpÞÑ&´ªTF-úUJLhŽò\û’uˆÖšW‹fL’O!ï"#J‹yKD÷Uq/nQ™FrÞ´˜vVFäô¦"T‰*Y–&…r¥-™`x’ŒÕâ¤9ßm™çoö†lÏ;´1Âußí[Š¢óõ,‰µfU"K¨rf(’ÒÐl"3‹ÎÑæ3ý¡+ ©#QæÀr½¿¡ ·S¬È«IZó©×Zi²F$E‘ m)ÁdfY³+yâ£Ý€n6Ùžvÿha¶Ìó·ûCŪߥ{ª©ò*Óªìõø¿ÝIïe›,Jý’vuã—Éý¢:3¸î)Tû §Q»Jº«š1”È»3 ¦:“N›ˆÕ¤”YV‚md£Qfp°$î ŶÌó·ûC ¶g¿Úø„¾ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûC ¶g¿Úø¾Û3Îßí 6Ùžvÿhcà>ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûC ¶g¿Úø¾Û3Îßí 6Ùžvÿhcà>ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûC ¶g¿Úø¾Û3Îßí 6Ùžvÿhcà>ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûC ¶g¿Úø¾Û3Îßí 6Ùžvÿhcà>ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûC ¶g¿Úø¾Û3Îßí 6Ùžvÿhcà>ûlÏ;´0ÛfyÛý¡€ûí³<íþÐÃm™çoö†>ï¶Ìó·ûCò«.GY6äçõŠ#4 œ3R°à_yðë4ÿû{û¡³ÿî½wþO@˜C>Ää”5¬–û:fIB3Ç$}\?Ž$:¥ý‰2_¬Yí½!׈ò)ZÌÉ&jk,z1À¿ÜC´ìšÆ5»ÙféÃîÇv8ôc÷á¼ucÃ÷?,YúܹöI9²ôc™¼pû„Ç1Ûš­NšÝR[nT"!iyd¤©ä‘‘’qï·hÍòŒéô›T§í² ÷ZŽŠY'6’Þ¨¦¥`„¡jR•• #3ÀnfèïGmÌ}´hîÌ$¥Å DÜDèÇË›íýžYŸÑøžì@ÌŽ»b;è~:èìºvE ÛJ“®Y8î]ÖD¥”¢#OØz9a‡wGÖb[m&µÉø‡bòb“ËÞ ¿Q¢Þë…îÁ.PåjW¤ávéýGÊmFœü7˜j¸ÄGmHKí<Ñ­£2À–’Y)8—If#-ÛÈËpãN^ðmú÷\/v½àÛõ-î¸^ìÖ£;R9éS¥£ŦQq8ôà¤Â#!zÙìî\åÝE•²äÛ²5´eà 5žVnÃ@åïߨÑouÂ÷aËÞ ¿Q¢Þë…îÀn«–½¯z3]‘W·RËr’¢DJjÔÉ¥HAÊÏŽ¯:¼¹q݆l7 ^{ceÙsÑö}£iÕbÞMv·[¬Ã£>³ÇÍÓ›ÆéÞ8ë—¼~£E½× ݇/x6ýF‹{®»È“kÌÚv³£HÚÙKu¦ÚõÍ$ÔiBñò’Fµ™î,Êë1¯v‹£×ilRœ¤Ú˧ÆY¸ÄUG`ÙiGÒ¤£ y¥ò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9%‰Vó!‰¶ž[HeN!m’´3-ùRk^ÐY•‡I‹j0¨J`¨­MˆfRvf̈²7‡œ’À°,º‡r÷ƒoÔh·ºá{°åïߨÑouÂ÷`/)vDNDJuµ5)¹©i†RR¢2R\À¼r23ÄqŽV¥zNnŸÔq/x6ýF‹{®»^ðmú÷\/v”9Z•é8]ºQòbm‡d:ĺkNIp}Hq 7VIJ J2ò*œO‚Hº‡r÷ƒoÔh·ºá{°åïߨÑouÂ÷`3^°¨/U•Wvü}Ê’Ô…ªZ QMãRJAšö<Ø¥II–ýÆ’2èŒöÆË²ç£ìûFӪżšín·Y‡F}g›§7Ó¼q×/x6ýF‹{®»^ðmú÷\/vÌ­CK)2¢šX’©l—ì°mõ)JS©êY©k3Qo3QŸ*|[2”©ñ¨2ÊTÂÔ!”`úhS»¿|Ðf“WI‘™c€ ò÷ƒoÔh·ºá{°åïߨÑouÂ÷`/ðcÙÐ*’j°X Å¨Kþø”ÊC¯oÇÇYoVþ³f—l2Ä]¶©ølM¤Û$ÆÁÙjË÷0B”Øxª2è1Ç\½àÛõ-î¸^ì9{Á·ê4[Ýp½Ø ìh–\Z˵¨Ñ­ö*“³[m”¾æ=9–^1ÿ3ЦÐaCf9tØÑ˜m-2ËN!m ,”¤·t4åïߨÑouÂ÷aËÞ ¿Q¢Þë…îÀr‡+R½' ·Oê+5ZdyuÙ5hzDJrCm´¦â&šdHF9S™ØëpÈKV QàkVà*¼½àÛõ-î¸^ì9{Á·ê4[Ýp½Ø ä+r${ŽŸU‘~*¤ÜY‹žãrÚ„…» ã.2W†ÚèiÃ#ÌK3ÈÞ’I’·ŒRì&9,S­¦“Pþý$0Áž?´À¼爣ò÷ƒoÔh·ºá{°åïߨÑouÂ÷`/ôö,êth±©ìÐb1 Óv3L%¤%…šTƒR·%F•©8–üeÄÆªÀ Yö…”#¨Æ§± EE¦šeéDÓiNe™žü¸àfxu˜ªò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9C•©^“…Û§õV¥zNnŸÔq/x6ýF‹{®»^ðmú÷\/v”9Z•é8]ºPåjW¤ávéýGò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9C•©^“…Û§õV¥zNnŸÔq/x6ýF‹{®»^ðmú÷\/v”9Z•é8]ºPåjW¤ávéýGò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9C•©^“…Û§õV¥zNnŸÔq/x6ýF‹{®»^ðmú÷\/v”9Z•é8]ºPåjW¤ávéýGò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9C•©^“…Û§õV¥zNnŸÔq/x6ýF‹{®»^ðmú÷\/v”9Z•é8]ºPåjW¤ávéýGò÷ƒoÔh·ºá{°åïߨÑouÂ÷`9C•©^“…Û§õV¥zNnŸÔq/x6ýF‹{®»‹N6ƒ®Ê¢©–Õ¿£ª´Ä4§–ÔZ45šNkV ø©#2,OÄȺL€^9Z•é8]ºPåjW¤ávéýF¿›; ìþÅîx>ÀÁ­ÙZ1¢ÄnUJDZXiÙ,Ålʇ f§^q-6’$¶fx­i.Œ yžFdÀßrµ+Òp»tþ¡ÊÔ¯IÂíÓúG7Ú=û<³?£ñ=Øs}£ß³Ë3ú?Ý€Ûòµ+Òp»tþ¡ÊÔ¯IÂíÓúG7Ú=û<³?£ñ=Øs}£ß³Ë3ú?Ý€Ûòµ+Òp»tþ¡ÊÔ¯IÂíÓúG7Ú=û<³?£ñ=Øs}£ß³Ë3ú?Ý€Ûòµ+Òp»tþ¡ÊÔ¯IÂíÓúG7Ú=û<³?£ñ=Øs}£ß³Ë3ú?Ý€Ûòµ+Òp»tþ¡ÊÔ¯IÂíÓú+öŽXaÇÝÑõ˜–ÛI­Gò~!àDXŸü˜¤ò÷ƒoÔh·ºá{°¡ÊÔ¯IÂíÓú‡+R½' ·Oê8¿—¼~£E½× ݇/x6ýF‹{®»Ê­Jôœ.Ý?¨rµ+Òp»tþ£‹ù{Á·ê4[Ýp½Ør÷ƒoÔh·ºá{°¡ÊÔ¯IÂíÓú‡+R½' ·Oê8¿—¼~£E½× ݇/x6ýF‹{®»Ê­Jôœ.Ý?¨rµ+Òp»tþ£‹ù{Á·ê4[Ýp½Ør÷ƒoÔh·ºá{°¡ÊÔ¯IÂíÓú‡+R½' ·Oê8¿—¼~£E½× ݇/x6ýF‹{®»Ê­Jôœ.Ý?¨rµ+Òp»tþ£‹ù{Á·ê4[Ýp½Ør÷ƒoÔh·ºá{°¡ÊÔ¯IÂíÓú‡+R½' ·Oê8¿—¼~£E½× ݇/x6ýF‹{®»Ê­Jôœ.Ý?¨rµ+Òp»tþ£‹ù{Á·ê4[Ýp½Ør÷ƒoÔh·ºá{°¡ÊÔ¯IÂíÓúŒyR¨RN9P…¬I%e!$¤ãÄ·ô—¡Æü½àÛõ-î¸^ì9{Á·ê4[Ýp½Ø@€t(ÈkYS„ûšV§ÒXcÀ‹Ž?Ç\ðù‘MbÒr3í<‚$M¬”Dy›Ý¸s ý×j¬R¨´}Ôg¿Žª'ÿQpâg3¾ðŸ3!»O>É8œ5Œ¸hZO‘—Aÿäñ!ð¡ÀU6œÜW&IšéoqçÜ5)jã†&xQýg‰ž"kµ(Ôz<º¤³2b+*uxt™tÞ}Ž©×eJ²ëOµ_“žsVÚ†”ÆSŸV•ºÉç™Xì!+§²§›Œ¨ï`d¥š›J7`|1ÝŽíû¿Ké-¥TES3ïñË„Lc9ûÇç}WJ´Z‹“F#ñŸ¼óþ E¥Q­È¹jPª³"Èi£¾ÂX`Û$f[ÈV8™ž'«#=æEÐ]gkÍAZiÏU¤µ–L¥d%Î9™”¨ò`k33-ê2=ØæÇ1Èõ-M樷ˆÄ{{DDòûºÚ\ÝéÚNfxç÷ÎZYS'L’ãÒt‰’Y«V”š×”ðQà¢=Ä{º13èÝÓŒÝJ¡S"¡®\gÒjN±(#4—J“”‹£¨Ëyo/¿ðÃ¥J®)ù,<âš[®²†•†sRÌÒxÿ“ã`xo#àd{ñn‡\’ËÈŒóSÊšq ’ÁYBOq’HýÃ_sÄfmÈòc¨æãKy¢éZâT¢-å¿1®¨ª¨Å3‰LLGhëµ ”dç+,§;ŠZm)h˜J±Þg™²#ÄÍEÜgl­ êêÑœ9´±T‹Ii$d•ù.#ùáÔdeÒC_Qe4Un ,¶çLÖ´ÔWæâù!³q´š0Q㸔½ÇÐxâ]#*Ü™«6S7bHœº ]±Æ 8%åbn'w’x‘bŸ¸º…mB½£Y½É®¼ñŸoÝ îÞ¦å_¢œGñm«ßà9ÿêÎÂc]jÞ,K&µ!©ó·éqáÄ'I òã¶IN8’RY–³I(ÒÚVUeÀlkßà9ÿêÎÂcî»^­rø$èõú$w¦M¢Ò©u†ËyÜ’„Ùq),qÌ”>·ˆ”¥d‚#5ßvk¦ÕSoö±8ýþʺUW)³\ڌՉÇïÇÖ4ñ~”õT£ÞioS­yÈRYLLe%.§"’·òã¹_·Ìffh4–]ˆÐ6’Q¤k]÷¦Gbv˜éF©ÆiÂ4$¤¼ÚLÍDÒË3t)'dÌ}v¯ qÞZ)¾Â‰ä”„ÈkgR\V+5(Õ˜ˆÌ‹?Š{Èü¬ ÕøZõ(jõå9§cG¸q¼¦ìvIÅ&A8åZŸY$Œ‹¶K#4¬Œq}"þ•]Ù¦äÌÇç<9rýÞ™ô-'L¹zi»3TqÎqÂs×/ÝâÍ»´_Kge˰SaÎÚ5˜ë6‡e#&\7eÙ±ÇÇ?Aa¿1𤫒¨¿š|HÌÊ}¬ŠñyN¥µc†Š˜t°#IJïÃƇX±h—N—«²î{uºœ·iŒE\¦MLë6й“X’Sg‰xÈ%–Y·Ô´ekSœ¹èÓï[(åU«65";³fДò¶´1)Q!ÓlÉ¥©¥´Ú‰ÓNr"Fü2Ñ?VæšRr‡·KhPŒÜ¨®äRu8’R‚ˆŒ±I‘àdGÖ3G[#Ñ­ÚfŠtQEdÍik¬3_¦µDu—dËn(ŸpÛÈG(±I–’Y8”™«yA³)°£ÚHµêé·]º"?B¥&3=¢z&­ÍIšTÓH”—4™VÈñN( ÅRê Ó9_mŸ«äxíȃ+V©fÉä¤ó(òŠœUÑ»Æ,wC…£wöOÞù_y.bÿÔ)ÿFó±±»ÿxûÌcr+¿+±ù3Vùoò³iå͉ÍW%íYòíXdÕì±ÔæÇ>üŸ¼œ‡ÆÎIƒCцë­%kŽñ Üḏ4(Ð¥$Ô]•J,Kq™o;lQŽ›¦ÅȉA‘5Rj3^™Q›Bz<˜ˆR\RL§æÕI`ÔiBÀÍ)R ð4ùhnÈeê…»>ç¶V§éV¶ÌSŸð-£–§‰e‚_lõç£1tfÞÏç$Á!èCuÖ’µÇxÐn2fXšhR’j.ƒÊ¥%¸Ì·eå]ù;Hb¡²íZÚ”95™0Úe³>8“­Í‡¸bXâ\:Û—Ȱå?lNªÖ¢YÔèÒgÛÏÊhŸC~2}³IÓäbx)ÕàDDòOTÓ\47­dQê²U* ‡ži•N2º£zÒBÒxæm ©kà ‰RŽýÁÈ 8jâ²`ÓÞ½ètŠ4êM¹*•H’†iã[K’R¥kò²œ Ì[n9:Ú|e ðÀÍEŽ– Ž›hÄ­ZÖ’!T!U¤À„ˆTw©í¿Td6R67 × L)i< + ^›þ¯slû‚¥L•G®SêÓ›¡L¢Ð¡ÉR¬™ªÌ<ô’Zw™léeä©—LÏÅÝ|¢RâXW]ç"‡lJb€Í ö R¡x²%%sµÉa²Á*yHDr4–fmã倷ßuß’ö=zæÙv¾H¦È³ë2kuM)y3`yqˆ8ô[ÕÞW«Ütý—SÈ•$AϬͮÍ<Œø`Y¾2á¿ÈÇø éÚ‚ÌøÚEn­fÖëõ¹ÔóM¯*5Ù:–¶D¤ÚC¨#&LŸ'”¤™¤ÜJȈ—ŽQµ›B¬'J×Z¹H¨Ulç.P޵`ÿ'ÀCsÙœ–R´)$ÚÐjÁF“6Ã’+”7}"ÙaTÙ³“I©%+‰.BŽ\g²)9HÈÈ”J>«0á·™¼äÑ+3éŽTiÕ‹ê\É)È¥6PاLˆÁ¹†âiz¦ñTo`xæÀæ§l2-^›nk–d+ͧž¤Ä†µ¶í9TÆMDÓ /Ú2SM Œ#…àd•nï$UíÊ~ˮ庒àçÖeÔå‰"F|0<ßÞùpÝåãŽì p×y"¯nSö]w-Ô—>³.§,I3áæþ÷ˆï/w`|+U ´º-ß³koÙè¾W.-!çTäjw&>Ùš£gC' ÜV¨ÒX¥Ä£/ŒI5R‚ʨ”3zÌ­¿g¢ù\¸´„S]7#Sù1öÌÕ‹:9âµF’Å.%|bI‡>ÈyÆžŒ„Dyô¼é¡klÐI`²)Y×™DfœRIñIGŠÓ».eÂ…T\¡À­ÒßÚ T#7*+¹cN$”…`¢#,RdxõŽ ¢[Š–ºd[2Úµ¼e»™2 ’ˆÔåÑe2¢q•—ìš[ês,ˆˆžBp,H†ÛC4YôÝ PhöŒ*}¥X†Ìvk%R¶Þ$½)ЗזÁº¥(“ûrRÒ¬¦X™ïHr°-~›NN–ê2î{b§TœôØ‹·j @qö¡°–š%$žIeŽdñ<µæ4çJȼ$R.úm:5Y¥Ö-j£—jïØ¦³°¸m*ªÍ)‚ÚpÈm¥ƒm½NlIiÍ“v`í.·FdU[zŸ´N(,¡Ô’ÔãŠtÛlÈ›5x«Ü¢Ç$«’L”Eñ±+¿*,z Ͳ윯M;gÖgÕkZJòfÀ³a› p,pè!Æö|IR.š dg˜*}nã¸mÖÍ‚ª2ZŠfGÒ•¦JÜIô Œ¸ X¬[t Ô©ÖÛÔúÊ™eŠûåi‘ªU*B”‰&e˜’—ÒÉ/rTHIa¸€sxÓX•ß•=æÙvNW¦Ç³ë3êµ­%y3`Y°Í†88tâmQ]‹pÚFųV§Üñ5ÿ,jÂq¦çbÉV/¨‰2sÈ6œFS^D¤ËÅèíÐYGMÒlÊÝ·žIº%M¦»\ÖȤ“KudDòóeHI´ ÈÉeÍV%wåEA¹¶]“•é±çlúÌú­kI^LØl3aŽŽ>ÔªÜYÓ—LSoDª3<ÙP^"7#¡óq(%)¦ÍY™u'‘J"4tài3àýÐYGMÒlÊÝ·žIº%M¦»\ÖȤ“KudDòóeHI´ ÈÉeºµ©ôKš×ŸY³¯"Æ¢G=tE©qå°Ä”IKPæ©L6zÅ$ÔIJ ¤ì4× w’*öå?e×rÝIpsë2êrÄ‘#>oï|¸nòñÇvK½-zÍuë*xr}ÂÂ.W–túc±£¢9S&IÔ)ç|SpÒ“3Q%YÒƒ-þ5Bã´.xﮇbÅv†Ô;ÝÇi LUh‘×o/:›ñM-¶©º‚Y¥./É3,¦ø>(yÅNv9Äy-!¤-2 Ñ«pÔj#A+6då#×µŠÅB˜.[oJ¸Ròß·¤ìëSéuªDMRâîÇ6¹*N-ïR‘”ñË7€ ¯ïÿª=ÿõã«ûÿêýDHãZÝégPç ÕÙA¦KJIFĺ‹L¸D}•J#ÀÅ_IuŠErÕ O¢U ÔâÕHA?B^lÔS™Ä³$̱!õÓ‰m'F‚U‚v,¸n¤Û—ˆœ6³­£Ç¤Œ±Ãü“Þ\HþZH¤Ó¨V]¯G¤Dn—%¦l°$$¦µþóâf{Ìñ32r0«Ü•ùíÔK¢´ÒŸlÚ)º“RZSªÊÚ’Þµ¨ÿw"-æe‰ch‰õP®“vQcMªÂ¨4ï“FÊ]hü´“É=&K<1Àð¡ê«µk4|ÄLüGʇ¨ß®Íj~c3ñº¥rQW~$؆êYyÖ¢®3ÑVfDZÆ”¥&D{ÈÓ‰bXbex›.4(OM™!¨ñ˜lÜuçTIBE‰¨Ì÷qg¤*Ë÷åÀŠ|:C0d>Òã4YHåk,ªqåàHA¨‹yá™™¸i&2©hÈOµ>܈Ҋ6bNЖd6ê™Ä÷xéA£~ï~á¯Ó¯Us^&­jbxO,ÿé_Òôšïm#[Z˜žóóá4{ÎV¨5#Ó’óøêM6Lt?V·JW¸ŒüS=Äf5–­ÁuO½ê”º¥f¦G×ê^ØÝo&GI-~ÕFhZÙ›Ÿ³"ÕåʬLÆ*kÕJÍï@]‰Õ¢¯mãÅKDÃæKÖºÉ)Nkµ Á· 8GIŠ=® Û3™¶y%nH}ºÁ3oÊeÖÐq^2D‰Î¸i–ZÄ·ã’LXbĉ]<:Îkv£ ªÄjBÞÂl˜îÉe¬§ã6Ò›JÕŽóež'›v8ò¯8W]>„å5Ö2éDã®'”g˜h¼TšˆÉÂ|–G‰HÌÉ5»Ê‹HsK­z§m¢ –áIˆ‰i¥œ¥G’oÅ\e)IB²NWÌœ<ŒÊÞY+™RxÓ‘O–ËHùSÇRRu]—ÄÌ·gA“þRH̱ ú÷øú³Ÿð˜ÓXuÓtU£r‘]vLEŽÜÉo!-ö™„”ân!\^âé3/¸nkßà9ÿêÎÂb†ªNäÐEF£`u :þ×A«qI*jòb{¼l¹wîß¼\ôûT]¿\œS9Ìüpž?…}.j‹S4óÿµá‰ºD—ME^IÅ m›¨*|fg-;Í?²Ù R‹$©ÂÃ%e22+>uUÚôØ5ç- ¦B˜–¦!’u…º¹´(ÚI$ðÕ$¸ïÇ1^kK6ìË\æÅªQ)Õ´ôŠìý…ØîÛYMx–ò#$™áUFœ¬ jáMRû¬|ž¨V(çÓT鮩´™Èt¼rc*Ë’“4™à´8“ÀÒ1Òt[–õjš5c3çãï3åž‹M¨×ÍS3ŽŸ|ÇüeΠ>0$·6 yŒ¥ä´ûIu y•²á‹%!dJB·ïJˆŒq‘û -€À­ÿ{'þŸýÒÇF?²þ´¿Õ¤ÿÄØï=oûÙ?ôÿî–:1ý/ðå¥þ­'þ&Æ>éöw £þ“þ•_ö˜Ä’Ã2XSC­,°RœHÿ‰fÑ:[®¿¤«·;Š5¨Ñ±$±3Äð"Nö”§âz›îüÆfàû±ÄÐ}jǨÕU:5U«Œâ9g8þRæZõmöus?‡o”¡„– "ÀˆHéÂô¥\ýËîôþmÂ÷cä½)\¿¹}Ýß͸~ìu"oOûUxoßí}ü;˜¥ÊÒ•Ûû·ÝÓüÛ‰îÇÉZR½¿vû¹?›q}ØÎ"ôÿµW„ïÖ¾îé:Ã.­ q¤)HÇ*Œ·–=8 é"´¥~í÷_þmÆ÷cä­)i÷oºßón?»Å»ÓþÜøNùiÞV”´™û·Ý_ù¶Ç»…iKJ?»}Ôÿ›l{±”Y½Ñ,·»_.îÔ©ÐjIe3¢·!,:O4K,I+"2% ƸíK|ÏO"kê Õ“=ž9?ê0=)i[…÷Qþm³îÇàô¥¥®ÜïæÛ>ìo¢4º#ëC]Wtjç5DOá޶ЖÐHBI).‚!ú=)i…÷/ù¶×»ƒÒ–˜ø_r›m{±¯v½Ó-»Í¯—{%Ä‹-‰QÛy$x‘-$xùħAˆ³\h4£é4' GEJZgá}½üÛoÝÏ:ZkõíÎÍ¿v2Ý/t§yµò︄s¥¦¿^ÜìÛ÷aΖšý{s³o݆é{¤Þmu;Ìå Žä“’ºtuÆñkåÞÚ³N?J–ÃIÌãŒ- ,pÄÍ&D67'-­[väÇ¡;&•I‹çqÃBÖÓ)B8¶GšO H‡@¹ÒÓ_¯nvmû°çKM~½¹Ù·îÂ4[Ñþ“xµòïäÚ6âMÇ2Ѷ$Ö’ëo&¢ì.I-¼ 'M¬Ù“•88–RàX9i®¶?ýç:ZkõíÎÍ¿véi¯×·;6ýØÚÿI¼Zùz9ËMu±ø×ì-5ÖÇã_°<ãçKM~½¹Ù·îÃ-5úöçfß» ÚÿI¼ZùzQz—P™M—1–z™$åCV¹ÒÕºl¸É«Nû7œN‰xØô‘fòÓ]l~5ûÎ>t´×ëÛ›~ì9ÒÓ_¯nvmû°Ý¯ô›Å¯—¡ñE‰±ì”ÚT}…•G‰ªlÓ³´¬¹›oüTžDbEx©ê!›ËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŽrÓ]l~5ûËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŽrÓ]l~5ûËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŽrÓ]l~5ûËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŽrÓ]l~5ûËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŽrÓ]l~5ûËMu±ø×ì8ùÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^ŠÀŸO ˜0#A‹„l°É) ¶’, )I7~Zk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯Ø t‹f]ÌÕÇ&!;=§ò Sä›êS‘.ê0Õk 8/.b"-û‡@¹ÒÓ_¯nvmû°çKM~½¹Ù·îÃv¿Òo¾^Ц}=3œž˜ÐJ[%•¾D­b›I¨ÒƒV¯IÔd]j>³~Zk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`yÇΖšý{s³o݇:ZkõíÎÍ¿vµþ“xµòôs–šëcñ¯ØZk­Æ¿`y³SÓ™iñÒó×ËêJ•”‰ 4gŽ|[û†»Ÿ.zí7±gØ«¢º'6S]5Faé¿-5ÖÇã_°´×[~Àó#Ÿ.zí7±gØ~t¹ë¬ÞÅŸ`cÅ—¦ü´×[~ÀrÓ]l~5ûÌŽ~t¹ë´ÞÅŸ`9ùÒç®Ó{}€âpzoËMu±ø×ì ]Í^\jD¹é¯Ud¢:›jG—RÍ%¹Oh".“3WAg›œüés×i½‹>Àsó¥Ï]fö,ûÄàî×ÊûËìž¿Þtïˆkª]åt¦O=Õé­³\§ÌvKõ+Cm³)·fH|Ô~*UÐF|0>ççKž»MìYöŸ.zë7±gØ«&^‰ĆY‘qä²Óì8X-§PKB‹ïIî1ç‡?:\õÚobϰüés×Y½‹>ÀjÉ8—¡4Úu:˜Ò™¦S`ÀmgŠ‘2Jï$b2G¼üés×Y½‹>Àsó¥Ï]fö,û"ŒF!Lb‰ó·Ÿ.zí7±gØ~t¹ë´ÞÅŸ`N¬§/D€yÛÏΗ=u›Ø³ì?:\õÖobϰ²eèEY§¥Ka¤æqÆ„–8bf“"fQbS,KN‹Vq§**3ã‘t–HÍ-6—2© IšMM$÷õâ|só¥Ï]¦ö,ûÏΗ=u›Ø³ì¬òETÓTb¨ËÑí–“ç5ûúŒ¶Õ›>¯L«T©LT§Rdª{ÓæH’q"2Ìa+/Iî•!µyM Óç?:\õÚobϰüés×Y½‹>Àˆ·9ˆ†4Û¢Ž4Æ›òÓ]l~5ûËMu±ø×ì29ùÒç®Ó{}€ççKžºÍìYö\YðzoËMu±ø×ì-5ÖÇã_°<ÈççKžºÍìYöŸ.zë7±gØ'¦ü´×[~ÀrÓ]l~5ûÌŽ~t¹ë¬ÞÅŸ`9ùÒ箳{}€âpzoËMu±ø×ì-5ÖÇã_°<ÈççKžºÍìYöŸ.zë7±gØ'¦ü´×[~ÀrÓ]l~5ûÌŽ~t¹ë¬ÞÅŸ`9ùÒ箳{}€âpzoËMu±ø×ì-5ÖÇã_°<ÈççKž»MìYöŸ.zí7±gØ'¦ü´×[~ÀrÓ]l~5ûÌŽ~t¹ë¬ÞÅŸ`9ùÒ箳{}€âpzoËMu±ø×ì-5ÖÇã_°<ÈççKž»MìYöŸ.zí7±gØ'¦ªLÈdÒke8Œ²šÌÌÍ Iô—Xé7ö@¿Ã–—ú´Ÿø›QÏΗ=u›Ø³ì Åï}]w³‘ºkÔ×–L)ÆÐ“A+ Åâ‘cä—Hbr;ÓIúSO¦Ò¶ê%V ÜŒ§%§TÆO-¥/V¥æÇvU©¢Ã ùúK ý°¤ý)Ž«Yu8TºÖj¢d.›%‡bÌK %9«qœÉ%©'•dFdX¤‡ãøÓ:ú^?úÿý¿é8ýYûËa"ÊšTÖ‰´K˜æÄN2†HiR›}ÖÒj5æÇTÒWŽ\¸)Y9K>¾E­[e—8̺Ê#®IºÄ¦A¶•¥ 2Rd£I­8¤ŒÌˆñ2Ãx·PtŸP®O\©u*«rhÚmÆÙŒQ¦Ç4e^)Q¥2‘•*I¤òîŸÌËâ–ªÝ rLê,eHLÖš¢Ã¦š’„´ñ!¨þ)¯"w-J=äÉéë\Ï'ocš²å•t77b]!â’lÆ}-gNe&A ™ÊXøÊQ­%”·–üH²ž} b"T .±mëqåµ!œM>[JRqÅ&FXâXo¾‘9^55RJlIíÕÎT©QM$´°—–ë)kòЩáŽâÁ®­Ú Õ©Š´i†VDÜRnL…Âj"¥;j7M–ŒÐƒÊ¤§qž93ó1•3^xÂ*ŠqÁ[±¬w³lšu~‘LzErT9õj”ŠtQO'YÎÓl,ÖëºÔ›i=zKB°$™˜¯Ó-ªÕJ"%CŠ…¡ÓY2•Hm>i,TM¡J%8eþiýÝ"Án_²hVd;z*æ*2çÍv«ZhbdwÙŒÚPx–Z§L”eâš’eŽò‹HÊ]6›‡ŸŽºœ*{¿'©òž}&úÞBç³.:ÈÜ2ñu„X‘cŽ:fkŒ¶ÄQ*œË"å‰Kåá0–vVæd)¬)ãaÄ%itš%›†ŒªIš²à[ñÃÃô݇t¸ä&š§²ãÓ$3¶1…:ÛŽ¨’Ú]A/39ŒÈˆÜ$–ñf¸ëvÅ>¢ÝVù³ªÎ[)ÊŽ†8¨S”¦ã8zâpÔjA)DhÕ– N{†Mÿ¶©—»×z«;.­S.¥ã6–ã!Y–á2½a›†jd’œÉFg‰ˆ×¯ˆN­ã*´K¢ýŸV¸U6˜ÑÓd°Êã9PŒ•¨œe×LËó‘!$M‘”£ZH³6²-]ÉmV-Õ2Š» °·MI&Ñ)§V…' Èq(Q›k,ÅŠVDe@Ë¡Õ)H³+”’æ²ä©¦Åv;)tÖ‚md¥§*U¯ò‹1–_$ñÚG¸(õä@82\ÖÔòåT&Cf;ï’²dBõJ2tÑ•g­V V}äXÎ&­l{1˜§W*x ` =Ÿh®á£V*yETÿµš6³§I·]6Èñ,¿³eÃÇ~ü¥‡ŒB°/ÖûM¶©4(¬ÛPªoÜäù/MSé4º£JI-êžJTZô‰2ÅJ,03Ç æ¬~–TDg‹F¶<Ûªá£3#TÅ.mE˜Î¸©Ì0òÛS‰K†Ê\VgDgä¥[øp4hæï\F¥•>)4äv¥bªŒd›l:„­¸Fæ-¶d¤øë"IàfG¸oí˪ɇpÛUI¥_CvÌÒ8LGŒÊŽLtÌ\„)Å)ÂȲÖ($J%`E™=#QQ»)Òyw#2Ë”-ªm%¬RŸèÛu+Æòes,Ozq"ÄðÃZ½n ñF2ÑÅШË4SÕ´0ãÅ$–ûe¶Û(¿´'MÜGµ´fxr©*%(³dü'GסÆö#\’y„4mHaÈÎ6ãrÖkÉ̹H£8y‹%y”ƒI¬5Ý!QgØÒhlƨ&K´Æ¢–Ú2gKTt™æÇ iÏðýæ÷oV_Åý¤Å´¨ÔU½Wƒ"2—eFŒÓ¸TR°BÖD´™Ni&•`J"p ØÆµÍ\á:¶ó†´UM¯Y­?6’ÒéRØalN)ëRã.¼kBµ¾?Š„åJIFæeeÄТ ³+íÜo[Ò§Æ©³œœfER3$•!ÃlÐj[„œùˆðN8¨°Q¤ÈÏsY¸íz„–œÌi´øóŸ…2Ç„ÑߎÃÍ«;d´¥¤º§”³Èj$t(†cw…¬õçwצSÞÍU©¹2œó´ØóÓjuÅ©µ4òµiR‰Hñü|¹QÕù3ûgSô[cL¹äæñ²k°é,ÙqÝŽíbmªÒ©œ QQªÔœ‡!²xÚ#ÀÜ&³g4tžl¸`F}ÅÞ™¥šÔ ÖÚ™à¹X·imÒš‘NjbÒ…¢;,!ô¥¢^C%©· ˆðÍ›~˜ù=¤¯[dÙ,âÔSHM+TÕh(û>cš¢7Ó™)ÀÏy‘)%†u®|6â–ߣ*í6ãªÆ¥ÅK´æfËjžoÎŽR%4ćY3Ky‰N,¥bIN;±Ã!BÍxÞ6„‹ªß¾™S\ø®Ê¨F§¢3JF'V™!¦ß^·•‚Òf’BüU‘ïÄpÈ›UU1ú‘r)‰àÚÖÑÞà¶¿Ó—ü*n¼ÿÁm§/øT*#‹§}W[CúI$@¨´ž O$„ !'€<€ $@ 0ë°= ¤ý)ŽºIÑ…}…W2˜f]N/Ø‹¤ý)Š_é—üGŠú'¯i~“zähÓ¯W9ŒòÎ?œ¼ÿB»U¹œ{¸QË°Ž™0?’×ìŒw,Ê¢:_‡ü–¯drœ¾#S+ˆý}¯ñŸªUÎcçMúåÇnZÕt½ù)_ Çrƒ1.1ü” ¼Jâ5rxŽ…¿ñ_¨UÎcÃ}5̪‹¦HGJÚÿyþƒà¸®#¤Óþñ¾“Äkdq â=6®s錵«I§¤|”êSÒF>ïñOñ(õÍ.yÌxo‹tËô©'¥+ÿqšª,'¥.¸¿QŠðÄxY§Õô™÷ ±b‰lUWŒž”;þâýGÍUȉémÿÂ_¨Ô:1éiõ+óðÙ5¶ùW$ôµ#ð—ê>) cô2 QZw Æ9ùC}:uélÚÛòšÔÉü)ýCå<©“øSúŠ‘ˆo×S¹Ú[¾S@ú™?…?¨|§õ2 QR>~ºnv–ï”Ð>¦OáOê) }LŸÂŸÔT@7ë¦çinùMêdþþ¡òžÔÉü)ýED~ºnv–ï”ð>¦OáOê) }LŸÂŸÔT@7ë¦çinùMêdþþ¡òžÔÉü)ýED~ºnv–ï”ð>¦OáOê)à}LŸÂŸÔT@7ë¦çinùMêdþþ¡òšÔÉü)ýED„õ†ýtÜí-¿) }LŸÂŸÔ>S@ú™?…?¨¨€o×MÎÒÝòžÔÉü)ýCå4©“øSúŠˆýtÜí-ß) }LŸÂŸÔ>S@ú™?…?¨©uˆ úé¹Ú[¾S@ú™?…?¨|¦õ2 QQß®›¥»å<©“øSú‡ÊxS'ð§õ úé¹Ú[¾SÀú™?…?¨|§õ2 QQß®›¥»å<©“øSú‡ÊhS'ð§õ ß®›¥»å4©“øSú‡ÊxS'ð§õ úé¹Ú[¾S@ú™?…?¨|§õ2 QRà 7ë¦çinùMêdþþ¡òšÔÉü)ýED~ºnv–ï”Ð>¦OáOê)à}LŸÂŸÔTº„ýtÜí-ß) }LŸÂŸÔ>SÀú™?…?¨©€ß®›¥»å4©“øSú‡ÊxS'ð§õ úé¹Ú[¾S@ú™?…?¨|¦õ2 QR àõÓs´Þ\ˆÕHe–ÞJ’á(ÍdDX`eÀþñ¢î\ªåZÕ7Û·ã‘D lÓÀA‰à À$ ð'€€0000"ˆ&`aÖ¡´Ÿ¥1‰H„ÜØõ„lí¼ö«s$ŒÉFKÃ>ø ºOÒ˜×A¨Çƒ¬—S/:Þ šHñ5`¬02èÞdÑ<*˜‰ý®9˜Çfcþ]º#Gªšqñï?|cÛ“Ñ·šLk²UiŒÁ%<‚Q2f‡)T‡”[’g”ˆÈú©DeŽ'OhbøV¯¸õåG\˜¦Ú£ËiD¥4¬1ËŽìHÉ'¿§ 7cˆäiõ?ª-6­W£B^ªNie5¥“QT®£4¤ˆˆø’”¢Ãq€ãúÖ¹;CTM"ò¾·•'*&óaªÀÞ,ÚÌÛþ‡£)y];·Þ~o¿þ*|†ù]ÿ°ù[käïÿ?U«É­þy³}ØqôkªÀ­è•dÜõ©´©tj‚¥¥ BSÊ”“SªÊ“/&dò‹`eŽò…ÎæyýùQòƒû‘ò[`Ú67þŸjÖdË“7“¿0ûñÆV¦‡(÷#—&i#¬P¡´ô‰ENY2n(žÎŒMdd”ê¼²#Ä•‰íúÛsE´ÚÊkõ¤Þ‘£Úe! ­9Ì^R’“Á,ã›q¨‹yã¼°#ÇvN….û~ݰ´L¬ÔvYµšY1OF¥ÅëœÕHN¥&IÞâ7¨È·ýÆ6šÒm:س«VœúÜ‹qér T*»PŠY2³$%D¦Ì2AGè< ´ô--:J·­c¸#¹M¸#9*Y˜æ¤­´´§>ŒÔ[ð$þ÷Bˆñà2*úeŠÓ2‘{@«N¶TáφÜE£"˜ñ5™á›*Tf’#"24æÜ,Ç¥;uÍ4Ú9×…V­H£3(¤T¦Ám¤ëaH=[L²•å5|¬ÆXð"3=e­Zp¹èÚªÙ>Rí<‘ý®éí9ö¬½ ñ1Ö£ËËÓ÷÷Ó½‘`Ð4[iO¢Õbkµ±Í÷ u¬Å3ªQŸìr¥F²J¿Ë4–µàïgÐ+òë÷ÒÊäÑí¸;[Ñ’fZÕ`µ8bDM¬ðı<8bG—¥+¦Ï»tCfÇ\uŠí»1N\7\f–P¥k|‚"&³óÇ4š ¿©ö]Z§½ Ù”ÜS‰=¶¼²-äJ"ı,¢2Ä·+èÀÂÇx^:!»,:Šf¢Ö¯Ç?înÀÒO[ÔkRR”á»%be‰b5w>‰éVîh÷]J÷e—*ô™ ©êÎã¦Ò&ID³,U–™©;ASSœÍ²‰·Tæ-$”á§) ñÁ[ü}×Ù:a°šð€bçn®ãôg-®MrR":Z§¶“wzM$£,·‘”_x ÉeQ´yX”ë”êS%U›~Ž Í–ˆâ™«zL‘†­ÂÁG‹÷ y:Ø©q™©ÞTÈ4ºzê ÑÞeI#m$fd§Œò¥X–òÃ=æDf50Ñ¥2ð‹S/H”ɳ^S1`±s< ‹;©A–¥8žå/Ã@º_×vŠ/í‚î¸ê54ÕbÒ´Fc-&ãŘҤ¼^*RJZ~8––ã#hHV-·£X0ÞªL¡V¢TÓ.¡²C7ª´…©Ig?BRdiIâeäžïÀ}¬-÷èÚb¢ÜúeN}”•Å’ät¸m£Èq+lÔX Ì²íø‘u(Ñ.‡ZÒU—r:MÒäHÊö+ÈJ<¦hAŸR‰)þcšjºJ±VÒÔ¦nº‹–Ã4Ü!¾F㨈ëJAâ‚Êy;Ïñ‹~ãÀ,ùTXw4 75u*BþÛŒ‡…-FG¤Èñ,q-剖¸g´“Gµ©4ê´*æ…‰Deµ”ZÕ ,:ñaÐâȲ)².Ÿ̸àK¯Gü“£›vö§Uާ ®£eämYÅ|‹èÌó+6ô¬±À¼’ݼsm/IÚ'³iU6õËrÖ":‘ƒ1N¹ƒ>„¤ÜOŠ\ ó«v=#Cà*-j\´®ªz‘ Ök-:²ý›6´™‘Ÿ<©<8‘/¬ÀW›Ð,·/ -¨‹‘‚ªK¥N¢ÚâàP[Å)ÊX,õŠ5(Ë÷|œx”Ú0¯›R:ïÚef™Pª",¸Û:™–…âyZ\|úÄ%Å'WœðËœŒ÷ ZeûJ¬éÒ¡wÜ5ºíêZbJ¥©$ë ,ÚV•%X£!`¢$ž&xõ‹V’ô“dË›dMQùIZ£ÕØ™>²Ý4â-Æ^m^S"ÄÏÅèÝŠO£cé3E4ªÞœ>KY5‘Þq²rt†¶š¥´†YÁYú73fñz ð3߈¦ß0G³Uw[WTKšŽÄ³‡-Ö£)…0î$^JŒñN&EŽ?¼“,Hñ‰#IöMOË¿©u‡êÔúÔ=– Ò!8ÚáPÊReŸ f&ÑáÐXôîÇS¦ $@ªXRh1t‹XºäM}&´%ˆqši+JÈ—‹$â–F’Þ•ÛŒ>µš|;Â5¬æ‘¡¦¥:*Ÿ„©«'4æ5bD³JRDœIF¬OÆÁ>.úüÝ ©»^⟠ï¦Ô*öÚ ujs /+D¥§)DIVâN¤Ëu¹´›dLð—µïÕ¼ô84¥Ç“+ex²8i’DY Ï鼈ËÜcGk_Öœ.z6ª¶¯å.ÓÉÚîžÓŸjËПj<¼½?qàÚF…!¥F®\wå:ß]i|$?Jc ¤´“š’†ÌÒe¸ÿbdc‰j1NBL3}‡Í‡TѺĶה̳!E¹I<1#.’‡Ñ.ì:¥M‡T½ë ˆˆÊEFS§¶]Y§¡…¥¿Ù£6&IRŒŒäuúà‘]z¡*™âAzS®F`ÿäš5¥ÈŒ‹ùÂà Äð`H@’Ÿ<©¶Ìš=ñT¹¨”Ê›ÈñäÌŠÛÚ´’_Ròç#ÃIc‡Qu …´wB¥i"ë‹qÑ ÏŠUS¥Ó™£èÜ“˜’¢2ÇT„oÿ8ÇèRî·­ÛHÔºÍCe™Y¥”x ê\^¹ÍT„áŠRdî#zŒ‹ÜbùNÓ ¬õÇ£‰S*3pX}ûí™ÃþÚ8{: È’f³Ý†)Çr‹¨ÀRœÑƒ5ûºý¬ÉªÂ¶-z%bS.IÙÄ£”Im¶‘†â#I`Xt¤ˆŒ|•¡IÍé.j¹]atÚüw$@«0Á­.! )Ï£5ýÉÝ›¡DxŸ@ßRïû.©H¶ez«"I¸kÔ`UŠ·H³<•'3dD½ú¶Ï 8™d*Ù©Ò­‚ÜiµlZp_‰Ê0¼ÎšãD¬‰#V#eÑŽ&{ˆ€UêúeŠÕ6‘{@«N¶TáφÜE£"˜ñ5™á›*Tf’#"24æÜ8xÇ:Z÷õ§ žª­«ùK´òGö»§´çÚ²ô'ÄÇZ//OÜxPt-p[6åðÜ»¾«Hy•°òЉÉ™‘“„…‘™pÝ¿<:Œ-öŽÿ‚ußZz•ʤzÃm³5qÐo¶ƒ\LR— ³xÊÜGûÇÖcåYЗ'i–‰£¯”ÚÞT‚©{vÁ†«xòêõ›þ‡§1y]·ít…xèÒ‹¢…£É• ’*³“)÷d6¤“8) 2ÅIIŸÑ!$DG»3Ǧàþ’tUUÒ•µ¤Y—,Ø“"S•Ø<œê’že¬‹y~ÕIÁ¬LÒ{ˆŒÓt/E½uV¦ÞqéÑ­ÚÛô·–üCKlÜR³23%îA±2"Ç~%]ÒîŽWar4¦+LVi•˜Ç"¦Ù6DD“*x(È÷tt ›.ëzã°4sK£T6©”jQǨ7©q—5QÓ†*I·¶½é3-ßyÙhn“A¤h‚èÒMZƒO®Hƒ1¨q£ÎkXÊHÔÑ,òžã3×þwt˜³ÕôgoÁð§¥Ñ؃7âò«±I)”¤‰Â4eVãI­¸÷`¬:7 Vˆ®ûU8¸´yxT¥A©Èn[S[ާ‰*J›5$ÒûõHÃw_G®‘o+Hšf:…Âõ^-²ÜTÃbLD¤ž,¦j%©*J¼SR—¸‹ ¬€~|!èõXÍR*j·ì¸4WÖöÃ2Úd’‡ÉFœò‹r”DØ׆<#ÁÖÝ£N‡xÝušdj¢-ÊR¤±Js2· (IýâÁ£,ü¯à?:W»­nlmÝZUë1ir)ꋱ”Æu¸d”¥[ÿåUð.žz¼èvê.k~ä}è”«Žœ¨ŽKi£pØVU¤”i-æX8®Ž8 »^VµˆÝõ£;Ž£LK¡ÜðÒüèq’ie.êФ‘$¼”šm&EÀŒúÆ„»mRtwP~¥kÑmúÉUÔÍéTBRp[¹wbh5™ãÐdž±£¯éVÖ‹¤KTÄ?T·í…^¶r)ãSdÙ¸”+ye$¡EŽËøýé^ÿ±ÞÑÍ~Þ·ªò«ÒëõµU oE[I€JRh#YoÃ&R•ÑÄ8ö«f[° ËZ/št´×õgR&‰Ò Z¬ÚÌÖ¸¦Ö©îMšU‰:©fBVÛq*²™·ž[ºHÏàê §F¬Æ»æÔ.–»ôd-Øt¹jJÝ”¬=BT¥ ÍI4%8’Tx¨·p>V°t§cò5•S¹*s`ÕìØÒ#5 ¨Šq3RãDÒr¨·$É)O•†üxoaë"æz÷¸.ʤê]VB™F‹&¤>ûšÕ›k2mX+V](é=ýAÉ~ V–Žê²£¹T6ëµ÷à¿%Ê|†ähM¡âh³âJqY‰EAAn3ã- T-¨7É­Û+¸ª2˜ôx‹$)ƒ’³Á:ÒRˆŒF’ãžà7ž ×u½eßóª—-Ca†í)ÈèsR㘸n´¢,“>„«~nÍ9`*eFüÔ–™“Ó {&â¶7°<hA‘¬·‘ôô‘a˜ g„õߢÖ(,ÓéQi5·©äíf&Í›pÉ8jøtë w.8N‡«V½2¸oY‰¹îÉò[f˜Ô¸éz"Rf’2RMXæVñá¼_k “Uy&R‡Ö’ŒâÍJgˆfdX™tc‡ˆ67EPëw-R´¦‰¥O˜ô£lF±f¬?–#\ÐÚOÒ˜©Õþ™Ä[)?Jb•[˜ÚjÅC3y)'˜ñ{*TfDfhI‘biWOPùûG·]Í"i¢&gÏ;ÑyµøL®#e!RŽZ]dÿÙr=¯Ìåc–‘Y?öcþÀýHŽtO‰th†¦W«“Än߃TV9hµ“ÿf¿ì é5¥y4*Éÿ³žöGRÍ‹±Î™ð³D¿'ˆÖÈâ,oÐkêÇ-¿Y?ÿ€ï²0^¶nUt[µ“ÿø.û#©jŠ£œ-Q]?*ÓüFüE™ÛNéWEµYü‹Ÿ ÅvλUÑlV$çè/Ûà±MÚ>aWxb<-NY7ôZõŸÉ¹úƒ–-æ}­gòkýÊ*–êo[ê*“£Þ‘prÀ½Ï¢Ô¬þQ ÆsG—ÑôZUŸÊ/ôè¹GÌ7Eû]QåMw Æ9ùBææŽ/Óè´k?•Wè>£[ÿý¬þUBÍ7­õG–ØÒ-uG˜TÌ@¶žoÿT+?•Psiú¡Yüª†[{}Qå;Åž¸ó ™ð-§£[ÿÕ ÏåTÚ_þ¨V* ÛÛê&ñg®<¤ÛÍ¥ÿê…gòªm/ÿT+?•PmíõG“x³×aRmæÒÿõB³ùU6—ÿªŸÊ¨6öú£É¼Yë0©¶óiú¡Yüªƒ›KÿÕ ÏåT{}QäÞ,õǘT€[y´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*@-¼Ú_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ"Ö-œÚ_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ Þm/ÿT+?•Psiú¡Yüªƒooª<›Åž¸ó o6—ÿªŸÊ¨9´¿ýP¬þUA··ÕMâÏ\y…O¬@¶óiú¡Yüªƒ›KÿÕ ÏåT{}QäÞ,õǘT€[y´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*@-¼Ú_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ Þm/ÿT+?•Psiú¡Yüªƒooª<›Åž¸ó ¶óiú¡Yüªƒ›KÿÕ ÏåT{}QäÞ,õǘT€[y´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*| o6—ÿªŸÊ¨9´¿ýP¬þUA··ÕMâÏ\y…H·›KÿÕ ÏåTÚ_þ¨V* ÛÛê&ñg®<Â§Ô [yµ¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*d-ô…yG²ÊÍ]yš%hÙ[m Å+Q©I5’s™¨ñ#<7áÐ>…£KÿÕ ÏåTÚ_þ¨V* ÛÛê&ñg®<¤ÛÍ¥ÿê…gòªm/ÿT+?•PmíõG“x³×aS à-œÚ_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ Þm/ÿT+?•Psiú¡Yüªƒooª<›Åž¸ó ˜mæÒÿõB³ùU6—ÿªŸÊ¨6öú£É¼Yë0©ðbÛÍ¥ÿê…gòªm/ÿT+?•PmíõG“x³×aRmæÒÿõB³ùU6—ÿªŸÊ¨6öú£É¼Yë0©m-_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ>·›KÿÕ ÏåTÚ_þ¨V* ÛÛê&ñg®<¤ÛÍ¥ÿê…gòªm/ÿT+?•PmíõG“x³×aR01mæÒÿõB³ùU6—ÿªŸÊ¨6öú£É¼Yë0©¶óiú¡Yüªƒ›KÿÕ ÏåT{}QäÞ,õǘT€[y´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*@-¼Ú_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ1ÛÍ¥ÿê…gòªm/ÿT+?•PmíõG“x³×aRmæÒÿõB³ùU6—ÿªŸÊ¨6öú£É¼Yë0©¶óiú¡Yüªƒ›KÿÕ ÏåT{}QäÞ,õǘT€[y´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*@-¼Ú_þ¨V* æÒÿõB³ùUÞßTy7‹=qæ Þm/ÿT+?•Psiú¡Yüªƒooª<›Åž¸ó o6—ÿªŸÊ¨9´¿ýP¬þUA··ÕMâÏ\y…Lì[9´¿ýP¬þUAÍ¥ÿê…gòª ½¾¨òozãÌ*@3«ÔŠ• ¨å.¯q&´”)ÆVe™´ÓŽ•Dxt—Aàcl‰Ïm‰‰ŒÃÐÚOÒ˜©Õþ™Ä[)?Jb§Wúeÿó寯?‡žhÜÕù|F¦W¶—Äjeqë \®#W'ˆÚJâ5rx޽…ª¹{µõçð󽚿/ˆÔÊâ6ÒøL®#½aÑ¡«•ÄjäñI\F®O×°µCW'ˆÖÈâ6RxlŽ#­en†½þ# þ#5þ# þ#¥mf–Ãá–ðÄx^¶±KшïHËtb;Ò.[n¥ˆïAŒsò†C½1ÏÊén€Ä 1$¤ø| ëBzÀ@ ë'¬@žð'¨@ž¡$„ !H8$@‘'€ƒÀA€ !H@ à O````D L:ÀìCi?Jb§Wúeÿl¤ý)Š_é—üGÏv¾¼þw£sWåñ™\FÚ_©•Äw¬:45r¸\ž#i+ˆÕÉâ:ö¨jäñÙFÊO­‘Äu¬­Ð׿Äa?Äf¿Äa?Ät­¬ÒÃxb<2Þ ÖÖ)bº1énŒGzEËmÔ±è1Ž~PÈw Æ9ùBÝ-Ð& d”ŸO€€!=bOX=bõˆ À@žõÔ $ I àˆ ðbx0$ I< à H"I‡Xu€€èm'éLTêÿL¿â-”Ÿ¥1S«ý2ÿˆùî×ןÃÎônjü¾#S+ˆÛKâ52¸Žõ‡F†®W«“Äm%q¹„õˆ!=` õˆÖ €OxÔ OP€B€$ƒ€ H€ÀA‰à À$ ð'€€0000"ˆ&`aÖ¡´Ÿ¥1S«ý2ÿˆ¶R~”ÅN¯ôËþ#ç»_^;ѹ«òøL®#m/ˆÔÊâ;Ö¹\F®O´•Äjäñ{ T5rxlŽ#e'ˆÖÈâ:ÖVèkßâ0Ÿâ3_â0Ÿâ:VÖia¼1o G…ëk±]ŽôŒ·F#½"å¶êXŽôÇ?(d;Ðcü¡n–è @“2JO€'À@ž±'¬’#3""33ÜDCšo]Ñí½È­¹RœåÝL(nÕágF¢"d¨ò Ë.bY\|l7ýä1š¢9ŽwÐÕ£M»îIÌÖß–Å&™J“RšäU¥.m#v¤¨‹Æ4ð=Ø…*Ѧ¯C5«â ü´JjªÅ6˜ÛkI4· :Çs‘¤ÌðGFXN!5Fp)=b}¿Nr¯_§ÒZÇY6SQÓ‡N+Y$¿í™á£K{GÒhÎÛê3`Ï9L¸¹Ž!jKÑÝ&ÜI’ÀŒðèàTDàq gÐÆŠmËŽÌs^3êÚQHU1¨KBê#´k}ÕЯ*1, .²âdF™ˆã"‘ÀAŽ]b‹  òSJuÞ$¬ò"§6#7A(М$ÿ0〨Üj‡¤¶lYšµÍ~[,0óG™·’ꈛqÄŒ”_õ—TH¨ä;Gk™¦½‘b7.thÉ¿1ÄþÅ-‘®:á%)J¬Ûð-ØóéÔifQäG¥ZõIÕ©qÓ–¡QR’˜Ž¹Ä˜F\ÙK£:”y¸EQ"¨Bžð$@‘$ì :À@ô6“ô¦*u¦_ñÊOÒ˜©Õþ™Ä|÷këÏáçz75~_©•Äm¥ñ™\GzãCW+ˆÕÉâ6’¸\ž#¯aj†®O­‘Äl¤ñÙGZÊÝ {üFüFküFüGJÚÍ,7†#Ã-áˆð½mb–+£Þ‘–èÄw¤\¶ÝKÞƒçå ‡z cŸ”-Ò݈bIIð$øÖ „õ€åïKJ Næzð¸dÓ¡ÐíóK¤íFBXŽô³úÔµn"ijOAˆ¾S-Šƒ¶–•äU/»2å™[¥ª¢ë4j®Òé.:ÍÒQ£)`‚ÇêñHpÇzò†èV]6›É´êr×&QëõŠ){åx¥† ñRøÞ?".55Ó¹E‰0‚ü}~«:NSñ²« ð>ø USTæR¶hïû… Kþä?꣱hqUÿ8õ'ù£Ò‡÷Bš:µËÅzcR+’ÓþV¹YYWà#!S©Þ;V‹©3í¸SÞŸ&N¿6ÒêË*O&RË•;ºO¸4¥xü¶¸cT[§rlXtö E‹¯Öêši8fÊœq33è.‘:³œ×ƒU15M8[-8E«$æ-GÐ’e tŒÿš\êh™¤ýET2ÖT¾^¼ÃD¯ÝDÒ73Qg=ÿÀÇhÆñùV©TÑNÛdJ¥Hƒõú½n‘;äžl¥‹»zHntQ¥)V¿_¦Æ¥"kõ"BáÉ[ù6Ò‡N’ržsÁÍÛËIª™™ÌZ®V`E¶tŽÅÜKF€Å¯OQË9!ܲ]ÿœ¥#y—I¦ÞW SFZ4³­‹BS´™uÚSuÊ­B1ä}óxÕªlœ-éJŒ°#êëMO•FFÚ\Iš\JL™á÷™`8¦$‡¢JjTgTÓì­.6âOJˆñ#/¼Œ‡,MÒÍ¥p=ÊW®‰©Uªá‘kgÆ©=ŸQ–ÚÉG»~ÿ÷ ê‰ø [4Û&u«yZUWêT ©œÊjä ‘!µ°âIm¸E¸Í*À³{ú±>K«Ð)”½<ÞÚG«²NÐ-ãjªÊU¹2åÈmGh¿Š×˜ú²–;Œq]ÉX»4³^‡n±MªI¤FRšˆÆb#< •)9–|Lº7 „µÔëtûFí¼ÂޢŽuÇX‚õÅé*~Ùm\¬8áÌZIA·¬5b“JÍe½D¬¾6ì ±fi&ŸÐnм,ØWe3ë‘ K\W£-~Y%ÔžS=øaÓÇ£ ­iVD»²Õ©Ó­ê}2‘j¼—)t†–¥6Ú‹5,÷©J2,U÷áŽ8άëg˜ÞœÅ×á Q£\És-K”©N³)Çe×¢6”-ç#=bÉÇgÒ¥pã€Ç£_ü[ÍŠýKÂR¡RŒO¤ÓmKLWÚ3ñš&ñ4$8‘$̺wŽ%wJIƒ¥Wo«^ÙHL¤8™Ôç¥.SS5¦£{9« ÊÇ ˆˆ°-Ã`î–¨tˆÒ]°4sLµjò›Sk©í®Ky¢Q`­Nr"hÌŒËè#ìçûÁ•–Ï«Ó¬Ë I÷Å¶Ó P­&‘@S¬â„£:Ý#È¢àÙ¡DJ.”–%ÒCï'H—}ÁÆ›U[•6»[®È]>tµk^‰¶É·Ò•‰¡YIĺ jÃÅ[ÈæhÂc³NÙÑ{óäÉ׿ÚYeIäÊYr§wIã÷½ï”ví­Cf°E·àd–¿Y®ujÌã¾IeÌxx»ðäÆZ™ž&\¦\Uýh®!5+†æ— UEG•r%8Ó«ÌÙ©E‘&gÓ¹pºA¼ê·Å^F¬šubŸ«"¡™KM‘- å2C„d“Üx+¤ñNì8râÒ¥Nf’h÷)+¢ÅU»¯Km4Œ¹Tx'VeâDE¹X}ã}Ï›"UnÔÑ*…sÉmÄQ3u,›„dµ´É‘%µ`g†|KpÆhœrQV™ÊYsÎ4x»KË{Q&–šÌ£<¨#32Ic™î!Ê’àÇa1‡.©Pz¤hè9(Y%¢W߫Ǹ‡ ÆŽ´2Ô¦L Ï¤@¸mÉË'$Òç$òk°'QoBð",K‚ê#-µG,!MTù±àÂaɤ8–™i´â¥­G$‹‰™ŽÐÆ…ß {ZéM-«Õc–$cŠRäfTf³?óTãxÿ ·¥Ê¾‡Ñæi6ÅMÄ ¢ôÇ'¾Î%›Fá ÿ‘ÿV´ï—èT‹½‡"96¥rCÙ=É&Je*^gLÈÒf³^âé,:wŒ*ŠªK–åUíëîȼ­ ·: E—9Yo¸¼¸“Q¾N%«:[û‹qoîcofÜ5Rè§\T§2L‚ñ:Œz] Iÿš¢3IýÆboJ¥:µuTjôªG#Ęñ¼ˆDþ´™5oQ²§ÅÇ"À°#"à2¦Y‚$„ Äð'€€0000"ˆ&`aÖ¡´Ÿ¥1S«ý2ÿˆ¶R~”ÅN¯ôËþ#ç»_^;ѹ«òøL®#m/ˆÔÊâ;Ö¹\F®O´•Äjäñ{ T5rxlŽ#e'ˆÖÈâ:ÖVèkßâ0Ÿâ3_â0Ÿâ:VÖia¼1o G…ëk±]ŽôŒ·F#½"å¶êXŽôÇ?(d;Ðcü¡n–è @“2JO€'À@ž±'¬ž±zÄ à O>‰Y«Ðå*U«:™!m›Kv$…²µ ÌŒÒf“#23"Ý÷ÂqkqÅ8┵¨ÌÔ¥&f|LGP€B€$ƒ€ H€ÀA‰à À$ ð'€€0000"ˆ&`aÖ¡´Ÿ¥1S«ý2ÿˆ¶R~”ÅN¯ôËþ#ç»_^;ѹ«òøL®#m/ˆÔÊâ;Ö¹\F®O´•Äjäñ{ T5rxlŽ#e'ˆÖÈâ:ÖVèkßâ0Ÿâ3_â0Ÿâ:VÖia¼1o G…ëk±]ŽôŒ·F#½"å¶êXŽôÇ?(d;Ðcü¡n–è @“2JO€'Àn¬:,k’ó£ÛÒ§;ºœ¶â†ã“ÆÚÜVTCZ1,Æœ|mʼn‘–™ÀÒåFôYF©Ýµ{6ܼ—rÓž’Ê!Î¥lÍË[¬éiļác‚e˜“Ž*=“yÈ(fÅ£_t§3¯ˆh§<­¡¼yÛÁ>2pROļbë!ŒU4,Õ;>¡K²Š¿SU‚ùÔգȥ¼ÛfIJ³+^¢$g%¡h6ü¢4«¨Æk^å“GUf5»Wz˜‚3TÆá8¦EÒf²,»¿ˆœÀÔÚÓm»Š¥L]R@ªÍ€ÛÄÂåG†ã%Ã4‘ Ö’2%­±ÇÆ.²ºnn*ÁÖè÷©´µÏý¥BótäJðIj¬Ž~Ñ^)jÕÔa˜OÈ\uµ|R`Õj½W8 SâÓ\uKd›5’ZqŲ6÷' Ä~6;…f]§tã5Z—mVcÓJÔ×`º–•áÉfœ¦JİÀ÷ã¸"¨‘¥°¯PëT ˆ‡]¤T)RVÙ:–fÆ[+R ̉D•‘–$eÜ}C^$OX‚ÖOXqfÎ…O·)Õë¶´õ%Š©)p#E…µIy¤žStÐkm(F;ˆÍXža¼|¯;N ‰E®Ñ®«TÚºŸm£Ù”Ãì¸Î¯:lÍDGûT™`£ÇýØÆ´ ˜ ½bÙ¹(Ñ™W·ªÔèÏ`M=*!ÁJ"#þCsxY±¨vŸvE«;1»¹Fl9™8ËŽ´¶²Ä–¬äjR°<¸ˆÌˆÏf<ÞM¯rÆ£¦³&Ý«³LY¦cœK #è2Y–]ÿÄ~áZWTè'¶kRaÌpÚŠû0][o¬³b”(“‚Œ²/qcäŸQ†`i@eÕéµ=AÚuZŸ.Ÿ5œ5‘å2¦œF$J,R¢#,HÈ÷ð2‚@€ð'€€=Bõ$ I 6ŒíFï ™ÉUVèðd¹î5¬Ltš’„™§Ç3‹m%åcÀDÎ8ŠÀ Õénεnúµ8R`ISdœ5„G⨋©E—Üd2›°/·m¦ì«‘n8ÙºÚK|ÍH#"5eÞX¨·ýåÖ\ à6Ô{fä¬Äve"ß«Tc2x:ôXn:„$Œ‹ùI‘‘™t‘‰$@‘'€ƒÀA€ !H_ôm£9¥½W¨³Un$¸Ì¼ºl%2kUIl –ëh<Ŕҕ7ÀñÎ]F"f#ŒŠ&™uNcp©°¤Í”áàÛÚSŽ+ø%$fbÃoYsä_´kRäT·œªJn*Vý=ZÄ)ÅdBµkR1NcN'ŽâÄË, 3* -µ-\ÅuW¨´ -b¾Ý¢ôd§¸á¶µ$ŒÉ¬¦yqÀÌÿ˜ÔÒm{–¯éT›v¯PŽÁ™:ìhN:†ÌºIF’2/æ¨01•M§T*sÑ›TÙn’ŽÊœqF]8%$fbå_Ñ̪.ŠÚ¼ªÔaN*×$É¥M¦› iFÊ'³^*I¤“Ò„ï3àDf™ˆ0$@‘$ì :À@ô6“ô¦*u¦_ñÊOÒ˜©Õþ™Ä|÷këÏáçz75~_©•Äm¥ñ™\GzãCW+ˆÕÉâ6’¸\ž#¯aj†®O­‘Äl¤ñÙGZÊÝ {üFüFküFüGJÚÍ,7†#Ã-áˆð½mb–+£Þ‘–èÄw¤\¶ÝKÞƒçå ‡z cŸ”-Ò݈bIIðý F“/LVsQcºû‰­ÄtÒÚ FHC©ZÕpJR¥ð"3=Ä*À@‰ŒÀæM'ßUkKJœ:5³H ÔÝ©Kmu$Ç|æ­§Që§œRQ¬B‰Y›JHÉX§2]%·^§x5詚„H†åE׌д#:ŸÏF}jA­Hë,L±-ã…€c©Ès,ÈÕ©¾ïU¦G¨IS÷ʧ=-Ô-fâV§”³é#tͳ=ëÝŽ"ÙV‹V¨xAÛ—•¶O&ÇŽTõ±PmxC‡ ¶›'šZü–̰t 2hB58kVT¤’’Ä÷àII".à6  < à OP=BIPBƒoèž"î…ÜTc¹d¦[oÅ£&BŒÑ4ƒS4E™JS˜lRM«qa­f="­yèÏLr›šýiØ+§BÔd4•4ħH”´¡*pÐY³šHÒ’Ç­¢zïF¥W®hóã±&Ò©)j’fI–öƒ¨Çéˆ×ã§,å¿y¡Ô¥Ñ«Pk÷ ¹d7&:Í$¢KˆQ)'î=ä[ŒYÞÒÖéõX´j „º»'¡"N“´£#S´qiBTdX’ $xaÐ5læ8'.O«Ç…Z´´>Ú¶nšãtÊ3M8ª U ¦Ô­Fñ¸ÞÎê³Q’µ†i%—V'źf¨1VÒmr¤Ä(Pv—’ã‘âJÚmÓBu„NRJ<ù±2,1ÇQ`gP à3¦ŒJ1"ˆ<ž }¡F“6c0áÇvL—ÜKL²Ò kqj<”¤·™™™tŽn\Ú&¯ëZ<ê•ÑO©ZÍ¡.Ãj„ÚÛâÌÕ Ò⤡JK™Ô‚^O%)Ã"B5S‘Ùªõ”í«PÒ…‹ øÓî(LI¶ŒÛ6–ü}r\—¬p3ZR¤¤Û/-ÛÇXt»Î&´i@­Ÿíjò%E¤¸ÚŽL6õ̩׌¹ƒ&Xî&Ö¬GЏŸ€ŒQ1Òìíël¢ø=!ÚÖ¥"¥G¹©U¹)¬8J4Ö™[†¤—”²žüÍ üS%–c3Qjn:ssmÛtkFï©»E¥7Stj’c: ÛŠ×“ÌœgÛ™ücZ8–·b}xoîeØÔ£×êÚ^D‡ ÏY‹P"A˜Oš°q*šËNS¬Z·â”–ó%a˜‹¹(—DvbÖ ÏmÈWy:l<…g†ÁÆRKX“ÞÑ‹ÜJÃ{‰ÿ(±à³¨d± $@ 0ë°= ¤ý)Š_é—üE²“ô¦*u¦_ñ=ÚúóøyÞÍ_—Äjeqi|F¦WÞ°èÐÕÊâ5rx¤®#W'ˆëØZ¡«“Äkdq)å¿¢Vy^ӨͪýªÑ—4‡ñòL±è.‘˰iÚŸ^v߃T Ê¬2âÛv5¬ò´’Òm“™ˆÒdx‘–ìÆÿØÿÿ§ÿŸýbH´YÔ[žä¦¦  ÐâÐàß*‚*5Ç&¨Ø­HtЖu$†ó)&Ù«Z¯Õ»ÆÀ¥+ÄÛɈÊ]vˆò’§[h‰¥ÈuX­d‚3$™'*èIb¥$ŒËíÍÕ›èë/{cbµ=‹FUЫ†àz¡"ü*zIÊ£æË1~S!JÍ“«FLM&¬ªR1ÈyGË–Ýù]‡Êj¯Ë•›/!m®j¹/jÉ›eÇ&¯cý¶».9÷gýÑ8ƒ6òb2—]¢<¤©ÖÚ"irV+Y ŒÉfIÅEŠºX©FI#2B±l9¬©èp’Ò]q•-©®-$¶ÖhZ É~RV•$ˤ&G¼…+SØ´e] ¸nª/§¤œª>l³å2Ô¡¬Ù :´dÄÒjÊ¥#‡”cY4æi¶Ò‹J¹P]ÍA¸gΑN‘]ùš¨K[M:Û®+"d0jñÌ‹Xj'jRs’ùº³}ýeïlk#Ûz.“qI·#¹Lzµ¢zE9º¢•%”S%­¢s2Sã£y–2zÈeè¶|뎻ÖK“‡Z4.• åIˆH#&–hÇ[¦jpϧ*›IùMpÝ–¬_;j—&墱=º%J"â¹9¤º—ß‘LS- X’ÜJLÒœ1Q™à¹-‡èÌÈ€Ë.ÊtÙŽ‡&¸•<²B–hAüedBÕoÁ*>‚1‡pÛZ/·b¢]Àºm":Õ‘.Ϊ)„)]DkpˆÏî=$¿Žö²TÍÍl¡—.Gö.ß}Jcû›<ËZ¢˜Dïìó'Å&ñQ’·c¤ Ò™aR¨Ë¼§[“.™ªz=9çštu™Ï3Î9©i)Õç<ê5fiH`n"ØV4¸ÍJ‹MiöA-·[˜ê´™bFFKÀÈúÇâ-‘`K¦µS‹;ð^dŸjKsœSKlË1-*%ài2VýøþáÑEr¥¥+ñ´vB¶Ìüê;5y)Ìñ`†”Kñ^&j"Þœ0F¢Õè<$ÅN–ÿØß÷í `p´ffi¨’Q‡â“n',ÉT†ËÞ[Œw®æ¢è’Ø8årÍ£QVmŸ”*ç]— Ùs¸Y°ÌœpèĺÇF| Ç|Oô(ÿêXâ¿Ø¸$izÖnÛ©Réó>OVMNT)ë–Ú‘´SqI!4dxå<ÙŒ°#,§Ž%’xV%‰6#S!SÙ“äÚy™®- IôTKÀÈúÈ}¹º³}ýeïlpÜÊR‹i[”EÊIõVn7_®½EŽŠ†¸B Tv–¦™^¹×GˆFY±,ªÞ¢°ñÛvRo‹Ápí÷ÑQÚªÐ*ï°ÓÏ!ä¦k˜Iej#dÝ3^'VÙòQc8KjÔ°ëôçgC¡¼ÛMN— Dì‡ YãHr:̰Yø¦¶”eÇ,Hq}NÒѹQÙ¬›pJ˜úq©œ¢½C‰s Z’¼ùL•™8üK‘[ÐÛW,ÝAvÓ¹)Ì´uŠÒ‘Y¤;-Ù$u99d‡ØÈ®“V$xšº†ÿ¦„huʶ„­ªmÏR¢TmÊ…©„AJu‡Ò…Çlˆ–ò¤-+Á‘™6ŒO\0 9Øö TN8LÕ4o}µÍa¶FI5åÏŽR3"Ç£!‡rÚ–œÔé”7œiÙÑ!$šá«<™ ÇAž+/–êLøàGî:S*chšèºãÍ]BçTã*Zs6¤Bƒ5QYP³AšQ&A©(Q’œ<¬¤C[J¨KmTŠå.§IEÉlª+pî9½C§V`#”óH=ä–ÏWŠ'˜Ï))$mZ–~œìèt7›i©Òá(á+X¸×~eÕzàºU2cÜ‚“”š³Û;K…%HI¥R†dæR[úæªÝê݄ԵMRî¨ÒèÔ¹r’£6Íqf)‡N¼£2#V¥$|0`r—7Vo¡ÿ¬½íU^Ë´a<”¦‹˜•ÿ½:Xt÷†‡+u;©5›š Rc%Çš€Ü%­Z¶ŽÑŒ©=Äe!o¶f^Q4ça¸½c·-µEuN¥·›[j6SK"4‘¥h2RO~å$ÈˤŒŒc<“ ×É‹OÐ?ÖÝýGR|3v ¦j©­@Û\ª©M¡jY‘%Æ’5(ÌÏ"ê,L̈±í¢í\µÛS«×´‹s\pÒᢓ]Iå!¶”’Åo¤Õ•Ç InË»>”Dßx]‹}ÿµÿï™oŠt:µåW§Ô×FwS8à܃-äd}$C¸7¿¢«m¦¸¤Rhͼf–•>ª¦ f\Öácü‡R±ãþ0ª_þ×ýÔ‘Úm$ʤÐo¶ëÅ}PmгôÆâškðõ±_e.8¤“k7Êæe¯1%ffY1Nä‰C5»G/Wétx´Í©U:|š„i KZØSL-„+Æ'7™œ”a·–Žç›«7ÐÿÖ^öÇRbµyÝ6"äÇ•o²å¾ëŒÑ¤;2§@I8…£#‰mÓÁâÀң̜Lñ<~ ¬áI·¡Þ7eR›m3P¯B“T:“‘ë±'©ˆm½) J‹陿,êl±Çp9+›«7ÐÿÖ^öÛ«7ÐÿÖ^öǪ·z·C¡5­ST»ª4º5.\¤¨Í³DÅYŠAàDáÁS¯(̈թI /º­Ôî¤ÖnjIŒ—jp–µjØr;DR2¤÷”…¾Ù™yDÒwžƒkÍÕ›èë/{b³B§èâ±X‹KoÍCÒyS"œyd’äùˆˆö88gã8áwoN&yOp£\«ñôŽÊ©Õ'Ûš‹²=5øòî‡ÎA°äÔG_÷- êÁ¡³uJJŒ²+2”x*É£/ñƒEÿýÛÿ¿Æ ß7Vo¡ÿ¬½í‡7Vo¡ÿ¬½í‹XS›«7ÐÿÖ^öÛ«7ÐÿÖ^öŬ©ÍÕ›èë/{aÍÕ›èë/{bÖTæêÍô?õ—½°æêÍô?õ—½±kÀªsufúúËÞØsufúúËÞØµ€`U9º³}ýeïlcÔ4g±N¦½$gýòîýÇþp¹Œ:Ïø=ßù§ÿaˆ‘Çß&-?@ÿ[wõM+Á·Ù¶/*dJL›6mFq<·ÜpóêÔ„‘ÃÆGRØšãMÏņԜI’dçn¶¼Ä¼‰I‹Ò'‘ùº³}ýeïlkë=£ )Rh¹ˆÌ‹ ©Òëÿ;º~…¿ùÅÿˆ‰ä˜S~LZ~þ¶ïê:åá‚Õ)Í ªL KPN=äˆ)2qn)Hn+ÛÍJ3Þ‡߆#’-íW)ºQ~¿'H÷dÛi¬¯Á£½W’¬¯ž(uF¿¤`F’=êÇâI=gxYÿˆùÿWÿÓ<1ùþÇbÔÜkýh<\›ÿ9#µ›lŸ­ÿå!Õìxyéý›ÿl‘ÙùòãÀƒ"tÇRÌhí)לWB’3QŸÜDFs!õj¿Ú›Ô¶ª‘W=†Òë±Râ ÖЯ%JGIð3-ã+m“õ¿ü¤8*˜‹®“.‘ª´ZdHò'.UNBjN*QA•«B[[&Á%:”¢2•ûCÃR³/(~(–—WQÄ»*ò¢ò[“ÜZ6¨¸‡ Pg—T† J'0ñT’I(°$ˆñ¶ÉúßþRû~äå¸ÌŠn¡¶æIˆdêG‡Üag»ƦÔe÷bD{‡ Ð+-.®£‰vUåÝ?,%Eä·'¸´l%Qq Ï.© ”Naâ©$’Q`Ipêõ;RÝÉ ©UÏ׫TשÈpð[ÎU%e¡&xµ¸6f\#=ÈÍ»lŸ­ÿå!Ö/ª„Ç­<'$(ã¦{N“{ˆ³›o–'‡Ià_ËYŽÁZ°&S(!Ôg¹>rRk•!j3ÎêŒÔ¼¸ù(ÌfIOBRDEÐ:çáçÿ£Ô¯õ¶à&9’ê Ð 0ë°= ¤ý)Š_é—üE²“ô¦*u¦_ñ=ÚúóøyÞÍ_—Äjeqi|F¦WÞ°èÐÕÊâ5rx¤®#W'ˆëØZ¡«“Äkdq)Ñ->úïž}¢Z}õÞ(@«Üðè³íÓï¨Þði®ý,X²©&Õ HVË5c6ºÊ[JqÄÏÄQ™žì0ÝÓŽ;°?.€¢\á1ö‘¢Nü/hqÞž. ßùï›.©T«òn¦%"¬‡–­T–ó`Œs‹¿v={‡LHOXŒ'.aðA«R¨Úa:±TLІÔüÙHa¿öTe™fEŽ QáŽ'†áßÎxtYö‰i÷Ôox<¡(z½Ï‹>Ñ->úïž}¢Z}õÞ(@«Üðè³íÓï¨ÞØsâϴKO¾£{ÁåX€¯sâϴKO¾£{Àç‡EŸh–Ÿ}F÷ƒÊê÷<:,ûD´ûê7¼xtYö‰i÷Ôox<¡¯sâϴKO¾£{ÁS½t¡lM–ÉÛÚDÑÂYJLÜTêóyG†â$+"çǂÙ #Ñ.p˜ûHÑ'~´:íáyQ¡=ihò‘H¹è5×éü¥µ*•=RÞ±ÆTŒM'‰bXá‰9O×` ˆN]Žð¸¨åëS™pWiT– -(—:kQÉE«}>.ucÅiÜXôŽèsâϴKO¾£{Áå CÕîxtYö‰i÷Ôol9áÑgÚ%§ßQ½àò‹€€¯sâϴKO¾£{Àç‡EŸh–Ÿ}F÷ƒÊê÷<:,ûD´ûê7¶ðè³íÓï¨ÞðyEÔ «Üðè³íÓï¨ÞØsâϴKO¾£{Áåê÷<:,ûD´ûê7¼xtYö‰i÷Ôox<¡¯sâϴKO¾£{aÏ‹>Ñ->úí(ˆ8õwž}¢Z}õÞ<:,ûD´ûê7¼P€W¹áÑgÚ%§ßQ½°ç‡EŸh–Ÿ}F÷ƒÊ!=^ç‡EŸh–Ÿ}FöÆÃ¥½¿HÕ/HVJ¦)&Mšë lŒ÷b£JŒð,qÀ‹~b]%åÑ.p˜ûHÑ'~´+·½Óo¿j^µ †´.L›F}>4jeeµ¸ëŠmF’$™âfg‰`[ÌÌ‹Ðð„å$=ðbÒ5@Ðõ bö¶ ÊÔ2jaú¼t8Œi&JI¬'ŠTXîw(z½Ï‹>Ñ->úí‡<:,ûD´ûê7¼QpÕîxtYö‰i÷Ôox+·¾•,鱨E½¤=„¬]TúëDDDG$£ÄÏ“2ÃÇw˜`Ñ.p˜ûHÑ'~´8gž³ABÓâ^µn§&î*ƒŒÑêH‘‘µFxŒò‘æ"%`Xôo-ûÇTÌ F—e¼ /KbÎ¥ßÜU˜TõJU=1›~B[Æ“‘›)(ËIb|1.&Xóÿ=Ú8õŽçcûÁçPÆL½ç»G±Àüìx5öþ–4_D€ì8·4U¶äÉ2ÌÝÏ;ï¸úËrËq)Å}ÄX™žñçÐÕ2ôßÒÆ‹è‡抶ܙ&Y›³£ç}÷YnYn%8¢/¸‹3Þ1ê:OÑ•BâW—x!Ä@#Tx;|BŽ—Œ”q–lê^UšKK¤’G¼tTËÑ^{´qëÎÇ÷ƒ|0okbî¶©ÇA¬B˜¶¦4Ji©-¸²"CØ«(÷xÄXý㬢Å82”L:ÀìCi?Jb§Wúeÿl¤ý)Š_é—üGÏv¾¼þw£sWåñ™\FÚ_©•Äw¬:45r¸\ž#i+ˆÕÉâ:ö¨jäñÙFÊO­‘Äu¬­Ð׿Äa?Äf¿Äa?Ät­¬ÒÃxb<2Þ ÖÖ)bº1énŒGzEËmÔ±è1Ž~PÈw Æ9ùBÝ-Ð& d”ŸO€€!=bOX=bõˆ À@žõÔ $ I àˆ ðbx0$ I< à H"I‡Xu€€èm'éLTêÿL¿â-”Ÿ¥1S«ý2ÿˆùî×ןÃÎônjü¾#S+ˆÛKâ52¸Žõ‡F†®W«“Äm%q¹„õˆ!=` õˆÖ €OxÔ OP€B€$ƒ€ H€ÀA‰à À$ ð'€€0000"ˆ&`aÖ¡´Ÿ¥1S«ý2ÿˆ¶R~”Å*¶Üç*êæF’YsESËRñ<ØþÑE†\:xôqùûG£_H˜ÌGwè¼Ú‰|F¦W²‘íùë ÿ*Qü@×ÈŽùë þT¯ÿ裳£ãýQåѦ™\F®O»~G±øÖ./åJgâÊ'ìÝMÎÙTŽô‹ƒ‘ì>5‹—ùR˜øŒä}q¬]Ê”ÇÄ tWö–è»Û*k½1ÏÊ7#èëbêþT¨ÿ>FØÿ†.ÎêñÍ7>ÒÛ»eS1Úqôm鋳º£ü@lú6ôÅÛÝQþ e´í”í»eS>´ãèÛÓguGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤBzųgÑ·¦.Þêñ³èÛÓouGø€Úvɶí•H·gÑ·¦.Þêñ³èÛÓouGø€Úvɶí•H·gÑ·¦.Þêñ³èÛÓouGø€Úvɶí•O¬@¶ìú6ôÅÛÝQþ 6}zbíî¨ÿNÙ6ݲ©¶ìú6ôÅÛÝQþ 6}zbíî¨ÿNÙ6ݲ©¶ìú6ôÅÛÝQþ 6}zbíî¨ÿNÙ6ݲ©¶ìú6ôÅÛÝQþ 6}zbíî¨ÿNÙ6ݲ© nÏ£oL]½ÕâgÑ·¦.Þêñ´í“mÛ* nÏ£oL]½ÕâgÑ·¦.Þêñ´í“mÛ*ŸÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤÛ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvÊ§Ô [v}zbìî¨ÿ>½1v÷Tˆ §l›nÙTÈ@¶”}zbíî¨ÿ>½1v÷Tˆ §l›nÙT€[v}zbíî¨ÿ>½1v÷Tˆ §l›nÙTÈ8 fÏ£oL]½ÕâgÑ·¦.Þêñ´í“mÛ* nÏ£oL]½ÕâgÑ·¦.Þêñ´í“mÛ*˜mÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eSà Å·gÑ·¦.Þêñ³èÛÓouGø€Úvɶí•H·gÑ·¦.Þêñ³èÛÓouGø€Úvɶí•L„ iGÑ·¦.Þêñ³èÛÓouGø€Úvɶí•O€mÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eRmÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eR01mÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eRmÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eRmÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eRmÙômé‹·º£ü@lú6ôÅÛÝQþ 6²m»eS-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lª@-»>½1v÷Tˆ ŸFÞ˜»{ª?ÄÓ¶M·lªfbÙ³èÛÓouGø€Ùômé‹·º£ü@m;dÛvʤ:¼T‚ª8T%Î]<’‚mSP„º¥d,ædƒ2"Ï›Ä÷a‰™Œ²'0Û˜ËÐÚOÒ˜©Õþ™Ä[)?Jb§Wúeÿó寯?‡žhÜÕù|F¦W¶—Äjeqë \®#W'ˆÚJâ5rx޽…ª¹•sÀÔÍ‹6šô÷›'šCÌ¥©/²¼­õŽ%)d–¥¥8$—¿£Ã|±êÇ^<8ã8ãöN¬©À/ÔMݵ «Œú)”ü‘$Hqr*‘SªSL-ÝK¤nbÓŠ$м¦DKY‘% 4וiÖŠÛ]ÂÚ`?¤%Ƕz”wže*Q!*q”,Ül³))ÅI-ê"âBiÓ4z§Všâg‡¼{òó„jÏÃDámÚtªÝ¹6c7éªC‚üç£8Î3-µŽ vA¬²­x ’…©hI¨ŒÌ‹zþ‹#ùp£\ªqÚ<×!×Íp2&Û!÷ ¬=rI1$ýY™ ·`xŒ+õ ÝSMS‰´ÿO>ÉŠ&\d”):(MQ<§O¨Öª'"±!‡ PÕ"bµ®HoFK¸$’¨¯æV°È‰%†&¢!¬Ná,ÔW®¨ü)µ|t@Q3",U<—§¤©µFxÒƒlü’ÄÒg€Æ=KF™˜ÖåÏ„ð÷ãÇßãÜÔ• ìr…kDnRjÑ©Sªu8rIRjåQ]i‚n;.<û±5d%ÒË÷ ÌÓ™b[ú5‡]¿-ê;ªÏí<¥¬«Î’4– ,‡€Î­ ÅYÍ<óüyùÁ­-•ÇY•]¨56ZCB‹ $ÑHñÛa¼Ïy¥´™ðÄÏ"ÜV;›IuûžW *öbÔ—Q^J[1W%kKiR\rmYL›"<¦•+ÅG‘¼” Îf­\Ó§—ÛÛ‡Â5¥q“~ÈrÚ¥ÑâÐit÷éY £DÆä2òT•é"TN¨ÒX¯WF`œ>Îi.²õ¸RiôÉ5áJ‚šÃäòçR]yÇó(ÜÈ¥,ä:F¥$̉G‘™™Òa¹X˜ÄÓïŸïnIÖ—&Ö´ÙwV¤F~ª†&›H}6üÉ«fI=Èî™7õm™¶ë„FÒ[ÃØá†Þ–®Xöa[#Á§´Qã³µD\†ž#aæžmÒ"wV—IM'ö‰A(ñQ™™ž#€kMÑb""ˆÄcŽ0kÕò¸ªýý§&Q Òê+”óÒ_¨È‘3jzC†g¯pÐú[qÄæ<¦´(‹~$x«¹Q­¹)2›¦Q˜yÙ*•RSl¹ýÔuM8ÊÔù)f^3o<“&òíVxbxŠ çA±<éùù÷ækJðÞ’j uM*ƒE]$™e¦i&RJÜ[jI¥ÒtÔKyåb§qXã»ÌÍ%×&Å™¶Â¥¿Q’™m•ML¬¤0Ô¥­o´ŒM’T§]éA™Š"2ÄR@79Õþÿïßçß&´¯ò4­_uĺTúJvQʨ¬›uGRpÙq•ħ ˆ”ÛΤɲAsâDeªUñPMãB¹"S©°Î€ã ¦ÁifRÓ¦òQã,Ö¢5š”fk33Qïc±4è:=<©öÇ÷ü¾ÑÂ8Ò€˜»ñdÑo;’ŽºÔ;ž‰NeS¦Gm‡(Ž>¤¥‰.²FkÚRFfMãä—HÎ{FWcÆfåá@QŸÿ§ÞøÁ¿Ðgø¼Gÿªÿ÷#K£B“.á—>U&ñâkufФítÕN$"\†Ð˜åt%)KdZÊ"2ÜY‡.='@‰ÎÂücú4F‡£Ç+qâKÑ-Æ¿*ë ûÿèrº¯*è ûGÆ_JW$i´´Av›9Š´“ŽÚã[UGšâ)Ìí¼’Ë4²¶¢Á²Až$­É%oؼ®Ù”úš½º&|xüŸƒDcé«P;¢gǎ€ËR˜öN­?»Ÿƒ$3éªP;¦gÇÁø0@>šº¦üxìX ÄBq¹‚Ý4új4ê›ñãóóX¥zBÝs~k¯HP;®oÇŽÈfG[þk¯HP;®oLJÍb•é uÍøñÙ ÈëÍb•é uÍøðù¬R½!@; ™où¬R½!@5ŠW¤(×7ãÇd3#­ÿ5ŠW¤(×7ãÃæ±Jô…ºæüxì€du¿æ±Jô…ºæüxŸšÅ+Òë›ñã±à‘ÖÿšÅ+Òë›ñáóX¥zBÝs~k¯HP;®oÇŽÈfG\>k¯HP;®oLjù¬R½!@; ™où¬R½!@5ŠW¤(×7ãÇd3#­ÿ5ŠW¤(×7ãÃæ±Jô…ºæüxì€du¿æ±Jô…ºæüx|Ö)^ w\ßÌŽ·üÖ)^ w\ßšÅ+Òë›ñ㲑ÖÿšÅ+Òë›ñáóX¥zBÝs~k¯HP;®oÇŽÇ€fG[þk¯HP;®oLJÍb•é uÍøñÙ Èë‡Íb•é uÍøñ5ŠW¤(×7ãÇd3#®5ŠW¤(×7ãÄ|Ö)^ w\ßÌŽ·üÖ)^ w\ßšÅ+Òë›ñ㲑ךÅ+Òë›ñâ>k¯HP;®oÇŽÈfG\>k¯HP;®oLjù¬R½!@; ™où¬R½!@5ŠW¤(×7ãÇd3#­ÿ5ŠW¤(×7ãÃæ±Jô…ºæüxì€du¿æ±Jô…ºæüx|Ö)^ w\ßÌŽ·üÖ)^ w\ßšÅ+Òë›ñ㲑ÖÿšÅ+Òë›ñáóX¥zBÝs~¬‹â¥(‹ÃÇ p1GMÒ뱈¢32çiúmZ>"Šs2áJoƒU¹QJÕ±o:h<žJœ•#«2Ny2K ÁBÁmùL†§eÕìüœRbdò³fÏ!ÜØø¸a— §ÛúÊ£Ûw… =Å;)‡X‰=üê2ã«J]Üg¹$jĈº $9šÒÿÖèâ,h÷¦ìqç%¿F¿7iœÇá.)Ðgø¼Gÿªÿ÷"ÛJ§B¥E\h êZ\‡¤©9X¸óªuÅbf}+Z‚ÇÀ°!f²)TÈÖ…)é°ÙJâ¡ål%$¥¬³­goR”¥(ϤÌÌÏyÎÅÍìÈnÂˈ#èîÑqÛ¦½ª4’ZB§>¢ŒD¢Q¬õþË/AuØSíZÂ&c>µÂ˜©¬ºü·žs^¦VÉ­KZK=ZÔŸÏvE‡'ìPüю̃b‡æŒvd'‰.‹ Õ¹ž’ífœëç-’bR˜ó(‚#"Ö!µ¥+4âyMDfØ`Bn‹VêEQéÑž™:[S—¯”ó$§Ð†Û%“­žvU«i)%# ËÇ–¶(~hÇfA±CóF;2 Ñ…¬õ¯K¨¦JXnMJ ¹Ï4ćCj6Ûl‹ZïŽáåi&¥¨ˆÍF£À[Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd#–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAKtØ¡ù£™ÅÍìÈ0)`.›?4c³ Ø¡ù£™,Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd°MŠš1ÙlPüю̃–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAKtØ¡ù£™ÅÍìÈ0)`.›?4c³ Ø¡ù£™,Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd°MŠš1ÙlPüю̃–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAKtØ¡ù£™ÅÍìÈ0)`.›?4c³ Ø¡ù£™,Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd°MŠš1ÙlPüю̃–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAKtØ¡ù£™ÅÍìÈ0)`.›?4c³ Ø¡ù£™,Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd°MŠš1ÙlPüю̃–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAKtØ¡ù£™ÅÍìÈ0)`.›?4c³ Ø¡ù£™,Ób‡æŒvd?4c³ À¥€ºlPüю̃b‡æŒvd°MŠš1ÙlPüю̃–é±CóF;2 Šš1Ù`RÀ]6(~hÇfA±CóF;2 X ¦ÅÍìÈ6(~hÇfAÃhvçÒ[N¤–…Ý%I>ƒ#…»ÎÔž¥P™åXjèAº‚3.ÉjIf/òˆ÷áàr…©L¦¢,é§ÄKÒªRÝá2’S«'”‚R TyP„â|EÐD7?4c³!®åšnbgœ4ݱMÜLóŽRà›NѪ½]Erâ$´m8nµ9-ktññÜ2Å;±3"#=ø%†Ì—þ³ÿCÿ¶Ø¡ù£™£,²Î:¦›oœ©"ÄM›TÚŒR›V©µN­/ÿÙxymon-4.3.30/docs/mainview-acked.jpg0000664000076400007640000015015011070452713017523 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀ¼"ÿÄ ÿÄ^  !1"AQ’“ÑÓ2SUW•TV–ÒÔ#3Babq$%457Rs‘±²CEFuƒ„…¡Ááð&Ddet‚µÃ6rÄÿÄÿÄ>Q!1S‘ÑA3RaqÒð¡±Á"Bá2Cñ#Âbcr¢ÿÚ ?ôôùrÓ:BS)ä¤Q‡b+˜øpÙŸk¼0¨ÿŒ$ÿ¥WûLT4ªÒ¾*ªz„꼿ûé=ì³bå _²O]òß2hŽqŸ«ëfK9œQê›Ö+*zKíÈq´´ê–FQÜCObæ‘¡Ç“Iïr¶Ã¶Ã†Ìû[ýáŠ]xŽªÝT±ÑƩԜ_ÁÚÈE¬(Õ(èe»$‹ø[Bo¼÷Ïhø+Çð®"¨¼ýK"p¬Ê¤Iu,º$´‚4Œâó´yŒÿhJ¶T‘¨óXwðÙŸk¼0á³>ÖÿxcO‡àÔ A6êu™i+^u:ëM6H¹dB[Jl‚23,Ù•´î£Ùmˆ>ü6gÚßï 8lϵ¿Þóö8¢?.±¤Z³Z„ùÇ©²K¯)Óã*r Ôã&®­Y¸DN¦çrÊŻŸ¿+WË5P\j2\d°ºraÉJÙC¦¹ ê]$¨ÐJlˆ‹!ÔwI åf¼Tz<Ú½F¢û ÇrL‡s-YBMJU“s;؈Ì}X«-÷d4ÅMN¹Âiô¡üÆÒÍ)Y%DGÍ<«J¬} #Üd)2Ôj³ð¾’›é$–é‘XÖ¢A%7=甈¶ì"-ƒåX§Ä«ReÒç´OD–ÊØyüHQ¨Àɱá³>Öÿxc嬹m)ص5Hm.-£SOæ"ZhZnG½*J’eÐdd{HU¥>mz“G“ßSµR”¸u·7)pãäRÝ?ôè[ ÿ§U½Qð›\Åòé_…P—ªn©ZnRiÅ 3M¨óœiZd–­M¡ ²ÿˆù›ngq‚Þá³>ÖÿxaÃf}­þðÆŸ În©†©u6¥p¶åÃeô¿ªÕëIh%ò ï{t^ÃbûðÙŸk¼1Ìã!1„8?*«#ZËÒWÁŒRÃ95®«2Ót§X‰Ì£¾ÄŒqQ(ôŒBÎ#ŸU¢Ñ+ø–%VK\²þDDa/1•Y6Rldp(ç)Ff{LËMˆjÌb0dûðÙŸk¼0á³>ÖÿxcÍØ*ˆºf ÑÍa8; QúéªÍ6IEýf¨ˆ–CwÖ™’\-b앬ùÖ¸î½#¯p¾;ô€²zQļE¨k&«…j3fË­Öäþè¾l¹†ÛFL¿ ™ö·ûÃ3ío÷†)ê®"ÄVMm¼ZPÈñ{^'àÌ Ž† ®¤›šÅµw/šÄ…ìIlQ/Ôq±á÷ñ½iQâ—i,Â]=…GK ªªMVI8¥¡&J#%‘R##;™qðÙŸk¼0á³>Öÿxb®¨ÖëmìKK¨âYsQ%6LY®AaR©RcTIA6Ù™©”’¢²MË«1'o"Æ&Ҹ¡‡Ú“‹Í¸Ñ%¢S4>¬Q™).ž´šSI"AåA%ÂÖcI @_ü6gÚßï bÑ«ÅX£Â«Óª/¿ tväÇw2Óµ¤”•YV2¹ŒˆÅ‡jŸãè“ZU*#~•R“#¼—$>äb5¦•ݳ&I'ö‘¥E´Ï’Ñ>*®#EíÊ3(Îaì$ðèz²7'¥1¤IRÌ®hQ§*RÙ•Žä£5sRïÃf}­þðÆÌû[ýáŠ@±^8‡…qEçêY…fU"K¨qeÑ%¤ ØDg£ÌgûBU²¤GšÂ×Ãðj ›u:ÌŠ´•¯:u¦›$\ˆ²!-¥6A–lÊÚwQì°Ž3ío÷†6gÚßï |QJ ðý+⪧¡XN«Áëñ¾“ÞË6.X•û$ðuß-ó'öˆçú¾±opÙŸk¼0á³>Öÿxb°sOo¦S•VSRV2â”Ý-’ž9Ôê²Ûé¶ks¯}£-W7MôìNóÌ-r”TÓ†Á2q•VT$‘¨‘¬Î”™(”EÍ"23¹˜*¼UX«“¢ûÍ"CÑ”¬ËMœeÕ4âlvÜ´(¯¸ír¹XÇÕú²Øv;OÔÔÓ’\6˜JßÊn¬’¥šRF|ãÊ…*ÅГ=ÄbœÑåN±Q¬Ô0ÁUñšªVžŒëm6·êFuD£lÜB”´fWMFyLÈ‘ëäèÊEN‘£íEEjTƪ¦Ão¥öÙý›Ì-ßÙšRKýšL¯:•u,½]Ãç*¸°©z;¬Õñ;ÕRÄí6ÜÈ«†ÃM4k€ì”­³B D«³cº'˜Ì‰;€¶ølϵ¿ÞpÙŸk¼1NhÛãJÕV…QŸ¤Š}\Þ)MJU9£6µ¥1õnœ…-*A!IpŒìj3$e°ê´:åv~£Wëø‚EV]Z™R¨ì´Ó&¶ÉG›AÏ1fÌfW.i$¶;ž3ío÷†6gÚßï |}6F$cKõ¿GéTš†j3]êNDÉýÑPË—#æ¿:÷ËkûìÃ~¬¶ŽÓõ54ä— ¦·ò›«$©f”‘Ÿ8ò¡J±t$ÏqúðÙŸk¼1Páš­z64”ÌÖ¢@‘QÆü|x¯œ–”Ùaô:”“‹m õšiW$¤îF[J÷æjØã›ô 4z¦$“ »#&¸áÒ[ilšMDäD8é8Ùš‰).j/Úו*ú^(2 F•Q}·j4TæYë&œtÓrÝÌigs±sm¼È+†Ìû[ý኎>»6§„Z¯µ%"bרiR×ä­®(–²7Š2ÔÒWu¨¬V¹%*ÊY‡ÇFxJ§à*G•uXš1”ȼ†ÓIŒ§MÄjÒJ,«A6²Q¨³8V$ì ÅÃf}­þðÆÌû[ýဠ>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï 8lϵ¿ÞøïÃf}­þðÆÌû[ýá€>ü6gÚßï |dÕÜ“_Pu¼çdÝÃÛÿ—ó4õ?ñ«ÑïÃÌø~'–Ÿh÷áæ ü?ËjdÑruBLm%Ô¡"{êyæXn—ÌÒI"3TSR¬„¡k5T¤ŒÎÃ`š>r5-ºƒ4 “Ô¶f,™LF7$r¤’ײ $]E°}¹>ÑïÃÌø~'–Ÿh÷áæ ü?ËMf­ILªÄ,9Q} )”»-¦]Z[Q)j#<¦Fw-ÇsÆ#AªQj0—@iÉëKªLv¤4òÒH"7[3-g5´£i‘ØŠÆV+\Ÿh÷áæ ü?ËO´{ðó~‰å€5˜B†h¸vu"lÊAºŒƒ‘1¤Gi˜ª<ˆm(CQ% ChIš½[™™˜ÜÓãàêth±iìÐa± Óz3L%¦ÒÆ• Ö‚-‰Q¥jMËm”eÒcãÉö~`ÏÃñ<°äûG¿0gáøžXoÆÔ¯yÂïÓâ>Sj4çá¼ÃUÆ"8ãjB_iæm•‰i%’“rÞYˆËfÒ2Ø5¼Ÿh÷áæ ü?ËO´{ðó~‰å€4-ᦩ;RoJ5dNy´´ì”±H'\BniJ•Á.dW;žË˜ßÔiø¥ê0°äÈÈyrËí2âêÔk[„“#"R”¥(Ïy™™žÓÉö~`ÏÃñ<°äûG¿0gáøžXlÝRÚ„T`¥ "$¥/ ˆ‹¨¶‰ãjW¼áwéñŽO´{ðó~‰å‡'Ú=øyƒ?ÄòÀkP«rÚ—YÇ’*R+6ì¸4g–‚þF¨fd:FèøAè®H¤âP/ÁæÔ™ˆ§‘ιeÈ„¥6ØE•%°Š÷=£#“íü<ÁŸ‡âyaÉö~`ÏÃñ<°0g±#±NE5‡éMAm’a¶É¤¶E”I-„’-–µ­°aGãÓÓNbj#½1ÐÓ)m,¼d§[$‘X³"5'rŒŠ÷'ðŽXaÇÝÑö Km¤Ö£ô~!؈®ðc‰ãï£o°ÑoÊáy`d´8Ú•ï8]ú|GÊmFœü7˜j¸ÄGmHKí<Ñ­£2±-$²Rn[Ë1lÚF[iÇßFßa¢ß•Âòþ¾ÃE¿+…å€>´}áJ4äO¤c§KEò?™DiÄß}”˜Dd;®ƒ¸óu6Ë“‡dk„eµ­¬õ­m–¸à8ûèÛì4[ò¸^Xq÷Ñ·Øh·åp¼°ê¹…è•|hÍvE_¥–ä1%Dˆ ”Õ©“Jƒ•žú¼èJòå¾Ëf¶ÁÕçÂç£ð~ÂuWo&»[­Ö[v}g?6üÜíûEuÇßFßa¢ß•Âòþ¾ÃE¿+…å€,IŠÂó8O :4ŽÊX“­6×®i&£JY$kY‘ÂÌ®³÷hº=v–Å)ÊN]>2ÍÆ"ª;ËJ=êJ-dŸó"_}}†‹~W Ë>ú6û ü®–²X•‡˜© H¥´òÚC*q l”m ÔhA™mÊ“Zì[‹2­¼ÇłŒ*˜*+G“b£Tž Ù‘Fíê&ÉIX¬V"êç}}†‹~W Ë>ú6û ü®–î"RðDNDJvŽš‚ÜÔ´Ã ))Q).X¹ädgr;ÞãqÆÔ¯yÂïÓâ*þ>ú6û ü®–}ômö-ù\/,hqµ+Þp»ôø“h,;!Ö%ÓZrK„ëêCˆIº²JPJQ—¬yP”ÜúE¸ˆVœ}ômö-ù\/,8ûèÛì4[ò¸^X5ìAz¬ª»¸ñ÷*KR©jE7HQ)kày®•%&[vHËpî3ᎠÁsÑø?á:«·“]­Öë-»>³Ÿ›~nvý¢ºãï£o°ÑoÊáyaÇßFßa¢ß•ÂòÀ–4²“*)¥‰*–É~Ê;¥)Ju=K5-fj-¦j3é1ò§ÅÁ”ì¥O@‰–R¦¡ ¢Ï©…;³øÍi5o23+Øp<}ômö-ù\/,8ûèÛì4[ò¸^X¿ƒ@ªIªÁbƒ¡/ü"S(i½¶üõ–Õmë1öixa– °ÒèíµO·m&Ù&5m–¬¿‚ÈR“²ÜÕn1]q÷Ñ·Øh·åp¼°ãï£o°ÑoÊáy`ö4L²íj4l>ÅQâ2vkm²—ܾüË.qÿiŒèSh0¡³ºlhÌ6–™e§„6„•’”¤¶n§}}†‹~W Ë>ú6û ü®–´8Ú•ï8]ú|G3U¦G—]“V‡¤IÔ§$6ÛJn"i¦D„_*s;n©j²”v5ªÖ#°åxûèÛì4[ò¸^Xq÷Ñ·Øh·åp¼°ò‰Óê²1âªMŘ¹î7-¨H[²2ã%yØm­Í8dy‰fy±¤’d­ã¼Âg%Švi5ðÒC Iéý¥‹Ÿý·?}}†‹~W Ë>ú6û ü®–ïéì`êth±©ìÐb1 Óv3L%¤%…šTƒR¶%F•©7-¶Q—IV `ü!E§E†åê1©ìB‘Qi¦™zQ4ÚS™fFg·-ìfvë1Êñ÷Ñ·Øh·åp¼°ãï£o°ÑoÊáy` C©^ó…ß§Ä8Ú•ï8]ú|E_ÇßFßa¢ß•Âòþ¾ÃE¿+…å€-6¥{Î~ŸãjW¼áwéñ}}†‹~W Ë>ú6û ü®–´8Ú•ï8]ú|C©^ó…ß§ÄUü}ômö-ù\/,8ûèÛì4[ò¸^XÐãjW¼áwéñ6¥{Î~ŸWñ÷Ñ·Øh·åp¼°ãï£o°ÑoÊáy` C©^ó…ß§Ä8Ú•ï8]ú|E_ÇßFßa¢ß•Âòþ¾ÃE¿+…å€-6¥{Î~ŸãjW¼áwéñ}}†‹~W Ë>ú6û ü®–´8Ú•ï8]ú|C©^ó…ß§ÄUü}ômö-ù\/,8ûèÛì4[ò¸^XÐãjW¼áwéñ6¥{Î~ŸWñ÷Ñ·Øh·åp¼°ãï£o°ÑoÊáy` C©^ó…ß§Ä8Ú•ï8]ú|E_ÇßFßa¢ß•ÂòÆÃ9 "¯ãï£o°ÑoÊáyaÇßFßa¢ß•ÂòÀ‡R½ç ¿Oˆqµ+Þp»ôøŠ¿¾¾ÃE¿+…å‡}}†‹~W ËZmJ÷œ.ý>!ÆÔ¯yÂïÓâ*þ>ú6û ü®–}ômö-ù\/,hqµ+Þp»ôø‡R½ç ¿Oˆ«øûèÛì4[ò¸^Xq÷Ñ·Øh·åp¼°¡ÆÔ¯yÂïÓâmJ÷œ.ý>"¯ãï£o°ÑoÊáyaÇßFßa¢ß•ÂòÀ‡R½ç ¿Oˆqµ+Þp»ôøŠ¿¾¾ÃE¿+…å‡}}†‹~W ËZmJ÷œ.ý>!ÆÔ¯yÂïÓâ*þ>ú6û ü®–}ômö-ù\/,hqµ+Þp»ôø‡R½ç ¿Oˆ«øûèÛì4[ò¸^Xq÷Ñ·Øh·åp¼°¡ÆÔ¯yÂïÓâ>2fP¤ä×΀æCºnúvß»ù ×¾¾ÃE¿+…å‡}}†‹~W ËwÑ“Bo>¾«MÜÖ'Xúvߴϧ®Å°QO qehò…Á¤²þZ·;Vá*×ev½…§ôwŸ:<4ýJ—%Բà Ñá­ÇV£²P”“wRŒÌˆˆ¶™˜¬¾›øs дDr……ðý!×j¤N;”Äw’iÎi­´=6½®D}3ê`õUGüa'ý*¿Úc–«ÕªáL<:”«ƒ´í¤š3“Î¥'fšIz瘬jÜ[‹1Ü‹¤¯GD§'ÅpÔ”ƒÞ%¨MðÍI¢6XdÊ;ì¤ÛÉJv"ÄVm{7Zǽ=)._‰×­Fé­Þ¯C•âØšØz[P[½^Ÿz|zÜE=;è—ù*ÈÙ= æÒ¥’MF’R’E{%G¿ lÇI VηNœó,¢;RJBÏ…ÎÄÛˆ""ÈŸi}ýº›¹pÞŠêKo6¦Ôm:¦–Dec4­JIíØ¤™o##0•+T…ëFÎåœ jõi¹WŽË¿õõ ‘àE92”¤¶KB9¨RÌÔ¥RDI#33Rˆ¶Hæôkƒ]ÁÔéqäâœC‰$I§8M^rßSm‘ž­´¤ÌÒ›$ùÊ"#Z®gbÊ”î1L)U 2˜…ª9 }‡N(Ò“Õº‡-r#µÉ6Übz®QƒqÞí¸±ZR9J í'o™‰>£Rz{TÛ²†\[¥6¬¶êó6HFu$²™‘¸ddG»iXl©5(õÜÕ’Ú}•d~;¥gVû(¿ï#-†V23!_Ï~eLhÕéŽrµ2m>oÍ&‚4’r$ÌÏ9ZÝF:l1 õE5ª‚x:‰ƒa¦ Æ¢lÎüõ¯Ñ¹;H·™Ÿ'ŠÅTÄJ3—¯Àâà1¸ºØ‰B¤-¯Ãwï¡Ó€×âJSuʺK“jS%¼…&¥GÉï%¡Äí##">’=ÆFFdzíá§p¦H“^«W¥§Ÿ&}JJÞuç ŠæYÔ¬ˆÙbAˆ·ÝF¥dï›JíJ5.©,̘ŠÊ]·™n/æ{…uNÅ•*Ë­>Õ~LRyÍ[hfSN{4­ÖO9ßg®Yº·[¤%P`ÄzRcE•,Ñ%J&Œ e×X•$‹2w·@äjѤ%GôȪÇa ]=•<ÜeGzÆJY©´£e¢û/³nÏ¥ðŒ,<Ÿ2PRmúéÃrj׿Ån>wÅqOÎT•G /ÂÿÇò:Œ%Q­Èĵ(UY‘d4ˆQßa,0m’3-ä*÷3;ž¬Œö™âë>¬qš,‚´Óž«Ik,™JÈJ'œs3)Q䱬Ì̶¨Èö_5ìC³ØÌÉSVJËÓÑ$ø|N¶TËÇÌwo}þnæ–TÉÓ$¸Å4"d–jÕ¥&µå;(ì¢=„{7\ÏvÍøÍÔª52*åÆ}&¤ë‚3IoRr‘nê2Ú[Kùÿ :TªâŸ’ÃÎ)¥ºë(iVÎjYšNÿæó¬vÚGÐd{qq îIeäFy©‹eM8…УµˆÑ}¤[nÙ¼ÏmKμŒŒˆËiá‰VžÝ>2\RãŽ8–™i; Çê¦ç°¿¬÷ –ÒÊ{ ’DêüO™´g#ÉŒr£›-æ‹zЗ¥m-¶#ÉJJÑvfSK{4uÚ…J 2s–SºZm)h˜J¯´Ï23dEÊæj+ÿ#;ËWWVŒäiÍ¥Š¤[–’FIQªâ/·"¬vê22ÞC_Qe4Uq[s¦kZj+ónù!³q´š,£¾ÂRöã½ËxÊÓ#ÕfÓªfìI—A‹Ã`“d¼«›‰ÙêÈ®Ÿä]B¶[ Eùõç}ïÓäêÖIDl¿3m^ÿÏÿéœÿtÇÇGØ8sèñ€$¢7 &‡J‰!9ß}Èí‘ŒÉ NgRR£CM¸¼ªÊd>Õïñÿþ™Ï÷Ls”ºuEÿ£Î‹+t¸ÏM~O¦O\F[58û*§ª3¹H¹Æ¤7!n’RJRÍ¢BJë#-ñU*ÒÃÔíME´µi;/ÅšÁ)I&ìŽRF3ÓÖ(µJeE&×b³T¥CªDCSÑ›Ï!ƒˆì†¬S#­Ä"KœÒ¤º‚B V΄4„!a4M“0ꌴÂä°VI8ÛÍ%ÖŸB3)ImiQ•ŒÏ*Ûu¥êó«ÏTäÓ(­M¬áz¶"8í¥i)Ôú•9ÈÌÓRÛL¥ :ûdÚ’´¸yÛà‹3sœ““sýè Ä:¾"§G\J¸°i”V•s×Cˆ— ¥¨ÐµHZrç%¤¸JR\IŽ7‡xå?Ũaã+Y¹mZÊÛ6õvw¾ï]ï‚/×Áª46§¹î·Ç_¿–¥…»Â1ÅS ð\¼›wÖ_Y”Œ™m³/½îwϸ­·1𤫒¨¿š|HÌÊ}¬Šæ4òKj½¬wS•ˆîYvÚå~±h˜§KÕÙxŸ·S€Xv˜ÄUÊdÔγ„T Ì—æëJlî\äÊÆY¶òZ2ÂÔç1=~5ÁG*­YÀÔˆîÍ›BSÊáhbR&¢C¦Ù“KSKiµ¦œäD¶Ê>”æ—M ©¹C[¥¿Â T#7*+¹cN$”…YDFWI‘ØÈ¬f6G£aÚfŠtQE‚f´ˆµÖ¯ÓZ¢:˲e·G”O¸mä#”WI–’Y8”™«i SaGÂHÂõtá×qDGèT¤Æq§¢´ODÕ¹©3Jši’ãæ“"ÊÙÓnh¸ªbª 3ølý_ÇnDë2µjælžªO2!óSunÙÎ+î…-ûÿÁ?‹Òüd¹‹ÿè)ÿ»?ÿ¢ø?øæc‰]ôºþŒÕ½7ô³„ñçsUÅ|+>^lš¾ûNkçÛ“ø€øÀyÉ0cÈz#ÐÝu¤­qÞ4Œ™•Í 4)I5ãÊ¥Ëa™mî£7M‹‘ƒ"j¤Ôf½2£6„ôy1¤¸¤™Oͪ’Á¨Ò„3c4¥H3± ÇËCx!—ªv~'Ã+Sô¬†ÙŠsâ£Ëhå©Â"YY/¶z¿é£1nÍ´ žÎIƒCцë­%kŽñ ÜdÌ®hQ¡JI¨·U(®[ ËhÖc*†*…kjP äÖd· –Ì|÷±úºÜÖéËk•îTì7.6ÀrŸÃªµ¨˜:ºLü<ü¦‰ô7ÎCo¶i:|‹”êìDDóNÖ¦˜ØsÐÞÂÈ£Õd ªT<Ó*&œeuFõ¤…¤ï™´2¥®ÖÈ•!WÛ° 5ˆ°L{ØÞ‡H£N¤áÉTªD”3H§Ú\’•+_•”Øœ»mÇ'[O9H;XÍE},(Ž›„bV°¶D*„*´˜‘ Žõ=·ãÊŒ†ÊGpÍqЙ–“±eak±f¸ÿ繸?T©’¨õÊ}Zst)”Z9*Bõ“"Y‡ž’KNÓ.˜ÙÖ^ª™tÌù»;Ê%.&ÅxÎE Jb€Í ö R¡sdJJçk’Ãed©å!ÈÒV33nþ±¯ÇußEð={p^ÅÙ¸>³&·TÒ—“5-òÚö;_q†®ñ½_Óø.§‰*HƒŸY›]š$yíbËþ–Û}KßmЕӵ™ñ´ŠÝ[Öëõ¹ÔóN• šìK\)6êÉ“'Éå)&i7²"%ß(ÚÍ¡V¥lEV®R*\æ!ae˜ëUŸâønb›"3’ÊV…"Årmh5YF“6À²+Ê_HÃ,#…M›91d‘’QR¸’ä!wËe™ðE')‰GÐJé… Xyœg&‰YŸLr£N¬c©s$§"”ÙCb2#å¶KÕ4v>jëóX槆N™¯HNšæ …ŒÚyêLHk[nÓ•LdÔM0’ý£%1yÔÚÈò8V;-\C]⊾§ð]wÔ—>³.§,I3ÚÇ›ü-¶z÷¾Ë×x¢¯‡)ü]Çu%ÁϬ˩ËDŒö±æÿËmž½ï²ÇJÕh-.‹D7ðmmüŒr¹qi§:§#S¸±öÌÕ‹:9âµF’º\J2ó‰&ªPYU†o`ÊÛø=årâÒMtÜOâÇÛ3Tb,èdäŠÕJéq(ËÎ$˜쇜ièÈDGŸKΚ¶Í– "•y”FiºI<ÒQÝiÙ—2‹WéUж±þñ½ ›“©]ÔÊÒJB‰sÜÉEdÛ5ÎÖ¾ÁVÑ0⥮f[XQÜc-Ø”ÉT”F§.‹)•Œ¬¿dÒßS–BȈ‰ä&År!‰i”øÚ0Ñæ‡‡×D™"|2¯G]-pÔãУ¡ù«2®%¸Ë-›©Ì•ç¶c±Ø {×}"¤?Pà¼URŸ&³=ø4·£ç½‹ÖÕf·Fk\ís`Úï¤T‡ê‚êªSàäÖg¿–ô|÷±zÚ¬ÖèÍk®t® ²ÝmE VácNfKãwi®¡³§M×>e“R¸æ´“Y¹ÊY,’w% ²ÝmE VácNfKãwi®¡³§M×>e“R¸æ´“Y¹ÊY,’w%.¬C]⊾§ð]wÔ—>³.§,I3ÚÇ›ü-¶z÷¾ËeF©Ÿ2›cú§ªrN,4äQë&\xÓr+ìÙqW;6Û̈ø]#Ó™Æ5ü1H›‡ê)´ÜTiœoÇQ0ó|Q%dálSÞm£5Xd¤O_Á8ut&§ ~¢ãe¹"hjš†`=DI/RÂ[R”ÉÍZLÒÚM$´^ÜÍ€_ÃMŽë¾‹àzö&à¼/Š)²'p}fMn©¥/&k[åµìv¾ã>:ÀqêtÝ1WœÃOÊÄêÞÃòJ:Ôú\n‘T¸†[IZä©9›Ú¥#)ß-‹úÒ†fEÁ˜m暪`*ë u¬æK"ŒQ‰Ã"3qõäe5]jº÷ØÀx>¿ý)ÿ¸¡÷ _¿‹þ”ÿÜP²Ä¯ áçšb¿‰(Ô—]I­´NœÛ ZHír%¨®CŒÒö! bãW¨ÊeY¶io%ÕÁ–‡Òƒ4‘ ÎÇýcw¥Íд“…—D¬¤Úu¬‰1 #r3ŸçYãNã.£"2æô…„è¸'èÛ‰pí11=ý§µn¬ÓÎZÏ¥GÒØV""›¨çqv z˜|M9/P¹.­Ó2j;(õœ]ˆÌú‰$WQÿ"3.ˆp:LCМ¨L±z0¡ª2$6ò ÓJT£Øœäñ‘캯s+Òñ µ(áå:|J^!Ztpòœ8ŸÃ¸¦½G˜ï;j#í—0WK ÛuTµç""3è¹Ó}ÇÞ²óOGD†Ö•4´’Ò¢=†FW¸à4ŸŒ‹O‡ ¦ÜþâS¨#™)[yˆ">cjØg{ìÚ¬¶ê––æ‹dá8Ò’‰Š¢*œÜ‹™8ljÉwß¿hƒZS©8)íÅp·Ä©á¸™U«R [qV³øéñ"<Âóf34ÉN%÷ÓŠŸ ¢ºµ’HhÕ*ædEeï°`úAйNâ>&þò^Ü#»û½F}¾«÷¿²ÔÛ?ñÞÛ¦¡_«ÎM )¡Ô£MˆÜÊw—T}sDù.BÚSyPÑ;”Úu&wéØEÉÖâU×ZŸ ðZƒX•‚[íáùNÊTC–”­Ó¨›„Þ©M)FmTHIå²I9“Ô:å×:£ ¨¥=«v¡ ãENS=c„ÓŽšnE³˜ÒÎçbæÛy‘¾«^rf‘O]5ÒMJ¦¨yn$ŠÅ Ù:Ô‘™•Ú6쬧{žâ#W7¦ -"£' T«Xm¸4꫊–‚¥œå¡…ÄÝ% R’n›dD{R“?Vå…Å•.QxWËàþ›ðn¥Y5>jµ—µ²k9™·fæïس#¢’¢è³ ²ÅIÊsR±5i¹/¡-™“I‘Qw{‰RH³6“½º\8 ꦇpÝ2;Ú—¥â,@Ãn\Ë"–ud‘ìê3pŒêlË…ŸèÈq ª{¾©ÖÓ*xÒ¿ ªxié.Ò–µwê3cÆ\¤ç[Ba¹Ì3¾SQ¤ÌŠö±‘¾©W\¯Ò˜ªQ„ΦÌô*F7q—£¡6S)"22uG¼ön=ƒ˜Ñî)¼×&Ó0þ(¢BD鵩e&ãHÈKJÌ3KÊJ% ”V>‘¨“¦¬#FªP1>=©GÃé‘§*2[RR™FvÞCGÁÔ«\Œ’ãGk,„˜Üé&ã %$¯w½~.ÎëÕ+ÁÆŸ™ýrosõõ³·æ^€5˜V½LÄøv ¢ºóÔéÍk£:ìgSˆ=Ë$8”¨’{È̬dder23ÙŠÄÀðŸû„ÿ¥oýôý>Éåþvÿô¬{îþ•¿÷Òî’ñq­ÅÕ—$®gs±{õ¨]Ò•S1ê±Þ9·Ffàùc‰áþ7CÄœ–2–ͯeÂ÷·è˘Œ°ñN´’½íw§Ôö” ’²H¬D$xÝZR¯ÿ;Æ_ÚÜ?,|•¥,Mü8ïkq<±ÔN³ÿj] ŽT¹‹©ìÐ.V”±wðã¼Sý­ÄòÇÉZRÆßÃŽñ'ö·Ë¨ÖíK¡¯™KßG´‹÷[uæqƯ«R“sM÷Øÿ‹ýCìJÒ–‘‡Öÿµ¸þXÙR­Ë} y”—÷#Ü<6­)i3øqÝ_û[cË´¥¥áÇuOím,oäÖ÷:—¼nÔ©ÐjIe3¢·!,:O4K+’VDdJþ»qáL>gn/"kØ«&{»äÿ¸xÀô¥¥nŒwPþÖÙòÇðzRÒ×F;ý­³å‰à±pVŽÒ"›ÃMÞVgºÛB[A! $¤·èx@ô¥¥þŒw/û[kËÁéKL}îOö¶×–#ËV÷Y¾b—¼{²\H²ÐH•·’Gr%¤ŽÆ>q)Ðb,×#M(÷šk ”´ÏÑŽÞþÖÛòÇóÊ–šþý¹Ý·å²•½ÓŠ^ñïpåKM~ÜîÛòÕ-5ýûs»oË ¥otfi{ǹœ¡QÜ’rWNާŒîk4m¿þˆ†k,2ÏîšB:6ðg*Zkûöçvß–©i¯ïÛÛ~Xek?A˜¥©îÚ³N?J–ÃIÌãŒ- +Úæi2!°Ñ¹9†´y†ðäÇ¡;&•I‹çqÃBÖÓ)B7lŽÆi;\ˆx •-5ýûs»oËT´×÷íÎí¿,²þј¥©ïÉ´, 7'ÌÂ8bMi.¶òj.ÀBä’Û±!déµ›2r¦Ç{–R¶áÐqÓ]lv×ùç*Zkûöçvß–©i¯ïÛÛ~XÎZ¿º3µ?G8é®¶;küÇMu±Û_äœ|©i¯ïÛÛ~Xr¥¦¿¿nwmùa–¯îŒÅ-OÐú‹Ôº„Êl¹Œ°ëÔÉ'*µÎ–­ÓeÆMV$Øÿfó‰±Ü¹×ÞDe›ÇMu±Û_äœ|©i¯ïÛÛ~Xr¥¦¿¿nwmùa–¯îŒÅ-OÐø‹¢Äà|›JÀYTxš¦Í<¥eÌÛvoš“È‹‘X¹©ê!›ÇMu±Û_äœ|©i¯ïÛÛ~Xr¥¦¿¿nwmùa–¯îŒÅ-OÑÎ:k­ŽÚÿ qÓ]lv×ùç*Zkûöçvß–©i¯ïÛÛ~Xe«û£1KSôsŽšëc¶¿Èt×[µþAùÇÊ–šþý¹Ý·å‡*Zkûöçvß–jþèÌRÔý㦺Øí¯ò5ÖÇm~qò¥¦¿¿nwmùaÊ–šþý¹Ý·å†Z¿º3µ?G8é®¶;küÇMu±Û_äœ|©i¯ïÛÛ~Xr¥¦¿¿nwmùa–¯îŒÅ-OÑÎ:k­ŽÚÿ qÓ]lv×ùç*Zkûöçvß–©i¯ïÛÛ~Xe«û£1KSôVú|LÁ X¬ ›e†IHm´‘X’”“v""è!÷㦺Øí¯òÎ>T´×÷íÎí¿,9RÓ_ß·;¶ü°ËW÷Fb–§èç5ÖÇm8é®¶;küƒó•-5ýûs»oËT´×÷íÎí¿,2Õýј¥©ú9ÇMu±Û_ä'ÓÜšÌç#A\¦¶Ú}D£q´¬ÒkJU«¹ ¹ü¥}Ä?:¹RÓ_ß·;¶ü°åKM~ÜîÛòÃ-_ÝŠZŸ£œt×[µþ@㦺Øí¯òÎ>T´×÷íÎí¿,9RÓ_ß·;¶ü°ËW÷Fb–§èç5ÖÇm8é®¶;küƒó•-5ýûs»oËT´×÷íÎí¿,2Õýј¥©ú9ÇMu±Û_ä:k­ŽÚÿ üãåKM~ÜîÛòÕ-5ýûs»oË µtf)j~ŽqÓ]lv×ùŽšëc¶¿È?8ùRÓ_ß·;¶ü°åKM~ÜîÛòÃ-_ÝŠZŸ£œt×[µþ@㦺Øí¯òÎ>T´×÷íÎí¿,9RÓ_ß·;¶ü°ËW÷Fb–§èç5ÖÇm8é®¶;küƒó•-5ýûs»oËT´×÷íÎí¿,2Õýј¥©ú9ÇMu±Û_ä:k­ŽÚÿ üãåKM~ÜîÛòÕ-5ýûs»oË µtf)j~ŽqÓ]lv×ùŽšëc¶¿È?6jzaÓ->:^{¾¤©YHÓFw±ŸKÈk¹yÒçßi½Ë?E8NÒ$Œã%t~›ñÓ]lv×ùŽšëc¶¿È?29yÒçßi½Ë?9yÒçßY½Ë?k¼ÛqúoÇMu±Û_ä:k­ŽÚÿ üÈåçKŸ}¦÷,þ@åçKŸ}¦÷,þ@Þ7¦üt×[µþAP®6ÔuJK%Q’·S:¿jñ’d'9!£3±”’ë2-£óC—.}ö›Ü³ù—.}õ›Ü³ùxÜ{kÒüeðž¿ó:wê?¤ŠŽ9Å8¹‡chº·úŒc¶ã•*y¥*RLˆÎÒ/k"òó¥Ï¾Ó{– ró¥Ï¾³{– ÆË?D„(‰HR”© #J’¢¹( È÷üîåçKŸ}¦÷,þ@åçKŸ}f÷,þ@Ùcqú M¥Ri‹qtÊM:Ü+-Qb6ɯúÍ$Wƒó·—.}õ›Ü³ù—.}õ›Ü³ù-¹ŠŒU’?D€~vòó¥Ï¾Ó{– ró¥Ï¾Ó{– ÎË3sôHço/:\ûë7¹gò/:\ûë7¹gòË?D†§G©8ºl9&-Flö×[í©£~L‡ÎBHÉDÛæ•X̯šÆecåçKŸ}¦÷,þ@åçKŸ}f÷,þ@Ùf$”•™ú=Ái?j¨üîwˆÖ×ð¶ Ä1[‰ˆimÖc4óo¡ŠŒùRZKˆQ)*$9tßefÔ©h;¥jIþyòó¥Ï¾Ó{– ró¥Ï¾³{– ÕSKzHÖ4éÁÞ*Ìý7㦺Øí¯ò5ÖÇm~dró¥Ï¾Ó{– ró¥Ï¾³{– ßy¾ãôߎšëc¶¿Èt×[µþAù‘ËΗ>úÍîYüËΗ>úÍîYü¼n?Møé®¶;küÇMu±Û_䙼ésï¬ÞåŸÈ¼ésï¬ÞåŸÈÆãôߎšëc¶¿Èt×[µþAù‘ËΗ>úÍîYüËΗ>úÍîYü¼n?Møé®¶;küÇMu±Û_䙼ésï¬ÞåŸÈ¼ésï¬ÞåŸÈÆãôߎšëc¶¿Èt×[µþAù‘ËΗ>ûMîYüËΗ>ûMîYü¼n?Møé®¶;küÇMu±Û_䙼ésï¬ÞåŸÈ¼ésï¬ÞåŸÈÆãôߎšëc¶¿Èt×[µþAù‘ËΗ>ûMîYüËΗ>ûMîYü¼n?M«0é% [)I-*3%,ÎÄ¢=Ù?òoÓçüžP?çoÿJÇŸyyÒçßY½Ë?hq®’q¾3§3OÄõ÷ªQ™{\Úi²Ê»\)#Üf`÷7XòM6•è•Zƒr,õ9-:¦2zí)zµ/5öeZš+[n}åm¾¶ëPÁu8TºÖj¢d.›%‡bÌK %9«qœÉ%©'•dFdWIŒÿ¦7¾.ßüù?â«lP¿þïüM„Œ4©¬;„K˜ç'CH$4©M¾ëi5ó_TÒW|¹l¥f4å,úùZ¶Ë.>q™u”G\“u‰M:ƒm+Jd¤(ÉF“Zn’32#¹•¶Žºƒ¤xÔú…rzà-K©U[ÓFÓn6Ìb69£*î•S)R¤šO!‘ìßüÌǵVè¨S’gQc*Bf´Õ0ÔÔ”%§‰ Gæšò'bÔ£ÚIØ›mõMª—à|…¡n'2æ Å ÍàK¤hÑÎ/\F¥•>)4äv¥]UÉ6Øu Zp˶ْ“ÏYHÎÆd{ÿb¬᪤ү¡¼34Žã2£“3! qJp²,µŠ#I‰V"ÌãQQÅ”é<{‘™eÆj›IjéO5èÜ:•Îõ‚¹c+žÔÜŠçm6§µ¸Þбó-b…FY¢ž®Ã’[ì!–Ûl¢þÐ7l¢>љؓ•IQ)E›'ðb3Cð#\’y„4mHaÈÎ6ãrÖkÉ̹H£8yŠè"Jó)’%t5Ý!Qgài46cT%ÚcQ Km3¥ª: Ìó^×§?ÑüMìÚ¬¿ÅÒbá*5oUàȆL¥ÙQ£4í‰ ª)VBÖD´™Ni&•X”Dá¶_U6oc;4ïcHZ?ª§ ÖkOͤ´ºT¶[SŠzԸ˯Эo?š„åJIFæee¹¡D0ƒ+íâ7°ô†éñªlç'‘TŒÉ%HpÛ4–á'>b;&÷QYDF“#=Ígáz„KNf4Ú|yÏ™ãÂh‰oÇaæÕ²ZRÒ]SÊYä57(†cxà =Œñ}ze=ìÕZ›“)Ï;M1M6§\Z›SO+V•(”Ž?.C±Æv§÷øÙ‰Fuw©´‰o?§§Vݤ;¤ÆáM-0ß5¥¼•-f·”FƒË”’•(É+%ÑJïqÇgƒjµÙ8SZýW´ÔfÖäþž\¶Û{ìñþ‘‹Ù¯HE]¢ƒ¤bÍ7µë˜}èêRfádZRÅÊÙˆÍV¹8hý)¡eã«Txó‰8Ÿ‚jÁrð>­ÖçÍ}_;&O[ø¬0¥?PãCUˆp&( G˜õR puRÛnk»óe#[hY©)5l%Nåc;æ‡iZŔ鸇Hu™––±.·¥INfóÔ’ZÎvÎcJ-™¹Æ]K‹Aɯê4’Iî75ê˜ÂÝ PpŸÛø³û§Sû®Ó.z¹¹Ù5ÖÞY²ßeök†«J¦qEF«Prr†ÉãhŽÆá5›9£yæËkží£·¦ifµá©‘ñ%cÒÛ¥5"œÔÅ¥ DvXCéKD¼†KSnÛ6m¶¹“ÚAŠö&Ég¢šBiZ¦¨kAGàùŽjˆßNdoMŒö™’V´;U4%´50ñ~Œ«´ÜGUKŠ—iÌÍ–Õ<ߤJi‰²f–óœYJ¹%7Ù{XÈpBæÆ8ÇHÅX32¦¹ñ]•PODf”‹Zd†›}zÛ´«-&i$/š¢2=·ÈÍ)I¯ê1QE=À¤`ÿŠÚÿN_î¨r#®Æâ¶¿Ó—ûªˆâ㽩ÖÁû"D *‰èbz !H@z è````D  0ë°ôO¬yªF«¬(Ò¹tã2êqzW¬pU_ß,x¯ðÿŽâü*u¯êµî¯ÂöýYöØÏ ¡Ž¥:ÿÓ{~6ìS«À•to“¶¿Ê> ÁÕ4×áöÕùE›#pÖÉÜ>ÊŸñ—‰Ë‹],ÿ‡ðk‚}Jõx^z7½´¯ðr…-Ücû~·‘¸Æ®OH½Kø«Ä%Å®…Yx&z>§*å2B7­¯ì3ðÅqÍ?ëé[ƶFóéÿãeÅ®…yxFz>¦µdiÞ>Ku)ÞF>ÏŒ7ÅÈxæ-ú®„2ðÊ ^¤ªcIÞ•ÿ¨‡ðª‹ Þ—?Ô^#шïH³Ä¿UЊ^EUãô;þ¢ñ«‘ {oöKÄiÝ®î1b>']èFð4‘¾V"„Eµ©’ñ?I {=”øŽißTÆ?H±ufFðtŽ·ÒhÆOe>!é<c'²ŸÉ¶z©Œ#®ôš±“ÙOˆzOØÉì§ÄrGÐ 3ÕFN‘×zMØÉì§Ä=&ìdöSâ9 õQ“¤uÞ“@ö2{)ñIà{=”øŽD=Tdéw¤ð=ŒžÊ|CÒhÆOe>#‘ÏU:G]é4c'²Ÿôž±“ÙOˆä@3ÕFN‘×zOØÉì§Ä='ìdöSâ9 õQ“¤uÞ“@ö2{)ñI {=”øŽD„õ†z¨ÉÒ:ßI {=”ø‡¤Ð=ŒžÊ|G"žª2tŽ»ÒxÆOe>!é4c'²ŸÈ€gªŒ#®ôš±“ÙOˆzMØÉì§Är]b=Tdéw¤Ð=ŒžÊ|CÒhÆOe>#‘ÏU:G]é<c'²Ÿôž±“ÙOˆä@3ÕFN‘×zOØÉì§Ä='ìdöSâ9 õQ“¤uÞ“Àö2{)ñI {=”øŽD3ÕFN‘×zMØÉì§Ä='ìdöSâ9 õQ“¤uÞ“@ö2{)ñIà{=”øŽK @gªŒ#®ôš±“ÙOˆzMØÉì§Är ê£'Hë½&ìdöSâ“Àö2{)ñ—P€ÏU:G]é4c'²Ÿôž±“ÙOˆäˆ@gªŒ#®ôš±“ÙOˆzOØÉì§Är ê£'Hë½&ìdöSâ“@ö2{)ñ‘@gªŒ#yˆ+ªË-¼•%ÂQšÈˆ­c.ƒþcD+Ô©*’Ú‘=:jš²$@‘3rzžH@’žz‘DL:ÀìýëzçE­7ÁšyýI9ÒFiQ¥v±ží¶ޱ ¦T£ÓâÖPä…2ûÌÙƒI*æ¢J­c-ÛL‡ˆÊ”qéÖÿMïÿÕëù|O»Æ)¼¡ÆëõGóJï ×«S™%ðSTu/"Í&H]ÌŒ¯cÜ9ø8@¥@†üÚ«0\žyb4¦ÍFáô\Èö_gúÈlèÕô¢‹ZU¨¾ãÆ4FKª[—Q¥dd[í½=Cù\ LƒCr©-è’(ê#&Òɬž$嵌·z©ßüÿ¬}à*Ó¦£èžé4Ÿú·Ý«oµÚýÎ5G‰„¥}}ÃÒ÷õâbá :ÒcbÊuV<>„¥<‚Q2f—9äfW"Üw-»sîa&éÕ¬5=©ŒU©5 Ì·¬ÔšHÏXWB’«ì2¾þ£¹Ž™‹(²%â©gœŠÝM¤6ÒÙ©jI!hè+ØËy‘\ƪ¥‰(0âáZ%>k’aÓj Ë“)l©²ÌÎÉßüJ=—èÞ/ÓŽÊšÝ{;ïÿ^믊ø¤ëm»§¾ß.Èǘ%OVΉP‚ÌÈÌ¡ôR™Ži² ´‘í+$ŒÎçb#ÞWµÆº…†éó°^ z©ÅMDY&\Z)Êá.sž³ky+º’£I'Õ,·Iß›·/àên(­âÈ9§ÈˆQÙÁ–”­D”s‰F[¹©#½aÚ÷!ʳ‹¨q4w„)ç)NO¥VÑ6Lt´«“iuÕ\”e”ÎÊNÂ>ŸëÒêŽJÛï뻊·UèVÿ¹²–ÿOÐçôñF Ñ±‹¬Ñe4•$Ÿ€Üe6˜–i¼¼ãؼ÷5lÝÓ´V¯‹ Mu k¹]¡U•8¦¥&óGmê B®«f½Œönëã-æÊÜ/èf7ÙW0ÝŽôŒ·F#½"xÈÄtb»¸ÆS£ÝÆ.À†F#¾©Œ~‘ïªc¤[ @“60Iô}OX‚Ö€=bõˆ ©ñ0&Šte†+ø‡GÅU¬HÑÉJ%um5•*±’¢+%Ä ÌÌö‘ÐUè=ÒN–(t}¼ýš£*i*!›QÝCJrÈA¨¯|¦“"2I\®3ðæ3Ѷ2Ñõ i5ê•2M¸s¢$ÔN5b"IÙ*2Ø”‘–_á##-¤>-ãíP´Ï†*øN†¨4 ;kbD”¶¢vN±µ6nLîyIW¹óoò ‚‰¢Ž3åûÿªô+]ÿ¹æáš½ôËW}Gô½oå·'hž•‡t}GÅu,nË.Ué…2$SÕÇM¤8L’‰fVç̈‹fþÎíÏE´Šn”Ž™‹%M™Šã¾ë)rœóhÖ8‡ò´“ÊgrS‡u(’VRzŒÇ ¦¼_‡±ÑÅ*QáRèÔ³b Þ¥Äj\ÕGM®¤‘+jWI™lþdûiGCp°KìS‘ŒÚ©V¦êJ94õ6äƒ[º³çgRRE²×>vÒ±Zã.¡ uµÆ4˜ÊŸ?SaÙttFZlƒ";%Ó;(ö•ŠÅë&ö¹Óæ¨U0áì[…f•N=*4e\Úq¢7Zã™l´‘î4íµ¶‹i»ÈLÊÜ "W£¡ÈÉàØ~=:\iì¤G™÷ZZM&{Oi™\ìg°€uDtÙš3£cª¾8‹E‡Q”¦CðT½Uœq”Ò«¬ÌÛ#µ’DFfgÍÛ`è§C4:˜ªx{¿¸¨ô¤N§Ç\eBȧTW4‘ Ó—!æ¾²åêŠûâì=3èÏ…ð|j†zä¢äI‹©p²6j’dyÍ9÷ˆØFg·ù´$é‹5ôc·Wqú3˜k‹\”ˆŽ–©îníI¤”eb-¤Gëó°lÅ0©4úì˜t:×ÓÛË©ÁU[t‘«öjÚ›(Í;wÚý#Ö.aL'A RKhš3 Èˆ‡$Uq—%÷©(YfY™m²T’+Ûe‡’ñ$Z\*䨴Z©Õ©í¨‰‰‡L›¥b3<ŠÚ·-½CÐZ>Æz£±N¬@®b\))„%RèÑßìi.­˜”K%žîrvuᣠ£:õ;Iu-Tˆ,BmhŽÕN–ý£ef§$£%¨–K"MÍe¨-¤j.ÑmË6[Ò FÎD×cSZbžä‡ßm Ê—i*¼t«a–³ vXgJX2¥‰´šu™/Ð`bبþ §µd–\hÔ¤"ç˜ó’íº÷+ô†Œ1öp®fšÕvm2¥°re?ž£vµ·m Õü RMd£+e2þ#eèÛEb™I4ì_6Õ:3ß8Ž:˜ .:ÜL¤•쵞R,É6¶8…g‹ôo‹¢øò$ã8sê®Áa¾læm })zæ³2ÌL‘å4‘–{_fÛUZIÑìœq¤¤HÄ‹j—‹i‘Ø=^Y2¤G[*% ÒJ3çf-–>²ÌlM£Š®„á`:æ# t:³²X[õ­SÚÖ:iÊ[jK¦\ã+t€1ªšÖ•âàHX™å+ŒÞ˜äCoTÞµMšIµf;’zKÖþCÒV£áz|YÔlmM¯¡çTËÑɾ .:Êþ» Q­)æ™\Ⱥ:ÈYø÷Hxµ§Z^"Š«q)lQSŒ)M©§|žqYT—[3R2«iN÷.£!¡úAã\!‰°Å:¦œEˆc¼j•Z*iÃ5µe6i2+žÔîÙÍ3+^À Tƒ : $@zžH@’¹~ˆtjEsI5•ªTœtQÝq-Kއ•“Ì‘(‰De{•ÿ™Ž¿à¬7Ë¥F³&ì.ô(s Ær:ÆiËm¶“Ë-‰JrÅm™JÂú/bì=ƒ1ôê¦%¨pnÒÜŽ‡5.9w Ö”Ed$ÏrU¶ÖØ7ô-)PšÑî£Ê—ª¨À­Ããg5+3LÏ©Æö‘sˆ³ˆ®{fÐ轟O²›H:v¡R#Ç“-ä°If23j<­¦Ås<ÊèÜ£¿_3]ÑáÏÂÒñz¶ÄÓš…¨Ôe ÛZÖIç4£½Ëœv¿ð™‡t­*`µéW¢TÙaœYˆ…Pb:ó4hŒMäQ­Ïp·^ä[ ŽãWTÒ ¥ÁÑÞ  ÔߨQðõmŠ”ê«±VÑ++ÊR²¶dk±k;[ ˆ®þ]ú>²æ!¬aº~>.¹2e7à­ q³JlkVc$eZÄjØi3µì(³ÃZMÁþ’ø£I­ä¡Î¥"†p,|6ÅOV‰´HéLÆ”’R5o©6I™ÒE°É7±ïä>ŒxJ—Œ4œˆ•˜é• G&8ÂýWM*BJë+¬ŽÝ6¶á¸Æ«aýÔ4‚kk©ªÔŠcÈŠ¦x3dm™ ÍDY•û$•ȈŽê=›s?Gìo i ª½Mœ ×J›Ne!*4¨”EÓe!7.«ÿP¶ÒÖttŒº$:Z…[UY¦µ«lØ'\#Q$¿ˆ’ʶ–ÓÍüˆvÚVÂø*Äò¦aJ.’ÔV Ô`µi2ž[FvpËlùK¼ŒÏùŠócì!LØ+ai×ét ™T¤¼ôu2—ÌRɲJÊûœYÊÛ·í·SŽ´¥£ç¨8Úu.­:«?Db:)CZHhÛÌjW4÷ææ™íIX—©ajD]RñS² ª¤Ùjaê" øÉ#t‰ÅYf«­'µûÂÛº÷FÀn¢“J†Û"t:KšøhÕ¯*Z2R)5$É)µ”Ö9Ú•gGxóKÕ™ØÂSX~€„>˜R¨Ð”Òæ,¤¶ë©Õ¬ÍÅ¡j5(Ò›åNíÆ.€p…2­_‹ˆ1Jt&* Bi¥¦å6c«$¶ÉúÉ+ç_ôKnñß#Gøz»ô±­Ð—JŒÕ©§3dËK³ &ɱÜ#>½·Þc‡Ñ~–Ý¡5†påVƒ†_£Sj tæÊ§­é1Ò·³¸ê •±i#;S~jwØvӴ݇¢éø«Ðá@w“ ŠåF%5*Jm“5;žÊ^­m$¬VMí}€céI\<=Aœî Ã4¥HZȪXzVhÏZÿ²R D²Ùκ¯•V>‚ãôO[Â4•˜—9_šqòR£)¤¸Æ¼ïcu&¢¹_)l#ØjÙ{ŸKx¿ žŒ0öŽðJEb56S’Ýžìe3sQ¸iA%[áUsݰ¿³[ôy›èØÅuüiVD./A.žÚâºòVùÞË2m'±½ŽÛLŒ·,|e£ü-TÒÖŽéH‹GX†r«´¸…«i¼ë2’KÕÌiu-±7ß´cioaŠÎ‹ñM~•†é”IxW¹KB ²MëÙJÛožE±J3pŽûö3ÍKÑ0þ˜¨ÚA‹ŽÆo®K«¨)nÃ8íI”†d¢Èµ‘nÈWßq³Ò¶?Á|ž×pީɪ=‰+‹«L[‘VÊc”…›|ëf<ÈNí›ÿ•À±Gx7Ž9)ôf›¯ô[Œ¸ÛWý×Âuº¬ÚÍöÍÎË»¢ÖØ9màHÑ…+¢†«U:ÅIMkÎåe,%KF­­Šýª”ƒ±’OQ ÃÓ.Ö>)Ó=*ôwŠ8«‚«.·Y¬Ök}\¹¿íÑ}ƒ–ÑN?Á瀨XkUeRÃuÆêðÝn2žL’J”½Q幤ó-[Oe¬«4‘€ãªÄN"* µ$Òtò\–eÉ+±fIï-›Œ‡<:­-bv1–‘k’3 f<ÇS©BýlˆBP“;n3$‘Ÿó1Ê€?DúÇUýòÇ{Ö8ÕÒêu9•62i·lü…9–÷µò‘Úö?õÏØDÝV‘è›q…äìs7 lî{âÅÌ3X?ú“žìŒT\Ü/X?úšüÐR‹\QÍ©^“þåÔãdn1«“Ò;‡°6Uí…+ÿT_€ÁG8ñWË„«ÿUW€éQ’\YNuaª8)[ƶFóú1Ò ½\X?ú²†Ú*Ò:f ¬ý\ÇJZkŒ—R¤çJíñ†ø±Ñ’Õ»V;Šî‡´ž­Ø"±ÜŽ…"9ÓÃúÇa>!ŸÂócÕw2Э@Y|‚é‡áýc°ŸäL?ë„ø† ÍUÜlËB´eò ¦‡õŽÂ|Dr ¦‡õŽÂ|C?…æÇªî6e¡Z€²¹ÓÃúÇa>"yÓÃúÇa>!ŸÂócÕw2ЭY|‚é‡áýc°Ÿ‚é‡áýc°ŸÏáy±ê»™hV ,®AtÃðþ±ØOˆr ¦‡õŽÂ|C?…æÇªî6e¡Zž±er ¦‡õŽÂ|C]0ü?¬vâü/6=Wq³- ЗÈ.˜~Ö; ñAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+@W ºaøXì'ÄO ºaøXì'Ä3ø^lz®ãfZ¯Xeò ¦‡õŽÂ|C]0ü?¬vâü/6=Wq³- ЗÈ.˜~Ö; ñAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+@W ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2Э@Y\‚é‡áýc°ŸäL?ë„ø† ÍUÜlËBµW ºaøXì'ÄO ºaøXì'Ä3ø^lz®ãfZ  /]0ü?¬vâ#]0ü?¬vâü/6=Wq³- Û @²ùÓÃúÇa>"9ÓÃúÇa>!ŸÂócÕw2Э@Y|‚é‡áýc°ŸäL?ë„ø† ÍUÜlËBµê,¾AtÃðþ±ØOˆŽAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+b,²Ð.˜~Ö; ñÈ.˜~Ö; ñ þ›«¸Ù–…jËäL?ë„øˆäL?ë„ø† ÍUÜlËB¶ èW ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2ЭY\‚é‡áýc°Ÿ<‚é‡áýc°ŸÏáy±ê»™hV¢—È.˜~Ö; ñÈ.˜~Ö; ñ þ›«¸Ù–…mÐ Å—È.˜~Ö; ñAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+@_ ºaøXì'ÄG ºaøXì'Ä3ø^lz®ãfZ±YhL?ë„øˆäL?ë„ø† ÍUÜlËB¶è,¾AtÃðþ±ØOˆŽAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+PW ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2ЭL Y|‚é‡áýc°ŸäL?ë„ø† ÍUÜlËB´er ¦‡õŽÂ|C]0ü?¬vâü/6=Wq³- Ô—È.˜~Ö; ñÈ.˜~Ö; ñ þ›«¸Ù–…jËäL?ë„øˆäL?ë„ø† ÍUÜlËB¶,¾AtÃðþ±ØOˆŽAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+PW ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2Э@Y\‚é‡áýc°ŸäL?ë„ø† ÍUÜlËBµer ¦‡õŽÂ|C]0ü?¬vâü/6=Wq³- Ô•È.˜~Ö; ñAtÃðþ±ØOˆgð¼Øõ]ÆÌ´+P_ ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2ЭY\‚é‡áýc°ŸäL?ë„ø† ÍUÜlËB¶0ëW ºaøXì'Ä9ÓÃúÇa>!ŸÂócÕw2ЭoñÆ Äø"£›Š©R¦IŒRšeå$ÖmÖ‚Q‘ۜڶe÷è˜Î3JQwLÔýëW÷ËïXિ¾Xüÿ…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  I‹èØûì鎎ÛO8ÚD†ÝJTdN'PµeQt–d¤ì})#èR‡™5 ]'-˜¹hW'Ð Z¸‰O3c=&¥3IÔ‡’kVlª5$ДÙ*A©&“¾û\Èeb<JÅXʦ?2øX‘dœ•¥m;Âe)²R’Fœªè3UËnÁ2ÂÉÆëø¹œ“³*Cñi”iGRª)šdÈL¸RßJз NE8„¥$H͈ËiÙ)Ú{Š—Ö¥åÛí~ÆðžÝÀ ¡qi˜‡Gú*¥×ݪ:äç¦ÂŽó¤›ÈCi5gJ³%$H"I[ao+”˜Ð©š•FÄNÔ'E¥ãWa ¢>H2ÊÉß)­*$¦æµX‹iŸEÌĹ_[îµÿ$ÿr?;áëþ p¡Š´uFÂQksjó'Îb%]ºdTEZ_=‚{X¼ÉUì•e+\ÈöØVtaA‰Š±THÏÎU?GˆkDŠŒv’ëäF_¶q m¤‘¶’ŒÌ¶8ˆ±”¨·?¾=™Ÿ>‡rŸiSð&v±]Šª¤™±ááÕV˜\ì:l©ÏŽé¥*JÔF{ÒiØ[¹ÅncIXr›GU1Ù*‹U£Ç©!•8Ö´•t’DJ¶]ö-ãIáçí3hÕŒ‘ʲôù—¦±_zAAs L[í4¯[.R%[q¨‰K"3ݘúÌtú!¢Å¤i ×hrg³Çœ—"¾ñ)i6P²RT¤¥$´‰ +¤¶¤ †ô°®¦ËOå¾ß¹¬ëlßw×(ÒÖ- !…ðÔ•á\K‰ÏA{µI— c­¯X³$©+/ÙÛ!ßœƒ#¹]9¶Ü.a*.#ÒÎ(¦ÁeÚ]>”S¤Èk„´’^©ÕV”hBAÝ$D¬Ä‚#33-ØËI¤×©Ÿ9\¬Z0p&‘]§2þ&‹‰_tâ^3Î5! "K*ÙdK%‰Yz ¬f7t%‡hµÜON©áÊŠ”Æ‘;$Éqß$¨•µl8–­sNL®X&K#J®VÌp“|L:ñE&é(ØT—U·`ÖfÒY-IMö¨ˆ‰Gn’"¿Qn½áÃŘΛ‡¸IF)n(”í¯•)I­V.“²NßÌWŒ\¤¢¸²VÒWf‡¬@°ð¦ÃXƱEv³N[•ŒéÌÊòTÖ©× d´¡)BìÑ‘ îgšäg”ÇÚƒpÍ^5±ڦϯ•Dwd¶o’–’4:…“v±f¹¤Ò{­}·)–rW_w#ub¸•° àÜ;F¡J¬Á]UÖiøÚ,–^}¼Ï! 5æB‰¾aØŒ¶’¶í·@ØéGXv*MTßÃK‚fr]mhy2H¶Y(I‘¤Î÷¿ò·HËÂÍ_áٿمZ;¾þø•8ë¨Xz’œ+VŽl†QM9˜°ÝCK5›zÃZ–¤®É"ØE—iõa7do)(œˆ * øª°µWÞnŠ˜°YÐÂD’O1ISFdi3Qg#4¨Œ”Eo[/“ºJª£„TÔ×¢^‘Ó•®A)¾oî,‡Ÿi–ÔåØ[¶ì›+7÷óìiçDª€‡]¤ì;KÃòhJ¤œÒb©DRR%:—Ú5Ý$¤¡$dD’èëþ¡È‚pp–Ë7Œ”•ÐjèÒ‰N¢IÀxŽDš™Ô+usj7y-¡”6ò[Q8YLÖKÌddFžižýÇ÷¯ÂfE/KòÓ"c/D­ ÜBVÙ²úW1d’RM²4™(î••îW-›l,3Ù»v¹¬¯o¾6*NÕŘ&‹‡pØ“L©T“£®5^I•6Ûæ´_XÑ œjÜì¦KQ’²Þלð¬BÄx·ÕX™-„½‰ º”¨ÈœN¡jÊ¢é,ÉIØúRGÐ ¥2j»Î[1rЮz„ :£ªUnF:TÙ‘˜Ä‡-/“KŠkƒ(ÉF“I$¹Ä[ïcé1‘‚è´Øõ,'Œ°ÔŠœ6•Ф¼Ä—Ò§ùTj%!)æ© RT“.›\ÈJ°³oßèÑÖßßÀªˆ@µqÍ&v8Å4i5(UJw3Ê[ÉÊá»!dJk*IHRVWÞ­…}Ý/áÚF"Ò>8&×9е.˜Š‘¸§qÜCl²FÞL¹ˆò™YY·Ü­³nÏ +6ŸùãØÕWW[¾÷w(ÐÍ‹EwKø èò*gá†ßb<óeÔ±vžRP¢&’N%$“µÈ•˜ÉWÙ”WXr@ªÒñ6$uª›4š+QÍÓ- âÝ^B»º²MˆÈÌù›Œ‹ùž²Ã5Áëù+™U“ôû{Ž0ƒ YHÎMO I7¤>náhKÖHVgWu8y–}*=æ}b´èU§åÍÆæð–Ôn@ Ö•DƒpNŒ(5‰U-š³q_mÒ2kT«§1(ŒÔ’KiI$Œ¬];,9ñpê~§R‘Gqʤ*ŒRóhs75'œmšµE²íßjˆÏ1^Å4°­o¾ë_òNß™¢¬žëzþí~År XøÒ.cC¸"\z;ŒÔf"i”<Ù”‡ÒJ7lÞg ~BÌYíutí¹<Âs1 Ar·]~„šœw^’ÓÇZ›ZÉ "i&´ó-rËmûobÆVMÙ=?>|ä•ßÇò*>' AŠÄ w¢XLÎŒr&F}Œ7.BÂÛÊ´$‹3kJУ2Qšv¤Òe”úî]ÑÞ®SðYµ˜ó1+3’j) ©¶]ŒGζ¬ŒÒ£Ióor¹s¶\ìC *‰8ú÷·îE*ª-ßïÔ©@·pi¼3 …W)IŸª¬DqÎLyHA©eÖŒÄm«3%²í¬w<ÄGb¬hîv!ÃìKžuŠ ªoÉZÐqŸ²µ¶”s'c…c5Ì·ËÃ=”âï÷þ9]¦Vô ƧÁ«cE&¢™tÆã,㸔-:Å DjJ‹a™­´ŠÛ/r¯í4‘+vW4À.ÑÖ× Éúj°ÚÓ¯k2”gÍtW°ˆ·•ŽöÞ‘¬ƒ£ªsë³êR×!ŠuuÊ;M¦¡ ¨ÑsS†ãüÓØEdÓÛ¶Äf,<%DEçĬŒ Y©ÁXJ5/L~£2¨Þ‘Ø“N˜ÖªS/¬’Eê*Ê-·2Q•Ïw7oßèæ…E…ŒŠÚ‹’°Ó°ŒÖòm¼Ü“+')$Œ”›—:ö>¢…©kýúöf|èÞß~ÑU€´+;£EˆpûçbƒH*›òV´gì„-m¥œÉØáXÍGs-Ä1±maÇ(«’Æ%}º­ ª’[nk¦Vá(ÒƒQ³e$̈ŒìFDFvUò–q½÷[þ­À®Yø×áj%%êÔ$V_¤È¦°õ2JæµûY.¨ùŠ"gøI+3Iù›Ë6ÊÀGV“¦ìÍ¡55tYxázƤUª'XD©¸º#„ĖɬFbpˆÛ3M³Êç|§ºû#`±ÁU|±ÞõŽ «ûåÏx_hÏG²FŽFá­“¸l¤nÙ;‡~‰B¡­‘¸Æ®OHÚHÜcW'¤uhfk%oÙÌl¥oÙÌuh”ækŸoŒÇÆã¥L­# шïHËtb;Ò.À‚F#£ÝÆ2®î1v21õLcôŒ‡}Sý"Üx°c¥Ñî&k Õœª¦<ÅÍ$dŽìw˜A´G|ÿ½aÒ¹•Šå”ȳÒQŽhÄ !7 )G‰¬¢¤¬Ë”*qI§H*el•Ntߊ‚Ÿ ›C§½ÃGÊ¥ôçQ¯¶÷Ú?š¾iõV\jdC•Ù%)Óf«•:ñÉkSpÈÔe}—3·E¬+Óè%ÌÕµ®iäÃBƪi-¹´zµ<¡U?¾dnÉ„´º²#ʵ‘BJ”¢;bQ+asˆÈŒ«¥J³©¾NæÑ„aÀ²¢i2$Hè1éÕ–ãÓR¤ÂIMƒv/k©'ÀnK=ùýk™îg?H´ø4”R˜¦VN$œ½[³¡;ã¿ík‚fµmÞ£;X­¸­\€“5WSO&á<õG+ Æmªs©}ÂL˜s’ë¥~y“¬$›Ql²“·ú¬Cø®i*?Õq4ZÓÔ’–¤4šœu0ëiJR’SNEZObHìf«öŠÄsUmkýý±äÂ÷,xF§Á•.LjU]+—¢:•L‚´j6ݤ¡PM(A™™šRDGÒF9ìm‰šÄ1©1Ú1¤S#pVŽSÌ:¢i$’B M°ÒŒ“cõ[Îֹߙ¤±%–÷T¢Ò:ì‹£áh³Òˆ•Iœƒeç£IŽÝÙ2õ?kÕÎæf•ù»9¤cwIPâVcUãSëmKˆÁÇŠiŸ $tòm¾‘{ni"3#2½ŒÅlEH¤“à(IÝ£¾›Ž)38;NÄ((pˆÉb­”¡Û‘ë,ˆdJ]ȹÇsþc"F‘¡?Un¨¨X›7L”ÕN#iQ¹ma­ „IYªÅ˜ÔG{÷ ä„õŒæjê<˜hXŒé –Ëêuª=U)\uGS.Õ©IR‹SÀuw5!g–ç”¶ˆFলª¹AÄ)Pø ‘Õ"\v§Tp²dþŽ[ ì5WSL46xž¦šÅrEEÚ$PûˆZ’IA$ŠèBbµˆ‰$DV.‹‰ÂÕÔšÃu ÔT¦9ì* ÄÆq••™M¬­kì·NþƒÕ€‹mímz’l«X°%ãº\‰‘¥:¾ÃÑž9 *-R,{:{Ü2nIJ?óŽæ>ªÒ9SàÍâÊÒ\€òŸŒ„N„–›t÷¹«(Y }9ŒŒÈÈŽ÷!]õˆæjêiäÃBÇ›¤jtÈÒcK¤U^bTôÔ^ir U$‰%¬·±’H•mŠº¯|ʺ¹¤´U#V’ä*ªŸ¬FC–ì˜JKº²V©KJa$ÌÒjØdiVÄÙE•&UÀ ¼UWêcɆ€uøKÓ¨T—!.ŸUr •%¾Q23Ê­KÑ\"2+îgý[‹'(;ÄÞQRVeµ†ôƒƒ P1#r â…TkJmNg~,”/Tf¤©m%)%*#mdIµ‹ iÛÇôôW]­”,Ds^Žq\RªÑTÚ™2¶¯Vpòd±6Öè ^*£I_¢£ çS±ab„ÓKQ1“Ž…Ju‡«+eI)¦;ÖÍë­s¿,@!œå7µ.$‘ŠŠ²;Ì3ŽáP©páÇ…[5Eq2®0Ф¶öÌËhœˆ³lŒËq+vÃ3éË{HÔç£Vc9Hª›U¥ë*$R ½VØ£2ƒr2>qZÊ3QsŒÌ뀬MT¬™££ïbÉ©é" I/&].®¤È}$¥à ¤­™&é& ¤G¶Ë¹!õ™¥w]RS1je6§,Hq÷ :‡‰$¢F±³‘f±•È̈Šû Õ—@œÝoxÇ“O@:mâf°YʪcÌ\ÒFHîÇy„Dw%þõ‡JæV+–S"Ì[IF9ÂnRIEIY–š@¦®-:2iµÖ[¦ÉrLEF#J޵¨Ô¼ŠD"4¤ÍGÌ#˰ŠÖ"·ô½!Ó•> Þ,­%È)øÈDèIi·U½ÍYBÈkéÌdfFDw¹ ï¨@—3WSO&-OHtêšT™´ÊÛ¨rQLy>Rû¤w%:E‰Â.¥Ü­²ÖÝoIQk(šš„*û‡9)D§R†ÛŽ¡6² h„J˰¹··òÚ+‚3š«©&D$B‘V¥Õ•O­µ6”Þª ¬O„ɲݭ’È„Di"3"IÜŠçb+þHÒ1’Š]m:ØülBSYY5< WlÆjõw™žóà fªê<˜huXÿ–*âÛ³1 ‚ɰ•Êu‡«Ù•$¦˜hìV?[7¬vµÎü·@t§9MíK‰$b¢¬‹*“bÁjÔ:ue„ѳñy¢l63 Ð»¹æ%kß1ÙGs"1LÇôºdi Òël0ü£˜m•B¥·ímcdp¬Òˆ¶£-‹u…zlÕ]Hü˜hwÑñÅ%Œ>Š tÚÿBChUR*–Ú]ýâPáÃ΂VÛ’L¯}££ÅLÂŽC¦E ÄÄ䈔ÄÓ kv$wRÊ )\Ôº²RˆÌ•”Ð[ aôSâV.ªV¸t`ÝÉèbz¬JuØFÂѧ$ ÌyùÈ6_[OF$­ƒ-­š^ŒéØÎ÷±‘+›ræ‘ì &Å‚Õ!¨têË £gâóDØ$lgA¡v>sÌJ<×¾c²ŽæDb´ªò¹ DJ.…\}¢ãÊcNtéø†G8NËDº´Y º²Ü£CÔ›—AÛ`àj±äÿC.”_¡cÁÒ<yªumj9jšK~|'–‡Ì’“Z¸Fh;!$YL­b°àj’xmNT˾z÷–íßtœsœ£>rˆ‹2¶í;ÏmˆcÖu§5i31„c½† Å´ü;M~2`U]rbI3 3ceQ©²v+„F›–Û™ÞæVÜ6qÝ&n~…*•[zò•1Ôª£:ßR®n›œ >s½³^ùy¾®Á_€Ùb*%²žã”[½Žò“¨´ÊriÑiµÄC†ëmH¨Ä|šYïR5•öoM†T]#ANjžÕ:¹©jyTPk¨C[œ(—œž7Ôk¾Ë™ÓÍõv äV&ªàãèX§¤:qɨH:elÕQtŸ”ƒŸ Û[¥¹ÂGÊ•ôçI¯¶÷Ú2%é>$¹³&K¥Tä½4šá&ôŠzÉÓk16£IÀ¶d’ÔD«^Ö+ØŠÕ™‡XÎj®¦<˜hlñeYUÜC.¬µLR¤¨”g-ô¼íò‘mRP‚=Û’V+EƬA&äîɲ²?DúÇUýòÇ{Ö8*¯ï–?>a}£=>É9†¶NᲑ¸kdîú% †¶Fã¹=#i#q\ž‘Õ Q™¬•¼kdo1²•¼kdo1Õ¢S™®|a¾3oŽ•2´Œ7F#½#-шïH» ŽŒWwÊtb»¸ÅØÈÄwÕ1Ò2õLcô‹qàBÁŽö‰„0ÚDYsô·M¥Ëu²SÐÞ¢Íql+¥&¦Û4ªÝdc‚1J´å?ôÉÇåoÝ0‹,ð6~7QþAQò„z £_ÔT|¡[@Z§6]#ô™ºÐ²ýѯÆê?È*>Pz £_ÔT|¡ZeªseÒ?HºÐ²ýѯÆê?È*>PA´kñºò ”+P µNlºGéZW Ú5øÝGùGÊè6~7QþAQò…h–©Í—Hý"ëBËôF¿¨ÿ ¨ùB=ѯÆê?È*>P­@2Õ9²é¤]hY^ƒh×ãuä(=ѯÆê?È*>P­@2Õ9²é¤]hY~ƒh×ãuä(=ѯÆê?È*>P­OXeªseÒ?HºÐ²½ѯÆê?È*>Pz £_ÔT|¡ZeªseÒ?HºÐ²½ѯÆê?È*>PŸA´kñºò ”+@ µNlºGéZ_ Ú5øÝGùGÊA´kñºò ”+^±–©Í—Hý"ëBËôF¿¨ÿ ¨ùAè6~7QþAQò…h–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBÊôF¿¨ÿ ¨ùB}ѯÆê?È*>P­ƒ-S›.‘úEÖ…—è6~7QþAQò„z £_ÔT|¡Z€eªseÒ?HºÐ²ýѯÆê?È*>PA´kñºò ”+n–©Í—Hý"ëBËôF¿¨ÿ ¨ùAè6~7QþAQò…h–©Í—Hý"ëBËôF¿¨ÿ ¨ùB=ѯÆê?È*>P­º„Z§6]#ô‹­ ,°6~7QþAQò„z £_ÔT|¡[€ËTæË¤~‘u¡eú £_ÔT|¡ƒh×ãuä(V jœÙtÒ.´,¿A´kñºò ”ƒh×ãuä(V¤–©Í—Hý"ëBÉôF¿¨ÿ ¨ùB}ѯÆê?È*>P­2Õ9²é¤]hY~ƒh×ãuä(G Ú5øÝGùGʰ€ËTæË¤~‘u¡eú £_ÔT| ôF¿¨ÿ ¨ùBµèa–©Í—Hý"ëBËôF¿¨ÿ ¨ùB=ѯÆê?È*>P­@2Õ9²é¤]hYe´kñºò ”#Ðmün£ü‚£å Ø„Z§6]#ô‹­ /Ðmün£ü‚£åôF¿¨ÿ ¨ùB¶èjœÙtÒ.´,¯A´kñºò ”ƒh×ãuä(V jœÙtÒ.´,¿A´kñºò ”ƒh×ãuä(V†jœÙtÒ.´,¯A´kñºò ”ƒh×ãuä(V jœÙtÒ.´,¿A´kñºò ”#Ðmün£ü‚£å Ô-S›.‘úEÖ…—è6~7QþAQò„z £_ÔT|¡Z€eªseÒ?HºÐ²ýѯÆê?È*>PA´kñºò ”+a–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBËôF¿¨ÿ ¨ùAè6~7QþAQò…h–©Í—Hý"ëBÊôF¿¨ÿ ¨ùAè6~7QþAQò…j–©Í—Hý"ëBËôF¿¨ÿ ¨ùAè6~7QþAQò…jaÖjœÙtÒ.´6¸º"™_‘ƒ^E~žÚ[6ç¢+‘Òê´©dHsœD•š“s"¾[دa©¢¬¬ÝÍOÑ>±ÁU|±ÞõŽ «ûåÏØ_hÏF²FŽFá­“¸uXA–dc:y !æ]¨ÇC­$¤­&âHÈÈöt ½gΫb*üÈò(ôZSUi˜vt‚ŽÒ”N*Í ˆqX·[£ }&Œ§¨œÊÕcY•dÆ5rzE„ÞŽq4ŒQ/­˜ñ^†Ö¾D‡Þ$Çm®‡ æŸòÛ¿föºfå7‰QE{afäNÜ÷*d˜Ž#>K%ËmUÈù¶½ˆÌtèÒšâŠS©JîVñ­‘¼Åí£}»FÓ>‡ˆ£W)5DJ[°´Ê‰$×µÊÆiV]å°ì>xãE®W¢`©”™X[Ç•…à’—6R"ðÉj%씑©n)Q–Û–ÑÕ£‘Juc{||a¾,Ê~ˆ±dÚÕj›1tº+tGÜùÕ9dÌV”­¨,ö;æ##+ã+Úä1äès2g !4ç øJžÝEÈáTúÏëÌ#2#Ù}¥³i ôÈe$UîŒGzG ôW¡Hnéj…KÄõ¬)_¡Mb[¶¦Ö´ÊSM‘HR2«X•:Úòìæ¡gs±§t‡…½¬5MôWõ±Òÿ ¢Íá,"êRr)V+,²ÜË©Ië)É7b ;œ›£ÝÆ2®î1zR1õLcôŒ‡}Sý"Üx°b˜±‚O @³4£Ø8¶¢ª¦ Ÿ-¹VÑÈJ”ᬶÝ(±–eoÛdí¹§}¦Ü CRæWp»´èÊŽj9™qmm¦üöȶˆ‹jKa–îw­Ë~-C7•ßt·¿Dô¿Ý¿N{ñ*+—ßWè¾*¨t=£ýaj&•+?K¨Ö&´H[*} D4•Òƒ#ýçZËv䮥S:FÂ¥…«Ôi­M#2£:—¥‘®•‘nQ\¶î;Ü­´‹—‚ñjÊ“…;ÿKµý¶ûßèsð¾%GRP…÷;_ÑüŽ\PèHîtML#Žj®ÂP‘6X‘d³¬io-+4šˆÌˆí’Ö22çÞäi#.&DŠî¶=R2%ÇáD”­{M-p{šËnÅk9·.ŽŽ‘ÅÅxÌpø‡Gféqw¶rõãª>{ãñÂâ ‹¥ÅÞÚ=ÊÛ÷=Q@ûÏŽq'?ÕœÙuM浯c2¸øÊi«£è#%%tdÉ=bõFèÿEØZ‰ƒ¥JÅOÒê5‰­ÊŸBÑ et Èÿyֲݹ'k©\ÿñ*XÅÎíɤ’ãÿ Ô¥ÇSÁÆ.{ÛvI}úqÔi –¬Q¦µ6ŒÊŒê\J–DVºVE¹ErÛ¸ïr¶Ò.\]§R5"§ µNq©(ð`æàù¡=P¡+âÙ4ÉR$FRàÀuÔ- !IØã„gcY‘ìIú·¹ó½J÷Jø6&šSèó~•%̨lž%.:ìgöÝI±•ü¬{ljåáüZ†#:¿ôî¿£~©}ï9ô|Jjò£O_F·P躆ª/ê²I¢–·&\õ˜ˆ¶}M³ft²ÿ„7{Û.WomK¹îè25üUR޽n»U«³©<Ùõ¬ä¶üÚÖ­¿:=bÕ?C 0ëÌ:Ór7RÐdN ”¤’g¼³%I¹t¤Ë Æ. ¬|5Q|šÉ&ŒZÝ^\õ˜ˆ¶}M³ft²ÿ„7{Û.WomK¹4¢ÂÆÔ¨ø5…Ÿ^ˆçK[õW#J~M“dÔcpË#Nšýa6y*Ôi2#åñÛÜ#W¤køF¶¥!zÝv·YwTy³ë^Ï}ùµ®ß~uúǺ¯ ¸ðôø­{|7ú›Ôƒƒ³âi@NhOP=BBÉ¢XLÒðý2­3Î)fü¥²FäVR—DÚŒÎ×Rv™“†FGb2ÆÇtçjÔ'Ô¢4ÔÖ`2ñ¼EÎ'yæãw¾Ô‘mÕ›¤q?G2èìîN×¾ûÞÜ4¿Çð>wÿPÃ6èlJv½÷ÞöánZðßb¤Û>ˆ’€ è@¹þú9£Õ”Ö*Ås = >Ç‘ýФ™‘­Ò¾Ä‘‘$ýc-¼Ý‹¥âúX µ^ ÑqoDUÆc)àé:µ8~mèS"Ÿ¦,M§˜ƒI‰ÀÔ¢á1êb¥‰M•ýS3õKÕ3ÙÍõk>¼kÁN$´+F´âO@ƒÐ ÄÄ YzÑì[QUSO‰Ü«hä%ÊpˆV[n”XË2·í²vÜÓWŒ¥ƒ£*Õx.¿%ñ Äâiá©:µ8"µ!êÓn¡©s+¸]ÚteG5œˆL¸„6¶Ó~{d[ DEµ%°Ëis½jT0x¸b©*‘ÝGèc ‰Ž&šœw| è' @´Xí4I‚q™™QbK‹•s[©K†G{!²=êUm¬’#3¾ÄªÎÒöŽð¼Öo„×L.HCL¶òIPI.jŒÏ×þ™ÌýcÜiåÕñj±k ï{]¿EÂ×ù߹ϫâTiâÞö»Ñ|Ï>€êëôGJƒTÅÉ:‹hzƒ…ªu¨IÅxFF!rK¦Ôd/Y;šÅ“¨Î¢±¯! ÈíÓkÛÕ²7ÕÉéjUöšmo(J…“IžŒkÓ\ÆÚ.—[Æ´*”˜'WMFsO6Ë-š›4·˜Œ“ŽÄ”™‘fµÊ÷†œê0'«>|iG@Žù°òW©u:ÌÈUš¢¹\i\qò·læ:4æäUò”wžŒÒµW ãÉØËÅÆT*cÎVaÕ Ï“(Š´”™[fònE”Èϧn΃¶ž!§Q§áL‡±ÞSô,æfOª!K¥Ô%æÔ¨Š_ù„Dg›w4‹¤Èyéñ†ø½ äV=ÅkF˜WNرV…%¦å¦¾õ Õ®˜ÚÜim²hQì/\ó[al¸óæ‘pÃxNºTƱ%!l“É•G•¯hˆÔ¢$)V+/›s"½‰E´jŽô‹tãfDÕŒGF+»Œe:1]Übü¤b;ê˜Çéú¦1úE¸ð!`Ä 1cç âØr¤R¢žv—b}…’êð2è>æFd{ o‹\ylCKŒ@5f4®Ä·÷çXÏatöõ[—>'F~e·šyqÚÛ¶ðSpÛ ãÇé´Wiuœ–Ò\De™62²gü=G´ËuŒ­nV¯Q•Tœ¹“Ìⶪ‚èIAëxÃ(ÂrŠÞÍ#N0m¥Ä”Üq…«¯Ð¦:ê§Yy³mÖ‰Õ7˜º ”[Œºy\ím㤕M-^3õ9N‘TÉÕ! 3#,Ç«I·ú¦véÞD82Ö)ÖÀP­=¹Æì¡_Ã0ØŠžeHݒ┵šÖ£R”wRŒîf}cù àÖ;\+¦Ñ]¥ÔZr[hG÷"ˆË2led(Ïøzi–ëZÜWXZPª­$i:qš´‘™W¨ÊªN\ÉŽfq[‹ÕAt$‹ ¿õ¼a€ ÒIYð2»ãGèL¹Oš—$S–•eJlkeFGµ7è3Þ_Ú]$zLEZ•[œr$VÓri¢>keÿ‰õŸOõX‹X(Ñ„fæ–öiqŒœ’ÞÀ MÍÖ{ƒãz ÕT£¯[®ÕjìêO6}k9-¿6µ«oÎX­½WÕO SacbLBýôËÂ'­êÞyl¹•jJˆ”…¸ü%$Í÷Bv- :(\^ž.Ÿ—Rÿƒ³üÕ]?ƒh’•YR–ÔN’}ת¯ÕdáúÌÉ•7øBÜE=·qå2¢4’SnyÊŽdDV={VõÓ|\v÷Çéþ­©H^·]­Ö]Õlú׳ß~mk·ß~±éº 1ŠŠ²àFÝ÷° ž¡z„:Œ+‹¤À:sÊ”LºÆÝaÂÎÑÛiUt¨¨ÊÅs=ö·×ãgÓ݃É®%âI8ô•$•”ŒÏ)%I/æ{̎ǰŠÜ™Þƒ«æ¸ïâP~†u¼çêãøýþÂù$AÐÒà\Y+ Í4¨”õ=Õ~Ý‚=¤ç§©_÷l>ƒ.h•)Ƥ\d·ÎœveÀÞâÌBýrU“™¨mŸìš¾ÿé+ùÿ³wYžˆH˜ÅAYI%dO@ƒÐ ÆÆ@Üá,C;TŠTSÎÒìO°£²]Oþ]ÑüÈÌLYÂ3‹Œ•Ó5”T•Ÿ©ÆØ±uÇ–Ä4¸ÄVcJìKpï~uŒÊÅÐ_ÛÕnXI§N4㳨«"z è76Ï¡U§Q*mÏ€îGQ°Èö¥iéJ‹¤ÿ2±‘èñž7]e’b.DmÔÌdj3µeü?ÏaŸQm#ãL E*0”ÔÚÞ8¹m[x)¸lpåZE®ÍB9f4\–ŒÆD´žò;¯§iÃàΩ+¦iRœjAÂjéò±âÂM·jÎ)62Žã“em¤Fá'X¢/æwU¹×¹Ž"|§§Mz\…fuåšÕý½ü‡Ä@¯‡ÁÑöé«\­…ÀP¶éFÍ€‹€gáʬŠ!¦×!¡¥É§Kj[)tŒÐ¥¶²ZIDFFer+ØËúÆ.9˜³D•W uN.)D·.â›*t7ÐÊ”£Y¥*S‰Ì’Y‘ÜМÙLÍ?´t—ÄéOµ‹«ñ߇Ö)ôø‰ƒ ^³[ëi+Zóº£3ºÍN(÷ŠÅu•É3è5iÔJ“sà;‘Ôl2=©ZzR¢é#ÿ̬dF:ŒäâÜ77/ûêQbµ8âµnYÔµ¤wõ,E³Ö¿@ÙÂÑN“Š$ͦÑeÖ[—†àÖèøiu> ·øB–KF¸Ï5›$ï¿;¤_ƒ±ZSÔòë£Þ‘}Uð–›'RÚÀUL1X‡R‹lÇTwZ{ö¦Ú®DâÒ‘lÄ{R« çte‚ bS§ªm"‘@¨&¾ÉÉp‰Êœ&’nó’¢RHÖóVI7vñnHŠLóc£ÝÆ=‹!ècÂÀüw€*u©•¬/¡7WXu†[7IYÞIš”á™*èºPDI±ÌUßH !ér¿…iŽºä(N¶¦ Óº‰4‡I&}6ÏkôØ[¥5'b)E—:·YƒE¥±Â'Ô$·+YÒc®(’„ÝFDW3"¹™XØc<ŠðtXRñ+€³6L¸±ÕÂs;±]ÔÈM£2Êç6çb=årÚ= K¤è¿FzfÁú=O®âÖ*t³•]]]qÑS«iÄêÙJM+Bs¤ì«î¿HìtÁ"â¬+JÄU”É{azÎ-R‹ l©I:²²´Ùo"3Iæ^ä$Œú„™›InÜÿÉG‰L@ͮʇ:¯*]>–Í*#®š™†Ë«q '¡$§ Ô«u™íþ[†ºhIô}iˆ)PišŽ‰iU½flü¹)ÕZÖͯe½÷;e¾ã½¶\ PØPiñ*SÄÊå>ŒÚ[5“óPú£¹R&[qWÚg´ˆ¶ÛØkM±1æ’Ô¦ÛqHK퉑‰I%’UcÞYˆnÒ#Øø€ ëCmR¥A‹H9ŒKJŸ!ì¹à°Ü’y‹¤Ì󛌥³Ê|Óʵm=—-  Hž±¶ÃØn»ˆšå˜üÔAk[ Û"²gb-»Ô{l’ºŽÇb;ÔõOàœY† èé¨V«„V7¹o)Û§1»ÍÚ½…~‹[/7(åø¦6¾0ò)í94¾ z·¿§ÝècñU¨F>L6›vø/žþ‡—Àvz\™C‰•"•ƒJVcœHY)µ9}å°¬½ùº íÓšü`èR›©&­rå99E6¬Hnl(4ø•)‹berŸFm-šÉù¨}HQÜ‹)-¸«í3ÚD[mìG‹1¦Ø˜ó IjSm¸¤%ö‰D‡HŽÄ¤’É*±ï,ÄG·iì|@€tˆ¬M¨5MJ%1¥ß4©IuM·b3+“HZö™[bOi•ìW2 @Ë«EbAرªQ*m"ÙeEK©mË‘ØB°ÎÛR[Hír±ž ê'¨@H@ˤEbmE¨²jQ).ù¥JKªm»™\šB×´ÊÛ{L¯b¹’¯ˆUbÆ©D©´‹e•.¥·.Dgbu^Ã;mIm#µÊÆ`bH:ƒ 6‡J¨ÖêÑ©4˜ŽK›%yi²Ú£ßýDDW33ØDFgb!„/£† ÃTJ\“‹K×bÜ¥¼ëÄJÕfæ“e—b=[ôš·ìÉn‰âªápÒ©Frô\ÍðÜSÇâ*aè9Ò†Ô½HÕióiU©õë)…eqµï#ÿÄŒ¬de°ÈÈË`Åæ›k:¥=| Ue(î¶éµwçÊÛQ¾Ý9·lÌ*1c VUi©MY“aêN¤š³' A‰èbÁ0H¬?*KQb²ãï¼²m¦›I©kQ‰$E´ÌÏa˜·~ŽŒ5FªÉ‘*±Ü¢8뤔¡¬¼íYe>yó®{òì-™ïOˆž*´á¶×¹~oÓR¶.¼èQ•HGi¯Où+\IB«aÊ«”ºÔ%ÖÙ\У%—Y)&d¢Øer3ÚF[ÈÆ°^ÚkÄ:­J*´Ü²µŽ* ÐñˆpÏ£›µ³ë[§(¢C^¥z*Ucizéø %Z•i)U™=ô lCJƒLÔp,KJ­ë3gà-ÉNªÖ¶m{-ï¹Û-÷í²àj@ mªT¨1i§1‰iS¤=“<’O1tÜ󛌥³Ê|Óʵm=—-£R ®¥A©ëøn%¥Q5yrpæä«[{ß.¡—7X¯šÛÊ×ÛmPm‰0Õw ¹ºå1ø ’Ñ:Ñ:EsI‘ŽÛ”W+¤ì¢¹\Šã­Ð5C S1Še× p¹¨ÊtÂqÂK(vç´ÊÇuîÉ}„wþ,¶³´³Š(u:læ±+û•yM_-b\ËÍ6Ï/¯¿ùZ÷ÙqǯâˆcUÒ¼-½Ýo{¸+úzßþyµq•ãŠT£Nñ¶÷uùo<ÞaÖÖ;H€~‰õŽ «ûåŽ÷¬pU_ß,~}ÂûFz4}’4Êqlº‡[Q¥hQ)&][HÇRî’_F‘}.â¦Í½N«€ë¹¶µýl¾Óö›·ÿ¬rr7 lÃèðÕgô¿‰Í¯N3â®ÆRðÔº¼¤°RÜ©C[&j^][¦¢RÜw4¨¯mŸÖCW3HV“ƒ*I ŸÂxV}¦Ù¬Ö[nÎ¥*÷Þ{†²Fã¹=#©B¤­k”ªB7½íkÔ$áL3Df90íå<™D»©ã%šš¹X­“2ȶŸ­Ð01Ž9gé>>/™B`á0ôeqJœ%´¦YÈFÉ™¦ÙU”ïtŸ¬{ sÒ·læ:”dÙNQHé´›Žã⺠€Õ=&]EöÓĤd•#\M¥$„’I²²JÛí{'pÙ?¥L;=T–ñ&Ž¢Ö£Ó¨PiH%ÔœeâTmgíPãi#A/Yµ}Tí³ã ñІò¼¢‹1Í5KV–©øÙÜ?P`SN–Õ$¤¨Ò¨šµ¤›[ª#5Öj32ÛbÅ;I•8xa·â¦K¸•ô¾©†îUGQ¸KzɱæÖPG´­—¤qÎŒGzEÈEI“ñ§¦~Œÿ{xaè”_ßë5úŒÿµõK.lÞ®Û[yÖ.Òµ3é#㞇'Ò**©Ñ¢È—x¹ãe¦‘) S[VQ™X’|ë‹yÖîŒWw·DŠEÒÞžhoÕ(xŸh²•XÆ¥FÍYUIæµäÁ§*”–]m“±gšÇcÊdD‘®Ä_HZܚƫP)"D ¥`O@ƒÐ Àý²ãŒº‡™qM¸…´&[HÈú ˪TfÕf*dù }åFDV.¢"Ø_Ø1„’VF¶äO@=L€ H"mV«Qª©¥T%¹%M ƒYî/üOa\ÏiÛiŒ ²næ,¯rL:ÀìdÉýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:ÀìýëW÷ËïXિ¾Xüû…öŒôhû$hänÙ;†ÊFá­“¸wè”*ÙŒjäô¤Æ5rzGVFf²Vñ­‘¼ÆÊVñ­‘¼ÇV‰Nf¹ñ†øÌ|a¾:TÊÒ0ÝŽôŒ·F#½"ì$b:1]Üc)ÑŠîã`C#ßTÆ?HÈwÕ1Ò-Ç  Iˆ$ú >'¬A ë@ž±zÄžzž¡z„$„ !$ƒ : $@zžH@’žz‘DL:Àìýëjê/Óä>l5 f»_„CiûZûµ‰U·ôZÿØC²ëW÷ËŸ°ª­£Ñ6#:)I\=Šj‰-ŒÑËþƉå ±…i%ÍnŽ_ö,?(`ÈÜ5²w ¥&ø³›R…%ý«¡²{WÓ{¿ìH~PÁH•7ʪ9Øp¼¡©‘¸Æ®OHéQŠ|QNt¡¢7oé'ÕrŽ_ö/$a=¤ü^“Øý¿ì>Hç¥oÙÌt¨Ò¦øÅt*NÐéÝÒ®4Né4AòF+ºZÇ Ý.òHä_oŽ…<5ý‹¢+É#±sKøì·M£þäŒw4ÇŠöGü=OòèÄw¤\†‡¸º"ÚhÒ n¨QÿSüŽæ›4ˆWµFøvŸäÑŠîã¡‚Ã?öãÑI³½^œ4ŽE²§Gü;NòÇ—=%_üiGü9Nòzïªc¤ZŽ oeˆ‰ÉêYG§=%{ÒøräåÓI^ô£þ§y¶1l†•‹±©jYg§=%{ÒøräåÓI^ô£þ§y¶>Âò£ÑvRÔ²ùtÒW½(ÿ‡)Þ@r餯zQÿS¼Zd0¼¨ô]†Ôµ,¾]4•ïJ?áÊw#—M%{Òørä Ô!…åG¢ì6¥©er餯zQÿS¼<ºi+Þ”Ôï V€ /*=aµ-K/—M%{ÒøräåÓI^ô£þ§yµÈayQè» ©jY\ºi+Þ”Ôï 9tÒW½(ÿ‡)Þ@­@2^Tz.ÃjZ–_.šJ÷¥ðå;È]4•ïJ?áÊw+BÖ /*=aµ-K+—M%{Òørä.šJ÷¥ðå;È C ÊEØmKRÊåÓI^ô£þ§yytÒW½(ÿ‡)Þ@­2^Tz.ÃjZ–_.šJ÷¥ðå;È]4•ïJ?áÊw+^±Âò£ÑvRÔ²ùtÒW½(ÿ‡)Þ@r餯zQÿS¼Zd0¼¨ô]†Ôµ,®]4•ïJ?áÊwºi+Þ”Ôï V  /*=aµ-K+—M%{Òørä.šJ÷¥ðå;ȨC ÊEØmKRÊåÓI^ô£þ§yytÒW½(ÿ‡)Þ@­ƒ!…åG¢ì6¥©eò餯zQÿS¼ºi+Þ”Ôï V  /*=aµ-K/—M%{ÒøräåÓI^ô£þ§y¶è /*=aµ-K/—M%{Òørä.šJ÷¥ðå;È C ÊEØmKRËåÏI^ô£þ§y9tÒW½(ÿ‡)Þ@­º„C ÊEØmKRË-:i+Þ”Ôï G.šJ÷¥ðå;ȱ †•‹°Ú–¥—˦’½éGü9Nòr餯zQÿS¼Z€d0¼¨ô]†Ôµ,¾]4•ïJ?áÊwºi+Þ”Ôï V¤Âò£ÑvRÔ²ytÒW½(ÿ‡)Þ@ž]4•ïJ?áÊw+@ †•‹°Ú–¥—˦’½éGü9Nòr餯zQÿS¼[ †•‹°Ú–¥—˦’½éGü9Nò—M%{Òørä × A†C ÊEØmKRËåÓI^ô£þ§y9tÒW½(ÿ‡)Þ@­@2^Tz.ÃjZ–YiÓI^ô£þ§y9tÒW½(ÿ‡)Þ@­ˆ@d0¼¨ô]†Ôµ,¾]4•ïJ?áÊw#—M%{Òørä Û @d0¼¨ô]†Ôµ,®]4•ïJ?áÊwºi+Þ”Ôï V  /*=aµ-K/—M%{Òørä.šJ÷¥ðå;È¡†C ÊEØmKRÊåÓI^ô£þ§y˦’½éGü9NòjÂò£ÑvRÔ²ùtÒW½(ÿ‡)Þ@Ž]4•ïJ?áÊw+P †•‹°Ú–¥—˦’½éGü9Nòr餯zQÿS¼Z€d0¼¨ô]†Ôµ,¾]4•ïJ?áÊw#—M%{Òørä Ø@d0¼¨ô]†Ôµ,®]4•ïJ?áÊwºi+Þ”Ôï V  /*=aµ-K+—M%{Òørä.šJ÷¥ðå;ȨC ÊEØmKRÊåÓI^ô£þ§y˦’½éGü9NòjÂò£ÑvRÔ²¹tÒW½(ÿ‡)Þ@r餯zQÿS¼Z€d0¼¨ô]†Ôµ,¾]4•ïJ?áÊwºi+Þ”Ôï V€ /*=aµ-K+—M%{Òørä.šJ÷¥ðå;ȨC ÊEØmKRËåÓI^ô£þ§y˦’½éGü9NòjaÖ /*=aµ-Mö8Æ8‡ÔcT1ÆdÈ‹¢±©ˆÌt!¢Z×”ÒŸYÅí}£@,Æ‚QвF§èŸXિ¾XïzÇUýòÇçü/´g£GÙ#G#pÖÉÜ6R7 lÿD¡PÖÈÜcW'¤m$n1«“Ò:´ 35’·læ6R·læ:´Js5ÏŒ7Æcã ñÒ¦V‘†èÄw¤eº1é`A#ÑŠîãNŒWw»Žú¦1úFC¾©Œ~‘n<X1L@ØÁ'Ð Iô!=bOXõˆÖ €ôÐ õÔ $ I$AЀH"Ð Äô0B€ôÐ ÀÀÀÀz¿‚°%Kcj]1éiq¼j–ÉR؈qÉ,ÕPâ,Y8¶PÙ](+¥£Ê{‹h¥‡jñ“„ñ<éj“I}tÆœg)†áT¶œpÙõlÛn™jÓr6óeÊj*ùeu•]úzimãoŸÇäÛZ¦)ѾFˆôxµ§ÒjŠ,EÚL—|âhž,†¥8ñ!¶ÒyËz‰DGm™pý“‡æª™I™ÃâczÍ6MC;IiM·ª6m4ÊÝÈÏ*RdDhzÄd¢Ku8 hø}XTŒ¥U»6økøÿ‡4×ê¦áü53G¸>±"]¡Òž¬UHÒ”ª¤ÁϘÚ³Þ£'a›ï´‚èNÌ­!hßñ–/©Ç‹PŽËS«/&dSiºm5Qä¾–a-¼—%¸M “e&ÚÖ앨ÁË«*›qªÖöíoFïn:þÊÖÜgm[vÉÀ9šÎ1‹DUiµá™u*kªžäy “–ŸRu Ju$M™*ŒöŸ8”“mDF_Ôü†*õÕ=HÕÈé¢Ñ_b—kJ‘ ¤E%;(–lØÛmIÈ哵Å(ó6G•€òê׺¬ø[×á_]ÿ+îkC¹ÒnÃx^ &5.\Ú”ée%åÎ×£‚ºËS¥FA¶Ù#1f(è]Íf[OfÒ·CW´È?G•T"•dôÔiÒäOj¥É(KìË#ŠH%›‰Ë•“4IF­aØÒÑ©5( Þ«ŒW™ÂW÷·7ið5ÚZÃx†Œ*ÒëXk§1lt›xynK9(5’ŸzI¤Õ (¶–d‘êòšž¢ÎÁú< Vð55…¢EY²Ä£¿ˆhÄmGˆÉÆ‚¢zF½”¸¦[5/a“dFk²¹Åš‘ ü>¬®ÕK6ï¹|-¯þjÖK*kCÐ#EØ";8&¹W“>¦ÍF]4ÞJ òŠúä:ÚV—Á ”jÍgŸöê5jM›RˆÓ¡Ãú,ƒUÁuªÜšUj’¨ÑêR"¸ôýq â¡ÕðwP˜„’söF“ÎëF~±"ÆI:t¿Ëñ ·ç»·§;’º^¾¿/–vÖ…Í¢Œ3P&jCÃÐ1–‡$“*]7¿9ú‚¤™EeN´K`Šû\$¶i¹×ÌIìè´ÔúZ+´jll¨´EÆ«ðT6·åºôRšÙÉ"%®É\ÌÈ5 šIÙ6#:jxlç7/3½7îõãÇãnÖµ¬SIp=J 7!èîb¬5“‹J4õB§CÃ캷‡a“ Lco«"æå5zÄÙ(ÍYvý)øi†±F*|W+º¬Rót¤%4êyÆŠ²Y¥YŽˆÜ”kȤ’\lÒGb$<‰øMMÿ÷5Ým߆ûÙz+î{ǘ´= a·pÖuæ`·†×ÄëŸ.M –ëŒ&Y5PJó¸êT·IM(²¡ Q–Ô‘|Œ4S&Q$âú6 Ö¢ª¡%êcÇ’Üèíp~ ƒ%mÙn­äç¾e6ÚŒFDgHuãá•bïæë骷£_6ýZ\,6Ö‡]¦ªc4}/búlf!ÇŽÍfQ0ÌE¶m4Ѻ£B«3Jl“"4l4™LˆÈȹÓ¡MÓ§7v’WÔÑ»³ôO¬pU_ß,w½c‚ªþùcÀ°¾Ñž‹dÃ['pÙHÜ5²wý…C[#q\ž‘´‘¸Æ®OHêÐ(ÌÖJÞ5²7˜ÙJÞ5²7˜êÑ)Ì×>0ߌ7ÇJ™ZF£Þ‘–èÄw¤]ŒGF+»Œe:1]Übìdb;ê˜Çéú¦1úE¸ð!`Ä 1cŸ@'Ð „õˆ!=`Ö OX€ Ð O@€Ô OP€$ t@"ˆO@ƒÐ ÀIBÐ O@€ H€I‡Xu€ ¢}c‚ªþùc½ëW÷ËŸp¾ÑždÃ['pÙHÜ5²wý…C[#q\ž‘´‘¸Æ®OHêÐ(ÌÖJÞ5²7˜ÙJÞ5²7˜êÑ)Ì×>0ߌ7ÇJ™ZF£Þ‘–èÄw¤]ŒGF+»Œe:1]Übìdb;ê˜Çéú¦1úE¸ð!`Ä 1cŸ@'Ð „õˆ!=`Ö OX€ Ð O@€Ô OP€$ t@"ˆO@ƒÐ ÀIBÐ O@€ H€I‡Xu€ ö¥Ö1Z;’èø·>d=2• qLº¶–dN>•[2[H· Tº2}jW Uôßÿ‰§ÿê&ƒ?Éâ?çj¯ÿ‘’5Ø/.4w¢Õiµ×˜V%¨Sʪá!QеT^m†®kÖeÚÛddƒBNɹZÅópþð¨;Æ—ÿ©w:ͱilíîù.Å|æÆKÿõòÿ§§~¬c9‚1’Ëÿáuòÿ¦§~¬X(ÒF$<åhðMA2ˆÑKJ qr­£©*)‘ZOffdjÒevó(º*¦ePä“PZCHy³Ž²mò^µÄ <¦D£3=×-£uB ‚5u$Ï,«èõŒ•ÿWûªwë‡É_GLd¯ø¢¿ÜÓ¿\=lî9¡ÆKçPáTãeøle6HR•+.¨È¯r+¨Ò«ÚÆÚú ç‰7H0š­• ¹Tš·%6Ò"6ÎW6 2RÜJRDo’n£-¨QoË›u¸rlòz¾ØÉEn*¯÷4ï×—Õ§_üY_î)߯ÕÃ5˜¸‚ŠÍRo´ÛŠqµ4ú2¸Ó­M¸…ÎÊJФŒÊå°Ìq2q²«X«³L[‰NV|ÛšâRˆÕYìʳQ¤ÔM­$âS›)(ˆírÝ6O0}Zq—»+ýÅ;õáõiÆ^ì¯÷ï×Shƒ±VÁ¸n»6¥-ª Gª•Q-¦]8èQ¥×T«©Õ\ÔdYŒ·ª×+éðÎ;­=ˆäN“C¬U;À¨3š”äŽÒäN2Y¥×’qM$¢#Ì£FÄÙ6,݃Î?VœeîÊÿqNýx}Zq—»+ýÅ;õã×31õ5,Ãv•L«WJU9º™•=”µ~£ª'ZʲS™G•VNÁ¤s} Oz Ýz™# ÓgÇE=)[m6§ff{+‹I]IÕìMÖ¢IX.ÅØ<ÃõiÆ^ì¯÷ïׇէ{²¿ÜS¿^=>î6T} Oz Ýz™# ÓgÇE=)[m6§ff{+‹I]IÕìMÖ¢IX.Ϧ-ÒÓÈ¥aè³ëfòhŽ%¦ÒÁ1ÁæËq¢qµ¶£qd“O9F’Q²v$ë .ÁåÏ«N2÷e¸§~¼>­8ËÝ•þâúñî(N¸ü6_v3±q´­L:i5´fW4(ÐjMËqå3-› Ëhç)8ÚŸP…*¨têœJ+\–ÝVCH(ÒG¬´YF²+s‹:S˜¶¦ä`òÕ§{²¿ÜS¿^VœeîÊÿqNýxõ=KHñ¤ÌÚ.'¡ºÕea.<}g`J[wZÓ¬ý¢Lál2ç‘‘6•±]B›%Øu©Nr‘&b£ŽBÍê›(&‘”Êä¦Ûx”›bZKq™ìaú´ã/vWûŠwëÃêÓŒ½Ù_î)߯ŸÆ¸ÙJÂ’ÞD Ý"£L«RT%¥<%L»=‚æê–¤­.$œE‰G{)&[Èu¸gµZ~l7)µ UBC~Ô¶N% #Ȳ6Ö´)*Ê¢#%Ô¨ŽÆAvýZq—»+ýÅ;õáõiÆ^ì¯÷ï×TU14êF”k0Û¤WkL Ÿ!1 dRY=|ÒqvqÄ$”¢&ÊÅu+!X.ÍŒÌ}MK0Ý¥S*ÕÒ•Nn¦eOemE_¨ê‰Å£Ö²¬”æQåU“°.Áäo«N2÷e¸§~¼>­8ËÝ•þâúñ멘öš™ñ!ÒéµJÚ¤ÓÚ©f€†Ì‘ÃQ!Ë-iRï•\Ô•³vÒ¾-/Jã­8ËÝ•þâúñëên-r§9êK4:•.¤ä&SÓTBܤ$Ò“UÛZÔ’%8Þd¨’²%—4s’1Ír‘M¬J«É¡¿™T¦Är¨ÓFŠDô´3)Kq\æR«šÉyn«¡I °y“êÓŒ½Ù_î)߯«N2÷e¸§~¼zÅÝ#a¹Ø“Q°Ö%ÃÕ‡jU”ÔY;ël¦$‡s‘!{9í6W22²Œ·™k½.Å~‰zª£ú7¨áÜTç à6Í®×gÉŸWÏÕêÿ£›¤.Áåÿ«N2÷e¸§~¼>­8ËÝ•þâúñꈚµb·@•JÚn3ñr.WT¬†ÂÐêÔd²Y¥$W%ŒÈÒ“-«°yêÓŒ½Ù_î)߯«N2÷e¸§~¼zt±¥f^$™Mf·„éÙšìhôj£n¦\¤¡f”¸—5‰"'‰IÊÛ–%ó¹ zÎ=’Æ0Ä—ô€ðËtÉGb5^1®C¨TV7 Î[[ N©%dÿó;…Ø<ÕõiÆ^ì¯÷ïׇէ{²¿ÜS¿^=Šô‘R¤â­8ËÝ•þâúðú´ã/vWûŠwëǹÀ6˜<1õiÆ^ì¯÷ïׇէ{²¿ÜS¿^=δÁá«N2÷e¸§~¼>­8ËÝ•þâúñîp ¦ }Zq—»+ýÅ;õáõiÆ^ì¯÷ï×s€m0xcêÓŒ½Ù_î)߯«N2÷e¸§~¼{œiƒÃVœeîÊÿqNýx}Zq—»+ýÅ;õãÜàLú´ã/vWûŠwëÃêÓŒ½Ù_î)߯çÚ`ðÇÕ§{²¿ÜS¿^VœeîÊÿqNýx÷8Ó†>­8ËÝ•þâúðú´ã/vWûŠwëǹÀ6˜<1õiÆ^ì¯÷ïׇէ{²¿ÜS¿^=δÁá«N2÷e¸§~¼>­8ËÝ•þâúñîp ¦ }Zq—»+ýÅ;õáõiÆ^ì¯÷ï×s€m0xZgÑʺÕ}ÚGªµ ñ Å›-¸ðâ$£‚Y¡ 7%¤”²Õ¬&dܶ‘‘ŸõõiÆ^ì¯÷ï×[RËŽ2ÿ™(Ÿì–>Ï̧ÎdÞšë/¸ëzæã-Dim£õO&ëÛz¦å¸UÅã#†ÞöÊxÜd0°R’»|ä?«N2÷e¸§~¼npÑ7WêNC~\Ê"PɺOÏ‹M¨ÈÒY Q)Åf;ßjH¬G¶ö#ô³Ãú~!D„´ÄìÒž†ò§‚Øœ=¶Ì¤‘¨¬EÔgapáoñƒŸèý¤$Ãâ<åÂÌ߈U£{YèV: ÿ'ˆÿª¿þFHÌô;ÿf8“Œãþ9Öê?ùŸÕ[7ýkÿJßÂ:ýàÚe+SØŽüÅ¥òrjŤ̗!Å>²+$¹¤§EÓb+™žÓ踂µ´^kJÌQ:RŒŠìdÇv®UjrŽšã=ÃNi“§­³ÈÖØˆˆ›2MÊægrÀ•CÆ2´‹R“¸Í5Kôè²%)N1!Òzi¬Ú#p²-’dF¥’IÂÌJ¹ºø‚µ´^Äý«ý¢ðI‰ðÍV>oáyn"#4s£·ÒŒÖ^¥¤HÖ(ÈÈÚi.žRõ³u¤ˆÿ³Âi©Õ±+8†Å&U%š$4¡i¹ÇȳuIµòÜÝÉ·oìˆíkÛAÚ¿Ú/â~ÕþÑx X]3 ÖŠ{•*Þ%n¡9ºk´è.³OK$Ê4)n-*ZÉÇ ÚhÏÕO3Õ+˜ÕÒtj¨‘§!us —P§LSTÚWŠ“‰%/ÜšÖ+öŽeÊ¥æèIÛ›cº8‚µ´^Äý«ý¢ð 0UÞ‡ìÇqüÇ:ÝGÿ3áÚ«fÿ£Íé[øF;!âÒX©éôë°ã«G¥¥‰O%hRI§ß%þÕ´’®IÈGt ÌÌËm³Äý«ý¢ð ‡í_í€XÌL?58š r}_†;=F2SÁ‰»·&K.¶›‘ÿÁ!„·{]~±ØîG£«hýéxw‰Ñ:!¥T'Ìq5:2e´|&K–T›‰4­½a¤–J±í3Nâ+‹ˆ!ûWûEàAÚ¿Ú/°)ÉÚ1:M4çU%Ê‹Å6é]rT–ÖÓo©wõÒ‡¤tm7/rË·a…pbè²è“«*lŠ| Ñ並2·¥¾Ãî=ëN{*æíõ÷ìÛiñ?jÿh¼ˆ!ûWûEàsCÃóicF‹W³I«Î¨JO/î†ä»!Òfæg“*ßAç-§ªµˆ”dZ:6ªÓêiµâvÞ¢á§Öº|"§åpÛ8ΰ„8î°óîÅS°Žäfw+‹ˆ!ûWûEàAÚ¿Ú/°(†ôqSÃÌ?„êjZdÒ›¦Ëª$!oÊæ·uþÅYs-I猊Śæ®â—‡Ú§âi•xî’Y‘L‡On17bi1×!Dy¯¶å"Ö±[&ó¾Îÿˆ!ûWûEàAÚ¿Ú/à¦éø ¯F¦Ò˜Ãø¡¨R¢Ð¢Ñe¾õ;\O·*&ÜBu‰Õ¸F· ®k.~Ò; ,U¦T{ bvé1‘C‡E&_§ð“&£›Æ‡ ZÄYË;b¹JÇrUÊ×Cö¯ö‹À8‚µ´^`§=ªÓ* ½…1;t˜È¡Ã¢“/ÓøI“QÍãC„­blå±\%c¹*åoêVŽYDEÆ¥Ôø"§ÑáÂ'#ëI“¦Éqö”®rs’i#Ieؓ۷eÃÄý«ý¢ð ‡í_í€ÎðpPi®Ô`ÖêtÊL¼A92U$ÁJNÃ%jQ©m ÍKæç;Œ®w3='K†¥á)õ´LÃk§9M0õo´Â“‰nç2Y¥Ò2Jvm<Ç´[AÚ¿Ú/â~ÕþÑx Xt‹AĘҭQ‰V©OàÇ…§ÑNTš à“NÊS$FHZÏ^²&ŒÔ¤6vI&×1ÓÌÁÕ:å7”™Š£Î©W#L —”Ó1`Ù±^ÜíA®Æ{ Ó¹l4‹“ˆ!ûWûEàAÚ¿Ú/S•<UªÓênTq;|u=úzÊlj~­¸íÃ’O´„4§·1¹u)Gµ{¬V:vD…ÕŸÆÓ±ÕD0Ëí.œHŠL°¥­¤+S—²ÜZî¥ÓÙk´8‚µ´^Äý«ý¢ð³Hñ©x’]R´Äg©éÌÃi’BDeÈRrØíc'É$’"¶N›ìæéø ¯F¦Ò˜Ãø¡¨R¢Ð¢Ñe¾õ;\O·*&ÜBu‰Õ¸F· ®k.~Ò; “ˆ!ûWûEàAÚ¿Ú/°)œO£Fê”j]èiÔè-BaR)‰‘.2[,¤äwó¤ÚvÄ\ã%ÒFD[o¼‡j1kxŠ\j» ­þØÙ8YbI0Ó²pוHÈÊO!·¼ýklWCö¯ö‹À8‚µ´^f j£f£Rq )S 6u–›FZU4¡1mæ4>†³¯öÙ”J5ßi¶…ašX&Jhšn´E^‰Q]SŒÎ%Ð䥥hY©¬Þ¡¶êÛ$’îIÊD­„bØâ~ÕþÑxCö¯ö‹À,ÁÂF…[K²“\mÇ£È[“ÔÜ"B% ÐáiI¨Í¢JÖڈV3<Æc‹sEï>Ö#)ŠsNÖhòijr !1zâ"×È$¸dû©¶Ã"AYK+ö]üAÚ¿Ú/â~ÕþÑx˜8ITm~/§b—SåÃÔä¾}{‘×›5öeàöµŽù÷•¶ëåág$áÔÒ\žÒTU´UIÖ¡¥²²*%0›È“"3± Íê;¬ÈÌÌŽËâ~ÕþÑxCö¯ö‹À,»Fã:¥o ÕqEAs2dÍ­Íö2Þå—÷ù¯·Õµ¶Ü¹Ÿ@ê\S迤¨ôNù8þéà÷¿×綪ÜÏÝæË³5ö‹‡ˆ!ûWûEàAÚ¿Ú/°+LIEÄõå5ÓY¦ÊFEÅ›G)&Ùe"2B‰ÔiÙi^Ó>‹þ›Âl±D1Òc ¼•·­Nu¾”Ãz1•r±ÙìÆv;嵶ܬž ‡í_í€q?jÿh¼À®jø>“U¨»>L¼BÛ®Û2bâ Ñš+Y¶žJ°º®w3Úf`î`—‡ 4Éij‡PrbJSîÊuìñä2i7]Y¯aÈÍs5X’I""µ¬n ‡í_í€q?jÿh¼À©0Þ›K—EfUy3)7DL=[Ý¥2k¹ÌœÈÒÖ‚²Q¾çsJ>ªÀÃ’°Áâeq1Sœ§ÓÒÄMT˜¨Rr¡Fös%©´ìI’QÖw=¢×â~ÕþÑxCö¯ö‹À, .†ÐÚj§Æ(nTpôÚ"Ž—@LB2‘«³Î~ÕJqiÕžÃU6Ì»suÕlÃèxâ™Æ:¿Jµ¿´Ô_‚ç„Ô]Ù¹öÕgÞŸZÝ;Gˆ!ûWûEàAÚ¿Ú/à©1&›T•Zf-y0éƒ/ÄT=cŽY¤²½S¹È›ÎÒƒºWºåcÖ"ÁVq„*ã“éÍ7K2QRÓÑ«23i‰ddÒÌ2M 3%(®Dekgˆ!ûWûEàAÚ¿Ú/‹0T§‚%9@¬P^­ ¡J¨ª¥O[Pò½åKT³Î¥-Iu$é•‹*y¤dy¯rÂgGÕW±LlETÄ‘\}™MHz,*aÇ‹-H%$–êêÍN‘+š²QXÒ›’‰$Esñ?jÿh¼ˆ!ûWûEà3¼6*ÂXƒEG›‰¡*‡5J'U$ŽShQß+o„„™ĨÛ5ˆîg´jø¶ ®T(8މ5Zb%©‰´Wd-µ¦3,Ñ%²22`ÕÙsÚbÖâ~ÕþÑxCö¯ö‹ÀbÀ¬äàø²ââ¨Òä›×唢4·•qTQXa&•_ÖI°NŠÆFeÕsÄÄ8%ÚÛô·åÖ2¸ÜvâÕòF²jl¥hs!–naÒ¯ó¹®8Ÿâ¹ZüAÚ¿Ú/â~ÕþÑx˜+*æXªVfIšëi©@…ÒH—ȯ>óo%Gr5ÞI‘X½·½‹§†15k ×(uÌU öjT¹8ÔN¬ÝA£Z»º£ZˆŒö$ÐGsÙºÖ¿Cö¯ö‹À8‚µ´^`W4Úv)w„ÇÄuÚLÈOÇ[Y)´çà<•*ŘáK4ìÍê’TFdd¢¶ß”,E‰1™MMÄÊq—âIÜMQudw"Rù¥E³jTFG¸ÈÈY|AÚ¿Ú/â~ÕþÑxNã\U­±‰aRq;t˜8‘ƒEAµÓõë'5 c;jÖ$’FÚ•$ÉW$ì4™ÜfÕðkÒÙ¯¥™ÔåñÅM¹ëf¡KL¸ùS˜ú¥¶kNr»$»’’dfE´ˆïjñ?jÿh¼ˆ!ûWûEà`¥[Ñ\Ä¡1.¨òÕF‰5¨¯0Ö©Æ}ö^K¬ÏTMj G8²+)™‘+»¤µ9ŠlvjS™1$½!¶5)q_ç3+-ú®c¯â~ÕþÑxCö¯ö‹À,hKÄý«ý¢ð ‡í_í€XЗˆ!ûWûEàAÚ¿Ú/°9 /Cö¯ö‹À8‚µ´^`s@:^ ‡í_í€q?jÿh¼Àæ€t¼AÚ¿Ú/â~ÕþÑxÍéx‚µ´^Äý«ý¢ð šÒñ?jÿh¼ˆ!ûWûEà4¥â~ÕþÑxCö¯ö‹À,hKÄý«ý¢ð ‡í_í€XЗˆ!ûWûEàAÚ¿Ú/°9 /Cö¯ö‹À8‚µ´^`s@:^ ‡í_í€q?jÿh¼Àæ€t¼AÚ¿Ú/â~ÕþÑxÍéx‚µ´^Äý«ý¢ð šÒñ?jÿh¼ˆ!ûWûEà4¥â~ÕþÑxCö¯ö‹À, ¦“þ\q—üÉDÿd±®•:>LŠ6%¥¢Uû Ý2ÈjA’M.•+$™•ŒË¦ÛâÈ£aiãlI^7åð™Ó9 ¶΃"Ë|Ær}¶Ø›m¾ÿˆ!ûWûEà!­AU¶û4WÄaÕd·Ù£ÏõWÒ&'uÖUÅKQ4o%?²b2ve#ݘӹ%}§}×1xáoñƒŸèý¤3ø‚µ´^"ŸL ãu¥º¥róŒ­k—òþC4(*WßvÅ Š{îßÿÙxymon-4.3.30/docs/xymon-alerts.html0000664000076400007640000003546112603243142017471 0ustar rpmbuildrpmbuild Configuring Xymon Alerts

Configuring Xymon Alerts

When something breaks, you want to know about it. Since you probably don't have the Xymon webpages in view all of the time, Xymon can generate alerts to draw your attention to problems. Alerts can go out as e-mail, or Xymon can run a script that takes care of activating a pager, sending an SMS, or however you prefer to get alerted.

A simple alert configuration

The configuration file for the Xymon alert module is ~/server/etc/alerts.cfg. This file consists of a number of rules that are matched against the name of the host that has a problem, the name of the service, the time of day and a number of other criteria. Each rule then has a number of recipients that receive the alert. For each recipient you can further refine the rules that need to be matched. An example:

	HOST=www.foo.com
		MAIL webmaster@foo.com SERVICE=http REPEAT=1h
		MAIL unixsupport@foo.com SERVICE=cpu,disk,memory

The first line defines a rule for alerting when something breaks on the host "www.foo.com".
There are two recipients: webmaster@foo.com is notified if it is the "http" service that fails, and the notification is repeated once an hour until the problem is resolved.
unixsupport@foo.com is notified if it is the "cpu", "disk" or "memory" tests that report a failure. Since there is no "REPEAT" setting for this recipient, the default is used which is to repeat the alert every 30 minutes.

OK, suppose now that the webmaster complains about getting e-mails at 4 AM in the morning. The webserver is not supposed to be running between 9 PM and 8 AM, so even though there is a problem, he doesn't want to hear about it until 7:30 - that gives him just enough time to fix the problem. So you must modify the rule so that it doesn't send out alerts until 7:30 AM:

	HOST=www.foo.com
		MAIL webmaster@foo.com SERVICE=http REPEAT=1h TIME=*:0730:2100
		MAIL unixsupport@foo.com SERVICE=cpu,disk,memory

Adding the TIME setting on the recipient causes the alerts for this recipient to be suppressed, unless the time of day is within the interval. So with this setup, the webmaster gets his sleep.

What would have happened if you put the TIME setting on the rule instead of on the recipient ? Like this:

	HOST=www.foo.com TIME=*:0730:2100
		MAIL webmaster@foo.com SERVICE=http REPEAT=1h
		MAIL unixsupport@foo.com SERVICE=cpu,disk,memory

Well, the webmaster would still have his nights to himself - but the TIME setting would then also apply to the alerts that go out when there is a problem with the "cpu", "disk" or "memory" services. So there would not be any mails going to unixsupport@foo.com when a disk fills up during the night.

Keywords in rules and recipients

These are the keywords for setting up rules:

PAGErule matching an alert by the name of the page the host is displayed on. This is the name following the "page", "subpage" or "subparent" keyword in the hosts.cfg file.
EXPAGErule excluding an alert if the pagename matches.
HOSTrule matching an alert by the hostname.
EXHOSTrule excluding an alert by matching the hostname.
SERVICErule matching an alert by the service name.
EXSERVICErule excluding an alert by matching the hostname.
COLORrule matching an alert by color. Can be "red", "yellow", or "purple".
TIMErule matching an alert by the time-of-day. This is specified as the DOWNTIME timespecification in the hosts.cfg file (see hosts.cfg(5)).
DURATIONRule matching an alert if the event has lasted longer/shorter than the given duration. E.g. DURATION>10m (lasted longer than 10 minutes) or DURATION<2h (only sends alerts the first 2 hours). Unless explicitly stated, this is in minutes - you can use 'm', 'h', 'd' for 'minutes', 'hours' and 'days' respectively.
UNMATCHEDThis keyword on a recipient means that he will only get an alert, if no other alerts have been sent. So you can use it e.g. when setting up alerts to specific people for some services, then after those you add a recipient with the UNMATCHED keyword who will only get those alerts that were not sent anyone else. You can also use it to setup a "catch-all" alert recipient, use the UNMATHED keyword on a recipient at the end of the alerts.cfg file.
RECOVEREDRule matches if the alert has recovered from an alert state.
NOTICERule matches if the message is a "notify" message. This type of message is sent when a host or test is disabled or enabled.

These are the keywords for specifying a recipient:

MAILRecipient who receives an e-mail alert. This takes one parameter, the e-mail address.
SCRIPTRecipient that invokes a script. This takes two parameters: The script filename, and the recipient that gets passed to the script.
IGNORERecipient that does NOT send an alert, and will cause Xymon to stop looking for any more recipients. See the example below.
FORMATformat of the text message with the alert. Default is "TEXT" (suitable for e-mail alerts). "PLAIN" is the same as TEXT, except it does not include the URL linking to the status webpage. "SMS" is a short message with no subject for SMS alerts. "SCRIPT" is a brief message template for scripts.
REPEATHow often an alert gets repeated. As with the DURATION setting, this is in minutes unless explicitly modified with 'm', 'h', 'd'.
STOPBy default, xymond_alert looks at all the possible recipients in the alerts.cfg file when handling an alert. If you would like it stop after a specific recipient gets an alert, add the STOP keyword to this recipient. This terminates the search for more recipients.

Wildcards - regular expressions

So now we can setup an alert. But using explicit hostnames is bothersome, if you have many hosts. There is a smarter way:

	HOST=%(www|intranet|support|mail).foo.com
		MAIL webmaster@foo.com SERVICE=http REPEAT=1h
		MAIL unixsupport@foo.com SERVICE=cpu,disk,memory

The percent-sign indicates that the hostname should not be taken literally - instead, (www|intranet|support|mail).foo.com is a Perl-compatible regular expression. This particular expression matches "www.foo.com", "intranet.foo.com", "support.foo.com" and "mail.foo.com". You can use regular expressions to match hostnames, service-names and page-names.

If you want to test how your alert configuration handles a specific host, you can run xymond_alert in test mode - you give it a hostname and servicename as input, and it will go through the configuration and tell you which rules match and who gets an alert.


	osiris:~ $ cd server/
	osiris:~/server $ ./bin/xymoncmd xymond_alert --test osiris.hswn.dk cpu
	Matching host:service:page 'osiris.hswn.dk:cpu:' against rule line 109:Matched
	    *** Match with 'HOST=*' ***
	Matching host:service:page 'osiris.hswn.dk:cpu:' against rule line 110:Matched
	    *** Match with 'MAIL henrik@sample.com REPEAT=2 RECOVERED COLOR=red' ***
	Mail alert with command 'mail -s "XYmon [12345] osiris.hswn.dk:cpu is RED" henrik@sample.com'

If e-mail is not enough

The MAIL keyword means that the alert is sent in an e-mail. Sometimes this ends up being an SMS to your cell-phone - there are several "e-mail to SMS" gateways that perform this service - but that may not be what you want to do. And also, for an e-mail to actually be delivered requires that the mail-server is working. So if you need full control over how alerts are handled, you can use the SCRIPT method instead. Here's how:

	HOST=%(www|intranet|support|mail).foo.com SERVICE=http
		SCRIPT /usr/local/bin/smsalert 4538761925 FORMAT=sms

This alert doesn't go out as e-mail. Instead, when an alert needs to be delivered, Xymon will run the script /usr/local/bin/smsalert. The script can use data from a series of environment variables to build the information it sends in the alert, depending on what the recipient can handle. E.g. for pagers you will typically just send a sequence of numbers - Xymon provides things like the IP-address of the server that has a problem and a numeric code for the service to the script. So a simple script to send an SMS alert with the "sendsms" tool could look like this:

	#!/bin/sh

	/usr/local/bin/sendsms $RCPT "$BBALPHAMSG"

Here you can see the script use two environment variables that Xymon sets up for the script: The $RCPT is the recipient, i.e. the phone-number "4538761925" that is in the alerts.cfg file. The $BBALPHAMSG is text of the status that triggers the alert.

Although $BBALPHAMSG is nice to have, not all recipients can handle the large messages that may be sent in the status message. The FORMAT=sms tells Xymon to change the BBALPHAMSG into a form that is suitable for an SMS message - which has a maximum size of 160 bytes. So Xymon picks out the most important bits of the status message, and puts as much of that as possible into the BBALPHSMSG variable for the script.

The full list of environment variables provided to scripts are as follows:

BBCOLORLEVELThe current color of the status
BBALPHAMSGThe full text of the status log triggering the alert
ACKCODEThe "cookie" that can be used to acknowledge the alert
RCPTThe recipient, from the SCRIPT entry
BBHOSTNAMEThe name of the host that the alert is about
MACHIPThe IP-address of the host that has a problem
BBSVCNAMEThe name of the service that the alert is about
BBSVCNUMThe numeric code for the service. From SVCCODES definition.
BBHOSTSVCHOSTNAME.SERVICE that the alert is about.
BBHOSTSVCCOMMAS As BBHOSTSVC, but dots in the hostname replaced with commas
BBNUMERICA 22-digit number made by BBSVCNUM, MACHIP and ACKCODE.
RECOVEREDIs "1" if the service has recovered.
DOWNSECSNumber of seconds the service has been down.
DOWNSECSMSGWhen recovered, holds the text "Event duration : N" where N is the DOWNSECS value.

This set of environment variables are the same as those provided by Big Brother to custom paging scripts, so you should be able to re-use any paging scripts written for Big Brother with Xymon.

Save on the typing - use macros

Say you have a long list of hosts or e-mail addresses that you want to use several times throughout the alerts.cfg file. Do you have to write the full list every time ? No:

	$WEBHOSTS=%(www|intranet|support|mail).foo.com 
	
	HOST=$WEBHOSTS SERVICE=http
		SCRIPT /usr/local/bin/smsalert 4538761925 FORMAT=sms

	HOST=$WEBHOSTS SERVICE=cpu,disk,memory
		MAIL unixsupport@foo.com

The first line defines $WEBHOSTS as a macro. So everywhere else in the file, "$WEBHOSTS" is automatically replaced with "%(www|intranet|support|mail).foo.com" before the rule is processed. The same method can be used for recipients, e.g. e-mail addresses. In fact, you can put an entire line into a macro:
	$UNIXSUPPORT=MAIL unixsupport@foo.com TIME=*:0800:1600 SERVICE=cpu,disk,memory

	HOST=%(www|intranet|support|mail).foo.com 
		$UNIXSUPPORT

	HOST=dns.bar.com
		$UNIXSUPPORT

would be a perfectly valid way of specifying that unixsupport@foo.com gets e-mailed about cpu-, disk- or memory-problems on the foo.com web-servers, and the bar.com dns-servers.

Note: Nesting macros is possible, except that you must define a macro before you use it in a subsequent macro definition.

There are rules ... and exceptions: IGNORE

A common scenario is where you handle most of the alerts with a wildcard rule, but there is just that one exception where you don't want any cpu alerts from the marketing server on Thursday afternoon. Then it is time for the IGNORE recipient:

	HOST=* COLOR=red
		IGNORE HOST=marketing.foo.com SERVICE=cpu TIME=4:1500:1800
		MAIL admin@foo.com

What this does is it defines a general catch-all alert: All red alerts go off to the admin@foo.com mailbox. There is just one exception: When the marketing.foo.com alerts on the "cpu" status on Thursdays between 3PM and 6PM, that alert is ignored. The IGNORE recipient implicitly has a STOP flag associated, so when the IGNORE recipient is matched, Xymon will stop looking for more recipients - so the next line with the MAIL recipient is never looked at when handling that busy marketing server on Thursdays.

xymon-4.3.30/docs/xymon-apacheconf.txt0000664000076400007640000000350112527752052020141 0ustar rpmbuildrpmbuild# This file is for Apache 1.3.x and Apache 2.x # # Add this to your Apache configuration, it makes # the Xymon webpages and cgi-scripts available in the # "/xymon" and "/xymon-cgi" URLs. # NB: The "Alias" line below must NOT be used if you have # the Xymon webfiles as the root URL. In that case, # you should instead set this: # # DocumentRoot /usr/local/xymon/server/www/ Alias /xymon/ "/usr/local/xymon/server/www/" Options Indexes FollowSymLinks Includes MultiViews # Apache 2.4+ Require all granted Order deny,allow Allow from all ScriptAlias /xymon-cgi/ "/usr/local/xymon/cgi-bin/" AllowOverride None Options ExecCGI Includes # Apache 2.4+ Require all granted Order deny,allow Allow from all ScriptAlias /xymon-seccgi/ "/usr/local/xymon/cgi-secure/" AllowOverride None Options ExecCGI Includes # Apache 2.4+ Require all granted Order deny,allow Allow from all # Password file where users with access to these scripts are kept. # Create it with "htpasswd -c /usr/local/xymon/server/etc/xymonpasswd USERNAME" # Add more users / change passwords with "htpasswd /usr/local/xymon/server/etc/xymonpasswd USERNAME" AuthUserFile /usr/local/xymon/server/etc/xymonpasswd AuthType Basic AuthName "Xymon Administration" Require valid-user xymon-4.3.30/docs/about.html0000664000076400007640000002736311600065757016155 0ustar rpmbuildrpmbuild About the Xymon

About Xymon

In this document:

What is Xymon ?

Xymon is a tool for monitoring servers, applications and networks. It collects information about the health of your computers, the applications running on them, and the network connectivity between them. All of this information is presented in a set of simple, intuitive webpages that are updated frequently to reflect changes in the status of your systems.

Xymon is capable of monitoring a vast set of network services, e.g. mail-servers, web-servers (both plain HTTP and encrypted HTTPS), local server application logs, ressource utilisation and much more.

Much of the information is processed and stored in RRD files, which then form the basis for providing trend graphs showing how e.g. webserver response-times vary over time.

Xymon was inspired by the Big Brother monitoring tool, a freely available tool from BB4 Technologies (now part of Quest Software) with some of the features that Xymon has. But Xymon is better than Big Brother in many ways:

  • Xymon can handle monitoring lots of systems.

    Big Brother is implemented mostly as shell-scripts, and performance suffers badly from this. In large networks where you need to monitor hundreds or thousands of hosts, processing of the data simply cannot keep up. Another problem with BB is that it stores all status-information in individual files; when you have lots of hosts and statuses, the amount of disk I/O triggered by this severely limits how many systems you can monitor with one BB server.
    Xymon avoids these performance bottlenecks by keeping most of the ever-changing data in memory instead of on-disk, and by being implemented in C rather than shell scripts.

  • Xymon has a centralized configuration.

    Xymon keeps all configuration data in one place: On the Xymon server. Big Brother has lots of configuration files stored on the individual servers being monitored, so to change a setting you may need to logon to several servers and change each of them individually.

  • Xymon is easy to setup and deploy.

    Big Brother has a huge number of add-ons, available from the www.deadcat.net site. This is both a blessing and a curse - you can find anything you need as an add-on, but many of the add-ons really ought to have been part of the base package. E.g. the ability to track historical performance data, simple things such as monitoring SSL-enabled services and SSL certificates, or just something as simple as a GUI for temporarily disabling monitoring of a system. Maintaining and improving all of these add-ons gets really complex.
    Xymon has all of these features built-in so you don't have to worry about getting the right add-ons and maintaining them - they come with the base package.
    Also, when it comes to deploying the client-side packages, Xymon clients require no configuration changes when you install them on multiple hosts. So you can setup a template client installation, and then blindly copy it to all of your hosts.

  • Xymon is actively being developed.

    New Xymon versions appear regularly, usually every 4-6 months. In contrast, development of Big Brother appears to have stopped - at least when it comes to the non-commercial (BTF) version.

  • Xymon is licensed as Open Source - Big Brother is not.

    Although the BB "Better-than-Free" license permits the use of BB for non-commercial use without having to buy a license, it is still a non-free package in the Open Source sense. I fully respect the decision of the people behind Big Brother to choose the licensing terms they find best - just as I can choose the licensing terms that I find best for the software I develop. It is my sincere belief that an Open Source license works best for a project such as Xymon, where community involvement is essential to get a tool capable of monitoring as many different systems as possible.

    An interesting essay appeared recently, which tries to explain why Open Source is the natural way for a software product to evolve. If you are curious as to why the trend seems to be that more and more software exist in an Open Source version, I suggest you have a look at it.

Didn't you write something called "bbgen" and "Hobbit" ?

Yes I did. The bbgen toolkit was the name I used for Xymon from 2002 until the end of 2004 (i.e. bbgen version 1.x, 2.x and 3.x). The bbgen versions relied on a Big Brother server to hold the monitoring data and status logs, and this turned out to be a real performance problem for me. So I needed to completely replace Big Brother with something more powerful. In March 2005 version 4 was ready and capable of operating without any need for a Big Brother server, so I decided to change the name to avoid any misunderstanding about whether this was an add-on to Big Brother, or a replacement for it. Xymon no longer has any relation to Big Brother.

From 2005 until November 2008 the project was called "Hobbit". However, it turned out that this is a trademarked name, and I was asked to stop using it. Therefore the project is now called Xymon.

Why did you call it Xymon ?

During the late summer and autumn of 2008 several new names for the project were discussed on the mailing list. I was looking for a name that was short, easy to pronounce, free of any legal ties, and a suitable group of domain names should be available. "Xymon" fit all of these criteria, and just sounded right to me - "XY" could be seen as meaning "anything" and "mon" is short for "monitor". So "Xymon" really just means "The Anything Monitor".

Why should I use Xymon ? My Big Brother setup works just fine.

It is your choice. I think Xymon has many improvements over BB, so I would of course say 'Yes, I think you should'. But in the end it is You who have to deal with the hassle of setting up and learning a new system, so if you are comfortable with what Big Brother is doing for you now, I am not forcing you to switch. If you want to see what some of the Xymon users think about changing to Xymon, check out this thread (continued here) from the Xymon mailing list archive. The executive summary of those messages is that You won't regret switching.

So where can I download Xymon?

The Xymon sources are available on the project page at Sourceforge.

Support

There are two mailing lists about Xymon:

  • The xymon@xymon.com mailing list is for general discussion about Xymon. To avoid spam you must be a subscriber to the list before you are allowed to post mesages. To subscribe to the list, send an e-mail to xymon-subscribe@xymon.com, or visit the list homepage.
    There is an archive of the list.
  • The xymon-announce list is an announcement-list where new versions of Xymon will be announced. You can subscribe to the list by sending an e-mail to xymon-announce-subscribe@xymon.com, or visit the list homepage.

If you have a specific problem with something that is not working, first check the list of known issues, and try to search the list archive. If you don't find the answer, post a message to the Xymon mailing list - I try to answer questions about Xymon in that forum.

Are there any other sites with Xymon stuff?

Several projects have sprung up around Xymon:

  • BBWin is a client for Microsoft Windows systems. It is available from the BBWin project page at Sourceforge. However, currently (October 2010) development seems to have stalled. A new Windows client based on Powershell is currently undergoing intense development, and the core server-side functionality is included in Xymon 4.3.0. The client itself is available from Sourceforge at the Xymon sandbox projects page.
  • DevMon is a tool to collect data from SNMP-capable devices. It is available from the DevMon project page at SourceForge.
  • hobbit-perl-cl is an add-on to Xymon for monitoring databases, BEA Weblogic servers, and NetApp boxes. It is available from the hobbit-perl-cl project page at SourceForge.
  • Xymonton is a site hosting a collection of add-ons for Xymon, including stuff like monitors for Solaris zones (the "zonestat" monitor).
  • The Xymon Wiki has some information about Xymon usage.
  • Deadcat is a repository for Big Brother extensions. Although these were written for Big Brother, most of these can be used with Xymon with little or no extra work since Xymon is compatible with the Big Brother extensions. See the Deadcat site.

Who are you ?

My name is Henrik Storner. I was born in 1964, and live in Copenhagen, the capital of Denmark which is a small country in the northern part of Europe. I have a M.Sc. in Computer Science from the University of Copenhagen, and have been working with computers and Unix systems professionally since 1984. I have been developing bits and pieces of Open Source software for the past 15 years - you'll find my name in the Linux kernel CREDITS file - and I am actively involved in the local Linux Users Group SSLUG, one of the largest LUG's world-wide, where I am a systems administrator for their Internet servers (web, e-mail, news).

I started using Big Brother around 1998, for monitoring a bunch of servers that I was administering. In late 2001 I began working for the CSC Managed Web Services division in Copenhagen, and one of my first tasks was to improve on the monitoring and SLA reporting. After looking at what the standard tools could do, I decided to setup a Big Brother system as a demonstration of what could be done. This was an immediate success. Systems were rapidly added to the Big Brother monitor, and I began to see some of the scalability problems that happen when you go from monitoring 50 servers to monitoring 500 (not to mention the 2500 hosts we are currently - 2006 - keeping tabs on). So I decided it was time to do something about it, and during the autumn and early winter 2002 bbgen was born. The rest is history.

xymon-4.3.30/docs/xymonmain.png0000664000076400007640000013477411535414771016710 0ustar rpmbuildrpmbuild‰PNG  IHDR²ý9mÔ° pHYs  ÒÝ~ü€IDATxÚìý}lçž7þή«3î Ò¥÷Úù‚G°Šý-Rl•U3ÚÜÚLÕÁ”Jq Ú&)IÚU©ÁeU˜ÃÑfªå8©”:©nH‚Ds«G*Å•ÓÉѲrС²#Ñ_-(ŽT{¿ðHdñ¬š¿?.›Ø8Nò@Þ/©©¯_sÍå™Ï\¿xüøñãÇ €ˆˆtìñÊx¼Ù°™)êȬ¢þ22!XY,€,@ Ö¤¢M%¯¯ËáõͪÈXIÏ,0ÝÜ~ÔtSÜZý‚¸5óoT›:ÕØ:ŽûÿÆq óSæÍÿl~q5¿Þ|û¹ç%qkÈ® ¹—w[æw~–ýírsàÙHSÇãÒ”Èï)y"ÿ¼ ³§æug!3÷ݾø¹–¾øÑþcGû—7–ïH={9ô4wVzš×þ‰½úûÉε¦’ÆOšJ 9;–×ó-ck­„/åfÖ–ÂXå=aìªÿÊwWýëýÛ­~]±–lîïõzÉç•8"+];­\άÜUÇF*ÿ°ºgû'êxNTŒü¤<È~ƒÚ‰c/—¯ü9pùù~½Üý ÚohA»»¿í¦»_¡RVpëË•¯v4Ñ…µQhj½Î=µÞ!×ð®!—8Pýq óÝ!—ÿúKòžÔ$/ý°6JÂréö}^×ísSÛnìç<ç ÅB÷íÛ »gu¶þ|ËØÆ(á¹µe¬åÞ—±±ï_‹ýûh?íÛ'ñ¦SÈï5l é×Ö‚솰6cÒB¨ê¡Šj÷:³Ÿ¨$¤éá„T?Q÷^ýDf„ñÀíýãÌ5c½ΘÀÞekÊeíz¹¬`OrÒŸÝó’¸U.;m’ËrŸ¾?l+ÒÔIMšbë¬t:œû_q8õúŠšÙ-‚åLLˆŸ B¨ò!”/úâç÷Å…±ªÿÆØ·sØ»óù=›e{ȞƳ<´uîþÞÖ©¨×§Ó­'Ø~jÊ̘¦°×K?RAû-A{![/|[ùösuH“ÇcÒ¤4uò¿¥©…×dß"» ìÿÇñ@äPú»°³ƒ•–ÌÏzšÏX<Í^_O×÷|ϵÌ#¸ØµØý\} éáXB2sÛ>4s¹u ;^™ÇŽ-¶oÇrŒu¶bµAfޱœÌ]^H‰ºê¿v÷ª¿~âÐ?æ?¾ùŽlfúIe&œT2Ó\ûuuá 9[¶ Ï™Ìó=sÍܵ”=/ü·{±{¾väÖEK9/ò¥Ÿ.Ë;R°=c°@SfÕô­ûË~ÖþfMj-Ž]Gærwÿñ¸»¿µîý‹­uì Œw k¯wÀÕÐvÓÕðÔšÿéîo26žn2²5ÍÜÎ.3§)Ú”ö3 ØMTkÝ{=­uʃë?*,Ž]Gîg ßv,lÛ ›‡¥¹Òyhùjƒl÷ìþÞî¹ê¿>¾hrùÿ8äªõÖì©õ.œ»Ù»zùÊŸ¯^fßn°üâÙÁòçU*Xš9s»™cyØwÿìû}÷¥©v}ú¦—í''Ud?£[Ê‘b¡«B¶^ø¶òíçê¨õ.¶l/6gÒiŽü¤<`¿°¹%êÙj’Åþv¾ç«ì2ÿ2†ÑR΋|ûcqX¾°8{¤`=úÅãÇ?~¯Œ÷Ç+ ÿ‹.GE}Tø:…|jy±¾š,4f ).ÄÏÇ…«—¿úóÕ˙ͤ-oX¾°¼a MÁÌاÂm·^·e®j W…Úô"WªÙ6{V¶ð÷eëŒ}{ÿø× ¶ðýaß1öjô·±WWsDƒ!×ðõ!»!ìèy»{€]¾xº~ã°:v]±:òå»`—hNoͯÞZïþݵÞÕÙÿü%óÎÑG™û>.lùüK–~¤ ßzáÛÊýìjæ*Ï‚Ý(²‹ÔÜý ¹oí ¹Ù³Ä¸0=XciÖê'sMvã:ÔréË¡–„”IHìr6³Áíó=×–^¢ ÙÏÕ?/ØÙÍZpø[†¿ñ·,¼Ï–7v]±¼ù:òNäëÅ~»|9–Îó:b¯fïm¡%*˜8 Xå²Ä™Çwá#kæJÛÍ šä†‡Ö~]]È/oáçãJÔW,g&Ýù`òÑÏ•¨§¿Ká{^øowá{þ|Ý|õI¡ùSÈy‘›ZáG Ö;v=¯ÛØ_2«¯f½Lm}¥çÙWÚíûÌÑíë£þû²Ö¿zùÚ«—Ó?DDìSÏkÿ Ùö鑎§G«¹oçÞ§Ôy<.u²†‹Z‰ö¹V’&ȇ=‰ ÖnÖ Ù/]²öøÞìñ·\ú2}Cò<<ûåûr©B·¾ÖJi.‘¯Ö‰¼1Xì0½ziŠˆ¦2×q5¹æj`ϲì»e¯ ³?Òó‹;Õìf´¬}A@¾òQ@ŽÅ¼‹×‡kƒd¤Ód\ÛçÚóŽtiÇqO±È7¹[ö7¹‰èƒçqr"Wʉôˆèçò<_‰2Ñv2QúI~FúÇwá#kóì¾móÄë¥Q(­â„ÒÕ*?«§ðóq­ÕW‹ßóå¬Ö¾¥œ›nêÄ&ãáÓMƘë Y=½ùjÈû¬_œñY3×Ï75¿÷»†¯û]l {ÆÎšç-¼u!TyOü×îž4Ý¿rk¾Ï¾?Ï »„BU3BÈÕpä®§·fÓ[ÈgYÿF6®\ÚþK¹4ø~dM÷eR—ûÏéH¾­Üý\}Òäɤ4ɺœä¾›fÆkvΖôÅ¿8ÓÏ=Òj~õÝ+à¿r+àwz÷ïþ¹’¶^εÂ÷sõ±g’fn[[ö˜lŸ3ëÀAë¥KƒVV7>¯oÇ: ä–(^æÿŽ—ÙëÌõ Ÿ  £ñLyG#ëÇž[ž×~]]Xîz>®D}Åäþª²ò³\{^øo÷Æ8¦+w^<Û‘€õhÓ ˜Öº–‹­uÍŸ ©Ë>Ö‹/h¿µ+hÏœ6,sôš§ÿÊÓØï?Þgk†Ý·÷‡Ý©'` b7ÆÝ¾.G·  Ü~3àå¢ ^ÎÞJ¡ûó|±kиpò¬üoøà­ ì{½¶uï_¿¶Uš<©I“k¿äˆüž—Dž5Œ_ý#Uø¶r÷sõ±n>vÏîÛvOn¯`¹ôdR.u¨yÝq =DVì|LÈ=ÌÜŽ.3ÇÆA0·µƒ¹¸Æ oŒs­ðý\i¹½£Yw–?¹uà ÕwnÐÊÖd¯ÙòçõíX7t‰ª~AÜ:¸ýæx@y02«<`]*2¿ …ž~÷@×Þî°ûû7ÃîÌÁ5×K]ýs¹Wèù¸õUºã@ôdTckvûζtûXùY®=/ü·{cÓ•8/–r¤`=zÆ1 `iØ D:žˆHÜ?ÛÒÏì ›é\ÛØuj<€••T´©¤bï´Ý°w®ÜØ«?ò¿†“Цðmš¢'"=Àº´aÇ,È|6•Ô‘„”TfÕ¤‚C¾‘°ú~?,L® ¹ 2gæDSÐÔh ²÷4E‹j Ѭª¥Î8N̾!™»ÍxáÉrƒ\dãDNäJ‰‚ö[»‚öõxd­Ï ZÅ­{wŠ[ööÜZ7X~ëÿ,µýЬ`ÙíY$ï»Ç?N·¾a°¾‘f )÷[¹†¯¹XÆþŽ"‡Æ»ä‡ÜñóQ-@!"2‡ASp{›)hæv~fæêÇëÞ­gO°Sïæi•ó™?Là³^<ç³>Yǰøt5eîÜ€õ+,Ð"M)äïÚÿJìbñÛ·ßøö[¢J3aUZÔ¸ °.X¶‡¢ŽÌ"d°zæZ°Û{^6TdMaç×B7 \‘õ¢ÎÀ‰¼Ì•r"ÛÊz9²}ñs-}q¹¬k¯\&—úÎJ“õã{ŠëÇ-c£™Kߘ¥oÏX^pbT‹÷G5ÖÊ _ÈÀÕÐò] '&¿üòÄdk]×ošŒ¯m_xm+ËŸ¤¢MmÜ0hýÄ¥KŠÊ:˜‚ÆÃ¦`“ñšŒ™ÿ;ƒlæJÛÍœ\zÚ(—Š|µNäY/}„ ?—3KZGs§ÐÑ´nÚþkwþôïæÜ¯gn›‚§Ë6lª»@ µEj‹)ñþXê:©$§’ЦÌÖ=ͪzÂeÍÆÀËE6^¶Ð®+R#û•€ÈW«"ã»rØØ¬Óœ?L e´âá²n-ØqÉ软ü¤f¶3˜Ã™9‘h&¬)l‹ìFq­æÉ½Î˜ užüo©ó¨±_k캒[³ƒ%s­-81ª©#Qm¨%Ò0ÔÂB™&E;ù¨ìEó[e/öÞW~ò4)§·ÕÙ÷püõ>k°bôÿ V˜¹mms!‰ÀÕpå»Q»1¸íCcÐìØù™Ùaö”›=Æqãaã¸Q5n1ª–ñ-ã1ú±:FƒßÙA˾Л»÷…"\¤+¡cB>ìÉ¿¦Ì„5%©$£é³Õ)ÔS ¢_±6QíЦ:ä-™¾š ^°Ì͆ f¿Ñÿâ÷}qöš=ÉyòÖœ !+L Lû³ûg²§pOþ9?vQž~r‚Ë Õ–îV°8¼\TÁ˲\°9„ÁJ™U‰Ø†fy{µIæD2“˜ÙäXS’SI…·TèEMѦæ–èK3CI…8¹¨š5JŒ$æ­õK*wŽDÿ`¢µyLY§ ‹ãÕ?XvÏ®ß!rP#qŠz{¿¢Æ„©ß¥j¤xú:~î_:ž‹GµÛû£š¿ç÷þžo|óÿ}û@“5§&'ΜTXÄfO°–X^°¾1Ôrëÿjéë9þŸ> Úol ÚÞš¨Ñ»‘náXk[ÈvÃjê=hêe#A˜‚¦k¦ Ù¾}»ÙnÙ÷ò˾Xbd6–zò}´÷ÃÑ£½£ö+µ{š»j<Í&ÉÔd’2È Õ%¤ÄHBz­S|áµNÚJÿ‹¶žJˆnQˆôd4c$€nž–™a‹cG—ŤQ ’ªüA­µ/0_˜€õ±Ôˆ¾}6_½LĆkJßÒp©‹iÖ³:hþ.h?UöÖ[§ÊTiÚ¯J¤;I™¯±%¬†ÊPÕLe%=ÓÖˆx™¯ž Ü8¢D¾ !ƒeĞ𳙸 gæ¸ôØs8qK…A6s;>3;ÈAD”¦?LpqᇩhjPCNäJ ²)hl4±Ñì¹D°èCžS¥éá¸À‚ Ùir¥D1nºk­¶/xÒMÀy´×â56š½C®EC.URh —Z+·ï·ŽçĨvkW$àw}f ø¯^üûÕËzQoÖ‹œÌÕprfàòIïý"NäÌœØäo¿[çr÷›p[Sƒ}*:Ãz®»2g:pzkö8½vÏn£Ýcö˜ÛÍž˜7Ç‹éå‹)–øñI€ ׉èoµѨ)z:jº¼^z5hLM&a³† rëÀ¹nß>¸ñ«P›ÏúÍtÐþä]uîS³*QRÑ¢ªä³~*HSš¢Mi qDÄ¥ÏPωœ¦ã9Æè?hlýÔiñó ý¸yÙ:*nØ:â•ñþx%Ž#@®õUO.Å<Á‡sO±ÃÕ¢'£»e×Ú®g† X¿_Žt$I•flªÄ&Gd“Þ¥Ï;ö©|LjÝTGOF0­Ñü±:Ìÿd÷„”©©¤ºÕýZ ªÝ~3ªš?¯ ø3×<ÚÛÿñÑÞ'aG:L`·Ø 2+ì3Â䣨yò‘^d]5æò‡ua0wt™‚TFÿ@”®¥‹*ÖgÝÅêsÖé`°åâÙÁòÒYòrÏ9,û^þÞ²/Òzçz¤•º‰¨ûÉYÿRF ðRvšG{ÛFöÛ.}ÁóÔ·ÉCDDݾžºnß“îD¤)?©DDÚ§åglÞ¢ùݼrkÈU?~ð`ýøzÏ“H òN$°9ËC>¶Ž ²uà8ä³ëÉg3O° õìN vˆ¨+µ];ÏôÄ­{^·¦ÃÓþ¨Æn:²G`žÿÆ#½fzNÔ”¢íä'¢›¬uR!¢qóžo2>•ÑQqª‹¼ý^]dýî¿Ïrñ¬Ïâpîßíp.%€ÿÊ­ìà&Ž#¬éºnïÎ¥ÕuKð_»³žëÉÅÊ;À! h4ÖÈDÆÃkãi»Èë½ïÿ¦÷~@W"ª"¢¼ÑdOĉìV‡a¶„ˆˆÒE ‰\$ 'áZ )ꈦ¨‘*-=56¡š"ŒœW„ –»Ó‹ìMD§Y@*ß76¦{ÝZ×âk­‹Ñ¯Äæ9Ëæ <=½"S?þö»õãd$"cæ8Að|ÍÜÉ9¿0Ø'¬{‹í°¼1±É³Y7avµcæÌí驦—k+ñ$ÓÕBÿ>O™£‚Ú‡ÿvGµ‰wÒ;¤Ožœ0.d—ÙOjvާò=Õ¾ÈƉ¦à¶óò 2_mÍ\i»1HôBÆ€|óý¬‡ÖlV‚'Ã/×ð2ŒÍSÀÂlÊÏÌÖß>ø¡ãêec°ÈÆË,'&%'Ç¿ÿúahüëP[B µä"›)Èêá;òNÈ­JÓÉ èŒ"‡²û'Ž÷ìiœ|ÔþËÖºÞû5¿ùùJ”¡:óÙeg-޹ó¼¤sõaøè÷o††Ü·÷‡Ü‘Àíý‘ëtÀŽû›fÂé’–z@½ºöÌå–ÙŠ'ýze¯ñ2·KÇ¥Œ"‡Æ¬Æ»ÃUa7›KNQo±¿A; ",×v×YË‚ÌQÁÙ<äV»eÀú…jÞ¡¬VªïW¥„¤ŽüÜÅ´^Ñ8–¡vĵãIì…ŽøÂS£¾ç `:Ì¥ŸwœÈmçDMѦæÎ)2xg9Od zÑÌ•~fvd~žu:`¯SC'Ù ²Q*®Ñä¸0Í'‰h6£íܳMvËM!Ý´æædé½öýÞûÍ%Kö•ßøUmynî¥K¬Ž×‹l ‚²Íÿ\ö"k/`¹RSPg©‘*iBúò=©$•Y•M˜ kB4ë4mö¼¦nEÔJúÛ‡•¡Ô¹¤Ã´æf‹X¬Hàî‘ÌÌCNÔ”pUȪ©³jªXVmï´ý›½“:éÔ™¹<5”¦ˆ|›ü,6±`œ>c*Ó'ùö×Ùù–¥‡žŒVÀÎDŽÓñ·±ók_­cç¾Ú;\r³'6Éo“Ñä·™ë¨'ÔõDmÏ[oÕöÄ„XL0M¦àÕËþo®^æ^+²q¯-vÍ¥H· ™Ãê™Ü5M7·5Ýdáˬ7ìT´×B¼l<ÌËkaâRýkz³þµÜc—ë”ùŸ¹Sf6—J¾%K×lz¯§ÙÔdl<Ýd¬ ¿z¯2œ»dé[•÷„pÐ6º-h[®5—žÃkŸþµ-6ýkÉo†Óߥðo—yÅ­Õ/ˆ[—7O ß“Â×Ì=úùÊüJ”Ò¥X¸ÕƦ‡RÀ}ZQÍ\ù3ñ»“®Ä¤KsϾCˆ{bWÄ®ÙgG4;ëwÙ8qygÅZwÁ‚Ônó…… XëƒEœŠè‚{ýŠjwŽD5¨“~f2$cp›j ²£†0ÁJ³8vvY19‘^̬:R­ ¬â6dUOé± Ø´ˆ³*±Ž ÁÌAæH”n§ )l}ö×Ìíì2sDtxíåLæ´²WýßL_õ{<þÏk[Å^Ûj ÿm¨¨È–®»Ê^Ü~´ìÅÞûÊOÞƒ£¨Ëä!Q›ÒHSÒÏl91c(VQ/Î&’JØ~çHØÕîŠj1á‡Î„4j¿òa·w ç]ï'r¥ÙOŒ×#6Tž4uü„4u‚>¦YïjŠÎ@ÔWrkW$@DßÚnnµ±Ñ ‚öÑíéÉÿ¬Ë«#©<K*§Ê>1*;Úûaðh/õR„z7ß¹›Y*æ&š )·Â!%s°Ò§>õ¤ÎLMŽ(rfNdm‚HÔÒ]ºRm ´ÀèAë+3l ™ÃóÜ$—µsr›CêhßGûöu4ý¾¸£Išjç¤)!Ï¢×\ M™MdÍñ¯ï¸Æ¿.|}"Ú¶øíÎÓŽà&ݼzyôÿ,705™n²ü »ÇªÂnEùEùê¿y6ëV“ñðéç=þ…\vÆ"— ß>©yr—,«©z¯ž½×{5ß’eØJÁ7ÿK @Þ#û™éµu°Ï9G?_™_‰R ¹’6•¢Zä˜À ³»ˆÖÄ®˜Ê'ª)˜t?K*DOĉô(ɦWfä°ö•öñÝ{ìãDºšåÛ«¼Á‚¾øÅs}qöºÉøö»kq£…Bâ«Ó×GW/õç«—¾˜f7œkÿ‚ûÙšö­—>Šì¢!»ñÌü½’Fí£ÛGS7/L0¸{d|Ñ—ÝVÇŽ.«cåöŠÝ$Dì‘?Eìz263ÇЋ:'&”ÄHBä‚SN’SOƒ¥™°*°YXwv¤4Y›Òd6`\˜V¥'©%ˆrIJ ׿ñb93X~¡j°¼ÞzH_oÕÏ”ÓøÑÞþ öfÛ'öæñ¯#¥ã_³úêÉØ+/”½x´·ÿãÖºŒïÏ>¨DdÕ”Ù¹H›íÔ´„¤Ž$¿õ÷V¿ÕáÜÿŠÃÉúêsªg¾Tk‚Ü0Á%ö¼$è9é½Fÿ<ߥÀínÀ¯<ùHyÀ–°ãÕ߉qOÓ‹§i±k.Íóì.¬¸ýÆÕˬæçD¾šH“‰Ti°ü›ý½J}óëÿ«¹dòÑ7ÿŸÓk v5¶5eVMHƒVßÙA·©Ád•+w­rÊü‰ñ”yÈåÿãK•¦ýªäèyÛ;à¨Ý»ÓQkÝ·ëŠuŸ¦ÌŒi {Í>•¹düêíýãWÙ3ÛÖº÷}­uÿõ速C-ÃׇZÌúÒv³>ß>D®N¼¹jqXþÛâ ¢ýó-‰WÞëŒW:{¾åìaܲnkþ–K_ú[Œ£ÛÚŒ£,µîÁÏßîìöu9º}OZÿ™91tôÖË¡£¹Ï–3÷\QGfÕÓØYéiÜwÀ±sßÌ5NùÙrxá”ëÇß:X?ήÀ[ë?¸ÖZïîku÷±ÐÒ· eöÛ›û¦/~®¥/>hñ´°o$MI“C®¯¾Ë¿Ý\ÑäÔÉh²¶§fOmªÍ»þ\¸±_%Çý»ܽm£î^gwÍgwîq,Gó‡ ÎÃÕéÓžU@ù%§Af¯ç¹ÄIµ&ȼÉ\‹ØOiá!ƒõ8”‘^äJõbº"È{«?KÄB ¯5»í/ °×ésvù£¤+WbYPuÜqûq{J@Nz…œœÌÙ89³|>U_}n}£µ®çï[눈4¥Ûwäé¶]ä#ÖÆ ŽèÄäo“'&E¾Z'ò,LÀžÆ¯÷6 kò*Ï©³›ÿ;NLÜÿ~ÈARq…¸Œo*ªubÞv`ñûÒˆHý4Aý™)o6ùËÆÓõ$»áo¢Ã§ærÿ|˜¼ÖŽH òNä¹u‰jwŽDa÷Ý#!7ç⦳ÂÔ”™*ÍÿtÉI*Dœ™”úñ7_1sµêñiEm2¦åÔEÞ~·.u{lëxå{[Gôµ{¶èkôLašÔl &"2±×n{Û¨;k¬‡ÜÞì¦kpü»ƒã,¸Ÿ»$h¿Q´ùîÐϤ/ò{^ùúСcõ¡zËÛïÖ[ê"Öå °3×y¼fóøÂßn±)žÃùR®<õÊíÊSaý­ÏÂz­|&¬•ë¼°[Àî°]±;FmßýfÔÆZCxC=½!ÚGDû–rdó峋Z.Î7‹º0V5#ŒyÝ¿ôºEÛžmâÏÙÂ÷­ð#^xÙ[ìš Ë÷힯̇ÜÏVhœ;½XdÓ‹NïÞ)§7ì¾½?ìŽcUa%aON%$fišŽ×N˜U9ASˆ4%h×µíûhú´XfO‚sÍ9Ø¥§Y2·›%"ê"R¥éaUJ5]Óæ¹°¾Ás₺.¸ÞÙò… 6ÏÄH•¡ª™Êmà± ò… V?L½W–/¬6ô—&= '$ƒ¼…7ˆz‘… 7¥ÍÜÓ°¹gb:žíž]Wì"ZGÇ”µ‹Ñ“Ž×äJ¹à“åæ§ËçÓõUmÏáOöùºwÓ­¢r»P¥j3‘3s"›vq¾”×:Vröpüõ¾¬'sGó§BGÖ$õ‡þ±~‚ìD4a¥a +Dôǰ›JæÖYxbÅL™õ¤w ë7ÞWÑ?¸®^üûÕË5”Õ¦NF5U›Vç3('X éxnþ5çBcdØe }½ñò1?öäÕÀ¬¥{mÚjl4m}¶5—ÂáÜ¿Ûá\J ÿ•[ÿ³}VS´©¤¢)3aÍ­)Z4³ƒ¦ôÅÿ§¢²6fî%§¦éÚ³Ol,ƒ•9Vϳ{©ö­Õ¾MH‰‘„d\âÅË{þ]¼ÜTòÞçM%®º“š«Žh6‘T8QgЋ¬ŒÄ„iTc.,„ÍÆ ֔Ĉ¦„Ýÿ¶%K{þþÄdRѦˆâÂÃQ-ªÝ=ÕÌ\é?YQíî‘ñ€«áÈ\ö&HÕoXæZØÍ㿞ú÷ý-bÙž„ RA„ ÑF*ØáÜ»Ãá ~Ñ8²Rº¨ŸØ:[æÚ ´ü_W¥oX2°¿”j;iOÕ–ºA6L0ùèŽkòQ\˜Ž ì²cu&šbš©r›jÍGëô—×4jj4¥ ô‹-‰UÆúc©ºWš<©I“µþ·¦ký}ñ Wú⦠iÚ2~© e5¤/|Í¥x^Ó‰å^°£ö‹ç¢Zv˜ µ§Q"ö+ žPG4Å¿â`]_ŸßpÚ¬]†uŸå ë¾ñ«‘wƯæ.ak²îvÕvîÑ^¢¡aÝÐ@fj™cüW¾ øÞƒ^önî’'uà^ï@ýÄÛïÕOt4w^éhæå¢^¸¨ÌJ¿¹¤ñtsILøqwL`9éé=SîY†Ù^Ny)S-.œ²ÈW=ùSeŸœ?U&ü±êáÜ)ÎÉÒë¹ÿÐë…ºªQ¡îÙ¾Qî>³|fv(W:‘¯®y"ݵüé Z.üË e_­³j_mÿû™žuÙÎ=Ž…+üˆ^ö»f¾³€…o–òíVÒâZ°²ßIJwz³ClùbS£gš5¦pì7Ô,m7)0SCMÔ¢š¨5^/²9ÈÌ\ù‡Å±ýC3ÇÉÜN^¹_Û_<~üøñãÇ,ÚWÈÂîpU8ÕÀ¬.òö{u‘µqÓkÁ¬J”f ‰M™ê·Ÿƒ5¤gÓ1¦&cCÏçœOË·&­XóZwﱈ»×]qìWî "ê{òFvp[l›€…±^œUõ¢^$Ò‹¤×ÂZÄ…xg\ i&L’¦Ì„5eÔþý›£vc°¨ÂdXûS¢¢ÛsóD̪D©Ô2Â"I…=HXÜþEúEjJ³'}ÖK—|Vö7û]XkÒSÏÎ÷7ûyZ¾¿kßÂõØJÿ]ªì[úYU/f.aÍÜöÍg&JwéÕñéؤ‰ìSfî¥3ÇfIHÏD“n}T2§™L‡ ÷-æiYà³ÿÑ—ÔâØÑeq„Ý·)ì¶yv}eÛ¤óT¬esÓÐ.AòÖ6MÉœl{ýIt|v€ !Í&)3aRØ÷³yvŽÙ<¼VºóÁâë4Osg¥§ÙÝÛ6:ßð`GûÛnío2¾ÛÓd´:,¬Žç•« ×Û¹9û[°Þ±qéY{½Ìå}÷ÏÜw±µJῃ‹-]›çÖ8jl4Žnìï¸ëe®+Gx^[OfŽP~M¤s‡§MwÿÏœ‡bî~*ý©§Û d¦™žéÙÛüÌl,4£xŒ8*ªXÚ d.1‹;+Ìbîòti¸ÙT†_ù¾2œ;¶…zBQO<¯ùŸW»4Ùl“†²0™ÛÖf挣Å5é‹3í[mJû–ÎzU©’:¢Jf϶6³'ßÔ‰k“¢^ŸVTö~¨eøìP y°ðGýÄÛ-õ•T6ÿðZØçnßçuÝ>7µ}àžçÝŽÆÎW;‰èÂz+oï·€M(˜û«GµÓ¦ >®˜øÇ`5e>áϼŸïÉ?Wúô§çZdæ>•ýà67ågñÙ›_AÆži²¦\vÚ$—±6 âÖ=/‰[c½ÎXÖ3Ïú‰º÷ê'Ø¿lMö´j<94žÕ|…=1fé°¿,}öL&sÍ„4=œXÊ™[ÜÞ?¾©›ÿ1ñÊéáxeæ_&`­bÂôpLˆj÷:£{RÍ>ÅæIfËÓï>cc)°Û¶ì5µ©¤’oyf ¹[aç+Û³*Qæ:,ýÍ}lgU"ã(_mUOÌŒ©'ØñeáÖÚ(óØEwÌ5cù?ÿs9Ÿ>ÊÓÃÙGsu꯯§Îë“KÛ9¹4³e{Í–{}]¯/·Ö’¦NjÒÔÂ5[’®gª_·Êeíz¹,wO ©»ØrÖ ,³õVáuTöžïyIܴߨ´Óû[°ØïÅŽ”ãÀÞŽ¶ÎÝßÛ:Y0ˆµÅÈ]¾6¿uzùÓ¿D¹ /]}ñóÇûâÙ¥kïNÇÜ5“ÊL8©°²wÕíîUÿÂå“­S?qèó£|¥ný5€Å˼Ï÷zþõÓ!€|©-§¿XYËn>Íœ¹Ý̱§4MÆÆÓMFwÿñÿt÷g®éiì¬ô4²9~ÙšžÆ3åžFwÿ±‰ì5¥©“ÿ-MµÖ½×ÓZ§<¸þ£òÀâØÙeqääî?w÷·Ö½±µŽ¥éèÚëp5´Ýt5læ">:V>ÊníØmyî:¦ ñ°)hó¼|Åæ1ë·}hÖ³ð)X\c V†+nT†mžò/lUšV%NäÌ\ÖÉ`‹k 2[‡ý ñþ¸À&É\Ξog¦¹•ÌmÅu$&°ç~lM¶WÆ`±Ó˜ZŸÝ.fŽ)ºÙð2_ÍË£¶±ªQ[:€2NPÒgå¶63Çâš¶ŽŠ¶Ö!Ÿ|u:?Ùš,…ÌœOeãaƒœ*' ®¹ÌeØýýþ°Ûî±Ý°Ï3˜«Ý³û¶Ý L<Õ+˜}w‹Ãò…űpÄ–°wÙšfng—™Ë­g ©»ØrÖ ,óyuáuÛs›ÇvÃæaõžªz(„V®ÞNß@>ý·`Ðb¿—)h:l ._»¸š9Ë4[n3ðl†tk-ª)fý¶¯ÌúT3ûM…KLc£ÉÁò'Fñó1JH³jþ X~&Z4°é·}eËÊOб„wtYÂùÊÉÂk®¯)ä¾õrÈÝÛv¶ª·-sMI<þ™”UÏ^wåZlUëÝ¿{¹GaÈ•·>™_ÜÉÿÜ“ó¿ÛVæèVÇ®+V‡vsVÕnÖ>ªÙSû(syLˆ÷ÇzDУUÍr:KåË•~á¥KUÍ!—çÈ\§·fÖé­•÷ï®Í:k{j^¯í‘KÛ#r©ÀW |æ»ùÊ'{Wš:—¦æ9F—éeºœ¯Ô­Í£°™­ã`A!\ G®¹Ø“ {Åî_Ù+èÁìôÀüâNµ°Îù\½|íÎÕËz‘+}Òd‡ 2r#—žtN¾@CöÀó§jŠ&¢pnÊ™)dõº×Ãl¹’øn—’˜o[:‘¦h#e´…¥c9Ì.ë-âŽ.‹ÈžÆ›=¥íæTkŽ*œ<ùùóGyá5— kËš ÇB“¬Aæ»!w¸*ä¶”•¿n)£¯é›t`mÖ]…ÔQ©–tüú¹ÝZLÝût“M´LÄÚ dåN('©ÛG `#X—Ý¿køºßÅ^³ÑË…På½ì´ if,!±flI_ü‹3}ñÜÁöØgþkwþtšWn ¹r×d›ù¬_œñY3—³ ©Bdæ*ë>À(bC!²pC4?Mæ¸èY‡KœU‰x¹¸†—Y¯ûÈÕ»G²çIïgæÄxå´?½õÌ&÷›Sæ,ÿYçvqϽƙ¹×ò}Ö sfƒœ›Ÿ¹ÝL˜ùÖ,²­d¦Éø^O“‘õ¦Î¥‚½fÏKÓ>Kd÷ìþÞîÉ]3·<^wåvÍØ¨uÔf¨{MÁmm¦`æ7Ê÷K”«ðÒÅF7B•?!¹´ý—ri$ðýSÓPu4ž)ïhdãD°n ÙåS™¯|ò2ÿw¼Ì^g®ÏFÚÌõ'Àz´.ƒìâ8ªEOF5Öó³Ûw¶¥ÛÇ.z2×”KO&åRÇš×ÒCŽÅÎÇ„Ô“Š¬5Û)—²ÉÒØšl’H^.ªà³g²ž™Aû­]A;Ûº0VyOëhþTèhF‘Z,6ŽÀ“á ?Mh—oÌ‚¥`a‚°{¬*ìŽî~¾8Î&„íUL¸÷iL`{ÅúýÎ7 ÈfÁZ d:˜ÙR#³U»±g£dçgü|Lˆ¦NFª43¦JGi»Å‘Û¢$©ÌŒ%•HàÞ§‘@jn…œ­¬Ö+›õúfͰÙ9Î^³P‚Èï)Ξ¡ðÉÓxú¯<}ñþã}q¶fØ}{Ø=_ThÝ%ò{^y6ÔÜÆ®£6CÝËŽ;륟þ%ŠŠrû|ùShéjmøà­ l×¶îýë×¶J“'5i27ÍÝa÷÷o†ÝløÏô~¶sså³úqëxàö›ãåÁȬò€ =˜9:CÈ}k‚éëÍ/?~üøñãÈÕï÷Ï÷|5W$pçH$Àš×EÞ~¯.²±&­™›”‚êÌ&Qó· “nœ ù2¡`¾uØí»Éä^ÓñÙϨ³{³ÏŸBáËy¹ÈÆËÜkE6î5vó©};«jß²gã™k²½âOñÕü)¶$ßš›æ0÷±–™2×dG07?ÓŸ›\“͆ ^½'´oµ¨ömæ¶Öæ4œ›g^úÕÁÚ°Ø;m7쑯#ïD¾Fž¬&E™UT ²°ÉŸ2û]÷ÞïùûÞûl8%€•–,X/u ‚Ë‹µ’pz÷¿âôº{EܽÈ€ÕÄ‚|€ÃÅ \¾òçÀeª _QEj‘ƒ®Â«Äê(m·:h”ˆF×Ë>#L°¼Ø„|ÔKB˜à¹YÇÀFµ9»x¬©–šÂþ€Í- KªeAT»ss ‘Îg¹xÖgYJl¤Dd%ÀÆš:Lª‚zb&¬ž(äŠz}ZQ5E‹jJ]äí÷ê"·`c`½téΪÈÀlð ‚enÌ‚Döݾó'º}ìukÝáS­uOÞÚ‚lƒl1!~>& `¹Ø:*nØ:0xêf†Z–jœû€s¹°XºÜE™a‹cG—Å¡¨7HQE¾ê¡È#Ë ŸH òN$€|€¥³uT­ù¨U`¹ VÁ¹8÷`±æ 8œ{ŠΨ=ÕD~O±ÈiQd†M¨‰|€gSø4®°y V¥@­‚spîÀ³I 4eVÕöÚDÆÃ&"ÚI ¢.¢¨vïÓ¨f ›‚d§-d_ÞH*ÚѨ=òNR ÚïI/·8JÛ‰DÞrA/ä"ÛZÍÄ ] ÚƒöØyE&Þ‰j}÷köôÝGñÖ´ž=†IHÓà )ó]½XT¡Íœ¹ÝÌ™¹mmfŽHÇ#×àyË;À! hÊLXSRa‚0h½±%©4—tVFµ¨vïSMq8_¾¢)B¨´]Sü®‘YUªí9cIHŽÇ&Bî¤2«®½L´8ŠlGØ}¯3àåØy^FÁØœõú´¢¶6ùCkƒ¸uÏKâVOó‹§9ªMŒj™¯6ÈfnG—™c×W IIHƒÖ ¿´:ìßí8Ðoü¤©„èÊwWýD3ᤂ\€Õ§{^î‹ßØB4tàÊ­°;0~Ú(pDºWH&] "žˆHäwÑQO—3¨Å…{1AYÇÛ×HÖÍO/Q)ŠÀf1ä¾>äêh>céhNH3c IæO&e¾ûAçîÔ¨{•‰èU""zHDº@öY;íÞc'¢š$MÒšLއã$}^×í#ê:Ù­éźwkãDo¿W7NÄ•¦®6VÐs˜:1&¨#DC®kwÆÝGÇÂÍí:„Ð`ù™òZï|ï³¶‘C!7Ñíý!7ÑϣˉD1µ©›gÕñ‚ÑIH3áôߘ0=LÕâçŸNY_j˜·eÛûGÆD3áì&ˆ°ÒØ¥¼¸µúqkæ_¶|éé›_Üù™ùÅì%æÎ^IR™ '•¦’ÆOšJ\ -ÿ×ÕÀ‰E6N VŒü¬¨õºH퉟jæŠm[Ÿ¹Ñ~ü|LHHg,î~¢]Û*íéoqk—RFDŸS'v¾Úw_/Ùænàïuí Çô¢A~©¦ÒM4î›âD¯Д"›4IÄW !¶¶×w}:©Ä…éaMI–ͪDqáa˜‰Ô‘¸ ò»®9”=*§QÑÓ{¨Ž$¤˜pò¿Ýýœh;n³EZÂÍœ?ÕT©fºÉj Öì©GAX9¬Ip_ülK_|¨eøìP kÌšþÖO¼ÝR?aPùˆAùjæ|€Ÿ“T´©¤RÛóö?Ôö„ýßyÃ~N,ªàÄÁò/Î –äâÆeë¨Eܽ¤L݈z4%|2ì&å][kƒ^<÷~÷Qi»™Ã€•ðZDµ{ìÙ¾º¤§ë1á´ÉÝOtøÔÑ^ƒ|ø´«Î ¿Ûãª#:|ÚÝK9 „Ýï}^?‘þDü¼\ÕîQ%ƒl¹ —×ìs•¶û[4åᘦ$¤pUSIR™ '$E"µnjréÛïäŽÆw>2ÈIez8.„܇b‚ͳ£‹óïáÉÿv5pâû¾¹=l缑@¬?!)ªïÜ õyxÓMS“éæÂK6¯¯§Îë“KÛ9¹”… Øröš-÷úº^_æ§X»iê¤&M±^ÇAû-A{L¸×ØÖ6A.k×Ëeù¶.—6Éeé¶ {^·²²ëŠ{1Áq`ÿß8°5ÙëÜ5YŸçôÖ÷¼$neéç¶k@­°rN•6ž* »¿Ûv³%NïþÝNo!c<±0eÈ® ¹ ߢ^|û½ô£M™ «RR9—¦õ°ç>,JÞ`A_üâ¹¾8û»¼›Ô”ŸÔ¤¢)³*'²ØüâÓ™½êj‘w¢šAÞuÅîÉ|Ï Wþ „ˆvv™9M¹s$ªÅ„»GÆIåGÐfÆlžùÒÜR!òœ¨3hʨýútGóëæ¶¤’¦‡³û¹êj~m jÊl‚õߊæŸ8\´'¤èɨƉúR½˜zê<Í1¡s÷sâ[›ŒNïùËWÿãG6›°ûûýa·Ýc»aŸçÜ·{vß¶{"‰§æôfsÄØ<¶6òàúÊ!TõP¹ûÿ§»¿ÉØxºÉ¨<ùIy`æXm£MiJn l„s¶&ûK!sM¶¤~¼îÝúq¶&{»¦4uò¿¥©Öº÷zZëØ^Y;»,ŽÜ­£VX l.ƒ¾øùÙWGlÀÂBR0ÈE6ƒ¬)3cš2ˆäþeaÁìÏmÿ0; ¡)Ñ“QhdVQqîÀJH ’ QRa3ÇŽ.‹#h¿µ+hgï.}“é>ÿɨ)vßÞŸ¿ßÝkt{RrÝÚ•î0ä™MHD·v)ª¦°Fþó÷ÜãÄ—¿²{’Š6¥) )z2à'Ò¦b‚¦hÑùZ4p¢±Ñé%âJy9!MÇ„¨öçšÔ}VPÃæ1·ëENÔTÉîyùŠqžgIeâP$@4íOH£öëÓWýDUEÞZ– VGî_cÐØh Fµ»G¢Z:ˆðç1!ØuÅæ‰ŠlœÈ®e’ÊÜþàÜ€åõ¤ekÆ6«9œ{ŠN&`?ìÙÚr5uyËDšòoæä²/~rSNHÚ'š‚|5J0&tû†¯G5"m*ª%mŠˆ—gUUŠjìVüizñ%§1¨)|5/k g6s™+Õ¢™p¾†Y•Ô"N,®1sµ^Û UR¥‡a¢ú‰“ZØÍ†f”¦.ž‹ gÅ¿‰|åó_ƒ™HS’Ê­]£öÜ« ?ê°™Ù{Ä"WÑ?¸Øú¬F ÚoíM%ï~ÞT–·6¼±µ-w5¹æj°wVþ‡½Óïºv7à/d¬œû°XyÇ,`!g¯—o£:žh¨¥ý—fÎæy©&ª)êèö¨&ŒµÝÈe—.%$E W%•«þpURñ»®OÇ^NF#S°¸†õâ¶63§ÛF¥É¤¢Ž$• ýà[ŽIåâ¹¾xL8omˆ :'Öz{ÞN `w]jQ%mÊŒj7Šê'Rä\–T¦NÊeQ-\Õ·8öîð·èŹŒ­Ž]¦ \ú^Ý~Ö”H`z˜—¥©s-éî1a&X!ˆ¹ƒöÈ;A»1Øóö`yTã̼ºÍãý#Œý£ã@BºòÝrLØV8üÀÃæ´Ï¹wÇ>'/ ¶§æõÚ6ˆ {ÍB ¬U!©yOÿ•§±/Þ¼/ÎÒ »oï»9‘+ÍîÀÚ&DµèɨÆÖìöméöÉ¥í¿”KsÓ´úÎ ZÙšì5[ž¹&ûl·¯ËÑíc7‘Àí7#^.ªàåÕÏ[Ô*°™Ù<7lË¥/ý-éLžž›€µD`ëðr‘—ÝýÇ&ÜýžæÎJOsnšÇË_YlÚE6" [ÎÆFaËÙvÙc’ùF7À¹ËC÷¼6lùj½ ÚGãˆ1æðY¯wE„¨‰“¦þ¸Ý4 ævSÐÓØxÃ4µ7‰ÄÑ“΃ëÇÍε¾mä¾×IÔíóÿ1&ð²¾”È$ÑpL‹ÉDªÐ'ŒÌš9¢ŸêBnÙÓBvO°¢Å¬ˆ ÓñS°¸Æ"QÇ“cü¦û7äÒí#­ÔÌíþ¥0`K_yÓåk4ˆŸvØØØEv-ü©6û /í!oîúÑGÑßFå.7·µ™‚ ]ÿñɃüRâ¨T~Ôþühž&)F“'‰ˆèG" RsÓ Ð•??iðt™þL—‰¨-{ëìV„5~&ÒýDtµ÷ÚÝ«½¡xø‹Pœ¾¦oèkÔ*kŽ'bAÉQºI£¤¨#ÿ£¨nj#÷:þV8÷6¶'Á‚ÙÄóÛ «ÃrÁ”K-dâ‰Ýà—’D´ƒˆ‚´ƒxb¦ã‰¬Žjy"z…¼TÀ _f®´Ýî¡ ]°I¤jÊê«ÔN”Ë.ü>{ë^áE«£´Ç QÌL<˜ùûd¨Öqü?£š¢|·+ ¢í©=™¯) Ž'²{ö¿Rë%¢Wˆˆè =çY‘s{¢Ÿ!Àzá8Póºã@ªƒX™¨¬÷~Ï/{ï?ß½B­k§é³^ü/Ÿ•µBr÷ ¸{‰§bâ×û·Ã¹°Qé¹úâ#³ )ªMŒ©VǶ6sV¨Â Ùôb“õà³Ò'~Šô€h¾'“+!pùÊŸ—©‚~E©EºBŽÍœ'«ƒu%0–m³ËLÁ—jLA"z;ÿúlö„ñ’ÈÅñ‘¯¾ òMjz`æK‹Í<[Ç,®1ê¶"£j¨3TêÈH§Éhùjƒl n+2MÁb¶­òÍÅÀóÅ:ž§F"jÄÑ€å• h ûˆˆx™HSÔæÄ'ÖOœ¾2.÷Þ?±:ô"WJÄæbš±DµÖñƒÍ›Á“MTKDôòÏ­/òÕ:‘—ZŽ)µ°.KDÔž½NGcç«é[}#&#{)MžLJ“RÛÉ—¥6"Ф×o2¾ÛÓdlj{—šÚpD`åämYàw ÿ1=.·Ó[ókç&º!vÕÕì1ÈZ³º#êp£Û£ZmO{æ6L™8‘kà*õ¢TW·ÛÌÙ½;ºôâæÉX˜4yl\š”ÚŽÿ­Ôf c«5OÀòš³@M¿ò»®|—X;º,ŽHà6E‡å‚e5su÷>m÷¸é0Ñe""*§yè>ň#uÂóPOÌ„ÕÈX.¨U`}aC–"pî¬wó´,p8÷;œ©é¾ø=Å"îuÆdäc머aë°uT­¹K‡Zç>ràùš'XÀÆé5+æv³BD]Dš¢MiJî,âL¼2Þ¯D>ÀrA­€sž¯¼c°Ð@Œîuƈ#®”ÛL¹°‰Í3flf,€L©–šÂþ€Í.,ˆjwŽD5dè|–‹g}–¥$¡¨#³ŠŠ¬Ø~{5Ö{ÏÆ8jl4Ž"`a˜ `}Ñ! àÙ°0n¡¬ý‘ÈWëD¹°öa6X4„ `±X˜]–Ö‹¼- pYùÔÑÛT‡lذæ  Á0Àf–,È Œî ƒ —‘ŒFdÀ†…1 ‚Á€a~ÑüÏæó¿»ó³üï.%e€¥[t°`ß=/í;°»Òï?Þ¶ÏæîUîWÃû] «ŸÅ çØÊå' DEݾ.G·OS~R5…-W¥‡UéTY»þTYÀ¸ðãd&äW…ÜÒÔIMš"šUÓËcBü|Lhmh¹ØÚ0h½xnЊ¼بÖPË¿ëâ9¿kåÒ÷|þ¶w`³`SÐxØŒî| ø]Ϧs˜Ý *êõiE¾ßYÁÁ,£ÚÔɨ&nÝ󒸕ý•ËN›ä²Ü§ëì™9Û7¶fÐ~cKО¦‡RýDÝ{õâÖêÒéŒnïφ³ð5Ù¶<Í•žf¶Ž­s÷÷¶N–'«¤b½Θà8°ÿoØž³×lyîú,3¿c¾5ËÌmo3sãÛo޼¾ž:¯-o*y÷ó¦¿kø~WÈ}kWȽ)ëL€Ma‚ìÙ8kÐ\òîçÍ%õߪŸµnµg®éwù¯û]õo¿W?Ñ\òαæWûŸ»šKÒ\¢)Ú”¦°×l}wÿGî~¶fzý÷/º¢ZôdT{¶ý|¶= ±óqíûÛ?ÛÒ_‰vl[웲o½”ÔxÙPÍËG{ÛFööÅϵöÅÝýÞt÷Gß¿ ƒÛ>4ÞƒÞ•+dÒÔÉÿ–¦ZëÞëi­S\ÿQy`qìì²8ØÏ\SSfUM±yl7l¶¦ªz(„ÜýÇãîþÖº÷/¶Ö)F~Rxºöz\ m7³[‹¾&Û–™3·›9¶­¾ûgßï»/Mµë¥©…¿»_x–~úfþé¿™OìŸìùºûëÇëÞ­g{Î^³åù÷|ä'åA“±ñt“1wÍgc‹k ²\zÚ(—ž*ûÄtªÌÙsð-gOØýÝ®°ÛÌíè2sMÆw{š0%À†¥[zé[—mmf®éþ¹â¦û¬é»ìkß+û*©òlej;ø¹–¾øÐý/¿ºÏÝßbãîkÊð¦p[lÜÀ¾{J÷è½|þãÞËl}iòXDšäï¿t†¿Ï–°0AGóKG³wàsZZKÂ÷Üëë¬ôúœ¡ƒ:gÈátìp8YÓ}M™=—}»›o+™A¬wµÙ“ZVàƒmËÚûÐr ¼ù¶cZC°K›ç•Û6Oæ-ßÑÉc‘£“ærs»¹|å YÐ>º-hïužÝÝë$/yk½5{j½nñØ„[¤GDô(sýZïþݵÞìníÑà-¤­ôm¥ºH i&œ¨^¦¶Å®É‰:ž3·e÷ØnØ=1!Þè}½W™—¯ü9pyáoÍÒg7óó‘wòÙ­*R¹ä=»§×K"‰õãÖËîö+²›¾&¢¯3×wzkö8 ZóÙX– VGeèoV†Fíÿ¶eÔnq”_°8<¯zÙ»¨@6ªeë† òÕ:‘g¯-Ë‹C•¦‡U)s›g÷m›‡5ŸVÔ‘YEåDÎ̉ùÒd·m®†®¥Ÿ±³>öQíî‘Å·,XÊž‡Ýßï»E¾ú/Ók:œ{ŠÎBÒg7½÷ÏÜ{?÷/{w¾mí)Nokéõ›iEeaÖš€å¡ß5|ÝïR¥ÄHö÷}^Ò¹¡›÷›_½|íÎÕËìö›ý ·Ýz9ܶ”5ómks›U‰†\—. ¹X˜ÀÌ•þ“™‹&E}ñó'ú⬻r `£Z†`AúïþçÖ”KÛ9¹´ÖûÖÁZoØ}kWØíî?6‘¿á´\Ö®—ËXóõÞû_œé½ï8û¾w€=«_Í=OÓÖÛŽj?tF5Ÿõ‹3>+kMP?þαúqö®¢^»«¨Ý¾ÏÝ>6äáJ샪¼'„þkwÒÃ(¹®Ür~Y@‡}‹Ìål(¾g[s­a¹ÄÂ7lÉ õÒ¥A«Ý³û{»'wýÌ5‡\Ãׇ\,…å(3S'£Z·¯§®ÛÇZ°n,éí^ºäw±q%؇›¥²ØLVu€CÖŸõHo­û ÐZÕî~0×Fàég¼š¢E5Å ; 2[ð_¹õ<Æí·y^¾bóí#³ÁÔX¬eÄÊl«â†Í£¨#ÿ³´ôãÂq¡£ù´©£™…9¼]¿ñ°nG{??ÚˉEœÈÀ³[Ä•øFriû/åR6#Š/¸ýf$ÀËE¼\H žÆ3åžÆ ýÖ® õùÆ*ï cÍŸ Í϶æR2fÁbyOÿ•§qÐê;7he{Î^³å™k² ë’ÃÖìöméö±|^Ê>°2p´ÿ£‰£©ÞÕËWþ|õr­÷àÁZ/ë€ÀËüßñrÀ}:àjwެL™€çK·š“ËNå2­D=¦•ÑçDMÞ÷/6y‰h‘ªšBløÃÁò‹gË›Œï_l2¶69ÞÚ`()úÄPRª® qqÏʼnèÇÕÚsWÝ‘€«Ž Ô磋ŸøÈæÙ}ÄæáD®”‰èβnëš«N.kçä2¿ëâ1¿‹µªx¶ÔšŒïõ4M¥Å5¦RNÜbKwy`ÝL¥&ÎTÊ–X/eq‘y¹sÏÌ•>DH÷ÑÕÞkw¯ö†âá/Bqúš¾I÷±>Šþ6:ÏHz±È¦û謭ˆè'"ª mTADÿò¬kæÛVôÑ¢þF…ŒY/ý|[1·µ™‚ºòç'“6\¦?Óe"j›7åIŠÑ¤DÇI¢Ô¹¤6 .ýx¹{Eܽ¦û¦M÷õbQ»>UfØ( f÷¶]f7•Q9ëXD"•’ˆÊ`#ùEìÕX_ìUöö´œ5äÜ=2ØÜ™³Qû¢Qû õËKƒVïÀg{7Ó¤Œ¢áogDC¼2Þ¯,üSìi¼*©OÆGè½ßó÷½÷­Ž]W0TÞæYà 7Ö2² pl:ĤŽ$$òéxòÉ¥'¯-­á÷æ‘z_A¿¢ŠÔ"]!„ Ö Á;ðùÛ›©lN,€L@ ‚å?~üø12 ·ØI2GÆQäÀÚä³|qÆgI ê#S' §ˆˆ8‘ˆHSˆt<‘^ÔñDœÈ™‰ˆ¸RMáD¯)š2u’Ò̘¦iQ"¢äûÑl‚ˆhVÍþËÞåÄY•5…HSÒK´èÜvçÖLK¥àĤ2·Nö»Lf:¹)ü”‘rV ‰Ì5ÓûƉ³ó®ÏöVS2·’ýíæû¦Oo%ßkNL*:^Sô¢%J*DDz‘hî»ÿ¤>}(gÕ§¿õÓyȉ³‰œ%jn>-´oseãÉ·{êiŠŽO¿ÎÞ£Ù§öù©¼}’N:å…¿+“¹yΖkSÙ{²0N$âDMÑñO—«•’Þâü¹¿6š{ØOäÌfúŽÏ¶E”R”í…¬î/Âúͽç¹çÙÇhåö¤”ó­³¼{µPjK)±ëáúð›µzy²öψÁò ÿ2XŽnå[ôÅ+ÿÃéEöäR¥ïvù]…­‹–° eÁêå ZÀº„`dA°² XY,€,@ Ë2 ËÏ”K“MÆ·:œ¹ïr"Wʉ±WG~,7sÛ?4•ç?ö4â0ÀZc Õ9qâÖËC­¡¶áoºØ_Vb-Ž]fnmî9'n©àDOc[°Éˆã™X¹e¥Z.-´„°s!úèú}÷—÷üz¶úÿÙ>»ÒçE¾ô—òMa¾r8òÓ`ùò–Ò…SØÌ–;X`½vGQëÇ÷îùÜw÷9«uv¢ŽUEQí‡Oc‚¸õð'î~X›Ô3aí[{gÍë­ ìo·ÏwÎïê8k­[›û¬u½XëÝ»SáB&V3û[¯ÝµÕï)~~%$!%FÒ³ÕÿÏöÙ•>/ò¥¿”o ð|-s° ࿱%h·8JÛMASÐtØÌ|·nüõb‘÷»w5_,Ÿ}*pùÜûr){–¬¸øº2Ÿå²– žÆ¹6ö©Ø«7~5ÔÊÚ/¤öçòç/— !Û¿ZlIýø›¯ˆ[HÙÎw^,|6¥·¸¥‚•ç?NŸÝìoæ^-œ~îÞ~Ž/œ°°Bjæ\…×Õ›n¹œU‰ü®‘Ù ½^Û»Cpy„~ØýQÅ-Ky½ÿ£YO‰^ÜBú@îçûî·s­uÒT×Þ¾x¨óöëÑvaÔ!;Ýdtx—¤)E½µ+ìn ¼±o’ˆÞ¢§·Zgó¨uêˆzbßT•Ãr]§ ÝâØñ™™ ¾x{g$À‰ωÞÇZ-¯?qk!wä­¨FcôVjãe(°°&ãþݧ29º=ä&""_áåv.î5iªËÑ×팾k`Á/¹ôƒÛõŽú‰c¡ï~û/[뤲žÃ>«ÒycKÈíîm¼Uë•K?lk’¤©Ï¾T:^ß¿ôEÑ“Ý ÔLDÔ·u¸Z‘Cm_Ú<'ì/Ö¼ÞÚڦȕ¢üoVBh÷m‹#!©Á„1:öç±~ŸõzO¯åö•†[Ê*É}üðõ€°ó«O”ӄ颡,XqžnH¯ã¹×º}—>¿ê•Ü~+&lÿjq Mvõȧö5·œ‘¢!÷í·"eB‰í_-y²m´IR¶Žþchgì,Í‹Ÿ¹B%·ßŠjbÃîÛv\Ú¨ÆFÿa¾ÏR¶_ÛÚX-)¹ç… Ÿ°Àß|g“ŽiŠH‡I"ê$¢€ö4uÕ c·‡èµ­ŸHS ¥Ÿ­°süYrccãOÙ¸×BÉáÎn)ë6ú˜JIž'ŸQ3ÏS¶~¦®FÝ›n%´^»«¨žÆc;]¼g¬Ÿ†ÈéÝS,„ž‘Ù C{qVÕ|z"Òg}Š]ðUž¨¸a±ô&Û;Ý•DôMêM£V:[M2QCT‹žŒ ¹èß¹RÃØ– NÜw¹ª\µ6Ÿ6uûêÇ÷ÿ¥È;¦ºbB¤ñn0ªÑÙÿK¤)³ª¦œª;ßãsöÞ?½ÃÍdþ'^¹¿ß HS]ŽAk$pçHTC±&óÂÔ óÕ¼ Mük´ÔÙÿá9N M-¦Ü²Eš2«jßF_ŒžŒ¥.4þEa·ûÁ;j\'÷'šmk3ëõÆ¥B4äº>´µtÝ´u.ȋѓ…•XMѦPþ7«T×õ¯FíÔLD®!×õiE V\(ö„޾xú…>‘HÇUžxù+‹ÅqêÝÿºçJUÌ[¢¾ ¹o¿™`K"{ŸÆ­\³¨!÷í7#%™ËÍmƳn(Y°”~rß~3]Ãî©“QÍÔV|Ö Ó‹ó¶²—§I]àìXèl²8,Ìœ»÷j½6ÏÎÏÌWÊÝ7È\5‰ôâ⎫1 ;ÇŸ%76¶T×°Œp ÃÚ„Ú¾üÒ“•Ï…×ÌùJE¾ºšÞ ¿AÍÝŠ ‚ö[»"ƒ\ôKN´ôìì2sµ{wмÇuö®ßN*í"wþOÏ&ˆ„±CÇŽökÊÃ1MYx+޲j`MzgU-¤ôŒn¹=ž¶ÏšŸí†Å¡¨·*¬K‚‹}ÊÓ|¶eÈåéäÖ¾¥Ÿ}[¬”¾|)i.®lï£:%=[î.÷¼-—¶ºÚ§»íM'ßóØ ò[êÖt‡-,ä_JNnNÏ^3çʪ«;i@Àư‚S'¹®Ý ÚÙÓ3·íCSPQoí å °§Cá£wD“Ž¦Ç”Î7Ê´¢~·+ä–&ß÷Õ³Žéå·v…ÜîÞçj½Šzk×xª³{ò — 4Ù3¶Eö4USp aåÄÝÆÒíó·t¾*M²µØr›OCǧ—Ôïß-òŠ:º=äf©Eµ{ÑdfÏdÖÛ|Ô¾ÐÄ$•d4©°ΉOn^™9΋ÍS~a­ÎýQxÙÎw^,Œ­É‰\)÷ûÅa·ë•¡—¿ÊΓÂÓ_ú9…XlÍ<ßÑgÿŸ¿®FÀf [¹¤Yg„`½o§'Ü=xq$0DSô×_øSM%Ç&:š=Á“‡[ë"Ž+m}÷¹Gº/i àÝrS=é%®¨·vEÞÑß:ùÁ€~äÂ&²‘äw]ÿ1h¯—÷ïùÐÍÛI ØÅœ¥|g¹©7â¹²»;”f𦇥­R»¥[¡Š,„5¶Lš¿3 ]¿91éóÒTS°Ðr˽ƕr¯)s‡</óÕz1˜êŠ MSÇ=V"š¢xSÉÉÿîöõQ{ uœ™›ÄhKüvÂÓ\rÜÑa]xÙ%r_饀b {¯ìèV’Ê̘¦â;Ñ£(ÿ›NýøÞ"?h½rKQsßõY¯ÝµK_¿»)f·ìä"®P{—×áhçܽDÚ—š DOÆœtŸn¬ÕïXHÝ®´)MË=/^“ß#égΦŽÞs§|ÎHÝ—_v;5eöÏD¡òÈ¡O4—'ùλ|é/å‡Â~E‘«º9 Û/?~üøñãúÈÔIÃ)¢t,]SX4]/êx"NäÌDD\©¦p¢Ž×”¾xå8½È>€Â¥{Õú¿ñ˜_¬~¡~y°Ö ®†å¢Jßíò» [—µaY¸•_¾u ùláJ‰8QSØÂâ,å³°Z–·,!OÖ÷1X~á_Ëÿbmî³êÓßúé<äÄÙDÎuþy=óí›4ó¨=ý4en&Òì=zznÒ§òöI:é”þ^:>7Ÿç–kSÙ{²°ô§:þérµRÖÃ<Ãëe–]̼™sfõ¿ã³m¥e{!«û‹°~sïyîyö1 › Z@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dÑ­D¢î^½9X‘¹ÄëKŒ8hʬªJ™Ë9QÇó²4in\&"¢Ô§$ºsD[‰}ëx½8{ߎö3í8 )Z4{ßÖw¿ñtv:­ò…3Žš23¶˜tËDzÒyÐ$wU;dæög°¼SPK*ŒDM%§MŽ éax1ÛX«t<‘ù§ØáùjÈ[å,N,²q"Ñl‚(.ÄÏÇ…ûöþ[QGþGQÃîïv…ÝÈ»g¬¸ñ«ì_1Çý»TIýÓ³ÿ²èx"§·fÓ+òÕ)òf®´ÝÌq"gæDMÑ¢šî}"È;‘€¢ÞØ’}Wf¯V3ž¥ìÑODDô«ùÖgõž«áÈ\ Ï·œ+nüJy@ôäŠ=SRIF“J\˜Ž QívÕÿÍôUÿ¨ýß¶ŒÚ7Ʊãeþïx¹Ö[³§Ökqìºbq˜¹mmfŽ-'ÒˆTIQ¥H`âHàª?pw190Xîû?ƒåfn{›™cK„±ªÿZ™{¢ù¶UM…mËé­ùµÓëpîÝépš‚Û>49QÇsbT»÷iTSÔëÓŠê³^ºä³ͪ«±çÏ’K«“Ûùò*.Üû4.\¿>}u<_^Í[W, &ÄÎDŽڞ·ÞªíY®ý_‘`@!x¹¸†—=§žF«ÃrÁêH½¢j ‘LD2Ñ DdæÌdæÌ^s»Ù[KoR- TE²pGþïx¹{ ko÷€¹×Ünî}òÖv IÖÓ ¤'YÈ@V²\°’%°ëˆ%Ðìn¤f}Ö=½¨7ëE3·Ìœ™Û®3sbcµQl 6Þz5Ø(—Ôä2M™Ó”õûY´Éظ·ÉH!" Ña"Sÿ‘ž^"=™ø—ÈÄ‹UF±Ñ;~ö#ï¸ÏúÅï}ÖìÔvt™9c°¸ÆÜçtìØç̼q]î=_žm˜ümòÄä>çëÅûœÔK£ÔKD(UÏ[i'Y‰ýµ7îÞeot÷·Ýt÷¯…=_ÍÜ.$¯ÌÜN2s®ºäª[®¼Z ¦FâIGüÊíóÒ·ÅêíÔ­/¥¯=Íg,žfVÏ»{Eܽ¬žgÇÝáÜ»Ãá ø¯Ý øŸ×ž¯~n’WÒ䱈4i no3 Ï«Ì3nžº¢gv4ÙC=D´¹[ˆ|qMݸÕÁW‹¼1È™Ó1!UÒ¢q!äžVŒŠ??h%šMü\üÒÔ—š‚¸¥½uÒâ(®BÜ€ÎÀ]Ž êH$0hý~·/ªÅÎG §c‹l¦ Èïþ¾uÒ6PúOBˆuNŒjÓÑ€Ï:2Ûí‹jñþìt:ßë,ÏXp¿©¤Ë‘î†àoiçæk|Òwÿx,p™ZȘjöÀÙóÑž°ÀúÁ:ä† šJO7•¨.õOª‹ˆþHDn"r‡iŒÂð_ù§€_.=Ý)—Ñ?¤S+¤©í³­ãìyû=gktÊ.þØÏ|ýDÝ?ÔO,výÌ5YC}‡sÿn‡ÓâØÑ•îv¡JÓê´n Úûâç÷Ås çn·©äÝÏ›JêÇ}T?nóTܰyRkÚG·íÍ¿·t4kŠ6¥)ùš5._¹¸Lô«tãÂdV†^ý¡2D"™ÓÏÖX܈:ñ?5½" Dè{ŠPÀMŸ}1Tà^ýD$ŒU‘0ƶÈ.ÊÙ³¾ÌfÀìB*ªMŒjÿõé€?à¿ò]z‹‹Íå*] {ºU7þö»uãì¶Š¿ÌWó—YwÖˆ7ìW…Ý,d†n›랣¦‡Õù®6öŸŽŸ¿ŽzçCgO­wÿîùêœÁò/Îd]g’ãÀþ¿[¾î61á^gLPêŸÔ¹éwéºújÉõé«%}RÏHŸd ÕÙîÙ}ÛîaõëJ–›ÚRjÅÜiŸóÍWö9-Žò/,vÏr†u‘`Ý ü®K—ü‹ˆ^„Ýcÿ;ìnv¿—ÙêÜ“Wnú¹cÁøáXPl©þRla‹5eV]Ïí)R%ǹ§Øá¤"`K­Ï ZGí7/¥;Yôñçþ²—KÛ9¹4}L÷‹|€®ÝÍ.Úë·#X!{^P^9ÏýeŸS¢vN¢…ó*ï—·®XNë,XÐd,m÷X[lö:b!‚ŒgKzzÌÜ>çj2Zµâpå@_üû7] ÉOÑÖºWïyô½/ðz‘BÔFO‡¼Dv:Úû·3^åTÙµ;õ1af,ž÷œ˜Ü¿Û; _Ø£IÎlc";˜¬‰ziêb´~‚õæZïUÀR°E"Š¥—°ŸÒ'a‚yEµ©ßEµú‰C|ö÷ÊaMëMã/Õ˜ÆSû@?tF—´þ‰Éc'&Y3H Ñm ev»Ð“‰ôTtRmP*Ï B½Ø¨Ö‹ 7ßõ4ž)÷4dÃŒA&™l$³åûèuÚG䟽KþSeŸ˜N•­D.±Ka=éSKØÅ" …Ü᪛M ¨7ŠuéM‘­Ž]_Y‚±òÁHó46ž d ÙÉFv2×mó™ëº}Ÿ×uûžW™g70réi£\ª_àŸ´ŽIíù Dô¤o—•Bî[!÷¨tsû(‚°@ÓY¹˜:ju°þ؃ãgÇ]Ôò¤5 (ý#7•þ•¨ö~4~´·¶ñÍòÚF≈§ ÕPeéÎP¶'5ƒŸ.‘IßÔÌ•þSú±%/;y¹¶ÎùëÚ:¶õ¤ò“šTúšÏYúšs?›eáÎTÈr,}[©à>G”º£HàöþH€ˆ.¥×am.¨…¾¤T „@Dýô×Ôÿ¼ö|õs»¼ ¹#‡BîÅæ•)¸­Íä‚E6.ÈÂâ+^Y¥Ù\u†êÀeiò¥š`…»×tXy Mš+¤É—j ;H•¡b§Ókul±ÙSOKbB2Õ¼¾È¡Ö¯/r¨©$ª= Ò§î›Õ!òÛ>l2.œ²¢NôY=Í7ŠšJ<Í7ŠŽöGµÄH:ös.ò–/êÇN'àÿ~¿Ï*—}y©©D.ûêVkCTûq8ª¥ÓÑ›õâ>çîÛ?—N¦Ö†.Ç|ÄÒÔÙ–¦’Ö†ÎÊú‰Ö†3–¦XWØS£Ì%a÷­—×Þ€…¦àK5¦ »àcÃw-<\ÓÂë³F†© b""b7Ò­ \km`­X[€tj¦Ã¦`“ñc?÷[ÆžÝå{—=¯c¯s›%3¬q#{7ß:ùí7¶íùrƒ5Å”&Ǥɫ—ýß\½ÜZ÷¾¯µ.sÍÂöêð'Ùë°¼’¦ÚõÒ{—å¡§¹Ëáɺ4gCL­\ÂUw$àªË ôÅ϶ôÅ3÷\.;c‘Ë‚ö[»‚d@8(Dàòð7Ëì‰eîß'¡Õe©£VÓ¨}t[öÀ~¹5ÿrÕŠ,Zï›»kSg:Ë V¤Ï²÷/6•ôÅû÷ÅY(séß‘µÝ`»>}µ{@ä«fDžF] -] Ki„¿v°1†2—Ä„é§ò0÷(ëŠÂ‰\)·‰:’W¬½Ìbóªïþço÷Ý÷·\<ëoaÁ6LcæoÜòZ7- ìþï²+Ê€?~Þë‹6τéêcÈu÷H·ÏÝk£îÔ:6OqÈ_¥»Gºó¦¬¨Ñ“C.MÓÞQ%¢Y•Ó†\‡ºîÞÊ'éXÆÃBˆ¦è»ŽÒ¹½È¥i3ê¤)DòŒ~è ¹{ߤޯt:ÛÚ„õSKGAß:&Lû£ —³|8&$„‡a5Àöyóœ~°1¤f:H aHD”fÆID´†ž£²KÕÈÖ»/E¶r ž^â…ÈVÖl8;X°ÿ‡“ßšlO꩎ê‰êÈG©§ý¬ÍÈÏíËO"¢¾ø¹Ö¾¸±ÙxØØ\«Õì©ÕœŽš¯œ©‘É9±èmN¤^â©7s»ìiRTšú]TZÞ(X‹DjK·€0·µƒFÕXdTY§‰ˆp廈 + ê§í´æ»‚µ&»ÎY[Rµúe"J=LÏq3g¹jÅÜtº}çZ»}O:\¢¬ÎP}=穯gå¾{eèÕ{•!²Ó6²Ëâé Y\ïƒ;²ym2µYç©l©ß»œy=æjïÔÌíæ6F¢±µŸ…ìùòæÕÂØîÞ6r÷rãܻܸÏzñ\öPšK±JÁ‚Akb¤©$!iŠ^œU91©°×DœØd|©¦ïþÂ)ð²Î`æ2;Ä„™pvÿÿ˜ ME473d½ÙÔOéxNL*?Qa§hLHŒD5ê¥s[ç̼L ôÝb†‹ˆ ÓÃQ-sx¹ÈÆËÔOË8ìÀzĚϱæâŒA.ª0È*M«kh?cB¼?&°KÌ¥¯Ÿzª–q9û¤Gqæå™ìOƒÆÃÆ m¥¤¼7!÷­—Cn’fÿDRÐ~£4h§”¤™ë°éš4…h¹/XÙE°K9B.Åæ©øW›‡,Xà€Ýg5¼'¢ôÓþnßç´ø®ÇË_YÞòÎW½åúq½Y?NãD4Nó/¬µ2vÿfØ-Ðî']JÙÓÔ}ä }©%‰Ë‰?'.³  £°‘&Pcll pâçc)¤Ò¼ïN/¦ŽZM™¯6ÈTNßPù“ºâ©Ù–«VÌM'h¿Q´ò-t2oÙ3áúñw>ªoñM¢ÈW‘Ès¥'5®ÔMÇh}OüÂnw_xòïÔ-1ÑŸæÖIÝèþ”óYusÓË“Wó¤ã‰ÌܶÍ\“±ñt“1{(Í·ß­÷ÑÅsË×ßn•º!$$¢˜ J³jTKH³jTc¯cQl öÞ×ñËÓTFÇ?=^wnT `3bÏQ3—Ø<¶'Ãò-a£äÕbgx¾·—l°ŽæO…Žæú‰CÿX?±ïÀ›»÷´~yiКû½X{‡Ånåhï‘kG{3s†5]–¦Njé. +ù-Ÿ¥t±q°S}zó`ÝIØÀ¬ãêŠÍ€ pÈÚ×äþ]¿£ÊÐîÛ•¡Ì%‘ÀÄ¡È25Öæœ8ìH ¹†ÿ8”5ò ¡®÷R:_þ©îo©öSÒÃpBÚlAÏBòÊ,®1=C^ͪéñ›ä²Ó&¹,{+†jƒül¿ªùü­ª4›È¾¬4‹lÙ½žLA®4{¶Ì„”ŒÆ„ä"Ç µ:^ªÉnBԑ袛ú[ÆÆì=Œ ꟢è2@ìÙiæ’úñwŽÕ§Ç´Ÿ{šÔ{ÿìû½YíÑXÝÌ%¹?Ãkë>sÉÑþãGû3ûÉçû»–fïýþ{ïƒÛ>4Γç¬ÝA_ü\K_<û¨%£IåÙšæf*ưË&6Ê:í|¹¾Ýr•®¸?šKÞû¼¹„…3<Í•žæ!—ÿú+ªýЙ½Ï©9&Ö!VW³çœ™ËYiÏ\²\µâ“®LO,Ü%êÙ´Ö}h­[øÜdÓàe.ٷʹ!~‹cוì;«c׫#ûSËYo¤¼Ê]’›WMÆÃ§òXÄæøÈ\²”_Õ|ÖM° äVÿ”}Yép»êÌ\‘Íæ1sE6‹£Ö»£ëhoæ:a÷ôð|S³d2s†j‹ÃÜb3svÏö6‘wzË/d¼´Oü¹IÌœ±Ñâ0‹kÌ\eÈrÁátz«f§£¨ï,~€“ôp5™ÅkG—Ýc ÕÆ A6Tók®±%ÀÂü®+ßù]Q-úä• ÓÕwÿlKß}Ö@M2Çœ7ßín2–_ø—Ár«cgWöåHî@AG{EŽö²ôrƒ ÏKÀåVö¯€«î½WÅaùÂâH?¯ÖˆŒAc£1èpîÝépz;+=Ë»'¹¿,vÏîïív‰Ÿjâ[0vDË/œ,g£šW†þöae(óíýp4û7šMj¸˜½š{f¥J3cÙG<= §ŽÏ˜kcYr`¹J×PË—_µ°’̾K$pûÍH€ ¹O#1w¬}llv¼cgzÝø;Õ÷Ý?û~ßýÌWÙ€£ö›Û³‡<\®Z1à¿v';vcŸýkR~Áâpztz‡Züß µ,öû²Ž¿/ïhduk5ÀÒg)íý0˜]×eИ‰}–ýµ8^~êÖ1w¥©Â¶õòWù·•;áe“ñšŒ,tÂ>ÕZ÷nOö½On=ŸÊ“œ<ó=*X®\Z®t ÙóBòªÉønOv 7¯XGOc竞FöYVÒØ ÅlnÌõsϯ¥[7ŽÚ§ý~—ÕXÜfn‹Íî1õf3ç Z¨{ }Óz2_÷Ãðx@ñÝ{³¯aá”]u»ow4‘ŽÊÉH·i’d2§û:Ž~¹•æ;ÓþŸIÇÝûzqG#•Q9Õ‘Ž&‰2Óù¡3äVÊ—ü D¤.滇ÝwŒÚÚEéKwï[S…#UÍ9é#¬'³*ÑÑþcGû;Ïœìh4sæv3ÇFºvÛȤr¥rºOD÷ÉHDFéÍÓ¸Ž]†ÖÓ[TŸZÂn_ÙDtIî'5ÉÑ…çýý®á?ú]–Éò˜%5IûÖÒäq’&©œ>N÷ì¥Fú˜WnOØ%Ef_ÇÔ€ˆÓ8 Tµ¨_6*ëŸê‡_Nôä:‰(5Ú9kŠßÝ𙣻áÙöJvs…¯9¢IDATQ¯O+jj ÄÔš©™½"J*?ý˜TH$žÄ¥çÀr•®ô(ÉHtìÉñe¹ÔK”刵eðNõhÞ)²Ó?fF€5ŠÍžu¦×QeŒÎÅn•=eíš§,wÛåªÓ鼜´L²XØØònj#7eýš¤Ïµ%v‡Ès$ó,î%sú\f-†º}Ÿ¿=ßÈ,ÝŸí}r3úou['/ï¶X­rïÿM(5- uÐïi¾ÛY×°@õ›†¥äóråÒjæöòæk«"4î.S%MÉè ®¹;ߨù˜à)éºè)!‰†—o èu,`¼¾©“®‘ç;ëÆížâ‘O |HDDª¤EãBÈ­Ž(ª¢Þ{s°šg?× CQï´ZÆÃ"Ï2Ô”Ù„*íS¿ øýÍ‘¢Á~"šþ¹}»ê¿½Ðj÷”¶Ï¥£EUIQ'üæÑ?>ã˜Æ}ñ+ßyš~mWÂ(„Ê/!NäÌéž<ÀúÅf×S#_ONïþJ§—ݼ™¹Òv3—7{6‘nªv‡«ÂîT†1z3=þ0kâι¸[œ‹¥Àó‹î‰úúÏŽöõwÓg Ì&°šN•}b:U¦„F~PBìrÓâ(ÿÂâH?ÐÒO³#»D©‰ ÇèîòͦèKÔ=ô%ê„På=!”nÐ8›H"úÇÂRkmøðfkƒÈW=yÖ´Ò46ÙNš¢E5…5Ëd—Pþ’+ý%¹C^¾Wݾs-Ý>ªÓ]¢:6eÛ–*©#ªÔ]ö¹©»L.=IÙO]žm[ËUºXG !TõPY;>›ïˆ³KF_É¥Ï}%›³ù.¬Gé®:ìÜ™Ž , ÈÎw˜ãD¢üý¨—«Vëg|Ö¨6õ»¨¶pšNoͯ^–¦)¸íCSu<'Fµ{ŸF5E½>­¨>ë¥K>+Ѭº´tü®K—ü®…ÓÉ%—¶ÿR.ùjÈg.ƪþK[‰|F°Ö v+¾Ï騱ÏIq$R;‰ì]=½DzÚç|ö9ÅûUQñ¾«¡Íæjˆ¾3ÈMíÄäo“'&÷9_/Þç¤^¥^"º@D2ÉVÚIVbí»wÙÝým7ÝýKIGpïÞ%¸]JÛM—RÈ÷e±·zTì]Í|F7Xg’ÊOjRé‹_8Óo*y÷ó¦’Ö†o¶6Œ"‡ÆSA½¨7ëÅÖº÷zZërS°y^¹mó¤n(&ü8Žö4q´Ÿ¥Õ~èL·JB»o !‡sï‡s1é|p-;»g÷m»'7\Gù‹£µî}ß|û¿Ò,€uC•fªäjh¹èj苟kí‹G‡"°û»]a÷©²3–Se™ë³[îÜtÎ=ÅÙ·ëƒÖ‹ç­£ö›ÛGía÷XUØÝ?×ÒÏ\Gä÷gwøÙtþwaédâÄ¢ N”KÛ9¹”…<­_^´®f>#XëF·ï3G·rßM*Z4YPó~6ÞAæ’Hàöþì43Û)0¹¡‡åJ'“4y<&Mš‚¦Ã¦`Ð>º=h´~qÁ€gÀ: d.ÉVàåâ^Î\¦‡cBæ’¸0=ÏZb·Ø 2'r¥œ¸¼é0NïÁƒN¯ÈW͈<ëÎ MµsÒÔêç$‚°î±›ö&ãáÓMÆÌåùðs"gξQ'šM<½V¾9 tür§cq¼üUz„6"ƒ4uR“¦4efLSV??1¬cìù¼§ñ´ÑÓhpª ©æýŠ:2«¨£öÛ2jŸïsì–þ…ÌtØmÿŸæÖIÝÌÿ”óYu¹Ó‘KOjr©^|׋Aû­]A»)hºk šxS±‰çù"Ïç~‡Ì±ØÔŒË•«hYëÐÓØùª§1sì€ûöþ[.;m’Ëò}v¾®|µ!«C1X\c f.IHà IS´©ôÓþåJ‡PÀ^³Îréɤ\Êþº{ÛFÝóL˜¹Îòæ-‚°Î°NÞ®½Þ»g×»‡-gÏäÝým7Ýý™·â¹¢ÚÔÉôt†ŒÅ±ëÊÓƒ=xaT»{$ûSË•ÎZƒn°nØ<ÿjóH“'5iÒäx©Æ”º ga‚n_O]·ÏDÆ„‰ˆ#ößQmêwé[tEùEù*J7ão2¾óQ“1ú¡3Ò”YUSZ'ß´NRSê™À}:àÏLóçÒÑ¢šÒ:ùnüçÒƪþKË÷­y™ÿ;^\¾r+p¹ðO-‚°nx;+=¬oærÖt_(?ÿ±Pžï³ÂX¥o­Yÿ{ÿoBn»ÇvÃî1ȆjƒÜA¿§Žy>r‡«Bî@õ›†ÌåË•ÎZƒ`¬¹a‚¥p÷›p÷×Çß>^ùjȃÆÃéñâBü|\`%ö_<7ØŸo^ƒÂÓšºxnh*ÿük‚°n,oÃ{6®A?ÑG}ñóÔ§­ô´5=AÆ-}<õß"Óy§°ÿG•Ô?©’@U$¬R>c€CÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@–_<~üøñãÇõ‘©“†SDDœHD¤)D:žH/êx"NäÌDD\©¦p¢Ž×M™:ɉ ifLSˆ´(‘ÏÚ) ;žOc[ÐÓèî¯üwÿRÒ,¿ð/ƒåº•Ø9$€õkÙ‚uãïûˆ‚J’ÜýD³ "¢Y5û¯¦qâ¬Ê‰šB¤)é%Zt®EÃÜši©œ˜TæÖÉ~—ÉL'7…Ÿ2RÎJ!‘¹fzß8qvÞõÙÞjJæV²¿Ý|ßôé­ä{͉IEÇkŠ^Ô¢DI…ˆH/Í}÷ŸÔ§ó~V}ú[?‡œ8›ÈY¢ææÓBû6×êäÉ·{êiŠŽO¿ÎÞ£Ù§öù©¼}’N:å…¿kí’›çl¹6•½' ãD"NÔÿt¹Z)é-Οûk¤Z(0÷°ŸÈ™ÍôŸm‹(¥(Û YÝ_„õ›{ÏsϳÑÊíI!)ç[gy÷j¡Ô–Rb×Ãõà7kõòd½œ³² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,€,@ ‚ÁÈ‚`dA°² XY,Xré—_Æ^•K}ÿgòÑr­9ßg}ÿgòKa3çJÎZÈ[Áõ[–Öfù\L Ï¿&\lnÿÜ·¾ð/ý<’&¿ü2úhéåÓæ©þK§÷ÄdÏ߇ÚXîµÖþ««—7óyº2û¹Ö¯7`uè°:­§õšBF*Anl®ãÞT¢)dÔ–tÜk½‡O{ÉË™õâ«kokƒ*Mÿ>:ED‡ËË - –•^tzß÷yØ“¢£½]¿ Vƒ¥ÿdq¾&'UðrÝøGãƒår©ïÿÄ^=ÚÛùê·ˆt½¸™òÿ;^n2þ69ÔÂò¡µîLù·äÒ ÿ{5û‰‡ŽçD§÷ÝnOã‰ÉþÇ¿N¯ßþË«—yyÛ‡f.s›™ÏvDþàÁ£½lë'&Ͼ?þµÅñÊm‡s=æØSybЋé%…æ1¸£Ëæi2¶ÿr¨…¥Ïr‰=»ãeãa3—+Ï“È×üúh/Ë öíNLö<ù¨Éøql°<}N}콟þ^þeò[ÂÞ}¶²±Ë‘ͳ§¸nœíCîžžË[>ÙûõãÇãƒåMÆc‘Þû™y˜[¢žÔ„‘µ].œÛù¾ÝÂçÑ\¹Š½šþ-ø¹œ_ÛêÇÇûîg÷ÅžAéüáÌé£_ë=r­{ ªM »Ÿ¥T¯®Â¸ÓûA }Y¯þàp®Üo\öõÆ…É–òë°¾Ê$Á€eÕ&Þ ÚƒöëÓ}qƒll4sûœ§åÒÂ×tzŸ–K­ŽÝß‹|È=º}Èðy©£™h6±ÙòÁÓhæv]B,Õ½£97§÷ݹÔîÙóRý¸¢_ïö]õ_<'M™‚å_Ø=õã->ïÀ|û¨3èE‘?xÐÝË.@õ"_mÎÆSóíçÚÏ1öÌ6½Öl"ý·ðüi2‹ôÝ7så_¡!׿—¦­]WCLøáÓHÀ ׃ù¶ò¼JšÃyø”\*òo¿çîU¥‡c µËÑT¢¨ÏIS¼üR™szßíñ4Z•÷ö9ƒökwûâì/[ÂÞ]ZÙX;eIgЋµÞw{:Ù>¤÷äÐGé=Y|n,OùÌ·ÇùË-« m7ÖnM˜/·çŽ{¾oWøy |·ëªŸ£Bòs}úù3há{¶R½š ?âQ-\¥¨ƒÖÎÊæv6­Üo\á×…ü:l¬2 D,³¤vüÏðñûSel™™ÛÑeó¾¦Õ±ûIÔßï:×âînnøÙ§6S>Ønˆ|!ù`÷Tþàô²×ûœï“&÷9ß9–¾2KÛížùör6A$—½×cëô4· cl©Aæ«WÿÔräX$0ö¿5sM¶¤ðüÑ”™°–Ê[!´§¸ÉhqìúJäcÂÝ#‘@L¸{$ìη•çUÖlžª™ô·´~ZÙTÂÊɨýú´ÏÚÑÜvSË,KÿÅs§ÊØ_¶$óÝg-k§,ýüž,>7–§|æÛã|%j=Ô„?ŸÛù¾]¡çÑ\~Σ…ós}zöœ|öR½ºsÄÿm‹ßÅÞÕõOª´r¿qÙgÙùãùϲB~6V™„ÿ{÷ÚÖ™ç{ü;¬àϸ —,#wS°M»ØÞ)ØbºŒÅfÙœ’åFÙ"7e#7…Øn—Æn Ž’eÝ,ÓU²4QRhmÛØ¤± ӯɲ4›ãe³Èåf-V˜ËN¬½ ÑæŽD‹ïUë±cW±ã_ñû£zŽŽžó<=ÒÉùêèH„kÀ’1* u ßDrö£­érOßëŒ;k¤@°T9¨Ï7ŠÍ¡7ý®èÉÙë—Lý÷‹™kg-Dzÿ=ýcDzÿ]D*¤am'¶Ø|zÓÇÊÝ>ïÖë-žr«bÄ®‰¼Øaº½æ–î¦ ¯oóÛ½]rH¶­¢9YbºÜS9DfŒkQun¬ž¹´´=YÚù©[ ï„Ë÷¼/>ÏÕm5¾¯F{Wì«l-î°xœYU‰©¾ ¨N¡WËFc×_PuúâÖL9É×óz`÷Ãcê;±këš/W™ˆ?°ë¹sH„¦[nHl}®Åc˜îÍåqOüÙŽ óÍ?uy˯ᤲ–JI}ßµø|šF&û«3á»Ò¾¸÷ò×]–ýé§Ñ©¯~fi}Yd®­¬Tr‰ÐµÒÁö|ÿßî½£úSÝüGÁQu‹ÑØÈ¦ü'xj.™î]o˧7}ïz°4çüœËÌõ$¼Î=ºb_GÓyî>øhy®/kç5¾wÎ¥ÛÇ鯲ùö³²wÀ“ƒ3 à1ó‚o„ÇÊ"ž=•)gäeËl?³5<^üšF»{sY_‹§c¸¿ÚÙº§=˜Šù¥e‹‘û¸ÕÁóúÉ¡itßåž;¾øöwÚý©ø×gã^™ºˆR.3u’äÕ)ÊNàþvºÞhòGkGëë¶Ýɺ72c)_rwÜ-"µOzbê^˾øÛ®Ó½]Ú¬¦Ñ½©N ÇÞüUíß“O&üí`Ê1îï)u'Ë"pd+Ôwh/Õ~’ŒT‰È¿Ê‡lE¾ª/nƒí§ÛB}¶ÛÞ9ÑSÝÔרÙÙ·£÷ŽŒæŽe+Rέ}#¡Áôé†Ð3“nôù·>×â·ˆÈhlxã¥A5ÖÏ{ÔÔx1Ç5?ç2{FEÛ¥_zz­¿Îùª”/¤êÇżŽ–çz³°Y½zfB1£[Š}Üùö3‡BEý{£ø½³ñIò£ÉÉÉÉÉɦ丑²£""ê'ÇR'¥”˜.·ˆa•""F…c¦ËíXŽ5~Ä03áû7KÄI‰ˆdÇÕãDò§ŒªS¤¦oÕ½†™³ Ó±D+¿ÄIMowzͼ©2†™µ¦×ÑïU ۙ݃‚–µ2…kæûf˜¹‡®¯zëX…[ÑG÷°‘ÎÜÊ\fÖr¹«ÄtRùï •˜"Óc`Ï|söÌQÏÌÐ0s™YKìÙ9Í×·é¹ñýèfŒÈ±¦N¶ çÑìvfn}º|ËóKÍÉÙ™«åθޓù¦ˆa:–Ë=s^-•üžþêPlzô“d–‡ú5u±´òø³5~u¹¦”óåö¸·7ýO%Ý«5Uf)s{>Ë»GX»é­dÏõçhéz2³åüuòs™¬þ]ÕçÞúãíÕ|­-fÆ®…ÿ€}Öòe²ú_ýÕgßë¯æÌX”•ýÑ¸ðø«¯–ñÄçpQ•£/ˆOÄ-;¥G-T¿’°Ôù/]«á矌ٸV’d.=soyÓžï§IWÏûQ‰‰È¤BDÖés=¼N×ÊœDñ(À¢°k\‰ž„O?˜9$¹¼ pfÁjžoÅŒq­>ƒ*1Î,X ïTœY€™¸À!ÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h(‹¬W;w’€•ãXêà9zòÓ Éõ&ÚÜ6‡ú~ê#µ‹b€uMíÌÈ(D±Àºõé§"¡¾OåI«y»Ü""9ûI~î–Œ Ûâzx.˜Û g˜"†¹\Ÿ¸®ÝôV²çús´t=)¦å¹Öy¼½š¯µÅÌØåíXoïX*\³h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±°æäl2ðäà= ÀjD±x““““‰Žž;}ÿpxŒ4O%©R]™—ÉŽ‰ˆ ÿ‰ˆÈõ?9öSf‰‘‰‘‰ÄH +b–UöêD_¢£ëÜÿsq~Ù«ÙT¢£çN÷.Ú±¦^cÓ·7w‹ˆÜØ$"’|]Ddä/ED6Dò;õÝHŒÄHŒÄHŒÄHŒÄH +ÁEXNíM“‘ªTíÍÓ©A±åÙ…·³ïr¤*ºy:5HªX Ô.\í¼µ W§ž¾»Ü""žféÙsTDäÌa#1#1#1#1ÃráÌ,«ÞôÇ'ÛãÞágGB‹kçôÞÁöaïµÒŵ,µ#ÿnDD¤á÷"ùyÅ/EDšÿyzÍïL/Q;õç? 1#1#1#1#1,/вˆ{³;Òuî]ãðXêïÞËþòoâuñºË¿;¿·Å³ë@ç\mñì>èŒ× =8¿7{õÖÛñºÌ¡äî«÷bŸ}òQ繦Ñ;ýÂõçÿÂädf(ÑÑ{§{×ᱦÑÝýxݵÒþêìÕŒ¯Kt\ÿYu¾ù¾†Ð|k Ð9ú¿“¯ß;9ùà^¼.s(c]½wõžõ ó\pt÷½W ÓâÙsÔHtŒüEµÚÊØRÿëÒgÁÑ]oÌÝ~[ðíXq}«ñWŸ­4Ô7ö÷÷ ŽÎn-ÑqýÏú«Õíì{ýÃD‹GµàŽlØáŽèiO_ @­9ö‡[íç÷NNfÇÅŒ¥j»ýÕgß‹Tdÿí»D¼.ûoÙ±x]¼îÚOzîx£/ü¦Ö¿˜ö;wšîÕ}]õíAµ#/¤jüó_Ôªð^õ Àz@b$Fb$Fb$Fb$†•G±`]3ÌÒzüzï“zï:·lØ诽pe°=œ:QÓ90á»ý~ʉ¶¼k„ÇÂcñOácÃc“mÁHÅ¡‰POÜ{í©¸7ÔûnI´5Rõ«à@í„ïÛ v¸Åœ§Ð0—`r×›‘Š#Ù¶ eåâÞö¦Ž/¢­áñwKzÓó?6Rqì§mÁhóñêPe_¹›l´õxÍ@mÚ—î³ÃíÁ½Þ«BM£»Þ؈6¯Þß¼|+î õ¼Ù9 ’Ë8VÍÀG‘ u¨?»o‘ŠãÕíÁbú–ŒÝ|=娇ïf¾DÃ7Þhakž¸g;Ròç_ÕøÕ­ZR¸Ž/Ñp»ÆŸ¼tswʱÃw/ØáÙci)ß} ±3ÔÓŽÔ~ú©e‡z¥£­ó¥¸ÙeTf¢cøOzï:wl1Ý]¿ ö׆úÞŒ¶&B_nOÆ*ç>ôÄö,˜îÍ®úèù¶‰T ¶]¸bÙ­Ï4ÿóѪÕ÷:Þ("òÍû"úîyêA÷|-¼wÃŽõòÎDb$Fb$Fb$Fb$†•Ç5 ÖµPOó±OeïÆîJã¥W‚o6=“lJȸœ.éûÕ€t;æ9<¶?ùÖ'-ý'?u'åöûi_[pϱ¦Qu0ê;âœlu,×qÈm1L¹,â<--ψˆý(½®ÿbc"äeûŸ‡ºËqì9$2øÃomÁ·/7Æ/÷¶wïûד­"ò¯"20cÅg“[2öÕö”c>½å[^±Çíÿr,iŸ Xöµ/Gü‰ý×¥¿Z}â}´êŸ^Ï8ö÷,¤o–}í©‘:ì‘©o™‰l l}ΗHW¤û&‚îˆ{sYdÛkÛn¶öÊé3ùË8x£/~Yã¿4xñ©¸WDDºgedÿMɘùô–?n¹‘‹Ë'–=tmî±cÏ;ÃM£•%Ïy*ë^zÅtµ¼fÙCÿ=¿ ¨QwŒJÃl‘=›!ÿúhÝT—êK»ÎY™¡\"ÔØýê«¡×ÖÂkNíÔ¨³D>œ^òN\DÄuQDdü Öùx½¿K‘‰‘‰‘‰‘‰aepfÁºèܲÁtìÿj{2¦>é½NçÀÇÇjÕßþÀ– ¦[ým‡ï^È„ý[Ÿ7Ý‘Š#Îþ_âů꣆9-ó‡ÆníK9Žå¤ëQ;á»{!tmÿ¹éŽ6ŸúÅþž†Ä_|W5L£âñå–}ùòhÌÛÿ®÷PÔߕƳúgæ ë›eå!ϰ§¹<î‰o|'î€ú¬þ|û…+–­ j‰ºWe eÙC¹¹¯ì°°±£±óÕ¦[#¾/,R¥QñKO<öÙå[=w’±›»SζW^þóPßZø…êÂRWͬ´ZR¸ÎóN/)laý 1#1#1#1ÃJ¢X°®U–l|§<žrRGò‡…³%c·öM4nì(Ÿ:hly¦ã‹ðx*;~$å´5½ÑÝ4z5óë_÷Þ™øÅ­·ãu½w>Ø©pGÜ› s9GÔúÌîƒù^íï}g¸i4^­´÷NæPƊשoλ#î¿Zš^9–3>}È=³hÒts!}³ì¡Ü°:/@ò_Fp¹EL÷– ¾Ä`û…‹{UÉÀ߸eƒ7j˜¥u†©Î)È·p­têÌ‚Ç6–b¨//$cÉÝsÏ®â•Ç7ì(‹\½wåÛ®sîHi}‰i>½õO[žÑû¹:ýö…é gï’ç:_F-)\n­—w&#1#1#1#1¬<ŠX ¸÷úÏFBÞS›]ÝÞ“¦«±»µü`2<®¾èÚ±Åè¯þ`k´yy{õŸO„ª~\s®±»v[ÍÇÝ­åÍÇÂãê³÷`r÷A ¿zà£åí•2ìýϧFBµó|gÓÍâû–Œ}õrʱÛC™°/Ñp»>êlÙÐP»UJˆ ^¼nÙ""†élÙàKø ·½ÑTvüÈ„/íûæý‡]­`©/¹Ü†ù¸*ÖþÆí/šnW™a/•Öfxì`R¿ŽÆjuè¿DDÒ}ÓKÔµˆ”ˆ¾›/ü[­Sø¨õóãF$Fb$Fb$Fb$FbXy\³`]Ke¿yÂWi<Ÿª´DäÕ‡­SãþƒJCDv‹¤œoNMøDdÆÛJʹµ/å$kSŸ¦û»?±crÉ<{¼óœY¶é;ý²|ËI] 0)7%5ØÛ}FbrÉŒý®óœú~e“ԾŽ×JGB¾HÃ횈26IL•Dr¶ÜP_"°ö^{*q®±sÇsГð ¸ýÃÞkgVî§%Ó é3>O|c‡Û+OËßË¢®)0²ÿ·?KÆ|76ý¿¦S½w>*TìOH¶’±[ݽéÓmƒíká5wwPD䣷DDÞü•ˆ¨ëV<ıŸNÿ}kŸÈì×Ýú@b$Fb$Fb$Fb$†•Á™ëÚ`ûPβëOV\ã÷%ê¯Õ?ä0µ=¸çXþóÛØà•»êl‘Þ;§"†iTÎ}JºÁÊ.ë)â½wξ©P§âÏÝ«»Ö+uÚüìßx\Ô Ö7˾VšÕGë®Õú;·¿˜¿Zþl^¸bÙþÀöÞè‹_ÕøÕå'—.íùS×JP£Ùë¨+5ÔæKQ?H][Á±œq‘¦›Íÿ®ÿÏÒD¨g¢{WxÌtoÙP¿Â ¢>PÔN]í°çºU’¯‹¬×ª?‰‘‰‘‰‘‰‘Vg¬kÑÖöö¦Ù-§üó{?z«+Ò›þät0å¤û2aàßøæáÍ._¢«ÿôÞþÚ”sûý´O=V}ÑÀ<¼i°!Ü_{ÁlOÓÇ2a_âgkýfÙf—/8q¸+$­Ò°\#R'ó› [64„û›?N¶§œÛ§Ô üµ~ãÖç}‰°÷ÐS]!™õ{£—’»Ïïí8“<l•f9^²¾ííoþøÄàhñ}S4^2* Óó’gOy,¯ñäÊ㪌ò¨íÛa{ȱ^Šl}·-’è¸n÷G¬{W¾í´êã/îiº™ö¥Ï¬Ä•ʼnZÞƒHŒÄHŒÄH $FbX­~499999Ù”?RvTDD íXêb%¦Ë-b˜F¥ˆˆQáX†ér;–c1ÌLøþ ÇÊ_H#;®'"’ˈä/¤1}«î5Ìœm˜Ž%âXù%Njz»ÓkæMµ1̬5½Ž~¯RØÎì´¬µ)\3ß7ÃÌ=t}Õ[Ç*ÜŠ>º‡tæVæúÛ0³–ËíX%¦“Q'¤—˜"Óc`Ï|söÌQÏÌÐ0s™YKìÙ9Í×·é¹ñýèfŒÈ±¦/ ¢÷hæ%îfdû};ù–ç—š“³3WËq½'ó3LÃt,—{æ¼Z*ù-><ýÕ¡Øôè'ɬ§1.l‹ÌRæö|–w°vÓ[ÉžëÏÑÒõ¤˜–çZçñöj¾Ö3c׿À>kù2Yý¯ˆþê³ïõWsÍ ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ùÑääääädSrüHÙQÃq,—[¤Ät¹E Ó¨1*Ë0]nÇr¬ñ#†™ ß¿áX"NJd ö”8X ÑæŽx´9Ô×ðûPßbÚé¯>û^µk):Ç“ÀÚõØŠÁÑ·DâVVB}"¹ŒˆHÎÖoKDÄ0s¶a:–ˆcå—8©é3¦×Ì›j!c˜Ykzý^¥°Ù-<(hYk!S¸f¾o†™{èúª·ŽU¸}téÌ­Ìõ·af-—Û±JL'%’µDDJL‘é±?°gfŸ³gŽzf††™ËÌZbÏÎi¾¾MŸuòýèfŒÈ±\îüßzr3ú<#ÛïÛÉ·<ÿ¸ÔÙ.³3WËq½'ó3LÃt,—{æ¼Z*ù-><ýUò¶Pdzô“dÖÓ¶Ef)s{>Ë»GX»é­dÏõçhézRLËs­óx{5_k‹™±káß?`Ÿµ|™¬•W×,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 ¬"ñºk?‰×õWŸ}¯¿úQï]LËwÍGmAÝGw½-¼·-øÖ@[p1£~\)-g”úhÝÔG ó)æQ†iTæá±˜8lÒ:ÃŒT¼û?"…Ÿ$«%êÞmVf¤âØO#Wï}þ¯Þë¹óÑ[=wÜ‘ ;Ü‘G]ódó‰ê“Í᱃Éð˜ZRøo¥Qùn¥Q̧¾Y+›ÊZåñò=åqÓ½ùL·éÞ²Át¦Ë½¸Q~*¾¿çÀèþ5–ó{ýëó{kü?ûM¿°åâGô¨}8¿wðóó{£Í§~m¾zÏzpõÞ\Ïi‹gÏÑO&leÂiß7§Ò¾âçŒ/±é;_"þn$îMŸnëM«[µDÝ»àÙ8Ï|PcQ «Ô:ÑæãÕÑfwÄýWîÈ\IV¿¬4ú«þ¥¿Z%£Ûy®ûo;ÏUÏ}Pi<®|ŠG±Àª£¥¬{W¾µîÞÎ^SÖšîÍ.ÓÝ_ûñ‰þZu«–ìïygxOáúê Î²‡þÛ²Û/þv°½Ö_s¶ÖßâÙ}@ÿ̹ø5 ©OæÕß¾‰3¾Â%sIûÒgÒ¾ÑXòõÑX sçÎ@gÓèÎM£j답ʳ±óå;KÌ’ÊS&Z<Í?øIû\#zÔ>(±Á‹×cƒáñCéð¸c9㎥÷³â—•FptçÎàèÉÖã5'[uæxâžfOÜß½`‡ —«%žø†ž¸þ,—ÖæìÛÙ-Ï?Ôxý-üÞôé½½éÞô™Ã½i_¢á¶/Ñ|ë“¶à\Ifi½a&B#›¡ðø'<Þ›þøDoÚ}á¢7º¿g_,Ÿäâó)Å«Nʹ}*å´<óÖ'-ÏÞÎ^³!ñ‹Û µþ@í'§jÕ­:S‡j…ëÛa{È[ö•»–­êÔòÍÇúgìůYhØûųÃ^õ·c9)Ç*\2?u¼:DT‡÷jÉâG­–›Oo}Þ|ºéæîƒM7ÕrwĽY?Ÿ¢ø=jëþˆc©ƒí¹2Ùßs0¹¿'6xùëØ`&|ÿFF;àŸ}öÇâY÷.ß²î;½æüóA³  1¡žŽáPO{pï@{P­Si<ÿA¥1÷ÜÈÙ"•Ƴ•F¤âH6RÑ|³;ÿXUJXþ|\¼ X}r¶H2öÕß%cÚâ:ù‰ÔÍ^Û0]e†)7E俣lÅå‘oE+—q¬Ç±æÂYöPβÛÂo´…'|ß¼?áK>sóõä3‹µ:4unÞ¿áÜLÉý)‘Ÿˆ”˜.w‰¹˜>/4ù‡S…¯¼pÑ+FC>—©“ðcŸ]ø<ö™O6‰oês~ÇÊÙŽ¥f‹¢Î ˜:l~Eþ^^QËÕ’´ïîý¤ý¹ŠPrC^—ÅÏÃïrþŒd†2ê;”iç’8Uθ3ç5 "ï‘ ·ß}Öíï8ÝÖ5zíÖåÔk]ç>ÜÚu®ð9*>ŸÅ£X` SŸÍªSß M ÝN¾åùÇ¥æäìÌÕrg\ïɽàE Ó±\î™ój©ä·øðôW‡bÓ£Ÿ$³žÆ¸°-2K™ÛóYÞ=ÂÚMo%{®?GKדbZžkÇÛ«ùZ[ÌŒ] ÿþû¬åËdõ¿"ÔogpC ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@C±h( Å ¡X4 €†bÐP,Š@ó£þê³ïõWP\5þ.Öø XŸêOÖ]«?™nH÷¥ÔËÊY6É+Åtov™nõ÷„/}f·üï .õ’±äîdŒ§XoêOÖIýÉÙËkü5ó±"°ì¯ÇÅ;e9ÙÕ{‚«pQaõÀ“Í0Kë “€µb©Ù ß\Ä À“'¾{!ŽT¯‰T•EÜ›Ë"õÑúkõQu¯:[A}Íádóñê“Í…¥XÀèd멆“­ÛÜ[\Û܆iÜ7Ì„3²/á¨{M÷æïLw*1~;•‘?|ÀO'ðJ9ß¼Ÿr<ñžx´õƒ­ÑÖ²HÙæ²H‰YRQbžl=Qs²Õtoºÿ°¯6pfO Ãt¹ ÓÛCv¸,]v¨,Ýtg÷¦;âOÜ{ýWq¯a†)‰>–3 €†3 X3ö÷u|±¿/í»{Ág­\F-u,Çz`ÏZùU¹‘ãv—8ã¹3"m¯í}§-m>^m®¨>[3Л>[Ù›n—½íÚ)°fø›¾3ÝåÁ²æ¹‰Ñ̰v,g\šËév¬¬%"RbŠˆdÂθˆc9©¬•‰~{!í³ìO^Ž:Žå|îXmÁ7»Û‚#¡/_ ÍÞ ÅÖ ÇÊÙ"™Èw#Žeûî9V&|ÿ†ˆU{áJoz¤êZéùö¶àÁd´Ù —Ö—Ç3áû#bÙ¾»2a'䤜©‘ê³´¾ÄôIÃmßC¶Â5 xB¦Qi˜†YZ_ÉZ9[DäíXÚÅÖ(UÈe²V¿á¶?PßøN¥áX.·;²˜v)°Æ8VÎÎ_¡@}1!å$_{'|ß¼ŸöeÂöPÚ'’Ëäïq¹ 3ûÃ(°Æò¦Ë-RbælǪñWŸ­4Ê""Y«ð^Ã,­/1 ÓUV\û\à€5cÂg9VƱ‡+í³‡²VÖº?âXžx½ø5‘†-þ€cI½Äßý‘ü£ëþHÖr¼NÊiU8œ+ XC¾I9ÃÞ3/ Ž‹ˆH•üœAZäî÷ÿ'<õßÒ©ÿD*ílë4ÌÒzÔˆˆÌy]Ь¡žŽáPTËG?tvÀCtŠHçÔí¼´bÁTu¬2ËyÌþ£ÉÉÉÉÉIBÖ³tCº/Ý þ¶ì¡œe“»Þ &IXÙ×£gØÓì^þ>üaicdd²'oIEND®B`‚xymon-4.3.30/docs/man-index.html0000664000076400007640000002312512465031236016706 0ustar rpmbuildrpmbuild Xymon man-pages

Xymon man-pages

Overview Introduction to Xymon

Server Configuration Files
The hosts.cfg configuration file
The Xymon client configuration (analysis.cfg)
The local Xymon client configuration (client-local.cfg)
Xymon environment variables (xymonserver.cfg)
Xymon server task configuration (tasks.cfg)
Xymon alert configuration (alerts.cfg)
Xymon Critical Systems configuration (critical.cfg)
Xymon CGI configuration (cgioptions.cfg)

Web page generation
Generating web pages (xymongen)
Viewing current status (svcstatus.cgi)
Viewing trend graphs (showgraph.cgi)
Trend graph definitions (graphs.cfg)
Viewing multiple trend graphs (hostgraphs.cgi)
Viewing critical systems (criticalview.cgi)
Viewing ghost clients (ghostlist.cgi)
Viewing historical logs (history.cgi)
Viewing the eventlog (eventlog.cgi)
Viewing information from a CSV file (csvinfo.cgi)
Linking to prebuilt reports by date (datepage.cgi)
Custom Xymon webpages (xymonpage.cgi)
Xymon webpage headers, footers and forms (xymonweb)
Xymon webpage access control

Report generation
Generating reports (report.cgi)
Viewing report details (reportlog.cgi)
Generating snapshots (snapshot.cgi)
Configuration summary report (confreport.cgi)
Single status summary report (statusreport.cgi)

Administrative web pages
Editing critical systems (criticaleditor.cgi)
Finding hosts (findhost.cgi)
Acknowledging alerts (compatibility mode) (acknowledge.cgi)
Acknowledging critical alerts (ackinfo.cgi)
Enabling/disabling tests (enadis)
Acknowledging alerts via e-mail (xymon-mailack)

Network service testing
Network service test engine (xymonnet)
Xymon ping utility (xymonping)
Re-testing failed network services (xymonnet-again.sh)
Network services definitions (protocols.cfg)

Combination tests
Combining status results (combostatus)
Combo-test definitions (combo.cfg)

Xymon server programs
The Xymon network daemon (xymond)
xymond communication module (xymond_channel)
xymond history module (xymond_history)
xymond RRD module (xymond_rrd)
xymond alert module (xymond_alert)
xymond file-storage module (xymond_filestore)
xymond client-data module (xymond_client)
xymond hostdata module (xymond_hostdata)
xymond admin command distribution module (xymond_distribute)
xymond data capture module (xymond_capture)
xymond sample module (xymond_sample)
Xymon proxy server (xymonproxy)
Xymon client HTTP gateway (xymoncgimsg.cgi)
Trimming Xymon history-logs (trimhistory)
Client data collector (xymonfetch)
Application status feed (appfeed.cgi)

Xymon Client
Xymon client filedata tool (logfetch)
Xymon client update utility (clientupdate)
Xymon client ORCA data utility (orcaxymon)
Xymon client task configuration (clientlaunch.cfg)
Xymon client settings (xymonclient.cfg)
Xymon client message cache (msgcache)

Miscellaneous programs
Running Xymon tasks (xymonlaunch)
Xymon communications program (xymon)
Digest calculation tool (xymondigest)
hosts.cfg utility for extension scripts (xymongrep)
hosts.cfg file combiner (xymoncfg)
Xymon command-line tool (xymoncmd)
List of XMH-field names
xymon-4.3.30/docs/Renaming-430.txt0000664000076400007640000001261611615610703016746 0ustar rpmbuildrpmbuildThis documents all of the renaming that has happened between the 4.3.0-beta2 and 4.3.0-beta3 releases of Xymon. Configuration files =================== bb-hosts hosts.cfg bbcombotest.cfg combo.cfg hobbit-alerts.cfg alerts.cfg hobbitcgi.cfg cgioptions.cfg hobbit-nkview.cfg critical.cfg hobbit-rrddefinitions.cfg rrddefinitions.cfg hobbitgraph.cfg graphs.cfg hobbit-holidays.cfg holidays.cfg hobbit-clients.cfg analysis.cfg hobbit-snmpmibs.cfg snmpmibs.cfg hobbitlaunch.cfg tasks.cfg hobbitserver.cfg xymonserver.cfg hobbitclient.cfg xymonclient.cfg bb-services protocols.cfg Common programs =============== bb xymon bbcmd xymoncmd hobbitlaunch xymonlaunch bbhostgrep xymongrep bbhostshow xymoncfg bbdigest xymondigest Client programs =============== hobbitclient* xymonclient* orcahobbit orcaxymon Xymon server programs ===================== hobbitd xymond hobbitd_alert xymond_alert hobbitd_capture xymond_capture hobbitd_channel xymond_channel hobbitd_client xymond_client hobbitd_filestore xymond_filestore hobbitd_history xymond_history hobbitd_hostdata xymond_hostdata hobbitd_locator xymond_locator hobbitd_rrd xymond_rrd hobbitd_sample xymond_sample hobbitfetch xymonfetch hobbit-mailack xymon-mailack bbcombotest combostatus Net test tools ============== bbtest-net xymonnet bbretest-net.sh xymonnet-again.sh hobbitping xymonping hobbit-snmpcollect xymon-snmpcollect Proxy tools =========== bbproxy xymonproxy bbmessage.cgi xymoncgimsg.cgi Web tools ========= bbgen xymongen bb-ack.cgi acknowledge.cgi bb-csvinfo.cgi csvinfo.cgi bb-datepage.cgi datepage.cgi bb-eventlog.cgi eventlog.cgi bb-findhost.cgi findhost.cgi bb-hist.cgi history.cgi bb-histlog.cgi historylog.cgi bb-hostsvc.sh svcstatus.sh bb-message.cgi xymoncgimsg.cgi bb-rep.cgi report.cgi bb-replog.cgi reportlog.cgi bb-snapshot.cgi snapshot.cgi bb-webpage xymonpage hobbit-ackinfo.cgi ackinfo.cgi hobbit-certreport.sh certreport.sh hobbit-confreport.cgi confreport.cgi hobbit-enadis.cgi enadis.cgi hobbit-ghosts.cgi ghostlist.cgi hobbit-hostgraphs.cgi hostgraphs.cgi hobbit-hostlist.cgi hostlist.cgi hobbit-nkedit.cgi criticaleditor.cgi hobbit-nkview.cgi criticalview.cgi hobbit-nongreen.sh nongreen.sh hobbit-notifylog.cgi notifications.cgi hobbit-perfdata.cgi perfdata.cgi hobbit-statusreport.cgi statusreport.cgi hobbit-topchanges.sh topchanges.sh hobbit-useradm.cgi useradm.cgi hobbitcolumn.sh columndoc.sh hobbitgraph.cgi showgraph.cgi hobbitsvc.cgi svcstatus.cgi hobbitreports.sh xymonreports.sh Templates ========= bb stdnormal bb2 stdnongreen bbnk stdcritical bbsnap snapnormal bbsnap2 snapnongreen bbsnapnk snapcritical bbrep repnormal hobbitnk critical nkack critack nkedit critedit Web pages ========= bb.html xymon.html bb2.html nongreen.html bbnk.html critical.html CGI option variables ==================== CGI_HOBBITCOLUMN_OPTS CGI_COLUMNDOC_OPTS CGI_HOBBITGRAPH_OPTS CGI_SHOWGRAPH_OPTS CGI_HOBBITCONFREPORT_OPTS CGI_CONFREPORT_OPTS Configuration settings (in xymonserver.cfg) =========================================== BB XYMON BBACKS XYMONACKDIR BBALLHISTLOG XYMONALLHISTLOG BBDATA XYMONDATADIR BBDATEFORMAT XYMONDATEFORMAT BBDISABLED XYMONDISABLEDDIR BBDISPLAYS XYMSERVERS BBDISP XYMSRV BBGENOPTS XYMONGENOPTS BBGENREPOPTS XYMONGENREPOPTS BBGENSNAPOPTS XYMONGENSNAPOPTS BBGEN XYMONGEN BBHELPSKIN XYMONHELPSKIN BBHISTEXT XYMONHISTEXT BBHISTLOGS XYMONHISTLOGS BBHIST XYMONHISTDIR BBHOME XYMONHOME BBHOSTHISTLOG XYMONHOSTHISTLOG BBHOSTS HOSTSCFG BBHTML XYMONHTMLSTATUSDIR BBLOCATION XYMONNETWORK BBLOGSTATUS XYMONLOGSTATUS BBLOGS XYMONRAWSTATUSDIR BBMAXMSGSPERCOMBO MAXMSGSPERCOMBO BBMENUSKIN XYMONMENUSKIN BBNOTESSKIN XYMONNOTESSKIN BBNOTES XYMONNOTESDIR BBOSTYPE SERVEROSTYPE BBREPEXT XYMONREPEXT BBREPPANIC XYMONREPGREEN BBREPURL XYMONREPURL BBREPWARN XYMONREPWARN BBREP XYMONREPDIR BBROUTERTEXT XYMONROUTERTEXT BBRRDS XYMONRRDS BBRSSTITLE XYMONRSSTITLE BBSERVERCGIURL XYMONSERVERCGIURL BBSERVERHOSTNAME XYMONSERVERHOSTNAME BBSERVERIP XYMONSERVERIP BBSERVERLOGS XYMONSERVERLOGS BBSERVEROS XYMONSERVEROS BBSERVERROOT XYMONSERVERROOT BBSERVERSECURECGIURL XYMONSERVERSECURECGIURL BBSERVERWWWNAME XYMONSERVERWWWNAME BBSERVERWWWURL XYMONSERVERWWWURL BBSKIN XYMONSKIN BBSLEEPBETWEENMSGS SLEEPBETWEENMSGS BBSNAPURL XYMONSNAPURL BBSNAP XYMONSNAPDIR BBTMP XYMONTMP BBVAR XYMONVAR BBWAP XYMONWAP BBWEBHOSTURL XYMONWEBHOSTURL BBWEBHOST XYMONWEBHOST BBWEBHTMLLOGS XYMONWEBHTMLLOGS BBWEB XYMONWEB BBWWW XYMONWWWDIR MKBBACKFONT XYMONPAGEACKFONT MKBBCOLFONT XYMONPAGECOLFONT MKBBLOCAL XYMONPAGELOCAL MKBBREMOTE XYMONPAGEREMOTE MKBBROWFONT XYMONPAGEROWFONT MKBBSUBLOCAL XYMONPAGESUBLOCAL MKBBTITLE XYMONPAGETITLE hosts.cfg tags ============== The "nobb2" tag has been deprecated. Use "nonongreen" instead. Xymon internal statuses ======================= bbgen xymongen bbtest xymonnet hobbitd xymond bbproxy xymonproxy Xymon internal RRD files ======================== bbgen.rrd xymongen.rrd bbtest.rrd xymonnet.rrd hobbit.rrd xymon.rrd hobbit2.rrd xymon2.rrd hobbitd.rrd xymond.rrd bbproxy.rrd xymonproxy.rrd Xymon network-daemon commands ============================= hobbitdboard xymondboard hobbitdxboard xymondxboard hobbitdlog xymondlog hobbitdxlog xymondxlog hobbitdack xymondack xymon-4.3.30/docs/editor-showclone.jpg0000664000076400007640000012156211070452713020131 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀò"ÿÄ ÿÄ`  !1U"”•ÓÔ#5AQVs¥²Òã2¤³7Bar346RSTtu’“£´Ä$qv±Á%bƒ„…‘Ñ&CDWXc‚–ðÿÄÿÄ%1!QAð"2aÿÚ ?ã²¼•è¯%v¹‹ÀØ_E@Ú™¤† w¾8„ŽG,4¹ óÇÎ?ôS=ZÁß7?E3Ú§äªO°gá )q²ö´“êÖù¹ú)žÐZÁß7?E3Úb($úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´'V°wÍÏÑLö…ˆ$úµƒ¾n~Šg´/dvxèÏT¬¯©©27ZFBƳÝÙ#É9ÛŽÌsíåŒA[Þ>V¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅ£¡mR_*löxj©é¦­C“îÙ½Àƒµ®<ÎqŒžx"f}3ºŽz›]öÓwêñ™eŠ•Ó2F°~Óƒe…Àgnp2{Xý†Z;ýaCüF,Á|²PST‹ Ž®šª¢ÓšŠÚñPcí-xc[`Ò[“žDãŸ5ÄÎÞ×M5Åö¨ŽCLèjx¯’2é™°·„íîrkÉ vGøØù–ïqÖ–ÍgÑÓZï4ÓGjqâ5Ù/ ¬©cüç{ր촙}hɯ¸hޏzäÍ°Ô fOñòÇ=h§´olm ìÆbÏj+Ô[‰¸Þ/:Vû&£©ª«e#bêrÕçEPfhá°ž`̤°ròÇ%™®5†¥§º xo,Š®ÇE[wdTñhbâ:LþÛŽãå‘Ë`+ÚïCT£µ û‹©-õqͶ‰õn{Úæç3JÌs9^Ð{ òF«6¥Ö>’¥­†ãZÊÊ($ÌÂIï0x%Àäík¿¬í 3J^uEmÒ¦Õq»Þ7ê*O ³ÔÉ™“Áò‰òš^Óч¼}*v£EE½]îSÕjkNžª¤®Ô´vJsFÚÔÈL²“!anH w!æFÑØ´U©v/Ïr¶ˆÓÚÒ úkårˆ$EŸÈBËšyyG’½¼ôyþ`ï÷0zµW{†ÿºÝ?«7ý:³úO°i½A¨*,Ö{LZÚ®6<݆]-Ž<¶£‰œÂFܲ&cˆàIw¸öNz=ká@ì€O÷=Z‡“¢Žc‘Ì6É2ÒAÄÿ‘]srõJ¥zo¶ëúÛ EGG‹Þ»Õ,‘´ÒSÁ$UÍùã.•ŽØþ^K²’C¹æJ¨ËßFÝ[:‹}æšY+k¡£ŒpiÀi{±¸ž`Ÿé8³‘ÊÝ#RS[úBÔ”P¶ ZkµT0ÄÞÆ1²¸5£ú.©¤¶êk^ŸÒ4úÃQ{ýzuþ–Jª–ÓÇ LqÏÅÆÖ1¹cÆpÜã“ÈÖòïJßÊŽ¬ÿ]Öé Ö‘iD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA[Þ>V¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅ“¦+«m´ô¶êÊŠ:¨ànÉ ”Æöå˜8p Œ‚GýÅ}ªgžª¦Zš™¤žyžd’I\縜—y’O<¬OÉTŸ`ÏÂRãeíi![|½W[`¶ÖÞ.44ûx4ÓT½ñG´mnÖ“€H‡%â¶íu®‚’ž¶ç[S vRÇ4î{`nÃ8hÃ[Èc°} t3®—›½Õ±6éu®® F*j&Áý‰Âõx¾^¯lŸûÊàäRÍ«¸+©u}âãfmN”ê0R] ª–_|"“ açÈ`öòú"t­ü¨êÏõÝgñÞµ¤I4‚"*ˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ‚·¼|­YöïüEb¬«ÇÊÕŸnÿÄV*" "" ’¼•è¯%v¹‹ÓòU'Ø3ð…”±m?%R}ƒ?YK—µ¡D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD½ãåjÏ·â+e^>V¬ûwþ"±Pd•ä¯Ey+µÈÌX6Ÿ’©>ÁŸ„,¥‹iù*“ìøBÊ\l½­ˆ """ """ """ """ """ "" VÅÑþª²PÖ]uCíµ5ñÌaHìîh9 xÆr9œòY¾:;úøß÷uʱŸ“PXa‰Ž|’[)ÚÆ´d¸‘€ܵþušÆÚ˜l•ôN·T6޲¢h¤ «s˜…ܱ½²7ÉåƒÎr}œÇq–ÛöñçÏœÊÉšª²á ôtí¦Þ×±“ìò߸m.{ц»³žׯãëÛïýþ“ärvëõþÿmgÁÇG_þî£ÙSÁÇG_þî£ÙTÎÑRê:8ÝHû£ê&qc =©òÓDìà fÈÙžG 8A$s“L‡[§mn-ÕT¯©ž«…ýî"Ï¥¹æáË#vövnWâñy»þÿLüž_Ôax8èïëãÝÔ{*x8èïëãÝÔ{*‘»éhíúfžïÖë&3EÌ¡&—/ðÄáÇã6–Žm#'çÖUŸ‰Ç|µ/årOdJø8èïëãÝÔ{*x8èïëãÝÔ{*ŠE¯‡‡î§ÌÏõ £¡í;|ªu6¾T^%Ž3,Âx"&äIž(ÁÉpìÊ”ñx¨ÿ%]é*Oÿ+a÷6ü»|ÿWãF¦ì:ƒ¥™ºRª†ë¡:®Œ”pi¦Ô®žÒ~9á²’àï Ñ· îçóãþ<î1îáÎç„ʪ [Ñ-ºÑ¡u.¡‚ã9žÃWôî™’bgšwm%ÚG¡§!Ç‘éísütÃÿ‹bþ±s Änˆˆ¨""" """ """ """ """ """ """ """ """ """ """ "" ÞñòµgÛ¿ñв¯+V}»ÿX¨ˆ€ˆˆ2JòW¢¼•Úäf,OÉTŸ`ÏÂR“è¦šŽ·RiŠ …u”•uÔóB÷½¡Íµ„åŽk²9öœŒƒŸz±Š‹í lPIx ’……ÄðËŽ×D\Äxsr~`{W+ÿ+k¨·M[f¶MQ¦íÚZ……Õto{êL¯ÝTöÔM‘ÛݵŒÄ;ù€ã’p1 rÓÉ_Iu·] …ÍeA¤t™„»³p{H'–æäg<Æs2”B¢ÛfеQ×ÅoeöË-eL1ME$—u[dŒ=›3 $8$,9ù»3‡GUÜXúFË„HÒ×õ˜ÉŽg0ƒ¼7m~Fs–7&ö‚%Ý­4Õº‚ºž+MâÝS4´”%”P2¤Ë#䧉Îx/ˆ7s‹€Üù#·KOOOTèn¶ºÚš6—ÕRSJ÷K AÃŽKCϱÎÇo`%I”£_E´ÒèÃ,6©§ÔÖ (n° i¤©šV7;ÜÇ5ÿv¹¤3èq^#Óµ Ž—µGYi‰×jVõYÚÙZÒçÏ+Cfò7q8€Ç pÏ)Ú eínššžÙS[ ÒÛXê=½ržžG™)Ü %¡®ˆnXç ½Qéy¦¦¦|÷[] E[éijd{d•¤á§!¥ŒæÞæç·°‚¯h HjKT–;õmžjªz™¨¦t2Éí›ÛÉÀnkO#‘œc#–F ›¿X-4ÚjÅp‚ùlЦ¦Øj%§-©2O'X™¾OÅZÃå4e„ó9ÍÁª"ÚçÒõUúªK4U¶hçŽÙT/‹‰5 m+%¥ÌÈ{£òÉxhÝ»$dgæ4{¸õgQXÅCÌQU™%ºQŒÇŽð@ ’Zw0§h5„S4šrºK…Â’ªZk{m¯,­ž¥äG ƒ¶í;A.%À€ 8'|®v:ª:ŠXà–Œuœ©f£ÜöÌs·hg–ÒÐyŽ\Ænà‹Eîx¥§žH'‰ñK‹Ç´µÍp8 ƒØAù—…A^ÚbÝ©º¶ž½Øtý}˪ÛàÙ$TrM% È9hý¦å®=¸È!{¶é½wBÊÖ3GÞåem;©æl–ÙÈ àyÌ9­p?HùÕ³Ñ%î«M{˜o:ކ8d«µZ§­“csâ¢cÚ·-Á8R:Û¥{埢i®”ûtšÎ•µ‘ÕÑLךxd¢ÒÕH@pw±€³ÊçÆ‡™Êôáù7dÓÍŸãL²ÞÔþ µt{âõ½wgãUp<+dãã*8{Ç0|‘Ãno3’Vn‡_Y}ï{z>¬­žÛ/Šj«MKŸ•¸´m ¸“Ì ‰К¤K]’é]K-ªñWIkáûíq¦†7S[·´8qw<<áŽkÝÃköµÀ»bßzO·ZnWúy4£Ó³2;½Æ!4Ô­tOÄ%Ò‡½­d ¸1®sv’F6“¯•õ®©ñ~÷µb_ZYkÛÑí]\Ö©7ÑMSjªs¢C!i >Q'$ ò#Ê=«íúš~†Å}ªu|⪳‡j¨ka­Û\Á“‘—cÉË‚pºW¤«ÝVšèëRê:á’®Õhª­“csâ…ÏhpÜ´g|áj6ž’(è´íÒù_­tη‚–¢ŠŸ…¤¨ÇÔÎ föš¹·nsÛäœ1ø8|«¿ÿª0Úu¸±Íkƒ£úún±qTÔEk©ÌÆ9®hp9`æÖ’CA8æNNa¾ë?ª7ÿFÍùWZiB붤¯ ¨¡¼Úë ¶ÒUIo®۶Yªãkƒ¡sò÷p p/- `5Æ@¶e©ù– _åÄ¿uŸÕÿ£fü©ð'YýQ¿ú6oÊ»iù¹~“áãûrÏDúkZÑ\.À_¦*&£T\ìÒNÆÊÍÍc ‘yY,˲@Éo^ðô‰ÿó"Ñÿú‘öÕcj¿—hÿÕÕ_Æ¥QKÅÍŸ|îUêãæ3ª!«§è/¥¨k«ã¸U3UB%©Ž“«6Gpm™">$›~Ú9ÆygšOkŸäk¦ü[𭋘Tž7DDUD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA[Þ>V¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅ½ÑMM¤Ó÷ Èèé)*)ª&™ì{ƒ[kÈÃçvàrí#8"BߨŸh³Ül±2 Ò^ñE\ÒáÀÞ6JèÀ8‘€(9µ+OÉTŸ`ÏÂRâå7kMÕ·[MÒ²‹ŒUŒ†ÑSA_¯»Ö_à£ÔŒ¡±êmžýÑ:‡‹,¸…?ƒ.ð"ß lc·1ý™%f^´/¾:{¤O¾œ/†<_Œêùê{íðÑönøÌpwö·ö±ódç_5Þ•²Þ…žår|UC‡Å-¥šHiø‡ñ¥k pî=œG7?2Å»t•£-WšëEuÒvU[¦ŽâÛ}D‘R:HÙ# ²¶3m-‘„9Î íËHïYèþÓ©ÙOm¶[¯Z†ÑQk¨¼G@ÇTì–.Þñ‡HÖá‡ipCG, Ië+Â+DþµÕxW* íü=ùêÕpÔlÆGíp¶çæÝœ`ê=5t‘kÒz?TÃGu–ŸPQYj*)ß “ÇM9‰æ+ÃeÏkd#w.G+a¾kÍ/eº¾Ûq¯¨ŽXžÆO$t3Ë3žhšf0Ç !Í?æòp=„ Í£±u}qtÔÝkw_¶ÑÐõ~8}^Z§ïÝž{ºÎ1§<¦T$Ú³OÃiºÝe¸m¥´Núzç_º)[Œ³fÝÎ'sv†ƒ»svçpÌØ9@DD¶±š(/²Ï+"¶êœ¹î¥ùÊ€÷ÚÕÞt_ïÛÿåfôŸ¦ìžçk£Ôvš[¥$µ3²ˆY#CÄ”íÃÚàîxÏ5¨ø*è³ê“Ìi½RÅõb¾Ö¯d t¿$nkØíY kšr1[9…Ìk¨õÓmTÝô›i²Xíöz f¢†–(hál{ü›{Ëß´\\ò2òCG‘âW·Ÿ”FHäyóóm’ò븳¶Ñp7#œQŠgñŽO‘Ý€žÎÀ›ƒ›tî sécmŽæçÖ4º•¢‘ùœ’YËÊúD3SO%=DRC4n-|r4µÍ#´y‚®ÇÍt‡¸æËl¾Áq¤ºÓuˆédkw¹¸p å¤ÂPsz/Ћ†šèºßw¤³×¾ÙIr­þõ¤žèæM?®Vµ$’_€ùÔ}§Mt]w´>ñi}²¾Ûíõt×GK vŒ»/l…£·Ÿ$žè¿C,:S£Ký¸X›Au£.,W'ÍáÚ71äd} ùxÐúF‰­sl» c­J>ŸýïèP~z"O¸{—ÿʤ=Ñ1ZäèÊzš LT&ŸU ‘#äs™<¼Éq=®$àcæñ”•tçTE1¤týn¥ºKACD’GGQRD0OÅÄç5¸ã85€ý/§ÛtˆtRRØ/±][i–ËrŽàöîm+©^&púC1’?±b\(«-õO¤¯¤ž’¡Ÿ·ñ–=¿÷ƒÌ)±ðDWo¹ÝGvÖUVû„V¬ûwþ"±Pd•ä¯Ey+µÈÌX6Ÿ’©>ÁŸ„,¥‹iù*“ìøBÊ\l½­ˆ """ """ """ """ """ ""Òè’ÉU©}Ì79C$1ÕÝmSÑ@ù‰µòÑ1. — à˜­³\ôWCw¥Ö5¶º™™v¿Y«hiá©” :yê)Û¦ k šçˆ¢>W&œ ¹Û¹ã£Ot;´V’¥°Ã¤ÝVb ß1¹¸1­Èoàa£–Oζ_J©zP‚ÝÖ:'T\&ÕÖ«T¶ceÖ:ýEL²6¦‹4ÑÓIÂcX[.c‰¥¹{6¸“å,ÝA¢n— /Ò•²è›>®ãu=î }²ž‘¼R‘‰"qòC¼’n@¥|m*>¤}ê=BxÚT}HûÔz„§Hú#Z\­úîѦ]§ßG¬)ÝÅžã<±ÉI)¤e1 k#p‘ŽdL îic‹Žذz`èë\êù5--ÎÑ](Ì÷M¨+èÙC˜ÇRÓ·‡PýÎ.‘Çø,pn sãiQõ#ïQêÆÒ£êGÞ£Ô ´Yl Õ]7ÕÕYîL¨²[[·Øa!ðÍtÏm; ¸‘ŒºAÚ Tàö+er¯¥GÔ½G¨OJ©zPƒª‘r¯¥GÔ½G¨OJ©zPƒ uŒÑAx¥–yYm·TåÏp|}/ÎU'a裣K7JUZö’z!Q(ß•œ iÉ;å`ÏiåØÓ¸ŽÑ·SÔÞèÛ§‚}IÑE¦õ ./Š;…LU Ä`–‡Ó>p ¼-tgÿôû£ÜRû*Í•[¦µ{$è[¥ù#s^ÇjÈK\ÓAŠÙÌ.cVþ±éŠÇvèâ碬Û4Å%|‘ÊãA4lŒ=²Fâã!`sˆ­Îs€>Œ*X“¢È'¨é+MGO “<])ä-cKˆkdkœì˜4OÌ*WDÙ5E=>°£¥³]ã¸GiŽÂÊY­2US»in2 £8ùÚ{Z2)fÆÛ¦¤¹]tÕÖÕC5EMÌõvSÀ]#éé]$QŽÒ7¾7ìon Ç"§ôÍÂ=OÑý¦ºžw^)®üY -.– Q$Nk^;[´¶wàö4ç*³D¸Þ8õèßSÍUÉ­mê‘•n’7€Çl¨âµäŽD<ÂÎXhX=(Ñ×ÑêxEÆ–¦žymtpž71ÎwT‰¯<ù“½¯ÿx8v‚µdIŽ®Áu¸oû­Óú³Ó®^]î<Ôv >ۜ׻å®Ú×ÑUY.qwŒ¸<‡sBбºHª¶Ó?¤ë{¢n¦¾ð> ÂöüuOýŽSðGk¸uM™çoìgqÀ9N’*­´Ïé:Å^蛩¯¼ƒp½¿Sÿc…”üÚîSfyÛûÜpU‰áC£Ï®ºwÒ~tð¡Ñç×];éH?:>—…ôWøY]p¬š,µ7K^ø#·¶á#¥‘Œ Át‘2¥¯’[ –u}KUmÔ Ö÷Ý8è®zeþðõÙ¨›Å†«Xç×í-È“¦&;ý½£ Äð¡Ñç×];éH?:xPèóë®ô¤wGUö»×H:²û¦êi«,U–øEU+ƒ ž®>±Æ-pò^Do¦i#?³ŽÖàlÚ§ûŒÖú¨¯ }uÓ¾”ƒó­w[ô‡§ëiàfžÖš H™]_wŒ8 '$ç´‘Œvò—ÅŠÿOtQ|¶ô£=þ§¤}Y[¦¢Û= žk½K¶ÌIË%q—0 Aæìáù k­~ :”z›NÝn5:Ÿ¯¾+U{gØÇA 'Üw/íù©6(±tv×I©`ºYí·b`í|£™¬húIqœµÔVÍÄn¶»îŽËx±Š)éïµbšVRvTIL ¢Hö~Öâ†çæ°ulUTZrÉm»5ìºÓ¾ ¾)OÆCNî 7ÖÂgm<Àp8浄S_{|{‹ÿ”9³ø3ª]>ä«Í¢É­j+/Z t k\_WU Ž­å¼Œœ¹¼‡Ò´:;¥íu¤ôíâ=9Q]¦¨µâ‡i¨¼K 0ÓÑîpâJéâ48¿l@åîÏìÎGM´5qtVmÖ«-ÇQh»F‡©} Î’²’H¤œÒI sÌ_3öGd6¿q— e€[‡GŸ]tï¥ üéáC£Ï®ºwÒ~tÝ%:¢é`¬¥ ©»Ûõ=~º›}Ÿˆ6¹îe8s¤áîŒÍ…!çû¬›wHÓ.µVÝR.~ ½_@Ü-ïêMÇ¥ü¥Nì~̬ÛQä)»¹žv'…>ºéßJAùÓ‡GŸ]tï¥ üè5Ý sÓwÎ’-Uš%ôÒ[(4Ì´•晸l3SšX$ÇìÈÆ²§È>Swž{þ¤þð?ÿß8P^:<úë§})çPÚ¿¤m+Ui1XµžŽ5eÀf¶ïcks’|‡O,c—nsËUVÚ‡¢‹åË¥/ôÝ#êÊ-5.éë¬ðÝê[º`FƒüˆŸ’\6ã ÀpáâtËþô£ÿÒ?ˆÅ°ü1©úóÑ¥æZgJWKkú1ÖòTjÝ%p¸Ýz‡ šÕql®<)™œ4߳ϖ{ 䤨æ„DZAoxùZ³íßøŠÅYW•«>Ýÿˆ¬TD@DD%y+Ñ^Jír3 §äªO°gá )ftwWECUl©¯‚ÚbÌbA†#´þÐcË]ŸjÛ/µú©Új¹•wš]Mi›†ÃRg5¤vðæ¹¡ø’í-æÐ$vã\®²i£¢ÜúJšÂû„ÑÛ.qVe¸²IkÙ$aN­,´—mÀ'pÉàgëzÑñE§®7:k¨·EArŠ«¤!‘U5Ò²<4 ŽÌÀo î|–{y±£¢ÜMŠ ¢ÓÕwHoò6åGÆ©e5LAЖÏ,N{ £Ãƒ¸d†cçq^µDÖ‚Z]޶ÜÍa³;…(¸0FÓ×*A.g.ÛˆÃÌ‚âì4ÄSš"ÝlºÞ&£ººª8E Tí–í7E å‚Ó¼a„m§ŸhÇ97ÐhèìÔ7É"¾ jª™i (©ˆÈÇÆ#s¤âpð[‰Y†m9ò’å«¡¨"ÚdÓ´6»Ž 7‰jf£³WuÚbÖIQ)t 9ÁÁƒ=ÄáÝ€cžFMŸOØîWý4è½ñ‹Íy |Fv à”98“f×%ÙØ3’9v§h4ÕîH¥‘¾HžÆÊÝñ—4€öä·#égéè[íÚz¶ËušÓï“*­p²wÉQ+LffDH`h1œÈÓ‚çòÏ57¤é¨)µÏGWÉY§Å%SOQ[,~AÙÊ=ìß³òœ7dîK¯Ñl”TZ~éSQQMKt ·Ûé]SX%«eD¯ØÆµ„DÀÒ]#FH8Î~l5”69mqß-ÐÜYGdtÕ´“Ô±ÒymsšY(Œ(G æÏ$ûYWc]^çŠX'’ â|RÆâDZí-s\ ö~e·jŠd½ÞlÂýLôކELLd“ö8pÉiØÁ>Pn9/½EŠÈ5&¸§ºÔ]eie–3$¡µl„‰2ß)Ïâ,‚ !ÙÂ†Ž‹hžÁCsmŠm>Ú¨EÚ¹öñdÍ‘ÑÌÓ=íkAi3ù£=«2ÇmÑ•Mâ))*ªD¢¢&о /“ho ðs³9&N\¾|‡a¥¢"Ð""" "" ó£n€"ÖšN–ùMr|"F0HÙ' òÌmyÀ^WÒ¶_I;å¾sú*Ñ÷-$ÔÖgð"P.ue?@Uõ÷Û“_©ß¢¤Ô6«˜§¢§4œSña»7Ã#š và´ÆìÎ 7ÅRNùoœþŠxªIß-óŸÑW6©é ¾ÑYžN6ºÇ¦v{÷Zêî±fNþ [—d21îËÙÛ¸…öð“n‚ûKc¹QÉK]Q|žÓ±¯ÞØÃ×Ç3Îñ-0ÇÌê† žÓE'â©'|·ÎEb?ÜË Zûìmpí¬üÒú&øu.—¢¿uN«k], âoÝ yáIœÛf×ãæÝŒœdèÝ,^/Ö 5mßN鯄•tÛ^úÕ%’0ß(Çä?{Ç#³‘œeØk³~•KܽΖÛu ÕÕº–iánç¼Õöû„9'æs'TßJº^=¯.n*‡Ô6°üc»I|,ŽÁ ˆÎbèZ c~×] \5ßHü¤©à:’W婌Èß-á³c-¤ä¸dà7iu9îŸþ\õÿ-ÿ+°VªüèÛ µ¦“¥¾S\Ÿ‘Œ6IÃ|³^pG—•ôª w—¹kù&£þ³?¨«¼U$ï–ùÏè§Š¤òß9ý¹XºAÕ”ýW×ßnM~§~Š“PÚ®bž6ŠœÒqOņìß Žh-Û‚Ó°w8 ÓTô…_h¬¿ÏG§]cÓ;=û­uw X³ '-„K²÷eìíÀÜB gÅRNùoœþŠxªIß-óŸÑWg„›tÚ[ÊŽJZê‹äö~öÆƾ9žp0׉i†>gT0döƒDߥÒôWî©Õb­k¥œMû¡/<)3ûlÚü|Û±“Œç?I;å¾sú)â©'|·ÎEu* å¯I;å¾sú)â©'|·ÎEu* å¯I;å¾sú+ç7¹dÂÍï¼´7ç=k³þ ꕇyù>_êŸüŠƒ–|Yéûþ/<¥Cê~m–[UÒwjÉUEj©¸ˆ#œHâØ˜H$pÆv2>|go½(ô‘­4~­¶Ym}K¨é®Òmõ”×N|»Itr4ÂDDçd»icK³ä¼73Z:¥çSº²(¡©: ¬ÍR™Çù[ƒ\ZÒàpK[žÜÅ%W)k§½jZKeSåd3oÜèÈcœ1Ghú:Ùº-ÿíßü_á=iߊ¤òß9ýñT“¾[ç?¢®Î–®:žŠ]'I¤ë¡¥­¸^Ý Œš6º:˜ã¡«¨à¸K÷ÀÀ^ß)£˜ú }oHÐGv¶ÝÌÓÁcLÞ®wJGDÞ43QËD×1ß8||IÚZ ?>PT~*’wË|çôSÅRNùoœþŠ·kzG½Ùa¨øM¤"·NÛqºÃ7N;M$rÄÊ’÷p›²H›3Zšìà?´Œöô“n©¼ÔÙí”rUVÁŠÏ±ïá‰71Ï–fœµ‚*‘Ôï )?I;å¾sú+£ÜÀȶ[Û¦«ÿ‚ºµjúÕÕ,ΣŠ)ªDo0Ç,¦6=ûFÐ縴Œ×c·±Kô®uñg§ïø¼ðz•XtÃÑõ¿E[ì•–ë°¸Çs’©›ÚýìÄ.¹k¶·9sœ;1ÈNUéÑwIÓXjÛ–éÑ”ºršÓ!†áYStâK´ÇD JH-vC¶†8;>SªÎŸ“~ŽÿúŸñ£RQL¢"Òˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆ+{ÇÊÕŸnÿÄV*ʼ|­YöïüEb """ É+É^ŠòWk‘˜´4U|ß{êê­Ô÷M²Jióµáñžc˜pÝ~bù”ÕUêÓ ®¶†Çhª£ëÌlu2UW ƒ±¯l›Zò˜Ó““Ë·µjÖŸ’©>ÁŸ„,¥ÅÊKZmGTÐ6¢‚èËuê´ŒeDµeÐâ˜FÖh9- åÎÎ8ǧêKi/1Séûƒe»R˜d–[¯Æî,r´·1snèÆC²HìpíZš,õ‚rûwµÜ,Vz*{me=]º›«™ßZÙ#‘¦I%qØ#ii/”ãÊ8h™ò—·^ísØi(«¬ÒÔVQRÉKK8¬,‰­t’HèÃrç5Ò¸,̃Ï0® ˜Ò7Z+5ÒZºêШ䣍¦ÃR #¢s·?8kÝŽÜÀAú:ïk“LZìÓ[k é+¥ªžfV´ [(¯cZc;أÉvâAÈ Sѵ\5MuþùU=¢g[/5=jjCV8‘˹ÎÜÉC0/ °ù. äóK~©¢¡¿Øê ´LÛeš§­CH*ÇIw5ÛŸ)f %‘ƒ†%  kUE:Á9i»Úè)57½µ’2çMÕéÏ]h4í²V—ü_ÆÑÆ6dnìÈ-ÉøMMN•«·ÛfЦÀÖf©2 ¶wOÐÆ– ï,»–ÑÚ :Ò+Ö Ž+õžŽ}¶Ë±ÑÍ ÖÅS\e}CZ@ÜÐÍ®c\Ü79í.—ƶñk}$ÊUM-¯¬¶¢©¬O;€-‰Ã nç†ùÄÝŠ ¬š¦ïk½jÊ‹ÔvÚÊh+*]QWNêÖ½Îsä.xcø`4`àe®ÇiÏb®Õ6º»ž­®uš±§P0†4W·þÌçLÙÜOÅycˆÆày8nFI!ÃSE:Á? †›OZ(¨i*`¸Û.W²°ÔµÌ.xŒ`G°Ž x;=ßHÛ·a³{éte=¥®© «²Ó^YP×>h_àÓ†‰cxÏ8náÛ…Y"\Aw—¹kù&£þ³?œ¾ô_§¯Ðt{SQqŽ‚‚ß5dR±µqÆØx‡íÛ¹Ñ1ÞN{¹›“tž§é¦Ó§¨é4ýc`¶ˆšè £$´´m$¹»‰Æ;yò Wá׺ ½?w¡üª¢Ô}ÚïwJú©n׊J;§ßku4ÑŠk†Æ†Ž.挱­c¸nfæ´¼ê.Œôíòç¹UKpŠª÷E$’A0i¦1æÍ’v˘á%Ç#â"åÈç—þ{ »Ó÷zÊŸ½Ð]éû½åMŽÌµPÓ[-”¶Ú8ÄtÔ²X?šÆ45£ÿ° ·ÔšÓLPß*¨ên¬BàÉÈžð×22Ö‘‘ØGÌr;W=ü:÷Aw§îô?•>{ »Ó÷zÊ—íV®¿Õúv餫h(.{ »Ó÷zÊ›ª‹Š¾{ »Ó÷zÊŸ½Ð]éû½åMŽÕEÅ_½Ð]éû½åO‡^è.ôýÞ‡ò¦Çj¨½U[In°ÕV×NÈ)âa/{Ï!Èÿy'Ì’\}ðëÝÞŸ»ÐþTøuî‚ïOÝè**󸤻Û÷y*Õµ-âÝzv°ª¶Tqáf‰­ÎØæáÃ'p°…Zü:÷Aw§îô?•bݵ_O[]]²¾¿IYàž> wÆö–¸d4O0r¤šÂÙº-ÿíßü_á=>êÎéýâ/̰½èíJÇ:>¥t¤Û#[$löA®®žAT~Ž^l”·[’º¢I›-š¹Õ´â2\÷SÍNCò[²wžX9 猃]ÑÞ­ÕõúŽ¥µ/}Â×Ql¬¢âM3'à‰d-ÆxŽl0¸8 ¬³Íq—‡~•¾µ}ßMêÖÅIÒOµt°ÕSÝ÷Ã3$nêÔ#-# à·=…QÕž-Ô¦­×KÍëP>{síluÎXÜ`¤~7ÄÎlÎì7sŸ¹îØÜ¸áxÓ½éÛÎÁr¥–á-U’†JHß4ÁƤ¼¸™¦òFés$Ä8`||¼¹Œrÿïtz~ïCùSá׺ ½?w¡üªlvªÑºEÔ¶;%u<;ƒ –F—µ®{¶ò! àg8'·è+˜þ{ »Ó÷zÊŸ½Ð]éû½åKö«Ïáþ’ïoÝåüªé÷ù7èïÿ©ÿ5—ðëÝÞŸ»ÐþU¬ë†ô¯­ºŸÂq×ú–þ¯ýëÍûw~ÆÜçc{sؤš¢-›à¬îŸÞ"üËõ¥oöj_r·: ^+aâqààâv“‚C\°­"oxùZ³íßøŠÅYW•«>Ýÿˆ¬TD@DD%y+Ñ^Jír3¦¶2ï-¾†If‘Ò¼ÆÝÏsc„ÈZÑó¸†à¤…-TÝ#Qi¬}»[®5¦ªfeC*rðܶ6pÈi.çv‘œáCèJhjå¶Á5Õ–iÙVüíŽFÆ\̑͠¸5»¿›œüËq¾ÍVí9^5EÂÑq­"?{¦‚ªšž&öî/’"Ig)nÜÕÄÏþÍ#µ–’žÅ,nŽ¢†X -,…­¹ÓK)’H#{ñ¸·{‚¸9 äá\tµòßG-UU$aàÎÆTÄù`ÉÀâF×ÇÌåÌálU&–CeÕÏ®¶MAG ¨ºœU1Õº ŽHÄ@— ÍÁ Èœ€qh裱Ô\îµW«mm4ÔuPAÀ«d’Õ:hÜÆ“;Ù‚àó¼7~œ,L®•ŒÔQÒV z6SVB&¦–K…;($Œ4¹ã/Yû@ò (:ºyé*¥¥ª…ðÏË$íØàpA1[•ÒÍ-ÓJi'Ar¶Äèí²‡ÃWY>ÖõÚŸ,qÏ1†äù=œÂÖ•”ÕÚ†Yi%ãÅ0S‰°GÅ #tœùùE…Üùóæµ¶£ïŒÔSSSTCG‘ÕÓõŠmµ—NÜC¿.x- °æ‘̇uÓ÷k]u•´ìd2?‡¹“Ç!cñ q,v?šìG—%¹Y!Ô=K%ÊØÈiZÉ*n0bœ6¶YÝÄòüƒÃ{‚O’2à@‚Š™ñt~ŽzÊ;/§†+át’ÙP×¹ËÛºXü¦‚I†’'j0> ßz‡\êlÛÁãðºÄ|~7oàîâmÇ=ÛqŽ}‹ûA¥ou¶Ê{œÒ *‡¾6O-t0=˜Ë^ñ±ÞP!®Á ä9­£4ž>{ëm÷§®uþ[gnwunwçÿÛÎݸçœsP7ôegª‘ÇßZÉ_jãt­kã§k胷€LRs#æã7.ÔbÐX® ¼WÛêm­–¢Š’¢i©ä©l.hlN;ÚIòöò“ks¸4üÙ+2'5NŒ¡¾ÓÔÐ6Yêªc‘“Üé¡Ã#l%¸kÞ»/~G3‡8lF™§_ܬûN—à™}õ§áq}ìêÛ8›öîâù8Îqå~Ï5o¢Žñ¢h(b¹Û)$¤¹ÕÍQ×*ÙÈ䊘5Á¤î8ŸÉÇ—g0§j¨ëv–¾\(⪥¤Ì›&>¦&K>78>N`$`…âÕ¦¯Kt· 8 u,3ˆ&’J¨£à¸‚Fð÷Æœì4FsÉMÕÑG|¨¶]ioVÚ*hhé`ŸVÈå¥t1µŽ"2w¿%¥ã`wí}9YÒ2õ§u}Šz fV_b¬Ššjèb”ÂÆÕ9ØÏv8±€9'$^Õ—}7s³Z«r·À$Š®ž#³è}K ŽôtÆN•‘¶º>f‡DÐòenÓœ³píùÁKt@ôkywY£kÍÒŽFÂê¨Û3šÈêç62íîÍ0>sþ+±±42—ô¬’Ü­†žž;Q–vÜ`t1¶bl ÈZ1È1œžXpÌíU¥Y¬—³e}Q¡À’iê#‚&œùÖäààg'{¿iûµ‰”ºÓ2Ÿ­±Ò@Þ0»fødsˆv왓¹¤ ·îZO[.´–›•ö×Eq­8¥¤¨«Ž9§ç!Ž »Ÿ.@¯¹»Ú…²¢èntB‚—‹Ö*ŒíáEÂ%²n~pÝ…®ÉäZAÆ=Ò&‚Ô× WªŒ? jíš@-SÚâŽ,dϪ‰Ó00È×B]‚òCC.ØïJ÷6´©´SÒ5Ú>ñ]Þá/£‡4Cã)Ã3¸¶WÇNó´Ž88. Üê=<5tñ¿ZÅåÌâ6ßÖãë%¸ÎáwcóŽÅü·ê]9q»Ëg·ßíUw([#¥£‚²7ÌÆÇ' åÌp r9;‘æªh4¦‡YK_ÂZ»|š§ßÈ禞ÖÊ·¬qš$/ˆÖnk~,µ¤‡5»CÚ×a¶EÖ)ì+”5t1ÒUV_®µÒm-&VM_<½Å¤ä˜o00À ME41‰Û\HÆ~•_Ñt¥£+k!££×Úf¦¦y0Ås§{ä{ŽÖ´;$’@v­óTÿqúÃÿUWZú2ÑvΑkuõš(ï•‘í|ŸÌcÎî$¬ocdx 9÷°½åø¾ª·÷FÜk®}ÖK]RùÝ´tîìdl¦5 @êIí%sjè~ž¿’k‡þ9—ø.xZ‰WǸ¿ùC—û?ƒ:êškh§é=%­`%˜b&ì`2y¦ˆˆˆ€´]]ª-ºk57«å¾ÑHé%­¨Ž–çhsÈà8ãúз¥_k›%§QÑ\,wÊ«­Õ‘ˆç‚QÉÑÌ@!à €VrXÖu/H4Mx©Òz²Ùpš™±6Y-ÕqLèD ,'i#v#È‘Ì.j÷Oÿ.z‹ÿ–ÿ•‰_7aÐ} TéÝ;IÀ¤‡„ç½ÄgÈÍÒÈì Ï8ù€ îŸþ\õÿ-ÿ+bUj»Ëܵü“QÿYŸÀ‰pjï/r×òMGýf%¤NXºPÓ׎‹kúB¦§¸Ço ·É_SG,Lm\q¶8›¶îtE¯o•‚Þal—-G§­—ZKMÊûk¢¸ÖœRÒTUÇÓóÇÇ]Ï— UA}èûVSôCo±[ZýLýžºÛ Dm9¤áŒ.پ⻦Fäîi^‘4¦¸j½TaøKWlÔ‚Ñjž×pˆád{&}TN™€9†Fºì’ p\&ïjÊ‹¡¹Ñ ^/Xª3·…–ɹùÃv¸;'‘i_¨ôðÔ ÓÆýk—3ˆÛ[¬–ã;„yÝŒsÎ;‘xÒW¹µ¥M¢ž‘®Ñ÷Šè.÷ x­9¢NŲ¾:wœ ¤qÁÁpι‚ÔÐë)`«øKWo“TûùôÓÚÙBÖõŽ3D…ñÍÍoÅ–´æ·h{Zì4-›~¥Ó—¼¶{}þÕWr…²:Z8+#|ÌlrpÞ\Àw×ù#“¹k΢šHÇÄí®$ ã?J‹èºÅ=‚År†®†:JªËõÖºM¥¤Êɫ璸´œ“£íæÁ§ûŒÖú©|XÐèºRÑ•µÑÑëí3SS<Šb¹Ó½ò=Ç kZ’I ;UEî¸×\ú+¬–º¥óº-hè#ÝØÈÙM k@€ÿÔ“ÚJ²-}h»gHµºúŽÍwÊÈö¾Oæ1çwV7±²<áÛƒØ^òú³§¯äšáÿŽeþ‹0sÂ"- ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆ+{ÇÊÕŸnÿÄV*ʼ|­YöïüEb """ É+É^ŠòWk‘˜°m?%R}ƒ?YKÓòU'Ø3ð…”¸Ù{ZA!t¼×Üèíôun§0Ûá0Óébˆµ„çÌh.æIˉ9sk‰1興€ˆˆˆ€ˆˆˆ‚JË|¹YÙV¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅ«ÑÝ® ÝÊÅf¨ª’‘•ΆœLÈD¥Žx iÚ\ÜÄgŸ!“Ï3qØìW z‘c¾ÖÏYO•^¶ÜØ8Œ¥ïÚæK Èk\ìgšÅèZ ê5®Žž&x­¤µ.!­s\ç`|Á ’~` [ж:Ê«Žš§Ó46½LÓDúq9›ŠÝNá;Þ[¿?'iË€<²;{V£PµÙ®÷Q)µÚ««„C2jwɰNÐp¼Û-w;¥S©m¶êÊÚ†‚]<‘àÓ†‚VûC@*ôŦØÍ5©+êíïµÐ[ë[©ê8Îò¤ˆÀ÷4ìáääã‘i_s ÷[ž§§§³¾éNùhU-¾áÄ­â¶7ƒ+"Û.¿‰äcsÚG!¹gº«cEX+º¤¨{öp8g‰»ü]½¹þ…‘Wj¬¶\a¥¾ÑWÛ‹KÄ´¤JO75-ÝË8ý!n“š“­oôŒ¹ÉWvšÕ= ò–²^ lˆ–œqD-’#ƒ—;=¤¨ÊëeÞGÇdºÑU²çQt‰Öêcw4±í“þÐq„^Qo,á^ÈŒ¿ik­¶¾òÈ(«k-öªéhæ¯e+„;£~ܹÃ!¤ù'ÿ8,:« òÒ «5Æ[ýè$¥{xýŸ±‘å~ÐìÏhúVë~£ª«é7Yii |s].ÉHÉÒglŽ’3þ;æƒØx ö%®áo¶ãlˆMS%¥ÖËgV©lHö½œGG#šàÓ ã‘ä’x›G2™]+H«²^hîÛªíôõ³–¶yižÙ$.8­#''ÂúTéëý5 õÕ6;œ4”ï1Í<”lq¸;ikœFÝäàüü–Ó©íòÁ¥©-éÛžª{‹M%-Æ´ORì±ÍwÀÂâcÉ?´ZÐçŒ^–ß|¤éRG^nÌ­¬˜µ²ï`žœLxdûLò˜Ëyv+2µ¥¾Š²áTÊJ IêêûA{ÝÿpÊÌ›Nê\ÖÍbºF]RÚF‡ÒH3;†[Èý²!½§èRšN*šÍ9{¶ÚZ÷ÝjNY_Ý&§o‹GkŽã ¶Žd4Ÿ™Hê{uö= ¥­UðÔÉ]ï•tPR]4aÍ¥ÛÎÐâI!¸Ï”9sVå÷¡­Téëý5 õÕ6;œ4”ï1Í<”lq¸;ikœFÝäàüü—βËx£ Š¾²Ó_OG68SËNöFüöaÄ`ÿbÝu•E}·¦ª÷ê_¶¦ó¾xækÚÚŠ&Ôå¼ídžríO.Åð‚ߨmÕWÛž¤ûßUERÉ*evb­•ÌwÆîÉ>7†ñ·8 '–™Q§IjºGSGM%¶±“Ö±’RFèPל1Ì˃ Fsó/¤6KÔϪd6‹„£•±U5”Ï&¹ÛZ×ày..y’0¶Û%Îù¦´ÍM²•õÔ´2SUNÑñtÏësÉñ®ì`Ù#]‚¶:ŠK³:Bé:–ŒKK],5& ãÃsÚúø8ý¶;ÉÿpÇhK˜­®¶»•ª SÝ-ÕtîÔÂèÜGÓ‡p±×w£¸Zt?½×è'¥¬}Å’ÑSTÙcŒFñ3¶mkœaíÆvv(Ým|:ž®;®ŠÕV6q))ÖÅÜm $s'Ÿi*˱Û}émyÓt®­¦†¢è"3TF*Þ$k,¬åpÃO à`–;è+a§Ðº¦j˜iè!šZYD5 ޶G:–5áþK¶=ŽÁç‡4ö´Ž/Öm%|uÏSÜélÖû‚’ JÊÙD4ï–ž¶àé#â; ¢"NH'Á^K¥¿ê(jm·k­ ›Skòcª ¨’™Õ´±i÷1Û^ܦ¥v;v‡4‚áEƒQ ôLSDû$ÅÕ2˜˜c}CÚcŸ—–’Ü0ùNÀÉks¹ÍíàëF÷?ï3~u G[SjÔqiêAuz o5 ¥©¹JdnÓ’U–I;½Íl²9Ä·crÐDE÷G]ªiàÕUµñPšY¦Œ¬àºçç-Hœâ>ß%Åûwn] »ÁÖîÞfüéàëF÷?ï3~u¢t劓UÃh’¾¢ŽSmlôæmU=š¼É#q§†GÕOäŒÆàæÃÃr㘸µDw{f—¹k­[s°SWhÚ ¾Z*Ù)]ÆV¹Õ‘Æ‘£€[ ÜÞC¾f†ù¤ô¦ƒÔºVÓ¨èlsGIu¡†¶MQ ‘¬•íäaÃ8$gç*OÁÖîÞfüê®è†Ë&¦·X-µwýEECGÑÆœ–{uÖjF6iE`2ü[.ÄL>IÀ܆âO@:é ¯¢]QQ¨¯•× TØÙwmUsßO0’ÕQUäÁže²BÌ5§œ”ÐÞ(4‰­¡§¬†É3bž&ÊÆÌúˆdà 9!Ìw>mpD¾Þ´osþó7çU§EôÚÙ–xï:§T5Œè÷OU‘Ixžœ¾ª~¹¾¡îct‡†Üäî[ƒ°1htOt­¾tY¤¯W)xÕ· %UL˜|’@Ç8àvd’š/Z7¹ÿy›ó§ƒ­Üÿ¼ÍùÖÖ‰¡ªx:ѽÏûÌß<hÞçýæoζ´M SÁÖîÞfüéàëF÷?ï3~uµ¢hjž´osþó7çOZ7¹ÿy›ó­­CTðu£{Ÿ÷™¿:x:ѽÏûÌßmhšAîÀµÐYúK·Ñ[i›Om ;A$’gŸ™'™?÷ýS ó÷l+4?êxÿ:£V÷•«>Ýÿˆ¬U•xùZ³íßøŠÅ@DDDA’W’½ä®×#1`Ú~J¤û~²—1C[r§ ¢·QÔVUIvCFG» ÉÃ@$àî íSôµ2ÓTÃ$Âó‘ÈÒ×1Àà´ƒÌyaq²ö´ù¢"€‹éSôµ2ÓTÃ$Âó‘ÈÒ×1Àà´ƒÌya|ÐÑÐNÚfTº=ѲBÓµÎhisAì$4‘ónH^ª)g§†šY£Úʘ̰œƒ¹¡îf£Êc‡?¡E–â-µJû} |rFc|5q—4‚AÈ ‡4òSH=£8%}/w‰.qÓÓ¶’–†Ž›q†š˜;c ±¹Ù{œâN’Iäù”j) DVBšo5§ÔÉO;vðœßÙ‘Çw’ãØÎX ŠýJYo&ÙoºÑ‹uP¹Ó y$˜Éº&‡µà³kÚ3½Œw”ûvFøªIß-óŸÑOI;å¾sú*_±ËȺ‡ÅRNùoœþŠxªIß-óŸÑTZ}ôƒ¡íš*ÝG[«ôü3±¯s˜ndHç ù|Žåó-‹Â‡GŸ]tï¥ üêŠñT“¾[ç?¢ž*’wË|çôT¯…>ºéßJAùÓ‡GŸ]tï¥ üêŠñT“¾[ç?¢ž*’wË|çôP^¾:<úë§})çO }uÓ¾”ƒóª+ÅRNùoœþŠxªIß-óŸÑAzøPèóë®ô¤<(tyõ×NúRΨ¯I;å¾sú)â©'|·ÎEëáC£Ï®ºwÒ~tð¡Ñç×];éH?:¢¼U$ï–ùÏè§Š¤òß9ý¯…>ºéßJAùÓ‡GŸ]tï¥ üêŠñT“¾[ç?¢ž*’wË|çôP^¾:<úë§})çO }uÓ¾”ƒóª+ÅRNùoœþŠxªIß-óŸÑAzøPèóë®ô¤<(tyõ×NúRΨ¯I;å¾sú)â©'|·ÎEëáC£Ï®ºwÒ~tð¡Ñç×];éH?:¢¼U$ï–ùÏè§Š¤òß9ý¯…>ºéßJAùÓ‡GŸ]tï¥ üêŠñT“¾[ç?¢ž*’wË|çôPh^ë»ÕžýÒem–éCr¦˜Øéi*+Zî4Çi-$‚?¤*muФòß9ýñT“¾[ç?¢ƒ—‘uФòß9ýñT“¾[ç?¢¨åä]Câ©'|·ÎEŽõU%‘•n©tÔ-©{‰ÈkŒ²3àda€öÒ´4½ãåjÏ·â+e^>V¬ûwþ"±Pd•ä¯Ey+µÈÌ\]†Z;ýaCüF)>,Ñh›Ê¾Ë u]-Æ–(ù¥`seŽræ<5ã- FÝ®Éý¬rZî…ºÉc©³Þ!¥§©šˆE4QÏ»fö€ZN×4ò88Î29äd/Z,7êM/>µ´iØôÔ²ï ¼K3j§.¦’¦œLYyC¤Î¼öŒãÕ.ZÕVù(i-Vë\9¯¨“3ön/{ˆóÚÜ àãÆSµt¿ ­Ú–;-®)íì°Ó´Îa&†ÄçfBâZÎÇv ƒ—eª!é)è$¶WTT\xpðúµ7ÎëvåLÚ9óíìV7@÷Jû»Y^íSõzû}’®ª–]wXèêœÇaÀƒ‡pAJ¯[sc).TÑÚíÍesÚæ¸Æç>”5ÅÁ±9Î% ç$’ÉùÕ¿îC¡¤ºk ûeÂTQÕÂ`¨‰ÿ³$o‚¡®iþ‚ Hë’îµö}9IWnŸ4—»M+±®ÌSÜiᕸ *9ÜöŒä`€T>šékÖ¾­Ó"Ûl¦m%Lð9’Ý€¸Ä\æÆ>%ä ¯kÜH{IŒª.bަƒß-W©o4飞’ß]4äŒæ79̉²ÊX@#ˆ÷sœ‘•–ݵu.¡¬¿^«ºDÕ445D`¥–V=sŒJFÙ\÷5 òj:¦Ë&¬Õ6»U+ìN‚òeáK}Цµ¼8Ý&j)ZÐ`cG”ü5ÛIžԗ½]MÓ›°Úhí“Ùk-µ5‚¢µÑI˜ê(ØéË£dÞKw´<ÈíÅ›]Ÿ¦´TV ÚsC¨¯ÆÕI¸RZ4]Rœ@hÄbW5 ù-{ÜÖà` fßtÜW=Eg¿Gt¸[«mbXšê^lðJè,2 ï!Æò[µÃœWZ U_,6©ÍFšú~Mis·ºà.8œIQzž(ÞØ8x1‰ek 2v¤ œ·tÙdøoï _b4âô,…¦û¹u“/p¢Û¸ÅÅòwoÝ+nÞkqøjø9ïX­êÞýû÷»{wñýñ÷ÃnvãgÉÆ3³–så/œ**[Ûë­úŠýCE-a®šÕÑ Y&s÷½Ù1™Zü¹Íl®%Ù'!Ò…ïWZoº.—KQÛ*›s»ÍMWmk©Û(m L­s`”µ¹ˆ¼¸AÁkÜ[ñÕ=!WÚ+/óÑéÆ×XôÎÏ~ë]]–,ÂÉßÁ‹aì†F=Ù{;p7¶-c¦âÔpÛÿö¥ÂÕWm«ë”u”<.,2p¤ˆ%cØAŽYCškéÁQ:£»]îé_U-ÚñIGtáûín¦š1MpØÐÑÅÜÂñ–5¬w ÌÜÖ€rE_zG¼Ûnz®Fiç°iJˆÙs¸žÙLF–™<2cdÙsKÛÐA$í~´¿G¦´ì÷gRËXöÉ <ñ¸5ÓO4¬†(òy ÒHÁ“Ùœ­)½ÍwÕšÚ®ót¼ÑÚo7hmôõuk3(i#"@Zç°#•Ž s €ÁËv­óSÙ(uŽ¢Ïqˆ'ÚwÄòÉ#{ÉáØæ½­p?1hA¯\µ^£µÚ(YpÒô¿Ü®BßACÓ}<Îá:bó9ˆ9¬lqÊOÅ“–² ‹¨éðÈhhaÒQ˨%Ô°ÔЛl0J(¤¬‰¸y|f&±ß°‡Ÿ$–í3uZ!•–(¨+õ5þ®ºž´WRÝd’UO0nÀXˆ …Í-1CÝK‰KV‚µÐ>Ù;«îU•´7i/UÔHÃ-]Kée¦.—kp"—¬ c1ÈCYªé3TQÛµ³BÒÇ•‘;¹—­Á­l,¨s©¾$± Œys8+#Sô‘}´Ï¬j©tt5–]#( ·]Drˤ†ªC \"æ²^msØI!»%ÏEZ®}ck𢵰êî'_sÐè÷ÑÅHxYnÅÂÓåyDžÌ¹è«UÂϬmsTV¶]ÄëîcÚú8© -Àø¸Z| ï(“Ù€>ƒXߣ¾>Ó~Òl¡¨šÕQt·²šæÉÝ; tM’)7¶6E(3Åüç3Ê>_%¬AÓ]'VÔ»àÓuõ–keî8lš•í’:`7Å3„M0<—°%ÀåØ'i }ÕBÓ©+ EÌÔ¹®´WYß$ÚÇÁVa2çpwÄ0Æ]ÈòÆ·7DÖê¸kc»jKt5VË5Ó´CKSÃßÃlpµ¡ã„Ü8‚Oó·``>¯éágª¬f²ÓqÙ¡ŠÉW{…ôÕýmΧ¦1ñ›#xl ‘¼hù4½§'ä£,÷=Iqé·Nü"ÓpY\4½ÖX7´SmË^xlÛ#vÀno”0ãϵûJÚo—Xëîl’pÛ]e©ôåÃ…,N€Ê1œÿÙØäçväb'Lè,Úž›PÏ©u æ²–Ý-¶œ\g‰ÌŽ  È‘´— |·â Ü]äà>½]/M·>híÓ”¶‹}K^k\'ˆÊúÀdˆ<§9ð†™kckÁ%î`øé^«îõ– ë4ãhl𛼕­®âË."|ìãE°·ÃÞݯf Ø¥ÓqnÝWOt¸RÔ:‘”ut±ðŒqÆetB@æ‚ÇO#c™’pr9(9ÑÝ®Ét ªŠíx«¤µq=é·Tͦ·oiiám`yÃæ7ˆçíkˆ!5ì;N:*ÞlV[­® umÀ ê×0Ã4u4M5 ‚ö™blƒ‡å ™åG´ãén5 ÖÝg¢Òº.:ÝÚR×{q¯¿¼ÛT& €Êèžùdå»öòK‹OíXu6JYõU£|“ ºš(˜á–NøòF3¸fc dŒFh­jÒ|{ª+eàY-öFõ‡µÙ‚ÂqÚÑåž;÷ÆàyHzD¯¼Åm~Ó"ïÖlt×Ú†Ô× S=@wŒò¾WpåòNÖœÞ2&„¾ü÷,Xu7Uë~ôhŠzî¯ÄÙÅáPµû7`íÎÜgì*F>Œm”¶Ë= ªÿµ{Ûg†Êù©'ˆIYIpÆJ]qŒ1À½Ø#*WàU«Ágƒž±[ïO¼žòq··¬p8Û¶íß·žvã?69 ‹ªÕÚ¶­¶¡£íþÿ\ÄõÔo¼¸E$"-òM(€ì“|Ìg dƒ¿ÇÊ.kîtvH,q•7»Ÿ]âQV×ux©:œÂ òµ’¶g5ƒkíÙä2§õn–†ÿSC]Úçf¹PqM]otbV²@Þ$dJDZÍvÆ O64ŒµQ¢ÛhÓ¶Q¥éõ•ö™&luºÊfÖ¹“’ùÜãV82q$ sñÏÊn @!—¡zAŸRWZ(ª¬¶O_ áòÆê¡!§u¾º*BÆ€âó.샆íÇ•œ¨AÓ ªß@顳PÖ×Üî´P Åé”4¡”O§|ŽÌ<ÜCcXã周ÒåëEtgSK£¬L«½^,—ê n ª*˜¦™Œ­©uDHéc{%çÃ˶äº0A b‹£Km¾Éo µßoÔ5–êŠÉ鮌ž9*Ç[ÓNÇ#s$kžáÉì?°ÃÃ(&z<Õ4zÏGÑj:ÆÃRdaÌÙ˜މá²7É{w±Øpäá‚;V­ zG¼ßéô¥}ëHÇf·êªpûd±ÜúÌ‚^®ê€ÉYÃ`htl‘Íps²å“…½Ù( ²× «ëkÝâêšÉå—â§0«î†ú7›Oi]%þéy©¸Y­0²;mUDRSÛê]dÆ3Aq‘€¹ï kˆnAý°t‘¨®š.Á¨£))çÔýY¶:/~ +¥‚IÞg˜ØãsÁoÎÍiòVpé »ÞÞ¬tã~{õï'½xp:ÏWë;¸û3Âêÿ»‡»¶ç’“v‚µ·CØ4­=}Ê•š~*v[+â‘‚ªA ²d°°¸°¹®…¤9Ãn øŽŽí~ñu}oá゙üq£ë½onÎ6vpóÃø½»6lòváf·é-ÚBŠÉO|¤°Úïwn°[ ÎþÊZÛ h{ºË£%ÙßÖˆ÷ÜÃv»õ1Ò/§/–ê+Wòj˜ê«å´ÖúwÓÉÂ{:Óc‘®.~î†8ä-®¿E²®ŠÛÿêKô7kwCxŽHMYdkƒ¢19®!¾OhØÜ´/íËGÏWf¤·G¬5-+àl­–ª9 |µMåâA$NŒÿFÖ7häÝ£’SÒ]Ušùj´‹=®)k¨"«Ýr½2‘’>G9½^™ûÉæy·sûÊå¯úl²i-MtµNûŽÊ"7&Ö_b¥¬vö6LSS9¤ÎDoiææd­ÜA `½tml¹iêM7êùAb‚ݲ[m<ñ˜ji£ZÇ™#sÚvò/ÌqÉä1›wÑQV^ª®”Šýdu~Ãp†Ý4Mެµ¡Î/Îc¶5­Ý˜ì5¼ùu!ÍI¯Ñ±Ûm‘ðå†=Õ—aMUR$c^d¦Ñ‘;Cˆ±à@Ìþ¼ÔÓ6sdVç c¤¸Ü™CK òÌàv· %®9p匑‹~ÑP^¯Ð\k¯×§QÃWhµ‰"ê¦x ]ùÆenÆ»k^Ö’AÉÎ^´Òôº¢’Š)««­õúÆÖÑÕјøÌönF=ŽòdxÚG<ö€@i6Ζå¼Yí²Øl¶ËÍÆ¯P>ÂöQ^Ù-em•|VT¶2$cŸ 8eÃisv™6ô…sê2QI¦a·Ácm¹·Ó:sJ*÷õŽ<>®w“ÃÝÈ·i+6ÅÑÕ²×] {®÷«…dwÇ_=dѹÒTº€Ðí¬g ’ñŒ4¬‹®‚µ×>ç;kîTuµ×hïÕÓÈÁ-%K)b¦‹s pb‹¯{óÈ€'¡Ú«eç¤)îÖÖ[kN¦cf§düf4¶×@ܵû[¹®8ÖœBˆè{Ušš‹†—²Û|´Z’öûÅKåáEB×Ý*Ýs´™%pÁ ¼Üæå¡Û¾‡ÒtÚR;¯çs¹Ïv¯7 ºŠùù1†(Ž65 7l-;@À$€0í}Y­wZ{µ¶¦áK_e]D³Ç#ªeMDµ‚Q·ˆI3‹9nn9;%ÅÁS¾éî:KÔ4óSE_hèú©ÍTú™#^¦pk¥•#†p^în<Ï2¬Þ”/zºÓ}ÑtºZŽÙTÛÞjj¸ëk]NÙChjel{›¥­ÌEåÀ ln ^âÕ¿¢ûºŠ†*Ë›¢£¡²QF]#7ZªQNO‘ûN{ˆÌG솞jsX鸵6ÿý©pµUÛjúåe ‹ œ)"$ Xöc–FæŸÚúpPWNÕWÍ)¨zR¼Sé¨.Keâ:ÛK®<Ym4A |7qÖ4¸‡9€äIÎ2õÿM–M%©®–©ßbÙDFäÚËìTµŽÞÆÉŠjg4™Èí<ÜÌ“µ»ˆ!n7=j¸Yõ®jŠÖë¸}Ì{C£ßG!áe¸ O”å{0Î¬½U](5úÈêý†á ºh›YkCœ_œÇlk[º71Økyò5ýOÒEöÓ>±ª¥ÑÐÖYtŒ \*ÝuË,b’© 1pˆsšÉyµÏ`8q$†ÍéýS{ŸVC§µ›†Ñ-e¾k… ¡¸u’øâ’&HÉG ¢9g‹“KÚrpîK&碭W >±µÍQZØuw¯¹ht{èâ¤<,·âáiòƒ¼¢Of“©²RϪ¨5ä˜UÐÐÔÑDÀG ²wÀ÷’1ÀÓ3 `» ä`$Ñqg»cùY¡ÿSÇüyÕ¯?vÇò³Cþ§øóª1oxùZ³íßøŠÅYW•«>Ýÿˆ¬TD@DD%y+Ñ^Jír3 §äªO°gá )bÚ~J¤û~²—/kB"(ˆ€ˆˆˆ€ˆˆ {Fk E£«%¬Ó•í¢žV†½æž)N{8v3Ìc´¨Aexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TAexwé[ëWÝôÞ­<;ô­õ«îúoV«TA9­5n ÖWH®z’áתâ€@É81LjÜà0ÆÚçsÆy¨4D½ãåjÏ·â+e^>V¬ûwþ"±Pd•ä¯Ey+µÈÌX6Ÿ’©>ÁŸ„,¥‹iù*“ìøBÊ\l½­ˆ """ """ """ """ """ """ """ """ "+µÞæpÓµ×½.ùTÞ©$ŠìñjÖýù¥¼îoTž-Zß¿4·Íê”Ø¤Ñ]ž-Zß¿4·Íê“Å«[÷æ–ó¹½RlRh®Ï­oßš[ÎæõIâÕ­ûóKyÜÞ©6)4Wg‹V·ïÍ-çsz¤ñjÖýù¥¼îoT›š+³Å«[÷æ–ó¹½Rxµk~üÒÞw7ªMŠMÙâÕ­ûóKyÜÞ©Ýÿˆ¬TD@DD%y+Ñ^Jír3 §äªO°gá )bÚ~J¤û~²—/kB"(ˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆ ôNáýøÿìÿÈ/ÎÅú'pþüöärXª¼ð5}»OõmÝvßWYÆßœ )Ù·n9îëÎF6vò޽k[UŽñv¦½8QPÛhè*_XKž ªê'ŒÚÖ’0è[åsý¾x Éõª­7™/Ö½E`ê×PAQJêjÙSC9‰ÎøÆµÅŽ‚2× dcžV—¯¬Ú‹ÞK•úäëT‹ÊÁGMOß5< †ç£Þ÷5Ž~_;Éò[Ë}+#y£ÖzrªÓ_tÝýø*©¥§– ŒÑÈÖ¼d·Éò¾l¨+6½·VêÍDç\&ŠÏm¶[žb©¢’ b¨šj¶¸ÞÆÊ\ðÈ[ƒœ·hò¹üë4Ž¢¼Å{¹]$µPÝ«}ïêSK$ôñõ)ÝQîcíò9ÁØhÃpp¾3é­w]W©®²ÕYíU÷:}-#(jåvÆÓÍ;åk¥1µÃ{f-5¹nã–‚â¤/%ب,fçKαÑܨè'¥6Ú¨ê!3ÊÖº# ®s›–€òw8)kÆ´ÓÖ˜i$¯¨«ˆÕSõ–DÛ}CædX|‘µ…ñ4dd¼7‘Áh´=êˆýü«|”,¨«užj:yïu•á²PÖ>¡Ì|ó´¼5ùh­ÀÉò9eÒº¿F^®÷ú}Gq:²kdTU”Qê:ë|q¹{Ù-;A”fWŒ=ƒ 6ä‚úFñq»Ûmö ›ýU[l¦¥udµ íµ…åãnK†ÑžYÏÌ¢®´Ûm±\ Eq†yŒ4ím²¥ÒÔ¸48º(Ä{åfÓì½¼ùñ½iyª:!­Ñvþ«O4– -tþSø1¸Ó˜›ÍÛŸ°s;¤¬^‘ôeöáhºÛ\]Qmdðõo}ª­Í–9¸dü}7–Ò MÀ!Í œŒà‚¥jõ–œ¦´PÝ {秸)KM-D³ !±F×<íÁÝäù8ç…æñ­ôͦ*Ik+å-ª§ëQð)&œˆ9|kÄlqŽ>cÊvô¨ #{²SX+¬tö£p¶²º)¨êkê «™³=¡í’S |m;œÓ»/äÜ€3.Ö}]ñ×Û0±TV×Za ®Ž®YcŠ'Äé^ÙcÚÇ—·3I–¹¾PA-Q¬4ô7êk¬š¢áS5EKI4àÃ+ÜÆJ]KẔÙy 7‘$ ‚¯×¶êÝ_¥ìÖ+”¯ë—iàªÍŠ¢èêžî¯f׆ËY1¸à€ Á çh#.šº‡6¢9èáÓÖËD9â¹Ô®©Üç `&f0O0îÌ ÂXt†¬¢«Ñ–ê—XÍ—JÎþñÍ!©ªˆROO,, c‡»†çs9 $Y+†ºRÿî?ü/á1w*á®”¿Ã»ÿ øLWµ”D[AV÷•«>Ýÿˆ¬U•xùZ³íßøŠÅ@DDDA’W’½ä®×#1`Ú~J¤û~²–-§äªO°gá )q²ö´""€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€¯+Ÿº6ùW_5D6vÓF÷y6¡® €dÇ’§ÿ.ÅF¢h]>0š‡üÃþ4~©0š‡üÃþ4~©U:¦íïåú¦éÕú¿oÅïÝ·kC{p>¡F"hPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD½ãåjÏ·â+e^>V¬ûwþ"±Pd•ä¯Ey+µÈÌX6Ÿ’©>ÁŸ„,¥‹iù*“ìøBÊ\l½­ˆ """ """ """ """ """ "—²é}M{¥u]›NÝîTìyÒÒQI3À´–‚3‚?¤,ïÚ÷êF¥ôTÿ•´‹eð}¯~¤j_EOùSÁö½ú‘©}?åA­"Ù|kß©—ÑSþTð}¯~¤j_EOùPkH¶_Ú÷êF¥ôTÿ•<kß©—ÑSþTÒ-—Áö½ú‘©}?åOÚ÷êF¥ôTÿ•´‹eð}¯~¤j_EOùSÁö½ú‘©}?åA­"—½i}Md¥m]çNÝí´ïx²ÕÑI È$43€N? ¨„D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA[Þ>V¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅƒiù*“ìøBÊX¶Ÿ’©>ÁŸ„,¥ÆËÚЈŠ" """ """ """ """ ""°÷!9ÌèžàXâÓïì¼ÁÇÿ± µ/7ˆlöz۽ƲH(¨i䩨—ÊvÈØÒç; É8œJª}È¿É5Ãý{/ð![¿KÕ5½jÚ::yjjg²VE 10½ò=Ð<5­hæI$jÅõYwe¹\b·GYr¤¬Ÿ<núš'M’'c78nN+bãÍþZOöН/÷_†Z­–[=ì®´•“VWZ碎š8&l®ÇŒsœðÓ öÎp2 cÑü ¨.4Ö …î²ù\ê§¶"ÚºŠv|’EŽ$ %­iÅÀŽg* ‡7ùi?Ú)Ç›ü´ŸíBê‹} zOQ>ϧ.Vý/Qq°²žÚ(ä¢|Ó‹„}aÐÂð×G¹®… á¹sIIÞº0¢¥§½ß§±Yj¬ºrVS ZY¨ŸF Kx¼y Ã\Æ–˜vÅŽ<ûIVoòÒ´S7ùi?Ú*¯“IÍQué÷EldzŽZ‡2Ç_%;@-w”9çoèžš¦‹¢Í%GYO-5LJ8¦†V>7¶5Í<ÁAìDUë馒‚Û’Èö6V9­s‰‘.HÓÿØ.q]îºþô·ý¤_ùL¹Õnx”[E-.—¦Ñöû­ÆÝxªª©¬©¦x‚å,&Âàà <ÄÀc=­ÏÏ««Á.¢ƒ£ël:wRÓÛ&}Æ®jˆ™‚兔쌽®•§¶9pÎ9ö82Õšzžçw†ß¦©ê)ª£¤’Jú;¥tQ¾šXä=›älM8cXòÈ˳û'QØnRXç½FÚWQA3`‘²-áî>HîÞs‚FÈk`8–¼MYdÕt7Ú«ÎåRãp®m<ÑKdtÒFçDç0îh cLc’‘¸\,úrõ`¢·TÇq¶Ñ\t¨|nâæ@XÃóe±1¹3žð¦ïð5ûŽ–¾[è䪪¤­‡v2¦'ËH‰\_2”2ûÓèÍC<s²šE[–•ﯧh˜[µ¤¼eà´‚ÁåÈ€¶ZšŠ*:k­x¢Ñôìž–x¡©¥®¨¨¨œÈÒш]RK ÝœÈÑ·Á ©iä’Ñ£iᬠ{ͽÑme|'ƒ#ª¦ 0ïŠòeŒ’ý¸çžmv+U¬O°O$FèåÅc† \#é[%³LOr¿i‹3¢§¡7hã-©ë‘ÈÙXùž8Ÿµ†¸YÃÈqtxÆça|:I1»¤A,ÓÏ ×æŠZy™,ocÞ^ÒÒAäáË<»!l¶Hâ‡Qôg<· ["¦do¨q¸ÁˆkfÜO/È<7´áØ$£.¿[Fµ¬hìt¦§µÅWP/5g‚ðI-cÃAg óÜÌmÜpµÛ´’RNúwÉ2`¨Žv€y>2Z{~cÈòí v£ššÙyèÖ¾ª¶‹HØRbªŽW@t³íc‰aÙ#i €¿Sèi÷‹UUªHÙU-†@Kz­t5 cé1=ÀnÍ6˜7-#mºÛ#,¨}]M5d•U±EXØ]kŸ°4‘)KœNÂGÐ"¯vym-„O]m¨’]ßIVÊ€cÎa-ÉÀÎyË2wôegª‘ÇßZÉ_jãt­kã§k胷€LRs#æã77~ÆXnï¿h_ï‹K„1†—I8Ú ·gçœ/íÆÁu¡ª¥¦š™²>¬í¦4Ó2vLsŒ1ñ—5Ç8<Ößq¢µM¬vÜj-5ŽmŠŒR°ÜÙÕ¥©Žž“Fü7’ÿ9¹-o<8÷¸ºš ~•t5ZzÇ-%öWNmµ½oªoÅ“ºW¹øá¸ù$³É“<÷ñZmãM^-4-®¬§‡ªº^ – ˜§kdÁ;cs¶»§‘XÚ»c)(¡2ÌàHI$òI'šÛu£(¢°¼fÕK]-s\`´\8ôÕ, Ç:0÷ÜÒ@hÈå#¼‘…¤&ƒÿjÛæ¨ŠšK…§‚i]µŒx–9s¿š#,Éä7sÀÉZ–ëhϲiˆõfŸ·êi¾ñVÚx碬‰áûœK$nöÒæ’?³–r!,ÖKÙ²¾Ž(„PàI4õÁ Î|Žkrpp3“‚¶})GïV´ÒPUê Í•sÄ+£4ÔlkØç;‹¿‡½ÍŒäüÖ ’@4´žøiŸx"®·A_Cršg¶jØ£Šv½‘³-”»†í¦';˜“-Ï57Dm.—¾ÔÞ'´CCšø tæ+ç±­ÜK2~3Éò€fIÆBùÝôýÒÕK]\PycÁUí;\csƒ]˜à­¾Ï$Ôt40\íæKn­¤’®JÈá‰óIHcXùÐì:xãæ’<‘•oŒ;£KÁ54mqºQÈÈ]UfsYC^æÆ]¼€e˜9ÿØv£à­÷¨uÓGÎ…Ö#ãð±»wn9îÛŒsì_ÛF”¿]©£¨ ¢d¢mÜÍDl–}¼78>LG’0Vù%Ö×Q©äÕ0Û´„†cTÚ©kjRÏœ0Ó \ñû8 ?HjŽÒ®¢’Ïc’áp´¾š”<¾¤Võ[…«=ßÁ›·ˆÜ1ÜÞG.Õ;Ý*¹E3i–½šb÷=ÒŠš‘ý_¬ÒJæ‰j°ó·†$í<Îåô¨e´t†œ÷5Å}³Au¤»=O»ke¨Ãk‹Nq üëSé¿¡vtq¥)︺¢Y룦lbMíÚèåq'Èná§´®´è®VSèdSîûdv×4ƒƒ#ˆ?÷AþÕTû·äd½[²=ùˆvý™Ñ\zˆŠ ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆ+{ÇÊÕŸnÿÄV*ʼ|­YöïüEb """ É+É^ŠòWk‘˜°m?%R}ƒ?YKÓòU'Ø3ð…”¸Ù{Z@DDD@DDD@DDD@DDD@DDDA{tÒ~šÑ]ÔÚ®S8×Íw’ E±øbhqpi%¤cúqË;·‡í'ôÕ.SE,ÚíÕž´ŸÑü_Tž´ŸÑü_T¹Më º†ëÓf†ºÒ²š¾4L¨†¥­ß3q$2¶XÝ‘ì{qØqƒ‘²ü?i?£ø¾©rš'XmÕž´ŸÑü_Tž´ŸÑü_T¹M¬6êÏÚOèþ/ªOÚOèþ/ª\¦‰Öug‡í'ôÕ'‡í'ôÕ.SDë ­Þž5ýZÛé}ì—㢕›£ÚÿÙNys@ípU"ÔAV÷•«>Ýÿˆ¬U•xùZ³íßøŠÅ@DDDA’W’½ä®×#1bØ 8¢ 5L™ð[½°ÈóärË\<|ÇÿU3ÄÓ½ßyô”^Π­?%R}ƒ?YK—µ¤ŸN÷}çÒQ{:q4ïwÞ}%³¨ÄPIñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìéÄÓ½ßyô”^ΣŸN÷}çÒQ{:q4ïwÞ}%³¨ÄA'ÄÓ½ßyô”^ΜM;Ý÷ŸIEìê1Iñ4ïwÞ}%³§N÷}çÒQ{:ŒD|M;Ý÷ŸIEìëçY5 Ñ˜¨mõ±Îdk¸Õ— Ùhkc`æH99ýž]¥`" ÞñòµgÛ¿ñв¯+V}»ÿX¨ˆ€ˆˆ2JòW¢¼•Úäf,OÉTŸ`ÏÂRÅ´ü•Iö ü!e.6^Ö„DPEº†®ãTÚZ(4¤óÌ’O æIäc¢›¯Ò—Ê+d·GÓA=%¢ié*á©dEÇy‰ÎÛ’qÏÖæÙYg¸>‚½‘²v±’|\Ì•¥¯`{ÂZàZ朂{T–Q†ˆŠ‚" "",ËE®¶íRêzØç1†I$¬‰‘´79ï!­ d‘Ìó¯íòÕ]e¹In¸ÄȪckæ²VHݯ`{Hs i®‘ùÔßð0‘JSéû¬úœé¦SÆ.¢¥Ô¼Ï¤‚Íîpnrùœœ…®ÁÚ¢Ÿƒ 4œhdãÆdÛòèð÷7kÇÌï'8úÓó¯Š,Ê;eee¾º¾‘¾ 2JœÌƹ­sà Üá¹Í´nÆBÃ@DDYQTÇm†âø±K<ÒC÷)ñ†9ã£Fsìç˰¬tD@E‘n¡«¸Õ6–ŠM)à|Às$“È9’y'_¥/”VÉn¦‚z(KDÓÒUÃRÈ‹Žó·$ãž9©¸!f^m•–{ƒè+Ù'k'ÅÌÉZZö±Áì%®®iÈ'µaªˆ€ˆ²*èªi`¤žx¶GY š¸ì>2yvyQ¼`óåôƒeæÙYg¸>‚½‘²v±’|\Ì•¥¯`{ÂZàZ朂{WÅ”û¨eªãB8r2>Æ;pqÜÎѳüÅÍúSc∳,–ÊËÍÖž×odrUÔ¿‡ 3"wÌÝÏ!¹=€g™ÀÈA†ˆˆ‹"’Цª ¹à‹|tp‰§;€ØÃ##Ÿo•#>@(1ÑEЦ‚vÁWGCÀn,’6ÈÃËékšqÚ3Ïš tD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA[Þ>V¬ûwþ"±VUãåjÏ·â+I^JôW’»\ŒÅƒiù*“ìøBÊX¶Ÿ’©>ÁŸ„,¥ÆËÚЈŠ" ""Ø,ßàUÿýóƤâc·«æMÿÙÄàn¾¶%gÔõºiø\xotFA+“–ãÌFA©D=)¯•TÔŠcE_vÂÍíÛ¿±¼7ùñó­Ö¾s¬¸OMSíÚfÝS Ì{úµ$`¸84H_ŽÃ³Ÿ,¯7kHW:AGSo‚:`ðó+iiãs‡ ç6-¡Ç™æry•ô«´ôUy†ðú(b­†ÀÇÓ¶–ðÚÝ¡¥ŒÃ\6ù8 ù 7°³wUUW×ôÏ¿òPÛ ¸PÜ¡…ކŠ(ã¯dÃâ á»i¿Íæ$óÉl©¨ªµæªÓl²ÚiíÐ £ l4q¶HŸsH×6@7º1äçn ¾ÅÒ tô²ÔÛi‹iĆGHÈì‚I‰¸Œç9iÈ9 ï·¤vj*Í@-Ôn¸Ö1쨑ðQ¹¯FÀ\2@ÉÜìçqÌÐùZiíÖí-h©Žé¦i*«Ù,Õëo–©ä _cqcpÌò!ÙwÑ…õŠžÍnº^ú©¡¦%ÔŽ¤¬®¶K=\HÜ÷ŶXË›¸þÞÂKc'çÊÇ´XºAµÓšz[u;áÞ^Øê[KPÖ8à4I¸5܇1ƒÈ} ëEjé&’¢ºvÓ6wW¸>­µN¦¨dÎç2Bæ’2pqË' Ök]GÂÔõ-÷º–ߘáw–MðœÄÃÄaÿùÞÌ̳Í[lzÍ-¾ÝQ-Æ'¨š®Ž:Ù™ñˆ†ðC@ Ëpï/·±}.Z?[Ükd­­ tÓÊAsÍDC°`° gZ,}!ZéM--¾A¼ÈØêK;Xò.`“vÇrÛƒÈ} ZúFU4ÂÁQ¬›l¥¢Ž7ÙhêÄ5‘T]$Ôn1ük]ɦW7çkIÉh"¿Ž¦Hë›XÖÂdl‚P×BÇGœç„m-ÿÝ#åŒ-æÙiéß5Âh¨)§’㎶êÈé*Œ¸vþ|]ßÎÇ¥­'°b".µ„²²(¬Î’G¸5­lñ’â{¹•1š=uÖª³§úz9¢ lTú´:bâ¯SØÀçÿþDäóíZí=t7½=¨"–×m§e¾’:ª7SÒ²9"=f¶™Ý -”þÙqÈbq©Ee5`¬¦ãÓN*Xþ£]0 _ä|cÆã‡?$Aæ°)/÷*Hî‘Óõ62êÃ[zŒ$—nÚÀYñcv Û‚Ö‘û-ĘÕl´í·¾»GÔVÛ¢|o²Lùú½\ £š­ŒšF0 `Žy<ÜÖ“Íak±¾×j©àYfÞùÚ.V¸Ä1ÔÃòc6=™ÎvŒ‰Ñ“ÍU|ŽKT°ÕC–¨]᥊727gs\ZÐ^çg~r^ãüçgóz¸]ÌB¶HvB ()ã‚6g´†FÖ´“Œœf7{D΃©m»UT¾š–v‘ÍÜÂî»K‚GσƒƒÈã!fÇMK¨áÒ•°QÑK_x–ÝU-%; k£oV!ÅŒ¡ÃŽî` àek6»Í}²ŽáGHêq  H’–)K˜pö’Þ`´ƒ–´ö´ýšõp–ÅMd{éÅ,ΞÚhÛ#^ïÚ&@Ýç8›ì·üVáÖïca£­ŽùQtµUYm´TÐÑÔÏ‘‘ËJècsÚ €o~KCòìîúp¥#mìn¥¢·Z' ²ñ&·ÕRp+Ù'qªdÅ™‘¹øÐÐürÛŽkS¸ê›åÂŽZZª¸Ë&À즉’σŸŒ‘­“˜Ê'˜ÊþɪïÒ[n}ciÅ0V‹Œ!>.Þ&ÌrÛ»åØh˜ºÚŒlðà ±í7:øÉžÛO3±Ã¥9Üö^|¬ç£8k@Ö*ýê÷²‡ªuÞ¿ñw‹·…û_ÃÇ?ÙíÏÏØ²ìº–óg¦êöú˜£`ÊÂúhätR|n{IØ æÒ!ô‰Wt¯«¶PÛ*'ßIAÄêÑìhÙ½ÛÌ œŸ¤•dÐÃDE¡°Y¿À«ÿûçIÄÇoWÌ›ÿ³‰ÀþÜ(ŠS^)+:©©Æ6оí…›Û·~9cxn3óãçSJÏ©ê3tÓð¸ðÞ茂V7'-!ǘ Œ‚9SwkHW:AGSo‚:`ðó+iiãs‡ ç6-¡Ç™æry•Ÿäz¯†œßë.ÓETûv™·Tãsþ­I.Î ã°ìçË*.ª¯¯éŸä¡·Ap¡¹C  QÇ;^ɇÄÃvÓ›ÌI‡g’–«´ôUy†ðú(b­†ÀÇÓ¶–ðÚÝ¡¥ŒÃ\6ù8 ù 7°¾uö.k§¥–¦ÛL[Hþ$02:F@×dLMÄg8ËN@ÁÈREg^¦¢ª×š«M²Ëi§·@.Ž°ÑÆÙ"|Í#\ÙÞèÇ“¸8 ,;M=ºÝ¥­1Ý4Í%U{%š ÝmòÕ<+ã n ‘¬nžD;.ú0¾±ÛzGf¢¬ÔÝFëcʉšðñ‡ùlÃ!Ä ÎÎwãÚ,] ÚéÍ=-ºðï/lu-¥¨kp š$ÜîC˜Áä>…:Ý sZRÑQêJ˜møêűÈÀØäcFøÚò%ûq .-ÁùÔÞ¨½Ö·Iiz ³…-™Ís¶œÈ¬©hÛ&Íí8hÉrãÌ’~5Ú3Z×VMYYA$õ<¾IUsœ{I;”…5›¤Z{G½PÑDÚnái=XÊÈÞI{!òÚÓ¹ÙhpqúJÖ¼"ºy§4ìö»l´uôvŠZ§KJÇÊñ%, ÜÙ/aÃNyä­FG'G2ø)Ì]èÄrð[Åh’íßŧ†Ã·8ÈÈ%lr[zG~¢£ÔÝFÛÊyZÀÁ†yl%£¤Œ­Æ6Œc:Á¯j®µûÕFÚJê‘S; #Ogik‡”À2àÒp9Ìšš­´o³ß#·Û­RÓlÁÕ:­ÂÕ‰XßË¥íá».w7˱k=(úgýoIüf­†ïmé*íK%=}3%mã½½Y’Ï·˜âHÜ:L”O0 À²iMqfºÓÝ-öØã«¦½ôò†;æv×’ÜŽÐqÈàŽ`+&¦‡ÊžºÞžÔKk¶Ó²ßIU©éY‘³ [L€nÊl¸ä¾µu±Øê-–ª[-¶¶šj:YçãÒ2Ij4m{€ìÁq`Ø[¿NVE%ƒ_RGtŽžÕFÆ]Xc«o‚ÒíÛX÷1»mÁkHý–ãínµt‘o£Š––’0Èr {ú³åƒ'?#²øù’|’9œ¦‡ÚŽŽÛhžão¤}¦9á½TSESx¡ãSÖCÐØÙ!c›†IqòyHß(`,k=mE¢«¤SÚè¨LtÄõ:ŠxªÅ9m| áfFàÐâ>‚C]Œµ¤mŽ‘­Tn£¤¢„Óºn?qK;[&ÞÞ&í®ÀPÁäÂß§uý ¢¾¾zæÔ‡ÓÎÙƒœw¶BZï(Ì`::ºªJʹ*¦l-’C—adL÷1€4` ~ÔuÓ_u¥’Á\Ûlu°Z,°Ûiâ‘‚Jj}ÄHÖ7 à 0Qw]#­î•òWW[ø³É€çq¡hÀ  :¢ÏÒ4ö‘l’Ž>¯ÃŽ"[Õ›+ØÌlc¤[šÝ­À. m@VÍŒ::Øï•KUU–ÛEM Lðp)´®†7= È÷ä´0ï.Îï§ Y«÷«ÞÊ©×zÿÆuÞ.Þí|_ÿg·??bÝ.6®’.rÒÕRFY6ïgVd³àçã$n'0”O1•…W¥µÝ]²†ÙQA¾’ƒ‰Õ£âÀ6ovçs''é%Yô4Ä[7ÀYÝ?¼Eù“à¬îŸÞ"üË[F²‹fø«;§÷ˆ¿2|ÕÓûÄ_™65”[7ÀYÝ?¼Eù“à¬îŸÞ"üɱ¬¢Ù¾êÎéýâ/ÌŸugtþñæMeÍðVwOï~dø«;§÷ˆ¿2lk(¶o€:³ºx‹ó'ÀYÝ?¼Eù“cYE³|ÕÓûÄ_™>êÎéýâ/Ì›Ê-›à¬îŸÞ"üÉðVwOï~dØÖQlßugtþñæO€:³ºx‹ó&Ʋ‹fø«;§÷ˆ¿2|ÕÓûÄ_™65”[7ÀYÝ?¼Eù“à¬îŸÞ"üɱ¬¢Ù¾êÎéýâ/ÌŸugtþñæMeÍðVwOï~dø«;§÷ˆ¿2lk(¶ˆº>ÖÊÈ¢³:IàÖµ³ÆK‰ìnæV®€ˆˆˆ€ˆˆˆ‚·¼|­YöïüEb¬«ÇÊÕŸnÿÄV*" "" ’¼•è¯%v¹‹ÓòU'Ø3ð…”±m?%R}ƒ?YK—µ¡D@DDÔ>á¿î·OêÍÿN¹yu¸oû­Óú³Ó ½tþ··)S~ÕwKEš¯7sf¨¨m<$S×OO•#±¼² O>g8r·]E§í6ˆï[í®‚Û.ÞeM\qÂýÃ-ÃÜCNGg>j¶¡Óz’ÇWh¾;LÉzê7MDçÛ¡¨€L]q|ÐT°ÈöÆHŒ`‚ðàÙÝó‚Õü´imE§it•Øé¶Ým7^5ž’¢ê>»P&‹‚é\ÈÝÁ`0þÓ|—»nG"%ëUék$T’Þu-šÛn:«ªë¢„Oœcas†îÑÙžÕªëMwp±j+L·õ:6éç‰fäÚûœ´³—Àa±ÆÓó;$î”Fº³ë:›¥(³Xª¨¨*,ÒÈË8µïŽPé7APú¸Ýšf‡7o Ž92y<ÀP”=jš1n·ÝìÍæÅ£(ëb–xž% ÂI«˜ï(‡FìžÐüá»$ý£Sé»Å²¢éhÔ6›…1pžª–²9bˆ´eÛžÒCp9œžKùAª4ÍÂÇ5öƒQZ*í0nâ×C[éãÛû[¤hÇÏ“ÉhºóF]îw½WQm¶ÓÉM[n±º(Ÿ#t´uµ3O¾ñ£.pÁ$4ã³LÝ5:¾ïqÑõ¶ø®‘ÛYOieu;*ß-$¯“¬ïcŸ“.Œ49Ä8@Ðâä-ë¥^­1XêjµmÑ^ª¥¦¥¬eÆ® q>G½Ï/`ÚÖ3‡Ë?´¦µ¬QOcdÆÉb’¾‰cÚ \ÓU ƒÚUÍ«\ÃCd½WØn:›^¨’àÚG>‚;”ôŽ·MJ3£{)0|ß3‡Åµ¼Ë†ƒÒ dí2û…OMWI4¼(Ÿ+ö¶¦"v±€¹Ç“Z =€”h÷zÝ+j­¤£®·Ùbš­Ûcß/éw“Èg–~ŸíXv׊~œ­Ô4°ÓÒÒ»K×Ìø©àdM{Å]phˆœã'ÉÌý!èê‰5V‹Ô52»ÉQ£j%w/ét$¬ {‹Sô×Ms·ÙïTttšb²žGÖÚ'£c^êª2Æ·{ÓÇrâ•ó8ÍÑ‘u¸oû­Óú³Ó®¥\µîþëtþ¬ßôë©P|+ÿ½ýŸù…ù€¿Oëÿ½ýŸù…ù€€ˆˆˆ€ˆˆˆ‚·¼|­YöïüEb¬«ÇÊÕŸnÿÄV*" "" ’¼•è¯%v¹‹ÓòU'Ø3ð…”±m?%R}ƒ?YK—µ¡D@DDÔ>á¿î·OêÍÿN¹yu¸oû­Óú³Ó êTD@DDD@ZßI_à}GúE/üÄkdZßI_à}GúE/üÄj_Дæ‹ùB£ýþ6(59¢þP¨ÿG?‹_ŸÈˆ¾ˆ""" """ "" “ÜëÒžŸèâ:çÞ)n•Î\#m,½»]ÃæK¤náö`ö«‡Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤Aؾ5z#¹µ›Cë“Æ¯Dw6¢óh}rã¤AØS{©ô<±–:ϨÀ?E4>¹qê"" """ "" ÞñòµgÛ¿ñв¯+V}»ÿX¨ˆ€ˆˆ2JòW¢¼•Úäf,OÉTŸ`ÏÂRÅ´ü•Iö ü!e.6^Ö„DPPû†ÿºÝ?«7ý:ååÔ>á¿î·OêÍÿNƒ©Qk}%õé¿ó­‘k}%õé¿ó©|#BSš/å ôsøØ Ôæ‹ùB£ýþ6,E~""ú ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆˆ€ˆˆ+{ÇÊÕŸnÿÄV*ʼ|­YöïüEb """ É+É^ŠòWk‘˜°m?%R}ƒ?YKÓòU'Ø3ð…”¸Ù{Z@DDD@]Cîþëtþ¬ßôë——Pû†ÿºÝ?«7ý:¥DDD@DD­ô•þÔ¤RÿÌF¶E­ô•þÔ¤RÿÌF¥ð Nh¿”*?ÑÏãbƒSš/å ôsøØ±ùüˆ‹è‚" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ­ï+V}»ÿX«*ñòµgÛ¿ñŠ€ˆˆˆƒ$¯%z+É]®FbÁ´ü•Iö ü!e,[OÉTŸ`ÏÂRãeíhDEu¸oû­Óú³Ó®^]Cîþëtþ¬ßôè:•·ÒWøQþ‘Kÿ1ÙF®ù*õüÔJQZ©Íò…Gú9ülXWíi5žçMošš÷Q-Q €Ó€æÈãËhËÁÏôaa2zÉ:~µEU,Çf“¸’nØãYCžÂFyqô,H®DEôAV÷•«>Ýÿˆ¬U•xùZ³íßøŠÅ@DDDA’W’½ä®×#1`Ú~J¤û~²–-§äªO°gá )q²ö´""€ˆˆˆ€ºÜ<æ²K¡sƒF%æN?È.`R¶MI¨¬qI–ÿu¶G+·HÊ:É!=™!¤d ý.ãCþV?ö‚q¡ÿ+ûA~pøA׿]õ/¥güÉá^ýwÔ¾•Ÿó ýãCþV?ö‚q¡ÿ+ûA~pøA׿]õ/¥güÉá^ýwÔ¾•Ÿó ýãCþV?ö‚q¡ÿ+ûA~pøA׿]õ/¥güÉá^ýwÔ¾•Ÿó ýãCþV?ö‚†ÖO•Ö¾†™õóÁQOPÚh$²J#-i‘Ífâq¹Àgç óë½úï©}+?æO:÷ë¾¥ô¬ÿ™\6ÿ¯[+%Þ÷°’Ç{ïlËI?íŽ Ú¿š>“V\zXƒQÞ4um‚†šÁUC¾¦º’n$²TÒ½¡¢^f'ä!Ïšä:÷ë¾¥ô¬ÿ™< ëß®ú—Ò³þež«¶´ˆ‹H""" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ "" ÞñòµgÛ¿ñв¯+V}»ÿX¨ˆ€ˆˆ2JòQk‘˜°m?%R}ƒ?YH‹—µ¡D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD½ãåjÏ·â+ÿÙxymon-4.3.30/docs/editor-disksetup.jpg0000664000076400007640000023227511070452713020147 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀª"ÿÄ ÿÄj  !1QV“Ó"ATU”•²ÑÒ2357RSqu‚’£Ô#a¡¥BDWƒ–¢¤³Â$46rt‘±%Cbs„´ Áðdv…¦µÄ&8EceáãÿÄÿÄ: 1Q!2Ñ4ARSq’ða‘"B¡3ÁáCbr±ÂñÿÚ ?ééòå¦t„¦SÉI:¢"'ÄW1cvÌð·ùà ÂóUÿS†•AÝúWÅUN²°Ws×âÿÚ“ÞË6.X•ú$îuß-ó'ôˆîŒýϺ>ilæqDgªlSX¬©é/·!ÆÒÓªYGq !¦4ËQªÏÂúJlñ1RbQéÊŠˆ–2ÐìD¬Öµ-&¾íN)¤dRH”Ùß6ÒÊÆ"®*±S¤5VÞöÝÅlRZšL¶j†Â©ŒÉ2NdšMJtÔ‚5’¶º[Ä@6†í™áoó†¶g…¿ÎÒ’qv(ƒN«Àf±&¶óx¹V§Ef"eÂÓÆE¬40nk3"ëÙ™gdû”lzÆ7•‹H~¥.‘*F'rœ¹/· ékˆT÷¤~‘,›Œ¡ÜÉ"+[bR£M”i0ÛÛ¶g…¿ÎnÙžÿ8cÇ §†ËÉvS¶”)÷I$·LŠÆµ )¹ðžR"Û°ˆ¶ UŠ|Jµ&].{DôIl­‡ÂBˆÈËþF dwlÏ œ1j%YrÚS±jjÚ\[F¦ŸÌD´(д܅*J’eÞ22=¤5iO›^¤ÁÑä÷ÔíT¥.mÎ.|Š[§ÿž…°ŸéÕor,M®bùtˆ¯Â¨KÕ7T­7)4â„™¦ÔyÎ4έ2KV¦Ð„ÙÂ>ãmÌîConÙžÿ8a»fx[üáŒ>œÝS RêmJÝmˆËéU«Ö’ÐJ%äþ ï{w¯a‘vÌð·ùÜs¤&0†çßUdkYzJ÷1‘êXg&µÕfZn”ë±9”wØ“±ˆTJ=#³ˆçÕh´Jþ%‰U’Ö笿‘KÆLeVG ”›#J;¥(ÌÏi™a± YŒG‡ðÛ‘¢T S@‡ZjiòŽ8•dq×ê "QSMÑ•}ÂŒÕ݃znÙžÿ8c\ŨäʪVU¸ÐÞšáªRõ ‘® êQ'2ob?t’á2ûTeb~¦ZiN®ŠŽ\ç79$ìk‹¬Seœ•ܪæ“ïØÎÆGc/–äTéøV©@rµ*§ü_’ûÒ[dœ}ÆÊ16£6„–T¼âH’DFFW¹•ÀmýÛ3Âßç 7lÏ œ1`%vÌð·ùà Û3Âßç sv ¢.™‚´sXN”D¾ºA*³M’gQYª"%£PÝõ¦d— X»%k>ê×®¸ëÛ¯~úà,to.ñjɪÝZŒÙ²ëu¹?Ò/›._àÛh”6¾í™áoó†¶g…¿ÎÓÕ\Eˆ¬šÛx´¡‘âö(»Ï¹˜4½ ]I75‹jî_5‰ ؒآ¥úŽ6<>þ#c­*äb5¦•ݳ&I'ö‘¥E´Î%¢|U\F‹Û”fQœÃØI‡aÐõdnOJb%H’¥™\УNT¥³+ÉFjîRßvÌð·ùà Û3Âßç iÅxâÄUŸ©dN™T‰.¡½—D–Fƒaœ^v1Ÿé VÊ’5k ¯‡àÔ A6êu™i+^u:ëM6H¹dB[Jl‚23,Ù•´î£Ù`ÌnÙžÿ8a»fx[üá‹TR¨;¿Jøª©ÖVªîzü_ûR{ÙfÅË¿Dλå¾dþ‘ÑŸ¹÷F{vÌð·ùà Û3Âßç k1töðje9Ue5%c-éMÒÙ(ÙßN«-¸w7~Ù­Ý^ûGŽ-W7MëìNóÌ-r”TÓ†Á2q•VT$‘¨‘¬Î”™(”EÜ‘ÜÌ6*¼UX«“¢ûÍ"CÑ”¬ËMœeÕ4âlvàZWà;\®V1uú²Øv;OÔÔÓ’\6˜JßÊn¬’¥šRF}ÑåB•bï$Ï€ŒiÍTëÍC QÜ;ª¥ièζÓk~¤gQ”J6ÍÄ) KFetØÔg”̉ïÓ£):F´Q©Sª› ¾—ÛgôlïKî“ 46›%.2ƒ#;¯a‘¨Ë` ¿»fx[üá†í™áoó†5F Äué20}Nf )éÄúÝÓKÔ4”ÓìÂÝý¥$¿Ñ©Êó©WRËÜð x«‹ —£ºÍ_½U,NÓmÌŠ¸l4ÓF¸ÉJÛ4 ”J»6;¨ÒyŒÈ“°ˆ6Þí™áoó†¶g…¿ÎÓš6ÅxÒµU¡TgÇ©"ŸW7ŠSR•NDhÆM­iL}[§!KJHR\#;ŒÉl%Zr»?Q«õüA"«.­L‹)HTvZi“[d£ÈM Žç˜³f3+—rI-€';¶g…¿ÎnÙžÿ8bÀ×ÓdbF4¿[ë~•I¨f S5Ûº¤äLŸé ¹r0îk÷W¾[X¸o°6õe°ìvŸ©©§$¸m0•¿”ÝY%K4¤Œû£Ê…*ÅÞIŸ»»fx[üáC†jµèØÒS3Z‰EGîiñâ¾rZSe‡ÐêRN-´+Ý4Ò®IIÜŒ¶•ï«cŒboÐ$ÑꘒL*쌚ã‡Im¥²i5‘ã¤ãfj$¤·A¨¿HDw^T¨7ÔêñA•4ª‹í»Pq¢§2ÏXá4㦛—pÒÎçbîmÂdGêݳ<-þpÆ£§O®Í©á«íIDˆ˜µöTµÅ9+kz%¬âŒµ4•Ýj+®IJ²–agFxJ§à*G•uXš1”È»™†ÓIŒ§MÄjÒJ,«A6²Q¨³8V$ì ‹vÌð·ùà Û3Âßç X _ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÇžUeÈë&Üœþ±Df”†jU»ÅúϽÆ?Fÿëßö†çÿ켫ÿ£ïð „=ð1’PÖ²[ì8é™% tÎöï‘ñw¾›å/þ!d¿XÁí½!׈ò)ZÌÉ&jjæWཋþD:‚½“XÆ£S»¯ú,Ü6ýWÙ{ð_õÛh厯Üûñƒõ¹sîI9²ð_3w·êÇ\ÕjtÖê’Ûr¡ KË%%O$ŒŒ”{h…»Fo|gL‡¤Ú¥?vÈ7Ýj:)dœÖ$–ÕE5*ÈJF¥)YP’3; ÌÝèí¹¶àÂJ\QoM„Gÿ–-v>Ñïòyƒ?«ñ:1Ùxb;è~:èìºvE ÛJ“®Y8팸3¬‰JùJ"3¹J^ˆ‰È‰NÃQÓPB›š–˜a%%*#%%ËvFFw#½î?{h÷ù<ÁŸÕøv>Ñïòyƒ?«ñ:0K/¾Ô¯ÂçÓë ö¥xÎ>ŸXÄv>Ñïòyƒ?«ñ:0ì}£ßäóWât`12hŒ¹:¡&6’êP‘=õ<ó,7KÈfi$‘ª)©VBP‚5š*RFgaM¹–ÝAšIê[ ³L¦#’ˆ9RIGì‚Ixˆ¶ Ý´{üž`ÏêüNŒ;h÷ù<ÁŸÕøÚÌ Z’™UˆXr¢úS)v[Lº´¶¢2RÔFyLŒî\sb8Ô¥£‰tœž´¸ú¤ÇjCO-$‚#u³2Öw-¥LŽÄV2±Z®ÇÚ=þO0gõ~'F´{üž`ÏêüNŒ3P0ÍΤM™B¨7Qr&4ˆí3G‘ ¥bê$¡(m "3W¹¹™™ŒÍ>>§F‹žÍÝ7£4ÂZm,8iR h"Ø•V¤Ü¶ÙF]ó{h÷ù<ÁŸÕøv>Ñïòyƒ?«ñ:0}ö¥xÎ>ŸXµ6£N~Ì5\b#Ž6¤%öžhÖÑ™X–’Y)7.ÌF[6‘–Áì}£ßäóWâtaØûG¿Éæ þ¯ÄèÀ`[ÃL7Rv¤Þ”jÈœóiiÙ)bN¸„ÜÒ•+r\È®v#=—1Ÿ¨Óð5J"!ÔaaÉ‘òä%—ÚeÄ%Õ¨Ö· &FD¥)JQŸ ™™žÓ´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ³uJChJQ‚”$ˆ’”¼‚"."Ú?wÚ•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€‰Ö° ·-©uœy"¥!¢³n˃Fyh/Ôj†fBHÝ=uÉœC*÷<Ú“1ò;«–\ˆJSm„YR[¯sÚ=´{üž`ÏêüNŒ;h÷ù<ÁŸÕø!ïbFbœŠkÒš‚Û$Â#!m“Il‹) ’[ $[-k[`ñGãÓÓNbj#½1ÐÓ)m,¼d§[$‘X³"5'FE{‹Oà=°Ã»£ì–ÛI­GÖüC±\ÿîÄ'º›~cE¾k…Ñ‚[C}©^3…ϧÖ-M¨ÓŸ†ó Wˆã© }§š5´fV%¤–JMË„³–ͤe°kMþêmùù®FýÔÛó-ó\.ŒÚ>Œð¥r'Ò1S¥¢ù‹L¢4âoÃe& ÖçÁÛù¿ºŠûeÉ»²5º2ÚÖÖ{«[e® ýÔÛó-ó\.Œ7û©·æ4[æ¸] Õs Ñ*øÑšìоK-ÈbJ‰)«S&•!+=õyЕåË}–Ím‚WŸ n]Ëž¹÷FéÕ]¼šín·Yn úÎï7në‡h×[ýÔÛó-ó\.Œ7û©·æ4[æ¸] ‰1X^féÝgF‘ºÙKu¦ÚõÍ$ÔiBïî’Fµ™ì,Êã1v‹£×ilRœ¤áeÓã,Üb*£°l´£áRQk$ÿY…ï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6K°ó!‰¶ž[HeN!m’´3-¹Rk]‹€³*Ü&,°XQ…BSEhà2lC4j“¹›2"ÈݽÂl”•ŠÅb.!¯7û©·æ4[æ¸]o÷SoÌh·Ípº0ˆ”¼‘†£¦ …75-0ÂJJTFJK–.쌌îG{Üf7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬Zbm‡d:ĺkNIp}Hq 7VIJ J2÷G• Mϼ’.!­7û©·æ4[æ¸]o÷SoÌh·Ípº0×°겪îãÇÜ©-HZ¥ªÞ5!D¤¯qæºT”™mØi#.8φ7.åÏGÜû£tê®ÞMv·[¬·}gw›‡7uôk­þêmùù®FýÔÛó-ó\.ŒÃ2†–ReE4±%RÙ/ÑY·Ô¥)N§‰f¥¬ÍE´ÍF}ó©ñpe;)SãP"e”©…¨C(³êA¡Nìþ Í&®#2½„º›~cE¾k…цÿu6üÆ‹|× £?ƒ@ªIªÁbƒ¡/ýbS(i½¶ýÚËj¶ñ˜¼ÒðÃ,Aa¥ÑÛjŸmÄÚM²Lk Û-YÈR“²ÝÊŒ¸ k­þêmùù®FýÔÛó-ó\.Œö4L²íj4l>ÅQâ2vkm²—Ü¿e—tÎcÝ m6a×M†ÒÓ,´â†Ð’²R”–Â"""".­7û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖ#5ZdyuÙ5hzDJrCm´¦â&šdHEò§3±Öá‘–«)GcZ­b;®ÿu6üÆ‹|× £ þêmùù®F9 DˆéõYñU&âÌ\÷–Ô$-Ùq’¼ì6×NbYžFìi$™+8Å/0™Éb†šMCýtÃR{ÿ¤±wÏqßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀOéì`êth±©ìÐb1 Óv3L%¤%…šTƒR¶%F•©7-¶Q—|Æ+P0~¢Ó¢Ãr„uÔö!H¨´ÓL½(šm)̳#3Û–ö3;q˜Šï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº1˜Âq´‹*Цa¬?£ª´Ä4§–ÔZ45šMˆÖ«7ܤŒÈ®v+™ ÆûR¼g ŸO¬7Ú•ã8\ú}cØÏ'øÌð}á­à­Ñb7*¥ð+ ;%˜­™Pá¬ÔëÎ%¦ÒD–ÌÎëZK‚Å´ÎÄFdÀÏoµ+Æp¹ôúÃ}©^3…ϧÖ1´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ¾ûR¼g ŸO¬7Ú•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€Ëïµ+Æp¹ôúÃ}©^3…ϧÖ1´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ¾ûR¼g ŸO¬7Ú•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€Ëïµ+Æp¹ôúÃ}©^3…ϧÖ0¯à=°Ã»£ì–ÛI­GÖüC±\ÿîÄ'º›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>±ç•*…!dã•ZÄ‘’VRJMûå·„»ÜC[ï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6¡FCZÊœ'ÜhÌÒµ>’µûÄWàïý71Ë_2#ɬa'#>ÓÈ(òHÔÚÉDG™½›ñ¡? íUŠU£zŒ÷ïª Çdš”d’nö$‘™ŸxˆÌöÐ]J«…X¡aú-·’· Nf6°ó6E›V’Ínõïk¸LLsC´j?IÿÍWýLEªõj„¸S¥*Üí;i&Œäó©IÙ¦’^ìó\ÀYŽäRJôtJr|W ICÆãj4ŒˆîGcï×x–¡7ÀS5&ˆÙa“(ï²’Co%)Ø‹Yµì൅=ô–_¤ïÞ³o6ã»Û=^–ÔÞÓÚÝDw{g§çT¾=n"ž‹ôKŽü•dlž†óiRÉ&£I)I"½’£áï ˜€Rh³­Ó§<Ë(ŽÔ’³ÝF³±6∲'ç/ÃÞ©±Û— 让ԶójmFÓªidFV3JÐd¤žÝŠI‘— ôi.^¹FoS‰ËÓ¡½~í¹ªý;g<¿eÑf\–b0o¾£J INÄšŒÍFDDD[NædB3£\î§K'âI"L…9ºjó–ú›lŒõm¥&f”Ù'Ý(ˆj¹‹*Sž¯E~e1LÆÉ­'q$µäq*µÈŽÞçˆzÞ×’mFRå5¸´¶–Ö§ Du¶•ªè$§2ˆ¬fF­¥~ ¤2ù¬ÍmFÞd8Ùåu¥•–Ú¸Œ¿ùð dâ•Jy†e´–Íä¨ÛÕºn&’2¶R;÷EÀ3Ø~ ­ÒU¢V¬ÛCEc2MïÝ|ÿaw»æs8à'ÆLÈnÆSϲN&ÚÆ\4-'Þ22à?þŽä,Pà*›Nn+“$Ít¶¸ówís;í;™Ô~×jQ¨ôyuIfdÄVTêíÂdEÀ_¬øº§bÊ•eÖŸj¿&)<æ­´3 )Œ§>m+u“ÎwÙîË7x‹€¥º@RU G¥&4YRÍT¢hÈЖ]pˆõ‰RH³!'{w„F­BTqŸLЬv•ÓÙSÍÆTw¬d¥š›J6Xû×Ù}›v}/¢4´~êUDU3>Þœ»¢cÏïÏô®ªZ-EÉ£ôÏï<ÿÂQ„ª5¹–¥ «2,†‘ ;ì%† ²Fe¼…^ægsÕ‘žÓ"à.3•ˆf‹ ­4çªÒZË&R²‰çÌÊTy,k33-ª2=—Í{™ŒIlâj‹qˆŒG³ÙË÷kh"çOêNf{ó󜰲¦N™%Æ)¤é$³V­)5¯)ÙGeì#ÙÁs> œ>fêU™ rã>“Ru‰A¤¸Tœ¤\F[Ki~ºt©UÅ?%‡œSKuÖPÒ­œÔ³4þOuc¶Ò>ñ‘íòâ‡\’ËÈŒóSÊšq ;¡Gk¢ûH¶Üÿ›„Ïo“Z^FFDe´€y*ÓÛ§ÆKŠBœqÇÓ-'a¸â½Ên{ é>é`,¡'°É$Gÿ!Äñ›Fr<˜Ç*9¸ÒÞh¸V„¸•(‹im±çTUTb™Ä¦&#¾X:íB¥9¾Ë)ÎÝ-6”´L%WÚg™²"ås5ÿQ‹%„+««Fr4æÒÅR-ŠKI#$¨Ü¸‹íÈ«¸ŒŒ¸Hcê,¦ƒ£Š® ¢ËntÍkME~mß$6n6“E”wØJ^Ãà;ܸG«LU›N©›±$N].ìq‚M’ò®n'g¹;‘]?¨¸‡›C¢½¦³?¯rk¯=óìùB÷oSr¯è§þYj÷ÀsÿáœôLcð¦/‰‚z™pMjC©óÃô¸ð⤅HyqÛ$¦ûL’’̵™-¡ÅeV[ …{à9ÿðÎz&5î0Âõ¬IÔ‰€ÃÌ¿*£F¤Ó*(ˆÃyœ’Âl¸”XÈó%­Â"%²Išˆièè·]ú)»8¦f3=#=òó_ªºmÕ4Fg›XV:¢1ªJ¨BÆvÜA”&(ìî'­À”¡I\ƒmd•]IxÌû³B’DDž‘ê|ÒŒ}(`åÎu¨ñkKìºJBŒÒJCí•ÍDÒÊöÍÀ¤8’5äÌ|—™T}zq £nÆyˆ™¶Îº»·ê ÁõZ>­âÚš_e¬@¨É‚ÛÍ’TìvRá¦EÈøSë",©¹6K+¥iqþ§ô^ƒI£¢«4Å5wcï¥u?罉è­N¢åÚ¢¹™ßÙþ!¼!×wF8ªaË—pSaÎÝËë7C²‘“-¶eÜ×½Îùø Û}ŒÕ =\•DmüÓâFfSídWpÓÊu-ªö±ÝL:V#¹eÛk•àuŒ DÅ:^®ËÄøuºœôÆ"®S&¦u›¢ nd¿s¬I)³¹wH%•Œ³m‰hË SœÄôiø×ªµgR#»6m O+u¡‰Hš‰›fM-M-¦ÔNšs‘6Û(ø6ûtЪ+”8º[û¢B3r¢»‘IÖ4âIHU”Det™ŒˆøÇ´sdz6¦h§EYØ&kH‹]ašý5ª#¬»&[tyDû†ÞB9Et‘©i%“‰I‘¶Ø82› >¨¢F«§»Š"?B¥&3=¢z&­ÍIšTÓH”—4™VÈî›w 'LUA¦o¾íŸ«ÞxíÈfV­R͓ܤó(òr›«ƒgtWÍ -þßÜŸÂë¿.bÿà)þöî/q±³ÿ´~³måw®ëõ³Vëß®ÍÓ¿›‰ÍVõî¬ùwU²j÷èu9¯ŸnOáÞBÌœ“<‡¢= ×ZJ×ãA¸É™\УB”“QpU(®[ ËhÓ¸bŒtÝ6.DJ ‰ª“QšôÊŒÚÑäÄB’â’e?6ªK£J͌ҕ ÎÆƒ´7‚z¡‡gâ|2µ?JÀxm˜§>!Ú<¶ŽZœ"%•’ûg«ÿÆŒÅÁ›hnx9& yDz®´•®;ƃq“2¹¡F…)&¢à<ªQ\¶–ÑŒÆUÞ·i T7.êÖÔ AɬÉmÓ-˜ùïc÷:ÜÖïåµÊ÷-; Ë‚0§ðÄê­j&§Dn“??)¢} ÷HmöÍ'O‘s²]ˆˆ‘òNÛSLl9ˆhoadQê²U* ‡ži•N2º£zÒBÒwÌÚR×kdJ«íØšÄX& =ìoC¤Q§RpäªU"J¤Sm.IJ•¯ÊÊlN]¶ã“­§ºRÖ3Q_ #¦á•¬-„‘ ¡ ­&$B£½Omøò£!²‘¸Ü3\t&A0¥¤ìYXZìY®€ç¹¸?T©’¨õÊ}Zst)”Z9*Bõ“"Y‡ž’KNÓ-ΘÙÖ^åLºf}ÎÉå—b¼g"‡†%1@fƒ{P)P»™’¹Úä°ÙY*yHDr4•ŒÌÛ¿º#/ÇuÞµð={n]×½Ù·>³&·TÒ—“5-òÚö;_€ÃWwÞ¯ˆéû—S¼•$AϬͮÍ<Œö±eÿXËm¾â÷ÛbÒºv ³>6‘[«`ÚÝ~·:žiÂò¡S]“©kr%&ÒA2dù<¥$Í&âVDD»åY´*Ât­ˆªÕÊEB«ƒœÄ,, 3j³ûß ÌSdFrYJФX®M­«(ÒfØlŠÆ2Ò0ËÝSfÎLY$F¤”T®$¹]òÙf{‘IÊFFD¢Q÷‰Ra¤ 3ŒäÑ+3éŽTiÕŒu.d”äR›(lS¦D`ܶÂiz¦ŽÇܨޱß5ö§†N™¯HNšæ …ŒÚyêLHk[nÓ•LdÔM0’ý#%1yÔÚÈò8V;Ú¸†»½|9Oܺíû©.}f]NX’$gµ7ú¾[l÷w¾Ë×w¢¯‡)û—]¿u%ÁϬ˩ËDŒö±æÿWËmžî÷ÙcÒµZ K¢Ñ ü[£®\ZB)ΩÈÔíì}³5F"ΆNA¸­Q¤®—Œ½Ñ$ÕJ *¢PÍì[£®\ZB)®›‘©ûØûfjŒE œƒqZ£I].%{¢I†ýó=ˆóéyÓBÖÙ ’ÁdR³¯2ˆÍ7I'¹%Ö™s(¬Pª+”8º[û¢B3r¢»‘IÖ4âIHU”Det™ŒˆøÆ ¢aÅK]20̶°£¸Æ[±)“ ©(N]S*'Y~‰¥¾§,…‘ÈMŠäC-¡š,ún†(4|# Ÿ„«ÙŽÍdªXmâKÒ‘ }y lªR‰?§%-*Êes=© ¬Kâª1±¦¦ªÑh2+$ÔaœºËܬ’[JÝQB‰ 6‚%-L¯jÔK+Ye|+Xo”×.¢“j«×6êbs8RSòt] o‰H&΢ͩµ ­ÝY U” è ·ÓiÑqü÷+˜b¦æ,UVk­Ö•Å4p”§ „”«d&É“m½Nk’Êù?„0Ø.Œó8±™‡j”Ý$ª%‰õ‡á¸ÒdÏ4ØœÝ*"CùîÐi5dM˸à0ܳÞr4ˆôÇZiKDvMãÆErBMjJIGÀY”’¹í2-¢?1” 6ôHfÕP•&iŒF¤Ù§æÇˆnš²™UHJ‰'cVS"à3-ˆ)4'äÖ `œZ£È‘£JûFv–ôw$ÉQÃ$ ¤‘¼íö‰%g3M”«lšãZK˜ÂN-”˜’f0Uú`”jÜñ§Ç~K„iÚ’%>ñ)Ek73"MÀn†ÆUÞ·i T7.êÖÔ AɬÉmÓ-˜ùïc÷:ÜÖïåµÊ÷-c‰pƒÔgñ'áçáPäSè²W šÑ²Ü›L“»ÐÉ&ÉÖ®3hJ‰63Ì‹íQàñ™G§ àÊÜ\*ýB€¨ô†)ÎÃuçZ¨!sf:‰ m&Ö¨VI]µ«‚꺱•w­ÚC ˺µµ(rk2[tËf>{Øýη5»ùmr½Ë'5çe+j#Ò”n¶ƒCF‚Q–I5žu$²¤ŒÔ{odžRR¬“ÐXŠ‚ÌŒ%Š“…ðen.~¡@S†)®ÃuçZ¨!sf:‰ m&Ö¨VI]µªöº†Eº).5YXC Ô©8iÊær,S‰úvjm®[莤¥M·ªÔæVT‘ê–® ¨ÃrѪ+Ü—N^Ër_Š¥dRlë-—SerãkMø×+‘‘hÕ:$ÃŒÐh8š…¨Tü-_Mfb—*Fp£=Sä9ƃh¤%1ÔII!ÏÑ܈ȽÉÞ“€éø›J5YÖ‡´Ú0Å*:$9 IйüóyM%JQ%iÌÙ—t¥¶K.뺹„ÞwtcЦܹw6íѬ¾³t;)2Ûf]Í{Ü­·29Æ% L*%N·K­O¤§áäbZn¥h•PZ7qºÝÌ®â›RÒ§#ìRÉdGÑw´“†ë3±^BXS Èj/[2›Áòê`!, ²°óo¶ˆk'‰Å:”‘ܳ)Eܤ7~;®õ¯ëØ›rî½è¦È¹õ™5º¦”¼™¬yo–×±Úü/H­Å‰Q{oDvlã…Ü"Re¬£ªAš2²¤Û¥úL‡v•b± Õ£ôíAf|m"·VÁµºýnu<Ó…åB¦»'RÖäJM¤:‚2dÉòyJIšMĬˆ‰wÊ=¸Û Såã9•¼MƒZ¥ÅÇ%!Ò]sÔ¨‹Ã̰jCIBÔã{¥,‘åI–fˆÏj6ölC]ÞŠ¾§î]výÔ—>³.§,I3ÚÇ›ý_-¶{»ße¥D·[ÃUÜ6ì:ëm·•ʉßCÄ© »IAÞ˨»­ÓmÂ"¹¬ˆkê&*Ý' R§`Ö£ÑXÆ/:ãQ©Óã¿©RHŸ\G Õµ:¢lЫ%g¶ß¤±†åÄ•êf‚‰•G$t™iâ;%×dg• ´•-Gd¨öì#>ðóQqn¬»Nj™Q) ©F‘**I¥¤ÔÛ6Ó×¹E!n¡&•YW3+w*´6‘M™…°¦“aP`O¥Å‡)÷h,Á§ë´23Ÿè¬¥.¤ÖlŒ’kÌ›–ÛSUÁXÇXFŸ‡*•Ú 4:¹;P„Û/­N;&òº¹ :“[Š'\32%¨Ð£½‰@'“1Ê”I•c9K„Ôù¦íІ#¸n¥)fYlfýû–]¶¹_Á†ñ¾Ä5§Ó¥ÊL½Q¾†&@~"ÝhŒˆÜlžB Ä™]H¹ËnÒ潃±2k˜Á:µŠªn’õ£µº·-B[îÃB™i¦ŒÍEc+–¸³Œ­%:“˜Ëai4Ê%nj$‡æM•R¦»ĸβQÒN¥&ášJÌÑt¨»«™ÌBÒ6›PfiòÜ'Þ&•½²J®²’Q$ÛÔ¨Í[ Ë;žÂ)ºMÂÕ âh‘™ÄÛ½Z£SNáj“Z´º¥%µ¸kŽDÚ HYgQ’{…mîNм<õF‹>HÁ‡Ž›ŒÔ¶#»B¬ÑpÇœ‰Ì’Í¢¶­¼Æ‚KîšR’##¹NéQ%#L8Žrã<˜aúK->m™6µ¢EDÖ‚W©$â ȶ‘-7á éXï Õ0Øê]/áæ"»-ÙdË„hi´š–£lÓœŒ’FvËs+XŽä=xƒP(:U6¯PLiuwµ›6Ö­bî”í4‘’K2ЛªÅ™i+ÜÈIÕ0Ö!¡õ6²å"‡Q‘*«¥VhíFYÉ)'O&Zy-[6±*³N&×4XÏÞˆŽKаn/ǘƒNT§Ðá)’£SÊ£Fy÷Ò–”NªS*'Ú$¿cIšVFQÚQlØa²Šh)Æ…ƒUPIWNTJ)¶²¼sZK%Û)žd¨²ß6Ã;[hÆT4ƒ Ê®Äzªë’(.Cj¢ÌxO¾¶Ü–¼‘Д¶ƒ7µ÷6Fc#Øv)¯bg1ST“¤bHtZ+±Ž{N3åµ"¤‰qÍd“3B›uEr#î]iv;¦ølEƒkU¶I‡ä*6“2©M§®C®ÊEnL‰2ZõŠF}fL‹Ê“EÒeb0ÝxcÓ±èÞøÕ¦w>\ûãF—ù¯l»¡¤g÷'|·¶ËÚå|ÈÖt„̯aŠä*}oâ)*ÜùÄ,HÃY;³3ÕI —v‘«)/Ü¥'”–w`œ)‰i¸ž$Ú…sÆo>w;#V*yn…£Hi-9´È»£,¾è¶‘™àÚï\T‡ê—rêªSàäÖg¾æ–ô|÷±{­Vkw³ZçkždhÇh¤ˆÔ•bü/R«a¦ëx•ÉPLv_éž©¸¸®2¥8Ùµ®Ê¬ª"Ö¡\2©4W›ÃØ8±¦«UpÄ}óÖÒÕ ÉîGÖ>J§kØA-Njãçlö+*”“> o ÄØëyq ÚNõë÷.ò~“te;5!ðe;jõyø{«Û¹µÆ¿Ò¥4§Ï¥AF K° ˆÉBr£‡%ÖTÛ—Ynt¡·˜Ž¥9 ÞZÈÕ˜‹7èîXÝàÄuÜ3ÚEaé躭‡Rên¨ë’ÉFDJJÛJ³¯€ÐGs·…¦1.zŒþ3¤á<ü*Š}JáSZ6[“i’wz$Ù:ÕÆm Q&Æy‘}ª#?20ô ¸w±B ×(FStýË Š;-RuJ’â!,³iIÔ%h$‘¸HrÄfw0Üu¤ |ÊlIêž©É8°Ó‘G¬t™qãMȬ_£eÅ\ì]͸LˆéªÿþïòCpãïIÁõp|*j(ø¦Zš‘Žå8Ž”§Ð§SÓ5ÆJÞ6¦îD¥6•Ûi ½Uþü#ßå#ZÖñ¦¡Î8¬YA¦KJIFĺ‹L¸D|•J#±ˆ¾’ëŠæ O¢U Ôâ*¤ Ÿ‡!/6j)Ìܳ$Ì®Bî˜ôK†t V زẓn\r"pÚÌF¶Žü$e{|“Ú]ò;ZH¤Ó¨X/ Ñé‡&$£4Ã-•‰ )­Ìûæg´Îæb‹60‹âJüöê ¥ÑZiO¶m‡ÝI©-)Õem ImZÔÁ¹Ó2¹^P 8‰õP±I»(1¦ÕaTw¼²hÙK­ü´“É<&K;^Ço¤/WjÖhë3Ò:¼‘¿]›;©ëžAÅÕ(3’Š»ñ&Ä7RËεqžŠ³2"Ö4¥(È®dG´7+•®e8›.4(OM™!¨ñ˜lÜuçTIBEsQ™ì""ïg¤*Ëøó"ŸÌ´¸ÍR9FÚË*œyDv$ ŒÔE´ˆíc32!0ÒM:eSÈOºŸnDiE1't%™ º¦n{;´ Ñ·gu·`çèëÕ\ßVêb{§–üyý©®÷êFíÔÄ÷O^¿ÃöŒèjƒPb=9/?}AɦɎ‡ìF£Õ­ÆÒ•ì#>äÏaŒfĪ~7ªRê”mÍL¯Ô½¸Ýo&GI-~•FhZÙ›Ÿ£"ÕåÊ«™*kÕJÎ7 .Šx¢,"uh«Á›F8ñRÑ0ù’õ®²JSšíBlÛ†› ˆ>‰WFpÌæpÎô­É·X&pü¦]mã$Hœë†™e¬K}Ù$ÈÕcÌW"VžÍÖíFUˆÔ…½i²c»%–²ŸtÛJm+Uíb±¼ÙXÎç›eìvÇ•yÂÅtú”×XTÈs¥ޏ›¤£<ÃEܤÔFNä²;‘‘¤ŒÌ“ÆTZCšXµêžEA-“ÓK9J$ߊ¸ÊR’…dœ¯™8vJ3+if;ø°52¥Ó‘O–ËHë§;Ž2¤¥:ê».5s2ÙjOÊI•Èþ½ðÿøg=lW]7EZ7)×hôÄ`væKy hö´Ì$¦æâÞu{ „Ì¿PÌ×¾Ÿÿ ç¢bªOh#Q¨Ö:„£ ÕbqI*jò\öwYríÙ·höz>ÕoÅ'Îs=;§¿èóêæ¨µ3O?ûN›¤ItÔUáDœPÖÙºˆÒ§ÆfrÓ´Óú-ÈhJ”V2Jœ+\‰YLŒ„‹Ϊ»^›¢üå¡4ÈSÔÄ2N°·W –…I$µI.þÛØÌGšÒΙ…ÎlZ¥[A?H®ÏÜ.Çp­µ‘¤×rÚDd“#Ø"¨Ó–ÃX…5LwXëz¡X SŸLS¦º¦Òg!ÒîÉŒ«+<”™¤ÎËC‰;Eu:[–öÕ4mŒÌsžŸ¼Ïò¾–›Q¿5LÎ;³>ÜÇüe½@Y%¹°cÌe/%§ÚK¨KÌ­—”W"RD¤+nÔ¨ˆÈö‹Ã‹ <¿õdý¿ð–8cÿˆØKþO¤Øîzßú²~ßøK1ÿÄ áÌ%ÿ 'ÒlWÚŸc°ª?IÿÍWýLy$°Ì–ĆëK+) MÈþ’GPÒ¾”·d¯UMÇkU™Ž’¹Ïa4D_AéKK}ìw7›g£M¬ÿHkôtÓUù¦˜«8Í\ñÏÙû¸×¨·OuNìBR„VIˆ‡èáÊZ]åÜÎm®Œ~vRÒ÷.æsmtc:} z?¾Ÿçþ•â­uwx쥥þ]ËæÚèÇçe-0òîW6×F)>ˆ½ÝOòž*×WvºÃ.­ q¤)H¾Um+ðØ\ÙKL|»“͵ÑéKLìw#›k£çÑw£ÛÉÄÚêï ÙKL¼»›k£”´ÍË·ù¶ú1Yôuèéü§‰µÕÝU*t’YLè­ÈK“ÍÊä•‘¾›ŒqáL>gmï"kæ Õ“<Ýò~ÁÄÝ”´ÏË·¹¶ú1ùÙKM»{›o£¦Æ®Übš±ò—:«ÓW9«ôw›hKh$!$”—¨pWe-4òíÞm¾Œ~vRÓW.ÝæÛèÇ Ñ^èéÄÚêï q"ËA"TvÞIÈ–’;·"Íq¢4҄Л\pŸe-5ríÎm¾Œ~vRÓ_.ÜæÛèÅxKÞéÄÚ÷î‚;)i¯—nsmôaÙKM|»s›o£÷ºq6½çs9B£¹$ä®OÜÖhÛþˆ‡µ–gÞšB;Ûpge-5òíÎm¾Œ;)i¯—nsmôaÂÞŸaÄZêîÚ³N?J–ÃIÌãŒ- +Úæi2!ѹ9†´y†ðäÇ¡;&•I‹çqÃBÖÓ)B7lŽÆi;\ˆpe-5òíÎm¾Œ;)i¯—nsmôa[Ñý§k«¿&P°4ÜBœG3 a‰5¤ºÛ©¨»+’KnÄ…¦ÖlÉÊ›îYJÜA¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‰á¯û§k«èæý5ÆÇß_°ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ýÓˆµÕô>¢õ.¡2›.c,:õ2Iʆ­s¥«tÙq“U‰6?Ѽâlw.êü$F^Ýúk¾¿`|ã쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþéÄZêútX›rSiQ÷ *TÙ§s´¬¹›nÍ÷)<ˆ¹‹¹Oný5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿtâ-u}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿºqº¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ý8‹]_G7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿îœE®¯£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_÷N"×WÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û§k«è¬ ôø™ƒ4±XA6Ë ’Ûi"±%)&ìDEÞ!~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿºqº¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ý8‹]_G7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿îœE®¯£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_÷N"×WÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û§k«¿pÍ# áÉÏÍ¥D$I}´²n?>L…!¤™™4Þ´•«lŒîHE“ú†bú|&ÖÜ8Ðc!n­å¥¢R N-F¥¬È›Ú¥(ÌÌøLÌÌÇήÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿îœE®¯£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_÷N"×WÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û§k«èæý5ÆÇß_°ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ýÓˆµÕôs~šãcï¯Ø úk¾¿`|ã쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþéÄZêú9¿Mq±÷×ìý5ÆÇß_°>lÔôæZ|t¼ö9}IR²‘!¦Œïc>û¨c»<és–³y–}ʺ+¢qS¥5ÓTfM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}^õ»ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý‹ÄÕ寤K™šõVJ#©¶¡Dq)qå,Ò[ñ¶‚"á35pØŒìGós³Î—9k7™gØÏ:\å¬ÞeŸ`;Îçmuߌ¿’zÿœéߘlU/b”Ñé磚½5¶k”ùŽÉ~¡hm¶e6âÌÉš¹J¸ϽaÇÝžt¹ËY¼Ë>ÀvyÒç-fó,û6É—Ñ!D†Y‘qä²Óì8V[N –…ëIì1óóΗ9k7™gØÏ:\å¬ÞeŸ`6É8—Кm:LiLÓ)°`6³º‘2Jõ’®=#çog.rÖo2ϰžt¹ËY¼Ë>Àˆ£ˆDDS‡Ñ ;{<és–³y–}€ìó¥ÎZÍæYöí”åôHÎÞÏ:\å¬ÞeŸ`;<és–³y–}€Û&_B*Í8ý*[ '3Ž0´$¯k™¤È‡æ ¢Ä¦`L'E«8Ó• Šqȇ:K$f–›K™T„¤Í&¦’{x‹aŸžt¹ËY¼Ë>ÀvyÒç-fó,û¶y"ªiª1Teô{rÒ|&£ç¹Þ±á›†°lú½2­R¥1RIR©ïO™"IÆtˆË25„¬¼${8T†Õî›A§çg.rÖo2ϰžt¹ËY¼Ë>Àˆ·9ˆ…i·EôÆM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}nõûŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ï;ŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`lާµÎ#˜åÉÞð¯ d©´­ÝDªÔ‘g©ÉiÕ1“Ý´¥êÔ¼×Ù•jh­m¹øJÛq³½á_@Ìຜ*]k5Q2M’ñf%„’œÕ¸ƒNd’ŒˆÔ“ʲ#2+¤‡öõÖGMýý:œoŒ²0TÒ¦°ìMÑ.c›ˆœe Ò¥6û­¤ÔkÍ}SI]ò岕˜Ó”³ãäajÛ,¸ùÆeÖQrMÖ%4ê ´­(Q’£%MiºHÌÈŽæVÚ%Ô#ƧÔ+“×j]JªÜ†š6›q¶ci±ÍWt¨Ò™HÊ•$Òy g 31Å-Uº*ä™ÔXÊ™­5E‡L55% iâCQû“^DìZ”{I;m¿Îw\Ï'QŽh˘+77q.ñI6c>–³§2“ ÐLå+÷JQ­%”¶–Û‘e;x1} b"T .±mëqåµ!›š}ÛJRot™^åm¢cWÒ&ûƦªIM‰=º¹Ê•*)¤––òÝe-\ýÚ!û_aY®-˜ Õ©Š´i†VDÜRnL…Âj"¥;j7M–ŒÐƒÊ¤§aòf=¦bÔÍyï„Uã¹ÑÌ7Á¸&_¤S‘\•}Z¥"”SÉÖs´Û 5ºîµ&ÚO^’¹!V$™˜Ó0Õj¥¡ÅBÐ鬙J¤6‡4•ÔM¡J%8eÿ„nÎ ØöM CÃÑW1Q—>kµXzÓC#¾ÌfÒƒ±û²Õ:d£.äÔ“+í!˜Ãú@¦Ré´ØÌ<üuÐÔáSÝëzŸ)çÒo­ä(Þ{2ã¬Ã.çXEb2+ÞüfkŒºÄQ(œÌ‰bR÷ÅøL%ÊÜÌ…5…?ÃTÌnö/CugeÕªqåÔ¢œfÒÜd"k2Ü&W¬3pÍL’S™(±ÜÄo¯ˆNÚ3ß(´L QÕ± ¦Ó:l–\g*’µŒºé™]Â<äHIdF¥(Ö’,ͬ‹‰0Õc©”UØe…ºjI6‰M:´)6̇…¶²ÌWJÈŒ¯À=t:¥)2¹A©.k.J‘lWc²—HÝa¹&ÖJZr¥ZÿtYŒ²û“¸÷iQëÈ€pd¹­©åʨL†Ìwß%dÈ…ê”dé£*ÏZ«)Yö‘X…âjÝb³íÊ£˜OƒðŠñ ±PÝåP[ÿFhÚÌr&ÝtÛ#¹eý.öíÊVîˆFûãÚn¤Ð¢³†¡T߇9Éò^š§ÒiuF”’[Õ<”©:´'ßeu(­c;Ò¹«Òµïxtkæâ¬CFfF©Š\Ú‹1qS˜aå¶§— ”¸¬Î(ˆÏÜ¥[{Ýám9ÅëˆÔ²§Å&œŽÔ«ª£&Û¡+C®¹vÛ2R{µ‘$ŒìfG°gðæ*Á0ñªM*úÃ3Há13*91Ó1r§§ "ËX¢4‘(•b,É኎,§IßÜŒË-ðÃTÚKWJ{—£nêWuîr¹c+žÔÜŠçjn¯wrø£ e£ŒP¨Ë4SÕºqâ’K}„2Ûm”_Ò¦í”GºÚ3;r©*%(³d¡:>Äf‡ÜF¹$óhÚÑœmÆä9¬×“™r‘FpóÐD•æR $J×t…EŸ¤ÐÙPL—iD%-´dΖ¨è33Í{^œÿ{øMìÚ¬´Q1í&.£QVõ^ ˆdÊ]•3Nغ¢•d-dKI”æ’iU‰DNÛeãu͹ÂvÛÎBÑýU8^³Z~m%¥Ò¥°ÂØ:œSÖ¥Æ]xÖ…k{¾å Ê”’ÌÊËsBˆxƒ+íâ7°ô†éñªlç'‘TŒÉ%HpÛ4–á'>b;&÷QYDF“#<Ígáz„KNf4Ú|yÏ™ãÂh‰oÇaæÕ²ZRÒ]SÊYä58”CØÞ0ÂÏc<_^™O{5V¦äÊsÎÓcÌSM©×¦ÔÓÊÕ¥J%#»îòä;ÜNêÿ>ˆÛCÉFuw©´‰o?§§Vݤ;¤ÆÝM-0ßrÒÞJ–³[Ê#AåÊIJ”d•’„­JîòoÆågsjµÙ7SZýWÎj3krãË–Ûoa;<†dbökÒWh ãi†3MÆmzæz:”…™¸Y”±r¶b3U®EÝ ]4,»õjŽþo&óîMB7.]ǸõºÜù¯«î²d÷_°ˆª¿i4Ñìb±Åóª@a­Âîª[mÍa×cžl¤km 5%&­„£"Iܬgr¡4­bÊtÜC¤:ƒLËKX—[¸Ò¤§3yê É-gu³¸iE³7teÞÚP±Ò‰ªcú”ª"'¸u@*cktAÂ{ãm÷ÞÏôO½nÆ™sÜæî²k­ÂY²ßeöc†«J¦oEF«Prr†ÉãhŽÆá5›9£„óeµˆÏƒh›Ó4³ZpÔÈøƒ±‡imÒš‘NjbÒ…¢;,!ô¥¢^C%©· ˆí›6Û\ŧ´ƒì6M’Î-E4„ÒµMP (Ö‚¹óÕ¾œÈáMŒö™’V·×::⎯/Ñ•v›ˆê±©qRí9™²Ú§›ó£”‰M1!ÖLÒÞbS‹#iW$¦û/kÜØÇá «ã†fT×>+²ª©èŒÒ‘s«LÓo¯[v•e¤Í$…÷*##Ûq¦DÚª©êEȦ'¸Õ̃Ƶÿž^Š„DK±ŸÁmç—¢¡ºï÷ZÚ?ö€G¨ë¨KãÐþ¦™èУwuÓ"VtÂõ6~éÜÏQ¥k <·c,ȉ*¶±¥%dGk”W+‘ÜŒÈDŽ¢¯hûT4¥ÄÒNâ µLRŠ”kcPfYг×cUˆÍV#¹&ÖÊV—èËã¯}SFô§ gc âê¿õ–©ù‘wBÔŠmK8æJaöc¢•GUž"RŒÍsŒÏ;î-Eô‘l๙a.ï ú„êLðÿ‘zǺw¼+è·8Gé/Jú'Oé æôOôÌã×LËÔÅU÷²›ëä;ÿ"õëF/à;ÿ"õŒAŠ>F÷úGG(Ÿåb‰fN¯¿€÷ü‹Ö?³¿îÞÿ‘zÆBÚ†]ßDééåü¯jÓ®D/û·þézÇá×býÛÿt½b>¡B†mݪy-ÂÛH·þÍ?÷KÖ?:à…óR>ézÄlÅ<-ÓO$Æ–ÚM× /š‘÷KÖ?:â…óR>ézÄ`Å#É]S“Â[J:ãƒóR>ê}a×,š“÷SëSŸò×~¸äžÚW×4š“÷SësÀù™?u>±1HòÕ­» àí%ÝsÀù™?u>°ëžÌÉû©õˆˆ㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¤»®x3'î§ÖsÀù™?u>±㮜¦wV#T!!–[y*K„£5‘ZÆ]ãýc<÷.Ur­Õ;Û·ãæ¸7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;Þô î€päLG„±ôuR!T*%§›í!Kmå¶ù'"—î ÔIÛrà.!ï ú·CX“…ð–92¨ä BQM6Ðæu<–ß"²GÉKEŒÌ¸Pýþ¤¢õ~‰˜±»u8Æ}êzwãÿg‡»õ{Òl £*–Ñö>•ŒðÌ$?½Jrœëú‰ mHióRi5 ŒÐwÙÀ\B%†tDU¡ZÅ0è’+«4Òb¹NªAÚås#"Eö[‡Ý'¾výi-à|sMÅøž£*UBšlS–ãÒ3,Úy*$ŸtH¹©3±pqlÊQq¾­P°CØ–­2•QÁêI¡„DS©–H$e$©;ïH=¶ï—~ãá55zNÍÛ³V{êŒÍ4Ìǃ»lN{³ˆ™ëžN”혇æ‰0$v`i:‰`ÒÊ£N††š—)”¸˜ªSO™:…¤­•W+ˆ»ä#‰Ñ»ÿê1™3©›TÓ9îÇ8ïðÎ}žÉÇzÝÙ`ú¤ðþÃÚAz>šÊV¢AH¥µ M& ™k'v{ÏsQÛ€ï}¦5i‘ÕTÇ»‰pÕqUÔRƒ}•DqÌhm¶È®²,÷Êg°¶ nbÖóú4îÎqí=ªLR*1HòÜ!IŠO„Tb“á‰Rb‘QŠG†¾k(ku;àú~^ Äx¥•É£a¸;­èÉ3-j¬µìer"mgk•ÎÝë‘äñ†2Ñ,Àu#£ Wã™onài'®â5©)Jm²ÆJ¹•ÈÊâ9 ¼}OÁujœ:ô7fPkqN$öÚ÷d[H”Er¹YJ#+–Å\¸,r[;A”,RƒãÌÄ5š‰Z“=µ‘ÂÛÂFiE­¶ÙHîv¹™Æâ}Ò°îhø®¥Ùeʽ0¦D‚ªz³¸é´‡ ’Q,ÊÝÑ‘¬Èˆ¶l;ìÝ4Íá‡ôæí?BÃrµ*5:ET8î^K‰SªN±i5"ÉOt}Ñ8[;‹ž˜Ó^/ÃØ‹hæ•F¨î©tjY±PoRâ5.j£¦×RH•µ +¤Ì¶~²BN˜°]P,bvêî?Fs ok’‘ÒÕ=ºMÝ©4’Œ¬E´ˆýÑ~» xR“@¸Æ©C©Ð«”øUVZf¤íMNs6ä5n©Ë´’S†œ¦ƒ½•·»Ùä“¡ÅKŒÍOÓ bitõÔ£¼Ê’FÚHÌÉOåJ¬GÂV¹Ó"3’Ę* ™SŸD¥!qd¹.F¨òJÛ5ÐfYfÛ‘q :ÒÃz5ƒ ê¤Êj%M2ê’¸íU¤-JK9ø“#JNæ^äöwF2õ]%`EU´·)ŒB—Q‰hñÙ¦Úän:ˆŽ´¤ÐYO1§iØ»¢Û°ì_DºkIT:^$t›¥È‘•ë¯!(ò™¡}âR‰)þqÐúJ£ájM:­ ¹¡GbQmeµCK¼VàudYÙtf]ãŃåQaâhq5u*BÿKŒ‡…-FGcI‘ܯrÚW2±ì!KÒv‰ðm&£'b\KXLˆêDz Å:äv ø“q=ÉwŒó«eø@i,W£ýéÑÎÆÔê±ÔáUÔl¼‚«8¯‘{ÙžefÚ••ì^ä¶mæô -ÜaEˆČR],êu×Å»¥9JË=bJ2þ¹¿|Hz“¥E­Q«˜KESÔˆN³YiÕ—èØqµ¤ÌŒûÄyRvï‘/ŒÄ>™iU:T1~!­×h°ßRÓU-I'XIY-¥iRU™ Ê"IÜÎü`=Ptc„acœ)xö™Y¦T*ˆ‹.6çS2лžV—>± qIÕç;eÎF{cIš)¥VôáÖ¶ ¨ÄŽó““ ”5´Õ-¤2Í•ŸÓs6nç€ÎÆ{n=KÒN —7MQë’µG«±2}eºiÄ[Œ6¼Ú¼¦Es>çƒeÒ|°õHÒ~ ¡éýxú—X~­O­Cܵ‘ Æ×’†R“,öÖ\Ú#;pøv\5Þ8Ñ|z> V/ÃXª&&£±,áËu¨ÊaL;°½ÊŒî›™ïü$™\ŽâgPêy§Ãư³šF†š”èª~ ¦¬œtÓ˜Õr%šR’$Ü”j¹÷VOs¶Ö˜4‘©€äPb鱊äM}&´%ˆqši+JÈ—vIÅ,%µ*">ý‹aæ±6“pDΩ|/Œ#VóÐàÒ—L­ÊñdpÓ$ˆ²3Ÿ¾#i–ßÔ`!St*¦ð¾"Ÿ Ój|6ƒ]ZœÃ ÊÁ)FD騔¢$«a&×I•ÅúF„ឣW1<§aõÖ˜×ÂCñT¦-”–’qóRPÙšL¶ÐW21’ÂØû ÂìѺªÚ¾¹wNô£º{§>êËÀžâúÔ{¼¼?¨í›Ñ.ð SaÕ1½aQH¨Ð*tâ–Ë«4ð0´·ú4f¹’T£##±Û„ªbih­â983 ¯%Ö”ëkGrEr3Õºµ³~« ” }£ÊîÀ/bšÄÚ=O)&ˆíÃ[ɘH$e$©;}Sfy­ü"ïÜ[èVub¡ŒiÕšëI8](7QÍÖ%%ųf#Jr¶G{Ù\,5Æ&‡M§×$ãÕʱ³-LÒŽ¦uÄi#3È£3MŒÌ¶ñ ÙHÒ¾¨¯Kµ*¤•S_İÅ*:™ZÔæHï4’3A$ö·{™Õðh¿:“i¸fMU15™Sb™<‚9‘[{V’L…/.r;\’W·q …´wB¥i#ÅÄth3â•TétƦGC¨÷·$æ$¨Œ¯ªB6ÿâ1­ô)‹°öÀG¥Öj–ef”Qéíê\^¹ÍT„ÚéI’v¸ª2-¿¨Äò¦,ö#ÑÄ©• ÌÜ=¹œ?ô£‡¹ÐfD“5žË]7Ø¢â0§4`ÍcÚÌš¬,1…蕉L¹'s‰EžQ%¶ÚE¶JÅn‘‹JФæô—@®WX]6¿É*Ì0kKˆCJsÞÍE·bvfàQÏ€g©xÿÕ iWª²)ÔœC\~£¨ÔUºE™ä©9›"%íÕ¶v·|Èì2HÒ® N•p q¦>ÖÂp_‰¾0¼ÎšãD¬‰#U»†Ë‚÷3ØD/WГ,P±LÊF6V†TáφÜE£"˜îk3¶l©QšHŒˆÈÓ›`ÓÃzal}„ávhÝUlrîèÿGt÷N}Õ—=Åõ¨÷yxQÚ¡\A†pæ7n^/£EªÒal<‡â¢A2fddá!DdfF›lÛc;qKðŽÿRv/­=J‚åR=a¶Ùš¸è7ÛA®%Ò— ³wJØGü#ã1j³¡-îÓ-G]skwÒ ¥îíÁmU‰ãË«Öm÷žÅî¸6mÊé èÒ‹¢†ÑäÊ…IYÉ”û²RI›) 2º’“?zBHˆeÌÎü3ô“¢ª®”°Ö‘fbY±&D§*#°w¹Õ%…<ËYÒý*“d®f“ØD`5Å7BñdaìUZ›ŒãÓ£aÚÛô·–üCJA·JÌÈÌ—±J¹‘öÜ£Ú]ÑÊðóJb´Åf™YŒr!Êm“hÔDI3ºLÎÅe Èïßï ½wa9:&ÒU жj…k½>žÎçtµÌ)öKÌi²{”(ì£#ÙÁÀ0ZlÅØ{à ÒèÕ Õ2J8õõ.#Ræª:mu$‰[[^Ô™–ÏÖ@2Z¤Ði ÅI«PiõÉf54yÍkIš%žSØfzâÛÞ˳„Äž¯£bîxˆÿXÑT¬+…«…'±‹âR"Ò5R#K$ëj(ý)¡ Ì´žk!°”wYlãÛXJZ>f…‚gU*Ó©3ðœ7㮚Ì5­3”¶‰¼Ä¤÷%Á›º·tgôMN<ˆÆÕ¬IP™Fžá»*ƒ * ÛqÕëTM.ͨ‰$z¤ð£ažÞ œu2àz$ºÕ:·‹â±%š›¯E£AÑ8‰+m¥-×”•l4 ’i-†Y”\Cߣì+‡]ǺY¬J¡Á¨u´äÇ)´·#ŽfN>i-Yl2-ZREÀY¾àÑ&š™‡ˆpÔSFÃ1)T˜‡TÓ\\Æ–T”åY)FF¥X••6<ÊØW n‘päÝ0׫ÎVœÁì­ǧT¨”òÕÉ-jÔ—e2´(ÝZÉIQ’wIpÒ OTf¥RØÂ8ž•JfXŠ˜R$Aa9[eâKjVTÿßH­ÿ‡õ˜Åè~µ…é¥Ã{'âÉò[f˜Ô¸éz"Rf’2RMWÌwVÛv‘\^Óö=…Œ¦Ñ)ôɲª0èÐõ'>KzµÌyYuŽåþ Dì?×ú†K©Î³p¾ú׫øª]|ÛTjY»OzJc’“Ýå]Ê•îLöÛ½´S€t§÷›Tñ%Nl¾ "3PÚˆ§5.4M'*‹bL’”û«m¿{h~¬6MUæ4˜nAJZJ3‹5)›(ûƒ3"¹—íÞ¿¨KãÐþ¦™èÒØ¢¨u¼KT­)¢iSæ=(Û#¹#X³U¿šãtõ |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ$ï ú .§R7 ›N™7WmfçaNd½í|¤v½þCõ%ùˆÓÄÏVuÏb… ÑálOɺǹìŠO âŽMÖ<…Ïd|ÝþþKS0Â([PΞÅ<›¬y ž¡Aá,UɪǑ9ê×íW<¢]"¨êÀ¨P¡žIßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~¡NÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=^ˆúBÆQðY`Øõ×™¡’VÊÛhMÒµ”“Y'9‘šŽägm¶àa!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTx‡¬ŒcÉzÇ‘¯ÔdcKÖ<~ ì­wÁ¯íŸ#}=Qà²1%ëF¿Pu‘Œy/Xò5úƒ²µß¿¶|ôõG€HzÈÆ<—¬yýAÖF1ä½cÈ×êÊ×|þÙò7ÓÕ!ë#ò^±äkõYÇ’õ#_¨;+]ðkûgÈßOTxo®¡/Cúšg¢CHU鳩×¥q¥!(RÚ_ºI)$¤ßˆì¢ÙÂ\´nþ¡/Cúšg¢CÃ]5Q3MQ‰…áÜc£/޼yõMÒœ3ã/޼yõMÒœ9B\;ÞôÛœ"I;ÞôÛœ#õ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L)1IðŠŒR|#Ãq*LR*1Hð×Í`úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰…&)>QŠO„xn%IŠEF)ù¬ ß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0¤Å'Â*1Ið Ä©1H¨Å#Ã_5€ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ$ï úmÎú–÷«ÇÎY׆ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_w©ïG8GR1m[Ôª´øT§!-%fÍ/)Å(µš¬M‘$¯Ãðs»£³j‰®©œ~~ÉŠ¦ZoV¾/Úµñ~ѹ4…@Ð,,:N ÆÕú•y½ËK*Kn]Ä’îg5º-¤\<уñ&&¯P¤bJ%V©“Š9ÑÖÚ\$êV¶ÕcÌiJ””‘“cͳ„‡/ÐÓÅ]S1óîÿƒ3–›Õ¯‹ö†­|_´n™:'ˆõªKÄ“ªÌRº%6IJ†˜gþËHKÄ¥%Ópõžé)$]Ià"U¼ýP—£=ï› Ù 3Ͷ˳ÝSh¼µ¦m¥²<Äœˆ#¹Ü¸v÷‚›:ZªŠwNgäf¦žÕ¯‹ö†­|_´mM hÆ&3ƒVÄx޶T<1G"Ýr‰$kZŒ¯‘7ØV+\ì|)"#¾Ìž•´ié˜>6Ñö3:½5R7;‘æ©)|Õ{ ²¡FdfWI¦ö;ð ›h¹úyœÿŒôÎ Î2Óµñ~ÐÕ¯‹ö¦ cÚM^Ÿ×>šÅ1ÙÑ#ÈTY‘ÅÏd–ÌÖiÎg°¯°ŒÈÕb;‰Å/©äëU,m¸Y®SØ£6–iPç=rdËTT»«qm¬ÛJIKkil4¸[HÒ«V«ZJ{÷ÿ˜üö§59ÓV¾/Úµñ~Ñ´1–‡4UN¯L£×ãV—Vz1çdÄ\[k…!´¶£w9$WQe<«±ØÓ|U{EZB¡a¢Äul/2-3*T§T¤›#à5 ”kAm/tD:S¦ÓUýÞÜs„n”V¾/Úµñ~Ñ?Ã#Ò6% ¦»EÂòeSÖFmºn¶Þ°‹ašRµ”[;Äc3EÑÅ.OSþ(dz©±[£US³%,‘gŽ•gI£6b×/øEÀ[8n«M¦ŽíÓÎ#œs“2Ôúµñ~ÐÕ¯‹ö… Í’±Òh Ÿ¸cµr¤ºI̽ZM)²Höf3ZKo\öÚÂgŽ4q¢4áz¬ì¤u.«K#7 UÖ†U Ëi¡²ZQªÄv±*çbïÜV½>žŠöLÎ9÷œe¢µkâý¡«_í|c‚ñ6©D§b Z¢É˜Ê_Œ”<ÛÄêfDiSjQÒà½ø8ÈfûéñAá”á—\ª¦2e-”IeDÛj3$šÖKÈ‹™‰FGú‡IÒi¢3¿»çékÝZø¿hj×ÅûFÝÁŵ-'DÁØšŸ*ˆ…Ærd‰m¸Ia3 ÉYWu©îL̳ÜÊÄc‹´C‹éºN•ƒ)TIsY¹"žZÆÖ§!ëV†ÞZ’yQ|»se±÷Šä)4³VÝþÌóŽFjk=Zø¿hj×ÅûDÏhãP17V(ĨÔÞC0·h}jQ$’— FŽ$ºÙr½†bn„t© ‰Ï¿ƒ¦jà•Þ4:ÒÌË)+¸$¨Í͇ü Ûn\$d-:]4cúùþðn©­5kâý¡«_í\W£†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo•Zø¿hj×ÅûEðεÖ>†ùXÕ¯‹ö†­|_´_ìë]góèo—œÐ¢+™l‹îûÙ‹?Uf›5Å4ôZ™Ḛ̀7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœ"I;ÞôÛœ#õ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L? „…b‹Øî?s—ëjå4Óß(ª£Xž#šÔñ¼êmG÷#l®·­O†µiˆ˜œºûª³/aúç]}`ï7ú>éÞÍ׺ÖË“YÜû¬·¿zýñ)‡^!Ó6Çx~£­=âr2[L´‘›†‡OTMÞæ« È‹f¤ïkájxŒ5©â1äý [6ÅÈöû:Æ:­™èêœUÿòÿ¦¯þýÉÿÝÅ.­ªl©Øš‡Œ¡“R(RiDf[o%D·u9b";Û*ˆïk~±ÎzÔñkSÄc­ªm[®+‹œ¦ÌDÂ'3ìoíÌ£ââÍL¬E¤Tª’2ÒU•¬µG’ÿK)ÙÃe‘Œat§¢FŽ0+rk˜¶<¬Vü„¥š|;)­WðŒó/amÌdE{»ãMëSÄa­OŽ‘UºnMTÜÄLæcþÑߎN¯êˆ’ùõUhâ.µz„®œ²Fnæêœ»¿^DÿÈ„¡Lª§¤VŠ0”¼5IîFÅžºúê2ãµ®²’»¶DI3RLX®"+å’àérêÑÆ±œê™j€Ò[lÔyRYa«a}+Qý£ãM­O†µŒí«5ÊæW²LûÂU¼üEzÄk ü;íz&'#'QTÅ]ËCÖý#Á?~±ùÖõÁ?~±•æKÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*1]oQüñë·¨þ ø‹õŒ¨Åu½GðOÄ_¬:Þ£ø'â/Ö2 ÖõÁ?~°ëzàŸˆ¿XÊ€ W[ÔüEúíê?‚~"ýc*#x†M‹G~DxÙN\ªÎ£µÔEß1ÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>5 çH2•ª1Ó)ô©‡Q‡(ªqŽCm²Nfi$µ Éy’¾t-=É«Üð«Tc¦SéS£QTã†ÛdœÌÒIjA’ó!%|èZ{“W¸3à23ŒŒX Ê…9øQ)Ò]SjEB1Èh’gt¤q«+gf”{/°Ëè/¬Ðž´‰°Í!ŠÄd&±*"ßi¶ã7úV™Dbqf£lÊä©-ðÏ6Â;–Æì£ÏW2ÇF phòì£ÏW2ÇF¦Óð¹‘[†’Ïû¢×YØ#Ø[Í,û"»“‡ï³°G!°·šYöC¬ìÈl-æ–}ݼzÎÁ†ÂÞigÙ³°G!°·šYöCtppæ¥P4yUй00fy¤Hz2•¼í&Î2êšq64—Т¿Úår±_YØ#Ø[Í,û!º 88Æêˆf}"-Š}.MŽÛÄ(Èa¾åÇ æI"ºŽÛLöÿ1XJÁX§ÔÚp>2+pÒYâÿtNL8$xõ‚9 …¼Òϲg`ŽCao4³ìˆÝ¼zÎÁ†ÂÞigÙ³°G!°·šYöCtppñë;r y¥Ÿds—U4:\ AN‰J¢RiL¶—ÓÖ¥¥]f’,Ç´í~÷ Þbra¦ÀJŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&'" …þö½‘‘©ñ­:@4ªU ÂÃ8Q©8r—SYÒÜQ;)É)RKvÊîKTêm—à¾ÓÛÁl’U£YÁ®"™9*‰%Q¡·mé~i²‹8¥)Y$l3;š­Á°AgÕj•ÑcO©L–ÄDjã6óêZYMˆ² Œì’²RV."â³jÕYÌD6§6K0Ó’+o>¥¥„ØŠÈ#;$¬”ì+p¦Ñ$:b³…k®b92¥¢"ZÜnÊ3Ršo$µh3ÚDm›¦h-Á¶ 5•Q~—‰akå0ˆš²•FžÁ)ïÓ ‹r8•lGdð&èRºµÆ»ªVjõT´š¥Vtâh¬ÙI·2êÌgaû:·Y ¨3ªóåEgÞ˜zJÖÚ>„™Ø¿˜6‰N «âwðž§DªV†º#¦üv¤8m© Ê’G™$v4¥´¤¶ì$¤»ÄB5_CiÞý]êUá6jÖ-jÝG¶ï§1’®ñÍ›¦«vinRšªNnžáÝqS!dÒŒÑ{ü‡žT¹Rõ[ªKÏêZ&šÖ8jÈ‚àJoÀ’ïlÔ+ªÊ áúEr R—*‚«ÒØ`ÈÏZ¶ÑHZQ³nÓ"/ç ÌQˆðÉÔ 8”±µðŒºóWŽÊ5o3«Õ¡”¦í=¬VRVe~‰]Ñ÷L±á·£:\éQ[)DÖHï­›¬š[LgJUkåRšMȶ¶W÷%m…A£ájèÞ-.•º—žF℆uÊùJÈ’Ì{Oiñ‰UIøN«KÒ•§jÙÔË[J}Òm:”#"M.‰-›¦¢I•Ô¥‘K˜–»Qn³†«nVU*½…$¶ª¹@)iÝvÈн£jŨ%É+îÎål¦{zÁ° N§ÃôXÐêj›ª{hnIŸ ¸’M—ü÷”Ì7‚©qÎ53 Ñ ²fʸôæÛI›.­’’.áÃ5§ä¨ÌÊÇ´HÖXmÌKBÃîb8¸™ó‚¬{. Ò#…3&¾ìeš–hÖëÝRÈÉd„F“Úg‘ë§îÞ¸:åNN»÷ƒ­ÝÎίSº÷6|ÙuÚÝ_úMóåɳ-¶•¹([qî[›tî½Næ,šýv»[–ÖÏ­ý&nýÕï´XÞ|+×\[ËK߬™7Çq#tåµ²ëræµ¶Zà 0+¥z@r“YÄuHqê³§Ã¥9ª{ⶇT„ Í&ûr[J3+ZJlÔ…&ÛH†g©ÎˆšÁÛ¢¯2¥®¢Âu¥,–æIÆlµ(Õ¡Blv5æ^Óº½$‹F‘kÏWãQ)LUä'+ÓÛ„„Èp¸”á'1—Òbõ¡²ûJd cRT‡Ñ*YK®¨ˆ”â‰$WQ‘Ô{NÅÄ,ÆìóŸÙ0Ý‘þsû&ø ²?ÎdÃvGùÏì˜ à,nÈÿ9ý“ Ùç?²`/€±»#üçöL7dœþÉ€¾ÆìóŸÙ0Ý‘þsû&ø ²?ÎdÃvGùÏì˜ à,nÈÿ9ý“ Ùç?²`/€±»#üçöL7dœþÉ€¾ÆìóŸÙ0Ý‘þsû&ø ²?ÎdÃvGùÏì˜ ã€ú§þ<ñþ›ÿjÐï]Ùç?²c‚º§þ<ñþ›ÿjЬ‹ŠÏÖôÿðf Þ“›‚\žÕ^¯Išª‚š‘&™ /:–‰´i5›­›iRÞ<Ùvû’ªµFiORZ©LnœúõŽÄKê&\VÎéH¾S>å;L»ÅÄ?)u:•*AÉ¥Ô%Á|Ë)¹å6«q]&F+4älMaGÄ/TXYÖŸ—PDfX˜Á›ÉIJKDâ¬fZOº%-KØGqLY•$é_Mr©ºTòâs’Ú˜~C*´(ß#33Y‘­w2R ;LŽç¯Ù«UX©MšœÖç¨ÌÎJQ:f|'œŽÿ´Z™>tÉÇ:\Ù2%¨ÉFû®©n—æ3½Åv%Ÿ‰6»W¬Óäâ(U¼PÍÝm˜ïÈyJtÒ›©(^Ó,¦iQ‘qøGæ‹Ûºwô¿á,c$bü‰ìÔ$W*oLe&–¤.ZÔãdddd•ÜŠÆ|c+¢†ÜwH¶šBœqjq)JJæ£6×b"êŒeT¬Ö!³T™‹J;Ò Zh:†I«²”YYuºÕ%´¿|ùr*ÄŸá Cc‰´X’`Õ&ꛫ×Úšša@Lõ3 ë,jÑ(µJm §*Ì»³=^Û™™ìYx{Ë­oܬ=F~«vÏv»OmOݵ%Mž°Ó›¹RRe·a¤Œ¸~U0ö ªÂD¦¢ÎŠÜ‡$¡‰4öÜm/-fµ¸IRL‰jR”£W ™™žÓŽv0¨–X“K©"4C…¨þ&z1pÒãµ!z“¹%nš²§?èУî¯Ü¥[é”)¶PÚÝ[ªJHÅ‘fQ—|ìDW?ÔDCü,>úd¥útS.2bH%ÅI“Ì'>V—rîZÇ,“ØYÕ³i[BŽÃl0Hi¦ÒHBŒ©JH¬DDE°ˆ»À=@,nÈÿ9ý“ Ùç?²`/€±»#üçöL7dœþÉ€¾ÆìóŸÙ0Ý‘þsû&øâέ˜?S·þ;ã³7dœþÉŽ2êÖ2V•à(Žätf̹÷Àu CýqÍÿBÿI”5VªTd’hU"i/™Ñ+›}_é6%wSv±] "ÖŸØÄ¢·‰¨qj¯ÇzzIÆÔIY% QØ®W"2¹~Áƒ®Tð-v)E­±OªGIæ&¦@7GÇe Ê㟵d-ìDå &Ÿ…¨.Qä+•*kר}–lkMQ”úÉ‘6‚%H–µCVÃö£bf0ª£UdUâT—[Þèz¶©ïTd Ø×THpâ´ï»Ú­†”_)ÊÒdÔp"(§DLzzifœ‡ 0i½í«É–×ïXXÖèãx·‡{iÓ|Û‡{ sÞ÷¾¯&^ÔDhØ£ÖYGj³6Ÿ%8¹Ú<‰o± É*a4×%,šÎÁ8J±];‚º}ÒDš™*±+Ta?‹ˆÅ D8¥Æ#æ¨Úifó§ŒjqM§U‰H=‡îGºìOCH›,½¯h˜§ä$;ªÕg+#bµ}ÅËn^çƒ`ªeKͪFªÌbŸ&¡diNÀ5¼Ïû‹4]?Ì`!”1†ºôlBöãV4• égJš~¶äu™¯.³9†²2YÂ,§´ÏoˆÆýàÍ˹Ñ7>èÝ:­Æ¬šín·Yl¶Ï¬îópæî¸v_]Ø{Ƃ粖:£>2_ÿËWøÎŽË¨®/ù¿èCŒ:¡nFVû*ÌÛŒšÐvµÈÝpÈÇ[Öñ5-UøïOI8Ú‰+$¡J";ÊäFW/Ø&y^i2*ºMÃ'IE©C¢Õ%@yWʇ’ü"Y •) /’£µŽÆQÚ®4”ÕCâTEµRb‰EŠüeä5ÃyS§4á+:’ƒÈK5‘©IA‘®I;ˆ¼I…W1¹ŠÒ¤´ÚÚm㌳Z³I©$¬·"3B Ë¿•ábgKGT¶RÍ2ŸI‚Ò^) Dzn­$é‘,‰(.êÆe~¦+ªÍÑýY§ÚªÃ¦OnI ßLšv´4_!¨”ƒÍ–çkð_` xåÞ«ö²Ûÿ ‘ÐÝwaï~ žÈç.ª)qçââ9¬ez̪Êe{!¢=‡·„„ÓÌ–t‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##SãZt€=RªRž«5M˜å9…êÝ––l¶­Ê—l¤}Òv÷ËŒxÄ‚ÅÅgëzø32ƒs«1"¢³³ºY£´á!N$¶¨‰FFIîHû£#"á>æ<@&¸®‰¼,í]4ÊM5æ'³›§U“1.!Ä:«¬‰× #k†é#Ìv-ƒÑ‰éT6hU'é´f_†Ö¯{ê°¦›«;­%þ”Ù¬õf¤fàBl«Ò;ˆß ë²Û.:Ë¡ôkR’dN'1§2O¾Y’¢¹wÈ˼-‰ž(©B,%…ã¦)ÕÑ”I’nHÖ6e2JLÒZÜ—3#QÝ&WQÚÅb,F eJdi°Û’ƒ¥Îq³RÖ“iÆã8Ꜫ+™)VUÈÈÏg“=Ù0ÈÑ¡»€j ²™©¤I%/1¶ëR H2Í–×i&G–ûOi•ˆ³¸ì+N«Ä†œ&ΦLr$©ßÎÒžŽÛŠ&.³""ϳ9/mûÖ Ý߉°fÁÔnØr#n†Rû:æÆÕîV›–ÔŽÆ[ J'Riø]™®Ï‚ÍeôU¤ÓZCÎ8†’Ldγ&Ô•ž±6Êáï_Ä G©ÊÁLÓiRaÚa¨á!û(ȦÊ7NRØ«(Èì[Nö0Ü!䆎á7!—Y¡.V“IšT’RUcïLŒ¾FF&8®‰¼,í]4ÊM5æ'³›§U“1.!Ä:«¬‰× #k†é#Ìv-ƒÙŠU½‹¨ôht¸/OIi3\ƒ[däfŠÊtÑ•$¢-©½ˆ®fw3nøz)ÐfÔ¦7 DÉN_#,4n-V#3²HŒÎÄFA ÅJ…K\:ƒeNj;;SX‡ä8h#Q%ÄÊ%šÈ²ÙM”eÞ¹þ>1ðÏÖñ?ÆHnÌf|®"hU½ÛM‡DD±ù1¥¦CŠuz–Ôᓤ¥2P¢îR›—{`ÉÑ Ñ&±‡ªjÃðJœËr °zéqL§2ŒÏ[Ü™¡H4åÊFµm-5`@@d¦7LzœíE™ Æ–¹†”Sif–Ù4Ü–N(ÎäGÜå33ïÜcE€b±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz¼|åsƶb… ÌP¡óz…©ä¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|k@Îr‹ˆ[§QdR_ RêLH’‰ T¥H%fBT”n ¬DâûÛsïb·¥X½ö·½4ê5*œÌ'$8L²O8‡µí¡·Iz×fF„lF[ ûâ46ÀNÄé‘B—FcÑáF’óO™Ç'³¡Æó‘(”·grZŠÊ¹Â#Ú.W1|Ê«SÍtÚdY5#-ß*;kK’l²_tF³Jn´¥G‘)¹€m›o8TV©¯R©’VÃG)æÖ§YmjRÌ’Y²_2Öd£I¨ŒöX­á¢T¤R*mT"“jq²RM.'2•$Ò¤¨»äiQ‘þ£ @NÅ"ƒ*ˆÍ“‡šIa/fiÔ‹:T§ ÎéZ’d¬ÄEÀD{FsbxQêP7¹šiQ)ÐÙbqÇ|”ÂÚeQe^D¯»B”YТ²‹ýÒ€°3ìA";r›%Z<‡µî579–·¾²R•‘öÙV=—½ˆ{¥ã9ïÌ¥KM:™Êlw"6M2¢C‘Ök»KI¨ÈÓg›‘Œ”w3;Œ€°$±:dP¥Ñ˜ÃôxQ¤¼ÓæqÉìèq¼äJ%-ÅÜ–¢²®DG°ˆöŠeb‰Âi½í§75¶˜dª B÷FFI$Ùš)2$$³%$fEc=§|ØñKË%1é¨r¥¶¦äÌŽÒÉׯtDF³B3pD§a™p†? Õ\¡×¡V‹KОKÍ6þl™Óµ&yT“Øv;^×-·+‘ãÀ1=3¼ôi(b•Kƒ"Z ¥FmiqÔ™ÝEcQ¡}ü‰Mø8 ÈzåÏ…IÁŽQ©5£žª²˜~jRÂÛ(ù}Qæ.èõŠ;šnFM¤ûö(°ØÍßÿbo^â…þ³º7V«ôþç.¯=ýÇ~ÖáÚ<`@b±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz¼|åsƶb… ÌP¡óz…©ä¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰.kjqÈIJ²žºs ™ˆö‹I™mᵸx†»ÂÿÆû^‰‰ÈÈÔøÖ†Oxª?*™çh(oGåS<í¥Àt²{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€'¼U•Ló´N”7Š£ò©žv‰ÒŒ`ÉïGåS<í¥ â¨üªg¢t£2{ÅQùTÏ;DéCxª?*™çh(Æ žñT~U3ÎÑ:PÞ*ʦyÚ'J1€Å"ª*Tu½å%-(ÔäâÔiU³'a™^Çk•Èö˜×B{‹>“ö=2 ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ$ï úmÎú–÷«ÇÎYש’3¸ÂÌÛRVD²,×RTJNR#E¬dfCË»ö cTÚvn·6˜ÕQéSŠË/ºâl›CjZ•«RTfzÔ‘wDEep÷³4ªUuè¯?K7iµ*¹éŽo¬—m6ù÷ #+žxçlä¢Ê­¤g´LÕ ‡ù)¨ÍçZ[qÓ+‘w(A­G·‰)3þaJ˜}1‘%L¸L8µ6‡ '•JI$Ô’>2%$ً̻Œ„¶‰#ÖŸT"¢8Ý6¢êÝn\…fR#)Ö–IS‡e%MöšTK>ça¨ªP£hÆŽÛØ~™5GSž‚q÷$ˆõqO?pêJöQ¬„ì¾cSp†ŸQ Ñ&±‡ªjÃðJœËr °zéqL§2ŒÏ[Ü™¡H4åÊFµm-‚'1ºcÔçj,Èn4µÌ4¢˜ÛK4¶É¦ä²qFw">ç)™Ÿ~ádcGHaΦ¶«´f*±*ËCæÊ—d(²¨Òw³F\$}ñÍã覌‘%ÝCj„F’¶¤%—–Þ±-¬Üs*7,ÄGcµÊüd,4gj£ž9O”ÿÿjGRÞ¡$§+I$ñî­ŸàÁ«•RÒdÌ,ö"¬Vãǧºô¥ÕéH‚ão¥ä!;›+MkÙ27.²%¤¬Ý–yÄߨÿ]ò#˜;Yãøý¯,.„Et¡ŠnÂ5Ê»UÔÊ•Jn:ÖÃok,o<”$•ú4Ûa¨øo°¶XÈÆÊÄ:IÇ´Ý(±¢h·wnÌÎé`ÑqÒdJyjÔ¯&d’Ó´ÈÔ’,ÙÐjòi—ý‰Òÿ„ˆ)r° ¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢cfƬ›be{¡­¤·!RTnk¦ÉD’M–H±Ü-©?v|I¶²ÂÿÆû^‰‰ÈÈÕFkZ 7Ur‡^…Xf,y/By/4Ûù²gNÔ™åROaØí{\¶Ü®Gè¦WSMÅqq*==¥Ey3ï)„­$YOk†³²ˆ•c]¯ú¶ 86ÌÀ¯œTÉŽºE:U=÷ò„þ´Ûe{lhQ,œ+ÛÝÈŠ÷±D,Y%Šâê¯S)Òï ÈMÆq.!–YZ ³J µ¤Ë¸RÊægîŒýÖÑÄ Å ºšEfMEš==ô¾Ëì”gíSHu&…r¸K÷ RHÔ£;øle]9O¦¢´ªeA¶Ÿ\ˆç1µ¯RâÒ„¨È‰D•\›FÅ’‹¹àá@ @”ËŸ “ƒ£RkG=Ue0üÔ¥…¶Qò"ú£Ì]Ñëw4ÜŒ›I÷ìX-ßÿbo^â…þ³º7V«ôþç.¯=ýÇ~ÖáÚ<`>ŠèÆ9KÑ|8ŠuæIæßlÜeÃCˆÌã…t¨¶¥E}†\>u ‡MšM ¨pñ"Ya¤åBOb.oiþ¾ø‘Û¸w"™\ßÉø‚µ^¨¢2â0õEL–çejB–„%–ÛOtm¶f£#QäNÑ{Õiôz¦T¥"39‰¥\ÍJ3-„E´Ïa‹¼F|8³¾•¹Uû¾7Fô­Ê¯Ýñº1¦ºÿÂ^6þîï²5Ö”**š:Òløk£»½Y”Ó{<‚=†D|$cUvwÒ·*¿wÆèÆ7igHš…"‡\¯îº|œºæwÍ•D´÷IAwI#Ø}áNPp@1X³à ?cÓ!ÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>5 çH‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##SãZt€Ý@¥È­U™¦E[HyìÙTá™$¬“QÞÄgÀ\C`ö ÒŠÕäïôb-¢ßöîý/øK@qæ!w ÐÑ*<ªU2™‡½ªÝ¸¢I$×eeIe©V;% ;€q?`!ø­^NÿF‚t‡âµy;ýë³Æ/ÕYÑÍJ–¥Ä_ª­™ÑÖ”©IIS¦º¦Tf]Êó)#2±Ý\dy-ÖäÕ4I…±rb&]$ÙÒVIm&µÇBÜY‘%%s3ØDEú€q—`!ø­^NÿF‚t‡âµy;ýêèZL£Õt‡O‰N«¸Õ¼;Q©ÏÝp\Š›6ô"iòSÈI›y\~ËIä=§sÊVͳ¤Œã^r|ȉ‚Ò_|¦S%FQ2¥’ Ô¥ÖÒklŒÊî$)á3"Ú»éÅjòwú0ì¤?«ÉßèÇmb,]‡póËf¯Q(î"6êRI•¸dÞ± 'ܤû¥8´¥)÷K;’Hìvõaºõ7Á\Êj¥dmÓiÄI†ìg[YU6êR´”“ÚEr207Ø'H~+W“¿Ñ‡`!ø­^NÿF;ÜpG`!ø­^NÿF1Oè·°òØ~U5§[Q¡h[Ž’¢;6¡ƒUãgMÀ¸B~ ¬Ô‰4©§• ²YË*WÚ£à/Ûb#1—"v2®x}+ž_°0øçÖpmMŠum¤µ!øå! ,Äy kFÒQ‘Ý ØeÄ}ñÑx‹J04‘ÔÓ‹ktiÒZ^ôHfd5¾fäu›fF…[…&Fv>#úH ýZßð>¦oüwÂ$hЀb±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz¼|åsƶb… ÌP¡óz…©ä¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÆÞø]ªÞªTب­ຄ"Ç#Kä¦Üs¹s5ÉD–]<¹vÙ$Ff{1õSŠ—„haµbœBÅ0唤%Ù&Þro:Ò„w7+™­IM¯ß¿xÆ>%*eN¢ôZ)õ2I¨ÐME3tÐG±JB YvZås"ã1çÌc4ª£Ò$Çf›1Ç¢6§d¶†je ÷JY]$W+™ðÚ¥­J&Ž©Kž,Ín˜êo9q–b+ÿ0dx€I©ØF¡SÄÏÐãSªÑ䯧®KÌ= FòVˆúÃI ¬d•¹d¤ÏmœG íºÕU4—hµ&ê NdÅTU“Ê.2E®eüÁº4½4JʪåGM" u#½¡”eëŽÅsî-›€Œø8{©x^¸ôš{²píyÈ2žJR¨Ð–jy65(š3+)Y£/ Ï€Œ3ß‹Y¨0‡àRgËeÇ·:f2Ö•;—6B2+²í· ¶<ØS Ì\)±$F’ƒ"S/6hZLûÆ“ÚBr,Ë?†1#¥?‡ªÍXT…á8›4›fpî^ä®WW\…8JŒþ"ÄôÚsq+›% šÐѸm¤Ïº^Rá$¦ê=¥°iÌs°ÔáŠÜI.·VÃÕÖˆH4”%¥iJRvpÉE±²Y£2»Ägß°òÃÃÕù¬°ü:NKRµ²¶¢-iq(;,Òd[I&dFeÀ|!˜ÀÇéUF)ÍÔŸ¦ÌjŠÈÜ•°¢iJâ%XÏaìýB¸tZÄØχIŸÖ¾Ôu­´[‡2ˆ¬_ÎM¢ßöîý/øKÝŒpYâÌ[L•V•%º5*;ŽFn FDI1ÎàÜ5²¤(’–³¤¬­ºåܶøGE¿íÝ;ú_ð–6í«¤­ «W‹Œkªf¯ZÒª“‹ÎK>à¯c²[ZŽæV"¾ÑÖÕ¯ÔÏ~0åvïéã¹½èú:¨Q11Ùm«S±ëL7.cÏÉFº¦Fw3îûévêY™ë¹•’JËÑðSå ¸z:ªKm–ETˆÆjJU¹I•­"3+ÜÊäGÁÀ9Éʦ[Â(ÄËÆ5„Ä\´ÅCgTZ£4¬ÉdW¶K¶´Þü)=ƒÏ*µ¤Ø²"Æ“VÅì?,È£6ä‰)SÆfDD‚3º®fE³Œvá'Þq⣣}õ³¤zž#Mb£+ ÑäFÃ5 D7éκúÓ)õÆR$VÚ’FÅõw<¶.éY.—„%aªãø»HSéðóTtÉ陉§T’â¤=ʼ¢JJõjND%'u$»»–]9QÄH§4ËÕ Þ,†Û噕¿*Cdáq¤Ìöÿ0õÑ+XÆ£N—PHµ dh¯4Ê—*¡,ó-ÂqI"&’³àiW½»ÂxIÆrqqœa¹p ©ÈÑ<•ÕÚf­X¬5ÐÝ`ÖÙ¢ -ÈËŠAgmÄ ³šÈIyŪÇk žŒ(•ÚTZô²unÌSÑc•AéÅ “B™)‘8ït•ªê"¶|¥±$9…5Í#<‰/ÀÄX¢|8ês4¸Òe)“Kv5*çc""4™æ"2%È®<Õ,]ŒâTdÄë³§RòÛ´‰4ée3+-Ï*¶mMÎDzæõ8¸èí K×¶3åuÎO{A×¶3åuÎO{Bx*º£Œ§£¶†žª×qWWüä÷´: Go½'GÔ)2^qçÝŽâÜqÅ”µî¨Ìö™™í¸óß±6¢&eÚÍø¹3 }¦jÞ.™¢lUnŽjtèë¥HÖJr¯MZZ"AžcJdƒ$f}â3Ø Zßð>¦oüwÆáÓ÷Ħ0ú¥ÿDÆžêÖø×õ3ã¾8Rï-È+|'ìzd B{‹>“ö=2 ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ$ï úmÎú–÷«ÇÎY×RHøHešj\)˜}I§¢©ú„E•%&„ëõ’Š:³+gsž:ˆûÉ4†·a¾¨²Ù’„4â™q.l–…줞Åà ¤Ni´œKJÁ˜À« L‡ø,¨š“t›Ë)‘ÿH”žÕ™‹gt[vˆöŽÝm aÇÞq-´ÝV*Öµ‰$N¤ÌÌø…5Dr ?™JnN]Òqægˆ1$ÍÅ«*s“b¹ ˜‰ÄäN°^İñ I¡Ïmç©<Œ›&n™nGG“ÝÜBH̬£UŠæ,nZò4e‡Õ %@›“^”l©¦—g]ÕÆKYL‹jIt“nJˆ¸ C19G­HÄšSJáOq¶¥™jTim%5•6| RKQÈ%l¸ª# ÔSA›I¡b)h‡ :. Y¶cÅu)-i¬…jIFjVÛæà2°lJQ4ŸÎ-“M£Ó¦´)Éeª åjÉ•UeW¹3Ë´ˆ®D"àÑ@@›E¿íÝ;ú_ð–6f¯7D¢I4W+}!¾–G•æPÔ”:“;ZÆN¥&\&JÙÀcYè·ý»§KþÇdÕð&†iއj4ÄÇ©ÖõÛÜʤË2{RI7;¢VTØ–Ÿte{Ø®cÑbí4f*öáÂýª«ÄÓìix¸º›•¹Ù­Lv-?1¹þ23–kšœ#;Úæ³;pÚý&±G¤T©dö!ßT"‹RvA2énv›5g5’FkVb3$’‹ôe´ÆáNÐʱ¡àÔÓªé@:‰Å)2ÎÑÉiA¬×›)e$²ß6Ò;[hÌöÑ¿'?¾ÈéiÔZýÜ#Osös$JÃg†'±=ÍÙ)Ê´IiaóY“©J$¦jI‘•ÍM‘ÙD£¾Î —ªŸ‰Y…A¬&*\IçC[Q ¥2M¶Ô‚Z’R5–<ËFÓ;÷Gm—"éÃz7äç÷Ù ÂÌÑÆããŠ^ëK6ï¦Ìº7ÆAj÷;±Q“.}¹·Mïr¶N¾ËN¦Üû%¦¹ØsåJ°R°tJ~¼’ùÕeËÃmêÛ"[qÉ $¤‰WK„D\DFBÆ6›£Œë•NkcJ¨Èy•å2Ì…8¥$ì{JäeÂ:“°Þù9ýöGH†ôoÉÏï²:@U¸öJ'Kr}°ä@wØoFüœþû#¤Ãz7äç÷Ù ·GIG _Xr éÝ|[aßøEŒàÏvÑ¿'?¾Èé-ìT}KM7H5Ê5‰‡*˜Õ°Òq$DkŽµÌŒî¥¨öñX‹Ëª¿M؈‡£Of«s3/Í?|Jcª_ôLiî­oxS7þ;â¤| ì ^›ˆô£ŠæÒ§¼¹‘qO6H<ÈIR,ÇÀ[Ki–Òá­oxS7þ;ãËKÕ-2TJJ²§ lšZ4’Ü~Kl6“Uò‘­Å%7;Š÷;·$1 =8Riµ)Té­j¥Eyl¼ŒÄ¬«IšTW+‘ØÈö–ÁçÖ˜G©ã ×ðôZ¾³skóþ‹+«Ë•jO´¯Á~•í`Â~øNôÂìžÖ 'á¿„ïL¬Oà ޘHã`“ÚÁ„ü7ð郵ƒ øoá;Óã`pïS¶ iÃmɶQp–©î”x+š Ñõ“"¥2zõ,'2‰ õÊÆ"øÒ«:µ†eÓ"áLL‡žÉ•NS”I+-*;ØÌø ˆQg=uOüyâ/ý7þÕ¡­FÊêŸøóÄ_úoý«CZ‹ª™•nlÑÙešbÒu9홿MŽò­«ŠwÌ´‘ÝgÝ^ö$•씑~KšÝE2•‹M›èq__;)O6•¨‰Ã,豨ÐY 6ËÇq„¢âZÍ6ç§Éi´†ê q›qM8dDkmKI›j±'jLaq®Šk”ømE‹-²C7&¸Í-Ö.wýŠI­½¦gÜ™m;ŠmlQŠf%ªSc8n±cÌ6³;æJi#þr!Ž333333Úf`/¼º–¾)¡ÿ¼ðè°Ž>’¡ÃÃxƒU ¹×+ÓªNIe4­[$…­·õ†Úò´”’P•f"΋ùº—\m'†JZRwFÃ;Ü4$xGG˜C Ie굘Éen8ˆëÄsžŽj^læ¦\}M¨ÌÔgsIí;ðíÀ2ªhFŽ1;µÊ¬¹˜Ã>ûE‘1nGF²Ò‹VÒŒÐΩm%²ÈI¹(ó\öŒö"n·XÅø ×j.Á)º´çN1èªy >Ê"6n¤Òá+S –²I‘Û;];z‰ƒp•¸åf š–­fLÓq¦5ŠÌ楥,Ûg1•Õ«Joß• „¦Ó§»m´ÔÙÚr<÷˜y§ßqÇZmiq9Ôë—"Q•kXˆ€A(2ªxxW Uk•TÃ=ý×ʉ1qdMÜQŒÎ´i_t…›‡”Ë1§nËœhš|Ú†eu nL~4ÙÐJK–5¾ˆòÞa·eÂ¥!´¨Ï¾gqr¡ƒp”Ú:Œ¸e%2Û‡qÌv+±û“Iäu¥¥ÄÜŒÈì®êç{ŒÍ.JK¦5,(­“L²Ù‘% .ÿý÷ÀDôŠšÚ¡L,8í=ª¶¤Î"§´µÇ5’Œì²B’«Èö^öU²ž¤À•m+×0~%¤j5†ÃqdÇ+‡‚Q)Å(ÝZI½†I±{æ#$å5íkˆqQÙ¡Wj”gaÁSÜÌÎÄ­„gc. –Ûp‘‘F+•ùS¨“¡3„±J\‘Æj§’dWÛÁ´Q.|êšø{ÿ÷R¤èÔãmõP4ë“ °ûkiÖð´4- I’’¢[¤dd|CR ¢@¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ1¸ðÝ9“ÃnU 'JL•¶üu)ܱZ$ Òâ’Ò’®èÔ¢ÌgbÉúÆ>ªqRðŠ€šPàá|AˆÉ¨ì•!„Ñ¥½!©N:¶Ó%¶^Qf‚Rò&ÈrÊÛÜ,»­„¬THÏT܈Ö#£ 3­\Å)æÚµÈ²‘-²qJÚ[ƒ>à#·›pÀG²ŸÄÔÊ"*4ÿûS&â™™ÃaÜÊ4'²ºÒhÚ’±ð؈Ìep¦€þ%¢±P¯Ñ$4ýYˆrá6óÚÒ%™§¹EŒ)£:dJZndGrMQÝXƒ ¦-fP–FjTT<’Gê=kh?ù\e)ØURè°êë®R!Æ–û‘‹t-ÒSn£!äQgÂKJ‰Et‘ti=‚s:CUÂS©±g-ù*œ¢)ЛqFôr5’ Jîrf4‘åQ™ŠäCò~Cê­.™‰%ʼn%եǒgdÉ&„÷³©7áà20Ý>?LÂÒ&RæÔ©Sà7Z"ÌD£q+dÔJ4¨É(<Äf…&ɺ®[RE´z)xnS8Ò‰MLºDÞãNB}âqq$¬É$¢$gÊ¥¤Ðdi+ïb¹†è€Œ?B¥Ô0UJ£.±O§Êf£–×$¤D)·Ô¢³M¬1¥6=¦Zµ_-Ë7Ž7¢”¹5š]>3®)¸ÎIS¥º2ŒÐIB”I¿ð”I.÷ › `ÀH`a)òdUã=2'é-¥éâ‹3F´ Ö…%&•gAðÝD¢ÊJœÃÅ—U‘³‡ê¨E9©+6MÕ-T”6y36œŽ%D‚2U#›/s´n&FVã¦KÑ#5S`Šn­â5u!H2&ÌÒiRLGdq(dž&šìùñe;žšrÍ’£&ÙQ+.SÊJ5™$ŒÎÆ|f't 8 ís 9J¢E¬Z™24É f1F[ŠS™“Zì¤R#ZJʲ®{m£9=Ô \ŠÕYšdU´‡žÍ•N’JÉ5ìF|Ä6`!ø­^NÿF"Ú-ÿnéßÒÿ„±ÞšJÆ`öh޳Ez­¾5#ˆãl¹•ÆšLgä8êS”õŠJ#ªÍ•Fv#¾Ã4ì¤?«ÉßèðNüV¯'£¨ö.€œEH§´¨îÓêTi•tÔJAhi…ÅI*)Y³\¬HïÞåä§i+OŽü†j! “+Vè!…)·œ&Ûu qkhÖ¢-bHÐ\&d[@q·`!ø­^NÿF? ½ ¤®ªbˆ¿[ôc¸¥bJe¸‡j-šÚ¨3Mq(#Z‘%ÒA¡³$‘™“ˆ>"#¹™]`Í023#"3#/ Äìü]ø/ôcÏRÐÎ8§Ó&TeBB#ÄŽä—T¤:’$6ƒZ¶©W²O¿·€t~6ÓFÁuÕQ1>$•Mž–Òé6¸2”JB¸•%³J‹a•Ògc#.2/.9¨¹Pk;­”q×&<Ór¶ÔŒ÷½ÛY£"MÈÈŒ¬De°DJpãQî RäVªÌÓ"­¤<ölªpÌ’VI¨ïb3à.!ámÿ·tïéÂX²žÁ:CñZ¼þŒ;éÅjòwú1ÙzJÆ`öh޳Ez­¾5#ˆãl¹•ÆšLgä8êS”õŠJ#ªÍ•Fv#¾Ãô½‹ 'R)í*;´ú•e]5DÚaqRGÁcJŠVl×+;÷¹ö ÒŠÕäïôaØ'H~+W“¿ÑŽÉ§i+OŽü†j! “+Vè!…)·œ&Ûu qkhÖ¢-bHÐ\&d[FbV$¡Æ[ˆv¢Ù­ªƒ4ׂ5©]$2I‘™8ƒâ";™‘˜ì¤?«ÉßèðNüV¯'£î8#°NüV¯'£Á:CñZ¼þŒw¸àŽÁ:CñZ¼þŒ;éÅjòwú1ÞàAš@#±ÓŒõ°ÿFƒqÿ‹¿þŒv¦1™¸\£T‚m¦ÖâɆÖâÔII’„©gÄ”‘™ðe‚tÑq¥u4L1‰%T§©µ:m¢ ¤’Pž)Jl’’ÚEu\Ì‹„ÈŽ¹K±±égƧ•_bÍJÖ7©ÉM‰²EË*&Ee¦Û-ÃÄ#=qï-ñ/_ö†Äê„u×ô}£çßunºâª‹ZÖ£R”£}³33>3ï,,†ÑÁ—±ŒW_¡ã,Bù´³B›*œ¥,¬I3;&û;¢Ú$}eiÿ”x£Ëg{"[Ô7ïµO÷^ÿöãyѱÚ&iµ„eÓ 0¤¦,¦ödMt¢±%ÆíbÈ´¢BL“sÌIY—¹2(¿ÖVŸùGŠ<¶w²eiÿ”x£Ëg{#§ãiŠÝ 5*²_ˆ·jÕ lx±˜vcïœIO0¥¥¶Pk22g9Ù&I%XÌøO#aIÝšÕn9ÅfšUG2R[LS5–³1•¶j#OºM¶‘\®ŸÖVŸùGŠ<¶w²‚´þEsÄxœ‹þ6w²;-Vª¼ÊKç™ ¶œ‚B¬„»›'ul¦g‘[îEc;\¯ë{Þ—þé€á¦‡tUœäúš$ΖíµÉ).8»]JlÌìDEô/`ì}âÿÁ£E¤"aÜ–å⪼ªtY/­¦]LWÞo9mÊfÚI3+™ÚäJµò°‡©˜Î‡+n©2].F!ŒÎµl<Â^Ê£3±8”šÒJ"ÚDe™&WºNÑ”¸Þ·N“G­N¤M$”¨2Œñ%W"ZiU¾W#A%Ò·ÆŽ,úîgøë¡d=ã*|6¡@ŵè‘YNV™b¢ê‚â$’¬Eô ýqï-ñ/_ö„hI{ ãÞ[â_:¿íd{Ë|KçWý¡^È8÷–ø—ίûAÙòßùÕÿhF€—²=å¾%ó«þÐvAǼ·Ä¾uÚ î­V*õ¹I—YªÎ©HB ´».BÞY ŒÌ’F£3µÌÎ߬DŽ+|'ìzd B{‹>“ö=2 ç¨YhoN+qÅ%Mi©J; ¶˜ÐÃoõ%S©õm(?OªA‹>´·u‘ä´—]–Ù•Ò¢2;ý$B'‘ñßjWŒáséõŒ^ŠÞiý3c·Xu¶ªMÊBˆÈû¹Ýò>ǘØcÍ,{#`èwáúúï ™J×êuÛŠ#lë2çË›!ísµø.b—Ï™Þð¯ FÜáIÞð¯ FÜá©oz¼|åsƶb… ÌP¡óz…©ä¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰±AHrœ—˪‹XjBŒ”ón›*k*ršTÒ´¬•ž÷+x,wÔø_áØßkÑ19ú¨ÍkÂråz˜ö-Šüš‰¿jD˜êjeE¯yÖ_lQ[9‘¨I™–c$^×; 4.·ig2;uºSó–ÛJf|ÊcDnƽcd…¶¥™jÌ–¦ûÊ+Ã8`6ѲX¢9Œ°5IÚý4Ú¥ä)î1Or:6¥8÷rÛmYIYr•Ìîj$ÜÌE0üˆxÒ¦®s3â@ŸBߊ—2­)ZV¬¤âR«•Œ¶‘m.-£àd«pi°RÊ`ÖØª8¼Æá°ÃˆCe³.ד3=·,¶+Ӿ̓§NQ`oÔ6妩%×Ù[o]†ÝCJÔd٤ȵ*3$šŽÊMˆÎäQ°=«Î¢I¯i[UèfÕQ T6_ÿH5ËjFRýrd–Í'›)f2±šn¢ÇHU¶ä ”Úâiêb,xò¢œwêµ-¥²6)4d¡'Ý)63>öÑN¾§VƒUøžc³ãFŸR®3=¸&‡Mf‚)¬¢FNk¨¶!_øs{©3¨‘«Ú>–íz5KB<É—Ïsš%»#)þº3K„’˘³ÜÉ6QÀ€6‰5z—C«Ð%W"DÖO!™keå4êZL„+)%²3Ö¤Ë2Kaìbì‚¡UéÐaª¾Ü¥%ØÈ\¨®ÚK&òÝJÈ›%å_éF•X¶tb(´N˜¨Ñª’±)9YKfM.-:¦4ñ›¤Ë‘ìµH^^â9™þµ‘ö™ap«°¢bfåÔãÄzM9,ÆmÄ:£ye!§lF„(‹c&WQ‘]Iï\Ê>´I1Ó¥S0¤hõ¨k[0N<³Õ¼EJ’ë·]Ûñä͵ µû“Vn­"\¯c(qgë O¨UªƒQ^[M%+rÚÔäΔÚA¤Ï)ÙD\$wè§Î›N”™Tù’!ÈO¹u‡M / ÈîH“âØ°à`L?,ÝØg:sÊtšSh^dFI)²%;ƒ+™Í*Ù°D¦¥PŸS”rêSdÍ¢±»!Õ8³/¥Ff<Âb1@›E¿íÝ;ú_ð–>€bª$ª­w ÎŽã)jWrl‚pÌ”¤* ¨äH±ÕôÛ‰[ob?ØF®Ý Ī»R›aJÌÊ]ÕšÈÒi2%YV=¼61Ðý¶’9ûÔºV«¢ÙÒñN+5Ñð¬Ì=V¦Çd³nˆnÏ\cpVÊl–¡K"ÌFFᤋ)½20V'ÅLw‹Ê¢ÆM-ç%œƒiK}F´#Vdl7•›-ÕÝÁ¨{m$r#÷©tÛi#‘½K ´p†Œ«´ÜSE®U*PRÊ•y¶sÙê¡“Ä…µr+¶I”â{« X¶¶mgà÷Ý?úæÛIˆýê]òV:¨ÑV§=NŸägÓ•Ä"´mš‹¾WK$v>+í+‘ì7%o ÐkuUF¯I‰6]"AÉ€ëÍ’•Ã+fOì;ÌÉB½ÒReÒúî.ÿî4ßú¨i¾ËØ'ù)ÿó ÞÀü•¦\:šf#G{ÜýRœüHß§È—Sc<ªnÇc±÷¸8HDBZhI´[þÝÓ¿¥ÿ b22¸F®Ý Ī»R›aJÌÊ]ÕšÈÒi2%YV=¼61d>ˆâª$ª­w ÎŽã)jWrl‚pÌ”¤* ¨äH±ÕôÛ‰[ob8UWE³¥â*œVj1£áY˜z­MŽÉfÝÝž¸Æá ­”Ù-B–E˜ŒÃIR+j®ÛIˆýê]vÚHäGïRèmé+â‡&;Œ‰ E‡åQc&–óŽ’ÎA´¥¾£Z«26ʂ͖êî`ña Wi¸¦‹\ªT >¥•*ólç³ÕC'‰ jäWl“)Ä÷V2&±l;jîÛIˆýê]vÚHäGïRèuPUí´‘ÈÞ¥Ðm¤ŽD~õ.€Uå^ÛIˆýê]vÚHäGïRèuPUí´‘ÈÞ¥Ðm¤ŽD~õ.€DboùÿèB!DÃt%F«Q¤RbB—WRgºËd•HpŠÙ•ûNų2–¯t¥è|MÕEIJZ‘[ÑÊå­¤š[½yÄ%$|6J["¹ì¹Úçbâ!ˆì½‚’Ÿÿ0½ì Ì$ÓÿüOüfÆ™í+é 4¦Ð©Ôì7¼qhû£"7qÉÏ®4(ö©$ecIñð÷¬ "ÈuPß¾Õ?Ý{ÿÛÞærb±L”†W¬³S¦IŽfnÃq¸QC›Hˆ–NGQÛiLˆö)I¡-ŒÛ—–€ª›² VVí&I)VK‘–­W>à¶Ü»ãfvÚHäGïRèmL?‚ñ½°ÑáÙ¸ŠŠÒ¥Å\—šˆëu »¨Íê”´©†Ëjäk+ð(Z•¢‰òàaØrç@u´É˜¼DÙ!D‰LÉ–SVËEcºuèB,«~‰NwÎǬ;m$r#÷©tÛi#‘½K ¾4M…*xR5ŠÔöjäJ¾èlÔy˜i¤0Æc2#Ϫi W{:—kÞç0{Þ—þéŽWí´‘ÈÞ¥ÐÃê³ddx#aÿþTº—Ñ)8Ž›Q¡× µ:33o°élQ^äw-¤ddFJ+‘‘‘Àâ¸Ñ¡7…!ÃŽÔhÌVá´Ë- †Ð›’R”–Â"""".¡ŸÓ}÷EËu×kZ׈ŸR”£;™™š6™Ÿ|WLøBÖ&FÑn­öK­+Ý<ªIÜŽÆÝiwÅv¥®4­ñ£‹>»™þ:Ähd±]WqMZ¹¨Üûã5ézœùµzÅšòæ±^×µìWÑd1X³à ?cÓ!ÜYðŸ±éÝ=F¿ëú­ÿIK ÓÔkñ¾¿ªßô"yìá-Ñ×ñÿèÿÌ"B[£¯ãÿÑÿ˜R9¦_9§{¾s„I'{¾s„~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&6}&†©°N|ª” \=i²‡¥›†N,ˆŒÒ”¶…¨ìJI™Úضíà ü;íz&6í%é‘p²^¨P›©ÐU5Ä6µ-HS227Ÿ*ÐwIšu~è'm„fGl}W‰xZ•„ç±RfJ‚ú_§½QbC.ššu–êÔdv¹èV›ܶۄ`Ãì¯âƤP¥T ¦¡‡gIKJtÒû'¹¤eB”’Nní¤-'b¿pv#°ñÓ§â3¢U«îÊ©=\$Æ6&>µ­ôC3tœqµ«i--§1pf2¾Ó]Ò!6f›Pwèþ­:Cé¬I«êœ|Ôiuø¦ãIJ–|*Ìj}>•ŽäC¡ˆ*/Vé˜rO‹JÜŽêlÔ7RƒÔêÓÀÝÝÕ ²Úä£-¤a¸AI4Xûñô•†œŽóŒ¬ê‘Û5!F“4©Ä¥I¹w&deß#2h¸¢º¼Rœu“*-N#PÞIÙqq¹&´2eµ´ž©dج_¬ÄÌÌ( ‰#:±mR¡¤®­ÖôIÑH›#5IqˆËuÂOÊ$­åß¼e~¹Õ:¼ÌÝj«6Zêqê&9ǯ4’§,çº2B‰“-½É«e®P‡‹Ëm‚‚Ó©“šBœZVÎC,‰"I¥Y¸1šŠÝ쿬†Ì®Vêsô‘Œ(re-t»UÌ¡ßô$¦š}Ä,‘ÀK΄«7 öíYs¦·£ì6ës$!Èuyû•itÈØ²",²ûžèÍ[;ægÂb"©‘ƒ®SŸ£Ö§Rd©µ¿ K‘ÜSff“Ri3#2#µËˆ‡Œm*ÔªÝ[Kf*R*|J¤äÁbJÖìdÈ$¼qš$ªéî””‘'¾[8xê5ŠÎ®¹ˆäÊ–ˆ‰kq»(ÍJjA¼’Õ Ïi¶n™ ¶wvØP‡ Óa§’˜òwB ¶ÔkÈi²jMä¨Í7ïÚýñ7ÇÃǪvkPÔº&å§5ÊN¶ ZÅ9v£Ì}ÑÜËeŒ¬C ÍR{zIvj¥:ëÏáB\“uF²{ÌNYËû²5¥*2UîdF§˜Ö@%³*µÞçH«Í~sÐꑎëë5­´8Ô“ZÏi$ͤ¸6 u¡ˆÓ%6ƒL\ƒ¡·RgsC$Þ9Ä%‘¡ì¾äÌÑeçá¾ÛÜ&¬ Hä—ß•%Ù2^q÷ÞY¸ãŽ(Ô¥¨Îæ£3Úfg¶âظ 6‹Ûºwô¿á,wUGè©¨Ç‰ æHLXÄü÷×¼¢3KhºË2Ì’fI-§câ+¢ßöîý/øK¿¦*LíWR*M±ebá*/û& d¤™mJˆÈŒ”[HÈŒ¶^ÀhœÔÀe2Þio4ÁÍpœZi%¬“žæ”›ˆ#2ØF´ß„…îÇX7ÄÿÞ^öƺªÖqKëyÐÚ¥ã  ¯G5E– fí<â¾EÁu©•'¼´,‹¹ÊgŠÀobL@ª”/„©ÎrulâÉ•W“PiÖ–Êž'c´QR®í3r%¬H"J„àm®ÇX7ÄÿÞ^öÃ±Ö ñ?÷—½±¯+سb¬!\ƸMÉѢćxÚÕ·•n<Òê«*y™lõd¢BÔ…6õ’w±á©õ:¼Ì[b‹˜ÜÖ°üx¯QñDš»±TõI¦¤ëy¤tƒIj®¼·]È’²I°6çc¬âï/{c/ a6$)­ãÍ–Ûw[¥ÞÿxO(”ØôŠc4è®Íu–³e\¹ŽÊtî£QæqÕ)jÚgk™Ø¬Eb"!®t±†Åti´ˆÕêµZ²®4úl•²ë.väRs£mv2ಉ**ÊaÆ4Ü1DÃS*laÔ:ë)"BW1ܹ”¢IÙ[HŒïm—µ®\#˜:¤"F¦zì8l¥–Ld¡ à"ÜÍÌÿ_|n¨6¯ƒ´5Pˆ±M[V¤ê™&dç_iµ‰³l¥Ã<¨+ŸubRÏiز¥:sªãÏé¿ö­$µ¨í~§Œ)@®èʺ¬ ÐúÛiV¹i²I–ÎÖJˆ¸LÇòêZø¦‡þò?ÀhJˆØcF2pùâÇNzŒ–VùÔ©©Q‰´_2õ„æ\¥c¹ÞÅcâÇX7ÄÿÞ^öÆ’Úð‡RNa : !¹m¤®Pç.œICÄ]äÍ?ÒáКdÙ³§Ë}Ç>E!$D£±[º;ØöÚÖ¶ß”taˆ1N-¦Uè:EÄØrœ$U¢D©<”8ÒRv[ %emñ$öeÛžÙ’dç³Gn!âx­)Õ6ΖÚM×TêÌ‹1©k3RfÕ(ÌÏ„ÌÌVqГh·ý»§KþÄdI´[þÝÓ¿¥ÿ bò«ºª87GtÕEMFé×+[›5ï×qyUÊÚª¥VUb ª‰l)g%zâï{»ßöŒx6ÎPq Ñ1Œ IW9•gbID•å8êy’Fâ‰[.E}›J峄¼ÕZÝFs%U*›”Æ–g$™Šu,§ø%ÞMȶ\’_Ap ` z)Ó¦Óf762D9Mß#Ì:m­7##²ˆÈÊäf_AC•ÊÓåBr±P\Yò™T•špִ̌ÞÊUÈŽç¶ä\Cp2ëu©õªªõ S"KR’µ¸‚#3"JŒîV33ÙÆcò]n³2¢ÍF]^|‰¬TÔ‡d­N¶i;‘¥Fw+Ò°ðŒ@Ê5ˆñ 5WªÍWªÔ_F­Ùi–á<âvw*]ów)ØgÞ.!çv«Tz”Í%Ú”Ç)Ì/XÔE>£eµmî’‹å#î•´‹¾|cƈéõšÅA–ŸVŸ-¨ÛCÒ´µþé÷?ÌJÍ^ª–“TªÎœM›)2æBýYŒì< ¬W+UVüV*Mõ[ªJÝÉ{_.c;^Å{qôuÕŠ7Ë|ºä¬níN£tîç5º»æÉ›5òßm¯kíp @ö5Uª3Jz’ÕJctç׬v"_Q2â¶wJEò™÷)ÚeÞ.!'¥ã„ÓiÐÚ‰¨‡¡’Ó[îáÂ×"ÆNœsI÷Yˆ•bY&ýëlÀ ¦$H &ŒeœsM\‰ Go2Òn>ê[BLÛQÔ£""¹–Ó1Þ]”4yË\;çF=±ó¤}ì¡£ÎZáß:1í‡e r×ùÑl|éE»(hó–¸wÎŒ{aÙCGœµÃ¾tcÛ:@ÑnÊ<å®ó£Ø€W1»r*Ò§c]·ÕfŠEc3™H­ue2+¯b཮|'Å#®ëõíR¦JÇš4C/e̦êöQYD¢µÌË„¸†…ꋨ@ªé’»>™:4èŽî}[ñK®ÑÚ#²’fGc#/¤ŒkàŒí.§|oƒèz1ƒ«Šhpä(­SµP´‘4Úv¤×tÒ{ ‡€‘ô[²†9k‡|èǶ”4yË\;çF=±ó¤}ì¡£ÎZáß:1í‡e r×ùÑl|éE»(hó–¸wÎŒ{aÙCGœµÃ¾tcÛ:@ÑnÊ<å®ó£ØvPÑç-pïöÇÎô[²†9k‡|èǶ<‡IX1ú<†éxË *b’dÑI«²–ÈÏeÔiQŠ÷±ÛZåÂ_>euã'—:/ó±ûC ˆëTçiª§SƘ"Cïá‰#ǧUµ¸µ$Ô’$¨îfgrØ|['Œ' ’hÉÖYÇ4ÕÈÄvó-&ã$͵]J2"+™m3°‡ÑnÊ<å®ó£ØvPÑç-pïöÇÎô[²†9k‡|èǶ”4yË\;çF=±ó¤}ì¡£ÎZáß:1í‡e r×ùÑl|é¯\ÆíÈ«HvtnÜCUš)ŒÎe"µÕ”È®v½‹‚ö¹ðž¿\:Õ!úd¬y£D2ö\Ên¯e”J+\̸Kˆr ÂrØ=Qu]2WgÓ'FÝÏ«~3©qµÚ;DvRLÈìdeô‘|%ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰äC³„·G_Çÿ£ÿ0‰ nŽ¿ÿGþaHæ™|æï úmÎ$ï úmÎú–÷«ÇÎY×¶ˆµjYeJ.iµ”[.Db±P†ØXl¢ÎÄ8*¬ý6œ‡gÕÎ Æ7#z‡Û%²YõFY äò“°ˆˆÑr±íü2Ù/ âÄ»‡ ª{.¡Å°•-§ [#J̳"éZÈÈŒ®G¶ö+Ná8«ÖLÃXYØÔZ.ºM5g"C´ÆVod’ûi##M³P›¬ˆ–w+™ìÜA…Ô’ÔÆrr"³Òz™²Û„ÚóíÕ¤Ö¤Ÿð¶EC!¡l9NÅxÝš-M¼Ì¾„¥'uE)Ô'7rdgbQì¸é>Ö 'á¿„ïL4/SÆÍ?ýæÿÇhtîüTûO·ó}&o¿XZýÛºº7Nà¾}eók3íÍ{æýbDsµƒ øoá;ÓkðßÂw¦|SŒñÄcúÅ=8t¨¸5ìÊŽüg•&kh[©%“„–ÕúUU•d{ÒV3Uú¾7 JÅõ…R©ê¦R±ç"+™’Òì*C¥ÝY׉O2ÚêBP”íI¤D{X0Ÿ†þ½0v°a? ü'za¸0Zm{ Ä®ÌDFÓPAIŒÔuç&ØY¶•,ŒÉkËc3M“s±\‹1À°¶“*³±­™&D …>¸óÌ2¸49ì²ÂÐÑ¢kŨ”“K++ grQ‘‚-#©¯Fz32*̲ì§M˜èpœJžY!K4 îéYµX¶Ù*>1{µƒ øoá;Ó ¤Zæ*Ä•ýâ:‘ÑQE¬Už› ,vœL˜ÉU&r›K‹RÍ.¡G˜É(Ê¢·u{•Ü?Œô¡?`:»ýhüfÛHi”DµÃrVµJ7OZœŒ¯ôdH25$³@0ݬOà ޘ;X0Ÿ†þ½0—ÀÅ5‡±"‰^…D™Q…‹Ü¤;-˜«JŽŒôÔ>ÂVµNV–ÎêWr§ ýÖÏ>Æxâ| YĉꃌYBSg›v#Š‚ì´¨Ü[Š%¤Òʈӕ&“QwJ±™„cµƒ øoá;ÓkðßÂw¦ôh.Ö 'á¿„ïL¬Oà ޘoР»X0Ÿ†þ½0v°a? ü'za¿@‚í`Â~øNôÁÚÁ„ü7ðé†ý µƒ øoá;ÓkðßÂw¦ôhõ2`öHvJœm*,ÉJ\I™_iëNÇúìcÇÓùÿê‹þoúù€‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'‘ÎÝþüÂ$%º:þ?ýù…#šeóšw¼+è·8D’w¼+è·8Gê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢cd±YžÅM µGÜ2^KΤⴥšÓ±&Ns•ˆÌˆˆÈ¬¥|¥_[a‡c}¯DÄädj|kCÝ­9ŠCô¦Ülâ>â]Rʤ¬¸…{,f“+–ùlÜU]— èKk#å•÷¤<ù^öqÔ¤–½¤GÝÜay± fÜÅuç)‰§.bÒc”b^æk\L‘X›ÖåÖd¶Ì¹­mœÍ#U©qN,W˜SÍÄ·"+O¥ 2"5 œJ²+amMaq P ecb´tURtêÈ4M\ˆí¼·K6ot´š’y¬«¤È HÊÃ5j‹4WèÍÊR`Hu/:ÍŠÊZxö¹}v;ø Þ @ÊÒ1R—ãÅv:ÙÎkKrb5!(QØI'¢J¶Ò±ì.!v*­Â“P‡ãHv¥b–©Ù’n‘+5Z…X³‹¾”ü’¶i‡q-:$y5 ³OÆÍÜ¢gÎÆ£;2òìä}‡üÛn¢á°…€LdHOU›­VêQQY}NÊmøLÉI‘¸neý*³5ŽÅkšRgÀVÅÑ곩2ô’ƒqBÛK¸›‘åRF•ÈŽÆG´ˆx€1!Q­TçÎfl‰FOG"&5HKIdˆîD„ ‰(+™žÂ-§q‘‘Œñ ìLaÉ1 ©¬›RŠ|t“ÄfJÌ¢$ÖF’2Y÷D{HÈgðþˆq•z’ÅN—c<„¬”Ûn¯.d’¬f”ØËeÇ¿°NüV¯'£ @ÀMÅÛ–A§Ñe8ᆦ¤·:šÂÛC¦óŽçhÖk±þ”ÓšÉ;!'ß²pk•hÒ§ÊjjÍú‹.1-Å‘-N¡ÃºÈÍD{NÜ%·õ‰÷`!ø­^NÿF‚t‡âµy;ýˆˆ¦3"ÒÅ<ÌìDmÜÿ§hv'c¬ »wFâ{U¯Ý‹|änflù·.³Q|Ý׸áÚ9‘¡Ý+QæÚB'SåM$ôR’ÒÈ„³%²; ÏYZå(òÙÞȑֳpæ™OÄ4ù1›\lGŸ}‘º[£4tGVÒUÑv›B{›p_„ÌÇáa¼4U¥Öw+jš¹§=KSëRwF¡¸ú܆¬¤¢i¤ ŽÛ 5¬jQŸ%õ•§þQâ-ì‡YZå(òÙÞÈdv ŸI£Gz=1 Æe××!M¥Ó4Öy–i#;$ŒîvMŠægk™ˆíGX‘V§Õ Áu)Ž-Êy9SëPó6¶Ô–Z[††ÐhqE‘)$ðlºSn`ë+Oü£Å[;Ù²´ÿÊ4fÑdÞ”n…žçËqÓ´ÕuÙ§žêü7á"1É]eiÿ”x£Ëg{!ÖVŸùGŠ<¶w²kÖæß}öÜÍîÝòßMfè_úÖäÜzËf·¼wm—¿lÛBÃéøzŸ3h‡2oJ7BÏs厸éÚjºìÓ‹Ou~ð‘䮲´ÿÊoPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ1·iΑhÖ²Í K*¤6Òò¢¶§’•·!JJ\4çI²ÞÂ>ñü¥_Qa‡c}¯DÆÕ…:–Þ©RÝzaTdN!¤¦:Mœ­!ÔÙKÎJ#=rbOÜÊîqõ~%á™wQ·ò%>$}ɵc»*§RfûH[htõ§«QšÈ»’Ypø±tJ DÖ*õI"9-Q[õùV”¥FnwiÈ›,­k™ÙV-ƒ'¿Øy­#ЫÍ?TrODw46Òò•´"ÉF´Óej’w5³ÃËÝ[ÂõÊ5;­±SÄLµ¬¤Äi*)‘ì’Kn²§I 22Q𬻳#½ˆy?« ~áÊM ¤ã(µiæê`Ä$³*TII‘Leëf§Ãr"±íKŠ;ì²¼¨4 4j…\ëóY‹ k1Í+§'XêC†•$‰Ó,÷mwI™¶æ3îE4úÍ%U\Br㿟Yim¥1K‡ŽCo$’“RIDZ²O l;þ¡{váTašÅ)‰U¦Ôü¶$Eϧ Z–]Ov¢q9s­åÂVRImY˜žñæ«Pé Q¦Õ)·ê E™9k ê iy•¹}«3%%M-›[a(ïb+ ²(mBœn&©S[ìêÊ9!n¥ÛÙJÌ”êV¬Û Ëø${¼?P¥&Q¢Ö1˜òžbBŠÒ]ZhœI¡JI:¯áŒ‹„eeâ:#0û´Æ'­¨÷éÒÙ})A¸Ó‹{2²Q÷JKëØiîL‹jƒ½ lÊNM5ª„Oþ"™Êª¥œŠÕéGæ²Ô”F‡â BÖ•©VZÉI2m{nG³ƒhÇUisé{—w1©Ýq‘)Ží*ÎÒï•[ í{ÃÚ2§RÛÀÕ*[¯L*Œ‰Ñä4”ÇI³•¤:›)yÉDg®QìIû‚ù]Î>«½_è»×»Õ‘º·N_ÛŸ&_àpZûxn&2;A8ŽU'Ft*E"”UZÍIF¨Ñ×#PÒ[j;Ç\s*(I­´ìJŒÍi".)ìêþ)j«ƒcTéñèÏT1°¦3Reµ!„Óe¾“CŠBTE¬iµ(UÐeîOn»Ðe±#aÜK‡ê´Ä9sÎZ̘ï±ÜA­ R›VfZQ+*½É•¶Ü¶SÔ|UYŸ…ªU¶è±¤VÝœëä:êR IŽ”¥Å!&âõ’ŒÍ(,·ï—uhú.:ÂÕŠÙÑéÕ»(ÍÂiJˆòmœ&^R ·'ÂM©VÛqMazÕ]ªU>|…¾ú¸Ër í1))+™°òÐM¼D[F¥lÛÁ´B4q¢Ú†­PÛ”†¦@ ç(s]Ä•) Q+e&PœVçeydf“QXÕ•)¹e±†tuŽXƘ^µ^©±/yæ<üÙJÄäìñ$2KDE¤£Ç<Τò ŽÅr%‘”\+¤¬Š%AEª>ùÔY7 ¸å>C-JI'1“n8ÚPµ\Í)3Rlw"±ÚDõR5È´GË>\g¥0ÖEwm2¦’â¯k”ûEc;žm—±Ú‡°MR…´[KuøFöÔîõ!jÊæJdˆŠÕw7;¸òOº$÷$gÃb<Ž2£â5âº.(Ã-R¥Jd¢T$¹5!qÖkKˆmÃ%%Q‘°Óc%ÒûSÒN§®#oÔ¤¸ôÇf³˜Ôé2ypÞ&d¥(mµ(ò8v=›HEt‘˜‘Q*”úÕ&5V•)¹p¥6N2ò8GûHûÆG´ŒŒŒiº}áÌm„"GF¨W7)%>ëœDšœGˆ²mjB‹\Ž+I¾ÒPÚ:=¡IøUšlÙ ¿1R$Ë’¶Rio]!÷q(#Û”ê‰7Ûb l%¤ªT=`Úž-ª¼åV©‡¢Te)ˆ¼®é”)ÇÜK2i¼Ê;¨É(/Õa$Äë P—5 ’Œå0r[ܱ]’DÁZï,ÚJµmm/Ò*Éýb‡°F6”Š!P•‡fÏo ÓèÍêiÈ©^Wš4¶£q&o9t(‘˜‰ÒvŒv"aZ(j–ô:æKJÃQ¨Fu·ÜdÕ¸³êÜh…ë\V½wbé5ز«a€¿?J'c ¯SñNŸ@§áVklÈërCðäìÉtž½Q(šCm6´¥4k^v󒤦1jPÆÏb*¢ 2¾Ä(K·2®Ÿ Òim&·Tn<á‘)]Õ‹a; èëHÑ4êS‡$ʾ)˜q¶¤)I6%´Äį[dG%r¹÷*Ù°¯˜ÅÚ7©Ö­Lj[I}ÜNÍrmÔ$ÄΔSY„¦ÜyŒ®4g•Ó#A«ø##R@JWð¢0ûU³¨HTge$4˜(ä›;˜‘®Ö%FhÉr"3µ¶ŒÝ© µKf¥OqÇ#=›)¸ÒÚYTiRT…‘)*####"22;pÖj à·á õEúÁT–ÌŒIRuD¢a,’ÓPYét’’"RPE–éË´ÔsmÓ+|# ^¨o…A£pÜ{\·l•8¥!ÅÙNdA¥ÔD¥eÌ{LÀ`XÒ–N¦nêÓ³¥Ê£Æ«éôYj'#µ; Y£ÎfdVJLÎÖ;gcšV-ïÖ4Ã(÷[͸£ý*N±—MJJHÒ¶M\®E˜Ós4˜´î’ðk[K©JÕ>Û.åM’l°N¥*o^á7‘ƒ4­gMD¢3"¸ÄbI“*Ÿ¿úsTjã)D§ ´²SinÄdjÊo4w2î_QÞé"<—´sŽ1j±$:uJ: ÔáãwO„Ü °HSj‹:·ÉK̬Î(ìK±¡D›lXøÏIÅÒ°¤i2Ÿ«Cp›”ÛP[qÔl¥äë$jÐJB’djQŸrWQžÒ1Tª•šÕ]öé˜uœ=O©ÆCŠ%Pôª‚ ìÄ’Q›±ÉlgdÜÌÍ^ŒKG®Ñðö‘¥Óº'â)¨U0¢¡Kq£rHiRÈ‹fGZÎ×"A\̶ÚÕsG2žz¦šDˆqcoM5-æQ!êl¹R—EïjÎÒv³ì+ÂIaYtJ•a5%Ç‹Lÿ^)‘Œô{‘s4êáf#,½Ïu}—0¦4ø¢tèyRU2žÛ.K& ñ]a.šÉ¼Èy QfÕ¬ík؈øFpÚîÄ5 ^'Äxú=2¦ûtçc±ÇeFe4çÕ)³qfÚæw¢VT’lE˜Ëm«OÄÚCÅø™ç(’!»O¦Aeú4¥JŠkeRÖ´êB5ª-z Ì’DYÉ<)3µ€‰ÿê‹þoúù€>ŸÏÿT_óԇ̬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH<ˆvp–èëøÿôæ!-Ñ×ñÿèÿÌ)Ó/œÓ½á_@¹Â$“½á_@¹Â?RÞõxùË:çlÅ ˜¡Cæõ SÉB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔøÖ€ Þú4ê‡V ÂQh,á5K6‰9Þ:‘ –¢BSrN¤ìVIl¹÷Ä—¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀNvÚHäGïRè¶ÒG"?z—@9Œtçm¤ŽD~õ.€;m$r#÷©t˜ÀM9Õbóˆ4/Ý'Â[ê]æP¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH<ˆvp–èëøÿôæ!-Ñ×ñÿèÿÌ)Ó/œÓ½á_@¹Â$“½á_@¹Â?RÞõxùË:çlÅ ˜¡Cæõ SÉB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔøÖ€ ÷QhõzÜ¥D£R§T¤!⚉o,FDj2IÚæEÖ@< $½±ï"1/šŸöC±ö=äF%óSþÈÐ /cì{ÈŒKæ§ýì}y‰|Ôÿ²4KØûò#ù©ÿd;cÞDb_5?쀒ö>ǼˆÄ¾jÙÇØ÷‘—ÍOû #@$½±ï"1/šŸöC±ö=äF%óSþÈÐ /cì{ÈŒKæ§ýì}y‰|Ôÿ²4KØûò#ù©ÿdZ—ñ¬H®Ë—ƒñ xì¡N:ë´×’†ÐEsRŒÓb""¹™€€ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰äC³„·G_Çÿ£ÿ0‰ nŽ¿ÿGþaHæ™|æï úmÎ$ï úmÎú–÷«ÇÎY×»"hðИPœ”MHBå¤íV³4žWNÄ›+ºMöçêT—’å#¯ú K)n,v,UÊÔÔ“Ÿt*è#Õ8»³•ãÊE‘]ÑwÂo„Ê6(¬@·+Q7âžÜÅ2ŠÜ¯ÑkÛqf’Q-<¡dFDVÊ݈µMäõª=*]bm ªu­ÚÔtÉ}¤Uf##oªRR¢2pˆ®fù$îœÚÚ¶²éé4‰ËÂ6•QÂhulaH-“°ôª™¢A7•l¥´8Úb¸›$ÍÅšLó\²lhÒŽÓÆ‹\ÄXeÝý¨a:QEÚJ”ãs[nAJ'^Èz— iœÒj"$í±!³£F{[žmhµ¹ód¬JM³kok8Y}ývµ²Ù»[TÞCôhÏksÍ­·>l•‰I¶mmíg /¿®Ö¶[7kj›É¨´[@­ÂÅÔwª¤lV7·áæpÔ†U0ÔÚÈõÓ–úšyÌ«NT™Ü’D”ȧÇ ÁÄZHçX£¢¥KH©kû:ÈúÕ; "VFYL̉Ã$«‡!™sr +ôhÏksÍ­·>l•‰I¶mmíg /¿®Ö¶[7kj›È~ínyµ¢ÖçÍ’±)6Í­½¬áe÷õÚÖËfímSy5T Ùirg‘µRëƒt31¬5!çÕ ]t·»Éòe jl…!I+wVB•e§ÀƒMr±‡j ÄÊ©Kqº±ÃqME)fÊJE² £m«ß9_/ð)£ôhÏksÍ­·>l•‰I¶mmíg /¿®Ö¶[7kj›È~ínyµ¢ÖçÍ’±)6Í­½¬áe÷õÚÖËfímSy5~iF®aƒgÔàâºîºª/Dq´L»+J®ò‹,ŒÏ›kFSVT¤ýϳFÁЩ#ÁdîyM©¸bˆÃRåJm1VYl‹Xé6òÐfÙ‘Ù)Qm°˜H˜Ô‰•l²*‘\£â81 k­ÈÈñ¸l?µûi"=Ü´jî¢<–G ´_š{‘#±M÷r­§´ç;(µK;Ò#þb<še'9 •:ƒM“‹a® 2›\CSJDw S!J%$‘üµ™JËéóâÚ¡ÿ–çø.\d¢ ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰äC³„·G_Çÿ£ÿ0‰ nŽ¿ÿGþaHæ™|æï úmÎ$ï úmÎú–÷«ÇÎYדö=2 §¨×ã}U¿é iaºz~7×õ[þ’O"œ%º:þ?ýù„HKtuüú?ó G4Ëç4ïxWÐ#np‰$ïxWÐ#npÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>5 çH;ÚV Àí>¦Óð¹‘[†’Ïû£‚GÑ:‡úâÿ›þ„+Raë;r y¥Ÿd:ÎÁ†ÂÞigÙÜgC¢Wô§†¡×©ú¤fè•WRÔØÈy Y?O"QˆÈŽÆe~¦#sf?DÈu‚9 …¼Òϲ"uw«¬×ŸÃÝ}I¦¢›FMDê#E7%­n¼G¬-Y šh›A!)UœMÕ}§Šˆñ «£>-,*ßZúÒ£f•÷U#Zj7RgªNDˆ¬~æÊNÛÏxØ=g`ŽCao4³ì‡YØ#Ø[Í,û#[ÄuSÐTì\Êw¾­ÖË•$'!+s¿¹MÂ,ª##Ê®ñ‘ðm|c?ХШ Uk•YUI}ùp˜§6ûfÚZ³ “ù$­JY'´Êæ˜ïN³°G!°·šYöC¬ìÈl-æ–}‘ \Å5V0½}Tèê¨*TÆS×–¨Î¥¶Û-®²—•Š"Í—V´•¬vôÖªU‰UÅR˜ÆRƒ@f¥»ÛŽÂ“9kS‰RÏXJ"iÒTd‹鋺-—w‰WYØ#Ø[Í,û#É:£È2 F•ƒ0³nÔ$h©ÞvXá4㦛’vw ,îv.æÜ&DqÜ)Vĸ§ÂuÚ¼Š<$áÊMUú{Ù3[ò$ÜmKq Q"ÍLŠÊØVRN÷ÀÒj5Z½kF5Ê–&)J«TdJU'RÒS{Ý.èlÒ’_èókÎj3Q—¹àñ²úÎÁ†ÂÞigÙm¥sdôT8ð¡ÂhÔÙ¥ˆŒ%¦›#m”•ˆ¿ëÂw=£¸Ç iKý»¨ÿEþ©’Q‘r3hzKM8ûqе’Të„£KdgµG”V.„gÄF-€²±Q×[½wáýôÝ›‹Q’g¿gÉ—6çËî¶^öýb6.6£1>…„©j©T*ŽÃ-ºOkNZL•úGÙ²šO)"ÙÏiÒxü*ºÆ$Ã…#T$’¡MnTfåhmj$8v½»•) ýDn|Å"©Æe(P ¢Þ"j±7W¬V‘ãÆ§Êa‚•%ˆeœEÄ ̛̲Uîáü³1]2Yž7À56&Ö™"¨–×P™’ɺÚld‡V¥—tâMj¶b<»r›ÿaªÅè-°ôæ•'sG[‰K¯d5êÒgcVRÚv-¶.+…[©×0Ö&S”¹¢ÁnLV£Œ½ÖâO #‹+&Åc->ü}%a§#¼ã+:¤vÍHQ¤Í*q)Rn]ãI™wÈÌ„çºPðШ‹ª1"Sµ4Ø‘ÖÛNH–kÈKs1¡6BT«™!gÁb$̇È,G¯ª›*£sµ(Øvl{¼ÖR^Su±­6îŠÜ$$4 Í^£JÓtú¬èh:´$šX¶ÈÉlÊÎV#þD_*oÀCÉ¢Çߤ¬4äwœegTŽÙ© 4™¥N%*M˼i3#.ùf{ÆšsîÑeU’¦ÉˆÒYŽ´™žcS©uI2+ZÖeWÛß.¶óÆmIi§n:²Jp”ilŒö¨ò‘ªÅðŒøˆÄ» Vk´ÝÖGªÔ¡¨ªðr”Y lû¶¥­”ËÝ¿Tñ‰ÎL¤M}’òe%Åäñ8K¿ušûs^÷¾Û‰‰ï‘z¹N~ZI’¦Öü).GqM™šMHQ¤ÌŒÈŽ×."1´«•ºœý$c ™K].Õs(wý )¦Ÿq $pó¡*ÍÂg}»F+ 92‡éË뎱OEQռúj_7l³lÒâÆómFÆÌÔV;سm¬UÝÞ @6aQ18(EQ¥DXÜè©S“rk_$5—2OV²NÓI•´–Û‘OH»¯®éJœ¸®>¦˜Q¹£i.²ƒJ͵+Q)EòBb¬ÈŒƒt§ÃVÑ*9¶ÄÆâ¸Çu­I¸…­ ÷9M'«Y{«Ü¶•ŒŒIaT+”Š&VzS+˜NnÌGwä“ËI4»{²&É£Èw.ìÎÛLY©¸û¸c»*ÈÝmç{­]v]Éoômï·¿å÷7Õ÷zÎí½Æ¼CZ¦hÒŠš}NTU¦«= ºÓ¦—A7Y¢Ú”š–¥JÄg´Än‘ ²ã”5cŠŒé u™g‡âÎaq¢!÷ K‘ã-ÇÑ©$j²Þ_ ZÆ¢Ú@·“Uf‡1*¬ây{øÃ1ܪÅj>¼Žù£ç7–¥‘™7ÃÜ¢çs,Û[Æ´>ÆófÏÂn¸uYµUÚ‘U’\75nY´(”i6̈óZÆ”w)¾Ø¥} §{õtW©W„Ù«Xµ«uÛ¾œÄVJ»Ä[6l‘wáʆ(«oe3TrrgJW›ºî’’"$‘™™š‹e„ß°NüV¯'£¦/šûÍÿŽÐïq#æv- Tp½~Eª„"dt¶§“3"%¡+O ÞÊ-†[(l®©ÿ¨—aDŒÌytÃt˜SH^±&¤žÓÝØElœ'}œl´ËºfbL+6ЦHfLWÛSO2ìe­!Ee%I4ØÈÈÌŒ„X¬ÕðMj Á¬¢J"Œ”lK„n¶f\•I2:´Ë¶æKÑôÊ;Tip©r)[W Úvvn Ñ”­ôV^ª­Ej© —9¸fG2iÚÂ`ÊÖÈJAåà.!Ä€L»¥“ ¢c“!”Éu´4ãÅdµ¡£BMYndFµ™{2¸ÌcãÈÑÜz²ªñéô–jKtÞT´Sr¼§ *I¬ÖHÍ›*ÔW½ì£.ùŽ&ÚeÝýwaï~ žÈãm)·uè¿Â@Œ€˜Œ¹÷âÉjLgœaöVN6ãj4© #¹(Œ¶‘‘í¸¶Puñyaˆ<ä÷´0±%J†é»KÑÜRÙ©¥šLÒ¢2Rn]ã#22ï‘‹ #ü “ JD¸Ÿ‰!áÖ\4-?A–Ò­ý­ïºkóQß$‘’fn•ëŠädv]óp—Œp ÀÈ3\­3»õ5Šƒ{ã}Ý–JËu^÷Ömîï™^êþèøÇž:m6csiÓ$C”Ýò<æÚÓr2;(ŒŒ®Feôó€`eÄx…¸Ó#7^ª!‰«[’ÛL· 2²²Ô²½”j-†g{÷ÇŽ:m6csiÓ$C”Ýò<æÚÓr2;(ŒŒ®Feôó€Œ@ÈC®ÖáN‘:b£\“3}ö¤­:fw3Rˆî«žÝ£ÈÌ™,LDÆd:Ü–Ü'Pòd´¬Žä¢Qm#¾Û‹@'(Ö#Ä,Õ^«5^ª7Q}·e¦[„ó‰ÙÜ©wÌeܧaŸx¸…¨ºÌnƒW¨EŠõõ¬³%hBﳺIùÇ€bQ¼Gˆ[©»Tn½TD÷ˆ’ì¤Ëppˆˆˆ”»ÜìDE´ûÃûÎÈ}o¾êÝuÅ–µ¨Ô¥ð™™ð˜ ÛM¬U©<Õ6©:o•Ly lœ.%L¯üãñª­QªSÔ–ªS§>½c±ú‰—³ºR/”ϹNÓ.ñq¿~«;Õ½;í?{üt/SÃq{~ÁCµZ£Ô¦i.Ô¦9NazÆ¢)õ-«ot”_)t­¤]óã0 |úÝf¡=ª„ú¼ùs"KR’µ¸‚#3"%ܬfg³ŒÅ5:ÅZ©!¹5*¤é¯¶VC’$)Å'è5™ {ªµš½[U¾µYÓõEf÷L…¹¸‹1‡žT¹Rõ[ªKÏêZ&šÖ8jÈ‚àJoÀ’ïl@NW â*¾«&«C”˜Óœ©qL¡Ò"¹¹Y^äG{l°šöwÒ·*¿wÆèƵ,Q^ªâjìŠårVë¨IË®{V”fÊ’B{”‘w)"Ø]á¬YðŸ±é î,øOØôÈ@€o^¡ØÍKÓq²ö}YÒe(ò÷$•p™ÑC|õ - éÅn8¤¡ ¢Í5)Gb"$Ó$;w{i73ŸO°-hö«¬Ò)Ã̱«‰N§Ó¤!k^g·•(•s""ÊDÒ,V½óm;‘±¯h£F•)EDz߄r,ïÃ'Q¨’ùdue~ÛràQå3à<Ó¼ÓúfÇn°êmTš5”…‘÷s»ä+ h¼%¡vqeuveÑ Ç\é‘ÛŽå:SÊJY’ë$f²˜‚32nû\#Þ}LñO†«@óDÏÏ Ï‹Ä}mUÿõ# £B“/ËŸ*“Œd8šÝY¢©;]5S‰—!´'s®¥)l‹Q±DF[ 0ÓíßIÌbu5ãÿ}^jÍϱ íe‰ãZšf~|~v²Cñ¥Í3?>3µ})bHÓih‚í6si'µÆÃUGšÜ)Ìí¼’Ë4²¶¢³dƒ;’¶$”eŸcbÙ”ú‘ÖO;µ}ÓæmŽmÚÁÆt4Íüøü>¥úŒ¨j›ùñ¸´X­ÔÞÄP«ûÜr©]‡ ¡hC¨ÜÑÞ%)J2Q›Ç²û6Û\å#œëu3Îå_̧ç>ÕêwŒ¨j›ùñùÚ¹Nñ•ÍS>:4'Szy×?̘‡9v®S|c@óTßÏÎÕºgŒhj›ùñÑÀ+7®O÷OòaÎÑz˜ Å}/±S !ÄÞǽ3N×+wçwkÂüw@ó4¿Ï ö“USÎF„íx_Žèf—ùàíx_Žèf—ùá¾ÀFe- Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Ÿåõ8"TuG‘Y -µ[2wžY^Ç~ôáíX¥xÂæ¹¿Ÿ ™ßÚ±Jñ…Ís>«¯P<×7óã¤3#›ûV)^0 y®oçõb•ã šæþ|t€dsjÅ+Æ5Íüøv¬R¼a@ó\ßÏŽÌŽoíX¥xÂæ¹¿ŸÕŠWŒ(k›ùñÒ‘Íý«¯P<×7óáÚ±Jñ…Ís>:@29†/S¾­â|W’Ý*‹YU5”J2K®XeÌêZe¶Wý-¬Iï ÅAÔü#:K°jxQÇ^cQ!©VEE³RVD¦Ü–âHó!&Gb=›„l¼+!PêÚT–‚#SšC‰¿Ó)ÿòºœÙ(fqi²ÖÙºQØuI+J}V"+—}JQÎ×;Úö1áÖê뱈¢œÌ³µúÚ´øŠ)ÌÊMÑ™TRµCEŽšËOcˆéR8³$Þ#/ç!³49faýõ½Bƒ tjÙì5™Ÿ.}Úæ²Ù»ž ·Wm‘:Ê£á¼aFƒOqNÊaÖ"O:Œ¤8êÒ—vìI®D\’› ûüÇ£OznÄçœwK¾šüݦsñÝ-S Ï‹Ä}mUÿõ"[J§B¥E\h êZ\‡¤©9WqçT늹™ð­j;pìV+“`ŠU26¥"=6)\T<¢m„¤”µ–u¬ì[T¥)J3á333Úc3¸¡ø#ÙØzZ‚>ŽðŒxëŽÝ5íQ¤’Ò9õb%ˆ˜ºÏQc"?Ñeà." ~¡ÁL"f3ë\)ŠšË¯Ëyç5êelšÔµ¨Ô³Õ­IîŒö[ˆ­³÷?c› ÜPüŽl„àjLQ€°®&zKµšs¯œ¶I‰HncÌ¢BŒ‹X†Ö”¬ÓsÊj#4챕ˆ~âŒ+ u"¨ˆtèÏL-©Ë×Êy’SèCm’ÉÖÏ;*Õ´”’‘Àe{ÎûkqCðF9² ÅÁæÈ04þŒ0³Ø^—QL”°Üš•Asži‰>†Ôm¶ÙµÞíÃÊÒMKQšGa,MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#ÙÀ…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A¦0hwé-§RKBñcÉRO€ÈáD¹ÈÍã<)=J¡3¾°ÕÀƒuf]ìäµ$³Ê#Ûn÷ÚR™MDYÒOˆ—¥T¥»!Âe$§VO)¥®£Ê„&çÞIÌn(~Ç6CË4ÜÄÏ8q»b›¸™ç¥¢pžª½]EsZ6œ7Zœ–µºwîÜ2ºv\̈ŒöØîV±î %ügìómÅÁæÈ\e–Y¾©¦Û¿T‘\M›TÚŒR›V©µNÚ_ÿÙxymon-4.3.30/docs/critview-detail-acked.jpg0000664000076400007640000027265011070452713021012 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀ©A"ÿÄ ÿÄj !1A"QTV“•–ÓÔ2SUWu‘’”ÑÒ#37²á46Baq$%5v³´FRbs„¡µ&'8CDrt‚ƒ…¤±ÁÄÕ 9EGcd£ðÂÿÄÿÄ?‘!1AQRSaÑ3q¡áð"2’ÁBC±4b²r#cÂñ¢ÿÚ ?ý=>\´Î”Êy)'TDDáà‹&<9lÏ ÊTÒçUÿÌÅCJ òý«ÝUN­:¯'¯Åÿ:O{Lغ`BWè“É×9ÔŸÒ#º3ø?ù’YÌÝž©±Mb²§¤¾Ü‡KN©deÄ4ñj.ä8”šLóœ–86¶g…¿å Rë¸ê­ÕJàZ9Âu:“wòv´o 5J:o "þËhNzO¤ò|G]wÄ;V⨼ýKBmY•H’êÙ”Iih6Åëhõþ•)#QêÀïå³<-ÿ(aËfx[þPƞ߃PÛ©ÖdU¤­zÔë­4Ù#$E¡ m)ÂÈ̵jWʆ6 IïËfx[þPÖÌð·ü¡Ï×Åùu¢Õ˜µ¨Oœz›$ºò>r§ ©ÐÍN0‚k*Ý‘›„Dêry-'ý­ÝßwÞ ¹+åo5P\j2\d°ºraÉJÙC¦¹ ê]$¨ÐJlˆ‹AžTyI-ÊÍx¨ôyµzEö!AŽä™êZ´6„š”¬'&x"3Á˜õb¬·ÝÓ5:äg §Ò‡õK4¥d•rzV•`ú”GÐd)²Ôj³í}¥6w1RbQéÊŠˆ–2ÐìD¬Öµ-&¾íN)¤hRH”ÙçWÊÅÅ\Ub§Hj­Íí»u±Iji2Ùª ¦3$É:’i5)ÓRÖJâép<-[3Âßò†¶g…¿å R’në¢ :¯šÄšÛÍÝÈ¢µ:+1û,rž2-ᡃsy©_ K<'à fǬ^ò£QiÔ¥Ò%H¹Ü§.KíÂzZâ=é¤K&ã(wRH‹à”¨Ó…L {–Ìð·ü¡‡-™áoùCpšqˆl°ì—e8ÛiBŸt’KtȰkQ ’œŸIé".<‹€ò¬SâU©2ésÚ'¢Kel<ƒþÒFF_Q&Ç–Ìð·ü¡(•eËiNÅ©ªCiqmšQУBÓ’>”©*I—Q‘‘ñ!V”ùµêLžO}NÕJRáÖÜèRáÇÐ¥ºóè[ ÿÛ«xM®]òé_…P—ºn©ZnRiÅ 3M¨óœiÚd–íM¡ Âÿ´}Ç™äAorÙžÿ”0å³<-ÿ(cOkÎn©mRêmJåmˆËéu»Þ’ÐJ%èþÎsœugb÷å³<-ÿ(c™¾v„Å¡ÉùÁUYÖ^’¾Ld{–ѽuZ–œ¥;ÄpN¥x$ðcЉG¤\,Üsê´Z%~å‰U’×'¬¿¡KÆLiV‡ ”›#J;¥(Ìω™i®³¿m¹%@·4u¦¡±Ÿ(à‰V‡~ ¢%i4åWÜ(Í]Ñ` Ó–Ìð·ü¡}rèD‡&UR²¨ÍƆô×ÝR—¸dˆÝpYR‰:“œü$—I¯¯JŒ«ŸÜËS­)ÕÑQ´—9ÎNI<âïÙk%w*ɤúðgƒ#Á–ÖäTéö­R€åjUN3öE~KïIm’q÷(ÄÚŒÚBZRó‰"Ig&Y[ü¶g…¿å 9lÏ Êðžü¶g…¿å 9lÏ ÊüÝeQL²¶sXMjQúéªÍ6IEýæèˆ–ÃyÞ™’\-âð•¬û¬dw]‘×¹_=ö@Z;(æ^bÜ5£uÊ·µiÞït”gV?ÙÇ$¿-™áoùC[3Âßò†)ê­Åqa5¶îÒ†Gw±Eæ~LÁ Øåè`Ë*I¹¼[Ys:°H_—òýFö;}û‹½iQÝ.ÒY„º{ Ž–UT$š°’qKBL”FK"=$FFy3ãå³<-ÿ(aËfx[þPÅ]Q­Ö-·®Z]Få—5"SdÅšä!*•!æ7D”m™š™I!J,$Üʵxò,\ÛBvð¨[íI»Í¸Ñ%¢S4>W¼Q™).žôšSI"AéA%ÂÞ£I @_ü¶g…¿å bÑ«ÅX£Â«Óª/¿ tväÇwRÓ­µ¤”•aX2É ˆÅnÔ.{†ðމ5¥R¢1oÒªR`ÃDw’ä‡Ü“¼FôÒ¼¶dÉ$ô"4¨¸™ò['º«ˆÙ{rŒÊ3–õ¤Ã°è{²7'¥1¤IR̲hQ§JRÙ–$£5w)÷å³<-ÿ(aËfx[þPÅ W]ñÕ¸ª/?RЛVeR$º‡6eZA „FqzÚ=F¤%cJHÔz°-{~ Bn§Y‘V’µëS®´ÓdŒ‘„%´§##2Õ©\O*>qËfx[þPÖÌð·ü¡TR¨<¿j÷US°«N«ÉëñΓÞÓ6.˜•ú$òuçNu'ôˆîŒþÂ0-î[3Âßò†¶g…¿å V]ÓÛ³S)Ê«)©*òæ”å-’žyÜî´ã§“uãV;¬çˆÃ‹U»¦öNõÎóÌÚå(©§ ‚dã*¬¨I#Q#y­)22Q(‹¹"23ɘ*¼UX«“¢ûÍ"CÑ”­KNeÕ4âpxèZYèèô¡JÁu$Ï ŒS›<©Ö*5š…°UGmØÍU+OFu¶›[õ#:Œ¢Q¶n!HJZ3,§£=&dHøy;2‘S¤lûeQZ•1ª©°Ûé}¶FÏ4¾é0“CiÂRã(23ÊøŒ¸-þ[3Âßò†¶g…¿å UeÇ^“"ϩ̸ zn}ï)¥îJiøanþŒÒ’_èÔ‚ezÔ¬©eðz‰U» —³ºÍ^çzªW;M·2*á°ÓMà;%+lЂQ+,àò£Iê3"O -¾[3Âßò†¶g…¿å S›6ºïJÕV…QŸ¤Š}\Þ)MJU9£6µ¥1÷nœ…-*A!IpŒðj3$iÀê¶:åv}…F¯×î YujdYJB£²ÓLšÛ%‚my=E«Q™d»’Ipw<¶g…¿å 9lÏ ÊðôÙ#_­ö?J¤Ô5P)›î]Rr&òІ:wV{¬çN0]9à†ýYl;§êjiÉ.L%oé7VIRÍ)#>èô¡JÁu$Ï ŒzòÙžÿ”1PÛ5ZôkÒS3Z‰EF÷äÓãÅ|ä´¦ÊßC©I8¶Ð¯„ÓJÉ%'’2âYÏ3V¾/~&T¹$®ÈѾ8t–Ú[&“Q9:N6f¢JK”‹ô„G•éJ€¾§WŠ ¨¥T_mÚ„ƒ:–{Ç §4äº;†–y<sŽ“"<®[3Âßò†*:túìÚ¢Õ}©(‘í}†•-qNJÚæ‰k#x£-M%yZ‹Œ’R­%¨xìÎ㸥Sì*Fí*ê®hÆS"òfLu&27»I(´­ÚÉF¢Ôá`“À€-™áoùC[3Âßò†<A'¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC[3Âßò†<ïËfx[þPÖÌð·ü¡{òÙžÿ”0å³<-ÿ(cÀü¶g…¿å 9lÏ Êð¿-™áoùC©ò’“R¦<”‘dÌÝ2"/¬xŒ:Ç)ä 份_Ú׌iëéáõõdI®ås~“%ÆÝÎ\' ‰8ééïtŸF ˆþª‰PfɉQzXpÒ´º¢4™$ÿyò¥ò.l-ÖçuƒÞã:sŽë:¸ãüz°5]ß3Õ·žCÉÝÝiéΓéÏã§?ÝŽX>b€¹Õš­NšÝR[nT"!iyd¤©ä‘‘’ñ[´fùÆtÈ{MªSùlƒ}Ö£¢–IÕ‚IqTSR°„¡jR•¥ #3ÀÜÍÙÞÎÛ˜ûhÙݘIKŠ".`‰ÀˆÿæÇ—kížüÞYžÄõc™&duÛßCñ×GeÔo´-ÚTòÉÇpeÑ­dJWüeäÆJ]…‘mGMA njZa„””¨Œ”—0]Ùä9Èž×Û=ù¼³=‰êõöÏ~o,ÏGâz°$Ûóµ+å8^]?ˆsµ+å8^]?ˆÔv¾ÙïÍå™èüOV¯¶{óyfz?Õ€52hŒ¹:¡&6ÒêP‘=õ<ó,7KÐfi$‘ª)©XBP‚5šJRFg°MÇr5-ºƒ4 “Ô¶f,™LF7$t¤’ŽŒá’.¢"à=»_l÷æòÌô~'«×Û=ù¼³=‰êÀYcÖ¤¦Ub¹Q} )”»-¦]Z[Q)j#=&Fy.ƒÉâãAªQj0—@iÉëKªLv¤4òÒH"7[3-çrÚQÄÈðEƒ,?®×Û=ù¼³=‰êõöÏ~o,ÏGâz°²Ð [4[vu"lÊAºŒƒ‘1¤Gi˜ª=m(CQ% ChIš¾LÌÌniñìêth±iìÐa± Óz3L%¦ÒÆ• Ö‚. Q¥jNKŽeÖcǵöÏ~o,ÏGâz°í}³ß›Ë3Ñøž¬·çjWÊp¼ºå6£N~Ì5\b#Ž6¤%öžhÖÑ™`–’Y)9.’ÔF\8‘—­í}³ß›Ë3Ñøž¬;_l÷æòÌô~'«h[¶˜n¤íI½¨Õ‘9æÒÓ²RÅ q É¥*W$É‘dðF|2cQ§ØÕ(ˆ‡Q…nLŒ‡—!,¾Ó.!.­Fµ¸I22%)JRŒúLÌÌø˜Ž×Û=ù¼³=‰êõöÏ~o,ÏGâz°Ùº¥!´%¨ÁJDIJ^Ax¸‰çjWÊp¼º¨í}³ß›Ë3Ñøž¬;_l÷æòÌô~'«ru« …[–ÔºÍù"¥!¢Ãn˃Fyh/î5C3!Ò7G´‰ºäŠMÃ*y<Ú“1ò;¬–JSŽZR\³“â2;_l÷æòÌô~'«×Û=ù¼³=‰êÀƒ=‰ëäSX~”ÔÙ& lšKdZI’àI"áŒcxÌíJ4äO¤^N–Œè~-2ˆÓ‰ÏN˜Dd;®Ogsç>î(<í§G.Ð×(ÓŒcyð±ŽÈà9ûÜÛñ-ó\/Výîmø–ù®«n«–½¯z3]‘W·RËr’¢DJjÔÉ¥HAÊ×Þ´%ztç†5c€êõÛ—’ë£ò~QÊwYoFû{½Þc£^ó»ÕÓ«ºéâ+®~÷6üFË|× Õ‡?{›~#e¾k…êÀ$ÅZó9O+:4ŽVÊX“½6×¾i&£JŸ„’5¬ÈjW|ƽÚ.Ï]¥±Jr“k.ŸfãUƒe¥J’Œa'ýäC‹çïsoÄl·Íp½Xs÷¹·â6[æ¸^¬d±*ÞbB¤1"–ÓËi ©Ä-²Q¶ƒQ¡eÇJMkÁt¥c¤Ç‹j0¨J`¨­MˆfÒy3fDZÇÀN’Á`°EÞç?{›~#e¾k…ê߽Ϳ²ß5Âõ`â%.ˆ‰È‰N¶£¦ …75-0ÂJJTFJK˜.쌌òGœän9Ú•òœ/.ŸÄUüýîmø–ù®«~÷6üFË|× Õ€-v¥|§ ˧ñLM °ì‡X—MiÉ.¯©!&êÉ)A)F_ô¡)Éõ$‹ ˆVœýîmø–ù®«~÷6üFË|× Õ€3^°¨/U•Wvü}Ê’Ô…ªZ QMãRJAšù¬¥II—’2èÆ»c’ò]t~OÊ9Në-èßow»ÌtkÞwzºuw]dYÇI_kížüÞYžÄõ` ¿;R¾S…åÓø‡;R¾S…åÓøGkížüÞYžÄõaÚûg¿7–g£ñ=XoÎÔ¯”áytþ!ÎÔ¯”áytþ#QÚûg¿7–g£ñ=Xv¾ÙïÍå™èüOVÛóµ+å8^]?ˆsµ+å8^]?ˆÔv¾ÙïÍå™èüOV¯¶{óyfz?Õ€6üíJùN—OâíJùN—Oâ5¯¶{óyfz?ÕŽ~釱YöX¸íÍžÒœ}&¶JU{Â#Áã-ñÇÿRï€;~v¥|§ ˧ñv¥|§ ˧ñ?{›~#e¾k…ê߽Ϳ²ß5Âõ` C©_)ÂòéüC©_)ÂòéüE_ÏÞæßˆÙošáz°çïsoÄl·Íp½XÐçjWÊp¼ºçjWÊp¼ºWó÷¹·â6[æ¸^¬9ûÜÛñ-ó\/V´9Ú•òœ/.ŸÄ9Ú•òœ/.ŸÄUüýîmø–ù®«~÷6üFË|× Õ€-v¥|§ ˧ñv¥|§ ˧ñ?{›~#e¾k…ê߽Ϳ²ß5Âõ` C©_)ÂòéüC©_)ÂòéüE_ÏÞæßˆÙošáz°çïsoÄl·Íp½XÐçjWÊp¼ºçjWÊp¼ºWó÷¹·â6[æ¸^¬9ûÜÛñ-ó\/V´9Ú•òœ/.ŸÄ9Ú•òœ/.ŸÄUüýîmø–ù®«~÷6üFË|× Õ€-v¥|§ ˧ñª¥!I4ª£I2Á‘¾“#/¬Výîmø–ù®«~÷6üFË|× Õ€;妅¿amUb6ÛYËdúL•žž“ëè>œ—ýT%Ñ™ Íl2ÔÄ”%ô™¨Í'ýù3ÿ?{›~#e¾k…êÇAÜÙmbÕz¹A²ìy‘˪)›~"›Y£Q¤÷xQ’eÃ%’2ê0`ù¾¡Së%Gý!'þu_üÌrÕzµB\)‡n¥*äí;‰&dó©Iᦒ_ õ ]ÐZ$]%z:%9>+†¤¡ãqµODy#Áõ®îZ„Ûv™©4FË ™G}”’y)O`‹ ¯‡F0})ëIyÓ¯Z;Ó[¹¾‡—ím&¶Kîo§ßS¯[ˆ§¢Ç}ã¿%Z'¡¼ÚT²I¨ÒJRH³„¨úz†ÌpšlëtéÏ2Ê#µ$¤,ùQ¬ðM¸‚"- øÌôõêlvåÃz+ªu-¼Ú›Q´êšY– Ò´)'Ç‚’deÒFF4h•+T…ëFÎæµz´Ü«Ç ¿#ÔxË’ÌF ÷ÔiA))à“Q™¨Èˆˆ‹‰ä̈s;5³]³©Òãɺn’D™ s”Õç-õ6ÙîÛJLÍ)ÂOºQÕ“<”§}^ŠüÊb™£zN6âIj2#ÐâUŒ‘>xk6˜“j2—)®@•¥´¶µ8R#­´­YA%:”Eƒ25q,ôq!°§Ífkj6õ!ÆÏK­,°¶ÕÞ2ÿëÐ}$8ÉÅ*”ó Ëi-›ÉQ·»tÜ5M$e$yî‹ o­ø2¹ITeþ‰[³m  É9Ït}gÿQuu™Ë°7À<'ÆLÈnÆSϲN'Æ\4-'ÔdeÐÿ§’8 ¦Ó›ŠäÉ3]..<û†¥-]xÉž ¼EÿYäΠšíJ5.©,̘ŠÊ^:Lˆº ûÏ WTë²¥Yu§Ú¯ÉŠO9»m ÃJc)Ï‹JÝdõžx|2ÕÔEÐ]nЕAƒéIT³D•(š24%—\"=âT’-HIçC‘«F•gÓ"«„%töTóq•ì)f¦ÒŽ>¬ðωVžÝ>2\RãŽ8–™i< ÇðS“à_â}%‚4²„Ÿ$‘Ô5÷Ê©êŒî’.èÔ†ä-ÒJIJY´HIede}*¥ZZ=IÑŽ)¨¶—V“²ýYX%)$Ý‘ÊH¼öÅ5Š-R™QD‰µØ¬Õ)Pãn‘PÔôfõÈ`â;!¬Èëq’çrR—PHA*ÙØ†Ð“´+MdÆL:£-0¹,N6óIu§ÐJR[ZTeƒ3Ò¶ÝA){½jüõNM2ŠÔÚͯV¸Ž;iZJu>¥Nr34Ô¶Ó)C¾Ù6¼¦$d­.¶ù"ÌÜî’rns½˜‡W¸©Ñׇ.,e¥d÷Ðâ%ÃD„©Fj4-R„令´— JK‰1ã{;Û”ý¡¥¨hñ•¬Ü±ZÊØmÍÙÞû¹ï|¾¾†¨ÐÅ=Ïu¼úýü:–:ï(¾*–Ï%ÓÈ)°çræwœ¡ÙHѧ4òlç'}Ž9ŒÕ =\•DmýSâFfSíhWpÓÊu-«8ÁåL:X#Éi㌖x:Å‹Dºv½]—sÛ­Ôà»Lb*å2jgyÊ*æŒ÷;Ä’›<—t‚Y`ËWKfVµ9Ëž>õ²ŽUZ³cR#»6m O+•¡‰Hš‰›fM-M-¦ÔNšu‘8ãHý)æ—M ©¹C[¥¿Ê T#7*+ºãN$”…aDFYI‘àȾ3GæÈôkv™²”QgY3ZDZë ×é­QeÙ2Û£Ê'Ü6ôÊ,¤KI,œJLˆÕÄ…ƒfSaG´*(‘kÕÓn»tD~…JLgz+DôMÛ›“4©¦‘).>i2--‘å8î@ÅRê Ó9ß–ÏÝóÞ~SDúîÛíšNŸ#'…:¼#þ)âÔÛ\47­dQê²U* ‡ži•N2º£{ÒBÒyÔÚR׌hJ¬ñà‚š¸¬˜4÷¯z":“nJ¥R$¡šE8ÖÒ䔩[ý,§æ[n9:Ú{¥ ñƒ5t° \tÛF%jÖ´‘ ¡ ­&$B£½Omøò£!²‘ÈÜ3\t&A0¥¤ðZXZðZ²¿À~{›gÜ*dª=rŸVœÝ e…J½äÈ…Va礒ÓÄË“¦6µ—ÁS.™Ÿsü¢RâXW]ç"‡lJb€Í ö R¡w2%%s·Éa²ÂTòˆäi,™·Ÿ„Fëïºïbö=zæä¼¯š)²'r}æîé¥/F¬œéÆpxÏA…½]çz½ÇO仞d©"½æ­ö¨‘äkÆ Oô8ãð3ž8*WnÔgÆÚ+uk6·_­Î§šmyP©®ÉܵÉ“i Œ™2|žR’f“q+""^t¬Úa;V¸ªÕÊEB«g9p°²€Ìu«ó|71M‘Ée+B‘‚É6´°£I›`Y‹Ê¾‘l°ŽU6läÅ’DjIEJâK…çNgÉ$ddJ%Q+¦[ÌÞrh•™ôÇ*4êÅõ.d”èR›(lS¦D`ÜÇi{¦ܨÞÁçVjvÉÓ"Õé ¶æ¹fB¼ÚyêLHk[nÓ•LdÔM0’ý#%1zÔÚÈô8X<-[†»Í{rŸÉwÜ÷R\{Í;1$H׌¯èúqÃáç<0k†»Í{rŸÉwÜ÷R\{Í;1$H׌¯èúqÃáç<0t­V‚Òè´C~Í­¿g¢ù\¸´„SS‘©ÜØûfjŒE­ œƒq[£Ie.%{¢Iª”UD¡›Öemû=ÊåŤ"šé¹ŸÍ¶f¨ÄZÐÉÈ7º4–RâQ§º$˜쇜ièÈDGŸKΚ¶Í– B•­z”FiÊI=É(ò´ðÓ©EáBª@®PàVéoòˆÍÊŠî…'xÓ‰%!XQ–Rdx2#‰n*Zè‘lËjÔvñ–ìJdÈ*J#S—E”ʉÆV_¢io©Ì!dDDò‚ÉÛlf‹>›±Š Ñ…O´«ÙŽÍdªVÛÄ—¥":úôØ7T¥NJZU¤Ë&|R¬­~›NNÖê2î{b§TœôØ‹·j @qö¡°–š%$žIiŽdñ<µê4ëJÈ»¿‚8‹¾›NViu‹Z¨åÚ»ö©¬ò ¥BUY¥0\§ ´°m·¹Õ’Zuhá¨{K­Ä™VÞ§ò‰Å”:’ZœqN›m™f®å|YÁ’U•’L”EãbW{(±è77%äœïM;“ï5î·­%z5`µcV3‚Î:Vö|IR.š dg˜*}nã¸mÖÍ…TdµÌ¥+L•¸“è2Auwa4`GÙÓt›2·@­Á§’n‰Si®Æß5É’in¬ˆžQ¾l© #Q¶”#@U‰]ì¢Ç ÜÜ—’s½6<îO¼×ºÞ´•èÕ‚ÕXÎ 8è ¸k¼ÑW·)ü—}Ïu%Á×¼Ó¹ÓDxÁêþ§>sÃJì&‚Ìû:n“fVè¸4òMÑ*m5ØÛæ¹"’M-Õ‘Ê7Í•!$j6Òƒ#$cHí¯K^³]zʧ^ßp°‹•Çå>˜ìhèŽTÉ„’u yÞäÜ4¤ÌÔIV´ Ëtš‘©Û'L‹W¤&Ûšå™ óiç©1!­m»NU1“Q4ÂKôŒ”ÅëSh##Ðá`ðd1æÛmJÙìÆ•I«SíÒ¹¹]˜åÙÈn/&$§–6þùihˆ&¦ "àÒõR5È´GÓ>\g¥0Ö…wm2¦’ⳌûEƒ<ž®Áã4Qvõ½Mì›gwÁ³¶S0j0›6hNDÑ%Z‹—ÒƒÇA`»kÐ-jÍNÚ±kôÇ /L‡Í.³&k­¡j4!+Ç(† ÂÉ,Ô’Ö¬pÆk6»Ù!ú‡%仪”ø:7šóÉ¥½^p_ u«Z±“ÆN°º¨ÆÆÚš«E È¬L“Q„frèO/’²Im+v5E $0Ú”µ2¾+Q,±…–|"X¬D·û$m¼ÝÒWë¦YG_*LG+ê' 'D¢­J2.àÒ£_^@lKÚÚ•rö:Ô×Ê n¸Ëdä'ÐË®6Fn6ÛÊA6âÒIQšR£2Ò¬—=”лì×—˜9·9^éÑw[ÝæŒkøtãWV3Àk×M*†Ô6iTj“MaÊzƘ¾òä¡×æ¯Ò=»Jdi-ÚTX3ß(Š©ìï÷¬r.Ì/>[ØFë˜9ÖrrM“Óú< U[ÖÙ¦ÓiõjG%šš5ÀLîLrRt’µ6Û)ZÖ’##3"2,–zG8U',Ûâé“S¢VæÆ­ÈbdTÚk³2HŒÓ'DÒTm™)¥,xAïOºÉÐ7Dæ{Nß—XvѪˆ~¤û2møœ±ÚkRåü•ÆÐ‡IiÁ´ŸÕ­$lô— ØTvŸgÓèk­É~±ÈÞò—Z¡Ntân’•¯”% š˜ÂV•~“’É–H·\…_‚¹X©²Ò63é’!9’"<’Biâ]Ñ3’ÎHñ\ÕUuW¶´•Õ9ò¦ÔcQÔý;“͜ʢa¸é"4¸n)ÄI)5RzHÕÓm6…X­s4Óùfç{¼ÿºú…Ntcú"½ÎáãN8gQ€7WÝw±{½sr^WÍÙ¹>óF÷tÒ—£VNtã8:p]ó>l“g²ßôæÐ?Ö…¹Def£“K‘Q–£&XA­ZK&}â"ë3è"ë1Éì·ý9´õ¡_îQCxÓ:ßy¸moä2ë2›g%úSeÔ;»ãúѧ|s«)F Å]Ø¥YJ0“Š»Iœ¼ÚýÒ“\‡_§ÒЗI­Ã°œy pÒ•k|–”¥zV“ÁºO¬èí ÷=Åy/°QæÅY7!¤«RḦÉIW I222<xÈŒŒ‹ž¤ß,SíÚìfi¬Õ:rœ3”EÉ›orËfO$Ï:µ!Dm™Á<™pÌìŠ äÄêÂÈÊ4´2ÌcÓ‚u ›Š7_ñ Ý4§¾H#.3ñt*¥JÑXñ]]«~_¾‡ƒ éÕ*i‚ž+¦ÚíýN‚½vPè³Scò˜¦ÉÞM òÝJ ̉jC(R’“22É‘àûÃUwÝ5Zë6‹<¹enœ{›ß”qÛ"^¥vÍ.¨÷ˆKf’Á¤Ôf|d0¥Ézܹ.uN‰\K·~N—N\Õ±ˆÍ²mš‡ *J›7 Z ¼ëâC–¯¢»:Ö ·rQ«ë“Q×*«@v£»h¤%ÞÁ‹»-âÙÒzÍ%£Jˆðk1ï¡-ª™³(Tùu(|†sñ[rLmZ·.)$jFzô™™gû‡ñM«ÆªS)uJZ›¦ÚfBHim›ˆqIY¥X>å8"5ee’"ÔeÌl’ ·ö\Å.ä§«ºvlg"LŠhIÇå/!´KRðÙµ ‰&¥–œwJ.'ËìîŠÔWfp©öÜŠdŠmI%ZG5®6$¦‘%§Yš–JY¡;âÊTfDJ3à²lÚÏdV…àäÜ—œéìLÜë׺޶•éÕ‚Î5c8,ã †ÿºWú£Pÿ|„<öOL-–ZPæGv4–(Úy—Ph[kK%%I>$dddd}Ò‰ÿ„]+ýQ¨¾BÄ‹Š¿P…CL«Ôª•Ù”–'ÍNb±-²27WÉÖiÔ® I%J<ãf^ÕZ…ùL£Vß©.tg RŸœÄ¸Ò"IˆâГ2iZ£¶á+†q§þÖG-³ú³v-rFåR¢Pn[z’˜•G3Éã¾ÃTêèoQ/RMXOq3É •û´x`Ü´ffÐePŽ2CµJ|·g*2t¡¯Ó4ÃK4÷Ojɰ†ÜQà’cÕöŽƒ‡Y©…Õ¯{¿ÖÛí¹îµ¹ô N›­'fÕÕß úo.`6Ív·`mt¸v]mê«°Ú'd¨©ÒZm¢3ÂHÖãiI(øá9É’TdFICh¥ÔýÛViÇéRØi:œq…¡%œdÍ&D67'-­ž[väÇ¡;&•I‹çqÃBÖÓ)B9liÚ[kñíÏ&ß«Ú[kñíÏ&ß« š¿hÚ)u>‡Ô^¥Ô&SeÌe‡^¦I9PÕ¾t·n›.2jÁ'ú7œN%Ýg¤ˆË7žšï±ö×ùÎ>Ú[kñíÏ&ß«Ú[kñíÏ&ß« š¿hÚ)u>‡Ä]'#ä”ÚT~BÊ£ÄÝ6iäí+N¦ÛÃ}ÊOB2E‚îSÞ!›ÏMwØûküƒçm-µøöç“oÕ‡m-µøöç“oÕ†Í_´mºŸG9é®ûm9é®ûm|ãí¥¶¿Üòmú°í¥¶¿Üòmú°Ù«ö¢—Sèç=5ßcí¯ò=5ßcí¯òœ}´¶×ãÛžM¿V´¶×ãÛžM¿V5~Ñ´Rê}离ì}µþ@离ì}µþAó¶–Úü{sÉ·êö–Úü{sÉ·êÃf¯Ú6Š]O£œô×}¶¿Èô×}¶¿È>qöÒÛ_ny6ýXvÒÛ_ny6ýXlÕûFÑK©ôsžšï±ö×ùžšï±ö×ùÎ>Ú[kñíÏ&ß«Ú[kñíÏ&ß« š¿hÚ)u>ŠÀŸO ˜0#A‹„l°É) ¶’,R’oD]D=ùé®ûm|ãí¥¶¿Üòmú°í¥¶¿Üòmú°Ù«ö¢—Sèç=5ßcí¯ò=5ßcí¯òœ}´¶×ãÛžM¿V´¶×ãÛžM¿V5~Ñ´Rê}离ì}µþ@离ì}µþAó¶–Úü{sÉ·êö–Úü{sÉ·êÃf¯Ú6Š]O£œô×}¶¿È4éÌ»™«ŽLBv{N%ä§É6 Ô§B]Ücu¼$à‰zuqà?vÒÛ_ny6ýXvÒÛ_ny6ýXlÕûFÑK©ôU3ééœäôÆ‚RÜi,­ò%oÚMF”·y4‘­FEÐF£ï˜÷离ì}µþAó¶–Úü{sÉ·êö–Úü{sÉ·êÃf¯Ú6Š]O£œô×}¶¿Èô×}¶¿È>qöÒÛ_ny6ýXvÒÛ_ny6ýXlÕûFÑK©ôsžšï±ö×ùžšï±ö×ùÎ>Ú[kñíÏ&ß«Ú[kñíÏ&ß« š¿hÚ)u>ŽsÓ]ö>Úÿ sÓ]ö>Úÿ ùÇÛKm~=¹äÛõaÛKm~=¹äÛõa³WíE.§ÑÎzk¾ÇÛ_äzk¾ÇÛ_ä8ûim¯Ç·<›~¬;im¯Ç·<›~¬6jý£h¥Ôú9ÏMwØûküÏMwØûküƒçm-µøöç“oÕ‡m-µøöç“oÕ†Í_´mºŸG9é®ûm9é®ûm|Ù©í‡l´øéyëåõ%JÒD†š3Î úÛþá®íóµÏ¦ù å8NÒ:Fq’º>›óÓ]ö>Úÿ sÓ]ö>Úÿ ù‘Ûçkž;Mò,þ@íóµÏfù ®òÛ¦üô×}¶¿Èô×}¶¿È>dvùÚçŽÓ|‹?;|ísÇi¾EŸÈÆãé¿=5ßcí¯ò=5ßcí¯ò™¾v¹ã´ß"Ïäß;\ñÖo‘gòñ¸úoÏMwØûküÏMwØûküƒæGo®xí7ȳù·Î×›óÓ]ö>Úÿ sÓ]ö>Úÿ ù‘Ûçkž;Mò,þ@íóµÏfù oÞ—Ó_‹WD:EƒY­F¶ùk!´ÛªÆOJ]y+ÁgRSÄeƒ=/e÷—Í=Îtïh‰{|ísÇY¾EŸÈ¾v¹ã¬ß"Ïä…‹Ÿ·vU ²Â®š…j‹"ŽåV¸©ŒF}æ\Y7Éc·“6–´ü&×מÁdv£çoo®xí7ȳù·Î×L+9ÇÂN3Ç€û|ísÇi¾EŸÈ¾v¹ã¬ß"Ïä ,\ú5B‹¨ÑW5†A!¶Û¬ÍJP’,àˆ‹†ö¸T… Ò©5,`ñ\œGõ‘ð8»|ísÇY¾EŸÈ¾v¹ã¬ß"Ïät¢ø¤rQwQYG¬ú}­gÒÝ¥Úôj]"²]”ã1IhJqYR±£ü‹¡)JRXJH‹sÏMwØûküƒæGo®xë7ȳù·Î×dvùÚ玳|‹?;|ísÇY¾EŸÈÆãé¿=5ßcí¯ò=5ßcí¯ò™¾v¹ã¬ß"Ïäß;\ñÖo‘gòñ¸úoÏMwØûküÏMwØûküƒæGo®xí7ȳù·Î×›óÓ]ö>Úÿ sÓ]ö>Úÿ ù‘Ûçkž:Íò,þ@íóµÏfù o¦üô×}¶¿Èô×}¶¿È>dvùÚçŽÓ|‹?;|ísÇi¾EŸÈÆãé¿=5ßcí¯ò=5ßcí¯ò™¾v¹ã¬ß"Ïäß;\ñÖo‘gòñ¸úoÏMwØûküÏMwØûküƒæGo®xë7ȳù·Î×›óÓ]ö>Úÿ æ/Põ&j´«ü•ã=9ÁšÕŽ$]òÍm{¶éÙå¿sMÚíÓú¤I[,È´ Ï$dFh#ÆHÿ˜þö…k\Å[¸]ÚÕß94ø.ÈäÇ  ãJLÉ­‚3àgƒÁAô »²OÀ?}ûËv[òýå÷ÈÞÎ÷*n;ãòM6•˨•Zƒr0õ9-:¦4|6”½Ú—«<4­M1Ç_Icënøü¡eÔáRëZª‰ºl–‹1,$”æíÄu$”dF¤ž•‘‘e$?ÿÓßK·ÿÿÜõ?ÕVÁBÿöÿõ6,©¥MaØœ¢\Ç98ÊA!¥Jm÷[I¨×«;¦’¼éÓ…+Q§Ik×ȵ«l²ãç—YDuÉ7X”Ó¨6Ò´¡FJBŒ”i5§)#3"<™cˆë¨;GO¨W'®Ôº•U¹ 4m6ãlÆ(Ócš4¯)Q¥2‘¥*I¤ôŸæeñKUnŠ…9&u2¤&kMQaÓ MIBZxÔ~äס<¥OãÕ1T¿ò…¸œË–UÐÜÞDºCÅ$ÙŒúZÖJLƒA3¤³Ý)F´–’â\rE¤ñpQgЦ"%@¢ïÞñ'[Riɧᴥ'9I‘–rXâ;¾Ñ9Þ55RJlIíÕÎT©QM$´°—–ë)k'ðЩã< w¸hvƒV¤V*ѤRYqI¹2 ¨Š”Ý6Z3BJ’žyѨø™‹EÎûÑQ¶ã›Ðævöm“N¯Ò)H®J‡>­R‘N‚Ê)äë:Úm…šÝwz“m'¿Id¬LÌsôËjµRˆ‰Pâ¡htÖL¥RCšK*&Ð¥œ2ÿ’GLJHè-ËöM ̇oE\ÅF\ù®ÕaïM LŽû1›JðËté’Œ»“RL³Ä†âßÚ2—M¦Æaç㮆§ žïcÔùO>“}o!FóÚ—dnw;Â,‘g9âÜÕΩAœœË"å‰Kçá0–y+s4Öñ°â´ºMÍÃF•$ÍZp\sŒ?¦ì;¥Ç!4Õ=—™!˜í°‰Œ)ÖÜuD–Òê z™ÔfDFá$¸Žšã­Ûú‹uXSæÎ«9lD§*:lâ¡NR›Œáï‰ÃQ©¥£vXZpgÀdÑïûj™{½w¡º³²êÕ8òêQN3in25™n+Þ¸f¦I)Ô”`Œòb1Î×Hœ0¾örÑ,j‹ö}ZáTÚcGM’Ã+ŒåB2V¢q—]3,¸G¬‰ "lˆÔ¥ÒE©µ‘jîKj±n©”UØe…ºjI6‰M:´)8Ô‡…¶²ÔYJÈŒ³Ð2èuJR,Ê夹¬¹*Di±]ŽÊ]#u†ä ›Y)iÒ•oþj2ÓðO#;h÷¼ˆæKšÚž\ª„ÈlÇ}òV^éFNš4¬÷ªÂ•¯‰]9b·"­G Î<C˜OgÚ+¸hÕŠ‡/(ª‚ßù3FÖ£”é6ë¦ÙKOèÙpóÇŽ’ÇtC˜õ£~ÓmªM +6Ô*›ðç9>KÓTúM.¨Ò’K{§’•'v„þ±&YR‹3Í&åoÂZ _yƒ³[mÕpÑ™‘ºb—6¢Ìg\Tæym©Ä¥Ãe.+SŠ"3ø)W®¡æœÝëˆÔ²§Å&œŽÔ¬ª£&Û¡+C®¹–Û2R{µ‘$ŒðfGÀoí˪ɇpÛUI¥_CvÌÒ8LGŒÊŽLtÌ\„)Å)ÂвÞ($J%`‹RzF¢£vS¤óî†e—8[TÚKYJ{—£rjWu𒹃,Ÿä‹'Šbž-Åí e³‹¡Q–h§«”0ãÅ$–ûe¶Û(¿¤'MÜ(•´fx$éRTJQjÑü'gסÆù®I<Â6¤0ägq¹o7äæ$Qœ=E”%z”ƒIºîШ³ìi46cT%ÚcQ Km5¥ª: Ìõg§?Õý¦øqVŸâ‰~ÒbÚTj*Þ«Á‘ ™K²£FiÜTR°…¬‰i2œÒM*Á(‰ÂG½ÞëÕßu£GÂþÖ)O˜q‡#UpØ—E<Ǫk»º–ÛsXuØç«IÛBÍII«(È’y,ä‡4;JÕÙN›pí Ó2ÒÕ˽äiRS©½ud–óºáÜ4¢á«º2êâ\Xé&¿I$žàå@:¦- îÐ(6Ÿ8ãù³ü§sú®XÓ.|]Öö:KVœðÏ bmªÒ©œàQQºÜ!²xÚ#Á¸MjÖhé=Zq‚3èâ;zfÖkP/[jd{‚åbÝ¥·JjE9©‹Jˆì°‡Ò–‰z –¦Ü2#Æ­\q“Om+ÖÙ6K8µÒJÝ5@€£Z ?'ÔsTFúu#¥83âdJIcqTèu´:˜w~Ì«´ÛŽ«—.Ó™›-ªy¿:9H”ÓdÍ-ê%8²6•’JsÃ8Áà…ÍxÞ6„‹ªß¾™S\ø®Ê¨F§¢3JFN­2CM¾½îZV“4’ܨŒŽE2&”¤×â"¢Š{€§0Gyÿ¢ÚÿŸ/áPäG]yÿ¢ÚÿŸ/áPäG‹§{ÓÖÐýÑ"ˆ Dõ1=B $ =Bõ0000"ˆ˜wÀþ€ô2À¥V«žæKF•A¯•dš#mòâ¿[H5/V‚Öœ(Ë¡YáÕÇZ{ŽÔ®Y~櫲߬]Gq·”ùD}pÍ—oAþG¼^².®Œ%Œl6=b[­Y•*¤z«ò]£3¨Ñ^žÂDjI[iô¡%Ã=ÊK&fgÄÌÇ–Ù¬F“²kª£ ŸS) R¤)³rà©8’=Y4*A¥]= ##ë#.…Ò`$©@wÇæ©6®°£Jåӌ˼âÿ ý+ßWõËÿOûwKöTê-¯ÅkÝ_…íþYûm3Ù”4êP×_ðÞß­½ uv%]2`ýµþQà»:¦‚âü?¶¯Ê,Ù[' ~ÊŸúËÚrâÖG‹?ôþ†¸'™^®×žŽ—£}¥~ÁÊ´t¸ÇîQþ·‘ÐcW'¬n¥þªö„¸µ‘–^ÄÑW'™Ê¹LŽ•µûŒÿฮ#¤Óõô®‘­‘Òc}?õ›.-dg—²4eÉækVFž‘ä·Rž’1ìøÃ|l‡·4·Ídq—³(.¹’©'¥+úˆ ¨°ž”¹õâ1]Žõ1ö¾’ù¬ŽRöulWŒ](wê/Ä ®D.–ßû%ø;£Þƒ#í:ï¡Íè4‘¾UÅ‹‹R>É~#ϲh'ì§ñÓ¿Æ?XÑ:³9½‘ÖöMâdý”þ!Ù<‰“öSøŽHÄ mÕHØéwdÐ>&OÙOâ“Àø™?e?ˆä¨@mÕFÇHë»&ñ2~ÊìšÄÉû)üG"·U#®ìšÄÉû)üC²x'ì§ñˆÝTltŽ»²x'ì§ñÉ |LŸ²ŸÄr uQ±Ò:îÉ |LŸ²ŸÄ;'ñ2~ÊÈ€mÕFÇHë»'ñ2~ÊìžÄÉû)üG"·U#®ìšÄÉû)üC²h'ì§ñ‰ ï†ÝTltŽ·²h'ì§ñÉ |LŸ²ŸÄr uQ±Ò:îÉà|LŸ²ŸÄ;&ñ2~ÊÈ€mÕFÇHë»&ñ2~ÊìšÄÉû)üG%ßuQ±Ò:îÉ |LŸ²ŸÄ;&ñ2~ÊÈ€mÕFÇHë»'ñ2~ÊìžÄÉû)üG"·U#®ìžÄÉû)üC²x'ì§ñˆÝTltŽ»²x'ì§ñÉ |LŸ²ŸÄr A·U#®ìšÄÉû)üC²x'ì§ñˆÝTltŽ»²h'ì§ñÉà|LŸ²ŸÄr]Bnª6:G]Ù4‰“öSø‡dÐ>&OÙOâ9 º¨ØéwdÐ>&OÙOâ“Àø™?e?ˆä»Ânª6:G]Ù4‰“öSø‡dð>&OÙOâ9"uQ±Ò:îÉ |LŸ²ŸÄ;'ñ2~ÊÈ€mÕFÇHë»&ñ2~ÊìšÄÉû)üG$AÔuQ±Ò7—b5Be·’¤¸J3Y0eÔÞ4@=J’©,R;Ó¦©«"D 9—'¨A‰ê`$„ ! ê'¨@€ $@$þð¥;ý…ØßC7üK{~ýŠ^D¿ü&=6 û ±¾†oø–<öýû¼>‰øLsæX»@X©@wÆž…¹ÑkMòfžrDδ‘šTi^0gÑÇqß eJ=>-eHS/¼Î4’²j$«2èâd>%þ•(ééÖü¶w¿ÿ×åæ~ïLSz¡Æëü£ù¥[¯Â ×«S™%òSTu/BÍ&H^LŒ³ƒèü@¥@†üÚ«0\žzb4¦ÍFáõdÈøg‡ÖCgF¯¥ZÔz­E÷~1¢2]RÜÊ+#"éÇJ{Ãù\ LƒCr©-è’(ê#&Òɬž$éÆ º> z¿üGìhÇ@«Nš$÷I¤ÿ6ûµmö»_ÉãTzL%+õä¼¹^üø˜¶…ºÒc]”ê¬x|¦3 Jy¢dÍ.wdfY"è<—9÷-&éÕ«j{S«Rj™oy¹4‘žð²…%Yàežžñä‡GL»(²%ÝR*Ï9º›Hm¤%³RÔ’BÑÔX#Á—I‘dƪ¥rPaŵh”ù®I‡M¨7.L¥²¤c 3<'§ûJ>êééÇEÕFÍn½÷þ}×^kÈÍ'[º{íðáêEù`D©Ü•³¢T ³23(}¦cšp‚m$|K #3ÉàˆúK8È×P­º|ë.Íz©ÍMDY&\Z)Êå.wOaµ¼•åIQ¤“ðKNRyîxïåÞ6u6è­Ý*r%O‘£³“-)Z‰(î‰F]ÊHóƒàxÎHr¬ÝÔ8›;´)ç)NO¥VÑ6Lt´¬“iuÕd”e¤Ï O>¿ñÒÑÕG%m÷绊¶k‘›ÿ¹…-ü¿ÁÏíâA£^.³E”ÒTd’~q”Úba¦ô÷GÁzòjáÑ×ÄV¯‹ mu jír»B«*qMJMæŽ2ÛÜ„eXÕœðèëâ*[[+p¿"c|*æ£Þ±–èÄw¬wÎF#£ÞƒNŒWz mÆF#¿Æ?XÈwà˜ÇëãÀâÁˆbˆ$ú„ >¡'¾ „÷À'¾ O|@ô^Ü6fÝ÷ZE©hSi”vž¢"KæÄt²Ói'ž%8¤ ‹'Á)þþäº:?:Ó5ý³ÚöÿOºé²Ý©QWA*d·šŽ´)¥ës$•’Lñ„gFxÉ–}÷²Æè¶‚®ërè‰sQ™”q%¼Ôu2¦#Ç™žS“"δ“,‘ämäìG‘S"³S¼é.iTõÔ£¼Ê’FÚHÌÉOéJ°GÒXÉ"3×…ÛdP6=;g¶UZUwª<²D§b©„²‚RH"WWèY"Á÷Gà ½ûwl¢þ8uÇQ©¦«pÝ¢3i7-F•%âîR’RÔ|s’ÆK‘ÅìÃf”ËÂ,UL½"S&ÍyLÅ‚ÄEÌ|ðxÔêPe¹NO‚—‚ÇÝX[?‡oѶÇE¸)ôÊœú%) ‹%ÈépÚ5GâVÙ¨²ƒ2Ð|8䋼Ý싲ëJuªÃ\…½Žh§¸K­j(úRŒÿC¥*5’UÿÒX ¸¶¥tÙ÷nÈlØñ«Ž±]·`¦"©Ë†áïŒÒÊ­ïÀ""kQq<ç¨Ç/²¨WömÎ\Ç™#œw[îXÚ×§w¯N+N>ç9êq”èÏŸ VÍÉKM ¿´¥ÖcôþÇ6An[»G™K®Uèw4æi:¥Òß§êä«ZÚ4-:ò• Ež -Eà ž¹å«hI¼ßa“–ubª-¦ÈÉÍöôÒY32,ðâgþ?F[ûGÙ]¬Ô¶€«¦sR+Ä0ìgiÎ錤îˆÒjI©FM§ Œ‹J»®$@ ÞU¡"¡°+&LF-ôÉ«×y .&™º˜k[’P’vV³ÖŒ¤»‚$ñîxù_»¦Z´Ú‰9´*RëTöó´Ù1Î)¼“N¬2µ«ô§ŒðItð<ýͼ­GýÏÖ]¨íJQÔ©ÕÎU>ÏåìÒµG‘uϼ^‘‘Ib£MÓ* ºLµ©òBR¼+ ÏN V@uì®5ÑgìÍTˆtÊS¡*er¬˜¨BP’b:µºe§ZŒÍfY>µH²cóÅmŠ|Z´¨ô©îT!6ᥙKcrn¤¿µ£R´‘õqÎ;Ýô/mv­>`[ÇQDº9QÎÈÊ¢9ú&BzSÝ(œ#Ñœ–¸~q¹ãÒâÜãÑ'rúbQD‘¡H7ÏrfJ"2 —èÑÐgŒNx^Ð6GM™³:-õW¾"ÑaÔe)‡ü/u‡Ai4«+36Èñ„‘™™÷?Üaî¡»­ëÒÿƒT¶ªºT¦ã­ÍËáÂuÕai#èRxã@VÌcÇ™´›b$¶‘úÄFÝiÔâòÒ¢>FFddbÛÚFËiõ»ûi³irbÐáÚÐcKnh)Ý»ª¸i-*I7“løàø¨ÏÿîÁº6)"jϸØU á¶Ö‡ áAÇ.q½:Vâ›AëÉ¡*î'\pgŸKkkVñÚJ®i˶#1#p§TÒ[el–¤£'¨Ò½]e’Æ@E/e¶Ä³®ŽÝöK[n“Éùy6·]oy«_wÖtá==<8ôîûŸ]ÁX¶é÷ô uÈ“)¸'hSšSƒZµ õ+#WIž3±“|lî`ìöÜ£ÜR%ó Ólµ¿ÖÔL!×”ã¸"2ÆVFI#5`ˆHÆ]³´Û"º^è¼$ÖôPçR‘4®Jñëp“Œ´5—×ÄÈ‹‡÷ƒ´©e[º©SY §Îf)¨ºS¼q)Ïýcô•ûgÙÕ6Ñ-Êm­L¦=fÁ*Øíé}ÍL)å‹é_™qÏNzGæ›r¦åá§VA-Èš’„™ã&…’ˆ¿êõõµ;è7¥Rݨ̗Y¼bÇŒì'")²†”4m(Ô³îUÜ©_ÏŽ:¸€36mh-­Ûë¡Û¶^㩜‰Ž5p0—q¤ž–‹áãIñ2IgŽ2?5KŽôINÅ’Òš}•›n!EƒJˆðdÞF.=U¶Oiɤ^o×ëŒW©ì¼RinFÞ¢CŠlÑú%¥$IOtgÝŸYtc'T\ÕEÖîJiƉ¥Ï˜ì¥ $“qf£"ÿ €?Tv»³yãµGc4ÝÿbÜåÎÛ¿ò¾S½ÝjÞtãWu§£«à9¿sí¹mUvsO‘Mµè·aUt³^:›D³‹Ô¬­­\2H$c¤Ìûà öÍdoÿ)Ó;*ìwš9«’«N÷y¼Þo~_ßœug€çvOØììêo\yt t Új›Æb­ÔÏ$©j$ %é<õ%==@rïÚ5ɶK†N»![ôt©Ø²¦nÔ²6Ò¦“¼Z?´¥™q3Â::Äl"UÞ“HM›å»j)ˆ¨% „ÚZ–k%(°zIgœ÷$EÒcû“TÙÍù¶[‚·wO¨[ô M›‘W¼¸§S»Aj$¶æ5$–³áÓ×ßÖlµ{5~‘QƒyH›G«oPí>°Â]t™"4™§vƒéàx3#øGÑ‚Zñv}bUýÔh”úrJ•N§ɰM K< ”IÐDØý#jÁpÎK£€ãöÇI ÕöAkm&“A§ÐäO–ì91ൻeDJt’zKnO^®=7«Ûm¼^èdÝÍFšÓy©×‰¿Ò-µïtôü,:t—€å6»wZ«ÙÍ»³Ë>¢ýV 2C²Þšäu2JR”á¥$•qá½^Oü?pª½gQö‘L ?´85 ñ&]Z¤²i'OtD•¬g»Iþ¸_Qî’¡Ú´‹3gr­JKP¢Ï‚óûÃi%!ôš#©ò‹Š”ZϤødñÀW»PƒcSëì3`VgU©jŠ•:ô´V—µ¬$FÚ8i$GYñïu{k»­ëŠÀÙÍ.PåS(Ô³Porâ7.n£§RH•ŵñI™pþòvöUÏL“³ºí÷tlÛgìS!â5=˜´4¡Ér,©J-’Î =?ñO?ži‡ 5(§QKÊ„O ä8Þy-DœðÎ3Œõ‹3iwe»'cv=ŸnÔ9C’¹5F‰—»i#Áš’D®éÇK)3.à+:kQŸ¨Æbd¢‰LJŸ4ɤ‘)zK‰à²x.'€è‰MØ~Éï:ÜK&½F¤°Úh“ù97)é;¤-Dg¯ô†„ôžI|xôm¬+>ΧQ¶wmÔ­jeMëÊ ©S&ÈoSíéa/$›_J8,‹†:3Ò9¬Övq\²aÛöÞÒ * GŠ$“9’“27=%• ™`J3ÎFÂÆÚˆT;.©qT&ĬÙÑ$FjqáL%´M$Ò²îSÜ¥?ËŽz¸€5¶E«@³l«þïªÑ Wß ÖN“šƒDãDHy´)Fžƒ3Þ—­<:Lo¤ìŠÙ_ºc™“<ÉÍ<òp£$ëÝnËšû¬tut:ÄÚ ³W¶/;R÷œý5ÃSçDËj:Ÿ$8n!kA¥<ñiÁã¿Ñ׸^Ûèåî‡ì½,ÉUsV½¤Ýj×¼Óÿ9Ç:¿€G®½Aœí•lÒ•!K"©[ÒµF{ýH"%—ë*Ε`úŠ™îÖîûLöaolîÑ©H¬F¦Êr[³ÝŒ¦rjS†”UÇÿ¬ŸGýÕéNÁav7ÐÍÿÇžß¿b—‡Ñ/ÿ M‚þÂìo¡›þ%=¿~Å/¢_þù–.Ð*PñÁU\±Þ÷Ǻ]N§!ò¦Ó¦M6ñ¯“°§4ç8Î’ÂÛô_9¯Q†] Ô—Úl?7õ°ŸÄ;Bí‡æþ±öø†ß¢ø±ÍzŒ2èV½áËí ¶›úÇØOâ#´.Ø~oëa?ˆmú/‹רÃ.…lB–[ÛÍýcì'ñÚl?7õ°ŸÄ6ýÅŽkÔa—Bµeö…ÛÍýcì'ñÚl?7õ°ŸÄ6ýÅŽkÔa—B¶ êWh]°üßÖ>Âí ¶›úÇØOâ~‹âÇ5ê0Ë¡Z²»Bí‡æþ±öø‰í ¶›úÇØOâ~‹âÇ5ê0Ë¡Zˆ_h]°üßÖ>¡vÃóXû üCoÑ|Xæ½Ft+n¡,¾Ð»aù¿¬}„þ!Úl?7õ°ŸÄ6ýÅŽkÔa—B´eö…ÛÍýcì'ñÚl?7õ°ŸÄ6ýÅŽkÔa—B¶!Ë-‚í‡æþ±öøˆí ¶›úÇØOâ~‹âÇ5ê0Ë¡[u_h]°üßÖ>¡vÃóXû üCoÑ|Xæ½Ft+PWh]°üßÖ>Âí ¶›úÇØOâ~‹âÇ5ê0Ë¡Z˜²ûBí‡æþ±öø‡h]°üßÖ>ÂÛô_9¯Q†] ЕÚl?7õ°ŸÄ;Bí‡æþ±öø†ß¢ø±ÍzŒ2èV ,¾Ð»aù¿¬}„þ";Bí‡æþ±öø†ß¢ø±ÍzŒ2èV ,¾Ð»aù¿¬}„þ";Bí‡æþ±öø†ß¢ø±ÍzŒ2èV—Úl?7õ°ŸÄGh]°üßÖ>ÂÛô_9¯Q†] Ô•Úl?7õ°ŸÄ;Bí‡æþ±öø†ß¢ø±ÍzŒ2èV ,®Ð»aù¿¬}„þ!Úl?7õ°ŸÄ6ýÅŽkÔa—Bµev…ÛÍýcì'ñлaù¿¬}„þ!·è¾,s^£ º¨ +´.Ø~oëa?ˆv…ÛÍýcì'ñ ¿EñcšõeЭ@Y}¡vÃóXû üC´.Ø~oëa?ˆmú/‹רÃ.…hÊí ¶›úÇØOâ¡vÃóXû üCoÑ|Xæ½Ft+cø²»Bí‡æþ±öø‡h]°üßÖ>ÂÛô_9¯Q†] ЕÚl?7õ°ŸÄ;Bí‡æþ±öø†ß¢ø±ÍzŒ2èV ;»“cûK¶èkõëB}:™ (T‰š”œKiþÖLÍKI`²|sÐFeÂôêÓª±S’kÉ܆šâ})Ø/ì.Æú¿âXóÛ÷ìRðú%ÿá1é°_Ø]ô3ıç·ïØ¥áôKÿÂaÌ’íb¥ßWõËï|pU_×,?è¾ñŸFºFŽG@ÖÉè)[' {ôL lŽƒ¹=ci# Æ®OXõhfk%tlŽ“)]#[#¤Ç«DÇ3\øÃ|f>0ß•34Œ7F#½c-шïXÛ„ŒGF+½2®ôÛŒŒG~ Œ~±ïÁ1Ö5ÇŃ$Ä Iõ}BO|A ï€ O|@žø€ Ô OP€Þ'¼ $ I$@AÔ€H"Ô Äõ0B€õÔ ÀÀÀÀˆ aßøÒ‚þÂìo¡›þ%=¿~Å/¢_þ›ý…ØßC7üK{~ýŠ^D¿ü&9ó,] ,T ;オþ¹c½ïŽAT‰µRônL–™RPâß”Ó %(”i,¸¢#3Ò®Žðøˆ›ªÒ>ˆ¤£E6r²:¶O@ë¶jF_Òh¾z‰ëF¾E­S2þ•Cóä?Z?AFèyõ*C©ÈÈè1«“Ö;'í*©çü®çè^´k¤YõcÏù]½ûî>¸z”SF)Î=N.WHÖÈé1Úɲë|&[Ÿ¾ã놽û"²få¶Ï¤´ÿ^=J;Œ“’8—Æã´zÅ­Ÿþ]kúONõãë ¸ùu­éM7×Fœ—S4š8§F#½cµvÀ®Ÿþ_jzULöŒæÏ«ÇŸòûOÒÊg´ œzœdqŒWz wlò¾ÿ´½-¥û@ÆsgW‘ÿœ-K©~Ð6B¤:£ŒŽß‚c¬wlâá2ÿHÙþ˜R½¤xv·¸sþ‘³½1¥{HÕ´íù‘ɦqÆ vG³{‡å;ÓW´ˆíopü£gzcJö‘mm>å™g}Bd{7¸~Q³½1¥{HŽÖ÷Ê6w¦4¯i m>嘳8à—k{‡å;ÓW´‡k{‡å;ÓW´†¶ŸrÌYœh˵½Ãòé+ÚDv·¸~Q³½1¥{Hki÷,Å™Çì{[Ü?(ÙÞ˜Ò½¤Ok{‡å;ÓW´†¶ŸrÌYœh˵½Ãòé+ÚDv·¸~Q³½1¥{Hki÷,Å™Çì{[Ü?(ÙÞ˜Ò½¤;[Ü?(ÙÞ˜Ò½¤5´û–bÌãˆO|v=­î”lïLi^Ò­î”lïLi^ÒÚ}Ë1fq ;.Ö÷Ê6w¦4¯iÖ÷Ê6w¦4¯i m>嘳8Ðk{‡å;ÓW´‰íopü£gzcJöÖÓîY‹3Žïˆ—k{‡å;ÓW´‡k{‡å;ÓW´†¶ŸrÌYœh˵½Ãòé+ÚCµ½Ãòé+ÚC[O¹f,Î4cÚÞáùFÎôÆ•í!ÚÞáùFÎôÆ•í!­§Ü³g±íopü£gzcJöíopü£gzcJöÖÓîY‹3Žk{‡å;ÓW´‰íopü£gzcJöÖÓîY‹3Ùv·¸~Q³½1¥{HŽÖ÷Ê6w¦4¯i m>嘳8þ¡²íopãý#gzcJö‘­î”lïLi^ÒÚ}Ë1fqÀ;.Ö÷Ê6w¦4¯iÖ÷Ê6w¦4¯i m>嘳8îðÙv·¸xœlïLi^Ò#µ½Ãòé+ÚC[O¹f,Î<„ȶopü£gzcJö‘­î”lïLi^ÒÚ}Ë1fqÀ;.Ö÷Ê6w¦4¯iÚÞáùFÎôÆ•í!­§Ü³gAÔ;Ù½Ãòé+ÚCµ½Ãôé+ÚC[O¹f,Î4cÚÞáùFÎôÆ•í"{[Ü?(ÙÞ˜Ò½¤5´û–bÌã„˵½Ãòé+ÚDv·¸~Q³½1¥{Hki÷,Å™Çõ1Ùv·¸qþ‘³½1¥{Hv·¸~Q³½1¥{Hki÷,řƀì»[Ü?(ÙÞ˜Ò½¤Gk{‡å;ÓW´†¶ŸrÌYœy‘lÞáùFÎôÆ•í";[Ü?(ÙÞ˜Ò½¤5´û–bÌãú„˵½Ãôé+ÚDv·¸~Q³½1¥{Hki÷,Å™Çì{[Ü?(ÙÞ˜Ò½¤;[Ü?(ÙÞ˜Ò½¤5´û–bÌ㌠v]­î”lïLi^Ò­î”lïLi^ÒÚ}Ë1fq ;Ö÷Ê6w¦4¯iÖ÷Ê6w¦4¯i m>嘳8à—k{‡å;ÓW´ˆíopü£gzcJöÖÓîY‹3ŽÙv·¸~Q³½1¥{HŽÖ÷Ê6w¦4¯i m>嘳8ñ²íopü£gzcJö‘­î”lïLi^ÒÚ}Ë1fqÀ;Ö÷Ê6w¦4¯iÖ÷Ê6w¦4¯i m>嘳8àk{‡å;ÓW´‡k{‡å;ÓW´†¶ŸrÌYœpǵ½Ãòé+ÚCµ½Ãòé+ÚC[O¹f,Î8cÚÞáùFÎôÆ•í!ÚÞáùFÎôÆ•í!­§Ü³g²íopü£gzcJöíopü£gzcJöÖÓîY‹3Øö·¸~Q³½1¥{Hv·¸~Q³½1¥{Hki÷,řǘwÇb{7¸~Q³½1¥{Hv·¸~Q³½1¥{Hki÷,řƀì{[Ü?(ÙÞ˜Ò½¤;[Ü?(ÙÞ˜Ò½¤5´û–bÌã€oî+F±A‚‰³]£?NZéõ¨s´¨È̉Dë4ä’¬jÆpxèhÎ2ü®äJv û ±¾†oø–<öýû¼>‰øLzlöc} ßñ,yíûö)x}ÿð˜¯2ÅÚÅJ¾9™?Õ:¯Ò1?ÙÉ7|s2ªu_¤b³’> û×ðþûúßñ¾ú£Ž}fEП²C_!å‘t7äÓø é[' {tR2Ô„zoÉp³Ü³äQø t‰¯{ˆß¾3”eÈè1«“Ö=J0‹äbœWCMBAâ~ø~P§G¸ëï3ÐÕQÜã{Éi({FsŒéAã8>žñŒI]#±Ø»hvUàÓ· µg%N¸J4¶FmåG¤Œð]<ϼF=m9I&‘НáW8šân*:ÒŠµ©ê_Á)T†Û5†¦Ë#LõfaâiÞncò MÁD¢ìê]¶uTÝ/˘Ãí´m<ˆ±Ú²¬)z•—rzI<:ÈÇñ¶(öm¥}Ö­Ê} Ë¬·’Û®OxÃËa*JÑÝàÒ“Q(Ò²VO%’#"/J5.6Y\¹X¯jë÷\®>ý¤¼Öö’Âw«¡iË|Rx<p÷+³K? ¥ù®7«ývͦÜÛKÙÝ ­í>-b܉*B%×I¢ÒëŠCFê–iN¥)É‘wŽyJ-2Ú¼é×[0-ö¨’(Ô·ª‘fKΈiIÔÛ¤âÔFf•p4’0eÑÔ5GF¥Ú²99 •ùÅÿˆ¥yª7«åR¸Tã©sdE¾ÜrždºÞcV[¬jÇtàX7K>‰²«åUŸeN®S).L’–]K“zÍ)pŒ–eƒîL““Ws$Xwi¾ç·«ÔÚJéy½ŽÔtO}Ô%•GS‰%%k4)i%%ÂJLÒ‚Ï3=0Ñèö,‘ÊMœ%V£pÓJ?8R ÃåL&L}ý 27Ì«:\F¦»¤ .­ì–£ŸèÔo3DõbÜ÷BV©­³a!v•ãvÏ¥ÈBÖì²6›Ô³Ü'‘nðFœ¨xQ÷yÁ’ëµlönKrç¥ZScË »U}³•)F¥6.2µ›Ù' Óm 4šK.'$¬Ó-¾ $rm•ܵ£yš'«Ù-GÁ¨Þf‰êƲk­¿-çÚŒÔVÜqKK  ™™%&³R°]¨Ìøq3>#ÄuÙhv,‘™º;–£àÔo3Dõb;%¨ø5ÌÑ=XÓŸP€Ùhv,ÄÍÏdµ£yš'«­–¦+v‹Ô©´—jî¢GBÛ¦°Ò·N·8ÜlÍ,¥FÚ2“àzK¼+eì»ú•+ýu·ÿÙÔFm.:te(E'ä‹E¶Î7²ZƒQ¼ÍÕ‡dµ£yš'«`vZ‹$W7=’Ô|æhž¬;%¨ø5ÌÑ=XÓl´;Hbfç²ZƒQ¼ÍÕ‡dµ£yš'«` –‡bÉ LÜöKQðj7™¢z°ì–£àÔo3DõcL²ÐìY!‰›žÉj> Fó4OV'²ZƒQ¼ÍÕ) ï†ËC±d†&ttŠ•ÅX¨5N¤ÑàÔ&½Üx´θ¼¨ð”´fx"3áÔF6µjnÑ)—6«d?*>ÒmVšBÅJdˆ†Çk¶oÓÐÞ/›6•¶}¢Ü‘îȵ‚†íVD»f^'e Öán¨BH5žƒ_ðÎK<çBŒ_äY"nÏÎ’Ô|æhž¬;%¨ø5ÌÑ=Xî6yeA•³ …í&*©%5tRâéՑ2E½[‹ZhÖx4’R•‘ü#Á‘pسÞÍì“«Ö)Tº]].•jËRÑOu¼’K|…¯Kn~ŒÈÔ£4å]רÑûH]•¿dµ£yš'«Ù-GÁ¨Þf‰êų´;- gÕʳ–E¼ä}M7M®[Õ™›a{ädžK)ˆ”Ià£I`²F^5[RÍ m~—²©vêgoœ‡ec–<™;ùAïI+tHI¸XJ¬’x˜…GGвB쯓u¿C~ºÅ¿ÚLg §ç"ÝŽ¨í,ôá*pšÒ“îÓÀÏûEß!¯ì–£àÔo3DõbÏ·é* ì—nt5HYèô¾’"ìæ»%¨ø5ÌÑ=XvKQðj7™¢z±bN‰f¯`_1,Š{5e]¦¼…L–¦ ¤³¾4¡;ì‘+I$õ)J—ƒ#ÒiöÛœ[ ÈÚUÁiÒìVŽÔT¡§©IÞF}ÈéRo»Á¥*ZTiY+Qä²DdE …í«Y"nú•¯dµ£yš'«Éj> Fó4OV-:­©fÐ6½KÙTËu3·ÎC‡2±ËLü„ ÷$•º$$Ü,%HVH¸˜Õij(‘vuµvçSØ“X´ê1#©%×R¬.Y²á {³N3,§%­\O†Š‹$.βZŽ?£Q¼ÍՈ얣àÔo3Dõc²½èöý3e›2ºaÐ"76©Ë¹ÉûæÜÎNúN¢72E[³G4ðÇe}[»<¥û Ñ³H–[mÓ¥K‰ RÊ¡$ä0·Ûo hÍÃFÜ#ÂÒ¼ž®$X"j(v,—!wÔ¦û%¨ø5ÌÑ=XvKQðj7™¢z±ãvRNƒtÕèjxž:t×¢„X%îÜ4jýøÈÖ ìÔ;H‹³uÙ-G‡ù5ÌÑ=XŽÉj> Fó4OV4ýá²ÐìY!‰›¢¹j> Fó4OV#²ZƒQ¼ÍÕ9 –‡bÉ LÜöKQðj7™¢z°ì–£àÔo3DõcL²ÐìY!‰›¢¹j> Fó4OV’Ôqýæhž¬iˆ:ƒe¡Ø²C, ‘Õªí^Ð¥ÔiÔ90¦WaGÊèÑ4¸ÚßBT“ýA‘™ $º“´º% "Ó?M nº§©Ì<µ«”¾œš–ƒ>„¤ºz†^Ãmv/úÇOÿyliîôE¹ôjÿÞä õ(ÓU#k®^R,›±=’Ô|æhž¬Gdµ£yš'«qFËC±dŠâfë²ZŽ?£Q¼ÍՈ얣àÔo3DõcOÔ Ãe¡Ø²C7=’Ô|æhž¬;%¨ø5ÌÑ=XÓl´;Hbfè®ZƒQ¼ÍՈ얣àÔo3DõcNBe¡Ø²C7]’Ôqýæhž¬Gdµ£yš'«~¡²ÐìY!‰––îÔÛA­ÍT„–MJ³Û"/ÿÀ9—® ³-—¡RZq 4­ ¢Å%$ˤŒ®;ßtïF{fÏGyÆ]E‡K4­µT“ý/2\‹U¥LØ÷=É[5{‚$¶ê²KóìFQ›n(Ï¥jm&D³ÎxtàsÔQJî $MÙJvKQðj7™¢z°ì–£àÔo3Dõc¹·©V­õL¼§[lÐ$ÐéUáHb[î­²¤’›xZ’jRUÀÐHÁ—F8¹©vµ‰I´Z¨[LÜ«t†jó$H–ûFÛo)ZZdšZR“$§Š–Kâ}à'QC†’"ï©ÃöKQðj7™¢z°ì–£àÔo3Dõc¸¢Pí®ÊöŸZ…Gp×E™ tY’p¤¶ÃòMJWºQ’_ÙéR¸ŸsÞoÓ6[³+¦#sjœ»œo¾mÌäï¡´ê#s)ÔYÕ»4qQãO N¢…íd…ßSì–£àÔo3DõaÙ-GÁ¨Þf‰êÅóqØ»8gi{C´˜´Ž<[rÞUf;íT_7m´Ë†ßvµ'B·˜â“Qp}\-ÅeÑ*ôm–Ôè°Z¢?xH~¦[uÇYimÊC$âwŠR‹$¼™jÇªŽŽÿ¡d‰»êp’Ô|æhž¬;%¨ø5ÌÑ=X¸'X’o ½©2-¯D¦E91ãVÝ»9©y²Q!o2r °µ¤ˆÐM%IÕÕƒå"iE÷<¢ñiÄŸZfå:R\\¹(CÍœ}÷éR‡2-> sžëTêhv,»êqëu©³‡ŸK“%÷Ó,µCе¸µR”“Y332""é •ÊÔ)C™O¥Æ’Êiæ]¡ÅBÛZO J’mdŒŒŒŒ ZA¡Û;wÙlÊ=1 ïG¤Uy¯8´Fq÷t™!Z‰g¤È–F|Hµj,‘ê/Xš{¡§ÛT»Zd*ã˜ÛÅSÍ99$újqn­Ä¶zP³ÊDZ¹<P¡Ø²Bìà;%¨ø5ÌÑ=XË“R¸¢ÓáÔdÑà± n¾I!Êd·#Aé^…XV“àxΤX›iOÙ…Õ_¤9o·Q¶äÄ%Lç[[o:mitå$ˆÕ’É)£ÁàòEÃ>ûBªÁgÜë²æÜ¶©R"=]¦ÜqÉ$¨ÊL„¤ÝF—ˆj>ìÉd¤êèJS܆¢‡(,»êV¯ÕëÑáFšý*œÔYZ¹;Ë¡FJÒxV…XVã Æ?dµ£yš'«E~Û…ZÙöÆX†…@‘^•6 ÇÊžu”¨¥4É8–ÜZ’ƒ<šÔHÒF£>X"Ë¥Z–mkÕM•C·SräÈpë±åIßÇBÏxêM[£B³ÊR„à•ÀÃQC±d…ÙVvKQðj7™¢z°ì–£àÔo3Dõc½¤S­(¾ç”^3­8“ëLܧJK‹—%y³¾ý*Páã&E£GÁNsÝjÔmºÜ£Ûõ[vM*¡E®Û°êçÝS‰Ž·‰Z•(ÍF’4ä²f|Dª¶’"ï©ÌöKQðj7™¢z°ì–£àÔo3DõcLÛ-Å’™¹ì–£àÔo3DõaÙ-GÁ¨Þf‰êƘe¡Ø²C7=’Ô|æhž¬;%¨ø5ÌÑ=XÓl´;HbfèîZƒQ¼ÍÕ‡dµ£yš'«cøl´;Hbfã²ZƒQ¼ÍÕ‡dµ£yš'«` –‡bÉ L±ö ÌvcKäÑcEKÑ-¹ n; iã”ãŠ$ ‰$jZ”£Áq33À²¶«ýoû…j9èœ%ñ_ù‰2>”ìöc} ßñ,yíûö)x}ÿð˜ôØ/ì.Æú¿âXóÛ÷ìRðú%ÿá1ߘ.Ð*PñÌÉþ©Õ~‘‰þÎHé»ã™•ýSªý#ýœ‘ð-Þ¿‡ðÏßÖÿúÿ(ã$t lž×=w]_ÖJçî¨8_ýF וÐEýf¸?uMÂÿê=êX|þÿSIÔíùœlŽƒ¹=c¸z÷º ?÷Orþ계0_¿.‚ÏýÔ]_º´áô•Ñ?—©Žr—C‚•Ò3m[¦E°u>OL§Íçk„ÿ*Þðe %¡iÆ®>’Á`ËŽzöƒt'þÝÿººáôOmè#þµ^ºàp¿ÿ‘éЩ(»¨¿—©ŽwjÍC2ZuÆ„,”¦œ5"<šOI’°}ƒ#ï Ý¡ÝïêýB(³B÷%%’4–’Q’Ô¬’IpÁw%Ã93éÚUÐ_ð®÷ýן”b»´Û ¿áeõû®W? ô)Õ©k`/S„Mô:ÅF¯A«E…O¤M Æn,a¹&›ýZN8²Q'*þóÔz³Ãú•ñ1Ê}J:H£Q:'½· ÉÕ¨ÑÝ­D„™àÍ($‘ãõͨÝÿ oßÝt9ù;›Sº ?÷[´Ýt¹êƸ֫Øó^§ #›¹¯)5«2…k;H¦G‹CÞrGØßoxywQ©Å$õ« >ä°e„é,Ævô•ÚÐì>h¥ò]ΫôÜ£”cN¼ï4|ã1Ž8Õݕͫ]ÿ ¶‡û®·=XÇsk7Agþëö‹û®×=XÕ µ|7šõ9I#CZÚ Úµ >§A¡K“–T¨µXqOµ$d”‘o7Zˆ”xY£Qt‘‘ñ;¦ë‹JÙWkª%ÌÕ~µUÌ) Äuƒj>iiDá‘©ÂÖiN¤‘¤»¥g‡ö½®]_Öý¤z^çª=·®Œÿ\6•鋞¨hJ¾ÍÚ]JÔÄ ,ö½txá´¯L\õB;o]8m+Ó=P鯭á<Ñ]JØú„ ,ö½txá´¯L\õB;o]8m+Ó=PkëxO4,º•¨²ö]ýJ•þºÛÿìê!ÛzèñÃi^˜¹ê†ÉªÅRùµÚ•Rºï‡ùÑJˆÛSîKm<¡ÌÝA)¡ÔîH’®8%+€á¤Ô©:RS†Öé“®T@,¾Û×GŽJôÅÏT#¶õÑã†Ò½1sÕúúÞÍeÔ­@Y]·®6•鋞¨Omë£Ç ¥zbçª }o æ…—R´eöÞº""-Çmë£Ç ¥zbçªÛ×GŽJôÅÏT!Õ¬ÿ´ó^¢Ë©£}ʆÝRh4W(u7‘!ê;ˆxâ¶êK¶Ïy½B¸Ÿs ñÑ‚/J^Ðê4Û†›T‡E¡·šÔ†£Ò‡ÒûJmÝdkÖ³RUÄÔ³>å%ÐDCoÛzèñÃi^˜¹ê„öÞºŸt–ЇÊ8HpÐ’I(Ék^I%< ‹¹.ÉŸIÛzèñÃi^˜¹ê„öÞº¬¸rS"*’Ù$ÉHY¡µ-*%)*R‚RxðÂyžÛ×GŽJôÅÏT#¶õÑã†Ò½1sÕÖUðžhYu+™/½*K²d:·^uf·YåJQžLÌúÌÌy‹/¶õÑã†Ò½1sÕmë£Ç ¥zbçª×ÖðžhYu+^ðeöÞºþºeÝðn£¨îjTâB`îKmEB> m¶E¥("ÉiÆ'œäÇEÛzèñÃi^˜¹êƒ¶õÑã†Ò½1sÕ ªµWö¾kÔYu4Õ  Nv›T…K¢Q(gWNŠ‹ôö'$£V£AïQ!&¢#4¶I#Æ:8] N*E2T¢Q+|Ò“E9ù츧c#V¢Ahq)ZHòd— dYÆ1Àn»o]8m+Ó=PvÞº\S|¤–­NN©&jYÏ ,%’²6£Y\Ùµf)4H•ùì­™U˜ì8™.Ó¥j"5›HR‹$jB|OÛzèñÃi^˜¹êƒ¶õÑã†Ò½1sÕ¶¯…ó^¢Ë© ìÞWk×üÍJ俜y_éùO(ÆyÞhý_qÇjîƒhw¼«Ó™ù]•N戧Fä;þ1Ñú´+zâó§*Áð3Ôy3áÿmë£Ç ¥zbçªÛ×GŽJôÅÏT'[[Ž©æ½E—RµevÞºýN­SvbhW"©,äÉRŸ¦)ãJœ2-D“sIpø)Iu à4Nø¯üÄHúS°_Ø]ô3ıç·ïØ¥áôKÿÂcÓ`¿°»èfÿ‰cÏoß±KÃè—ÿ„Ç~`»@X©@wÇ3'ú§UúF'û9#¦ïŽfOõN«ôŒOörGÀ´zþÃ?_þ/ßTq’:¶O@ÙHèÙ=Ü¢g¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ën޲֍J›Fµ£Ëi 9s*Ü‘J”¥8xÁÊàœ%II%¾èôšºømÂezèÅw ÇU´˜ÐáÞU¢rD2hCŒ’„¥âm;Ý _tHÞk4‘ñÒd9Wz mÆF#¿Æ?XÈwà˜ÇëãÀâÁˆbˆ$ú„ >¡²ö]ýJ•þºÛÿìê"´^Ë¿©R¿×[ýDdÓ¿ãÏàZZJ‰St‘6 2KjÏ6¢K©Q’ÛAçF]dpÝ9øØlä³tÌ5C§ËIQ*n’&ÁfR mByæÔIu*I-´qÔeÐfG4ûbÜ;.›sUni±•2L'c3KKΥƒÒÈÑ—’KA¥ääÌÐi>JéìÁÇîi¶Â©×¥VÝqM¸Õ\èr™†N&S*€©•%J#lœŽ¥¢ÔiQ—í•cÓë4ú$Ê5^£1]ÝV?ÍÍ ©fIÔ¥(Íü):Ij%«v“JO‰))ŒH0 …Ç—¹.-¦íRžÒô³1ÈÜœÞ".*ÝêV’Îq“É– ÈŒð[Ø6Í ¥O[tË™ÙU¦éÎO\S§)ÈšhÞu²xרÜJ¿üY$Í&D£ÉÍÁÉééÖõª$:Ç]“M*†µBf,’µ¡*4‹Ëˆ$#ZT’Á©FhWsÑž®èµ©•½«Ë£®§–]Gž‰iéLG]n–Ô—¡7h^—©)3#2î8ž#Z;“´mDÒ W¼e¢‘6Cг¤(Cí’ z›ßiÝ’]lõ’Ìû¢îsœx1oI¦3S_©®<ê#Ì–Œ—”„Oe¥§xj#lÉÃiE„ž¢I‘šzØ8ÐÂí+V-*ߨT®ù‘“[…ÊB)â˜Z^q•ï?LE»%4zVYR‹9Bqƒån\š~£E™£”Óå;í”ëmf•cû²F%4Á…Ô OP {Â÷„$„ !$ƒ¨:€†Ãmv/úÇOÿyliîôE¹ôjÿÞä ÆÃmv/úÇOÿyliîôE¹ôjÿÞä •=ô~?Ä‹.œ@‘YRz„ž¡H@’ž¡z„ív*T=¶YOD’ôw]†Ò–ÒÍ&h[ÉBÓ’êRT¤™t‘ð1Åëö;.•KÚ-"¹XŸ$zL”OAIuöÒó­-*Cz™aõuƒ<£”¨µ$ÌŒeÓ“–Q%{§»®âÑâŽ×dT¸Ìí®×­#k)µ'k±ÖêšMP¤K7"q×$fá)I=j"=g¨ðf8Êt:K”'o;ÍÚÍQU“Ñ™j,´´ô‡”8û®<âèß7ý“5ωcCeÀ³-½¢Ó.dß–ä˜4ÊŠfÇ„nT’éî×­¤­în2<'Q“e¨ˆðIÉdS"XmÓåPê·½:‡ËW2 MÈ©µ."”D“-÷6© Ô”¶JËe“BL´ñ!ä¹Ê\’›ME~[;'+¥dº¯Óƒ¹~F¾‘aÒ'Ü rEÔêé´S«S 4ãmN˜dù°¨ÉQ¥IÞ%HxòIV¤´fIÉà³ìªm¹F÷@Ø B^BS‚©tú†•QÉÒ–Ö³l‰Ä–s$„êJ´÷ É–Z²_«;Η5“.‰ÍeK‰ê‡a6N“¤ãO*°é¬–f³I‘ï\-$JÁ'O¢*ö¶n(BµnÚäÅ™gUêÒËÊy$ë¼…:ÏRŒ¸%$I$‘s©^¢”d¥g¸>kuì¸õÜ·ÿU·’Eaq?n¾ë'nÒª´öÉ'½Lú“rÍGÔi40Ö’þã#ýÃs*)žÚµwJ¬ënÖ'ÇŸ—$›Y4˜k5°[³Ü­Hxf­çÒ}Énîkg’Ó»zñ¶©HlÖ§—*EV[¯±‚ÉSÛJRœ“žèò¥pÆz¡XoXô+nEïBS”ú«ó¥InME%!¥¤8ÚtÃÝž˜íaF¥‘³4™(‰;e¤¬4ðÂ{›º´¯kIqøÛ›+n'ÅgXÌÞw]—HràUFŒU'#Ï‘!£eÎF‡]SJh›%gCJNð—ÅDG ˆðY6­ãØ>ǨÕKqUêezMj …̇Sm¶[-ÃR7Í Þ´Dö £V5ofd²Jve6Ãsj·é*í¡.-i¹åÈ[›QBÙ\Æ–ÛªÞ,ÉDDó¦’ÐFFhÉ«IêÓÈ…a¿³X6ÂïzT¡M“1¹å&£¹5¿¸JÈØæÍX&ã ‹ô„zJ32ÂKåV0§^” wO¥{õIÚë‡DËp»FaöŸf®õÖ»&å<ßË÷írN]Îz7ÆóyŸíiþÈ­EÛÎg;vUÙe«Ùvwœ¿UäÜ£Òy?7êÞç»ýf|t〦'2Üy¯ÇfS2ÛiÅ!%’"<ÒKJTD}%©$x>$GÀz~Ï©Rm©©-ËŠ|wݯ._$Rir<@ze 0ï‡|²¶«ýoû…j,­ªÿE{èë[þÅ!ZŒš' |WþbZGÒ‚þÂìo¡›þ%=¿~Å/¢_þ›ý…ØßC7üK{~ýŠ^D¿ü&;óÚÅJ¾9™?Õ:¯Ò1?ÙÉ7|s2ªu_¤b³’> û×ðþûúÿñ~ú£Œ‘Ð5²zÊG@ÖÉèå=C[# Æ®OXÚHè1«“Ö=ZšÉ]#[#¤ÆÊWHÖÈé1êÑ1Ì×>0ߌ7Ç¥LÍ# Ñ»aV<š,&çn›Ra+L—"GD–ååjRU…ºƒlÉ&Iá¨I2g#£Þ±¶ —­]ªÝ}ÙìG[ n™ŽÊ½k&Úi Ôx,¨Ò‚3¡²ö]ýJ•þºÛÿìê"´^Ë¿©R¿×[ýDdÓ¿ãÏàZÛ("K„á¨Ì¹:OŠ ;Ã,÷$jæ»âX_d¶_gÜëË®mìgšuó[;í÷7rZ9FKyÏqíŒJÕoÛÔú<Bª50ñtœˆ-ÿ”6x#a²'{¦É&¼›fk$¯$d’E~0 gW“HEbJhOÎ~›«1×5”´öœ%*RrG’Égœ°ÞÓhnΚ·î;Þ-&¡\3¡Gi³ƒžŽãI$#~”º„ÈÉ&–Ï«%Æ™qOˆ:ȵ;j«@¦SîGªÐߤ¶ãž·ÉæTêÝФ­Äh2[Ž¢5d”E§‡˪Êh*®ëЩŽ[GKܦOºËÇOä8#7KA'ôšû“3-: :…f„[•rEA¡»2ªÜصy2¦š`6¦ÐËéam«|Fµ¤£¤ô™ ŒÖe¨´å[ºÅÏjN¸6‘QDšÚ¹[YÓ’tö²•®[RŒý?rD¦‰²4ëÉ(Õ‚2ÐuÈaWrTmÊ2΄Äʪy¶é-p-¤ºù©’'yúÒD­Þtäµ'iJuvÿ¯W)*–pªSÞ˜ÙJe-¸êf“JT¢îMFY#âDG‚Î Ÿ)z„ ê$Ox@žð€$ uP°Øoí®ÅÿXéÿï-=Ãþˆ·>_ûܸØoí®ÅÿXéÿï-=Ãþˆ·>_ûÜ’§¾Çø‘eÀÓˆ k*OPƒÔ ÀIBÔ OP€NÌit*ÅÅ*Á¤üVéS¦  ËDuëÉF¥´á(š4tdD¬ž'Ëîö¹ _OL‰U‡Jŧ¸•"¤Ô-9 æ™Ðã‹A÷®7ŒKáp$™–]:N:5I'f“òßmÅ£ÅݘRèU‹ŠL;‚=Iø­Ò§LAA–ˆë×3’KiÂ2Q4¤tdD¬ž'‹oYÕúì4TEÞHz\æ"¡×ˆÍ ›ËNñDFYJre’áćs³;Úø¸kU*]oh'©ïЪ8ÍfãÝGunBy¦’{÷I 3uÆð]%ð¸LËHtô]¶}·›W£D‘GŒôI‘ª¢U%׉ô›ªI8F—II3Qnº1Œãž‘Z¤—åæÚ_›ôÚöK"ÖMUqTjà·ž§¯w0çÉjqÖfdHZÞRR•’ˆ’g“Áà¸ÝZ[<©O¾ª6¥q¤Ó&B¥Í˜¶ßšÄl-¸‹yžíÅiR­Ù™‘þ¬Ô¼’HÔ]lz”ÕNæf BÙ©ÆÑJŽtúÛüª™ÆŒl.[RãFÚÒ¤šˆDjL…d¸¢$š+;cœÔ:Êú,Ê{&NÞ4Ó®Òœa ïׂ6ꉤ¬ð Ið!ÊZf‘5R+sP¿tìŸ_7ËõºhaJÇ]¤Ê¢Ï8S€ëº z¡Ob[x?ÿ¨ÊÔŒÿvrCunYÚ‹ê‡Kå^¤G*‹¥Mm*ÂÊ:3ZÏ‚’JCk"Qt †¦ä¢¹BšÔ7ª4¹¯)’qÎo–‰(hÌÌ´ˆÊ¬p¥\s’.Ê«Mjé‘E¯Sî:-:$jd(²ŠUA¶^„¸ì¡¥©,¨ÉÇ5 ÒÝ%y׎œÙZ¼”"Ô•Ÿ;;~–wßË~wERÞj®+"Zv—sÚÖëK‘Q”Á=)öÚKl´ñ¶•¼ê £û$fzK&D]$CQSµkôúÌJCôå92i$á¦3ˆ‰$¥HÚ[f¤¸F¢2ÊLË$eÔ,kÕPª×†Ó­øµª:«ÜIªSåEžK)”¹![½ù+v“Rd!}ÒˆˆÚ4žX”š.Û;jݨՠ½!‚«”™‘^) Â9±S¢Þ7’^íI7LÐj"×Ã'’)iµð.nÜ,îÿïð¾îy–qG#U°nºl8“¦µ&4¹i„˰&11'!E”²fÊ×¥Ã"< ð|€ò¸ì«ŽKER£9ÁSü˜äEœÄ¤!ì·K6–­ ÁéVðà7ôj[ö´úÊ¿iô×®Ä|‘O”ÝA˜©mG‰®“K4joYéA÷FF¿ƒý¬Í¥5Mi¸œÐ Tߪ6³‹oV9T)­%·ÊÑ8²ei5$ŒÒxudHN=#¦UÖÆ7M>i?åòê±yÙ *ÅdÖ9€aßøemWú+ßGZßö) ÔY[UþŠ÷ÑÖ·ýŠBµ4Nø¯üÄ´¥;ý…ØßC7üK{~ýŠ^D¿ü&=6 û ±¾†oø–<öýû¼>‰øLwæ ´Š”|s2¿ªu_¤b³’:nøædÿTê¿HÄÿg$| A÷¯áü3÷õ¿ã~¿Ê5CµÌ¿ÒõÏÝHlÿû‚õ:×2ÿK\ºŠÙÿ÷#G@ÖÉèõ)y/Ÿ©Š¤'Ýò6ORmsÏùÖåýÔ&Ïÿ¹/Ñ-sÏùÒêýÖógÿÝ LŽƒ¹=cÒ£‹•¾ÿSã.¦íû~×WÿÄ®ÿÝm¶ýÐÂzÛµÌÿÒ7Ÿî¶?þìsÒºF¶GIN’Ÿ&²ú™&ŸS§vÖµÏÿâ¿îµ[öÁŠí§kŸþ_}~ëM¿l‹ã ñ¾«Ü²ú™äŽÅËB×?ü¾ýýÖ‹~Ø1ܳmsÏùvÐ?užß¶Ž)шïXÙVïY}N2;‡,«\ÿòÝ¡þë5¿mîY¹çü·h¿ºËoÛGèÅw Æ¨S¯Þ²úœ¥c½]‹k™LÚG¡-ûpñì×ÏôÍ¥zß· õß‚c¬j-#Ä_·êrmt,£°í ÚW¡ ûpŽÀí ÚW¡ ûp­Œ@¶«Hñíú‘uвÎõü3i^„7íÂ;µü3i^„7í¶>¡ªÒ³ÑëT‹Œ¦š~_Pš\‹/°;_Ã6•èC~Ü#°;_Ã6•èC~Ü+PÕi"ý¿Quв»µü3i^„7íÂ{µü3i^„7í´Õi"ý¿Quвûµü3i^„7íÂ;µü3i^„7íµÕi"ý¿Quв»µü3i^„7íÁدá›Jô!¿n¨«Hñíú‹®…—دá›Jô!¿nÀí ÚW¡ ûp­O|5ZGˆ¿oÔ]t,®Àí ÚW¡ ûpvkøfÒ½oÛ…hªÒ’,™™ð"#1ÔÑ­›.§=ºRoÓ‡9ÅhL‰”ÍÕ?WV_ÞšÒœÿiM'xéé ûŸÿŸ¨ºèm»µü3i^„7íÁدá›Jô!¿n}F‹=™G¸Xœë®N—.#ñ×L­„°¢4¬–zÉI}=)N Œ°eƒ? …»pSélU'Ъ‘ HÆæSñCNg‰iY–÷jô~ߨºèvÝÚþ´¯Böàì×ðÍ¥zß·&»pL¤=X‰C©È¦±ì¶¢-l·ŽK"Ò_¼Â—n\5XÍʦPª“˜vG%mØñq {N½ÙHÈ×§ºÓÓŽ=«Òž)Qþ¹¶£ÍñÍòù·”rnY¹Vç}§Vï^4ëÓÇNsŽ"uZGˆ¿oÔ]t;þÀí ÚW¡ ûpžÀí ÚW¡ ûpâZ¶®7ªiÍP*®M¨G)0£¦†ä–LDãiÆVƒ$¨õK}áíÛ‚ŸLb©>…T‰F72Ÿˆâs%’Ò³,ñˆÕé"Ëê.º¿`v¿†m+Іý¸G`v¿†m+Іý¸r%5ÉyÑíéS‚ÝN[q CqÉãmn+JA­-Fœ÷\ &DfX<:%±\”q(”™õ9 N³ju¼²O #<¯Hñíú‹®‡yدá›Jô!¿nدá›Jô!¿nÿ7Ïç.lä2yvóuÉ·JÞëÎ4èÆsž¬dl*VÕMfSÕjµ ¨imr—" ­¥„¸£J f¤–’Q‘‘g¤Ë½#Ä_·ê.º`v¿†m+Іý¸;µü3i^„7íÃ!{'r–Ü«¬ÝÅU’ˆï"›Üq\©+зYeãWÛeKZˆÛÁjIžHpñ豞±fÜIœéI‡S ȧ´iå¥Âs^rFÂÈÓ£­'¨ø‘B…wýÅû~£wC°ì×ðÍ¥zß·ì×ðÍ¥zß·'±Ûƒ™9󘪜՜rîHæã§¬ÆžŸï u»pT©¯Ô©Ô*¤È1òOIb#Ž4Þ8ž¥ï1:½#ÄY}E×C·+×ðÍ¥zß·ì×ðÍ¥zß· ؆ö©lÕ›¬Ë¦Ã·ëÈ‘rgF“ Dür&n¸´‘e ”fJQr¤ç‰†¯Hñíú‹®‡[دá›Jô!¿nدá›Jô!¿n=j]¡“Z¢Ô©…!&¦y\U³¼.úud¸—@Zô‰ÉM¡Ä%Ðdºþ"Ëê.ºEoÚöÅíB¹5m*_4Ô£ÎÜvÚ7»§½¹iéΜgŒôÒAµ ThtÆëÑïºtØL.9· ÖL¶Ô“yÇ Z×%£#ý&1§«¤óƉE¬L“24JLùÂioKm¨ëR£¶ƒÂÖ²"ÊR“2Éž³Äm¡Ø×Bî %¡C©Òœ­JDxk™ Æ’æT”𓍋Q'Yã£$*èVm7Q]y||üÅ×C¦ì×ðÍ¥zß·ì×ðÍ¥zß·fæ·©ÔÚ*½6°õA©5)Ð\Bd‹“îT—dµj%¡ô ‹I‘—tXQëêíÁO¦1TŸBªD#™OÄq 9ž%¥fX?ÜbÚ½#Ä_·ê.º¿`v¿†m+Іý¸;µü3i^„7íÈnÜ [ÕH*¤¸ó¾”ÄGÓxâz–E‚ýæ1ªôÚ¢í:­O—OšÎ7‘å2¦œFH”YJˆŒ²FGþBuzGˆ¿oÔ]t,Àí ÚW¡ ûpŽÀí ÚW¡ ûp­@5ZGˆ¿oÔ]t,²°í ÚW¡ ûpŽÀí ÚW¡ ûp­ˆ@j´~ߨºèY}Úþ´¯BöáÚþ´¯Böá[u V‘â/Ûõ] +°;_Ã6•èC~ÜÚþ´¯BöáZ€j´~ߨºèY}Úþ´¯Böá··)emrŽÇ.í±Q¹Nÿ µy>÷NtêÑ<µcR±žŒŸ|S¦+=´ã†SMyÇêH¾yÖåùÐÛϘœÿò!η/ΆÞ|Äçÿ‘0í«þ¿±Œ¾yÖåùÐÛϘœÿò!η/ΆÞ|Äçÿ‘0ûjÿ¯ìC|ó­Ëó¡·Ÿ19ÿäCn_ ¼ù‰Ïÿ"(`öÕÿ_؆2ùç[—çCo>bsÿȇ:Ü¿:yóŸþDPâýµ×ö!Œ¾yÖåùÐÛϘœÿò#ÆtºÜèO›´¹Ê‹!µ4ó/[ëZB‹ J’u‘‘ð21F/gYÝaýˆc,®Àí ÚW¡ ûpvkøfÒ½oÛ…jN«Hñíú‘uв»µü3i^„7íÁدá›Jô!¿n¨«Hñíú‹®…•دá›Jô!¿nÀí ÚW¡ ûp­@5ZGˆ¿oÔ]t,¾Àí ÚW¡ ûpvkøfÒ½oÛ…hªÒÔ¤4ùUÄJ´V£&ªC(²T–iŠhœSD¥h%’5‘j>åI<ŠàY[UþŠ÷ÑÖ·ýŠBµ „¾+ÿ1>”ìöc} ßñ,yíûö)x}ÿð˜ôØ/ì.Æú¿âXóÛ÷ìRðú%ÿá1ߘ.Ð*PñÌÉþ©Õ~‘‰þÎHé»ã™•ýSªý#ýœ‘ð-Þ¿‡ðÏßÖWÑ¿_ådŽ­“Ð:Çè´Ó/ëm¿öRý@×È¡Ó ¿®42ÿØÌöqïQƒûfJ“_iœŒŽƒ¹=c²~ƒJ<ÿÝ­¿ö3}œk¤[ô“ÏýÜÛÅþ,NöaêQF)É\®‘­‘Òcµ“nQÌøß¶á‹ý˜kß¶¨Ægÿ|d¿öe¥$Ùľ0ߣÖÅÿþbÚåÿG¨û ÄzÖ¡ŸÿÌ‹X¿èõ/d9#4™Å:1ë«¶­ ç*Ô/ú=OÙ3–¥ýó-2ÿ£TýŒl„×Ú8Èâ®ôî´¨9ö—ݪžÆ1œ´müýôm»U=Œl…Eç“8Èá]ø&1úÇpå¡ocö§gýÚ«ìCðû{?µ[;îµ_b£Q[žLäÑÇÙŸo|êÙßuªûŽÃíï[;îµ_bÖÇÏ'èEŽ<ú„Èìû{çVÎû­WØ„vo|êÙßuªûkcç“ô8à—aö÷έ÷Z¯±aö÷έ÷Z¯±¶>y?AcÙvo|êÙßuªûŽÃíï[;îµ_b l|ò~‚DZì>ÞùÕ³¾ëUö!=‡Ûß:¶wÝj¾ÄØùäýŽ4eØ}½ó«g}Ö«ìB;·¾ulïºÕ}ˆ5±óÉú pǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Çžøì{·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆ5±óÉú h˰û{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Æ€ì{·¾ulïºÕ}ˆOaö÷έ÷Z¯±¶>y?Ac]³Éñ)÷SNNy,G‘T%¼¢<3Ê#¸Á8xã„›„£Ç1­]„jzm1TêjÔº¤£Ó’EIx²—3ÔHÔjàDFf={·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆF±yäÅÝ !A±6Z®Ó$ö>›¾[’^\unœdÓŒ³ŒI—ˆ»æÚËû'õN"¢Ç¹ë3m{š;3 ÉKµ*­ÄÛ°f-D{³lÓ<¡[Í A!])#3JH̸nÃíï[;îµ_bÃíï[;îµ_bļò`²6]mîn+ þk»kp÷±Š›545L‰¾ZVë ¥ð%-iZ7ˆ5«Q¢3áé4ûŽ›±«ÍENªEeêtYê6‚Fí¹„ãn;“JÖÉ( Ö‚?„Y×vo|êÙßuªûvo|êÙßuªûb^y0{í. U‹fÁR…1’“o¨óí)$é&l“NeÝa¥2eÿ%H>ƒ!üÙ´Ê…{gw ú…K)Ó: o-–Û˜…©(.*Ò§›Îñ«#˰û{çVÎû­W؃°û{çVÎû­WØ„ãV¶ü˜±ÚÓ¨µ*=÷±$NжË\vµã(ÞbB–Þ¢á­â5'¥&dG§Jºi2.:ÍÚ™EIM–‡e¾³6*/-µrsiGÁã'¥‘§8$™ð"…*‡m]ë‚>Òl9’)Ò%–¥E¬îÍÄžP£Ñ*=*±œ‘g%’=|ËRÚ~cϵ´Ë"+n8¥¥†£V žI)5ÃR°]¨Ìøq3>"1¯<˜<6%L½°ÙÍEŽëî&µÓKh5!¥kV ©)J”gÔDf|gÓhÕê…€õ¹D§Or³´òªôÖZW)R ¶ÒΦ‹ºQ6´È#áÜšË8ÈÂì>ÞùÕ³¾ëUö!‡Ûß:¶wÝj¾Ä%Í_žLXë ÇùËšNJ{/ìKï7ż圧Vë^YÈÿCŒç=ÇO¬ªRnj&Ä*Pn%ÁOdp^PëY7R÷jî’•a83"΃Ç@Ä¡Ûöý*¦ÔâÚMƒ7w¨‰”ú£­,”“I’’p»Æx2Á‘àÈÈÈŒl+Ñ(bipïÝÑiäñH\x1+FNºI4’Ô§b­fdJQjÁjV ‰ˆÆ¼ò`Þ7m\pýÐ{>åt ¬}ç0n÷°ÜN¾O&ÿ.;½*×ÿœ`qðèu¨ûºÝ‘H¨2ÜKŠœÔ•.2ÒL­¶¦¡iY™w&•:ÒL ÜAq»·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆN5ç“ ûtùÛ—LRåv†YÝÔݸn•È´à™Y”EhFï¸6uËŠx¨jvu­&‹gT’Äøi€O+Š— –Í/ü¡Å(§4´ 3Q÷IÔÚ’]×Á.°û{‡ýõlïºÕ}ˆGaö÷έ÷Z¯± Ý[žLy ¾ꇶfQ‰Wj¤ÅŒ—Bb8N¥I îȱœ“å»ÿÏî~À•Ÿo|êÙßuªûŽÃíï[;îµ_bsO®LXÉ¦Ã«ÌØ…Ã=Q'Hƒà€®Pm©M6f̤ºzº Š£’¿½Mç¥9óÙGù½ÚõԮ䨴—–¿þåüGgÞF鬿æÌyöo|êÙßuªûöjÚ¤µ ømm~ÔDi Jže,ÕÉs¤ÔžEƒ2ÔxÏFO¾מLXØØ1 ×h1&U ·´\©m¬Èè*ˉh¿»~“GøÊ!ëiÓeÜ´ ½vD[¦ä•Qª)Sé´I„ɤÒD´Èx·MDjuÂIèÂt¯º,àhÊÏ·¾ulïºÕ}ˆ;·±ûU³¾ëUö Ƽò`±¤WÑ·g_¤R+$ìåKŒi#ñ™Ñ ²sx„‘:fùèÞ$ˆ”áพ³ÇjÔ—® UÉ­v/R™%J.O:A¦1w ø.jV£àGú=[Ø}½ó«g}Ö«ìCÝ«j’Ô7áµµûQ¤) y”³W$8iΓRy ËQã=>øŒJÜò`ÚÐa”gõªí6Océ»å®KÎGVélš`‘–qƒÉ2ñ|ÛYdñé•uÒg\Õ›½2¹ªu:b˜òòÅEå¶¢Žm/ཇ¥–œà’gÀˆh;·¾ulïºÕ}ˆGaö÷έ÷Z¯± Ƽò`ÞÏ¥]5iÝfÒL£¥A¦Äm©l,ÉŠsÈm% Ý_C&o«=XÉ(‰ç6Åû]¼¾žþð±ÕÑÙ¶iô豺öW=è†g\šmhIš]ÖˆÉC¸3á¼Jø`ºˆhª6Õ¡P‘>nÖíåIuO<â£Urµ¨ÌÔ£ÿ"é330SWç“8`—aö÷έ÷Z¯±ì>ÞùÕ³¾ëUö!ml|ò~‚ÇBdV}½ó«g}Ö«ìB;·¾ulïºÕ}ˆ5±óÉú PÙvocö«g}Ö«ìB;·¾ulïºÕ}ˆ5±óÉú pǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Çì»·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆ5±óÉú hǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Çì»·¾ulïºÕ}ˆGaö÷έ÷Z¯±¶>y?AcŽÙvo|êÙßuªûŽÃíï[;îµ_b l|ò~‚Ç v]‡Ûß:¶wÝj¾Ä#°û{çVÎû­W؃[<Ÿ ±Çì{·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆ5±óÉú pǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Çì{·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆ5±óÉú pǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Çì»·¾ulïºÕ}ˆ;·¾ulïºÕ}ˆ5±óÉú hǰû{çVÎû­W؃°û{çVÎû­W؃[<Ÿ ±Ç˜wÇbv}½ó«g}Ö«ìAØ}½ó«g}Ö«ìA­žOÐXã@v=‡Ûß:¶wÝj¾Ä‡Ûß:¶wÝj¾ÄØùäýÎÕ¢½ôu­ÿb­E‰´¹ÔÙñê+¤Ô™©DŽÝ¿¥2ÛˆmÕǦ)— $âR½:ÛQ¤‘™p+±ÃDÜ¥ñ_ù‰2>”ìöc} ßñ,yíûö)x}ÿð˜ôØ/ì.Æú¿âXóÛ÷ìRðú%ÿá1ߘ.Ð*PñÌÉþ©Õ~‘‰þÎHé»ã™“ýSªý#ýœ‘ð-Þ¿‡ðÏß×ÿ‹÷Õ}šìÌïJ õN}T Ô¥GÝòcs8JœëOünŒu˜öŸøZçÜÖï¹£ú‰7é7?Ù4-öÍÙÚ£éG‚þ•Óà~"­jŠmb|J<ýÏé?ø\÷ÝëGð~ç¶ÏþÉýÑÜõÂóßý»Dð£ûW¡Ï[S¹”QûÚ>›Â_îeß\?“÷:0ðÆo“{׋Üì/‡‘Éõ(c÷8Ç?øc?ì½ëÇò~æøÇÿ ª?ÿŸ×‹ììZ7‡ÖK©AŸ¹¶)ÿÃ*ŸÚ‘íù?s\Cÿ†uO·#Úüv=ÃY"1Ë©@¹¦ÿÃ:¯”“íÜÏÿá¥_ËJöúìš?bÉ Rê~}?s,ÿ†•/+ÚD{ØàxëYûÄ¿i ÀNËC±dˆÄÏÏžö8:Ö~ñ/ÚCÞÇÇZÏÞ%ûHý²ÐìY!‰ŸŸ=ìp{ØàxëYûÄ¿i{k?x—í#ôËC±d†&~|÷±ÀñÖ³÷‰~Òö8:Ö~ñ/ÚGè0 –‡bÉ Lüùïcã­gïý¤=ìp{ØàxëYûÄ¿i{k?x—í#ôËC±d†&~|÷±ÀñÖ³÷‰~Òö8:Ö~ñ/ÚGè0 –‡bÉ Lüùïcã­gïý¤=ìp{ØàxëYûÄ¿i{k?x—í#ôËC±d†&~|÷±ÀñÖ³÷‰~Òö8:Ö~ñ/ÚGè0 –‡bÉ Lüùïcã­gïý¤P^ëë*FÉ‘k·DºkŽ»STÃ}g9òN–ÉISŠÁåÅäóÇ%Ç ñwÿ©‡ëì?ýãÿÊ(l´;Hbgå"ºîŸk?~wó ­]ùY§U'À¸§)ŠTr‘0Þ­“*CfzIIKŽ—ÝS„ž¥ ºT’>D‡k³)ÍRoeբ˗¨(Þ3JXq_çXÂÔ…‘qÁñIäˆË†rPôj)~E’f=]ùY§Õ'À¸§*=*9I˜oVÉ•!³=$¤¥Ç Kî)ÂÏR]*I«²»§ÆZÏßüì¢Éµ³o”Шµ¸2JˆÉ©Éµf¥ ÑÎP²D”GlÈóŽ: Ër_Ìú‹6Ôº5»G¨Ä‘O…&W)€‡žš·ÚC‹J]2Þ7¤Öm–íIÆŒôäÅvz=‹$.úœ·ewOŒµŸ¿;ù†TÕë6,ù1kõ—§Ç)2•Î -Ûfê%`ÕÇ»u‚ÉñÏA—sOG I«R ¹BjL{Š\6eÜÎQ¡£BRÊ6Ö––œš”}ÁáÔ¢Ág R•A›µDD¢Ó©†ÔC2§ÊˆÄäÄ4Õ# ™Ë¨Q(’KQtaF”¨Ë)I“g£Ê $MÙÄöWtãúËYûó¿˜GewOŒµŸ¿;ù‡©Ç[:µ>â Óf”¢ÈžeOa$e»K (%rDjG<ซqQµëRlvdÓè³Tå6=ã¨7&4GÔ©;“#s[yZMí‰%À„½‚þ…’"ì­{+º|e¬ýùßÌ6 ©_+·¸SpÕNjZ!¸²«­­ ZHÛ׬ˆÒ…áZtž•rFCe ‹Vß¶dA£Qê.ÕXvTÅO€Ü­zd¸É0dz’Ñ+(Ò¯Òtôc§±iôš¤[¬§·ÚˆÍ×O}ªl³%iY"¡»…—PiÎLju:H‰F¢áƒ‡£Ñ_вDÝõ+rºîŸk?~wó ½>þ¸&®"·Y’ú7TŽrR0’2#<©d]*!ƒ}T'Tn‰®Thð(ÒqM* 8 ÄD}*>ãBY2èʲ£Ç1c{Žÿmô¿üæÞXÙhö,‘f—±í°xUgÏ õƒž¸*wåªí*±Y®D˜ÒPµ´¹î’V„­’Q‘‘¥I2>ñúà>d{´?ð–»?èîl Ùhv,»+~ÊîŸk?~wó ܳE›´«ª]³qVK:7Orù£îY÷)q9΂.'ÀPcô·ÿ§ßíMïý_öCe¡Ø²C/ÿ{k?x—í!ïcã­gïý¤XûVKCmMŸX¹Q5ärj]6‘Tv*äI%³Nµqân›JS¨Èˆ”g^mæô›E°SgÕ¯h”;š=¨íV|Æj †ü©(aie¨ÜR£7$¡J2Gö[4™~ƒe¡Ø²C1gû›¨Ð È:þ©Å‰¥<ûïL’†ÚBK*Z”rp”‘™™ð"!íïcã­gïý¤Y[g—~À¯IÐd³*$›Z{Ì>Ë„¶ÝB¢¬Ò´¨¸)&FFF\ ŒkjwÕhËÙsTiì¦Û¨WYE1‡Y[\ŒÙÞ0£Z×¼ÎýY> å¸;RìãäZϤÕ\0n›ºâ‚õÏR¦·Jæ›[O-bCn*D¼0‰nÖK$·†ÜI')^¥—26„í:ãn‰RˆÑºšË±dºÖR˜ñM-žLøš¥EAŸFT³á§Ù¨ö,»=Ѳý—®cÓMª*KM¡×+¦ kBj$¨Ó¿ÉšD}zUÞ1íÚ—g"Ö}&¨úáÇF½'Âz½yH‚‡%J·¨‹ŒÃM8¢Ó"|ô1”'RÔd—5HÌÌ•‚,‘ ÌòàM°äªq¿&3Иƒ-ê<Ê\wÜ”ñ2”›r;¿Ñ¬ÈÖiQ‘¥Iè>Ù¨ö,»6IÙ~Ë×1Èi¦Õ%¦Ð댕ÓP5¡ 5TißäˆÍ ">½*ïöíK³‘k>“T}pæUX¹(Û*¦t™ÕB¦P¢D\v–à Só&4ÚœB–µ$’·{¢%RœðÎ 2©{]ÚîxÕÆ©U©‘)ŽC]>#èÞ¹2C̶‰N/ RÜ£RŒˆÌ²j"&ÍG±d…ÙºíK³‘k>“T}pÔ^;:ÙíÚ™SbVuÖRD„®æ¨éÔ¥HÏñ"3Î8gÉtÖÎn:ÅnEN%Z+ÆQ •³4è²é­¾NkÊ ©=Ö¤8™(ÈÉiè<ÊÚ§õ¥ÿ²ÿj€Ù¨ö,»? íq×d"Sﺷ]r®µ­j5)J:1™™ô™ŸX¬E•µ_è¯}kؤ+Q] YKôÿÌD¥;ý…ØßC7üK{~ýŠ^D¿ü&=6 û ±¾†oø–<öýû¼>‰øLhæ ´Š”|s2ªu_¤b³’:nøædÿTê¿HÄÿg$| A÷¯áü3÷õÿâýõE³îjZSbÍ%)$|æçIÿý&…¡¼oãõÆÌÜ5øQ r§„gCLËZœžOG‚âf¼cH¼.Ò.Mp¿éîþaõ ýQISŒuorKŠ?7WÙ3ro?ioøÄýa¼oãõïޗ‰gex¿÷‹¿˜kd_©g…À_áR{ó °ÿQS—ô33öl—õ½7üb~°Þ7ñ‰úÇÏ©7åòGÂó¸Ëü*~a€þÐ/Ò3Åír—þõó 0öÌ%ý,äô).gÑM㟬7üb~±óqí¢mº/›œ¿÷³ÿ˜b=´m¡Eùt—þ÷óöŒ_ôœÞŒ×3évñ¿ŒOÖÆþ1?XùŽîÒvŠ]õÕ牜c9´½£–q´ ¯Ï?8ì´´ùtZæ}AÞ7ñ‰úÃx߯'ë-ÚvÒK£hWožd~qŒæÔ6–DxÚ%Ý穜uU“äQÂÇÕM㟬7üb~±ò‰Í©m8‹†Ñ®ÿ=Éü㶦ÓóûG¼|÷'óީܩõ—x߯'ë 㟬|š=ªm?çñóܟε6ŸóxùîOçAõ—x߯'ë 㟬|š=ªm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?´{ÇÏr8vÔÚÎ=ãç¹?œõ—x߯'ë 㟬|ší©´ÿœ{ÇÏr8vÔÚÎ=ãç¹?œõ—x߯'ë 㟬|ší©´þ÷Ǽ|÷'ó‡mM§üãÞ>{“ùÀYwüb~°Þ7ñ‰úÇÉ¢Ú¦Óþqï=ÉüáÛSiÿ8÷žäþpÖ]㟬~0ÿõ/27ì3##/óGøEš{jm?çñóÜŸÎ4×-Õt\ÜŸ²K’±ZäÚ·á9É­XÕ§ZNt§8éÁw€‚Z%ÃS£Sª *"cÕc”y„ô&^RÛ#ÔIJœA©Ñ%YA‘êJ¥)2Õu6”K†©F§Õ @TDǪÇ(Ó èL¼¥¶G¨’•8ƒR;¢J²ƒ#Ô”JRe›I½®ZU=˜P§4–ãä£8äF]z6LÌ÷.­ã\LϸRx™ŸHç@E: åpÑ)ë§Á–¢)ó’MJ†Ì”¡ã"#qê¡x"-IÁð.<5&ä¬Ó*²ªqå!É3¤Ê9L7% J%¨œC©RW•+º#âD}$5"ȵº¤úÕMÚ•Iýü§t’”HJ‰)$¥$”‘RI"""""""!ÒGÚ]âäò'Á[æÒ˜uçiQ\vCjA¡HyjlÔòM&ddᨿyãú„Y0o­ë¾à Å(ÔÙl¥¤¸n´ODeóaÃÁÚ7£iG‚à\xó‹tVcPåÑPìG!Ì–‰’ ø,<ã#à¨ÜZ |2¢Æ¬ak,ajΔÈ›²æ«Ý3ÛZr#²i-Ø‚Äl¡%„‘“HI+DEœàˆ‹ †~Ìoj–Ïî¶nJL8%2œ!¹©qM䔕°…¤òJJO§8‘Ž`„ µúWߟµ?‘mºÉöGí:óªmø¨]õ–!ÇŸ?u½n"–‹vÒ-$¥(úYÉŸÿ€æú„ô·ÿ§á‘mIó3".ç§þbHüÒ6¶åËqÛOºý¹_ªÑy$‡Wc‘Ô´‘ä‰Fƒ,–zŒõ^æ±-kŠábà¨Qº£N#R ×&BRZ5j4á‡P\O‰ž2x,ô6Ó¨´‰ö¬‹bq9.—& >ÛòÜ[޲¤JtÕ¼R&yY«Qç9Ïò»¶¦Óþqï=ÉüáÛSiÿ8÷žäþpÕŠõ>™\¡Ï¢ULˆÎE”ÖðÓ¼iÄšVœ¤ÈË)3,‘‘÷‡œúE}Qš”ÈÌ¿%˜oÂB–£4îSJuœéQ(Ùo¤Œûœ2yùWÛSiÿ8÷žäþpí©´ÿœ{ÇÏr8éí ó¨ÌÌj;x‰‘yÅ2c²¿Éø–á;å«C\Oôi¸`ÇÙ}†Ê%¤éò_å”·é*UZSê8ohÞ0JqÓ4 ô'“-¥]6Õ åKUåZ£’É·"Tˆá%XÔ“[+B'¥9I™‘à²\Λ6¦#DŠÒa–ðIm´‘%)"ê"""(»jm?çñóܟε6ŸóxùîOç}eÞ7ñ‰úÃx߯'ë&»jm?çñóܟε6ŸóxùîOç}¸®'­Ia«jä––ÔIßG§(ÛY‘t™™d³’ÏAõd°c—½*u Õ³.™Ò¹ÐóÚ4©Êr‰%…¥GœŸAw‡àîÚ›OùǼ|÷'ó‡mM§üãÞ>{“ùÅp“ráÚÿÿ¸/õއþÎ ýQ¯PÙ¨IeêÍ9·ê’´*RÒdfFFYàcæË‚½2àMÃ2·R‘YKºšƒ²–¹$´`­áž­IÒœrX,tnÊ®ë}só jâçÒh“íµ)µ*Ô´Ëœhå䙯Bt¤¸«DYàX,™ŸI™ž¦}7g“P´»> jTÅÍ'cՔèydDµ!m¸JF¢.$“"<™™™ý•\þ1Ö>úçæÊ®ë}sóÂ.}• g’£È"M!ÆäBÂ9åú–µ2Iîû•!N¬Éi²dyàXõu«Ú]f˜íFœäZÚM5®¥•>FÂ#žTkÔFm6„䌆zLÌþsvUsøÇXû럘;*¹üc¬}õÏÌEÏ¢5ŠvÎêõntŸ6œäƒÝïI5CCOè<£zÒVHwIôkJ°?º¬Õ«?>EçjðÓ rŽqºÊuiOw&ZºN£rXù×ÙUÏãcï®~`ìªçñޱ÷×?0a>>Ý‚ÿ+'¥ÑœLÈLÀ} ˜“J˜hÜ6ѧV Iºá‘–OÆ4Z~Ï£Ó'SŽ¥Tyè&äòÚÂå-iNt§[®)DIÉ™`Ï%ƒ;»*¹üc¬}õÏÌ•\þ1Ö>úçæ "çÐTÐö{›ZfÊ[Ò*ÑPÄ•Ô*îIßîõ›[Å-Ã_rn2Q0}Êq«²(Vì7.ëóèU¦XŒìDÖœžFÛ;ÃJ–ûøqk3u]E¤’‚.ŒÁçu\þ1Ö>úçæÊ®ë}sósèݽØ]~túÜc[úIÇ%V)Ås¥:ÝqJ$–£Áà²|ÒkTyvTøñjÐy{½-·! QáÄ™àˆóÐCç‡eW?Œu¾¹ùƒ²«ŸÆ:Çß\üÁ„\ì¶«ýoû…j,­ªÿE{èë[þÅ!ZŒÚ' |WþbL¥;ý…ØßC7üK{~ýŠ^D¿ü&=6 û ±¾†oø–<öýû¼>‰øLwæ ´Š”|s2ªu_¤b³’:nøäæÊaýF—‡Ý›Ô'Å(Cä£ÏGZ~¿ñнëø úTÞe×Ðä¤t lž×=X¦c«CýîÌõÃêÅ'm[÷»;×~’KŸùô0Ô«ÿVq²: jäõŽáêÅŽm[k÷»PõÃúÅŽm[W÷»RõÃÒ£$¿þ3çäÎ WHÖÈé1`?X·úí[C÷»TÿèðÂz±ng«f~÷jÞ¸ztª%ÉäÌ“—‘]¾0ß#µ‹k®Õ²?{µ\1]¬[v­‹ûݬúá¾×G“3ɕˣÞ±d9Xµzí[ ÷»[õÃÊÅ©Ç6®Ïÿ{µÏ\6CH]¯&q‘Z:1]è1f¹X´¼UÙçïv»ë†;•‹CýÊìë÷»^õÃT4¥Û,™ÊH«Ýø&1úÅ ºÅê®Íÿ{µÿ\¡Ë:Å›â®Í|­Áë„sÅ›â®Í|­Áëƒk]’ÉŒ%jËç‹7Å]šù[ƒ×¡O¨@ ïˆ!=ð ïˆßéeVѳô^Æ–y±Ry>’QïH¸‘8iÆ4’¤ç?Œ°4Úmél²ô†ã6ã‰JÞp”ilŒðj2IŒ‹§÷ˆÅÙE»ö{ÎuëjT©Q­ù””ÓÑ5É:‰¢-ËÇLbq.j3YêVÍ|O†tP§ ß·O‰åûKJÒ((ºræì¯øSWKÏ}Õ®÷p)úE¹Wi×i4jA¶Z¨±Vé#üM$xýãzVY»³ˆ·\9rŸ˜ík™×MäxQ:mšÈТYšòZKHòf]Dg½çj ëß·St5F“@¨Iu×Ñõ"rV²RkJ3­$X"p‘Àˉ²Ï¿,øÖÙª·:BT«ÁÊñ§0þõ¦\Iµ½ËMn·ÉÎó”ã8"VºÓ£I»J\ºýðù˜´¿hi±Ž*tÞépIÝ­öÞÕ­%¾êØx2§U•y'^«J¾[µ¥µæœ÷rµc >瞤à¿å|`F¡Ö¤Õ—IG¨=QlÌ—¸ËSÉ2éʵ?ÀZ.T­*M§´J}2þn¢õuQ]§¸ìye!{§TâÒê¬kQ+IpgÄô‘ðØ^·•¡V¹¯ö ×˜n=Ï$©rgÉ1ÔÎ’q§»ÖZôt¥*,gŽHG§kâù¯?E˜‡µ4·&µM®O —fû>˜¥»‹ÀÊ›±{˜¢L”ví_“ÂQ¢S¼‰Í )$J2Yã 2##<ã˜6ÍmçV·èµ”DŒÛr&¼Ì¸qã¨Dé‘à°i%(ŒÔ’Øw$8\–T†%¥–”É%+iÒlñ´ç(É|çŠF¢]ñDªÀ¸è’ê”ØOT(ðaG©E‡)1ÓÉÝ5j5šßQ)”šÍ$g§Šxdí:q;Kuß?¿þg-ÚZ~ª*¥|1»iñj8’äܯ'øwqÝÇ_v$‹~µD¦RÝWv¯Kf¢Ë\„Ú};Ã^6Ò¥÷DHãƒï÷²5'f^l¤íJéî©–K›Ýý#‰%žçŠˆ³2.%¥]ãú®ër]ÍKä—j+vÆr„ì–aÈSÐä% RŸRtdÓFfFDJ3Á`Ϩý6‘FØ»“ë¬Jt¹rÞ˜¶žÒm"Kk#J4o0dƒJr’Ï à²eihô›m=ß4¿“/jéŒ!8~'~1w†o‚Kµ+qw¹Sv#ví°vÅoz鬛G wRÍ…‘ž:O§½Ö1)T:ÕZC±étŠ„÷™,ºÜhËqHÿÎ$‘™~ñuöukœƒhî¶ôžÐʺnî$éäÙ/«Îu#F>Åë¾Ñv=ÙHLÊC¼¶åUf¹NDwZQ”ãCÉZ úÈÓXÏ ½—)üÑÚÕÓZx¨>\Ÿ[sµþ¿?…WO¶nJ„w$À·êÒØiíÃŽ1 Å¥ð-dX%wIáÓÄ»ãiiX=Ë*³=æäQâ.L¦žeÂ^¤ô2DI3Þ«Ž”3¤ûù“yQªöÒž~à§Åª\ „¨± K)uQÏS†DD²I/&IÔ¼™äÔH#õ›ÎБµËÖªÅy“¥ÜvÛ´øòŠ3ä–^[M#'w¯¥³<¤”XQu䈨QVn_5çè³ö–Ÿ%(Æ“N×O Ÿ(;r¿æ’_ü_À©)öÅËP•&, z­.DG ¹-1 Å­•‘™VDYI‘‘–¼5²£¿K±e0ëZ›u§iZGƒJˆø‘‘– Œ[Û9¯Ú4:#öõb¿FªÑ©¥÷˜“O–ÛÜløî6“ÁçZH— û‚>çQ‘U—˜ó.”¸ŽÊz;òÝq§%,ÖòÐ¥™‘­GÒ£#,ŸYäp©N1‚iï=K­Z¼á85k;5|ÿÅ·uf¼Ò$@‘ êbz„ !H@z„ ê````D  0ï‡|éNÁav7ÐÍÿÇžß¿b—‡Ñ/ÿ M‚þÂìo¡›þ%=¿~Å/¢_þù–.Ð*PñÁU\±Þ÷ÇUýrÇóþ‹ïôhû¤hät lž²‘Ð5²z¿DÁPÖÈè1«“Ö6’: jäõV†f²WHÖÈé1²•Ò5²:Lz´Ls5ÏŒ7Æcã ñéS3HÃtb;Ö2Ý]éN¤EÙŸT‡I}O•r© uÕ÷e„©f’ÕJÁt‘cÀzT)9ÆROò«üÒþO?IÒcFtàÓxÝ—6rß¿¢}JùÑŠïA‹.ÔÙŒúý™SSÓ›EUõ³ãS•%¶ô«I­õ’‹tY,á]xÁæfÌ#GDuÚì¬Ï˜üIÆšzMõ°JßjV÷*Ӥ̸PF®D“ôièuœT°îý<½O:§¶´ÍÓsÞ›\{òòyXªÝø&1úŧml¦E~•¥eLâUe»žã4•<”¥ ÐNÉ4¯ $Ïû׌+¤‹#ƹHDƒ:™Ôè-Õé׊髒ˆÍ¥í Ž¥)µ8DJYk3>èÏ ‹ ˆ‹T4i¨ÞJÊ×8ËÚú;¨©Ówx”_+^ëšäÕ™Ygl®…G«lúï¨Ê R'Ôé+†¨nÔ*Ek8hZV¢y´`‰9NLQã'À‡•*Ò¥]µJÄBæû^Mй獵P‡'BJQ;¾Y ô¸Òp“p²•îD­ME®_Ó—µ¨Âu!$Öf÷sIÞɹ[ñ.\JÜú„âŸfQ*4ênÍ%tJT&_¨>ªf—Úy×TÚK[Í+3ÒJÕ¬‹ ï‘ÚÄÙ[ ¨Ô£É¸ÔË [¥qB˜:Ó&&2z‹xFÚòdX-]|xKG¨ø/š-?kh°º”š·Òòòã½;q³¿²gÎÙK Æ”ä;”ä:›l®HÍ®ï{’Yë= âx"ÔGŽ’¬GP̦žv;r[miR™pÔHpˆòiQ¤ÉX>ƒÁ‘÷Œ…'JTßâ;hÚm)7EÞÞM›@-ëŠÔ¶£ÞK†Fg°¹´ƒ©¹O¼d”¶œ:ѯ^­æðÐ’ÁãRÐX2ÎuÖžÌUyÅ*–ºœISÐûÈe4WŽŸÒ¥šY9JYŸ¤°xWÂ"336Z˜°­ïïÔȽµ£*j¬ïõkƒßtí{5g~K®ò²dµ˜ÿ¹îù±c2óWiC\æ!6rJ9Æ7]ɹ…(̉Jê"É6ÖÏ›nö¼žŸQ‡O¥[ÍD\§iÔÍ¥<„hmƒsffy3_Iõà6iZëËü7ü½­ETpžë6¹»ÙÆ;¬¹¹-ÜJ˜ÿ.Ù£Õv»bÓ¢5HŽuU™ZŠŠÚ¢Ê|Ðò”ãŒ!M‘e)3#,àÉŒq.5»j+`§sÉ\æë<ú¸dóqõ‘â9­,àÝ$è> 74ê#3-&E“´´Y+ïëò·©Î—¶¨ÍFñwxy7ùœ’ý? ô+°dÍ›PÙ§Rk Ý© t‰ç-4„a’gm(¹GÃÔdŒg”ž'“2¬Ç”¥Oóôm2Ž”›¤ïo&¹µÍ-÷Lžø‚ßÍD ïˆß@z„ ê*™PŸKœÔêdÙ0eµÛñÝSn#$dxRLŒ²FeþbjÕ:•ZY̪Ô%Ï’dI7¤¼§Vd]©Ff-·rlɆéT”C»[¤s²VÓ¶Ü—Øu:µ+KI_rE•àˆ¸J…‡HcdôäC¦6ýÛ.àb‘"C¯¸DËŽ´OiI(FHBI>:úðe«f©‡sÝký>'ˆý¯¢ªŸŠ-MKuç{þ_?•Ê€„ J¹±Ê=—Ünl´¦%Eˆž¨SWÒ¹»'YpÔ{Ö‰XʰžGŒÉ©ìd¡\ÔëuÊìÈÓfÎä͹6•¹Žê RiÔº²_¥$ƒÒ£5§q²Vèu^Ýк©×“ä®ùtiü VÙ´ZmÍL¡È¨\ ?(¤)öÜ·Ôo¶M£-©´6êÒñ8¬¤*-8ʰCÚVÈj½ÚÔ¸²d!ûsÎ0Uøûž.ï5+OtXQ䌅vj½>þÙ÷ɹîiµ¹ðW¿.‰¿†þ ¡P°‹g”ɶ‹5êÇ&zå×[¢CŽå4™ÖúÈ”JZ·ªÐœ™`”8Ééô½¶UP·(5Jª^¨:Ý&J#Ë9TÅÅmÍj4“Œ,Ô{Ôj",á=)<`ÁèÕ-{n%{_CsPÇfݬÓ[÷.k«KâW8‘"ˆOPƒÔ ÀIBÔ OP€ H€I‡| ;àJv û ±¾†oø–<öýû¼>‰øLzlöc} ßñ,yíûö)x}ÿð˜ç̱v€±R€ïŽ «úåŽ÷¾8*¯ë–?Ÿô_xÏ£GÝ#G# kdô ”Ž­“Ð=ú& †¶GA\ž±´‘ÐcW'¬z´ 35’ºF¶GI”®‘­‘ÒcÕ¢c™®|a¾3oJ™šF£ “z‹~•C›lQ&D¥!i¼T¤¨Ã%8£4<œš”YïQpû£Þ±èÑ©(_3“£S¯…Í~]ë{Vv·/&×êt•ö}E·W¤R*m׿°‰ »ˆÎ<½n48“4š¸éV¢Ø—Ín «X·D2‡Txßp÷:TÊŒ°½Ñ$É(%'¹2ÇÁàX'Gœ˜²›ˆÔ·#<ˆï)IiÕ Éq¨’}e¨³ŽŒ—|o…z­Þæ)h,R†k¦—+­û—ÍÛ3i𒎇>“K«Ã„ê݆™¨s1Ô³#Y$ÛZrFdFiVK=CÊUë.EŒí ºE%1¨Dßm·éH>ˆ‰dÙŽãI#IV{¡Ï»ðLcõ1«;ZþEe¡Pr¾wçÇ®{ßWÄé(7|š=Ÿ[¶Z¥SdF­håO=¾Þ–ìòÞ“K„’Ò¬¨»“Éž¨°B,k¾M¥Î¼š•MŸÎ—G,ßpa ݸŒjÁdø™i,qΤ©SUAr¸–Ú8-ÊLE¬žF´¸¤©i#Fu‘!XV4ž“,䌆¶²q³éÀ«ÑtzŠqµñ?Å¿š·ð—éc{kÜóhêÛm>¤ÒZ›RTm7IüRèvlmj°ÍÍE¸‘@ s…ŸÍðÕ»|’McIe$é™–EÐ]Ùä Ó¨¥_R©ô)4"¡ÑdÓ¨I˜ÒZqÄFN‚4eÎé$ž\ÖGŽ9â9Ê]:¡U˜˜tÈ2§IQ¥˜ì©Å™N’3Ûtš«•S¤·Lšº(ÐqRÂâQt–Œg?¸5Õ^û“°hP¼l·%Ï’m®|›y³¯¨\ÍÓ¶R›6[MI©ÒZ˜òJ:ÛT^àÆj,oI&F“2=àjÁpc*§OŸK˜¨u82aIG3!¥6²ÿ¨ˆÇ«ÔZ˦êÏRg·NtðܵÆY2³ïÌ´ŸÖ)9JozàvÑéÑ¡Âÿ;½÷ooád`žøÛVm‹–‹2«6õ^›k&Òì¸N4ƒQ‘™$DEœž?¸Æ.PªÌL:dS¤¨ŒÒÌvTâÌ‹§ IЏÉ;4wjrŽ5$×[î1@lâ[õé•'i‘(•)™Îö3QV§QøÈ"É~òµ3©²×£D9(øl¾Ñ¶´ÿŠLˆÈC‹Jö%U„¥…5sÊu»œÝFm¥¸ÝÈz*ÐÒóÑ…`Âm»žÝFm¥¸ÝÈz*ÐÒóÑ…`Äá—Bªµ7kIoÝÇ™®ïˆß´zEZ°ú˜¤RæÔJu)¸¬)ÕwÌ’Fx“{‘yJ0X¤ìŒ°éYµ3¦C¦M“9&dqšaKtŒºKAx€þãÑk2*ª¤Ç¤Ïz¢“2TDFZž#.’4jáþ…ô*êÁq’ëúu5à3[¤Õ\ª%ºdÕÔ FƒŠ–o‹¤´c9ýÃø©ÓçÒæ*N ˜RQÅLÈiM¬¿Å*"0ÂírUH7d÷ñý PïQk,R›«=IžÝ9ÓÃr×dÊϼK2ÒXþ‘B­®ªº(ÕSSð¥”e›%ÿ¯?õ‰Âú®§Çãn<ú|MpÊ¥ÓªY‰‡Lƒ*t•šYŽÊœY‘tá)#1Oµ®j„©Q`[µyr"(“%¦!8µ²gœÈ‹)3Áô÷Œdø!:Ôá|RJÞfœ¬¸ïÄ”ìYL:ĆV¦ÝiÄV…àÒ¢>$deƒ#äIMDfc‘žDgÔ¤²ò›2C†œj$« Ìµ'8èÉwÄX¾%»˨@÷LIGsŠ3Ç.“*|›=Ù,ÈÌjèÔdFxéÁxTتrÓ› LÙ+ø,ÇiN-_à”‘™…™qI¶øÀ6\Á]*¿3¤U,g‘òUï¾Æ5Ô1êTùôÉk‡Rƒ&”cS2SkOø¥DF@â×"±« ;&¯Çôêo˜½êП·åј‰I›BŒ¨Ñ¤Æ%©n%JR•¼'´™šœpø$‹»2Æ $Y Úa6©PJ$eU炨~—•rÌþ·;ÍÇsÇjî‡;Q¤U©±aʨÒçC5È®¿M¡ôàR Ë ,)'’ÏIwÆé­©×3lz-D¥…=üVøóÞÞç¸ëª7Óê§U~ضÎk²‘*[ªŠµò¥%d³%¥k4¤”eÝ ˆÌº ÆcûK¨; 0íú ÒbHrJiËm÷X[‹iMä÷Ž©E¤”f’J’Dx2,áˆ@kçÔ?ghÍ$ãÆ÷ðëÓ‡NE„Þ×.6äDÝB¦&XÓÑÉå¶l¼i7Ö§ Ü™¥8=|1‚ÀR6‘P9v”$³I Æ¡NZâÎç§—úbR ÃÞ'“,j=8%dÏ5è m:ýý£›öN‰k(%Ççu7øŸÞîå©x^Tˆ¶½&šsÚ¸9àž¥GÔv4·¥åÙ¬Ìõw‹EÀˆr=Úå|å¼ý‰lç7²æ0Ê÷¯+:Œûµ©(3>&hJsǨ̇6CûK/*:ä%¥›(RP· '¥*Q¤ŒúÌ’¬^¼"uç2tgPÑÒk{»wo~÷χ—ÿÓÌÐ$@ήR§QjK§T[iÛn~ä:ƒKˆJФ­iQT“##>‘*;ñ%;S±!•›n´â +BˆðiQ22Á‘‰i­Ì¬g¤âîžõð<ú„ž¡é.;ñ%=S±!•©·Zq•¡Dx4¨‰`ÈÄu{@3 Ò§M¦Ô*1›iqéÈC’²ò´%k$%Dƒ2R‹R’Fi#Æ¢Î2CKM¥6“áÇüÿ‚H@’ ±=Bõ01´¸(5*µSLVžY¨–æ2ëq”¸„(ÔÚ¸ô,ˆú{Çå*ª£Õž8»¾hÓËÚuĶë9p›âÚŒ–xY’OzLË8É `•íc’¯IÅIIYó¿¿ÎèÓ/:‡VÛKZYN·T”™’¨““ïT’Éõ™Xó:ÜGÙy…’im(Ò•’V“#4©$¤Ÿ£###ë##~G˜ è4©Óiµ ŒfÚ\zr䬼„­ ZÉ Q Ì”¢Ô¤‘šHñ¨³ŒÆLwÕÉIaÓŽÚÒÚÝ$„©D£JLúÌ£"ëÒ}ãfUN.é>¿_¶1Fu>³%Æ 6Ñ›M›®­é ²ÛhÉ'R–â’”–T’âeÄȺÁ&ÝœãŠNÈÀ“S*›9ÈSZÝ<Þ È”JJˆÈ*JˆÌ”•$ÉD¢3%‘‘™ÆÕ·2c%%uÀΠҧW+©ÖÚrd¥îØC!¢Z¡:–dœŸAx™‘LȆ›;\ŒQrÃ}ÿ~Œ‚ÀuV•:˜Ü&6ÒQ>*eÆSo!Â[F¥'9Až ”…¤ð¢4™ÁÓ\JÆQ’¼]Ѐ$þð¥;ý…ØßC7üK{~ýŠ^D¿ü&=6 û ±¾†oø–<öýû¼>‰øLsæX»@X©@wÇUýrÇ{ßWõËÏú/¼gѣ‘Ð5²zÊG@ÖÉèýC[# Æ®OXÚHè1«“Ö=ZšÉ]#[#¤ÆÊWHÖÈé1êÑ1Ì×>0ߌ7Ç¥LÍ# шïXËtb;Ö6Àá#ÑÙ]p®y;* O¨Ój\’$¹$Û«Š¤´Ôu3 -($¨ÉXWö•¨òff8×F+½= 3šê`Òh:“§4ÒÂïÂüšÝ½[™ˆïÁ1Ö2ø&1úƈð.ÎþÆj²ÆÎ«3é”sÕ[§4ÞöŸÊš5nå$È’i4š²ëiè3#u8ÁšGZųN§Vî:|J4ÅÍpHeQ‘@j¢¦à–“`Í.ºƒi %(÷‰é".é<3I˜®ÔRMpúžEfέIMT¶//$•÷ﵞyÝvíÝU³%¢ÄšMBê›NåRÚyÅAÔÉ‘É%%Ê œ%(Ët½*Ò“Ä„Ôíý–Óß›iB%½>§MvLêBIÄ'vÑ$µšH÷‰pß4¨ÌÔ“iI. REx}B×Mn_{¼¼„=™(É9Nê÷à÷þnwãø¸ùcê‘r\ë¯PêTÚj­Zd™å”MšUªŽél’”$Ím?žN‡ˆpY¦Õé·¬ÄUèñ©FáëŒÜXE…3ý•!$”ðÇNK9É Œ‡$*VS­÷¼¶‰ìùШ¦çukZÖä•Ö÷ÓÓ}rÒ/ÈvåÁZ¸éÕWdÕÚiê‹Ò6Ùa³}³A™™MÓY ‰ø 5‘q$äUâÔ›¹î{†B+Zd h‰!GþNóKiE¤B”…=ÁqNƒÉ U ²éóøùy‘gJÖr\øFÛž÷5…Yü¯¼µªñjMÜ÷=Ã!­2´D£ÿ'y¥´¢ˆÒ¡JBžà¸§Aä‹2îVJUB½Qj€ý2ˆP¤•:¼Ü§ˆœkt¢e‚3VéHYikv”’ˆ•Çà˜§€NзîûËï©_ö·x¼|¸5»wž÷»×‘ÝÑáE™n×ilšNt…Dsvä4±!æRoo[ChqÍe¨ã«y='à ÈéQ½MTžgUrén ‰P‰×7‹l’¥!dÒ‰ÅéB¢¡*##Ig‚L…>#]G‘zÞÎu¼ù§Ã}Õ—Öíܾ'o{ä2ìvªRjt¹­RÒmÒÛo•"#¦ã§¸Rœu*i'Ü/Y–õY,—ý^-I»žç¸d!ⵦ@–ˆ’äï4¶”QAô)HQ³Üè<‘`ÅR5Êü>þþž&’sä×¶{·Ý=Û›müKWj4”¼ýÏX©Û讞S¡[¯5QqÇËRP¥ž—iZÖJBQ‚F ¸ŽbÎ2£iܪ3N¿V}è«K ›¯ÆN÷z„¤¸«»S 4–x'=C‘!=ñª¥œÛã‹@»tGm䩵m¥¨Û¬ÈA“hÔz‚OéÚJ4“DGÓT:÷¾ïŸÇË̘{1Çâ[ø[†Ë~åøxo\,•‘Nj’¸³Q›:<„#1PÄDº‡Uƒàµˆ4tñ"_IðáƒßXT‹¦à‡S£Ñ5TÅ2*|š:2$k&û”‘©Gݯ.“â|”òñŒd“WFúÔ¥8µ½Ú×WJÞ[¾*ïsȳêÑ«õÝ„Sf±p:TÃ(* iQ8yŒµ§§$fdX<{ÔâÔ¦[[ÐÐô‹¥ ¢tv\‡C²M`¸©IJáå“-ßîOHºõÓïÔÃþÚì’’ÝgÚIuệÏqp#zš2©<ΪåÒÝ:¡®oÙ;%JBÉ¥‹Ò…D#BTFF’Ï™Z÷‡HeØíT¤ÔésZ¥¤Û¥¶ß*DGMÇOp¥8êTÒO¸^0³-ê²Y.<@•e%k£ìçJxÔü÷uò»i/Òþe­W‹Rnç¹îx­i%¢$…ù;Í-¥F} Rl÷Å:$X1—r²R§×ª-P¦Q ’§W›–ñnÔL°FjÝ) --nÒ’Q¸üð m ~ï¼¾úœÿÚÝâñðVàÖíÞ{Þîw^GwG…e»]¤Y²ju9ÒÃmÈibC̤ÞÞ¶†ÐãšËQÇVòzO†‘Ô”zŒ‹]Ê:­¨÷-Z$jyÔ!®K¦ûn!sI»hÉkÐË­%]Ñh=$d|qMu_­ËÖötª·øù§Ã}Õ¹¦·nà­¿#u{À…M¹¤Ã§÷,¡-(ÛÞ›—ÚTãZ¿µ¡f¤gþHéî˜7T­’[µ .©É"L”M¼¸‹KMFS0’ʈðI$,ÉXWB•¨òff+àUâÝÄÑ-OTño‡6®ÞæŸ=׿™rN¥À©ìn º${·™âÈŠücU:¶Ù–Nº¥¥ó#I¬Ï[Ÿø²&Ó…pÇ=K¥WÓ-­ê3tç¥[="Ì7—X`ÝA«Fžé&³$™¶“J´¡X>8:÷¨@»®·©û:pRXõðãf¯Â÷|÷«=å¯QqÉ­7 ‰¸“ ÛJfP jÖM­J†ßîUܺiÔKÒ¥–®£æ6§¼Lú;OEæ÷›¥¡.SIF|€÷®þ‹º3YdŒœÂÌÔ[ÌðxÌ£NæÚ‹s9¤‚Q)‰mkid¤šLŒ²GÐ| ŒŒFFDb%UI[ïïåäZ–ƒ*2SM;_u­wñ»ÍÝùñ¿k <)Rl&'¡—:£i·—¥·^)s”(ò]Êœ$$ø—šU-·¤SÕ~ÐâÒ'Õ&(§7rPQÞQ™Ní+Nù1ÒFzukQjÇ®. õ‡ã)QcCb+4hÄ­Û-êRðZÔ¥Tµ(ÌÌÏ*1¬U”_ ý¢’ö}J‘oïñWmîw·;=Îö;­ªÁºRÕO™ á;¿å†)†´§v|§Ž•–³$ê,c83ÓiVsŽÛ”—(’iÊ*ääÓ™%4Ò%HlÜ[„’6Ô–ÐFKÉ)jOQ–FCm]®V›G‚tØ1 •ã6ãî·RkS†kÖµu­Åw$Ÿ†eÐI"F´Tœ­úd*è5*t”¯fîíÁ4ù]pmZÜ,Ÿ#¹–mC¤XðkÖí:6·”ͨ®˜–^Ý¢rÿHÛ„’Â÷ÞUÄÔ—Õœ¤Çó>Ÿ\(—Wµ)ð$4óÂLRÚO)|ßAH"OùSfÙ¬û­æM)ãÝ`ëëß—ßÞòËÙ­;©.7áç}Û÷nü/×BêºéõH’nÇéö$U.çj9)¡%Iܼo¤Ó£jÿ&Ó«8ß'N5$bTíw)ïÜ‘ÎÓÞÓ©·´VØ'c“9޳|£¢#KjIÅâ¥i-âÃVN¡ êzBnöûßåðÈãeT‚²©Ó“å‡þÞO÷?Öêr‹ «L.§Lm‰J‡%Tø½Ž²ÔźKdˆ—œKO¤§ Ék4«$­$‘R¥%©P-Ó•r&4S\9tv²J”öùÔÂJœJ„Ç#I–KR”II¨À‘ý?1eT—ý7q½¸ðò;}«¢m6ú‰)Ø-F_5Óeµ2N0¢LFSÜ’ˆÒãd¤)»Ž ÙUwÞ¯$¿/L>|ðïê¾=}f Tj †ÜƒHTÈɘ•’6’­îå Y#kÂIFi.ÄŒ†ý4züêÍ2 vסңªy®3‡,›èm Y²‚mHT„,’I%dÌÔh"pµq¬ˆ@檤Þîf¹èS”b”÷¥kµ}öâ·î}xßx·m-˪ƞ‹q÷U&ºä ‹R­¦b#rDÊ´®:MÄèÖú‰j°“Wö CCi5wjh™o³½MC0؇Ýj[¦‚qãukŒâЕ¸“Ý Ödj""Ég**·¨@èô…{¥óò·ÔÍeOŒªo¶çn‰¾µ¬íkp:úÜ*6¦Ô ¹©±“1+$6¦’¢Fû¹BÖHÁšð’QšKñ#!¿ŸO® ˫ڔøyŽa&)m'”¾o ‰¤'ü©³lÖ}Öó&”ñî°uˆjªWÝÄÓ= RPü_•%½týw_ƒãu¸îöÎåbÖjÒjÖ¢-ºƒÎÃ')´‡Ù'ÖhqIÐIx•ƒÊÔJ׌˜î.X·IW6‰]rÞŽì!P\M)µÎ1ÜK®QúTèJ–KsQ(³Ê‰+Å`bëHß'×Ïâq—²ï QM~oËÇz{·îáçĶ+ÖÍIžÌÉVšã§±ÊmIDT­<™õ**6ÏNZ.2ÈÒ“"ÂF]Ç =ªÓN=“E‹I`楶]=¶^JM <4ûJ4ËgeÕeYÑljæ³­šK«òó&—³ªBQ“íåÇtWWÓçn·°ôÊVÈéUÛ×Û™2£—I¥$Ït¦™ÐiwI¬–ošffFÚˆ 4õj‰R‹Vª9ÕŽw éô—™€ºCxÝ®)r·[ŒhÐfO$’xGrf¾ƒ#ÅB6´*»TÆä4ý—Ueý&h˜ÚòƒNpi[jBÓð$JÁðÉ ˃ûÝn…jû>jòƒ»»åÆòR·IYõò,é‘çÆ©]ïSíè[º}¥M5³ž…ÇmkT'Ök$¤Òáç|¼¯VIœ¥<2ª”ËŽ-.µF¤Û1—-Ê4õÄ~ŽÆ'`½ÊèÃm¡îçW¶f¢#NUš~µR“W©»P—£zá%$–Ó¥JRIJ]IJHˆ‹¼D0…ž’¯¹|þ>^#”=“<+•ì¹_zÃç¿|^yöû*¤ªkµ9ÍÇ)ŽFi ¦;t„ÔŸ#Y™ïQKJI$•’-eÃ&F]¢h•ºUbójٶݔԫ~-„.„ÛäâÝv*•¥³K‰"3å¡&¤‘´};¢4Ò¢!YF)[[üNúG³ªVªçYÛsÖçÕ_‡Í—‹‘åÖjTêÔ¸‡èpN’äjG&g%`–„7ú>PH"ôf£B ,pJOúz¡ªç•Õ).C Ç—%3h,#s(¥ ‰{”)Âcô;Å)³4’‰+R“¤‹è =%>[þ'û"Q²SVV݇£^|í¿ÏyÙlÝoÖvÏ@•žÓk~ºÌ“ “&ÙIl³`O³Zu3n9TÉŽÈ£$Ýäå¸Ö“Y£QO”ž³=IÝ,ˆÈ¢-5"—X…E§¦j@© ô×J¡ äï¡å¤Úuk£¤›Kg’Sg•+¸ ×­Û¾//™ÏýºwoÞïÁõ“îÿ¶i2á¥Qk¨6Ív«’™•iÔd%ÕSMokC³dÛsN¤÷K`ËI–­òó©"ž©QM-Ü>†­E• I¹_þßvú¾©~™r6I‡| ;àJv û ±¾†oø–<öýû¼>‰øLzlöc} ßñ,yíûö)x}ÿð˜ç̱v€±R€ïŽ «úåŽ÷¾8*¯ë–?Ÿô_xÏ£GÝ#G# kdô ”Ž­“Ð=ú& †¶GA\ž±´‘ÐcW'¬z´ 35’ºF¶GI”®‘­‘ÒcÕ¢c™®|a¾3oJ™šF£Þ±–èÄw¬mÂF#£ÞƒNŒWz mÆF#¿Æ?XÈwà˜ÇëãÀâÁˆbˆ$ú„ >¡'¾ „÷À'¾ O|@ ê'¨@ ïÞ’$„’  ê@$@‘ êbz„ !H@z„ ê````D  0ï‡|éNÁav7ÐÍÿÇžß¿b—‡Ñ/ÿ M‚þÂìo¡›þ%=¿~Å/¢_þù–.Ð*PñÁU\±Þ÷ÇUýrÇóþ‹ïôhû¤hät lž²‘Ð5²z¿DÁPÖÈè1«“Ö6’: jäõV†f²WHÖÈé1²•Ò5²:Lz´Ls5ÏŒ7Æcã ñéS3HÃtb;Ö2ÝŽõ°8HÄtb»Ðc)ÑŠïA°8ÈÄwà˜Çëüýc\xX1L@±ŸP'Ô „÷Äžø÷Ä ïˆ =Bõ=á{ÂB€AÔ@ˆ =B OPƒ$ IOP=B H"&ð0ï€ })Ø/ì.Æú¿âXóÛ÷ìRðú%ÿá1é°_Ø]ô3ıç·ïØ¥áôKÿÂcŸ2ÅÚÅJ¾8*¯ë–;Þøàª¿®XþÑ}ã>tŽ­“Ð6R:¶O@÷è˜*Ù5rzÆÒGA\ž±êÐ0ÌÖJéÙ&6RºF¶GIV‰Žf¹ñ†øÌ|a¾=*finŒGzÆ[£Þ±¶ ŽŒWz e:1]è1¶Žüýc!ß‚c¬k‹ Iˆ “ê$ú„žø‚ß@žø=ñ@'¨@ž¡'¼ Ox@H@’H:€ƒ¨‘D'¨A‰ê`$„ ! ê'¨@€ $@$þð¥;ý…ØßC7üK{~ýŠ^D¿ü&9’màl‚Ì¥Vnú,ìÑ™ÞÇzZ Æõ”D¤ç)3I‘àúŒ ÈcmŸi»=«lžè¦Óo*$©’)!–[–“SŠ4žEž&}áÏ™côà (øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLcõŒ‡~ Œ~±®<,& X‚O¨@“êB{âO|{â÷Äž¡z„žð=á !H@ ê D ž¡'¨A€’$„'¨@ž¡$@‘“øwÀ>‚ì?öCjýÏðŽÈq»ýÚ¿F3ü#²‹Ø •(øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLcõŒ‡~ Œ~±®<,& X‚O¨@“êB{âO|{â÷Ä?Wì'Üã³ûãd4¾»U¹ÙŸQåÆáHa-'w!ÆË¶”eÁÖ|r;_zFÉþ[½¾õÔº?u¹=é;(ùnöûÔ_Pô“ü·{}ê/¨ ¢l~û“Þ“²–ïo½EõïIÙ?Ëw·Þ¢ú€º?w„Üžô”|·{}ê/¨zFÉþ[½¾õÔбøp„Üžô”|·{}ê/¨§º/a›:ÙÍ‚í^‡:ê•TR’LÉ1Í„§x„¬ÔIh”g…ð"2ï™ðÁ®ˆ±ù˜‚H:€ƒ¨‘D'¨A‰ê`$„ ! ê'¨@€ $@$þð »ýÚ¿F3ü#²nÃÿd6¯ÑŒÿì‡"ŶåJ¾8*¯ë–;Þøàª¿®XþÑ}ã>tŽ­“Ð6R:¶O@÷è˜*Ù5rzÆÒGA\ž±êÐ0ÌÖJéÙ&6RºF¶GIV‰Žf¹ñ†øÌ|a¾=*finŒGzÆ[£Þ±¶ ŽŒWz e:1]è1¶Žüýc!ß‚c¬k‹ Iˆ “ê$ú„žø‚ß@žø=ñ@¢äïülßúwûãçÚmfM¿k"©Ç[R*tæœ6£›ëSNMa·R”T¥›ZÒD’5qîxàsäïülßúwûãý¸)«p‡)n¡¶æF–FÑ‘¶mô>¦ÒGýÆx2>#›âIÉ̾™›tÚ”ºJ+q“:¦ëRÊm TT8ÒaJp’K}¤§;ÆÛVzIõjôŽémZ• V¿ërǪ4jB&8ôÇ©Òq$Ó»´hQilˆõ+‰i"mV‘¥>‘1õº—)S-‚A‘–l:Á’²G’Òò†8‘qÆHôlY\Š‘I¦Q”Õ2žÍ=³Žã Þ¶Òt¤Ö—ZZ5ã¥IJLÿÀˆˆ~å~´íŸI¯Q¶‰QZ^»2iô?=¶³KŒ­Ité¤ð¢I)z ŠFÍÆî 7Z1nÚ‹§Ó››.¤¨ñU.JŸuä¶‚-Öå)I2¼á¼žQÄ&{„Z´[1mô9,£GœÌýá¸Ju×Û”™F¥¨Èó­Ôå\ á1ÃÝÅlµU¨±TU©QªL´l¸ oZÚ3É¡Iq B‹¡'¾ „÷À'¾ O|@®§í&ö§Ð)Ô•Å·L¦¥ÄÄŽl4¤´KqN/I™™©FfgÇ ºˆ¿®Ù·¿Ëü+?qàì;fÞÿ-ÿð¬þ@í›{ü·ÿ³ù!Ô Øvͽþ[ÿáYüÛ6÷ùoÿ…gò<lÛßå¿þŸÈ#¶mïòßÿ Ïä‡x@°-¦Þÿ-ÿð¬þA‡Z¾®ªÍ5ÚmJ©¿Šöã|¤ç %¤¤ˆs„ uP"ˆOPƒÔ ÀIBÔ OP€ H€I‡| ;àAvû!µ~ŒgøGd8݇þÈm_£þÙE‹lÊ”|pU_×,w½ñÁU\±üÿ¢ûÆ}>é9[' l¤t lžïÑ0T5²: jäõ¤Žƒ¹=cÕ a™¬•Ò5²:Ll¥tlŽ“­Ísã ñ˜øÃ|zTÌÒ0ÝŽõŒ·F#½cl1®ôÊtb»Ðcl21ø&1úÆC¿ÇõI¨?K¨µ:3qu¬éL¨IlòFG–ÝJ®ÖGƒÁ—#ãÀâÌS?Pí^Ö¶o=™ÝS­{z“J¯YUéŒKjŸ ¶ è¨udFd‚,á²J²}m¯#Ü‹jÛR*üßrÐ)•yµJSµ4"tT¼¨l†ÿ§³N~m* ªdG JêðɇòDiÒæ÷Aš‰Di,÷Eœg9›²Û®Z•§h× 5ê|öˆ”¦œÁð>ƒ##2Q|ŒÈ“àÁ©Øl]ä£j6ä7aÓæF¨TâÃ’ÌØ,ÉBÚqöÉdIu*$™— I‹'ƒ,˜í}ÐÔ7ª[~—bÚôŠ$&Úq†©ÑcF‹”·c4³JœÂ5™«:Ij>*Òž*ÁÕMìÙêõúýˆŠKEq°Ù8¸KdhKÊd•ž…´¤Ìñ“Çrx[[3½nKŽ­nÑ©-I«RSsbœèí­³JÍ Æµ–²% IÉS“î‹3‰u­“³‹Ê=¿2¼ªB]ôÍSÙyqO¼ëhY­³.²RKc’Óà æÀ«Ó"YÖ•&/dr'MŒîõw%9oJrAÌ”¡Km&H-Ö7†žžŽŠÓlëP¶‡Sb¿nÒíéähטÁ5HIšI–E«9âf}ªWv"B{âÍ÷3ØÔûÿj1éUt©ÊlHë›)¤¨Òn¥”’2\HKNqÇèé>È`S6½Sº­yÔ$¢˜ìê;Ð)íFr+ˆq)JMM‘‰=áï Gäˆ9¤ (å±;r›PØ¥ç\£Ð¢×¯xRD8¯ÃLÃmƒSyZY)*Q‘½Ò“øûñ=Ó¶í‚Ýšì:dZEÁ>އëc6M¶Óº[ÁîË‚ Ôn– ¸5ŠÄئv²­ªæÍ딪…ñfï£ÊŽëÑ¡Ëw ¾{³$šgÜ-HQ ðg‚#Ær-}…Q[½¨WÝ Ùôx¶›t×YbÌ´ê§ôN´„œêâ‚#éÁ¥4•È?:wÄ e–½2.Æ/=§Ô E¨Ê¦:Ük›'mÕ©²SŠA÷+2'“‚Qtä«Ö§oÓîßsœ¢•: ݯȥ® dGjK*Ýé54Ù D§“Å$\óÆ® lE\²nª%±L¹ª´gâÒ*˜ärTi4¹’Ô\òœ‘–¢,‘d².P­Z¿¹&ð¸!Z4ª|¨5f¢Ã’mÒÐÞò!™©õ£Qï:SƒÁ$‹€—4ùðÎÜŸO¦N\¹ô†ª¦†Ï“²óŠKDîK p“Åi"ÕÜä²xÉ™‘Û¾í µl:"ŸJŒº#N©˜Qʳ}ò5RDFx",ÿq•¥`QàîÚÕ—±Úu¿nSèôÉ×$Ø S¨Tb"^ƒR$ÓM¸Jm)#JøšLÏĬì DvÕKÆ“Rµc–Å"%ѦÓíO‰Oi¶ŽH^¦Ý`¿D£×»› Ê’›‹˜<¨ßb+Eu¦šlÍM¸£#ÉäÔž‚㤻(—u¸Ýq;AÙ}8©NBÜI”šC ¢æ…n'XÓ”ôäœ3ðÚ»²»ñ¦âÔ"iù­o¢Ãrc –ú;èŽkÞ«£©"Ø—Pq@:ê6Íï Å›"ð§Sâ½CŠK9N¥­$¤)ÂZUÑ„™dÈÒdG’νdÜ· 154å´¹e ¶Ó-’yÇŒ’zPɬœ_™¥&DD£3"JŒ˜9â:›‹g÷]¿lŠ9‚D%3J<æ$*)©D’'RÒÔmåFEÝq<ò¡±Øe°;nøQh«uIf‡Û—Y†Ä4´fþ4)f’Þa åÍDzÈÒF“$Ú@¦ú„†Ü³.Jý2ERN޲mÙ²¤µ:VxÂw®©(ÕĸgÓI{Q)D…±„™+º>“< º4¿c[Ijtømë›Ohž‘©±Ü}-™’ÒÚ\5-`åÌ uKë¬[ÇqD§2Õ Ü”Ù“XˆÊ×ÿ*yi%àYè1¤®Rj4:«Ôº´7aÌgNñ§ ‰’JIÿyLŒŒ¸ º ÜïQ¥ÂÚM\ÊmJ„qeʨ3*šÄ¥#Ä}ÒÐn$ÔƒÊsÜšu`ˆóÑmÓf Z!mÆ[;>sˆ‘{´¾ÜU™å(ZVFJlÏj#/쨳ðªçiY‚–|Úö{;NÛ-"Ú›“ƒ©0©´ØñæöWÉ´„çS®Nt’•§†«í#WåE³íF¨-¤Øüê mîú´zåmU(ôèÔòr4d8Ìv[i³u 6‡”6”¥:Ö•/DE¨vµ«p] ’š5r‘½ì—im–ÿÇd„é2è1{îÞA¥Ð\–mÉoS£Tªtô•>R M!©1ÜQt¤iJFx 狇o¶ÄYö†ÈB£C¬\Ó\…DJ}mE2Ôi$ »¥«Á£Æ2*æ®ùøÖç Tmº‘Óª¼ˆ¥$Z#NbQ ÈÌ*6–¢JˆÈò“22ïq¡~ “øwÀ>‚ì?öCjýÏðŽÈq»ýÚ¿F3ü#²‹Ø •(øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLTš{õJ‹Pc9·]ΕJ–ÔfËfyqÕ% à]fY<q2!ü»ðLcõqàqeñDÚ }šû .ª¼õǬ[W©Ž>Ý2[ æ\yÅ4¾áf’W} 22JÏ%ij¸÷/ÜÔõmz½{Wê´**E9È1Z•Ta“d’äsi”¶µ’Í i’V=É–r?7˜WM4.^V J•b÷ÆË'Õië†l†eŪƒ+‹%%¹V褡FÖH›2â¬ef]$xñ›Z£ÚÞæYö ê6¥pUjå-¶ ÊD¤Cm&×t§5#'ºQ`”gÝÿˆ¥¨@œçèt;ЪÛ7ÙM•_ M™L‚˜šYоNú™Ž”ë2s’6Ü#s: TY,áû´ªtŠæÑ©5zf“U„ªB#›°g4þ—óªQ(£4ðq3"#ãŒàñEˆÓµ¼…ίc…®Ù¸ùzû‘· ¤J7»ÊÌÕšb@«R侤–LÛQÔ®ÓÀŒpv®ÑêûTcE ƒP•DÖT¹spÝŒJqN`´8”¯ Z”ZÒ¬ðÀæ.JÕJâ®Ì­Ö$ªTùŽ›¯ºdE©GýÅÀˆº‹ ÂÜ®Áúm¹vò½×Ímï]6ûíkjA՘ɫnt):µ6y#<¬’]œ™ÄØmV‡F÷Nm½T¸íø”¹¯q-Ê´rmíü¤:Þ…kîò„™žœé> ÒfD?/€®«u¯ä.~÷==—³½¬Rªõê9ÕH* ¹5˜¨å¥© =&n`Ó©ÔaÌè<ðQàñùø]FͲ «—>mEï ·M“3“ŸUe‡a>hNý&ÚÍ+Q%zôèJ²XâgÄm}Ô·µúÚ’ªTï D„Ü$HÒi'Í*ZdGÇ^ =:ET‡}Ø,ïs5óO°6¢ÅV®¥7M—p¥:”š¤¬Ò¢^ ‰‘) Î8ã==¨Ù êfÈj—UÑ:½DœµÓ…GfA©.Kqn%IQ¥³3m% Œ÷„“ãÐgÀQ$'¾!Á2n^ʽ½îa‹cÑkÚUìrgÇ™1¸e9£70d㆔+¦ø¿ñ៯Wèe°»&Êr­ ³tSqÙ2"¼R•˜gzœ¥\Ùa&eú?ðÍ(ƒyè °¢Ó¸n{2ŸQÚóõè ¥ÈC³6Í0Ýe“Vé n D¢5‘'Šº ±=ÏMÏoîÈîÒ݃Bb;É’ÔZË2—4II2Ê”³Â*î’GÜŠ(`݆äܼí‹ÒÞ­Ø;I°~-ºíMUJ'+Y4É~™ Ü)gܶzZA™’zx— àÔî }¥îs‘³¢¨ÀŸ[­Uùl´A’‰ Fe;½$§[3A¨ÔÊx$Ïžp)¾ø8¹rmRm9í„XÑ£í!ú䦴ïhŠ6Œ¡~ŒóÁ)%–ƒýo Y%e8.§µbG…îW»,™W ¨Ý~¡WnLX‘Á=ãd¨¦jÖOh. /™ï,þt7X\ÚÓ¨§ÕäÒØ~”‰µk[õXÌ2zTI=8á6¾'ÃJ%IJE‘uû²\rÞ±.[~»oÕ)±i Æuqk1\pœßºzI¢sx®$ò”™ŸQãóø 8ݦ@nÖëݰÓíë’X¥Â¸¡ÀL ¥>£1¸š*5­8饵$ÍKᨌ²\$ãwpvw·nÓ(ôzlJë+®d“å|žkGOˆÑá(A¼dI5™žT½z]=ñlmÞ${›g[1¤ÐîR\Ú ãT[ìŽ 7nc'NTñ¸¶²ÊLˇ÷üè!Çzw¥Ö-ÄLºoê5:º¨+f–qªQÝm¥ÄDFã®ÇRɶԑž“#d”f¬™² ¢VmJeu;P½iUªÓÔÜXEWb£&CÆdD”M:ˆõ™èâ?/€‡ JÌ›–·¹Yq`mŠ“_©ÔéTÚm;}Ê^Pb>7‘ÞBt¥Å’—Ýé#ÆK8ÈævÐÊQµŽcS)ó#T*r¦Fzæd¡m8úÍjiJ$™—*‹%’,ä:„ aüW ΠAj§]§Ó^Rä¶ÂåHQ%¦µ’MÅ™ô%9ÉŸx‡èƒµbÛ4‰4]œí;ftÄËku:³*âO8JOZ¥–ÏöPf| *1ù¤J7æ ¿eW±hÜûH±Wm*ôytÈG\'Ê ÖØZÖ‚Á¥IpÏY:+B± f»!¾i“j´©•»¶àÅ‹OœÔ½ \JÝZÚR’’Òê°FzŒË£¬RÝáárn]w}bÒöCcS!UiPëvÃnA•¡9¨šÚ4¶”:…º¤¥E¥¤äˆõŸGXÞÜ[Z¡Ñv³6é² ¥K²éè…*Sf—T¶RËÆÞq¨‰), žz¸Ï F­ Ÿ¢ìÉZ/º2¥´É×í¥I›5·QQmo¼‡²CE|J-eÀÐ_üxÔ£ÖnêÍb#<éïÉi£,nз¢OñÕ´cgr ƒg[Y²í›: ­±Û~á›y¼¨Ê6wêqK,êaGÜ’‰?ø$º:AÔBTRÞúÉn=Éw5¦í~Úf·V©µ27kÐÛZÚÌEeZ"Aáµå+2QiÁ–Ea²:“çYeÔ"F¥ÓkíÔMRži†Ùî™7–n,Ë¥ÑÀω¤‰%•`øPµüÁúƒh~ýÎÊû#·ù‹“òŽ_ÎÑ÷:y'Æ­x×¼á£ácºÆž#Ä»mz6Ó6½HªÔ(曡R¹¶k’‰ÈN’Ôò’…¼Ê»”­/$ÌÉI2Òdf•üÜ WT‰¹t\×Sv)T´^ì"š‰uŸL£Hv¢êÖF“[Æÿ*u –”%:OQ«'ÁøœØ?QßWÍî=œ]u*ýÞ·.I1ÔQùš¸Ì·j/ïnsââP£'Hûý$F9GfÑî¯r•±hA¸(‘k4ªÒÞ—}A¨ÊKF©'¬·Š-e‡}ÎO§fX)NÜÅÏÐôË‚Ò¨ì »œå¹U¨Ñkn¼†k’œ§5=“[ºB‰æˆ—¥Ä–…8x">zLbÖ.v«GÙDIµ{M  ?å ¨°XmÖÔMª[Ï­/[hÏ$eÄô‘¬ÌP}BV.~Æ´î r'ºÊðº¤Ý–Ût9tFZ0ëQ´8³(éÒ_¤ÎHØw%Ž#<Óªº¶]ƒ Ü‘z[3kÖúkr*ç%ˆ|óNºÛNFÖ¤‘8z³¹tÒEÅdDiÔJN?…KϧÈ\ý²+âeÔ[N·N´.šJ]uÇbTê,Azš³yÎ8z^#Jµ’‘…µ'«sîU”½¥8«i̦”6PêÉõºÚ]I46¥™¡(KdDG‚Æ DE[²…¥qsµÙH®Ô$œÚTF›¤Tc§TãÅÔãðd4ÒRN­:²µ$ŒË$œ‘«ynö v,ù¶]ÞÛUKBs‹5‚Zd6ÂŒô©ÆÍ&iZ¯I™(»¤äúiÐâ¥Äƒô {úÚÙϺvMV‘%Y4蔽ôW‰ÿòtÄŽ’RTGÝTÒs×ܨºE}WÙüWn'΋xZŽÐ\xÔÄçªì´¤4g’ÖÂŒž%t‘ øôdWà!BÜjû¡¯š5Ñ&Ý·m—‘C¶)ɃSˆ4…iBT²Iñ$á´g…ìÜ5û’í›Mªý´õn“SvdÈmW¡¸´5™jÊtºd³ÃˆÂPf£Õ‚,Ï@7$¹H¹¶UpÐålôÙÓÕ(tªåJKrá½1Òe© Jš3hÝWr“ý±¨È»¿ñÈ2ÑÙ6µGµ½Ì³ìÕ:mJàªÕÊ[lA”‰H†ÚM®éN6jFOt¢Á(Ï»ÿtBº,XÔšÑk3-z†æ‚å*|Æ«ñIÚKŠŒÊTddïB·n$Öž%‚$ŸtD¯Å`(é&MÎÃk>Ò¹F¸©5úCËR¡Ê…=—Õ ±Ü¸”(Í ,‘dȉX3.ƒ"ãÀE¹H 0ï‡|è.Ãÿd6¯ÑŒÿ쇰ÿÙ «ôc?Â;!ȱm€¹R€ïŽ «úåŽ÷¾8*¯ë–?Ÿô_xÏ£GÝ#G# kdô ”Ž­“Ð=ú& †¶GA\ž±´‘ÐcW'¬z´ 35’ºF¶GI”®‘­‘ÒcÕ¢c™®|a¾3oJ™šF£Þ±–èÄw¬mÂF#£ÞƒNŒWz mÆF#¿Æ?XÈwà˜ÇëãÀâÁˆ‰iÕ Ö–Ö¤—I’O<Å®A'Ô Iõ!=ñ'¾€=ñ{â€OP=BOx@žð€$ uP"ˆOPƒÔ ÀIBÔ OP€ H€I‡| ;àAvû!µ~ŒgøGd8݇þÈm_£þÙE‹lÊ”|pU_×,w½ñÁU\±üÿ¢ûÆ}>é9[' l¤t lžïÑ0T5²: jäõ¤Žƒ¹=cÕ a™¬•Ò5²:Ll¥tlŽ“­Ísã ñ˜øÃ|zTÌÒ0ÝŽõŒ·F#½cl1®ôÊtb»Ðcl21ø&1úÆC¿Æ?X×~¶Ø->œîÅ¢“±#,ŸCûýH#×Ý(»®ÿ"ãÔCòd’"’é' –xúÅÁ³zîÏ`ìÒe>µU¬G¨ºNïeç•ä°Z ' òX.ë¯9áN¯Õ§:sÃ#óÁÑ*PÓ4ÉË¥-×V\øoßÄö½©¤F®£Æ6ÝNý8ô ú†UJ2ɹk;““2ZI¨ŒÍµgJŒˆòœ‘dˆðfFGÐdg±²é,U«ˆLõ-ºdFÕ. âxXoŠˆþ2¸!?ò–’ëUµ¯WkpoùÌS™rb%Sòîí¸êx¹)¥rMAM¡-™ê=E!¼(‹yNu`Žn ²'ì,J¬1˜ƒ¨¢VZy‰+JJÕÓ¼aÒ"RÔîH”¤¨¸’ÃðTÄ6©¢?ÌÔ껲¢±|ç¡!k5e¥4–µ¬‰'ÜâB:2|ã7íqÚ²jT5¸ÛR-æî’c¥ÊÛ3 Šzuon+l¥qÐiÑ©(ÏR ²¥kiòjõ[^Û¦T®7pë)¨”²mÄÃ&HÍÒ­%ÔE§†“I›°+Úý.]µ2‘9)L˜o)—4+RLÈñ”ŸZO¤¬ŒŒQé2^·&×R¶Š49qâ8“3Öky-&EŒ`‰…çZxnvªãJ½å0Û¨xá1 ® ò—¶\QYÛQç¯#:̹§[›=¯.W:}QÚÅ5MN’^6ÒÔÝfž½$jA(ˆD|ƒ›»\@ÐÖd«a‹ö¸®Èa³D~ð’ÛñZ«Å…PTâI p”…*[*#Qi2J &¬§V¡É[Ud;²gi’ªìÓ"±YE¬´ƒñšÔ†äAZMO-Fd”º€“AäB1ùTýñ{âÒ¬^ê;¶Û¥Oª”»EˆT4φ٥ÆT–ãESÙIdÂRVƒ?„X4g!fÈ*Àmz« £z[)™Vj3Ì®rùɈ%EÓB›#e²t™CqÓ¬”MšÈͳpÕ„iHþ«Õ:aÝ1¤Ókq¸µ”Ó5 5†e­šMYöZR„oN:M pȱ©¨ø,ëÈ’ b“%ërmu+h£C—#‰3=f·òÒdXƘ^xõ§ñƼYŒÝUú»s¼›¡¥\oV)JT¨³㎥ækR\I÷x3m+ZLÈÍX32WÎ]¶)õË¡ºj¡ºÉ]Sž}¶ëìSãL§‘4…kiÎRÏ{†Ï=ѲF““\ˆ) &Mjsâ­¤8ÜI2ÌÜ3"Ðà yeÀ‰¥µy–L‹ˆ×‹ŽÆ«¥‹&;1®*db-ÚË8Lm·$Nq©[¥Fz–£B˜JVDxÒ¤äX:pJw`ÝÒ-Š­J³nÒÒ†˜ráq´SÜuÎáD¹ ŽJVœšHœBÈøg¹Î Œ³¤!tSnʵZ§²ŠjóTÊ|”b©·:²JSRP}dó-z°L)½2ÒE„ê.…l]PêˆT®º“s&E¨Õ™#vBätXü“‰¥DÓi}k4¤Òœ+d“!™%H6,Q*Ò)­TcAyøÎ¸ûhSE¬òËiqܤ»¢$¡iQ¨ËÏŽ—lSÛ¨\0\ÂU%¸nKʬµSuõ“Ž-Ù !RôÃ=ÊS“3ÉI±»ºlZ3dÔ\eÉMUc²Ôe™—F’”¢.œn˜6ÌË£z]fB\®AÁƳî92§Eb˜§L*¬¤¥Ä~Ž)¶‡ ÃãÿÄ’î¸ã#"ȧX—5B•¥,'[šÒÞŠÇ9F)/¡+ZhŽnoUÝ6²àž:OÃuë*x×eH¸–ì7êñ)Í*žÓRŽDÌ’%þ•[p”ÞZ¾à$K‚Ý·ªvU-ö(³]§Å~9×Yã¯SÜç›·R”¸l¨‘”íaöãÓѵB¤)kSi2&ÝWq­ N³ÂIDdfF,³¬Q¨U)5 Ý/{EµÍòQ- içALWã!dxRÝÙ¤ˆúPát¨j`BEéÙ,ÙÕ{“ÒßzØ­Ä“«$¾f²mÅ ›ZTkø%œ‘ð lÙZwÊ•4§—"Eºcí$Ò¥¦K›Í ’Hò£=ËœK%Üôñ,øÜ6õRƒ¸:Š"iQ6¸ÓY’ƒ4ãRMM-DJ-E”™‘–K€¶-‹’€õŒŠœú¼H•iÒ˜¦LB×úD)ú„væšKºÐE">¥êB¤ÈW÷…*›H´èqÿÌê®™œ±ÚuD¥“±ðɰ¥š[iVMôá:O N¢Ï•'{2 e­o*àMA,Õ©ñ$Èô´F’Ok’†šqç ³CjI!³øjFrX3ã ê6^ôvnÅ"L–"¦U2£ ¾á6Ù8ü'ÚoR•‚IÖ’É™g'Àw{'ªRèVüŠ|ƒŒ¹ÑêîQ¢¸£Â.)6„¥ R›p¥5¨žîZ<÷DdJÊM2Û@§YTÍ-½‘Ì’ôæ\§·"• 9¬‰Å±)m¬Ô’é4¥%,Œûï'¿ÇitW(ïl™¸7nE:d&›iÊë:cÌA·¿q¸$Öõ.)Dö\5éRVg“îRQ‹Èå×o*€ªr“V§ÕcTbr¸ÒaÄ… žu“#'[BˆÉl¯û=î#KÔ:ˬš™dZcK„âa@rŸ%’”Þý·Žd§‹-g^ƒCˆ=dZrxÎxO¨Y¦nÆ®=SvœÂ©Ê‘žÕB^úsQ‘· ²I8ãÊB yu²4‘Ÿ‘t‘‘cijë’êÓ)±QOyÈhK’EN1Åm*ÆœÈÞn¸šˆ±¯§‡Iη"´ÞÔî´9ÔXÌר9ŒY1Ž4˜¯8Ûèkü¥&ÖRiOÂÆ £,ä°yu£N¦K¡C~Ùj²÷7ΞÒ&7!æU).4‡Iil²ÛÌ(É JMI^ƒèÄÉ8Z­tÒéR*u J£G޳K¤·›Þ$‰ÍÞ½Þ­{½}ÆóupÎF¹š4—í¹5Ö]alE’ÜwÚ#=ëzÒ£Ḇ¥E’>X2,–nx7«W—kÌ™d(”¸Ñ™~D˜ì·)ÆÂ†Ýy½)A¸—_æ´(ÒXA)Dc‚DxÔÛ~þ–Ä™L’ú)p$îô•”¤>N%=Xi“3"ø;Ô—Y“æ¨A‰êc¡B€õÔ ÀÀÀÀˆ aßøÐ]‡þÈm_£þÙ7aÿ²WèÆ„vC‘bÛr¥ßWõËï|pU_×,?è¾ñŸFºFŽG@ÖÉè)[' {ôL lŽƒ¹=ci# Æ®OXõhfk%tlŽ“)]#[#¤Ç«DÇ3\øÃ|f>0ß•34Œ7F#½c-шïXÛ„ŒGF+½2®ôÛŒŒG~ Œ~±ïÁ1Ö5ÇŃ$Ä Iõ}BO|A ï€ O|@žø€ Ô OP€Þ'¼ $ I$@AÔ€H"Ô Äõ0B€õÔ ÀÀÀÀˆ aßøÐ]‡þÈm_£þÙ7aÿ²WèÆ„vC‘bÛr¥ßWõËï|pU_×,?è¾ñŸFºFŽG@ÖÉè)[' {ôL lŽƒ¹=ci# Æ®OXõhfk%tlŽ“)]#[#¤Ç«DÇ3\øÃ|f>0ß•34Œ7F#½c-шïXÛ„ŒGF+½2®ôÛŒŒG~ •“E_¸9ÉÎÁŒˆ’¥¼ûQÉå¥ã¸ú‰(5 ”fM™T]=#ZïÁ1¸Ùý±‹”ë v[.¢æv*´¸ÛÏDu¦ÖG’Æ•¸“ÉHˆÌ²x!©^ÛŽ,ØRmš=zã§Rí9µ ËŽ¸[øõ‰H[…­ &ÙqrJœV£",—$¨³Œ;™E¬H©À©±P9%L™.ñ¥!´4¸ñ^!M¨Ü%i. F8ñ>­µ£{Ézú¡WoÛšå©F¢LnldšŽrÍhuµ›dNº‚l”Hâ¢3èOr}ZËn¥A ÞkÌŠ”Ê3‘%CSˈ†¤h‘ƲhœRr“tÌ‹yÝi.)Ïò *«^¯C~]. <Ë' ÍO¶Ù¸½&­ ’ÔFâðFzJV:‡õÒ¯H óãqX(FÛŽ£\ÆPë­ Ì–´4¥“‹JM*Ê’“"Ò}ãm}S-ÊYÓ‘)´Aª»P§L*)/¹©-¤ˆÉóW&WèPz›Rðfy%`Œ`Ðîº,kÚ5PçT(’ ê|weÇ F‡[’g½gJ”K4$Œ”¢<ždKÈÓöÝiˆÏÉv–X†Ä×½F —$Ú‹3Z{’Ê‹ŽH´«u[*á¥*:*áÇSÒÒªŒ|°êºùkýð?ÖéÆ8ÁŽšõ¨=d6¥\7"Ôe ßxÜà·a¶·UXéÒg!üwÒ„Àÿîº-zßj;G:¡U9IxçͧÇaö›$(”ÒhÍRu(ÒzÖI2ÑÀ»£ÛÓ³úÅà¦Ñc½©&£;̦$Øî¨”ã º¢Q6â´%;Ã"Z°•¥:ÓÜôxÓöywÔ+¯Q ÒÛ“5¨‰™¥©Œ)2¥¥ Snô9•­)"A™™ž ‰Ü1yQ¡ÝÔ+ž*&ºûT¦éµÏDeM¶H‚˜zÚ5)Iw)%/KˆIdˆQãsAÚ]™z±Tº„è1¡ÂŒÎê• ¤™ª15d–2mimÌwJ3Z¸™÷1yX’²®Òj:£´Ê¤~O-¢I­Ҳ’JI’’fFF•‘‘ôÁ»Ò­·XbdT:†Û¦@ˆ¢tˆŒÖÄ6YYð3àjmF_Üe’#à4‚ë†ò ßB{à ý‡N©Ú•Ú—9Ëj¥IŽ™\—‘¥LºÊŸaŒï·„¤¯SùÓ»2Â~KvɉSƒIDšâ¢U«›ÎiˆQ7ˆ{JÔÚwŽk-Þ·¤' _ã‚â<ìiö¤*Á»R­Æ“V†˜I(TƤ!´&DwÉÃRä6fflštã†Hõ@ÙZW™…:aÕÑU·¦â±(8óR)¤¼£Y /¨ÔdI^¢J~ –E|©¥Û4J­5äÓ®7Þ¬1Ov{‘•N4G$´Ñºâ ã^­d”¨¸¶I3,$f›e¹ fÍ]Òj D‡¦²Ê)Û®ì˜y›o©Yá¨ã¸Dœq,+82ÎÐëLk™é+‚FLb:šŽËœ­âî‰÷)#DrQFO”JÂRŸêçÚ$;ŠÒ¬ÓåZ´¨5:„è/¡øg'B·ÑÐãê$šRâP”’téRødd»=³ên{”èç½5®çÙ&””šf+®¶œ«† m¤ûŒø—ImlûN2v“GµoSMº³ñã²å: ÉoœJRò\$:‡PDjàœdÿ´X2vÍÞÊo$V.(Í&76Í‚´R)Ñ¢ŒóI2CiB ÉNäÔ|p]x"½–Ré÷ŸQ¥32M:×ääÙÉBZzI7)rTf”©DŒ©Å$‹R°D\AÜ jÚ¬Ün¼Ý"3nî &âÝÛI¨ð”ëqIN¥Nr}DcÚ“h\5B”q %îNï)ÜÓqýwŠN·8pœ«û†Þ‘S³â±X I•^r‰.\I‘å· ¤ÉÖÂ]- ozi"2}ÂÔKƒ©”­ª”%]t·Þ‚úV­j ¥Nc)4“©K©J’¬jI¤Ô]DfF,NÙVlWé<ÙK—,Kž›XäìÒbÇ6cÇßkgx…k²Þ'JÝ>8…Z—i²jÐDºk[Ŷöõ ¸û(Q¥O!•(œSeƒÊ‰&IÁ‘™`ǽ©A“l&ݸܩEf4×&Ä•„>¤©Ä6‡¦Ö´‘“M™(•ÃIð<ðê-ËÒÍ¢ÛR`ƦËnK”ú”#5S"ºãÊ}·Ëª”£Þ·¥.6…!²I$Փɤá¶ÈU¬»’•En±:†ã,>JL¦–´¶ò m-HJiJˆË 2"ÏsÒFCø¬Y÷%–›M4“ïrCO6êÐñ–I§…›pø÷ "WáÀv›B«ÑiÐ_†Ç8¹Wª[Ho¡ÆÐQÚm1a¿­*Õ¨Ô{¦Ó¤ÒD]Ñäó‚ʪí&Ù![t•²¨— ÄxʥƌÛMÇKß S­¸ùåÄáÇ2fZ¸$óª¤IÂͳ+Ъqi³M"I¸”•X©m AehqÃsCk.ÊÍ'“"ÆL†u È—\ÚŠìÄ›TgS8o&læ¸Å¿&”’Q©´Èq9ø-à׃ÒX訷d»WÈêW PS‹’ë°qÖrYB‚x‰Î< f¤d:x`÷U›ª„ÖÛZ¾èê©K„u¬ºÄ¸ÈaÄ+”›¦Ñiqd¢"ÁŒË&gÜ–8ÍÙ7&Ù¬2©„–cJ(n²Ëˇ1™(%¼Fm’TÒ”KÎ ²“2#àx>_S…&›R•N˜„·&+Ëeä¥iY%i3Jˆ”“2>$|HÌ…“²‰Tú%bè¬SÚQ· SIâ“22X4JCˆv)-)ZÒJ7Û$‘j3Ru ‰^âÖãŠqÅ–£3RŒòfgÖ%6Ø,›GdÒn²j²Ûî]öýëh}m'WtZµš;Ÿƒ“Éudrí:üKyºûðR˜% ÔO¶n% 3$-Mµ¡ 2<)I">£1ÕZÛG]E™§f¢—Kä§XކÐg'qR~Ztdú’ñc&œ«$|ŒbÕ®Ê$›jfáª<ÔiiZ[h(Í7ØÃˆY+R”¢Œßri,j_É §+’i³.Wjò)(¦ælj»TW›ß·ÜÌuN% gV&Ë…¨Iiâe’Ì˲î“ E–ÌêžNnv§ å²ÊзMÍ ­<еˆÌ‹2#ï;aZ \ª¯Eb¸·§^0.9­¸ÃD–’ʤ)Ö[2põž§û•œ—I':òm^;ö5*†H{•D©Í–âÌ‹A¡æ¢¡$Gœä…ç‡ZxŸJrd[—gõŠUûQ´¢= ¢ìGĆæ°M“M­IÞ:¢pÒÁ÷948¢4äˆúK8,»–UV}1ºrS&žRNÉi´$Õð–¥TkÉi$™š¿³‘ÕñAch×~-T•—ŽYJ¥F¨n;!/™!—V¦ßJTÚK*ÐfF|dF1eÝô:¼šäZÛõeÁšôØ“ v]Õ•²†Í”[m CŠ"Òg£Jx/•äIÌ_Ô˜Ô ê¿B†·\N©ÉˆÊ25© º¤$ÔdDFx"οÀL[N¿*Þr¾ÄªiZÍFûdâƒ"ZÒÑ«ZГ<’“"ë2U£Wïªývn5F§&[)tˆ–”8ê–’Q™àË83ÿÐÒ®Ê$knýª<Ó©©šCh8η$ßË«Y«RT’’çrI<éGÁ‰»² ÒÔì›–›Dç™D=ÃLÓ)•¸–_JTÓ†ÚTk$(–’ÔeŒž“<ðèíªWm:IWI Ë.p¶i´–u%=Ëѹµ+ºàƒä®`Ë'Ý'$Y0ߌ7Ç¥LÍ# шïXËtb;Ö6Àá#ÑŠïAŒ§F+½6Àã#ß‚c¬d;ðLd[S#×bH¬°ì˜ ¸N<ÃDYx“Ä‘ÄË£"#>’#3"3, qàqgAØb\äpŠ{0æ7Nç:»óe+4î’d„)f£%¶g‚Q™º”àŒ;–Âi74ˆê4š]::”oÌ’ûŠar$CixJ’•¨÷‹Þ¨¸i"#>äˆhéWZ“[­N®Ä]MŠã+f¢ÛO“ Q)ÔÉÎðtWµ’ÌHGU¤Ì§Qè´¹Ò %ç!²~4}oS§Jžwà’²Z˹$àzÔ¬$ÒlÙê—6”õiÈõ%)…N5)N´ñ¬’‚=Hk*Ê’ZZ‹ ‰×‡)çóvŽr À£þ»;¾MÈÿKðxê䟆7'§Žæ¡´x¹MZÈ)òëÑ+µ¿3zÌ—™'µ ›ÐZ[Y¼£Á©FYQdÈËM‰43-ØTg©Óªu6ª´Iky¢³É¸ÒRjkôÈI¥Dko&i2ÂÈËW@þ¯="-\¤5Q†ÍLßICžòu)hÐDêV” ”…š”’îK‹k.#£¯í.›_›o•vƒW¬S©%I[ êžvB^CDMowE¡ SYÂSƒ#Æò£æoúý2ä©¢£ Z4ƒ#K¼¶¢Ô„ˆ†’Û iI‘$²XÁ8Ê¿2hÀßB{àZËÙ½mÃQ¶©Š«Å—G›,Ú”µ¡q_K²[¼B 6ËS©ZrµêAä…R;ê–ÐÐýº$X^@µ4RZrSdÊ•î-)ܶjB þ»”÷\5•ùgE³m«ªŸ¸®R©på½J*u(ñÍ÷ù,‡™J_[Im“RØ$)+%iÞ'‰äxS­*ö•oЪTÜJUmÖb0ëYYqÇÉò$6Á´âGƒl‹9éYt ;ƒh V‡L™³:ÓÛé Ô«k“%Õ†É/hI!(%¬ÒDƒ,¨õj.ú¡ß4 Mnß}‹b tÊÅTaÆçdkeF·]6 ”Œ0„èJß՜涑&–¦Qk*p*lTIS&K†üiHm .Ôv£ ¹U¡;*·O“"TGXžlF5¼úß=ë:k-n(¸-IO$CUÙ¬NlÞó¹ÿš¹§œ9_è¹>ïsÎŒï7?£Õ¯ã§±H¤9 㩺ÓÓ§¹,ŸhÖ‡Û‘©¶TÞ©Ö£%)eÀȈˆÃñÆÿ³éÖͯD}¹r¬;.\:³j4î˜y¦ã9»F 9IHÒ¼™÷I¨tª«NÈÝ!-D®:Ã.²ÓHi ÉI$ÍòÂ2fJA¨Ô¬ŸÅ^+’4‹FÛ]àõ=5µÖY"$Šƒ/4ˆ±7KZMÕ4hR–ÚRj=hÁjéÆO+° WaüéÈ® Ï3ó‡?ëG6ï÷z¹.ׯô9Þg_8qoÊ ´±*ÖõaÊVK²*õ†£*i­ÃY ÉQœ4¶FdzIXQñ<á$Ÿ¿`óy¸T)Xænfßó‰ò]Æçs«“èνs¯N¾ïND~ n®žÒ]¯±I´!Ê~+õ¦éíUÊâ‡RaM¸á¶ÚÖÔvÒ¦MfiQkW|°fy-5F‹gµGEÇÆå&<äÄËóiÙiqn_iÍÉ¥ª;¤¤šW8Õœ™y@½i´8ý¥o½LžûŒ-ç¤T9JM<‡Ò–‘¡&’Þ4ÙåJYá8Ïs®‹iøÉ¦1k·H~o.žÃ5T›®º”--¥·É“m£x¼¡fd£#WA‘)>-…FÔ.»y§¥*—o?-KQºÚq–¤(#qz[Aš–K<%%©XáÏ_”ˆôZÊ#E6NGK¤Ü™ŒË%™áM¾ÉA‘D\r\q“ÜV/ZDëÚ¹\j5ª}À—yÒ •4­jSïÌÚt™N‚%¥³"RWðO&¢<Šî­Ç¬»¨0ŸM†Pâ0ãûç źfµéI)F·Vy$¤¸‘p±_yŒÁ"ˆeÒ\§5Piuh²åÂ,ï‹%,8®Œ-HYžHŒ¸g%ÚÓ­kqt“bÔ[ªÈ¦ª¼ª‹qÚu9KšñÖX'ÔÔv¤¶ÚPÒTÚ¥­Òqfh3A‘7§R¸âgFr·"º¶V¶Ï 6^K¨Ï÷)&i?ñ#1ÒÛ·kVåЙÔXÕ6èéQ¨ =Q%9¨Ú4o7©m)Þ$ÔkB÷}Á’x8ë/Zçd—4ºÏ%8ÛòAhS›Åž„%–¼µ«N¥+©JQಠ÷õhRcT¥K‘Q[­RéñW*bÚ2%™„$ÌŒ‰KqHA³ƒ"1¤·jÑš³Y¡ÁC©uù'*¢âȈœ4‘¥”'Å)%-Y0ß•34Œ7F#½c-шïXÛ„ŒGF+½2®ôÛŒŒG~ Œ~±ïÁ1‘nOb•]‰R“‘Ât£­ZPµêàyN¬—Y–K9-qàqgVí§KKÜÙ2Jà.Lç ô¶Ú7ÜJÜq´¡„4kJMH7ZA–SÝ)ÌžC¡Ÿ³vë÷\ÔÒyr©tê]*]"Œ©NºãðZQ;¹A¤É*4¸µ¨Ï9?í)\kê5Ë:VP}˜õNqmmÏbnµ"RV²Yë4)*δ¥YJˆò’<œ»úlÚ¬Ù•%dY¬ÅiÚzÚu1Èã2L²´èq+J’‚>…c»Qc Hƒ2Îd½>\)5$0å6°ý:¨igYFCM8á¼]Ñj#KðîWÓdž’ͧC{œ+fwÔÊ\sqÆÍF’}åw,³’2>é\OG¡ 2èÝ"ñªÒb\1`µ ¦kì›RPLàš#QžZ"2$´u–•¨†šÆ»^JÞLò\U‚,–7¶™Zy-8Õ6‘bj±kLi•ïdË`œ$¸æ¥šO;ň’DgĈ²¬ÖÒ°?«²ÎE”º5Z¥«69O¡1jp\¦¼µ´”g)Ô£6òê ”“#Q‹¹2áM¡Â¦RèsÛ¦S©³'ó¹ç6„ C»Ç Y™¬”’qX"AðÕ‰U¾^žšs'nPY‡L™)ˆ†]Sn®BKšÍn)JýRLQ)&| °:Ë’ãr±itêM>œqˆ’æ‚qÍ$µšœZÖ¥6‚â£à’Ƥ÷\@O|A ï€ dÕ­Ú½³Ã~U5.Z}^žuyç ´7!™Nr5% O&5¨Œ”Fµ$Œ´ŠØuu¢^•Kbm»V¹*µ8Se÷9dçžQn‰xAjQ–ƒ5’ŒŒ*m³á¤VI¾ì)tÛZ®V¼9vu6P«9&Z[ƒ&a£¡¥¥„ºn¼æ„8òU©dDim³ƒÈÉz‹eÒÙbeÃI¶i“fAQ™)ófRÔHŒHVö+Ž9¯vrr’qDFM™‘jÀ¯ŠñªÚ›,Ã'PÇ%L]Ùœr¹Ü:Ló Ú3ONpfyÏ”õìNòXÇj[¥JŒ—tS ·Ín›zÜÖn›¤³Ý6Y' œ2:ádT+FÛ•{޲ųšÚbs{h™3›]'÷ÄN¤×%DGÒ4’‰fyÒ”™ túM-˜w½>M³L*NR….4Éš ÉDÙ©Í em¾¥§Z e¬²®N»î[¯)¹tJ4ªVᶤ­·S”¶¥©ƒC„á(”ã§«^Ox¼™ädFÚ©U]sí[~¤º³HŒù¿Ê‘¢3fɶ §ÐIB;XÙ%UúlÈOäïNyM°É- ÃiÕ¥=Ë{¼c´ãˆ›Hƒ”t‡áƨ4üø<¾:2j½6ÉgƒÁ“ÇÁž0fDdFYÉb ºDÒ§Ô–pâLJ2JbSf¶ÖFFFFDd}ÒFFGƒ##"1pw÷]:‰@f‹T•iRž—=tøWdÀ=*l›^õ·V¥+‹¤¦Ò÷àòYÒj•6‰Oº¡ÓjRU™ µÊ§T+ œþ\5¶n)Ô(”m“JÂÝÊT¥ õµô¤É¥Taȃk[­F‚Ûå‰;¶{A-ô¯}½Þá´+_rEÃDe¬;ªžsÝ|ì{lÙy)×J˜¤šÈÔ{ÂZ¤¤£Õƒ"^“Áe9,Žvd5ÁC·àöwGj…Ÿ¤ÓãN1O¾n°êß„Û$õ“n2[çI*4”F•j2ÀÅÙ]*q¸Ý&U½Nq´gÏvª¦æ¥¨õE`–[Õ%)øÛ¦fE“N¢Æm¡ºJ«.}«oT—Ue¸¯›ü©½›6M¦M>‚JqÚÁãW Œ_mÝ렵ȖýÊ”5âTiÎPµ‰DIp›Z’g’5¡FX.¢ ³°6ôWèØUš…FÌ¢·É#7 $ÆäM'Þšç¬Èä|—Q4ä’X"Q …›k\²—:×UœSâʼn*$—ß“5j}´ºÖ•š’≕-ym ‰eÝ‘]bLš !¶ËQ!8ëÉ&ÈÈÝqÃN¥¯'Äô¡ ,`ˆ’]y3êkJ~|š|Ö-Kz™>˜l:L5K.GºY-;¶Öúš,™qÊ&fgÄò%¦ ý¥[p)–§ ‘J˜ÝP¢3Í5UNiÆ´,×¾Q¸á6á#”ˆ×Ü‘ZŽŽàº×T¤*•‡G£DrJeÈD:[÷R•%*Q¸âðI'„§JKQðà˜¦–ò¯fìRç̪S*Tx“w”‰òYã%È®1 ÷¤hZRyZ’ZTX.Éçmb·h=j´Ì¶mG«ë¨QžL¸tŸ4«š-=o¨ízY*J¤G) ¾®JgŒ!&N‘­‚Â]5ÿ~LÏ0ÓaƒEv‡Û‡M¶¼Ôˆ“¢Ô¨·<¦”‡’”´iRb™“dÎ’3<«$dyÀÀ¦Ûh»3®L«FS·émU þ‘I(qùdfR¥$ S¤ò̉YÂR•Ã#-TòtiJ©ªF‘]ß¹!‡Zs•!Õ¬Öna+&Ô¢RŒÉJBŒ¸c ±üAÚ%éÞŸ@ì’ªý6d§òw§<¦Ød–…a´êÒžå½Þ1 ZqÄE¤I¶M:“^´'M…h¢â^f-æe<ëÕ *q¦TKQ¥fM©J56”LF]Ù÷¼(ö•¹@·^bœUIêgS-inkÍ3dI2<h[êNSƒY'9-De­¹6†íe1\nØ¢RfACh§Ë§=5§!j%$ÙIÈ6Ðy,™éÎLÕð¸›HºêTÚ}6¿Pv¿·¥“UGÝO)ÆÒÞ•ê_BI*4aI7dy> 0vɱè¢=^§K&)ò¦Êª¹÷‡£²Ñò„­Õg[ê5¡ R°„‘i5¯ö‰Ob V#‘ Ó#D—2]6CÎÆkNñ½ÿéSÅ“Jø’®Ž‚É;îRw£P¨±i !Ô*”Ûow‰ÓlÜ5šœ7LÌÚh󬌷iÆ04×5uúì˜î9$(ñ#”h±"¥DÓ ”­)Ô¥(ò¥­FjQ™šˆ˜§}àÔ€¹ˆ Ñlâ‰á»âS';»‰º~Kç½&òÛ,­å'Yä“’lËQ‘ã9êì+b…Pž™‘(v츧S•¥-¸ilêD•È4¸É¡Œõ6•š"2Ϻ…T“Fª3QˆM©Æµ¡ÔêCˆRM+B‹­*J”“.ñ˜é´ mbF PØ£îeÊJ[xã¼N-µ­JR7u™dòK#-Úq‚!I'}À±œ°­9t•Ef†Ìzü˜JqMÇ“!øí¾´¨£&ä¥4é“•’Ô³2Ô–ÍJIŠR¹Nz‘W“LfoFY¶æZq³Ô]%¥Ä¥Eÿ¬DÜ7§|TSqSêñéôØÍSâ.h !|Ü' Æø¬Ü=[çLÕ¯VVfFGŒj.zÔ«‚´íV[l4ãˆm´¶É!´6Ú[B¨ÌðHBK&fgŒ™™ñ¦¸ƒ:ͧC{œ+fwÔÊ\sqÆÍF’}åw,³’2>é\OG¡ 2è©û4©ÂTéï>¤ÛìDvSCh°úI¦œh´jÊMg":xžÜ<´™jMc]¯ƒ6á¦ß\™.kÉÈtËJ Ë‚B8q⥞{¬ꥴk–¡b³fHy“¥´Ó zÍ,­Õ¤ŒóŽ—H‡CM÷2ñrÞ–\z ŽÆ¬œé4ª‚i•VUtLIR\2&Õ¨÷ˆË.§Q’O(èÁ‘Ž¢™bP m§iÓ«\•x¬UáEÒ·hqäA•»[FkV¥%Ä#’L”i4š±’ãn«Ò¡pÀTYiÑMù%2sÑ›Z\› ’i']Ô£-XRø ’YZ1âåÝS]çVº÷QS:ªsä%*&ÑÊÛu·4¬– Õrgƒ"ÎzâÒ°1.ºLz]T¶ª)œüt’%©¶ðÛo—Ãm Éë$Ÿ X"3#ÆKz‘°¯U¤Ö§é¨k•iCΠŒ”úˆ±¼_+2ÆL±“,žLÌÏ^,€0001 $@‘“øwÀ>‚ì?öCjýÏðŽÈq»ýÚ¿F3ü#²‹Ø •(øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLcõŒ‡~ Œ~±®<,& X‚O¨@“êB{âO|{â÷Äž¡z„žð=á !H@ ê D ž¡'¨A€’$„'¨@ž¡$@‘“øwÀ>‚ì?öCjýÏðŽÈq»ýÚ¿F3ü#²‹Ø •(øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLcõŒ‡~ Œ~±®<,& X‚O¨@“êB{âO|{â÷Äž¡z„žð=á !H@ ê D ž¡'¨A€’$„'¨@ž¡$@‘“øwÀ>‚ì?öCjýÏðŽÈq»ýÚ¿F3ü#²‹Ø •(øàª¿®Xï{オþ¹cùÿE÷Œú4}Ò4r:¶O@ÙHèÙ=ߢ`¨kdtÕÉëI5rzÇ«@Ã3Y+¤kdt˜ÙJéÙ&=Z&9šçÆã1ñ†øô©™¤aº1ënŒGzÆØ$b:1]è1”èÅw ÆØdb;ðLcõŒ‡~ Œ~±®<,& X‚O¨@“êB{âO|{â÷Äž¡z„žð=á !H@ ê D ž¡'¨A€’$„'¨@ž¡$@‘“øwÀ>‹lz}µBØ —R¯È¦AaÊ[D¹3¥›Ôf¢"ÔkJs„ô ‹úñ·Õ²«®½eThsåÓiÏ-¹¦’Žîƒ4™‘-IÉt‘(ŒHË€ä¬;¿f=¡íkFñ¸è)ÞÐZnd2’KJTjQ‹9IàÒ¢è>)2ê1§».Ûû¯Ù–eÑDVio¡–Q1 vC¦“Ê”ÚZ¿.¢Ë®@X©ù¦À´çÝ6êëR¯‹’ŽTg2LEL2i´3-æE®:•ðPž•ÂöHÂÏ+½îu÷µO?þÔlvûƒ!­ÚÌÊËö^Ñ"=x9 Š(á”w˜š9 *S®ž‚2SŠqM§w¡$¤ø#¢¬\UÅV*t†ªÜÞÛ·[–¦“-š¡°ªc2L“©&“R5 d®.—ÁE>Õ‘Éu0aÔ3é¹+gþ0©žÈ?“ØU¾}7 `ÿè4Ïd6Ì*U9¯]PªU­.¸p£ÉÝ6ƒÝ”XË4«vD“Q-Å’9àE‚.ÈNª ’ÈŒrêT§°kpúkÕcÿ RýŒ'°Khúk•SÿÝô¿cà ÁƒêT'°\úk5?7RýŒAûŸíSé«Ô¼ÛKö1o€œ+¡e>~çËLújµ6Ò½Œ'îz´O¦©?Í”¯c ²)Ã÷#«ˆÒš‹Oµ8·M-$’Fµ¨Öµ`ºÔ¥)F}ffgÄǸ4¬Pèl&rX´èm&¡ý4‘ ²)=¤Áw¿#"ŸŸN5>Þ¥Db¦ìf˜Ž„%…šTƒR¸%F•©9.8Q—Y5šE"µ%2«½¢úS)v\FÝZ[Q)j#=&Fy.ƒÉJœÕS!ɤ@[3C³¨í­2’A~”FKÊ[Jrdg¤ˆˆË˜4–"=°Äæ)PÛi©’ÎRÐIBƒÝ¡²J‚JR’Ch",uq3>#uËæx;_ódåó<¿¯ù‡/™àíýÌH#—Ìðvþ¿æ¾gƒ·õÿ1 @Ž_3ÁÛúÿ˜rùžß×üÄ€Y9|ÏoëþaËæx;_ódåó<¿¯ù‡/™àíýÌH#—Ìðvþ¿æ¾gƒ·õÿ1 @Ž_3ÁÛúÿ˜rùžß×üÄ€Y9|ÏoëþaËæx;_ódåó<¿¯ùhReÉšÄsi´®%®9â ²s­ rf%Z]Cp²mÇ)ôIRÚ%R­;ƉH3Â’x#áž#úåôz-?ÕG¹ûúƒqý$ïû«ÝÐQÿ6ŸþD/R qèVÅ.¦Ã—Ó¾2½è´ÿV<^¨ÆZ\Lä8ó o”3.›"Ї Í "tˆÔFm(¸w ¥3ý3OÿÒSÿÈÇ÷vÿ\*ÿGSÚϲ,k'Öù}ûéîu¡²&Ù[‹R–¢JRINTfjQXòM}Ýë-¹L«Gß<Û\ŠD¦[ÖâÉ#ZÐINT¢,™‘dÆ%Oõ”Ϧ)ßïŒíÏýÓß÷Ö¨¦.xóƒßñ[úñsäÿa¦Õßêÿê1G¬í~á@õåó<¿¯ùt˲)+2£JŒú1©·e¡ NK%’5d¸Ù úîÿøÓEþäÀY©ìÚòÍïÍþa±‡Y\ØÈ“ ãIayÒãNÒ¬GƒâFCóæÑ¨Õý_À,ÏsÇìZØÿÑøÔ@ïy|ÏoëþaËæx;_ódåó<¿¯ù‡/™àíýÌH#—Ìðvþ¿æ¾gƒ·õÿ1 @Ž_3ÁÛúÿ˜rùžß×üÄ€Y9|ÏoëþaËæx;_ódåó<¿¯ù‡/™àíýÌH#—Ìðvþ¿æ¾gƒ·õÿ1 @Ž_3ÁÛúÿ˜rùžß×üÄ€Y9|ÏoëþaËæx;_ódåó<¿¯ù‡/™àíýÌH#—Ìðvþ¿æ¾gƒ·õÿ1 @Ž_3ÁÛúÿ˜þSQ”¬ée¥c§ þcUzV'æñçí¿ëd?£ÕÿÍ#m T£*·àyúFžèé4èa¾.w;~_3ÁÛúÿ˜rùžß×üÄ€Ådzrùžß×ü×Ìðvþ¿æ$ÈËæx;_ó_3ÁÛúÿ˜ G/™àíýÌ9|Ïoëþb@,¾gƒ·õÿ0åó<¿¯ù‰²rùžß×ü×Ìðvþ¿æ$ÈËæx;_ó_3ÁÛúÿ˜ G/™àíýÌ9|Ïoëþb@,¾gƒ·õÿ0åó<¿¯ù‰²rùžß×ü×Ìðvþ¿æ$ÈËæx;_ó_3ÁÛúÿ˜ G/™àíýÌ9|Ïoëþb@,¾gƒ·õÿ0åó<¿¯ù‰²rùžß×ü×Ìðvþ¿æ$ÈËæx;_ó_3ÁÛúÿ˜ G/™àíýÌ9|Ïoëþb@,¾gƒ·õÿ0åó<¿¯ù‰²rùžß×ü×Ìðvþ¿æ$ÈËæx;_ó_3ÁÛúÿ˜ jîXНÓãA˜Ú›n=F-EÒÈ”nGtœAsÜ™—éÇAÉ’oH}N¼Á(Ͳl“«‚K9<‰’sÿšC,#F¥¤ÓtªÆñ|QxT•9)EÙ£QJ§5MªÌ©GŠ¥H™»ÞïRÒZÉ:Rg„ôžqŒõ„g¤Ç\ƒm„’^yOhÉiA«‰?Üjʸ犫^à8èþÏÑ´gŠŒvKô[’ý T¯R§çw6½—V<'Ô˜¨Ó‘ÿÙxymon-4.3.30/docs/xymonprocs.png0000664000076400007640000024010611535414771017075 0ustar rpmbuildrpmbuild‰PNG  IHDRlÔ™˜àt pHYs  ÒÝ~ü€IDATxÚìýhSÙ¾ÿ§çöp‰(ŸÄ«Ðý`zš0š0Â5=wR=`ª&*LS=œ4LÛñ0môòu’8im*Çi;0ÚxQa´ñÍÌ$¾ùxHä(MAßI9Ý…ñcr¯bzL>œB¿¼Ì¸;iÚ½³³cªÏ¸§³³öÚ¯õZ¯×k¯½öúQ“lJŽ$›$ #©ó_ޤ~EÄ‘ÑAG$@tÐ tDD‘` ²áÜL6<è;môI$³hð‡wGäD÷-ÝÆU;ÖWWmÿµq•aRÿÐ0éiÐ{Ú+_Óž]¿3í©Nåªn¯ïRÝ&-å;ÖWMtǶMt—÷^êϨWˆ¡çLOÊ9c”ïXm”K$µr15fÚý¾y(œ¹9Îþ:’úÊ>’ê=:Õ5ZùÚ/¬M²üñÀµ»ã·3|¨W¨?ŸouÕ†ßqõ{¿c¾nÿµq¯N™…ÄÒꌇ‹Û‰x±k¹X)¼=Ô$›’#É&îPçËà…¡}ƒtí-‡Î3¹?frjé†Ój)ÔJÐ 0ó‚9Ƽ 3Ý­w":çÌñœs&üôæ?ÃOËw¯gÔ+˜Žäïµk8ÿåXCDwgKDç½pú?¼Ø¿šö|°Ñ´Ç9}<çœ6Lè2L¼ÞÚL$ ÆUü߯U‰ë÷v&®Ã«‡pæû'á uêmºxnl“Â%ß®p¥™›i§ujßaëT÷ðÑD÷°Q¾½Ö(¯&­¾ ¾ÌÝNÄ.o5[)¼=Œ¤Î9’â="’^ãUU›*Â>_Ø™v>¹švZ§,‡­Sìñ€ñà½]ñà|Q¾îI&·ýÃ0I)©Ë‰Ë¯…£]¨{ˆÆÔäÓïúiŸ'ó õçêÔUA²i¶Þ×P†J7Ll{f˜`r˜\iºÊw~½‘êª?!sÕÞ«P3Lnæ8“Ë_»cq•«¾Oåª/‘Ä]º u­Rêl-M?&ó®wMæpæûÇá {8•:iH}4°» ˸¸µ”—´óÙdÚ©–®ûd¾ås·@î5B%¥ òT"¶­’ žgç@µ9_3»~gÚ3¸ñãxÀ:uðÏÅëšK-gÃÏcÙ0;Ï×kKƒ¾!Ë ÏUwBꪣ.H:OÓùü‚Ådx%maÝ-ni¥i›ÎäÂÏ'saú›o¤*ôî×r·F±),…ë-–?—ZP^xwDÚ”‡†lJãªíµÆU¶µ‡ÏÚÖŽ5\üj¬¡põÀîÑžT÷h‡åO;,4úoðÂé/8öwÞvìg§ô´ŸÔxÚǯ\ûÛøJI#˜¸üZH÷hÏwZã–CÖ8¥§¿é<;e.<›É…ÕRõ µ4üôûÇá§#Îýiä‘sæ„Ì9#†ºi¯Æ´á´ÆTš®¨6e[ŸMI)ÕÒ§ÕÒ\87“ /~wçÌñÿÏ9Óa9<Ôa¡òjLOkL…×r—‡t¨õhoi=”'u¶–¦ê$Òy¶Þ×yÆß?ÉwfùüŽÖÁÝ;Zϯµp‡JšŸ”½í†ÉæUï¯i^E]Z¥Y ÷¡»«"ªT‘à•‚WÆ6~6¶‰|l˜}¾Ð†=mzO[¤ñÖo#$•§íä&O[ûÚ¶/Ú×vXþä›_×Ý£G§òÒ.^Ëôq¢uhß[‡º‡?v·˜?ØÐb~½¶뾿+Ö͵ÍFçÙzOçI§$‚…2hLšóIK¾VXwKD­’´Mg¤Æ•R#{Ä´HÅýZîÖ(Äw \Vžb½ÅäáRËÊ ï©Ù¡ñJc ¾sc jéÆ3j){:­f§æ¼f§*¢üÅØÉ´óy,íŒuÞÙë¤3Ô™B¯»æÁÝ¿7¶îÚÚ:H+.þká´;¿¿~oWüºÌ(­“éEW³sË5ÍÎÄõÄüÚüµ4%ðÕê‡åš*H« R·#•:eH}2Œ_ùöoãWØ]$ÜuE)':cÛ&:Ù¥ËËÌÖWÍ^Ë]*c²‰9–l*× ’´~Øò^Úç½@ƒNÿÇà…Ó–k ¦be\ÜZ„Px/’FÞìW¿ Øù[ ×)f«yýÿÔ?ß‹ m˜Vw¥1n)Ó«)ƒÔX+—Á©ƒ‰ Æ´é›ùãìº.VË$•ZZwB-¥Ù®Ã×eKy $Ì×X¡lì!¦_<82ýbñº[ÜÒ„h»°î¸Gª…¼žûµ\­Q¸ï,n«…é…éó—¹q¯e傦f×–v1u=¨ãuuÜ<¸û’yP7°õ±n 0åø•Ưä_ö$‰DÒ)Ù,éœ'Ê£sy±D×G,~ÝåË~ÝØïðØPÀ~ùRÀ¾ø¯åP…X°Ð«òË‘M’͒Αº¯3Rçõ1y}#’ÑÏFx몒p‘‡Ê(yQ+—”mý5“ùƒ&³s 'å )–¹µ¹³¹µì.È¢f-ºµ¼‚6ð±uÛwÙº%É‘JÔÉ/mUj”ÖI’ÉRúwìÿø†c?Ó5ný­®Qòtö±ä©J²^¢’иyù³êzñZÖz¶ÞÓz‚Æïë‚FCÝ6©¡®lIëÙ|M뙘Ž%'¦iü#ûWÚ0JS¿é}M½äºä; Å-Mˆ¶Å‰Tân3%6âè@¥á=5»pÕ¶D0q0T¸V›ó«°´„¯áüI_û|ážÑ´2­ýçª;ñW]"xW~Êäâ¿b˜Ð?4LW¿¼Üw¬áò屚ðûzÕmS~ÔgS& ÉѤ½Šw]Q)Ø¥£ñƒ4Ùpñ»“f‚‚?Oy¾vg¡k¹Ë#Ô]e˜ØöÜ0áØÿñÿrì7îÞaär-_kÒRK×uÎ_#’»r¯áü¼ºëGù‘‰#©ó'GRr—üßå.ú›žF=sɹ¿íä¦þ6Z ’&,Wƒ-Ù”‡‡lJZÊÎÖíï°Ø}Káµ…þE5ÅÝÒ„hûe‡lÅ©¤5Vƒõr©eå…wGd~‹ýÃü¦´Üà…¦Áy{Ó^´r~e=ýCÃdû)Cÿ¼®ŠŽýGþWÇ~JÓ¼êƒÿ»yíŒÌå×BÛ D"I >àÍ#""B#"EÄ‘ÑAG$@tÐ tDD§–ö¬"âQ“lJŽ$› €xÔÌÍÍÍÍÍAñ¨¥ÿ´zÍ;Z½P \ø;ßû;b]“Ûb]µìŽ«?P@…ó°k¹$¼yø4Ïù4•¹W-Ô ÀÛŒÉüÁF“Y"™MK$¹0ý›Í¼ú}6#‘dó™løç3éü_¹ðl&f§ŒußÛë.¼Ë¯ h€Ø # :UÑIûæÈšejYórÌ¿:txws¬«¦¦¦¦¦†=8öuå/Džj«/±uûfà°Ú/:¬Tkå­;èþû€7ƒªèˆÔö7ÞÒögCY&ZŽùWž–VÓÆ–V·ú ¥[ýæ%ßúJŒOHŒëú·Þ×õ—W’@ÇåËÓž]¿3í¡3 ÷³Âmˆm{nˆ¡SƒHé¤ô^ßY‹×7Ñ{o¢óMò5ðöø;€Å©_¡þ¼~…05{™A£{"ºèºˆ®køÈ®aè$~Ë…cÝw·ÄºËÕ9˜éÍÜÌôZ§µN9§gÓt>Ù”M6¹êŽg]uÐüKž\MèoMˆӚè,/°8ªÛë»T·éo!Ý‘KtDÒX''k~G+kV¸ÛîvU[_»*Ê1¹ưôÛNéûmª¨ªM¥ wªèúNUt$ùuÏH’’ò¤4\¦Î±'ÙÑhµz™úD½Œrhõ~øa«WHþ|å'h„N½lã™z™Øïœ9!sÎtwF»‡¥Í+µÒ&3zÇÎZ¼c4vŽŽ«ß:ÊU¿nõ—·:¯Ÿw´²fkâàQkBxz¾õE) “Ûþa˜ü9]>!“=“†‡IC.œ›É…už-×t:/m®•K›ŠkŒ ‰¤VQj=²-9?©ù­¬™Æy¥ô©Ñ”¾\öɲ‡f…±¶YA–@ù7+Þ_Ó¬`²?a² é_ÿp!ý³SæBÏc¹ùˆOsñœOÃþµ¥õ[[ZIÂäO¦ô$-[3Ý#GÝ#…Å7žP)È;òúYØž…Ô/_àïåZàí´nñŠ¦Ï¿£•5Ö#Ù•úàÍCu[eËwA²©_±qw䑦=»ß7í‘»Vï–»Ò=éæÅƒ#Ì‹x0q0ìí¼Ý=ÊNO/ºt>`¿|)`§ w‰ë±÷×uí­|‡‘ =‹eC‘Æ[¿4ò}¬áò屆‰Î;›óSAÓGãù‘k¥åÏW~‚Fè0¹?frâÐIŒßß•gnΆ3–#7:,ÅRfœ™›gº÷q ÝÛa94Ôaé=:5¿¦J«_‚~e^0ǘɦŸ’MLîÁÇL®Ø]¸§ç[_T;ìôÙг‰lˆÎ ™ ¬–n8­–’fFR£=#©—ušÍäÊ<éXQ}¤ŠPÙ5¦§5¦®ÑÎÛ]£å²Oîdó™lØU×§tÕ¥{Ó7Ó½éžt8Ý£Œ(?RFZ‡öý±uˆ»þÙ)©ÓÜo¿|ÉoïØÿñÿêØÏdgŽ3YïØ™¼cIÃOIÃàØéÿ"¿uÊrØ:¥Œ¬Þ­Œä‰ë÷v%®Gt·Þ‰è„Ç!ËäfŽ39æsœyA^CWÌ_¸×oiÀß…ûûÛl?\ é󪈲M nü Ì/ûůÆ,ñ}‡-qè€7‰b]lxwGÎÍÍÍÍÍ™wÿÞ<È>“lJŽ$›èÌô æØô‹9~{à;¿^hÙçóWÕÊ%’áG£Ÿ ?Êþðl"ûÃÜ¢LtÞù·‰ÎüÝÿù”[ÊøõÄþøõ9pÏ¿4ù¹ãihò´)#ë>QF¨s§kø“H×p²é§þdÝ«køÓx×páµæÁ½{̓½ÓŸ%{§/cºç±?ÝCç#ÑÍ¿´/TR®õËÎ_Œô¥ÕWi鹿~ogüºÖÓøÿhó#"Ò:©‘ü…j­´œÙ2S]Ðùñ+Á¿_‘»äÿ¾fĶÏbä»~jåó­¨4ý^8ýƒ4¦ÍßjLd…Â7.ö\˜÷xB>E)iLö¯¡§ßýOèi1ûç^¿¥Ùü]xú·Í~JÃUwâ7®:zÑ™ìÙéì¹?‘¡ª±M¾¿Œm¢Ô~N6=ö'›¨=œ?þÔŸl¢{þøÀ‘?R›<¼·3~òdß…ZãEGD& ©¯ó뾩eë>QÏ›r¥–®ÿD-Í8Ÿ\Í8Ùç•Qe›2ê·_ºä·ûΟô5(úTmо†Íù†– ÿƃ ¿\ý²b¬F'¶üICr4i`^$0/××UU›*b˜ÜþkäzÅÆ3êjéúNµ”}Mýn<º‡&º—XRî–o—»ógµr©1ÿ˫њ¥ÕoeÒWš–Í×4-#¾úÓÈ#:C]r4‚Æ<´÷CóP9¬nõneôå׆ȚݪHÆ™ùß iFlû ú¯Ý ú 1ýCCŒ=uÑ¸êƒÆUÉl¦Zµ)?ê³)i\’Q¾½Ö(WËêN¨MêäbÏBâ ;Ãä¶ç†Éü´âw´²æ–=æ÷[öÐÈh!õ[ðwá¼ÍöÞؾøôvK|ß!K<¸v' iÎÇÕïiÓ7“¦eÓùRŸÈo³þxÛ(Ú©Š(?REèo&ûðÔüµá˜ÜO§˜ (¼ÖìݽÃì ¥Ã³¡t6”gCÖ¸å5N¯ª_)âÉï±Ôxl4M•ººF>MtLg™Î&õÉѤ¾ÃzäFǼ•ò\õ'd®úËŸ|v§ƒ„Ô¯ØéùSúZ|¡)нÓÇr½ÓQÝíõQðø8ô^hò^X(m)öÉšMk˜Z§þÙ:E9SÙMæ][Mf!e¤]wi»Ò›´Yª–6ëcMõ1ƒÙ:´{Gë" ¤ O®¦ Š>…QѧÐÞÒ ´˜MZ~–¿ôñt~»ïœß.3JëdFZHág‹}n˜L§$‚ÂêW\àï°áP·cT÷×w¢:ýDÓOú ªá9Cÿ¼ ÔЂ‘­^óŽVoÀqõ‡€ƒÎ@5¯Ö°s˵†´³-f*O¬ëîæX—n`ëÿÑ ÐV Â'‡Š‘'ô_ŒpúûÇá4M<§i˜ËÑfìçíú@l|š‹ç|1r¶$ö¶$èo¢T uW'4B-zvBü—.°8Úþwïkûçúç$sýÐF5CÉikI0ÝC_~è2Gví6G %ûþ…hLšóS~ñ7úGÔÊ_¥Zà×_|¶—kå2c8ske8Sx—_AÑ€7ZéÒ¶öÐYÛZšJISƒå.ùv¹Ë{ah&TØôx}`j6o)45[Œ‘…S³1" :興:"¢ƒŽH¿`6-‘ÈšejY3kjjjjjè<äuÝÝëO'|ó"­ÒBZ‚Ý¿,w{€-ÅrÏÕeÀaµ_tXÙUÍñáíí±×Ð@<–èˆlWµõµ«êeêõ2r …{Yá¦ó™ÞÌÍL/;=;ÐÌ:¿VÔÔÐ>˜…ŽZ˜¾{äh¢{¤˜csIODµ·×Eµ†˜þ¡!–OÿŽVÖÜÒú‡­-­Lvæ8“¢>'s<çdØúihÑœoh §oΆÑXª:(ÄbÛžçíAáVlW¸é “ýñˆ0{xÛÈ…žÇr!kÂrØš Ï¢øàdzRN¦òù‹-O1ZZMÝê/”nõr¬Ç…ä¯UH$ÙP–Ɇ"·~i\ne*§ü˽~GÛßxKÛOºâ’>1>u 1®ëßz_×}V«ÿVΪMþ·Ã¿–{|ÕBJÿp ¥÷úÎZ¼¾‰ÎØ{‹ÛjåãÃÛOÐ{³ëwqÐ[î”WŸÂëwD‡Å–»Vƕ׎Ž+5-›M ½êÛ̇ÏÚÌ­óñVCÈž ¹)}1çiõ~øa«WY½[)ü5z6‘ î³S .éINãªkŒ«œæžwæs+ar¡ÜL.d[k¿h[Û:´{GëÐDWL2ÑUšúdÆ_ËeÆHã­¾H£2´ŽQ†¨ËÃ:e9lJê“£I=ܲÈ…rÌÏö0xt«s0º9yiEÔa-‰Ô¶I"Ðwû;£Žý©\j4•K_IÞI_É8373NƒkÛ9ƒK=­N©§mªCC6Ueò[žBèID]Ñùí—üöåUƒË]~è§òäÂÏc¹plàî–Ø€¤kö©¤‹û³ú„}ÂÄó/ø’4<¹š4HnK$’Ûš– §5-Ë·,ˆ‡o6ÐO!h½Ùöù6´–é±Ôxlš–Í×ò'ióJ­´Ùa±û–pæÖ;áÌâ9¤ô©Ñ”>à¸ú}ÀaS²)+S0&7sœÉåÂÏ'sá®á#7º†©òH~›ò£>›2Ö}ÿ±n!wéeŽåzet]§2Jg Ûž&2Î籌nY=0¹?frç“«g‡åO¾ Û™õ±¦‡ú˜ZVwB-ƒ®¸1›–HÆÎ9Öàª;!uÕ‘g‘/tX>¾ÑañúÎÙ½¾Â+é O½lã™zYùò/]!8gNÈœ3ÝÃÑîaº#/65ƒË”~Û)}¿MUµ©¢4nW]ß©ŠŽ$¿îI²S²s t\¾è`ΦÏ?¥É_4¶‚¾æG¤*¶çGÐÓÇvúLï“@¦—äd§/6ÂòoVk›”’JÚ¬xM³BŒÍ\ôã;kñŽÑØ[::®~è®­þRãVçíá­¬Ùš8xÔšžž~å>UŠR&·ýÃ0ùsºù³„ë“»ýÓçFÒ^Þ+/wÉOzG+k.̇ꗮ­Œs‰Ÿ|Ÿ_¥ÙßøÏתҞw\ì¹4ýçíMÿp!{[(=?{¦·?².v$§òŠ1‘í1!ñí1´Ç„Ø?Úc‹ë“¯<|ë·´çi5Pâ‘áÌÍÙpF?ñî=ýÄâ)GR_ÙGRZOã-­‡†¦QE×w©¢¤²|•<åŠKæ’^Ó²éM‹ÖÓøÿh=4é€\šRޤ¾îIÙ”>-_Ç(MTï=:Õ=êiëSzÚª¹âß6ÔÒºj©Ü%ÿw¹«uÈr¸u(è¿ñ è/\^p–5È…s3¹°2¢üHiõšwäÃ4ù{"xW"Xx-}á¡®ábZ¾ù ‘§4ã÷w%Æ)vXŽÜè°Ï“FÝ£·»GöË—vcž¸{/q]çÑÞÒyŠ];ÖpùòXÃDçÍù©UÎé£qçt%å7íÙý¾i£O÷<¤{˜Ž0/âÁÄÁxÊÅNß:dùcëýîIަ{Ò½é^£|Ûs£¼0ÿlx6“ »êú”®ºtoúfº7Ý“§{^ÖøÐ¾Ÿs«dýÒ¨[’¼Ãrh¨ÃBOáú!èWæsŒy‘lúi ÙÄä|ÌäŠÝ…{úlèYŒÏT©Â©U4;Î/>™ˆ‹>ùÚ¿uêàQë}td^0Ç™¤Uª‘búäâ/ÔVQE”mªH0pãÇ``þµ¿k°Ä÷¶Ä+#ûÏòñ<ÇäÂ\ìþ%žqÊ¿"ñ“»=ðÿ|í¡Úà[ÞÒì™»þ··…Òó³gš¦Œ¬Þ­Œ¥%®ßÛ•¸ÑÝz'¢+LŸïˆYú($žpí1´ÇÞÔçÚc•oñ•‡oý–ö<­ ææææææÌƒ»odŸ)FèéwÿzJ®¿žØ¿¾xzedÝ'ÊÈð£s~Ä>O‹C²é§þd“~â½gú K|ß!K\HzbúslúÉÀ.µ~¢é'ýDö‡ìtö‡¹2Ayv éžU Ù%~àSKœ–y{xï™~‚‹=‚Ö"í‘—©¥N«¥ù_ïü[þ×Êä/¶<…˜÷î5öN–ì^H~öÿùt©óù˜–I6I$µr‰døÑègò?<›(£Ø¹ñµÞÅåçR–…$¥ö¯~{à;¿ž ¥à˜Ÿž/ùGu­|¡úå"¿úM÷<ö§{ò’Dÿ5ßh¢vþb¤¢1ôÉ×þIç$ù>ûWv+Eˆ¿¸êNüÆUG’Ój3HÒ:©‘Ceä)Í>Ű¾öÿÏ¿JóÇÅã'ßç—°úZ:þ ··× ßò ±g¾úÃÞ¸È/Äb…Ä´ÇÐC{ í±J¶ÇJ“§Tê¿ÄØ&ß_Æ6‘´÷vNtƯßÛ¿ž?&ö¿:>pįÓ}óGæØü#õ×QžóK{o¢“LjHAF}®Á+×þ¼¢iÙt¾øz"Aÿµ;A?õõZã>µÎë«–»åÛånv4‰ÒUw<몣©ÜBÒÓH«æU;Ö4¯¢‰äT…Ô¡©–n<­–¶}øa9¾ØÐTÓ¨îöú¨Ž¦…Vußó[ ÙϘ曓cZÁ“œDáRlW¸Z‡ö~X¾/xo6r×ÊF¹‹þV¸äÛ®éìƒ#Ó/'b¤Ï&ÓNz¹Û?[Ÿ†ÉmÏ “ìñ2-{Ìï·ì¡‘×Bü…>p×î4—‚ZÓ¦o4&vk¤2ò”fŸbÛû‡U•‰Ÿüë‹ß’8|í/…›a OÏ·¼BìYlýp‹üåºÚcÂíí1îþ…öÚc|õ)\>þ¾ü–˜ãÔI³å­Sÿl ?½ñ÷ðSZSoñ«úÛϘúÛmÊGmJi³T-­èVô‰ñ?NŒÓôOö‘¤¨k²pˆ¯´žwïi=Â×õ•„œÖ9}4áœNïÿ¡|Swß½Q×^á”g:£1m¾¦1U&±åaãª?!sÕÓJ£ìFÏ|^N˜ºDÏßìݽÃì ¥Ã³¡t6”gCÖ¸å5N*%ÿÂeÉ…f3 -š¡Š(?ÊoDÆdžš¿6“ûé“£/~ ¥Ÿ9¾ÔZB´Ú=°išt@“YƯ|{güJ>máëÖÒò ÓÏÒðÕϼ_ENÏ~KeóÕ'ûgë3ÙÄK6‘%Ì? ʪ–m8£–QÜ8®Ý 8h5n9<ÿÃjeä)MŸâÛƒØñþ%4>óŸ¥?¿ø××Òñ¿’°'¾qñY.éù–Wˆ=W\ä/¼ª°K·Ø‘’¢~táJ¤žø‰®;›KÝ}ˆ Ù$-»KѼenfz}çìƒ>êJ†®¸Q«Hh¤3-ÐKžE«Šô·èûÛ;,‡‡Z)ƒVÓ(\ZXXþ¥ËÃ׊èH×Ec‚iÃi‰&5Dµw·Dµt~¡±Û¯ ˤ/ù¥‹é!T+—H¤F©Z؈Nîò+K±7ôí”<È9s<çœ!ùÉ¿<í'5žvk|ïÞ|sÒå;VåÝ£=ÿÝ=š_çw6}ÏÎ?ÎÍdÃôVz%ÍÆÜõŸKÝõBä¢.ðÕ›bé‹­qÌ7=_T‘Õ»ó¶m ×'wû—»W›ån“y×»&sÇþÎÛûÙ«ý’×ÓTáå¥f÷ oÈ2è#û±Æ÷úå JÈSš}ŠmbËÿŸùÆÏÒž_|ë‹{ü_îð-¯{®žòÒ’GΙžÔ/åÐ{Ú°Ò‚.ÝbG¾ñí1´Çð¼@{¬¼òp×§y¸Ôïrž.ÑéØoÿ/Ç~š^­Øz_7ÀeíNKN^lƒš´óùdÚIS§ixªê¶úsÕm¹kµYîy4Ú3òHHz™8~åÛ¿_ñ;?ø´ß -frO1¹ñ+W¿{õݦtò;: ÝÓˆ‡Ì¸R+3ÒR²š[®kvR}©W¨O¨WРèà•«ß¯@Wܼ0 ¼@‹‘“givjÿªÙIËÛT‡†lªÂ«h1u&7óŸÅ7«)-ÿÒäáuqÒØôh)–’âmZeÚ³ëw¦=†Ø¶ç†ØRw˜Íä¿°)úÖ˜}d¥~Ç¥Ë~-]ù Ë2¶iô³±M¶µ‡ÏÚÖ¾ÜÍ­ D~ûåK~{Êú:e ùÉ¿h) OÛÉMó·ðòÛ}ñÛɨ¾h—CòSvJñêihò´ÑØ|’Á¸jÇã*“y×Öù¢J“¿4ýp‡¯~gË5G½Bý¹z…êöúNÕí“æ›-/$}i».Ò¢(½ÓDz½ÓdÛ´£"…铟ýûí¾s~»Ì(­“Õ+6žQ¯ø¹DÏ “‰àÔrŒp§fnT÷×w¢:Z š4°PýŠ+Oiö)¶=ˆ-?ü«˜qo|ãg©Ï/¾õÅ5þ¿ð-oiö,|í™"vÊðäjÊ èS}ºí-Ý@‹Ù´¡åg{ã;þ·”x‚öÚcx^ =özÛc¥Éý~—ï󴆌¤fŽ«?t¦š…€JBc±vn¹Ö°“vÖ£oPõ  OèöàB8ýýãpš&öÒ´D¾9 ¾Ù@?Ð'ôùzñi.žói4&Íùüøe©‘þµòWiøõŸ—dÆZ¹ÌÎÜZÎXû[tž†ñ¡#@ ©Lnæ8“£}hB"mJ3WÆ4¾scè ª‡JvDþê Ö#€ŠA+ ÚÖ:k[›_Pk}§ê¶Ü%ß.wy/ íó^€–àm¦* ZI0>~O—H$» óÁˆH€è # :興NÙ:"c]w7Ǻjjjjjj$’Ùt¹囿yhY³L-k~³«_ìZ«$«ý¢ÃJµö6Ô¨nfÓ Û—›—‰+?žˆü €jb¹·P_Ë©¾ÿ¡ÏÊêóíŠoâ÷œ¼]ú,±#²¥Õ´±¥Õ­þBéV¿yJÑö7ÞÒögCY&â’>1>u 1®ëßz_×/Fz°8)ýÔÞë;kñú&:cïMtr¯;P ,÷x²üµ ‰„ì0Òxë·‘ÆåV¦rÊçáñÿÍÖguøoéTþùÿz½ú`)–{{`1Ð~ƒþÅí«å Ï79¾½Þ.}òžàˆ.º.¢ë>r£k&“ ?å±î»[bÝ\z¬ù¦‹“4<¹š4Ðßš– §5-ÐÉra¹ÇÄCè‡/Bâ?ôYýöYÉç;ìáõꀷ´ß µöUõè.ðîˆtΜ9gº‡;£ÝÃÒæ•Zéƒ{½cg-Þ1…{Yá¦c ãê÷ŽÂ”4–¾?ÈšßÑÊšnÅv…»]ÕÖ׮ʅrLn>{·úK[­ŠªÚTQºÊš8xÔšžž~å>–R&·ýÃ0ùsº|…ƒŸù¦'ý4+ŒµÍ Ò ¥iV¼¿¦YÁd<Âd ¥ê·Ò÷Ûòå•©eͪèúNUt$ùuÏH’S-3ÇsNFׯ½¥ëÏô> dzË›1è^­Þ?lõ²í¡{äh¢{¤¸þõÒçBö–MéI{lÉ)ÿêüœ =åBäy{XØžÙCÇûm_júm‹ûc~¸þ;ZYs¡_Púz™úD½¬¼%*OŠ }ç2$ž»}²s t\¾œ/#]Ev(<r‡o<äë/¥Å1êÏ .ñ¿4}r·îñ„¯¿”OÄ“§4}ò•‡oýòõ_ø—þáî/o[ûäõÂ×+ß¾-Þ~+¥¾ø¶O–{ûMx}!þW¾}}–k4îþÎ÷}ïó…(­=ÆÝªíyQ=ðèˆLŒßß•gnΆ3–#7:,ÅRfœ™›gº÷q ÝÛa94Ôaé=:Õ=Z˜Ò´g÷û¦=r×êÝrWºçq Ýüxp„y&ƃݣ·ºŠ~e^0ǘɦŸ’MLîÁÇL®Ø]¸§Ï†žÅø …-:› =›È†è|áàgÞéó™lØU×§tÕ¥{Ó7Ó½éžt8Ý£Œ(?RFZ‡öý±u¨ÐIoûåK;噸{/q]çÑÞÒy/¹\0pãÇ` üôælø©Ü½Ú,w—+ÿÅi²ü\¢tOr4ÝCVd”o{n”óÕazë”å°uJY½[!M&®ßÛ•¸ÑÝz'¢«N/ÿÁ£Ö)&7sœÉ1/˜ãÌ òò¸bþ’ ç˜\xq¤áúªˆ²M¡Úgÿ:Öpñ«±K|ßaK|¡ÛÒG!ñ„o .Í>Ç._k˜è¼³9?µß9}4Ã7òöžñDx^^ðÕ'_û/-žpñ—Òâ‰xò”¦O¾òð­_¾þ ÿ*¯Á_¸ûËrlŸ,wøú#ßö­xí·ÒêKHûd9¶ß„¼ þ ÿЧxúä”EÞG¸<_ˆÒÚcÜí¡ÚžUÄÜÜÜÜÜœyp÷ï̓ì3…˜÷î5öN–ì.üu¢óοMtæ«ð±?ÝCç#ÑÍ1;}²)9’l¢óÓ/˜cÓ/Ø¿úíïüvRhaþb¤/V–¹¹>[±Ó’ µò…µZ+—H†~6ü(ûó‰ì\$é° vX”‘uŸ(#Å®â›?wæÛÃÇüú®O.ö&¤FĆ|Š$¤u0Ù¿†ž~÷?¡§Å쟋?®º¿qÕ‘§Ó™ìÙéìR£´NjŒ_Oì_/W‰¸Çv,^×BìŸoé—_ ûdׯáO„Ä+¹¯.*†ü|ãaiþÂ7žT¦~ñ¼(—>¹Û¿xÂÝ_¸Ç“ÊÈÃ]ŸÂåáãïüžwð¯Ê?/ÞfákÏ˽}"FûMX|àÛ·}Ë=þð­/!í“åÜ~ãW_ˆÿåú|]Tæ}„}ñkq~‰‡{«8uDºêOÈ\õ–?ù:,l¥ AQ~¤ŠÐßLöá©ùk0¹ŸN19êÁ-¼Vìôü©U”;=­B 8Z±‚†þÒàêñ+ßÞ¿RÌÜÍÞÝ;ÌÞP:<JgCép6d[Yã4 Øǯ|û·ñ+Þ Cû¼¬Sm_X§H†Â”¥åÏÇfŽ—{­:.öV®{±®s¾Î%=[þds,ÙD–0ÿ(t¨¼Z¶áŒZ¦1m¾¦1×î4‰Æ·¶.0é©° ^ìÈ?ž,ì#iç³ÉôÁT û_•%šÍäBÂã!_O¸Èç…xÏ ¾úäbÿÕO*#w} “géúò¼ƒ•׿à/嵟êiŸ”†í·bö)N{€kûVÌö¿úÖ>)ü¯ÎúBü#þCŸåÕ'áï勵ò¯¯ò÷?”KÿåŠ?ÕÆ‘´\(=BœÓGÂVaCߢµžwïi=Ιã9ç -¥™éÍÜÌôzÚOj<íÖøÞ½ 5/Š¥·)|jS OÏ߈WïÎAT{wKT+<}6œ›É†é›€Ü%ÿw¹‹Ì‘Ø]ÿ¹Ô]_̽éK~~iR2âZ¹D"5JÕ¯z뉴¹V.m¶$ö¶$Læ6˜Ì…7¥åO«o,¾”8ÙƒQ¾cµQÞ=ÚóßÝ£ô•±–ìüõï=ÓO8gzR¿´‡½§½:]” •:Mæ]ïšÌû;owì'Éóõòp ¥§åº…ß‹^Ã}C–A­ïcï;´'6Á‹ùÆiÃi‰ìŠí#ôE½ØUBìŸ ¥ÅCvY ×K*-òõ—Òâ wùñ¼ãyÁWŸÜí¿ÚâIeäá®O!òp©ßÒžwð¯òúü… \ÚoÕÙ>©NÄkðmߊ×~ã[_BÚ'bÄÿê¬/ÄÿòÆè³¼úäî/|ý½´÷A¾õ%^ÿ.ÏS±ãOµ±DG$í!E p²7-)~ûåK~{Êú:ePô­1+úÔ+Ô'Ô+ÔÒ§ÕROÛÉMž¶Â«tž-×tõ õçêªÛë;U·LšoL´è©ô¥í¥Œ®ëTF{§e{§M{výδ‡v°¢ciéix°§m ÉÓf:øgëÝݸjÇã*“y×V“y!Îfò_xHŸt•ßqé²ßA˱s©—‘GCûF19æ8“s«¿PºÕBò§Åb™ÜÌ2¹Å¿gúí¾¿øí”†&IÑ.TŦŠó…$Lž\M} £¢O7 ½¥h1›6´ü¬O¾ß*‡ßî;ç·ËŒÒ:™Q½bãõŠŸ-ö¹a2œ: ¿ 5£º¿¾Õé'š~ÒOÅ Ï™{<¡ëïà_ånÁ_–†WûmY·O*ƒxí±Û·¥Å.õ%¤}"¶üÕS_ˆÿ¯»}}.Ý¿ÁÅ_øú{©ïƒ|ëKÜþ¾ÏS±ãOõPC F¶zÍ;Z½ÇÕ:CÃSvn¹Ö°“vÞ¡>×ê,B§¿NÓ@q”—åO¡èú„ü€å…ðö-âçë­/Äÿ·Ù¨<>ÍÅs>Ƥ9Ÿ)5Ò?¢Vþ*í¿þâs—ÌX+—Ù[+ÚwKçc]“Ûb]E;"Q à̓~3¹™ãLNkz¨ÑÐåÖ¡?lRFVïVFÆ4¾scè T?hߢ¾@8•ìˆüÕ¬G~­La[{è¬m-íÏECÙå.ùv¹‹6ê–Àrí[Ô,/j¡ðö@+SÄÇïIâã‰d4–3hߢ¾`y‘ÑAG$@tÐ tD.íã#k–©eÍ¥æpws¬«¦¦¦¦¦F"™M/”Æaµ_tXé.‹ß‹›<³i‰„Ûâwåfy럋ÅV2!ò÷_èS|}¾]ñJl{&[%žw@ #r´ý·´ýÙP–ɆÄÈ?¥8Ò{}g-^ßDg콉ÎÅïÅMžZ…DBi"·~i¬f ·´š6¶´ºÕ_(Ýêåh! Éý/WÿMŒOHŒëú·Þ×õCŸ•Òçrò—7±ŸwÀ‘¯¤áÉÕ¤þÖ´l8­iy{ÊNcg"ºèºˆ®køÈ®aÈù_/¹ðóX.ë¾»%ÖÍ´ ôYN}x³Y¢#2¥O¦ôÍŠ÷×4+hê–*º¾Sí9šè©æ©XìÉbùIÐïheÍ4N‡ÊUx¥á>UÆ6²õS/SŸ¨—ùßÞõ;Ê_¦–5&õ “?ßQW|j6_yø’ =åBíª¶¾v•­خpÓ­‰ƒG­‰\(ÇäÊÐAº]HÿÆÚfE^~™ZÖL5Âd<Âd‹YE ãòå|žtU«÷Ã[½¥É_$?§£²S)¨F õ ܹÈï;kñŽ)ÜkÌ 7IÿÂå'Üê/5nµ*ªjSE¹Ø÷ô|ý%ïÛþ±?r™¬ }–WŸ\ü…‹¿›,Ìå|¿íKM¿K}ezŸ2½7ØõEþX¬Üía¹?ï %:"­S–ÃÖ)edõne$Ý“§{×ïíJ\èn½Ñ-—Bª"ªT‘lèY,Ò˜6žÖ˜ºF;ow¦¤4ܧ š‡ö6©¥ë>QK³¡gÙÐDçÍÁÀƒ…òÿåTDºªØ´8¾òðÅ:uð¨uŠÉÍgrÌ æ8ó"Ýó8îÉ8373ÎîÑÎÛÝó´”q]úXx¯Äøý]‰ñpææl8Óa9r£ÃÂþ•¦ª"Ê6U¤P{c ¿k°Ä÷¶Äçé'<›É†]u}JW]º7}3ÝKVªŒ(?RFZ‡öý±u¨XÙÇ._k ú"ý;§ÆÓÅÒ/.i˜öì~ß´GîZ½[î"Í3/a^ă‰ƒñ`¡þ…ø#wù©öÓ½éÞË¡¡K÷èÑ©îQáòô+ó‚9ƼH6ý4lbr>frÅîÂ==_YÜŸ¬ }–WŸœòàïÜÉ…sL.Ì¥¾Z‡,?ß1Ý“M÷ÐUFù¶çF¹p{XîÏ;X€¹¹¹¹¹9óàîß›Ùg’MÉ‘d™~Á›~1ÇÂo|ç·çÓÿóé\Õ1Ñyçß&:IB* ¿üûø¹Kþïr—k‹•Nˆ~¸ä/vútÏcº‡ÒÐ:•ì_CO¿ûŸÐSê)W˜÷î5öN–ì.–ÆUwâ7®:JIg²?d§³?HÒ:©1~=±?~˽ò¯Öµò¼=j†{nÜå/¯ý°õ/Ü—Ÿ-3ÙF^“ÑÍwR‘Ÿ¿é+é_Ðgåã_/–'—óüëëc¾>…ÛÛô¼T?c›|ÛD½C÷vNtƯßÛ¿ž?&ö¿:>pįÓ{PþÈ›L6ýÔŸl¢<Ùw¡ü‹ŽˆLR_ç×1TËÖ}¢ž7%V-]ÿ‰ZZ®ÎPöÄ=.Ó÷ø¦WFWïVFéoUdÍnU$ãÌüïŒSˆÌ•Ô°å7Ln{n˜dglÙc~¿e­õ&ü^´yE0pãA0Ð=|4Ñ]t=K|ß!K<¸v' iãÇÕïiÓ7“¦eÓùùëiý×îý†˜þ¡!ÆžZn\õÁFã*‰d6S\*î«sr—¿¼ö“q>¹š·R!öÆW~¹[¾]¥ÆZ¹Ô˜ÿåÕ´M¾òÏûUäôb}¾.„ø;wø×W݉ùúž¿ð¼T3E;"UåGªýÍdžš¿Ö“ûé“+—ì‰{\¦ïñMŸÒ?¹š_!+ix|5i "Bd®¤~øS«Èÿ• ÍfZ'Ž-²‰9–l¢izó¿Ômap±#û*Wý ™«¾Ãò'_‡…ý^ˆZ¶áŒZ¦1m¾¦1×î4)Û·¶Æç×ij4¥§SZ¡¦:’äãW¾½3~%ŸVèë=wùKÓ1û¡jÂí¿üå±¶üó~9½Ç O¡þÂßß–!í|6™.Cgëüúš9>_Ÿ¯—·ïyXNíˆTF•mʨ~â½gú çLOÊ9C[dz373½žö½§}¹r$õ•}$E5œÿr¬Á(ß±¦ø^\`ëÇ]Bê®§`Ú¾ÀUß§rÕ¿®òjLNkL4Q±Øê]r÷j³Üm2ïz×dîØßy»c?Õ,ýJ›Ðv.ì« »€‹)=mA]ŠÎ飉â+0²±Æ-‡¬ñAßeÐGò[ãûY±:dn&¦1Pù×ìZE¾ÃÂ]ÿ¹Ô]ý—&?ý“ýh=ïÞÓzœ3Çs¿ô¯“O»5¾wo¾Ô¥ùciòs·îò³)–Þ¦<ð©M)<=_T‘Õ»ó,QíÝ-Qmyíúî/|ý'[a]®ú2Êw¬6Ê»G{þ»{”FpÓS è¿ñ è/—mÐj¤…[uáyXŽ,±YMÀ~ùRÀž2<¹š2(úFEŸn@{K7Ðb6mh1çSñÿRiÒÎg±´“&ñ%‚>N½š¼ SòÝõ5`¿x.`grO19J©Ù©ý«f§Q¾ý_„½ø•&A»÷Žmýll“míá³¶µ/ó‰m{nˆ±Súí¾s~»Ì(­“Õ+6žQ¯øùŽÏ “‰àÔDPˆü´§0mÈ@]Ÿ\®¢nǨî¯ïDuú‰¦ŸôÊèºÎüdC‚¦CzÚšõ õ õ µtãiµÔÓvr“§Mˆ?–&?wøÊOè<[®é<êêÏÕ+T·×wªn7˜4ß4˜h!éKó²®ÞécÙÞiÓž]¿3í¡¥é(Ü Ïbúäî/|ýòô´õ)=m$C¡÷•£¾|ñÛ©KNѧjSôÑ.Ø´…Q¹îB›ç0¹™ÿdr\Æw/ßçàm †Œlõšw´zŽ«?tfñËÂéï‡Ó4QŽ&ÇU[Áb]w7Ǻt[ÿn€–ϯþÓ7 𮨰s˵†´ó/©übPèË]ÿ°¸ƒç@>ÍÅs>Ƥ9ŸŸ[&5Ò?¢Vþ*í¿þâíCf¬•ËŒáÌ­•áŒ%±ï°%Açc]“Ûb]µ‹‹BߘÜÌq&§5=ÔÇh*Ÿ{èËÝCæÈ®Ýæ* B#˜²¡g'ª¯“zùÊÏÝ—»þaÀ›ÇS³ie.ÛÚCgmkiªMå“»äÛå.ï…¡} MøˆüË—%FDÒ8 øø=I|\"‘ìZ>Óö¿{_Û?×?'™ëG5ƒ7ƒåëñÀó°\øTtDD‘ÑAG$¼áĺînŽuÕÔÔÔÔÔH$³é׿yb]“Ûb]²f™ZÖüfh€åÆlZ"!¤ãróqåG¼@<à_Õ¬½rÝñíiwUgI«Uª7áyä°Ú/:¬ìˆ°ò.ïöØ‘íª¶¾vU½L}¢^FÅS¸×˜n:ŸéÍÜÌô²Ó³1_)¿VÔÔÐ>¿…&^˜¾{äh¢{¤˜KpIÏ®BCLÿÐcË_,=_œÌñœ“aë§¡Es¾¡%œ¾9ÆëjÕ‘·‡mÏ_Ùƒb»ÂMg˜ìG˜,´Ä\èy,²&,‡­ ònò/'Ó“r2•Ï_ly¸ÃdgŽ3Y’!¥O¦ô°–r¡ío¼¥íφ²L6Ä%}b|ê@b\׿õ¾¹¼ªMÿ•—§¥Õ´±¥Õ­þBéV/Ç\HþZ…DB>i¼õÛHãr+S9å_îõ»8•·o¶>«ÃËY_¯W~øo|ý…/bûWJÿp ¥÷úÎZ¼¾‰ÎØ{‹—…[y—w{l‰ŽH¹kõn¹küʵ;ãW¨É&æX²)ÎÍdíCæ­Cìô”¦ðhܽÇ%œ¹õN8³x4(à¸ú}ÀaSZ¨#R ¨W;exx*eèîŒv¿|€QÃrxÈakøæäXƒ»ô2Çr½Œ2º®S¥3†‰mÏ çóXÆ óª˜Ü3¹ŒóÉÕŒ³Ãò'_‡…Ýí¨5=ÔÇÈ6 +n̦%’±†ó_Ž5¸êNH]uÈ:,ßè°x}çì^_1߬—m Ì?þºð޵xÇh¬(W¿t¦¤ow4!?ÂT±=?"ž:÷ ¯r«¿Ô¸Õª¨ªM¥«¬‰ƒG­ áééWîS(¥arÛ? “?ç ›?š¾°¼ÍŠ÷×4+èWíîw|{×ï¨~ŸdÏt\¾è`Öoõ~øa«—žFSmRÍr©/ú€—¯/™Z֬ЮïTEG’_÷Ìïè/UÿÆÚfE^™ZÖL5R8boyùÊ#çÌ ™s†Z ‘ %gÛ0—ÉPÜõÏW?Üå/ ¾ñ„b&ÉÉN_lF _û¯~oKó/.úänÿ|ãwÉO—{G+k.̇ꗮ­Œ<¥é“{}±%iiýÃÖ–Öü\´Îh÷{ÎÕ;}~â;ZY33â>GþUÍí¾ñ™o}µ æxÎÉèúµ·týÕÓ®®¼~øÆ“Òäá¢ÿÒü¯?r÷¶<ý¶/5ý6.ú»}˜Ï_ÿp¡üJÏ/>,_J\#2œ¹9Îè'Þ½§ŸX<åHê+ûHJëi¼¥õÐÓÂ4ªèú.U”L0ïBÏc¹¢ÃPù¦/F"8u0,_ÐÉÜÌôvêõ´õ)=mo¢Á,WÔÒºj©Ü%ÿw¹«uÈr¸u(è¿ñ è/\^p¦ç¹™\XQ~¤Œ´zÍ;òÍbò÷Dðþ®…ü‹¾8Q×p±ÀÊ7!òˆhu² gÔ2óà®­æAWýI«¾ê.ãÌÜÌ8Ó½éÞË¡¡ E­Â”¦=»ß7í¡qñéžÇtóâÁæE<˜8vvÞ^è*ú•yÁc^$›~H61¹3¹bwáž>zã3õ pªBáhzvzóÐ¾Ãæ!µtÝ'j)¥¤ôÁÀƒåå¡c —/5üTRçôѸsšÆ:uð¨uŠÉÍgrÌ æ8ó‚j™,¤°~©áHçöË—vÊ™Æë<Ú[:ýgó™lØU×§tÕÑXõtO:œîyéÑCûþ8ßòò•'ß\úX(Obüþ®Ä8µ”:,GntX„×)_ýóÕØòó'­C–ŸkœF¸SÔ2Ê·=7ÊðwöÃîúA¼-æ_|õÉ×þùÆ7îþBï2ªˆ²M)|:ÐŒ+K|ßaK¼2ò”¦ÏÒê‹>ô^Ú7x¡¿ý”¡¿Ý{áÌx/ÐOû€~þüUDõ‘*B¶¤1m<­1uvÞî…-÷ö ßøÌ·¾ ¡.3’?üôælø©Ü½Ú,wKª±õÃ7ž”&_ýs÷w¾þÈ×_ˆ\8ÇäÂ\ô)äù%ÜJ_Jy—%ssssssæÁÝ¿7²Ï#ôô»ÿ =%Ó‰_Oì__<½2²îedøÑ¹? ?bŸ§";‡dÓOýÉ&ýÄ{Ïô–ø¾C–¸ô„ZZ÷ÿSK{§e{§çæþùtnnúslúçR^îè'š~ÒOt éžU Ù%~àSKœ^NÈÈŠ¸Ø3 hm Ò^Þ§6œVKó¿Þù·ü¯•É_ly„[Ô¸²Qj¤8ö:êë•Ò=ýy"ÑÍ?äØé“MÉ‘d[Ÿì_ýöÀw~;= ó#}±²PTç^öbé¹”—û_ŸW¾*éâÑŒl€R’ï°e?åÒR­\"~4úÙð£ìÏ&²?×ÿâä›bµòùVʽ¼å•‡ æÁ½{̓½ÓŸ%{§¹Ë°¸l|õ_š~¸È/†±ím~úŽùéËe?Bì{ý"Þ–ËÞ¸Ûiñ¯¿¸êNüÆUG’Ó™ìÙéìR£´NjdçPyÄó_v*#Û’ ϰÓS­Q>ãW‚¿Bà_âù—Øí¾ñ™o}^Õa9ì°P—VÇëElýð'¥=O¹ëŸ¯¿óõG!ñŠ»½ y~qGìçi¹äÛäûËØ&²®‰Î{;':ã×ïíŒ_Ïû_8â×É®òGæØü#õ×Qžó¥½7ÑÉcD$ £>õà•k ^Ñ´l:_|~{ÐíNÐO}óÖøO­ó¾ ÊÝòír7;šDI“i*·ô­nI_ÕhPnËž][[öÐ$qêÞ™KSM£ºÛë£:úZø†÷^/[È~Æ4ßœÓ$õÉѤžœDáRlW¸Z‡ö~X¾o6r×ÊF¹‹þV¸äÛ®éìƒ#Ó/'¾¥Ï&ÓNjŽW&±ånu&óMæjX/’b)ý-5ÖÊ_éäÕèÔ¤!õu~µlÝ'ó—,PK×¢–ÒB…ù‹^ ¸”·\÷*Ül­¼éóV·Øê3ìò&·=7L²Ç÷µì1¿ß²‡F.³¯RF•mʨß~é’ßîk8Ò× èSµ)úh‹6j!Ñ µh¢{ª‘qÕ«$’ÙL©å­$Ôn<º‡&ºË¶®™ýs×òó'óÓs]2EˆýˆW¿ˆ·åÒ'wû/-¾ñõ \» Ь,zј6}£1±ßV*#Øñç¥ 7×Ê¥ÍlK.<3¿ÖVïÎ/]¥Š¬Ù­Šdœ™ÿ]ÜÒà_•‰·åËŸß’V\êk«NLÉGè¾\º£=&¶~øÆ!òðÕ?â|)ÍÞijP§ŽHZÄ:uðÏÖ©ðÓ?¥5õ¿ª¿ýŒ©¿6¨‘6KÕÒ×P=´ºeD{keDKSuâã÷vÅÇ_:ðÄÖ{†‰rÝKëy÷žÖ#|%PI((;§&œÓ‰àý?Tvêîr×uíNy¦3ÓækSeò[áÐ'“þö3ô·Wÿ‚ªˆò#ÕËñÂLöá©ùk«1¹ŸN19úbYx­Øéù³ô&T\Ê[.ÝnæVÞô|ë÷åt¡g±lhþqá{™½»w˜½¡tx6”ΆÒálÈ·²Æ‹oѶ´þi!j@ÓŠ`4•†$¿òíñ+ù´Â›\7%+lb;Îóôú2W=­DÌns‘>™,.ýóŒTœä_¸,¹Ðlf¡ErøÆ“ùégŽ/µ¶£0ûYZ~aúA¼-§>¹Ø¿øÆZz…Úǵ;MʶÆ-‡ç¼¨Œ<ÂýW Rú'Wó+Ä% ¯& 4B þ%ž‰ÝžáŸ…3~åÛ¿_ñ^Úç½`jûÂ:Å}¥ÑÅ£=&¶~øÆáòp×?ââÃ/ŠÑ>/—ü\Ú3ÕÀ‘Þ±³û¼c¶µö‹¶µ‘Æ›ÿŒ4jûß½¯]bSsZ<œùþI8SlƒZâ”ítÆ]ÿ…Ê]o2°Ád’>_ Ïc¹ûµ?ªýëʨ–Æ%•kå#úò9ÑugóDWõWùÛ Ù$-¤Í dƒ¾söAu%CWܨUH$4Ò™'_£UœúÛôýí–ÃC ù­þS¸”»°üK—§2ÐG£|{­Qîõù ²Ûæð…ÆžG8gŽçœ3´t4ù ÅOk|ïÞù¯[D±ô6åOzðMÏUdõî|£'ª½»%ª-V^Z¢Á]Bê®§ zʸêûTÕ±¾g¹ •}Læ]ïšÌû;owìg?%Ékè$û*Šœ4ò(¿”85zjå‰Ô(U/4"†‹þ³áÜL6LcÖòÍÖZEþŽîúÏ¥î²éŸ‹¡^A΃W®~¼]qgð€~ð‚2²z·2B“¤4;µÕì¤eÚmªCC6UáU´x0“›ùÏâ›Õ”–iòTI º—¶ÅV%ñÛ/_òÛS†Ô×)ƒ¢oYÑGþ¢–n<­–zÚNnZhK.gË5G½Bý¹z…êöúNÕí“æ›m"!$}i»ÚÑ"´R°iϮߙöÐŽ–td§ Ø/ž Ø™ÜÃSLŽr&û1Ê·ÿ ·Å¼—~»ïœß.3JëdFõŠgÔ+~ÖðsÃd"8uà—#Äg3ù+d”Þï¸tÙï í#JÓ?hö´ 4yÚhîål\µcq•ɼkëBKƒ»=ð…>Ђè‹/¢O3'hS;’ÁÛöÜ[ê¥è_ ù Ë2¶iô³±M¶µ‡ÏÚÖ¾´¢‚ñ'~»ï/~;=#(žÓ;…SÄØwùKÓâm1ÿâ¯O~öÏ?¾•u;Fu}'ª£•âI刷•ð_ñâ!‘v>‹¥ôÖ–>ø8ô^hò^(—üð¯ò¶g¸·Ï¹Ççò2òhhßÈ#&ÇgrnõJ·ZR•ˆ­¾ñ¤\ò,®îþÎ×ÅÞÕº2ñ;¥•—{{¦z¨¡#i‡Ù€ãê©Nq`¹ÓÒjÚØÒj˜ØöÌ0ÑË|–êe –/4W£aç–k ;içGúæùQ¿ú|Ûô뺻9Ö¥Øút´aÂâa,_øú;¨~|š‹ç|Is>?¾Rj¤D­üUÚ~ýEíËŒµr™1œ¹µ2œ¡qµyË™Ü명º ’ŒûƒÆýÐo4"/zvâõ¯ô6Êý@ŸÐ'â€å:"à5ÃeZAu,„ ”:"à5ƒNF,whSÓ¹þ9É\?´ü€bü *ˆ :"¢ƒŽH€è #²b̦ó[Rᦦ¦¦¦†ÎCþX×Ýͱ.ñtÂ7!òІô\¶ 2À¿ªY{åºcåå|SíùÍ’jy?ð<-˽ý `?ÀžQ_˯¾ªíý«Ú¨ÒŽÈ–VÓÆ–V·ú ¥[½f!ùkù-)"·~i\ne*§ü˽~GÛßxKÛÏ}û‘ÄøÔĸ®ë}]‰ ý¾Ùú¬ÿ-g}½^ùá_¼=ðõ¾ˆí_Ë]þê 2íÏÙ´Dâ°~|ÃaU¸Ûn:ZZ…©s¡ç±\Èš°¶&dÍïheÍ ÷³ÂídzRNFxz°ÜìسPÐý//ª®#’zv#ºèºˆ®køÈ®áå¥Ðå.?ôSyráç±\8Ö}wK¬›ÿè0è³Òö)¤¾à_ËË¿o¶!>”‹î‘£SÝ#áÌ÷O™‰Î;›':Ó½é›é^ï…&ï…ÂôŽýQÇþ”!5š2¤{’£éžÄõØ{‰ë¾†‹ç| #ɯì#I!éàíý'9²DG$}lWµõµ«èÛ&}‡¤/œ¹PŽÉ•ùµsæ„Ì9Ó=Üí–6¯ÔJ›Ù\8ô”ËÔ~Û)}¿MUµ©¢4¬W]ß©ŠŽ$¿î™ßpaçè¸|9ÐQ/SŸ¨—ÑU­Þ?lõ–&i¤ôRzê_ÏVlW¸©F õŸé}Èô’œìôÝ#GÝ#ÅòoVk›ùú•©eÍÍŠ÷×4+˜ìG˜leê—wì¬Å;Fߺéè¸ú} C¸~·úK[·‡¥í™{zú•ûÐqJi˜ÜöÃäÏ9èò9p™ŒÆEŸÜퟯ¿s÷—üôºw´²æÂ|¨~éÚÊÈSš>¹×[’–Ö?lmi¥_»G:£Ý#†˜þ¡!Fg¨vØéVûE‡•JJãtRúÔhJÿÛ¿òñðý5Í ú•ìÇïøö®ß!<úñÏ|뫨U0ÇsNFׯ½¥ë'ª³9"¶~øÆ“Òäá¢ÿÒü¯?r÷¶<ý¶/5ý6.úþüZœj“¿Úž•o¿-Ž×÷•Ýëó´ 4yÚÔ² gÔ/¥•»W›åîùigÓÉXÃù/Ç\u'¤®:zZ)£ë:•ÑËÇ7:,^ß9»×Wjúꂯ¿—ö¾ÃÇÞÊÓÞX±ßK{ßá?ùÆ“ÒâÊ»¼àûü%?b·'éÍ‹êKŒ‰´ÅûO*ñ|Yîý'Âëk9¾UKtDZ§µN1¹™ãLŽyÁg^¤{Ò=gæfÆÙ=Úy»{”>ßp\úXx¯Äøý]‰ñpææl8Óa9r£ÃR®ÀArì—/ì4¸—¾£ê<Ú[:O±kÇ._k ïºt•súhÜ9],½ò›öì~ß´GîZ½[î"Í3/a^ă‰ƒñ`¡þ[‡,l¢¿é‹qº÷q Ýk”o{n”æŸ Ïf²aW]ŸÒUGß®Ó=épºGQ~¤Œ´íû97áp×YIÞa94Ôaé=:5¿¤¥é‡ _™Ì1æE²é§d“{ð1“+vî鳡g1>CÇ ‡šgCÏ&²!:¿ød4.úäkÿ|ý»¿Ðô:UDÙ¦Š7~ æ_{ñ«±K|ßaK¼2ò”¦ÏÒê‹^œ/ í¼Ðß~ÊÐßî½pæ?¼茧}@ïig§WET©"dKÓÆÓS×hçí®Qø—ØþeÚwØ<¤–®ûD-¥”d?…[|ã3ßú*„šP$øéÍÙðÓ…:ª±õÃ7ž”&_ýs÷w¾þÈ×_ˆ\8ÇäÂ\ô)äùÅÍ«Kþj{>ŠÝ~ãÞžg²3Ç™l.ü|2NžJêeÏÔËèÅ©ÕkÞÑêeɧÏÍäÂ/¥õšwä_SµžÆ[ZO"xW"XZúj¦´ç;_¸·Ä“Gˆ¿ˆñ¼(­=Ã=žðMÏ÷}y¹—w¹ÃWŸÖ)Ëaë”2²z·2B‘9qýÞ®ÄõˆîÖ;p{`³xû¿òÏ—åØ·¾J“¿ÚÞ¿ª‚¹¹¹¹¹9óàîß›ÙgÒ=ýé:3Ñ{o¢sŽEèéwÿzJ š+æÁ½{̓½ÓŸ%{§ è¼óoy ÿùt©óD²)9’l’HjåÉð£Ñφex6‘ý¡˜ ìÜâ×ûã×Ë%?—²,$¹D"‘L¿`ŽM¿`ÿê·¾óÛÙúŸŸþc~z¾ä›æµò¼=ð•_Hý’íå%‰þkþ%Aˆ~Øù‹‘^ˆ~ÄÐ'_û/Íßùú‹«îÄo\u$9ÉþÎþ 5Jë¤Fv•‘G<ÿe§¡2²-¹ð ;=Õå3~%ø÷ñ+r—üß—Š´ð/±ã-_-žÿÒñ™o}^Õa9ì°(#ë>QFêUbë‡o<)íyÊ]ÿ|ý¯? ‰WÜíMÈó‹;Õ µ=GŒöÛRu{/Ÿ§Q¾ý_Œrz‘#Ë7™w½k2Ó±0=Ù³Zºá´Zº„¥¤¯6øú{iï;ÜíMH{C<ïy!¤=Ã%ž‰?(oõø¦8ïãåoOÂåýEìçË›ÒRJ}-¯÷/.ŒmòýelEï‰Î{;':ã×ïíŒ_Ïû_8â×).å̱ùÇdÓOýÉ&Ês¾fbïMt™4¤¾NèoÃä¶ç†Iv|Ëóû-{hmá¡´Xx0pãA0Ð=|4Ñ]¶yõʨ²MõÛ/]òÛ} çOú}ª6E_C‹æ|CKÐãAÐ_ìZMˆӚ–×%?[ÿjÙºOÔó†L«¥ë?QK3Î'W3Î…ÒטŸ¾Aÿµ;A?MeO0®ú`£q•D2›)G-ðÕÜ-ßž3"5ÖÊ¥Æü/¯EóÕϼ_EN/6ÜõÉÝþ…û;±Ä÷²Äƒkw‚š¶p\ý>àИ6}£1iZ6ÏçPyÄŽ?/m¸¹V.mf[rá™ùµ¶z·2J«"kv«"gæ·4øWeâmùò矹××Vœ:˜’ÐwÚréŠ=q•Ëô[.éÅÖßx"D¾úçâïBü‘/¥Ù›xöS òWÛó‘¨Lû“Î]+å.ú»kø“h×0ÕMOë>즵# Ó+\òí ×töÁ‘é—ýÒÎg“i'½—–¾Úâ_÷öòñ1žBâ'ßx"vüyÊ[I䯾ïãåoO²áÞþ¯äóe9÷Ÿð«¯åþþU íˆTE”©"/•ÒÄK6ÑÐýùÇ_N]) ÅŽì«\õ'd®úËŸ|v%ͧV±ÐYj‚,^H³w÷³7”φÒÙP:œ Yã–CÖ8 Ä®Dnò/\–\h6³Ð¼}¶þ™ìÃSó×b`r?brÔýPú™ãK­ D«!Pƒ€V4 ¡ÂT³ãW¾½3~¥øãdiù…égiøêgÞ¯"§ç϶].}r±ÿÒü/´n”Æ´ùšÆp\»pФkÜrØ*ï¿bÒ?¹š_¡)ix|5i  ð/ñü‹Ky˧ϥã³pƯ|û·ñ+Þ Cû¼¬Sm_X§Êµò{â*ä’^lýð'Âåá®.þ.ÄŇ_<äk?Õ µ=+Ó~ãÞžÏwŽÔʹ–´î„ZF]‡…Sªé é¡´ôÕßøú»÷¾ðmoð}áë/bš(¾‚€Æ´á´ÆD ¨öî–¨–ÎS~±«ÈhäW~©N2âZ¹D"5JÕ¾ r—¿XYŠ­>FcÙ´žwïi=Ιã9ç ÉOµài?©ñ´[ã{÷æÃ¥7Êw¬6Ê»G{þ»{”¾xP˜(û™ çf²aú¦‘ovÔ*òs×.u× ‘_ˆ~¸ÀW?lŠ¥·)|jS OÏ?è¬Þ:lÛ®Oîö_š¿—uƒú†,ƒ>²k|ß¡ù5UyJ³OîõU#©¯ì#)ú›–ç7Êw¬Yh øW¹ê‹Ê«Ÿxï™~Â]Bê®§ÈIëš¹êûT®¢ñV‡)\ê»0îñY84êÖ’ØwØ’0™?Ø`2—ëÛˆ­¾ñD¸<ÜõÏÅß…ø£Øˆ«Aþj{>V¦ýƧ=_«H,ñ½{-qWýI«žü…¬Ôë;kñúÈ›òy×*$küÀ§Ö8-ðOéI“ýíúþöËá¡W+mñM_½pñ÷ÒÞwÄ“‡¯ýˆí/|ãsuÆOîþõf”·:ï}œÚ“ΙžÔ/Óÿr]xþñV")µý/öó…;ÕÖ·¾ÞŒ÷¯j`‰Íjüvß9¿]f”ÖÉŒêϨWü¼ÏàsÃd"8u@ØâÐÔ¤ ;_DŸ¦xxÚú”ž6Óž]¿3í1Ķ=7Ä–ºÃl&ßc­è[cVô‘ü~Ç¥Ë~mßQù Ë2¶iô³±M¶µ‡ÏÚÖ¾ÔjA‰üöË—üö”!õuÊ@ò«W¨O¨W¨¥O«¥ž¶“›N½š¼Ê%?ü«X}ìÏìLîá)&G9kvjÿªÙI«žÓ-ÖÎäfþ“É-þ}˜{|./#†ö—>¿ª´ö¿ØÏ±å¯žúz3Þ¿ªZ0’v  8®þpбoLÃËvn¹Ö°“v¢>àå¼–»üÐô }V>c]w7Ǻt[ÿn€–C^¼{`ùÂ×ßð÷7UÞÂéï‡Ó4ñ™&;óÍý'¯·¾Þ†÷/Ÿæâ9ŸFcÒœÏ?•éÁ^†e_ñ4‘kå2c8ske8Có„è|¬kr[¬«öu’zܳ¡g'^ÿ Ao£üÐô }"þÊMdfr3Ç™œ>ÖôP£©²î¡/?t™#»v›#¥åŒ÷—×[_xÿ*/¿‚ „@+-ÚÖ:k[KKÐTY¹K¾], %ÔxmS³¯—JNÍÆˆH€è # :興NÑŽÈX×Ýͱ®ššššš‰d6Í'Sšõ-k–©eͯ«`Bä#ÿå¥Ïrho6-‘Ìt¯.@y­½ü÷mÖ?ð¦"ʈHmã-m6”e¸mmžŸ:×õo½¯ë/íŽ-­¦-­nõJ·úÍ«¤Êë³Ô*$’9Òxë·‘F8Û›joà͆¶2S¸ÛîÅ;[ÛUm}íªz™úD½Œ:²î5f…›Îgz373½ìôìó?ZüZQSCûÖ ‘<zË…¬ Ëak‚r#yœLOÊÉ׌ØùóÕ?êõ @õSS³sáç±\8Ö}wK¬›ÿhÁ»›c]]t]D×5|äF×0*Uˆ>€Q¾½Ö(÷^Úç½°xJ¹kõn¹küʵ;ãW¨#;ÙÄK6eù™l¸uȼ£uˆžÒ̓»w˜mÊGmJ!’;öwFûS†ÔhÊîIަ{×cï%®û.žó5Œ$¿²$«9¾úGý¢~¨~8uDºÕ_jÜjUTÕ¦ŠÒ¸kâàQk"Ê1¹yc¦èWîSq)¥arÛ? “?ç ›?zbqÙœ3'dΙîáÎh÷°´y¥Vº@zïØY‹wŒÆ2Ð1Ðqõû@GaÊ”þá@JOã+ó# Ûó#> ËËW?Õ¦O*o³âý5Í ú•F»øßÞõ;*oŽ|õŸÒ§FçË¯Š®ïTE»GŽ&ºGªtI^ÿÆÚf•”JA%b²?a²¥Õ{²pKë¶¶´Rúî‘Îh÷ˆ!¦hˆÑ™~Û)}¿¯½±óï·}©é·qñ¯Ò óþòª–G’_÷Ìï Ld-y}.ì_¥ÉÏ×_¸ËS(U ãòå@{ôY«÷Ã[½BôSÖ#7:¬ÓÆÓÓâ)=¶“MÓ²ùš¦…ÎPLvXì>‡%œ¹õN8³”G¤FSú€ãê÷‡Myx¨ôŽªÙ´D2Öpþ˱WÝ ©«Ž$QF×u*£–otX¼¾sv¯¯Zó/Eÿ¨_Ô/Õ§ŽÈx0q0d^0ǘɦŸ’MLîÁÇL®{ôèT÷(;e6ô,Æg*náÔÝlèÙÄüÑÅ®MŒßß•gnΆ3–#7:,ÅRfœ™›gº÷q ÝÛa94Ôa)”œ0íÙý¾iûH÷<¤{˜Ž0/HÝ£·ºŠ»~ªMŸæ¡}‡ÍCjéºOÔRJ9ÑygóDg0pãÇ` òæÈWÿÖ)Ëaë”2²z·2’îI‡Ó=‰ë÷v%®Gt·Þ‰èªßý²áÙL6ìªëSºêÒ½é›é^*…2¢üHiÚ÷Çù#ŒJ«/z‘¼0´oðBû)C»÷™ÿð^ 3žö½§½4{#rá“ sñ/¾PÇÕ{À~ùRÀN6Lã’tí-g¾=/óÞ½æÁÞéÏ’½Ó‹ç™îyìO÷ÐùHcô_ó,ìôɦäH²‰{yùê§ÚôÉ¥¼|kDlyØú©¤ü•'ßX+Ï[)ßò²užý!;ýmù…gøÖ_ÿ*|©kåÉð£Ñφex6‘ý¡0%É@÷茽7ÑÉþ5ôô»ÿ =-æåŠlñ•§PªøõÄþøõréG8¥EivI¹”HY÷‰22üèÜŸ† “6öÞüx«–n8­–.T–jÌ¿\úGý¢~àÂØ&ß_Æ6QKx¢óÞÎ‰Îøõ{;ã×óÇÄþWÇŽøõéÓ/òGæØüc²é§þdåɾ åÏiD¤Z¶îµlÞéúOÔÒŒóÉÕŒ³ò§´K0pãA0Ð=|4ѽĺr·|»ÜMKµr©1ÿË«i§ICê뤡´òŠ^ ¸”·’uÊWÿ•”¿p³…r¥ú¯Ý úi¢4{ê®qÕ«$’ÙL9êKÚ\+—6³-¿ðŒ¸øWiúQF•mʨß~é’ßîk8Ò× èSµ)úZ4çZ‚þ‚þBý&·=7L²Ç÷µì1¿ß²‡ÖN/>³g¾òš– §ó`…ë§òÐÝ[‡,l ^¹ö·àM˦óÅKD¾@cE­ñŸZã‚lÒµ²Q.ùv…k:ûàÈôË…ÒÎg“i§Ô(­+ÕþÅοúAý¾Ùõ €xpêˆd²OÍ_«ŽÉýtŠÉÑ8ˆrˆQ«à“ÚUBæªï°üÉ×aaw"AQ~¤Š”V^±Ó‹¡O.å-Ÿ™½’'šÍ,´n&_ýWRþÂÍ„§§µÒ¨CŠV8¥©Á49züÊ·wƯäÓΦ+]_âÂWŸfïîfo(ž ¥³¡t8²Æ-‡¬qš˜_h/7Ð=‹eCó¥ïÎWÿbËÃW?D±]Œùvµ/­ni:øgëTøé¿‡ŸêcMõ±Å¯êo?cêo§ L¤ÍRµT jYÝ µŒºŠ §ÐÒióµRWå;ÿjõûf×/bé#Ò9s<眡­2½™›™^OûI§Ý¦<ð©°]/ UdõîüK{T{wKT[,%mßp\»p8§&毘&[¤õ¼{Oë)V^k|ïÞ…ÆqðÕO5è“Ê«Ÿxï™~Â]Bê®§¯Lï“@¦×Uß§rÕËŸVç¤m4¸È£1m8­1ÑÒb«éñÕ?[~çLOê—é_­{XÐ>³4æQî’ÿ»ÜEݵÔAé®ÿ\ê®/W}-_H4ö*¿µ uj×Ê%©QªÎH’»W›ån“y×»&sÇþÎÛûÉòù<Hé©EH|à®±å᫟—VWdãÅ»†)ç\x6“¿IŸ 7ÛñŽÝç³­µ_´­4Þüg¤QÛÿîý¥Ö¤¨Î|ÿ$œá² ·øS«HhämhF‘æûÛôýí–ÃC ­,\ù—¢ÿÒ@ý¾Ùõ @µÁ©#RçÙrMçQ¯P®^¡º½¾Su»Á¤ù¦ÁD›l°S–¶ 6íDÙ;},Û;mÚ³ëw¦=´,Ù)é•€6” WýòªÃo¿|ÉoOR_§ о5fEŸz…ú„z…Zºñ´Zêi;¹ÉÓ&D?զπýâ¹€É=<Åä(gÍNí_5;òíÿb”ÓmîÁäfþ“ÉqÙ“šöÛ4úÙØ&ÛÚÃgmk_–+¶í¹!&Dÿ´AGÊðäjÊ èS}ºí-Ý@‹Ù´¡ÅœOÅo¼me 7ž¶&O-"WíXc\e2ïÚj2^UZ}qGø.öåf6“Mö@2ø—.ûTûóíÇwÎo—¥u2£zÅÆ3ê?—è¹a2œ: ls ¾ú[¾ú)Ñ*~/«—ýÞ0©ÿ¶ŠßËêe¿§#;¥c¿ý¿ûiú­n`ë}Ý—±–´û0}„ಠ÷ø3xa@?x6³¢IëT_–ø¾Ã–¸MuhȦªæüùêõ‹ú ú©¡#iGÈ€ãê©6Aiˆ[®5줔iŒªNÿ8œ¦‰Ï4 :(ħ¹xΧј4çóóY¥FúGÔÊ_¥]à×_ ÿ’kå2c8ske8cIì;lIÐùX×ä¶Xׯ–‹Rhu*¡ 455ª½½.?ýœ&Àºë¿lp×›wmÍï^/˦#€Bh¥EÛÚCgmki?bšê.wÉ·Ë]Þ Cû¼ %€j *Ë'¿'‰K$’]Ð@µ‚‘ÑAG$@tÐ tDÀN¬ëîæXWMMMMMD2›~Ýù ‘'Ö5¹-Ö%k–©eÍo†öªáޝ›Ù´DBuJÇ7»ì¨ß·©ì°ØêëMö¯7»ýóæÉ„?._{~óZ KtD¶«ÚúÚUõ2õ‰z)Zá^cV¸é|¦7s3ÓËNÏvŒùNòkEM ík\¨ÊÂôÝ#GÝ#ÅÜÏaýø†Ãªp+¶+Üt´&µ& SGµ·×Eµº~í-]?Ýò7Äô 1úUˆúœÌñœ“aë§¡Es¾¡%œ¾9Fƒª Ãßä¶X—!¶í¹!–·gÅv…›Î0Ù0Yh‰;¹ÐóX.dMX[ä_œLOÊÉT>±åá“9ÎdI†”>5šÒÃZÊ…¶¿ñ–¶?Ê2Ù—ô‰ñ©‰q]ÿÖûº~h¯Z©UH$T§‘Æ[¿4B#¨ßÊ€ø{(/-­¦-­nõJ·úM‘9Õ×r×ÿâT¾ýS^}ò•Ÿ/oG™ñ×r™1Òxke¤‘]Rë”å°u æU=äB9&2®Ú±Æ¸ªuð[[ÉÈ~úÛ¾ÜÔßFÁpDZ¿3êØŸ2¤FS†tOr4Ý“¸{/qÝ×pñœ¯a$ù•}$YÉüÅ–‡;´Ÿ;EOûI§ÖòÚ|?ü<– Ǻïn‰ucÄ € â(4À"¢‹®‹èº†Üè†üÿõ"$¾-G}"žØçòb‰ŽHêÔ´l¾¦i¡3Òæ•Zi³Ãb÷9,áÌ­w™Ås Ñ@ÇÕï›òðÐB‘Üñú¾²{}ž¶&O›Z¶áŒZFçåîÕf¹»0=WF×u*£/ 4›É…²áf²aUdõnUDˆ<½Ì±\/ÃÎß0±í™a"ã|Ë8a^Õ“ûñc&—q>¹šqvXþäë°°»õ±¦‡úuAWܘMK$c ç¿kpÕºê(2/tX>¾ÑañúÎÙ½¾Â+é‹P½lã™zYùò/]ñpÕϺê(jezŸæ]xÇÎZ¼c4V”ŽŽ«ß: S¦ôRzúžaªØžOû…W¹Õ_jÜjUTÕ¦ŠÒU4b]xzö¨v.^ŽŸÜöÃäÏ9èæ¾/,o³âý5Í ú•F»ûßÞõ;„kžl Õûᇭ^¶>‹Ï(¥¾šÆÚfåL¥ ±G|³g$ôÛ¾ÔôÛÏŸoz‚F(“µäåYÚ–/¨ßj¨ß~Û)}¿-OdjY³*º¾SI~Ý3ÿCT©ñaiýWÊR£óã•”òó&;ó}U^?Ι2çL÷pg´{˜Z yÿ¢é{ïheÍ…rRýÒ³Fˆ½±½8Ðqùr>OºŠì°4ù—K}q‘íŸbñMl}ò•¿2ñœ{ýr÷/ÒÉYX"ŸæüIŸf©7 ·%~Â_×ûH177777gÜý{ó ûÌâ¸êNüÆU§ŸhúI?Á%¥Öóî=­‡}~¢óοMtÒ•åGʈÜ%ÿw¹Ë?ð©%žýáÙDövúé̱é”~øÑ¹? ?RK7œVKé*’?ÝóØŸî)”a¢3öÞD§Ô¸²Qj¤4¦MßhLɦäH²i®L¤{ÒátÆ´ù[iðÂéÿ¼0ª²(²“y×»&óø•àßǯP­A?|™~ñÀ‘÷Gú›|~ = ÿ3ôTj”ÖI ùã+ߟ›ûçÓrä/D±±Ä÷²Ä»†?w ¿®úbëœb2ïþ,Ù;M±´ð*ŠÛù˜œÎþ@1–"?uèæ??}:ü*ý‘`©éùÚOiéõï=ÓOØ”¹mJJIå%=p¿c1Œò«róàÞ½æÁü3îŸOçæÆ¯|û·ñ+Â닞’‘Æè¿Fóq/;ý4Ì~ óÍ¿4yÈòíÿb”SÍ’<Ùö#¤~«Ôoyë—Úl\Ž”>ÙôS²‰r¦ ktž¼˜ÚBäá®ÿÊØižž/…ñs¹xwýs•¦¾öÆ&~ýÞÎøuúµX«’êÑo|ç·Ï÷£½{̓T×Bì­IÊ“ýND¿Ó-ù«­¾¸Ëößh †>ùÊ#v<çkŸ|üëŸOçæhF)½}>\u}ÿW^ooFü,Mføc1Ä~Yœ±M¾¿Œm"/›è¼·s¢“bBþ˜ØÿêøÀ¿NïÝù#slþ‘|™òœ¯Ø{¼;"CO¿ûŸÐSr0bñôÊȺO”ê:dŸ§ fç@‚’êÉôW"‘H$ó¾Ï&ò _:..]E93¬Ò cíþ$òúºÀâ½Q ¡îo²(²:.ö ý‘ ûá1?ÔV"±ånu\šøbÖ×+ °Oô’S¨úHÃÖ'ûWz•¢§@aþb¤/V–r=ø¹”Wȃ~þóó^_‹“_E¨VþÊ_øåÏ7=¥¡ó…/ ìV„ðú­P¿ÕP¿ùZ¨•K$ÃF?~TøI[ y õ/¶=ˆ¯^׳IH|fÛ[åõS¬3‘ ½rSJ:C¯»ô‰”{û³ÐÞ 5É·5ËEþj®¯ÅåGû‡¯µ—WŸ¥É#^<ç[¿¥ùõä;’ØÏÍZ¹DB=ogü„?¾Þ÷.T²#’Ç®ÙAÿAëå­CÁ+×þ¼¢iÙt>?e{¡ô×îýgæfÆiøÔgÿ*wË·ËÝìh%Mf¤©ÜóÒ»V6Ê]ôw×ð'Ñ®aʆ‹w  v ÓÚ‘‹—‚®¢ð:’úºg$%|T)M5ên¯êhZè5hö ‚ìmLóÍÉ1MRŸMêÉI.Åv…«uhï‡ó×<Eýˆå —|»Â5}pdúåD¡´óÙdÚIÍëÊä/¶<­Îdþ`£É\ ëER ¤¿¥ÆZù+¼šV4¤¾NèoµlÝ'ó—,PK×¢–ÒB…ù‹^ ¸”·|ùó[‚K}ôÌ¥­ØØSe«>Øh\%‘Ìf„å_šý&·=7Læ§±¼£•5·ì1¿ß²‡ÖÊ©¼ýnŽ'<=ê·êWU¶)£~û¥K~»¯áüI_ƒ¢OÕ¦è£-©+$îúÛÄŽWbû‹ñ™ý¼¨¤~¨ý Üx tMt]GX×î´¬½éÐ ­Â÷©Òüдl8]üí¬4ù«³¾øÊöOyíïó¥â¹úåî_6e[ŸM9ÖpùòXMìk¸øÕXƒQ¾í™QÎ^ÒMlª9~ÂK«/ɧŽHZ Á:uðÏÖ©ðÓ?¥5õ¿ª¿ýŒ©¿6¨‘6KÕÂVÉ7æjåå,þbr¾ÐpYá몀JBvåœ>špN'‚÷ÿB'ÜõF]{‰àý]óõFg4¦Í×4¦Êä/¶<¡O,ýíg>èoÏôfnVÇz‘ÅPE”å×Ïe²OÍ_‹ŠÉýtŠÉÑÂÂkÅNÏŸ¥7¡âRÞòésæøüü…C«ùP­è”î}H÷ÒmãW¾½3~%Ÿ¶kƱËûrƒ»üfq¬c±}_Õ­é\^Ù 7Óžõ+Fývi;²¯2{wï0{Céðl( ¥ÃÙ5n9dßBpéøÀWÿbÛƒØñJlák|ŸG¥é§4{sÕŸ¹êib û¥ºZמÚ!ǵ;uLXã–ÃójTÒß¹Ë_mõUªüåñ¯7©ý#¶>… F<R¿Ü¡Ý5hË\úä0’úæË‘”MùQŸ°Ý2ªÙÅï#¯Wÿb³DG¤wìì>ï˜m­ý¢mm¤ñæ?#Úþwïk—ØtœQ¦ñ‰Å6¨¡e¼ÙM4:ã®ÿBå®7™?Ø`2Vž%¾w¯%îª?©qÕÓEúÎàõµx}´òÂ|ùÏ|àKŒßß•_è.»¶þò.¥…›Mç5-]w6Ot½IÆñ&A6IËS#/o™›™ÞAß9û ½òXŠZ…DB#iAkòGZ^·¿}@ßßÞa9<Ôa)¼’ü±pivaù—.Oe F‰Q¾½Ö(÷úÎ|PÙmsøBߢÉ#œ3ÇsΊ´ä/4®Óß»wþëQ,½MyàÓ…ž|Óó…½)YT{wKT[¬¼´Dƒ»þ„Ô]O/xô¼pÕ÷©\õÂõIO¨îÑžÿî%û¤»«• çf²aú´F+á’GP¬s×.u×K*m÷r­Àý·;ö³;ßÉ+éçžbÚpZc¢ŽÁÀƒê†¨_1ê·°K«Ø1ßÔhJOÚÎ/-OþZ¹D"5JÕ ˆçøê_l{`Ç+çLOê—ñs@ÿºÇÝs‡‹=ð}•¦¾öF­JêR¤Ù\ÊKÝ(ƒ¾!Ë Êkï;4ÿIZ/MþꩯÒäçî_oOûGl}–†xñ\Hýò…ÆER2œ:Ò´÷bé¹½U£?ŠÞGÊû>Rm,ÑéØoÿ/Ç~š^­Øz_7ÀeÚíNKF£ío¼µPÇeÚù|2íl^µcMó*šn º­þ\u[îZm–»FöŒ^]¾°§ O®¦ Š>…QѧÐÞÒ ´˜MZ~–‡ßx¨ÊÃÝø>ÄÖ}òì°ê°P×<—«¨Û1ªûë;Q­,_8I³2þ^šüÕS_¥ÉÏ'¾½]í±õÉ_~±â¹úå‹5~à¨5žNL̓»w˜Ÿ!Êýýh¹ÇOøãë}©jhÁÈV¯yG«7à¸úCÀAgÞ¤B@õÐÒjÚØÒj˜ØöÌ0ÑË|–êe  §¿NÓÄ^šÌ ”W?4—«aç–k ;™Ž0/h ËrÑÀò’¿°¾–»þaoô Š>M;Ö«üó?Dý¾yø4Ïù4“æ|~¼­ÔHÿö2‰ üú û–kå2c8ske8cg ìþ€IDATIì;lIÐyÆ÷«7XP…ŒûƒÆýè‚P4u1ª½½.?½‹¦’¹ë¿lp×›wm->ú¢±H/á˱˦:åç^_Ë]ÿ°‡·‡‘äWö‘¤Âµ²QáZ^]x¾€ÊP Àë…ËÂÜþ¨/À›­$hÛsè¬mÓ<£e^F$“ëƒí&-d$qK$7ôý ¾¨$´èœÜµR+w=òõŒ=Z^ò×¥-ï÷tDÀkV¨/àcŠß“ÄÇ%É.húA}P,÷iËðÇåciËû}S³¢ƒŽH€è # :E;"c]w7Ǻjjjjjj$’Ù4ŸLiCn.ËgÞD©ío¼¥íoùÌÄøÔĸ®ë}]?ª€êgYNÍÎ…ŸÇráX÷Ý-±n¾£5•‡SG¤wì¬Å;¦p¯1+Üt t\ý>ÐQ˜RÖüŽVÖL“²¹Oëî·Ò÷ÛTQU›*Jת¢ë;UÑ‘ä×=#ÉùùËÔ²fÃä¶&¾£.ÇÂÉà)ýÔ¾¥Õ´±¥•dS¸ÛîvU[_»*Ê1¹yc6ÙÒ—/:êeêõ2ʹÕûᇭ^JI 9 KäÓœ?éÓÔË6ž©—ÁÈàÔ™qfnfœéÞÇto‡åÐP‡¥{ôèT÷haÊlèY,Š4Þúm¤‘KÎÔQØ=Úy»{4`¿|)`§ ݉ë±÷×uí-g~þYf~þÙг‰lˆÎN7íÙý¾iܵz·Ü•îyH÷0/a^ă‰ƒñ Ý·˜lc —/5LtÞÙ<ÑI9;§ÆÓô«Ù»ë]³7ÎÍäÂáôÍÙð¼îÖ‘Ôù/GR6e›Û¦„‘À©#²Ãò'_‡…þn1ÿáÝ3“ûñc&Wjåùc<øàãx0zË…äîÕf¹›Öš,-ß”>5šÒÓômWÝ ©«NÚ,UK›)çîᣉîaêj,–ƒ«îÄo\u”žÎhûß½ÿJžZ…DbSøÔ¦ô5œ?é{™O¦÷I ÓÎÜœ glÊGÑ ÇŽH¹[¾=ß'5ÖÊ¥Æü/B×gTF•mʨß~é’ßNÝyŠ>U›¢¯¡Es¾¡%è¿ñ è/-ç¤!õuÒ@«eë>QÏ›"­–®ÿD-Í8Ÿ\Í8‹å iÙpZÓ²ø]lʶ>›’:4i¢÷XÃůÆŒòmÏŒret]§2 # *6«1{wï0{Céðl( ¥ÃÙ5n9d[§,‡­S ]Q«X*OUDù‘*B3Ù‡§˜,ûW&÷Ó)&GS¶…H®iÙ|MÓ¢1m8­1W¿8FRß|9’²)?êÃXHò¼æŽHš@M#ó[ÇP'c­\"‘¥êW£/_¡Š¬ÞïdŒjïn‰j ÓÐXK­çÝ{ZsæxÎ9Cùgz373½žö“O»5¾w¯5.¼4.ÒUß§rÕ'‚SAóàÞ½æA˜D™;"ùîj-‘Ìf$Wý ™«^ѷƬè£4~Ç¥Ë~m_SxšòÜ;},Û;mÚ³ëw¦=´ã6Ù)ýöË—üö”!õuÊ@ù«W¨O¨W¨¥O«¥ž¶“›ÍÅs>Ƥ9¯1åç(Ó?‚6š~õ÷/~ýEÿ—ÌX+—Ù[+ÃKbßaK‚ÎǺ&·ÅºªbÈåÎHò+ûHRáZÙ¨p¡ €Bj¡!ÈšßÑʚ宕Z¹k쑯gìt@!èˆD6ô,– A,¦fD‘ÑAG$@tÐ "뺻9ÖUSSSSS#‘̦¡‘êÓ!ßü…ÈëšÜë’5ËÔ²æå¢½åU^@5³DGd»ª­¯]U/SŸ¨—Ñ‹„½ƬpÓùLoæf¦—žÒkj~­¨©¡=¦)%ûŦ0}÷ÈÑD÷ÈBͦ%‡õã«Â­Ø®pÓÑš8xÔšàRàfÅûkšåz¡u2ÇsN†­Ÿ†Íù†–púælU½bÛžby{VlW¸é “ýñ“…–¸“ =åBÖ„å°5AÞMñÁÉô¤œLåó[ž·&;sœÉ’SúÔhJ” mã-m6”e¸mt–Ÿ:×õo½¯ëÊË—å®Þ6–舔»VƯ\»3~…^$’M̱dS6œ›É†[‡Ì;Z‡Øé)MáÑ<¸{‡yЦ’¬dþbËóö –ÕPË(šyÚOj<íÐÉë"~Ë…cÝw·Äº1¢ú`¹³DG$ujZ6_Ó´ÐióJ­´Ùa±û–pæÖ;áÌâ9Ðhš€ãê÷‡Myxh¡ŽHîx}_Ù½>OÛ@“§M-ÛpF-£ór÷j³Ü]ìªLï“@¦×Uß§rÕ»êNüÆUW.õõ2Çr½Œ2º®S¥3†‰mÏ çóXÆ óª˜Ü3¹ŒóÉÕŒ³Ãò'_‡…Ýí¨5=ÔǨóºâÆlZ"k8ÿåXƒ«î„ÔUG‘|¡Ãòñ‹×wÎîõ^I#˜êeÏÔËÊ—éò€b¸êŽg]uu)ŠVƒTÞ±³ïu¥c ãê÷ŽÂ”)ýÔ¾¥Õ´±¥5?BV±=?¢Ÿ>N^åV©q«UQU›*JWш{áéé×ü,¥GåSJÃä¶&ÎA7ö@ayiÔ?ýJ£õýŽoïú•×?ßòý¶Sú~[^Ÿ2µ¬Y]ß©ŠŽ$¿î™ÿ!¡4ýp·ö¼@ÇåËöì‡Vz)%i€ä,,}]*âð¶Pâ‘áÌÍÙpF?ñî=ýÄâ)GR_ÙGRZOã-­‡¦h¦QE×w©¢ìIÖ4Å’†¦ æÂÏ'sá¤áᩤšõtU«×¼£Õ[ìU¹cÿÇÿ«c¿sº'éœV¸Û.1TIÕ»GNuzÚú”ž6˜Wõ –ÖPKå.ù¿Ë]­C–íCAÿAáò€ yÌÍäÂʈò#e„|~%OïïJ ¯¥LÔ5\¬c‚oþBäE½F¶áŒZfܵÕ<èª?©qÕWƒTgæfÆ™î}H÷vX uX(ê¦4íÙý¾iëO÷<¤{˜Ž0/âÁÄÁx°{´óöBWÑ¯Ì æó"ÙôÓ@²‰É=ø˜É» ÷ôÙгX6i¼õÛH#—’Ò({vúÂÙìôæ¡}‡ÍCjéºOÔRJIó‚?•×?ßòRG!ÕKÀ~ùRÀNe¤qÍ:ö–Î#D?¥Ù1ÖpùòXé“rvN;§_jÞ»ë]³—âOáÂ,#©ó_ޤlÊ6·°±¼ðîˆ §¿N{ÚO›<í#¾þläÑâé}ç샾Ëá¡ û¼ZºáŒZ¿žØ¿žÔ'G“úÄõ{»×™sœÉÙÖ>k[ËNO/?ô7M´¤WzñË…g3¹°uªí‹ù¢©³‰Éý4Àä,‰G- ñTiÚóÁFÓ“yÇj“¹ÃzäF‡æU=Ðø¸Hct]¤Qî’o—»lkÛ¾°­Uô)ŒŠ>Z#’FêAW\È8ŸO¾ó[«HbÝ÷þë¦ÿW¸ÞiT¸èµ¼ðZmÿ»÷µýssssssŦÃóÍ_ˆ<`qœÓdzÎi¯ï¬Å뫆Žûüˆf‰D"i1ÿáÝs¾Sû4Ÿ¦ëæGÈJÕÒf;ß=|4Ñ=L]K…ùÏO/ßþ*ýůʑ^ ¨¼QÝ_߉êz§çz§É ¨¼ô®’ú/•Zyþ>ø8¤O’TŠb2¹ë§4{ø¹–ãªcϽ 8ÆŽ96åOmJ_Ãù“¾—ùÐÇQúp[liÞ6xtDR§^ëå­CÁ+×þ¼¢iÙt>?e{¡ô×îýÔhøÔgÿJ/lìh%M¤©ÜóÒ»V6Ê_Ždìþ$Ú5L9PS×ð‘`×0­Iihš•c¿ý¢cÿÈ£³û–ê0u`Eu·×Guô’êNÈÞÆ4ßœÓP÷÷ô æØô 'Û:´÷Ãùkž‚b°ýQá’oW¸¦³ŽL¿Üê'í|6™vJÒ:©±2ù‹-¼Ædþ`£É\ ëERä§¿¥ÆZù«:}5º6iH}4ÐßjÙºOæ/¹ –®ÿD-¥… ó;½p)o%õ_ʨ²MõÛ/]òÛ©;OѧjSôÑpÔO?‹×—¦eÃéâ­¦lë³)©C“Z Ôm”o{f”³—pàm†SG$­Žd:øgëTøé¿‡ŸÒšz‹_Õß~ÆÔßN£hôAóë÷ш‰¥I$ Lnæ?™\ÃÎ-×vÒJOº­ÿG7@ijj~½ª¦¦\;\k=ïÞÓz¨c†µ\ »rNM8§ÁûÀÔ]>z£®½Â)ÏtFcÚ|McªLþbËèQû™úÛ«AUDù‘*B3Ù‡§˜,ûW&÷Ó)&GSt ¯;=–ÞD‹Ky—‹¥™½»w˜½¡tx6”ΆÒálÈ·²Æ‹oWý¯/ZM[cÚpZc¢©#©o¾IÙ”õa,$y–èˆôŽÝç³­µ_´­4Þüg¤qþt¤…a²?a²4>±Ø54e‰VvcŸqסr×›Ìl0™ç_Q«H,ñ½{-qZ­Œ&mѸš6h”ïXm”SjZÝl®€‰Î;ÿ6ÑIiææþùtnΨØ^k´[2šèº³y¢ &UMÒ64M/ou™›™^Z@€º’¡+nÔ*$éìœ9!sÎ?Ò*oýíúþöÂˆÄøý]‰qÚö¡|ù—.àu²åÛkr¯ïÌÕ½í­#vÎÏ9gèIAþNã:­ñ½{çÓ'Š¥§‰·ÂÓóEY½;߉ÕÞÝÕ+¯~â½gú wý ©»žÆ'²7j«~£ÈL#ó[ÇP'c­\"‘¥ê…F4s×OiöÀI:O§$‚æÁ½{̓ˆ!KtD:öÛÿ˱Ÿ¦Wë¶Þ× °÷£,Ü•’ Ýi©Ñ_l]§´óùdÚÙ¼jÇšæU´¥ê¶úsÕm¹kµYîy4Ú³Ðdjï…¡}Þ ªˆªM¡I[о5fE­9¶iô³±M•Wb¬kr[¬«˜6@5 3®ÔÊŒ´V—fç–ëšT_êêê´}JðÊÕï‚W +î ^Ð^PFVïV¾ôGÍNí_5;-ñ}‡-q›êÐMUxU.œcra­¼øtN¾ù—&à‹ô´è=í…[ŠU~ûåK~{Êú:e 'ù»Zºñ´Zêi;¹i¡-Åtž-×tõ õçêªÛë;U·LšoL®º>åBËnpOÏw—g‚¦ôöNËöN›öìúií(MGvÊ€ýâ¹€É=<Åä(g²£|û¿ä?ÑU4êò.ïlF"qÕŸ¹ê©¾(ßqé²ßAÛ×ÑOiöÀküÀQk<œ:˜šwï0 ŸÀ›D ¤fŽ«?ùM$%Öuws¬‹… QØ\&“V3-­¦-­†‰mÏ ½Ìg©^µ …{YáöÛ}ñÛŠkŒËÚãÀ›OsñœO£1iÎkLù9Iô`/“¸À¯¿hïÊŒµr™1œ¹µ2œ±$öÎoMÃøj¡nÜ÷Œû¡ I~eI*\+.cïŽ5ƪ^M€ÊƒŽH‚à²0E6”e²U=•õ…ú¦Õw´²f¹k¥Vî{äë{P:"@Dhƒ¯¹þ9É\ÿ›ZFtZ¡¾@6ô,­°¿‚ bƒŽH€è # :舀7œX×Ýͱ®ššššš‰d6ýºó"O¬kr[¬‹Ëv+ËE{ÕpÇ×Íl:¿…ßì²£~ߦ²ó«ýÊÇ7Øx³ë ퟷ™åoá_o¯‰¡=‡Õ~Ñae[T5ÛÏ‘íª¶¾vU½L}¢^F…Q¸×˜n:ŸéÍÜÌô²Ó³‹=ß©~­¨©¡=% U_˜¾{äh¢{¤˜»:¬ßpXnÅv…›ŽÖÄÁ£ÖD±ªå“??œÌñœ“aë§¡Es¾¡%œ¾9Fƒª Ãåä¶X—!¶í¹!–·gÅv…›Î0Ù0Yh‰;¹ÐóX.dMX[äÝœLOÊÉT>±åá“9ÎdI†”>5šÒÃZÊ…¶¿ñ–¶Ÿûv+‰ñ©‰q]ÿÖûº7v³ åO­"¿…N¤ñÖo#Ðê÷í„o|ƒ=T-­¦-­nõJ·úM‘9Õ×r×yãƒðöô)>x>¾½þU^Rú‡)½×wÖâõMtÆÞ›è¬þ¶Ä»fË]«wË]ãÊkGÇ•š–ÍŒ¦…^õmæÃgmæVƒùx«!äφܔ¾X[½~ØêUEVïVE ͆žMdC䊋Ó=rtª{$œùþI83ÑygóD§Z¶áŒZ–é}ÈôJ܉Ä-$¾ÈŒ¿–ËŒ‘Æ[}‘Feh£ Q—‡uÊrØ:•Ô'G“耨 r¡“ WíXc\å<ºÕ9 Ýœˆ¼´Š¨ööº¨V©m“D +î8öwFûS¹Ôh*—¾’¼“¾’qfnfœ×¶s—zZROÛT‡†lªÊä/¶<ÜQËêN¨eæÁÝ9ó 'rRã‰x$Læuø~øy,Ž ÜÝtÍ>•t‰ñ,ð6C "ºèºˆÎo¿4à·C~ÈÿzÒþ>Ï¿Ä ixr5iÜ–H$·5-NkZª_‡KŒˆôØNj<6MËækùÂH›Wj¥Í‹Ýç°„3·Þ gÏFW¿8lÊÃC6¥q½¾¯ì^Ÿ§m ÉÓF]t^î^m–»+¯¾^æX®—QF×u*£tÆ0±í™a"ã|Ë8á¢Õ“ûñc&—q>¹šqvXþäë°°ƒ…>ÖôP£Î#芳i‰d¬áü—c ®ºRWEò…ËÇ7:,^ß9»×Wx%}Aª—m¡Ï·¾šÆÚfåL¥ ±G|³g ôÛ¾ÔôÛÏŸoz‚>[’µäåYÚ–/¨ß×[¿Üå)­¼Üõ_Z<á߈~Û)}¿-?ejY³*º¾SI~Ý3’|“ü‹ïóˆÞ>Øú'Í?Š1‘Ð9sBæœéîŒvS $oo4Ýï­¬¹PN²7² !öƶê@ÇåËù<é*ŠK¥É¿\ê‹‹ühÿpŸ°¹¸>o_o¼­Îxÿz]ïyyô’§ªíssssssæÁÝ¿7²Ï,Ž«îÄo\uú‰¦Ÿô\Rj=ïÞÓzØç':ïüÛD'ÝQQ~¤ŒÈ]ò—»,ñŸZâÙžMd`§Ÿ~Á›~Aé‡ûÓð#µtÃiµ”®"ùÓ=ýéžÒòNº'N÷hL›¿Õ˜/œþÁ s j '0™w½k2_ þ}ü Õô×éy¤¿Éé×ÐÓð?CO¥FiÔXx-Û7çæþù´ù ‘Gl,ñ}‡,ñ®áOã]﫾Ø:§˜Lç{§?KöNS,-¼Šâv>ff§³?PŒ¥ÈOú…ùÏOŸ¿J$Xjz¾öSZzýÄ{Ïô6åGn›’RRyIÜïX £|Çj£Ü<¸w¯y0ÿ úçÓ¹¹ñ+ßþmüŠðú¢§d¤1ú¯‘Æ|ÜËNg ³ŸÂ|ó/MòA£|û¿åT³$E`¶ý©ßêõ[Þú•W6J\Ž|å[ÿBâ wý$›~êO6QJšÐGçé.4-«ú½†{y¹?òþ¸ý_Œrzþ>_ ïÈ×ÞØÄ¯ßÛ¿N¿kU’]ùíïüöù~´w¯ylOˆ½±5Iy¾Ó-ù«­¾¸Ëößç){@¼#ÞV§q—þU ±ß/„ø{!c›|ÛDV=ÑyoçD'Å„ü1±ÿÕñ#~Þ»óGæØü#ùå9_ÚØ{¼;"CO¿ûŸÐSš²MB,ž^Y÷‰2B]‡ìódìHPª*r•Ä•H$ÉüÀ÷l"øèXZþÂ!ãîþ$òúºÀâ=P`¢îi²(² .ö ý‘ ûa3?V"±ånu\šøbÖ×+ °_N¨‘W¨™dSr$ßä"}²¥W)z æ/Fúbe)WCKy…<ÚççÿÀ1?áõµ8ùU‡jå¯ü…_þ|ÓS:_Ø@g·"„×o5€ú}½õËW±õ/$žðy1¦»ÔÊ%’áG£Ÿ ?ã{%ŸMBâ3»~ÅŽç…ëLdC¯è”’ÎÐë1}"åÞþ,´·BMòmÍr‘¿šëkqùÑþákí‹ëñV¼x»ã!üëõ¾_÷÷B*ÙÉc×ì ÿƃ ¿uÈòÇÖ¡à•k ^Ñ´l:_|þyÐíNÐOk´Yã>µÆÙ¿ÊÝòír7;šDI“i*÷¼ô®•rýÝ5üI´k˜r áâ]ÃG‚]ôvdiù ¦šFu·×Gu4-´ªÁ¾Å=Œi¾99¦¡<ÉI.Åv…«uhCÐØþ¨pÉ·+\ÓÙG¦_N”H;ŸM¦Ô¼®LþbË#ÜêLæ6šÌžö“Oûk®;·|{~! ©±VþJ'¯¦!$ ©¯“ú[-[÷Éü% ÔÒõŸ¨¥´ÐAaþb§.å-_þü–€àR_=s 1ýCCŒ=UÊ¸êƒÆUÉlFXþ¥ÙarÛsÃd~ÚË;ZYsËóû-{hmÊÛáæuÂÓ£~_oý ‘G ý‹OeTÙ¦Œúí—.ùí¾†ó'} Š>U›¢¶L¤{uú‹ñ™ý¼¨Œþ jÿ7ÝÃGÝÃÅRÒˆ`àÚ`€¦µÒ›ˆÆ´é©ð}ª4'¸¯Æ]þê¬/¾ò£ý#ÜoÅ‹·Ë=¿J«/É[ §ŽHZmÄ:uðÏÖ©ðÓ?¥5õ¿ª¿ýŒ©¿Ý¦}ΟŸ¿phõz Ò½éÞlèY,¿òíñ+ù´å\Ky“M̱dI2ÿXl/¿Wõ• ÍfʽΠݗ}žõ+Fývi; “§üú;ž°1{wï0{Céðl( ¥ÃÙ5n9dÓ–‰Õé/|íïó¨4ýs·7öU®ú2W=M$d¿„BëÚS;$à¸v'àk¸øÕXƒ5n9< F%ý»üÕV_¥ÊÏ/¾½ í¾úD¼/ÞV›‰Þ/^¯þ«%:"½cg÷yÇlkímk#7ÿiÔö¿{_»Ä&å´ˆ,O,¶A -ëÎn²Ówý*w½ÉüÁ“¹°²-ñ½{-qWýI«ž¾(Ò‚£´U9­ÐTjþ¥C_2'ºîlžèz›©š!›¤e†é!—·ŠÌÍLï ïœ}ÐÇ^©,E­B"¡‘δ 5ù#-ÇÛß> ïoï°ê°^™¿¿+1^¸4»°üK—§2Ж_FùöZ£Üë;óAe·Íá }û%pÎÏ9g(Ò’¿Ð¸Nk|ïÞù¯OD±ô6åOzðMÏUdõî|# ª½»%ª-V^Z¢Á]Bê®§.=5\õ}*W½p}Òª{´ç¿»GÉ>é.¿¥gù™l˜ÆÐJ¸äëÜõŸKÝõ’ BÛǽ\+jçíŽýìÎwòJúÀ¹€§˜6œÖ˜è£c0pãÇ` ú£!êWŒú-ìÒ*v"ú;žäË•MéɺòKïÓKQ­\"‘¥ê×1€/\ìïóˆ­çLOê—éô ÍKàno”žZ•Ô¥H³¹”—º-}C–A•×ßwhþ“´2þ^šüÕS_¥ÉÏ=ž¿=í¾úD¼åo¹½ïT£‰Þ/İÏåË‘Žýöÿrì§éÕº­÷u\¦]Ðî´ddÚþÆ[ u\¦Ï'ÓÎæU;Ö4¯¢áÖªÛêÏU·å®Õf¹käÑhÏÈ£r¾0´Ï{AQµ©"4(ZѷƬèË…g3¹ðئÑÏÆ6 É¿4ò;âUýÎDo12ãJ­ÌÎÜœ g4;·\×ì¤úR¯PŸP¯ IÁ+W¿ ^®¸3xa@?xAY½[ùÒ5;µÕì´Ä÷¶ÄmªCC6UáU¹pŽÉ…™ÜÌ2¹Å¿çóÍ¿4y* ‹¤¾«¢zñÛ/_òÛS†Ô×)EZòµtãiµÔÓvr“§­ð*gË5G½Bý¹z…êöúNÕí“æ›“«®O¹Ð²ÜÓ—¶ $-ÊÑ;},Û;mÚ³ëw¦=´ƒÙ)ö‹çv&÷𓣜É~hUârèÓ÷¿lþåó˽ƬpS\’3ö´ 4yÚhîiøjÇã*“y×Öò}xãUÞs~»Ì(­“Õ+6žQ¯ø¹Ÿ&Á© @§Yô4·­=|Ö¶öåU±mÏ ±êöÔïë¬ßÒäOÿ|ã ÿø6›É`¢øLiüŽK—ýŽ€ýò¥€½šý…¯=ð}‘R†'WSEŸÂ¨èÓ hoéZ̦ -?׿ñblè“g‡åÐP‡…ºf¸\EÝŽQÝ_߉êheyzBUÞßK“¿zê«4ùùÄ“·«ýÃWŸˆ·\â-÷÷åá_¯÷ýbùRC F¶zÍ;Z½ÇÕ:ó6+Ä£¥Õ´±¥Õ0±í™a¢—ù,ÕË@'€Ø„Óß?§iâ'Möä›͵jعåZÃNæÅƒ#Ì ó²\4°¼ä/¬¯å®Ø¨fÿ‚N€OsñœO£1iÎçÇçJô`/“¸À¯¿èΖkå2c8ske8cIì;lIÐyÆW u@%÷Œû¡@ h*%“›9Îäh]{ššçúòC÷9²k·9RZÎ4b+zvby¾´W§üÜëk¹ëöªÙ¿¨$èˆ€× —…„,þ P_ðö@+ÍÙö:kÛÃ4Ïh™—Ûäú`»ÉE =I܉ÄýV« õü þU5¼mïèˆ€× :­P_ÊóŠß“ÄÇ%É.hõü þUݼmï¿B•Ä‘ÑAG$@t8uDÒÛK-Ÿ9›Î/±IÇššššš:@%‰uÝÝë*fÜì”N‘ÚþÆ[Úþ¥–ϬUä—ØŒ4Þúm¤±z ™Ÿ:×õo½¯ëG•nö ÊÉ[15;~Ë…cÝw·Äº1B€Ê³DG¤¬ù­˜S­s¡ç±\¨]ÕÖ×®R¸Ûnº£5qð¨5‘ å˜ÜcÖúm§ôý6UTզВlªèúNUt$ùuÏHr¾ü2µ¬Ù0¹í†ÉŸK¤Ë—¨prnJÿp ¥oi5mli%IH*’°Pöà@ÇåËŽz™úD½Œrnõ~øa«Wxy«îò³5ÓoûRÓoS¸×˜n::®~è(ÌŸô߬0Ö6+òùËÔ²æfÅûkšLöÇ#Lv¡ôï¯iVPJÒ¿ßñí]¿£\öÌÝÞ@1–èˆÌ†žÅÄœjm:xÔ:ÅäfŽ39æsœy‘îyH÷dœ™›g÷hçíîQvzêx¢óûåK;M°M\½—¸®óhoé<óåÿåTñlèÙD6Dç 'çšöì~ß´GîZ½[î"I˜Ž0/âÁÄÁx°P6c —/5LtÞÙ<ÑI9;§ÆÓBÊ[m”&.œcrátïã@º·Ãrh¨ÃÒ=ztj¡”Ùðl&vÕõ)]uéÞôÍtoº'N÷(#Ê”‘Ö¡}lb§7í;lRK×}¢–RÍ’þƒ?Â홯½€b¼¶©Ù™Þ'LoÀqõ‡€ÃÓ6 ÷´ÉÝòír·´Yª–6w  v S×Þüëjåùc<øàãxÆèÉÝ«Ír7­ýWš<)}j4¥§éÛ®ºRWIB9wMt/(Ï+\u'~㪣ôtFÛÿîý¼<¥–·Z"‡åO¾ ýÝbþû-f&÷ãÇL®0¥ZVwB-ÓÇšêct†òwX9,±îÉm±nv}Eu}'ªë>žë¦UJIÿÎéžäü.àRËÞÞ6j_ד†Ô×Iým˜ÜöÜ0)i–h%¿ØÅx6#‘Hz_þ“H$ʨ²Mõw\Zïïð6œùÀÛàÐ}|áS¬ëTxÚš•«>œ:æÂ³™\X²J²Q²J"™äS_­T<{xÛ©#òU×R.4›É…¤Íµ é¼N+UDù‘*"‘H®K$É&æX²‰=–pqÌÞÝ;Ì^³w÷¬ÙKYnõ*·Ú:eÑ[§Ò’ôÍtQyŠñ³<•H˜ìÃSL–FçѯLî§SLNîZ}Vî*M#BÊ˾ûAsI/¶ü4±嶹«å¶ßî;çÿÿ·÷ÿ¡Meûþø¿{N7ñ8ˆBâUhŠ‚éUhÊxhÂ×ô8|Lõ€©˜êÀ4µ‡Iã€mÇË´Ñ˧“ôðqÒ ÚVŽÓv`´õ¢&Âhã—ã4~x{Hä*IAoR®Cwaü˜Ü;ƒ Øc6L¡ß?^Fw'M»wv’¦ú|€AvVV×^kíµwVÖ›yà€×<Àt•+™.âîœ?Q·Îø»ºuTâBÊ‹a˜ó‘6ñõ ~­ S³µ¦-ç´&šÐšmµ>êÆ2™÷¿o2·i»ßz$Ù•¼›|5’ŽÖæ£í_øŸ¢î*ŸçöŸ'½5 u2–+Ff”idÆÌ¿¥¬? Ðÿƒº‡;‚ºÌ04öMç~ÿ‘Îí˜9Í9f(~J•»ùŒÖÝÜ9t¨1’[žäv¾¥£ÐéOù¹™”ŸÆT*œŠU8©d©Ä]•_Ê\•™å¥}ðBrUvË\•ÔEHSÈiL¥ô³Î­¾@¦ewÍ·ë4‘Õ­ÕÉêF·|1ºÍº±å‚uã«x»f a~Hû&7Ê*äFÍš­ç5k^ÿÅYÃ$MÎ]÷\’aœ•Ýrg¥²gƒYÙCá=ö«×ÙÍGxqìiÎÁòó§ª^{©ªÞŸ¸;çǨ’C_! á]³†pº>+w+]t„MýpœM!—„ã&fÃÜDcÔÒÒ¥«›ÚÛw°Å¿Ðéyw°©™ÓlŠò0®ÄõÈ“|ÑõVßÓõ¦&RljBHøèøÔÑèxMïÎÇ5½¥þ¸þi_\?0vÁ20j j[ú\„o¹’a(L úÞïÕ¥S^¥–ÿ°º®_È´LG¤Â¹þ€Â9~ýæƒñëôà«eOÅjS~n&åo4ïi䇧0™¯æþ{ÌýVÕÑ“VUæ_IM¼- ﶞѺ­™!;†ONu û“w~ö'Cm¶‡Ú]‰»‰®Ë}µ—¥‡KnüBn Tß[¨æŸi㔥¥q Õ«tpËM×íÙ`\×Ðÿ§ ýTë¨>ô6}µ­·‰¾ ƒpö#mAû‘¸!>7$:c#‰Îè­ðÑ[cUW.ŽU Ǿ¶ ÇŠ¡ÓóîÐÈ+º5rjÍÜÍg´îfäÉJáü³aÎîx¸#ÜQ #c†ŸoÄ ômý–sÚzä?·LG$ujë·ßLÙÕ­ÕÉêìÛ˜ÝâOÞ{ÏŸ\:Mãµß¸ãµ[U-ƒ‹uD 70öµm`ÌÝÔWënÒÈ·œ×Èé¸ÂµÞ¬pI/V{ŠëbUÁMmª 1„v½0„’ŽÙpÒêU:Xî‡ÏX.éøùFÒÑjùt¬ÕÂïvÔ‡kŸêÃÔù‚¼f.Á0£U—¾­rVtËœÔ2еÐjùìv«e`ì¢m`,ó“4¨R¾õ|¥<ñçžÈÆYq:嬠V4Ùõ³wáø÷•20zÁ20Jc]éÕÛz㎷53$Ý«o0m­oHUîNè§'2?åÒ|¥uiÔAu“:HŸ¢ôÒÃӻ§SHÃä®&_ÇP³pö@æùÖ)?ÜP§¤wi´¾ÇþÝC]zΧӣºXz /î|Å¢ÐTšT²BÊ«×zVßkM——\#¯S7·©ƒÃ±o:þP‘[þ ¯oüy!ÞÖk×¼­üÙ }Ô0 ý|K‡ðôós¦×ú•¶×*üz¯SËë”éøåy]™3Ä^/¹Õgáõ àÝ‘ã‘þäÝ9Rzÿ‘>´tÈáø×¶á¸Î]}Oç¦)-™aÔÁÍíê Ò4=°òÃÐTAÎ?;Éùc†§gcêÈ O5 ˜÷4 ð¿*‹ /MTï99Õ1ânêQ¹›P½J‡FVÑ­‘)œŠU8-- ƒ>Ïí'>Oæò Dúúâf8¿* úD kŠÞ¥ë=ê{¼?êËü,0¢®ál_äÄÆ/%=õª‘o9¯‘›û÷ï4÷;+Ïh•¥ª¤#y7éHtýäMtµZŽ ¶Z¨ÕÍ i:xàCÓAןèüÉ›èd_>9ξŒø¢G|#m÷û½Ë¾dO±/cµ?öÅjYîÉg,—í¯Ÿšx3õ8sªræì~xóàáó F¶é„FF!i€Ï{ûŸWzÎ/žÅ‹;_±§>>Ù8År3§YŽ}Éžf_R)S É,_êx¢ã^Ûµ«^¥œÆM׸u÷jÜRò?·úFF«®]­¢ò¢˜Ó'#Ži)ç[jrK?ççXÎ/äzOùç’)¿³¢G嬠¹‰Î„?ÑùêŽ0xøÏ gðˆ½^ÄÖg±õ à2?????oî?ðGs?ÿH6Ïÿö¿ÏéQ;r+z$rkéðªÀ¦ªÀг‹Ÿ=ã§D~ ±Ú{cµúÐ/ô!Käð1K„žÖ¢¢»kTP ©ï_„Rß›Ìûß7™é5·ðÒéCµ?êCíC'íCóP’¨¾Y"G?·DèË ÕªuBê3d^_Ó/ÙSÓ/5²-ç4²ô»þ%ýnqâ/tz¤åÿ¯ÿò|u^52ãÚj™‘ZÑ•ÍÃDçOžtÕÁNw ðÃÇjcñZ~}à¿ë±yÿæ±Ñ],3þB„—R„„r¾ùª…H¿ØðT( ]ûüwùO)‹åR¹‚a†ž|1ôŒžŠ“ÿ™éáǼôÝ'·ó-bÓ/öz_Zºë°\‘þ””ëEx}έ¾¬”ÑmcÝFOk¡¶GûBm‘[öEn¥_£GÞ¼>±GnM¿|bŸ~™~eO-|¥þ=Š“ÿW(~#"iYàåÏ ƒ¾ë7ÿÓw][¿íRöõ¡|ž›|ú­»1rôóÆÿ]…K±[áâÇ@“(i2 Må^Þ¹¶Zá¤ÿ·¶Q 4³}踯}ˆÖ‚Ì-¼4Õ4Xss°†¦…¢ƒ»4Q}Õ~{fTÓÇFbzºH”Nån¥³aðÐG GL@6üëKéTìV:§SOŽO¿šø–p¼˜L8dFY…ÌXœø \5&óÞ­&s)¬I-9ý_f,W¼)Ó7£kc†ø7éu 5òM'.¹ ‘m>¡‘ÑB ™ñ:|!9ß·©NòÏ×0¹kÖ0™ž6ûžN^WÐüaýAyÍÿ”*¨jR=¶«W=¶±ªKgƪ”=ê&em1GO8…Ëÿ¥ëÃÒ«mæv¾¹ÉÜQ¿ï̦žž]¸6Ëýx–åhVæg ^¼å7Ñr¾«§®½9_nb.¹Øº‡üó}µÞÄ‹pjbáëâÆÍö˜&þ¹‰Dj"áOM4F,Ç#Ù·˜ËOþK©RÎW¬ÌÍ¥‡/túi-rêÐìj v ÑTnŠyüúwƯ§ÃÎ%Š{½ˆ¯oo¿e:"F/µn´]±n Tßý%P­ë}ÿñbë<òÑ¢à4Þ0Û5´>#­ìÆ?âªü‹ÚUi2ïÝb2/üD¹’a,‘C‡,Z­ŒÖ‘¤ÎÆ.XÆŒŠ=ëŠ\ÃçŽF …Úlµ£J•&ª“´l<}iI׺äÝdWÿØE[ÿu%#¯„)W2 tvÌtË3t}ѪX½Í}úÞæVKË`«%ó“ÑñÇû£ã´-@þâÏ== mYfTì.7*ÆÎï-ímh,]ÑŽ™Óœc†Z~ºÞi\gcäС…ãôI¶ðVÕÑÏ»—‰ /–:°þ@ºÓ$¨{¸#¨Ëv¾´Ä„«²[檤º«:+{Ô¥±¾§ šfÚrNk¢³­ÖGÛÍÑâ*­GÚî·áwŽÓUO? ò?E-?DKoBŒå †‘ešÅFL ÏÿÜ꛹oé(túS~n&å§1´4•,•¸«òK™«²ø×Knõ à]°LG¤ýˆí?ìGhzuMßÎÇ5}B¦áÐî´ôPžmƒš„cv2á¨[·gCÝ:š>£¾¯ùR}_á\oV8‡Ÿt?[$æËƒ‡.«ê&u€&¹({6˜•=œ.ÉùG·|1ºMJøÜ„Û'w…Û…Lb‚•"7®ÕÉ´É’vߎ[Ú}T^š5šnÍšæ»~ão¾ëÈ+áú/÷éû/«ë¨^]_Ú}º¿k÷Y"‡[,«úØ Uù)Ú|€åfþ=ûf5¹ÅŸ[z@8énîÓ»›3·+5Ûµ«[Üÿ&n –Ÿ®wlë9ÌÝtfÛb[ŠÕ¸wܬqkÖh¾Ô¬Qßßܦ¾_eÒ~[e¢M0¤„» 3¡EKº¦O¥º¦M÷ÿÁtvà¥W~H¯íÊE¯åžže9Š™ê?­’¼­nNçK³ èîlÝØrÁºñU<á]³†ðÂò»è±É² ¹Q³fëyÍš×qÖ0õMýõ÷¹$Ã8+»åÎJªÞc¿zÍc§íD¤änõML}{¾¥v=*ý4"ÞÝÔWën¢¹;³qÝž Æu&óþ¿þa;—ëE|}Î¥¾¼ ÊhÁHÚaÖk¿ñ½×NG5Ò…Ûn·×ôíü¯š>ÚÜ@ÈdÏRVß`ÚZß`ízau±_Ä»X”2Àê5¦½rqL«5i/¥ç'ÉŒôð—=\äÝ_}ÕËr£?yo­?i‰n±Dé8 ã+Gv€pãß“ql³¢¡#$²0E¾6Ó”¬^èˆ( Úàk¾wž™ï}[ÏV(/!~ƒ,€BCG$:" àÐ ð– ·?Ün/+++++c˜¹ÄJÇ/%=áöÉ]áv!Û­¬–Ü+…¿¸Òæé-tèõí>w”ï»tî(/@y-Ï'€úú_š¹÷öÕ·R³LGd³º©§Y])×tWÊ)»•® f¥‹Ž'»’w“]üðü‚YXH¿S–•ÉëÞÓ¥«&¿êd†ï>íÎVüöÆÏnÛ•.ån¥‹^£ŸlŒf†žžÜ8ØÓœƒåçOU½öRU½?qwÎ Yr¨‰4„wÍÂéú¬Ü­tÑ6õÃq6…\Ž›˜ sQKKc”®&jlgÜÁ?þB§G865sšMQâúøH\Ú’/ºÞê{º^áÛ­DǧŽFÇkzw>®yk7 ZýÊ•é-tÕ÷~¨FŽ |åUõ ¦­õ .Í_T.ÍÛ’þÕT^«=ÿ—Vüç“·;?…ÁýåÝ­ÿ¨o«=?—Ù5[á\@áWÝ<9®ÒÖogµõôUßjn¹`57̧ .ÿÜ„‹Âg«| }Ô0 ¬? d¾›šxJMPÑ.­cøäTǰ?yçg2Ôö`{¨M#ßr^#OvýìMv1.†a\ cÎ%=ÂÉ¿SÈê{=jÕÄ&V5A]S––Æ©˜>6CDIà&8–›0®Û³Á¸ÎÑr§£?0q7xU낺û›‚:&PÞÄWÂÙ´íGâ\|$Î%®Ç$®'É»I‡Á¹ë¢Á©™ÖÄ5ÓVõ±A«º8ñ:=Âiäݹ¹ÿgîwÎhÝ7ÓǸQeVâÚ÷φ9¸ïáŽpÓ>÷œir¯€· €Ô7j<¶«}Òô¯,)Ï'ÈOx—ë?¼ù¹ÌˆH·õŒÖmÕÖo¿©­§#²ºµ:YÝb³[üÉ{ïù“KÇ@£¼öw¼v«ªeЪ’’ܱ¯mcZwuAÒq…k½YáC~ÓÓÅžâºXUpS›*HG ¡]/ ¡¤c6œtà’(,÷Ãg,—tü|#éhµ|:Öjá_œúpíS}˜:WÂÌ%f´êÒW£UΊn™³‚ZºZ-ŸÝnµ Œ]´ Œe~’~±©”o=_)Ï_ü¹§§pœ§SÎ jµ^ýXRF/XFi¬(½z[oÜñ¶f†ŒëŸöÅõô{{z„©rwzDE#Ö¥‡§w…O… †É]ÿ0L¾Ž¡fáèøÌó­S~¸¡NIïÒhwý»‡»ôœ§:@?ƒñó3û €\Ê«Ni,¯SRÌttFüßü ½Ö¯´½Ö¥ãžÐÏ–T[ÒéY¾>¬^(ß•*_~úí¶+öFJ È6&]x~¦ÃÇG¶êàæ6uÊ7³Ez×ê¿Øû…Øü”Î1Ó-wÌt µ;†è !]h:á{:y]f:©þÓ½@Jýá×Roëµké8éSÔnä–þÕR^BÒç“lÏ'bê3ÚÃÕÚ^¡þ¯Ôó¹Øú/–Øú/ö~!½=Y)9®éOÞó'õ¡÷éCK‡ŽmŽëÜÕ÷tn²›FÜÜ®ò'YSñÃÐTGÎ?;Éùc†§gcêÈ O5 ˜÷4 ùª/$=¹¡‰ê#'§:FÜM=*wSiù»I#«èÖÈNÅ¿*œ ƒ––†AŸçöŸ'sy"}=r3œ_P}¢ Ð5HïÒõõ=Þõe~–~±¡®ál7*±ñKIOk|ËyÜÜ¿§¹ßYyFë¬,…²£Q¢‰®Ÿ¼‰®V˱ÁV µZ™!M|h:Hãâ?yìË'ÇÙ—_ô㈯c¤íþbŸ¢wÙ—ì)öe¬öǾX-Ë=ùŒå²ýááS/Âb¦BdN Ñ÷tèøãýÑqúæÒj9~»Õ—¾ ¨ª&u ³µ­ºòõh•%r¸Å‘~=¦ã¼vm´Šî/t'rLŸŒ8¦³…_:ý¥Y^¹¥Ï'ÙžOrËO´‡¥Pÿ…Cý_©çs)í¹Rê¿û…”öd…ÍÏÏÏÏÏ›ûüÑÜÏ?’ÍÄó¿ýïÄsªú‘[Ñ#‘[K‡W6P†ž]ütèÿ80?†Xí½±Z}èƒú%rø˜%Âj j£»kTP ©ï_„Rß›Ìûß7™é5·ôH§Õþ¨µ´ÍCI¢úf‰ýܡƅjÕ:!õ2¯Çé—ì©é—Ù–sYúÝÿ’~·8ñ:=Òk̸¶Zf¤Vk%ÊëM$:ò¤Ó¨þsú¦Å« ÇjùùÉ×cóþÍc£»@fü…Ÿí\æçy.æÜ³…r¾Âÿârñ?±/Œ_zy--ýhR®xs½ˆ‹_lx CÇéÚä¿ËŠ^¾¥å»²å˓ʂŽ_÷ý÷øuúRJ~Šm¤äO©ÉWûÉ?ßB··™Ìý‡™û»¦¿ˆuMg ã¬èþ'g…¤#©ïSÓ©ïeFY…Ì(üù0³þdæ¤Ø§M!é/åòZ:ýx>[Û…çç»Ö®Æö õeŸÏskÏ…§?·úŸÛý"_ÏW£ÛÆþ:ºRj{´/Ô¹õh_äVú5zäÍë{ä=÷¦_ÙS _©â\˜Úð¡6#"iýæï»~ó?}×µõÛ.¥§l/þ柇úz#G?o\ð[¢Â¥Ø­pñc I”4™‘¦N/ï\[­pÒÿÛ‡NÛ‡(ŽÞ>tÜ×>DkGæ–)hªi°æþæ` M -Ñ^çwÕ·Qí·gFµ´‚']$J§r·ÒÙ0xè#i¿x¼;ø×£Ò©Ø­tN§žŸ~5p=áx1™pÐã{qâ/tz¤×:“yïV“ÙÝ|Fën^á²s)v§²ËoòäÍèÔ˜!þMÌ@ÿ×È7X¸dF¶ù„FF dÆ_èð… ä|ó¿¸% „”¡{œ!¬jó§~×íÝj\Ç0sIiñçV “»f “üñJõÍÖ¤‘Ñůÿ™›×Iò-òU×H/•£l8 $Éÿw±–Dx~ŠmŠ™?…¨Ï…h?ùíy¡Û[>z>÷yo?ñy;†NF;†²…¤>ïÍ>/ÍÊ¢o"ZÓ¶oµ¦Ìï;¹]D[¿å\öoO¹¥¿4ËKlúñ|’ßú𮵇«½½BýÏ­¼¤ÿ)í¹ðôçVÿ…ß/V#A‘4;½qêãkœò?¿ýßþç´¦ÞÒŸêm>oêm¶ªŽž´ªdu2´ÕLÒ÷åŠ\cÈoz2éÜï?Ò¹¥¯ÛÅDõÊ1}2꘎úÿ©¸SwW{¾Q×^æ”g:¢5m¿©5'þB§G:ú‰¥·ùüÞÞæÒ_@P}’ÞÈ‹M==»pm–ûñ,ËÑ/x™Ÿ-txñ–_ªYÈùæ/?gNK[k&­^D4´bMí¡É2ã׿{0~=6Ÿk® 9ßX-{*VK)YøšmªÈ›òâ&æ’ù^7Š?QEÈt!áQ¾…(ßÌ.³l¯ óêçéÐb†ŸnÄ 4HJ~Šm¤åÏÊ×g±å%ö~‘[{›[}pVvË•´28ÿK~&ZJ…ž¼ö›¼vš”ݱ´,¸PÌëQxúK­¼rM¿¸öç]x>‘’ŸïZ{Xjõ¿ð|žßü—Öž‹«oŬÿ«Å2‘£ŒZ7Ú®X7ªïþ¨Öõ¾ÿx¹uiQOŸ˜mCZÏ‘ÿÈNG\•Q»*Mæ½[LæÌ̵D²Dhµ5úÅ’ø»`3*ö¬_l%&!é‘‚~) µ?Øj_mà]Au ×zVßkå/ÕL]BýcmýcÔ•Œ¼¦\É04²˜̦둖ûímîÓ÷6·ZZ[¹†V·É\ú]Zü¹§§8hË/£bw¹Q10v~oq·ÍKT5©‚tE8fNsŽjiéz¡q‘C‡Wž-¼UuôóÅÚ^±áÅRÖH?uwuÙΗ–hpUvË\•ôÀAw%geZÚúž?Ý¡:F:ÿ§c$½ò\"=Û@Jü)?7“òÓo¶é¯åÊô–«òK™«¨ë“Òöq´XJë‘¶û­GøïtUÒœ‹\)¦-ç´&úÑ1_«ÿçzAùæ·|3»Ì²½ò?Eë€Óÿiû2£bφ…O†bó“ß>8f:ã¿n¯úô ǹKÉŸR#¤¼ÄÞ/Äægnõžú¨K‘~lr¾˱ÆHÿØ ¥ŒÎ·1røXc¤ø×cné/òÊ-ýÂÛÛwçùDJ~®ööPØ÷…R¬ÿ…ƒçóü>ŸKiÏ…Ô·b>oOJÇ2‘ö#¶ÿ°¡éÌ5};×ô ™ÖA»ÓÒE’mC˜„cv2á¨[·gCÝ:žª¾¯ùR}_á\oV8‡Ÿt?[$æËƒ‡.«ê&u@Ù£nRö({6˜•=œ.ÉùG·|1º-·ôH‘Þq¯t÷$¹q­Nn¤¥µûvÜÒî£òÒ¬ÑtkÖРhßõó]G^ ×¹Oß™o¦ëQ»O÷wí>ZÖݪ>6hUg~Š6C`¹™ϾYMnñç–žb¢q‘ôà’¹%W©ñØ®]õØâ†ø7qµ´t½hd[Ïidî¦3ÛÛ’«Æ½ãf[³Fó¥fúþæ6õý*“öÛ*--%|n»ÂÑ¢]Ó§R]Ó¦ƒûÿ`:H;Ò+?¤×vå¢×ÆrOϲÅLõ‡V%ÎG~ŽýÕc£:ÿêþåÚ`Vº¨]’3v7õÕº›hîå†qÝž Æu&óþ¿þa¯8õgì¢Ç&7Ê*äFÍš­ç5k^—à¬a2ê›:ºØtšU@wsëÆ– Ö¯>Þ5k—öõ‚ò]ùòM8^„zªŒúž|õ \,=?½¶kW½¶¸áçqƒ²GiTöÔôéîÕôÕ›M[ê_‡3!·ü)5ÂËKìýBl~ŠE?IÒ†ôUPȧ¨Û1Xó÷÷‚5´ò;ÝAŠ=æ–þÒ)¯ÜÒ/¦ýy·žOrËÏÕÞ ÿ¾°ÚÛ+Ôÿ•z>—Òž‹©oÅxžŸ¥£ŒŒ¤f½öß{ít¤4“ °ÚÕ7˜¶Ö7B»^B]ìñ.y›pûÃíáöš¾ÿUÓG ´ó ¡?qç'‚&vÑ4+”ÈÊæ'͵ªÚ·ãfÕ>ÚI–ÆÔ¬–X]éÏ,¯Õžÿ«½> =\]í@©Ó^¹8¦Õš´—Òã=eFúGøË$.òî¯Z¹±\!7ú“÷Öú“–èáK”ŽÓ0¾ß¼ÅùP‚Æ=¾'ãtA¬4Q+¨»¿)=݉&X¹*¿ªrUšû÷ï4÷#—J!?i„ u ¬Æ.°ÒL¿ðòZíùú°²×ï»Ö^¼ËÊ‘+KÈÂù[ÌP^ ­$e=xì‚õ [7£c_µ&çÞÝ&'-ĸ†q½ÓÙ„üDyêÃ[WPÿW <Ÿ¯.˜š ðŽÂÔlx« # ‘Ppèˆ( pûÃíáö²²²²²2†™K GJ/ÅÆ/%=´*Šå´Ws œK¤— §WÔ ËtD6«›zšÕ•rMw¥œ¾N(]ÌJ§­ëùáù_<~ ù²¬L^÷ž.ýÕ‹ÿÕ(3|ÇðÉhÇðb)šK0Œ½ñ³ÛöF¥K¹[é¢×ÆèÇ'£™¡ƒºû›‚:CXÿÔNÇÿžN^Wßð§õ ljæ4›’’}ö4ç`ùùSU¯½TUïOÜóã WÉ¡.Cx×lº>Pý¡#lê‡ãÒêû†›˜ sQKKc”®,jlgÜÁ?þB§çÝAm#åa\‰ë‘'ù¢ë­¾§ë¾g_t|êht¼¦wçãšÞÕs–åÊô¾„ê{¿T—NÊVg~¼=–éˆT8×P8ǯß|0~¾TÄjÙS±ZÚÆ¾aм§ažÂd¾šûì1÷[UGOZU™%5ñ"´0¼ÛzFë¶f†ì>9Õ1ìOÞùÙŸ µ=ØjKt%î&º.÷Õ\懤. ãº=ŒëêÍz¿ÞL%ÑIt*œŠÝ gÃà_¥_,¹ñw ¹1P}om š¦S––Æ)T¯ÒÁMplº>4ôÿigCÿ«úЕ¸›èêmúj[oSæNO°4û‘¶ ýH܉èÊŠÞ ½5VuåâXÕpìkÛp¬˜ñ:=ï¼¢[#§ÖÌÝ|FënFž¬Î?æüᎇ;ÂQˆüXí–鈤Amýö›Úz:"«[«“ÕÙ-¶1»ÅŸ¼÷ž?¹t 4šÆk¿qÇk·ªZëˆn`ìkÛÀ˜»©¯Öݤ‘o9¯‘Óq…k½Yáâ‡d¹™Ó,Çùg'9ûÐñÛíCÔÍDé·ª>鱪Âÿî’ž.ö×Ū‚›ÚTA:bíza%³á¤Õ«t°ÜŸ±\Òñó¤£ÕòéX«…ßí¨×>Õ‡©óy%Ì\‚aF«.}5Zå¬è–9+èÊ¢k¡ÕòÙíVËÀØEÛÀXæ'iDR¥|ëùJyþâÏ==³âtÊYA­n²ëgïÂñï+e`ô‚e`”ƺҫ·õÆokfȸþi_\_ß`ÚZß!«ÜÑO?Nd~Ê¥ùJëÒ¨ƒê&u>E#§w…OU¦†É]ÿ0L¾Ž¡fáìÌó­S~¸¡NIïÒh}ý»‡»ôœOÇo,¯SRNÒ_¡¿(}D9ý|H¥“Ž©üäÏ«ð¶^»æmåÏNhøè£†)ù …ã‘þäÝ9Rzÿ‘>´tÈáø×¶á¸Î]}Oç¦)i™aÔÁÍíê ’5}!ᇡ©‚Ô±3<=3PG}ªaÀ¼§a€ÿUY[¿í[m½Î]ýtî± –1úÊG1Ç¿éŽ[UG?—Ö1ÊGÕ;FNNuŒ¸›zTî&T¯Ò¡‘Utkd §â_ΆAKKàÏsû‰Ï“¹¼‘¾¹ί ¨>Qè¤wézúïú2?K#’¨k8[GŒØø¥¤²^5ò-ç5rsÿþæ~gå­³²R•t$ï&‰®Ÿ¼‰®V˱ÁV µº™!M|h:Hãú?yìË'ÇÙ—_ô㈯c¤íþbŸ¢wÙ—ì)öe¬öǾX-Ë=ùŒå²ýááS/Âb¦*gNmΜ=Ào<ÜbÔÈ6ÐÈ($ÍðyoÿàóJÏù”.™ò;+zTÎ KžèLø¯®¸ÁÖ6àqêã“Sô#"û’=;¤R£ÏV^d´êÚµÑ*:_ÊÇôɈcZJ~@!ˆîˆô'îüäO¸›Ï™ÜÍÃϾùbøÙÒáûÇ.ÚúÇZ--ƒ­þqlËy,r+z$r+¦ÄôÑ[öGo±{šå¬[.X7òÃÓWú?M´¤¯ôÅóÏ%9ãTÓ_ÞLˆ.W2ŒÇvãŽÇæn>·×Ý\Vö»ueeò?¾W#ÿ#}Qì¿M¿M•idu4v¾cèd´cˆº®2ã_^±ûMø+_ç#|!Ðùkþþ^°¦kú4×5MW¯cº3¶°K.74fœÆ§ÛU™FVg·´ Ú-áŽÉ]¹Î0 ½öß{íî¦>½»‰r’âo:îkÏZ^¯Kៜü¹ÔÎàú(5":"iYàåÏ ƒ¾ë7ÿÓw][¿íRzÊöbáo>ðy¨±1rôóÆÿ]úšÁ&QÒd@šÊ½ ¼smµÂIÿo:lJQY«KQ¡µ#ÓŸ˜K0Lݺ=êÖÑDòùù_žÏÏÓlë9¬að£¤à Ô¬¹¿9XC_JQ±JÕ·Qí·gFµÔý=ý’=5ýRéTîV:å¥>¼ ø×£Ò©Ø­tN§žŸ~513áx1™pÈŒ² ™±8ñ:=¸jLæ½[MæRX/’Z~ú¿ÌX®xS¦oFׯ ñobú¿F¾éÄÂ%4²Í'42Z¨!3þB‡/!ç+ý¯Ð=6ãO6®Û»Õ¸Žaæ’ùH¿ar׬a2=ý=¼®þ ùÃúƒ4’:{-Ýr.ûÓ”A‘´úRãÔÇÿÖ8å~û¿ýÏùc"²ém>oêm¦ jh\ƒ”„¦×ï+W ÿá³è8”á¯I_b©k2_ÖˆÎýþ#›:FQ±V ªWŽé“QÇtÔ÷øO˜º+&ߨk/sÊ3Ñš¶ßÔšŠ¡ÓôQoóù½½Í¥¿ : úD ÿ³©§g®]Èr?že9š²ùÙB‡oùM´„œ¯”ЈKêìj v ÑÔxšl>~ý»ã×Óa3[x“~nb.¹Ø:›üô¿ÚoâE85±ð5_S§±)ÀJZ¦#r`ôÂáQëFÛëÆ@õÝ_ÕB¦;Ñ¢õ4>1Û54‹VvãqUþEíª4™÷n1™~¢\É0–È¡C–­VF«=Òö4mШسި ÐÙ¦6Œ:&èËóÂ5"/Ú†ãZÓ¶oóÑ1A#†Bí¶‡ÚQ¥JÕÉ^ëY}¯•¾T§k]òn²‹ ®dä•0åJ†¡‘ÎŽ™n¹c†®,Ú΢·¹OßÛœ¹ ‰Ž?Þ§m%òîé!hË2£bw¹Q10v~oioû£ ªšTAº¢3§9Ç Ý)èz§q‘C‡ŽÓ'ÙÂg[SXlx±ÔõÒtAÝÃA]¶óÕ‡>x¡¹*»e®JºßÑ]ÕYÙ£–¶¾gÊÏͤü4æ‘VÚ¥+ŽÚRWå—2WÖøµ¦-ç´&ú1Û4¥ÚdÞÿ¾ÉÜz¤í~ë~g7]Åôƒhqò g™ŽHûÛØÐôêš¾kúøûKfÛe’v§¥/Ù6¨I8f'š:MÓ¯Ô÷5_ªï+œëÍ çð³‘ÎÅVŸ¸Z©vµO­o0m­o0„v½0„ºØ/â],J`õÓ^¹8¦Õš´—Òó™dFúGøË$.òáÊå ¹ÑŸ¼·ÖŸ´D·X¢tœ†ñ•#»@¸qïɸùb¡#$²0Eþ6”¬Vèˆ( Úàk¾wž™ï}[ÏV(/!~ƒ,€BCG$:" àÐ ð– ·?Ün/+++++c˜¹ÄJÇ/%=áöÉ]áv!Û­¬–Ü+…¿¸Òæé-tèõí>w”ï»tî€ú€òZIxþA}(ÚhPcù–éˆlV7õ4«+åšîJ9¿ÒµÁ¬tÑñdWòn²‹ž_QVšß)ËÊäuïéÒM'?ã2Ãw ŸŒv g«ŽöÆÏnÛ•.ån¥‹^£ŸlŒ.V<“»Â톰þ©!ÌOöøÅq°§9ËÏŸªzí¥ªzâîœÍW 6Tv;©ÊÝJaS?gSÈ%ḉÙ07ѵ´4Féê¦ëËÁvÆlñã/tz„cS3§Ù¥!®Äõ¨-ù¢ë­¾§ë¾ÝJt|êht¼¦wçãš·v³ Õ¯\™ÞB'P}ï÷jäÊ·8 Ý> ýy×®÷úÓÖú—æ/*—æmIÿj*¯ÕžÿK+þóÏj¯« îG‹A}{›-Ó©p®? pŽ_¿ù`ü:U‚X-{*V›òs3)àyOà ?<…É|5÷Øcî·ªŽž´ª2ÿJjâEhax·õŒÖmÍ Ù1|rªcØŸ¼ó³?j{°=Ô–èJÜMt \œÞtpÿNÓA£bÏz£‚b¦OV]ùz´ª×zVßk•’}rãïrc úÞÚ@5ÿL§,-S¨^¥ƒ›àXn¸nÏ㺆þ?ílè§ZGõ§·é«m½MÔØpö#mAû‘¸!>7$:c#‰Îè­ðÑ[cUW.ŽU Ǿ¶ ÇŠ¡Ó#œF^Ñ­‘Skàn>£u7£¶¬ØµïŸ sþpÇÃáü¾ |…nÐþ¼;h€E &¸)PÓ>tüvûÒô¯,)íòsu•W)Ä Ö2‘Ô!¨­ß~S[OGduku²:»Å6f·ø“÷Þó'—ŽFyí7îxíVUËàb‘ Œ}ms7õÕº›4ò-ç5r:®p­7+\üÔë7<=7t µ;^5 ÔA`·´ Ú-£Ußž­’’ž.ö×Ū‚›ÚTA:bíza%³á¤Õ«t°ÜŸ±\Òñó¤£ÕòéX«…ßí¨×>Õ‡©n ¯„™K0ÌhÕ¥¯F«œÝ2gµ t-´Z>»Ýj»hËü$]›•ò­ç+åù‹?÷ô޳âtÊYA­V²ëgïÂñã+e`ô‚e`”ÆŠÒ«·õÆokfȸþi_\O¿‡§G˜*w§GÄSç~æ§\š¯´.:¨nRéS4b]zxzWøÔ i˜ÜõÃäëj޾Ï<ß:å‡ê”ô.v÷Ø¿{è±KÏyª }Ô0ÀÏÏ¥Gè‹-¯:¥±¼NI1ÓYÐñG|óg$ôZ¿ÒöZ—Ž_lxB#”©¶¤Ó³|}X½P¾¥P¾ôsº=‘käuêàæ6up8öMç¢rm–ϱñg›Z%dÊ•ðó]íÄÞèÛ¿=§œ¡ë±Ù3ÝrÇ }ã 't9ÒtÚ÷tòºÌtÒõE÷)õ_[¼­×®¥ã¤OQ»”[úWKy I?ž²µoÅ©…«ÏbÃúy÷£•½•æý¢ÔÚŸ’0?????oî?ðGs?ÿÈÒœÝÿä¬Ð‡jÔ‡„„Թߤsó‡ÚüK¨þ¢* úDP8ÿªpZ"G?·DRß¿¥¾ç‡Ÿ~Éžš~Iᇞ]ütè™F¶åœFFŸ¢ô':ò$:)|äVôHä…Ot&üéãüTÉŒ² ™q>Oè¯hMÛ¿Óšú/Ÿû¿ú/ÏCÉ EµÅdÞÿ¾É<~Ý÷ßã×3ë1ýò‰=}=Òÿé¤w'žû™xžíúâ_ûóó¿<ÏGüRÒSh–Èác–HûÐç‘ö¡•*/~žSëGÇ»¦¿ˆuMS[šù)j·Ómrj:õ=µ±ÔòS‡~fü Ã'üoÂ÷å^lýÉ-¼>ôÁ }ȪúÄeUQH:_Êá1›oî?tÈÜŸ¾Çýò|~~üúwÿ9~]zyÑ]2Püç@uºÝKM§¾§æß…ÅÆŸ[zè4*vÿÖ¨ ’¥ôP ̯?RÊ·t |ó[¾2ãÚj™QÈ+…ÕþØ«¥˜i§«8Ôþ Ô&%=Âó_lüÙÂ,ýÙÜηÔÏá÷£ôõ¸û·FÝ3ï/™Ql}ã‹Üz´/r‹ÞÍöTI×‘Çæý›Ç¶ð::tÈÜOך”úÆÏIŠ“ÿˆÞÍ–·BÒ_jå%<ýxþ{?-D}(t}¾ÐÏ{¸â~Tšíð4—Bû#Äè¶±¿Žn£R µ=Új£6!ý=òæõ‰=r‹¾w§_ÙS _©nPœ s&üA¨MtGäÄó¿ýïÄsš²M‰X:¼*°é„*@]‡üã”Aü(¡Ô4PUX$¹ Ã0ÌÂß¡ôƒ/½.¼ñWüßY×ô©T×4U Ê:.¼ãU*ìö¡•ën€¥Q}£ •º¿©P­RŸ!ózL_SoÓ…·ŠbÄ_èôH¯uBé Y^or€ÿpF1™9« §)(?ùïÒW)º dÆ_ˆðÙÎ%_âBÎWʃÈÂøŸØÆ/½¼––^U§\ñæz¿Øð†Žg>€òŸ"¤—o)@ù–Bù¦K¡\Á0CÏF¾z–ù“v!Ò“™ÿbãÏõ‹_.ç[jòÕ>óë[¡ÛóLÙ:ùè+(…¤#ôu‘~"þü™­¾ñsRìÓ¬ô—ry-~<ÿˆ­íù­Å©ÏÂç}Àý¨÷£Õx¿(µöGˆbvDŠØ5Ûç¹ýÄçi´ü¹aÐwýæú®kë·]JOÙ^,üÍ>OÒ‘¼›t4FŽ~Þá¿«p)v+\üh%Mf¤©Ü Â;×V+œôÿö¡Áö!І‹·÷µÑÚ‘üOÑê–þäÝ9’ÁÖÜ¿³þ M§®é£Jiªi°æþæ` M -Ñá¯ï<ªo£ÚoÏŒjcúØHLO‰Ò©Ü­t6 úháš§ ÿzT:»•ÎéÔ“ãÓ¯&$/&z¼.Nü…NôZg2ïÝj2—Âz‘ÔrÒÿeÆrÅ›¡‘ÑB™ñ:|!9ßüÅ/n !åEèžK›³ñ§Ê×íÝj\Ç0sIiñçV “»f “éieïéäuõÍÖ¤µŠŠ_ÿ37Ç“å[ å« ªšTAíêUm¬êÒ™±*eºIÙC[Ò¬”øsËÿÕ{¾…»^ Ñ>óï…nÏùèùßç½ýÄçí:íȺŽ °ðyo>ðyiYú¦£5mûVkÊü>%¥¾ië·œËþí,·ô—fy‰M?žŠ_ŠYŸ…„—Rß„·o¸â~´Úï¥Öþ”A‘´ÚBãÔÇÿÖ8å~û¿ýÏiM½¥?ÕÛ|ÞÔÛLÔÈêdi«K¤îËb>E«[t÷Öt´-IdüÑþÈ8½kí|då++i­ôu4 ˜¨^9¦OFÓQßã?E}ÈáùF]{Qßãý óŽhMÛojMʼn¿Ð鑎~bém>¿··9Ù•¼[ëEf£¨>Q¿/̦žž]¸Ö Ëýx–åè¶ÌÏ:¼xËoB%ä|ó—Ÿ3§Æ/­nC@´¢S¢ë'o¢+5ñ"œš¿þ݃ñëé°ÅXžœ¾¯6¸›xNM,|Ͷïç›òâ&æ’ù^×&s3=éáQ¾…(ß̯|Ù^ùŸ2Øc˜Høç&©‰„?5ѱkŒdßBpùöAZþ Ùoñ0ôÚÒŸ¾+½ˆ­bïG¹µç¹Õ7ge·ÜYIåø_23Ѻöôâµß|àµÓ¶™KËÂżޅ§¿ÔÊ+×ô‹kßÞ…çŸBׇR¾‰­obÛ7Üò{?*µög¥êçʵ'ù·LGäÀè…ãֶ+Ö껿ªu½ï?Ö-³é;-’Jã³mPC˺óÙ鈫ò/jW¥É¼w‹ÉœYù,‘C‡,gå­³’~Q¤8Æ.XÆh…&þg( ÿkP÷÷µAKjµ¿Ýj‘ž‰ôKf¨ýÁöP{i3P¤et©O׺äÝdWÿØE[ÿeXN¹’ah¤3-hM×-¯ÛÛܧïmnµ´ .v}EÇïŽg.Í.-þÜÓSô£ˆQ±»Ü¨;¿·¸ÛæˆE¿mÒá˜9Í9f¨¥¥ë…ÚÏÆÈ¡C ¿>‘lá­ª£Ÿ/v/^,u`ýôM=¨{¸#¨Ëv¾´Dƒ«²[檤8º+9+{ÔÎJéùIw¨Ž‘Îÿé¡úIEúoÅ)?7“òÓoà´.]ÔÖ¹*¿”¹*™"¢íã^­x¤í~ëþ]˜®Jús‘+Å´åœÖD?:ú¼·ðyK¿5Dù¢|3¿òe{MÿÝøH\O¹^š¾´”+Ff”i/¤}’ÿBâçç ?LæÜ ¾ÜηÔ©bïGüöÜ1Óÿuø>ýbóÄÖ7zª¤.Eú1[ÈùÒ×òþ±AKÿocäð±…wÒâ\ï¹¥¿tÊ+·ô oÏßçŸBׇR»úy÷#áç+ìû`)¶?…®ŸÅiJÁ2‘ö#¶ÿ°¡éÕ5};×ô –L»ÓR&êz«ï-Öq™pÌN&uëöl¨[GÉÕ÷5_ªï+œëÍ çð³‘Îág‹Ä|yððÀeu@ݤР_eϳ²‡óÏ%9ÿè¶‘/F·ñÃÇ ñ‘˜¡¦Ow/òÆ©£'§ÜMg´î&ê¹—ž‰éñò3  An\«“i’¾vߎ[Ú}T^š5šnÍšDæ»~ão¾ëÈ+áú/÷éû/«ë¨^]Ú}º¿k÷Y"‡[,«úØ Uù)ÎϱœŸåfþå–þýSlü¹¥§˜h\$ÝØÒ]¥Ëc»vÕc‹âßÄ ÔÒÒõ¢‘m=§‘¹›Îls7e~ªÆ½ãf[³Fó¥fúþæ6õý*“öÛ*“³¢GµØ²ÂÃç¶ $-úA+›îÿƒé í(G¯ü^Û•‹^Ë==Ër3ÕZ•8ù9öWêü«û—kƒYé¢vIJÌ4"ØÝÔWën¢¹ ”Æu{6×™Ìûwþú‡½âÔŸ±‹›Ü(«5k¶ž×¬y]‚³†É¨oêèb#ÐiVÝÍ­[.X7¾úTx׬!\Ú× ÊweËw.™ÑCíÅì±_½æ±{m×®zm¹µRò_Hü”'»‰ÂË\ηÔ¯bïG”qÃÏ7âeÒ¨ì¡ïõfÓ–ú×å%n¼ýäÙj96Øj¡®y!Ÿ¢nÇ`Íßß ÖÐÊòTCнç–þÒ)¯ÜÒ/¦}{·ž WJóþUèç=Ü„œ¯ðý~QšíO)(£#Ì{¼öß{ít¤4“ °ÚÕ7˜¶Ö7B»^B]ìñ.yPhþÄŸü šØH“ÅÆ@s¹ªöí¸Yµ}ùä8û’ư¬–X]éÏ,¯Õžÿ¨«…ôûÅj4¦½rqL«5i/¥ÇŸÊŒôð—I\äÝ_u×Êå ¹ÑŸ¼·ÖŸ´D·X¢tœ†ñ•£’Ó¸Ç÷d܃|(š*Èr3§YŽÖµ§©j®Á¯>r šû˜¹ÅL#’R/ºWç—ÒÒL¿ðòZíùúPj w¿€¥¡#`… YØAØÂÿ€òx×ÑJjÖƒÇ.X²u3:öU‹mrîÝmrÒBOŒ‹a×;M(/xç¡ýY)èˆXaè´By@¾Ð8¯Èø#&2Î0Ì~äÊ `1hVÊoPh舀‚CG$\ÖŽÈpûÃíáö²²²²²2†™Kˆ‰”6䲜¾HImÚ\"½½J‹­´ä#Þfbógéðůÿ°ú¯ß¦¿Ð-@~¯ å>[ê×Ú[ä'dS‘ºÞê{º^áËùGǧŽFÇkzw>®é]¹¬(W¦· Tßû} •ŠSÿ‹¯¾Á´µ¾Á¥ù‹Ê¥Y9¼XúWûõ›Ïô¯öòÍïõ%ýþ²²ùYüûãÛ]`e•ÄÔlÎ?æüᎇ;ÂïP84¶(Pܨi:~»}éGù¾Ý¤Ü_J!?‹yDý€BÔéÒ|¥uiÔAu“:(¯{O'¯kŒ~|²1ÊMp,·`L ½+|j!…4Lîú‡aòu 5é2'ßÅõOûâú:å‡ê”ôn¥\Ó])÷Ø¿{è±?ûÒé1–×)•.ån¥‹RE)dS?gSüðü)fÞÖk×¼­”~úTÃÀG5 H _jù#V©åØðbë¿ØôKç˜é–;f:†Ú‚C²ºµ:Y]fJøi2)²×zVßkM·r¼NÜܦǾéŽå÷|³¥_ÊõK㿨ìè*nV7õ4«3Û·d×ÏÞd¥“¾cød´cXzûP¸òå½`Uº6˜•.zõ¶Þ¸ãm•ž?bï¥v›Ÿ¹¶'BëC®÷ÇÜëÛÒç‹ûH'¨#2â‹~ñ±/ÙSìËXí}±Z–{òËuŒœœêá‡LM¼‹™Z˜915ñ"”š ã™“ï̃‡[̃Ù¦… µ=Øjóyoÿàó?ûRþ¹dÊï¬èQ9+]‰»‰®DgŸèTTŸ¨ ƒ‡ÿÜ0˜í³£U×®VQúéLÓ'#Ži)áK-¤(…ü^lý›þtGÌò¯™ñGÇïŽû“wçüÉVËñÛ­éeD#m÷;F¼¶kW½6JyôVøƒè­·î^;_å[ˆô›øÐtPá\@áLtþäMt²/Ÿg_R‹GçÅß0hy}E':c#‰ÎD×OÞD—Q±kÖ¨Èoû –ðüI:’w“Jy«åØ`«%³%Ï-ÄÞ/Jíþ"6?E·"ëƒØôK©ob¯/Ü¿ Góóóóóóæþ4÷ó„ÚüK¨ŽL¿dOM¿œçñؼóØè ê|þgççy>¿ !ácµ±áXíÒéþ¥§gi鯎åŠt~fƹ=¹%<%K‡/fþNéä”ü^Äž¯æþC‡Ìý]Ó_妅×ù¥Ï%Kå †z6òÅгÔ÷/B©ï q¾K§¿í ¿}[þ‰}aø|µRÚáå›èüÉ“èL§$øÏéN.)ù#ö~Qj÷±ù™ßö¶õAxü¯/Ü¿ÞV£ÛÆþ:º-Ôþ Ôj{´/Ô¹õh_äVú5zäÍë{ä}/N¿²§¾ÆjìÕRœü¿Bñ ©‘o:¡‘/8"Û|B#K:~¾‘t§Ã4fˆ3,žâwãú<7ø<†°þ©!œž ÷žN^g\·w«qÃÌ%³V[¿åœ¶^øßZ:|1ó‡?1PÈôF±áK!Š_ßÄž¯p´Ù…Ï{û‰ÏÛ1t2Ú‘·ußTAU“*è±]½ê±U]:3V¥ìQ7){ªêµ—ªê}žÛO|éç[ˆô )_~û¶0|E÷Âð…h W¾ —b·ÂEÿ—Ë2cú7ÓœÅæÏ‚w ¾Ð„ägníC¡ëCnñçv}­Þû¬,A‘lêéÙ…kK±ÜgYŽF¬ä#åÊåB¨ªOÔ¥Ó“¿ly“nb.¹Øºfq}|$®¯?hþ°þ ­¨ESiòàøõïŒ_O‡-Æö;ÅÌþÄ@!{׊ _ ùSÜú&Tf—n¶Wþ§œ•Ýrge«åÓ±V ¿JÈ5˜p¼˜L,Ód8°Ç<0‘ðÏM$R j¢1b9Öiœ²´4NI?kaéwý )_~û¶0üÌéåÖÚ“Ö>,Ÿ~iù“Ÿë%[û_èðRÚó|Õ7±íC¾êC!ê[!êO¡ÛgX½uD:fNsŽÚ: Ù•¼›ìr7ŸÑº›­ª£Ÿ[UÒ¡¬?þÔ=ÜÔe†¡±WúÐ/ô!We·ÌUI_¨hûgeÚY™¯LÑš¶œÓšh"[öÕ¾¸™”ŸÆ˜(œŠU8éë"}!tU~)så-=B3V#±ùSšù™Ù¥›í•ÂÓö^ûÍ^»cúd4û nü:Ï¿½öw¼Y·‰ ÚN#Ó[‹P§I¹‚adF™æÍh»\O¿Øë—ÊWç~ÿ‘έ}kŒ:Ôá‡7*ö¬7*:F:ÿ§c„›˜ sT+2Ç~Ji„¤_Jþ¿^„ç”ûE)Ü_Äæ§ØöAJ}’þÜâ/\ýÁý ²ÔYãÞq³Æ­Y£ùR³F}s›ú~•Iûm•‰Åç‡Ìm—RUpS›*Ø5}*Õ5m:¸ÿ¦ƒ´ƒ*½òCzmW.zm,÷ô,ËQÌÚ}º¿k÷»»Øf¹¡ÝBG·|1ºÍº±å‚uã«ó ïš5„) MÏt7õÕº›§>þ·Æ) c\·gƒqɼ§É\üâ,Nþ¬^bóGlxé»ôæíK’(\ëÍÙÇ:Qw7õ¨ÜMt òk{vsÉôˆ*eϳ²‡ÎÑc¿zÍc§íkŠ“~±×/ñØ®]õØâ†ø7q¥_³FÓ­Y£‘m=§‘¹›Îls7- ?öWºHh:í:M[|ðCJi„§?·üNlþˆ½_”ÚýEl~ o¤Ô!éÏ-þB×Ü¿ S-Ù0`ÞÓ0àµßøÞk§#È€Õ‹¦WíÛq³jítLcŽ~”/ ?Q€oL{åâ˜VkÒ^JÏÏ“é)W¼ »È»¿ZNJn,WÈþä½µþ¤%z¸Å¥ãáöÉ]áörd7ÀÛ‡FH¥&^t¯ÄŠœH?òù‰óÈôÖvD ™»R§¼kÞÚŽHt2”Žß  ÐÐ ‡ŽH(8tDP¸ýáöp{YYYYYÃÌ%#¥—‡bã—’žpûä®p»íÔJ)÷æé-àèõmªÏ¸B‹yu¿þÃê¿~ ›~Ü_J¹=ä'¼­–éˆlV7õ4«+åšîJ9ÝØ”® f¥‹Ž'»’w“]üðü…… ¿S–•ÉëÞÓ¥oü¦33|ÇðÉhÇpfz„ÇO¸‰Ù07ѵ´4Fé]J¿ƒíŒ;XéÙç`Os–Ÿ?UõÚKUõþÄÝ9?n%‡Ñ á]³†pº>+w+]t„MýpœM!—„+ôõ%6þB§çÝÁ¦fN³)Êø>>×#OòE×[}O×+|;µèøÔÑèxMïÎÇ5½+—êrez ¸@õ½ßªQŽPœú_|õ ¦­õ .Í_T.ÍjÌáÅÒ¿Ú¯ß|¦µ—o~¯/é÷—•ÍÏâßßîúPLËìš­p®? pŽ«nžWië·³Úzúªo5·\°š æÓ † —nÂEá³Ýü>ú¨a@X@È|75ñ"”š G¥‰ß~¤-h?çâ#q.q=ö q=éHÞM: Î] NÍ´&®™¶ª ZÕ¹eŸÜø;…ܨ¾×¨VMlbUÔåÑ8eiiœŠéc#1|/ ÜÇrÆu{6×9úOîtô&j]PwSPÇÊ›˜òJ¸B__bã/tzÞyE·Fnî?À™ûÝ3ZwÀÍô1ndÌJ´]þÙ0ç÷=ÜîcÚçž3íBî• ý@¨ n ÔxlWû<6¤åûv“r)…ü,æýõ ¿–鶞Ѻ­Úúí7µõtDV·V'«³[lcv‹?yï=réh4×~ãŽ×nUµ ZUù=ìñÏ%f´êÒW£UΊn™³‚R® njS[-ŸÝnµ Œ]´ ŒIùë]ì)®‹¥8éˆ!´ë…!”t̆“T¯ÒÁr?|ÆrIÇÏ7’ŽV˧c­þÊ>\ûT¦Îä•0¹__ô v¥|ëùJyþâ/Æõþ®qVœN9+ƾ¶ Œ%»~ö.ÿ¾RF/XFi¬+½z[oÜñ¶f†ŒëŸöÅõ4~!=BV¹;=¢Ÿ~œÈü”Kó•Ö¥QÕMê }ª1úñÉÆ¨ôðô®ð©…Ò0¹ë†É×1Ô,œ y¾uÊ7Ô)é]­ï±÷Ðc/~I¥Óc,¯SRÎSª(…™#Ðùó$¼­×®y[ù³ èçF)áK-Ä*µü^lý›~é3ÝrÇLÇP[°cˆî ™)á§YȤÈ^ëY}¯5Ý>È5ò:ups›:8û¦s8–ßóÍ–~)ׯðö“î”N~øl3œÄ¶…+_Ü_„Ü_Äæg®í‰Ðúëý1÷ú¶ôùâþ VŽkDú“wçüI}èýGúÐÒ!‡ã_Û†ã:wõ=›¦ d†Q7·«ƒtcHßbgÜ iÙâ§©…œŸ›áüª€êU aÀ¼'ݬSø¨ïñþ¨/_YIÕ;FNNuŒ¸›zTî&T¯Ò¡‘Utkd §â_ΆAKKàÏsû‰Ï“¹¼!åú¢_°©k8Ûƒ²Øø‹½¿W|ËyÜÜ¿§¹ßYyFë¬,…TÑ(×D×OÞDW«åØ`«…ZÝ̦ƒ>4¤qý‰ÎŸ¼‰Nöå“ãìˈ/úqÄ×1Òv±OÑ»ìKöû2Vûc_¬–åž|ÆrÙþŠðð©‰a1S 3§"Òì:ž9?ÀoñK*åŸK¦üΊ•³"Ñ•¸›èJt&ü‰ÎWWèàá?7 fûìhÕµk£U”~:SÇôɈcZJøRË)J!Ć[ÿŦ?ݳükfüÑñÇû£ãôdÛj9~»Õ"½Œ¨ã€Ú¯íÚU¯R½þ z«Æ­»WãÎWù"ýbÛφAËë+:ÑItR+mTìš5*òÛ>ˆ%<pÉv›Ÿ¢Û‘õAlú¥Ô7±×î_‚ÌÏÏÏÏÏ›ûüÑÜÏ?’ÍÄó¿ýïÄsºõFnEDn-^ØtBzvñÓ¡güãtàÇ«ý±7V«}ðB²D³DæÈ¨-üA¨Îhú%{jú¥F¶åœF–~÷Á¿¤ßÏ}¨öG}¨}èD }hJÕ7Käèç–=|P Z'¤>Cq®/±ñÿzs.ü¿þËóÕyÕÈŒk«eFj·W6?yÒiTÿ9ý%„>VŽÕòëÿ]Íû7îb™ñ"¼”ú $¼óÍW ”^ŸÓ_Ë K³ÖXxøbæOq®‚•Í)ù)¼þˆ=_)Ìý‡™û»¦¿ˆuM ¯óKŸK:—Ê 3ôlä‹¡g©ï_„Rßâ|—N!Ú~û¶0üûÂðùj¤´?ÂË÷éù™ßö¶õAxü¯/Ü¿àí0ºm쯣Ûè›u¨íѾP[äÖ£}‘[é×è‘7¯Oì‘[tßO¿²§¾RÿÅÉÿ+¿ˆ‘4‚Œ~óô]¿ùŸ¾ëÚúm—ÒS¶ óÏC¿.6FŽ~Þá¿«p)v+\üh%M¤©ÖË¥gÉøk«Nú¿Ò©Ø­tN§žŸ~5ð>áx1™pÈŒ² ™Qzg.M5 ÖÜ߬¡i¡èà.MTßFµßžÕÒ žt‘(ÊÝJgÃà¡ò÷ üÛ­Ð×—Øø‹y½¿›Wɼw«Éìn>£u7¯pÝs)v+^­J,3–+Þ”é›Ñµ1Cü›˜þ¯‘o:±pÉló ŒjÈŒ¿Ðá AÈù¿¤èmëŸÂé©pïéäuÆu{·×1Ì\r©Z·å\ö§ ±á‹™?™›éå7|)äOñë›ØóŽžß|ÞÛO|ÞŽ¡“ÑŽ¡|Ŭ ªšTAíêUm¬êÒ™±*eºIÙC[Òµôó-DúŶŸ à ]âFJûP¸òÅýEz~æÖ>º>än××꽓 ŽHZ½¢qêãkœò?¿ýßþç´¦ÞÒŸêm>oêm¶ªŽž´ªdu2´ÕjÄÆOCÔõ9%“ŽhMÛojMùJÎýþ#[úºIo\Ʀžž]¸öËýx–åhDIæg ^¼å—Þr¾ùËÝ7éá&æ’‹-¢Bk7×4XVÔ¢©Ž4ypüúwƯ§Ã.µŠY1ëC¾þb ½kņ/…ü)n}*³K7Ûë‚–­²[•£ùPB®Aú‰kéT™ì1L$üs‰ÔDŸšhŒXŽ5FhKCég-,ýâ®_±íçÂð3§—[kOZû°|ú¥åO~®—·éþ"6?Ŷùª…¨o…¨?…nŸV‹e:"F/µn´]±n Tßý%P­ë}ÿñbë<òÑ¢¿þäŸýÉlÔвÖüG:âªü‹ÚUi2ïÝb2K‰ŸnN4R’¦u'iÕžÞæ>}os«¥e0+éЈ¡Pûƒí¡vT©ÒDu†–§‡’t­KÞMvõ]´õQW2òJ˜Ü¯/Zm‡–ÙÎ_üÅ»ÞßM´e™Q±»Ü¨;¿·´·ý¡±HtE;fNsŽZÚŸ®w×Ù9thá8z’-¼UuôóÅî5bË¥¬?þÔ=ÜÔe;_ZbÂUÙ-sUÒ*º«:+{Ôù[ßSkÚrNk¢‰lÙWûâfR~cB+óÒJm¯«òK™«¨ë3V#±ùSšù™Ù¥›í•ÂÓS×~ó×N?F ©óükpé¹;TÛiäczkê4)W0ŒÌ(ÓH¡/<ýb¯_±í'…7*ö¬7*:F:ÿ§c$½Îû\"=›*_íƒôKÉÜ_¤ç§ØöAJ}’þÜâ/\ýÁý €,Ói?bûûšþ\Ó·óqMŸiD´;-ݤ³mP“pÌN&uëöl¨[GÃãÕ÷5_ªï+œëÍ çð³‘ÎágÙR%$~Ò¹OßYX@ I1Ú}º¿k÷Y"‡[,«úØ U-=Ãí“»ÂíÂ'UAñÉkur#-5­Ý·ã–v•—f¦[³†¶Oñ]¿ñ7ßuä•p¹]_œŸc9?ËÍü{öÍjr‹¿8×û»ŒÆEº›ûôîfá[Š­íÚU-nˆ7({6˜•=t½kd[Ïidî¦3ÛÛR¬Æ½ãf[³Fó¥fúþæ6õý*“öÛ*-r/%|n»”Ò¢%]Ó§R]Ó¦ƒûÿ`:H;¨Ò+?¤×vå¢×ÆrOϲÅLõߨØýÛÅ6‹È úÝ6òÅè6ëÆ– Ö¯Î+¼kÖðjžPv7õÕº›h.…1®Û³Á¸ÎdÞ¿3û…SœüY½ÄæØðÒwéÍ/úÉŠ6$Q¸Ö›³u¢:O›Ò5ȯíÙÍ%Ó#ª¨ý¡sôد^óØiûšâ¤_ìõ›[ûé±ýÕc£{:Ýi×izî⇔Ò>OnùƒûK¶û‹ØüÞ>H©BÒŸ[ü…®?¸”Ñ‚‘´Ã¬×~ã{¯Ž k¤ ·?Ün¯éÛù_5}´”¸ØÉP¥¦¾Á´µ¾ÁÚõÂêb¿ˆw±(eX-h.NÕ¾7«öÑNÇ4æéGùòõÞecÚ+Ç´Z“öRzþÌHÿH¹âMØEÞýÕ7\¹±\!7ú“÷Öú“–èáK”ŽÓ0¾rd77îñ=÷ `5¢R©‰Ý©’Óý¶¦ùƒüÄù:"@!Ó*Wj#@y@é@G$@Ñ_ó½óÌ|ïÛzŽè´Byñd:" àÐ ‡ŽH€·\¸ýáöp{YYYYYÃÌ%V:~)é ·Oî · Ùneµä^)üÅ•6—Ho¡C¯o÷¹£|q5¡¼åUœ+ôí~>y×®ßR«-hÐ>”rûPúõy™ŽÈfuSO³ºR®é®”SÆ)]ÌJOv%ï&»øáù}a¥ÿ²¬L^÷ž.õü¬É ß1|2Ú1œ™áñó5 ˜÷4 (]ÊÝJW~ ÃÁžæ,?ªêµ—ªêý‰»s~<°•`s6¹+ÜnE›€>?àIDATïš5„ÓõY¹[é¢#lê‡ãl ¹$71æ&£––Æ(]}Ô>8ØÎ¸ƒ-~ü…Npljæ4›¢4Äõñ‘¸µ%_t½Õ÷t½Â·[‰ŽOŽ×ôî|\óÖn´ú•+Ó[èªïý>PAù–¦w£=y›¯ÇúÓÖú—æ/*—æmIÿj*¯ÕžÿK+þóÉj¯o·Ò¸_ >¼»íCé[¦#Rá\@á¿~óÁøuʸX-{*V›òs3)àyOà ?<…É|5÷Øcî·ªŽž´ª2ÿJjâEhax·õŒÖm],d.ñ»ËŠËƒ‡.ç7ûäÆß)äÆ@õ½µj~J§,-S¸äJ7Á±Ü„qÝž Æu ýÚÙÐOµ.Ñ•¸›èêmúj[o5Ö œýH[Ð~$nˆÄ ‰ÎØH¢3z+üAôÖXÕ•‹cUñ¯mñbÆ_èô§‘WtkäÔ¸›ÏhÝͨ-+víûgÜ?ÜñpG¸#z@ ´'« €Ô7jÚ‡ŽßnBú‘þ•%¥=A~¾Ýå ð.ÔŸe:"©CP[¿ý¦¶žŽÈêÖêduv‹mÌnñ'ï½çO.òÚoÜñÚ­ª–ÁÅ: ¥kãñÛ­ZÓÖsZS~ÿz{ŠëbUÁMmª 1„v½0„’ŽÙpÒK¨t°ÜŸ±\Òñó¤£ÕòéX«…ßí¨×>Õ‡©óy%Ì\‚aF«.}5Zå¬è–9+¨e k¡ÕòÙíVËÀØEÛÀXæ'éžJùÖó•òüÅŸ{z ÇYq:å¬ûÚ60–ìúÙ»püøJ½`¥±¢ôêm½qÇÛš2®Ú×Óïíé¦ÊÝéñÔ¹Ÿù)—æ+­K£ª›ÔAúTcôã“Qéáé]áSK(¤ar×? “¯c¨Y8š>ó|ë”n¨SÒ»4ÚÝcÿî¡Ç.=ç©4 |ôQÃ??³ÍÈ­¼ê”Æò:%ÅLgAgÄñÍŸ‘ÐkýJÛk]:~±á P¦Ú’NÏòõaõBù®lùн~…ç§´öDhü«Øû=½óËKÜܦÒõRˆ©dŽ™n¹c¦c¨-Ø1DOéúOÓåÞÓÉë2ÓIõŸê’”òå_eÞÖk×ÒqÒ§¨ÝÈ-ý«¥¼„¤Ï'ÙÚ“âÔ‡ÂÕg±á ý<†ûÅjlÏÑ>¬Ô÷—šŸŸŸŸŸ7÷ø£¹ŸdiΊîrVèCµ?êCBBêÜï?Ò¹ùÇCmþ%ÔFQP}¢ (œŠU8-‘£Ÿ["©ï_„Rß OIfü™øq~þ—çóy–èLøZÓöï´¦þËçþ¯þËóP2¨FQ3™÷¿o2_÷ý÷øu*5äXÓ/ŸØ§_ÒÕDÿ§6„Þxîÿeâ¹Ì(«s»ÅÆ/%=…f‰>f‰´}iZ©òâç9µ™t¼kú‹X×´F¶åœF–ù)jWÓmrj:õ}¢ó'O¢“Z~êÐÏŒaø„ÿMøã¾\Ë­?¹…ׇ>x¡YUŸ¸¬* IçKù ýÞaTìYoT˜û2÷§ïq¿<ŸŸ¿þÝŽ_—^^Ó/ÙSÓ/ÕÁT§Û½Ôtê{Êaþ]Rlü¹¥‡®A£b÷o *YJµÀüú#¥|KÊ7¿å+3®­–…¼ævý ÏÏÜÒŸ[ü¥Føù ¿_¤¯—Ý¿5*èþ˜ÙþgþE±õ/rëѾÈ-z7ÛSÕsÍû7ma=?tÈÜOׂ”òåç$ÅIùÃ7[Þ I©•—ðôãùDìý®õ¡ÐõYløB?½›÷‹Òl„§íC¾êóÒF·ýut[¨-üA¨-Ôöh_¨ÚœôkôÈ›×'öÈ-úÞ~eO-|ÕþØ«¥8ž]øƒP›èŽÈ‰çû߉ç4e›±txU`Ó U`èÙÅO‡žñSñc „RVRU’YÙâÏWs/¦Q«ýQj:X¹îXÕ7j8¨û›êÕ:!õ4¯:þØSÓ/ù7ƒ…×Z1â/tz¤×:!Œ…,¯79Àø£‡žÌœ‰ÕƆcµüüä¿K_Õè.!Âg;—|ÝÈ…œ¯”{ÇÂøŸØÆ/½¼––^¨\ñæz¿Øð†ŽÓµÉ—ÿ!½|KÊweË7¿×of~æ7ýKÇ_jòÕ~òëC¡ÛÛLÙ:ùè+.…¤#ôõ’~Âþ|˜­|ù9)öiSHúK¹¼–N?žOÄÖöüÖ‡âÔgáá‹û<önÝ/Vc{Žö¡øß_ŠÙ)b×lŸçöŸ§aÐòç†Aßõ›ÿé»®­ßv)=e{±ð7ø6ÓÓE¢t*w+ ƒ‡>Z¸æ)d£p®­V8éÿJ§b·Ò9zr|úÕÄ„ãÅdÂAïʼn¿Ðé‘^ëLæ½[MæRX/’Ú^ú¿ÌX®x“'o¦ Ä ñobú¿F¾éÄÂ% 4²Í'42Zè 3þB‡/!盿øÅ-!¤¼Ý aýSC˜?UÖ¸nïVã:†™KJ‹?·úc˜Ü5k˜LOKyO'¯«?hþ°þ ­}SüúŸ¹Ùôð(ß•-ßÜ®ßÜòS¸BÇ_¸ú\ˆüç·ç…noùèùÜç½ýÄçí:íȺŽ €ðyo>ðyiÙú&¢5mûVkÊü¾#¥|µõ[Îeÿö”[úK³¼Ä¦Ï'ůŬÏBÂK©oâï×ïÖýbµ·çhò{½”A‘´šCãÔÇÿÖ8å~û¿ýÏiM½¥?ÕÛ|ÞÔÛLÈÈêdYž·*/tübÑðWéët@1Ñ—FÇôɨc:ê{ü§¨y"<ߨk/ê{¼a¾Ñ­iûÍ\We¡Ó#ýÄÒÛ|~oos²+y·4Ö‹ÌFP}¢~5^˜M==»pm–ûñ,ËÑ/~™Ÿ-txñ–ß„JÈùæ/?gNç{­Z‡:€hŨD×OÞDWjâE851~ý»ã×Óa‹±Ü5ÿ|_mp7ñ"œšXøšmßÀ7åÅMÌ%ó½Î`æfwÒã| Q¾™_)³½Š½~¥åçòíI1Ë«õYly‰½_äÖÞ ¯üO9+»åÎJšˆÇÿ›I#ßr^#§ç¯ýæ¯}´êÊ×£UKËÂÅ,_áé/µòÊ5ýâÚŸwáù¤Ðõ¡”ï/bë›øûõ»u¿(µöa¥ê¾¿”Že:"F/µn´]±n Tßý%P­ë}ÿ±n™MÄiQUòÎÏþd¶ dhYwþ#;qUþEíª4™÷n1™¥ÄÏG‹†rþ¹dú÷yºüòµ˜:ýRj°=Ô^Ê…ý.£:Ók=«ïµR£Ÿ®uɻɮþ±‹¶þ1þJ °œr%ÃÐHdZ0›FÐr¹½Í}úÞæVKË`«%ó“ÑñÇû£ã™K¿K‹?÷ômùeTì.7*ÆÎï-î¶9b©‚ª&U®ÇÌiÎ1C­%]/4®³1rèÐbãг…·ªŽ~¾X[-6¼XêÀúé›tP÷pGP—í|i‰We·ÌUI|tWrVö¨•Òó“ÖìéüŸŽªŸôWh¶”øS~n&å§ßÌi%\º"¨­sU~)sU2E¤p­7+\¯Ö <Òv¿õ¿ó®Jús‘+Å´åœÖD‘|ÞÛ?ø¼¥ß¢| Q¾™_)³½Š½~¥ä§ö¤ÔÊK !å%ö~Á//ÇLgü×áûô‹Í^(<=õQ—"ýØ,ä|#–c‘þ±AKÿocäð±…wºâ”oné/òÊ-ýÂÛÛwçù¤Ðõ¡ÔÚ«â<½÷ aß§J±}(týÁ÷—|]/…¶LG¤ýˆí?ìGhúsMßÎÇ5}B†=Óî´T t½Õ÷ë¸L8f'Žºu{6Ô­£áÇêûš/Õ÷Îõf…søÙHçð³l©?ŸüòJù “úÿïõÞC”WÊÿH¯Ò31½ã^~&¹@!Èkur£?ywΟÔîÛqK»ÊK³FÓ­YC“È|×oüÍwy%\ÿå>}ÿeU`ýU@Ù£nRöh÷éþ®Ýg‰n±D¬êcƒVuæ§8?Çr~–›ùw–[ú÷=±ñç–žb¢q‘tcNwU”.íÚU-nˆ7({6˜•=t½hd[Ïidî¦3ÛÜM™Ÿªqï¸YãÖ¬Ñ|©Y£¾¿¹M}¿Ê¤ý¶Êä¬èQ-¶l…ðð¹í2I‹~tMŸJuM›îÿƒé ípG¯ü^Û•‹^Ë==Ër3ÕZ„;ù9öWê<ÕOÚõÚ%)1Óˆ`wS_­»‰æ.Pn×íÙ`\g2ïß™ý‡½BÖŸ±‹›Ü(«5k¶ž×¬y]‚³†É¨oêèb#ÐiVÁè¶‘/F·Y7¶\°n|õ©ð®YC¸´¯”ïJ–¯ðëWJ~ iOJ³¼r#¼¼ÄÞ/¼¶kW½¶¸áçqƒ²GiTöÔôéîÕôÕ›M[ê_ç¸ñb|ô“d«åØ`«…ºÎ…|Šºƒ5/XC+¿S‰ÿzÌ-ý¥S^¹¥_Lûón=Ÿ®>”f{Uèç±·ã~!üûÔjoÏÑ>¬ì÷—Â)£#Ì{¼öß{ít¤” °zÕ7˜¶Ö7B»^B]ìñ.yàOÜùÉŸ ‰Š49Ql 4תjߎ›UûØ—O޳/iÌÈjÉÕ•þÌòZíùúP¸öyRúÆ´W.Žiµ&í¥ôøY™‘þ‘rÅ›°‹¼û«îf¹±\!7ú“÷Öú“–èáK”ŽÓ0¾rd7@1{|OÆ=Èx7ÑÄC–›9Ír´îú¨a@Jøtz>ÜP§¤0Þcÿî¡Ç^úÅYjù#6¼¼î=˜©µbÓ/c¦[î˜éj v ÉêÖêdu™)á§YȤÈ^ëY}¯UT7©ƒ”rups›:8û¦s8–ßóÍ–~)×/ÿ¢²£«¸YÝÔÓ¬æ&8–[0æ.Ùõ³7ÙEéä‡ï>í–Þ>®|ùF/XF•® f¥‹^½­7îx[¥çqi¾Òº4éúðžN^×ýødcTzx±×…4Lîú‡aòu 5é„Lî^:?smO„Ö±é—^ß–>_Ü¿V¸#2åŸK¦üΊ•³"Ñ•¸›èJt&ü‰NU@õ‰*Ð0xøÏ ƒÙ>;ZuíÚhU¨íÁöPM3tLŸŒ8¦¥„7n1jd›Nhd©‰¡Ô…÷yoÿà󮮢-…ü>5ñ"œëÔZ!éOwÄ,ÿštüñþè¸?ywΟlµ¿Ýj‘^FÔqÐ1Òv¿cÄk»vÕk£”Go…?ˆÞªqëîÕ¸óU¾…H¿éàMÎõÎDçOÞD'ûòÉqöeÄý8â£óâ‡o´¼¾¢±‘Dg¢ë'o¢Ë¨Ø5kTä·}Kxþ$É»I¥¼Õrl°ÕÒ1rrjá™æ–?„Þe_²§Ø—±Úûbµ,÷ä3–ËöW„‡{}eNu§«˜Ž/=¹[H~ŠnDÖ±é—RßÄ^_¸À;j~~~~~ÞÜàæ~þ)Bmþ%Ô–Ží—çâcHu,W,L?æÈ­è‘È-á)Y:|¬66«¥Ó/ÙSÓ/ùïzlÞ¿ylRΨ8J'¤ä§ðú#ö|¥0÷:dîïšþ"Ö5-¼Î/}.é\*W0Ìг‘/†ž¥¾J}_ˆó]:ýbó_HùRÜbáŸØ†ÏWû ¥ý^¾‰ÎŸ<‰ÎtJ‚ÿœîä’’?üø ^Jþ"?óÛÞ¢>_øõ…û”¦ÑmcÝj j µ=Új‹Üz´/r+ý=òæõ‰=r‹¾×§_ÙS _cµ?öÆj)Nþ_¡øWxD¤ÏsóÏcëŸÂé©pïéäuÆu{·×1Ì\2ûgµõ[Îië…ÿ­¥ÃÇ ñobú¿F¾é„FÎW#Û|B#Ë×Yó' ™Þ(6|)äO1ó3·óŽ6»ðyo?ñy;†NF;ò¶î›*¨jR=¶«W=¶±ªKgƪ”=ê&eOU½öRU½Ïsû‰Ï#ý| ‘~!å›tü|#éX,|E÷Âð…h W¾ —b·ÂEÿ—Ë2cú7ÓœÅæÏ‚w ¾Ð„ägníC¡ëCnñçv}­Þû€êˆ,W¦ÿÇMÌ%[×,®ÄõõÍÖ¤µhª#M¿þ݃ñëé°…Ý^€¨ªOÔú?›zzváZ`,÷ãY–Ë×ßâO ²w­Øð¥?ÅÌOá2»t³½ò?å¬ì–;+[-ŸŽµZøPÙê<_Âñb2±LgyàÀóÀDÂ?7‘HM$ü©‰ÆˆåXc¤qÊÒÒ8%ý¬…¥_Üõ+¤|iDÞbágN/·Öž´öaùôKËŸü\/üüYðnÃKiÏóUßĶùª…¨o…¨?…nŸVJA:"µ¦-ç´&šÈ–}µ/n&å§1& §â_NúºH_]•_Ê\•ÅÌ›¦}ðBrUvË\•ô…“¶×pVö¨EMO©›?¥™Ÿ™]ºÙ^)ÝßµûŒŠÝ¿]l3wØü^ú.½ùE{àÒ†$ ×zsö±NTçÝM=*w“éàþ?˜òk{vsÉôˆ*eϳ²‡ÎÑc¿zÍc§íkŠ“~±×/ñØ®]õØâ†ø7q¥_³FÓ­Y£‘m=§‘¹›Îls7- ?öWºHh:í:M[|ðCJi„§?·üNlþ÷Ž›5nÍÍ—š5êû›ÛÔ÷«LÚo«L´‰Š”ð¹]_ªà¦6U°kúTªkšê6íÐM¯RòSxû ¥>InñºþàþoŸ2Z0²aÀ¼§aÀk¿ñ½×NG5ð.£éÃUûvܬÚG;Ó˜#¤å ÈOÔx›Œi¯\ÓjMÚKéù…2#ý#åŠ7ay÷WËaÉå ¹ÑŸ¼·ÖŸ´D·X¢t<Ü>¹+Ü^ŽìÈD#¤R/ºWbEN¤ùƒüÄù¼}²vD ™»R§Àê’µ#Œ/¿A@¡¡# ‘Pp舀’n¸=Ü^VVVVVÆ0s‰•Ž_JzÂí“»ÂíB¶ƒ+¥Ü›K¤·°£×•ÅÛW»ÞµüY:|ñë?¬þë·°éÇý¥”Û@~ÀÛj™ŽÈfuSO³ºR®é®”ÓMéÚ`Vºèx²+y7ÙÅÏPXøÐð;eY™¼î=]úÖÈo:3Ãw ŸŒv g¦Gxü¹¥_,{šs°üø«êµ—ªêý‰»s~ÜJ=¢»f át}PîVºè›úá8›B. ÇM̆¹‰Æ¨¥¥1JW]_¶3î`‹¡Óóî`S3§Ùåa\‰ë‘'ù¢ë­¾§ë¾\t|êht¼¦wçãšÞ•Ku¹2½…] úÞïÕ(G(Ný/¾úÓÖú—æ/*—f5æðbé_í×o>Ó¿ÚË7¿×—ôûËÊægñïowý(¦e:"ÎõÎñë7Œ_§[¬–=«Mù¹™”¿aм§ažÂd¾šûì1÷[UGOZU™%5ñ"´0¼ÛzFë¶.R\übÓ/–Üø;…ܨ¾·6PÍOI㔥¥q Õ«tpËM×íÙ`\×Ðÿ§ ýTë]‰»‰®Þ¦¯¶õ6ÑÃ.g?Ò´‰â#qC¢36’èŒÞ ½5VuåâXÕpìkÛp¬˜ñ:=ï¼¢[#§ÖÌÝ|FënFž¬Î?æüᎇ;ÂïP8ôy &¸)PÓ>tüvûÒò}»I¹¿”B~óþˆú_ËtDR‡ ¶~ûMm=‘Õ­ÕÉêìÛ˜ÝâOÞ{ÏŸ\:Mãµß¸ãµ[U-ƒ‹uDJ±tüÒÓ¿´.ö×Ū‚›ÚTA:bíza%³á¤Õ«t°ÜŸ±\Òñó¤£ÕòéX«…ßí¨×>Õ‡©óy%Ì\‚aF«.}5Zå¬è–9+èÊ¢k¡ÕòÙíVËÀØEÛÀXæ'éìJùÖó•òüÅŸ{z gÅ锳b`ìkÛÀX²ëg¯´ñãù20zÁ20Jc]éÕÛz㎷53d\ÿ´/®§ñ é²ÊÝéñôãDæ§\š¯´.:¨nRéSÑO6F¥‡§w…O-¤†É]ÿ0L¾Ž¡fál€Ìó­S~¸¡NIïÒh}ý»‡{ñK*cy’ržRE)ÌΟ'ám½vÍÛÊŸmÐ0ðÑG R—ZþˆUjù#6¼Øú/6ýÒ9fºåޙޡ¶`ÇÝA2SÂO³I‘½Ö³ú^kº}käuêàæ6up8öMçÂƤŸo¶ôK¹~…·Ÿt tòÃg›á$¶}(\ùâþ"äþ"6?smO„Ö‡\ï¹×·¥Ï÷/±r\#ÒŸ¼;çOêCï?Ò‡–9ÿÚ6×¹«ïéÜ4e 3Œ:¸¹]¤Cú;æM+¿”ô G½;FNNuŒ¸›zTî&T¯Ò¡‘Utkd §â_ΆAKKàÏsû‰Ï#}zþ»‰¦îr~n†ó«ªOT†óžôc]QßãýQ_ægélêÎö ,6~)é¬W|ËyÜÜ¿§¹ßYyFë¬,…T%É»IG¢ë'o¢«Õrl°ÕB­nfHÓÁšÒ¸øDçOÞD'ûòÉqöeÄý8âëi»¿Ø§è]ö%{Š}«ý±/VËrO>c¹lExøÔÄ‹°˜©…™S3gðÛ·˜5²M'42 j{°=ÔæóÞþÁç-~I¥üsÉ”ßYÑ£rVÐØóDgŸè|u…þsö £U×®VQúéLÓ'#Ži)áK-¤(…ü^lý›þtGÌò¯™ñGÇïŽÓ“a«åøíV‹ô2¢Žjg¼¶kW½6J9Ó¯qëîÕ¸óU¾…H¿Øö³aÐòúЦ ÔJ»fŠü¶b ÏÜ_²Ý_Äæ§èöAd}›~)õMìõ…û€ óóóóóóæþ4÷ód3ñüoÿ;ñœn½‘[Ñ#‘[K‡W6P†ž]ütèÿ8Ýø1ÄjìÕêC¼Ð‡,‘ÃÇ,‘y²ÅŸ¯ô §Õþ¨µ´ÍCI¢·DŽ~n‰ÐÃÕyªuù­o·P[øƒPåÞôKöÔôKlË9,ýîƒI¿[œø \52ãÚj™‘Ú함ooJ0Ñù“'†@uðŸÓ_Bøácµ±áX-¿>ðßõؼóØè.!Âg;—ùù_ž‹9÷lá…œ¯ð¿(==KKu,W,,5~ÌBZcáá‹™?Ź V6¤ä§ðú#ö|¥0÷:dîïšþ"Ö5-¼Î/}.é\*W0Ìг‘/†ž¥¾J}_ˆó]:ý…hOøíÛÂðOì Ãç«}Òþ/_Ü_¤çg~ÛÛBÔáñ ¿¾pÿ€·Ãè¶±¿Žn£oÖ¡¶GûBm‘[öEn¥_£GÞ¼>±GnÑ}?ýÊžZøJý{'ÿ¯Pü"FDÒ2úÍÓwýæú®kë·]JOy^,üÍ>ýºØ9úyc„ÿ®Â¥Ø­pñc I”4¦Z/—ž¥â—ž~áhªi°æþæ` M Ewi¢Õ~{fTÓÇFbzºH”Nån¥³aðÐGùûþí¦p®­V8éÿJ§b·Ò9zr|úÕÄ–„ãÅdÂ!3Ê*dÆâÄ_èôàª1™÷n5™Ka½HºwÐÿeÆrÅ›2}3º6fˆ3Ðÿ5òM'.¹ ‘m>¡‘ÑB ™ñ:|!9ßâ—Ý£ aýSC8=î=¼Î¸nïVã:†™K.Uë¶œsw^:|1ó's3½ü†/…ü)~}{¾ÂÑó›Ï{û‰ÏÛ1t2Ú‘·ußTAU“*è±]½ê±U]:3V¥ìQ7){hKCz"•~¾…H¿Øösax¡KÜHi W¾¸¿HÏÏÜÚ‡BׇÜâÏíúZ½÷/€bÔI«W4N}üoSþç·ÿÛÿœÖÔ[úS½ÍçM½Í´Œ¬N¦‘¶Z”øsK¿X:÷ûtnéëò@1ÑC³cúdÔ1õ=þ¦îŠÉ7êÚËœòLG´¦í7µ¦âÄ_èôýDÔÛ|~oosé/h ¨>Q¿ï̦žž]¸öËýx–åhDIæg ^¼å7Ñr¾ùËÝ7éá&æ’‹-¢Bk7×4XVÔ¢©Ž4ypüúwƯ§ÃcûbæOæfzù _ ùSÜú&Tf—n¶×-[e·ÜYI+Gó;¡„\ƒô×Ò©2Øc˜Høç&©‰„?5ѱkŒäkKCaéwýŠm?†Ÿ9½ÜZ{ÒÚ‡åÓ/-òs½¼M÷±ù)¶}ÈW}(D}+Dý)tû °Z,Ó90záðÀ¨u£íŠuc úî/j]ïû—[‡‘ýõ'ïüìOfÛ †–µæ?²ÐWå_Ô®J“yï“YJüRÒ/ µ?ØjG•*MTghÙxz(I׺äÝdWÿØE[ÿu%#¯„)W2 D¦¼i]WZ«·¹OßÛÜji\l%Zm‡–ÙÎ_ü¹§„ -¿ŒŠÝåFÅÀØù½¥½íE¢+Ú1sšsÌÐÒþt½Ó¸ÎÆÈ¡C‹£ÏÞª:úùb÷±áÅRÖH êîê²/-1áªì–¹*é ÝU•=êü­ï©5m9§5ÑD¶ì«}q3)?1¡•yé ¥¶×Uù¥ÌUÔõF‹™?«‘Øü)ÍüÌìÒÍöJáé©Àk¿ùÀk§#…Ôyþ5¸ôܪí4ò1½µuš”+Ff”i¤Ðž~±×¯Øö“Â{Ö#ÿÓ1’^ç}.‘ž”¯öAHú¥äî/ÒóSlû ¥>Inñ®þàþ@–鈴±ý‡ýM®éÛù¸¦OÈ4"Ú–nÒÙ6I8f'Žºu{6Ô­£áñêûš/Õ÷Îõf…søÙHçð³l©¿”ô‹nŸÜnÏWlPrãZÜHKMk÷í¸¥ÝGå¥Y£éÖ¬¡íS|×oüÍwy%\ÿå>}ÿeU`ýU€&i÷éþ®Ýg‰n±D¬êcƒVuæ§8?Çr~–›ù÷ì›Õänéáh\¤»¹Oïn¾¥ØJñØ®]õØâ†ø7qƒ²gƒYÙC×»F¶õœFæn:³m±-ÅjÜ;nÖ¸5k4_jÖ¨ïonS߯2i¿­2Ñ"÷RÂç¶K)-ZÒ5}*Õ5m:¸ÿ¦ƒ´ƒ*½òCzmW.zm,÷ô,ËQÌTÿŠÝ¿]l³ˆÜШÿÑm#_Œn³nl¹`Ýøê¼Â»f ¯æÐewS_­»‰æ"Pãº=ŒëLæý;³ÿÐX8ÅÉŸÕKlþˆ /}—Þü¢Ÿ¬hC…k½9ûX'ªó´ !]ƒüÚžÝ\2=¢ŠÚ:Gýê5¶¯)NúÅ^¿¹µŸÛØ_=6º§Óý—v¦ç.~H)íƒðôç–?¸¿d»¿ˆÍOá탔ú $ý¹Å_èúƒû@-I;Ìzí7¾÷Úé²2Õ7˜¶Ö7B»^B]ìñ.y«ÍũڷãfÕ>Úé˜Æ!ý(_@~¢þÀ»lL{åâ˜VkÒ^JÏ?é)W¼ »È»¿Z.Cn,WÈþä½µþ¤%z¸Å¥ã4Œ¯Ù Â{|OÆ=ÈXh„TjâEwª¤Çt¿­éGþ ?q¾€ŽHDȴʕڈP^P:Ð ’ Ó å :"V@YYYYY™ððX¹V»ß  ÐÐ W‘´·åóK3þÒÈÇÛÃíé ¿s‰•Ž_JzJ­¼ ·ï‚’èˆÔõVßÓõnùüBÇ_|õ ¦­õ .Í_T.ÍÛW)Å–Wt|êht¼¦wçãšÞü¦ÄÛzíš·ÕtpÿLéˆÒµÁ¬t»f atJ‡©Ù« Î Ô7jÚ‡ŽßnBžpþÙ0çw<ÜîÈWç`²+y7ÙÕ8õñÉÆ)Çôé”cšŽÇjc#±ZgÅ锳9 Ü2‘qýÓ¾¸žÆßÉëÞÓÉë”.ån¥«YÝÔÓ¬æ&8–[dÌZ¯õ¬¾×ªª›ÔAš`«nnS‡cßtÇø!)N #dê+’,V«”kº+åCÃÀG5 H‰_lú È«”o=_)/t9fºåޙޡ¶`Ǭn­N¶ÈäåÑ –Q»G¯ÞÖw¼­ù*_—æ+­K“Ο÷tòºÆèÇ'£ÒË-/ i˜ÜõÃäëjÒ1H™Ü3<í‹8?7ÃùkÜ;nָ鸬®\!«3*÷l0*¦\‰&@˜e:"M|h:¨p®? p&:ò&:Ù—O޳/#¾èÇ_ÇHÛýŽ~xêØ¢ã^Ûµ«^M°Þ ½UãÖÝKwèÔÄ‹pj"P}ï÷j±I­ºvm´*Ôö`{¨þŠcúd$=r-·øÅ¦ŸÐˆ<–ûá3–+ÜtÝèøãýÑqòîœ?Ùj9~»Õ’-dÒ‘¼›t$º~ò&ºZ-Ç[-#'§–TnåKè]ö%{Š}«ý±/VËrO>c¹lExx±åE¥ÃŸšxJMÐq)“ñ5²-ç42Ê™áøHçpüUYOÌ%¹·d‚?@1e툌ëã#q=MwuVtËœ²:™FV§p­7+\C'£CÔ¸ðsåŠôkÄ÷䳈›˜ sô)Zû/_IwVtÿ“³‚b¦#ºÞ÷K?—ôÓߟŸŸŸŸ_z”\z¬åæ6uFv ·;†©”þVÇðÉhÇpægi,$MÇV¸»Óg©ÕòéXº›²Þü§÷ëÍéNRéåû*çyá»ß„¿òu>—Jm úî/êPGxW¨ƒŽ+{”FeOÀyOÕ!ʳ½3Ä¿‰˜û ÃÜ×È7Ð,˜t¬‘m>¡‘%?ÿWÒÁt1 ÓEÇUAU“*èi½ºÙÓ:Pu~ï@•½æ³ÛöMߦ6MŸ»©¯ÖÝdjØ»ÕÔ =éÚú-ç´õùÍŽB§?fˆÄ ìË(ǾäüsIÎ?ÿºi8n˜Üm3L¦ÖÌžO­qÈ:cÃ0·ÓŸ¢©ß>ïí'>ïð³£ÃÏ£b²vDò»)eÆr…ÌÈL2ÿ3™­Y®Ìµ|_½[àð¥C[¿ý¦¶~Øÿõöa ³“©ahôe‡ãä݇Ùè³?À™ZXÅò6|0È0LÑ2mæ›Y;"ÕÕ'êÃ0g6õô,›ÒÈ+ºÓÝI,÷ãY–S8×_P83?k8°Ç<`80g Î/—æ/j—¦qÊ¢oœJ0‰»¥½ÙpáÒﶞѺ­ôYÃÈêڙϣíLûðçL{z¤þտל•Ýrg%sTXZ…Uú9J)ßB‡¯xk5ÒeÙå8õ^—£nñwuë˜yfž™Gƒ«]²ëgo²‹ó3 çg˜¹ä›wæ’ “òÏ%Sþ×G^wÑ`;úÌû&fÈÖ©Ù46Pç~ÿ‘Îí˜9Í9fhkÚMØÝ|FënnŒ:ÔáŠ&üú<·Ÿø<é­H¨“¨\Á02£L#3–rvç–~Z½‘¶ÍÉozØÔÇÙ”×~ó×î˜>]¸¦¹•/ÉÞª:ú¹U%=¼XêÀúêWƒƒº‡;‚º|åüpìkÛpŒ9qÜ 71VuéÌXå)!–Ù¬Æc»vÕc‹âßÄ Êž fef¦[³F#ÛzN#s7ÙænZø‰¹dz…§‹=ö«×²Iü_YÐ9?????¬xX¢‡[,Ñâü­2t>@á„Û'w…ÛËãúøH\¿O@T5©‚(Èâ[½uJGÌÿ&f@>¼;Êbµ±áXíêJ4uA¢;l¥ø“wçüI£bw¹QÜ!²nV¨ nÔ?A†þGC(Û»è‚,Ô™ÙIG?°tÍA>¼›鈤.HóÀ=æâ'hL{å☫ ÆHê ,mAG$¿ 2Ù•¼›ì*~‚ø£í´&í%­IP}¢ ¨J¿k «þÁÒ´Œ–Ñ2~ßÝ£~º#Þ5åùNáºrQÙÃ02 Ã$»ìItJ‰-áHÜM8Ô&Õ·j“”xBñoN¥smµ¬.åçf¸ †™KÊê8?ÇÒÿ†ó§XÎÏ0sI™‘ós3ô†I88þq–w|&åO:b#I‡cúd]¥Ù-Ñ9—Xîà ׵kÊú²ëС7ÝŽsÉt ×ïß„9ðGi]“¹¡.H}xËy†‰ŽO•ÕÅ ³ád—ÒY®¦\Á02£¢If¤ð27g†‘e…‹a˜rn‚1—ïT¸¦\ÁM¨ª&•ÜéüRÆ: 3ÈQ™²ÉqDdº òÓ+ÃÜßÄr × %Q†a42…ëk›²†av>b†©¾§s+\_Û”ÅïŽL‚dY] &¼+Ü^ãÔÜeͽ÷ücœ6ÌùSö_¦^vL:fÃILùg'S~ÎϱÜTÒ1;™<¨ ¬?  3cM£"Òêx°#ÔÑ1ÒïIÁäXÎoî?tÈÜß1Ô좚5š/5kØ—ì)ö¥ôsÏol…3p¬F¦t®? påw¼jÜÀžN:Z--ƒ¸ÐVZÖŽHÎOÿ×:«U/Vßg˜OŸZU SËhM Ã0ºméÏd/3 ÃjæÂá±*úTúÝbšKÊêèrc¹RfT+*º•N«±‚±˜¯mŒÜø;…ܘòsá”_fd™‘r@n,WÈœƒa8‡ÌX®HwxÉZ†ÑrÃBS`?òÙmû‘þ˃‡û/׸u÷jÜL5³‰©fûØÉö32æ#{7« uAd¼jàKëdú™IGæß u<ÚêèmîQ÷6sþ¹$ç§1¼FÅÞ­FE«¥e°ÕB! “ú§†É@upS Zúù ‰­¦oçãš>£b× £ÂÝÔ§w7-Œa׬a2P}om>ÒÓ1Òì‰øž|ñÉ2ܨp®­V8ÓqÇ´F¶õœæ­™_KMÍN.÷á¸þÀž7Ý‘;1# óþã‚aFfd˜û›ê2Ì£?½™¸MÝ=Åöjl]ÃÈêR~ŽM:ó\¹RÆr?ß`9ê^L8R3 Ã0ìÂNØ”.™ò3~†aü¯»«’ Ãm›K0­ÂÓp$ï&ê€úŽ:À0Ì'éãÙ–%:zRþÙpÊß0xøÏ ƒ­ÛX«¥Þ¼wK½¹qÊÒÒ8År?žM§_f\«“ÝMg¶¹›ªLÚo«LÌ*±RãU3qÇLïôEï´Ö¦½ªµÑq–cõ,·²yBeqFDœÑ¦GÛ¢MZÓŽ›Ú‚”©É|`Éì¾¾ëû:cc0¶€êA4 êptj;Û5ÆcCC ÒýFʇUÁwÔ÷æÓ+Vüÿ˜Æm% Ã0,Ç0µOû/3̱AK„¿šäJàwªÎ%ÆŸ¼ó³?9Z5Ò9ZEÝ‹r#ÃÈ鮯_*}<Å2 Ãp3 Ã0åJ†a˜_’ÂR`U´ªŒëv—×Y7¶\°n­ºòõhU¶_긤.ÈŽ¡Ï|CÔIïÒ(¹@õ½ßªýÏïþâN]#'§:FV[%̯¨èV¬ªÃǬªôñß)äF±HãU_‡WÈ_ŽäW­£R[ê¯R'u\òkdšîì]Ãô)ëÆOz¬iÇp:ÞzäÓ+­Gìil<ôQà …a¹'ŸåÚ­i·ØÆìwsŸÞݼtHeén>£u77Nniœ¢¥„ü£b×ìÂÝ«kܺÿSãŽâ#Øò'ÇŽÈ7]´Fäpœa¾¶QXãÃ0Œ³’a.¶a˜‡ÛǪæÓ+:·*xó¡ú~ñO2½Â ýŸcc–{ÚÇrJç†J'Où96=æîÕ(äµ_»æµ;fºå‹u6oüä/Íi‚¼!´kÖâ¿7Ä¿‰¬]°n¤q‘´1Ëýð™´‰ÞíCŸùÚ‡z›ûô½ËŒ‹4™÷¬7™¥ü-Ÿ÷öŸ—^Û‡NÛ‡ÐD@¾ˆÙ>Òoi99Õ>Ò¬n¶ª£÷Þ³Dèx:ԛξÆhp³%BahU>úìÂð…Åùg'yX‰tÇbÌû&f Ç„cv2áH¯Bøf\çŸK¼^òվ̧¸.¿@ͽ÷Žh‹ú¢G}JçzszT&_oÓ™m½M ÇÏ7šrË—R«¨?Q¿šV<¿tf8¾°«nuXÙñªêÀæ6u ¡ÿ£C ýÃϾùbøÂ5ŸÎ½ã;;PܼØÈDªÏÔM™y寛ô¡NO…s½YáLÙü5ê"ÏìdŽ:ûÇ-ýcý—/~ÚYéTî^¬fä&ëf5üI¯„ºGµcGµÜÇrÌå¹$sY¦-WÈ´ÞÖ›½­öI&â¬èYï¬pŒœœj_&|ûÈÉ;í#Ί•³‚þ Õ¿B‘“ŽøHÒADÔ¥µ°Û‘aÞt;Ò¨º¹™7Ÿ§N®rÃ8ÿ¦s8Þ1yòhǤÌ(ÓÈŒÌHyœé¿ÜWÛ™q3˜E&Ò\>·wàrãTÓŸ§úCƒ?ö‡hÝ@gÅ锳Âd<ð¡É¨œRlPN+wc¬”UÊ:e•ÌK†a^®¦j¸ÜxUÎÁÝåÒÅþ¹$ãçw¿¯Ê”'e çdÎ)³1 ÃpÔÑ­Züoj‚›5†þizl#í­®\Ï©+™jæS½ þOŸæÓç ‡ 0xb Ðj±]Iï¬M¡êmª‹êm ÃÜc˜Ñª«×F«†ÉË:‹CmŽ¡Vî³Ó­ÜëZ·61S¤»ùÜ^wó𳋟?S6˜Õ4Ž_å¹}LV'Ó¤7!:÷ŽÓ:·gæ†Ü3#=|~¥x#iŽ„Ûœðrn†3¤wĦ0ü‘¿$æÕ8;ÿ\‚ñs~næW#"+¹°4 ?ùbøSÍ0L5óœù…yÎ0ÌO ø™ŸvA²/ÙSìënÄrÃŒnûöÿÝÆX˜1æU·WCÿ¡C ý Ì!¦yÏs†až;˜Îã&{l¥èõxÕ=²:þxÕ¤ãçIçàœƒßY¼ÈxUÇ\’yµ¶œy‘¿¯ºDéÐDì^îÌé^Ž:@eSå Ù”³¢;–îÏDæ­Žã·:†Ýßê†ÝVÕÇ'­*ZÔ:Öôë˜rJÑ¢œ2ŒéoÆdFY…,ëZ“ö’ÖTãÖMÕ¸_Ù¬f6-ì*ÍÔ8uôdãÔè¶KgF·e Cëc**×k•vçgÿ?»“a˜†R¾ôg„Ô¹p,äl˜›Õ•+duÜÄ\’› Î25³©MÍ4xýÜàuØ;¯9ìbÃóÇEæ7“î Ò¹«ÿÎ­í¯øeý Ãìd˜W#U è^M¤U1 £JùçzÞŒ åX†a, ÃXäFÅ Üø*¾T¡|+ÖxUÚyœa˜;¿zcÛ«¯ªƒ›Õü#—Ïï¸Lõ„ŽÐÆ2¦ëûŸ˜®3Û˜'Ì6Ч•ùlm+³tl™²…¡½Ñ…‡Òj jcž3?1Ïs•±¡@!,Ñùf•½WÓ¥c ÃĨˆ¿s1ŸÖ´õ­In,×Ê~KK£ŸÙX®`62ѹ$•)WȤ'}—+†±Ï%û«ø§çÌ4Ã0ù>ɨ=p$§“wŒÖ±ƒÕÖ3&†ÑÖ/²Î£‰)=ÚÑMÿõÎÖ×y"c1Ñ@Í7&qä罜ŸibdrrS ãU ÐˆŠ}{f(×ÏœŽëS~†I½ÚÅ8óÿJãZÒØ5ÝÍtMËŒŠF%7¦¦&•õ8ÃÌ¥ s’&óîr¹qÔwåbÔÁx¹Q»]×d9îc†±’†¹É`[œa¼*ÀÛOPGdt|êht<œ|°#œdj˜7syý¿>¤OèC…8É*“ö[†©b´{ò¾ ° ]R|¼êò`åeíˆ|5úì•7]B–èÑ“–h!’BÝr†Á|ÚwŠ!¤»—t ø¾þ,Ì0c›® “ÞM;‡ÿw0ŒÌX/Ûó1Ã0&ä1ÀÊ4"Rf,Wäcç_€L™¦›a4fÍz†af}ºÎñë_Îÿ?‡ü( :" !ý†Ð˜öÊÅ1­Q±{·Qñê 'Ã0N£bcTÄõñ‘¸¾IQ2ŠÝJÆŸ¼;çOªª&U@éTîV:†ù°š-2"Ò¨Ø]nTP‡`ñÄï‚TTŸ¨($€Õ.ëÔl­I{IkJ8wŽb&]oŸ¬‘Ô¨6©¾U{³LÄ^uTAU“*¨bTM*d,C×[Íèz ·È”¦²Xml8V‹Œ€Âù ² íÿD Q*!~IEND®B`‚xymon-4.3.30/docs/stdview-detail-acked.jpg0000664000076400007640000030022511070452713020631 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀ©A"ÿÄ ÿÄ`  !"1A2Q#TW’“ÑÒ37BSVu‘•²ÓÔ$CUaq”á%&–456Rt´bs„¡¤±8v‚ÁErƒ…³ðdµÄÿÄÿÄ@!1AQ3Ra‘"Sq’¡ÑÒð2“ÁÓs±#BáCbrÂñcÿÚ ?úz|¹i!)”òRP8pMxvÙŸé .?ö„Ÿýê¿ûšä6«o⾪º{ŠÒw^Ï‹þÔžöÙ±vÀ„¯‚Og^vçr~â}_Xó$éÌêˆÏ\ض±ySÒ_nC¥§T°DwÓÃpJJIÎr1ÐâÃ¶ÌøÛÿHk‹¯QÝ[º@´zBuºÓ«û;[æ×(èe¼$Åm ωñ9=kÀj½qJê+‹Ïܶ'J̺D—pôfQ%¤‚Â#8½íÄü V6¤Ø ;m™ñ·þÓ¶ÌøÛÿHjŸOÁ¸@‚[¹Þd]¤­{Ôë­4ØF@–Òœ Hݹ]NTzbÆ„žý¶gÆßúCNÛ3ãoý!¯ŸµÅ‘ùwŽ"ݘÒÖ'Ì{›!wå:}%n@·C*q„²®X%À©ÉÈÚïWêý`­Iy«‚ãYÂã%…Û“JVÊ+¹¥Ð‚TPØl'*9HuËÍøYìón÷‹ìBƒÉ2ܵlm *R°œ“€ À׫e¾ì†˜¹©×#8}(qie)XJ€=ÓµiV’ð"¸Çn7Yú_‰ML-1,öåEDKE2ÐìD¬­jZJûêqM#b’›9ÝÔUåãQ_x¹Ú»z=·u[–¦†[*†Â­ŒÉ!;’RT§J ºº:@uÛ3ãoý!§m™ñ·þד«µDuÞ7‰7·›ÕȲµ:+1û,vž s .s7#+é¹g õQY±ïÞTk-¡û”»D©Ërä¾Ü'¥® ·½#áÉq”;¹ c¢R¢œ(¤×»lÏ¿ô†¶gÆßúCXpšqˆl°ì—e8ÛiBŸt$-Ò ÔœŸ´× ¥y^-ñ.Ö™v¹í¢Kel<ƒøÈP ÔhIcÛf|mÿ¤5åì¹m)Ø·5Hm.-¢¦ŸÜТ…§ ø¥IRHò ƒÔW-æß­0xy=õ;u—öç‚—>Å-Óÿ¿BØOÿÇV=Zð›|Õòí_…p—ÊnéznRmÂf–£Îq¦yi’9jmNøÇ¹×$äA×»lÏ¿ô†¶gÆßúCTú^swM5k¹µ+µ·./¥þW/š€ ½Ÿ‹œçYÅXÐý¶gÆßúCZιâC³úAWYÖ^’¾ÌAä°ÎÎkªÜ´å)æ#¢w(ç¢N iQ,öBΣŸu²Ù/ú–%ÖK]žòþÄDa/ÆÕlp²’ÆÇJ;ÊQ$õ$Sj³Oé·#D¸M‚é¨lE·Ê0‰VÇ~à Òœ£jûŠ%]á€;§m™ñ·þÕ}óTF²C“*éyTfãCzk€º¥/È×T ÉÎõ’x'ƒÅ¹;~•ºX½J¹ÆD_ä¾ô–Ù>ãb0mD´„$mKÎ$€#9#4_í³>6ÿÒvÙŸé xR “ß¶ÌøÛÿHiÛf|mÿ¤5óvв.Ù¢¸sxNŽÒ–D¾»@UæÛ$›‹üÎPhä7ži!.bð•¬÷±šÞ½Ñß»_¦ýÐ žê= è.C[9]«‘»vÞo7gôŒîÛ·ñqÖ¤ƒ«öÙŸé ;lÏ¿ô†¸õ×Qj,&öÞ­ÁÕìY}Ù˜(,vô0FT’ç1meÌîÀBú$tPþ_¸ëc§ßÔljõ¥GT»ifíì*:XUÕP’U„‡´$…Úä;m™ñ·þÓ¶ÌøÛÿHk—\ow6ö¥µÜu,¹¨‰Û&,× °© T©1Ê @m²J™HB”0’æU¸'®¢Æ¦âºÂá§Ú“«Ëq!¢KALØû_1D…%ÓÍ )¤€ƒµ.`ÜR €ïý¶gÆßúCX¶kð¼Yá]í×ß…:;rc»¹iÞÚÒ•aX# ƒ‚®§nŸPëè“zUª#~Õr“#¼—$>äžb9¥+Ëd2v •¤ê\'ÕWÄp½¹DˆÎií$ðì|°\ž”ÄJ‘%K#% )Ú”¶FB‰Wu w~Û3ãoý!§m™ñ·þׯ\CÒºŠâó÷-‰Ò³.‘%Ü=”Ii °ˆÎ/{Gq?©Gv+«éø7Kw;Ì‹´•¯zu¦›ÈbÚS„ ·+©ÊLqÛf|mÿ¤4í³>6ÿÒð®Qj°öþ+ê«§¸­'uì÷ø¿íIïm›lJø$öuçnw'áÞ'Õõˆ{¶ÌøÛÿHiÛf|mÿ¤5ÌÕÓÛÑ©”åՔܕ¬½œ¥°¢Ï¦y<­¸ñìÞxÝŽösÖ°âÝucvßtïjwž`j×-BÚa°1•vT$‚ Žfô¤‚t É uUø]b®L ‹ï4‰FR·-8q—TÓ‰ÁǂСŸŒŒŒõ~ì¶ŽÓ÷54ä— L%oí.¬%K)H'¼v¡JÀòI>×áåÎñq¼Ü4Àº;§c5t½=ÖÚmo܉¸Ê -—¤%-2œ´ëäðÊEÎÑÃîEEêTÆ®¥†ßKí³ðlú%÷C (m8J\e•ô ¨Ž”_í³>6ÿÒvÙŸé r¨ïÒdhûœÍ@'§Só{M¯ÒSoà wàÊRðj@e{Ô¬©cÕð¯= uÕ‚×ûÍßS½u¦Û™pØi¦Šà;%+l¡AYg*);‰=­öÙŸé ;lÏ¿ô†¸ç µ^´½]lWñîH·ÝËÂSR•nDhÄ6µ¥1ùn™ ZT€…%ÀN ‰ÛŠÚ¸:åö~‚³_ïú‚EÖ]ÚÙR¨ì´Ó%m…´“¸nÜHÈ”óÛf|mÿ¤4í³>6ÿÒð®}6F¤c‹÷¿sö«MÃu‚ÙÎí×'"lþ‘pÛ·cîÏ{9ÛŒô¡¿v[ÇiûššrK…¦·ö—V¥”¤Þ;P¥`y$Ÿk×¶ÌøÛÿHké›­ú6´”ÌÖ¢@‘qÖýš|x¯™-)±§ÐêR[hW¬ÓJÈJNAFs¬ÝµÆ±/Ø$Ùîš’L+ìœãÒÛKd¤¨9:l•¤v‚¡ð€¯jTz~e@*âûnÜ$ÑS¹g˜àiÇJr<;,äàwqâ@9]¶gÆßúC\ŽÝ>û6ç¤Z¿µ%"jרiR×É[^ˆ–°^–¦’¼­C J¶ÕãÃ=G¨¥[ôÎã«EõZš1"öfLu&2.#–¡µh ¬(¨np`'  ;m™ñ·þÓ¶ÌøÛÿHk•žý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCNÛ3ãoý!¯ Pý¶gÆßúCP©ò’’¥Ly)$—H~ºñ¬;Çiì 켽߿ÛçãÓõùf¤‚W©\ç°†¤Éq·s—„ãÇÇÙâ|0:×õp¼HzÃ6LKŒƒµ‡ V—T HIÿˆ5åkì^Œ®O+›ŒíÎ;ÙÝ×ã努ïúíÈäöÎï+oŽvŸõÎÚ8w£R ‰Ðÿ»¯/{îüžhÏù~'ðë™&duéˆï¡øë³²ê9Û‚ÚTžrÃŽà ëJÿÄ  ɬ(–½‘ݦ£¦à…75-0ÂD”¨¤¹ßsœÔûßp÷äóFËñ?‡O{îüžhÏù~'ðèIoékWöœ/§O×OKZ¿´á}:~º¨÷¾áïÉæŒÿ—âž÷Ü=ù<ÑŸòüOáÐ2lŒ¹:á&7îP‘=õ<ó,7kØIHHª)R°„¡¬¨íJA'`›>‡r5­»ƒ6 “Ö¶f,™LF.6;R á y:W·½÷~O4gü¿øt÷¾áïÉæŒÿ—â€›Ì z’™WˆZrâúS)v[Lº´¶ B ;H'#Àä×ñ¨ãXn–[Œ%ØrzÒãê“© <´„]l‘Ìî¶”u à ëÞû‡¿'š3þ_‰ü:{ßp÷äóFËñ?‡@Vi ™²éÙÖ‰³,Wî2 ‰";LÅQ؆҄1•¡(m •z¹$“W6øú:Ý,[{6lCt½¦Óia• ­tJŠV¤äuˆó5ãï}Ãß“Íÿ/Äþ=ï¸{òy£?åøŸÃ -ý-jþÓ…ôéúëÊmÆÜü7˜jøÄGmHKí<Ñ[DŒ¤,)9#p#§PGJ­÷¾áïÉæŒÿ—âž÷Ü=ù<ÑŸòüOáÐ-馹;roŠ7dNy´´ì”±h¸„ä¥*WdÉ'ž™5q·èk”DC¸ÂÓ“#!åÈK/´ËˆK«QZÜ €¥)JQ>$’OSQï}Ãß“Íÿ/Äþ=ï¸{òy£?åøŸÃ -›ºZBP‹Œ¡ ¥/ =ƒ­O¥­_Úp¾?]T{ßp÷äóFËñ?‡O{îüžhÏù~'ðè Nõ ¬W¹mK¼ëÉ) 6ì¸6g–ýÅPɲ7gÒD€ÝòE§PÊžÏ6äÌE<ŽöF݈JSŽ€mHèrzÖG½÷~O4gü¿øt÷¾áïÉæŒÿ—â„ìHÓ¬[‘maûSP[d0ˆÈ[a¤¶Ѐ‘Ð$˜Æ1Ò°£ÀÐñíé·1 Nµ ÞŒ˜èi”¶–^!N¶@*O‚ˆÍy? ørÃ>ï´b[m%j>çâ2«­'Óßsoä8[û.ðèIÔ=-jþÓ…ôéúëÊmÆÜü7˜jøÄGmHKí<Ñ[DŒ¤,)9#p#§PGJæžžû›!ÂßÙp¿‡OO}Í¿áoì¸_à=lü3Ò–iÈŸhÖÝ-Øü[e‘§Ÿ)0½v}éÏNò,>–Û³·lk´mÆ1Ìõ±Ž˜Íhžû›!ÂßÙp¿‡OO}Í¿áoì¸_à.¯š^ÉwÖŒßd]ôêYnCT‘5jd¥HA•¿<½èJöíÏLnÇJÚ÷éŽËÙwÙû?hí<¬·³Íæó1á¿™ßÝ㻽ãÖ¹×§¾æßÈp·ö\/áÓÓßsoä8[û.ðè‰1Z^giífÍ#µ²–$óKkç4’¢”/>²AZȠܯiª÷l¼=vÖÅ©ËN–]¾2ËŒETv -(ø©(Ƽ Òý=÷6þC…¿²ážžû›!ÂßÙp¿‡@t–%iæ$*C-m<¶ÊœBÛ - ¨¡Ž»RV¼¹Xñ5âÀÒŒ*˜VŒKÊ9IìÍÆñê' HÀÀÀÊçžžû›!ÂßÙp¿‡OO}Í¿áoì¸_à7ˆ–½‘ݦ£¦à…75-0ÂD”¨¤¹ßsœÕÇ¥­_Úp¾?]rÿO}Í¿áoì¸_ç§¾æßÈp·ö\/áÐCÒÖ¯í8_NŸ®¼˜›aaÙ±.ÚÓ’\¾¤8„—V”(XíBS“ä<®iéï¹·ò-ý— øtô÷ÜÛùþË…ü:5íazì«»ºñ÷.KR©je/!AH%}vR¤¤Ž½ A¼oÓ—²ï³ö~ÑÚyYog;›ÍæcÃ3¿»Çw{Ç­s¯O}Í¿áoì¸_ç§¾æßÈp·ö\/áÐ (RÊH²”±%RÙ†ßR”¥:ŸbÊ–²T:’¢|Íy[âèËvÑo`‰¶R¦BFR ïOÇ(%%^$3ŠÐ}=÷6þC…¿²ážžû›!ÂßÙp¿‡@oðcèèI7X,XbÜ%ÿÖ%2†ëÝsßXꮾÓ^Í/L2Ä]¶­øìM¤¶-ŽXüL!JOLwTG®uéï¹·ò-ý— øtô÷ÜÛùþË…ü:}Eż»zO±txìÖÛe/¹ŸËãÿYЦØaCf9vØÑ˜m-2ËN!m JR‘Ð æžžû›!ÂßÙp¿‡OO}Í¿áoì¸_à:‡¥­_Úp¾?]k7[dywÙ7h|DjrCm´¦â&Ú@B3µ;Ž·KV£‚µcâµ_O}Í¿áoì¸_ç§¾æßÈp·ö\/áдäHúŽßu‘¯rn,ÅÏq¹mBBÝc.2W½†ÚðiÂà²v7‚’xůA0™ÉbݦšMÃþºÃIóøLÿüsZ?§¾æßÈp·ö\/áÓÓßsoä8[û.ðè þÞÆŽ·F‹Þ͆#Ý.Æi„´„°²• ©tJŠV¤äuˆó5U ,?HYmÑa¹b7Öö!H¸´ÓL½(4ÚS¹dzíÎ 8öšÕ}=÷6þC…¿²ážžû›!ÂßÙp¿‡@uKZ¿´á}:~ºzZÕý§ éÓõ×/ô÷ÜÛùþË…ü:z{îmü‡ eÂþÔ=-jþÓ…ôéúéékWöœ/§O×\¿Óßsoä8[û.ðééï¹·ò-ý— øtPôµ«ûNÓ§ë§¥­_Úp¾?]rÿO}Í¿áoì¸_ç§¾æßÈp·ö\/áÐCÒÖ¯í8_NŸ®ž–µiÂútýuËý=÷6þC…¿²ážžû›!ÂßÙp¿‡@uKZ¿´á}:~ºzZÕý§ éÓõ×/ô÷ÜÛùþË…ü:z{îmü‡ eÂþÔ=-jþÓ…ôéúéékWöœ/§O×\¿Óßsoä8[û.ðééï¹·ò-ý— øtPôµ«ûNÓ§ë§¥­_Úp¾?]rÿO}Í¿áoì¸_ç§¾æßÈp·ö\/áÐCÒÖ¯í8_NŸ®ž–µiÂútýuËý=÷6þC…¿²ážžû›!ÂßÙp¿‡@uKZ¿´á}:~ºzZÕý§ éÓõ×/ô÷ÜÛùþË…ü:z{îmü‡ eÂþÔ=-jþÓ…ôéúéékWöœ/§O×\¿Óßsoä8[û.ðééï¹·ò-ý— øtPôµ«ûNÓ§ë§¥­_Úp¾?]rÿO}Í¿áoì¸_ç§¾æßÈp·ö\/áÐCÒÖ¯í8_NŸ®ž–µiÂútýuOkÐ<8¹ÚâÜàè- ì9m%èî›$$‡[WT­9@ÊHê#¥d{Ùè/“ý ûØ¥aékWöœ/§O×OKZ¿´á}:~º×aiΗp‹Bè—Ý·Ie„X"Û¼´;·<¼ãˆ= 8ñ ¿{îüžhÏù~'ðè KZ¿´á}:~ºzZÕý§ éÓõÕG½÷~O4gü¿øt÷¾áïÉæŒÿ—‷ôµ«ûNÓ§ë§¥­_Úp¾?]T{ßp÷äóFËñ?‡O{îüžhÏù~'ðè KZ¿´á}:~ºzZÕý§ éÓõÕG½÷~O4gü¿øt÷¾áïÉæŒÿ—‷ôµ«ûNÓ§ë§¥­_Úp¾?]T{ßp÷äóFËñ?‡Zþ©‡Á,û,j=9ÃÛS¤­‘*É ¾`o®?ýcÛ@nþ–µiÂútýtôµ«ûNÓ§ë®_éï¹·ò-ý— øtô÷ÜÛùþË…ü:¨zZÕý§ éÓõÓÒÖ¯í8_NŸ®¹§¾æßÈp·ö\/áÓÓßsoä8[û.ðè¡ékWöœ/§O×OKZ¿´á}:~ºåþžû›!ÂßÙp¿‡OO}Í¿áoì¸_à:‡¥­_Úp¾?]=-jþÓ…ôéúë—ú{îmü‡ eÂþ==÷6þC…¿²á€ê–µiÂútýtôµ«ûNÓ§ë®_éï¹·ò-ý— øtô÷ÜÛùþË…ü:¨zZÕý§ éÓõÓÒÖ¯í8_NŸ®¹§¾æßÈp·ö\/áÓÓßsoä8[û.ðè¡ékWöœ/§O×OKZ¿´á}:~ºåþžû›!ÂßÙp¿‡OO}Í¿áoì¸_à:‡¥­_Úp¾?]=-jþÓ…ôéúë—ú{îmü‡ eÂþ==÷6þC…¿²á€ê–µiÂútýu ºZ’•\`©$`‚úH#õ×0ô÷ÜÛùþË…ü:z{îmü‡ eÂþ¿-6.{ jë¶ÚÎ[¤…gÇÄùøŽ•ý\%Ù™°Íl1¹‡P—ÒJ‰Iþü“\ÿÓßsoä8[û.ðë`§8[xÒ¯_,:/C̈¦]TyLéøŠme)<¼($Ž™y0~oÒ”®…OÖKý¡'ÿz¯þæµk½Úá.çR•vvÄ’áçR“†šHõÎႯà7²_£¢S“â¸T”<\mE'p|s½Kp›§`)›“@²Ã$G}”„6òRžˆÀm}<1ƒâŸ4#¤ëÖ£NôÖœ_#ËélMl=,ÐZq|¾ù›|{ÜE=;è—ù*ØØzÍ¥K *) R@ΣãåVu Zl³{·Ny–Q©"BÏj+8 ¸€ØŸÊgÇÊ·©±Û— 让ԶójmE§TÒÀ#¥h!I=z)$â5£ RµH^´lîiÀÖ¯V›•xåwÝàz׌¹,Ä`¾úŠP”ôIQ%DNIµžè×tuº\y:§PêId)ÎÓwœ·ÔÛ`ž[iI%)ÂOy@µdœ ©Mõú+ó-Šf6Îhq·¢ØâUŒ€qêû+Y´Ä›q”¹Mv­-¥µ©Á":ÛJÕ”§r€Á «¨Ï‡QVù¬ÍmE½Èq³µÖ–0¶Õì#ÿ×à|Ei“„«SÌ3-¤¶^J‹|·K…E% Œm=ááWÚ~ ®Ò.2þ \²Ú$'9ï3ÿÈyy“.À¾¥xOŒ™ÝŒ§Ÿd8œsp¡i>DàþÎExXà*Ûnn+“$ÍtuqçÜ*RÕ猓ìÿ™É5ßnQ¬öywId†"²§WðÞ|+[µeÊòëOµ“<ç-´3 )Œ§?&•ºÉÞsÓ×¼€ðo•AƒéIT²‰*Ph‚„²ë€bT7!'8ò­FíBTc>™Xì!+·²§›Œ¨ï`…,©´£¦–zg§^ŸÒôFOY()6øòÝ¢j׿ŠÐþw¥qO®T•G /Êþ/ÀÚ4•Æ÷#RÜ¡]fEÒ!G}„°Ál#rÞB³’NO,Ôà=§k­3…V›s×i-m“)[ƒÎ9¹”¨ìÁY$Žª ôÎìàVç^GIdÚd©«%eÂIîñ=l©³Ç¬wo[û]ÊYS'L’ãÐè …•rÒ’µí8QÂèO “áÓÇ»•Â&EܸϤ©<Ä ‘â¤íÃØGQÔðâÕ|SòXyÅ4·]e +Ê–JNð÷°qÔ"\]C0ß$²ò#<ÔŲ¦œBŽP£ŒŒõ®OüØåÆÝx×RæINÅ)± ‹tÈŒ1Ð4¾SGº¢öw`ÍÏL›d[½¡:nkš2³iç­1!­m»nU±’ Ó Ș½êmƒ±Áƒ‚(«¨o¾ˆ»éËeçznä¸;ù›y;bH‘¿;¿êûqÓ×Îz`µ ÷Ñ}9oì¼ïMÜ—3o'lI7ãwý_n:zùÏL+u°´»-¿£ooèôk•Ë‹hE¹Õ9ÝèÇÛ%Q€Þ†L‚â¹E#)q(ÛÞ +¥…•Y,eí{G£\®\[B-®—#[ýûdª0ÐÉ\W(¤e.%{Á$û!çz2çÒó¥ [e, ŠVõîP%9HOt(åié·r‡…Šéùc{µ¿Ú \#7*+»žcN$) €#) à€}µÈ,šqR×`Œ3-­(î±–ìKdÈ*J#[—e”ʃŒ¬|K}Na ò*Ûƒ6YöÞ XlúF¿I^!³›È¹i·‚^”ˆèKëØÁuJPOÃ…-*ÚFIê:µ+–¿m·'‹wzŸL\›zvàÔj i ¤‡’6Ç!àò׸§zVÕ­#WÛmÑ®Í.ñ¥®ŽjÕëØ¦óØ\-*®Í)Úq°¶– mòwd-;¶tÝ@wiw¸"3"êÛÖþÑ8Ae¤-N8§Km*†pBU•„  åZïl,Àæí:2÷`½Á·„ê‰Sm®Æç5ÙÒÝXåË*BAQm( „cmÚ´%÷ÝF‡°ênËÙ=/m;³ó7ò¹­%{7`nÆìg8ðÔ7ßD]ô忲ó½7r\üͼ±$Hߌßõ}¸éëç=0x¯l,Àæí:2÷`½Á·„ê‰Sm®Æç5ÙÒÝXåË*BAQm( „cmnÚÓKÞo¯h«v°ô~¡a•Çå›}±ØÑÑ[&‡P§î— RIPJ·¥uïÓi\Fç¦M²-ÞÐ75Í Y´óÖ˜Ö¶Ý·*ØÉPi„„dL^õ6€AØàÁÁ7Mµ+‡³U¦íoÓ£Sv»=±Ë ³Ü^ÌPý¼aÒŸç-- Jš8Hí/] 3|‹dqý³åÆzS lW}¦TÒ\Vq…>ÐÁ9;ºgµÂôöž¶û¦áÞ Ô;a…3㠲͉DŽ7ÌèË„æÂ•®*6¥÷¼€Ç1I*OZ˜:R#ÜT¸@{M½t‹v“pMÒdëÑäFaÖÝè'îåIaEA´2R¤‚ƒ€;+Œµm×:ŠÓ6–fF»ék<È6É’[Lë¢Ûq–¦!G¡ •n’â|Pq°ht½ƒK^nzkBßí†$½2¢]fL×[BÔP„¯¡þ˜. …•$oV:Ѫ›Fß}ÑZ¸v^ËʹOƒ³™¿=š[Ñ÷çÖånÇ–ìdã'˜j«1cM]¢Ød^&I¸Â$˱<¾ÊÈKi[±®(PC  -L¯ªÔ1…ŒøDЬDÓþé#é·›Õ#^¸úeˆëíIˆåýA“Á…EZ”@Ï4M‰­´Ô­Kîu©¯‹uÆ[B} ºã`—må 6âÒ¢R•6«#¡¬Ÿu6/pþí{wûѾ”í|¥ÿÕy\ÞfÌoõ:íÆï,g¥W®Ú.PTÙ¢àëV›k[ж6Äm÷—%¸‡7|#Ü´¡$ŽZT0O9@rŸpz¿þ‹‹Ý†³í¾â9^€ì~ùØqÙ6vNÁã3Ëvî´\ÔšßMé뀷ÜeÊT¾P}lC€üµ´Ñ$ ¡e´¼ƒ×¡¯êë­tͶÛo¸;r2Y¹£|ÀŽäÇ%'hVæÛe+ZÒñ­p\œÑºãTɹÙ/sc^ä12 «mµÙ™ŒÓ&:ƒIQl…4¥‚¼ óO{ ÕvOCé=?.ñVÙ®ˆ~äû2tüNØíµ©r‹ý•ÆÐ‡BÓ‚Ò~ö´‚ψé7 ô}¾Æ»Ü—ï®oiu«çLNRRµö„¡’¦0•¥_‘’2ÆÁ¦ï¯ðW2 6ZC¥¢™öÉœÈä!ô!E=Gx g#9æê­U~àb\#\çÈvÛqgSöîÏ6s*‰„ÇH.âBRT“´b¶n&د¯Gú&ßÛ9<Þgûßp²mÎÌÕ®np}|mÇLî4Ö»¾û—Ð÷íMÙ{_¢-²'v~fÎo)¥/fì¹ÛŒàã>®k^´¾£‰Áî"Á‘exKŸ§å3†u]Æüãë1Þ L¦Ò[Q*H¼•“×ÕNk8›evV¡Õ¥ý3v¸jy|q×F!8ëppÃiNH)²@uÅî(Þ•Þð ;•+–¿m·'‹wzŸL\›zvàÔj i ¤‡’6Ç!àò׸§zVÕ­PB½/ˆìÜ`i.ÇsgVG ’Öš˜ôµB3P‡72èk’¶T¢YJV…mÚÉ«éué­C Óè¾GjôßÂvÛ}pn†Ñžg3wïg5¹×°è†oz²ÈΨÓNL¶°î¯umMŠ£©ëÓ+c˜• ª orРÃ;r7þÁ“lÑ^“DdÄºÜØŠÓéP(Љò ÝvrC{ONÒ:b€ðÕS Û ±>å2<(ŒÃB~C©m¶Ç^ªRˆj¶Ý}¡nS™nÖšnd·Õ±¦#ÝqÇìJR¢Iÿ Ûõ ,É<†ó.ÂJmi JÒA|AUÊxcÁ] 5MÓPÚqÉ2ÖDP÷xAh¹¶Ï÷œ÷]¸Òy²K>ÿÛœ@ÿóB¿ôQ+l¼ÜcÚmr.2ÔC, ­[FIö<ÉðÌÖ§ÂßûsˆþhWþŠ%l:Æ™Ú}æáµÏˬÊmœ…,º‡y}zw¶mëí®ue(Á¸«»«)FqWi3W›Õ)+ëöûZèkì'B\)Jƒk|-)Jö­'+Äà«¶=!~ôÜW’û<Ø« Èi*ÜH)*é¹$AÀö kÖrÅ¿Nßc3mfè©Ó”á2€ìÍ·Ée²I9ݹ ²ªrGLÏ ¾xX"4´2Ìc·Ô6\Qq#ÿ.”§Úé‚|\*¥JÑYó]]«~¾GƒÇT©ˆŒó]6×wó6 ö¬±Ùf¦ Çå;1M‡{4(/Ëu($€µ!”)II ŒÁöUV¯Õ7iHw"ÏnD™\§ô{òŒvÀ^å픺£ÌB[))*$ôI….KÚsRjuN‰|K·~Î×n\Õ±ˆÍ²[(B)RTÙpoAAæyõ«_Ñ}¥¬-êK3·}òn;å]lÜym ²ó`ÅåŽbÙÚw”›T Í{Çô'Z°I›2Åo—r‡Øg?·$ÆÝ»’â’ ‘Ÿ=¤‘Ÿî¯âÛwt¶Zî–´;6Í´<Ì„€†–Ùq)+)Vu8«+n#Xá$oð¹‹^¤·«¼ìØÎD™¡&?iy  ´µ/ –¶’¥¸ï(u:¿ì­AÒ¼3…oÓr-’-·$‹Ò=¸Ø’›D–œyd …,¡<ᔨ‰é@ty÷E¤,ºƒ³v_IÛØ™Éß¿•Ím+Û»8ÝŒàg°ìŸþ"í_þQ¸ë!WŸ ãI…ÂÍ%dwcIbÉ §™u miaIROPA|+ÒÉÿâ.Õÿå‡þ²ðdZ5þá ÇÙw¹]/³-,OšœÅb40¶ÁÕöu”îWD¤%J8'k­Ã^[,×·îKè§ç1.4ˆ’b8´$Ò·GmÀ®™ÆÜcñ³Z·îÍè[ä+Ž¥R¢Xu.ž´¦%ÑÌöxï°ÆÕ0ê¼Ü¹%XOEu'"¬µïàMƒ©lÌͰʱÉÝ-òÝœ¨ÉÚ†¾¦YOyíÙXCn(à$׫Ò8½gS «^÷µ¶K[¡)Óu¤ìÚº»Ý–§f¥hÜ5âÞ€â<épô]íë«°ÚÉP·Ii¶8H+q´¤(õÂs’¢ 8ÞkÎ5ŠR””¥¥)@)JP R””¥¥)@+F×ölïü³ÿ¼åo5£kû6wþYÿÞr«-Ä£ò‚”¥Xƒõ’ãÿhIÿÞ«ÿ¹¬I,3%…1!¤:ÒÆ…§ ÿˆ®A"Û©ßãîñ/W¸¢µmìI''GÀÿ\…Þ)]7V»×8òÜÜá×…Ñý7C¤œ–2–[^Ëuïoì͸Œ°ñN´’½íwË÷>ÀBR„$a ` šøÝ\R¿þ.»Ö_ñnðëÉ\RÔß‹®õwü[‰ü:õ¬ÿéKÈÈåKÖ/3ìÚWÅÊâ–®ü]wªâÜOá×’¸¥­¿]êOø·øuuÏþ”¼Šõ”»èûIÖuh[!JFv¨Ž£>8¯Jø‘\R×ß‹®ïÿñn7ðëÉ\Râ/âë»ßü[ü:º§YÿÓ~Du´»èû‚•ðÚ¸¥ÄÏÅ×wø¶ÇðëøW¸£øºîéÿØþ[©­ÜduÔ»ÈûvånƒrK)¹ aÐóAc!+€¯ñÁ5\t¦Ÿ'¯ÈVú<ìÿå_)q[Ë]Ü?âÛ?ïàñK‹^Zîwü[gøuÞ hæG)¼4Ýåf}ÖÚÚ”+ú¯„¸¿å®åÿŶ¿‡_Áâ—üµÜŸø¶×ðëžÍ[ºËí»ÇÝ’âE–€‰QÛy ä¤ó‰nƒeq¢4Ò‰BqšøPñKŒþZíïø¶ßðëù÷Òã_çÛŸFßðêÛ%néE.ñ÷½+à}.5þ}¹ômÿžú\küûsèÛþ6JÝÑ´Òïs9b³¹$É]º:ž'%esÿöf²Ã,ýé¤#Ë ¯ƒ=ô¸×ùöçÑ·ü:{éq¯óíÏ£oøtÙk>h¥Ìû¶ìÓÚ¥°Òw8ã BFq’R@«‡4×4Þœ˜ô'dÚ­1`¼ãN8Pµ´ÊP¢œ¶ IÆ@¯€½ô¸×ùöçÑ·ü:{éq¯óíÏ£oøtXZËý£h¥Ìûòm‹CMÔIÔs4Ž˜“zK­¼›‹°¹!mà!aÒÖíÉÚœämð­ƒÓM{XùëûùÇï¥Æ¿Ï·>¿áÓßKŸn}é٫÷FÑK™ú9馽¬|õýŠzi¯k=b¿8ýô¸×ùöçÑ·ü:{éq¯óíÏ£oøtÙ«÷FÑK™úqz×p™m—1–zÙ$ʆ®s£–éeÆJ°ƒðo8œŽö|@#7ÓM{XùëûùÇï¥Æ¿Ï·>¿áÓßKŸn}æÍ_º6Š\ÏÐø‹²Äì}’ÛjØYTxœ¦Ê{;JÛ¹¶ðßu'b2u>ÁY¾škÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~Žzi¯k=bžškÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~Žzi¯k=bžškÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~Žzi¯k=bžškÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~Žzi¯k=bžškÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~Žzi¯k=bžškÚÇÏ_دÎ?}.5þ}¹ômÿžú\küûsèÛþ6jýÑ´Ræ~ŠÀŸo ˜0#A‹„Ùa¤6Ú@ÀJRÀy ÷ôÓ^Ö>zþÅ~qûéq¯óíÏ£oøt÷Òã_çÛŸFßðé³W3ôsÓM{XùëûôÓ^Ö>zþÅ~qûéq¯óíÏ£oøt÷Òã_çÛŸFßðé³W3ôsÓM{XùëûôÓ^Ö>zþÅ~qûéq¯óíÏ£oøt÷Òã_çÛŸFßðé³W3ôsÓM{XùëûA.Ѧeêfµ˜Ùí8—>I`:”ìK¼Œr¹8{w^•ð¾—ÿ>Üú6ÿ‡O}.5þ}¹ômÿ›5~èÚ)s?ES>Þ™ÎOLh"[%•¾¹Šm%E(*åä¤¨à ´×¿¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+óßKŸn}ç¾—ÿ>Üú6ÿ‡Mš¿tm¹Ÿ£žškÚÇÏ_ا¦šö±ó×ö+ófçÆ2Ûã¥çµËêJ•´4Ñ9Á>mÿuW{üñsóÚoгö+”á8;HéÆJèý7ôÓ^Ö>zþÅ=4×µž¿±_™ÿ<\üö›ô,ýŠ{üñsóÖoгö*º–Ðý7ôÓ^Ö>zþÅ=4×µž¿±_™ÿ<\üö›ô,ýŠ{üñsóÚoгö)¨Ðý7ôÓ^Ö>zþÅ=4×µž¿±_™ÿ<\üö›ô,ýŠ{üñsóÖoгö)¨Ðý7ôÓ^Ö>zþÅ=4×µž¿±_™ÿ<\üö›ô,ýŠ{üñsóÖoгö)¨Ðý7ôÓ^Ö>zþÅ=4×µž¿±_™ÿ<\üö›ô,ýŠ{üñsóÖoгö)¨ÐûÓYê›ü[º!Ú4 æõߥ´}­Û^—³Zí’ì§Š„©×•+?Àà”¥)J@>škÚÇÏ_دÌž.~zÍú~Å=þx¹ùë7èYû}Nº¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟ž³~…Ÿ±Ož.~zÍú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟ž³~…Ÿ±Ož.~zÍú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟žÓ~…Ÿ±Ož.~{Mú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟ž³~…Ÿ±Ož.~zÍú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟žÓ~…Ÿ±Ož.~{Mú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟ž³~…Ÿ±Ož.~zÍú~Å5¦þškÚÇÏ_ا¦šö±ó×ö+ó#ß狟ž³~…Ÿ±Ož.~{Mú~Å5¦þškÚÇÏ_Ø­cXº‡­3T…¥_Ñ^'np +V:íÈ8k¥õn©áæŸÔÓx»ªb¿t‚‰+e˜q„@%ã ÿ­|BÒÚƒLhkÞ¡w‹Z¾rmð]‘ÙŒ(h¤‚­‡ž„ààáUwdŸR¾ûÿ¡o ·õ—ùÈßËÒ¯r¥Ç¶¾I¶Ú»u’ëpnF·%§TÆÏ]¥/–¥îÏM«SCë¿Äc¯ÖÞÚùCEÜáZï[®‰»l–‹1,$)Î[ˆ)Ü¢RNÕ€HH¯âÿüÆ÷ÅÛÿçÿ¹êŠ­’…ÿîÿÔ°‘¢¦‹kÄíæ9؃Œ¡¤4©M¾ëi*+ÝžSI^v핸§hß_#K^ÙeÇÌf]e×$ºÄ¦Am+JB¢RVœ¤@9#kn°ñ5¾á|ž¸ RîWVä4Ñi·f069FÕå*)L¤mJ’Rvzxÿ35Å­W»*ä™ÖXÊ™­5e‡l*jJÓÁ Gî•ìOE©G¨ODã¯Õ3T¾ãù BÛÍeͪ›Ø—hxI,Æ}-oNå&A@ghÏyJ+HÚ:޹iÆ ²Ï±LDK€‹Ì[|ĘòÚ‚œ”úí)IÎRAÈÇZÜnüDô¼kj¤‰±'·w2¥JŠR–òÝe-dúèT‡ñžƒ {:Pñíh¼]£H´2°Š“!pšˆ©NïZ‹¥–‰BÕ%= ÎÍÇ©5h¹ßTD”m¡­Ò”®‡1JR€R” ¥()JwѺ&Ý´[‘|•}Úå"Ý”[ìïi¶Vë¼Ô–ÒyéVI5¯Û4Õêå¡ÅBÐéXe*Ú|¤eA´)ANÿ²^ž5°iÍ{&Å£!é諘¨ËŸ5Û¬>iC#¾ÌfÒƒƒëŽS¤(ŽéRHÏQWˆË]¶Û‡ŸŽ»œ÷}Ï[å<úKëy /=¹qÖ „wy€`3œñnjçT ÍNfˆÔ±-~‘~ g²·3`šÂž,8„­.†‚Ë…T’U·®qƒé½ª\rM[Ùqé’ŽÛ˜ÂmÇTÚ]@^æw.޵³j;Þ˜·Ü[ºÂŸ6uÙÍ1ܨèa³ rÔÜg88TT€¥ŽXÂÓ‚zVMŸ_é«f·{W¡»³²î×8òîQLfÒÜd"k2Ü ¯˜K„©”îJ0 ɨÏ;]"rÂú³V‰¡®/èû¶¡TÛcFÛ%†WË„d­AÆ]t‘—Þ`)Eisk¯Ri«ÆS(»°Ë t©!´JiÕ¡IÆä8”(–Ö7 ¥`Ÿ ˱Ý-HÑ—Ë ÉsYrTˆÓb»”º ¬7!µ…-;R®¬7·Õ9¬î#ê =ù 2\ÖÔòå\&Cf;ï…lØ…ò”C¥VyªÂ•¿¨tåšÜ µ·4úR•Ðæ)JP R””¥­ŸGéê5âáÛÄUAoú3E­ÆS¡·]-ƒ‘·àÙpç¯]£áZÅoÚG^ÛtÕ¦Å5 æü9ÎO’ôÕ>’—TR–ùO%*O- ûâHÊ”1‚sI¹[Ñ-¯©ƒÃ]7Uj329LZæÜYŒëŠœÃ-µ8”¸YKŠÜâ€'ÕJºùyWš8s«×©bß4äv¥eWÉ-°ê´:à.e¶ÈR{ë œJ¿Óš«DÃÔ:jé4_ÐÞ™š &#ÆeFLtÌ\„)Å)Á±c˜ R‚°äøÕEÇV[¤úwc2Ǥ4Õ¶ÒÖRžëÑ»õ+½êÊæÉ꜓Šfžm Ú<Ç5B£,¢Þ®Ðà !o°†[m±á¥Ü(ÖÑ';T•(nÙü'‡ÚŒ¡Æû\óhµ!‡#8ÛÈs™ÏmÚgᔕîR @VÃ}â–~†“cf5Á2]¶5)m£fôµgA$îÎ3nËñ›éÕ[‹&½´ÅÒVk*Þ»Á‘ 2—eFŒÓ¸]ÑJ°’'4’•`(ÇLÆj™obrÓ½ŠAÃûªt½æôüÛKKµKa…°nqO5.2ëÅhW7¿ÝBv¥!EÍÊÛ’… À^Œ¿·¨ÞÓҷƹ³¼8Ì‹¤fBT‡ eKp'~àpœåC ¤‚no:KÜ ê[s1¦ÛãÎ~ÈF<&€[ñØyµol-)i.©å,ì*ðB³ÖYíg«ïÓ-ïnºÜÜ™nyÛlyŠiµ:âÔÚšy\´©AHï÷öì859§÷ù–$ÝÞ¶Ú%¼üvž{vÐì&7jihq†û­-ä©k+y@ íÚ•(„¬*µÿr—ßBzc²³Ù¹\í©®+òœÜÝŸû{vã®q[Ù×úfF¯fý!v„m#PÆi¸Í¯œÃïGR²\”±‘À•c wªÝM‹o¦±qôç¡=Ù9ì»{cæówîÏ/½³g­øØ¨RŸãV¡Ðš¢Ác×H 5Ø]åKm¹¬:ìs»h+m *JJºr0NEkUº^µeºn¡âÁ¦e¥­KÍìiRS¹½÷dŽg{§q¥›»Äyu]tƒ“^‘I$ž‚”¥\¨¥)@mLio,:OÒ8ô¿£?¤ò~õÛeÏWw{g;#vÜôÏJÄé«Ò­žQÊä; †ÃÅ p\ nÞQâwmÆ>kw¶qfõZé©‘õ¥cNÚÛµ5"ÜÔÅ¥ DvXCéKA{Z›p€q»w\dדÜAŠö› …˜·Újå5`€¢´ýŸqš _Näx§õ )#ãš§#­¡ÌÃÕü2¾ÛuÖ5®*]·36[VòüèâD¦˜ë$¥½ÁN,•”ç¦q‚+B®Í¬uŽ‘ª´þ¸feÍsâ»*áÞˆÍ)7i’mõórÒ°´’…÷T=s\f¦”¤×¤EEô¥+©ÌR” ¥()JJR€£Öö[_ûñûª­F¶ígÿeµÿ¿ºªÔkÅÇv§­ƒì‰¨©¨¬†¢|ª O•A ¥( "¢€Ÿ*ŠŸ*ŠJR€JR€R” ¥( ¨©¨ ¥()JJR€R” ¥()JM=´4öÐJR€R” ?C4ªõ|û™4ªÃ ’l·Û„nzÚAR÷lÓ…à¬ôòë‚)õ”¾h¿¹«Viûƪ:¸Ö§ÄG× ²ãMì?£Ì^ð<¼0:uŇ´&˜½p{F\®‘î¯ÉvÌÎâ‹ôö ’[iô¡#¦{©$“Ô“^\fÐ:FÓÂmUq…o¹‰ Z¤)²æ ¹8v’…H)W‚ÌÒ¨XúN”¥IS€{kæ©6¾°¢•Ë·=Ž/ìWÒ¾ÚЮ¿~]|_ü?Ó¸¾ŠE†kҵöþìþÛÑ”1Ô¡×_ѽ¿;|Ž:½ wGŒ˜?=f¼£®h_‡óÕök¦ÈðªÙ>ý•?ñ—IË{^G‹?ðþ nOÌç«ÒóÑâôoœ¯ª¼±KG‹ŒÁGê­ÞGª¹>uº—ø«¤%½¯#,º ¸?3UrÙ!+kþýUฮ#ħõÕô¯­‘âk}?ñ6[Úò3Ë¢0˃ó+V |kÉn¥> ׳õ†ýl‡Nbßäq—FP\üÉTÆ“â•þ¡_®,'Å.~¡õÖ+µˆïiKâ_är—GQE‚®ñ‡ŠýCë¯áWȃŷþhúêÚÅwÀÖˆôwÈæð4‘|­E­Hù£ë¯?tÐ?#'æ§ë­ißTÖ?hŽ:³9¼#m÷Mò2~j~º{§ù?5?]jF¢­·U#c¤mÞé ~FOÍO×Otð?#'æ§ë­HùTSnª6:FÝîšädüÔýt÷Mò2~j~ºÔiMº¨Øéwºh‘“óSõÓÝ<ÈÉù©úëQ¥6ê£c¤mÞéà~FOÍO×OtÐ?#'æ§ë­F”ÛªŽ‘·{¦ù?5?]=ÓÀüŒŸšŸ®µSnª6:FÝîžädüÔýt÷Oò2~j~ºÔiMº¨Øéwºh‘“óSõÓÝ4ÈÉù©úëQ>ÚmÕFÇHÛ}Ó@üŒŸšŸ®žé ~FOÍO×Z)·U#n÷Oò2~j~º{¦ù?5?]j4¦ÝTlt»Ý4ÈÉù©úéîšädüÔýu©{j)·U#n÷Mò2~j~º{¦ù?5?]j4¦ÝTlt»Ý<ÈÉù©úéîžädüÔýu¨Ò›uQ±Ò6ïtð?#'æ§ë§ºx‘“óSõÖ£JmÕFÇHÛ½ÓÀüŒŸšŸ®žé ~FOÍO×Z6ê£c¤mÞé ~FOÍO×Otð?#'æ§ë­F”ÛªŽ‘·{¦ù?5?]=ÓÀüŒŸšŸ®µ/*ŠmÕFÇHÛ½Ó@üŒŸšŸ®žé ~FOÍO×Z)·U#n÷Mò2~j~º{§ù?5?]j^ÊŠmÕFÇHÛ½Ó@üŒŸšŸ®žéà~FOÍO×Z¨¦ÝTlt»Ý4ÈÉù©úéîžädüÔýu¨Ò›uQ±Ò6ïtÐ?#'æ§ë§ºh‘“óSõÖ¤)åMº¨Øéš‚ñá ²ÛÉR\ %`Œä¾¨©JÏR¤ªK4ŽôéªjÈšŠšŠæ\Ÿ*ƒSåPh)JEEH¨ 'Ê¢§Ê¢€R” †††€R” ¥()Jj*j()JJR€R” ¥()JJR€“Om =´R” ¥(Òžþô7èfÿyuçÇïÀ¦°ýÿîšôà/à/C~†o÷—^|~ü kÑ/þé®|K¶”¥X©À=µOb‚Üè·¦û3O?Éé¥E+Æ ð늸öÕ²åßò‡$)—Þg …d¨%XÁH¯‰‡eJ8ôë~;ßÿÏáâwŒSx;C}×÷Gójӯ°ß»[™ ì¥QÔ½‹)! Égµø:@J ù·V`¹<íˆÒ›*.,zg§ëgf¿¥[Ô{­Å÷~1Ddº¥¹•¬?Œ£Ó>^5¾œp½TlÖ—³¾¿K¯àf“­Ý=mìÝó#^h—=I{6K„fFe¢ÔÌrœ 6zŒ$rpñÆjºÅ¦íó´^zé覢N¼†\Z-Êí.wžÃky+Ê’¢ŸTmÊN{½oåëmÕ½Yç"Tùvcve¥+PJ;ÁDxwRpzg"µVuuŽ'ô…¼ÊS“íW´M“-+!´ºê²FÒp¤ôÏükzXuQÉ[[ñÓz·šàfÿS*ZðþƿNj5†Í¬]fË)¤¨„‡à7M¦&ooxô^ü•tðóë\Õúè\k¸X/ZµËíŠì©ÂjR^hÆ[|‚„!eXݜӹëõ-ÖÊÛ¯À˜ß*¹†íb;çYnÖ#¾uÞ9ŽÖ+¾²¬W| mÆF#¾©¬:ÈwÕ5çZã¸âÁ¨©5b >U'Ê¢€R” ¥()JJR€R” §ÛP*}´R” ¥( öÔTûj()JJR€WÑ|pá›z‡Ž¶)¤-¶Ë;OY%òÄt²Ói<â’€2z%?ßÝ:WÓ7þ3é|·ê»l·nVUØE²[ÍGZÒ‹ës!+ 'FqäN2F(_®øXÝ—H+WiÍQSY™”bKy¨êeL::¤“”äœþ2HÈ9«y<ìVȬÜõ²¦•o]Á›;Ì© ¶I x©VñÈ=H×¶°Õº"ÁÁéÜ=ÑWiWßK\{d‰NÅS eHP@ êUðH¼zto¯uw 5ñ«µÆæ›¬[A†í‘˜ËIqḥIxwR¥¨õÎF2:@ÒøaÃKf°‹S5¤KdÙ¯)˜°Xˆ¹œnu(#’œžŠ^:øVõ ¸OÙ¸ÇeÔûeÎ}’Ô…Å’ät¸Z*!Ä­²¡”6r²¼x?Ä- ¦øk×I–+ÔKšeÜ;$"ã·Vµ),•ø%$¤äTÿâ5ouâV„UÛ‹r˜Ô)u–Ï›n!¾ Ž¢#­)(Nâž§¼:ô8úÕ|6Ò—íÂæ½+gÒ’î6ÖÛ.7nÜõÂCŒ°S›wuÝ•-] Çš«œÚx3y—Ä þ˜™t‡-°ýÂä´•6†Šw¡A= %'8$c¯N»&¨×ÚNhà¿e»s=ÍvoKÿGtvm—wŠ{øå/ÔÝáýã6Ê⦋_uú%Mæ™Õˆ. G^æŠ#‰Ø ŽûƒÃ9¡4=Õ¼(—lrm‚÷ÿgÔRQô´¦9JÚ´+%=sæ}Ud U¶½àݳJÛn!Î!Z—z·°—¶ÉŽb—’S» ­jøSŒôHñèpzW¶¾Öš9½¤xy§î¥¦Ï8L›si“ÕË'’•õJ¾ oZÛõ¯ø/†—«µ]î PÞV‘pà‰“>™7{ïaeÄÛ9S Öä”$;+yÞŒ¤wv ž½Þ¾Z÷ƒvÍ+m¸‡8…j]êÞÂ^vÛ&9Š^INì2µ«áN3Ñ#Ç¡Áé_ÜÝe¥ûŸ´^”vå(Ü­×ÎÕ>Ý`wO´Ê”b iH OxžùóÉåšè»Þ¤¹Þœh4¹ó”¤’âʈášê{½ézs6Þ¹oIz[—ý/´óy[¹ž8ÝÞÛáåŒt­oî}ÓšjëÛ|‹n—²ê ®éfünm˜±J••µ»¦Blj'ÙYŒÚ#˜uø3ÝW¹ßDz+²«o7™Ìæs}]»¿¿8òÏJ×xO¯ô;<:°iíAw—`—`½¦éÌf*ÝLð•-A d/iÏ’Sãä®þÐÚ“Œš†ÍnÕ´ÆžŽ•;TÀ9jX-¥M'˜´~2–GRp:ŽJ°—¤Ú£cê][pp"Ø‹‚P¸M¡#rÊ”0v…œàžèÄ×÷&éÃyÆ]A{ÕÓî~Á)²äUÅo.)ÔòÐ7¶æ7$-g§Ÿ¶³…«á«ö‹Œe"mžíÍC¶ûà uÐÈ$§–ƒãÐà}cá@ux¼>Зº‚M’ßnHµ[­ÆdØ% K= ('`ñ>µ`tÎG‡JÓøÇi°ÝøA¥¸“i°Ûìr'Ëv˜ðZå² èIÚ:9'¯žî¾¯WÆÝ<>èdêæ£HMˆÛ}ëÁ¿„Z7oæíñõ°1ã´{zV©ÅÝ]¥WÃ;ÃÍq~ëÙ!ÙoMr:™ R”áJBU×§5y?áÿ*®úGYø‘l°?Ä87 ñ&]Ú¤²R< µ‚³ËHsðƒ¡óÚ>é+•´hÎÊÒ––¡EŸçù…¤‰¤¢:^Pê¥ çÄôÉÇJç¼Pƒ¡­÷öЙ×kZ¢¥N½-+KÛÖ @-£¦Ðƒáæzû6¾5êí=¨´mvk‡j™fµ˜÷ù.#’ç*:q•$um}RHéýâ€ÝôV§¶IáÝ÷]êŽpý‹dÓ·Ðä$®MѠˈåÈ)© +¼ã£)$tÿ ævÖ£?qŒÄÉB$gB| ¬4‚@Röާ'©ÅôD¦ô¯á>³½ÄÑ0´õšÒÃi²Oìá¹OHÙÞBÔ ßð… ñ9 ë×ÂÛAhýn³pïMÜ´µ²æö²ƒ*TɲÜû{XKÉ ¯ÅLxgƵŽ,Þxq|Ñ0ôþ›â@…j³CQ‡hE’I3$%$‚ã§hÊL‘€T¢sš°ÐÜSЂǢá6%çGD‘¨MÄS‚`[A¤”¬wSÝJ}b:çË­[¢4­ƒFè­«î¶H÷ì7“iŒÍÁ ã@!æÐ¥øy£¯–Þž&¯¤ð‹L¯î˜ô2`'О‰ôÉ€•‚wò¹c¯D•÷±áåáZv„â™»ég¥5¼çìñµ ÏÒ‰–Ôu>áq Z S×ú´àãÛáçp¾7ÙÇÝî½,ÉUƒ°z+~Ï„ånßÌÛÿ¼ë¿ßÒ€£û ­+‡§¬3ÑZfÔ© X-=+tg±Ÿ‚R ;ÙVv«Èqšë¼[ÕúLðÃOpïHܤ^#[e9-ÙîÆS9*S…( W_ëU“áÐÑP¥<üèoÐÍþòëÏßMaú%ÿÝ5éÀ_À^†ý ßï.¼øýøÖ¢_ýÓ\ø–;m)J±S€{kBºýùu¾ûkM]®çsø¶Û¦M-ãgaNmÎq ã8?ª¾„MÕiDÏQNNƱ#«døVÜöÕŠ4ÍàÿðN}U‚öˆÖ*Ý/x?üþªþ‚”ZÞ6¥zOýËÌÓdx«“ç[ÃÚ[+8Ò—ƒÿÂ/ê¬øs¯ºJðøU}UéQ’[ÙŽuaͯ­‘âk ?à «ÕÑ÷ƒÿÃ*°žáWÔzhËÁÿáÍzTjÓ[ä¼Ì“œyœíúÃ~º#¼#âZ¼4Uãè+Þq=^"ñô5èSÄÑ_ï^hÏ&Žríb;ç]!Î qHøh{ÇÐÿ­c¹Á^*œãBÞ>ˆ}u²ºõæŽ29£µŠï®šçx²|4%ãèÇ×Xîp7‹‡8ÐW£]j†7 ¿êGͤ™ËÝõMcù×P_x¾GMxù‰úëÇÞŒ9üÞ>b~ºÕ~ݬ|ÑÉÅò9©¨®–x Æ“ûÇÌO×Qï Æ“ûÇÌO×VÛð¾¶>kæFYr9±ò¨®–x Æ“ûÇÌO×Qï Æ“ûÇÌO×M¿ ëcæ¾c,¹Ö•ÒýáxÃòxù‰úéï Æ“ûÇÌO×M¿ ëcæ¾c,¹Ò•ÒýáxÃòxù‰úê=áxÃòxù‰úé·á}l|×Ìe—#šÒºW¼/~Oï1?]O¼/~Oï1?]6ü/­šùŒ²äsJWK÷…ãÉýãæ'ë¨÷…ãÉýãæ'ë¦ß…õ±ó_1–\ŽkJé^ð¼aù?¼|Äýt÷…ãÉýãæ'ë¦ß…õ±ó_1–\Žj*}µÒ½áxÃòxù‰úéï Æ“ûÇÌO×M¿ ëcæ¾c,¹Ò•ÒýáxÃòxù‰úéï Æ“ûÇÌO×M¿ ëcæ¾c,¹Ò•Ò½áxÃòxù‰úê}áxÃòxù‰úé·á}l|×Ìe—#šûj+¥ûÂñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9¥+¥ûÂñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9¥+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­t¯x^0üŸÞ>b~ºŸx^0üŸÞ>b~ºmø_[5óeÈæ”®—ï Æ“ûÇÌO×Qï Æ“ûÇÌO×M¿ ëcæ¾c,¹ÛÊ¢º_¼/~Oï1?]G¼/~Oï1?]6ü/­šùŒ²äsZWK÷…ãÉýãæ'ë§¼/~Oï1?]6ü/­šùŒ²äs_eEt¿x^0üŸÞ>b~ºx^0üŸÞ>b~ºmø_[5óeÈæÂ¢ºXà/~Oï1?]G¼/~Oï1?]6ü/­šùŒ²äsZWK÷…ãÉýãæ'ë¨÷…ãÉýãæ'ë¦ß…õ±ó_1–\Žl)å]+ÞŒ?'÷˜Ÿ®žð¼aù?¼|ÄýtÛð¾¶>kæ2Ë‘Í)]+ÞŒ?'÷˜Ÿ®§ÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­Et¿x^0üŸÞ>b~ºx^0üŸÞ>b~ºmø_[5óeÈæÞUº_¼/~Oï1?]=áxÃòxù‰úé·á}l|×Ìe—#šRº_¼/~Oï1?]G¼/~Oï1?]6ü/­šùŒ²äsaQ],pŒ?'÷˜Ÿ®£ÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9·•Et¿x^0üŸÞ>b~ºx^0üŸÞ>b~ºmø_[5óeÈæ´®•ï Æ“ûÇÌO×Ox^0üŸÞ>b~ºmø_[5óeÈæ¦†º_¼/~Oï1?]=áxÃòxù‰úé·á}l|×Ìe—#šRºW¼/~Oï1?]=áxÃòxù‰úé·á}l|×Ìe—#šÒº_¼/~Oï1?]G¼/~Oï1?]6ü/­šùŒ²äsZWK÷…ãÉýãæ'ë¨÷…ãÉýãæ'ë¦ß…õ±ó_1–\ŽmQ]/ÞŒ?'÷˜Ÿ®£ÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9­+¥ûÂñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9¥+¥{Âñ‡äþñóõÓÞŒ?'÷˜Ÿ®›~ÖÇÍ|ÆYr9±§¶ºW¼/~Oï1?]=áxÃòxù‰úé·á}l|×Ìe—#šRºW¼/~Oï1?]=áxÃòxù‰úé·á}l|×Ìe—#šÒ·½IÁþ%é»ÛýûHO·[!% ‘!ò„¥N%´þ6I*ZFO\øF‰]éÕ§Uf§$׃¹ 5¼ý)à/à/C~†o÷—^|~ü kÑ/þé¯Nþô7èfÿyuçÇïÀ¦°ýÿîšq$í´¥*ÅNí­ ë÷åÖûí­ ë÷å×çü/hÏ£G²E ­“áVR<*¶O…{ôL ÙªäùÕ¤Ur|ëÕ a™Y+Æ«dxš²•ãU²U€R” $TTŠŠ|ª*|ª()Jhhhh)JJR€R” &¢¦¢€R” ¥()JJR€R” ¥( 4öÐÓÛ@E)JJR€ý)à/à/C~†o÷—^|~ü kÑ/þé¯Nþô7èfÿyuçÇïÀ¦°ýÿîšçıÛiJUŠœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦±üë\wX5&¢¬A'Ê¢¤ùTP R””¥¥)@)JP R”TûjO¶€ŠR””¥>ÚŠŸmE¥)@)JP R”‚””¥>U>U”¥>ÊŠŸeE"¢¤TP R”ŠyPSÊ€ŠR”ÔTÔPåPj|ª ¥)@H¨©ùTTùTP R”ÐÐÐÐ R””¥¥)@MEME¥)@)JP R””¥¥)@)JPií¡§¶€ŠR””¥úSÀ_À^†ý ßï.¼øýøÖ¢_ýÓ^œüèoÐÍþòëÏßMaú%ÿÝ5ωc¶Ò”«8¶´+¯ß—[ï¶´+¯ß—_Ÿð½£>Ér<*¶O…YHðªÙ>ïÑ0T+dx«“çV’< UÉó¯V†ed¯­‘âjÊWVÈñ5êÑ1Ì®~°ß¬Çë úô©™¤a»XŽùÖ[µˆïmÂF#µŠï¬§kß[`q‘ˆïªkβõMcùÖ¸î8°j*MEX‚O•EIò¨ ¥()JJR€R” ¥(©öÔ Ÿm¥()J}µ>ÚŠJR€R” ²/E^ÑÃôkb–}©=ŸhQæÔ q…IRsŸXŠ †ÓoKe—¤7·JVóE-‚pTBAQÇ 'Ø vË.¯áï¤ïÚjT©Q´üËJmèšä‡aA 9.71ƒ‰sq+;•€Júž™ÑBœ'|îܽ§—ÒX¬EB\]•ýÕÒñÖê×zn8ý¢Ã|»´ë¶›5ÆàÛ?}TX«t#üJAÇüjôh²ï"ê¸rå?1Ûס×mìxPt¶V Jò6Œm$ M塞3´&ŸÓ©Õ Y¤Ø.]uôG}Hœ•¬)5µÞ0ê+lÑúóGÆÓeW¹Ð®¥k/ÆœÃüÖ™q%®nZk•ÎNy˜N3€€:Ó£I»J\9ýîø˜±}!ŒsS¦ô–äÚÖÚµkIkul»™ÉÕ¢µ’wîÒWñËZ[^mÏwV¬a'»ÐÉÀÿÚÚÀc½I».ÓÏpzâÙ!qŒµ<’Y¥¦÷‘œ›Ü¾¦&J:vïÙá(¢S½‰ÍŒ) (…œa$ Î:SLÞÞuk~ËyDHÍ·"kÌÀ[†÷œî1ëü=ê®{WécêËBfZíº•W˜ræ59Ýi@íAäly+A>`§;±žŠª¼=.ø£´:WÓÍAðàùÛ¯ì½øû9]¿LêK„w$ÀÓ÷il4÷!džâÒ‡z „€®òzxõÚ´ÒZSêYW˜-ï7"Ïre4ó.îOƒ “ÍW]¨8ÎÓì­æN²³\4÷žP[âÝ5á*#lB’Ê]Ts¹Â É Ü¼“’ €k>ó¬ô„Ž.k[«æM¯Qé·mñåÏ„²òÚiq<½þ-“”… (yä¡EY¹|WÉy‰ô–>JQ&®žY>váÅ$¿ñ~Ã’[ôÆ¥¸J“ž»K‘ÂÜ–˜„âÖÊÁ ¥` ¤‚ÁöUl¨ïÄ’ìYL:ĆV¦ÝiÄ­ *¨ Œk¯pæÿ¤lvGôõâÿfºÙ¹¥÷˜“o–ÛÝlã¸ÚNw¤ì=À{»ˆ³QÉ3PÜ¥ÄvSÑß–ë9)eo- Y ­GÅD“æs\*SŒ`šzžŽZµyÂpj*ÖvjþÚÚse})JàzDÔTÔPåPj|ª ¥)@H¨©ùTTùTP R”ÐÐÐÐ R””¥¥)@MEME¥)@)JP R””¥¥)@)JPií¡§¶€ŠR””¥úSÀ_À^†ý ßï.¼øýøÖ¢_ýÓ^œüèoÐÍþòëÏßMaú%ÿÝ5ωc¶Ò”«8¶´+¯ß—[ï¶´+¯ß—_Ÿð½£>Ér<*¶O…YHðªÙ>ïÑ0T+dx«“çV’< UÉó¯V†ed¯­‘âjÊWVÈñ5êÑ1Ì®~°ß¬Çë úô©™¤a»XŽùÖ[µµëKu¢/ ô}Ò¦ÕÚ¤%×TWÈp60•,¤nÎå`xŒ•éP¤çI?¯ñK÷<üN&4gN 7Ùnßg-uäŸ3Ÿ;X®øézS†3ïö;eÍONmWÖÌSÜ©-·µ[JßXPå#vFp¯q_ÌÎFÈë·ÙYŸ1ø“Šmé(·­€®våsr­»IP º}x:Î*Ytü¼>gS¦°1›¦çªmn{ÕïÃÁùXånú¦±üë©é®ȿڠ\£Ì¹˜—YnÇ·¸Í¥O%)Böd”¯ $Ÿï^0¯3^7ËB ðÔηAnïnÖ+¶®J#6—¶&:”¦ÔàKÉ=â|ð PÃMFòVV¹Æ]/‡u:nï2‹ákÝq\³9‘¨®Â»žíÃí_q•`´O¹ÚW Pݸ\ŠÖp¡iZƒÍ£')ÉqÆOA^V­%jÕ·KÄAèý/&Ée\÷ÓÓp‡'bŠ” ï9ek' . ¥G¡îÔ¬<š‹\çòà%ÒÔa:’k#³zqIÞɹ[Ò\7œÜùTVñoÑ–Kºã{‡©¤®Éj„Ë÷ÕlÚûO:ê›C)k™µdí ݼ +Ú«Xœ+aw”y:L°ÆŠ„ÁÞ™11“¸smy `nóëÐd°õåñE§ÒØX]JM[~’ððߪvßg}Ç2¥tùÜ)a¸Òœ‡©L‡S¦Æ¤ŒÚàòù±02w‹êpàqâ+šÄu Êiçc·%¶Ö•)— ‚ä¥E$+Ààƒì"©:R¦ý#¶G›¢ïo¿½*W^ÔZSMGÖMCn³3î.m ÜÜŽ§Þ!)m8u¢½û¹œÂ„ŒnZÎk´Ÿ U¬âÇ•k]Î$©è}ä2›+Æß¥K)dÊRÉꔌ+Ö’k¦ËS6U«ûù™Ma•5VwŒyµ¹ëtí{5g~ ž§2¥t–¢[ûžáÏ›3/5«D5ÎbfHŽcÝÒæ¢@R¼€ÈbÃ]pù¶õ¶²z}ƾէšˆ¹NÛ­›”òCl0 $䕸‚|ñMšVºðþÍþÄ®–¢ª8OK6¸»ÙÆ:YqrZo95+¿ËÓ6{¯t-º#Vˆæã¥Y•¸Y[TYO”<¥8ãS`e)$œŒu$m;¥ÀS©ä®swŸN®y¸ûÁÄr´³‚èNÃÑEÍ»$m dÚXY+ëÏáo™Î—MQšâîòðoñ9%ùz/äsºWL™Ãk6ëMá½QqzÑp·Hže¦ÐŒ2À-(v_qÆq¹IêrHæuÆ¥)SüFü62Ž)7IÞÞ qkŠZÝ0*}µ§Û\ÍDR” ¥( öÔTûj()JJR€R”   ¥( ò¨©ò¨ ¥( «eÂ}®sS­“dÁ–ÖyoÇuM¸Œ‚’È$57kÊí,̺Ü%Ï’@IzKÊud¹Dšê04ž›Ôœ2a»U¥õkvK%m>ê„ÖÛ’û§bÖ µ¤¯ºTN+Òá í pžÜˆvÆßÕ²õ‰}ÀqÖƒÁ´¤( îBT“מճTË£Ò×ÿiâ>—ªž”Zš–]ÊëÆ÷ü>? œ€TWR¾prãoe÷›-)‰qb§®ÕÄcá\å‡Yp¨óZ ÆU„ô ã²n|µ5»N¹}™lÙÝ™·&Ú¹1Ý@BÔ§Zu.¬/ªRƒµD­=Z’·#ªéÜWU9ð|ßM?aÉ)]íÃh¶ÝMl±È¸jŸ”$)öÜÓê/¶F[ShmÕ¥àâ²R¡·V{Já ×Ý–µÅ“!Ô|îO¤`ª#ñù=]æ4T¬a=á…‚*»5^_l¿ùÆɹèÓkG¹^ü9&ýšîh悞UЇ-“t‹7룓=rï­Ù!ÇrÚÞúÀPRÕÍVÄà’0}\ã'o¦¶áUÃNXn—T½pu»L”G–e[·7¨¤8ÂÊ5€Â|RqƒG†©kÛBWKàÜÔ3Ù·k4Öº.+›KÚsŠR•Àô‰¨©¨ 'Ê ÔùTJR€‘QR*( ò¨©ò¨ ¥(¡¡¡ ¥()JJR€šŠšŠJR€R” ¥()JJR€R” $ÓÛCOm¥()Jô§€¿€½ ú¿Þ]yñûð)¬?D¿û¦½8 ø Ðß¡›ýåן¿šÃôKÿºkŸÇm¥)V*pmhW_¿.·ßmhW_¿.¿?á{F}=’(äxUlŸ ²‘áU²|+ߢ`¨VÈð5W'έ$x«“ç^­ ÊÉ^5[#ÄÕ”¯­‘âkÕ¢c™\ýa¿YÖõéS3HÃv¶ :ÐHÓö«Ý1d™Ô…¦71R’ \!N(”<œ•(gØ<€+_v±ó¯FIBùx˜q8juò¹¯ÃªÕ«;[‡ƒkó6K޽ŸqC­Ýí‹›FkóXD†ÝÄg^÷68’RU×j· ­‰®opt­ãN0ˆbÑâû‡“µL¨Œ/”BPžéõz Uµç&,¦â5-ÈÏ";ÊRZuH!ãpIð$ndžG¶·Â½Vïs°X¥ Š×M.Zè¾.Ûø–õ„–4ô[ûM®ï«vf¡ÌÇRÈ+ -­9€JU‘Ÿ*ò•­eÈÐÎéÚ-)ˆíÀÜKí¶âMÀ†ÀÙÜÚ´,÷«_wÕ5çZcVvµü ËAÊùxߎþ~z¾oy²Xu|›>½é–­VÙ¯[;SÏs¹£–rÞÒ—FÕeCºrN¸`Thm_'IzW³Z­³ý) p$vÎwFë¡<·Ø=HÚ0G\Ô‹TÕX\¾%¶Œå&"ÖFô¸¤©iÞV§iÈ"°jÝdãgËqW…ÃÔS¯™úZñVý’ü¬^é}O6Áá ¸Ñ&ÛîM%©°å%E§‚U¹ìRT OPB…_Ãâå‹•ÆkÖ›<¾Ûjp˨y-Ç…Œ[q$Ó©%]:“ùTR5§dÅ\«rœnÞÿ‡É~I# Bâ­Ý¼Û%’V4ûzxóRøÌ4ç ìu=åde_û#nÞ¹çõbÅ’æô óS%«{-?$8âPâ[uIJ¢¤’´uH oI8Uu'9ÊÙ‰ÃPÃÒrêRá{{4öhïù›'»[ß½øÑL›`”dm<Ð ovq³p Æ3¸š¼³ñbûm™`œ›U–Lë NÇ KÍ;»“±HÚ —OEð^ÒzçP¸X¯vø,Οg¸ÄˆÿÞ_~2ÐÛž}Õƒÿ þ^²ÞXµ7vzÓ=»s§ Ë\e†V}dm?®®ªU‹Ñ½?mÇ á0UbÓI©7ù·£óâ_{¸_¸ÿržæ¬žŒôŸ¤öfVînqÜìíåüÙ-pîPdÂ’ŒnfCJmiÿ¨(â×±« ;&¯¿òæ_1­îПÓòìÌD´Í±FThÒc©n%JR•Ì)i$©ÇDß# !µvÌý÷<Í™Çw1ޏÝÞ­vãh»[bÕqµÎ‡j9‘]~:›CéÀ;H†“‘Ÿí¬éÖÔŽ—3lxZ‰K*zïüÛßÇVôzuÇ\9>ên¯é6f»)¥º¨«_jRVBÒµ”¤(Žð@FàHð&³â]ÁØP­‡OØM¦$‡$¦Ü¶ßu…¸¶”ÞO1Õ(m %!*H ŠÑ…E:ùó£°Í$ã»v¯ÙÏ–î\„ß5r"r¡[,íè„CËl²ñIp©ÂîIJpwôÆ)hâEÀËÒP’ͦÃÅ9k‹:U>U”¥45i¨,7+µsLVžYP,·1—\h§KˆBŠ›W_€|}‡Ê,WUG»7ñ·÷ÓÚVÒ½eçPêÛikK)Þê’’B¸''Ø2¤ŒŸ2yÕN·¥z>ËÌ,!ö–ÒŠR°•¤‚R¤…$õò ‚˜ Ð_çJ΃j6Ûp¸Æm¥Ç·!JËÈJЕ¬!*$)Cr’ H8Ü3ŒŠÆLwÕÉIaÓµ¥µºv%J )I>…<öŸa©³*§tží??¶:ŠšÎ±ÙçÞd¸ÄÚ%¦Ë®­é ²ÛhÈNå-Å%)RGR:<è“nÈNq‚Í'd`R²np%[g9 k\§›Á ()*•%@¤©$(( A¬j†­£&2RW[…+:Ãj|¼F´[[iÉ’—Ëa<†‚Ô|¹d''À õ$’@¬›;\ŒÑrË}~þLR”¨,)Y×[Tëcp\˜ÛIDø©—M¼‡Ú*Rs”‚…“…’ƒRÓ[ÊÆQ’¼]Ð¥)PXR” $ÓÛCOm¥()Jô§€¿€½ ú¿Þ]yñûð)¬?D¿û¦½8 ø Ðß¡›ýåן¿šÃôKÿºkŸÇm¥)V*pmhW_¿.·ßmhW_¿.¿?á{F}=’(äxUlŸ ²‘áU²|+ߢ`¨VÈð5W'έ$x«“ç^­ ÊÉ^5[#ÄÕ”¯­‘âkÕ¢c™\ýa¿YÖõéS3HÃv±ó¬·kß:Û„ŒGkrÕpµ<žX'Üm·.É\Û«Š¤´Ôu3 -(`%D+ üen9$šÓ]¬W| zg•5ÌÁ‰ êNœÓK+¾ëðkMU·ø˜Žú¦±üë!ßTÖ?hŽâìßô3W–8uyŸl°úOuîÜÓ|Ûjh«—)$””•eÖÓàH.§%5¶±¦mÖëÞ£·Ä³L\Øú‚C*Œ‹W7m,—]Ai Qæ'ÄÞOLñ3QZá]E$Öïù<Šý:µ%5RÙ¼<W×[Yùùö½;g.«Lĉ¤X“i¸j©¶îÐõ­§œTÌ É ) ‡”G){Uµ&µ‰ ¹éþÛß›¤¡½>çmvLëBCˆO- ‘¼¤b\/”¨’¤–”‘Ñ*MsÃåQG]5¢ûÓÃÀC£%')Ý^ûž¿‹÷ú[üØÆR5&§]úÇr¶ÛU¥m’gˆ6 ÙJ·BqÝ­„¥ %m?ž˜NÇ;Š qfÛw¶ëYˆ»ÙãZ‹‡|fâ˜S?Ф$%=1㑜äEjT¨©YN6·Þ¥°:Üî­kZܺÕò×þ5éږѯ!éÍAzÔv뫲ní4õÅé Ùa²ûe’K¥e!¢J¨NEÞ-ɽO©õ „<4´ÈÑBôwš[JAðR¢ÏpuNÃ0k”ÒŽ²åñöøx‘Ž•¬ä¸î´ywk£YUŸÂúZïäÞ§Ôú†BZd h‰!Gú;Í-¥ ø)HQg¸:§aÈ5—©Y®ë‹Ví–A H·_›”ð5ÊPe€J¹JBÆÖ¹iHP ëêšãÔ©Úº}ù}ó+þVïŸr¶æ´ÓÇW§¯{³Â‹3Nßm6MÎç:B¢9ËrXó)/s[ChqÍãqެ“´ôÂs[*9©³*Óèu_5KvèlJ„s˜¶Ã²T¤,4 âö¡QBT)è’+Ò¢5Ôx­ÑΣwŸ÷kue½5¦›•½¦ï­áÚv;W)7;\Ö­i-ÚÛoµ"#¥ÇO!JqÔ©¤žâñ…‘ÍVFG[û¼[“zŸSêxii%¢$…èï4¶”"4ƒà¥!Ežàê‡ `×)¥G\¯»ïïØYà$ÒN|ÝÎÏMnžš6ÛöWŠ6”¼þ§¼\ôÄ{+†Oiƒp-ך¸¸ããrP¥®$¥kXRŒ`޵¬hèÓ.:OPZ¬Í:ýÙ÷¢­,0 uøÉæóP”Žªï©…ŒôN|«Q>Ú‰URžk}ùG*t:¬÷³MoÒÖÓVÝ´çÄìL¢q±;iU«Ý í›l&§YÔµ•­AÙE+PiAÕ)¦”Ê ¡ýïW§^Ãqë4‰iÀ‡ Úá¡Ä ¤z ªC£•°’§9ƒ ÂÊ”ŽgSÒ¹•*î½ãk}ù}ûN4ú1¦u>7Üü/ºV¶šiàÛWO«êØúŽ-ƒV/TGm䩵 ÛKQnðL„Ú7Š@OÂÒQ´4ñÅ5l}GÁ«ª#¶‰rTÚ…í¥¨·x&BmŽÅ 'ái(Úøâ¹E(ëÞú|}¾$ãrúKG}ÖÝ—E®‹ÑݪÝd¬ŒësV•Ř«ŒÙÑä!І"%Ô:¬‹Qq;z€¿Ó¦ ö‚´jAçg²"j­Š,ȹöhêt€á¾êAR}x@ñ=ODå:§¶¢¸ÆI5to­JS‹Qz»Zêé[ÃOj»Ñù>íÿp^¨´"Û5@è¶]énÃCmPTáÌe­>90qïs‹r™¦ÓÐÐôRˆQ:;G|‡C²ŠšÀê¥%+‡” ‘Ëê;§¦•ׯ\¾þfò×d”––{¸¤—=ÚnøèvsSfU§Ðê¾j–íÐØ•:ç1m‡d©HXiAÅíB¢„¨R3Ñ$V­­áÚv;W)7;\Ö­i-ÚÛoµ"#¥ÇO!JqÔ©¤žâñ…‘ÍVFG]"•¬¤­bÔz9Òžu?9ø]´—å«]âÜ›ÔúŸPÈCÃKL-$(ÿGy¥´¡¤) ,÷Tì9²õ+"TûõÅ«öË …$[¯ÍËxå¨2À%\¥!ck\´¤(uõMqêU¶…®Ÿ~_|Îånñy÷+nkMÿ;—­ÑҪߧÅ=ÚÝ[ŠkM7+kä]kx­ºšL;u”%¥ùÎKŠm*q­ß±eHÏþÍlú¦ª•ÂM;p¹Úî’$ÉA·—ii¨ÊfYP8 Y ¼­Ç$“\ú•EQzZo4K 'Õ<ÚËWoFŸ/²NµÀ¹ðnà»$}[èx²"¿ªÂ‹[l˺¥¥ò JÉÞçõ`6œ+¦5ë]ªþ™h§¬ÍÛž•§zD30¼»ÃÔlÛÞIY %´”«jƒ×žùTUÝtí¡šŸGN K=ÓwÕ{7Ù«î½ßUž§W¸ÇÔroM²Gn$Á¦Ò™–µo [• ¾¼Ü«ºéNཪXÝäuŽ)ó>ÎÓÑ}óv´%ËhQ=€ó]ø.ñ+9…’¡ÌÁ=+O¬Ë4ïFÜ[˜aÚĶ·´°¤”FAð= ƒ‚ ‰URVûûøx¥•)¦¯¥­wí»ów~;ïºÂ TÄô2ãfÇ(´ÛËÚÛ¯ s‹(QÈî©À„ž£¡«›U­·¤[Õ¯lqmŒÕ&(·7rP#¼ ÊyiZyÉŽNÝÛÔ7c¨ç‚ðíáøÊTXÐØŠÀ4`®[-îRð7©J9RÔ¢I'*5YVU”^ëý¢’èú•"Þl­ßÚ®ÛÑÞÜlôw±½qV xÚ–«|Èw¼þÑhbØV€SË=§ä'pÆ3‚kc²Bzm«G8¹d“nP¾NM¹¦šD© —àH-©- ¼…-IêTF+‘ж¾ß ÖÛg‚m°b TS·.ïu%jp•ïZ†w­ÅwB}r<@F´Tœ­ùy ¸Ž•:JW³wvÜš|.·6­mÖO¼Ë-C´hx7í;n…m½Áe3n+¶%—¹hœ¿„mÀ‘…òyWR¤¸ ³”šþgÛï‚åÝô¥¾†žcÐ!‹[Ií/—ÐH?Ò›-•ž÷3%)ëÞÁæ4¨uïÃïïRË£ZwR[ï»Æúk¦ž‹ßuÈíZ®ßt‰'V?oÐJ­z¨Vä¦Ä•'’ñx””ìÛ¿£mÝœs“·“X—=.å½ýIé>mºÛ­¢¶Àv8g1Ö_£!@¶¤˜½T­£˜…tÝ“ÈE<ªÏ›½¾õðöyaÑU ¬ªràøeÿ»ÁûÏóíNYa‹Ó ¹ÛbR¡ÉU¾/¹ÖZ˜·BÙ. q->…8P¬å*ÈVКÀ¹Z’Ô‹‚¬tÊÔ‰®»; XJ”÷9ÔÂJœJ„Ç$dnR‚R5ÈéGˆ‹ÿoÄG¢ªG}KþZo½·îð7~+¢m·]D”ì£/ÑvÇ™mL‡PLFSÝ .6…'®àvsÖ·meÿ#Qêk›:zÝ2äåÍÃddÚã©r!—\.HKAz°Ö•ä-dBˆâuU_Y;o×yÖ]Ü)¬ÊðV½·­;¥…¹¸(!g* ^8a¡«¬F²|ü}§t]áJ)¯A[ðïÕ=5ÓwŽó¬_´ÍÉŸvaZMqÓîrÛrP­½™õ**-¹hu– R@ÂîtÃ⭴ǰ¢Rl±m,©m†om—’’…œ4ûJ)–ÏA—U•gg^§<Ε­šKÍøx“K£ªBQ“íá¿H®o—ÆÜïÐôËWíWé‹kíÌ™qƒÛ¤Ú’O)M3°¥Ý •…—ÊI ¶ SW׫%Ê-Úèä=+êÛí/3v†ñË\QÚÝn1FÂCÉ 8Gt•øqÈjÖÅwjØÜ†Ÿ²Ú´”LmyANpR¶Ô…§Ö9X=2&5–ç÷¥¹«ÑóW”Ýß ÷’•·ðJÏŸÓ¦GŸå«Þ·éè\»~’¶•³Þ…ÇmkT'ÖV’—yËÊ÷d ç)OL«¥³QŵެÖ3‰rܳO\Gììa°ì»C˜um´=ÝÝÑ-’  r¬ñûÕÊMÞæíÂ^Îk) m;P„¥!)BG’RÀ+ ¬ñ*ú/·ÃÇàr‡DÏ*Í%{.Õeñ×X¿?=ß…V•Mvç9¸âc‘šCiŽÝ¡7'ÁY'šˆêZP ‚ •7Ž™ Ñ6Kݪñ¬ÚÓ:mÙMJÓöél!v&ß-×b©[[)q ÚÄ•$(ñZФ+(Å+kÎþÓ¾#£ªVªçYÛG­_5}ßw#˼ݹݭq c‚m.F±ÄqrfvVІþ´ÿÁ• ¡#“€ý½PÕ©åAÒ¢Kì1åÉLÛ äÊÐù(Sæ)M’ •©IÚ8í*ÏŸ }§ôD£d¦¬­¦^Mxñ¶¾:›— ÖýçŒö Q­í6·ï¬É1¡2Cl¤<PBv¡ ÿrSýÕ³pêÉ2cºA§,rÝ©ŸƒwKöæ‰m…˜À"@Rzõ2’¼z$‚ž•Ju”w¯½>FœNU[Ë+h–ëð’æ¸Kàv d¹ú3FÀŸ£Zu3u«dÇdY’]ì㑽%eIí'y;“ÊX( kE®ñ ËoMŸJ@¹Ó}(_g}-%§V¼*:Cilä)³•+¯NœÞ•=zÓO³ÃÃâsÿ.ÛεwÜùÉ÷¿îóI†Õe¼N°é›2ô«’™•¤î2ê­¥ooC³d¶æÝÉï-‚6‘»œ€s¹5Ç©J¥JŠii»þ X\,¨JMÊùµÝmnß7Í/ËÉJR¹)JM=´4öÐJR€R” ?Jx ø Ðß¡›ýåן¿šÃôKÿºkÓ€¿€½ ú¿Þ]yñûð)¬?D¿û¦¹ñ,vÚR•b§öÖ…uûòë}öÖ…uûòëóþ´gÑ£Ù"ŽG…VÉð«)['½ú& …lUr|êÒGª¹>uêÐ0̬•ãU²U”¥¥)@)JP R””¥>ÚSí "”¥¥)@O¶¢§ÛQ@)JP R””¥ ¥¥)@O•EO•E¥)@O²¢§ÙQ@H¨©”¥"žTò "”¥55ùTŸ*ƒ@)JP**EE>U>U”¥4444”¥¥)@)JPQSQ@)JP R””¥¥)@)JP R”š{hií "”¥¥)@~”ðð¡¿C7û˯>?~5‡è—ÿt×§zô3¼ºóã÷àSX~‰÷MsâXí´¥*ÅNí­ ë÷åÖûí­ ë÷å×çü/hÏ£G²E ­“áVR<*¶O…{ôL ÙªäùÕ¤Ur|ëÕ a™Y+Æ«dxš²•ãU²U€R” $TTŠŠ|ª*|ª()Jhhhh)JJR€R” &¢¦¢€R” ¥()JJR€R” ¥( 4öÐÓÛ@E)JJR€ý)à/à/C~†o÷—^|~ü kÑ/þé¯Nþô7èfÿyuçÇïÀ¦°ýÿîšçıÛiJUŠœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦±üë\wX5&¢¬A'Ê¢¤ùTP R””¥¥)@)JP R”TûjO¶€ŠR””¥>ÚŠŸmE¥)@)JP R”‚””¥>U>U”¥>ÊŠŸeE"¢¤TP R”ŠyPSÊ€ŠR”ÔTÔPåPj|ª ¥)@H¨©ùTTùTP R”ÐÐÐÐ R””¥¥)@MEME¥)@)JP R””¥¥)@)JPií¡§¶€ŠR””¥úSÀ_À^†ý ßï.¼øýøÖ¢_ýÓ^œüèoÐÍþòëÏßMaú%ÿÝ5ωc¶Ò”«8¶´+¯ß—[ï¶´+¯ß—_Ÿð½£>Ér<*¶O…YHðªÙ>ïÑ0T+dx«“çV’< UÉó¯V†ed¯­‘âjÊWVÈñ5êÑ1Ì®~°ß¬Çë úô©™¤a»XŽùÖ[µˆïmÂF#µŠï¬§kß[`q‘ˆïªkβõMcùÖ¸î8°j*MEX‚O•EIò¨ ¥()JJR€R” ¥(©öÔ Ÿm¥()J}µ>ÚŠJR€R” ¥((()J|ª*|ª()J}•>ÊŠEEH¨ ¥( ò §•¥( ¨©¨ 'Ê ÔùTJR€‘QR*( ò¨©ò¨ ¥(¡¡¡ ¥()JJR€šŠšŠJR€R” ¥()JJR€R” $ÓÛCOm¥()Jô§€¿€½ ú¿Þ]yñûð)¬?D¿û¦½8 ø Ðß¡›ýåן¿šÃôKÿºkŸÇm¥)V*pmhW_¿.·ßmhW_¿.¿?á{F}=’(äxUlŸ ²‘áU²|+ߢ`¨VÈð5W'έ$x«“ç^­ ÊÉ^5[#ÄÕ”¯­‘âkÕ¢c™\ýa¿YÖõéS3HÃv±ó¬·kß:Û„ŒGkßYNÖ+¾¶Àã#ßTÖ?d;êšÇó­qÜq`ÔTšŠ±Ÿ*Š“åQ@)JP R””¥¥)@)JPSí¨>Ú)JP R”ûj*}µ”¥¥)@)JP PP WÕü ûœx®8CaÕ÷Û®§f}Ç´s…!„´ž\‡ iDt@ó=s[¯ý8Oý·­¿ÍEþEбðç•E}ÉÿDžmëoóQOú$pŸûo[š‹ü ]cáºWÜŸôIá?öÞ¶ÿ5øÿ¢O ÿ¶õ·ù¨¿À¥Ð±ðç²¢¾äÿ¢O ?¶õ·ù¨¿À§ý8Oý·­¿ÍEþ.…‡E}ÉÿDžmëoóQ\Óî‹àg¸s ]»Øçj©WE)!2LrÂSÌBVTÐQ8_@ö“ÓtE™©JT‚E<¨)å@E)Jj*j( ò¨5>U€R” $TTŠŠ|ª*|ª()Jhhhh)JJR€R” &¢¦¢€R” ¥()JJR€R” ¥( 4öÐÓÛ@E)JJR€ý)à/à/C~†o÷—^|~ü kÑ/þé¯Nþô7èfÿyuçÇïÀ¦°ýÿîšçıÛiJUŠœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦±üë\wX5&¢¬A'Ê¢¤ùTP R””¥¥)@)JP R”TûjO¶€ŠR””¥>ÚŠŸmE¥)@)JP R”‚”è‡Üÿá§FÿñßúÇ«gâmæNŸÒȺEqÖÔ‹¹§ QËëSNMa·R”©J*mkH ]{½qZÇÜÿá§FÿñßúÇ«}Ԉ׸ C”·PÛs#K¢ÞÃí¾Ô…M¤î'µÍï$Ôæk¦fê)k´¢÷3®nµ,M±JЇL)N…¾ÒSžcm« ;ŽÓ庵è:TÎÓZRásºßà@§!Lzãf´"cLq$4ï-lPÚØrº WMºÚ#\§Ú&>·Råªb¥°@ YaÖVAÈÚòLu®2 +±Z-6Ë>©Ô6¦­–ömí˜î0¾km'jJÒëKFüx©)I?àkú•ûÓº>Ó~³qâ´½:"ì8pÃO¡ùí°¥”¸ÊÔ—B)8PHRØ:¦¬ÜoPIÔcHÅÕ·o·76]ÉQâª\•>ëÉmr¹)JC+ÎÉÊ:ƒ’n¤-hÓ1tú–#GœÌþap)×_nRe-Dïu9WAëc¦?½E¦ZºÜXºFºÜ¬×&Z, pÞõ´NJ—´(g¨ÊI8#'"Mÿª/ÑcB´L¾\¢¿T*Ó6áh¶&D‰,ú9Ém”³Êw½Õ½¨8Ú²6[&¬½µ§ª$ÝeM°Û.î±)Ùpć ìJTû­„$¶¶^ß‘µm %9"·(6Õ 6ž[Óí¶àåËœã¡nIã.²µºHïe/+ Æ6¤ $m©ºi m§ˆãòÚcRÆ,MCKH %’ÊœFRp² “‘ÜOOˆ=´C·‰vÜ/jZ$Mqr[Œ¤%&#*9m“ÕIFÝÄäî*ëŒÇ~íßÁª?ãÿõ˜®ý\îÝü£þ?ÿYŠ-àø‚”¥t ‘O* yPJR€šŠšŠ|ª O•A ¥( "¢€Ÿ*ŠŸ*ŠJR€JR€R” ¥( ¨©¨ ¥()JJR€R” ¥()JM=´4öÐJR€R” ?Jx ø Ðß¡›ýåן¿šÃôKÿºkÓ€¿€½ ú¿Þ]yñûð)¬?D¿û¦¹ñ,vÚR•b§öÖ…uûòë}öÖ…uûòëóþ´gÑ£Ù"ŽG…VÉð«)['½ú& …lUr|êÒGª¹>uêÐ0̬•ãU²U”¥¥)@)JP R””¥>ÚSí "”¥¥)@O¶¢§ÛQ@)JP R””¥ ¥·[ø“­­ö u†%ñmÛ-©q1#–RZ qN/I$•(’O_à×¾n·þÛÿéYû§Ò€Ü=óu¿ößÿJÏØ§¾n·þÛÿéYû¨yTP‡¾n·þÛÿéYû÷ÍÖÿÛý+?b´úP¾n·þÛÿéYûùºßûoÿ¥gìV¡ì¨ 7ÄÝoý·ÿÒ³ö+õ®µUæÚí¶åtçÅ{o1¾ÎÒs…©H> V¸*()JE<¨)å@E)Jj*j( ò¨5>U€R” $TTŠŠ|ª*|ª()Jhhhh)JJR€R” &¢¦¢€R” ¥()JJR€R” ¥( 4öÐÓÛ@E)JJR€ý)à/à/C~†o÷—^|~ü kÑ/þé¯Nþô7èfÿyuçÇïÀ¦°ýÿîšçıÛiJUŠœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦¿«MÁû]ũћˆã­gjeDjKg ƒ–ÝJ®‡ÌÔZã¸âÌSQ_Pñ_KigÃ=U;KéëMªý¢¯Ó–Õ¾l¢¡Õ€H@Ãa*Éómxñ¬_¹Jé©Gê[²ï6éjvæ„NЇ„hí¼ÛM p­ÒöPÙðUS­Yn,|Ò|ª+f¶Ù5>¼¹Í›m´°ò™l;-ÈñØ…:ÀR¶„2л$Ôä׎¤Ñº“O[£\®vô‹|¥164†¤ÇqCÅ!Ö”¤g¡éœô5Òëq¿Jß.!×öömÏ͵Ab5Ì JîðÃä®sv  R3ÞÆpkYÕšnù¥/NÙµ µë|ö€Ršs¡ð ‚Bö‚E“ÜÁSJÜ8.òQÅ9 Øvù‘®8°ä³6 2P¶œ}°°êTHé¹8PÉÁ5ºýÐÖ7®\~—¡t½¢É ¶œa«tXÑ¢Á [±šYJœÂ7’¬í Qê­©ê¬r³°8Õ+pc†zÕízþ„E¥¡¨Øl8¸K‚„¹ÝQXJÎÅmI'8îœ4× õ®¤Ôwm;f´µ&íhqMÍŠgGmm”¬¡XÞ±¼ ' e9=á™Ì¹ƒO¥m²xq¬£éù—åZì'lÕ1-——ûm +l0¤ŒyÖ¥DÓÜ+¼è ½²&ŽÒV˜v¾È63¼ÕêKrÞ”äƒ2BR…-´°5ŽaOCiÆw¨\C¹±Ó¶½=<oƒl`5! )¤‚Fìç©'ê¥w`j"§Û]7îgÐÖýÅö«ºTå¶$uÍ”ÒTR]J R‘Ô¥§8ëŒøxÖÏÂÎ/\õV—a²AZ-ŽÎ³½ÞÔg"¸‡”¤©° ‰<À0¨ôñ­Ò ¥w. éËmšÎùg±E¿kxRD8¯ÃLÂÛMåheaIRˆ/x¤úƒþ8Ÿtî°Ø[ѮöE´j öt?|ƒ°Ûm;µ¼Xè‚T]õGJgY¬MŽ1JÝei«ç ï–«†¸Ñ¼èò£ºôhrÝÃožY *($÷¤( àœqœ×WàU•½mbÔxƒ£ìñt›v×ybÐÌ´ê·ài æóÝPñÁJi+|éí¨®¿ÂÍ/l‹ÁgÄû„·VÇ[ƒmbSaÆ[ujl)Å ÷V@y8 xä/[žŸ·êß¹ÎGEº Ý–ïØ¥® dGjK*åí*i°òz¤€ç4ή7Jدš'UY4ųS]lÏÅ´]1Øä¨¤¥Ìà9N@$n df» (ZVï÷$ë A HÚ­ò Ýš‹Ih=- ó"Tú†â£Ì^víN@éRæ>|¥YéÉöûdåËŸhjêPÙìì¼â’Ðw# p'ªÒîîFN2H»÷hXì¶(ÛaØ­ûTeÙuLÂŒ†P¥—ßE)€¸QÊÒ°8})]»‹Vk_mÚN[ìöÉÚ’lιÜ.1/aRŠCM6àSiH)_R’NZ9YØF‚·k¦±´Ü´¬`昴DÕîm>Ôø–ö›aøá ÜÛ¬‚QßË8Ù‚2þ×jâ½–ö׸ovМ?µL›t´ 7‡`é’·8¦c©*Pä(#%Nõöt‡;4™'Ëô¯¢øQ§-ú›‹VÍÄ{š<ûl7.Jn,`ö¢û\j+­4Ód© \Q'%Iði5e“WiÆï‰â íÂÔä) Ä™i´0Ú!>P®CÖ6å{r$ã= èc¬W°±Ä<ª+¹p ÷Tñ‡Lé™:gMªÆ¸A‡£?c†ãޏ̹Å:Zæ§[.uV{ØëZÏu#1µV»ÒîXl)†‰Ò!ÛLK4HÎC-LIJƒ´?ÚÛÁW]ù9©Ìïks:UŽ—~×RÚäß"¹.ÔÔÆW9†ýwX Ä£©N@ê<|Ev>\­¼Aâ Ò·¦Õa¸5 †£[eØIJ¤”¾€'!)Ê”}j™K*¸8g²¢»w x§ÞÔÜG»Lm{FŠ-ØŒºrÜ¥ »ÊRñÉÚÉ$xG—Cç¤,ð¸•Âss›jµC½é†ÛU¾ QÚ)qKihi)J†Ö•‚FàO•Cš&ÇÚµ}ž xE¡®p­V©—½NÛ“¥J¸Aj^Æ‚[RBJ’‘µÔ丑ãåW·„¶‹×8j»;×nÖЙ&3« KIuþ^s´(`uÿwJޱ >Ò¾†ÔV+Ä!]mV>i‹¦š´º¶ÕgGeUÅøèî—Jòe¤«Ö :Ž„xüôA‚0Gˆ«FYˆžTò«)_HpÊׯ¹sPÞíºFÉvÕû›píÎ7¦âÈ‘ÊOeÈÛÊ<õn¥+©$ôÍj°mÚµÕ[-ËCZ’5à Cg…eš•0ôWœZ,·÷ÆÔ¦R7ÊZ‡ˆ\ó“cTWÐ?ÓvxuÒt›ºE˜vwƒ¨U¢ì†'ÑØËÉʉq îJT THi>°<ëWi;²Ã¥,ÅîÏwË Cl2‡Ö:ø%´$`dà‚¥M6A¢ùTØ5&Ôz~Ûçr‚ߣ䬶ÌȲš•k)æ´¥#wCÓ9è}•jï õãMÄ/XƒOÍk“L·ÑíDr¾j¼<“V̹ƒJ¥mÖnë Æ‘¬-Öø¯Xâ…™MÊ29[$x½ôÔ‚–•°jM©4õº5ÊçoH·ÊQCcHjLw?~5‡è—ÿt×§zô3¼ºóã÷àSX~‰÷MsâXí´¥*ÅNí­ ë÷åÖûí­ ë÷å×çü/hÏ£G²E ­“áVR<*¶O…{ôL ÙªäùÕ¤Ur|ëÕ a™Y+Æ«dxš²•ãU²û[ÚnÌd«°rv);·6r ÊÂG€ÎH‰ÀÛ­ŽÍ÷NqýtÔz~%®GkäKrí6÷>Rob·÷ò„’vçiè­¤_/Ò«Õikø Ÿ@ýÏOAµðï‹«½úÁuÒ  BnMæ*;CéjBNÒ\ÁNçQ‡3°ç¢Ž>~¥*ê6mt´-®|Û4‹.¯°·m“3“Ÿue‡a>PžzKk)Z‚W¿nÄ«#IëV¿u.¶²ë®)*å`_:HMÂD¥!ò•-E`¸Êð3ã¶¹U)—[°tï¹›\ÛôXºÝÔ¦í²ã.§R’¢ÒVR ¼¤!9Ç\gǶŽζp†éªµDëõ’r×lv˜¤¹-Ÿ•%E-’[HØ æž¾ô®*}µ “s¸[.ö{÷ÜÃCÙoÛV¡‹v2gÇ™1¸bsD¹‚p¥ ÀS} ¿«ÿ øñzÿc Ñ:)Ë´+Ψ¶<ã²dExHDvT\Ã<Ôå*è¦ÆHø?ðÏ¥2jAôQ¤õ§Ñ–ûŸ¿@]®B˜ñl¦ܬ²UÊG@·‚X ê¯1>禇u÷º=C­4ìÞL–¢ÞY”¹  „¤2Ê”³…«¼{µÂ©Q“L·&çsÓÓO^ôtoŲ7}¹ªédík 2> ä)gºÙÚÒ$„øõ3ƒsÔý%÷9ÈáиÀŸ{½]ûl´A’‰ Fe<½¡N¶J Š™OD“Мâ¸ß¶¢§";'&ÛžàF†‰ß%5·›dQhˆ_sÑ) ÁŽaVB²œ•³éX‘á}Êú³DÊÔ:Q»ýÂîܘ±=ÑÁ<ÆÂ¢’­á탣KèH=?¼gçJTdÒÂå­ºÁ:}ÞM­‡íH‘võ¿uŒÃ'j‚NÇœp6¾§¦ÕŽ£ f»_Ý’ä K­bj]?}Ó÷Kl[C1\[ÌWsÝ;CAÎbº8“”¤€ >G?Ò¬ãv™»oïÞ0Ûôö¤·^-pµ8 t·Üf7qJŠƒ­8éKjI*_MÀŒŽ•Ä©G»ƒsÔzoNÛ,ö{lKë-W2Ií}žkFߣ„¡âJÉ9R÷ìHñö×Xã¼Hú›‡\1´Øõ”—6Çh1®-û£‚ŽCœ˜ÉÛ•<º¶±”’:x¯(*uNàêQ4´yn"f©×ÖkuõPVͬƹGu¶—Œv:–Ñu ¤B‰VH=;„D¼éKeõÁ_D+LÚ$ÙxsÄîÛ-®TëÌ­DŸHJOšµ,7ŸÅA' Ê|ÓJ‰FüAÛøU¨ôÆ‘ÔüHЋ»¶‹ú<»d £®Ê ­°µ­*K„ï =<´…â xC®m“n¶©—½NÛpbÅ·Îj^Æ‚\JÝZÚR’‘µÕ`¸‘áç\[ÙQG “sµêûÄ.%ð‡C[!]mPïza· Ê‹pœÔMí¶”:…º¤¥CkIÈp'Ãίu¬v^#ðÍ»lrµè»z!J”À%.©l¥—‹yÆà‘ƒÓ'>]kçQQÕ¡sè½"Ëeû£.\L¬lM*LÙ­º‹‹k}ä<…„4#ƒÎ ÇBêÿ…pcryÕ×›ÄF xó§¿%¦ˆÇ- qJ éì ª¥Z1³¹`á×t^™ÑÐlwnéýC673™q”Yæ?¹Å,gs =РŸXôHðð®AåAO*•µ@úD· r^¦ÒnßôÓ7»µÍ©á»~†ÚÖÖb+*Üè8myJÈPÛ‚3\Äw'ξÑeÜ"FµÛoíÜJ¥<Ó ³Þd¼²âÈñDtt'©H V“Jª…¯â¨=+cÿ¦çº¿tzÐ]Ÿ´vÿKGäíì=Ÿ·ã3¦Ï[ìmëX:Vé{78½hºÜ,å:¡R½5ÉAÈN…©å% y•wR´¼’HRHÚA)P¯›ª*½R&çhÔÚ€[x)tÒ/{ˆ¶¢]ŧã[,Ò¸ºµ‚’·‹ý©Ô26¡)ÚwdôOS]‚½Ñº–øÁ×LhɬAoú.«xj4¢• ¦>á%•î넞ê‰Å|qåPhé&.wß¹³SX ñCPh=둤5Jß…/ä2°É9ð+A)>yR}•[ç@ñšÉ§,÷ø1¢éW%¥Så´¥0üÇ_3˜r¬7põB7uÇ^s¦5j¬Ùm=c—24³2$ù,¸dGs Æ V”­  (%iRA$ã©­u÷]û¾âœuÅ­j9*Q9$ŸmNMX>£×Z‹†ú‡®å³éí9©$ÇPèkã2ݸ¼O1%ÁõO1(QƒíñÖ¨ìÛ>ªû”´Æƒ¨,‘o6«ÒÞ—}Á¨ÊKERNñÌPÞ0òw'Ç‘Šà¢¢Š¸‹ŸCÛ5’¸ð ½nsN]n6[Û¯!›ä§-ÍOd­Ý¡Aæ€^×6)ÀBvšÅ¼jv¯GáDI·}&…XŽe¢Áa·[PmRÞ}ix¥¶‰È#©Ú É®åQN¬\ûIê 9î²ÖªN¬ÓmØåÙj4Ãz±Å‘;GÂg °îF:`€´îçZeØ0¾äi¦fß´úor.æKý3NºÛNFÞ¤€áÝžK¥ uX§pRsóõ*/_sèþk‹t~Ytîݤ5M¥.ºã±.w ½mYyθv¼ U¼)PÞ¤ùuç?t‚´Rø”â´$Ó2Ú!²‡V[­¥Ô‚©D’„¡-€ÀÆscCVP´®.n¼ ‚©Û„“6Õ¦íÅS®qâîqø2i)­;²µ$2U€s[o¸ t,ùº/W¶ÕÓHNqqæ°™ °¢v©ÆÊIJÐ|ö’;ÉÉñã´©qRÞAô }}¦¸s÷NɺÚ$¢ã¥“n‰kçEx?ý1#¤)*¼R¦“Ÿ>ê‡së¿⻨Ÿ6]a¥°¸ñSž»²ÒÑ9ØQâ_ ×?¥B…·ªýÐÚæÍª$éÝ;¦\rEL[“4§Pd+j¥„ž¡8mg¯C[†¶nþä½3¤Ú¿é§¯v››³&Cjý Å¡¬ËVSµÒpâ0”£»f¾z¥2h’àI5Ù¸U¨lr¸­8tõʪùr’ܸoLt2Ô„¥MÑu]ÔŸ‚V7;ÿã\f¢¦Qº í“oV}-÷2ÏÐ3®vÛ– ºÝĶ؃)‘ ´–»Êq²¤dò”0Oük´BÕ5§†¶[ÌÍ/päØ\µO˜Õþ(vÒâ£2•C¾ 帒´õ'¼¾+¥QÒL››‡4¿IjgcYµ¦ÿhyjT9P§²ú¶ w\JJ2HX$x4úRº-”¥H¥()JJR€“Om =´R” ¥(Òžþô7èfÿyuçÇïÀ¦°ýÿîšôà/à/C~†o÷—^|~ü kÑ/þé®|K¶”¥X©À=µ¡]~üºß}µ¡]~üºüÿ…íôhöH£‘áU²|*ÊG…VÉð¯~‰‚¡[#ÀÕ\Ÿ:´‘àj®Oz´ 3+%xÕlVR¼j¶G‰¯V‰Žesõ†ýf?Xo×¥LÍ# ÚÄwβݬG|ël1¬W| e;X®øÛŒŒG}SXþuïªkÎ4wåIDx¬8ûÎ(% ¶‚¥(ŸêMjM%vqg™¨¯@Ó¥%A¥ŸzT½C-4ë¬:Ûo'sKR NHÊO˜È#§˜5lÈYžgÊ¢¤ùTT)JP R””¥¥)@)JPSí¨>Ú)JP R”ûj*}µ”¥¥)@)JP PP R”ùTTùTP R”û**}•ŠŠ‘Q@)JP)åAO*)JPQSQ@O•A©ò¨4”¥"¢¤TPåQSåQ@)JPCCC@)JP R””¥55”¥¥)@)JP R””¥¥)@I§¶†žÚ)JP R”éOzô3¼ºóã÷àSX~‰÷Mzpð¡¿C7û˯>?~5‡è—ÿt×>%ŽÛJR¬TàÚЮ¿~]o¾ÚЮ¿~]~ÂöŒú4{$QÈðªÙ>e#«døW¿DÁP­‘àj®OZHð5W'νZ•’¼j¶G‰«)^5[#Ä׫DÇ2¹úÃ~³¬7ëÒ¦f‘†íb;çYnÖ#¾u¶ ŽÖ+¾²¬W| mÆF#¾©«þÞ _Ýk›òëª}SW<=‘.¥I}¶£>†”âÂQÌSj '¦Ò¢ÝÝÆsÓ4Æ&ðÕäÿ±Z}¢öŸJð¹Þ EÄŒ°ú/î@<Îò‡{ÛÐ×ʾt½ïskÇ€»Ìü63[ϯ¼=…Ãi¶ûÝÚïâï;˜Ã¸”¬‘°$ì9õ¼óž˜®}z“z"ÍHmRQ&BùhX;Z;BJ€èH_{>[kùž‰ÁÔ£¯9f´ª_Ueº{õZÚþÃÛéD*a¨Å[Hðwå¿‘®*ʹ[¦[»7mg’dÇL–’T -«;T@9N@È‚Øè»Kkâ=KnÙµK¸8ž…,7Õ@üJè„ÿí-#κ€ºémjíŹ—&"U¿.òÛŽ§‡e)OQÝl*;˜Î6F9îæ¿±r±üùÈi]ÒÁª­ÓnJ—ñÙffú±v‹"J\»3l²ÔvBA{ ¶òv$¹i8óM³X]t÷ m0ì7®Ç)wÉïJi•§˜¦ù‚Óâ[Q §º­¤vô…&øQ¿ÚdÙg5RÚ[ŽD,É#cì6òP:„¸¼:Õ}u>#Þ­rôœhv ±™‹u¥7J•;lé@B‡â´´©+kÄ/¼sŒ7Ë*bîrîš¹¥6T4ÚdK¼£™!J{iYBIN07«$àg #9ÇAênÞÜ4E„êÖÚÝ.5rŒ¶ZJ6…—K…¶ö•$µ nO´VÝá·Òú‘ã[æéÑ :ägÜ„AT2#ª@x«Ì%a^`Õ­¹û[@1v^Žrÿ&Û-—âF“‹tÆù±•§ÝŽRÒ _s)R[hj®L“@—ÃÍ_ ‰ÏZ‘Ù™mNóQ1•¥ä%;–¶JVyÉJz¨·¸$xâµJïõu®5êÕ¥_zÖÕ½ËZÚ~,i­9ª0Ì…ó¾ -ÎiF]P_1)År~!³c=»d¶eEËjJÚå%E´•6 IKjQR7 «n@Á©Œ›ÞA¯ÒºÆšU½ë%Šì»Ý¡†íÚJõm}‡¦¶‡Ì‡pShKdî;„†ð 0NSØuÙøF–%^Šƒ¨¢^Zy‰+JºO1‡@ ZÈ RT:…Ó6 ä­SdÐÖ뻲¢±|ç¡!k*ËJi,)kX =ÜHG†OEtðÏ`ÖÚJɹXÖãmHÓÍê’c¥ËÛ3 ôîæ2ÜVÙJã §fä8¢w cvTªÖ¸Ÿ&ïuÒúnÙrÔuðÞ.8¦¢RÃn&d‚}b•m@mé´¤›°9íþ×.Éz™hœ”¦L7”Ë›¹$ƒŒ¤ù¤øƒæ5ýG´É{NM¾¥mÐåLjâI;ÊÞCËIÀ /=|ÓÐõÅÏ\iZÞS º‡Œ&"ÁuÄ¥ÇcÇm—˜+mG>y¬í©§iÎß—g»›}ÑÛŵM x¶–¦ï)óÚ GL,ÑX3wkƒH¥} £%i†5íñ^èa³dXImø­]âÂŒ¨*q! p) T¶T €m$%%YNíÕ©i«²á3¶ÉWvm‘X,òÒ ‡‰Z܈+ISËQ!)u¢JAAü 9?¶¢§Û]Jñ­Ôun›µOº‰zEˆV4φÙKŒ©-ÆŠ§²‘\ JÐO¬0QœdU› å”®Û~ºÂ¸ëM2™—f£<Êç/ÒNj—JØ,¶ ¡¸éÞ+¶\*Â6¦¿«õÎØuLi6ÛÜFµúYM3p“xfZÙ¸ «›-)B9¦:Jáw‹5ÏàIÈ´É{NM¾¥mÐåLjâI;ÊÞCËIÀ /=|ÓÐõÅ}tÆuUþÁ§u;ÉÕ +Q½xµ)R¢ÌCŽ:”G™½Iq'¿‚[JÖ’A*Á$+®çf¾é‹}óT7mT7Yªs϶Ýý‹|i–â@i ÞÓ¥žŽ÷9ï² NMp â L›Ôç!Å[Hq¸’e’á la…¼±Ð¥-¨ï#$µ_]C]ÒÆ‰ŽÌmElƒlF¼±s€ôÆÛrDç•ÊPhËQB˜JVÆÕ' «ŽT§v »F˜ºÜ¯:vÖ”4Ú…ÆÑoq×;Š ¨áJÛ’BÁéžîpA¤Ú-º²ív¹ð¢çzÖj™oƒrŒ.mμ…)© ¸>°ó-{°R4 a;‡…aiUáîBåªîMÌ™ãvdd!GA‹²u)Pi´¾µ”’”áX$ŠŒÌ“’U‹K´‹kWÐ^~3®>ÚÐÞrËiqܤw€J•Œg¯C—ŒSÛ¸j.a*’Ü7%å^Z¹ºúÃŽ·d4„!KØPž™î¥9$ä “ƒzºÍ¦4ŒÙ7rSWXìµd.<¢R€ñÇ)‚Ù#Ú<È©rv¹‡Gê92§EbاlYIKˆø8¥´8=ð8ƒ´wºã ‹v„Ô× TK”8°nkKz+’Œ$¾„­hQDrç5]æÖ:'®ÓŒ×Xný¢¬Æû*F¢[°ß»Ä·4«{MJ2 Fd!À¿…FÖÜ o ½C€pqIPiÝ=sÑV·Ø²Ívßøæú̇zÞç¤frÝJRáeACÀ) AÁIÎÉ9ܽ©"J‡E±M»6Ônñur eOݽ¡GiïtÆ3Y“8}©â¿iaMZŸvðûqíè‹z‡!Rµ©´u]ÍèRwœ$(H5ÒÍâÈåÂéi¸^í|Û.•ÿgÉD´-§œ]…1_Œ…ƒ…(»Ë)ø¡Á⪩ ]SÂY³®ú³Úßzؽij«Ò’_%a·BkJŠýQœJg`çcIê#*TTÚž\ˆwí´’•-2\æll$¨žKFGwǨώ¡Ó×K ÜQkûƒk5™(%8Ü’¦– 7 ¤FGJëcRXÐȹϻĉv)‹dÄ-…"ßpŽÜÒ‘ÞØˆû”;£âEsýaj¶Ú4Ž?ûWÁ&glvÝqñðÉaK(qm¥Y/§ Úp”îêeIÞÌ‚³KiåjÜÍÚßL8KDi!íòPÓN<àl¡µ$†Ï®¤g#õÅ%m/z;:±H“%ˆ©•l¸ÃC¯¸l8ü'Úor•€V´Œ’ÎOJÞøOtµØ´ü‹|ƒs£ÝÝ7F†¢ <¸¡´%(Z”Û‚S[ƒÝÖŽ{À€¬¤¦[hr•Ò¬7›[|#™%éÌ"ùonEªr°[–ÚÊ’Þ¶š¢ùg{„ÍÀËr)¶Bi¶œ¾³¶<Äùî75ÍKŠP{.íRVNOu"3xžj½<«­ÊMÚßuq‰ÚãI„RβA¶…ÊÿÙÖ©|«lÕa©š#HM.‰…Ë|–D¦ùí¼fJxe¬ïØPâð6äã9éZŸ•YfoC_¹»naVåHojá/9¨ÈŠÛ…°ã) Ë­‚OUâñ4}ò]Úe¶*-ï9 rCè¹Æ1[J±·29œ®¥@cOEnw¹¦ø§¨fØçYc3`Ì`]“Æ“ç} IIk))O­ŒˆÎF]ÀY§[%Ø¡¿¦Z¼½èùÓÚDÆã[¤<Ê¥%ÆèZ[mæB”•%{…S3$ÑnºTÚíR.w J£G޲—BÞo˜åïåîßËßÜæcnî™ÍW3f’þ›“}eÖÄY-Ç} O5½éQBÈÆ6ª¡ dg³ÁÖ6{­Þ^—™2$ÈQ-q£2ü‰1ÙnSŒ!„) ºó{R‚â]•¡E# P5¡"J|°Ó$=^jG˜¢“â Ê ÔùTè@¥)@H¨©ùTTùTP R”ÐÐÐÐ R””¥¥)@MEME¥)@)JP R””¥¥)@)JPií¡§¶€ŠR””¥úSÀ_À^†ý ßï.¼øýøÖ¢_ýÓ^œüèoÐÍþòëÏßMaú%ÿÝ5ωc¶Ò”«8¶´+¯ß—[ï¶´+¯ß—_Ÿð½£>Ér<*¶O…YHðªÙ>ïÑ0T+dx«“çV’< UÉó¯V†ed¯­‘âjÊWVÈñ5êÑ1Ì®~°ß¬Çë úô©™¤a»XŽùÖ[µˆïmÂF#µŠï¬§kß[`q‘ˆïªkβõMcùÖ¸î8°j*MEX‚O•EIò¨ ¥()JJR€R” ¥(©öÔ Ÿm¥()J}µ>ÚŠJR€R” ¥((()J|ª*|ª()J}•>ÊŠEEH¨ ¥( ò §•¥( ¨©¨ 'Ê ÔùTJR€‘QR*( ò¨©ò¨ ¥(¡¡¡ ¥()JJR€šŠšŠJR€R” ¥()JJR€R” $ÓÛCOm¥()Jô§€¿€½ ú¿Þ]yñûð)¬?D¿û¦½8 ø Ðß¡›ýåן¿šÃôKÿºkŸÇm¥)V*pmhW_¿.·ßmhW_¿.¿?á{F}=’(äxUlŸ ²‘áU²|+ߢ`¨VÈð5W'έ$x«“ç^­ ÊÉ^5[#ÄÕ”¯­‘âkÕ¢c™\ýa¿YÖõéS3HÃv±ó¬·kß:Û„ŒGkßYNÖ+¾¶Àã#ßTÕ–‰²Æ¿êÁ2s°c"$©o>ÔpòÒˆñÜ}A(+@Q!²T<|jµßTÕÇïþæ5)¼%Ùlºˆ˜aتÚão=Ö›X9Ú·r@Œœ Ô¯m,°´é›=ûQÛ­zNmÂòã®|{€‰h[ƒzeÅÈq*q[ˆŽ„%C8ÃÐ6Ë-âEÎÍ‹’-“%Ã~4¤6†—+ÏáÄ)µ‹iŒuê|­´Ž·’öº±_uî¦Ô·(ÖIÍŒ’£9ehuµ–ÀuÔ‚:¨àžéò¬Ów+ ‡Y®C2.S,ÎD• O."‘²DWZÃAÅ').’3½´uNz5 °i[õúòípC̲v§Ûl¸½¥[ P./ˆ V<«ú¤¯Ò,>œn+mÇQ¾c(uÖÐHZÐÒ–ZRR¬©) m>Ã[n‡×VÍ9k6ÆäJmn®Ü-ÓŽ—ÜÜ–Ò•ve| æÔ¼r€kǪ챴#¶k¡ptDÌxO[ã¸Ë.8TPërIæ³µJ (H!J' / kOé»ÓŸ’ì-¬± ‰®/šŒ^) ¨uêIZ{£*rÕc.뢵 ©QÑp:žˆÅ*¸ÇË«Á/ÿz¾íÆqƒ[6µ¸=„:RË.‘n2Ð_x¹ÑnÃmnª"±ã´™ãÚ” õ¬=ªì·í>ÔvŒë…ÔÊKÆ|Û|vi°…4§Z%Rw(¤ïXI:ñ¢mƒTðþñeÔÛ,w Ý$ÜcGy”Ä›Õ8Ãn¨(6â¶%<ÂÕ„­)ޞ‡š¾á}zÉÖÜ™­DLÍ­LaHq•-(J›p/c™ZÒI$àu®ÖVhzºÅ©â¢k¯µjnÛqŒôFTÛaS{EJR]ÊB—µÄ$dwqsaâ]žÙ­XºH]ÂtÐáFg•j‰¤3tbjÂXd†Ð [såµu ì^V$æWÛMÂÇtvÙtÙå´VéXÂ’’’A*| `ÕÞ´»F½Þ™¡¶í"(:%lCe•ž„ô*mDqôªJºÝ©”¥H¥(©öÔ Ÿmc±Û®zRûrôœ¶®V˜é•Ù{Tˬ©öÏ;˜•î;yda>·^–šwDĹÁ´¢MñQ.×Îg¢bœÄ=µjm<Ç7Ž^÷¤' _Q×­yèiúRƒPD¾Ü¯q¤Ý¡¦D+cRÚ";áÂ¥Èl’K%;qÓ î>e¤µšÙÅ:a»¢ë§¦â±(1æ$HT¦’òŠÁ@Kê* %{‚Sꑚ£o€*mzfÉu¶¼›v£}ëÃ÷g¹Vâˆá-4]qâ½ÛÂR¡Õ°’FŽA)º-È\6kWI¸%šË(·r»á‡ùmõ+=7îœuVpFm ãDÆÐ>‡´\µ Œ˜ÀÜÔm ¹ÚÞàÏ;´‚ˆá@tÉÆåa)Oõ©ø‰Qi+;V•µA¹Ü'A}Ã2v!Û}> ’”¸”%!;v©}2Bì÷¬ Ôú”ÙÏ4­p'>ÈiIIS¬ÅuÖÓ•tÁ[iû‰ê•Ö¦–îÏÇŽË–ëƒ s‰J^K¡ÔUÑ8Éüa‚+ÏLêöS¬‘xÔQšLoFÍ‚´Z-Ñ¢=æ’BJHS¹*=p<ðzû¬µÛõž¸Ú™™&Ý¥û8lÉBZzHnR䨔¥JÊœR@ܬ:ÑÜkM^u¯7hŒÛ¼€’âÝÛIQÂS½Å%;”zç'Èö´é CtŒh @ˆ÷gw´Èn?Ãuø$óît=Äå_ÝVö‹žŠÅâÁ&UùË$¹q&G–Ü6“'{ tlS|Ò}Á¸,ãjUŒ‹ž«°jvîHÔmÜàóo“/1ýÓnî2voe{Ô r‘…ØÊ»§4»\ý$ù°Ù®vÆu/Ù\¹\ëˆKlm™!‚pCHÂI*R‰9aÍÒWèV4^dÅa¸ªi·¶öÆKémÌlqL…ó…nNRÜ:õ{?ZBŸÃ‹VÄ”³”—[m!]°J’ârs•´[|'½Õ*ÉHñ þ®z®Ë/‡æÑ ι\»4v#vøàÁ-©;Š%$ó\AJT€Ú’B‡S´Rò‡JR®((mv­Ûïz"Ûé_ºžWÂrsÙwÍv/†îþ9[üSëcË'T®¦5Vœ†t¥Öä.ɺi\vXñØmlKÛ)É(Þâ–×}Ò“„/ `Õe~×&é+ì+o2b°ÜU4ÛÛ{c%ô¶æ68¦Bù‰B·' )îzŠþ®š;R[†ì»i±Ä²Òu¸P-­QSk ‚° ¯®z®Ë/‡ÆÑ ι\„hìF2íñÁ‚[RwJI渂”©µ$…§h«­EÅ(ó/ûÜ48_Mö=êLDCŠÐu¢µm/´9¯õZ€S˜À'!DäEä WWhÙ:gJZgÜ€EÂmÂlu¡¹M>Ðm”F)!M’7nuĨné´ iô™ZƒSÛ¬©|F$%¥¾S¸2‚{Α”åDu]k+¾šJÚl:uwwSá6c®Üm²C茔¥! W‡$ƒíèzg Ãáýú›ºÌºK€™îöãÆa{ƒJ[©å+yBÒ°žZÜê“œíÆ‹\ikÈØCi[ç,)*JÕ¹rб”à(Vò±&œlÛчQ.;NF\¶£¡æ®,(²T;Ž u%\¢R¥mBº+p#*ýl²£BØo¶Æ.äÊ—.ÄÉ”‡µ°ÔUó m—ÕÝ%xÀï˵OÒpÖåe•r½¢í2[B¶4¸é[’„7Ì2°¾Ð’U³»´€•xÖ¥-R8vÕŽJæµqq~dN[ [/‡Ñ JÔV e!Œ‚¼ç5mnAi`áõÙZ»N[uW"Àº]ã[¤-‰ -Ö Ž%*BÀ*-;´’âAèzª™`{M\¡+UÚßz éZ¶A¸2•9Œ¤¤:”º”©*Æä”• ×D÷Êѱ_´ú2×.4XšžÛxììÚbÇ,ÇÎÞÏ1 ß!c˜«tõëÑwh:¶ïe~Åk±Ø} äX’dÌ[³›B.>I@ RJRÊ;ÙD¨á> ɽI=/úBB8“¨4­… ݲá)„9%öÛ e—¨O@2£´dùg¯Þ-³m'í· ˜V×H8è Œ‚ ‚ GJè#\Ø™â&¡ÔDÃR²ñ˜$ÚãHT7]—ÈCN©M¾”©´€W°OD iÚâð›ö¦“rCî¾ÚÓM­Ø¬Æ%-´†ÓðL€Û`œà2OS1o‰½†ÃmzÈ«åþîý²Þ©&$~Í IyçR”©xAZJBÑ’Užúp\B´…åÛl›´Q.Ú×1m½ÍCn>ÊR§Ê”Sc* !8 ‘ƒ^öK¥†N˜NÔn\¢³k“bJ‚ÂRTâCˆSkZ4Ù é´ô9é´iÍi£lºjLÖÙmÉrßr„J­‘]qå>ÛÈeÕJQæ·µ.6…!°BJ²rRa¶¨]´^¤µY[¼N€†á¸Ë…&SKZ[ym-HJŠÒ•0¢ÏwÄ_ÅãGê;K,;6ÚRxGiæÝZ#!§…6áëÜX èzt­ÓˆW{-º ðØô‹—{¦˜²C}6¦ÓûÒ­ÛŠ)´í)wŽNp2®¼IÓ1¡ÄnÒ¶UPÀ¼GŒ«\hÍ´Üt½ð u¢\|åÄáÇ2HÝÑ';¡JDš,Ý~…s‹m˜›lyK‰Arë-¡HZp¹±µŽÕ”œ1’+:Å¢%ß8¢½’Õ™ÄÜÌ7“6s \aÏ )!EM¦C‰ÏªÞ ðvŒxa\[Ñ.Ýãö;–¡jªqr]v.:ÎFP„ <z•# çoL«Îª±5ÆÖµÝW)pð^]b\d0âÚK¥¡µÅ…0‰$÷F:ÍÙ·'LÞTÀ–cJÝe——c2Pð%°•4¥çe$€z•_s…&Ûr•n˜„·&+Ëeä¥iXJÒJT’H=Aê ÒxQ*ßd¼j‹Å½©×=ÚfFK⊔­i /¶âTǨ½Å­ÇãŠ*Z‰*Q9$Ÿ:”Û`é:G„ÒuÑNµymˆú—ÏpÇÝØ6>¶“»¼7o(îú¹9Y­B^“¿ÄÓÍßß‚”Àq(^àûeÄ¡d„-MoBA”‘5µin#®É#FGiÙ¨µÚû)¼GCh&O"äü´ìÉòKÃ)ʲ@ bݵe’Nš™Èjã離 ¢KKm3MÆ,aÄ,+r”¡¾éHÆåõ9TårJF´f¥vï"Ò‹nfÆ»µey¾{}ÙŽ©Ä¡¬îÁÉeÁ¸£oR232ô^ ‰2YlÀŽ©áÎC®Üã!œ¶2´-ÒæÆÖž€¡j Œùï…¤Ôª¿Ebø·§kŽkn0ÐKIeRë-áÞw?ÝQۑ⌞y6ïý j±„=Ú¢\æËqd …5 ç9…ç§šzž¸”äÈ-u/ï­{qÒQ…qv#bCsX †›Z“ÌuA–w%(äâ3EêYWYöÆíÉL˜{HvKM¡%^  R‚TW‘´$’¯ÅÍmg\XXâ6¢¿Ãíªƒ©YxË­Q¤*ŽÈKä!—V¦ßJTÚFU°OD bËÕö;¼›ä[Û÷eÁšôØ“ v]Ý•²†Ë()m´)( ¤ìÚž‹ÁÊò$Ö5õ¦5ƒ]_ìPÖë‘­×91S¤© º¤$¨€88ü*bé;ü­<åýˆ)TÒµ•Û) -ih«zÐ’pT”<Ȩ××h×ýu¾ÃC­Æ¸ÜäËe.€”8ê–  àŒàŸñ­†Õ«,‘´Ü>{WLÛ­­šCh1nI.­e[’¤‰.wBNv£¨Á©»² ¥¹èKm²zfdÑÄ’S)•¸–_JTÓ…´¨¬!AiˆÆNÒsÒµÚÝ®Z¶Ý$_B–=!¦m¶–w%=×£vêW{¢esd÷“2q¤ÔÆü@¥)R)Jj*j()JJR€R” ¥()JJR€“Om =´R” ¥(Òžþô7èfÿyuçÇïÀ¦°ýÿîšôà/à/C~†o÷—^|~ü kÑ/þé®|K¶”¥X©À=µ¡]~üºß}µ¡]~üºüÿ…íôhöH£‘áU²|*ÊG…VÉð¯~‰‚¡[#ÀÕ\Ÿ:´‘àj®Oz´ 3+%xÕlVR¼j¶G‰¯V‰Žesõ†ýf?Xo×¥LÍ# ÚÄwβݬG|ël1¬W| e;X®øÛŒŒG}SXþuïªk#N=l}‰"òò`2àqæ/õêFˆŸ 1Zã¸â̓Üb\ìp„öaÌnÝé;»óDxL¬§”’…,¨…¶N‰.¥8Øê]Òu4ˆî6›]ººÔ_™%÷ÂäH†Òð•%+Qæ/š¡ÓhžèGjÕjMîõ:ûw6/Œ­›‹m>Z‚CÀ¡{TC ŽéÅl‘8¨ì[ÕÊD(wkU¾|X mW•ÅÙ‡0Ù„¤Ä¤¤úîR CÌAA A_%JJ¢ÇyGm’RêÕýÆÐV¥9„œ#j\9?¾ž¯Ò6˜×9Rä\VëV»|Uʘ¶ˆ a(BI-Å!àãvp@5sg×ÒmÌêÄFBõ VRãÒTµÆu|Ä©ÍÊÊœQiçI9<Ì“í¦zí­ÅŽ K¯Ê2®.,),¡8=R¥«'S‡§t:ƒbÖÚ%˜ÖÓ2ÜeµÎ•/8© ‡ãGÞñÊvíSÎú¡YÇt'ërÐI´èÙê—6ÔõéÈõJR; œjRiâ°”¹ eYRFÅ Ã ª‰Úôúcý³ÒV¿g—Ù»Âú½wvOW¦9ž'o[›‡àHRå5¥'Ë¿D¾ÜVüÎk2^d=¹½ƒkk/(à©DeC$¶¾•‰(fiØVg­Ó®w6®¶Iky¢Ð³’ãIIS_ „”¨·’RFÝá_Ö±³Ú"Øì×ËCWlÜËé缇JZ(Ô­(@RT¤ŽèêÚÇZØïüK¶ßæéñ}°ÝïëDÉRVÅÂú§—Ð syCb¦³„§`¨ë:þÿlÔ—4\aÁ»FAK½¶âÔ„Ò[a ÚR## u•~$Õ)J¸¥()J*}µ§Û@E)J]Y|7³MÔ75lUÞ,»<رfÜ¥­ Šú]’Ü~b’ØÜêVœ­{ È®S[õˈh~ÂÝ’, ¯`ZšzrSa”-+ä06§’ÙRO¬®ê{Ýk+ð—F髪ŸÈ¾Z­på½J.w(ñËïöY2”¾¶’Û%K`!IXVÞbzœ×…»IXÄ­?b¹Xoq-W·YˆÃ¬j²²ã„‘!¶ N! à¶sâ±áXzƒˆ ^‡l™ó:ÐÓÜé ܯk“%Õ) „½±! @ZÊ@AQݸt¯êÇ®l›ÞŸ}1p6ËÅ\aÆô²yÎK+eEnºX!HÃNÄ¡ÝÙÎkiRè+e–ñ"çæÅÀÉÉ’á¿RCKçðâÚ‹E´ŽŠF:õ>WzKéû¶”jkÑ$ÝoO}ƒ>¥‡oq %¶KjKO6µºV§gäñŒÕv—Ô:RǸOr÷"3ðÞ‰M4•´‡ã¸ÃÅkìÄ,áÂS„£nBë ÓsÒQœyS´ÅÂ`L•;mØ6RßM­¼C$8=dÉÉðè»múC‡Vû’ÞüÛv¢pÉSȸ\ã)‰dSn)$IJ›$”‡•·ÝX&«Ó£,ʶ.EÜÞÛ²¦ì¹aHìi*Šf&9FÍÁF:TB·õRHÛ€M{GâƒnÜa_.¶'e^íòdJˆëËŠÞ}ožk;V7¸¡ÑhÊ@IÈUîÖ'£9¾ƒW§ýèŸHv¿‚ìü¾Ny;3ÌäüíøÇ]¹ëQéi•—hrÜÕÁ¥Ý¢Ë—g˜ÌY)aÅt8ÂԅתN@#¦r1+.Ð幫ƒK»E—.Ï1˜²RÊèq…© ®Tœ€GLät Ûåi;4¬íÒÞž».˜vQXmhm¹)ŽÚw””¥J[å[H'o•/VM)a¸GvãR=á/™ 1!•]eÖÝqM+*CŒ¨‡ŽÒ0Wmoh™®/—Ö´ôÄ[õH/\’µ©N½Î%§C)Ø´¶R•ࣩP8v^ X`ÜûSšRaL8-²©‹¢õ¹!kZÜÞ¶•º¥8¥oؤ’ yúDžRô攵êçtÔ˜zšë9×Ùm†b<Ë.1ÌmµrÖ Ìu Z›RFÁ”xõÀ·O ­ðâ-ÇûuôÈ‘-0×n¸F½–qžkm»¹rTKKW-¼a;{Ýî•e¤­ ]QL_Ä™ëÂg¦þЖÓ%- ³Žú·´¥*)!>·xYµµ¦Úý²XÓÒß™buj±¸åÈmaÕ<Ú_HkáŠ\Z•”–󜎔ô—¨t•$™Ö.o¦ÛT‰¬ê8o¥•­¦Öþøhkœ„¡j[}å  'ÀúëÎÆÓ6©Œ7976Ì™mÏŒãIt¨$¥QR Í œ„8µwðžèÝÒ†Û©,v«c«¶iÙ Þ^€ä%9qÞÀK­ZYå…© W‹… « Y?ÄD4üûÅ¢Ðä-Gsu§§OrX}¢´>ÜͲ¦ðδ…¥,t = xëýnÓ:^Èûrä=xv\¸wfÔSÊa曌ç-ÊD«É=äœttŠÛuN»¹j=+ Ép…lBãÜ$N\ˆ¶èÑ‹…Ô40ÓIÆ9j$翹;¾öœjUxÞÚn|7Òñu [¤‡-—«Ü¨|žUªÐ´¢K©Y^÷rPçqR'.'ÀdÕå×Dé‹"Ü\ÖõÑÜŹ†!8Òˆàa—V—²…‡Jž-„'få2çQåªi=CÙi¹YîÖ¹3­÷u}–oey k~Ü,¡`¤ó””œ“Ð[^%²ÕÞ}ÐÚ®­;#”„µøë ºËM!¤7%!$¾0Œ’‚¢¥dõ«ÍrOæÑ¤tÚõƒÚzok¼³:DI^ibr–´—TÑB”¶Ò”ïQÞŒ Þ8ÉÊ÷j÷éNŨ9>‡ô‡§÷£Ñ¼þ^îË·fwïøó3¿®ÜV]yavÃ6%ÛO^¹Ýd»"ïpxj2¦•¸VB£8RØ$¡XQês„„ø{ÑåÁb/†ô7?Ò'²ò9<ÝŸfwìëûw÷öæ£ÒÖ¨áí¥Ûû!Sñ_½7ojî5;“ mÇ m­mGm*d¬”¨oW´`“‘Mq²èö¬èÔpàj7-1ç&$†_˜ÓNËKˆ{’ûNrJP7Gt)%+ÆÜnÎHò­m¶8þ’Óï['¾ã yéÒ„†žCéKHØ’‘Ìi³•)g Æzšóª4Óñ“lcK·h~onžÃ7T—]u(Z[Kn)’mÅà,¢ ¼% gÅÐQ$qCUéæž”«^ž~Z–¢ëhyÆZ@./kh%KFåœ%#r±Ó¯kËD{-å¢À› §#¥ÐÜ™ŒË œ)·Ù €0 \ޏɏ¼k[Dím|¾5`šÕ¿P%ßJAræ•­Jqþy-:NÀ–È JýS’ p(µuî=åØ A€¨ûl1#?Îp#˜·IZö¤)En¬ä%#¨t©Y¯©)J¸&¢¦¢€Ë´¹njàÒîÑeË„3Ìf,”°âºajBÀëƒÕ' Ó9­»KiÄqÒN…¸·u‘mUùVxî±-¶^o2ƒIud´´¯ É) NO˜ð­*Ò幫ƒK»E—.Ï1˜²RÊèq…© ®Tœ€GLän¾î4ç¾ï»ÿs7_úÿ¥;¦ÿ®vŽvwö½~.Í»¼÷ùUe~þ4²ê='s”¹¯Ëõ5©-§–”4•6¢Ò[¡Å’‚P@onåt5¤ÎŒä9nEul­mœ(²ò]F¹I%'üA5²éÝZÖœÕ esnΕ\BœÜZ(æsRÚSÌIQZËk5­óÝ&¦—yì¦7< lSœÅˆJ7-xÖ­»”¬ ÊRŽh¯pZBÓå*\‹ŠÝj×oйSÑd %I €¥¸¤ nΩ*íÛ´f´k68(u.¿$ʸ¸°p¤²„àõJB–¬œeNÐM%JùTTùTTJR€JR€R” ¥( ¨©¨ ¥()JJR€R” ¥()JM=´4öÐJR€R” ?Jx ø Ðß¡›ýåן¿šÃôKÿºkÓ€¿€½ ú¿Þ]yñûð)¬?D¿û¦¹ñ,vÚR•b§öÖ…uûòë}öÖ…uûòëóþ´gÑ£Ù"ŽG…VÉð«)['½ú& …lUr|êÒGª¹>uêÐ0̬•ãU²€” Çkº`¨Ž”´y¤ô•ZbħbÙ.W›úv mÒH)Ü1…ˆn…]—?Jéë’òÿjodfË%¦}(AŽÖ7tÁQ_¦õzì-Er&Ÿ²9r†¢¸—'Zs´0­ÅA@%ÀÚÔ’r Т0<€¥oe~Àþ‚¼Ü.:2ÊßdŒÜ(“‘4>ô×:%d¾ˆKŽ(mÈHÀ a`¶émAkçiuXmÂ|X±%D’ûòf­O¶—ZÚ²¤¸ Ê–¼¶„áAŽø¢K¼I“`d-²ÔHN:òC`‚ëŽîZòz¨BF0HóÉ;Mã‰OÏ“ošÆ”ÓÖÉöÂÉ·I†©c±ò–ž[k}M ‘×(9$“Ôæ¥¦ þ%i¸Í0©ÆÅhµLnè"3蛪§4ã[WÎQqÀÛ€„`e@¯¸6×5­PjµÝ- µE±ÙìÑ’™rŽ{©J’•(¸âð^©J×*bšZm|7b×>eÒÙr³Ä›Ì´O’̇y.Eqˆo¼…#bÒ“•¡9 J†LdæÛB·¤Ò­3-(õýw‚Ñ|vâÐS¶y!µFRZOŸ’á‹Ô ×ôV¦N˜“&H°Z®®ÈaÈÁS• r›u¥´êRu²P$䎅;OZ›V¦‹o[ê:GOK ’©ĆßWe'BHt `a.•ÿ~I9†˜7–+¶8šn·L9¬Ôˆ“¢Ü¸·Áî’êý¶doìïNyM°ÈZ†Ó»j{­òñŒlZÓŽµ‘%²mÖ›ö6‘E¡Ä¼Ì[;ÌÊy×®Tâ™PZŠVCjRŠ›JH@#¾{ë >’Ó– :óát‘ápvu2Ö–æ¼Ó1VH8 ¡o©9N Âs‘¸[©8†íå1\oLY-3 ¡´[åÛžšÓƒj Ie&Am#$íÎIW­Ö¼fq#UÜ­¶ûmþàíþ$)oK ]v@yN6–ö¯rü¢‚0¤—AÉè³ì`uî÷86kXbß*l¨Ðî«‘oqz;-Еº¬ï}EhBÔ¬! m+Ïø‰ob Ö#‘ Û#D—2]¶CÎÆëO1¾§ª JWÔ) ðð']ÊO"4k–-¡¤:…Z›mãàél¸VTát’Zhçx#–œcM©¯¯ßdÇqÈ‘!G‰F‹*Ta ¥+jw)J9RÖ¢T¢IQëSï¨*iJUÈ&¢¦¢€Ø¸qd‹¨u|Kdçyq9OÉ|óCym–Vò“¼ä'!²7qœùVû LX®Ó2%NËŠ`Jr¡Ü¥·Cí-È’¹.2P‡ ‰ÜÚTTÐg¯.±]$Ù®ŒÜbÔã[C©Ü‡¤”­ iRT¤‘ì&¶Dq[A1#X,lYù²å¥-¼c¼[kZ”¥:]ÜTË'!`ŽZq€*’Nú£9 ´œ»J¢³cf=þL%8¦ãÉüvßZT#&áJiÐTœ¬-K$nKeJI®)|·=h»É¶H$½e·2ÓÃÄmq)Pÿô€?ÝW§\\S¨­÷xöûlf­ñ 4¾ÎˆîõYpîç:J·îÊÉb£SÞ¥j Ó·Ym°ÓŽ!¶ÒÛ „6†ÛKhBwp„Œ’IÆI'­"šÞ ín†÷¤/fyÖË\r㕇ÞWu–r=åu8 ìBÈð«©ü4¹ÂTéï>¤éö";)‹¡haô†šq¡³vRVdGOS€\8*ÚEkRoô¼K x܆›}rd¹¿&C¤mA#è^ªYÏ{êåÄmKpЬèÉ2mm4ÃC ;ÊY[«H'8ñtÓÁ¦ý‡2ópëMÁc±¯&t›UÁ6Ë«*‹Ê IR\ 6­Ç˜Œ²êw“”x`ƒ[E³BX qç¤íׇ5%Þ+xF"í\´8ò Êå­¢V­ÊKˆGBBŠJJ±‘¦ê­ipÔ0DtRü‘2sÑ›Z\› $¤:îå» _DŒ­G5âæ®¹¯Yݵ_**g]Lâò•ÑÚÛu·6 Ù¨§$àœùÅ¥`bj»L{ÝV¶®)œüt„KSmá¶ß»hVNð“Óv$d`šš°¿]¤Þ§ ÓP×j-¥:€BŸPæ/¯U‘Œ‘Œ‘“’I5õd¡¡¡©”¥¥)@)JPQSQ@)JP R””¥¥)@)JP R”š{hií "”¥¥)@~”ðð¡¿C7û˯>?~5‡è—ÿt×§zô3¼ºóã÷àSX~‰÷MsâXí´¥*ÅNí­ ë÷åÖûí­ ë÷å×çü/hÏ£G²E ­“áVR<*¶O…{ôL ÙªäùÕ¤Ur|ëÕ a™Y+Æ«dxš²•ãU²U€R” $TTŠŠ|ª*|ª()Jhhhh)JJR€R” &¢¦¢€R” ¥()JJR€R” ¥( 4öÐÓÛ@E)JJR€ý)à/à/C~†o÷—^|~ü kÑ/þé­…'^=½&›6¨²Û 5ha 0õ‘o¸:d•/´$TO‚FR 6Z£Oñ RiË…‚å®,†Â:ã½ËÓªJ‚T0H=§¡®e¤éJUŠœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦±üë\wX5&¢¬A'Ê¢¤ùTP R””¥¥)@)JP R”TûjO¶€ŠR””¥>ÚŠŸmE¥)@)JP R”‚””¥>U>U”¥>ÊŠŸeE"¢¤TP R”ŠyPSÊ€ŠR”ÔTÔPåPj|ª ¥)@H¨©ùTTùTP R”ÐÐÐÐ R””¥¥)@MEME¥)@)JP R””¥¥)@)JPií¡§¶€ŠR””¥ú ÀÿÁ•ýÏîÖåZoÿ:Wôc?»[•r,uºR•r§öÖ…uûòë}öÖ…uûòëóþ´gÑ£Ù"ŽG…VÉð«)['½ú& …lUr|êÒGª¹>uêÐ0̬•ãU²U”¥¥)@)JP R””¥>ÚSí "”¥¥)@O¶¢§ÛQ@)JP R””¥ ¥¥)@O•EO•E¥)@O²¢§ÙQ@H¨©”¥"žTò "”¥55ùTŸ*ƒ@)JP**EE>U>U”¥4444”¥¥)@)JPQSQ@)JP R””¥¥)@)JP R”š{hií "”¥¥)@~‚ð?ðC¥F3ûµ¹V›ÀÿÁ•ýÏîÖå\‹n”¥\©À=µ¡]~üºß}µ¡]~üºüÿ…íôhöH£‘áU²|*ÊG…VÉð¯~‰‚¡[#ÀÕ\Ÿ:´‘àj®Oz´ 3+%xÕlVR¼j¶G‰¯V‰Žesõ†ýf?Xo×¥LÍ# ÚÄwβݬG|ël1¬W| e;X®øÛŒŒG}SXþuïªkεÇqŃQRj*Ä|ª*O•E¥)@)JP R””¥¥)@O¶ Tûh¥)@)Jè³-ºeØw%[-§[˜Šêã̇=}½$ì[̸° wc~ÆÀH'àg¤)¹Þ̬¥”ç~ÚŠÞï:_OÈÕ-69—}ÏÁŠû¨¢áQt©!­JZÉÎܤ¯¶ŒÖ@Ñv›J/)Ô/^#„ÙÚŸ®Ù²CITÄ2¥-•:œ+9HI$¬«9 û<îüžQO™êò2¬dÅPëP¨Í¤í¼—R(Ô)[nšÒp.nØâϽ®»ãÉD4"5âÖõ«zpJ’°;z”ƒšÏ±ðæeæÚÄØ˜}¹Ët[ÜnÒ¥´R•©¾âTC$©$`olj8ëS%¹}ý°êEo4O*Šß´½’ÛÉ,MšÓ÷ ~\¥Cv\m T5¼ÑKª$¥Ñ†×‘‘»ÄgIÛ£]'K!ÒÚ›·K’Èå¥ki…¹ƒ…¤§¢ ïw‚r’ ¨tž‹˜Îµ)é[z4•±ëT'ؾ¾©“m\šŽ¸!)‚÷5aü,¤àîó ª½'æç>{L{l#(ÇÞPQu¶’’GP΂qƒ€zŽªI¤ÉΊ_eElŠ<¬vËì(·‰O?è͸µ¶•´Vä•(HÁ'ªO_!w6Ío¼iû ¢S0î~çäI ³ DéEJqi)ÂËm`+jŠŠ;Äx™T›m"ÒW4QQ[\-) çàÚ¼­«åÁ¦œDÜÎ]HSH[»ÁJ”Ÿ7 ‘×KÁ°ìºÈ¶Ã&èÞa§£¬s÷²~Õ=xs©êœ ué˜ë"j´­½½+d]ºÐêµA.ë§c³"Ä*aÀ§ÈJS±k #¼”œ„œ_¬¬ Xa”Iœ·W»{3 *3ˆP”•!Y8!GÀ䙇JQWaM7b„SÊ­4ä›4Gå?x·.ãˆäEc˜¤6§·'Â’°'yÂNIÚ: šØN•ÝO ßg¶¿ÕAíW8‘Ò·Ì<)[‚IY%²I;—´šF›’З4·šM+kâ~Ÿ]†þß*Ç>ÓLHÎ0Ü”/×1ÚS©Ü¡ÞRV²Ó½4î“¶Ýí¶gñèòîÓ·2Á‚”¾žVܯ™êò2¬dÅPëSÔË;‡GX²©EnVm-j—yÓIjîä˜7k‚ )k„FÇÐ[ÈÚMžs}फœ09¤­—{m™å__.ë9ÛsL!I§”Sßæz„<Œ«ñT:ÑQ›ÿêðù¡ÖDÔ|ª mZ{KÁ»{™ßuǦ®O[œÄ0¾Îêy[øA½'žŒžéN€¬ Ù7¤¬×húZ¢UÄ]®VåÈy¾Ã½ Øô€â•nJZ)JRŽöÄž…DhN[¾÷|éht­ý|7‰Ì!ÕÞ#Ç}‡]i¹’Ô×TÚ†ã©}󇡅õ^`ŠÓ¯°™·]Ÿ†Ä•Ém¢ql)•d€JT…uJ$Ôd0LN”à¯$Lgn0…EH¨®e‰ò¨©ò¨ ¥(¡¡¡ ¥()JJR€šŠšŠJR€R” ¥()JJR€R” $ÓÛCOm¥()Jôÿ‚+ú1ŸÝ­Ê´Þþt¯èÆv·*äXët¥*åNí­ ë÷åÖûí­ ë÷å×çü/hÏ£G²E ­“áVR<*¶O…{ôL ÙªäùÕ¤Ur|ëÕ a™Y+Æ«dxš²•ãU²¹˜ÔnBì¶gù‘[‡)Çs™)–Ò”¶…(,€½ìÎÑœâ£Ý³¥¶:~ËÙš„¸*µýް_¥*ø\÷\N{ÅU™7IéÿEÞgFÔiŒ!M‹¤\#¾Ûƒ˜Ã‹Z”4®øZ Ȳp 3N0¥[Ó57»BÂ[iÙM¶ë‹TFœRRsjÀ+HRPT¤“‚œô®­\±E‘™°µÌ¸å²åŽÉ%M·%„•²â6°ÿ3˜È ­!(Ë«#(gã¥`»©ŸU…ÛK6ËlQ!–™“!†Ö—Ce*HPݳ9JIPHQÇRrsg«tt[mÓR5k¿À˜Õ•Õ•Ç!ðølH €Ii(*IZ7`ã®SšÇ^‹’Ü©ˆzójj$F⸩ª/rV$·Ìk7¼e>jHޤtÊJªô_í÷À”Ἤ²_µÂ™Á…6<¥6â›’•‡ݱÄíPê7¬`䜃V—-f«‡¥{V³+Ò—&î2pdŒºÝÃtJ·»‘ãðªÁFÚ»=‰ëž«cN"t¤?+²¶úœ+aNµ8SaY VPu u«Xš\±³^ìÎv×U6sád§nXÏ_¾ž¾§xwºÕaÖµe÷÷re’÷gó3Z?6å:\ëžSs%ªiŒâ^å4úÀÞâ0æîñ”•ô0 f´~µ)+3ŽÛ.N\™qHy;ž^Üå(q( ÂR”ËO‘PV-¯KKŸ<„΀Ãó7v-aé{IIÙ„”Œ¨ÊNH f½Ó£'­¸HEÆÙÛ¦¦:Ú‚§”‡Š_) ¨nHB³½$„¨2H8”ë=~ù‘hn=mšÞDmηc³¸»\‚õ¼¸—fÒï-#™…'q=W¹]}oQmÖj·ú+²éÛ2}rrã&IëÛÐü7T§cX?œ“•îÄ“¦C7Ѳ8—‹‰[Üõ¶– c*%hJÓýÝÓ¸ôNãÒ¿¡¥%›‚XMÂÞaª!›é ëùe}Q¿×Û»wLRõ~í÷ÈZͤu–Þ›UÖ[öŽe¶J¤5 p䙇4¸a{”Úñ:w$©DdŒRߨ܋of#ö›]ÁQ’¤Äz[JZ£…¢ PÜ¥+ J†IöÖkú.KF…æÐãb99O¡nòØŽ— AÅ’Þ{ˤg¡H$ ¥½ÚݵImµ¾Ä–žh<Ć -¼‚HÜÀ A‚"“•D•Õ­ÿ*-—V½i&ZS–[D×Ûˆ¸*~Bæ9M©®ZŠHè…`(¬7c¥Ué‹Ñ±\\š›t9åÈÎÆ-Ê.m u #–´œ”)Iñ鸟q3BËaÖXfùc–óÅ•%¦ŸZWÉq‚ø|…¡$6 Q=SÓ#¨Î'¹9*u s¶È·©¥º»‚àa´ ¤/vä‚ Ð1·'zqœÑª·Wà‘ Yª/£±§lÎö kÖäo2~§·ï*Ãüy¯u˜ztFÚKÑûLµ¾Ël¼‡SO0òJ›yµx¥@qЂ Ah4¢‹Ž¹éë/£Úm TðëŠd• ¤ ¸v(í('§ZË·h‰Šã»s¶ÆnQà¥n¼ç,sšqÆ—Ým@¡Íƒj‚²?8PPŒµd×ßÞáx+”·Ë÷DÆdD‹$d¨10PmŽTrµ)D“Œ•zà[BÖj‹èìiÛ3½‚Úõ¹ÌŸ„iíûʰðïkÝFæ+§DmòF”ìhNǺ[r\—ØK …¡,‚\u{Û „€¬ç8> þS¤¤¸òÅÖØý¼´·WqJœ 6”…… 8+@ÆÌéÆsDª§u÷÷¡/#V&®™¨ëôuµÛ„Vƒ1®+m|öR‘„c %#*RI=v]e&Û,uZ-S{,wâ!É(wyŽðs˜Ñ(q=2êÈ# øã¥F¹¶B¶³§Ì4DÌ›Puçb¸âÛ}bCí‡0ä%´0œ÷SáWMi›T‹.—µÂ•aUÛP6’$HTÐë.)÷P6§”–ÒÙÊTw)Dwp±hª™¬žïøÿ‚­Â×±­MÔ+’ÝÕmdÙš 4Bà}<Âç¥ũ*ÊÔ²@äc"n£ra¸Ó-1cÈ̃,Bà@}Ð0•­Ja*À;r€1‚jN’ZO1Wë'cKuùiyŶ”¥¤4°”s2ÚŽ“ÝïGZþÙÑ’–f©w‹KLÅŠÜÐúÖémøët4\A9 Z€)8Vz’µ_»xšbñè+ªnÛà´$†Ñ,9µ ?Ž6-$(yôÎ|@#û»^Y¸\bKô²+QÒ¨Ìs¶?ðŠY.)NNâ ÞŒ κèù–ès$*ãl¨5!ÆXqef;¥·†RÕsÓ;†á”Šóáí¢Õ}Õ°-W‰¯Å%öÙ„eÇ·€”“Ñ>¶I>'¡8guO™7â1õMù7éß6{u½ÆYCÄ/bm ¶Ìq~ªP#õÎMfØõ{¶˜ÖV™²Zž]žzç°ë¥ýËuA=WµÐ’-¢ïiñÊ·`ا d›êçºójm1bDZZ.îݽeÅ!a!8OLdîð5jý³M[¯s-’c^®o­ÈÂ1ä·Iæ6T´:TÚòâT¤#¡~¦9›Ïu¯ßì_Ãcø¶ë5[ýÙtí™>‹¹9q“$áÕã¡øn©Nư<~ 9'+ܶë5[ýÙtí™>‹¹9q“$áÕíè~ªS±¬‚NIÊ÷Vk–Û~§Ÿз×;¼¤)çR⊒0¾òR¡¸+¦*îv±·:ç§£®ãé«c/­ÇÖ⠸ Þ@@HR@^¸çhè3ÒS©v“Ý÷ûÔm¿½LK²“fq…Å´Z–"ÜMÂCª\%øL”Ú|¨÷Aµ,k9Qã4Ì{=¡²Â\e— KZÛŽ·â˜ÖFÂ\X'ÊTAQÖŸ·Û—ky»‰NC†ãLc8–Üu×w”êJ‚@KK$í>c®G–§¶Å‚ì)õ¼¨7¢Tpö ˆÖÚ’¢0 mc €…FjŠ7¹6‹v±’5+)…#LX4¦Ì^C…*ܤ¨«˜\.…e#,`d (ëýÖMêêíÊZ[K®% ÚØ!)J”Œ’z% d’N:’jÆùhµDÒV[¬ ¯Ê“-ù ËÜ­¡Hm…„ xœsˆ$ø‘Ðc©×ê“r^‹&)oDŠŠ‘Q\Ë“åQSåQ@)JPCCC@)JP R””¥55”¥¥)@)JP R””¥¥)@I§¶†žÚ)JP R”è/ÿ:Wôc?»[•i¼üé_ÑŒþínUȱÖéJUÊœÛZ×ïË­÷ÛZ×ïË¯Ïø^ÑŸFdŠ9['¬¤xUlŸ ÷è˜*²< UÉó«Iªäù׫@Ã2²WVÈñ5e+Æ«dxšõh˜æW?XoÖcõ†ýzTÌÒ0ݬG|ë-ÚÄwζÀá#ÚÅwÀÖSµŠï­°8ÈÄwÕ5çYú¦±üë\wX5&¢¬A'Ê¢¤ùTP R””¥¥)@)JP R”TûjO¶€ŠR”¯-7K#vqn»ØW-H§Û•PŽÿy) QmaHr«©ª:U£'Ä5sosXB˜ýËÒÖ32,·bº†1MíTf–ÓakÚT°R³»TOPEXݸˆÝÊÑu·?ì¸Ååvaw&,gâB™d·„$cnIÚH 5 {j+¢ÄTI«ïöê¢n“µ…ž]Òé1Í8òSyC¾’ ¸wÜ[6ð-¨·µ JÛ•(‚OLz7­íÍÞMÉ›=Ê"Õ ,bb]ËJ†ƒX–AmiJ2…%G)è¡’+G¥:ùïýêâ_Y¯ñákÈúû`SlÏíɇÐÊB‚÷¥ %*ÂB±ÓöôŽ`R OuD6R’Rk•lR½7Õôã¹= Tb÷#ù÷Âm3˜}늃QÝg´»sß9;Ô‚6H傼¼')QkëÓ%­PΨœÛ[^Sjr “u¾¹­v€óa/­°êTs•¤ Á±èÈچǣ½™I»^om’ì¶nSÄCœ¤¥e2 v)ýIHŠk>ŒÔwk9»A‚Úâ÷ùaršm×ö ¯”Ò”îÑã±*ÅDzR.ù¤—;Ùqkã•ÛØC ¸#c¸ê¦tíÞÚÍ™N¶Ô{1·J.?Ò\’‚¡¹RAI;†1Òµma}sP\Û–³=A¦RÊ ÙË–ñ“•8¬y¨ôHHþìä›ð÷V&ÆÕèAŠä'­æâÒš¸ÆZÜŽ ‚Ö”%µl(Vô¹¼á5ýñBÎÑ’#"MÆÕ1¹b¼ [ŒgœJžŽÛÅ%¶Z‚RVR %`'¢…Uô•*²ê”Ó½ôºákÿð•K.¶!ý^Û¡²Á—Æ„ÔBÛ“w¬¥ v|¥Ä!¶P2’<€É¹k£=Ð̦.ó .2ãÈEÂð¹/­*[kî¸RÞÓda]íÝ1•¡ø{*å eÂ÷ öá*Ç>á L\mä)ˆî<Û«aAN)…)­™ÚJÁ éƒ@ÆŒÔ顨š€ƒoSKyÉh<ãHQJÜC%\Å6•%@¬$¤m9= IÃ4¡oðµÝôöé¸u+GbÆÉ¬™²=-‹D;¥¶Ý) s 즥)mîÚ¢ðFw¨„㯾¬rµÝÙz ÀΟ64¦å9sS¥¾BÚ·¤­d¥ÅäïvàœIÂíAj¿@³Â‘jº¿:$y ¦-Ò"Ö’¸©æä¡å6€UðªÂ”ïj…jº†Ér°N®l¶Û‹l:Úš}4ê‚ÐãeHZrÊIyTÒéu’TæÕÒÓsðŠNí’5Ô÷5t=DÄtÅr3*k–Ë….%\å¥C*Zœq@T¨cÀVEÇ]öçƒ3#Þ'ÛÜŒäi ϼ®CëJ–Úò— v·…4ÙG\w·tÅ Znòí”^&!BœI/¶Z¢•--îÞ¤‚*ƒ“ÐÖD­~Œ©Éy¸ 0"¢\Œ\ã+ ,e Nïç)ÀNOy;Éε:Ö{õð)–™üj‹ÍºëÑ­èÛqFùAàâ Ëu'ÔN—“œ˜ Æ*Öݪì‘%éIž¸®FŸåõôš$muÇü9N]sÚ{£o‰ßT“4Ýæ¥IˆËmt}µ8”/ Sa[Ò•daJŒxв^›f}Eà—Äûuº,æÔ†”Ñ8ÂH;7…¤¦@)RV:Hë€Nªy·~\µýƒPµ¾þõ0­W‹tVî6ù6ÉmC¡‘,!ö”ÞþYì)$%Ń”`î=LX«UÛ—åVi Žõ­6Ø(nh™ñ ©d¶yŠ.€N6 Œ‚š™šnóÒ‹¤ˆ‰De¶‡z>ÚœJ2…©°­éJ²0¥F©Ø6ÿyCÉ‹ìZ¯Ó–ËS¬¡¤f3OK.­†¶‡”²‘¹\Ï„Àg À­~•N¶VKöE²#:$˜-Û'1"ÝÚ%¿ËìÒyêOg‰_tt^áÓ¯‡^MÕqTÛ‹Vuµ{žÊÙ“,ÊÜÑæ'k«C[AJÖ %Dw•€:cV¨¨U$•qLÙ~³¦MÆ:l nÉ8´¾ÄÜÓÌem‚´:¤«¯yÏ‘…‘ì5çw¾Û®Žl¾S G¶+µ(˜m¥jZò0…eJ$0I   ò¨5=d­oÙ ˆØ§^lhè–FmåFyÉ ’»‚‚ë‰e.e°È;pÈÚ7ärUZí)U”œµd¤–âEEH¨ª’O•EO•E¥)@ ¥)@)JP R”ÔTÔP R””¥¥)@)JP R””¥&žÚ{h¥)@)JP ¼üé_ÑŒþínU¦ð?ðC¥F3ûµ¹W"Ç[¥)W*pmhW_¿.·ßmhW_¿.¿?á{F}=’(äxUlŸ ²‘áU²|+ߢ`¨VÈð5W'έ$x«“ç^­ ÊÉ^5[#ÄÕ”¯C°_n¬*E®ÉrœÊTP§#E[‰ À8% ŒàŽŸÞ+Ö ›Üc¨ìkÖõµ½¢µ‘ðÒWãÿòç¾Íb=¡õ¡ðÒ€ÿüµï³^¥8K‘–R\ÍMÚÄwζÇt.·>;Q~Ì{ìÖ3š\œãFj?Ùo}šÙË‘ÂM‹µŠï­¹Í®Ï†ŠÔŸ²ßû5Œçµé#S~ÊìÖ¸&q“4÷}SXþu·¹ÃÍ~GM ©ÿd¿ökÃÞëˆ9ÿ¸š£öKÿbµÇqÉš¹¨­¤ðëˆ?˜š£öKÿb£Þëˆ?˜š£öKÿb¬A¬*ŠÚO¸ƒù‰ª?d¿ö*=ù‰ª?d¿ö( ^•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb€Õé[G½×15Gì—þÅ=ù‰ª?d¿ö( ^•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb€Õé[G½×15Gì—þÅ=ù‰ª?d¿ö( ^•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb€ÕÅO¶¶{® þbjÙ/ýŠŸ{® þbjÙ/ýŠV¥m÷\AüÄÕ²_û÷ºâæ&¨ý’ÿØ 5zVÑïuÄÌMQû%ÿ±O{® þbjÙ/ýŠXöÔVÓïuÄÌMQû%ÿ±QïuÄÌMQû%ÿ±@jô­£Þëˆ?˜š£öKÿbž÷\AüÄÕ²_û¯JÚ=ù‰ª?d¿ö)ïuÄÌMQû%ÿ±@k°c92kS)q÷ÚóÈi¨à-d%¯U(€R@®ÏsÒö[ÍêV¬¼¿k~ï-k“*ÔUgLGä«%K2Ðâ[RÉQ@o ¡\ëÞëˆ?˜š£öKÿbž÷\AüÄÕ²_û“‡©U§ e·ƒã¿ŠåíäË&‘Ôô–ße…¡q½[{VŸÔÏ^¦6ÅöÊ´) ö¡µ›‚JŽb6 )HÕ¼°Ÿ¦ížÑk„›¶šJ¬ yçD­2ûò_qæÖ^~C‹Š°§B9©ë’xï½×15Gì—þÅ=ù‰ª?d¿ö+N‰Kçšw×ðø·ÏþçÿÒÊ¥Ž³e²Y£2%ê‰í+q³Ë ^,‹Ãò»VŒÜ†ä'¶¯©ÚO%=0òõ½u¤™¾A>ÂÎ/i…†ÝÕVdÆi¢"9(P”TáYm ÉÛÞVAW½×15Gì—þÅ=ù‰ª?d¿ö+¥>Ž­ b¨¯ÿ6ß{›i«Xë6M¥W÷«ÕÒ{‚´ó–'Ú‡¨ì®²€mꄇÒU9]Ý„¶Bzäïò9º^=šßjbé»z²H¶Ln4­8û©uØŽ0©)–¹‰}YZ÷–ò€)݃ƽû‰ª?d¿ö*=ù‰ª?d¿ö+”ú&sM:‹—áܵÝép¾œ~!T·®B´iÅÌfïrrÐõÝVˆVì»|°Êqã2Ç9,»3l’°Ï‚ùaÕÑD4¾=.íiU±. Ò"ÛÞ‚òa›`hí’ëÉp7çÞá#%)ê‚Bœ%Djþ÷\AüÄÕ²_û÷ºâæ&¨ý’ÿØ®Ô:6TªÆ£íáák^îËÃóßvCÕ‹Ë«Òðà5l?.[…% Y¢ºàqÈëiO&B”9R·lÊF ÇC¯ÜuR´tKJc­3ÒRÔ™Œ8ÃeE”ûr Šû›oÙ^¾÷\AéþâjÙ/ýŠ{® þbjÙ/ýŠöÝi5cЦ“¹ypÕz]ë%ê߇áµ>n; Y¢ ÇZ^iÔ¡O¥A×Ry{J”sÔª>·;î–{Ó}ž]å]²ÃÝ}½´ü+Œ•aㄞ̎£$sÓ¸7×qóT~ÉìT{ÝqóT~ÉìTºò{×Þ¿2$·— W¥Þ²^­ñ~WA¸ì5fŠƒiy§R…>•]I唕(ç¨;T|1nº‡L‰\­«¼=,Zki¹ÛmµȘÊuD8¢žîâ냻ʫ}ù‰ª?d¿ö)ïuÄÌMQû%ÿ±Gˆ“ûûæ$‹Ó¬,-L•+²ÕT;{j~U–,…¡È¬rz2êÔ‚• «;‚8êݧêËš/éÛ.Ö„sm³µJÜi)BF0”Žƒ¦O‰´:âæ&¨ý’ÿا½×qÿq5Gì—þÅVu¥5fL`¢îZ•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb¹5ŠŠÚ}ù‰ª?d¿ö*=ù‰ª?d¿ö( cÊ ÖÓïuÄÜMQû%ÿ±QïuÄÌMQû%ÿ±@jô­£Þëˆ?˜š£öKÿbž÷\AüÄÕ²_û°*+i:âæ&¨ý’ÿب÷ºâæ&¨ý’ÿØ 5*ŠÚ}û‰ª?d¿ö*=ù‰ª?d¿ö( ^•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb€ÕÍ m÷\AüÄÕ²_û÷ºâæ&¨ý’ÿØ 5zVÑïuÄÌMQû%ÿ±O{® þbjÙ/ýŠW¥m÷\AüÄÕ²_û÷ºâæ&¨ý’ÿØ 5zVÑïuÄÌMQû%ÿ±O{® þbjÙ/ýŠX¨­§Þëˆ?˜š£öKÿb£Þëˆ?˜š£öKÿb€Õé[G½×15Gì—þÅ=ù‰ª?d¿ö( ^•´{ÝqóT~ÉìSÞëˆ?˜š£öKÿb€Õé[G½×15Gì—þÅ=ù‰ª?d¿ö( ^•³¯‡šý+^†ÔéJFI6—ÀæÖ±@)JP R”š{hií "”¥¥)@~‚ð?ðC¥F3ûµ¹V›ÀÿÁ•ýÏîÖå\‹n”¥\©À=µ¡]~üºß}µ¡]~üºüÿ…íôhöH£‘áU²|*ÊG…VÉð¯~‰‚¡[#ÀÕ\Ÿ:´‘àj®Oz´ 3+%x×ÒßqË,¿¥nHy¤8‘=ÒÒÏ-m|Ó+ƾ™ûŒ¿î½Ïÿ<ïî1_Òô?n½‡—ŒìÎïèøôIú©èøôIú«&•ýIåÞñ(ßDŸªžñ(ßDŸª²i@cz>Ä£}~ªz>Ä£}~ªÉ¥èøôIú©èøôIú«&”7£à|J7Ñ'ê§£à|J7Ñ'꬚PÞñ(ßDŸªžñ(ßDŸª²i@cz>Ä£}~ªz>Ä£}~ªÉ¥èøôIú©èøôIú«&”7£à|J7Ñ'ê§£à|J7Ñ'꬚PÞñ(ßDŸªžñ(ßDŸª²i@cz>Ä£}~ªz>Ä£}~ªÉ­Rtë“]³ÛQrxÛ&Ø'¾ì"Û|°ó!¥…mæn)´TS€œ$’ÅèøôIú©èøôIú«WÔþž]Ôz ó6Ýdÿ¶nq»8b߆’ú÷¥n¥ÕíeÄ8yM¯!@'rHö¹kTƼNLßîì[KW)emÄYm”–Ôê^uA§^mÂBÂS¹yHbô|‰Fú$ýTô|‰Fú$ýU¨ëÎ%ZtSËvùk¹3iiÄ´ýÙkŒÄd,£˜R€óÈuõw°Ãn…%;–• fNrc‹¶{j.OdÛ÷Ý„[o–bD4¡Ð­¼ÍÅ2’ Šp„ƒ’@ؽâQ¾‰?U=âQ¾‰?Usÿ|)C­ÚºZï3íV;’ôØÑÚKÈ~Šò”µ-HS¸RßYKAׯR76q¨5ü;<»¨ôæmºÉÿlÜãvpÅ¿ %õïJÝK«Úˈpò›^B€NåÑèøôIú©èøôIú«]¹kTƼNLßîì[KW)emÄYm”–Ôê^uA§^mÂBÂS¹yH­½_5³c²Øa[¬Ë°Ê¶Ë²åÉiuĶì$©ÒŽÎ­«oœ°–Âö¸J”‚( ÓÑð>%è“õSÑð>%è“õVMr›íïRÛÞâ6«oQÌ\=#$©›"£Çì²nÛKˆRù\àµ]ڰ梂P´¤¡@tßGÀø”o¢OÕOGÀø”o¢OÕTrïÅ eƒtÆ£=e™3o!¥1!h~23ÌßÍBÛz»6(?ÙF+Æå­Sñ:3»±lq-\¦@m•·e´:R[S©yÕœmxe· Nåå ‹Ñð>%è“õSÑð>%è“õV£fÕ®'WêK,Ž:B/íöÄa´sØ ºëŠðÃMªBÖ¥¨ø­(R›B·zÑð>%è“õSÑð>%è“õW?ÔºžùHqz|iÛ$éÞÑè¥ò{>ÛDi èF‡\Z»ÙñÇ€³/WÍlÇì¶Vë2ì2­²ä,¹rZ]q-» *t£³«jÛç,%°½®’¥ ¤ tô|‰Fú$ýTô|‰Fú$ýUG.ñ!P¶X7Lj3ÖY“6òS‡ã#<ÍüÔ-°ç«³bƒùÝ”b¼gN¹1ÅÛ=µ'²m‚{îÂ-·Ë1"PèVÞfâ™ IE8 ÂAÉ l^ñ(ßDŸªžñ(ßDŸª¨åÞ$#ŠËéFzË2fÞCJbBÐüdg™¿š…¶õvlP;²ŒV®×ôíͨjÐÚ–ä܉-ʼn"°Je:´çkhrJ;@YQ()mk=Ä•PG£à|J7Ñ'ê§£à|J7Ñ'ê­G^q*Ó¢ž[·Ë]É›KN%§îË\f#!e”žC¯¨#½†pœ))Ü´©Æõ|ÖÌqŽËa…n³.Ã*Û.BË—%¥×Û°’§J;:¶­¾rÂ[ ÚàY*R @ 7OGÀø”o¢OÕOGÀø”o¢OÕTrïÅ eƒtÆ£=e™3o!¥1!h~23ÌßÍBÛz»6(?ÙF+PkøvywQè+ÌÛu“þÙ¹Æìá‹~KëÞ•º—Wµ—áå6¼…Ê £Ñð>%è“õSÑð>%è“õV£xâE¾Ûq¿G6 ü˜ºuÀ›ÍÁ¦¡·ÙÛ]*[‰S© ¹’–’·Ôw›ß»ÐÞñ(ßDŸªžñ(ßDŸª¨ô}ÒtýC¬âK˜Í¶ôÜX‰Ø‘ËhÛá¼S2~ד“ÞÇ€VëÎ%ZtSËvùk¹3iiÄ´ýÙkŒÄd,£˜R€óÈuõw°Ãn…%;–• ·z>Ä£}~ªz>Ä£}~ª×nZÕ1¯ AÓ7û»ÇÕÊdÙ[q[C¥%µ:—PiÆ×†[p°”î^R+oWÍlÇì¶Vë2ì2­²ä,¹rZ]q-» *t£³«jÛç,%°½®’¥ ¤ tô|‰Fú$ýTô|‰Fú$ýU“\óˆ¶ðÔ¤ÆÓKe†-—ûL Ä·›Þ¥2¢¤Åi'ñ‹2µ:A JPµ)L½z>Ä£}~ªz>Ä£}~ªäÜAÕ·Ë}ÛU;ÿy…&ÍÿeB‡kCöɈÓÉíòK ·:µ¥{Ÿck! îUب oGÀø”o¢OÕOGÀø”o¢OÕ\›\ñ.eŠ×ÅHÜÛϤlüßC=Ã"K¿ÙqžF÷ÊšykYæ« #vŠÜu¿‡g—u‚¼Í·Y?훜nη᤾½é[©u{YqSkÈP Ü RÚ=âQ¾‰?U=âQ¾‰?UQܵ®£WÝbb™Ò|ÎÞ”!%NlˆÔ³Êʰ~ ÔŽñOxáÔáÊ×Ì¢ýw´ÂÒú–çèY(bå&$VÔÓL4øZw8÷qÞ¨e.8 HÙÞoxG£à|J7Ñ'ê§£à|J7Ñ'ê­vå­Sñ:3»±lq-\¦@m•·e´:R[S©yÕœmxe· Nåå#k 1½âQ¾‰?U=âQ¾‰?UdÒ€Æô|‰Fú$ýTô|‰Fú$ýU“JÑð>%è“õSÑð>%è“õVM( oGÀø”o¢OÕOGÀø”o¢OÕY4 1½âQ¾‰?U=âQ¾‰?UdÒ€Æô|‰Fú$ýTô|‰Fú$ýU“JÑð>%è“õSÑð>%è“õVM( oGÀø”o¢OÕOGÀø”o¢OÕY4 1½âQ¾‰?U=âQ¾‰?UdÒ€Æô|‰Fú$ýUå2$6"<óvèÎ-¶Ô¤£•ë3ŽêIý@Ÿ`5X·†ÜvÑ1¦™ç¸¸ëJZÊFòRpžø)ëáÞ{A«]zVˆ»»*ÀÅ´·Éå-$’¼º3ÑHAݧÃñ°p¤©#òæ¿N.P›‰¡/ËnÓØ’çgÎòy¤: ÓD`’s·ý €”þcÐG}Ê<,Ñ\@Óoöã*rg–¹ÎÊq´0Ò[B’–Ôœ©JZ÷ !8©7¿tÇ´ŽáƒºžÇË\ˆ/ qá(8´#b‚Ôv PRqà B·$£}Î\e‡ÃæÄºZ^™ç{BÅ9„§j·(B‡QÞ+p(í×)iŸºÑ#I<^³Â*m ‚ô¦X“!{‹¡l¬•î 0RrÞê{À«Ñ¥‡»[–ºja§CS£ôxrûñ>+¥mOÑ“4.¬zÇ*Kr‘·›äŠ[EJHÞÞIm`¥AH>d$¥JÕë,d§(»¦o”\]žòM=´4öÕˆ"”¥¥)@~‚ð?ðC¥F3ûµ¹V›ÀÿÁ•ýÏîÖå\‹n”¥\©À=µ¡]~üºß}µ¡]~üºüÿ…íôhöH£‘áU²|*ÊG…VÉð¯~‰‚¡[#ÀÕ\Ÿ:´‘àj®Oz´ 3+%x×Ó?q—ý×¹ÿçýÆ+æi^5ôÏÜeÿuîùçqŠþ—¡ûuì<¼gf}JR¿©<¡JR€R” ¬5]mi¶Iº*å 0"ó»D¢úyLò”¤»½yÂv,+'ºRAÆ {H—;Ñ™‘%–\”áj:°•<°…,¥úÊÚ…«®£à íJR€R” ¥(+Î4ˆò[.F}§¶Ê›XP BŠTœ0 ADå^””¥¥)@+Nºi½Q+‰ýQQY™3°ÑË;Ž:¦\u¼ ÂJFòc ªåá!G)^3[( Sh;¥Ñz– A%“TçÓ =mSÒ{ñ›Šçgx<„·–ZFÝí¹…îQÜ@Ì•¥õ{õÞfžÔÐíïRQ*z^µ™Pèa¨åQÝ.¥´| ”‡tî'rNÁ¸×œiä¶\ŒûO -m•6° …©9a@‚<ˆ#Ê€çZ÷†sµ½H¸Z†¹†Úä 2]´¦Løí) Ùa‡Ôà Æ% Z™ØIRÞRV…-*EÅÓMê‰\H·êˆÚŠÌÌ1†ˆ.YÜqÕ0òã­à^R7“mW/ 9JñšÜi@i×鿵zS•î¿›ðœŒöMð‰á»á1ÉßâŸ[Y8z›AÝ.‹Ô°`êq,š§>˜aëjž“ߌÜW;;Áä%¼²Ò6ïmÌ/rŽàBûJžkιªuî+—`BVÚZD¹=t€œ)‰q…$åÄ)Hp¡Õ)Y#j}ªôÜë¥îÝz´^½>$iT銗ÿ£HS*t¶ /²…¨-½¹µäce¥­ á î“®Ú™‡õ?s:šJ^¹[ÓmP”´vFc-”ÉçmJ–Q o ZÂT•mZwÚPuÓMê‰\H·êˆÚŠÌÌ1†ˆ.YÜqÕ0òã­à^R7“mW/ 9Jñš­×œ7sTêÜW.À„­´´‰r,zé8Sâ IˈRáCªR²FÔ'"<–Ë‘Ÿiä­²¦ÖТ•'#Ì(G‘yW¥¤+‡±ZÔwýUo”Ì=GršÜ¨×$Dƈ¬1ÙïüuJ”Ù)^S±Ä!ѻҔ…©´Òè½K ‡ɪs醶©é=øÍÅs³¼B[Ë-#nöÜÂ÷(î \j½7:é{·^­¯DωD:b¥ÿèÒÊ-‚@KÀÇl¡j @ïnmyÙi@i×M7ª%q"ߪ#j+30 Æv ¹gqÇTÃËŽ·xIHÞLaµ\¼$(å+ÆitÓz¢W-ú¢6¢³3 ga¢ –wuL<¸ëx„”äÆUËÂBŽR¼f·PuÓMê‰\H·êˆÚŠÌÌ1†ˆ.YÜqÕ0òã­à^R7“mW/ 9Jñšñ¹iduœíCjÕ%æÒÄFî6'¤¹ ¨ÞÓkD¶“µn'˜£³rŽÀ¥(6ØNï^q¤G’Ùr3í<€µ¶TÚ€ZR¤äy…ò *kÞÎÔrõ"ájväjk$ÉvÒ™3ã´¦ƒe†S€7”%jga%KyIZ´©&«Ós®—»uêÑzôLø‘¤AS¦*_þ!L©ÒØ$¼ vÊ ´öæ×‘–”tÓz¢W-ú¢6¢³3 ga¢ –wuL<¸ëx„”äÆUËÂBŽR¼f°õ6ƒº]©`ÁÔâY5N}0ÃÖÕ='¿¸®vwƒÈKye¤mÞÛ˜^åÀ„ ö”yÐþ‘°kûW¥9^ëù¿ ÈÏdߘž¾þ)õ±å“¸Ò”­3¬ j;ýËNê‹X·™­Í\yö'¤¸ÒÓˆä-°RC W«Tzš­×¼3¨åêEÂÔ0íÈÔ6× I’í¥2gÇiMË >§n1(JÔÎÂJ–ò’´)iR:M(y¯8næ©Ô ¸®] [iiäXõÒp¦%Ä“—¥!‡T¥d¨Mö«Ós®—»uêÑzôLø‘¤AS¦*_þ!L©ÒØ$¼ vÊ ´öæ×‘†4ˆò[.F}§¶Ê›XP BŠTœ0 ADå^”´}Âí«ÕÚ§i˹®l9/ÏzÔËϼ†ijiK (¥m¶Z9$«Àއw¥¡jmtº/RÁƒ¨!IJjœúa‡­ªzO~3q\ìï–òËHÛ½·0½Ê;í)@i×鿵zS•î¿›ðœŒöMð‰á»á1ÉßâŸ[Y8z›AÝ.‹Ô°`êq,š§>˜aëjž“ߌÜW;;Áä%¼²Ò6ïmÌ/rŽàBûJžk^Þ/que²Õª™´Û5Sk7«g>J]TTFø' h¡–· ¶¥¹µÄ$·µéû¢nÚŠjçzjä‰Û9{y;bG³9;¿êû³ÓÖÆ:dÜWœiä¶\ŒûO -m•6° …©9a@‚<ˆ#Ê€Ð5ç ÜÕ:w˰!+m-"\‹º@Îĸ‚Â’râ¤8Pꔬ‘µ èt¥¥)@)JP R”•çDy-—#>ÓÈ [eM¬(¡E*NG˜P "ò¯JJR€R” ¥()^q¤G’Ùr3í<€µ¶TÚ€ZR¤äy…ò *Ò”¥¯)ƒtG“Ëu̶¡±¥ìZºx%Y>Ñh¯Zż-mZ&:ÛÈZ#­Ii¥©+p„žêJz‚|}”ƒ¨Ί¾ÌTI±Öâc4yòu* w#i})pùÏM½Fwcòþ¿Qu¦E§‡÷–ßb;AÅ2¤ò]IIøD纆šH>pIð' H¯ËªVrõtÓ·¸·«,Ç!ÏŠ½Í:€ˆ ¤‚RT’R¤¨©$‚$U}( =I»êK—¤¯sW6^À‚êÒ¢‘œ€3Œþ¬*²”¨I%dKm»²M=´4öÔE)JJR€ýàà‡JþŒg÷kr­7ÿ‚+ú1ŸÝ­Ê¹:Ý)J¹S€{kBºýùu¾ûkBºýùuùÿ Ú3èÑì‘G#«døU” ­“á^ýB¶Gª¹>ui#ÀÕ\Ÿ:õhfVJñ¯¦~ã/û¯sÿÏ;ûŒWÌÒ¼k韸ËþëÜÿóÎþãý/CöëØyxÎÌú”¥RyB”¥¬;çgô$îÙÛ;7fsØù¼ý›Nî_'áwã8å÷ó½qY” 8ŽŠi>ã­Œ@Óט¶½;«'ÜæZܱI‹Ì‚ä‰êŠXeÆÐå—#H £*G);SÌ ¡^/èÝMÇs€í¡åȼZ^ƒ¦Â•§O<©²¤2 HŒ–šr ÞÉRA·¥(*R#%ÎéJõ$»[ìN}øñŠw8ë2ÜŒ¤Ùæ6¤©#§\Ó ôÍi¶F™•hÓ»¨..Iqh.ïÔr¥¼Xï'¼þR­êGD‚{ÛpµVøòÔÛ+ZZ[ªJIA”}ƒ$ Ÿï U– i½,Ù·LlÚlë@,=` A*Æp…wÚDYS’VLþ™±iCËåÞnKÎÍŸï$µnÏ+oõÝs¹¯ñæç8:vÃ¥ /‚¾O{2žØQ¨¤`åäíCäÞhdõQ^T78 vôK­¹µÌFí¹Êšîçfs…ùnVqù5c9Nì;,éÅ$Û¦uè$ºÒ¶ü.$:¿Wrô娧º’²'<¹šäÛ”TÛ?.ù<æPØ¢²æYî€Tþrw4rœ’‚6¸¢s™±iCËåÞnKÎÍŸï$µnÏ+oõÝs¹¯ñæç6³'HíVÐmÓæHÁÖ‡‹D@tnÆå_Þ”B}UVb%ÈVÜÚæ#vÜåMws³9Âü·+8üš±œ§rÈg—3DÐÚ{I"δ±Ÿ *ç5HR5ø%RÉ ø9 åm “¹EyX qI¬É¶(©¶~]òyÌ¡°E!e̳ݩüäîhå9$/mqDÝé[„‡í«Q1Y)%EöœÙ‰H}ÏWr]9Jî·Y'HíVÐmÓæHÁÖ‡‹D@tnÆå_Þ”B}UT$¬^¥I¹¶ß©›”<¾]æä¼ìÙþòKVìò¶ÿ]×;šÿ`ñÞsƒ§l:PÂø+ä÷³)í…ŠF^NÑ„>A=æ†OUåCsŠoD¹ Û›\ÄnÛœ©®îvg8_–åg“V3”îòÎìRMºgY‚K­+oÂà‚C«õw(NZ€J{©3dS<¹šäÛ”TÛ?.ù<æPØ¢²æYî€Tþrw4rœ’‚6¸¢s™±iCËåÞnKÎÍŸï$µnÏ+oõÝs¹¯ñæç6³'HíVÐmÓæHÁÖ‡‹D@tnÆå_Þ”B}UVb%ÈVÜÚæ#vÜåMws³9Âü·+8üš±œ§rÈg—3PÓ¶(a|ò{Ù”öÂE#/'h žóC'ªŠò¡¹Å›aÒŠ›gåß'œÊÔR\Ë=Ð ŸÎNæŽS’BðF×NÇe!ؤ›tβ—ZVß…Á‡WêîP œµ”÷RS'HíVÐmÓæHÁÖ‡‹D@tnÆå_Þ”B}URÈg—2©›”<¾]æä¼ìÙþòKVìò¶ÿ]×;šÿ`ñÞsK¡´ö’Eibÿ>@UÎj¤j'ðJ¥’ðr ÊÚ'rŠò°â“[Ú%ÈVÜÚæ#vÜåMws³9Âü·+8üš±œ§u^•¸H~Úµ™Ò’T_i͘A‡Üõw(Ó” ŽëuW.ªO#Wâ¿r’m‡J*mŸ—|žs(lQHYs,÷@*9;š9NI Á\Q9ÌØ´¡åòï7%çfÏ÷’Z·g•·úî¹Ü×øóŽó›Y“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ª«1ä+nms»nr¦»¹Ùœá~[•œ~MXÎSºlŠg—3PÓ¶(a|ò{Ù”öÂE#/'h žóC'ªŠò¡¹Å›aÒŠ›gåß'œÊÔR\Ë=Ð ŸÎNæŽS’BðF×NÇe!ؤ›tβ—ZVß…Á‡WêîP œµ”÷RS'HíVÐmÓæHÁÖ‡‹D@tnÆå_Þ”B}URÈg—2©›”<¾]æä¼ìÙþòKVìò¶ÿ]×;šÿ`ñÞsƒ§l:PÂø+ä÷³)í…ŠF^NÑ„>A=æ†OUåCsŠoD¹ Û›\ÄnÛœ©®îvg8_–åg“V3”îòÎìRMºgY‚K­+oÂà‚C«õw(NZ€J{©+!ž\Írm‡J*mŸ—|žs(lQHYs,÷@*9;š9NI Á\Q9ÌØ´¡åòï7%çfÏ÷’Z·g•·úî¹Ü×øóŽó›Y“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ª«1ä+nms»nr¦»¹Ùœá~[•œ~MXÎS¹d3Ë™¢hm=¤‘gZX¿Ïsš¤)‰ü©d„ü…r¶†IÜ¢¼¬8¤ÖdÛ”TÛ?.ù<æPØ¢²æYî€Tþrw4rœ’‚6¸¢nô­ÂCöÕ¨À˜¬Î”’¢ûNlÄ‚$>竹@€®œ¥„w[¬‰“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ªªV/R¤ÜÛo‰TÍ‹J_.ór^vlÿy%«vy[®ëÍ0xï9ÁÓ¶(a|ò{Ù”öÂE#/'h žóC'ªŠò¡¹Å·¢\…mÍ®b7mÎT×w;3œ/Ër³É«ÊwaÙgHv)&Ý3¬‡A%Ö•·ápA!Õú»”§-@%=Ô™²)ž\Írm‡J*mŸ—|žs(lQHYs,÷@*9;š9NI Á\Q9ÌØ´¡åòï7%çfÏ÷’Z·g•·úî¹Ü×øóŽó›Y“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ª«1ä+nms»nr¦»¹Ùœá~[•œ~MXÎS¹d3Ë™¨iÛ”0¾ ù=ìÊ{aF¢‘ƒ—“´aOy¡“ÕEyPÜâM°éEM³òï“Îe €ê) .ežèOç'sG)É!x#kŠ'c²ÎìRMºgY‚K­+oÂà‚C«õw(NZ€J{©)“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ª©d3Ë™TÍ‹J_.ór^vlÿy%«vy[®ëÍ0xï9¥ÐÚ{I"δ±Ÿ *ç5HR5ø%RÉ ø9 åm “¹EyX qI­íä+nms»nr¦»¹Ùœá~[•œ~MXÎSº¯JÜ$?mZŒ ŠÌéI*/´æÌH ‚Cîz»” éÊPGuº‹+—U'‘«ñ_¹I6Ã¥6Ï˾O9”6¨¤,¹–{ ?œÍ§$…à®(œælZPòùw›’ó³gûÉ-[³ÊÛýw\îküyƒÇyͬÉÒ;U´tƹ’0Au¡âÑ$±¹D€÷¥ŸUU˜‰r·6¹ˆÝ·9S]ÜìÎp¿-ÊÎ?&¬g)Ý6E3Ë™¨iÛ”0¾ ù=ìÊ{aF¢‘ƒ—“´aOy¡“ÕEyPÜâM°éEM³òï“Îe €ê) .ežèOç'sG)É!x#kŠ'c²ÎìRMºgY‚K­+oÂà‚C«õw(NZ€J{©)“¤v«h6és$`‚ëCÅ¢H :7cr‰/ïJ!>ª©d3Ë™TÍ‹J_.ór^vlÿy%«vy[®ëÍ0xï9ÁÓ¶(a|ò{Ù”öÂE#/'h žóC'ªŠò¡¹Å·¢\…mÍ®b7mÎT×w;3œ/Ër³É«ÊwaÙgHv)&Ý3¬‡A%Ö•·ápA!Õú»”§-@%=Ô•Ï.f¹6Ã¥6Ï˾O9”6¨¤,¹–{ ?œÍ§$…à®(œælZPòùw›’ó³gûÉ-[³ÊÛýw\îküyƒÇyͬÉÒ;U´tƹ’0Au¡âÑ$±¹D€÷¥ŸUU˜‰r·6¹ˆÝ·9S]ÜìÎp¿-ÊÎ?&¬g)ܲåÌÑ46žÒH³­,_çÈ ¹ÍRDþ T²B~B9[C$îQ^VœRk2m‡J*mŸ—|žs(lQHYs,÷@*9;š9NI Á\Q7zVá!ûjÔ`LVgJIQ}§6bAsÕÜ @WNR€B;­ÖDÉÒ;U´tƹ’0Au¡âÑ$±¹D€÷¥ŸUU +©Rnm·ÄªfÅ¥/—y¹/;6¼’Õ»<­¿×uÎæ¿Ç˜;Nì;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aI0»!år®»ýMŸí%«wÞvþ?\åŸñæyóìKÖG"¤µxçHp úQnnè æ¯?ÔŒgññµ<š’¦\ÁsD«h\è}éP );þ’ç ú®0¼e'opª³ÝÌmß.±·v"¨gÔÎ>ã8s8ÜŸ§uD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU–Â쇕ʺïõ6´–­ßyÛøýs–Ç™çÌ;€YEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UX–'¬ŽEIjñÎþàAô¢Ü݇P3Í^©Ïããjy…4õ‘2­A«ÆwÈH@ô¢Ï3à’R1Íóð'^wço|ª€·Cw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕzWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÖC ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0î¬ÒOÙ¶•5zíÓ¤% ô²ÝÎ$$$gžæ©ÝøøØåºŽ%—á|Ë9‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nê‰Y*Ô¼g|„„J,ó> %#Ñ¿?q…ç~v÷Ê«-…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwIQe5E%s¡»‰…ÂŽpx8ÏwrFÔì))‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÒCÖDʵ¯ß!!Ò‹<Ï‚IHÇ4oÏÀœayß½òªÝ ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwaÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; I…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÐsÍ­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªÌCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕ²&U¨5xÎù ”Yæ|JF9£~~ã Îüíï•V[ ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0îJúMËjÔ»„7ñ:RT Ò•êÈ €{C˜Æ×»¹HØ…ºÈ˜.h•m ½# …'Á@áŸUÂŒ¤íîUf’~Èõ´©«×hþ!(W¥–îq!!#<÷3ýHÆïÇÆÄo-ÖD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU qiþ&[¡»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nì;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aI0»!år®»ýMŸí%«wÞvþ?\åŸñæyóìKÖG"¤µxçHp úQnnè æ¯?ÔŒgññµ<š’¦\ÁsD«h\è}éP );þ’ç ú®0¼e'opª³ÝÌmß.±·v"¨gÔÎ>ã8s8ÜŸ§uD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU–Â쇕ʺïõ6´–­ßyÛøýs–Ç™çÌ;€YEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UX–'¬ŽEIjñÎþàAô¢Ü݇P3Í^©Ïããjy…4õ‘2­A«ÆwÈH@ô¢Ï3à’R1Íóð'^wço|ª€·Cw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕzWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÖC ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0î¬ÒOÙ¶•5zíÓ¤% ô²ÝÎ$$$gžæ©ÝøøØåºŽ%—á|Ë9‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nê‰Y*Ô¼g|„„J,ó> %#Ñ¿?q…ç~v÷Ê«-…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwIQe5E%s¡»‰…ÂŽpx8ÏwrFÔì))‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÒCÖDʵ¯ß!!Ò‹<Ï‚IHÇ4oÏÀœayß½òªÝ ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwaÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; I…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÐsÍ­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªÌCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕ²&U¨5xÎù ”Yæ|JF9£~~ã Îüíï•V[ ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0îJúMËjÔ»„7ñ:RT Ò•êÈ €{C˜Æ×»¹HØ…ºÈ˜.h•m ½# …'Á@áŸUÂŒ¤íîUf’~Èõ´©«×hþ!(W¥–îq!!#<÷3ýHÆïÇÆÄo-ÖD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU qiþ&[¡»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nì;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aI0»!år®»ýMŸí%«wÞvþ?\åŸñæyóìKÖG"¤µxçHp úQnnè æ¯?ÔŒgññµ<š’¦\ÁsD«h\è}éP );þ’ç ú®0¼e'opª³ÝÌmß.±·v"¨gÔÎ>ã8s8ÜŸ§uD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU–Â쇕ʺïõ6´–­ßyÛøýs–Ç™çÌ;€YEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UX–'¬ŽEIjñÎþàAô¢Ü݇P3Í^©Ïããjy…4õ‘2­A«ÆwÈH@ô¢Ï3à’R1Íóð'^wço|ª€·Cw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕzWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÖC ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0î¬ÒOÙ¶•5zíÓ¤% ô²ÝÎ$$$gžæ©ÝøøØåºŽ%—á|Ë9‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nê‰Y*Ô¼g|„„J,ó> %#Ñ¿?q…ç~v÷Ê«-…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwIQe5E%s¡»‰…ÂŽpx8ÏwrFÔì))‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÒCÖDʵ¯ß!!Ò‹<Ï‚IHÇ4oÏÀœayß½òªÝ ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwaÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; I…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwbXž²9%«Ç;úCÒ‹sv@HÏ5yþ¤c?©æÐsÍ­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªÌCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕ²&U¨5xÎù ”Yæ|JF9£~~ã Îüíï•V[ ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0îJúMËjÔ»„7ñ:RT Ò•êÈ €{C˜Æ×»¹HØ…ºÈ˜.h•m ½# …'Á@áŸUÂŒ¤íîUf’~Èõ´©«×hþ!(W¥–îq!!#<÷3ýHÆïÇÆÄo-ÖD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU qiþ&[¡»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nì;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aI0»!år®»ýMŸí%«wÞvþ?\åŸñæyóìKÖG"¤µxçHp úQnnè æ¯?ÔŒgññµ<š’¦\ÁsD«h\è}éP );þ’ç ú®0¼e'opª³ÝÌmß.±·v"¨gÔÎ>ã8s8ÜŸ§uD‡¬‰•j ^3¾BB¥yŸ’‘Žhߟ8Âó¿;{åU–Â쇕ʺïõ6´–­ßyÛøýs–Ç™çÌ;€YEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UX–'¬ŽEIjñÎþàAô¢Ü݇P3Í^©Ïããjy…4õ‘2­A«ÆwÈH@ô¢Ï3à’R1Íóð'^wço|ª€·Cw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕzWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÖC ²W*ë¿ÔÙþÒZ·}çoãõÎYÿgŸ0î¬ÒOÙ¶•5zíÓ¤% ô²ÝÎ$$$gžæ©ÝøøØåºŽ%—á|Ë9‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nê‰Y*Ô¼g|„„J,ó> %#Ñ¿?q…ç~v÷Ê«-…Ù+•ußêlÿi-[¾ó·ñúç,ÿ3ϘwISø¶&îå¹Í—%ÞsÉ 1–´…0zsÕÓ£7 e# ØRj´Ø’8}ûKÞŒG-¶–Y+ø>êB³”œ`nÏ^žÞÞöž]¡Õ9}øã »é—:$8€þrˆéÊë¸zþ ÞSXºZ,[‡àÁ-lH·\ZÞ T«œà‚HÇ€Æ1Ó©s"/ïˆvÚ¸h*aI$¥)_Â'Á i 6œíÉÜ£”§ó¿Tµý¢-¿H^d°äµ­öã¶ ü…½€‡²0VI¹éœwŽ+h)JJR€“Om =´R” ¥(Ð^þt¯èÆv·*Óxø!Ò¿£ýÚÜ«‘c­Ò”«•8¶´+¯ß—[ï¶´+¯ß—_Ÿð½£>Ér<*¶O…YHðªÙ>ïÑ0T+dx«“çV’< UÉó¯V†ed¯úgî2ÿº÷?üó¿¸Å|Í+ƾ™ûŒ¿î½Ïÿ<ïî1_Òô?n½‡—ŒìÏ )Uº‹PXtÜ$NÔW»mž*Ü !ùòÃjY„…,€U„¨ãÇû*²Á¯´N¡½¦Ë§õ]šó<ÆrQjß-64…!*R‹d„õuNN3´ãú“Ê6ZR””¥¥)@b^®í6y·Y{û<(îHw`ʶ!%GÌàåú{Ž ‹Ž#“®\$6Ô¢!¸R„¥°Þó´ŽæåôÈW«êƒ´×Yx8YXehC…'b–ÉÈÈþìñª=,.hÓzX*t0…¶ÖÔ†’QÈÈIøa¸„…õÚ¡’•lI®SUô^Õݰµ0Q‹Ú)ÊO†Y¨éùÂWó^ÃZG¸h­¹ºLFí¹Ì';¹ÙœàynVqù5c9Nï wxvÛ!®7V·V¼; Ü„­aI>*éµyè|¬ÜIéènæ6ï— XÛ»T3êgqœ9nOŽÓ»Ê.jŠJçCw !…áÜ9xðpžî䩨Ri—Þ^ëú}D_°©ú±þž=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ^èã÷ ·7IˆÝ·9„çw;3œ-ÊÎ?&¬g)ݾL4J¶…·ޑ…“¿à‰ pϪá ÆRv÷ «1 ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚw2â;ËÝPUú# Ÿ«á9FžãßÓI•s¸6µK}_ Õ¥Oå?Žç@•øx6 Žâ+!î<ðíç¡­»À!…¾D'pÚJr¼Ð)Ìx/ª¨ªÞô¯¤Ü¶­K¸C¥%J )^¬‚´9Œmp»»”ˆØ[¬‰‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUBŽ#¼½×õ:ýwþ…KÿV?Âhhã÷ ·7IˆÝ·9„çw;3œ-ÊÎ?&¬g)ÝánãÏÛd"UÆàÊÖêׇa;•¬)'Å]6¯=‚€;‰== ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwaÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; LåÄw—ºþ¢:þˆ¿aSõcü'<{<;yèknãpC¡o‘ Ü6’€œ¯t s êƒê*½ÑÇî+nn“»ns Îîvg8[•œ~MXÎS»|˜.h•m ½# …'Á@áŸUÂŒ¤íîVb¹»åÃV6îÄU ú™ÇÂgcÇ“ã´îeÄw—ºþ «ôG?V?Âs wxvÛ!®7V·V¼; Ü„­aI>*éµyè|¬ÜI=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ]Ê.jŠJçCw !…áÜ9xðpžî䩨RSÍ­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªeÄw—ºþ¢:þ‰·aRÿÕðš8ýÃEmÍÒb7mÎa9ÝÎÌçËr³É«Êw`iî=ðí0T™W;ƒkT·Õð±QJTþSøît _€Wƒj(î"ºº¹»åÃV6îÄU ú™ÇÂgcÇ“ã´î«Ò¾“rÚµ.á üN”•(4¥z² Ðæ1µÀîîR6#an£."ÿ‰{¯ê/×ôF^§êÇøMî<ðíç¡­»À!…¾D'pÚJr¼Ð)Ìx/ª¨ª÷G¸h­¹ºLFí¹Ì';¹ÙœàynVqù5c9Níò`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UYˆnæ6ï— XÛ»T3êgqœ9nOŽÓºrâ;ËÝQU_¢8Щú±þ˜[¸óöÙ•q¸2µºµáØNä%k IñWM«ÏCà…`âIî<ðíç¡­»À!…¾D'pÚJr¼Ð)Ìx/ª¨ªèvQsTRW:¸èQ (çà€yËǃ€ ÷w$mNÂ’˜.h•m ½# …'Á@áŸUÂŒ¤íîS.#¼½×õ×ôM» —þ¬„ÐÑÇî+nn“»ns Îîvg8[•œ~MXÎS»ÂÝÇž¶ÈD«Á•­Õ¯Âw!+XROŠºm^z+wzz¹»åÃV6îÄU ú™ÇÂgcÇ“ã´îò‹š¢’¹ÐÝćBˆaG8wÎ^<g»¹#jv–\Gy{¯ê'¯è‹ö?V?ÂsǸó÷ž†¶î7„:ùÃi( ÊðG@§1ྨ8¢«Ý~ᢶæé1¶ç0œîçfså¹YÇäÕŒå;·É‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Næ\Gy{¯ê ¿Dq¡Sõcü'(ÓÜ{áÚ`©2®wÖ©o«áb:¢”©ü§ñÜ迯ÔQÜEd=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ[Þ•ô›–Õ©woât¤©A¥+ÕAö‡1®7wr‘± u‘0\Ñ*Ú:zF Nÿ‚$€9Ã>«„ /IÛÜ*¨QÄw—ºþ¢g_¢nÿЩêÇøM ~ᢶæé1¶ç0œîçfså¹YÇäÕŒå;¼-ÜyáÛl„J¸ÜZÝZðì'rµ…$ø«¦Õç¡ðB°q'§¡»˜Û¾\5cnìEPÏ©œ|!Æpæ;Nì;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aIœ¸Žò÷_ÔG_Ñì*~¬„çqç‡o= mÜnt-ò!;†ÒP•àŽNcÁ}Pp=EWº8ýÃEmÍÒb7mÎa9ÝÎÌçËr³É«Êwo“Í­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªÌCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|v̸Žò÷_Ô~ˆãB§êÇøNanãÏÛd"UÆàÊÖêׇa;•¬)'Å]6¯=‚€;‰'¸ó÷ž†¶î7„:ùÃi( ÊðG@§1ྨ8¢«¡ÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UL¸Žò÷_ÔG_Ñ6ì*_ú±þCG¸h­¹ºLFí¹Ì';¹ÙœàynVqù5c9Nì =Ǿ¦ “*çpmj–ú¾#ª)JŸÊÎ+ð ðm@%ÄWWCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vÕzWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÔeÄ_ñ/uýEúþˆËØTýXÿ ¢=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ^èã÷ ·7IˆÝ·9„çw;3œ-ÊÎ?&¬g)ݾL4J¶…·ޑ…“¿à‰ pϪá ÆRv÷ «1 ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwN\Gy{¯ê*«ôG?V?Âs wxvÛ!®7V·V¼; Ü„­aI>*éµyè|¬ÜI=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ]Ê.jŠJçCw !…áÜ9xðpžî䩨RSÍ­¡s¡÷¤a@0¤ïø"Hœ3ê¸@Âñ”½ÂªeÄw—ºþ¢:þ‰·aRÿÕðš8ýÃEmÍÒb7mÎa9ÝÎÌçËr³É«Êwx[¸óöÙ•q¸2µºµáØNä%k IñWM«ÏCà…`âOOCw1·|¸jÆÝØŠ¡ŸS8øCŒáÌxãr|vØvQsTRW:¸èQ (çà€yËǃ€ ÷w$mN’ˈï/uýDõý~§êÇøNx÷xvóÐÖÝÆà‡Bß"¸m%9^èæ<ÕÔU{£Ü4VÜÝ&#vÜæÜìÎp<·+8üš±œ§vù0\Ñ*Ú:zF Nÿ‚$€9Ã>«„ /IÛÜ*¬Ä7swˆ¬m݈ªõ3„8ÎÇŽ7'ÇiÜˈï/uýAWèŽ4*~¬„å{|;L&UÎàÚÕ-õ|,GTR•?”þ;WààÚ€J;ˆ¬‡¸ó÷ž†¶î7„:ùÃi( ÊðG@§1ྨ8¢«{Ò¾“rÚµ.á üN”•(4¥z² Ðæ1µÀîîR6#an²& š%[BçCïH€aIßðD8gÕp…ã);{…U 8Žò÷_ÔLëôMßú/ýXÿ ¡£Ü4VÜÝ&#vÜæÜìÎp<·+8üš±œ§w…»<;m‰Wƒ+[«^„îBV°¤ŸtÚ¼ô>Vî$ôô7swˆ¬m݈ªõ3„8ÎÇŽ7'Çi݇e5E%s¡»‰…ÂŽpx8ÏwrFÔì)3—Þ^ëúˆëú"ý…OÕðœñî<ðíç¡­»À!…¾D'pÚJr¼Ð)Ìx/ª¨ª÷G¸h­¹ºLFí¹Ì';¹ÙœàynVqù5c9Níò`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UYˆnæ6ï— XÛ»T3êgqœ9nOŽÓ¹—Þ^ëú‚¯ÑhTýXÿ Ì-ÜyáÛl„J¸ÜZÝZðì'rµ…$ø«¦Õç¡ðB°q$÷xvóÐÖÝÆà‡Bß"¸m%9^èæ<ÕÔUt;(¹ª)+ ÜHt(†s‡p@<åãÁÀ{»’6§aIL4J¶…·ޑ…“¿à‰ pϪá ÆRv÷ ©—Þ^ëúˆëú&Ý…KÿV?Âhhã÷ ·7IˆÝ·9„çw;3œ-ÊÎ?&¬g)ݧ¸÷ôÁRe\î ­RßWÂÄuE)SùOã¹Ð%~^ ¨£¸Šêènæ6ï— XÛ»T3êgqœ9nOŽÓº¯JúMËjÔ»„7ñ:RT Ò•êÈ €{C˜Æ×»¹HØ…ºŒ¸‹þ%¿_Ñ{ Ÿ«á4G¸ó÷ž†¶î7„:ùÃi( ÊðG@§1ྨ8¢«Ý~ᢶæé1¶ç0œîçfså¹YÇäÕŒå;·É‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáUf!»˜Û¾\5cnìEPÏ©œ|!Æpæ;Néˈï/uýEU~ˆãB§êÇøNanãÏÛd"UÆàÊÖêׇa;•¬)'Å]6¯=‚€;‰'¸ó÷ž†¶î7„:ùÃi( ÊðG@§1ྨ8¢«¡ÙEÍQI\ènâC¡D0£œ;‚ç/3ÝÜ‘µ; J`¹¢U´.t>ôŒ(ÿIs†}W^2“·¸UL¸Žò÷_ÔG_Ñ6ì*_ú±þCG¸h­¹ºLFí¹Ì';¹ÙœàynVqù5c9Nï wxvÛ!®7V·V¼; Ü„­aI>*éµyè|¬ÜIéènæ6ï— XÛ»T3êgqœ9nOŽÓ»Ê.jŠJçCw !…áÜ9xðpžî䩨RYqåž¿¢/ØTýXÿ ÏãÏÞzÛ¸Üè[äBw ¤ '+ÁœÇ‚ú àzНtqû†ŠÛ›¤ÄnÛœÂs»™Î–åg“V3”îß& š%[BçCïH€aIßðD8gÕp…ã);{…U˜†îcnùpÕ»±C>¦qð‡ØñÆäøí;™qå*ýÆ…OÕðœ£Oqï‡i‚¤Ê¹ÜZ¥¾¯…ˆêŠR§òŸÇs Jü¼P Gq÷xvóÐÖÝÆà‡Bß"¸m%9^èæ<ÕÔUozWÒn[V¥Ü!¿‰Ò’¥”¯VAÚÆ6¸ÝÝÊFÄl-ÖDÁsD«h\è}éP );þ’ç ú®0¼e'opª¡GÞ^ëú‰~‰»ÿB¥ÿ«á44qû†ŠÛ›¤ÄnÛœÂs»™Î–åg“V3”îð·qç‡m²*ãpekukðÈJÖ“â®›Wž‡Á ÀÄžž†îcnùpÕ»±C>¦qð‡ØñÆäøí;°ì¢æ¨¤®t7q!ТQÎÁó—îîHÚ…&râ;ËÝQD_°©ú±þž=Çž¼ô5·q¸!зȄîI@NW‚:9õAÀõ^èã÷ ·7IˆÝ·9„çw;3œ-ÊÎ?&¬g)ݾL4J¶…·ޑ…“¿à‰ pϪá ÆRv÷ «1 ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚw2â;ËÝPUú# Ÿ«á9…»<;m‰Wƒ+[«^„îBV°¤ŸtÚ¼ô>Vî$žãÏÞzÛ¸Üè[äBw ¤ '+ÁœÇ‚ú àzŠ®‡e5E%s¡»‰…ÂŽpx8ÏwrFÔì))‚æ‰VйÐûÒ0 Rwü$Îõ\ axÊNÞáU2â;ËÝQDÛ°©êÇøM ~ᢶæé1¶ç0œîçfså¹YÇäÕŒå;°4÷øv˜*L«Áµª[êøXލ¥*)üw:¯À+Áµ”w]] ÜÆÝòá«wb*†}Lãá3‡1ãÉñÚwUé_I¹mZ—p†þ'JJ”R½YhsÚàww)°·Q—Ľ×õëú#/aSõcü&ˆ÷xvóÐÖÝÆà‡Bß"¸m%9^èæ<ÕÔU{£Ü4VÜÝ&#vÜæÜìÎp<·+8üš±œ§vù0\Ñ*Ú:zF Nÿ‚$€9Ã>«„ /IÛÜ*¬Ä7swˆ¬m݈ªõ3„8ÎÇŽ7'ÇiÝ9qåª¯ÑhTýXÿ Ëbqó‡±á,¿2æÞ·Ò¡¹¼¥K N2¥U};Àa#jN×byÄð⇋Rv°…íqÌ5Ð%H$‚¬t#¨ÈèJ¸¶&îå¹Í—%ÞsÉ 1–´…0zsÕÓ£7 e# ØRiìK}žCqM.Sˆµ%Ii‚¦Ô±ÊÊP’ PV02:稺SUó´ýŠß»1b§„’ŽÍ Gži)_ÙhFÜyüõkÜ)Ví~‰&ÝÙ>ðâV‡[^^ÛÐ6Óhœ´î=˜Uú‡«cò´Þ _£®±7G†7N•Ï߇ÕÑ'zñŒõ¼ÇAâ¯ËÊèc¥()JM=´4öÐJR€R” ?E¸=?MX¸¢îWùÈ,9kh.Lée„n%@ ÅiNpŸ È×ÚÇO«…Z®ý¢®69òí¶ç–܈S‘Ý„¤¤äx€ AÇPGJÔ´¯á¼>–Ò:ÇQØSͰ´ÜÈ2e$-)QR€PÎRpR¡àz¤#Tú³Pð‡Oðÿ£4f¨²+6·ÐË(˜…;!Ò“•(þ2Õõä+™cëšR•b§Í:IÏÕ:uw©ZãRCqËŒæCS 4Ú–óH|u+ÕB|Tzæ®ÂFr½o©Ô½«yÿþZ±àgàñ¥®¿ÿ±“T*°ÿ·&_=Åi?û~óþÜ紿벑êöÿCïާͬ« An‚òGnº§yù™GƒÐÏŽ²Ô‡ÿà[¿”¯äðjÞ|u~¢?ü5»ùJÔnÚãX—ìl÷MI&öFÎq‡im¥²RTˆ‡6J‚R;APø@Wµ*ÙÙ¼kYQ¬–—®3-¤jg-ÎIÜ'¥®(·½#áÉq”9¹ cÕJŠp¢“mš’ÿjòDu³ï3ÆõÂ?h³Í»Üµ•ý˜Pc¹&K½ŽÜ­¡%JV2N'_Û<ÓÒ]Ó:Âðó‘œ >”G¶(´²”¬%@Dî«J°|”[Å™——ô_"=¬†ÅŽÔaˆï17ä4©NºvâœSiåìHRCêÖÅxÔWÅ^.v†®ÞmÝVÅ¥©¡–Ê¡°«c2HN䔕)Ò¤°®®Ž‡Tõû«È޲\Ì#ÀëñÔ—³þ0­ŸÊU—…ë²4¦¬Ü@ÕÖÖÖ¢¥""`4N2HLQ× ýB¬xar¹Í{UB¹_èZï†y<¦Ðyb,e”«–J‚ÜXQÇŽz€7*²„bôD97½š4tôg¤q?\<äW ±Ö· ©L¬¡H*A1»ªÚµ§#®¡àM .‹šÔåñ?\*S-­¦Ÿ.A.! )+HWfÈJŠH Bsà+y¥^äg¸»÷ÊÆ¾úxËSÜ]ûåc_}ŒnmÙhB“‘‘U‘ЃVUϵwÿ´Mý²ÓîÚÍý³eÿ<ßÚ«w•ÍŒ‰0Ìi,/;\iÀ´« Šùóˆ¿÷ñÿ—WîWLûž?Úcÿ(}T²ûÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þ´íó>.ßëÿZšRÈÛæ|]¿×þµü¦ã)YÚËJÇŽþµU­?îÄïÿp~ð­MÿÞÈ£ÕÿÝ5¶Ž T£*·ÜyøŒ{£‰§C-óq¹»öùŸoõÿ­;|Ï‹·úÿÖ¦•ŠÈôíó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)díó>.ßëÿZvùŸoõÿ­M)d ½KWû|h3SmǸŸ ´°\Žèqç=ÒGQã*/°ÝL-ö”ÓŒ“µm,R|Rsžÿ…ZÒ«(Fk,–…g5–Jè »Zd] Fƒ6uÁÖb…AuNqç·¯‡LøV}ƒdµ3m…rš¼µeKQ9R”|É$Ÿª¬)Q0ƒºEaJwŠÔµ÷]xøœOÔ~Õ*ª•ÐèÿÙxymon-4.3.30/docs/manpages/0000775000076400007640000000000013534041774015736 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/manpages/man8/0000775000076400007640000000000013534041774016601 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/manpages/man8/xymonlaunch.8.html0000664000076400007640000000771413534041733022206 0ustar rpmbuildrpmbuild Manpage of XYMONLAUNCH

XYMONLAUNCH

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonlaunch - Master program to launch other Xymon programs

 

SYNOPSIS

xymonlaunch [options]

 

DESCRIPTION

xymonlaunch(8) is the main program that controls the execution and scheduling of all of the components in the Xymon system.

xymonlaunch allows the administrator to add, remove or change the set of Xymon applications and extensions without restarting Xymon - xymonlaunch will automatically notice any changes in the set of tasks, and change the scheduling of activities accordingly.

xymonlaunch also allows the administrator to setup specific logfiles for each component of the Xymon system, instead of getting output from all components logged to a single file.

 

OPTIONS

--env=FILENAME
Loads the environment from FILENAME before starting other tools. The environment defined by FILENAME is the default, it can be overridden by the ENVFILE option in tasks.cfg(5)

--config=FILENAME
This option defines the file that xymonlaunch scans for tasks it must launch. A description of this file is in tasks.cfg(5) If not specified, files at /etc/tasks.cfg, /etc/xymon/tasks.cfg, and /etc/xymon-client/clientlaunch.cfg are searched for, as well as ~/server/etc/tasks.cfg.

--log=FILENAME
Defines the logfile where xymonlaunch logs information about failures to launch tasks and other data about the operation of xymonlaunch. Logs from individual tasks are defined in the tasks.cfg file. By default this is logged to stdout.

--pidfile=FILENAME
Filename which xymonlaunch saves its own process-ID to. Commonly used by automated start/stop scripts.

--verbose
Logs the launch of all tasks to the logfile. Note that the logfile may become quite large if you enable this.

--dump
Just dump the contents of the tasks.cfg file after parsing it. Used for debugging.

--debug
Enable debugging output while running.

--no-daemon
xymonlaunch normally detaches from the controlling tty and runs as a background task. This option keeps it running in the foreground.

 

STARTING TASKS

xymonlaunch will read the configuration file and start all of the tasks listed there.

If a task completes abnormally (i.e. terminated by a signal or with a non-zero exit status), then xymonlaunch will attempt to restart it 5 times. If it still will not run, then the task is disabled for 10 minutes. This will be logged to the xymonlaunch logfile.

If the configuration file changes, xymonlaunch will re-read it and notice any changes. If a running task was removed from the configuration, then the task is stopped. If a new task was added, it will be started. If the command used for a task changed, or it was given a new environment definition file, or the logfile was changed, then the task is stopped and restarted with the new definition.

 

SEE ALSO

tasks.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
STARTING TASKS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_sample.8.html0000664000076400007640000000345213534041734022514 0ustar rpmbuildrpmbuild Manpage of XYMOND_SAMPLE

XYMOND_SAMPLE

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_sample - example of a xymond worker module  

SYNOPSIS

xymond_channel --channel=status xymond_sample [options]

 

DESCRIPTION

xymond_sample is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives messages from xymond via stdin, and simply displays these on stdout. It can be used with all types of xymond channels.

xymond_sample is not designed to actually run, except as a demonstration. The purpose of this tool is to show how xymond worker modules can be implemented to handle different tasks that need to hook into the xymond processing.

 

OPTIONS

--timeout=N
Read messages with a timeout of N seconds.

--debug
Enable debugging output.

 

SEE ALSO

xymond_channel(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/trimhistory.8.html0000664000076400007640000001060213534041733022224 0ustar rpmbuildrpmbuild Manpage of TRIMHISTORY

TRIMHISTORY

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

trimhistory - Remove old Xymon history-log entries  

SYNOPSIS

trimhistory --cutoff=TIME [options]

 

DESCRIPTION

The trimhistory tool is used to purge old entries from the Xymon history logs. These logfiles accumulate information about all status changes that have occurred for any given service, host, or the entire Xymon system, and is used to generate the event- and history-log webpages.

Purging old entries can be done while Xymon is running, since the tool takes care not to commit updates to a file if it changes mid-way through the operation. In that case, the update is aborted and the existing logfile is left untouched.

Optionally, this tool will also remove logfiles from hosts that are no longer defined in the Xymon hosts.cfg(5) file. As an extension, even logfiles from services can be removed, if the service no longer has a valid status-report logged in the current Xymon status.

 

OPTIONS

--cutoff=TIME
This defines the cutoff-time when processing the history logs. Entries dated before this time are discarded. TIME is specified as the number of seconds since the beginning of the Epoch. This is easily generated by the GNU date(1) utility, e.g. the following command will trim history logs of all entries prior to Oct. 1st 2004:


    trimhistory --cutoff=`date +%s --date="1 Oct 2004"`

--outdir=DIRECTORY
Normally, files in the XYMONHISTDIR directory are replaced. This option causes trimhistory to save the shortened history logfiles to another directory, so you can verify that the operation works as intended. The output directory must exist.

--drop
Causes trimhistory to delete files from hosts that are not listed in the hosts.cfg(5) file.

--dropsvcs
Causes trimhistory to delete files from services that are not currently tracked by Xymon. Normally these files would be left untouched if only the host exists.

--droplogs
Process the XYMONHISTLOGS directory also, and delete status-logs from events prior to the cut-off time. Note that this can dramatically increase the processing time, since there are often lots and lots of files to process.

--progress[=N]
This will cause trimhistory to output a status line for every N history logs or status-log collections it processes, to indicate how far it has progressed. The default setting for N is 100.

--env=FILENAME
Loads the environment from FILENAME before executing trimhistory.

--debug
Enable debugging output.

 

FILES

$XYMONHISTDIR/allevents
The eventlog of all events that have happened in Xymon.

$XYMONHISTDIR/HOSTNAME
The per-host eventlogs.

$XYMONHISTDIR/HOSTNAME.SERVICE
The per-service eventlogs.

$XYMONHISTLOGS/*/*
The historical status-logs.

 

ENVIRONMENT VARIABLES

XYMONHISTDIR
The directory holding all history logs.

XYMONHISTLOGS
The top-level directory for the historical status-log collections.

HOSTSCFG
The location of the hosts.cfg file, holding the list of currently known hosts in Xymon.

 

SEE ALSO

xymon(7), hosts.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_history.8.html0000664000076400007640000000764713534041733022745 0ustar rpmbuildrpmbuild Manpage of XYMOND_HISTORY

XYMOND_HISTORY

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_history - xymond worker module for logging status changes  

SYNOPSIS

xymond_channel --channel=stachg xymond_history [options]

 

DESCRIPTION

xymond_history is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives xymond status-change messages from the "stachg" channel via stdin, and uses these to update the history logfiles in a manner that is compatible with the standard Big Brother daemon, bbd.

 

OPTIONS

--histdir=DIRECTORY
The directory for the history files. If not specified, the directory given by the XYMONHISTDIR environment is used.

--histlogdir=DIRECTORY
The directory for the historical status-logs. If not specified, the directory given by the XYMONHISTLOGS environment is used.

--minimum-free=N
Sets the minimum percentage of free filesystem space on the $XYMONHISTLOGS directory. If there is less than N% free space, xymond_history will not save the detailed status-logs. Default: 5

--pidfile=FILENAME
xymond_history writes the process-ID it is running with to this file. This is for use in automated startup scripts. The default file is $XYMONSERVERLOGS/xymond_history.pid.

--debug
Enable debugging output.

 

ENVIRONMENT

XYMONALLHISTLOG
This environment variable controls if the $XYMONHISTDIR/allevents logfile is updated. This file is used by the event-log display on the nongreen html page and the eventlog-webpage, among other things. You can disable it by setting XYMONALLHISTLOGS=FALSE, but this is not recommended.

XYMONHOSTHISTLOG
This environment variable controls if the $XYMONHISTDIR/HOSTNAME logfile is updated. This file holds a list of all status changes seen for a single host, but is not used by any of the standard Xymon tools. If you do not want to save this, you can disable it by setting XYMONHOSTHISTLOG=FALSE.

SAVESTATUSLOG
This environment variable controls if the historical status-logs are saved whenever a status change occurs. These logfiles are stored in the $XYMONHISTLOGS directory, and are used for the detailed log-display of a status from the Xymon "History" page. If you do not want to save these, you can disable it by setting SAVESTATUSLOG=FALSE. If you want to save all except some specific logs, use SAVESTATUSLOG=TRUE,!TEST1[,!TEST2...] If you want to save none except some specific logs, use SAVESTATUSLOG=FALSE,TEST1[,TEST2...]
NOTE: Status logs will not be saved if there is less than 5% free space on the filesystem hosting the $XYMONHISTLOGS directory. The threshold can be tuned via the "--minimum-free" option.

 

FILES

This module does not rely on any configuration files.

 

SEE ALSO

xymond_channel(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_client.8.html0000664000076400007640000001261513534041733022511 0ustar rpmbuildrpmbuild Manpage of XYMOND_CLIENT

XYMOND_CLIENT

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_client - xymond worker module for client data  

SYNOPSIS

xymond_channel --channel=client xymond_client [options]

 

DESCRIPTION

xymond_client is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives xymond client messages sent from systems that have the the Xymon client installed, and use the client data to generate the Xymon status messages for the cpu-, disk-, memory- and procs-columns. It also feeds Xymon data messages with the netstat- and vmstat-data collected by the client.

When generating these status messages from the client data, xymond_client will use the configuration rules defined in the analysis.cfg(5) file to determine the color of each status message.

 

OPTIONS

--clear-color=COLOR
Define the color used when sending "msgs", "files" or "ports" reports and there are no rules to check for these statuses. The default is to show a "clear" status, but some people prefer to have it "green". If you would rather prefer not to see these status columns at all, then you can use the "--no-clear-msgs", "--no-clear-files" and "--no-clear-ports" options instead.

--no-clear-msgs
If there are no logfile checks, the "msgs" column will show a "clear" status. If you would rather avoid having a "msgs" column, this option causes xymond_client to not send in a clear "msgs" status.

--no-clear-files
If there are no file checks, the "files" column will show a "clear" status. If you would rather avoid having a "files" column, this option causes xymond_client to not send in a clear "files" status.

--no-clear-ports
If there are no port checks, the "ports" column will show a "clear" status. If you would rather avoid having a "ports" column, this option causes xymond_client to not send in a clear "ports" status.

--no-ps-listing
Normally the "procs" status message includes the full process-listing received from the client. If you prefer to just have the monitored processes shown, this option will turn off the full ps-listing.

--no-port-listing
Normally the "ports" status message includes the full netstat-listing received from the client. If you prefer to just have the monitored ports shown, this option will turn off the full netstat-listing.

--no-cpu-listing
Normally the "cpu" status message includes the full cpu-listing received from the client. If you prefer to just have the monitored cpu load shown, this option will turn off the full cpu-listing.

--uptime-status
Generate a separate "uptime" status column. The uptime is normally just reported in the "cpu" status column, but if you would like a separate status column for the uptime, you can use this option. It is useful if you want to generate an alert in case of a reboot, without having this alert mixed in with the cpu load alerts.

--config=FILENAME
Sets the filename for the analysis.cfg file. The default value is "etc/analysis.cfg" below the Xymon server directory.

--unknownclientosok
Expect and attempt to parse clients with unknown CLIENTOS types. Useful if you're submitting custom host responses with file or msgs data that you'd like to parse.

--dump-config
Dumps the configuration after parsing it. May be useful to track down problems with configuration file errors.

--test
Starts an interactive session where you can test the analysis.cfg configuration.

--collectors=COLLECTOR1[,COLLECTOR2,...]
Limit the set of collector modules that xymond_client will handle. This is not normally used except for running experimental versions of the program.

--debug
Enable debugging output.

 

FILES

~xymon/server/etc/analysis.cfg

 

BUGS

The "disk" status cannot handle filesystems containing whitespace in the filesystem (device) name.

 

SEE ALSO

analysis.cfg(5), xymond(8), xymond_channel(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
BUGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/enadis.cgi.8.html0000664000076400007640000000544013534041734021640 0ustar rpmbuildrpmbuild Manpage of ENADIS.CGI

ENADIS.CGI

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

enadis.cgi - CGI program to enable/disable Xymon tests  

SYNOPSIS

enadis.cgi (invoked via CGI from webserver)

 

DESCRIPTION

enadis.cgi is a CGI tool for disabling and enabling hosts and tests monitored by Xymon. You can disable monitoring of a single test, all tests for a host, or multiple hosts - immediately or at a future point in time.

enadis.cgi runs as a CGI program, invoked by your webserver. It is normally run via a wrapper shell-script in the secured CGI directory for Xymon.

enadis.cgi is the back-end script for the enable/disable form present on the "info" status-pages. It can also run in "stand-alone" mode, in which case it displays a web form allowing users to select what to enable or disable.

 

OPTIONS

--no-cookies
Normally, enadis.cgi uses a cookie sent by the browser to initially filter the list of hosts presented. If this is not desired, you can turn off this behaviour by calling acknowledge.cgi with the --no-cookies option. This would normally be placed in the CGI_ENADIS_OPTS setting in cgioptions.cfg(5)

--env=FILENAME
Load the environment from FILENAME before executing the CGI.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

 

FILES

$XYMONHOME/web/maint_{header,form,footer}
HTML template header

 

BUGS

When using alternate pagesets, hosts will only show up on the Enable/Disable page if this is accessed from the primary page in which they are defined. So if you have hosts on multiple pages, they will only be visible for disabling from their main page which is not what you would expect.

 

SEE ALSO

xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
BUGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_channel.8.html0000664000076400007640000001171313534041733022641 0ustar rpmbuildrpmbuild Manpage of XYMOND_CHANNEL

XYMOND_CHANNEL

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_channel - Feed a xymond channel to a worker module  

SYNOPSIS

xymond_channel --channel=CHANNEL [options] workerprogram [worker-options]

 

DESCRIPTION

xymond_channel hooks into one of the xymond(8) channels that provide information about events occurring in the Xymon system. It retrieves messages from the xymond daemon, and passes them on to the workerprogram on the STDIN (file descripter 1) of the worker program. Worker programs can then handle messages as they like.

A number of worker programs are shipped with xymond, e.g. xymond_filestore(8) xymond_history(8) xymond_alert(8) xymond_rrd(8)

If you want to write your own worker module, a sample worker module is provided as part of the xymond distribution in the xymond_sample.c file. This illustrates how to easily fetch and parse messages.

 

OPTIONS

xymond_channel accepts a few options.

--channel=CHANNELNAME
Specifies the channel to receive messages from, only one channel can be used. This option is required. The following channels are available:
"status" receives all Xymon status- and summary-messages
"stachg" receives information about status changes
"page" receives information about statuses triggering alerts
"data" receives all Xymon "data" messages
"notes" receives all Xymon "notes" messages
"enadis" receives information about hosts being disabled or enabled.

--filter=EXPRESSION
EXPRESSION is a Perl-compatible regular expression. xymond_channel will match the first line of each message against this expression, and silently drops any message that does not match the expression. Especially useful for custom worker modules and during testing, to limit the amount of data that the module must process.
Note that messages for "logrotate", "shutdown", "drophost", "renamehost", "droptest" and "renametest" are always forwarded by xymond_channel, whether they match the filter or not.

--msgtimeout=TIMEOUT
Modify the default timeout (30 seconds) for the worker module to handle a message. If a message is not handled within this time, it is considered lost. You normally do not have to modify this unless you have an extremely busy server.

--daemon
xymond_channel is normally started by xymonlaunch(8) as a task defined in the tasks.cfg(5) file. If you are not using xymonlaunch, then starting xymond_channel with this option causes it to run as a stand-alone background task.

--pidfile=FILENAME
If running as a stand-alone daemon, xymond_channel will save the process-ID of the daemon in FILENAME. This is useful for automated startup- and shutdown- scripts.

--env=FILENAME
Loads the environment variables defined in FILENAME before starting xymond_channel. This is normally used only when running as a stand-alone daemon; if xymond_channel is started by xymonlaunch, then the environment is controlled by the task definition in the tasks.cfg(5) file.

--log=FILENAME
Redirect output to this log-file.

--md5 / --no-md5
Enable/disable checksumming of messages passed from xymond_channel to the worker module. This may be useful if you suspect that data may be corrupted, e.g. when sent to a remote worker module. Note that enabling this may break communication with old versions of Xymon worker modules. Default: Disabled.

--debug
Enable debugging output.

 

FILES

This program does not use any configuration files.

 

SEE ALSO

xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_filestore.8.html0000664000076400007640000001065113534041733023225 0ustar rpmbuildrpmbuild Manpage of XYMOND_FILESTORE

XYMOND_FILESTORE

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_filestore - xymond worker module for storing Xymon data  

SYNOPSIS

xymond_channel --channel=status xymond_filestore --status [options]
xymond_channel --channel=data xymond_filestore --data [options]
xymond_channel --channel=notes xymond_filestore --notes [options]
xymond_channel --channel=enadis xymond_filestore --enadis [options]

 

DESCRIPTION

xymond_filestore is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives xymond messages from a xymond channel via stdin, and stores these in the filesystem in a manner that is compatible with the Big Brother daemon, bbd.

This program can be started multiple times, if you want to store messages for more than one channel.

 

OPTIONS

--status
Incoming messages are "status" messages, they will be stored in the $XYMONRAWSTATUSDIR/ directory. If you are using xymon(7) throughout your Xymon server, you will not need to run this module to save status messages, unless you have a third-party add-on that reads the status-logs directly. This module is NOT needed to get trend graphs, you should run the xymond_rrd(8) module instead.

--data
Incoming messages are "data" messages, they will be stored in the $XYMONDATADIR directory. This module is not needed, unless you have a third-party module that processes the data-files. This module is NOT needed to get trend graphs, you should run the xymond_rrd(8) module instead.

--notes
Incoming messages are "notes" messages, they will be stored in the $XYMONNOTESDIR directory. This modules is only needed if you want to allow people to remotely update the notes-files available on the Xymon webpages.

--enadis
Incoming messages are enable/disable messages, they will update files in the $XYMONDISABLEDDIR directory. This is only needed if you have third-party add-ons that use these files.

--dir=DIRECTORY
Overrides the default output directory.

--html
Used together with "--status". Tells xymond_filestore to also save an HTML version of the status-log. Should not be used unless you must run with "XYMONLOGSTATUS=static".

--htmldir=DIRECTORY
The directory where HTML-versions of the status logs are stored. Default: $XYMONHTMLSTATUSDIR

--htmlext=.EXT
Set the filename extension for generated HTML files. By default, HTML files are saved with a ".html" extension.

--multigraphs=TEST1[,TEST2]
This causes xymond_filestore to generate HTML status pages with links to service graphs that are split up into multiple images, with at most 5 graphs per image. If not specified, only the "disk" status is split up this way.

--only=test[,test,test]
Save status messages only for the listed set of tests. This can be useful if you have an external script that needs to parse some of the status logs, but you do not want to save all status logs.

--debug
Enable debugging output.

 

FILES

This module does not rely on any configuration files.

 

SEE ALSO

xymond_channel(8), xymond_rrd(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymonfetch.8.html0000664000076400007640000000726313534041734022025 0ustar rpmbuildrpmbuild Manpage of XYMONFETCH

XYMONFETCH

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonfetch - fetch client data from passive clients  

SYNOPSIS

xymonfetch [--server=XYMON.SERVER.IP] [options]

 

DESCRIPTION

This utility is used to collect data from Xymon clients.

Normally, Xymon clients will themselves take care of sending all of their data directly to the Xymon server. In that case, you do not need this utility at all. However, in some network setups clients may be prohibited from establishing a connection to an external server such as the Xymon server, due to firewall policies. In such a setup you can configure the client to store all of the client data locally by enabling the msgcache(8) utility on the client, and using xymonfetch on the Xymon server to collect data from the clients.

xymonfetch will only collect data from clients that have the pulldata tag listed in the hosts.cfg(5) file. The IP-address listed in the hosts.cfg file must be correct, since this is the IP-address where xymonfetch will attempt to contact the client. If the msgcache daemon is running on a non-standard IP-address or portnumber, you can specify the portnumber as in pulldata=192.168.1.2:8084 for contacting the msgcache daemon using IP 192.168.1.2 port 8084. If the IP-address is omitted, the default IP in the hosts.cfg file is used. If the port number is omitted, the portnumber from the XYMONDPORT setting in xymonserver.cfg(5) is used (normally, this is port 1984).

 

OPTIONS

--server=XYMON.SERVER.IP
Defines the IP address of the Xymon server where the collected client messages are forwarded to. By default, messages are sent to the loopback address 127.0.0.1, i.e. to a Xymon server running on the same host as xymonfetch.

--interval=N
Sets the interval (in seconds) between polls of a client. Default: 60 seconds.

--id=N
Used when you have a setup with multiple Xymon servers. In that case, you must run xymonfetch on each of the Xymon servers, with xymonfetch instance using a different value of N. This allows several Xymon servers to pick up data from the clients running msgcache, and msgcache can distinguish between which messages have already been forwarded to which server.
N is a number in the range 1-31.

--log-interval=N
Limit how often xymonfetch will log problems with fetching data from a host, in seconds. Default: 900 seconds (15 minutes). This is to prevent a host that is down or where msgcache has not been started from flooding the xymonfetch logs. Note that this is ignored when debugging is enabled.

--debug
Enable debugging output.

 

SEE ALSO

msgcache(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_rrd.8.html0000664000076400007640000005007713534041734022027 0ustar rpmbuildrpmbuild Manpage of XYMOND_RRD

XYMOND_RRD

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_rrd - xymond worker module for updating Xymon RRD files  

SYNOPSIS

xymond_channel --channel=status xymond_rrd [options]
xymond_channel --channel=data xymond_rrd [options]

 

DESCRIPTION

xymond_rrd is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives "status" and "data" messages from xymond via stdin, and updates the RRD databases used to generate trend-graphs.

Clients can send data to Xymon using both status- and data- messages. So you will normally run two instances of this module, once for the "status" channel and once for the "data" channel.

xymond_rrd understands data sent by the LARRD 0.43c client-side scripts (the so-called "bottom-feeder" scripts). So you still want to install the LARRD bottom-feeders on the clients you monitor.

Note: For certain types of data, the RRD files used by Xymon are imcompatible with those generated by the Big Brother LARRD add-on. See the COMPATIBILITY section below.

 

OPTIONS

--debug
Enable debugging output.

--rrddir=DIRECTORY
Defines the directory where the RRD-files are stored. xymond_rrd will use the location pointed to by the XYMONRRDS environment if this option is not present.

--no-cache
xymond_rrd by default caches updates to the RRD files, to reduce the disk I/O needed for storing the RRD data. Data is collected for a 30 minute period before being committed to disk in one update. This option disables caching of the data, so that data is stored on disk immediately.

--processor=FILENAME
xymond_rrd can send a parallel copy of all RRD updates to a single external process as a stream on its STDIN. The data will be in a format similar to that used by rrdupdate(1):         <rrdtemplate> ts:<rrdvalue(s)> host <rrdparameters>

If the process exits, xymond_rrd will re-launch it.

--extra-script=FILENAME
Defines the script that is run to get the RRD data for tests that are not built into xymond_rrd. You must also specify which tests are handled by the external script in the --extra-tests option. This option can only be given once, so the script must handle all of the external test-data. See the CUSTOM RRD DATA section below. Note that this is NOT needed if your custom graphs are generated by the NCV (Name Colon Value) module described below, it is only required for data where you have a custom script to parse the status message and extract the data that is put into the graph.

--extra-tests=TEST[,TEST]
List of testnames that are handled by the external script. See the CUSTOM RRD DATA section below. Note that NCV graphs should NOT be listed here, but in the TEST2RRD environment variable - see below.

--no-rrd
Disable the actual writing of RRD files. This is only really useful if you send all of the data destined for the RRD files to an external processor (the --extra-script or --processor options).

 

ENVIRONMENT

TEST2RRD
Defines the mapping between a status-log columnname and the corresponding RRD database format. This is normally defined in the xymonserver.cfg(5) file.

XYMONRRDS
Default directory where RRD files are stored.

NCV_testname
Defines the types of data collected by the "ncv" module in xymond_rrd. See below for more information.

SPLITNCV_testname
The same as NCV_testname, but keeps the data into separate files. That is, it creates one rrd file per "NAME : value" line found in the status message. It is useful when the list of NCV lines is varying.

TRACKMAX
Comma-separated list of columnname for which you want to keep the maximum values along with the default average values. This only works
 for the NCV backend.

 

COLLECTED DATA

The following RRD-file datasets are generated by xymond_rrd:

la
Records the CPU load average. Data is collected from the "cpu" status report. Requires that a Xymon client is running on the monitored server.

disk
Records the disk utilization. Data is collected from the "disk" status report. Requires that a Xymon-compatible client is running on the monitored server.

memory
Records memory- and swap-utilization. Data is collected from the "memory" status report. If no "memory" status is reported, it will use the data from the Win32 client "cpu" status report to generate this dataset. Requires that a Xymon-compatible client is running on the monitored server.

netstat
Records TCP and UDP statistics. Data is collected from the "netstat" status report; however, this data is often sent via the Xymon "data" protocol, so there need not be a "netstat" column visible on the Xymon display. To get these data, the LARRD netstat bottom-feeder script must be running on the monitored server.

vmstat
Records system performance metrics from the "vmstat" command. Data is collected from the "vmstat" status report; however, this data is often sent via the Xymon "data" protocol, so there need not be a "vmstat" column visible on the Xymon display. To get these data, the LARRD vmstat bottom-feeder script must be running on the monitored server.

tcp
Response-time metrics from all of the Xymon network tests are recorded in the "tcp" RRD.

apache
Apache server performance metrics, taken from the "apache" data report. See the description of the apache keyword in hosts.cfg(5) for details.

sendmail
Sendmail server performance metrics, taken from the "mailstats" output. To get these data, the LARRD sendmail bottom-feeder script must be running on the monitored server.

mailq
Mail queue size. To get these data, the LARRD nmailq bottom-feeder script must be running on the monitored server.

bea
BEA Weblogic performance data. This is an experimental set of data collected from BEA Weblogic servers via SNMP, by the "beastats" tool included with Xymon.

iishealth
IIS webserver performance data, collected by the "iishealth" script. This script is a client-side add-on available from the www.deadcat.net archive.

temperature
Temperature data, collected with the temperature script from www.deadcat.net. To get these data, the temperature script must be running on the monitored server.

ntpstat
Tracks the deviation between the local system time and an NTP server, using the output from the "ntpq -c rv" command. A simple script to collect these data is included in the Xymon contrib/ directory.

citrix
Tracks the number of active sessions on a Citrix server using the "query session" command. An extension for the BBNT client that generates data for this graph is in the Xymon contrib/ directory.

 

CUSTOM RRD DATA IN NAME-COLON-VALUE (NCV) FORMAT

Many data-collection scripts report data in the form "NAME : value" or "NAME = value". So a generic module in xymond_rrd allows for easy tracking of this type of data.

The "ncv" module will automatically detect all occurrences of a "NAME : value" or "NAME = value" string in a status message, and generate an RRD file holding all of the name/value data found in the message (unless you use SPLITNCV, see above). The colon- or equal-sign must be present - if there is only whitespace, this module will fail.

Only the valid letters (A-Z, a-z) and digits (0-9) are used in the dataset names; whitespace and other characters are stripped off automatically. Only the first 19 characters of a dataset name are used (this is an RRD limitation). Underscore '_' is not allowed, even though RRDtool permits this, and will be stripped from the name.

When using the alternative SPLITNCV_testname, the dataset name is not limited in length, and non-valid characters are changed to underscores instead of being stripped off. The dataset inside the resulting rrd file is always "lambda".

Note that each "NAME : value" must be on a line by itself. If you have a custom script generating the status- or data-message that is fed into the NCV handler, make sure it inserts a newline before each of the data-items you want to track.

Any lines in the status message prepended with a "<!-- ncv_skip -->" will be skipped by the module. This can be used to prevent unneeded RRD files from an existing dataset from being created.

A line prepended with a "<!-- ncv_skipstart -->" will be ignored, along with all subsequent lines until a line starting with "<!-- ncv_skipend -->" is found, at which point processing will resume. This can be used to ignore explanatory or other text with a mostly-ncv message.

"<!-- ncv_ignore -->" can be used to ignore certain text at the beginning of a line, up until a closing '</-->' tag on the same line, at which point the line will continue to be processed as usual. Wrapping is not supported; but skipstart/skipend can be used to handle multiple lines.

A bare "<!-- ncv_end -->" on its own line will stop further NCV processing of that message.

All of these ncv_ terms are case-sensitive. Note that if you have full control over your NCV output, it is most efficient to have NCV data near the top of your message and use "<!-- ncv_end -->" once your data is complete.

To enable the ncv module for a status, add a "COLUMNNAME=ncv" to the TEST2RRD setting and the COLUMNNAME to the GRAPHS setting in xymonserver.cfg(5) , then restart Xymon. Xymon will now send all status-messages for the column COLUMNNAME through the xymond_rrd ncv-handler.

The name of the RRD file will be COLUMNNAME.rrd. When using SPLITNCV, the name of the RRD file will be COLUMNAME,DATASETNAME.rrd.

By default, all of the datasets are generated as the RRD type "DERIVE" which works for all types of monotonically increasing counters. If you have data that are of the type GAUGE, you can override the default via an environment variable NCV_COLUMNNAME (or SPLITNCV_COLUMNAME).

E.g. if you are using the bb-mysqlstatus script from www.deadcat.net to collect data about your MySQL server, it generates a report in the column called "mysql". One data item is the average number of queries/second, which must be logged in the RRD file as type "GAUGE". To do that, add the following to xymonserver.cfg:

    NCV_mysql="Queriespersecondavg:GAUGE" 
If you have multiple datasets that you myst define, add them to the environment variable separated by commas, e.g.

    NCV_mysql="Uptime:NONE,Queriespersecondavg:GAUGE" 

The dataset type "NONE" used above causes xymond_rrd to ignore this data, it is not included in the RRD file.

You can use "*" as the dataset name to match all datasets not listed. E.g.

    NCV_weather="Rain:DERIVE,*:GAUGE"
will cause the "Rainfall" dataset to be of type DERIVE, and all others of type GAUGE. If you want to track only a few of the variables in your data, you can use "*:NONE" to drop any dataset not explicitly listed.

For a more detailed "how to" description, see the on-line HTML documentation of "How to create graph custom data" available in the Help menu section on your Xymon server.

 

SENDING METRIC DATA TO AN ADDITIONAL PROCESS

xymond_rrd provides a mechanism to send a copy of isolated metric data to a single external processor for further processing. This can be used to inject metric data that xymond_rrd has prepared into other storage systems, such as OpenTSDB, graphite, etc. The data is printed in a format nearly suitable for injection using rrdupdate(1) and easily transformable to other formats. If the process exits, xymond_rrd will re-launch it automatically.

 

CUSTOM RRD DATA VIA SCRIPTS

xymond_rrd provides a simple mechanism for adding custom graphs to the set of data collected on your Xymon server. By adding the "--extra-script" and "--extra-tests" options, data reported to Xymon from selected tests are passed to an external script, which can define the RRD data-sets to store in an RRD file.

NOTE: For performance reasons, you should not use this mechanism for large amounts of data. The overhead involved in storing the received message to disk and launching the script is significantly larger than the normal xymond_rrd overhead. So if you have a large number of reports for a given test, you should consider implementing it in C and including it in the xymond_rrd tool or writing a separate stream listener that injects appropriate "trends" data messages back to xymond.

Apart from writing the script, You must also add a section to graphs.cfg(5) so that showgraph.cgi(1) knows how to generate the graph from the data stored in the RRD file. To make the graphs actually show up on the status-page and/or the "trends" page, add the name of the new graph to the TEST2RRD and/or GRAPHS setting in xymonserver.cfg(5).

The script is invoked for each message that arrives, where the test-name matches one of the testnames given in the "--extra-tests" option. The script receives three command-line parameters:

Hostname
The name of the host reporting the data.
Testname
The name of the test being reported.
Filename
File containing the data that was reported. This file is generated for you by xymond_rrd, and is also deleted automatically after your script is finished with it.

The script must process the data that is reported, and generate the following output:

RRD data-set definitions
For each dataset that the RRD file holds, a line beginning with "DS:" must be output. If multiple data-sets are used, print one line for each dataset.
Data-set definitions are described in the rrdcreate(1) documentation, but a common definition for e.g. tracking the number of users logged on would be "DS:users:GAUGE:600:0:U". "users" is the name of the dataset, "GAUGE" is the datatype, "600" is the longest time allowed between updates for the data to be valid, "0" is the minimum value, and "U" is the maximum value (a "U" means "unknown").
RRD filename
The name of the RRD file where the data is stored. Note that Xymon stores all RRD files in host-specific directories, so unlike LARRD you should not include the hostname in the name of the RRD file.
RRD values
One line, with all of the data values collected by the script. Data-items are colon-delimited and must appear in the same sequence as your data-set definitions, e.g. if your RRD has two datasets with the values "5" and "0.4" respectively, then the script must output "5:0.4" as the RRD values.
In some cases it may be useful to define a dataset even though you will not always have data for it. In that case, use "U" (unknown) for the value.

If you want to store the data in multiple RRD files, the script can just print out more sequences of data-set definitions, RRD filenames and RRD values. If the data-set definitions are identical to the previous definition, you need not print the data-set definitions again - just print a new RRD filename and value.

The following sample script for tracking weather data shows how to use this mechanism. It assumes the status message include lines like these:

green Weather in Copenhagen is FAIR

Temperature: 21 degrees Celsius
Wind: 4 m/s
Humidity: 72 %
Rainfall: 5 mm since 6:00 AM

A shell-script to track all of these variables could be written like this:

#!/bin/sh

# Input parameters: Hostname, testname (column), and messagefile
HOSTNAME="$1"
TESTNAME="$2"
FNAME="$3"

if [ "$TESTNAME" = "weather" ]
then
        # Analyze the message we got
        TEMP=`grep "^Temperature:" $FNAME | awk '{print $2}'`
        WIND=`grep "^Wind:" $FNAME | awk '{print $2}'`
        HMTY=`grep "^Humidity:" $FNAME | awk '{print $2}'`
        RAIN=`grep "^Rainfall:" $FNAME | awk '{print $2}'`

        # The RRD dataset definitions
        echo "DS:temperature:GAUGE:600:-30:50"
        echo "DS:wind:GAUGE:600:0:U"
        echo "DS:humidity:GAUGE:600:0:100"
        echo "DS:rainfall:DERIVE:600:0:100"

        # The filename
        echo "weather.rrd"

        # The data
        echo "$TEMP:$WIND:$HMTY:$RAIN"
fi

exit 0

 

COMPATIBILITY

Some of the RRD files generated by xymond_rrd are incompatible with the files generated by the Big Brother LARRD add-on:

vmstat
The vmstat files with data from Linux based systems are incompatible due to the addition of a number of new data-items that LARRD 0.43 do not collect, but xymond_rrd does. This is due to changes in the output from the Linux vmstat command, and changes in the way e.g. system load metrics are reported.

netstat
All netstat files from LARRD 0.43 are incompatible with xymond_rrd. The netstat data collected by LARRD is quite confusing: For some types of systems LARRD collects packet-counts, for others it collects byte- counts. xymond_rrd uses a different RRD file-format with separate counters for packets and bytes and tracks whatever data the system is reporting.

 

SEE ALSO

xymond_channel(8), xymond(8), xymonserver.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT
COLLECTED DATA
CUSTOM RRD DATA IN NAME-COLON-VALUE (NCV) FORMAT
SENDING METRIC DATA TO AN ADDITIONAL PROCESS
CUSTOM RRD DATA VIA SCRIPTS
COMPATIBILITY
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_distribute.8.html0000664000076400007640000000422613534041733023410 0ustar rpmbuildrpmbuild Manpage of XYMOND_DISTRIBUTE

XYMOND_DISTRIBUTE

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_distribute - xymond worker module for distributing commands  

SYNOPSIS

xymond_channel --channel=enadis xymond_distribute [options]

 

DESCRIPTION

xymond_distribute is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It is used if you have multiple Xymon servers running in a master/slave configuration. xymond_distribute runs on the master server and receives "drop", "rename", "enable" and "disable" messages from xymond. xymond_distribute then forwards these to the other Xymon servers as standard xymon messages. So if a user on the master Xymon server disables a red status, xymond_distribute will forward this to the other Xymon servers so that the change happens everywhere.

NOTE: xymond_distribute does not check to see if a message has already been forwarded, so you can easily create forwarding loops.

 

OPTIONS

--peer=HOSTNAME
The peer that messages are forwarded to. If you have multiple peers, repeat this option.

--debug
Enable debugging output.

 

SEE ALSO

xymond_channel(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_alert.8.html0000664000076400007640000001505513534041733022343 0ustar rpmbuildrpmbuild Manpage of XYMOND_ALERT

XYMOND_ALERT

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_alert - xymond worker module for sending out alerts  

SYNOPSIS

xymond_channel --channel=page xymond_alert [options]

 

DESCRIPTION

xymond_alert is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives xymond page- and ack-messages from the "page" channel via stdin, and uses these to send out alerts about failed and recovered hosts and services.

The operation of this module is controlled by the alerts.cfg(5) file. This file holds the definition of rules and recipients, that determine who gets alerts, how often, for what servers etc.

 

OPTIONS

--config=FILENAME
Sets the filename for the alerts.cfg file. The default value is "etc/alerts.cfg" below the Xymon server directory.

--dump-config
Dumps the configuration after parsing it. May be useful to track down problems with configuration file errors.

--checkpoint-file=FILENAME
File where the current state of the xymond_alert module is saved. When starting up, xymond_alert will also read this file to restore the previous state.

--checkpoint-interval=N
Defines how often (in seconds) the checkpoint-file is saved.

--cfid
If this option is present, alert messages will include a line with "cfid:N" where N is the linenumber in the alerts.cfg file that caused this message to be sent. This can be useful to track down problems with duplicate alerts.

--test HOST SERVICE [options]
Shows which alert rules matches the given HOST/SERVICE combination. Useful to debug configuration problems, and see what rules are used for an alert.

The possible options are:
--color=COLORNAME The COLORNAME parameter is the color of the alert: red, yellow or purple.
--duration=MINUTES The MINUTES parameter is the duration of the alert in minutes.
--group=GROUPNAME The GROUPNAME parameter is a groupid string from the analysis.cfg file.
--time=TIMESTRING The TIMESTRING parameter is the time-of-day for the alert, expressed as an absolute time in the epoch format (seconds since Jan 1 1970). This is easily obtained with the GNU date utility using the "+%s" output format.

--trace=FILENAME
Send trace output to FILENAME, This allows for more detailed analysis of how alerts trigger, without having the full debugging enabled.

--debug
Enable debugging output.

 

HOW XYMON DECIDES WHEN TO SEND ALERTS

The xymond_alert module is responsible for sending out all alerts. When a status first goes to one of the ALERTCOLORS, xymond_alert is notified of this change. It notes that the status is now in an alert state, and records the timestamp when this event started, and adds the alert to the list statuses that may potentially trigger one or more alert messages.

This list is then matched against the alerts.cfg configuration. This happens at least once a minute, but may happen more often. E.g. when status first goes into an alert state, this will always trigger the matching to happen.

When scanning the configuration, xymond_alert looks at all of the configuration rules. It also checks the DURATION setting against how long time has elapsed since the event started - i.e. against the timestamp logged when xymond_alert first heard of this event.

When an alert recipient is found, the alert is sent and it is recorded when this recipient is due for his next alert message, based on the REPEAT setting defined for this recipient. The next time xymond_alert scans the configuration for what alerts to send, it will still find this recipient because all of the configuration rules are fulfilled, but an alert message will not be generated until the repeat interval has elapsed.

It can happen that a status first goes yellow and triggers an alert, and later it goes red - e.g. a disk filling up. In that case, xymond_alert clears the internal timer for when the next (repeat) alert is due for all recipients. You generally want to be told when something that has been in a warning state becomes critical, so in that case the REPEAT setting is ignored and the alert is sent. This only happens the first time such a change occurs - if the status switches between yellow and red multiple times, only the first transition from yellow->red causes this override.

When an status recovers, a recovery message may be sent - depending on the configuration - and then xymond_alert forgets everything about this status. So the next time it goes into an alert state, the entire process starts all over again.

 

ENVIRONMENT

MAIL
The first part of a command line used to send out an e-mail with a subject, typically set to "/usr/bin/mail -s" . xymond_alert will add the subject and the mail recipients to form the command line used for sending out email alerts.

MAILC
The first part of a command line used to send out an e-mail without a subject. Typically this will be "/usr/bin/mail". xymond_alert will add the mail recipients to form the command line used for sending out email alerts.

 

FILES

~xymon/server/etc/alerts.cfg

 

SEE ALSO

alerts.cfg(5), xymond(8), xymond_channel(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
HOW XYMON DECIDES WHEN TO SEND ALERTS
ENVIRONMENT
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_capture.8.html0000664000076400007640000000566313534041733022703 0ustar rpmbuildrpmbuild Manpage of XYMOND_CAPTURE

XYMOND_CAPTURE

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_capture - catch selected messages from a xymond channel  

SYNOPSIS

xymond_channel --channel=status xymond_capture [options]

 

DESCRIPTION

xymond_capture is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. It receives messages from xymond via stdin and filters them to select messages based on the hostname, testname or color of the status. By default the resulting messages are printed on stdout, but they can also be fed into a command for further processing.

xymond_capture supports the status, data, client and hostdata channels.

 

OPTIONS

--hosts=PATTERN
Select messages only from hosts matching PATTERN (regular expression).

--exhosts=PATTERN
Exclude messages from hosts matching PATTERN. If used with the --hosts option, then the hostname must match the --hosts pattern, but NOT the --exhosts pattern.

--tests=PATTERN
Select messages only from tests matching PATTERN (regular expression).

--extests=PATTERN
Exclude messages from tests matching PATTERN. If used with the --tests option, then the testname must match the --tests pattern, but NOT the --extests pattern.

--colors=COLOR[,color]
Select messages based on the color of the status message. Multiple colors can be listed, separated by comma. Default: Accept all colors.

--batch-command=COMMAND
Instead of printing the messages to stdout, feed them to COMMAND on stdin. COMMAND can be any command which accepts the mssage on standard input.

--batch-timeout=SECONDS
Collect messages until no messages have arrived in SECONDS seconds, before sending them to the --batch-command COMMAND.

--client
Capture data from the "client" channel instead of the default "status" channel.

--debug
Enable debugging output.

 

SEE ALSO

xymond_channel(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/msgcache.8.html0000664000076400007640000000745213534041733021412 0ustar rpmbuildrpmbuild Manpage of MSGCACHE

MSGCACHE

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

msgcache - Cache client messages for later pickup by xymonfetch

 

SYNOPSIS

msgcache [options]

 

DESCRIPTION

msgcache implements a Xymon message cache. It is intended for use with clients which cannot deliver their data to the Xymon server in the normal way. Instead of having the client tools connect to the Xymon server, msgcache runs locally and the client tools then deliver their data to the msgcache daemon. The msgcache daemon is then polled regularly by the xymonfetch(8) utility, which collects the client messages stored by msgcache and forwards them to the Xymon server.

NOTE: When using msgcache, the XYMSRV setting for the clients should be XYMSRV=127.0.0.1 instead of pointing at the real Xymon server.

 

RESTRICTIONS

Clients delivering their data to msgcache instead of the real Xymon server will in general not notice this. Specifically, the client configuration data provided by the Xymon server when a client delivers its data is forwarded through the xymonfetch / msgcache chain, so the normal centralized client configuration works.

However, other commands which rely on clients communicating directly with the Xymon server will not work. This includes the config and query commands which clients may use to fetch configuration files and query the Xymon server for a current status.

The download command also does not work with msgcache. This means that the automatic client update facility will not work for clients communicating via msgcache.

 

OPTIONS

--listen=IPADDRESS[:PORT]
Defines the IP-address and portnumber where msgcache listens for incoming connections. By default, msgcache listens for connections on all network interfaces, port 1984.

--server=IPADDRESS[,IPADDRESS]
Restricts which servers are allowed to pick up the cached messages. By default anyone can contact the msgcache utility and request all of the cached messages. This option allows only the listed servers to request the cached messages.

--max-age=N
Defines how long cached messages are kept. If the message has not been picked up with N seconds after being delivered to msgcache, it is silently discarded. Default: N=600 seconds (10 minutes).

--daemon
Run as a daemon, i.e. msgcache will detach from the terminal and run as a background task

--no-daemon
Run as a foreground task. This option must be used when msgcache is started by xymonlaunch(8) which is the normal way of running msgcache.

--pidfile=FILENAME
Store the process ID of the msgcache task in FILENAME.

--logfile=FILENAME
Log msgcache output to FILENAME.

--debug
Enable debugging output.

 

SEE ALSO

xymonfetch(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
RESTRICTIONS
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymon-mailack.8.html0000664000076400007640000000667513534041733022417 0ustar rpmbuildrpmbuild Manpage of XYMON\-MAILACK

XYMON\-MAILACK

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymon-mailack - permit acknowledging alerts via e-mail  

SYNOPSIS

xymon-mailack --env=FILENAME [--debug]

 

DESCRIPTION

xymon-mailack normally runs as an input mail-filter for the xymon user, e.g. by being called from the xymon users' procmailrc(5) file. xymon-mailack recognizes e-mails that are replies to xymond_alert(8) mail alerts, and converts the reply mail into an acknowledge message that is sent to the Xymon system. This permits an administrator to acknowledge an alert via e-mail.

 

ADDING INFORMATION TO THE REPLY MAIL

By default, an acknowledgment is valid for 1 hour. If you know in advance that solving the problem is going to take longer, you can change this by adding delay=DURATION to the subject of your mail reply or on a line in the reply message. Duration is in minutes, unless you add a trailing 'h' (for 'hours'), 'd' (for 'days') or 'w' (for 'weeks').

You can also include a message that will show up on the status-page together with the acknowledgment, e.g. to provide an explanation for the issue or some other information to the users. You can either put it at the end of the subject line as msg=Some random text, or you can just enter it in the e-mail as the first non-blank line of text in the mail (a "delay=N" line is ignored when looking for the message text).

 

USE WITH PROCMAIL

To setup xymon-mailack, create a .procmailrc file in the xymon-users home-directory with the following contents:
DEFAULT=$HOME/Mailbox
LOGFILE=$HOME/procmail.log
:0
| $HOME/server/bin/xymon-mailack --env=$HOME/server/etc/xymonserver.cfg

 

USE WITH QMAIL

If you are using Qmail to deliver mail locally, you can run xymon-mailack directly from a .qmail file. Setup the xymon-users .qmail file like this:
| $HOME/server/bin/xymon-mailack --env=$HOME/server/etc/xymonserver.cfg

 

OPTIONS

--env=FILENAME
Load environment from FILENAME, usually xymonserver.cfg.

--debug
Don't send a message to xymond, but dump the message to stdout.

 

SEE ALSO

xymond_alert(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
ADDING INFORMATION TO THE REPLY MAIL
USE WITH PROCMAIL
USE WITH QMAIL
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond_hostdata.8.html0000664000076400007640000000460213534041734023040 0ustar rpmbuildrpmbuild Manpage of XYMOND_HOSTDATA

XYMOND_HOSTDATA

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond_hostdata - xymond worker module for storing historical client data  

SYNOPSIS

xymond_channel --channel=clichg xymond_hostdata

 

DESCRIPTION

xymond_hostdata is a worker module for xymond, and as such it is normally run via the xymond_channel(8) program. Whenever a status column in Xymon changes to an alert state (usually red, yellow or purple), this module receives a copy of the latest Xymon client data sent by the host, and stores it on disk. This allows you to review all of the data collected by the Xymon client on the server around the time that a problem occurred. This can make troubleshooting incidents easier by providing a snapshot of the host status shortly before a problem became apparent.

Note: This module requires that xymond(8) is launched with the "--store-clientlogs" option enabled.

 

OPTIONS

--minimum-free=N
Sets the minimum percentage of free filesystem space on the $CLIENTLOGS directory. If there is less than N% free space, xymond_hostdata will not save the data. Default: 5

--debug
Enable debugging output.

 

FILES

All of the host data are stored in the $CLIENTLOGS directory, by default this is the $XYMONVAR/hostdata/ directory.

 

SEE ALSO

xymond(8), xymond_channel(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymoncgimsg.cgi.8.html0000664000076400007640000000512613534041733022741 0ustar rpmbuildrpmbuild Manpage of XYMONCGIMSG.CGI

XYMONCGIMSG.CGI

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents

 

NAME

xymoncgimsg.cgi - CGI utility used for proxying Xymon data over HTTP  

SYNOPSIS

xymoncgimsg.cgi

 

DESCRIPTION

xymoncgimsg.cgi(8) is the server-side utility receiving Xymon messages sent by the xymon(1) utility over an HTTP transport. The xymon utility normally sends data over a dedicated TCP protocol, but it may use HTTP to go through proxies or through restrictive firewalls. In that case, the webserver must have this CGI utility installed, which takes care of receiving the message via HTTP, and forwards it to a local Xymon server through the normal Xymon transport.

The CGI expects to be invoked from an HTTP "POST" request, with the POST-data being the status-message. xymoncgimsg.cgi simply collects all of the POST data, and send it off as a message to the Xymon daemon running on IP 127.0.0.1. This destination IP currently cannot be changed.

The CGI will return any output provided by the Xymon daemon back to the requestor as the response to the HTTP POST, so this allows for all normal Xymon commands to work.

 

SECURITY

xymoncgimsg.cgi will only send data to a Xymon server through the loopback interface, i.e. IP-address 127.0.0.1.

Access to the CGI should be restricted through webserver access controls, since the CGI provides no authentication at all to validate incoming messages.

If possible, consider using the xymonproxy(8) utility instead for native proxying of Xymon data between networks.

 

SEE ALSO

xymon(1), xymonproxy(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
SECURITY
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymond.8.html0000664000076400007640000004147213534041733021156 0ustar rpmbuildrpmbuild Manpage of XYMOND

XYMOND

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymond - Master network daemon for a Xymon server  

SYNOPSIS

xymond [options]

 

DESCRIPTION

xymond is the core daemon in the Xymon Monitor. It is designed to handle monitoring of a large number of hosts, with a strong focus on being a high-speed, low-overhead implementation of a Big Brother compatible server.

To achieve this, xymond stores all information about the state of the monitored systems in memory, instead of storing it in the host filesystem. A number of plug-ins can be enabled to enhance the basic operation; e.g. a set of plugins are provided to implement persistent storage in a way that is compatible with the Big Brother daemon. However, even with these plugins enabled, xymond still performs much faster than the standard bbd daemon.

xymond is normally started and controlled by the xymonlaunch(8) tool, and the command used to invoke xymond should therefore be in the tasks.cfg file.

 

OPTIONS

--hosts=FILENAME
Specifies the path to the Xymon hosts.cfg file. This is used to check if incoming status messages refer to known hosts; depending on the "--ghosts" option, messages for unknown hosts may be dropped. If this option is omitted, the default path used is set by the HOSTSCFG environment variable.

--checkpoint-file=FILENAME
With regular intervals, xymond will dump all of its internal state to this check-point file. It is also dumped when xymond terminates, or when it receives a SIGUSR1 signal.

--checkpoint-interval=N
Specifies the interval (in seconds) between dumps to the check-point file. The default is 900 seconds (15 minutes).

--restart=FILENAME
Specifies an existing file containing a previously generated xymond checkpoint. When starting up, xymond will restore its internal state from the information in this file. You can use the same filename for "--checkpoint-file" and "--restart".

--ghosts={allow|drop|log|match}
How to handle status messages from unknown hosts. The "allow" setting accepts all status messages, regardless of whether the host is known in the hosts.cfg file or not. "drop" silently ignores reports from unknown hosts. "log" works like drop, but logs the event in the xymond output file. "match" will try to match the name of the unknown host reporting with the known names by ignoring any domain-names - if a match is found, then a temporary client alias is automatically generated. The default is "log".

--no-purple
Prevent status messages from going purple when they are no longer valid. Unlike the standard bbd daemon, purple-handling is done by xymond.

--merge-clientlocal
The client-local.cfg(5) file contains client-configuration which can be found matching a client against its hostname, its classname, or the name of the OS the client is running. By default xymond will return one entry from the file to the client, looking for a hostname, classname or OS match (in that order). This option causes xymond to merge all matching entries together into one and return all of it to the client.

--listen=IP[:PORT]
Specifies the IP-address and port where xymond will listen for incoming connections. By default, xymond listens on IP 0.0.0.0 (i.e. all IP- addresses available on the host) and port 1984.

--lqueue=NUMBER
Specifies the listen-queue for incoming connections. You don't need to tune this unless you have a very busy xymond daemon.

--no-bfq
Tells xymond to NOT use the local messagequeue interface for receiving status- updates from xymond_client and xymonnet.

--daemon
xymond is normally started by xymonlaunch(8). If you do not want to use xymonlaunch, you can start xymond with this option; it will then detach from the terminal and continue running as a background task.

--timeout=N
Set the timeout used for incoming connections. If a status has not been received more than N seconds after the connection was accepted, then the connection is dropped and any status message is discarded. Default: 10 seconds.

--flap-count=N
Track the N latest status-changes for flap-detection. See the --flap-seconds option also. To disable flap-checks globally, set N to zero. To disable for a specific host, you must use the "noflap" option in hosts.cfg(5). Default: 5

--flap-seconds=N
If a status changes more than flap-count times in N seconds or less, then it is considered to be flapping. In that case, the status is locked at the most severe level until the flapping stops. The history information is not updated after the flapping is detected. NOTE: If this is set higher than the default value, you should also use the --flap-count option to ensure that enough status-changes are stored for flap detection to work. The flap-count setting should be at least (N/300)-1, e.g. if you set flap-seconds to 3600 (1 hour), then flap-count should be at least (3600/300)-1, i.e. 11. Default: 1800 seconds (30 minutes).

--delay-red=N
--delay-yellow=N
Sets the delay before a red/yellow status causes a change in the web page display. Is usually controlled on a per-host basis via the delayred and delayyellow settings in hosts.cfg(5) but these options allow you to set a default value for the delays. The value N is in minutes. Default: 0 minutes (no delay). Note: Since most tests only execute once every 5 minutes, it will usually not make sense to set N to anything but a multiple of 5.

--env=FILENAME
Loads the content of FILENAME as environment settings before starting xymond. This is mostly used when running as a stand-alone daemon; if xymond is started by xymonlaunch, the environment settings are controlled by the xymonlaunch tasks.cfg file.

--pidfile=FILENAME
xymond writes the process-ID it is running with to this file. This is for use in automated startup scripts. The default file is $XYMONSERVERLOGS/xymond.pid.

--log=FILENAME
Redirect all output from xymond to FILENAME.

--store-clientlogs[=[!]COLUMN]
Determines which status columns can cause a client message to be broadcast to the CLICHG channel. By default, no client messages are pushed to the CLICHG channel. If this option is specified with no parameter list, all status columns that go into an alert state will trigger the client data to be sent to the CLICHG channel. If a parameter list is added to this option, only those status columns listed in the list will cause the client data to be sent to the CLICHG channel. Several column names can be listed, separated by commas. If all columns are given as "!COLUMNNAME", then all status columns except those listed will cause the client data to be sent.

--status-senders=IP[/MASK][,IP/MASK]
Controls which hosts may send "status", "combo", "config" and "query" commands to xymond.

By default, any host can send status-updates. If this option is used, then status-updates are accepted only if they are sent by one of the IP-addresses listed here, or if they are sent from the IP-address of the host that the updates pertains to (this is to allow Xymon clients to send in their own status updates, without having to list all clients here). So typically you will need to list your servers running network tests here.

The format of this option is a list of IP-addresses, optionally with a network mask in the form of the number of bits. E.g. if you want to accept status-updates from the host 172.16.10.2, you would use

    --status-senders=172.16.10.2
whereas if you want to accept status updates from both 172.16.10.2 and from all of the hosts on the 10.0.2.* network (a 24-bit IP network), you would use

    --status-senders=172.16.10.2,10.0.2.0/24

--maint-senders=IP[/MASK][,IP/MASK]
Controls which hosts may send maintenance commands to xymond. Maintenance commands are the "enable", "disable", "ack" and "notes" commands. Format of this option is as for the --status-senders option. It is strongly recommended that you use this to restrict access to these commands, so that monitoring of a host cannot be disabled by a rogue user - e.g. to hide a system compromise from the monitoring system.

Note: If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses.

--www-senders=IP[/MASK][,IP/MASK]
Controls which hosts may send commands to retrieve the state of xymond. These are the "xymondlog", "xymondboard" and "xymondxboard" commands, which are used by xymongen(1) and combostatus(1) to retrieve the state of the Xymon system so they can generate the Xymon webpages.

Note: If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses.

--admin-senders=IP[/MASK][,IP/MASK]
Controls which hosts may send administrative commands to xymond. These commands are the "drop" and "rename" commands. Access to these should be restricted, since they provide an un-authenticated means of completely disabling monitoring of a host, and can be used to remove all traces of e.g. a system compromise from the Xymon monitor.

Note: If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses.

--no-download
Disable the "download" command which can be used by clients to pull files from the Xymon server. The use of these may be seen as a security risk since they allow file downloads.

--ack-each-color
By default, sending an ACK for a yellow status stops alerts from being sent while the status remains yellow or red. A status change from yellow to red will not re-enable alerts - the ACK covers all non-green statuses. With this option, an ACK is valid only for the color of the status when the ACK was sent. So an ACK for a yellow status is ignored if the status later changes to red, but an ACK for a red status covers both yellow and red.
Note: An ACK for a red status will clear any existing yellow acks. This means that a long-lived ack for yellow is lost when you send a short-lived ack for red. Hence alerts will restart when the red ack expires, even if the status by then has changed to yellow.

--ack-log=FILENAME
Log acknowledgements created on the Critical Systems page to FILENAME. NB, acknowledgements created by the Acknowledge Alert CGI are automatically written to acknowledge.log in the Xymon server log directory. Alerts from the Critical Systems page can be directed to the same log.

--debug
Enable debugging output.

--dbghost=HOSTNAME
For troubleshooting problems with a specific host, it may be useful to track the exact communications from a single host. This option causes xymond to dump all traffic from a single host to the file "/tmp/xymond.dbg".

 

HOW ALERTS TRIGGER

When a status arrives, xymond matches the old and new color against the "alert" colors (from the "ALERTCOLORS" setting) and the "OK" colors (from the "OKCOLORS" setting). The old and new color falls into one of three categories:

OK: The color is one of the "OK" colors (e.g. "green").

ALERT: The color is one of the "alert" colors (e.g. "red").

UNDECIDED: The color is neither an "alert" color nor an "OK" color (e.g. "yellow").

If the new status shows an ALERT state, then a message to the xymond_alert(8) module is triggered. This may be a repeat of a previous alert, but xymond_alert(8) will handle that internally, and only send alert messages with the interval configured in alerts.cfg(5).

If the status goes from a not-OK state (ALERT or UNDECIDED) to OK, and there is a record of having been in a ALERT state previously, then a recovery message is triggered.

The use of the OK, ALERT and UNDECIDED states make it possible to avoid being flooded with alerts when a status flip-flops between e.g yellow and red, or green and yellow.

 

CHANNELS

A lot of functionality in the Xymon server is delegated to "worker modules" that are fed various events from xymond via a "channel". Programs access a channel using IPC mechanisms - specifically, shared memory and semaphores - or by using an instance of the xymond_channel(8) intermediate program. xymond_channel enables access to a channel via a simple file I/O interface.

A skeleton program for hooking into a xymond channel is provided as part of Xymon in the xymond_sample(8) program.

The following channels are provided by xymond:

status This channel is fed the contents of all incoming "status" and "summary" messages.

stachg This channel is fed information about tests that change status, i.e. the color of the status-log changes.

page This channel is fed information about tests where the color changes between an alert color and a non-alert color. It also receives information about "ack" messages.

data This channel is fed information about all "data" messages.

notes This channel is fed information about all "notes" messages.

enadis This channel is fed information about hosts or tests that are being disabled or enabled.

client This channel is fed the contents of the client messages sent by Xymon clients installed on the monitored servers.

clichg This channel is fed the contents of a host client messages, whenever a status for that host goes red, yellow or purple.

Information about the data stream passed on these channels is in the Xymon source-tree, see the "xymond/new-daemon.txt" file.

 

SIGNALS

SIGHUP
Re-read the hosts.cfg configuration file.

SIGUSR1
Force an immediate dump of the checkpoint file.

 

BUGS

Timeout of incoming connections are not strictly enforced. The check for a timeout only triggers during the normal network handling loop, so a connection that should timeout after N seconds may persist until some activity happens on another (unrelated) connection.

 

FILES

If ghost-handling is enabled via the "--ghosts" option, the hosts.cfg file is read to determine the names of all known hosts.

 

SEE ALSO

xymon(7), xymonserver.cfg(5).


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
HOW ALERTS TRIGGER
CHANNELS
SIGNALS
BUGS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man8/xymonproxy.8.html0000664000076400007640000002253713534041733022115 0ustar rpmbuildrpmbuild Manpage of XYMONPROXY

XYMONPROXY

Section: Maintenance Commands (8)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents

 

NAME

xymonproxy - Xymon message proxy  

SYNOPSIS

xymonproxy [options] --server=$XYMSRV

 

DESCRIPTION

xymonproxy(8) is a proxy for forwarding Xymon messages from one server to another. It will typically be needed if you have clients behind a firewall, so they cannot send status messages to the Xymon server directly.

xymonproxy serves three purposes. First, it acts as a regular proxy server, allowing clients that cannot connect directly to the Xymon servers to send data. Although xymonproxy is optimized for handling status messages, it will forward all types of messages, including notes- and data-messages.

Second, it acts as a buffer, smoothing out peak loads if many clients try to send status messages simultaneously. xymonproxy can absorb messages very quickly, but will queue them up internally and forward them to the Xymon server at a reasonable pace.

Third, xymonproxy merges small "status" messages into larger "combo" messages. This can dramatically decrease the number of connections that need to go from xymonproxy to the Xymon server. The merging of messages causes "status" messages to be delayed for up to 0.25 seconds before being sent off to the Xymon server.

 

OPTIONS

--server=SERVERIP[:PORT][,SERVER2IP[:PORT]]
Specifies the IP-address and optional portnumber where incoming messages are forwarded to. The default portnumber is 1984, the standard Xymon port number. If you have setup the normal Xymon environment, you can use "--server=$XYMSRV". Up to 3 servers can be specified; incoming messages are sent to all of them (except "config", "query" and "download" messages, which go to the LAST server only). If you have Xymon clients sending their data via this proxy, note that the clients will receive their configuration data from the LAST of the servers listed here. This option is required.

--listen=LOCALIP[:PORT]
Specifies the IP-adress where xymonproxy listens for incoming connections. By default, xymonproxy listens on all IP-addresses assigned to the host. If no portnumber is given, port 1984 will be used.

--timeout=N
Specifies the number of seconds after which a connection is aborted due to a timeout. Default: 10 seconds.

--report=[PROXYHOSTNAME.]SERVICE
If given, this option causes xymonproxy to send a status report every 5 minutes to the Xymon server about itself. If you have set the standard Xymon environment, you can use "--report=xymonproxy" to have xymonproxy report its status to a "xymonproxy" column in Xymon. The default for PROXYHOSTNAME is the $MACHINE environment variable, i.e. the hostname of the server running xymonproxy. See REPORT OUTPUT below for an explanation of the report contents.

--lqueue=N
Size of the listen-queue where incoming connections can queue up before being processed. This should be large to accommodate bursts of activity from clients. Default: 512.

--daemon
Run in daemon mode, i.e. detach and run as a background process. This is the default.

--no-daemon
Runs xymonproxy as a foreground process.

--pidfile=FILENAME
Specifies the location of a file containing the process-ID of the xymonproxy daemon process. Default: /var/run/xymonproxy.pid.

--logfile=FILENAME
Sends all logging output to the specified file instead of stderr.

--log-details
Log details (IP-address, message type and hostname) to the logfile. This can also be enabled and disabled at run-time by sending the xymonproxy process a SIGUSR1 signal.

--debug
Enable debugging output.

 

REPORT OUTPUT

If enabled via the "--report" option, xymonproxy will send a status message about itself to the Xymon server once every 5 minutes.

The status message includes the following information:

Incoming messages
The total number of connections accepted from clients since the proxy started. The "(N msgs/second)" is the average number of messages per second over the past 5 minutes.

Outbound messages
The total number of messages sent to the Xymon server. Note that this is probably smaller than the number of incoming messages, since xymonproxy merges messages before sending them.

Incoming - Combo messages
The number of "combo" messages received from a client.

Incoming - Status messages
The number of "status" messages received from a client. xymonproxy attempts to merge these into "combo" messages. The "Messages merged" is the number of "status" messages that were merged into a combo message, the "Resulting combos" is the number of "combo" messages that resulted from the merging.

Incoming - Other messages
The number of other messages (data, notes, ack, query, ...) messages received from a client.

Proxy resources - Connection table size
This is the number of connection table slots in the proxy. This measures the number of simultaneously active requests that the proxy has handled, and so gives an idea about the peak number of clients that the proxy has handled simultaneously.

Proxy resources - Buffer space
This is the number of KB memory allocated for network buffers.

Timeout details - reading from client
The number of messages dropped because reading the message from the client timed out.

Timeout details - connecting to server
The number of messages dropped, because a connection to the Xymon server could not be established.

Timeout details - sending to server
The number of messages dropped because the communication to the Xymon server timed out after a connection was established.

Timeout details - recovered
When a timeout happens while sending the status message to the server, xymonproxy will attempt to recover the message and retry sending it to the server after waiting a few seconds. This number is the number of messages that were recovered, and so were not lost.

Timeout details - reading from server
The number of response messages that timed out while attempting to read them from the server. Note that this applies to the "config" and "query" messages only, since all other message types do not get any response from the servers.

Timeout details - sending to client
The number of response messages that timed out while attempting to send them to the client. Note that this applies to the "config" and "query" messages only, since all other message types do not get any response from the servers.

Average queue time
The average time it took the proxy to process a message, calculated from the messages that have passed through the proxy during the past 5 minutes. This number is computed from the messages that actually end up establishing a connection to the Xymon server, i.e. status messages that were combined into combo-messages do not go into the calculation - if they did, it would reduce the average time, since it is faster to merge messages than send them out over the network.

 

If you think the numbers do not add up, here is how they relate.

The "Incoming messages" should be equal to the sum of the "Incoming Combo/Status/Page/Other messages", or slightly more because messages in transit are not included in the per-type message counts.

The "Outbound messages" should be equal to sum of the "Incoming Combo/Page/Other messages", plus the "Resulting combos" count, plus "Incoming Status messages" minus "Messages merged" (this latter number is the number of status messages that were NOT merged into combos, but sent directly). The "Outbound messages" may be slightly lower than that, because messages in transit are not included in the "Outbound messages" count until they have been fully sent.

 

SIGNALS

SIGHUP
Re-opens the logfile, e.g. after it has been rotated.

SIGTERM
Shut down the proxy.

SIGUSR1
Toggles logging of individual messages.

 

SEE ALSO

xymon(1), xymond(1), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
REPORT OUTPUT
SIGNALS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man7/0000775000076400007640000000000013534041774016600 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/manpages/man7/xymon.7.html0000664000076400007640000007024613534041733021011 0ustar rpmbuildrpmbuild Manpage of XYMON

XYMON

Section: Environments, Tables, and Troff Macros (7)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

Xymon - Introduction to Xymon

 

OVERVIEW

Xymon is a tool for monitoring the health of your networked servers and the applications running on them. It provides a simple, intuitive way of checking the health of your systems from a web browser, and can also alert you to any problems that arise through alarms sent as e-mail, SMS messages, via a pager or by other means.

Xymon is Open Source software, licensed under the GNU GPL. This means that you are free to use Xymon as much as you like, and you are free to re-distribute it and change it to suit your specific needs. However, if you change it then you must make your changes available to others on the same terms that you received Xymon originally. See the file COPYING in the Xymon source-archive for details.

Xymon was called "Hobbit" until November 2008, when it was renamed to Xymon. This was done because the name "Hobbit" is trademarked.

Xymon initially began life as an enhancement to Big Brother called "bbgen". Over a period of 5 years, Xymon has evolved from a small add-on to a full-fledged monitoring system with capabilities far exceeding what was in the original Big Brother package. Xymon does still maintain some compatibility with Big Brother, so it is possible to migrate from Big Brother to Xymon without too much trouble.

Migrating to Xymon will give you a significant performance boost, and provide you with much more advanced monitoring. The Xymon tools are designed for installations that need to monitor a large number of hosts, with very little overhead on the monitoring server. Monitoring of thousands of hosts with a single Xymon server is possible - it was developed to handle just this task.

 

FEATURES

These are some of the core features in Xymon:

Monitoring of hosts and networks
Xymon collects information about your systems in two ways: From querying network services (Web, LDAP, DNS, Mail etc.), or from scripts that run either on the Xymon server or on the systems you monitor. The Xymon package includes a Xymon client which you can install on the servers you monitor; it collects data about the CPU-load, disk- and memory-utilization, log files, network ports in use, file- and directory-information and more. All of the information is stored inside Xymon, and you can define conditions that result in alerts, e.g. if a network service stops responding, or a disk fills up.

Centralized configuration
All configuration of Xymon is done on the Xymon server. Even when monitoring hundreds or thousands of hosts, you can control their configuration centrally on the Xymon server - so there is no need for you to login to a system just to change e.g. which processes are monitored.

Works on all major platforms
The Xymon server works on all Unix-like systems, including Linux, Solaris, FreeBSD, AIX, HP-UX and others. The Xymon client supports all major Unix platforms, and there are other Open Source projects - e.g. BBWin, see http://bbwin.sourceforge.net/ - providing support for Microsoft Windows based systems.

A simple, intuitive web-based front-end
"Green is good, red is bad". Using the Xymon web pages is as simple as that. The hosts you monitor can be grouped together in a way that makes sense in your organisation and presented in a tree-structure. The web pages use many techniques to convey information about the monitored systems, e.g. different icons can be used for recently changed statuses; links to sub-pages can be listed in multiple columns; different icons can be used for dial-up-tests or reverse-tests; selected columns can be dropped or unconditionally included on the web pages to eliminate unwanted information, or always include certain information; user-friendly names can be shown for hosts regardless of their true hostname. You can also have automatic links to on-line documentation, so information about your critical systems is just a click away.

Integrated trend analysis, historical data and SLA reporting
Xymon stores trend- and availability-information about everything it monitors. So if you need to look at how your systems behave over time, Xymon has all of the information you need: Whether it is response times of your web pages during peak hours, the CPU utilization over the past 4 weeks, or what the availability of a site was compared to the SLA - it's all there inside Xymon. All measurements are tracked and made available in time-based graphs.

When you need to drill down into events that have occurred, Xymon provides a powerful tool for viewing the event history for each status log, with overviews of when problems have occurred during the past and easy-to-use zoom-in on the event.

For SLA reporting, You can configure planned downtime, agreed service availability level, service availability time and have Xymon generate availability reports directly showing the actual availability measured against the agreed SLA. Such reports of service availability can be generated on-the-fly, or pre-generated e.g. for monthly reporting.

Role-based views
You can have multiple different views of the same hosts for different parts of the organisation, e.g. one view for the hardware group, and another view for the webmasters - all of them fed by the same test tools.

If you have a dedicated Network Operations Center, you can configure precisely which alerts will appear on their monitors - e.g. a simple anomaly in the system log file need not trigger a call to 3rd-level support at 2 AM, but if the on-line shop goes down you do want someone to respond immediately. So you put the web-check for the on-line shop on the NOC monitor page, and leave out the log-file check.

Also for the techies
The Xymon user-interface is simple, but engineers will also find lots of relevant information. E.g. the data that clients report to Xymon contain the raw output from a number of system commands. That information is available directly in Xymon, so an administrator no longer needs to login to a server to get an overview of how it is behaving - the very commands they would normally run have already been performed, and the results are on-line in Xymon.

Easy to adapt to your needs
Xymon includes a lot of tests in the core package, but there will always be something specific to your setup that you would like to watch. Xymon allows you to write test scripts in your favorite scripting language and have the results show up as regular status columns in Xymon. You can trigger alerts from these, and even track trends in graphs just by a simple configuration setting.

Real network service tests
The network test tool knows how to test most commonly used protocols, including HTTP, SMTP (e-mail), DNS, LDAP (directory services), and many more. When checking websites, it is possible to not only check that the web server is responding, but also that the response looks correct by matching the response against a pre-defined pattern or a check-sum. So you can test that a network service is really working and supplying the data you expect - not just that the service is running.

Protocols that use SSL encryption such as https web sites are fully supported, and while checking such services the network tester will automatically run a check of the validity of the SSL server certificate, and warn about certificates that are about to expire.

Highly configurable alerts
You want to know when something breaks. But you don't want to get flooded with alerts all the time. Xymon lets you define several criteria for when to send out an alert, so you only get alerts when there is really something that needs your attention right away. While you are handling an incident, you can tell Xymon about it so it stops sending more alerts, and so that everyone else can check with Xymon and know that the problem is being taken care of.

Combined super-tests and test inter-dependencies
If a single test is not enough, combination tests can be defined that combine the result of several tests to a single status-report. So if you need to monitor that at least 3 out of 5 servers are running at any time, Xymon can do that for you and generate the necessary availability report.

Tests can also be configured to depend on each other, so that when a critical router goes down you will get alerts only for the router - and not from the 200 hosts behind the router.

 

SECURITY

All of the Xymon server tools run under an unprivileged user account. A single program - the xymonping(1) network connectivity tester - must be installed setuid-root, but has been written so that it drops all root privileges immediately after performing the operation that requires root privileges.

It is recommended that you setup a dedicated account for Xymon.

Communications between the Xymon server and Xymon clients use the Big Brother TCP port 1984. If the Xymon server is located behind a firewall, it must allow for inbound connections to the Xymon server on tcp port 1984. Normally, Xymon clients - i.e. the servers you are monitoring - must be permitted to connect to the Xymon server on this port. However, if that is not possible due to firewall policies, then Xymon includes the xymonfetch(8) and msgcache(8) tools to allows for a pull-style way of collecting data, where it is the Xymon server that initiates connections to the clients.

The Xymon web pages are dynamically generated through CGI programs.

Access to the Xymon web pages is controlled through your web server access controls, e.g. you can require a login through some form of HTTP authentication.

 

DEMONSTRATION SITE

A site running this software can be seen at http://www.xymon.com/

 

PREREQUISITES AND INSTALLATION

You will need a Unix-like system (Linux, Solaris, HP-UX, AIX, FreeBSD, Mac OS X or similar) with a web server installed. You will also need a C compiler and some additional libraries, but many systems come with the required development tools and libraries pre-installed. The required libraries are:

RRDtool This library is used to store and present trend-data. It is required.

libpcre This library is used for advanced pattern-matching of text strings in configuration files. This library is required.

OpenSSL This library is used for communication with SSL-enabled network services. Although optional, it is recommended that you install this for Xymon since many network tests do use SSL.

OpenLDAP This library is used for testing LDAP servers. Use of this is optional.

For more detailed information about Xymon system requirements and how to install Xymon, refer to the on-line documentation "Installing Xymon" available from the Xymon web server (via the "Help" menu), or from the "docs/install.html" file in the Xymon source archive.

 

SUPPORT and MAILING LISTS

xymon@xymon.com is an open mailing list for discussions about Xymon. If you would like to participate, send an e-mail to xymon-subscribe@xymon.com to join the list, or visit http://lists.xymon.com/mailman/listinfo/xymon .

An archive of the mailing list is available at http://lists.xymon.com/archive/

If you just want to be notified of new releases of Xymon, please subscribe to the xymon-announce mailing list. This is a moderated list, used only for announcing new Xymon releases. To be added to the list, send an e-mail to xymon-announce-subscribe@xymon.com or visit http://lists.xymon.com/mailman/listinfo/xymon-announce .

 

XYMON SERVER TOOLS

These tools implement the core functionality of the Xymon server:

xymond(8) is the core daemon that collects all reports about the status of your hosts. It uses a number of helper modules to implement certain tasks such as updating log files and sending out alerts: xymond_client, xymond_history, xymond_alert and xymond_rrd. There is also a xymond_filestore module for compatibility with Big Brother.

xymond_channel(8) Implements the communication between the Xymon daemon and the other Xymon server modules.

xymond_history(8) Stores historical data about the things that Xymon monitors.

xymond_rrd(8) Stores trend data, which is used to generate graphs of the data monitored by Xymon.

xymond_alert(8) handles alerts. When a status changes to a critical state, this module decides if an alert should be sent out, and to whom.

xymond_client(8) handles data collected by the Xymon clients, analyzes the data and feeds back several status updates to Xymon to build the view of the client status.

xymond_hostdata(8) stores historical client data when something breaks. E.g. when a web page stops responding xymond_hostdata will save the latest client data, so that you can use this to view a snapshot of how the system state was just prior to it failing.

 

XYMON NETWORK TEST TOOLS

These tools are used on servers that execute tests of network services.

xymonping(1) performs network connectivity (ping) tests.

xymonnet(1) runs the network service tests.

xymonnet-again.sh(1) is an extension script for re-doing failed network tests with a higher frequency than the normal network tests. This allows Xymon to pick up the recovery of a network service as soon as it happens, resulting in less downtime being recorded.

 

XYMON TOOLS HANDLING THE WEB USER-INTERFACE

These tools take care of generating and updating the various Xymon web-pages.

xymongen(1) takes care of updating the Xymon web pages.

svcstatus.cgi(1) This CGI program generates an HTML view of a single status log. It is used to present the Xymon status-logs.

showgraph.cgi(1) This CGI program generates graphs of the trend-data collected by Xymon.

hostgraphs.cgi(1) When you want to combine multiple graphs into one, this CGI lets you combine graphs so you can e.g. compare the load on all of the nodes in your server farm.

criticalview.cgi(1) Generates the Critical Systems view, based on the currently critical systems and the configuration of what systems and services you want to monitor when.

history.cgi(1) This CGI program generates a web page with the most recent history of a particular host+service combination.

eventlog.cgi(1) This CGI lets you view a log of events that have happened over a period of time, for a single host or test, or for multiple systems.

ack.cgi(1) This CGI program allows a user to acknowledge an alert he received from Xymon about a host that is in a critical state. Acknowledging an alert serves two purposes: First, it stops more alerts from being sent so the technicians are not bothered wit more alerts, and secondly it provides feedback to those looking at the Xymon web pages that the problem is being handled.

xymon-mailack(8) is a tool for processing acknowledgments sent via e-mail, e.g. as a response to an e-mail alert.

enadis.cgi(8) is a CGI program to disable or re-enable hosts or individual tests. When disabling a host or test, you stop alarms from being sent and also any outages do not affect the SLA calculations. So this tool is useful when systems are being brought down for maintenance.

findhost.cgi(1) is a CGI program that finds a given host in the Xymon web pages. As your Xymon installation grows, it can become difficult to remember exactly which page a host is on; this CGI script lets you find hosts easily.

report.cgi(1) This CGI program triggers the generation of Xymon availability reports, using xymongen(1) as the reporting back-end engine.

reportlog.cgi(1) This CGI program generates the detailed availability report for a particular host+service combination.

snapshot.cgi(1) is a CGI program to build the Xymon web pages in a "snapshot" mode, showing the look of the web pages at a particular point in time. It uses xymongen(1) as the back-end engine.

statusreport.cgi(1) is a CGI program reporting test results for a single status but for several hosts. It is used to e.g. see which SSL certificates are about to expire, across all of the Xymon web pages.

csvinfo.cgi(1) is a CGI program to present information about a host. The information is pulled from a CSV (Comma Separated Values) file, which is easily exported from any spreadsheet or database program.

 

CLIENT-SIDE TOOLS

logfetch(1) is a utility used by the Xymon Unix client to collect information from log files on the client. It can also monitor various other file-related data, e.g. file meta-data or directory sizes.

clientupdate(1) Is used on Xymon clients, to automatically update the client software with new versions. Through this tool, updates of the client software can happen without an administrator having to logon to the server.

msgcache(8) This tool acts as a mini Xymon server to the client. It stores client data internally, so that the xymonfetch(8) utility can pick it up later and send it to the Xymon server. It is typically used on hosts that cannot contact the Xymon server directly due to network- or firewall-restrictions.

 

XYMON COMMUNICATION TOOLS

These tools are used for communications between the Xymon server and the Xymon clients. If there are no firewalls then they are not needed, but it may be necessary due to network or firewall issues to make use of them.

xymonproxy(8) is a proxy-server that forwards Xymon messages between clients and the Xymon server. The clients must be able to talk to the proxy, and the proxy must be able to talk to the Xymon server.

xymonfetch(8) is used when the client is not able to make outbound connections to neither xymonproxy nor the Xymon server (typically, for clients located in a DMZ network zone). Together with the msgcache(8) utility running on the client, the Xymon server can contact the clients and pick up their data.

 

OTHER TOOLS

xymonlaunch(8) is a program scheduler for Xymon. It acts as a master program for running all of the Xymon tools on a system. On the Xymon server, it controls running all of the server tasks. On a Xymon client, it periodically launches the client to collect data and send them to the Xymon server.

xymon(1) is the tool used to communicate with the Xymon server. It is used to send status reports to the Xymon server, through the custom Xymon/BB protocol, or via HTTP. It can be used to query the state of tests on the central Xymon server and retrieve Xymon configuration files. The server-side script xymoncgimsg.cgi(1) used to receive messages sent via HTTP is also included.

xymoncmd(1) is a wrapper for the other Xymon tools which sets up all of the environment variables used by Xymon tools.

xymongrep(1) is a utility for use by Xymon extension scripts. It allows an extension script to easily pick out the hosts that are relevant to a script, so it need not parse a huge hosts.cfg file with lots of unwanted test-specifications.

xymoncfg(1) is a utility to dump the full hosts.cfg(5) file following any "include" statements.

xymondigest(1) is a utility to compute message digest values for use in content checks that use digests.

combostatus(1) is an extension script for the Xymon server, allowing you to build complicated tests from simpler Xymon test results. E.g. you can define a test that uses the results from testing your web server, database server and router to have a single test showing the availability of your enterprise web application.

trimhistory(8) is a tool to trim the Xymon history logs. It will remove all log entries and optionally also the individual status-logs for events that happened before a given time.

 

VERSIONS

Version 1 of bbgen was released in November 2002, and optimized the web page generation on Big Brother servers.

Version 2 of bbgen was released in April 2003, and added a tool for performing network tests.

Version 3 of bbgen was released in September 2004, and eliminated the use of several external libraries for network tests, resulting in a significant performance improvement.

With version 4.0 released on March 30 2005, the project was de-coupled from Big Brother, and the name changed to Hobbit. This version was the first full implementation of the Hobbit server, but it still used the data collected by Big Brother clients for monitoring host metrics.

Version 4.1 was released in July 2005 included a simple client for Unix. Log file monitoring was not implemented.

Version 4.2 was released in July 2006, and includes a fully functional client for Unix.

Version 4.3 was released in November 2010, and implemented the renaming of the project to Xymon. This name was already introduced in 2008 with a patch version of 4.2, but with version 4.3.0 this change of names was fully implemented.

 

COPYRIGHT

Xymon is

  Copyright (C) 2002-2011 Henrik Storner <henrik@storner.dk
Parts of the Xymon sources are from public-domain or other freely available sources. These are the the Red-Black tree implementation, and the MD5-, SHA1- and RIPEMD160-implementations. Details of the license for these is in the README file included with the Xymon sources. All other files are released under the GNU General Public License version 2, with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. See the file COPYING for details.

 

SEE ALSO

xymond(8), xymond_channel(8), xymond_history(8), xymond_rrd(8), xymond_alert(8), xymond_client(8), xymond_hostdata(8), xymonping(1), xymonnet(1), xymonnet-again.sh(1), xymongen(1), svcstatus.cgi(1), showgraph.cgi(1), hostgraphs.cgi(1), criticalview.cgi(1), history.cgi(1), eventlog.cgi(1), ack.cgi(1), xymon-mailack(8), enadis.cgi(8), findhost.cgi(1), report.cgi(1), reportlog.cgi(1), snapshot.cgi(1), statusreport.cgi(1), csvinfo.cgi(1), logfetch(1), clientupdate(1), msgcache(8), xymonproxy(8), xymonfetch(8), xymonlaunch(8), xymon(1), xymoncgimsg.cgi(1), xymoncmd(1), xymongrep(1), xymoncfg(1), xymondigest(1), combostatus(1), trimhistory(8), hosts.cfg(5), tasks.cfg(5), xymonserver.cfg(5), alerts.cfg(5), analysis.cfg(5), client-local.cfg(5)


 

Index

NAME
OVERVIEW
FEATURES
SECURITY
DEMONSTRATION SITE
PREREQUISITES AND INSTALLATION
SUPPORT and MAILING LISTS
XYMON SERVER TOOLS
XYMON NETWORK TEST TOOLS
XYMON TOOLS HANDLING THE WEB USER-INTERFACE
CLIENT-SIDE TOOLS
XYMON COMMUNICATION TOOLS
OTHER TOOLS
VERSIONS
COPYRIGHT
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/0000775000076400007640000000000013534041774016576 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/manpages/man5/xymonwebaccess.5.html0000664000076400007640000000621613534041734022662 0ustar rpmbuildrpmbuild Manpage of XYMON\-WEBACCESS

XYMON\-WEBACCESS

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymon-webaccess - Web-based access controls in Xymon

 

DESCRIPTION

Xymon does not provide any built-in authentication (login) mechanism. Instead, it relies on the access controls available in your web server, e.g. the Apache mod_auth modules.

This provides a simple way of controlling access to the physical directories that make up the pages and subpages with the hosts defined in your Xymon hosts.cfg(5) setup - you can use the Apache "require" setting to allow or deny access to information on any page, usually through the use of a "Require group ..." setting. The group name then refers to one or more groups in an Apache AuthGroupFile file.

However, this does not work for the Xymon CGI programs since they are used to fetch information about all hosts in Xymon, but there is only a single directory holding all of the CGI's. So here you can only require that the user is logged-in (the Apache "Require valid-user" directive). A user with a login can - if he knows the hostname - manipulate the request sent to the webserver and fetch information about any status by use of the Xymon CGI programs, even though he cannot see the overview webpages.

To alleviate this situation, the following Xymon CGI's support a "--access=FILENAME" option, where FILENAME is an Apache compatible group-definitions file:
svcstatus.cgi(1)
acknowledge.cgi(1)
enadis.cgi(1)
appfeed.cgi(1)

When invoked with this option the CGI will read the Apache group-definitions file, and assume that an Apache group maps to a Xymon page, and then - based on the logged-in userid - determine which pages and hosts the user is allowed access to. Only information about those hosts will be made available by the CGI tool.

Members of the group root has access to all hosts.

Access will also be granted, if the user is a member of a group with the same name as the host being requested, or as the statuscolumn being requested.

 

SEE ALSO

The Apache "Authentication, Authorization and Access Control" documentation, http://httpd.apache.org/docs/2.2/howto/auth.html


 

Index

NAME
DESCRIPTION
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/protocols.cfg.5.html0000664000076400007640000001003013534041733022376 0ustar rpmbuildrpmbuild Manpage of PROTOCOLS.CFG

PROTOCOLS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

protocols.cfg - Configuration of TCP network services

 

SYNOPSIS

$XYMONHOME/etc/protocols.cfg

 

DESCRIPTION

protocols.cfg contains definitions of how xymonnet(1) should test a TCP-based network service (i.e. all common network services except HTTP and DNS). For each service, a simple dialogue can be defined to check that the service is functioning normally, and optional flags determine if the service has e.g. a banner or requires SSL- or telnet-style handshaking to be tested.

 

FILE FORMAT

protocols.cfg is a text file. A simple service definition for the SMTP service would be this:


   [smtp]

      send "mail\r\nquit\r\n"

      expect "220"

      options banner

This defines a service called "smtp". When the connection is first established, xymonnet will send the string "mail\r\nquit\r\n" to the service. It will then expect a response beginning with "220". Any data returned by the service (a so-called "banner") will be recorded and included in the status message.

The full set of commands available for the protocols.cfg file are:

[NAME]
Define the name of the TCP service, which will also be the column-name in the resulting display on the test status. If multiple tests share a common definition (e.g. ssh, ssh1 and ssh2 are tested identically), you may list these in a single "[ssh|ssh1|ssh2]" definition, separating each service-name with a pipe-sign.

send STRING
expect STRING
Defines the strings to send to the service after a connection is established, and the response that is expected. Either of these may be omitted, in which case xymonnet(1) will simply not send any data, or match a response against anything.

The send- and expect-strings use standard escaping for non-printable characters. "\r" represents a carriage-return (ASCII 13), "\n" represents a line-feed (ASCII 10), "\t" represents a TAB (ASCII 8). Binary data is input as "\xNN" with NN being the hexadecimal value of the byte.

port NUMBER
Define the default TCP port-number for this service. If no portnumber is defined, xymonnet(1) will attempt to lookup the portnumber in the standard /etc/services file.

options option1[,option2][,option3]
Defines test options. The possible options are

   banner - include received data in the status message

   ssl - service uses SSL so perform an SSL handshake

   telnet - service is telnet, so exchange telnet options

 

FILES

$XYMONHOME/etc/protocols.cfg

 

SEE ALSO

xymonnet(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/hosts.cfg.5.html0000664000076400007640000021263713534041733021533 0ustar rpmbuildrpmbuild Manpage of HOSTS.CFG

HOSTS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

hosts.cfg - Main Xymon configuration file

 

SYNOPSIS

hosts.cfg

 

DESCRIPTION

The hosts.cfg(5) file is the most important configuration file for all of the Xymon programs. This file contains the full list of all the systems monitored by Xymon, including the set of tests and other configuration items stored for each host.

 

FILE FORMAT

Each line of the file defines a host. Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. Long lines can be broken up by putting a backslash at the end of the line and continuing the entry on the next line.

The format of an entry in the hosts.cfg file is as follows:

   IP-address hostname # tag1 tag2 ...

The IP-address and hostname are mandatory; all of the tags are optional. Listing a host with only IP-address and hostname will cause a network test to be executed for the host - the connectivity test is enabled by default, but no other tests.

The optional tags are then used to define which tests are relevant for the host, and also to set e.g. the time-interval used for availability reporting by xymongen(1)

An example of setting up the hosts.cfg file is in the Xymon on-line documentation (from the Help menu, choose "Configuring Monitoring"). The following describes the possible settings in a hosts.cfg file supported by Xymon.

 

TAGS RECOGNIZED BY ALL TOOLS

include filename
This tag is used to include another file into the hosts.cfg file at run-time, allowing for a large hosts.cfg file to be split up into more manageable pieces.

The "filename" argument should point to a file that uses the same syntax as hosts.cfg. The filename can be an absolute filename (if it begins with a '/'), or a relative filename - relative file names are prefixed with the directory where the main hosts.cfg file is located (usually $XYMONHOME/etc/).

You can nest include tags, i.e. a file that is included from the main hosts.cfg file can itself include other files.

dispinclude filename
Acts like the "include" tag, but only for the xymongen tool. Can be used e.g. to put a group of hosts on multiple sub-pages, without having to repeat the host definitions.

netinclude filename
Acts like the "include" tag, but only for the xymonnet tool.

directory directoryname
This tag is used to include all files in the named directory. Files are included in alphabetical order. If there are sub- directories, these are recursively included also. The following files are ignored: Files that begin with a dot, files that end with a tilde, RCS files that end with ",v", RPM package manager files ending in ".rpmsave" or ".rpmnew", DPKG package manager files ending in ".dpkg-new" or ".dpkg-orig", and all special files (devices, sockets, pipes etc).

optional include/directory
Both "include" and "directory" can be prefixed with the tag "optional", which will preven an error message being logged if the file or directory is not present on a system.

 

GENERAL PER-HOST OPTIONS

noclear
Controls whether stale status messages go purple or clear when a host is down. Normally, when a host is down the client statuses ("cpu", "disk", "memory" etc) will stop updating - this would usually make them go "purple" which can trigger alerts. To avoid that, Xymon checks if the "conn" test has failed, and if that is true then the other tests will go "clear" instead of purple so you only get alerts for the "conn" test. If you do want the stale statuses to go purple, you can use the "noclear" tag to override this behaviour.

Note that "noclear" also affects the behaviour of network tests; see below.

prefer
When a single host is defined multiple time in the hosts.cfg file, xymongen tries to guess which definition is the best to use for the information used on the "info" column, or for the NOPROPRED and other xymongen-specific settings. Host definitions that have a "noconn" tag or an IP of 0.0.0.0 get lower priority.

By using the "prefer" tag you tell xymongen that this host definition should be used.

Note: This only applies to hosts that are defined multiple times in the hosts.cfg file, although it will not hurt to add it on other hosts as well.

multihomed
Tell Xymon that data from the host can arrive from multiple IP-addresses. By default, Xymon will warn if it sees data for one host coming from different IP-addresses, because this usually indicates a mis-configuration of the hostname on at least one of the servers involved. Some hosts with multiple IP-addresses may use different IP's for sending data to Xymon, however. This tag disables the check of source IP when receiving data.

delayred=STATUSCOLUMN:DELAY[,STATUSCOLUMN:DELAY...]
Usually, status changes happen immediately. This tag is used to defer an update to red for the STATUSCOLUMN status for DELAY minutes. E.g. with delayred=disk:10,cpu:30, a red disk-status will not appear on the Xymon webpages until it has been red for at least 10 minutes. Note: Since most tests only execute once every 5 minutes, it will usually not make sense to set N to anything but a multiple of 5. The exception is network tests, since xymonnet-again.sh(1) will re-run failed network tests once a minute for up to 30 minutes.

delayyellow=STATUSCOLUMN:DELAY[,STATUSCOLUMN:DELAY...]
Same as delayred, but defers the change to a yellow status.

 

XYMONGEN DISPLAY OPTIONS

These tags are processed by the xymongen(1) tool when generating the Xymon webpages or reports.

page NAME [Page-title]
This defines a page at the level below the entry page. All hosts following the "page" directive appear on this page, until a new "page", "subpage" or "subparent" line is found.

subpage NAME [Page-title]
This defines a sub-page in the second level below the entry page. You must have a previous "page" line to hook this sub-page to.

subparent parentpage newpage [Page-title]
This is used to define sub-pages in whatever levels you may wish. Just like the standard "subpage" tag, "subparent" defines a new Xymon web page; however with "subparent" you explicitly list which page it should go as a sub-page to. You can pick any page as the parent - pages, sub-pages or even other subparent pages. So this allows you to define any tree structure of pages that you like.

E.g. with this in hosts.cfg:


   page USA United States
   subpage NY New York
   subparent NY manhattan Manhattan data centers
   subparent manhattan wallstreet Wall Street center

you get this hierarchy of pages:


   USA (United States)
     NY (New York)
       manhattan (Manhattan data centers)
          wallstreet (Wall Street center)

Note: The parent page must be defined before you define the subparent. If not, the page will not be generated, and you get a message in the log file.

Note: xymongen is case-sensitive, when trying to match the name of the parent page.

The inspiration for this came from Craig Cook's mkbb.pl script, and I am grateful to Craig for suggesting that I implement it in xymongen. The idea to explicitly list the parent page in the "subparent" tag was what made it easy to implement.

vpage
vsubpage
vsubparent
These are page-definitions similar to the "page", "subpage" and "subparent" definitions. However, on these pages the rows are the tests, and the columns are the hosts (normal pages have it the other way around). This is useful if you have a very large number of tests for a few hosts, and prefer to have them listed on a page that can be scrolled vertically.
Note that the "group" directives have no effect on these types of pages.

group [group-title]
group-compress [group-title]
Defines a group of hosts, that appear together on the web page, with a single header-line listing all of the columns. Hosts following the "group" line appear inside the group, until a new "group" or page-line is found. The two group-directives are handled identically by Xymon and xymongen, but both forms are allowed for backwards compatibility.

group-sorted [group-title]
Same as the "group" line, but will sort the hosts inside the group so they appear in strict lexicographic order.

group-only COLUMN1|COLUMN2|COLUMN3 [group-title]
Same as the "group" and "group-compress" lines, but includes only the columns explicitly listed in the group. Any columns not listed will be ignored for these hosts.

group-except COLUMN1|COLUMN2|COLUMN3 [group-title]
Same as the "group-only" lines, but includes all columns EXCEPT those explicitly listed in the group. Any columns listed will be ignored for these hosts - all other columns are shown.

title Page, group or host title text
The "title" tag is used to put custom headings into the pages generated by xymongen, in front of page/subpage links, groups or hosts.

The title tag operates on the next item in the hosts.cfg file following the title tag.

If a title tag precedes a host entry, the title is shown just before the host is listed on the status page. The column headings present for the host will be repeated just after the heading.

If a title tag precedes a group entry, the title is show just before the group on the status page.

If a title tag precedes a page/subpage/subparent entry, the title text replaces the normal "Pages hosted locally" heading normally inserted by Xymon. This appears on the page that links to the sub-pages, not on the sub-page itself. To get a custom heading on the sub-page, you may want to use the "--pagetext-heading" when running xymongen(1)

NAME:hostname
Overrides the default hostname used on the overview web pages. If "hostname" contains spaces, it must be enclosed in double quotes, e.g. NAME:"R&D Oracle Server"

CLIENT:hostname
Defines an alias for a host, which will be used when identifying status messages. This is typically used to accommodate a local client that sends in status reports with a different hostname, e.g. if you use hostnames with domains in your Xymon configuration, but the client is a silly Window box that does not include the hostname. Or vice-versa. Whatever the reason, this can be used to match status reports with the hosts you define in your hosts.cfg file. It causes incoming status reports with the specified hostname to be filed using the hostname defined in hosts.cfg.

NOCOLUMNS:column[,column]
Used to drop certain of the status columns generated by the Xymon client. column is one of cpu, disk, files, memory, msgs, ports, procs. This setting stops these columns from being updated for the host. Note: If the columns already exist, you must use the xymon(1) utility to drop them, or they will go purple.

COMMENT:Host comment
Adds a small text after the hostname on the web page. This can be used to describe the host, without completely changing its display-name as the NAME: tag does. If the comment includes whitespace, it must be in double-quotes, e.g. COMMENT:"Sun web server"

DESCR:Hosttype:Description
Define some informational text about the host. The "Hosttype" is a text describing the type of this device - "router", "switch", "hub", "server" etc. The "Description" is an informational text that will be shown on the "Info" column page; this can e.g. be used to store information about the physical location of the device, contact persons etc. If the text contain whitespace, you must enclose it in double-quotes, e.g. DESCR:"switch:4th floor Marketing switch"

CLASS:Classname
Force the host to belong to a specific class. Class-names are used when configuring log-file monitoring (they can be used as references in client-local.cfg(5), analysis.cfg(5) and alerts.cfg(5) to group log file checks or alerts). Normally, class-names are controlled on the client by starting the Xymon client with the "--class=Classname" option. If you specify it in the hosts.cfg file on the Xymon server, it overrides any class name that the client reports. If not set, then the host belongs to a class named by the operating system the Xymon client is running on.

dialup
The keyword "dialup" for a host means that it is OK for it to be off-line - this should not trigger an alert. All network tests will go "clear" upon failure, and any missing reports from e.g. cpu- and disk-status will not go purple when they are not updated.

nonongreen
Ignore this host on the "All non-green" page. Even if it has an active alert, it will not be included in the "All non-green" page. This also removes the host from the event-log display.

nodisp
Ignore this host completely when generating the Xymon webpages. Can be useful for monitoring a host without having it show up on the webpages, e.g. because it is not yet in production use. Or for hiding a host that is shown only on a second pageset.

TRENDS:[*,][![graph,...]]
Defines the RRD graphs to include in the "trends" column generated by xymongen. This option syntax is complex.
If this option is not present, xymongen provides graphs matching the standard set of RRD files: la, disk, memory, users, vmstat, iostat, netstat, tcp, bind, apache, sendmail
* If this option is specified, the list of graphs to include start out as being empty (no graphs).
* To include all default graphs, use an asterisk. E.g. "TRENDS:*"
* To exclude a certain graph, specify it prefixed with '!'. E.g. to see all graphs except users: "TRENDS:*,!users"
* The netstat, vmstat and tcp graphs have many "subgraphs". Which of these are shown can be specified like this: "TRENDS:*,netstat:netstat2|netstat3,tcp:http|smtp|conn" This will show all graphs, but instead of the normal netstat graph, there will be two: The netstat2 and netstat3 graphs. Instead of the combined tcp graphs showing all services, there will be three: One for each of the http, conn and smtp services.
COMPACT:COLUMN=COLUMN1|COLUMN2|COLUMN3[,ditto]
Collapses a series of statuses into a single column on the overview web page.
INTERFACES:REGEXP
On systems with multiple network interfaces, the operating system may report a number of network interface where the statistics are of no interest. By default Xymon tracks and graphs the traffic on all network interfaces. This option defines a regular expression, and only those interfaces whose name matches the expression are tracked.

 

XYMON TAGS FOR THE CRITICAL SYSTEMS OVERVIEW PAGE

NOTE: The "NK" set of tags is deprecated. They will be supported for Xymon 4.x, but will be dropped in version 5. It is recommended that you move your critical systems view to the criticalview.cgi(1) viewer, which has a separate configuration tool, criticaleditor.cgi(1) with more facilities than the NK tags in hosts.cfg.

xymongen will create three sets of pages: The main page xymon.html, the all-non-green-statuses page (nongreen.html), and a specially reduced version of nongreen.html with only selected tests (critical.html). This page includes selected tests that currently have a red or yellow status.

NK:testname[,testname]
NOTE: This has been deprecated, you should use criticalview.cgi(1) instead of the NK tag.

Define the tests that you want included on the critical page. E.g. if you have a host where you only want to see the http tests on critical.html, you specify it as


  12.34.56.78  www.acme.com  # http://www.acme.com/ NK:http

If you want multiple tests for a host to show up on the critical.html page, specify all the tests separated by commas. The test names correspond to the column names (e.g. https tests are covered by an "NK:http" tag).

NKTIME=day:starttime:endtime[,day:starttime:endtime]
This tag limits the time when an active alert is presented on the NK web page.

By default, tests with a red or yellow status that are listed in the "NK:testname" tag will appear on the NK page. However, you may not want the test to be shown outside of normal working hours - if, for example, the host is not being serviced during week-ends.

You can then use the NKTIME tag to define the time periods where the alert will show up on the NK page.

The time specification consists of

day-of-week: W means Mon-Fri ("weekdays"), * means all days, 0 .. 6 = Sunday .. Saturday. Listing multiple days is possible, e.g. "60" is valid meaning "Saturday and Sunday".

starttime: Time to start showing errors, must be in 24-hour clock format as HHMM hours/minutes. E.g. for 8 am enter "0800", for 9.30 pm enter "2130"

endtime: Time to stop showing errors.

If necessary, multiple periods can be specified. E.g. to monitor a site 24x7, except between noon and 1 pm, use NKTIME=*:0000:1159,*:1300:2359

The interval between start time and end time may cross midnight, e.g. *:2330:0200 would be valid and have the same effect as *:2330:2400,*:0000:0200.

 

XYMON TAGS FOR THE WML (WAP) CARDS

If xymongen is run with the "--wml" option, it will generate a set of WAP-format output "cards" that can be viewed with a WAP-capable device, e.g. a PDA or cell-phone.

WML:[+|-]testname[,[+|-]testname]
This tag determines which tests for this hosts are included in the WML (WAP) page. Syntax is identical to the NK: tag.

The default set of WML tests are taken from the --wml command line option. If no "WML:" tag is specified, the "NK:" tag is used if present.

 

XYMON STATUS PROPAGATION OPTIONS

These tags affect how a status propagates upwards from a single test to the page and higher. This can also be done with the command-line options --nopropyellow and --nopropred, but the tags apply to individual hosts, whereas the command line options are global.

NOPROPRED:[+|-]testname[,[+|-]testname]
This tag is used to inhibit a yellow or red status from propagating upwards - i.e. from a test status color to the (sub)page status color, and further on to xymon.html or nongreen.html

If a host-specific tag begins with a '-' or a '+', the host-specific tags are removed/added to the default setting from the command-line option. If the host-specific tag does not begin with a '+' or a '-', the default setting is ignored for this host and the NOPROPRED applies to the tests given with this tag.

E.g.: xymongen runs with "--nopropred=ftp,smtp". "NOPROPRED:+dns,-smtp" gives a NOPROPRED setting of "ftp,dns" (dns is added to the default, smtp is removed). "NOPROPRED:dns" gives a setting of "dns" only (the default is ignored).

Note: If you set use the "--nopropred=*" command line option to disable propagation of all alerts, you cannot use the "+" and "-" methods to add or remove from the wildcard setting. In that case, do not use the "+" or "-" setting, but simply list the required tests that you want to keep from propagating.

NOPROPYELLOW:[+|-]testname[,[+|-]testname]
Similar to NOPROPRED: tag, but applies to propagating a yellow status upwards.

NOPROPPURPLE:[+|-]testname[,[+|-]testname]
Similar to NOPROPRED: tag, but applies to propagating a purple status upwards.

NOPROPACK:[+|-]testname[,[+|-]testname]
Similar to NOPROPRED: tag, but applies to propagating an acknowledged status upwards.

 

XYMON AVAILABILITY REPORT OPTIONS

These options affect the way the Xymon availability reports are processed (see report.cgi(1) for details about availability reports).

REPORTTIME=day:starttime:endtime[,day:starttime:endtime]
This tag defines the time interval where you measure uptime of a service for reporting purposes.

When xymongen generates a report, it computes the availability of each service - i.e. the percentage of time that the service is reported as available (meaning: not red).

By default, this calculation is done on a 24x7 basis, so no matter when an outage occurs, it counts as downtime.

The REPORTTIME tag allows you to specify a period of time other than 24x7 for the service availability calculation. If you have systems where you only guarantee availability from e.g. 7 AM to 8 PM on weekdays, you can use

  REPORTTIME=W:0700:2000
and the availability calculation will only be performed for the service with measurements from this time interval.

The syntax for REPORTTIME is the same as the one used by the NKTIME parameter.

When REPORTTIME is specified, the availability calculation happens like this:

* Only measurements done during the given time period is used for the calculation.
* "blue" time reduces the length of the report interval, so if you are generating a report for a 10-hour period and there are 20 minutes of "blue" time, then the availability calculation will consider the reporting period to be 580 minutes (10 hours minus 20 minutes). This allows you to have scheduled downtime during the REPORTTIME interval without hurting your availability; this is (I believe) the whole idea of the downtime being "planned".
* "red" and "clear" status counts as downtime; "yellow" and "green" count as uptime. "purple" time is ignored.

The availability calculation correctly handles status changes that cross into/out of a REPORTTIME interval.

If no REPORTTIME is given, the standard 24x7 calculation is used.

WARNPCT:percentage
Xymon's reporting facility uses a computed availability threshold to color services green (100% available), yellow (above threshold, but less than 100%), or red (below threshold) in the reports.

This option allows you to set the threshold value on a host-by-host basis, instead of using a global setting for all hosts. The threshold is defined as the percentage of the time that the host must be available, e.g. "WARNPCT:98.5" if you want the threshold to be at 98.5%

noflap[=test1,test2,...]
Disable flap detection for this host, or for specific tests on this host. Flap detection is globally controlled by options given to xymond on the command line, but, if enabled, it can be disabled using this option.

 

NETWORK TEST SETTINGS

testip
By default, Xymon will perform a name lookup of the hostname to get the IP address it will use for network tests. This tag causes Xymon to use the IP listed in the hosts.cfg file.

NET:location
This tag defines the host as being tested from a specific location. If xymonnet sees that the environment variable XYMONNETWORK is set, it will only test the hosts that have a matching "NET:location" tag in the hosts.cfg file. So this tag is useful if you have more than one system running network tests, but you still want to keep a consolidated hosts.cfg file for all your systems.

Note: The "--test-untagged" option modifies this behaviour, see xymonnet(1)

noclear
Some network tests depend on others. E.g. if the host does not respond to ping, then there's a good chance that the entire host is down and all network tests will fail. Or if the http server is down, then any web content checks are also likely to fail. To avoid floods of alerts, the default behaviour is for xymonnet to change the status of these tests that fail because of another problem to "clear" instead of "red". The "noclear" tag disables this behaviour and causes all failing tests to be reported with their true color.

This behaviour can also be implemented on a per-test basis by putting the "~" flag on any network test.

Note that "noclear" also affects whether stale status messages from e.g. a client on the host go purple or clear when the host is down; see the "noclear" description in the "GENERAL PER-HOST OPTIONS" section above.

nosslcert
Disables the standard check of any SSL certificates for this host. By default, if an SSL-enabled service is tested, a second test result is generated with information about the SSL certificate - this tag disables the SSL certificate checks for the host.

ssldays=WARNDAYS:ALARMDAYS
Define the number of days before an SSL certificate expires, in which the sslcert status shows a warning (yellow) or alarm (red) status. These default to the values from the "--sslwarn" and "--sslalarm" options for the xymonnet(1) tool; the values specified in the "ssldays" tag overrides the default.

sslbits=MINIMUMKEYBITS
Enable checking of the encryption strength of the SSL protocol offered by the server. If the server offers encryption using a key with fewer than MINIMUMKEYBITS bits, the "sslcert" test will go red. E.g. to check that your server only uses strong encryption (128 bits or better), use "sslbits=128".

sni
nosni
Enables or disables use of SNI (Server Name Indication) for SSL tests.

Some SSL implementations cannot handle SSL handshakes with SNI data, so Xymon by default does not use SNI. This default can be changed with the "--sni" option for xymonnet(1) but can also be managed per host with these tags.

SNI support was added in Xymon 4.3.13, where the default was to use SNI. This was changed in 4.3.14 so SNI support is disabled by default, and the "sni" and "nosni" tags were introduced together with the "--sni" option for xymonnet.

DOWNTIME=day:starttime:endtime[,day:starttime:endtime]
DOWNTIME=columns:day:starttime:endtime:cause[,columns:day:starttime:endtime:cause]
This tag can be used to ignore failed checks during specific times of the day - e.g. if you run services that are only monitored e.g. Mon-Fri 8am-5pm, or you always reboot a server every Monday between 5 and 6 pm.

What happens is that if a test fails during the specified time, it is reported with status BLUE instead of red, yellow, or purple. Thus you can still see when the service was unavailable, but alarms will not be triggered and the downtime is not counted in the availability calculations generated by the Xymon reports.

The "columns" and "cause" settings are optional, but both or neither must be specified. "columns" may be a comma-separated list of status columns to which DOWNTIME will apply. The "cause" string will be displayed on the status web page to explain why the system is down.

The syntax for DOWNTIME is the same as the one used by the NKTIME parameter.

SLA=day:starttime:endtime[,day:starttime:endtime]
This tag is now deprecated. Use the DOWNTIME tag instead.

This tag works the opposite of the DOWNTIME tag - you use it to specify the periods of the day that the service should be green. Failures OUTSIDE the SLA interval are reported as blue.

depends=(testA:host1/test1,host2/test2),(testB:host3/test3),[...]
This tag allows you to define dependencies between tests. If "testA" for the current host depends on "test1" for host "host1" and test "test2" for "host2", this can be defined with


   depends=(testA:host1/test1,host2/test2)

When deciding the color to report for testA, if either host1/test1 failed or host2/test2 failed, if testA has failed also then the color of testA will be "clear" instead of red or yellow.

Since all tests are actually run before the dependencies are evaluated, you can use any host/test in the dependency - regardless of the actual sequence that the hosts are listed, or the tests run. It is also valid to use tests from the same host that the dependency is for. E.g.


   1.2.3.4  foo # http://foo/ webmin depends=(webmin:foo/http)

is valid; if both the http and the webmin tests fail, then webmin will be reported as clear.

Note: The "depends" tag is evaluated by xymonnet while running the network tests. It can therefore only refer to other network tests that are handled by the same server - there is currently no way to use the e.g. the status of locally run tests (disk, cpu, msgs) or network tests from other servers in a dependency definition. Such dependencies are silently ignored.

badTEST[-weekdays-starttime-endtime]:x:y:z
NOTE: This has been deprecated, use the delayred and delayyellow settings instead.

Normally when a network test fails, the status changes to red immediately. With a "badTEST:x:y:z" tag this behaviour changes:
* While "z" or more successive tests fail, the column goes RED.
* While "y" or more successive tests fail, but fewer than "z", the column goes YELLOW.
* While "x" or more successive tests fail, but fewer than "y", the column goes CLEAR.
* While fewer than "x" successive tests fail, the column stays GREEN.

The optional time specification can be used to limit this "badTEST" setting to a particular time of day, e.g. to require a longer period of downtime before raising an alarm during out-of-office hours. The time-specification uses:
* Weekdays: The weekdays this badTEST tag applies, from 0 (Sunday) through 6 (Saturday). Putting "W" here counts as "12345", i.e. all working days. Putting "*" here counts as all days of the week, equivalent to "0123456".
* start time and end time are specified using 24-hour clocks, e.g. "badTEST-W-0900-2000" is valid for working days between 9 AM (09:00) and 8 PM (20:00).

When using multiple badTEST tags, the LAST one specified with a matching time-spec is used.

Note: The "TEST" is replaced by the name of the test, e.g.


 12.34.56.78  www.foo.com  # http://www.foo.com/ badhttp:1:2:4

defines a http test that goes "clear" after the first failure, "yellow" after two successive failures, and "red" after four successive failures.

For LDAP tests using URL's, use the option "badldapurl". For the other network tests, use "badftp", "badssh" etc.

 

CONNECTIVITY (PING) TEST

These tags affect the behaviour of the xymonnet connectivity test.

noping
Disables the ping-test, but will keep the "conn" column on the web display with a notice that it has been disabled.

noconn
Disables the ping-test, and does not put a "conn" column on the web display.

conn
The "conn" test (which does a ping of the host) is enabled for all hosts by default, and normally you just want to disable it using "noconn" or "noping". However, on the rare occasion where you may want to check that a host is NOT up, you can specify it as an explicit test, and use the normal test modifiers, e.g. "!conn" will be green when the host is NOT up, and red if it does appear on the network.

The actual name of the tag - "conn" by default - depends on the "--ping=TESTNAME" option for xymonnet, as that decides the testname for the connectivity test.

conn={best,|worst,}IP1[,IP2...]
This adds additional IP-addresses that are pinged during the normal "conn" test. So the normal "conn" test must be enabled (the default) before this tag has any effect. The IP-addresses listed here are pinged in addition to the main IP-address.

When multiple IP's are pinged, you can choose if ALL IP's must respond (the "worst" method), or AT LEAST one IP must respond (the "best" setting). All of the IP's are reported in a single "conn" status, whose color is determined from the result of pinging the IP's and the best/worst setting. The default method is "best" - so it will report green if just one of the IP's respond to ping.

badconn[-weekdays-starttime-endtime]:x:y:z
This is taken directly from the "fping.sh" connectivity- testing script, and is used by xymonnet when it runs with ping testing enabled (the default). See the description of the "badTEST" tag.

route:router1,router2,....
This tag is taken from the "fping.sh" script, and is used by xymonnet when run with the "--ping" option to enable ping testing.

The router1,router2,... is a comma-separated list of hosts elsewhere in the hosts.cfg file. You cannot have any spaces in the list - separate hosts with commas.

This tag changes the color reported for a ping check that fails, when one or more of the hosts in the "route" list is also down. A "red" status becomes "yellow" - other colors are unchanged. The status message will include information about the hosts in the router-list that are down, to aid tracking down which router is the root cause of the problem.

Note: Internally, the ping test will still be handled as "failed", and therefore any other tests run for this host will report a status of "clear".

route_LOCATION:router1,router2,...
If the XYMONNETWORK environment variable is defined, a tag of "route_XYMONNETWORK:" is recognized by xymonnet with the same effect as the normal "route:" tag (see above). This allows you to have different route: tags for each server running xymonnet. The actual text for the tag then must match the value you have for the XYMONNETWORK setting. E.g. with XYMONNETWORK=dmz, the tag becomes "route_dmz:"

trace
If the connectivity test fails, run a "traceroute" and include the output from this in the status message from the failed connectivity test. Note: For this to work, you may have to define the TRACEROUTE environment variable, see xymonserver.cfg(5)

notrace
Similar to the "trace" option, this disables the running of a traceroute for the host after a failed connectivity test. It is only used if running traceroute is made the default via the --trace option.

 

SIMPLE NETWORK TESTS

These tests perform a simple network test of a service by connecting to the port and possibly checking that a banner is shown by the server.

How these tests operate are configured in the protocols.cfg(5) configuration file, which controls which port to use for the service, whether to send any data to the service, whether to check for a response from the service etc.

You can modify the behaviour of these tests on a per-test basis by adding one or more modifiers to the test: :NUMBER changes the port number from the default to the one you specify for this test. E.g. to test ssh running on port 8022, specify the test as ssh:8022.

:s makes the test silent, i.e. it does not send any data to the service. E.g. to do a silent test of an smtp server, enter smtp:s.

You can combine these two: ftp:8021:s is valid.

If you must test a service from a multi-homed host (i.e. using a specific source IP-address instead of the one your operating system provides), you can use the modifier "@IPADDRESS" at the end of the test specification, after any other modifiers or port number. "IPADDRESS" must be a valid dotted IP-address (not hostname) which is assigned to the host running the network tests.

The name of the test also determines the column name that the test result will appear with in the Xymon webpages.

By prefixing a test with "!" it becomes a reverse test: Xymon will expect the service NOT to be available, and send a green status if it does NOT respond. If a connection to the service succeeds, the status will go red.

By prefixing a test with "?" errors will be reported with a "clear" status instead of red. This is known as a test for a "dialup" service, and allows you to run tests of hosts that are not always online, without getting alarms while they are off-line.

ftp ssh telnet smtp pop3 imap nntp rsync clamd oratns qmtp qmqp
These tags are for testing services offering the FTP, Secure Shell (ssh), SMTP, POP3, IMAP, NNTP, rsync, CLAM anti-virus daemon (clamd), Oracle TNS listener (oratns), qmail QMTP and QMQP protocols.

ftps telnets smtps pop3s imaps nntps
These tags are for testing of the SSL-tunneled versions of the standard ftp, telnet, smtp, pop3, imap and nntp protocols. If Xymon was configured with support for SSL, you can test these services like any other network service - xymonnet will setup an SSL-encrypted session while testing the service. The server certificate is validated and information about it sent in the "sslcert" column. Note that smtps does not have a standard port number assignment, so you will need to enter this into the protocols.cfg file or your /etc/services file.

bbd
Test that a Big Brother compatible daemon is running. This check works both for the Xymon xymond(8) daemon, and the original Big Brother bbd daemon.

 

DNS SERVER TESTS

These tags are used to setup monitoring of DNS servers.

dns
Simple DNS test. It will attempt to lookup the A record for the hostname of the DNS server.

dig
This is an alias for the "dns" test. In xymonnet, the "dns" and "dig" tests are handled identically, so all of the facilities for testing described for the "dns" test are also available for the "dig" test.

dns=hostname
dns=TYPE:lookup[,TYPE:lookup...]
The default DNS tests will attempt a DNS lookup of the DNS' servers own hostname. You can specify the hostname to lookup on a DNS server by listing it on each test.

The second form of the test allows you to perform multiple queries of the DNS server, requesting different types of DNS records. The TYPE defines the type of DNS data: A (IP-address), MX (Mail eXchanger), PTR (reverse), CNAME (alias), SOA (Start-Of-Authority), NS (Name Server) are among the more common ones used. The "lookup" is the query. E.g. to lookup the MX records for the "foo.com" domain, you would use "dns=mx:foo.com". Or to lookup the nameservers for the "bar.org" domain, "dns=ns:bar.org". You can list multiple lookups, separated by commas. For the test to end up with a green status, all lookups must succeed.

 

OTHER NETWORK TESTS

ntp
Check for a running NTP (Network Time Protocol) server on this host. This test uses the "ntpdate" utility to check for a NTP server - you should either have ntpdate in your PATH, or set the location of the ntpdate program in $XYMONHOME/etc/xymonserver.cfg

rpc[=rpcservice1,rpcservice2,...]
Check for one or more available RPC services. This check is indirect in that it only queries the RPC Portmapper on the host, not the actual service.

If only "rpc" is given, the test only verifies that the port mapper is available on the remote host. If you want to check that one or more RPC services are registered with the port mapper, list the names of the desired RPC services after the equals-sign. E.g. for a working NFS server the "mount", "nlockmgr" and "nfs" services must be available; this can be checked with "rpc=mount,nlockmgr,nfs".

This test uses the rpcinfo tool for the actual test; if this tool is not available in the PATH of xymonnet, you must define the RPCINFO environment variable to point at this tool. See xymonserver.cfg(5)

 

HTTP TESTS

Simple testing of a http URL is done simply by putting the URL into the hosts.cfg file. Note that this only applies to URL's that begin with "http:" or "https:".

The following items describe more advanced forms of http URL's.

Basic Authentication with username/password
If the URL requires authentication in the form of a username and password, it is most likely using the HTTP "Basic" authentication. xymonnet support this, and you can provide the username and password either by embedding them in the URL e.g.

    http://USERNAME:PASSWORD@www.sample.com/
or by putting the username and password into the ~/.netrc file (see ftp(1) for details).

Authentication with SSL client certificates
An SSL client certificate can be used for authentication. To use this, the client certificate must be stored in a PEM-formatted file together with the client certificate key, in the $XYMONHOME/certs/ directory. The URL is then given as

    http://CERT:FILENAME@www.sample.com/
The "CERT:" part is literal - i.e. you write C-E-R-T-colon and then the filename of the PEM-formatted certificate.
A PEM-formatted certificate file can be generated based on certificates stored in Microsoft Internet Explorer and OpenSSL. Do as follows:
From the MSIE Tools-Options menu, pick the Content tab, click on Certificates, choose the Personal tab, select the certificate and click Export. Make sure you export the private key also. In the Export File Format, choose PKCS 12 (.PFX), check the "Include all certificates" checkbox and uncheck the "Enable strong protection". Provide a temporary password for the exported file, and select a filename for the PFX-file.
Now run "openssl pkcs12 -in file.pfx -out file.pem". When prompted for the "Import Password", provide the temporary password you gave when exporting the certificate. Then provide a "PEM pass phrase" (twice) when prompted for one.
The file.pem file is the one you should use in the FILENAME field in the URL - this file must be kept in $XYMONHOME/certs/. The PEM pass phrase must be put into a file named the same as the certificate, but with extension ".pass". E.g. if you have the PEM certificate in $XYMONHOME/certs/client.pem, you must put the pass phrase into the $XYMONHOME/certs/client.pass file. Make sure to protect this file with Unix permissions, so that only the user running Xymon can read it.

Forcing an HTTP or SSL version
Some SSL sites will only allow you to connect, if you use specific "dialects" of HTTP or SSL. Normally this is auto-negotiated, but experience shows that this fails on some systems.

xymonnet can be told to use specific dialects, by adding one or more "dialect names" to the URL scheme, i.e. the "http" or "https" in the URL:

* "2", e.g. https2://www.sample.com/ : use only SSLv2
* "3", e.g. https3://www.sample.com/ : use only SSLv3
* "t", e.g. httpst://www.sample.com/ : use only TLSv1.0
* "a", e.g. httpsa://www.sample.com/ : use only TLSv1.0
* "b", e.g. httpsb://www.sample.com/ : use only TLSv1.1
* "c", e.g. httpsc://www.sample.com/ : use only TLSv1.2
* "m", e.g. httpsm://www.sample.com/ : use only 128-bit ciphers
* "h", e.g. httpsh://www.sample.com/ : use only >128-bit ciphers
* "10", e.g. http10://www.sample.com/ : use HTTP 1.0
* "11", e.g. http11://www.sample.com/ : use HTTP 1.1

These can be combined where it makes sense, e.g to force TLS1.2 and HTTP 1.0 you would use "httpsc10".

Note that SSLv2 support is disabled in all current OpenSSL releases. TLS version-specific scheme testing requires OpenSSL 1.0.1 or higher.

Testing sites by IP-address
xymonnet ignores the "testip" tag normally used to force a test to use the IP-address from the hosts.cfg file instead of the hostname, when it performs http and https tests.

The reason for this is that it interacts badly with virtual hosts, especially if these are IP-based as is common with https-websites.

Instead the IP-address to connect to can be overridden by specifying it as:

        http://www.sample.com=1.2.3.4/index.html

The "=1.2.3.4" will case xymonnet to run the test against the IP-address "1.2.3.4", but still trying to access a virtual website with the name "www.sample.com".

The "=ip.address.of.host" must be the last part of the hostname, so if you need to combine this with e.g. an explicit port number, it should be done as

        http://www.sample.com:3128=1.2.3.4/index.html

HTTP Testing via proxy
NOTE: This is not enabled by default. You must add the "--bb-proxy-syntax" option when running xymonnet(1) if you want to use this.

xymonnet supports the Big Brother syntax for specifying an HTTP proxy to use when performing http tests. This syntax just joins the proxy- and the target-URL into one, e.g.

    http://webproxy.sample.com:3128/http://www.foo.com/
would be the syntax for testing the www.foo.com website via the proxy running on "webproxy.sample.com" port 3128.

If the proxy port number is not specified, the default HTTP port number (80) is used.

If your proxy requires authentication, you can specify the username and password inside the proxy-part of the URL, e.g.

    http://fred:Wilma1@webproxy.sample.com:3128/http://www.foo.com/
will authenticate to the proxy using a username of "fred" and a password of "Wilma1", before requesting the proxy to fetch the www.foo.com homepage.

Note that it is not possible to test https-sites via a proxy, nor is it possible to use https for connecting to the proxy itself.

cont[=COLUMN];URL;[expected_data_regexp|#digesttype:digest]
This tag is used to specify a http/https check, where it is also checked that specific content is present in the server response.

If the URL itself includes a semi-colon, this must be escaped as '%3B' to avoid confusion over which semicolon is part of the URL, and which semicolon acts as a delimiter.

The data that must be returned can be specified either as a regular expression (except that <space> is not allowed) or as a message digest (typically using an MD5 sum or SHA-1 hash).

The regex is pre-processed for backslash "\" escape sequences. So you can really put any character in this string by escaping it first:

   \n     Newline (LF, ASCII 10 decimal)

   \r     Carriage return (CR, ASCII 13 decimal)

   \t     TAB (ASCII 8 decimal)

   \\    Backslash (ASCII 92 decimal)

   \XX    The character with ASCII hex-value XX

If you must have whitespace in the regex, use the [[:space:]] syntax, e.g. if you want to test for the string "All is OK", use "All[[:space:]]is[[:space:]]OK". Note that this may depend on your particular implementation of the regex functions found in your C library. Thanks to Charles Goyard for this tip.

Note: If you are migrating from the "cont2.sh" script, you must change the '_' used as wildcards by cont2.sh into '.' which is the regular-expression wildcard character.

Message digests can use whatever digest algorithms your libcrypto implementation (usually OpenSSL) supports. Common message digests are "md5", "sha1", "sha256" or "sha512". The digest is calculated on the data portion of the response from the server, i.e. HTTP headers are not included in the digest (as they change from one request to the next).

The expected digest value can be computed with the xymondigest(1) utility.

"cont" tags in hosts.cfg result in two status reports: One status with the "http" check, and another with the "content" check.

As with normal URL's, the extended syntax described above can be used e.g. when testing SSL sites that require the use of SSLv2 or strong ciphers.

The column name for the result of the content check is by default called "content" - you can change the default with the "--content=NAME" option to xymonnet. See xymonnet(1) for a description of this option.

If more than one content check is present for a host, the first content check is reported in the column "content", the second is reported in the column "content1", the third in "content2" etc.

You can also specify the column name directly in the test specification, by writing it as "cont=COLUMN;http://...". Column-names cannot include whitespace or semi-colon.

The content-check status by default includes the full URL that was requested, and the HTML data returned by the server. You can hide the HTML data on a per-host (not per-test) basis by adding the HIDEHTTP tag to the host entry.

content=URL
This syntax is deprecated. You should use the "cont" tag instead, see above.

post[=COLUMN];URL;form-data;[expected_data_regexp|#digesttype:digest]
This tag can be used to test web pages, that use an input form. Data can be posted to the form by specifying them in the form-data field, and the result can be checked as if it was a normal content check (see above for a description of the cont-tag and the restrictions on how the URL must be written).

The form-data field must be entered in "application/x-www-form-urlencoded" format, which is the most commonly used format for web forms.

E.g. if you have a web form defined like this:


   <form action="/cgi-bin/form.cgi" method="post">

     <p>Given name<input type="text" name="givenname"></p>

     <p>Surname<input type="text" name="surname"></p>

     <input type="submit" value="Send">

   </form>

and you want to post the value "John" to the first field and "Doe Jr." to the second field, then the form data field would be


    givenname=John&surname=Doe+Jr.

Note that any spaces in the input value is replaced with '+'.

If your form-data requires a different content-type, you can specify it by beginning the form-data with (content-type=TYPE), e.g. "(content-type=text/xml)" followed by the POST data. Note that as with normal forms, the POST data should be specified using escape-sequences for reserved characters: "space" should be entered as "\x20", double quote as "\x22", newline as "\n", carriage-return as "\r", TAB as "\t", backslash as "\\". Any byte value can be entered using "\xNN" with NN being the hexadecimal value, e.g. "\x20" is the space character.

The [expected_data_regexp|#digesttype:digest] is the expected data returned from the server in response to the POST. See the "cont;" tag above for details. If you are only interested in knowing if it is possible to submit the form (but don't care about the data), this can be an empty string - but the ';' at the end is required.

nocont[=COLUMN];URL;forbidden_data_regexp
This tag works just like "cont" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message.

nopost[=COLUMN];URL;form-data;expected_data_regexp
This tag works just like "post" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message.

type[=COLUMN];URL;expected_content_type
This is a variant of the content check - instead of checking the content data, it checks the type of the data as given by the HTTP Content-Type: header. This can used to check if a URL returns e.g. a PDF file, regardless of what is inside the PDF file.

soap[=COLUMN];URL;SOAPMESSAGE;[expected_data_regexp|#digesttype:digest]
Send SOAP message over HTTP. This is identical to the "cont" test, except that the request sent to the server uses a Content-type of "application/soap+xml", and it also sends a "SOAPAction" header with the URL. SOAPMESSAGE is the SOAP message sent to the server. Since SOAP messages are usually XML documents, you can store this in a separate file by specifying "file:FILENAME" as the SOAPMESSAGE parameter. E.g. a test specification of
    soap=echo;http://soap.foo.bar/baz?wsdl;file:/home/foo/msg.xml;. will read the SOAP message from the file /home/foo/msg.xml and post it to the URL http://soap.foo.bar/bas?wsdl

Note that SOAP XML documents usually must begin with the XML version line, <?xml version="1.0">

nosoap[=COLUMN];URL;SOAPMESSAGE;[forbidden_data_regexp|#digesttype:digest]
This tag works just like "soap" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message.

httphead[=COLUMN];URL
This is used to perform an HTTP HEAD request instead of a GET.

httpstatus[=COLUMN];URL;okstatusexpr;notokstatusexpr
This is used to explicitly test for certain HTTP statuscodes returned when the URL is requested. The okstatusexpr and nokokstatusexpr expressions are Perl-compatible regular expressions, e.g. "2..|302" will match all OK codes and the redirect (302) status code. If the URL cannot be retrieved, the status is "999".

HIDEHTTP
The status display for HTTP checks usually includes the URL, and for content checks also the actual data from the web page. If you would like to hide these from view, then the HIDEHTTP tag will keep this information from showing up on the status webpages.

headermatch
Content checks by default only search the HTML body returned by the webserver. This option causes it to also search the HTTP headers for the string that must / must not be present.

browser=BROWSERNAME
By default, Xymon sends an HTTP "User-Agent" header identifying it a "Xymon". Some websites require that you use a specific browser, typically Internet Explorer. To cater for testing of such sites, this tag can be used to modify the data sent in the User-Agent header.
E.g. to perform an HTTP test with Xymon masquerading as an Internet Explorer 6.0 browser, use browser="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)". If you do not know what the User-Agent header should be, open up the browser that works with this particular site, and open the URL "javascript:document.writeln(navigator.userAgent)" (just copy this into the "Open URL" dialog. The text that shows up is what the browser sends as the User-Agent header.

httphdr=STRING
Xymon can be send additional headers when performing HTTP checks, to allow for validation of any custom configurations needed for your site. Note that this is a host-wide configuration. The string will be added directly to the headers for all URLs on that host. There is currently no way to have this occur only for specific URLs checked.
The string should be encased in quotes, like httphdr="X-Requested-With: XMLHttpRequest". Newlines can be included, however the string MUST NOT end with a newline as that may cause premature ending of the headers sent.

 

LDAP (DIRECTORY SERVER) TESTS

ldap
ldaps
Simple check for an LDAP service. This check merely looks for any service running on the ldap/ldaps service port, but does not perform any actual LDAP transaction.

ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]]
Check for an LDAP service by performing an LDAP request. This tag is in the form of an LDAP URI (cf. RFC 2255). This type of LDAP test requires that xymonnet(1) was built with support for LDAP, e.g. via the OpenLDAP library. The components of the LDAP URI are:
  hostport is a host name with an optional ":portnumber"
  dn is the search base
  attrs is a comma separated list of attributes to request
  scope is one of these three strings:
    base one sub (default=base)
  filter is filter
  exts are recognized set of LDAP and/or API extensions.

ldaps://hostport/dn[?attrs[?scope[?filter[?exts]]]]
LDAP service check using LDAPv3 and STARTTLS for talking to an LDAP server that requires TLS encryption. See xymonnet(1) for a discussion of the different ways of running LDAP servers with SSL/TLS, and which of these are supported by xymonnet.

ldaplogin=username:password
Define a username and password to use when binding to the LDAP server for ldap URI tests. If not specified, xymonnet will attempt an anonymous bind.

ldapyellowfail
Used with an LDAP URL test. If the LDAP query fails during the search of the directory, the ldap status is normally reported as "red" (alarm). This tag reduces a search failure to a "yellow" (warning) status.

 

PERFORMANCE MONITORING TESTS

apache[=URL]
If you are running an Apache web server, adding this tag makes xymonnet(1) collect performance statistics from the Apache web server by querying the URL http://IP.ADDRESS.OF.HOST/server-status?auto. The response is sent as a data-report and processed by the Xymon xymond_rrd module into an RRD file and an "apache" graph. If your web server requires e.g. authentication, or runs on a different URL for the server-status, you can provide the full URL needed to fetch the server-status page, e.g. apache=http://LOGIN:PASSWORD@10.0.0.1/server-status?auto for a password protected server-status page, or apache=http://10.0.0.1:8080/apache/server-status?auto for a server listening on port 8080 and with a different path to the server-status page.

Note that you need to enable the server-status URL in your Apache configuration. The following configuration is needed:


    <Location /server-status>

        SetHandler server-status

        Order deny,allow

        Deny from all

        allow from 127.0.0.1

    </Location>

    ExtendedStatus On

Change "127.0.0.1" to the IP-address of the server that runs your network tests.

 

DEFAULT HOST

If you have certain tags that you want to apply to all hosts, you can define a host name ".default." and put the tags on that host. Note that per-host definitions will override the default ones. To apply to all hosts this should be listed FIRST in your file.

NOTE: The ".default." host entry will only accept the following tags - others are silently ignored: delayyellow, delayred, NOCOLUMNS, COMMENT, DESCR, CLASS, dialup, testip, nonongreen, nodisp, noinfo, notrends, noclient, TRENDS, NOPROPRED, NOPROPYELLOW, NOPROPPURPLE, NOPROPACK, REPORTTIME, WARNPCT, NET, noclear, nosslcert, ssldays, DOWNTIME, depends, noping, noconn, trace, notrace, HIDEHTTP, browser, pulldata. Specifically, note that network tests, "badTEST" settings, and alternate pageset relations cannot be listed on the ".default." host.

 

SENDING SUMMARIES TO REMOTE XYMON SERVERS

summary ROW.COLUMN IP URL
If you have multiple Xymon servers, the "summary" directive lets you form a hierarchy of servers by sending the overall status of this server to a remote Xymon server, which then displays this in a special summary section. E.g. if your offices are spread over three locations, you can have a Xymon server at each office. These branch-office Xymon have a "summary" definition in their hosts.cfg file that makes them report the overall status of their branch Xymon to the central Xymon server you maintain at the corporate headquarters.

Multiple "summary" definitions are allowed.

The ROW.COLUMN setting defines how this summary is presented on the server that receives the summary. The ROW text will be used as the heading for a summary line, and the COLUMN defines the name of the column where this summary is shown - like the hostname and testname used in the normal displays. The IP is the IP-address of the remote (upstream) Xymon server, where this summary is sent). The URL is the URL of your local Xymon server.

The URL need not be that of your Xymon server's main page - it could be the URL of a sub-page on the local Xymon server. Xymon will report the summary using the color of the page found at the URL you specify. E.g. on your corporate Xymon server you want a summary from the Las Vegas office - but you would like to know both what the overall status is, and what is the status of the servers on the critical Sales department back-office servers in Las Vegas. So you configure the Las Vegas Xymon server to send two summaries:


    summary Vegas.All 10.0.1.1 http://vegas.foo.com/xymon/

    summary Vegas.Sales 10.0.1.1 http://vegas.foo.com/xymon/sales/

This gives you one summary line for Baltimore, with two columns: An "All" column showing the overall status, and a "Sales" column showing the status of the "sales" page on the Baltimore Xymon server.

Note: Pages defined using alternate pageset definitions cannot be used, the URL must point to a web page from the default set of Xymon webpages.

 

OTHER TAGS

pulldata[=[IP][:port]]
This option is recognized by the xymonfetch(8) utility, and causes it to poll the host for client data. The optional IP-address and port-number can be used if the client-side msgcache(8) daemon is listening on a non-standard IP-address or port-number.

 

FILES

~xymon/server/etc/hosts.cfg

 

SEE ALSO

xymongen(1), xymonnet(1), xymondigest(1), xymonserver.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
TAGS RECOGNIZED BY ALL TOOLS
GENERAL PER-HOST OPTIONS
XYMONGEN DISPLAY OPTIONS
XYMON TAGS FOR THE CRITICAL SYSTEMS OVERVIEW PAGE
XYMON TAGS FOR THE WML (WAP) CARDS
XYMON STATUS PROPAGATION OPTIONS
XYMON AVAILABILITY REPORT OPTIONS
NETWORK TEST SETTINGS
CONNECTIVITY (PING) TEST
SIMPLE NETWORK TESTS
DNS SERVER TESTS
OTHER NETWORK TESTS
HTTP TESTS
LDAP (DIRECTORY SERVER) TESTS
PERFORMANCE MONITORING TESTS
DEFAULT HOST
SENDING SUMMARIES TO REMOTE XYMON SERVERS
OTHER TAGS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/xymon-xmh.5.html0000664000076400007640000001434013534041733021570 0ustar rpmbuildrpmbuild Manpage of XYMON-XMH

XYMON-XMH

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

Xymon-XMH-variables - Configuration items available online

 

DESCRIPTION

The hosts.cfg(5) file is the most important configuration file for all of the Xymon programs. This file contains the full list of all the systems monitored by Xymon, including the set of tests and other configuration items stored for each host.

Although the file is in text format and can be searched using tools like xymongrep(1) it can be difficult to pick out specific fields from the configuration due to quoting and other text parsing issues. So Xymon allows for querying this information directly from the xymond daemon via the "xymondboard" command. So the information can be provided together with the current status of a host and/or test. This is done by adding a "fields" definition to the "xymondboard" command.

 

XMH items

Except where specified below, all items return the text of a particular setting from the hosts.cfg file, or an empty string if the setting has not been set for the host that is queried.

XMH_ALLPAGEPATHS
List of all pages where the host is found, using the filename hierarchy page path.

XMH_BROWSER
Value of the "browser" tag.

XMH_CLASS
The host "class" (if reported by a Xymon client), or the value of the CLASS tag.

XMH_CLIENTALIAS
Value of the CLIENT tag.

XMH_COMMENT
Value of the COMMENT tag.

XMH_COMPACT
Value of the COMPACT tag.

XMH_DEPENDS
Value of the DEPENDS tag.

XMH_DESCRIPTION
Value of the DESCR tag.

XMH_DGNAME
The text string from the hosts.cfg "group" definition (group, group-only, group-except) in which the host is defined.

XMH_DISPLAYNAME
Value of the NAME tag.

XMH_DOCURL
Value of the DOC tag.

XMH_DOWNTIME
Value of the DOWNTIME tag.

XMH_PULLDATA
Value of the PULLDATA tag (including IP:PORT, if any)

XMH_FLAG_DIALUP
Value of the "dialup" tag.

XMH_FLAG_HIDEHTTP
Value of the HIDEHTTP tag.

XMH_FLAG_LDAPFAILYELLOW
Value of the "ldapyellowfail" tag.

XMH_FLAG_MULTIHOMED
Value of the MULTIHOMED tag.

XMH_FLAG_NOBB2
Value of the "nobb2" tag (deprecated, use NONONGREEN instead).

XMH_FLAG_NOCLEAR
Value of the NOCLEAR tag.

XMH_FLAG_NOCLIENT
Value of the "noclient" tag.

XMH_FLAG_NOCONN
Value of the "noconn" tag.

XMH_FLAG_NODISP
Value of the "nodisp" tag.

XMH_FLAG_NOINFO
Value of the "noinfo" atg.

XMH_FLAG_NONONGREEN
Value of the "nonongreen" tag.

XMH_FLAG_NOPING
Value of the "noping" tag.

XMH_FLAG_NOSSLCERT
Value of the "nosslcert" tag.

XMH_FLAG_NOTRACE
Value of the "notrace" tag.

XMH_FLAG_NOTRENDS
Value of the "notrends" tag.

XMH_FLAG_PREFER
Value of the "prefer" tag.

XMH_FLAG_TESTIP
Value of the "testip" tag.

XMH_FLAG_TRACE
Value of the "trace" tag.

XMH_GROUPID
Number of the group where the host is listed - first group is 0. If a host is present on multiple pages, this is the number of the group for the first page where the host is found.

XMH_HOLIDAYS
Value of the "holidays" tag.

XMH_HOSTNAME
The name of the host.

XMH_HTTPHEADERS
Value of the "httphdr" tag.

XMH_IP
The IP-address of the host (as specified in hosts.cfg).

XMH_LDAPLOGIN
Value of the "ldaplogin" tag.

XMH_NET
Value of the NET tag.

XMH_NK
Value of the NK tag (deprecated).

XMH_NKTIME
Value of the NKTIME tag (deprecated).

XMH_NOCOLUMNS
Value of the NOCOLUMNS tag.

XMH_NOPROP
Value of the NOPROP tag.

XMH_NOPROPACK
Value of the NOPROPACK tag.

XMH_NOPROPPURPLE
Value of the NOPROPPURPLE tag.

XMH_NOPROPRED
Value of the NOPROPRED tag.

XMH_NOPROPYELLOW
Value of the NOPROPYELLOW tag.

XMH_NOTAFTER
Value of the NOTAFTER tag.

XMH_NOTBEFORE
Value of the NOTBEFORE tag.

XMH_OS
The host operating system (if reported by a Xymon client), or the value of the OS tag.

XMH_PAGEINDEX
Index of the host on the page where it is shown, first host has index 0.

XMH_PAGENAME
Name of the page where the host is shown (see also XMH_PAGEPATH).

XMH_PAGEPATH
File path to the page where the host is shown.

XMH_PAGEPATHTITLE
Title of the full path to the page where the host is shown.

XMH_PAGETITLE
Title of the page where the host is shown.

XMH_RAW
All configuration settings for the host. Settings are separated by a pipe-sign.

XMH_REPORTTIME
Value of the REPORTTIME tag.

XMH_SSLDAYS
Value of the "ssldays" tag.

XMH_SSLMINBITS
Value of the "sslbits" tag.

XMH_TRENDS
Value of the TRENDS tag.

XMH_WARNPCT
Value of the WARNPCT tag.

XMH_WARNSTOPS
Value of the WARNSTOPS tag.

XMH_WML
Value of the WML tag.

 

SEE ALSO

xymon(1), hosts.cfg(5), xymongrep(1)


 

Index

NAME
DESCRIPTION
XMH items
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/xymonserver.cfg.5.html0000664000076400007640000010040113534041733022755 0ustar rpmbuildrpmbuild Manpage of XYMONSERVER.CFG

XYMONSERVER.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonserver.cfg - Xymon environment variables

 

DESCRIPTION

Xymon programs use multiple environment variables beside the normal set of variables. The environment definitions are stored in the ~Xymon/server/etc/xymonserver.cfg file. Each line in this file is of the form NAME=VALUE and defines one environment variable NAME with the value VALUE.

You can also append data to existing variables, using the syntax NAME+=VALUE. VALUE is then appended to the existing value of the NAME variable. If NAME has not been defined, then this acts as if it were a normal definition.

 

ENVIRONMENT AREAS

In some cases it may be useful to have different values for an environment variable, depending on where it is used. This is possible by defining variables with an associated "area". Such definitions have the form AREA/NAME=VALUE.

E.g. to define a special setup of the XYMSERVERS variable when it is used by an application in the "management" area, you would do this:

  XYMSERVERS="127.0.0.1"            # Default definition
  management/XYMSERVERS="10.1.0.5"  # Definition in the "management" area

Areas are invoked by using the "--area" option for all tools, or via the ENVAREA setting in the tasks.cfg(5) file.

 

GENERAL SETTINGS

XYMONSERVERHOSTNAME
The fully-qualified hostname of the server that is running Xymon.

XYMONSERVERWWWNAME
The hostname used to access this servers' web-pages, used to construct URL's in the Xymon webpages. Default is the XYMONSERVERHOSTNAME.

XYMONSERVERIP
The public IP-address of the server that is running Xymon.

XYMONSERVEROS
A name identifying the operating system of the Xymon server. The known names are currently "linux", "freebsd", "solaris", "hpux", "aix" and "osf".

FQDN
If set to TRUE, Xymon will use fully-qualified hostnames throughout. If set to FALSE, hostnames are stripped of their domain-part before being processed. It is highly recommended that you keep this set to TRUE. Default: TRUE.

XYMONLOGSTATUS
Controls how the HTML page for a status log is generated. If set to DYNAMIC, the HTML logs are generated on-demand by the svcstatus.cgi(1) script. If set to STATIC, you must activate the xymond_filestore(8) module (through an entry in the tasks.cfg(5) file) to create and store the HTML logs whenever a status update is received. Setting "XYMONLOGSTATUS=STATIC" is discouraged since the I/O load on the Xymon server will increase significantly.

PINGCOLUMN
Defines the name of the column for "ping" test status. The data from the "ping" test is used internally by Xymon, so it must be defined here so all of the Xymon tools know which column to watch for this data. The default setting is PINGCOLUMN=conn.

INFOCOLUMN
Defines the name of the column for the "info" pages.

TRENDSCOLUMN
Defines the name of the column for the RRD graph pages.

RRDHEIGHT
The default height (in pixels) of the RRD graph images. Default: 120 pixels.

RRDWIDTH
The default width (in pixels) of the RRD graph images. Default: 576 pixels.

RRDGRAPHOPTS
Extra options for the RRD graph command. These are passed directly to the "rrdgraph" command used to generate graphs, see the rrdgraph(1) man-page for details of the options.

TRENDSECONDS
The graphs on the "trends" page show data for the past TRENDSECONDS seconds. Default: 172800 seconds, i.e. 48 hours.

HTMLCONTENTTYPE
The Content-type reported by the CGI scripts that generate web pages. By default, this it "text/html". If you have on-line help texts in character sets other than the ISO-8859-1 (western european) character set, it may be necessary to modify this to include a character set. E.g.

   HTMLCONTENTTYPE="text/html; charset=euc-jp"
for a Japanese character sets. Note: Some webservers will automatically add this, if configured to do so.

XYMWEBREFRESH
The default HTTP page reload interval for many xymongen and status pages. Note that while this can be overridden in the header template files for regular pages, dynamically generated status logs displayed with svcstatus.cgi(1) use this value in the HTTP response header and for security reasons the value in hostsvc_header may be ignored on many modern browsers. (default [seconds]: 60)

HOLIDAYS
Defines the default set of holidays used if there is no "holidays" tag for a host in the hosts.cfg file. Holiday sets are defined in the holidays.cfg(5) file. If not defined, only the default holidays (those defined outside a named holiday set) will be considered as holidays.

WEEKSTART
Defines which day is the first day of the week. Set to "0" for Sunday, "1" for Monday. Default: 1 (Monday).

XYMONBODYHEADER
Text that is included in the Xymon web pages at the location specified by ~xymon/server/web/*_header templates. If this is set to a value beginning with "file:", then the contents of the specified file is included. Default: "file:$XYMONHOME/etc/xymonmenu.cfg"

XYMONBODYFOOTER
Text that is included in the Xymon web pages at the location specified by ~xymon/server/web/*_footer templates. If this is set to a value beginning with "file:", then the contents of the specified file is included. Default: Empty.

XYMONBODYMENUCSS
URL for the Xymon menu CSS file. Default: "$XYMONMENUSKIN/xymonmenu.css"

HOSTPOPUP
Determines what is used as the host comment on the webpages. The comment by default appears as a pop-up when the mouse hovers over the hostname, and is also shown on the "info" status page. This setting must be one or more of the letters "C" (COMMENT), "D" (DESCRIPTION) or "I" (IP-address). Including "C" uses the COMMENT setting for the host, including "D" uses the DESCR setting for the host, and "I" uses the IP-address of the host. If more than one of these is set, then COMMENT takes precedence over DESCR which again has precence over IP. Note that DESCR and IP only appear in pop-up windows (if enabled), whereas the COMMENT is always used - if pop-up's have been disabled, then the COMMENT value is displayed next to the hostname on the webpages. Default: CDI

STATUSLIFETIME
The number of minutes that a status is considered valid after an update. After this time elapses, the status will go purple. Default: 30 minutes

 

DIRECTORIES

XYMONSERVERROOT
The top-level directory for the Xymon installation. The default is the home-directory for the user running Xymon.

XYMONSERVERLOGS
The directory for the Xymon's own logfiles (NOT the status-logs from the monitored hosts).

XYMONHOME
The Xymon server directory, where programs and configurations are kept. Default: $XYMONSERVERROOT/server/ .

XYMONTMP
Directory used for temporary files. Default: $XYMONHOME/tmp/

XYMONWWWDIR
Directory for Xymon webfiles. The $XYMONWEB URL must map to this directory. Default: $XYMONHOME/www/

XYMONNOTESDIR
Directory for Xymon notes-files. The $XYMONNOTESSKIN URL must map to this directory. Default: $XYMONHOME/www/notes/

XYMONREPDIR
Directory for Xymon availability reports. The $XYMONREPURL URL must map to this directory. Note also that your webserver must have write-access to this directory, if you want to use the report.cgi(1) CGI script to generate reports on-demand. Default: $XYMONHOME/www/rep/

XYMONSNAPDIR
Directory for Xymon snapshots. The $XYMONSNAPURL URL must map to this directory. Note also that your webserver must have write-access to this directory, if you want to use the snapshot.cgi(1) CGI script to generate snapshots on-demand. Default: $XYMONHOME/www/snap/

XYMONVAR
Directory for all data stored about the monitored items. Default: $XYMONSERVERROOT/data/

XYMONRAWSTATUSDIR
Directory for storing the raw status-logs. Not used unless "xymond_filestore --status" is running, which is discouraged since it increases the load on the Xymon server significantly. Default: $XYMONVAR/logs/

XYMONHTMLSTATUSDIR
Directory for storing HTML status-logs. Not used unless "xymond_filestore --status --html" is running, which is discouraged since it increases the load on the Xymon server significantly. Default: $XYMONHOME/www/html/

XYMONHISTDIR
Directory for storing the history of monitored items. Default: $XYMONVAR/hist/

XYMONHISTLOGS
Directory for storing the detailed status-log of historical events. Default: $XYMONVAR/histlogs/

XYMONACKDIR
Directory for storing information about alerts that have been acknowledged. Default: $XYMONVAR/acks/

XYMONDISABLEDDIR
Directory for storing information about tests that have been disabled. Default: $XYMONVAR/disabled/

XYMONDATADIR
Directory for storing incoming "data" messages. Default: $XYMONVAR/data/

XYMONRRDS
Top-level directory for storing RRD files (the databases with trend-information used to generate graphs). Default: $XYMONVAR/rrd/

CLIENTLOGS
Directory for storing the data sent by a Xymon client around the time a status changes to a warning (yellow) or critical (red) state. Used by the xymond_hostdata(8) module. Default: $XYMONVAR/hostdata/

XYMONCGILOGDIR
Directory where debug output from CGI applications are stored. If not specified, it defaults to $XYMONSERVERLOGS, but this is often a directory that is not writable by the userid running the CGI applications. It is therefore recommended when using "--debug" on CGI applications that you create a separate directory owned by the user running your webserver, and point XYMONCGILOGDIR to this directory.

 

SYSTEM FILES

HOSTSCFG
Full path to the Xymon hosts.cfg(5) configuration file. Default: $XYMONHOME/etc/hosts.cfg.

XYMON
Full path to the xymon(1) client program. Default: $XYMONHOME/bin/xymon.

XYMONGEN
Full path to the xymongen(1) webpage generator program. Default: $XYMONHOME/bin/xymongen.

 

URLS

XYMONSERVERWWWURL
The root URL for the Xymon webpages, without the hostname. This URL must be mapped to the ~/server/www/ directory in your webserver configuration. See the sample Apache configuration in ~/server/etc/xymon-apache.conf.

XYMONSERVERCGIURL
The root URL for the Xymon CGI-scripts, without the hostname. This directory must be mapped to the ~/cgi-bin/ directory in your webserver configuration, and must be flagged as holding executable scripts. See the sample Apache configuration in ~/server/etc/xymon-apache.conf.

XYMONWEBHOST
Initial part of the Xymon URL, including just the protocol and the hostname, e.g. "http://www.foo.com"

XYMONWEBHOSTURL
Prefix for all of the static Xymon webpages, e.g. "http://www.foo.com/xymon"

XYMONWEBHTMLLOGS
URL prefix for the static HTML status-logs generated when XYMONLOGSTATUS=STATIC. Note that this setting is discouraged so this setting should not be used.

XYMONWEB
URL prefix (without hostname) of the Xymon webpages. E.g. "/xymon".

XYMONSKIN
URL prefix (without hostname) of the Xymon graphics. E.g. "/xymon/gifs".

XYMONHELPSKIN
URL prefix (without hostname) of the Xymon on-line help files. E.g "/xymon/help".

XYMONMENUSKIN
URL prefix (without hostname) of the Xymon menu files. E.g "/xymon/menu".

XYMONNOTESSKIN
URL prefix (without hostname) of the Xymon on-line notes files. E.g "/xymon/notes".

XYMONREPURL
URL prefix (without hostname) of the Xymon availability reports. E.g. "/xymon/rep".

XYMONSNAPURL
URL prefix (without hostname) of the Xymon snapshots. E.g. "/xymon/snap".

XYMONWAP
URL prefix (without hostname) of the Xymon WAP/WML files. E.g. "/xymon/wml".

CGIBINURL
URL prefix (without hostname) of the Xymon CGI-scripts. Default: $XYMONSERVERCGIURL .

COLUMNDOCURL
Format string used to build a link to the documentation for a column heading. Default: "$CGIBINURL/columndoc.sh?%s", which causes links to use the columndoc.sh(1) script to document a column.

HOSTDOCURL
Format string used to build a link to the documentation for a host. If not set, then Xymon falls back to scanning the XYMONNOTES directory for files matching the hostname, or the hostname together with a common filename extension (.php, .html, .doc and so on). If set, this string becomes a formatting string for the documentation URL. E.g. for the host "myhost", a setting of HOSTDOCURL="/docs/%s.php" will generate a link to "/docs/myhost.php". Default: Not set, so host documentation will be retrieved from the XYMONNOTES directory.

 

SETTINGS FOR SENDING MESSAGES TO XYMON

XYMSRV
The IP-address used to contact the xymond(8) service. Used by clients and the tools that perform network tests. Default: $XYMONSERVERIP

XYMSERVERS
List of IP-addresses. Clients and network test tools will try to send status reports to a Xymon server running on each of these addresses. This setting is only used if XYMSRV=0.0.0.0.

XYMONDPORT
The portnumber for used to contact the xymond(8) service. Used by clients and the tools that perform network tests. Default: 1984.

MAXMSGSPERCOMBO
The maximum number of status messages to combine into one combo message. Default: 100.

SLEEPBETWEENMSGS
Length of a pause introduced between each successive transmission of a combo-message by xymonnet, in microseconds. Default: 0 (send messages as quickly as possible).

 

XYMOND SETTINGS

ALERTCOLORS
Comma-separated list of the colors that may trigger an alert-message. The default is "red,yellow,purple". Note that alerts may further be generated or suppresed based on the configuration in the alerts.cfg(5) file.

OKCOLORS
Comma-separated list of the colors that may trigger a recovery-message. The default is "green,clear,blue".

ALERTREPEAT
How often alerts get repeated while a status is in an alert state. This is the default setting, which may be changed in the alerts.cfg(5) file.

MAXMSG_STATUS
The maximum size of a "status" message in kB, default: 256. Status messages are the ones that end up as columns on the web display. The default size should be adequate in most cases, but some extension scripts can generate very large status messages - close to 1024 kB. You should only change this if you see messages in the xymond log file about status messages being truncated.

MAXMSG_CLIENT
The maximum size of a "client" message in kB, default: 512. "client" messages are generated by the Xymon client, and often include large process-listings. You should only change this if you see messages in the xymond log file about client messages being truncated.

MAXMSG_DATA
The maximum size of a "data" message in kB, default: 256. "data" messages are typically used for client reports of e.g. netstat or vmstat data. You should only change this setting if you see messages in the xymond log file about data messages being truncated.

MAXMSG_NOTES
The maximum size of a "notes" message in kB, default: 256. "notes" messages provide a way for uploading documentation about a host to Xymon; it is not enabled by default. If you want to upload large documents, you may need to change this setting.

MAXMSG_STACHG
The maximum size of a "status change" message in kB, default: Current value of the MAXMSG_STATUS setting. Status-change messages occur when a status changes color. There is no reason to change this setting.

MAXMSG_PAGE
The maximum size of a "page" message in kB, default: Current value of the MAXMSG_STATUS setting. "page" messages are alerts, and include the status message that triggers the alert. There is no reason to change this setting.

MAXMSG_ENADIS
The maximum size of an "enadis" message in kB, default: 32. "enadis" are small messages used when enabling or disabling hosts and tests, so the default size should be adequate.

MAXMSG_CLICHG
The maximum size of a "client change" message in kB, default: Current value of the MAXMSG_CLIENT setting. Client-change messages occur when a status changes color to one of the alert-colors, usually red, yellow and purple. There is no reason to change this setting.

MAXMSG_USER
The maximum size of a "user" message in kB, default: 128. "user" messages are for communication between custom Xymon modules you have installed, it is not used directly by Xymon.

 

XYMOND_HISTORY SETTINGS

XYMONALLHISTLOG
If set to TRUE, xymond_history(8) will update the $XYMONHISTDIR/allevents file logging all changes to a status. The allevents file is used by the eventlog.cgi(1) tool to show the list of recent events on the "All non-green" webpage.

XYMONHOSTHISTLOG
If set to TRUE, xymond_history(8) will update the host-specific eventlog that keeps record of all status changes for a host. This logfile is not used by any Xymon tool.

SAVESTATUSLOG
If set to TRUE, xymond_history(8) will save historical detailed status-logs to the $XYMONHISTLOGS directory.

 

XYMOND_ALERT SETTINGS

MAIL
Command used to send alerts via e-mail, including a "Subject:" header in the mail. Default: "mail -s"

MAILC
Command used to send alerts via e-mail in a form that does not have a "Subject" in the mail. Default: "mail"

SVCCODES
Maps status-columns to numeric service-codes. The numeric codes are used when sending an alert using a script, where the numeric code of the service is provided in the BBSVCNUM variable.

 

XYMOND_RRD SETTINGS

TEST2RRD
List of "COLUMNNAME[=RRDSERVICE]" settings, that define which status- and data-messages have a corresponding RRD graph. You will normally not need to modify this, unless you have added a custom TCP-based test to the protocols.cfg file, and want to collect data about the response-time, OR if you are using the xymond_rrd(8) external script mechanism to collect data from custom tests. Note: All TCP tests are automatically added.

GRAPHS_<COLUMNAME>
List of GRAPHs that should be displayed on the corresponding colmn page. Note this will override the default, so to add multiple graphs you should include the original one (e.g. GRAPHS_cpu="la,vmstat1").

These are used together by the svcstatus.cgi(1) script to determine if the detailed status view of a test should include a graph.

GRAPHS
List of the RRD databases, that should be shown as a graph on the "trends" column.

NORRDDISKS
This is used to disable the tracking of certain filesystems. By default all filesystems reported by a client are tracked. In some cases you may want to disable this for certain filesystems, e.g. database filesystems since they are always completely full. This setting is a regular expression that is matched against the filesystem name (the Unix mount-point, or the Windows disk-letter) - if the filesystem name matches this expression, then it will not be tracked by Xymon.
Note: Setting this does not affect filesystems that are already being tracked by Xymon - to remove them, you must remove the RRD files for the unwanted filesystems from the ~xymon/data/rrd/HOSTNAME/ directory.

RRDDISKS
This is used to enable tracking of only selected filesystems (see the NORRDDISKS setting above). By default all filesystems are being tracked, setting this changes that default so that only those filesystems that match this pattern will be tracked.

 

XYMONNET NETWORK TEST SETTINGS

XYMONNETWORK
If this variable is defined, then only the hosts that have been tagged with "NET:$XYMONNETWORK" will be tested by the xymonnet tool.

CONNTEST
If set to TRUE, the connectivity (ping) test will be performed.

IPTEST_2_CLEAR_ON_FAILED_CONN
If set to TRUE, then failing network tests go CLEAR if the conn-test fails.

NONETPAGE
List of network services (separated with <space>) that should go yellow upon failure instead of red.

XYMONROUTERTEXT
When using the "router" or "depends" tags for a host, a failure status will include text that an "Intermediate router is down". With todays network topologies, the router could be a switch or another network device; if you define this environment variable the word "router" will be replaced with whatever you put into the variable. So to inform the users that an intermediate switch or router is down, use XYMONROUTERTEXT="switch or router". This can also be set on a per-host basis using the "DESCR:hosttype:description" tag in the hosts.cfg(5) file.

NETFAILTEXT
When a network test fails, the status message reports "SERVICENAME not OK". The "not OK" message can be changed via this variable, e.g. you can change it to "FAILED" or customize it as you like.

FPING
The command used to run the xymonping(1) tool for the connectivity test. (The name FPING is due to the fact that the "fping" utility was used until Xymon version 4.2). This may include suid-root wrappers and xymonping options. Default: "xymonping"

FPINGOPTS
Options used for the fping(1) or xymonping(1) tool for the connectivity test. Note that xymonnet will still expect the output to match the default format. Default: "-Ae"

TRACEROUTE
TRACEROUTEOPTS
Defines the location of the "traceroute" tool and any options needed to run it. traceroute is used by the connectivity test when the ping test fails; if requested via the "trace" tag, the TRACEROUTE command is executed to try to indicate the point in the network that is causing the problem. For backwards compatibility, with prior versions, if TRACEROUTEOPTS is unset, TRACEROUTE is assumed to have whatever options are desired and no addl options are used. Recommended defaults are: "-n -q 2 -w 2 -m 15" (no DNS lookup, max. 2 probes, wait 2 seconds per hop, max 15 hops).

If you have the mtr(8) tool installed - available from http://www.bitwizard.nl/mtr/ - I strongly recommend using this instead. The recommended TRACEROUTEOPTS for mtr are "-c 2 -n --report" Note that mtr needs to be installed suid-root on most systems.

NTPDATE
Defines the ntpdate(1) program used for the "ntp" test. Default: "ntpdate"

NTPDATEOPTS
Options used for the ntpdate(1) program. Default: "-u -q -p 1"

RPCINFO
Defines the rpcinfo(8) program used for "rpc" tests. Default: "rpcinfo"

 

XYMONGEN WEBPAGE GENERATOR SETTINGS

XYMONLOGO
HTML code that is inserted on all standard headers. The default is to add the text "Xymon" in the upper-left corner of the page, but you can easily replace this with e.g. a company logo. If you do, I suggest that you keep it at about 30-35 pixels high, and 100-150 pixels wide.

XYMONPAGELOCAL
The string "Pages hosted locally" that appears above all of the pages linked from the main Xymon webpage.

XYMONPAGESUBLOCAL
The string "Subpages hosted locally" that appears above all of the sub-pages linked from pages below the main Xymon webpage.

XYMONPAGEREMOTE
The string "Remote status display" that appears about the summary statuses displayed on the min Xymon webpage.

XYMONPAGETITLE
HTML tags designed to go in a <FONT> tag, to choose the font for titles of the webpages.

XYMONPAGEROWFONT
HTML tags designed to go in a <FONT> tag, to choose the font for row headings (hostnames) on the webpages.

XYMONPAGECOLFONT
HTML tags designed to go in a <FONT> tag, to chose the font for column headings (test names) on the webpages.

XYMONPAGEACKFONT
HTML tags designed to go in a <FONT> tag, to chose the font for the acknowledgement text displayed on the status-log HTML page for an acknowledged status.

ACKUNTILMSG
When displaying the detailed status of an acknowledged test, Xymon will include the time that the acknowledge expires using the print-format defined in this setting. You can define the timeformat using the controls in your systems strftime(3) routine, and add the text suitable for your setup.

ACK_COOKIE_EXPIRATION
The valid length of an acknowledgement cookie. You want to set this large enough so that a late-answered acknowledgement for an alert is still processed properly. Default value: 86400

XYMONDATEFORMAT
On webpages generated by xymongen, the default header includes the current date and time. Normally this looks like "Tue Aug 24 21:59:47 2004". The XYMONDATEFORMAT controls the format of this timestamp - you can define the format using the controls in the strftime(3) routine. E.g. to have it show up as "2004-08-24 21:59:47 +0200" you would set XYMONDATEFORMAT="%Y-%m-%d %H:%M:%S %z"

HOLIDAYFORMAT
How holiday dates are displayed. The default is "%d/%m" which show the day and month. American users may want to change this to "%m/%d" to suit their preferred date-display style. This is a formatting string for the system strftime(3) routine, so any controls available for this routine may be used.

XYMONPAGECOLREPEAT
Inspired by Jeff Stoner's col_repeat_patch.tgz patch, this defines the maximum number of rows before repeating the column headings on a webpage. This sets the default value for the xymongen(1) "--maxrows" option; if the command-line option is also specified, then it overrides this environment variable. Note that unlike Jeff's patch, xymongen implements this for both the "All non-green" page and all other pages (xymon.html, subpages, critical.html).

SUMMARY_SET_BKG
If set to TRUE, then summaries will affect the color of the main Xymon webpage. Default: FALSE.

DOTHEIGHT
The height (in pixels) of the icons showing the color of a status. Default: 16, which matches the default icons.

DOTWIDTH
The width (in pixels) of the icons showing the color of a status. Default: 16, which matches the default icons.

CLIENTSVCS
List of the status logs fed by data from the Xymon client. These status logs will - if there are Xymon client data available for the host - include a link to the raw data sent by the client. Default: cpu,disk,memory,procs,svcs.

XYMONRSSTITLE
If defined, this is the title of the RSS/RDF documents generated when xymongen(1) is invoked with the "--rss" option. The default value is "Xymon Alerts".

WMLMAXCHARS
Maximum size of a WAP/WML output "card" when generating these. Default: 1500.

XYMONNONGREENEXT
List of scripts to run as extensions to the "All non-green" page. Note that two scripts, "eventlog.sh" and "acklog.sh" are handled specially: They are handled internally by xymongen, but the script names must be listed in this variable for this function to be enabled.

XYMONHISTEXT
List of scripts to run as extensions to a history page.

XYMONREPWARN
Default threshold for listing the availability as "critical" (red) when generating the availability report. This can be set on a per-host basis with the WARNPCT setting in hosts.cfg(5). Default: 97 (percent)

XYMONGENREPOPTS
Default xymongen options used for reports. This will typically include such options as "--subpagecolumns", and also "--ignorecolumns" if you wish to exclude certain tests from reports by default.

XYMONGENSNAPOPTS
Default xymongen options used by snapshots. This should be identical to the options you normally used when building Xymon webpages.

 

FILES

~xymon/server/etc/xymonserver.cfg

 

SEE ALSO

xymon(7)


 

Index

NAME
DESCRIPTION
ENVIRONMENT AREAS
GENERAL SETTINGS
DIRECTORIES
SYSTEM FILES
URLS
SETTINGS FOR SENDING MESSAGES TO XYMON
XYMOND SETTINGS
XYMOND_HISTORY SETTINGS
XYMOND_ALERT SETTINGS
XYMOND_RRD SETTINGS
XYMONNET NETWORK TEST SETTINGS
XYMONGEN WEBPAGE GENERATOR SETTINGS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/analysis.cfg.5.html0000664000076400007640000007643313534041733022220 0ustar rpmbuildrpmbuild Manpage of ANALYSIS.CFG

ANALYSIS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

analysis.cfg - Configuration file for the xymond_client module

 

SYNOPSIS

~Xymon/server/etc/analysis.cfg

 

DESCRIPTION

The analysis.cfg file controls what color is assigned to the status-messages that are generated from the Xymon client data - typically the cpu, disk, memory, procs- and msgs-columns. Color is decided on the basis of some settings defined in this file; settings apply to specific hosts through a set of rules.

Note: This file is only used on the Xymon server - it is not used by the Xymon client, so there is no need to distribute it to your client systems.

 

FILE FORMAT

Blank lines and lines starting with a hash mark (#) are treated as comments and ignored.

 

CPU STATUS COLUMN SETTINGS

LOAD warnlevel paniclevel

If the system load exceeds "warnlevel" or "paniclevel", the "cpu" status will go yellow or red, respectively. These are decimal numbers.

Defaults: warnlevel=5.0, paniclevel=10.0

UP bootlimit toolonglimit [color]

The cpu status goes yellow/red if the system has been up for less than "bootlimit" time, or longer than "toolonglimit". The time is in minutes, or you can add h/d/w for hours/days/weeks - eg. "2h" for two hours, or "4w" for 4 weeks.

Defaults: bootlimit=1h, toolonglimit=-1 (infinite), color=yellow.

CLOCK max.offset [color]

The cpu status goes yellow/red if the system clock on the client differs more than "max.offset" seconds from that of the Xymon server. Note that this is not a particularly accurate test, since it is affected by network delays between the client and the server, and the load on both systems. You should therefore not rely on this being accurate to more than +/- 5 seconds, but it will let you catch a client clock that goes completely wrong. The default is NOT to check the system clock.
NOTE: Correct operation of this test obviously requires that the system clock of the Xymon server is correct. You should therefore make sure that the Xymon server is synchronized to the real clock, e.g. by using NTP.

Example: Go yellow if the load average exceeds 5, and red if it exceeds 10. Also, go yellow for 10 minutes after a reboot, and after 4 weeks uptime. Finally, check that the system clock is at most 15 seconds offset from the clock of the Xymon system and go red if that is exceeded.

LOAD 5 10
UP 10m 4w yellow
CLOCK 15 red

 

DISK STATUS COLUMN SETTINGS

DISK filesystem warnlevel paniclevel
DISK filesystem IGNORE
INODE filesystem warnlevel paniclevel
INODE filesystem IGNORE

If the utilization of "filesystem" is reported to exceed "warnlevel" or "paniclevel", the "disk" status will go yellow or red, respectively. "warnlevel" and "paniclevel" are either the percentage used, or the space available as reported by the local "df" command on the host. For the latter type of check, the "warnlevel" must be followed by the letter "U", e.g. "1024U".

The special keyword "IGNORE" causes this filesystem to be ignored completely, i.e. it will not appear in the "disk" status column and it will not be tracked in a graph. This is useful for e.g. removable devices, backup-disks and similar hardware.

"filesystem" is the mount-point where the filesystem is mounted, e.g. "/usr" or "/home". A filesystem-name that begins with "%" is interpreted as a Perl-compatible regular expression; e.g. "%^/oracle.*/" will match any filesystem whose mountpoint begins with "/oracle".

"INODE" works identical to "DISK", but uses the count of i-nodes in the filesystem instead of the amount of disk space.

Defaults DISK: warnlevel=90%, paniclevel=95% DefaultsINODE:warnlevel=70%,paniclevel=90%

 

MEMORY STATUS COLUMN SETTINGS

MEMPHYS warnlevel paniclevel
MEMACT warnlevel paniclevel
MEMSWAP warnlevel paniclevel

If the memory utilization exceeds the "warnlevel" or "paniclevel", the "memory" status will change to yellow or red, respectively. Note: The words "PHYS", "ACT" and "SWAP" are also recognized.

Example: Go yellow if more than 20% swap is used, and red if more than 40% swap is used or the actual memory utilisation exceeds 90%. Don't alert on physical memory usage.

MEMSWAP 20 40
MEMACT 90 90
MEMPHYS 101 101

Defaults:

MEMPHYS warnlevel=100 paniclevel=101 (i.e. it will never go red).
MEMSWAP warnlevel=50 paniclevel=80
MEMACT  warnlevel=90 paniclevel=97

 

PROCS STATUS COLUMN SETTINGS

PROC processname minimumcount maximumcount color [TRACK=id] [TEXT=text]

The "ps" listing sent by the client will be scanned for how many processes containing "processname" are running, and this is then matched against the min/max settings defined here. If the running count is outside the thresholds, the color of the "procs" status changes to "color".

To check for a process that must NOT be running: Set minimum and maximum to 0.

"processname" can be a simple string, in which case this string must show up in the "ps" listing as a command. The scanner will find a ps-listing of e.g. "/usr/sbin/cron" if you only specify "processname" as "cron". "processname" can also be a Perl-compatiable regular expression, e.g. "%java.*inst[0123]" can be used to find entries in the ps-listing for "java -Xmx512m inst2" and "java -Xmx256 inst3". In that case, "processname" must begin with "%" followed by the regular expression. Note that Xymon defaults to case-insensitive pattern matching; if that is not what you want, put "(?-i)" between the "%" and the regular expression to turn this off. E.g. "%(?-i)HTTPD" will match the word HTTPD only when it is upper-case.
If "processname" contains whitespace (blanks or TAB), you must enclose the full string in double quotes - including the "%" if you use regular expression matching. E.g.


    PROC "%xymond_channel --channel=data.*xymond_rrd" 1 1 yellow

or


    PROC "java -DCLASSPATH=/opt/java/lib" 2 5

You can have multiple "PROC" entries for the same host, all of the checks are merged into the "procs" status and the most severe check defines the color of the status.

The optional TRACK=id setting causes Xymon to track the number of processes found in an RRD file, and put this into a graph which is shown on the "procs" status display. The id setting is a simple text string which will be used as the legend for the graph, and also as part of the RRD filename. It is recommended that you use only letters and digits for the ID.
Note that the process counts which are tracked are only performed once when the client does a poll cycle - i.e. the counts represent snapshots of the system state, not an average value over the client poll cycle. Therefore there may be peaks or dips in the actual process counts which will not show up in the graphs, because they happen while the Xymon client is not doing any polling.

The optional TEXT=text setting is used in the summary of the "procs" status. Normally, the summary will show the "processname" to identify the process and the related count and limits. But this may be a regular expression which is not easily recognizable, so if defined, the text setting string will be used instead. This only affects the "procs" status display - it has no effect on how the rule counts or recognizes processes in the "ps" output.

Example: Check that "cron" is running:
       PROC cron

Example: Check that at least 5 "httpd" processes are running, but not more than 20:
       PROC httpd 5 20

Defaults:
       mincount=1, maxcount=-1 (unlimited), color="red".

       Note that no processes are checked by default.

 

MSGS STATUS COLUMN SETTINGS

LOG logfilename pattern [COLOR=color] [IGNORE=excludepattern] [OPTIONAL]

The Xymon client extracts interesting lines from one or more logfiles - see the client-local.cfg(5) man-page for information about how to configure which logs a client should look at.

The LOG setting determine how these extracts of log entries are processed, and what warnings or alerts trigger as a result.

"logfilename" is the name of the logfile. Only logentries from this filename will be matched against this rule. Note that "logfilename" can be a regular expression (if prefixed with a '%' character).

"pattern" is a string or regular expression. If the logfile data matches "pattern", it will trigger the "msgs" column to change color. If no "color" parameter is present, the default is to go "red" when the pattern is matched. To match against a regular expression, "pattern" must begin with a '%' sign - e.g "%WARNING|NOTICE" will match any lines containing either of these two words. Note that Xymon defaults to case-insensitive pattern matching; if that is not what you want, put "(?-i)" between the "%" and the regular expression to turn this off. E.g. "%(?-i)WARNING" will match the word WARNING only when it is upper-case.

"excludepattern" is a string or regular expression that can be used to filter out any unwanted strings that happen to match "pattern".

The OPTIONAL keyword causes the check to be skipped if the logfile does not exist.

Example: Trigger a red alert when the string "ERROR" appears in the "/var/adm/syslog" file:
       LOG /var/adm/syslog ERROR

Example: Trigger a yellow warning on all occurrences of the word "WARNING" or "NOTICE" in the "daemon.log" file, except those from the "lpr" system:
       LOG /var/log/daemon.log %WARNING|NOTICE COLOR=yellow IGNORE=lpr

Defaults:
       color="red", no "excludepattern".

Note that no logfiles are checked by default. Any log data reported by a client will just show up on the "msgs" column with status OK (green).

 

FILES STATUS COLUMN SETTINGS

FILE filename [color] [things to check] [OPTIONAL] [TRACK]

DIR directoryname [color] [size<MAXSIZE] [size>MINSIZE] [TRACK]

These entries control the status of the "files" column. They allow you to check on various data for files and directories.

filename and directoryname are names of files or directories, with a full path. You can use a regular expression to match the names of files and directories reported by the client, if you prefix the expression with a '%' character.

color is the color that triggers when one or more of the checks fail.

The OPTIONAL keyword causes this check to be skipped if the file does not exist. E.g. you can use this to check if files that should be temporary are not deleted, by checking that they are not older than the max time you would expect them to stick around, and then using OPTIONAL to ignore the state where no files exist.

The TRACK keyword causes the size of the file or directory to be tracked in an RRD file, and presented in a graph on the "files" status display.

For files, you can check one or more of the following:

noexist
triggers a warning if the file exists. By default, a warning is triggered for files that have a FILE entry, but which do not exist.
type=TYPE
where TYPE is one of "file", "dir", "char", "block", "fifo", or "socket". Triggers warning if the file is not of the specified type.
ownerid=OWNER
triggers a warning if the owner does not match what is listed here. OWNER is specified either with the numeric uid, or the user name.
groupid=GROUP
triggers a warning if the group does not match what is listed here. GROUP is specified either with the numeric gid, or the group name.
mode=MODE
triggers a warning if the file permissions are not as listed. MODE is written in the standard octal notation, e.g. "644" for the rw-r--r-- permissions.
size<MAX.SIZE and size>MIN.SIZE
triggers a warning it the file size is greater than MAX.SIZE or less than MIN.SIZE, respectively. For filesizes, you can use the letters "K", "M", "G" or "T" to indicate that the filesize is in Kilobytes, Megabytes, Gigabytes or Terabytes, respectively. If there is no such modifier, Kilobytes is assumed. E.g. to warn if a file grows larger than 1MB, use size<1024M.
mtime>MIN.MTIME mtime<MAX.MTIME
checks how long ago the file was last modified (in seconds). E.g. to check if a file was updated within the past 10 minutes (600 seconds): mtime<600. Or to check that a file has NOT been updated in the past 24 hours: mtime>86400.
mtime=TIMESTAMP
checks if a file was last modified at TIMESTAMP. TIMESTAMP is a unix epoch time (seconds since midnight Jan 1 1970 UTC).
ctime>MIN.CTIME, ctime<MAX.CTIME, ctime=TIMESTAMP
acts as the mtime checks, but for the ctime timestamp (when the directory entry of the file was last changed, eg. by chown, chgrp or chmod).
md5=MD5SUM, sha1=SHA1SUM, rmd160=RMD160SUM
and so on for RMD160, SHA256, SHA512, SHA224, and SHA384 trigger a warning if the file checksum using the specified message digest algorithm does not match the one configured here. Note: The "file" entry in the client-local.cfg(5) file must specify which algorithm to use as that is the only one that will be sent.

For directories, you can check one or more of the following:

size<MAX.SIZE and size>MIN.SIZE
triggers a warning it the directory size is greater than MAX.SIZE or less than MIN.SIZE, respectively. Directory sizes are reported in whatever unit the du command on the client uses - often KB or diskblocks - so MAX.SIZE and MIN.SIZE must be given in the same unit.

Experience shows that it can be difficult to get these rules right. Especially when defining minimum/maximum values for file sizes, when they were last modified etc. The one thing you must remember when setting up these checks is that the rules describe criteria that must be met - only when they are met will the status be green.

So "mtime<600" means "the difference between current time and the mtime of the file must be less than 600 seconds - if not, the file status will go red".

 

PORTS STATUS COLUMN SETTINGS

PORT criteria [MIN=mincount] [MAX=maxcount] [COLOR=color] [TRACK=id] [TEXT=displaytext]

The "netstat" listing sent by the client will be scanned for how many sockets match the criteria listed. The criteria you can use are:

LOCAL=addr
"addr" is a (partial) local address specification in the format used on the output from netstat.
EXLOCAL=addr
Exclude certain local addresses from the rule.
REMOTE=addr
"addr" is a (partial) remote address specification in the format used on the output from netstat.
EXREMOTE=addr
Exclude certain remote addresses from the rule.
STATE=state
Causes only the sockets in the specified state to be included, "state" is usually LISTEN or ESTABLISHED but can be any socket state reported by the clients "netstat" command.
EXSTATE=state
Exclude certain states from the rule.

"addr" is typically "10.0.0.1:80" for the IP 10.0.0.1, port 80. Or "*:80" for any local address, port 80. Note that the Xymon clients normally report only the numeric data for IP-addresses and port-numbers, so you must specify the port number (e.g. "80") instead of the service name ("www").
"addr" and "state" can also be a Perl-compatiable regular expression, e.g. "LOCAL=%[.:](80|443)" can be used to find entries in the netstat local port for both http (port 80) and https (port 443). In that case, portname or state must begin with "%" followed by the reg.expression.

The socket count found is then matched against the min/max settings defined here. If the count is outside the thresholds, the color of the "ports" status changes to "color". To check for a socket that must NOT exist: Set minimum and maximum to 0.

The optional TRACK=id setting causes Xymon to track the number of sockets found in an RRD file, and put this into a graph which is shown on the "ports" status display. The id setting is a simple text string which will be used as the legend for the graph, and also as part of the RRD filename. It is recommended that you use only letters and digits for the ID.
Note that the sockets counts which are tracked are only performed once when the client does a poll cycle - i.e. the counts represent snapshots of the system state, not an average value over the client poll cycle. Therefore there may be peaks or dips in the actual sockets counts which will not show up in the graphs, because they happen while the Xymon client is not doing any polling.

The TEXT=displaytext option affects how the port appears on the "ports" status page. By default, the port is listed with the local/remote/state rules as identification, but this may be somewhat difficult to understand. You can then use e.g. "TEXT=Secure Shell" to make these ports appear with the name "Secure Shell" instead.

Defaults: mincount=1, maxcount=-1 (unlimited), color="red". Note: No ports are checked by default.

Example: Check that the SSH daemon is listening on port 22. Track the number of active SSH connections, and warn if there are more than 5.

        PORT LOCAL=%[.:]22$ STATE=LISTEN "TEXT=SSH listener"

        PORT LOCAL=%[.:]22$ STATE=ESTABLISHED MAX=5 TRACK=ssh TEXT=SSH

 

SVCS status (Microsoft Windows clients)

SVC servicename status=(started|stopped) [startup=automatic|disabled|manual]

 

DS - RRD based status override

DS column filename:dataset rules COLOR=colorname TEXT=explanation

"column" is the statuscolumn that will be modified. "filename" is the name of the RRD file holding the data you use for comparison. "dataset" is the name of the dataset in the RRD file - the "rrdtool info" command is useful when determining these. "rules" determine when to apply the override. You can use ">", ">=", "<" or "<=" to compare the current measurement value against one or more thresholds. "explanation" is a text that will be shown to explain the override - you can use some placeholders in the text: "&N" is replaced with the name of the dataset, "&V" is replaced with the current value, "&L" is replaced by the low threshold, "&U" is replaced with the upper threshold.

NOTE: This rule uses the raw data value from a client to examine the rules. So this type of test is only really suitable for datasets that are of the "GAUGE" type. It cannot be used meaningfully for datasets that use "COUNTER" or "DERIVE" - e.g. the datasets that are used to capture network packet traffic - because the data stored in the RRD for COUNTER-based datasets undergo a transformation (calculation) when going into the RRD. Xymon does not have direct access to the calculated data.

Example: Flag "conn" status a yellow if responsetime exceeds 100 msec.
       DS conn tcp.conn.rrd:sec >0.1 COLOR=yellow TEXT="Response time &V exceeds &U seconds"

 

MQ Series SETTINGS

MQ_QUEUE queuename [age-warning=N] [age-critical=N] [depth-warning=N] [depth-critical=N]
MQ_CHANNEL channelname [warning=PATTERN] [alert=PATTERN]

This is a set of checks for checking the health of IBM MQ message-queues. It requires the "mq.sh" or similar collector module to run on a node with access to the MQ "Queue Manager" so it can report the status of queues and channels.

The MQ_QUEUE setting checks the health of a single queue: You can warn (yellow) or alert (red) based on the depth of the queue, and/or the age of the oldest entry in the queue. These values are taken directly from the output generated by the "runmqsc" utility.

The MQ_CHANNEL setting checks the health of a single MQ channel: You can warn or alert based on the reported status of the channel. The PATTERN is a normal pattern, i.e. either a list of status keywords, or a regular expression pattern.

 

CHANGING THE DEFAULT SETTINGS

If you would like to use different defaults for the settings described above, then you can define the new defaults after a DEFAULT line. E.g. this would explicitly define all of the default settings:
DEFAULT
        UP      1h
        LOAD    5.0 10.0
        DISK    * 90 95
        MEMPHYS 100 101
        MEMSWAP 50 80
        MEMACT  90 97

 

RULES TO SELECT HOSTS

All of the settings can be applied to a group of hosts, by preceding them with rules. A rule defines of one of more filters using these keywords (note that this is identical to the rule definitions used in the alerts.cfg(5) file).

PAGE=targetstring Rule matching an alert by the name of the page in Xymon. "targetstring" is the path of the page as defined in the hosts.cfg file. E.g. if you have this setup:

page servers All Servers
subpage web Webservers
10.0.0.1 www1.foo.com
subpage db Database servers
10.0.0.2 db1.foo.com

Then the "All servers" page is found with PAGE=servers, the "Webservers" page is PAGE=servers/web and the "Database servers" page is PAGE=servers/db. Note that you can also use regular expressions to specify the page name, e.g. PAGE=%.*/db would find the "Database servers" page regardless of where this page was placed in the hierarchy.

The top-level page has a the fixed name /, e.g. PAGE=/ would match all hosts on the Xymon frontpage. If you need it in a regular expression, use PAGE=%^/ to avoid matching the forward-slash present in subpage-names.

EXPAGE=targetstring Rule excluding a host if the pagename matches.

HOST=targetstring Rule matching a host by the hostname. "targetstring" is either a comma-separated list of hostnames (from the hosts.cfg file), "*" to indicate "all hosts", or a Perl-compatible regular expression. E.g. "HOST=dns.foo.com,www.foo.com" identifies two specific hosts; "HOST=%www.*.foo.com EXHOST=www-test.foo.com" matches all hosts with a name beginning with "www", except the "www-test" host.

EXHOST=targetstring Rule excluding a host by matching the hostname.

CLASS=classname Rule match by the client class-name. You specify the class-name for a host when starting the client through the "--class=NAME" option to the runclient.sh script. If no class is specified, the host by default goes into a class named by the operating system.

EXCLASS=classname Exclude all hosts belonging to "classname" from this rule.

DISPLAYGROUP=groupstring Rule matching an alert by the text of the display-group (text following the group, group-only, group-except heading) in the hosts.cfg file. "groupstring" is the text for the group, stripped of any HTML tags. E.g. if you have this setup:

group Web
10.0.0.1 www1.foo.com
10.0.0.2 www2.foo.com
group Production databases
10.0.1.1 db1.foo.com

Then the hosts in the Web-group can be matched with DISPLAYGROUP=Web, and the database servers can be matched with DISPLAYGROUP="Production databases". Note that you can also use regular expressions, e.g. DISPLAYGROUP=%database. If there is no group-setting for the host, use "DISPLAYGROUP=NONE".

EXDISPLAYGROUP=groupstring Rule excluding a group by matching the display-group string.

TIME=timespecification Rule matching by the time-of-day. This is specified as the DOWNTIME time specification in the hosts.cfg file. E.g. "TIME=W:0800:2200" applied to a rule will make this rule active only on week-days between 8AM and 10PM.

EXTIME=timespecification Rule excluding by the time-of-day. This is also specified as the DOWNTIME time specification in the hosts.cfg file. E.g. "TIME=W:0400:0600" applied to a rule will make this rule exclude on week-days between 4AM and 6AM. This applies on top of any TIME= specification, so both must match.

 

DIRECTING ALERTS TO GROUPS

For some tests - e.g. "procs" or "msgs" - the right group of people to alert in case of a failure may be different, depending on which of the client rules actually detected a problem. E.g. if you have PROCS rules for a host checking both "httpd" and "sshd" processes, then the Web admins should handle httpd-failures, whereas "sshd" failures are handled by the Unix admins.

To handle this, all rules can have a "GROUP=groupname" setting. When a rule with this setting triggers a yellow or red status, the groupname is passed on to the Xymon alerts module, so you can use it in the alert rule definitions in alerts.cfg(5) to direct alerts to the correct group of people.

 

RULES: APPLYING SETTINGS TO SELECTED HOSTS

Rules must be placed after the settings, e.g.
LOAD 8.0 12.0  HOST=db.foo.com TIME=*:0800:1600

If you have multiple settings that you want to apply the same rules to, you can write the rules *only* on one line, followed by the settings. E.g.

HOST=%db.*.foo.com TIME=W:0800:1600
        LOAD 8.0 12.0
        DISK /db  98 100
        PROC mysqld 1

will apply the three settings to all of the "db" hosts on week-days between 8AM and 4PM. This can be combined with per-settings rule, in which case the per-settings rule overrides the general rule; e.g.

HOST=%.*.foo.com
        LOAD 7.0 12.0 HOST=bax.foo.com
        LOAD 3.0 8.0

will result in the load-limits being 7.0/12.0 for the "bax.foo.com" host, and 3.0/8.0 for all other foo.com hosts.

The entire file is evaluated from the top to bottom, and the first match found is used. So you should put the specific settings first, and the generic ones last.

 

NOTES

For the LOG, FILE and DIR checks, it is necessary also to configure the actual file- and directory-names in the client-local.cfg(5) file. If the filenames are not listed there, the clients will not collect any data about these files/directories, and the settings in the analysis.cfg file will be silently ignored.

The ability to compute file checksums with MD5, SHA1 or RMD160 should not be used for general-purpose file integrity checking, since the overhead of calculating these on a large number of files can be significant. If you need this, look at tools designed for this purpose - e.g. Tripwire or AIDE.

At the time of writing (april 2006), the SHA-1 and RMD160 algorithms are considered cryptographically safe. The MD5 algorithm has been shown to have some weaknesses, and is not considered strong enough when a high level of security is required.

 

SEE ALSO

xymond_client(8), client-local.cfg(5), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
CPU STATUS COLUMN SETTINGS
DISK STATUS COLUMN SETTINGS
MEMORY STATUS COLUMN SETTINGS
PROCS STATUS COLUMN SETTINGS
MSGS STATUS COLUMN SETTINGS
FILES STATUS COLUMN SETTINGS
PORTS STATUS COLUMN SETTINGS
SVCS status (Microsoft Windows clients)
DS - RRD based status override
MQ Series SETTINGS
CHANGING THE DEFAULT SETTINGS
RULES TO SELECT HOSTS
DIRECTING ALERTS TO GROUPS
RULES: APPLYING SETTINGS TO SELECTED HOSTS
NOTES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/graphs.cfg.5.html0000664000076400007640000001470713534041734021656 0ustar rpmbuildrpmbuild Manpage of GRAPHS.CFG

GRAPHS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

graphs.cfg - Configuration of the showgraph CGI

 

SYNOPSIS

$XYMONHOME/etc/graphs.cfg

 

DESCRIPTION

showgraph.cgi(1) uses the configuration file $XYMONHOME/etc/graphs.cfg to build graphs from the RRD files collected by Xymon.

 

FILE FORMAT

Each definition of a graph type begins with a "[SERVICE]" indicator, this is the name passed as the "service" parameter to showgraph.cgi(1). If the service name passed to showgraph.cgi is not found, it will attempt to match the service name to a graph via the TEST2RRD environment variable. So calling showgraph.cgi with "service=cpu" or "service=la" will end up producing the same graph.

A graph definition needs to have a TITLE and a YAXIS setting. These are texts shown as the title of the graph, and the YAXIS heading respectively. (The X-axis is always time-based).

If a fixed set of RRD files are used for the graph, you just write those in the RRDtool definitions. Note that Xymon keeps all RRD files for a host in a separate directory per host, so you need not worry about the hostname being part of the RRD filename.

For graphs that use multiple RRD files as input, you specify a filename pattern in the FNPATTERN statement, and optionally a pattern of files to exclude from the graph with EXFNPATTERN (see "[tcp]" for an example). When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each file in the set. "@RRDPARAM@" contains the first word extracted from the pattern of files (see e.g. "[memory]" how this is used). "@COLOR@" picks a new color for each graph automatically.

The remainder of the lines in each definition are passed directly to the RRDtool rrd_graph() routine.

The following is an example of how the "la" (cpu) graph is defined. This is a simple definition that uses a single RRD-file, la.rrd:

[la]

        TITLE CPU Load

        YAXIS Load

        DEF:avg=la.rrd:la:AVERAGE

        CDEF:la=avg,100,/

        AREA:la#00CC00:CPU Load Average

        GPRINT:la:LAST: : %5.1lf (cur)

        GPRINT:la:MAX: : %5.1lf (max)

        GPRINT:la:MIN: : %5.1lf (min)

        GPRINT:la:AVERAGE: : %5.1lf (avg)\n

Here is an example of a graph that uses multiple RRD-files, determined automatically at run-time via the FNPATTERN setting. Note how it uses the @RRDIDX@ to define a unique RRD parameter per input-file, and the @COLOR@ and @RRDPARAM@ items to pick unique colors and a matching text for the graph legend:

[disk]

        FNPATTERN disk(.*).rrd

        TITLE Disk Utilization

        YAXIS % Full

        DEF:p@RRDIDX@=@RRDFN@:pct:AVERAGE

        LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@

        -u 100

        -l 0

        GPRINT:p@RRDIDX@:LAST: : %5.1lf (cur)

        GPRINT:p@RRDIDX@:MAX: : %5.1lf (max)

        GPRINT:p@RRDIDX@:MIN: : %5.1lf (min)

        GPRINT:p@RRDIDX@:AVERAGE: : %5.1lf (avg)\n

 

ADVANCED GRAPH TITLES

Normally the title of a graph is a static text defined in the graphs.cfg file. However, there may be situations where you want to use different titles for the same type of graph, e.g. if you are incorporating RRD files from MRTG into Xymon. In that case you can setup the TITLE definition so that it runs a custom script to determine the graph title. Like this:

       TITLE exec:/usr/local/bin/graphitle

The /usr/local/bin/graphtitle command is then called with the hostname, the graphtype, the period string, and all of the RRD files used as parameters. The script must generate one line of output, which is then used as the title of the graph. Each of the RRD pathname parameters will be enclosed in double quotes.

 

ENVIRONMENT

TEST2RRD Maps service names to graph definitions.

 

NOTES

Most of the RRD graph definitions shipped with Xymon have been ported from the definitions in the larrd-grapher.cgi CGI from LARRD 0.43c.

 

SEE ALSO

xymonserver.cfg(5), rrdtool(1), rrdgraph(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
ADVANCED GRAPH TITLES
ENVIRONMENT
NOTES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/clientlaunch.cfg.5.html0000664000076400007640000000265313534041733023037 0ustar rpmbuildrpmbuild Manpage of CLIENTLAUNCH.CFG

CLIENTLAUNCH.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

clientlaunch.cfg - Task definitions for the xymonlaunch utility

 

SYNOPSIS

~xymon/client/etc/clientlaunch.cfg

 

DESCRIPTION

The clientlaunch.cfg file holds the list of tasks that xymonlaunch runs on a Xymon client. This is typically just the Xymon client itself, but you can add custom test scripts here and have them executed regularly by the Xymon scheduler.

 

FILE FORMAT

See the tasks.cfg(5) description.

 

SEE ALSO

xymonlaunch(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/tasks.cfg.5.html0000664000076400007640000001631613534041733021514 0ustar rpmbuildrpmbuild Manpage of TASKS.CFG

TASKS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

tasks.cfg - Task definitions for the xymonlaunch utility

 

SYNOPSIS

~xymon/server/etc/tasks.cfg

 

DESCRIPTION

The tasks.cfg file holds the list of tasks that xymonlaunch runs to perform all of the tasks needed by the Xymon monitor.

 

FILE FORMAT

A task is defined by a key, a command, and optionally also interval, environment, and logfile.

Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. Long lines can be broken up by putting a backslash at the end of the line and continuing the entry on the next line.

An entry looks like this:


    [xymond]

          ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg

          CMD /usr/local/xymon/server/bin/xymond


    [updateweb]

          ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg

          CMD /usr/local/xymon/server/bin/xymongen

          NEEDS xymond

          GROUP webupdates

          INTERVAL 5m

          ONHOST localhost

          MAXTIME 10m

          LOGFILE /var/log/xymon/updateweb.log


    [monthlyreport]

          ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg

          CMD /usr/local/xymon/server/ext/monthlyreport.sh

          CRONDATE 30 4 1 * *

The key is enclosed in angle brackets, and must be unique for each task. You can choose your key-names as you like, they are only used internally in xymonlaunch to identify each task.

The command is defined by the CMD keyword. This is the full command including any options you want to use for this task. This is required for all tasks.

The DISABLED keyword means that this command is disabled. xymonlaunch will not start this task. It is recommended that you use this to disable standard tasks, instead of removing them or commenting them out. Upgrades to Xymon will add standard tasks back into the file, so unless you have them listed as DISABLED then tasks may re-appear unexpectedly after an upgrade. There is also a corresponding ENABLED keyword, to explicitly enable a task.

The ONHOST keyword tells xymonlaunch that this task should only run on specific hosts. After the ONHOST keyword, you must provide a "regular expression"; if the hostname where xymonlaunch runs matches this expression, then the task will run. If it doesn't match, then the task is treated as if it were DISABLED.

The MAXTIME keyword sets a maximum time that the task may run; if exceeded, xymonlaunch will kill the task. The time is in seconds by default, you can specify minutes, hours or days by adding an "m", "h" or "d" after the number. By default there is no upper limit on how long a taskmay run.

The NEEDS instructs xymonlaunch not to run this task unless the task defined by the NEEDS keyword is already running. This is used e.g. to delay the start of some application until the needed daemons have been started. The task that must be running is defined by its key.

The GROUP keyword can be used to limit the number of tasks that may run simultaneously. E.g. if you are generating multiple pagesets of webpages, you don't want them to run at the same time. Putting them into a GROUP will cause xymonlaunch to delay the start of new tasks, so that only one task will run per group. You can change the limit by defining the group before the tasks, with a "GROUP groupname maxtasks" line.

The INTERVAL keyword defines how often this command is executed. The example shows a command that runs every 5 minutes. If no interval is given, the task is only run once - this is useful for tasks that run continually as daemons - although if the task stops for some reason, then xymonlaunch will attempt to restart it. Intervals can be specified in seconds (if you just put a number there), or in minutes (5m), hours (2h), or days (1d).

The CRONDATE keyword is used for tasks that must run at regular intervals or at a specific time. The time specification is identical to the one used by cron in crontab(5) entries, i.e. a sequence of numbers for minute, hour, day-of-month, month and day-of-week. Three-letter abbreviations in english can be used for the month and day-of-week fields. An asterisk is a wildcard. So in the example above, this job would run once a month, at 4:30 AM on the 1st day of the month.

The ENVFILE setting points to a file with definitions of environment variables. Before running the task, xymonlaunch will setup all of the environment variables listed in this file. Since this is a per-task setting, you can use the same xymonlaunch instance to run e.g. both the server- and client-side Xymon tasks. If this option is not present, then the environment defined to xymonlaunch is used.

The ENVAREA setting modifies which environment variables are loaded, by picking up the ones that are defined for this specific "area". See xymonserver.cfg(5) for information about environment areas.

The LOGFILE setting defines a logfile for the task. xymonlaunch will start the task with stdout and stderr redirected to this file. If this option is not present, then the output goes to the same location as the xymonlaunch output.

 

SEE ALSO

xymonlaunch(8), xymond(8), crontab(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/alerts.cfg.5.html0000664000076400007640000002457013534041733021662 0ustar rpmbuildrpmbuild Manpage of ALERTS.CFG

ALERTS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

alerts.cfg - Configuration for for xymond_alert module

 

SYNOPSIS

~xymon/server/etc/alerts.cfg

 

DESCRIPTION

The alerts.cfg file controls the sending of alerts by Xymon when monitoring detects a failure.

 

FILE FORMAT

The configuration file consists of rules, that may have one or more recipients associated. A recipient specification may include additional rules that limit the circumstances when this recipient is eligible for receiving an alert.

Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. Long lines can be broken up by putting a backslash at the end of the line and continuing the entry on the next line.

 

RULES

A rule consists of one of more filters using these keywords:

PAGE=targetstring Rule matching an alert by the name of the page in Xymon. This is the path of the page as defined in the hosts.cfg file. E.g. if you have this setup:

page servers All Servers
subpage web Webservers
10.0.0.1 www1.foo.com
subpage db Database servers
10.0.0.2 db1.foo.com

Then the "All servers" page is found with PAGE=servers, the "Webservers" page is PAGE=servers/web and the "Database servers" page is PAGE=servers/db. Note that you can also use regular expressions to specify the page name, e.g. PAGE=%.*/db would find the "Database servers" page regardless of where this page was placed in the hierarchy.

The PAGE name of top-level page is an empty string. To match this, use PAGE=%^$ to match the empty string.

EXPAGE=targetstring Rule excluding an alert if the pagename matches.

DISPLAYGROUP=groupstring Rule matching an alert by the text of the display-group (text following the group, group-only, group-except heading) in the hosts.cfg file. "groupstring" is the text for the group, stripped of any HTML tags. E.g. if you have this setup:

group Web
10.0.0.1 www1.foo.com
10.0.0.2 www2.foo.com
group Production databases
10.0.1.1 db1.foo.com

Then the hosts in the Web-group can be matched with DISPLAYGROUP=Web, and the database servers can be matched with DISPLAYGROUP="Production databases". Note that you can also use regular expressions, e.g. DISPLAYGROUP=%database. If there is no group-setting for the host, use "DISPLAYGROUP=NONE".

EXDISPLAYGROUP=groupstring Rule excluding a group by matching the display-group string.

HOST=targetstring Rule matching an alert by the hostname.

EXHOST=targetstring Rule excluding an alert by matching the hostname.

SERVICE=targetstring Rule matching an alert by the service name.

EXSERVICE=targetstring Rule excluding an alert by matching the service name.

GROUP=groupname Rule matching an alert by the group name. Groupnames are assigned to a status via the GROUP setting in the analysis.cfg file.

EXGROUP=groupname Rule excluding an alert by the group name. Groupnames are assigned to a status via the GROUP setting in the analysis.cfg file.

CLASS=classname Rule matching an alert by the class that the host belongs to. By default, the classname is the operating system name; you can set another class either in hosts.cfg(5) using the CLASS tag, or a client running on the server can set the class (via a parameter to the client startup-script).

EXCLASS=classname Rule excluding an alert by the class name.

COLOR=color[,color] Rule matching an alert by color. Can be "red", "yellow", or "purple". The forms "!red", "!yellow" and "!purple" can also be used to NOT send an alert if the color is the specified one.

TIME=timespecification Rule matching an alert by the time-of-day. This is specified as the DOWNTIME timespecification in the hosts.cfg file.

EXTIME=timespecification Rule excluding an alert by the time-of-day. This is specified as the DOWNTIME timespecification in the hosts.cfg file.

DURATION>time, DURATION<time Rule matching an alert if the event has lasted longer/shorter than the given duration. E.g. DURATION>1h (lasted longer than 1 hour) or DURATION<30 (only sends alerts the first 30 minutes). The duration is specified as a number, optionally followed by 'm' (minutes, default), 'h' (hours) or 'd' (days).

RECOVERED Rule matches if the alert has recovered from an alert state.

NOTICE Rule matches if the message is a "notify" message. This type of message is sent when a host or test is disabled or enabled.

The "targetstring" is either a simple pagename, hostname or servicename, OR a '%' followed by a Perl-compatible regular expression. E.g. "HOST=%www(.*)" will match any hostname that begins with "www". The same for the "groupname" setting.

 

RECIPIENTS

The recipients are listed after the initial rule. The following keywords can be used to define recipients:

MAIL address[,address] Recipient who receives an e-mail alert. This takes one parameter, the e-mail address. The strings "&host&", "&service&" and "&color&" in an address will be replaced with the hostname, service and color of the alert, respectively.

SCRIPT /path/to/script recipientID Recipient that invokes a script. This takes two parameters: The script filename, and the recipient that gets passed to the script. The strings "&host&", "&service&" and "&color&" in the recipientID will be replaced with the hostname, service and color of the alert, respectively.

IGNORE This is used to define a recipient that does NOT trigger any alerts, and also terminates the search for more recipients. It is useful if you have a rule that handles most alerts, but there is just that one particular server where you don't want cpu alerts on Monday morning. Note that the IGNORE recipient always has the STOP flag defined, so when the IGNORE recipient is matched, no more recipients will be considered. So the location of this recipient in your set of recipients is important.

FORMAT=formatstring Format of the text message with the alert. Default is "TEXT" (suitable for e-mail alerts). "PLAIN" is the same as text, but without the URL link to the status webpage. "SMS" is a short message with no subject for SMS alerts. "SCRIPT" is a brief message template for scripts.

REPEAT=time How often an alert gets repeated. As with DURATION, time is a number optionally followed by 'm', 'h' or 'd'.

UNMATCHED The alert is sent to this recipient ONLY if no other recipients received an alert for this event.

STOP Stop looking for more recipients after this one matches. This is implicit on IGNORE recipients.

Rules You can specify rules for a recipient also. This limits the alerts sent to this particular recipient.

 

MACROS

It is possible to use macros in the configuration file. To define a macro:

       $MYMACRO=text extending to end of line

After the definition of a macro, it can be used throughout the file. Wherever the text $MYMACRO appears, it will be substituted with the text of the macro before any processing of rules and recipients.

It is possible to nest macros, as long as the macro is defined before it is used.

 

ALERT SCRIPTS

Alerts can go out via custom scripts, by using the SCRIPT keyword for a recipient. Such scripts have access to the following environment variables:

BBALPHAMSG The full text of the status log triggering the alert

ACKCODE The "cookie" that can be used to acknowledge the alert

RCPT The recipientID from the SCRIPT entry

BBHOSTNAME The name of the host that the alert is about

MACHIP The IP-address of the host that has a problem

BBSVCNAME The name of the service that the alert is about

BBSVCNUM The numeric code for the service. From the SVCCODES definition.

BBHOSTSVC HOSTNAME.SERVICE that the alert is about.

BBHOSTSVCCOMMAS As BBHOSTSVC, but dots in the hostname replaced with commas

BBNUMERIC A 22-digit number made by BBSVCNUM, MACHIP and ACKCODE.

RECOVERED Is "0" if the service is alerting, "1" if the service has recovered, "2" if the service was disabled.

EVENTSTART Timestamp when the current status (color) began.

SECS Number of seconds the service has been down.

DOWNSECSMSG When recovered, holds the text "Event duration : N" where N is the DOWNSECS value.

CFID Line-number in the alerts.cfg file that caused the script to be invoked. Can be useful when troubleshooting alert configuration rules.

 

SEE ALSO

xymond_alert(8), xymond(8), xymon(7), the "Configuring Xymon Alerts" guide in the Online documentation.


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
RULES
RECIPIENTS
MACROS
ALERT SCRIPTS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/combo.cfg.5.html0000664000076400007640000001306413534041733021463 0ustar rpmbuildrpmbuild Manpage of COMBO.CFG

COMBO.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

combo.cfg - Configuration of combostatus tool

 

SYNOPSIS

$XYMONHOME/etc/combo.cfg

 

DESCRIPTION

combostatus(1) uses it's own configuration file, $XYMONHOME/etc/combo.cfg Each line in this file defines a combined test.

 

FILE FORMAT

Each line of the file defines a new combined test. Blank lines and lines starting with a hash mark (#) are treated as comments and ignored.

The configuration file uses the hostnames and testnames that are already used in your Xymon hosts.cfg file. These are then combined using normal logical operators - "||" for "or", "&&" for "and" etc.

A simple test - e.g. "Web1.http" - results in the value "1" if the "http" test for server "Web1" is green, yellow or clear. It yields the value "0" if it is red, purple or blue.

Apart from the logical operations, you can also do integer arithmetic and comparisons. E.g. the following is valid:

WebCluster.http = (Web1.http + Web2.http + Web3.http) >= 2

This test is green if two or more of the http tests for Web1, Web2 and Web3 are green.

The full range of operators are:


        +      Add
        -      Subtract
        *      Multiply
        /      Divide
        %      Modulo
        |      Bit-wise "or"
        &      Bit-wise "and"
        ||     Logical "or"
        &&     Logical "and"
        >      Greater than
        <      Less than
        >=     Greater than or equal
        <=     Less than or equal
        ==     Equal

There is currently no support for a "not" operator. If you need it, use the transcription "(host.test == 0)" instead of "!host.test".

NB: All operators have EQUAL PRECEDENCE. If you need something evaluated in a specific order, use parentheses to group the expressions together.

If the expression comes out as "0", the combined test goes red. If it comes out as non-zero, the combined test is green.

Note: If the expression involves hostnames with a character that is also an operator - e.g. if you have a host "t1-router-newyork.foo.com" with a dash in the hostname - then the operator-character must be escaped with a backslash '\' in the expression, or it will be interpreted as an operator. E.g. like this:


 nyc.conn = (t1\-router\-nyc.conn || backup\-router\-nyc.conn)

 

EXAMPLE

WebCluster.http = (Web1.http || Web2.http)
AppSrvCluster.procs = (AppSrv1.conn && AppSrv1.procs) || (AppSrv2.conn && AppSrv2.procs)
Customer.cluster = WebCluster.http && AppSrvCluster.procs

The first line defines a new test, with hostname "WebCluster" and the columnname "http". It will be green if the http test on either the "Web1" or the "Web2" server is green.

The second line defines a "procs" test for the "AppSrvCluster" host. Each of the AppSrv1 and AppSrv2 hosts is checked for "conn" (ping) and their "procs" test. On each host, both of these must be green, but the combined test is green if that condition is fulfilled on just one of the hosts.

The third line uses the two first tests to build a "double combined" test, defining a test that shows the overall health of the system.

 

FILES

$XYMONHOME/etc/combo.cfg

 

SEE ALSO

combostatus(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE FORMAT
EXAMPLE
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/cgioptions.cfg.5.html0000664000076400007640000001022413534041734022536 0ustar rpmbuildrpmbuild Manpage of CGIOPTIONS.CFG

CGIOPTIONS.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

cgioptions.cfg - Command-line parameters for the Xymon CGI tools

 

SYNOPSIS

$XYMONHOME/etc/cgioptions.cfg

 

DESCRIPTION

cgioptions.cfg(1) controls the command-line options passed to all of the Xymon CGI tools through their respective shell-script wrappers. Typically the options listed here are used for system-wide configuration of the CGI utilities, e.g. to define where they read configuration files.

The exact set of command-line options available are described in the man-page for each of the CGI utilities.

The file is "sourced" into the shell script wrapper, so assignments to the CGI-specific variables must follow standard shell-script syntax.

 

SETTINGS

CGI_ACKINFO_OPTS
Options for the ackinfo.cgi(1) utility.

CGI_ACK_OPTS
Options for the acknowledge.cgi(1) utility.

CGI_CSVINFO_OPTS
Options for the csvinfo.cgi(1) utility.

CGI_DATEPAGE_OPTS
Options for the datepage.cgi(1) utility.

CGI_ENADIS_OPTS
Options for the enadis.cgi(8) utility.

CGI_EVENTLOG_OPTS
Options for the eventlog.cgi(1) utility.

CGI_FINDHOST_OPTS
Options for the findhost.cgi(1) utility.

CGI_HIST_OPTS
Options for the history.cgi(1) utility.

CGI_COLUMNDOC_OPTS
Xymon-specific options for column documentation. This uses the csvinfo.cgi(1) utility with the server/etc/columndoc.cfg configuration file.

CGI_CONFREPORT_OPTS
Options for the confreport.cgi(1) utility.

CGI_SHOWGRAPH_OPTS
Options for the showgraph.cgi(1) utility.

CGI_HOSTGRAPHS_OPTS
Options for the hostgraphs.cgi(1) utility.

CGI_CRITEDIT_OPTS
Options for the criticaleditor.cgi(1) utility.

CGI_CRITVIEW_OPTS
Options for the criticalview.cgi(1) utility.

CGI_REPLOG_OPTS
Options for the reportlog.cgi(1) utility.

CGI_REP_OPTS
Options for the report.cgi(1) utility.

CGI_SNAPSHOT_OPTS
Options for the snapshot.cgi(1) utility.

CGI_SVCHIST_OPTS
Options for the svcstatus.cgi(1) utility when used to view historical logs. Note that the "--historical" option must be included in this setting.

CGI_SVC_OPTS
Options for the svcstatus.cgi(1) utility.

 

SEE ALSO

xymon(7), the individual CGI utility man-pages.


 

Index

NAME
SYNOPSIS
DESCRIPTION
SETTINGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/xymonclient.cfg.5.html0000664000076400007640000000575313534041733022743 0ustar rpmbuildrpmbuild Manpage of XYMONCLIENT.CFG

XYMONCLIENT.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonclient.cfg - Xymon client environment variables

 

DESCRIPTION

Xymon programs use multiple environment variables beside the normal set of variables. For the Xymon client, the environment definitions are stored in the ~xymon/client/etc/xymonclient.cfg file. Each line in this file is of the form NAME=VALUE and defines one environment variable NAME with the value VALUE.

 

SETTINGS

XYMSRV
The IP-address used to contact the Xymon server. Default: Chosen when the Xymon client was compiled.

XYMSERVERS
List of IP-addresses of Xymon servers. Data will be sent to all of the servers listed here. This setting is only used if XYMSRV=0.0.0.0.

XYMONDPORT
The port number for used to contact the Xymon server. Default: 1984.

XYMONHOME
The Xymon client top-level directory. Default: The $XYMONCLIENTHOME setting inherited from the "runclient.sh" script which starts the Xymon client.

XYMONCLIENTLOGS
The directory for the Xymon clients' own log files. Default: $XYMONHOME/logs

XYMONTMP
Directory used for temporary files. Default: $XYMONHOME/tmp/

XYMON
Full path to the xymon(1) client program. Default: $XYMONHOME/bin/xymon.

Commands
Many extension scripts expect a series of environment variables to point at various system utilities. These are included in the file when the client is built.

 

INHERITED SETTINGS

Some environment variables are inherited from the "runclient.sh" script which launches the Xymon client:

MACHINEDOTS
The hostname of the local system. Default: Taken from "uname -n".

MACHINE
The hostname of the local system, with dots replaced by commas. For compatibility with Big Brother extension scripts.

SERVEROSTYPE
The operating system of the local system, in lowercase. Default: taken from "uname -s".

XYMONCLIENTHOME
The top-level directory for the Xymon client. Default: The location of the "runclient.sh" script.

 

SEE ALSO

xymon(7)


 

Index

NAME
DESCRIPTION
SETTINGS
INHERITED SETTINGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/client-local.cfg.5.html0000664000076400007640000002373513534041733022740 0ustar rpmbuildrpmbuild Manpage of CLIENT\-LOCAL.CFG

CLIENT\-LOCAL.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

client-local.cfg - Local configuration settings for Xymon clients

 

SYNOPSIS

~xymon/server/etc/client-local.cfg

 

DESCRIPTION

The client-local.cfg file contains settings that are used by each Xymon client when it runs on a monitored host. It provides a convenient way of configuring clients from a central location without having to setup special configuration maintenance tools on all clients.

The client-local.cfg file is currently used to configure what logfiles the client should fetch data from, to be used as the basis for the "msgs" status column; and to configure which files and directories are being monitored in the "files" status column.

Note that there is a dependency between the client-local.cfg file and the analysis.cfg(5) file. When monitoring e.g. a logfile, you must first enter it into the client-local.cfg file, to trigger the Xymon client into reporting any data about the logfile. Next, you must configure analysis.cfg so the Xymon server knows what to look for in the file data sent by the client. So: client-local.cfg defines what raw data is collected by the client, and analysis.cfg defines how to analyze them.

 

PROPAGATION TO CLIENTS

The client-local.cfg file resides on the Xymon server.

When clients connect to the Xymon server to send in their client data, they will receive part of this file back from the Xymon server. The configuration received by the client is then used the next time the client runs.

This method of propagating the configuration means that there is a delay of up to two poll cycles (i.e. 5-10 minutes) from a configuration change is entered into the client-local.cfg file, and until you see the result in the status messages reported by the client.

By default, xymond will look for a matching entry by matching the client hostname, classname or operating system name against the section expressions. Hostname matches are used first, then classname matches, then OS matches. The first match found is the one that is returned to the client.

If xymond is started with the "--merge-clientlocal" option, then xymond will instead merge all of the matching sections into one, and return all of this data to the client. So you can have host-specific entries, and then supplement them with class- or os-generic entries. Note that the merging does not remove entries, so if you have e.g. a "log" entry defined in both a hostname- and an osname-matching section, then both entries will be sent back to the client.

 

FILE FORMAT

The file is divided into sections, delimited by "[name]" lines. A section name can be either an operating system identifier - linux, solaris, hp-ux, aix, freebsd, openbsd, netbsd, darwin - a class, or a hostname. When deciding which section to send to a client, Xymon will first look for a section named after the hostname of the client; if such a section does not exist, it will look for a section named by the operating system of the client. So you can configure special configurations for individual hosts, and have a default configuration for all other hosts of a certain type.

It will often be practical to use regular expressions for hostnames. To do this you must use


    [host=<expression>]

where <expression> is a Perl-compatible regular expression. The same kind of matching can be done on operating system or host class, using


    [os=<expresssion>]

    [class=<expression>]

Apart from the section delimiter, the file format is free-form, or rather it is defined by the tools that make use of the configuration.

 

LOGFILE CONFIGURATION ENTRIES

A logfile configuration entry looks like this:


    log:/var/log/messages:10240

    ignore MARK

    trigger Oops

The log:FILENAME:SIZE line defines the filename of the log, and the maximum amount of data (in bytes) to send to the Xymon server. FILENAME is usually an explicit full-path filename on the client. If it is enclosed in backticks, it is a command which the Xymon client runs and each line of output from this command is then used as a filename. This allows scripting which files to monitor, e.g. if you have logfiles that are named with some sort of timestamp. If FILENAME is enclosed in angle brackets it is treated as a glob and passed through the local glob(3) function first.

The ignore PATTERN line (optional) defines lines in the logfile which are ignored entirely, i.e. they are stripped from the logfile data before sending it to the Xymon server. It is used to remove completely unwanted "noise" entries from the logdata processed by Xymon. "PATTERN" is a regular expression.

The trigger PATTERN line (optional) is used only when there is more data in the log than the maximum size set in the "log:FILENAME:SIZE" line. The "trigger" pattern is then used to find particularly interesting lines in the logfile - these will always be sent to the Xymon server. After picking out the "trigger" lines, any remaining space up to the maximum size is filled in with the most recent entries from the logfile. "PATTERN" is a regular expression.

 

COUNTING LOGENTRIES

A special type of log-handling is possible, where the number of lines matching a regular expressions are merely counted. This is linecount:FILENAME, followed by a number of lines of the form ID:PATTERN. E.g.


    linecount:/var/log/messages

    diskerrors:I/O error.*device.*hd

    badlogins:Failed login

 

FILE CONFIGURATION ENTRIES

A file monitoring entry is used to watch the meta-data of a file: Owner, group, size, permissions, checksum etc. It looks like this:


    file:/var/log/messages[:HASH]

The file:FILENAME line defines the filename of the file to monitor. As with the "log:" entries, a filename enclosed in backticks means a command which will generate the filenames dynamically. The optional [:HASH] setting defines what type of hash to compute for the file: md5, rmd160, sha1, or sha256, sha512, sha224, or sha384. By default, no hash is calculated.
NOTE: If you want to check multiple files using a wildcard, you must use a command to generate the filenames. Putting wildcards directly into the file: entry will not work.

 

DIRECTORY CONFIGURATION ENTRIES

A directory monitoring entry is used to watch the size of a directory and any sub-directories. It looks like this:


    dir:DIRECTORYNAME

The dir:DIRECTORYNAME line defines the filename of the file to monitor. As with the "log:" entries, a filename enclosed in backticks means a command which will generate the filenames dynamically and a filename enclosed in angle brackets will be treated as a fileglob. The Xymon client will run the du(1) command with the directoryname as parameter, and send the output back to the Xymon server.
NOTE: If you want to check multiple directories using a wildcard, you must use a command or glob to generate the directory names. Putting wildcards directly into the dir: entry will not work. E.g. use something like
       dir:`find /var/log -maxdepth 1 -type d`

The "du" command used can be configured through the DU environment variable in the xymonclient.cfg file if needed. If not specified, du -k is used, as on some systems by default du reports data in disk blocks instead of KB (e.g. Solaris).

 

NOTES

The ability of the Xymon client to calculate file hashes and monitor those can be used for file integrity validation on a small scale. However, there is a significant processing overhead in calculating these every time the Xymon client runs, so this should not be considered a replacement for host-based intrusion detection systems such as Tripwire or AIDE.

Use of the directory monitoring on directory structures with a large number of files and/or sub-directories can be quite ressource-intensive.

 

SEE ALSO

analysis.cfg(5), xymond_client(8), xymond(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
PROPAGATION TO CLIENTS
FILE FORMAT
LOGFILE CONFIGURATION ENTRIES
COUNTING LOGENTRIES
FILE CONFIGURATION ENTRIES
DIRECTORY CONFIGURATION ENTRIES
NOTES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/critical.cfg.5.html0000664000076400007640000000365713534041734022166 0ustar rpmbuildrpmbuild Manpage of CRITICAL.CFG

CRITICAL.CFG

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

critical.cfg - Configuration of the showgraph CGI

 

SYNOPSIS

$XYMONHOME/etc/critical.cfg

 

DESCRIPTION

critical.cgi(1) uses the configuration file $XYMONHOME/etc/critical.cfg to determine which of the statuses currently in a red or yellow state should appear on the Critical Systems view.

This file should not be edited manually. It is maintained by the criticaleditor.cgi(1) utility via a web-based frontend.

 

FILE PERMISSIONS

Since the file is maintained by a web front-end tool, the userid running Web CGI scripts must have write-permission to the file. Typically, this means it must have a group-ownership matching your webserver userid, and group-write permissions (mode 664).

When editing the file with the web front-end, a backup file is created. Therefore the critical.cfg.bak file should have identical permissions.

 

SEE ALSO

criticalview.cgi(1), criticaleditor.cgi(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
FILE PERMISSIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man5/xymonweb.5.html0000664000076400007640000001555113534041733021501 0ustar rpmbuildrpmbuild Manpage of XYMONWEB

XYMONWEB

Section: File Formats (5)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

Xymon-Web-Templates - web page headers, footers and forms.

 

DESCRIPTION

The Xymon webpages are somewhat customizable, by modifying the header- and footer-templates found in the ~xymon/server/web/ directory. There are usually two or more files for a webpage: A template_header file which is the header for this webpage, and a template_footer file which is the footer. Webpages where entry forms are used have a template_form file which is the data-entry form.

With the exception of the bulletin files, the header files are inserted into the HTML code at the very beginning and the footer files are inserted at the bottom.

The following templates are available:

bulletin
A bulletin_header and bulletin_footer is not shipped with Xymon, but if they exist then the content of these files will be inserted in all HTML documents generated by Xymon. The "bulletin_header" contents will appear after the normal header for the webpage, and the "bulletin_footer" will appear just before the normal footer for the webpage. These files can be used to post important information about the Xymon system, e.g. to notify users of current operational or monitoring problems.

acknowledge
Header, footer and form template for the Xymon acknowledge alert webpage generated by acknowledge.cgi(1)

stdnormal
Header and footer for the Xymon Main view webpages, generated by xymongen(1)

stdnongreen
Header and footer for the Xymon All non-green view webpage, generated by xymongen(1)

stdcritical (DEPRECATED)
Header and footer for the now deprecated old critical webpage, generated by xymongen. You should use the newer criticalview.cgi(1) utility instead, which uses the critical templates.

repnormal
Header and footer for the Xymon Main view availability report webpages, generated by xymongen(1) when running in availability report mode.

snapnormal
Header and footer for the Xymon Main view snapshot webpages, generated by xymongen(1) when running in snapshot report mode.

snapnongreen
Header and footer for the Xymon All non-green view snapshot webpage, generated by xymongen(1) when running in snapshot report mode.

columndoc
Header and footer for the Xymon Column documentation webpages, generated by the csvinfo.cgi(1) utility in the default Xymon configuration.

confreport
Header and footer for the Xymon Configuration report webpage, generated by the confreport.cgi(1) utility. Note that there are also "confreport_front" and "confreport_back" templates, these are inserted into the generated report before the hostlist, and before the column documentation, respectively.

event
Header, footer and form for the Xymon Eventlog report, generated by eventlog.cgi(1)

findhost
Header, footer and form for the Xymon Find host webpage, generated by findhost.cgi(1)

graphs
Header and footer for the Xymon Graph details webpages, generated by showgraph.cgi(1)

hist
Header and footer for the Xymon History webpage, generated by history.cgi(1)

histlog
Header and footer for the Xymon Historical status-log webpage, generated by svcstatus.cgi(1) utility when used to show a historical (non-current) status log.

critical
Header and footer for the Xymon Critical Systems view webpage, generated by criticalview.cgi(1)

hostsvc
Header and footer for the Xymon Status-log webpage, generated by svcstatus.cgi(1) utility when used to show a current status log.

info
Header and footer for the Xymon Info column webpage, generated by svcstatus.cgi(1) utility when used to show the host configuration page.

maintact
Header and footer for the Xymon webpage, generated by enadis.cgi(1) utility when using the Enable/Disable "preview" mode.

maint
Header, footer and form for the Xymon Enable/disable webpage, generated by enadis.cgi(1)

critack
Form show on the status-log webpage when viewed from the "Critical Systems" overview. This form is used to acknowledge a critical status by the operators monitoring the Critical Systems view.

critedit
Header, footer and form for the Critical Systems Editor, the criticaleditor.cgi(1) utility.

replog
Header and footer for the Xymon Report status-log webpage, generated by svcstatus.cgi(1) utility when used to show a status log for an availability report.

report
Header, footer and forms for selecting a pre-generated Availability Report. Handled by the datepage.cgi(1) utility.

snapshot
Header and footer for the Xymon Snapshot report selection webpage, generated by snapshot.cgi(1)

 

SEE ALSO

xymongen(1), svcstatus.cgi(1), xymon(7)


 

Index

NAME
DESCRIPTION
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/0000775000076400007640000000000013534041774016572 5ustar rpmbuildrpmbuildxymon-4.3.30/docs/manpages/man1/xymonnet.1.html0000664000076400007640000007155213534041733021505 0ustar rpmbuildrpmbuild Manpage of XYMONNET

XYMONNET

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonnet - Xymon network test tool  

SYNOPSIS

xymonnet [--ping|--noping] [--timeout=N] [options] [hostname] [hostname]
(See the OPTIONS section for a description of the available command-line options).

 

DESCRIPTION

xymonnet(1) handles the network tests of hosts defined in the Xymon configuration file, hosts.cfg. It is normally run at regular intervals by xymonlaunch(8) via an entry in the tasks.cfg(5) file.

xymonnet does all of the normal tests of TCP-based network services (telnet, ftp, ssh, smtp, pop, imap ....) - i.e. all of the services listed in protocols.cfg. For these tests, a completely new and very speedy service- checker has been implemented.

xymonnet has built-in support for testing SSL-enabled protocols, e.g. imaps, pop3s, nntps, telnets, if SSL-support was enabled when configuring xymonnet. The full list of known tests is found in the protocols.cfg(5) file in $XYMONHOME/etc/protocols.cfg.

In addition, it implements the "dns" and "dig" tests for testing DNS servers.

xymonnet also implements a check for NTP servers - this test is called "ntp". If you want to use it, you must define the NTPDATE environment variable to point at the location of your ntpdate(1) program.

Note: xymonnet performs the connectivity test (ping) based on the hostname, unless the host is tagged with "testip" or the "--dns=ip" option is used. So the target of the connectivity test can be determined by your /etc/hosts file or DNS.

By default, all servers are tested - if XYMONNETWORK is set via xymonserver.cfg(5) then only the hosts marked as belonging to this network are tested. If the command-line includes one or more hostnames, then only those servers are tested.

 

GENERAL OPTIONS

--timeout=N
Determines the timeout (in seconds) for each service that is tested. For TCP tests (those from XYMONNETSVCS), if the connection to the service does not succeed within N seconds, the service is reported as being down. For HTTP tests, this is the absolute limit for the entire request to the webserver (the time needed to connect to the server, plus the time it takes the server to respond to the request). Default: 10 seconds

--conntimeout=N
This option is deprecated, and will be ignored. Use the --timeout option instead.

--cmdtimeout=N
This option sets a timeout for the external commands used for testing of NTP and RPC services, and to perform traceroute.

--concurrency=N
Determines the number of network tests that run in parallel. Default is operating system dependent, but will usually be 256. If xymonnet begins to complain about not being able to get a "socket", try running xymonnet with a lower value like 50 or 100.

--dns-timeout=N (default: 30 seconds)
xymonnet will timeout all DNS lookups after N seconds. Any pending DNS lookups are regarded as failed, i.e. the network tests that depend on this DNS lookup will report an error.
Note: If you use the --no-ares option, timeout of DNS lookups cannot be controlled by xymonnet.

--dns-max-all=N
Same as "--dns-timeout=N". The "--dns-max-all" option is deprecated and should not be used.

--dns=[ip|only|standard]
Determines how xymonnet finds the IP addresses of the hosts to test. By default (the "standard"), xymonnet does a DNS lookup of the hostname to determine the IP address, unless the host has the "testip" tag, or the DNS lookup fails.
With "--dns=only" xymonnet will ONLY do the DNS lookup; if it fails, then all services on that host will be reported as being down.
With "--dns=ip" xymonnet will never do a DNS lookup; it will use the IP adresse specified in hosts.cfg for the tests. Thus, this setting is equivalent to having the "testip" tag on all hosts. Note that http tests will ignore this setting and still perform a DNS lookup for the hostname given in the URL; see the "xymonnet tags for HTTP tests" section in hosts.cfg(5)

--no-ares
Disable the ARES resolver built into xymonnet. This makes xymonnet resolve hostnames using your system resolver function. You should only use this as a last resort if xymonnet cannot resolve the hostnames you use in the normal way (via DNS or /etc/hosts). One reason for using this would be if you need to resolve hostnames via NIS/NIS+ (a.k.a. Yellow Pages).
The system resolver function does not provide a mechanism for controlling timeouts of the hostname lookups, so if your DNS or NIS server is down, xymonnet can take a very long time to run. The --dns-timeout option is effectively disabled when using this option.

--dnslog=FILENAME
Log failed hostname lookups to the file FILENAME. FILENAME should be a full pathname.

--report[=COLUMNNAME]
With this option, xymonnet will send a status message with details of how many hosts were processed, how many tests were generated, any errors that occurred during the run, and some timing statistics. The default columnname is "xymonnet".

--test-untagged
When using the XYMONNETWORK environment variable to test only hosts on a particular network segment, xymonnet will ignore hosts that do not have any "NET:x" tag. So only hosts that have a NET:$XYMONNETWORK tag will be tested.
With this option, hosts with no NET: tag are included in the test, so that all hosts that either have a matching NET: tag, or no NET: tag at all are tested.

--frequenttestlimit=N
Used with the xymonnet-again.sh(1) Xymon extension. This option determines how long failed tests remain in the frequent-test queue. The default is 1800 seconds (30 minutes).

--timelimit=N
Causes xymonnet to generate a warning if the run-time of xymonnet exceeds N seconds. By default N is set to the value of TASKSLEEP, so a warning triggers if the network tests cannot complete in the time given for one cycle of the xymonnet task. Apart from the warning, this option has no effect, i.e. it will not terminate xymonnet prematurely. So to eliminate any such warnings, use this option with a very high value of N.

--huge=N
Warn if the response from a TCP test is more than N bytes. If you see from the xymonnet status report that you are transferring large amounts of data for your tests, you can enable this option to see which tests have large replies.
Default: 0 (disabled).

--validity=N
Make the test results valid for N minutes before they go purple. By default test results are valid for 30 minutes; if you run xymonnet less often than that, the results will go purple before the next run of xymonnet. This option lets you change how long the status is valid.

--source-ip=IPADDRESS
On multi-homed hosts, this option can be used to explicitly select the source IP address used for the network tests. "IPADDRESS" must be a valid IP-address on the host running xymonnet.

--loadhostsfromxymond
Instead of reading the hosts.cfg file, xymonnet will load the hosts.cfg configuration from the xymond daemon. This eliminates the need for reading the hosts.cfg, and if you have xymond and xymonnet running on different hosts, it also eliminates the need for copying the hosts.cfg file between systems. Note that the "netinclude" option in hosts.cfg is ignored when this option is enabled.

 

OPTIONS FOR TESTS OF THE SIMPLE TCP SERVICES

--checkresponse[=COLOR]
When testing well-known services (e.g. FTP, SSH, SMTP, POP-2, POP-3, IMAP, NNTP and rsync), xymonnet will look for a valid service-specific "OK" response. If another response is seen, this will cause the test to report a warning (yellow) status. Without this option, the response from the service is ignored.
The optional color-name is used to select a color other than yellow for the status message when the response is wrong. E.g. "--checkresponse=red" will cause a "red" status message to be sent when the service does not respond as expected.

--no-flags
By default, xymonnet sends some extra information in the status messages, called "flags". These are used by xymongen e.g. to pick different icons for reversed tests when generating the Xymon webpages. This option makes xymonnet omit these flags from the status messages.

--shuffle
By default, TCP tests run roughly in the order that the hosts are listed in the hosts.cfg file. If you have many tests for one server, this may result in an exceptionally large load when Xymon is testing it because Xymon will perform a lot of tests at the same time. To avoid this, the --shuffle option reorders the sequence of tests so they are spread randomly across all of the servers tested.

 

OPTIONS FOR THE PING TEST

Note: xymonnet uses the program defined by the FPING environment to execute ping-tests - by default, that is the xymonping(1) utility. See xymonserver.cfg(5) for a description of how to customize this, e.g. if you need to run it with "sudo" or a similar tool.

--ping
Enables xymonnet's ping test. The column name used for ping test results is defined by the PINGCOLUMN environment variable in xymonserver.cfg(5).
If not specified, xymonnet uses the CONNTEST environment variable to determine if it should perform the ping test or not. So if you prefer to use another tool to implement ping checks, either set the CONNTEST environment variable to false, or run xymonnet with the "--noping".

--noping
Disable the connectivity test.

--trace
--notrace
Enable/disable the use of traceroute when a ping-test fails. Performing a traceroute for failed ping tests is a slow operation, so the default is not to do any traceroute, unless it is requested on a per-host basis via the "trace" tag in the hosts.cfg(5) entry for each host. The "--trace" option changes this, so the default becomes to run traceroute on all hosts where the ping test fails; you can then disable it on specific hosts by putting a "notrace" tag on the host-entry.

--ping-tasks=N
Spread the task of pinging the hosts over N processes. If you have a very large number of hosts the time it takes to ping all of them can be substantial, even with the use of tools like fping or xymonping that ping many hosts in parallel. This option causes xymonnet to start N separate ping processes, the IP's that are being ping'ed will be divided evenly between these processes.

 

OPTIONS FOR HTTP (WEB) TESTS

--content=CONTENTTESTNAME
Determines the name of the column Xymon displays for content checks. The default is "content". If you have used the "cont.sh" or "cont2.sh" scripts earlier, you may want to use "--content=cont" to report content checks using the same test name as these scripts do.
--bb-proxy-syntax
Adhere to the Big Brother syntax for a URL, which allows specifying a HTTP proxy as part of a URL. See "HTTP Testing via proxy" in the hosts.cfg(5) file for details. Beginning with Xymon 4.3.0, this behaviour is disabled by default since URL's that include other URL's are now much more common. This option restores the old Big Brother-compatible behaviour.

 

OPTIONS FOR SSL CERTIFICATE TESTS

--ssl=SSLCERTTESTNAME
Determines the name of the column Xymon displays for the SSL certificate checks. The default is "sslcert".
--no-ssl
Disables reporting of the SSL certificate check.

--sslwarn=N
--sslalarm=N
Determines the number of days before an SSL certificate expires, where xymonnet will generate a warning or alarm status for the SSL certificate column.

--sslbits=N
Enables checking that the encryption supported by the SSL protocol uses an encryption key of at least N bits. E.g. to trigger an alert if your SSL-enabled website supports less than 128 bits of encryption, use "--sslbits=128". Note: This can be enabled on a per-host basis using the "sslbits=N" setting in hosts.cfg(5)

--sslkeysize=N
Enables checking of the length of the public key in SSL certificates. N is the minimum size of the SSL public key, typically such keys are 2048 bits, but some older certificates may use keys with 1024 bits or less. If you specify this, SSL certificates with keys less than N bits will result in the "sslcert" status going yellow. Default: 0, i.e. this check is disabled.

--no-cipherlist
Do not show encryption cipher details on the "sslcert" status.

--showallciphers
List ALL locally available encryption ciphers on the "sslcert" status.

--sni=[on|off]
Sets the default for whether SSL connections use SNI (Server Name Indication). This can also be set with the "sni" or "nosni" options in hosts.cfg for each host - the hosts.cfg entries override this option. Default: off

 

DEBUGGING OPTIONS

--no-update
Don't send any status updates to the Xymon server. Instead, all messages are dumped to stdout.

--timing
Causes xymonnet to collect information about the time spent in different parts of the program. The information is printed on stdout just before the program ends. Note that this information is also included in the status report sent with the "--report" option.

--debug
Dumps a bunch of status about the tests as they progress to stdout.

--dump[=before|=after|=both]
Dumps internal memory structures before and/or after the tests have executed.

 

INFORMATIONAL OPTIONS

--help or -?
Provide a summary of available command-line options.

--version
Prints the version number of xymonnet

--services
Dump the list of defined TCP services xymonnet knows how to test. Do not run any tests.

 

USING COOKIES IN WEB TESTS

If the file $XYMONHOME/etc/cookies exist, cookies will be read from this file and sent along with the HTTP requests when checking websites. This file is in the Netscape Cookie format, see http://www.netscape.com/newsref/std/cookie_spec.html for details on this format. The curl(1) utility can output a file in this format if run with the "--cookie-jar FILENAME" option.

 

ABOUT SSL CERTIFICATE CHECKS

When xymonnet tests services that use SSL- or TLS-based protocols, it will check that the server certificate has not expired. This check happens automatically for https (secure web), pop3s, imaps, nntps and all other SSL-enabled services (except ldap, see LDAP TESTS below).

All certificates found for a host are reported in one status message.

Note: On most systems, the end-date of the certificate is limited to Jan 19th, 2038. If your certificate is valid after this date, xymonnet will report it as valid only until Jan 19, 2038. This is due to limitations in your operating system C library. See http://en.wikipedia.org/wiki/2038_problem .

 

LDAP TESTS

ldap testing can be done in two ways. If you just put an "ldap" or "ldaps" tag in hosts.cfg, a simple test is performed that just verifies that it is possible to establish a connection to the port running the ldap service (389 for ldap, 636 for ldaps).

Instead you can put an LDAP URI in hosts.cfg. This will cause xymonnet to initiate a full-blown LDAP session with the server, and do an LDAP search for the objects defined by the URI. This requires that xymonnet was built with LDAP support, and relies on an existing LDAP library to be installed. It has been tested with OpenLDAP 2.0.26 (from Red Hat 9) and 2.1.22. The Solaris 8 system ldap library has also been confirmed to work for un-encrypted (plain ldap) access.

The format of LDAP URI's is defined in RFC 2255. LDAP URLs look like this:


  ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]]

where:
  hostport is a host name with an optional ":portnumber"
  dn is the search base
  attrs is a comma separated list of attributes to request
  scope is one of these three strings:
    base one sub (default=base)
  filter is filter
  exts are recognized set of LDAP and/or API extensions.

Example:
  ldap://ldap.example.net/dc=example,dc=net?cn,sn?sub?(cn=*)

All "bind" operations to LDAP servers use simple authentication. Kerberos and SASL are not supported. If your LDAP server requires a username/password, use the "ldaplogin" tag to specify this, cf. hosts.cfg(5) If no username/password information is provided, an anonymous bind will be attempted.

SSL support requires both a client library and an LDAP server that support LDAPv3; it uses the LDAP "STARTTLS" protocol request after establishing a connection to the standard (non-encrypted) LDAP port (usually port 389). It has only been tested with OpenSSL 2.x, and probably will not work with any other LDAP library.

The older LDAPv2 experimental method of tunnelling normal LDAP traffic through an SSL connection - ldaps, running on port 636 - is not supported, unless someone can explain how to get the OpenLDAP library to support it. This method was never formally described in an RFC, and implementations of it are non-standard.

For a discussion of the various ways of running encrypted ldap, see
http://www.openldap.org/lists/openldap-software/200305/msg00079.html
http://www.openldap.org/lists/openldap-software/200305/msg00084.html
http://www.openldap.org/lists/openldap-software/200201/msg00042.html
http://www.openldap.org/lists/openldap-software/200206/msg00387.html

When testing LDAP URI's, all of the communications are handled by the ldap library. Therefore, it is not possible to obtain the SSL certificate used by the LDAP server, and it will not show up in the "sslcert" column.

 

USING MULTIPLE NETWORK TEST SYSTEMS

If you have more than one system running network tests - e.g. if your network is separated by firewalls - then is is problematic to maintain multiple hosts.cfg files for each of the systems. xymonnet supports the NET:location tag in hosts.cfg(5) to distinguish between hosts that should be tested from different network locations. If you set the environment variable XYMONNETWORK e.g. to "dmz" before running xymonnet, then it will only test hosts that have a "NET:dmz" tag in hosts.cfg. This allows you to keep all of your hosts in the same hosts.cfg file, but test different sets of hosts by different systems running xymonnet.

 

XYMONNET INTERNALS

xymonnet first reads the protocols.cfg file to see which network tests are defined. It then scans the hosts.cfg file, and collects information about the TCP service tests that need to be tested. It picks out only the tests that were listed in the protocols.cfg file, plus the "dns", "dig" and "ntp" tests.

It then runs two tasks in parallel: First, a separate process is started to run the "xymonping" tool for the connectivity tests. While xymonping is busy doing the "ping" checks, xymonnet runs all of the TCP-based network tests.

All of the TCP-based service checks are handled by a connection tester written specifically for this purpose. It uses only standard Unix-style network programming, but relies on the Unix "select(2)" system-call to handle many simultaneous connections happening in parallel. Exactly how many parallel connections are being used depends on your operating system - the default is FD_SETSIZE/4, which amounts to 256 on many Unix systems.

You can choose the number of concurrent connections with the "--concurrency=N" option to xymonnet.

Connection attempts timeout after 10 seconds - this can be changed with the "--timeout=N" option.

Both of these settings play a part in deciding how long the testing takes. A conservative estimate for doing N TCP tests is:


   (1 + (N / concurrency)) * timeout

In real life it will probably be less, as the above formula is for every test to require a timeout. Since the most normal use of Xymon is to check for services that are active, you should have a lot less timeouts.

The "ntp" and "rpcinfo" checks rely on external programs to do each test.

 

ENVIRONMENT VARIABLES

XYMONNETWORK
Defines the network segment where xymonnet is currently running. This is used to filter out only the entries in the hosts.cfg(5) file that have a matching "NET:LOCATION" tag, and execute the tests for only those hosts.

MAXMSGSPERCOMBO
Defines the maximum number of status messages that can be sent in one combo message. Default is 0 - no limit.
In practice, the maximum size of a single Xymon message sets a limit - the default value for the maximum message size is 32 KB, but that will easily accommodate 100 status messages per transmission. So if you want to experiment with this setting, I suggest starting with a value of 10.

SLEEPBETWEENMSGS
Defines a a delay (in microseconds) after each message is transmitted to the Xymon server. The default is 0, i.e. send the messages as fast as possible. This gives your Xymon server some time to process the message before the next message comes in. Depending on the speed of your Xymon server, it may be necessary to set this value to half a second or even 1 or 2 seconds. Note that the value is specified in MICROseconds, so to define a delay of half a second, this must be set to the value "500000"; a delay of 1 second is achieved by setting this to "1000000" (one million).

FPING
Command used to run the xymonping(1) utility. Used by xymonnet for connectivity (ping) testing. See xymonserver.cfg(5) for more information about how to customize the program that is executed to do ping tests.

TRACEROUTE
Location of the traceroute(8) utility, or an equivalent tool e.g. mtr(8). Optionally used when a connectivity test fails to pinpoint the network location that is causing the failure.

NTPDATE
Location of the ntpdate(1) utility. Used by xymonnet when checking the "ntp" service.

RPCINFO
Location of the rpcinfo(8) utility. Used by xymonnet for the "rpc" service checks.

 

FILES

~/server/etc/protocols.cfg
This file contains definitions of TCP services that xymonnet can test. Definitions for a default set of common services is built into xymonnet, but these can be overridden or supplemented by defining services in the protocols.cfg file. See protocols.cfg(5) for details on this file.

$XYMONHOME/etc/netrc - authentication data for password-protected webs
If you have password-protected sites, you can put the usernames and passwords for these here. They will then get picked up automatically when running your network tests. This works for web-sites that use the "Basic" authentication scheme in HTTP. See ftp(1) for details - a sample entry would look like this

   machine www.acme.com login fred password Wilma1
Note that the machine-name must be the name you use in the http://machinename/ URL setting - it need not be the one you use for the system-name in Xymon.

$XYMONHOME/etc/cookies
This file may contain website cookies, in the Netscape HTTP Cookie format. If a website requires a static cookie to be present in order for the check to complete, then you can add this cookie to this file, and it will be sent along with the HTTP request. To get the cookies into this file, you can use the "curl --cookie-jar FILE" to request the URL that sets the cookie.

$XYMONTMP/*.status - test status summary
Each time xymonnet runs, if any tests fail (i.e. they result in a red status) then they will be listed in a file name TESTNAME.[LOCATION].status. The LOCATION part may be null. This file is used to determine how long the failure has lasted, which in turn decides if this test should be included in the tests done by xymonnet-again.sh(1)
It is also used internally by xymonnet when determining the color for tests that use the "badconn" or "badTESTNAME" tags.

$XYMONTMP/frequenttests.[LOCATION]
This file contains the hostnames of those hosts that should be retested by the xymonnet-again.sh(1) test tool. It is updated only by xymonnet during the normal runs, and read by xymonnet-again.sh.

 

SEE ALSO

hosts.cfg(5), protocols.cfg(5), xymonserver.cfg(5), xymonping(1), curl(1), ftp(1), fping(1), ntpdate(1), rpcinfo(8)


 

Index

NAME
SYNOPSIS
DESCRIPTION
GENERAL OPTIONS
OPTIONS FOR TESTS OF THE SIMPLE TCP SERVICES
OPTIONS FOR THE PING TEST
OPTIONS FOR HTTP (WEB) TESTS
OPTIONS FOR SSL CERTIFICATE TESTS
DEBUGGING OPTIONS
INFORMATIONAL OPTIONS
USING COOKIES IN WEB TESTS
ABOUT SSL CERTIFICATE CHECKS
LDAP TESTS
USING MULTIPLE NETWORK TEST SYSTEMS
XYMONNET INTERNALS
ENVIRONMENT VARIABLES
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/ghostlist.cgi.1.html0000664000076400007640000000401013534041734022367 0ustar rpmbuildrpmbuild Manpage of GHOSTLIST.CGI

GHOSTLIST.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

ghostlist.cgi - CGI program to view ghost clients  

SYNOPSIS

ghostlist.cgi

 

DESCRIPTION

ghostlist.cgi is invoked as a CGI script via the ghostlist.sh CGI wrapper.

It generates a listing of the Xymon clients that have reported data to the Xymon server, but are not listed in the hosts.cfg(5) file. Data from these clients - called "ghosts" - are ignored, since Xymon does not know which webpage to present the data on.

The listing includes the hostname that the client reports with, the IP-address where the report came from, and how long ago the report arrived.

By far the most common reason for hosts showing up here is that the client uses a hostname without a DNS domain, but the hosts.cfg file uses the hostname with the DNS domain. Or vice versa. You can then use a CLIENT setting in the hosts.cfg file to match the two hostnames together.

 

OPTIONS

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymonping.1.html0000664000076400007640000001145413534041733021647 0ustar rpmbuildrpmbuild Manpage of XYMONPING

XYMONPING

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonping - Xymon ping tool  

SYNOPSIS

xymonping [--retries=N] [--timeout=N] [IP-addresses]

 

DESCRIPTION

xymonping(1) is used for ping testing of the hosts monitored by the xymon(7) monitoring system. It reads a list of IP addresses from stdin, and performs a "ping" check to see if these hosts are alive. It is normally invoked by the xymonnet(1) utility, which performs all of the Xymon network tests.

Optionally, if a list of IP-addresses is passed as command-line arguments, it will ping those IP's instead of reading them from stdin.

xymonping only handles IP-addresses, not hostnames.

xymonping was inspired by the fping(1) tool, but has been written from scratch to implement a fast ping tester without much of the overhead found in other such utilities. The output from xymonping is similar to that of "fping -Ae".

xymonping probes multiple systems in parallel, and the runtime is therefore mostly dependent on the timeout-setting and the number of retries. With the default options, xymonping takes approximately 18 seconds to ping all hosts (tested with an input set of 1500 IP addresses).

 

SUID-ROOT INSTALLATION REQUIRED

xymonping needs to be installed with suid-root privileges, since it requires a "raw socket" to send and receive ICMP Echo (ping) packets.

xymonping is implemented such that it immediately drops the root privileges, and only regains them to perform two operations: Obtaining the raw socket, and optionally binding it to a specific source address. These operations are performed as root, the rest of the time xymonping runs with normal user privileges. Specifically, no user-supplied data or network data is used while running with root privileges. Therefore it should be safe to provide xymonping with the necessary suid-root privileges.

 

OPTIONS

--retries=N
Sets the number of retries for hosts that fail to respond to the initial ping, i.e. the number of ping probes sent in addition to the initial probe. The default is --retries=2, to ping a host 3 times before concluding that it is not responding.

--timeout=N
Determines the timeout (in seconds) for ping probes. If a host does not respond within N seconds, it is regarded as unavailable, unless it responds to one of the retries. The default is --timeout=5.

--responses=N
xymonping normally stops pinging a host after receiving a single response, and uses that to determine the round-trip time. If the first response takes longer to arrive - e.g. because of additional network overhead when first determining the route to the target host - it may skew the round-trip-time reports. You can then use this option to require N responses, and xymonping will calculate the round-trip time as the average of all of responsetimes.

--max-pps=N
Maximum number of packets per second. This limits the number of ICMP packets xymonping will send per second, by enforcing a brief delay after each packet is sent. The default setting is to send a maximum of 50 packets per second. Note that increasing this may cause flooding of the network, and since ICMP packets can be discarded by routers and other network equipment, this can cause erratic behaviour with hosts recorded as not responding when they are in fact OK.

--source=ADDRESS
Use ADDRESS as the source IP address of the ping packets sent. On multi-homed systems, allows you to select the source IP of the hosts going out, which might be necessary for ping to work.

--debug
Enable debug output. This prints out all packets sent and received.

 

SEE ALSO

xymon(7), xymonnet(1), fping(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
SUID-ROOT INSTALLATION REQUIRED
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/confreport.cgi.1.html0000664000076400007640000000555613534041734022550 0ustar rpmbuildrpmbuild Manpage of CONFREPORT.CGI

CONFREPORT.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

confreport.cgi - Xymon Configuration report  

SYNOPSIS

confreport.cgi

 

DESCRIPTION

confreport.cgi is invoked as a CGI script via the confreport.sh CGI wrapper.

confreport.cgi provides a plain HTML (Web) report of the Xymon configuration for a group of hosts; which hosts are included is determined by the hosts available on the webpage from where the CGI script is invoked.

The configuration report include the hostnames, a list of the statuses monitored for each host, and if applicable any configuration settings affecting these. Alerts that may be triggered by status changes are also included.

The report is plain HTML without any images included, and therefore suitable for inclusion into e-mails or other documents that may be accessed outside the Xymon system.

 

OPTIONS

--critical
Report only on the statuses that are configured to show up on the Critical Systems view.

--old-nk-config
Use the deprecated NK tag in hosts.cfg to determine if tests appear on the Critical Systems view.

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

--debug
Enables debugging output.

--nkconfig=FILENAME
Use FILENAME as the configuration file for the Critical Systems information. The default is to load this from $XYMONHOME/etc/critical.cfg

 

BUGS

Client-side configuration done in the analysis.cfg(5) is not currently reflected in the report.

Critical Systems view configuration is not reflected in the report.

 

SEE ALSO

hosts.cfg(5), alerts.cfg(5), analysis.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
BUGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymonpage.cgi.1.html0000664000076400007640000000333513534041734022367 0ustar rpmbuildrpmbuild Manpage of XYMONPAGE

XYMONPAGE

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonpage - Utility to show a webpage using header and footer  

SYNOPSIS

xymonpage [options]

 

DESCRIPTION

xymonpage is a tool to generate a webpage in the Xymon style, with a standard header- and footer as well as a Xymon background. The data to present on the webpage, apart from the header and footer, are passed to xymonpage in stdin. The generated webpage is printed to stdout.

 

OPTIONS

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--hffile=PREFIX
Use the header- and footer-files in $XYMONHOME/web/PREFIX_header and PREFIX_footer. If not specified, stdnormal_header and stdnormal_footer are used.

--color=COLOR
Set the background color of the generated webpage to COLOR. Default: Blue

--debug
Enable debugging output.

 

SEE ALSO

xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/report.cgi.1.html0000664000076400007640000001122413534041734021667 0ustar rpmbuildrpmbuild Manpage of REPORT.CGI

REPORT.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

report.cgi - CGI front-end to xymongen reporting  

SYNOPSIS

report.cgi [--noclean] [xymongen-options]

 

DESCRIPTION

report.cgi is invoked as a CGI script via the report.sh CGI wrapper. It triggers the generation of a Xymon availability report for the timeperiod specified by the CGI parameters.

report.cgi is passed a QUERY_STRING environment variable with the following parameters:


   start-mon (Start month of the report)
   start-day (Start day-of-month of the report)
   start-yr  (Start year of the report)
   end-mon   (End month of the report)
   end-day   (End day-of-month of the report)
   end-yr    (End year of the report)
   style     (Report style)
  The following non-standard parameters are handled by the xymongen version of report.cgi:


   suburl    (Page in report to go to, if not the top page)

The "month" parameters must be specified as the three-letter english month name abbreviation: Jan, Feb, Mar ...

Start- and end-days are in the range 1..31; the start- and end-year must be specified including century (e.g. "2003").

End-times beyond the current time are silently replaced with the current time.

The generated report will include data for the start- and end-days, i.e. the report will begin at 00:00:00 of the start-day, and end at 23:59:59 of the end-day.

The "style" parameter is passed directly to xymongen(1) and should be "crit", "non-crit" or "all". Other values result in undefined behaviour.

All of the processing involved in generating the report is done by invoking xymongen(1) with the proper "--reportopts" option.

 

OPTIONS

--noclean
Do not clean the XYMONREPDIR directory of old reports. Makes the report-tool go a bit faster - instead, you can clean up the XYMONREPDIR directory e.g. via a cron-job.

--env=FILENAME
Load the environment from FILENAME before executing the CGI.

xymongen-options
All other options passed to report.cgi are passed on to the xymongen(1) program building the report files.

 

FILES

$XYMONHOME/web/report_header
HTML template header for the report request form

$XYMONHOME/web/report_footer
HTML template footer for the report request form

$XYMONHOME/web/report_form
HTML template report request form

 

ENVIRONMENT VARIABLES

XYMONGENREPOPTS
xymongen options passed by default to the report.cgi. This happens in the report.sh wrapper.
XYMONHOME
Home directory of the Xymon server installation
XYMONREPDIR
Directory where generated reports are stored. This directory must be writable by the userid executing the CGI script, typically "www", "apache" or "nobody". Default: $XYMONHOME/www/rep/
XYMONREPURL
The URL prefix to use when accessing the reports via a browser. Default: $XYMONWEB/rep

 

SEE ALSO

xymongen(1), hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/appfeed.cgi.1.html0000664000076400007640000000632513534041734021766 0ustar rpmbuildrpmbuild Manpage of APPFEED.CGI

APPFEED.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

appfeed.cgi - Xymon CGI feeder for Smartphone apps  

SYNOPSIS

appfeed.cgi [options]

 

DESCRIPTION

appfeed.cgi is invoked as a CGI script via the appfeed.sh CGI wrapper.

appfeed.cgi is optionally passed a QUERY_STRING environment variable with the "filter=FILTER" parameter. FILTER is a filter for the "xymondboard" command sent to xymond(8) daemon. These filters are described in detail in the xymon(1) manual. Typically, the filter will specify hosts found on a specific (sub)page to be returned, e.g. "filter=page=webservers" will cause appfeed.cgi to only return hosts that are present on the "webservers" page in Xymon.

If no filter is specified, appfeed.cgi returns data for all red, yellow or purple statuses (equivalent to the data present on the "All non-green" page), or if invoked with the "--critical" option it returns data from the "Critical systems" page.

The output is an XML document with the current status of the selected hosts/services.

 

OPTIONS

--env=FILENAME
Loads the environment from FILENAME before executing the CGI.

--critical[=FILENAME]
FILENAME specifies the "Critical Systems" configuration file (default: critical.cfg). appfeed.cgi will only return the statuses currently on the "Critical Systems" view.

--access=FILENAME
In addition to the filtering done by the "filter" parameter or the "--critical" option, this option limits the output to hosts that the user has access to as defined in the Apache-compatible group-definitions in FILENAME. See xymon-webaccess(5) for more details of this. Note:Useofthisoptionrequiresthataccesstotheappfeed.cgitoolispassword-protected by whatever means your webserver software provides, and that the login userid is available via the REMOTE_USER environment variable (this is standard CGI behaviour, so all webservers should provide it if you use the webserver's built-in authentication mechanisms).

 

SEE ALSO

xymon(1), critical.cfg(5), xymon-webaccess(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/snapshot.cgi.1.html0000664000076400007640000000662613534041734022225 0ustar rpmbuildrpmbuild Manpage of SNAPSHOT.CGI

SNAPSHOT.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

snapshot.cgi - CGI program to rebuild the Xymon webpages for a specific point in time.  

SYNOPSIS

snapshot.cgi

 

DESCRIPTION

snapshot.cgi is invoked as a CGI script via the snapshot.sh CGI wrapper. It rebuilds the Xymon web pages to the look they had at a particular point in time, based upon the historical information logged about events.

snapshot.cgi is passed a QUERY_STRING environment variable with the following parameters:


   mon (Start month of the snapshot)
   day (Start day-of-month of the snapshot)
   yr  (Start year of the snapshot)
   hour (Start hour of the snapshot)
   min  (Start minute of the snapshot)
   sec  (Start second of the snapshot)

The "month" parameters must be specified as the three-letter english month name abbreviation: Jan, Feb, Mar ...

"day" must be in the range 1..31; "yr" must be specified including century (e.g. "2003"). "hour" must be specified using a 24-hour clock.

All of the processing involved in generating the report is done by invoking xymongen(1) with the proper "--snapshot" option.

 

OPTIONS

--env=FILENAME
Load environment from FILENAME before executing the CGI.

xymongen-options
All options except "--env" are passed on to the xymongen(1) program building the snapshot files.

 

ENVIRONMENT VARIABLES

XYMONGENSNAPOPTS
xymongen options passed by default to the snapshot.cgi script. This happens in the snapshot.sh CGI wrapper script.
XYMONHOME
Home directory of the Xymon server files
XYMONSNAPDIR
Directory where generated snapshots are stored. This directory must be writable by the userid executing the CGI script, typically "www", "apache" or "nobody". Default: $XYMONHOME/www/snap/
XYMONSNAPURL
The URL prefix to use when accessing the reports via a browser. Default: $XYMONWEB/snap

 

SEE ALSO

xymongen(1), hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/findhost.cgi.1.html0000664000076400007640000000552413534041734022200 0ustar rpmbuildrpmbuild Manpage of FINDHOST.CGI

FINDHOST.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

findhost.cgi - Xymon CGI script to find hosts  

SYNOPSIS

findhost.cgi?host=REGEX

 

DESCRIPTION

findhost.cgi is invoked as a CGI script via the findhost.sh CGI wrapper.

findhost.cgi is passed a QUERY_STRING environment variable with the "host=REGEX" parameter. The REGEX is a Posix regular expression (see regex(7) ) describing the hostnames to look for. A trailing wildcard is assumed on all hostnames - e.g. requesting the hostname "www" will match any host whose name begins with "www".

It then produces a single web page, listing all of the hosts that matched any of the hostnames, with links to the Xymon webpages where they are located.

The output page lists hosts in the order they appear in the hosts.cfg(5) file.

A sample web page implementing the search facility is included with xymongen, you access it via the URL /xymon/help/findhost.html.

 

OPTIONS

--env=FILENAME
Loads the environment from FILENAME before executing the CGI.

 

FILES

$XYMONHOME/web/findhost_header
HTML header file for the generated web page

$XYMONHOME/web/findhost_footer
HTML footer file for the generated web page

$XYMONHOME/web/findhost_form
Query form displayed when findhost.cgi is called with no parameters.

 

ENVIRONMENT VARIABLES

HOSTSCFG
findhost.cgi uses the HOSTSCFG environment variable to find the hosts.cfg file listing all known hosts and their page locations.

XYMONHOME
Used to locate the template files for the generated web pages.

 

SEE ALSO

xymongen(1), hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymondigest.1.html0000664000076400007640000000453013534041733022166 0ustar rpmbuildrpmbuild Manpage of XYMONDIGEST

XYMONDIGEST

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymondigest - calculate message digests  

SYNOPSIS

xymondigest md5|sha1|sha256|sha512|sha224|sha384|rmd160 [filename]

 

DESCRIPTION

xymondigest(1) is a utility to calculate message digests for a file or document. It is used when defining HTTP- or FTP-based content checks, where xymonnet(1) checks that a URL returns a specific document; instead of having to compare the entire document, the comparison is done against a pre-computed message digest value using the MD5, RIPEMD160, SHA1 or any of the SHA2 (SHA-512, SHA-256, SHA-384, SHA-224) message digest algorithms.

The optional filename parameter is the input file whose message digest should be calculated; if no filename is given, the data is read from standard input.

xymondigest outputs a string containing the digest algorithm and the computed message digest. This is in a format suitable for use in the hosts.cfg(5) definition of a content check.

 

EXAMPLE


   $ xymondigest md5 index.html
   md5:88b81b110a85c83db56a939caa2e2cf6


   $ curl -s http://www.foo.com/ | xymondigest sha1
   sha1:e5c69784cb971680e2c7380138e04021a20a45a2

 

SEE ALSO

xymonnet(1), hosts.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
EXAMPLE
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymoncmd.1.html0000664000076400007640000000370413534041733021454 0ustar rpmbuildrpmbuild Manpage of XYMONCMD

XYMONCMD

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymoncmd - Run a Xymon command with environment set  

SYNOPSIS

xymoncmd [--env=ENVFILE COMMAND|--version|--debug]

 

DESCRIPTION

xymoncmd(1) is a utility that can setup the Xymon environment variables as defined in a xymonlaunch(8) compatible environment definition file, and then execute a command with this environment in place. It is mostly used for testing extension scripts or in other situations where you need to run a single command with the environment in place.

The "--env=ENVFILE" option points xymoncmd to the file where the environment definitions are loaded from.

COMMAND is the command to execute after setting up the environment.

If you want to run multiple commands, it is often easiest to just use "sh" as the COMMAND - this gives you a sub-shell with the environment defined globally.

The "--debug" option print out more detail steps of xymoncmd execution.

The "--version" option print out version number of xymoncmd.  

SEE ALSO

xymonlaunch(8), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/acknowledge.cgi.1.html0000664000076400007640000000753613534041734022652 0ustar rpmbuildrpmbuild Manpage of ACKNOWLEDGE.CGI

ACKNOWLEDGE.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

acknowledge.cgi - Xymon CGI script to acknowledge alerts  

SYNOPSIS

acknowledge.cgi?ACTION=action&NUMBER=acknum&DELAY=validity&MESSAGE=text

 

DESCRIPTION

acknowledge.cgi is invoked as a CGI script via the acknowledge.sh CGI wrapper.

acknowledge.cgi is passed a QUERY_STRING environment variable with the ACTION, NUMBER, DELAY and MESSAGE parameters.

 

PARAMETERS

ACTION is the action to perform. The only supported action is "Ack" to acknowledge an alert.

NUMBER is the number identifying the host/service to be acknowledged. It is included in all alert-messages sent out by Xymon.

DELAY is the time (in minutes) that the acknowledge is valid.

MESSAGE is an optional text which will be shown on the status page while the acknowledgment is active. You can use it to e.g. tell users not to contact you about the problem, or inform them when the problem is expected to be resolved.

 

OPTIONS

--no-pin
acknowledge.cgi normally requires the user to enter the acknowledgment code received in an alert message. If you run it with this option, the user will instead get a list of the current non-green statuses, and he may send an acknowledge without knowing the code.

--no-cookies
Normally, acknowledge.cgi uses a cookie sent by the browser to initially filter the list of hosts presented. If this is not desired, you can turn off this behaviour by calling acknowledge.cgi with the --no-cookies option. This would normally be placed in the CGI_ACK_OPTS setting in cgioptions.cfg(5)

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--debug
Enables debugging output.

 

FILES

$XYMONHOME/web/acknowledge_header
HTML header file for the generated web page

$XYMONHOME/web/acknowledge_footer
HTML footer file for the generated web page

$XYMONHOME/web/acknowledge_form
Query form displayed when acknowledge.cgi is called with no parameters.

 

ENVIRONMENT VARIABLES

XYMONHOME
Used to locate the template files for the generated web pages.

QUERY_STRING
Contains the parameters for the CGI script.

 

BUGS

When using alternate pagesets, hosts will only show up on the acknowledgment page if this is accessed from the primary page in which they are defined. So if you have hosts on multiple pages, they will only be visible for acknowledging from their main page which is not what you would expect.

 

SEE ALSO

xymongen(1), hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
PARAMETERS
OPTIONS
FILES
ENVIRONMENT VARIABLES
BUGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/clientupdate.1.html0000664000076400007640000001370413534041733022300 0ustar rpmbuildrpmbuild Manpage of CLIENTUPDATE

CLIENTUPDATE

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

clientupdate - Xymon client update utility  

SYNOPSIS

clientupdate [options]

 

DESCRIPTION

clientupdate is part of the Xymon client. It is responsible for updating an existing client installation from a central repository of client packages stored on the Xymon server.

When the Xymon client sends a normal client report to the Xymon server, the server responds with the section of the client-local.cfg(5) file that is relevant to this client. Included in this may be a "clientversion" value. The clientversion received from the server is compared against the current clientversion installed on the client, as determined by the contents of the $XYMONHOME/etc/clientversion.cfg file. If the two versions are not identical, clientupdate is launched to update the client installation.

 

OPTIONS

--level
Report the current clientversion.

--update=NEWVERSION
Attempt to update the client to NEWVERSION by fetching this version of the client software from the Xymon server.

--reexec
Used internally during the update process, see OPERATION below.

--remove-self
Used internally during the update process. This option causes the running clientupdate utility to delete itself - it is used during the update to purge a temporary copy of the clientupdate utility that is installed in $XYMONTMP.

 

USING CLIENTUPDATE IN XYMON

To manage updating clients without having to logon to each server, you can use the clientupdate utility. This is how you setup the release of a new client version.

Create the new client
Setup the new client $XYMONHOME directory, e.g. by copying an existing client installation to an empty directory and modifying it for your needs. It is a good idea to delete all files in the tmp/ and logs/ directories, since there is no need to copy these over to all of the clients. Pay attention to the etc/ files, and make sure that they are suitable for the systems where you want to deploy this new client. You can add files - e.g. extension scripts in the ext/ directory - but the clientupdate utility cannot delete or rename files.

Package the client
When your new client software is ready, create a tar-file of the new client. All files in the tar archive must have file names relative to the clients' $XYMONHOME (usually, ~xymon/client/). Save the tar file on the Xymon server in ~xymon/server/download/somefile.tar. Don't compress it. It is recommended that you use some sort of operating-system and version-numbering scheme for the filename, but you can choose whatever filename suits you - the only requirement is that it must end with ".tar". The part of the filename preceding ".tar" is what Xymon will use as the "clientversion" ID.

Configure which hosts receive the new client
In the client-local.cfg(5) file, you must now setup a clientversion:ID line where the ID matches the filename you used for the tar-file. So if you have packaged the new client into the file linux.v2.tar, then the corresponding entry in client-local.cfg would be clientversion:linux.v2.

Wait for xymond to reload client-local.cfg
xymond will automatically reload the client-local.cfg file after at most 10 minutes. If you want to force an immediate reload, send a SIGHUP signal to the xymond process.

Wait for the client to update
The next time the client contacts the Xymon server to send the client data, it will notice the new clientversion setting in client-local.cfg, and will run clientupdate to install the new client software. So when the client runs the next time, it will use the new client software.

 

OPERATION

clientupdate runs in two steps:

Re-exec step
The first step is when clientupdate is first invoked from the xymonclient.sh script with the "--re-exec" option. This step copies the clientupdate program from $XYMONHOME/bin/ to a temporary file in the $XYMONTMP directory. This is to avoid conflicts when the update procedure installs a new version of the clientupdate utility itself. Upon completion of this step, the clientupdate utility automatically launches the next step by running the program from the file in $XYMONTMP.

Update step
The second step downloads the new client software from the Xymon server. The new software must be packed into a tar file, which clientupdate then unpacks into the $XYMONHOME directory.

 

ENVIRONMENT VARIABLES

clientupdate uses several of the standard Xymon environment variables, including XYMONHOME and XYMONTMP.

 

SEE ALSO

xymon(7), xymon(1), client-local.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
USING CLIENTUPDATE IN XYMON
OPERATION
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/logfetch.1.html0000664000076400007640000001032413534041733021405 0ustar rpmbuildrpmbuild Manpage of LOGFETCH

LOGFETCH

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

logfetch - Xymon client data collector  

SYNOPSIS

logfetch [options] CONFIGFILE STATUSFILE

 

DESCRIPTION

logfetch is part of the Xymon client. It is responsible for collecting data from logfiles, and other file-related data, which is then sent to the Xymon server for analysis.

logfetch uses a configuration file, which is automatically retrieved from the Xymon server. There is no configuration done locally. The configuration file is usually stored in the $XYMONHOME/tmp/logfetch.cfg file, but editing this file has no effect since it is re-written with data from the Xymon server each time the client runs.

logfetch stores information about what parts of the monitored logfiles have been processed already in the $XYMONHOME/tmp/logfetch.status file. This file is an internal file used by logfetch, and should not be edited. If deleted, it will be re-created automatically.

 

OPTIONS

--debug[=stderr]
Enables debug mode. Note that when run by the xymonclient, debug output may be written into the client data report, which can cause false positives and other unintended side effects. Use '=stderr' to cause the output to be written to stderr instead.

--noexec
The client-local.cfg(5) section for this host, class, or OS is automatically retrieved from the server during client submission. Logfetch can be requested to execute arbitrary commands to generate a list of log files to examine dynamically, but this can present a security risk in some environments. Set this option to prevent logfetch from executing requested commands

 

SECURITY

logfetch needs read access to the logfiles it should monitor. If you configure monitoring of files or directories through the "file:" and "dir:" entries in client-local.cfg(5) then logfetch will require at least read-access to the directory where the file is located. If you request checksum calculation for a file, then it must be readable by the Xymon client user.

Do NOT install logfetch as suid-root. There is no way that logfetch can check whether the configuration file it uses has been tampered with, so installing logfetch with suid-root privileges could allow an attacker to read any file on the system by using a hand-crafted configuration file. In fact, logfetch will attempt to remove its own suid-root setup if it detects that it has been installed suid-root.

 

ENVIRONMENT VARIABLES

DU
Command used to collect information about the size of directories. By default, this is the command du -k. If the local du-command on the client does not recognize the "-k" option, you should set the DU environment variable in the $XYMONHOME/etc/xymonclient.cfg file to a command that does report directory sizes in kilobytes.

 

FILES

$XYMONHOME/tmp/logfetch.cfg
$XYMONHOME/tmp/logfetch.status

 

SEE ALSO

xymon(7), analysis.cfg(5), client-local.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SECURITY
ENVIRONMENT VARIABLES
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/statusreport.cgi.1.html0000664000076400007640000000776313534041734023150 0ustar rpmbuildrpmbuild Manpage of STATUSREPORT.CGI

STATUSREPORT.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

statusreport.cgi - CGI program to report a status for a group of servers  

SYNOPSIS

statusreport.cgi --column=COLUMNNAME [options]

 

DESCRIPTION

statusreport.cgi is a CGI tool to generate a simple HTML report showing the current status of a single column for a group of Xymon hosts.

E.g. You can use this report to get an overview of all of the SSL certificates that are about to expire.

The generated webpage is a simple HTML table, suitable for copying into other documents or e-mail.

statusreport.cgi runs as a CGI program, invoked by your webserver. It is normally run via a wrapper shell-script in the CGI directory for Xymon.

 

EXAMPLES

The Xymon installation includes two web report scripts using this CGI tool: The certreport.sh script generates a list of SSL server certificates that are yellow or red (i.e. they will expire soon); and the nongreen.sh script generates a report of all statuses that are currently non-green. These can be accessed from a web browser through a URL referencing the script in the Xymon CGI directory (e.g. "/xymon-cgi/xymon-nongreen.sh").

 

OPTIONS

--column=COLUMNNAME
Report the status of the COLUMNNAME column.

--all
Report the status for all hosts known to Xymon. By default, this tool reports only on the hosts found on the current page from where the CGI was invoked (by looking at the "pagepath" cookie).

--filter=CRITERIA
Only report on statuses that match the CRITERIA setting. See the xymon(1) man-page - in the "xymondboard" command description - for details about specifying filters.

--heading=HTML
Defines the webpage heading - i.e. the "title" tag in the generated HTML code.

--show-column
Include the column name in the display.

--show-colors
Show the status color on the generated webpage. The default is to not show the status color.

--no-colors
Do not include text showing the current color of each status in the report. This is the default.

--show-summary
Show only a summary of the important lines in the status message. By default, the entire status message appears in the generated HTML code. This option causes the first non-blank line of the status message to be shown, and also any lines beginning with "&COLOR" which is used by many status messages to point out lines of interest (non-green lines only, though).

--show-message
Show the entire message on the webpage. This is the default.

--link
Include HTML links to the host "info" page, and the status page.

--embedded
Only generate the HTML table, not a full webpage. This can be used to embed the status report into an external webpage.

--env=FILENAME
Load the environment from FILENAME before executing the CGI.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

 

SEE ALSO

xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
EXAMPLES
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/csvinfo.cgi.1.html0000664000076400007640000000555413534041734022034 0ustar rpmbuildrpmbuild Manpage of CSVINFO.CGI

CSVINFO.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

csvinfo.cgi - CGI program to show host information from a CSV file  

SYNOPSIS

csvinfo.cgi

 

DESCRIPTION

csvinfo.cgi is invoked as a CGI script via the csvinfo.sh CGI wrapper. Based on the parameters it receives, it searches a comma- separated file for the matching host, and presents the information found as a table.

csvinfo.cgi is passed a QUERY_STRING environment variable with the following parameters:


   key (string to search for, typically hostname)
   column (columnnumber to search - default 0)
   db  (name of the CSV database file in $XYMONHOME/etc/, default hostinfo.csv)
   delimiter (delimiter character for columns, default semi-colon)

CSV files are easily created from e.g. spreadsheets, by exporting them in CSV format. You should have one host per line, with the first line containing the column headings. Despite their name, the default delimiter for CSV files is the semi-colon - if you need a different delimiter, invoke csvinfo.cgi with the "delimiter=<character>" in the query string.

 

Example usage

This example shows how you can use the csvinfo CGI. It assumes you have a CSV-formatted file with information about the hosts stored as $XYMONHOME/etc/hostinfo.csv, and the hostname is in the first column of the file.

Use with the xymongen --docurl
The --docurl option to xymongen(1) sets up all of the hostnames on your Xymon webpages to act as links to a CGI script. To invoke the csvinfo CGI script, run xymongen with the option


   --docurl=/cgi-bin/csvinfo.sh?db=hostinfo.csv&key=%s

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5), xymongen(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
Example usage
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/orcaxymon.1.html0000664000076400007640000000443213534041733021634 0ustar rpmbuildrpmbuild Manpage of ORCAXYMON

ORCAXYMON

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

orcaxymon - Xymon client utility to grab data from ORCA  

SYNOPSIS

orcaxymon --orca=PREFIX [options]

 

NOTICE

This utility is included in the client distribution for Xymon 4.2. However, the backend module to parse the data it sends it NOT included in Xymon 4.2. It is possible to use the generic Xymon NCV data handler in xymond_rrd(8) to process ORCA data, if you have an urgent need to do so.

 

DESCRIPTION

orcaxymon is an add-on tool for the Xymon client. It is used to grab data collected by the ORCA data collection tool (orcallator.se), and send it to the Xymon server in NCV format.

orcaxymon should run from the client xymonlaunch(8) utility, i.e. there must be an entry in the clientlaunch.cfg(5) file for orcaxymon.

 

OPTIONS

--orca=PREFIX
The filename prefix for the ORCA data log. Typically this is the directory for the ORCA logs, followed by "orcallator". The actual filename for the ORCA logs include a timestamp and sequence number, e.g. "orcallator-2006-06-20-000". This option is required.

--debug
Enable debugging output.

 

SEE ALSO

xymon(7), clientlaunch.cfg(5)


 

Index

NAME
SYNOPSIS
NOTICE
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymongen.1.html0000664000076400007640000010424213534041733021461 0ustar rpmbuildrpmbuild Manpage of XYMONGEN

XYMONGEN

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymongen - Xymon webpage generator  

SYNOPSIS

xymongen -?
xymongen --help
xymongen --version
xymongen [options] [output-directory]
(See the OPTIONS section for a description of the available command-line options).

 

DESCRIPTION

xymongen generates the overview webpages for the Xymon monitor. These are the webpages that show the overall status of your hosts, not the detailed status pages for each test.

Note: The data for the webpages is retrieved from the xymond(8) daemon, and xymongen uses the values of the XYMSRV / XYMSERVERS environment variables to determine the network address where xymond can be reached. If you have more than one server listed in XYMSERVERS, make sure the first one is the local Xymon server - this is the one that xymongen will query for data.

 

OPTIONS

xymongen has a large number of command-line options. The options can be used to change the behaviour of xymongen and affect the web pages generated by it.

 

GENERAL OPTIONS

--help or -?
Provide a summary of available command-line options.

--version
Prints the version number of xymongen

--docurl=URL
This option is deprecated, use the HOSTDOCURL setting in xymonserver.cfg(5) instead.

--doccgi=URL
This option is deprecated, use the HOSTDOCURL setting in xymonserver.cfg(5) instead.

--doc-window
Causes links to documentation for hosts and services to open in a new window. The default is to show documentation in the same browser window as the Xymon status.

--htmlextension=.EXTENSION
Sets the filename extension used for the webpages generated by xymongen. By default, an extension of ".html" is used. Note that you need to specify the "dot".

--report[=COLUMNNAME]
With this option, xymongen will send a status message with details of how many hosts were processed, how many pages were generated, any errors that occurred during the run, and some timing statistics. The default columnname is "xymongen".

--htaccess[=htaccess-filename]
Create .htaccess files when new web page directories are created. The content of the .htaccess files are determined by the XYMONHTACCESS environment variable (for the top-level directory with xymon.html and nongreen.html); by the XYMONPAGEHTACCESS variable (for the page-level directories); and by the XYMONSUBPAGEHTACCESS variable for subpage- and subparent-level directories. The filename of the .htaccess files default to ".htaccess" if no filename is given with this option. The XYMONHTACCESS variable is copied verbatim into the top-level .htaccess file. The XYMONPAGEHTACCESS variable may contain a "%s" where the name of the page is inserted. The XYMONSUBPAGEHTACCESS variable may contain two "%s" instances: The first is replaced with the pagename, the second with the subpagename.

--max-eventcount=N
Limit the eventlog on the "All non-green" page to only N events. Default: 100.

--max-eventtime=N
Limit the eventlog on the "All non-green" page to events that happened within the past N minutes. Default: 240.

--no-eventlog
Disable the eventlog normally displayed on the "All non-green" page

--max-ackcount=N
Limit the acknowledgment log on the "All non-green" page to only N events. Default: 25.

--max-acktime=N
Limit the acknowledgment log on the "All non-green" page to acks that happened within the past N minutes. Default: 240.

--no-acklog
Disable the acknowledgement log normally displayed on the "All non-green" page.

--cricitcallog[=Critical log column]
This generates a text-based log of what is shown on the critical.html status page, and sends a status message for the Xymon server itself reflecting the color of the Critical status page. This allows you to track when problems have appeared on the critical status page. The logfile is stored in $XYMONSERVERLOGS/criticalstatus.log

--loadhostsfromxymond
Instead of reading the hosts.cfg file, xymongen will load the hosts.cfg configuration from the xymond daemon. This eliminates the need for reading the hosts.cfg, and if you have xymond and xymongen running on different hosts, it also eliminates the need for copying the hosts.cfg file between systems. Note that the "dispinclude" option in hosts.cfg is ignored when this option is enabled.

 

PAGE LAYOUT OPTIONS

These options affect how the webpages generated by xymongen appear in the browser.

--pages-last
Put page- and subpage-links after hosts.
--pages-first
Put page- and subpage-links before hosts (default).

These two options decide whether a page with links to subpages and hosts have the hosts or the subpages first.

--subpagecolumns=N
Determines the number of columns used for links to pages and subpages. The default is N=1.

--maxrows=N
Column headings on a page are by default only shown at the beginning of a page, subpage or group of hosts. This options causes the column headings to repeat for every N hosts shown.

--showemptygroups
--no-showemptygroups
When groups are hosts are made, display the table and host names even if there are no tests present for any of the hosts in question. Use --no-showemptygroups to hide. (Default: yes)

--pagetitle-links
Normally, only the colored "dots" next to a page or subpage act as links to the page itself. With this option, the page title will link to the page also.

--pagetext-headings
Use the description text from the "page" or "subpage" tags as a heading for the page, instead of the "Pages hosted locally" or other standard heading.

--no-underline-headings
Normally, page headings are underlined using an HTML "horizontal ruler" tag. This option disables the underlining of headings.

--recentgifs[=MINUTES]
Use images named COLOR-recent.gif for tests, where the test status has changed within the past 24 hours. These GIF files need to be installed in the $XYMONHOME/www/gifs/ directory. By default, the threshold is set to 24 hours - if you want it differently, you can specify the time limit also. E.g. "--recentgifs=3h" will show the recent GIFs for only 3 hours after a status change.

--sort-group-only-items
In a normal "group-only" directive, you can specify the order in which the tests are displayed, from left to right. If you prefer to have the tests listed in alphabetical order, use this option - the page will then generate "group-only" groups like it generates normal groups, and sort the tests alphabetically.

--dialupskin=URL
If you want to visually show that a test is a dialup-test, you can use an alternate set of icons for the green/red/yellow>/etc. images by specifying this option. The URL parameter specified here overrides the normal setting from the XYMONSKIN environment variable, but only for dialup tests.

--reverseskin=URL
Same as "--dialupskin", but for reverse tests (tests with '!' in front).

--tooltips=[always,never,main]
Determines which pages use tooltips to show the description of the host (from the COMMENT entry in the hosts.cfg(5) file). If set to always, tooltips are used on all pages. If set to never, tooltips are never used. If set to main, tooltips are used on the main pages, but not on the "All non-green" or "Critical systems" pages.

 

COLUMN SELECTION OPTIONS

These options affect which columns (tests) are included in the webpages generated by xymongen.

--ignorecolumns=test[,test]
The given columns will be completely ignored by xymongen when generating webpages. Can be used to generate reports where you eliminate some of the more noisy tests, like "msgs".

--critical-reds-only
Only red status columns will be included on the Critical page. By default, the Critical page will contain hosts with red, yellow and clear status.

--nongreen-colors=COLOR[,COLOR]
Defines which colors cause a test to appear on the "All non-green" status page. COLOR is red, yellow or purple. The default is to include all three.

--nongreen-ignorecolumns=test[,test]
Same as the --ignorecolumns, but applies to hosts on the "All non-green" page only.

--nongreen-ignorepurples
Deprecated, use "--nongreen-colors" instead.

--nongreen-ignoredialups
Ignore all dialup hosts on the "All non-green" page, including the eventlog.

--no-pages
Do not generate the normal pages (normally used to generate only the non-green page).

--no-nongreen
Do not generate the "All non-green" page.

--includecolumns=test[,test]
Always include these columns on "All non-green" page Will include certain columns on the nongreen.html page, regardless of its color. Normally, nongreen.html drops a test-column, if all tests are green. This can be used e.g. to always have a link to the trends column (with the RRD graphs) from your nongreen.html page.

--eventignore=test[,test]
Ignore these tests in the "All non-green" event log display.

 

STATUS PROPAGATION OPTIONS

These options suppress the normal propagation of a status upwards in the page hierarchy. Thus, you can have a test with status yellow or red, but still have the entire page green. It is useful for tests that need not cause an alarm, but where you still want to know the actual status. These options set global defaults for all hosts; you can use the NOPROPRED and NOPROPYELLOW tags in the hosts.cfg(5) file to apply similar limits on a per-host basis.

--nopropyellow=test[,test] or --noprop=test[,test]
Disable upwards status propagation when YELLOW. The "--noprop" option is deprecated and should not be used.

--noproppurple=test[,test]
Disable upwards status propagation when PURPLE.

--nopropred=test[,test]
Disable upwards status propagation when RED or YELLOW.

--nopropack=test[,test]
Disable upwards status propagation when status has been acknowledged. If you want to disable all acked tests from being propageted, use "--nopropack=*".

 

PURPLE STATUS OPTIONS

Purple statuses occur when reporting of a test status stops. A test status is valid for a limited amount of time - normally 30 minutes - and after this time, the test becomes purple.

--purplelog=FILENAME
Generate a logfile of all purple status messages.

 

ALTERNATE PAGESET OPTIONS

--pageset=PAGESETNAME
Build webpages for an alternate pageset than the default. See the PAGESETS section below.

--template=TEMPLATE
Use an alternate template for header and footer files. Typically used together the the "--pageset" option; see the PAGESETS section below.

 

ALTERNATE OUTPUT FORMATS

--wml[=test1,test2,...]
This option causes xymongen to generate a set of WML "card" files that can be accessed by a WAP device (cell phone, PDA etc.) The generated files contain the hosts that have a RED or YELLOW status on tests specified. This option can define the default tests to include - the defaults can be overridden or amended using the "WML:" or "NK:" tags in the hosts.cfg(5) file. If no tests are specified, all tests will be included.

--nstab=FILENAME
Generate an HTML file suitable for a Netscape 6/Mozilla sidebar entry. To actually enable your users to obtain such a sidebar entry, you need this Javascript code in a webpage (e.g. you can include it in the $XYMONHOME/web/stdnormal_header file):

<SCRIPT TYPE="text/javascript">
<!--
function addNetscapePanel() {

   if ((typeof window.sidebar == "object") && 
       (typeof window.sidebar.addPanel == "function"))

      window.sidebar.addPanel ("Xymon", 

            "http://your.server.com/nstab.html","");

   else

      alert("Sidebar only for Mozilla or Netscape 6+");
}
//-->
</SCRIPT>

and then you can include a "Add this to sidebar" link using this as a template:


   <A HREF="javascript:addNetscapePanel();">Add to Sidebar</A>

or if you prefer to have the standard Netscape "Add tab" button, you would do it with


   <A HREF="javascript:addNetscapePanel();">

      <IMG SRC="/gifs/add-button.gif" HEIGHT=45 WIDTH=100

           ALT="[Add Sidebar]" STYLE="border:0">

   </A>

The "add-button.gif" is available from Netscape at http://developer.netscape.com/docs/manuals/browser/sidebar/add-button.gif.

If FILENAME does not begin with a slash, the Netscape sidebar file is placed in the $XYMONHOME/www/ directory.

--nslimit=COLOR
The minimum color to include in the Netscape Sidebar - default is "red", meaning only critical alerts are included. If you want to include warnings also, use "--nslimit=yellow".

--rss
Generate RSS/RDF content delivery stream of your Xymon alerts. This output format can be dynamically embedded in other web pages, much like the live newsfeeds often seen on web sites. Two RSS files will be generated, one reflects the "All non-green" page, the other reflects the "Critical" page. They will be in the "nongreen.rss" and "critical.rss" files, respectively. In addition, an RSS file will be generated for each page and/or subpage listing the hosts present on that page or subpage.
The FILENAME parameter previously allowed on the --rss option is now obsolete.
For more information about RSS/RDF content feeds, please see http://www.syndic8.com/.

--rssextension=.EXTENSION
Sets the filename extension used for the RSS files generated by xymongen. By default, an extension of ".rss" is used. Note that you need to specify the "dot".

--rssversion={0.91|0.92|1.0|2.0}
The desired output format of the RSS/RDF feed. Version 0.91 appears to be the most commonly used format, and is the default if this option is omitted.

--rsslimit=COLOR
The minimum color to include in the RSS feed - default is "red", meaning only critical alerts are included. If you want to include warnings also, use "--rsslimit=yellow".

 

OPTIONS USED BY CGI FRONT-ENDS

--reportopts=START:END:DYNAMIC:STYLE
Invoke xymongen in report-generation mode. This is normally used by the report.cgi(1) CGI script, but may also be used directly when pre-generating reports. The START parameter is the start-time for the report in Unix time_t format (seconds since Jan 1st 1970 00:00 UTC); END is the end-time for the report; DYNAMIC is 0 for a pre-built report and 1 for a dynamic (on-line) report; STYLE is "crit" to include only critical (red) events, "nongr" to include all non-green events, and "all" to include all events.

--csv=FILENAME
Used together with --reportopts, this causes xymongen to generate an availability report in the form of a comma-separated values (CSV) file. This format is commonly used for importing into spreadsheets for further processing.
The CSV file includes Unix timestamps. To display these as human readable times in Excel, the formula =C2/86400+DATEVALUE(1-jan-1970) (if you have the Unix timestamp in the cell C2) can be used. The result cell should be formatted as a date/time field. Note that the timestamps are in UTC, so you may also need to handle local timezone and DST issues yourself.

--csvdelim=DELIMITER
By default, a comma is used to delimit fields in the CSV output. Some non-english spreadsheets use a different delimiter, typically semi-colon. To generate a CSV file with the proper delimiter, you can use this option to set the character used as delimiter. E.g. "--csvdelim=;" - note that this normally should be in double quotes, to prevent the Unix shell from interpreting the delimiter character as a command-line delimiter.

--snapshot=TIME
Generate a snapshot of the Xymon pages, as they appeared at TIME. TIME is given as seconds since Jan 1st 1970 00:00 UTC. Normally used via the snapshot.cgi(1) CGI script.

 

DEBUGGING OPTIONS

--debug
Causes xymongen to dump large amounts of debugging output to stdout, if it was compiled with the -DDEBUG enabled. When reporting a problem with xymongen, please try to reproduce the problem and provide the output from running xymongen with this option.

--timing
Dump information about the time spent by various parts of xymongen to stdout. This is useful to see what part of the processing is responsible for the run-time of xymongen.
Note: This information is also provided in the output sent to the Xymon display when using the "--report" option.

 

BUILDING ALTERNATE PAGESETS

With version 1.4 of xymongen comes the possibility to generate multiple sets of pages from the same data.
Suppose you have two groups of people looking at the Xymon webpages. Group A wants to have the hosts grouped by the client, they belong to. This is how you have Xymon set up - the default pageset. Now group B wants to have the hosts grouped by operating system - let us call it the "os" set. Then you would add the page layout to hosts.cfg like this:

ospage win Microsoft Windows
ossubpage win-nt4 MS Windows NT 4
osgroup NT4 File servers
osgroup NT4 Mail servers
ossubpage win-xp MS Windows XP
ospage unix Unix
ossubpage unix-sun Solaris
ossubpage unix-linux Linux

This defines a set of pages with one top-level page (the xymon.html page), two pages linked from xymon.html (win.html and unix.html), and from e.g. the win.html page there are subpages win-nt4.html and win-xp.html
The syntax is identical to the normal "page" and "subpage" directives in hosts.cfg, but the directive is prefixed with the pageset name. Don't put any hosts in-between the page and subpage directives - just add all the directives at the top of the hosts.cfg file.
How do you add hosts to the pages, then ? Simple - just put a tag "OS:win-xp" on the host definition line. The "OS" must be the same as prefix used for the pageset names, but in uppercase. The "win-xp" must match one of the pages or subpages defined within this pageset. E.g.

207.46.249.190 www.microsoft.com # OS:win-xp http://www.microsoft.com/
64.124.140.181 www.sun.com # OS:unix-sun http://www.sun.com/

If you want the host to appear inside a group defined on that page, you must identify the group by number, starting at 1. E.g. to put a host inside the "NT4 Mail servers" group in the example above, use "OS:win-nt4,2" (the second group on the "win-nt4" page).
If you want the host to show up on the frontpage instead of a subpage, use "OS:*" .

All of this just defines the layout of the new pageset. To generate it, you must run xymongen once for each pageset you define - i.e. create an extension script like this:

#!/bin/sh

XYMONWEB="/xymon/os" $XYMONHOME/bin/xymongen \
        --pageset=os --template=os \
        $XYMONHOME/www/os/

Save this to $XYMONHOME/ext/os-display.sh, and set this up to run as a Xymon extension; this means addng an extra section to tasks.cfg to run it.

This generates the pages. There are some important options used here:
* XYMONWEB="/xymon/os" environment variable, and the
  "$XYMONHOME/www/os/" option work together, and places the 
  new pageset HTML files in a subdirectory off the normal 
  Xymon webroot. If you normally access the Xymon pages as 
  "http://xymon.acme.com/xymon/", you will then access 
  the new pageset as "http://xymon.acme.com/xymon/os/"
  NB: The directory given as XYMONWEB must contain a symbolic 
  link to the $XYMONHOME/www/html/ directory, or links to 
  individual status messages will not work. Similar links 
  should be made for the gifs/, help/ and notes/ 
  directories.
* "--pageset=os" tells xymongen to structure the webpages
  using the "os" layout, instead of the default layout.
* "--template=os" tells xymongen to use a different set of
  header- and footer-templates. Normally xymongen uses the 
  standard template in $XYMONHOME/web/stdnormal_header and 
  .../stdnormal_footer - with this option, it will instead use 
  the files "os_header" and "os_footer" from the 
  $XYMONHOME/web/ directory. This allows you to customize 
  headers and footers for each pageset. If you just want 
  to use the normal template, you can omit this option.

 

USING XYMONGEN FOR REPORTS

xymongen reporting is implemented via drop-in replacements for the standard Xymon reporting scripts (report.sh and reportlog.sh) installed in your webservers cgi-bin directory.

These two shell script have been replaced with two very small shell-scripts, that merely setup the Xymon environment variables, and invoke the report.cgi(1) or reportlog.cgi(1) scripts in $XYMONHOME/bin/

You can use xymongen command-line options when generating reports, e.g. to exclude certain types of tests (e.g. "--ignorecolumns=msgs") from the reports, to specify the name of the trends- and info- columns that should not be in the report, or to format the report differently (e.g. "--subpagecolumns=2"). If you want certain options to be used when a report is generated from the web interface, put these options into your $XYMONHOME/etc/xymonserver.cfg file in the XYMONGENREPOPTS environment variable.

The report files generated by xymongen are stored in individual directories (one per report) below the $XYMONHOME/www/rep/ directory. These should be automatically cleaned up - as new reports are generated, the old ones get removed.

After installing, try generating a report. You will probably see that the links in the upper left corner (to ack.html, nongreen.html etc.) no longer works. To fix these, change your $XYMONHOME/web/repnormal_header file so these links do not refer to "&XYMONWEB" but to the normal URL prefix for your Xymon pages.

 

SLA REPORTING

xymongen reporting allows for the generation of true SLA (Service Level Agreement) reports, also for service periods that are not 24x7. This is enabled by defining a "REPORTTIME:timespec" tag for the hosts to define the service period, and optionally a "WARNPCT:level" tag to define the agreed availability.

Note: See hosts.cfg(5) for the exact syntax of these options.

"REPORTTIME:timespec" specifies the time of day when the service is expected to be up and running. By default this is 24 hours a day, all days of the week. If your SLA only covers Mon-Fri 7am - 8pm, you define this as "REPORTTIME=W:0700:2000", and the report generator will then compute both the normal 24x7 availability but also a "SLA availability" which only takes the status of the host during the SLA period into account.

The DOWNTIME:timespec parameter affects the SLA availability calculation. If an outage occurs during the time defined as possible "DOWNTIME", then the failure is reported with a status of "blue". (The same color is used if you "disable" then host using the Xymon "disable" function). The time when the test status is "blue" is not included in the SLA calculation, neither in the amount of time where the host is considered down, nor in the total amount of time that the report covers. So "blue" time is effectively ignored by the SLA availability calculation, allowing you to have planned downtime without affecting the reported SLA availability.

Example: A host has "DOWNTIME:*:0700:0730 REPORTTIME=W:0600:2200" because it is rebooted every day between 7am and 7.30am, but the service must be available from 6am to 10pm. For the day of the report, it was down from 7:10am to 7:15am (the planned reboot), but also from 9:53pm to 10:15pm. So the events for the day are:


   0700 : green for 10 minutes (600 seconds)
   0710 : blue for 5 minutes (300 seconds)
   0715 : green for 14 hours 38 minutes (52680 seconds)
   2153 : red for 22 minutes (1320 seconds)
   2215 : green

The service is available for 600+52680 = 53280 seconds. It is down (red) for 420 seconds (the time from 21:53 until 22:00 when the SLA period ends). The total time included in the report is 15 hours (7am - 10pm) except the 5 minutes blue = 53700 seconds. So the SLA availability is 53280/53700 = 99,22%

The "WARNPCT:level" tag is supported in the hosts.cfg file, to set the availability threshold on a host-by-host basis. This threshold determines whether a test is reported as green, yellow or red in the reports. A default value can be set for all hosts with the via the XYMONREPWARN environment variable, but overridden by this tag. The level is given as a percentage, e.g. "WARNPCT:98.5"

 

PRE-GENERATED REPORTS

Normally, xymongen produce reports that link to dynamically generated webpages with the detailed status of a test (via the reportlog.sh CGI script).

It is possible to have xymongen produce a report without these dynamic links, so the report can be exported to another server. It may also be useful to pre-generate the reports, to lower the load by having multiple users generate the same reports.

To do this, you must run xymongen with the "--reportopts" option to select the time interval that the report covers, the reporting style (critical, non-green, or all events), and to request that no dynamic pages are to be generated.

The syntax is:


   xymongen --reportopts=starttime:endtime:nodynamic:style

"starttime" and "endtime" are specified as Unix time_t values, i.e. seconds since Jan 1st 1970 00:00 GMT. Fortunately, this can easily be computed with the GNU date utility if you use the "+%s" output option. If you don't have the GNU date utility, either pick that up from www.gnu.org; or you can use the "etime" utility for the same purpose, which is available from the archive at www.deadcat.net.

"nodynamic" is either 0 (for dynamic pages, the default) or 1 (for no dynamic, i.e. pre-generated, pages).

"style" is either "crit" (include critical i.e. red events only), "nongr" (include all non-green events), or "all" (include all events).

Other xymongen options can be used, e.g. "--ignorecolumns" if you want to exclude certain tests from the report.

You will normally also need to specify the XYMONWEB environment variable (it must match the base URL for where the report will be made accessible from), and an output directory where the report files are saved. If you specify XYMONWEB, you should probably also define the XYMONHELPSKIN and XYMONNOTESSKIN environment variables. These should point to the URL where your Xymon help- and notes-files are located; if they are not defined, the links to help- and notes-files will point inside the report directory and will probably not work.

So a typical invocation of xymongen for a static report would be:


  START=`date +%s --date="22 Jun 2003 00:00:00"`
  END=`date +%s --date="22 Jun 2003 23:59:59"`
  XYMONWEB=/reports/bigbrother/daily/2003/06/22 \
  XYMONHELPSKIN=/xymon/help \
  XYMONNOTESSKIN=/xymon/notes \
  xymongen --reportopts=$START:$END:1:crit \
        --subpagecolumns=2 \
        /var/www/docroot/reports/xymon/daily/2003/06/22

The "XYMONWEB" setting means that the report will be available with a URL of "http://www.server.com/reports/xymon/daily/2003/06/22". The report contains internal links that use this URL, so it cannot be easily moved to another location.

The last parameter is the corresponding physical directory on your webserver matching the XYMONWEB URL. You can of course create the report files anywhere you like - perhaps on another machine - and then move them to the webserver later on.

Note how the date(1) utility is used to calculate the start- and end-time parameters.

 

ENVIRONMENT VARIABLES

BOARDFILTER
Filter used to select what hosts / tests are included in the webpages, by filtering the data retrieved from xymond vi the xymondboard command. See xymon(1) for details on the filter syntax. By default, no filtering is done.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5), tasks.cfg(5), report.cgi(1), snapshot.cgi(1), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
GENERAL OPTIONS
PAGE LAYOUT OPTIONS
COLUMN SELECTION OPTIONS
STATUS PROPAGATION OPTIONS
PURPLE STATUS OPTIONS
ALTERNATE PAGESET OPTIONS
ALTERNATE OUTPUT FORMATS
OPTIONS USED BY CGI FRONT-ENDS
DEBUGGING OPTIONS
BUILDING ALTERNATE PAGESETS
USING XYMONGEN FOR REPORTS
SLA REPORTING
PRE-GENERATED REPORTS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/hostgraphs.cgi.1.html0000664000076400007640000000526413534041734022545 0ustar rpmbuildrpmbuild Manpage of HOSTGRAPHS.CGI

HOSTGRAPHS.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

hostgraphs.cgi - CGI program to show multiple graphs  

SYNOPSIS

hostgraph.cgi

 

DESCRIPTION

hostgraph.cgi is invoked as a CGI script via the hostgraph.sh CGI wrapper.

If no parameters are provided when invoked, it will present a form where the user can select a time period, one or more hosts, and a set of graphs.

The parameters selected by the user are passed to a second invocation of hostgraph.cgi, and result in a webpage showing a list of graph images based on the trend data stored about the hosts.

If multiple graph-types are selected, hostgraph.cgi will display a list of graphs, with one graph per type.

If multiple hosts are selected, hostgraph.cgi will attempt to display a multi-host graph for each type where the graphs for all hosts are overlayed in a single image, allowing for easy comparison of the hosts.

The hostlist uses the PAGEPATH cookie provided by Xymon webpages to select the list of hosts to present. Only the hosts visible on the page where hostgraph.cgi is invoked from will be visible.

The resulting graph page can be bookmarked, but the bookmark also fixates the time period shown.

 

OPTIONS

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

 

BUGS

This utility is experimental. It may change in a future release of Xymon.

It is possible for the user to select graphs which do not exist. This results in broken image links.

The set of graph-types is fixed in the server/web/hostgraphs_form template and does not adjust to which graphs are available.

If the tool is invoked directly, all hosts defined in Xymon will be listed.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
BUGS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/datepage.cgi.1.html0000664000076400007640000000760713534041734022140 0ustar rpmbuildrpmbuild Manpage of DATEPAGE.CGI

DATEPAGE.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

datepage.cgi - Xymon CGI script to view pre-built reports by date  

SYNOPSIS

datepage.cgi?type={day,week,month} --url=URLPREFIX [options]

 

DESCRIPTION

datepage.cgi is invoked as a CGI script via the datepage.sh CGI wrapper.

datepage.cgi is passed a QUERY_STRING environment variable with the type of time-selection that is desired: Either "day", "week" or "month" can be requested. It will then generate a web form with appropriate day/week/month selection boxes, and based on the users' selection a resulting url is built from the URLPREFIX and the time selection. The browser is then redirected to this URL.

The URL is constructed from the URLPREFIX, the type-parameter, the value of the "pagepath" or "host" cookie, and the users' selection as follows:

type=day
The final URL is URLPREFIX/daily/YEAR/MONTH/DAY/PAGEPATH.

type=week
The final URL is URLPREFIX/weekly/YEAR/WEEK/PAGEPATH.

type=month
The final URL is URLPREFIX/monthly/YEAR/MONTH/PAGEPATH.

YEAR is the full year (4 digits, including century). MONTH is the two-digit number of the month (01..12). DAY is the number of the day in the month (01..31). WEEK is the ISO 8601:1988 week-number (01..53). PAGEPATH is the current value of the "pagepath" cookie if set; if it is not set but the "host" cookie is set, then this host is looked up in the hosts.cfg file and the page where this host is found is used for PAGEPATH. These two cookies are set by the default web-header templates supplied with Xymon.

 

OPTIONS

--url=URLPREFIX
This specifies the initial part of the final URL. This option is required.

--hffile=FILENAME
Specifies the template files (from $XYMONHOME/web/) to use. The default is "--hffile=report".

--color=COLOR
Sets the background color of the generated webpage. The default is blue.

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--debug
Enables debugging output.

$XYMONHOME/web/report_form_daily
HTML form template for the date selection form when type=daily.

$XYMONHOME/web/report_form_weekly
HTML form template for the date selection form when type=weekly.

$XYMONHOME/web/report_form_monthly
HTML form template for the date selection form when type=monthly.

$XYMONHOME/web/report_header
HTML header file for the generated web page

$XYMONHOME/web/report_footer
HTML footer file for the generated web page

 

ENVIRONMENT VARIABLES

XYMONHOME
Used to locate the template files for the generated web pages.

QUERY_STRING
Contains the parameters for the CGI script.

 

SEE ALSO

xymongen(1), hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/showgraph.cgi.1.html0000664000076400007640000001040213534041734022353 0ustar rpmbuildrpmbuild Manpage of SHOWGRAPH.CGI

SHOWGRAPH.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

showgraph.cgi - CGI to generate Xymon trend graphs  

SYNOPSIS

showgraph [options]

 

DESCRIPTION

showgraph.cgi is invoked as a CGI script via the showgraph.sh CGI wrapper.

showgraph.cgi is passed a QUERY_STRING environment variable with the following parameters:

host Name of the host to generate a graph for

service Name of the service to generate a graph for

disp Display-name of the host, used on the generated graphs instead of hostname.

graph Can be "hourly", "daily", "weekly" or "monthly" to select the time period that the graph covers.

first Used to split multi-graphs into multiple graphs. This causes showgraph.cgi to generate only the graphs starting with the "first'th" graph and continuing for "count".

count Number of graphs in a multi-graph.

upper Set the upper limit of the graph. See rrdgraph(1) for a description of the "-u" option.

lower Set the lower limit of the graph. See rrdgraph(1) for a description of the "-l" option.

graph_start Set the starttime of the graph. This is used in zoom-mode.

graph_end Set the end-time of the graph. This is used in zoom-mode.

action=menu Generate an HTML page with links to 4 graphs, representing the hourly, weekly, monthly and yearly graphs. Doesn't actually generate any graphs, only the HTML that links to the graphs.

action=selzoom Generate an HTML page with link to single graph, and with JavaScript code that lets the user select part of the graph for a zoom-operation. The JavaScript invokes showgraph.cgi with "action=showzoom" to generate the zoomed graph webpage.

action=showzoom Generate HTML with a link to the zoomed graph image. This link goes to an "action=view" invocation of showgraph.cgi.

action=view Generate a single graph image.

 

OPTIONS

--config=FILENAME
Loads the graph configuration file from FILENAME. If not specified, the file $XYMONHOME/etc/graphs.cfg is used. See the graphs.cfg(5) for details about this file.

--env=FILENAME
Loads the environment settings defined in FILENAME before executing the CGI.

--rrddir=DIRECTORY
The top-level directory for the RRD files. If not specified, the directory given by the XYMONRRDS environment is used.

--save=FILENAME
Instead of returning the image via the CGI interface (i.e. on stdout), save the generated image to FILENAME.

--debug
Enable debugging output.

 

ENVIRONMENT

QUERY_STRING Provided by the webserver CGI interface, this decides what graph to generate.

RRDGRAPHOPTS RRD-specific options for the graph. This is usually set in the xymonserver.cfg(5) file.

 

FILES

graphs.cfg: The configuration file determining how graphs are generated from RRD files.

 

SEE ALSO

graphs.cfg(5), xymon(7), rrdtool(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymon.1.html0000664000076400007640000005712113534041733020772 0ustar rpmbuildrpmbuild Manpage of XYMON

XYMON

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymon - Xymon client communication program  

SYNOPSIS

xymon [options] RECIPIENT message

 

DESCRIPTION

xymon(1) is the client program used to communicate with a Xymon server. It is frequently used by Xymon client systems to send in status messages and pager alerts on local tests.

In Xymon, the xymon program is also used for administrative purposes, e.g. to rename or delete hosts, or to disable hosts that are down for longer periods of time.

 

OPTIONS AND PARAMETERS

--debug
Enable debugging. This prints out details about how the connection to the Xymon server is being established.

--proxy=http://PROXYSERVER:PROXYPORT/
When sending the status messages via HTTP, use this server as an HTTP proxy instead of connecting directly to the Xymon server.

--timeout=N
Specifies the timeout for connecting to the Xymon server, in seconds. The default is 5 seconds.

--response
The xymon utility normally knows when to expect a response from the server, so this option is not required. However, it will cause any response from the server to be displayed.

--merge
Merge the command line message text with the data provided on standard input, and send the result to the Xymon server. The message text provided on the command line becomes the first line of the merged message.

RECIPIENT
The RECIPIENT parameter defines which server receives the message. If RECIPIENT is given as "0.0.0.0", then the message is sent to all of the servers listed in the XYMSERVERS environment variable.

Usually, a client will use "$XYMSRV" for the RECIPIENT parameter, as this is defined for the client scripts to automatically contain the correct value.

The RECIPIENT parameter may be a URL for a webserver that has the xymoncgimsg.cgi or similar script installed. This tunnels the Xymon messages to the Xymon server using standard HTTP protocol. The xymoncgimsg.cgi(8) CGI tool (included in Xymon) must be installed on the webserver for the HTTP transport to work.

MESSAGE
The message parameter is the message to be sent across to the Xymon server. Messages must be enclosed in quotes, but by doing so they can span multiple lines. The maximum size of a message is defined by the maximum allowed length of your shellaqs command-line, and is typically 8-32 KB.

If you need to send longer status messages, you can specify "@" as the message: xymon will then read the status message from its stdin.

 

XYMON MESSAGE SYNTAX

This section lists the most commonly used messages in the Xymon protocol.

Each message must begin with one of the Xymon commands. Where a HOSTNAME is specified, it must have any dots in the hostname changed to commas if the Xymon FQDN setting is enabled (which is the default). So the host "www.foo.com", for example, would report as "www,foo,com".

status[+LIFETIME][/group:GROUP] HOSTNAME.TESTNAME COLOR <additional text>
This sends in a status message for a single test (column) on a single host. TESTNAME is the name of the column where this test will show up; any name is valid except that using dots in the testname will not work. COLOR must be one of the valid colors: "green", "yellow", "red" or "clear". The colors "blue" and "purple" - although valid colors - should not be sent in a status message, as these are handled specially by the Xymon server. As a special case (for supporting older clients), "client" can be used as the name of the color. This causes the status message to be handled by Xymon as a "client" data message, and the TESTNAME parameter is used as the "collector id".
The "additional text" normally includes a local timestamp and a summary of the test result on the first line. Any lines following the first one are free-form, and can include any information that may be useful to diagnose the problem being reported.
The LIFETIME defines how long this status is valid after being received by the Xymon server. The default is 30 minutes, but you can set any period you like. E.g. for a custom test that runs once an hour, you will want to set this to at least 60 minutes - otherwise the status will go purple after 30 minutes. It is a good idea to set the LIFETIME to slightly longer than the interval between your tests, to allow for variations in the time it takes your test to complete. The LIFETIME is in minutes, unless you add an "h" (hours), "d" (days) or "w" (weeks) immediately after the number, e.g. "status+5h" for a status that is valid for 5 hours.
The GROUP option is used to direct alerts from the status to a specific group. It is currently used for status generated from the Xymon clientsaq data, e.g. to direct alerts for a "procs" status to different people, depending on exactly which process is down.

notify HOSTNAME.TESTNAME <message text>
This triggers an informational message to be sent to those who receive alerts for this HOSTNAME+TESTNAME combination, according to the rules defined in alerts.cfg(5) This is used by the enadis.cgi(1) tool to notify people about hosts being disabled or enabled, but can also serve as a general way of notifying server administrators.

data HOSTNAME.DATANAME<newline><additional text>
The "data" message allows tools to send data about a host, without it appearing as a column on the Xymon webpages. This is used, for example, to report statistics about a host, e.g. vmstat data, which does not in itself represent something that has a red, yellow or green identity. It is used by RRD bottom-feeder modules, among others. In Xymon, data messages are by default processed only by the xymond_rrd(8) module. If you want to handle data-messages using an external application, you may want to enable the xymond_filestore(8) module for data-messages, to store data-messages in a format compatible with how the Big Brother daemon does.

disable HOSTNAME.TESTNAME DURATION <additional text>
Disables a specific test for DURATION minutes. This will cause the status of this test to be listed as "blue" on the Xymon server, and no alerts for this host/test will be generated. If DURATION is given as a number followed by s/m/h/d, it is interpreted as being in seconds/minutes/hours/days respectively. TodisableatestuntilitbecomesOK,use-1astheDURATION. Todisablealltestsforahost,useanasterisk*forTESTNAME.

enable HOSTNAME.TESTNAME
Re-enables a test that had been disabled.

query HOSTNAME.TESTNAME
Query the Xymon server for the latest status reported for this particular test. If the host/test status is known, the response is the first line of the status report - the current color will be the first word on the line. Additional lines of text that might be present on the status message cannot be retrieved.
This allows any Xymon client to determine the status of a particular test, whether it is one pertaining to the host where the client is running, some other host, or perhaps the result of a combined test from multiple hosts managed by combostatus(1) This will typically be useful to Xymon client extension scripts, that need to determine the status of other hosts, for example, to decide if an automatic recovery action should be initiated.

config FILENAME
Retrieve one of the Xymon configuration files from the server. This command allows a client to pull files from the $XYMONHOME/etc/ directory on the server, allowing for semi-automatic updates of the client configuration. Since the configuration files are designed to have a common file for the configuration of all hosts in the system - and this is in fact the recommended way of configuring your clients - this makes it easier to keep the configuration files synchronized.

drop HOSTNAME
Removes all data stored about the host HOSTNAME. It is assumed that you have already deleted the host from the hosts.cfg configuration file.

drop HOSTNAME TESTNAME
Remove data about a single test (column).

rename OLDHOSTNAME NEWHOSTNAME
Rename all data for a host that has had its name changed. You should do this after changing the hostname in the hosts.cfg configuration file.

rename HOSTNAME OLDTESTNAME NEWTESTNAME
Rename data about a single test (column).

xymondlog HOSTNAME.TESTNAME
Retrieve the Xymon status-log for a single test. The first line of the response contains a series of fields separated by a pipe-sign:

hostname The name of the host

testname The name of the test

color Status color (green, yellow, red, blue, clear, purple)

testflags For network tests, the flags indicating details about the test (used by xymongen).

lastchange Unix timestamp when the status color last changed.

logtime Unix timestamp when the log message was received.

validtime Unix timestamp when the log message is no longer valid (it goes purple at this time).

acktime Either -1 or Unix timestamp when an active acknowledgement expires.

disabletime Either -1 or Unix timestamp when the status is no longer disabled.

sender IP address where the status was received from.

cookie Either -1 or the cookie value used to acknowledge an alert.

ackmsg Empty or the acknowledgment message sent when the status was acknowledged. Newline, pipe-signs and backslashes are escaped with a backslash, C-style.

dismsg Empty or the message sent when the status was disabled. Newline, pipe-signs and backslashes are escaped with a backslash, C-style.

After the first line comes the full status log in plain text format.

xymondxlog HOSTNAME.TESTNAME
Retrieves an XML string containing the status log as with the "xymondlog" command.

xymondboard [CRITERIA] [fields=FIELDLIST]
Retrieves a summary of the status of all known tests available to the Xymon daemon.

By default - if no CRITERIA is provided - it returns one line for all status messages that are found in Xymon. You can filter the response by selection specific page, host, test, color or various other fields. The PAGEPATH, NETWORK, HOSTNAME, TESTNAME, and *MSG parameters are interpreted perl-compatible regular expressions; the COLOR parameter accepts multiple colors separated by commas; the *TIME values accept unix epoch timestamps. Other variables identified in xymon-xmh(5) may also be used.

Because host filtration is done before test filtration, it's more efficient (with very large data sets) to use PAGEPATH, HOSTNAME, NETWORK, and other XMH_ filters when possible, before globally filtering with COLOR, *MSG, *TIME, or TESTNAME.

You can filter on, for example, both a hostname and a testname.

page=PAGEPATH Include only tests from hosts found on the PAGEPATH page in the hosts.cfg file.

net=NETWORK Include only tests from hosts with this NET: tag

ip=IPAddress Include only tests from hosts with this IP address. This is a regex, not CIDR.

host=HOSTNAME Include only tests from the host HOSTNAME

test=TESTNAME Include only tests with the testname TESTNAME

color=COLORNAME Include only tests where the status color is COLORNAME

tag=TAGNAME Include only hosts with a certain tag specified in the hosts.cfg(5) line. Note that only items known to xymon components are included here; arbitrary text is not included

XMH_string=VALUE Include only hosts with a xymon-xmh(5) variable matching this value

Advanced Filtering

msg=MESSAGE Include only tests with full content matching MESSAGE. Use "\s" to escape spaces (or other PCRE strings)

ackmsg=MESSAGE Include only tests with acknowledgement(s) MESSAGE. Use "\s" to escape spaces (or other PCRE strings)

dismsg=MESSAGE Include only tests that have been disabled with strings matching MESSAGE. Use "\s" to escape spaces (or other PCRE strings). (It is most efficient to pair this with color=blue.)

Timestamp Filters

Certain fields (explained below) can be filtered with unix timestamps and with the following inequalities: >= > <= < = !=

These filters are: lastchange, logtime, validtime, acktime, disabletime

The response is one line for each status that matches the CRITERIA, or all statuses if no criteria is specified. The line is composed of a number of fields, separated by a pipe-sign. You can select which fields to retrieve by listing them in the FIELDLIST. The following fields are available:

hostname The name of the host

testname The name of the test

color Status color (green, yellow, red, blue, clear, purple)

flags For network tests, the flags indicating details about the test (used by xymongen).

lastchange Unix timestamp when the status color last changed.

logtime Unix timestamp when the log message was received.

validtime Unix timestamp when the log message is no longer valid (it goes purple at this time).

acktime Either -1 or Unix timestamp when an active acknowledgement expires.

disabletime Either -1 or Unix timestamp when the status is no longer disabled.

sender IP address where the status was received from.

cookie Either -1 or the cookie value used to acknowledge an alert.

line1 First line of status log.

ackmsg Empty (if no acknowledgement is active), or the text of the acknowledge message.

dismsg Empty (if the status is currently enabled), or the text of the disable message.

msg The full text of the current status message.

client Shows "Y" if there is client data available, "N" if not.

clntstamp Timestamp when the last client message was received, in Unix "epoch" format.

acklist List of the current acknowledgements for a test. This is a text string with multiple fields, delimited by a colon character. There are 5 fields: Timestamp for when the ack was generated and when it expires; the the "ack level"; the user who sent the ack; and the acknowledgement text.

flapinfo Tells if the status is flapping. 5 fields, delimited by "/": A "0" if the status is not flapping and "1" if it is flapping; timestamp when the latest status change was recorded and when the first statuschange was recorded; and the two colors that the status is flapping between.

stats Number of status-changes that have been recorded for this status since xymond was started.

modifiers Lists all active modifiers for this status (i.e. updates sent using a "modify" command).

XMH_* The XMH-tags refer to the Xymon hosts.cfg(5) configuration settings. A full list of these can be found in the xymon-xmh(5) man-page.

The ackmsg, dismsg and msg fields have certain characters encoded: Newline is "\n", TAB is "\t", carriage return is "\r", a pipe-sign is "\p", and a backslash is "\\".

If the "fields" parameter is omitted, a default set of hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,line1 is used.

xymondxboard
Retrieves an XML string with the summary of all status logs as for the "xymondboard" command.

hostinfo [CRITERIA]
Retrieves the current configuration of a host (i.e. the hosts.cfg(5) definition). CRITERIA selects which host(s) to report, and is identical to the CRITERIA in the xymondboard command.

The response is one line for each host that matches the CRITERIA, or all hosts if no criteria is specified. The line is composed of a number of fields, separated by a pipe-sign. The first two fields will always be the hostname and the IP-address. The remaining fields - if any - are the hosts.cfg tags in no particular order.

download FILENAME
Download a file from the Xymon serveraqs download directory.

client[/COLLECTORID] HOSTNAME.OSTYPE [HOSTCLASS]
Used to send a "client" message to the Xymon server. Client messages are generated by the Xymon client; when sent to the Xymon server they are matched against the rules in the analysis.cfg(5) configuration file, and status messages are generated for the client-side tests. The COLLECTORID is used when sending client-data that are additions to the standard client data. The data will be concatenated with the normal client data.

clientlog HOSTNAME [section=SECTIONNAME[,SECTIONNAME...]]
Retrieves the current raw client message last sent by HOSTNAME. The optional "section" filter is used to select specific sections of the client data.

ping
Attempts to contact the Xymon server. If successful, the Xymon server version ID is reported.

pullclient
This message is used when fetching client data via the "pull" mechanism implemented by xymonfetch(8) and msgcache(8) for clients that cannot connect directly to the Xymon server.

ghostlist
Report a list of ghost clients seen by the Xymon server. Ghosts are systems that report data to the Xymon server, but are not listed in the hosts.cfg file.

schedule [TIMESTAMP COMMAND]
Schedules a command sent to the Xymon server for execution at a later time. E.g. used to schedule disabling of a host or service at sometime in the future. COMMAND is a complete Xymon command such as the ones listed above. TIMESTAMP is the Unix epoch time when the command will be executed.
If no parameters are given, the currently scheduled tasks are listed in the response. The response is one line per scheduled command, with the job-id, the time when the command will be executed, the IP address from which this was sent, and the full command string.
To cancel a previously scheduled command, "schedule cancel JOBID" can be used. JOBID is a number provided as the first item in the output from the schedule list.

notes FILENAME
The message text will be stored in $XYMONHOME/notes/FILENAME which is then used as hyperlinks from hostnames or column names. This requires that the "storenotes" task is enabled in tasks.cfg (it is disabled by default). FILENAME cannot contain any directory path - these are stripped automatically.

usermsg ID
These messages will be relayed directly to modules listening on the "user" channel of the Xymon daemon. This is intended for custom communication between client-side modules and the Xymon server.

modify HOSTNAME.TESTNAME COLOR SOURCE CAUSE
Modify the color of a specific status, without generating a complete status message. This is for backend processors (e.g. RRD graphs) that can override the color of a status based on some criteria determined outside the normal flow of a status. E.g. the normal "conn" status may appear to be green since it merely checks on whether a host can be ping'ed or not; the RRD handler can then use a "modify" command to override this is the actual ping responsetime exceeds a given threshold. (See the "DS" configuration setting in analysis.cfg(5) for how to do this). SOURCE is some identification of the module that generates the "modify" message - future modifications must use the same source. There may be several sources that modify the same status (the most severe status then becomes the actual color of the status). CAUSE is a one-line text string explaining the reason for overriding the normal status color - it will be displayed on the status webpage.

 

EXAMPLE

Send a normal status message to the Xymon server, using the standard Xymon protocol on TCP port 1984:

   $ $XYMON $XYMSRV "status www,foo,com.http green `date` Web OK"

Send the same status message, but using HTTP protocol via the webserveraqs xymoncgimsg.cgi script:

   $ $XYMON http://bb.foo.com/cgi-bin/xymoncgimsg.cgi "status www,foo,com.http green `date` Web OK"

Use "query" message to determine the color of the "www" test, and restart Apache if it is red:


   $ WWW=`$XYMON $XYMSRV "query www,foo,com.www" | awk aq{print $1}aq`
   $ if [ "$WWW" = "red" ]; then /etc/init.d/apache restart; fi

Use "config" message to update a local mytest.cfg file (but only if we get a response):


   $ $XYMON $XYMSRV "config mytest.cfg" >/tmp/mytest.cfg.new
   $ if [ -s /tmp/mytest.cfg.new ]; then 
       mv /tmp/mytest.cfg.new $XYMONHOME/etc/mytest.cfg
     fi

Send a very large status message that has been built in the file "statusmsg.txt". Instead of providing it on the command-line, pass it via stdin to the xymon command:


   $ cat statusmsg.txt | $XYMON $XYMSRV "@"

 

SEE ALSO

combostatus(1), hosts.cfg(5), xymonserver.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS AND PARAMETERS
XYMON MESSAGE SYNTAX
EXAMPLE
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymonnet-again.sh.1.html0000664000076400007640000000456513534041733023173 0ustar rpmbuildrpmbuild Manpage of XYMONNET\-AGAIN.SH

XYMONNET\-AGAIN.SH

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymonnet-again.sh - Xymon network re-test tool  

SYNOPSIS

xymonnet-again.sh

 

DESCRIPTION

xymonnet-again.sh is an extension script for Xymon that runs on the network test server. It picks up the failing network tests executed by the xymonnet(1) program, and repeats these tests with a faster test cycle than the normal xymonnet schedule. This means that when the server recovers and the network service becomes available again, this is detected quicker resulting in less reported downtime.

Only tests whose first failure occurred within 30 minutes are included in the tests that are run by xymonnet-again.sh. The 30 minute limit is there to avoid hosts that are down for longer periods of time to bog down xymonnet-again.sh. You can change this limit with the "--frequenttestlimit=SECONDS" when you run xyxmonnet.

 

INSTALLATION

This script runs by default from your tasks.cfg(5) file.

 

FILES

$XYMONTMP/TESTNAME.LOCATION.status
Temporary status file managed by xyxmonnet with status of tests that have currently failed.
$XYMONTMP/frequenttests.LOCATION
Temporary file managed by xymonnet with the hostnames that xymonnet-again.sh should test.

 

SEE ALSO

xymonnet(1), xymon(7), tasks.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
INSTALLATION
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/reportlog.cgi.1.html0000664000076400007640000000623213534041734022374 0ustar rpmbuildrpmbuild Manpage of REPORTLOG.CGI

REPORTLOG.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

reportlog.cgi - CGI program to report service availability log  

SYNOPSIS

reportlog.cgi

 

DESCRIPTION

reportlog.cgi is invoked as a CGI script via the reportlog.sh CGI wrapper. Based on the parameters it receives, it generates an availability report for a specific host-service combination for the requested time-period. The availability report includes a calculation of the availability percentage (split out on percent green, yellow, red time), and an eventlog for the period listing the status changes that have occurred to allow for drill-down to the test reports that indicate a problem. Access to the individual historical status logs go via the svcstatus.cgi(1) CGI script.

reportlog.cgi is passed a QUERY_STRING environment variable with the following parameters:


   HOSTSVC (the host and service to report on)
   STYLE (report style: "crit", "non-crit", "all")
   ST (starttime in seconds since 1-1-1970 00:00 UTC)
   END (endtime in seconds since 1-1-1970 00:00 UTC)

The following non-standard parameters are handled by the Xymon version of history.cgi:


   IP (IP address of host - for display purposes only)
   REPORTTIME (the REPORTTIME: setting for this host)
   WARNPCT (the WARNPCT: setting for this host)

The REPORTTIME and WARNPCT options are taken from the hosts.cfg(5) definition for the host, or the defaults are used. These modify the availability calculation to handle reporting against agreed Service Level Agreements re. the time of day when the service must be available, and the agreed availability level.

 

OPTIONS

--env=FILENAME
Loads environment from FILENAME before executing the CGI.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5), svcstatus.cgi(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/history.cgi.1.html0000664000076400007640000001132413534041734022056 0ustar rpmbuildrpmbuild Manpage of HISTORY.CGI

HISTORY.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

history.cgi - CGI program to display service history  

SYNOPSIS

history.cgi

 

DESCRIPTION

history.cgi is invoked as a CGI script via the history.sh CGI wrapper. It is passed a QUERY_STRING environment variable with the following parameters:


   HISTFILE (a Xymon service history file)
   ENTRIES (the number of entries to show)
  The following non-standard parameters are handled by the Xymon version of history.cgi:


   IP (IP address of host - for display purposes only)
   PIXELS (width of colorbar when in pixel-mode)
   ENDTIME (when the colorbar begins, a time_t value)
   BARSUMS (which colorbars and summaries to show)

history.cgi analyses the service history file for changes that have occurred within the past 24 hours, and build a colorbar showing the status of the service over this period of time. A statistics summary is also produced, listing the amount of time for each status (green, yellow, red, purple, blue, clear).

Finally, a summary of the last N events is given, with links to the actual event logs.

Unlike the standard history.sh script, history.cgi provides a colorbar and statistics summaries also covering the past 1 week, 4 weeks and 1 year of data. Via links it is possible to browse the entire history of the service at the requested interval.

Note that since the resolution of the display is limited, events may be too short to show up on a colorbar; also, the exact placement of an event may not fully match up with the time-markers.

The graphs should correctly handle the display of months with different number of days, as well as the display of periods that involve beginning and end of Daylight Savings Time, if this occurs in your timezone.

All dates and times shown are in local time for the timezone defined on the Xymon server.

 

PARAMETERS

HISTFILE
Defines the host and service whose history is presented.
ENTRIES
The number of log-entries to show in the event log table. Default is 50; to view all log entries set this to "ALL".
IP
The IP-address of the host. This is only used for the title of the document.
PIXELS
The width of the colorbar graph in pixels. If this is set to 0, a percentage-based graph will be shown, similar to the one provided by the standard history.sh script. Pixel-based graphs can have a higher resolution, but do not resize automatically to suit the size of a browser window. The default value for this parameter is defined at compile-time; 960 is a good value for displays with a 1024x768 resolution.
BARSUMS
Defines which colorbars and summaries to show. This is a number made up from a bitmask. The 1-day graph uses the value "1"; the 1-week graph uses the value "2"; the 4-week graph uses the value "4" and the 1-year graph the value "8". To show multiple graph, add the values - e.g. "6" will show the 1-week and 4-weeks graphs, whereas "15" will show all the graphs. The default is defined at compile-time.
ENDTIME
The history display by default ends with the current time. Setting the ENDTIME parameter causes it to end at the time specified - this is given as a Unix "time_t" value, i.e. as the number of seconds elapsed since Jan 1 1970 00:00 UTC.

 

OPTIONS

--env=FILENAME
Load the environment from FILENAME before executing the CGI.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
PARAMETERS
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/svcstatus.cgi.1.html0000664000076400007640000001224613534041734022420 0ustar rpmbuildrpmbuild Manpage of SVCSTATUS.CGI

SVCSTATUS.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

svcstatus.cgi - CGI program to view Xymon status logs  

SYNOPSIS

svcstatus.cgi [--historical] [--history={top|bottom}]

 

DESCRIPTION

svcstatus.cgi is a CGI program to present a Xymon status log in HTML form (ie, as a web page). It can be used both for the logs showing the current status, and for historical logs from the "histlogs" directory. It is normally invoked as a CGI program, and therefore receives most of the input parameters via the CGI QUERY_STRING environment variable.

Unless the "--historical" option is present, the current status log is used. This assumes a QUERY_STRING environment variable of the form

   HOSTSVC=hostname.servicename
where "hostname" is the name of the host with commas instead of dots, and "servicename" is the name of the service (the column name in Xymon). Such links are automatically generated by the xymongen(1) tool when the environment contains "XYMONLOGSTATUS=dynamic".

With the "--historical" option present, a historical logfile is used. This assumes a QUERY_STRING environment variable of the form

   HOST=hostname&SERVICE=servicename&TIMEBUF=timestamp
where "hostname" is the name of the host with commas instead of dots, "servicename" is the name of the service, and "timestamp" is the time of the log. This is automatically generated by the history.cgi(1) tool.

 

OPTIONS

--historical
Use a historical logfile instead of the current logfile.

--history={top|bottom|none}
When showing the current logfile, provide a "HISTORY" button at the top or the bottom of the webpage, or not at all. The default is to put the HISTORY button at the bottom of the page.

--env=FILENAME
Load the environment from FILENAME before executing the CGI.

--templates=DIRECTORY
Where to look for the HTML header- and footer-templates used when generating the webpages. Default: $XYMONHOME/web/

--no-svcid
Do not include the HTML tags to identify the hostname/service on the generated web page. Useful is this already happens in the hostsvc_header template file, for instance.

--multigraphs=TEST1[,TEST2]
This causes svcstatus.cgi to generate links to service graphs that are split up into multiple images, with at most 5 graphs per image. This option only works in Xymon mode. If not specified, only the "disk" status is split up this way.

--no-disable
By default, the info-column page includes a form allowing users to disable and re-enable tests. If your setup uses the default separation of administration tools into a separate, password- protected area, then use of the disable- and enable-functions requires access to the administration tools. If you prefer to do this only via the dedicated administration page, this option will remove the disable-function from the info page.

--no-jsvalidation
The disable-function on the info-column page by default uses JavaScript to validate the form before submitting the input to the Xymon server. However, some browsers cannot handle the Javascript code correctly so the form does not work. This option disables the use of Javascript for form-validation, allowing these browsers to use the disable-function.

--nkconfig=FILENAME
Use FILENAME as the configuration file for the Critical Systems information. The default is to load this from $XYMONHOME/etc/critical.cfg

 

FILES

$XYMONHOME/web/hostsvc_header
HTML template header

$XYMONHOME/web/hostsvc_footer
HTML template footer

 

ENVIRONMENT

NONHISTS=info,trends,graphs
A comma-separated list of services that does not have meaningful history, e.g. the "info" and "trends" columns. Services listed here do not get a "History" button.

TEST2RRD=test,test
A comma-separated list of the tests that have an RRD graph.

 

SEE ALSO

xymon(7), xymond(1)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
ENVIRONMENT
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/criticaleditor.cgi.1.html0000664000076400007640000000451113534041734023356 0ustar rpmbuildrpmbuild Manpage of CRITICALEDITOR.CGI

CRITICALEDITOR.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

criticaleditor.cgi - Xymon Critical Systems View Editor CGI  

SYNOPSIS

criticaleditor.cgi

 

DESCRIPTION

criticaleditor.cgi is invoked as a CGI script via the criticaleditor.sh CGI wrapper.

criticaleditor.cgi is a web-based editor for the critical.cfg(5) file, which is used to configure the Xymon "Critical Systems" view.

A detailed description of how to use the editor is provided in the Xymon Web documentation, available from the "Help" -> "Critical Systems" link on the Xymon website.

 

SECURITY

Access to this CGI script should be restricted through access controls in your webserver. Editing the Critical Systems View configuration will impact the monitoring of your site.

 

OPTIONS

--config=FILENAME
Name of the Critical Systems View configuration file. The default is critical.cfg in the $XYMONHOME/etc/ directory.

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

--debug
Enables debugging output.

 

SEE ALSO

criticalview.cgi(1), critical.cfg(5), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
SECURITY
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/eventlog.cgi.1.html0000664000076400007640000000335113534041734022201 0ustar rpmbuildrpmbuild Manpage of EVENTLOG.CGI

EVENTLOG.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

eventlog.cgi - CGI program to report the Xymon eventlog  

SYNOPSIS

eventlog.cgi

 

DESCRIPTION

eventlog.cgi is invoked as a CGI script via the eventlog.sh CGI wrapper. Based on the parameters it receives, it generates the Xymon event log for a period. This log shows all status changes that have occurred for all hosts and services.

eventlog.cgi is passed a QUERY_STRING environment variable with the following parameters:


   MAXTIME (maximum minutes to go back in the log)
   MAXCOUNT (maximum number of events to report)

 

OPTIONS

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/criticalview.cgi.1.html0000664000076400007640000000676013534041734023052 0ustar rpmbuildrpmbuild Manpage of CRITICALVIEW.CGI

CRITICALVIEW.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

criticalview.cgi - Xymon Critical Systems view CGI  

SYNOPSIS

criticalview.cgi

 

DESCRIPTION

criticalview.cgi is invoked as a CGI script via the criticalview.sh CGI wrapper.

criticalview.cgi matches the current critical statuses against the critical.cfg(5) file, and generates the "Critical Systems" view.

 

RELATION TO OLD CRITICAL PAGE

This view is a replacement for the statically generated "critical" page provided in versions of Xymon prior to version 4.2. Although the "critical" pages are supported throughout Xymon 4.x, it is recommended that You switch to the newer Critical Systems view provided by this CGI.

 

OPTIONS

--acklevel=NUMBER
Sets the acknowledgment level for acknowledgments sent via the ackinfo.cgi(1) page. Note that this may be overridden by the configuration of the ackinfo.cgi utility.

--tooltips
Hide the host description in a "tooltip", i.e. it will be shown when your mouse hovers over the hostname on the webpage. This saves space on the display so there is more room for the status columns.

--hffile=PREFIX
Define the header/footer files used when building the webpage. The actual files used will be PREFIX_header and PREFIX_footer found in the ~xymon/server/web/ directory. Default: critical.

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

--debug
Enables debugging output.

--config=FILENAME
Use FILENAME as the configuration file for the Critical Systems information. The default is to load this from $XYMONHOME/etc/critical.cfg

--config=ID:FILENAME
Allows the use of multiple Critical Systems configuration files on a single webpage. "ID" is a text that will be shown on the web page prior to the critical systems from FILENAME. This option can be repeated to include critical systems from multiple configurations.

 

ENVIRONMENT VARIABLES

XYMONHOME
Used to locate the template files for the generated web pages.

QUERY_STRING
Contains the parameters for the CGI script.

 

SEE ALSO

ackinfo.cgi(1), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
RELATION TO OLD CRITICAL PAGE
OPTIONS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymongrep.1.html0000664000076400007640000001456213534041733021652 0ustar rpmbuildrpmbuild Manpage of XYMONGREP

XYMONGREP

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymongrep - pick out lines in hosts.cfg  

SYNOPSIS

xymongrep --help
xymongrep --version
xymongrep [--noextras] [--test-untagged] [--web] [--net] [--loadhostsfromxymond] TAG [TAG...]

 

DESCRIPTION

xymongrep(1) is for use by extension scripts that need to pick out the entries in a hosts.cfg file that are relevant to the script.

The utility accepts test names as parameters, and will then parse the hosts.cfg file and print out the host entries that have at least one of the wanted tests specified. Tags may be given with a trailing asterisk '*', e.g. "xymongrep http*" is needed to find all http and https tags.

The xymongrep utility supports the use of "include" directives inside the hosts.cfg file, and will find matching tags in all included files.

If the DOWNTIME or SLA tags are used in the hosts.cfg(5) file, these are interpreted relative to the current time. xymongrep then outputs a "INSIDESLA" or "OUTSIDESLA" tag for easier use by scripts that want to check if the current time is inside or outside the expected uptime window.

 

OPTIONS

--noextras
Remove the "testip", "dialup", "INSIDESLA" and "OUTSIDESLA" tags from the output.

--test-untagged
When using the XYMONNETWORK environment variable to test only hosts on a particular network segment, xymonnet will ignore hosts that do not have any "NET:x" tag. So only hosts that have a NET:$XYMONNETWORK tag will be tested.
With this option, hosts with no NET: tag are included in the test, so that all hosts that either have a matching NET: tag, or no NET: tag at all are tested.

--no-down[=TESTNAME]
xymongrep will query the Xymon server for the current status of the "conn" test, and if TESTNAME is specified also for the current state of the specified test. If the status of the "conn" test for a host is non-green, or the status of the TESTNAME test is disabled, then this host is ignored and will not be included in the output. This can be used to ignore hosts that are down, or hosts where the custom test is disabled.

--web
Search the hosts.cfg file following include statements as a Xymon web-server would.

--net
Search the hosts.cfg file following include statements as when running xymonnet.

--loadhostsfromxymond
xymongrep will normally attempt to load the HOSTSCFG file by itself when searching for lines to transmit. If the file is unreadable, it will exit out. With this option, it will query the xymond server (set via the XYMONSERVER environment) for the hosts file. This can be used if you're running this on a client or remote system and can't or don't want to have the hosts.cfg file synchronized across your servers.

 

EXAMPLE

If your hosts.cfg file looks like this


   192.168.1.1   www.test.com  # ftp telnet !oracle
   192.168.1.2   db1.test.com  # oracle
   192.168.1.3   mail.test.com # smtp

and you have a custom Xymon extension script that performs the "oracle" test, then running "xymongrep oracle" would yield


   192.168.1.1   www.test.com  # !oracle
   192.168.1.2   db1.test.com  # oracle

so the script can quickly find the hosts that are of interest.

Note that the reverse-test modifier - "!oracle" - is included in the output; this also applies to the other test modifiers defined by Xymon (the dial-up and always-true modifiers).

If your extension scripts use more than one tag, just list all of the interesting tags on the command line.

xymongrep also supports the "NET:location" tag used by xymonnet, so if your script performs network checks then it will see only the hosts that are relevant for the test location that the script currently executes on.

 

USE IN EXTENSION SCRIPTS

To integrate xymongrep into an existing script, look for the line in the script that grep's in the $HOSTSCFG file. Typically it will look somewhat like this:


   $GREP -i "^[0-9].*#.*TESTNAME" $HOSTSCFG | ... code to handle test

Instead of the grep, we will use xymongrep. It then becomes


   $XYMONHOME/bin/xymongrep TESTNAME | ... code to handle test

which is simpler, less error-prone and more efficient.

 

ENVIRONMENT VARIABLES

XYMONNETWORK
If set, xymongrep outputs only lines from hosts.cfg that have a matching NET:$XYMONNETWORK setting.

HOSTSCFG
Filename for the Xymon hosts.cfg(5) file.

 

FILES

$HOSTSCFG
The Xymon hosts.cfg file

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
EXAMPLE
USE IN EXTENSION SCRIPTS
ENVIRONMENT VARIABLES
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/xymoncfg.1.html0000664000076400007640000000465513534041733021456 0ustar rpmbuildrpmbuild Manpage of XYMONCFG

XYMONCFG

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

xymoncfg - output the full hosts.cfg file  

SYNOPSIS

xymoncfg [--web] [--net] [filename]

 

DESCRIPTION

xymoncfg(1) dumps the full hosts.cfg file to stdout. It follows "include" tags in the hosts.cfg files, and prints the full contents as seen by the xymongen(1) and xymonnet(1) utilities.

If no filename is given, xymoncfg displays the file pointed to by the HOSTSCFG environment variable.

 

OPTIONS

--web
Show the hosts.cfg file following include statements as a Xymon web-server would.

--net
Show the hosts.cfg file following include statements as done when running xymonnet.

-s
Output only the lines that look like environment variable definitions, in a format suitable for use with Bourne-style shells (e.g. bash, ksh). You will probably not use this with the default hosts.cfg input file, but e.g. xymonserver.cfg. To define all the variables in xymonserver.cfg inside your shell script, you can use


   eval `xymoncfg -s /etc/xymon/xymonserver.cfg`

-c
Similar to "-s", but for C-shell.

 

ENVIRONMENT VARIABLES

HOSTSCFG
Filename for the hosts.cfg(5) file.

 

SEE ALSO

hosts.cfg(5), xymonserver.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/combostatus.1.html0000664000076400007640000000573413534041733022166 0ustar rpmbuildrpmbuild Manpage of COMBOSTATUS

COMBOSTATUS

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

combostatus - Xymon combination test tool  

SYNOPSIS

combostatus --help
combostatus --version
combostatus [--debug] [--quiet]

 

DESCRIPTION

combostatus is a Xymon extension script that runs on the Xymon server. It combines the results of one or more of the normal Xymon test results into a combined test result, using standard arithmetic og logical operators.

The resulting tests are sent to the Xymon display server as any normal test - so all of the standard Xymon functions (history, statistics etc.) are available for the combined tests.

The tool was born from the need to monitor systems with built-in redundancy and automatic failover - e.g. load-balanced web servers. But other uses are possible.

 

OPTIONS

--error-colors=COLOR[,COLOR]
Specify which colors trigger an error status. By default only a "red" status counts as an error color - all other colors, including yellow, will count as "green" when evaluating the combined status. COLOR is "red", "yellow", "blue", "purple" or "clear".

--quiet
Normally, the test status sent by combostatus includes information about the underlying test results used to determine the current value of the combined test. "--quiet" eliminates this information from the test status page.

--debug
Provide debugging output for use in troubleshooting problems with combostatus.

--no-update
Don't send any status messages - instead, the result of the combotests is simply dumped to stdout. Useful for debugging.

 

FILES

$XYMONHOME/etc/combo.cfg
Configuration file for combostatus, where the combined tests are defined
$XYMONHOME/etc/tasks.cfg
Configuration file controlling when combostatus is run.

 

SEE ALSO

combo.cfg(5), hosts.cfg(5), xymonserver.cfg(5), tasks.cfg(5)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
FILES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:11 GMT, September 04, 2019 xymon-4.3.30/docs/manpages/man1/ackinfo.cgi.1.html0000664000076400007640000000546313534041734021776 0ustar rpmbuildrpmbuild Manpage of ACKINFO.CGI

ACKINFO.CGI

Section: User Commands (1)
Updated: Version 4.3.30: 4 Sep 2019
Index Return to Main Contents
 

NAME

ackinfo.cgi - Xymon CGI script to acknowledge alerts  

SYNOPSIS

ackinfo.cgi

 

DESCRIPTION

ackinfo.cgi is invoked as a CGI script via the ackinfo.sh CGI wrapper.

ackinfo.cgi is used to acknowledge an alert on the Xymon "Critical Systems" view, generated by the criticalview.cgi(1) utility. This allows the staff viewing the Critical Systems view to acknowledge alerts with a "Level 1" alert, thereby removing the alert from the Critical Systems view.

Note that the Level 1 alert generated by the ackinfo.cgi utility does NOT stop alerts from being sent.

In a future version of Xymon (after Xymon 4.2), this utility will also be used for acknowledging alerts at other levels.

 

OPTIONS

--level=NUMBER
Sets the acknowledgment level. This is typically used to force a specific level of the acknowledgment, e.g. a level 1 acknowledge when called from the Critical Systems view.

--validity=TIME
Sets the validity of the acknowledgment. By default this is taken from the CGI parameters supplied by the user.

--sender=STRING
Logs STRING as the sender of the acknowledgment. By default, this is taken from the loginname of the webuser sending the acknowledgment.

--env=FILENAME
Loads the environment defined in FILENAME before executing the CGI script.

--area=NAME
Load environment variables for a specific area. NB: if used, this option must appear before any --env=FILENAME option.

--debug
Enables debugging output.

 

ENVIRONMENT VARIABLES

XYMONHOME
Used to locate the template files for the generated web pages.

QUERY_STRING
Contains the parameters for the CGI script.

 

SEE ALSO

criticalview.cgi(1), xymon(7)


 

Index

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
ENVIRONMENT VARIABLES
SEE ALSO

This document was created by man2html, using the manual pages.
Time: 23:08:12 GMT, September 04, 2019 xymon-4.3.30/docs/clonewarn.jpg0000664000076400007640000001046511070452713016633 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀqƒ"ÿÄÿÄ6!"123#AQBaq$7S‘’u“±´ÿÄÿÄ$!Að1BQq‘ñÿÚ ?þ©"ÉÈDŒù2ó¦•{lÉ 4£c¤ì¢*MŸ‚³+?ƪé¢3Tàˆ™ôJ#²²ŒÙ‰o¸JQ$¼%%jQŸ‚IêffDEû˜„ŒÇÅdâð¼Ô”«7›ioºÁ!JK–J#NäTDIA¥&uz_Ìĸ$Srÿ¢5EÇ®’_£’+ÿHIÿÉEú¤g9>)Ù~®ñÎB†=°±òÒ¥Õ’UhJHÿ©“«¯ìcã·½Ò‰»6³Å1?±GõÛfÍXÊç§£:ö"ZÍr"\?›­ŸÐ¿û—Ïö22ý¦Î¸þíåµ?ŒÔ”——?+Oõ2­‹û(‹êÑÝCì¡æ”JBÈŒŒæCÕØwJw 6}Ôñ-Z›3j¯·±†á_ļŠåÎò‡â³‘Cs‹n×JKjQ§´ÜÐÈD²-¬õ¯r2øþÞ:kgä9ظÖßïN)·šøbVÛjFmö’/ù ÂMxªð=Ç;7ijÓñø¶°Ø\S9,¤üÞ}ô6ü³ŽËl³“x–µ,³úm$D“³WèDf,Ï2“ÞÂCÁñ–äÎÉGž·›—èD7!¾Ó¡jKk5cŠI)$Ix£3MƒÜD€Ëeq³#L›)™±–×r~-õ<ót¶ÔƒA©EDi3-æÊÄÌ'Åâ%âäÃ\­ñ°åEo±ÂWoĺӮ¸á™Z–kd•vEîW%U|·ªàañHcÈä_˜Á³•Ë¢fWÓeò7Í*Ú—D’J ÔGtDGSqÞ ¹œÅ`Ýã8˜ÙÙtJq-9&ã´ˆÎO«¹^é'„¤Ò“Ûb?,\áS”ÀÊe1Ó#Ë›)™ÑÖßr[êyæéhRƒR‹Ú¤ŸÐŸÔ¬}'qåFÇsù¸ù,i5“C­ªJ’鑸•nÚ›4¨É>Ý(µNµD£/=#„.DˆÊŠó¹¬ºÜaJ%J<”“4™—ƒ2?_°Ñàs˜NA s09Œ~V26”ô)(} Y¤Ôƒ2#£#¯ê_¸øpþ?‹à[ÃB‘.C(}÷û%8KuJy庻UûœWõª³3ò-Äž?Î]ËsY|| cã¦4‡™RÉ‘N"lÌ»Ž1 ¿)FEª’µY)'DFuCèï$ÌEá^žã2˜bãòx¨Ñ ËDîÇTãpÍÒ7Љ RY‘’Ô"2#?ñ&UÉãg%f²ó> ÷dC†û›1œq B&H' µZˆ’¥©$GàŠŠ½ãøŽ6+Šãš~Zšã|©iÙÍ"¹»=¾}ލükî"ý<½@Êɉ \Y%4ÃÎ`–™ö䥥•¾ÚG_åv6Ú”FFåW’#ð=»êv%Æe–63’䵇.3f½%rT’CDª:27cÙÑÑ<E–‚ã±R[ÉådÅÆïød  ãÁÜ'ת gIR’[©Z¤ÌŠ„\w¦\jqdÁͼnEÉí#5©uM/Ç–Ñ£:§Á—C^NŽÜPùžMs!bpq3dÍ‘š39™u¥ |âaJR͵«U›–II#Ú‚-JÓ*?8Èd"b˜ÄñöÞÌÎ\Ô»Lî¦cüÝ ÝJj"pÒ”Ò=Ûû|‹|7Æâ²±ò1ß–§cþ#¡8´šOã¥"K·I/’ÐDŸÙ7{‘IÉ8™ã±‘d`Ï;>4ù’Pî:LdIJe¼·žA|Au)µ'Ú¯$II‘š“ä/ø&}îKÇ•‘V5Ȫtœ6Ôć;Q™›wãåugVyO¨¼žv+dƒ°Û<™,rK0JZ\S |‰Òê"C}m¸­’kU$½„gCIéfgá1“ö)]Òdº•½Ú¤ò{U/ùÔ]”jýLŒÇÛÄq°q\WÓòÔ×ÓàKNÎiÈÅÙíóìuGã_qéàÂ¥|âcœ™Øœl†/ P&¢V] BeFÒK‡!H#ÐÐë&Í[*µ¢3*Äz­î ¼ÔX˜©3•ü.C­e‰xæWÔNöªZ[?ÊÔÒ[idµLˆìh2üv\„ä20åÈË#,‰ )³TyŠˆÄh%¡I4õ£ä´«ÊŒÿjóá{0ù?!j\üdŸÜÒŸ7zPÉ•)³lÐil½¦ƒ"?‘$‰ÂªXå<®6âÑàÁ«‘ÄÌ•(‘–ìIõÈŒŽÖÖ†¹%Z ÐKíVÚ ã+ÕÜGñ़9°YbÄO0ÙOïìêØ¢k·_g·m¶¯vºùøþ ¬+˜ì¦R+Ø¥H§P¦”©Iò^}’›2ÕkBLô$)¤Hgˆ·.¹³¹¨pÜ”sƲëeÇ[©Vh7”«R’•’LÌ켑ã†r,¿!•=×pqàâãM™ ¹8Üu÷#É[;dÙ ôQÙ®Èʵ2÷R9¬ØùnNoakÆT¯È*iö)% ¹'ÖÉ6{vL”´•Q‘™ÚKIÇñ°‡n­·&I–f鑞ï¾ãë/^ N(‹úY™ùÛã˜ÂN}·¹,çÞ7g2é‘ î;QÍDFI42Ÿš¼üˆŠÆq¿WqÉ|jðä˜X—²êü+0Þ@ÐÃZö%ÒBSÖálŸo¹'gJ:1z÷(Îc¸ä¬¶wŒ"„¨í O)÷pšm¥¡$Ú÷Zþ¤–ÖJ:1'Ä[f4¨y,îk7DEÃøYî¶m¥•‘“ìBT³2*Ùf¥Uùòwá®XxlŽw7”Žù4M.SèìÔ­›6Ô„'Ü•+ul£4¦ÌèVGžeqp2MdxËeš‚þ9 6C±§Û›$˜ihuM§ÎÄå’^Qó£±.W(äÍÏ,L~-^V<2e¼©“L´·CImjdÇÔ³ÔÒ„‘¤ÈÕò3û3Á`ôHøü¶W%2LÈRž›%mw+áKÌ·HBP”’vD’3Ý^lìJä\MŒ¾P²Meò¸™Jð’Ô'âX³Q6½Ðª£RÌ”T[*”V/£_å ÿ Aÿç@Ö þ3ˆÇøÞ3 n¹ ¨Œ©Ó#ZÚ 5]a`" “rCXÙ.Ãl’†”¦̲#¢ÿq ª3"q*Èœ“ŒA‚Ô&gJÕ¢£5ã¤ì¥Ú”ªn¬ÔfgýLÅ.J_™É!æÿˆs-.+Jl¢·Zc9µùZ:¼™_ÏúìCUÔßúhÿ`êký4ćÎ\é«UÌÌ×<ùòë\Ço?È0¤á-¼‹¤¤‘þ+Áÿâø‹í©ScDJÿiÛŠjmH¤HÍ$J"2$¨Ô’²#¢!yÔ×úhÿ‰IJSô¤‹ûÛµôý­¶ìÜ·\óÙ/j¦í8˜~€÷Ü žW,ˆ™×1qøô©zT·›I¥¦Ò§I²µ­Ä’”EºÍ(ØÉ-‘›Jâ±”çVü2s[é¶ï3ù{u]Ôƒú{WuaÊ»o²á€Ac;)έødæ·ÓmÞgòö껩ôö®êþÕvßaŒì§:·á“šßM·yŸËÛªî¤ÓÚ»«ûUÛ}…NŒì§:·á“šßM·yŸËÛªî¤ÓÚ»«ûUÛ}†3²œê߆Nk}6Ýæ/n«ºOjî¯ì9WmöàXÎÊs«~9­ôÛw™ü½º®êAý=«º¿°å]·Øc;)έødæ·ÓmÞgòö껩ôö®êþÕvß`NŒì§:·á“šßM·yŸËÛªî¤ÓÚ»«ûUÛ}†3²œê߆Nk}6Ýæ/n«ºOjî¯ì9Wmöàî#ʤr.s˜e²m¬[x\TÈŒ!H^ªrTµˆRÉfd†ÊÒµ#ÚFŸ™™ìDö«Ô ÓÝ5¼Xéìê­©Ù'®ýeuµ×bëkѽ¶vp‚ûUêiîšÞ,töuVÔì“×~²ºÚë±uµèÞÛ;8Y@V[;•ÏIåÆøÚ±±ž fKžÂßChqkCHKhZ F£iÓ35$’^üPd}G{ ñQ#:Î}x|©²•¸•À»%£`¾­œÿD“ØífŸ'JLÿÉ?F{æÅä¾¢?ñ0ÎK´J5 ”‚Z²MKÔÉEõªÈüUcžÂ—YyiÊ)9W²y3‘&™Ër#ÑÝ!)Kˆ×ê¢h‹ÉžÂ¢ÿ‹HÏLˆìÌìHÐ;—´hhµ:Ãuà^Æ•,þfI"$ü­U±Ü n)ˆ›ƒ†î=ü»¹(h_ø/ˆA›ìµ_mnl}µú(È•Uf£òw"(9¥÷ó¼ÓÝÝÝœg®ÎÞÍí2ÏmûÚþwØåü÷_Ô}8sJïçy§»»»8Î]½›ÚežÛö;µüï±Ëùúp² ç™x¾¤ä3ÎæKŒðæ$®“»\’sjSitB4FI8IQlUKq4Iqd¨Œb½Mg«LG>­5ß—åzõUÛ'·ØEÝín]ö¹¿NG1cêk=Zb8áõi®ü¿(«×ª®Ù=¾Â.ïkrïµÍÌb½Mg«LG>­5ß—åzõUÛ'·ØEÝín]ö¹¿N1cêk=Zb8áõi®ü¿(«×ª®Ù=¾Â.ïkrïµÍÌb½Mg«LG>­5ß—åzõUÛ'·ØEÝín]ö¹¿NÅŒW©¬õiˆã‡Õ¦»òü¢¯^ª»döû»½­Ë¾×71Šõ5ž­1pú´×~_”UëÕWlžßawµ¹wÚæý8s1^¦³Õ¦#ŽVšïËòнzªí“Ûì"îö·.û\ÜÆ+ÔÖz´ÄqÃêÓ]ù~QW¯U]²{}„]ÞÖåßk›ôà„ôãŽò\o$ÌæyX¶>.QÛ‡‘~bª9¿jqÇ›JŒÌO“5™™ù°ÿÙxymon-4.3.30/docs/criticalsystems.html0000664000076400007640000002624411535462534020263 0ustar rpmbuildrpmbuild Critical Systems

Critical Systems

If you are monitoring lots of hosts, getting an overview of which hosts need attention can be difficult. Most likely you've split the hosts among several pages, and the "All non-green" view is just cramped full with systems where a logfile is showing some errors, a filesystem needs cleaning up etc.

The "Critical Systems" view lets you define exactly which tests on what hosts need attention. In other words, this is the view your Operations Center will be using to decide whether to call out people in the middle of the night. It might look like this:

This document describes how you configure the Critical Systems view, and how it works for your operators. By "operators" I mean the people who are doing the 24x7 monitoring. Where I work, these people normally do not resolve the issues - they just raise the trouble-tickets and assign them to the "engineer" on duty. It may be different in your organization.

The Critical Systems editor

To configure what goes on the Critical Systems view, you use a dedicated editor.

The default Xymon setup has nothing on the critical systems view. So to use it, you must configure some of your systems and tests to be included on this view. From the Administration menu, pick the Edit Critical Systems item. This is usually in the password-protected area of Xymon, so you will need to authenticate yourself before you are allowed access. If you haven't set this up yet, look at the installation guide to see how you do that.

After authenticating, you are presented with the editor page.

The editor form

Let me explain what the various fields are for:
  • The Host and Test fields are text entry fields. This is where you enter the name of the host and test you want to configure. If you would rather not type too much, you can enter just the beginning of the hostname and use the Search and Next buttons to walk through the currently configured tests.
  • The Priority field defines how important this test is. By default you have three priorities: 1, 2 and 3. Priority 3 is the lowest - things you must fix, but it can wait until you've had lunch or finished the department meeting. Priority 2 is for more important things, like one of your RAID systems running in degraded mode. Priority 1 is the highest priority - the kind of problem where you want to get a phonecall at 3 AM in the morning.
  • Then there is a group of time-related settings. The Monitoring time defines when this test should show up on the Critical Systems view. By default, that will be 24 hours a day, 7 days a week. But you probably have some systems that don't need attention during week-ends, or perhaps you only want to support a server during normal work-hours. Then you can use this setting to make sure it will only show up on the Critical Systems view during those periods. If you are migrating from the old "NK" settings in the hosts.cfg file, this is the equivalent of the "NKTIME" setting.
    The Start monitoring and Stop monitoring settings are used if you have systems that go into production at a certain date, or which are de-commisioned at a certain date. Instead of having to update your Critical Systems configuration exactly when that happens, you can configure the dates when monitoring of the systems should begin or end.
  • The Resolver group is a text field. You can use it for your operations people to see which group of engineers the should call about this problem. If you have multiple groups handling different parts of your IT systems, use this to let the operations staff know whether to call the Unix admins, the DBA's or one of your Webmasters.
  • The Instruction is a text entry field, where you can place a brief instruction to the operators handling the problem: If there is a simple thing that the operations people can try to fix the problem before calling the on-duty engineer, then you can place instructions here - e.g. perhaps the issue is with an external partner, so they just need to call them and let them know there is an issue. You can use HTML tags in this field, so if it's a long story then just put in an HTML link to another document.
  • The Clone fields at the bottom of the form (not visible in the screenshot) are described later

Setting up a disk status

Right now, there is a yellow disk status on my system.

But it is not on the Critical Systems view, and I want it to be. It is a priority 3 event, and I only want it monitored between 7AM and 8PM on weekdays. Most likely it is just some logfiles that are filling up, so the operators can try and clean out the /var/log/ directory - if that doesn't solve the problem, then they must escalate it to the Unix admins.

So on the Critical Systems editor, I enter the hostname localhost and the test disk, then hit the Search button. I get this warning:


telling me that there is nothing configured yet for this host+test combination. If there had been any previous configuration, it would have shown up on the form.

So I fill out the fields of the form and hit the Update button. The form changes to look like this: As you can see, there is now a Last update text showing who has changed this configuration, and when it was last done.

If I now go back to the Critical Systems view - from the menu, pick Views and Critical Systems view - you will see that the status is now showing up:

Template definitions - cloning records

If you have many hosts that share a common setup on the Critical Systems view, then editing all of them can be tiresome. Instead, you should define a template and then clone it to all of the hosts.

NOTE: A cloned definition is not a copy of the original definition. It is in fact a pointer back to the original definition, so if you change the original definition after you performed the cloning, then the clone definition will also change.

Defining a template is just like defining the Critical Systems view for a host. Just call the host something that looks like a template - "Standard Unix", for instance. So here is a definition for a Unix cpu template.

Now we have created the template (if you haven't pushed the Update button to save the template, do it now). To apply this template to a host, scroll down to the bottom of the editor form, and enter the hostname that you want to apply the template to, then hit the Add/remove clones button:

After it has updated, you can see that "localhost" is now listed in the scrollbox showing the clones.

NOTE: Cloning happens at the host level, so even though we did the cloning from a cpu test definition, it will also affect all the other definitions we have for the Standard Unix host.

The Critical Systems view

The critical systems view lets the operators filter active alerts in several ways. It might look like this:

Filtering the Critical Systems view

The drop-down boxes lets the operators filter the alerts that show up on the page.

  • The Priority limits alerts so that only those with a matching priority get displayed.
  • The Color removes those alerts that have an unwanted color
  • The Age limit can be used to only see the most recent events.
  • The Acked selection can be used to toggle the view of events that have been acknowledged by the operators.

Tip: If you have a preferred default setting for these, then you can bookmark it in your browser - the settings are part of the URL, so your bookmark will include the current settings.

The detailed status view

When looking at the status of one of the items shown on the Critical Systems view, a number of additional items show up. On the example Critical Systems view above, you will notice that the instructions we entered about what to do with the disk status is shown here, so they are available to the operators. There are links to the host documentation and host information. There is also an acknowledge function, so that the operators can acknowledge an alert right away.

Critical Systems acknowledgment

From the detailed status view, the operator can acknowledge an alert, after he has assigned the problem to an engineer or has handled it in some other way. This serves two purposes: First, it removes the status from the Critical Systems view, so the operator can concentrate on the new problems that appear. And second, it lets everyone else see that the problem has been noticed and is being handled by someone.

When acknowledging an alert, the operator can add information about what the problem is, or who is handling it, and when it is expected to be resolved. E.g. like this:

The Host-ack checkbox lets the operator acknowledge all current alerts for a given host, e.g. a full disk could easily trigger alerts for both the disk-, msgs- and procs-statuses - a Host ack lets him handle all of those.

After the operator has acknowledged the status, the acknowledgment will be visible on the Critical systems status view:

(If you are wondering why this image says it is a "Level 1" acknowledgement, then the answer is that a future release of Xymon will allow multiple acknowledgments by different groups. Level 1 is the operator who sees the alert on the Critical Systems view. Level 2 could be the engineer who gets paged by a Xymon alert going out).

How acknowledgements are visible to everyone

The acknowledgments that the operator enters from the status page will show up on the status visible to everyone. E.g. here is how the overview page will appear to a normal user: Note that the "disk" status has a yellow checkmark, indicating that it has been acknowledged:

And the detailed status page also includes the acknowledgment information:

xymon-4.3.30/docs/howtograph.html0000664000076400007640000003302311535462534017214 0ustar rpmbuildrpmbuild How to setup custom graphs

How to setup custom graphs

This document walks you through the setup of custom graphs in your Xymon installation. Although Xymon comes with pre-defined setups for a lot of common types of graphs, it is also extensible allowing you to add your own tests. For many kinds of tests, it is nice to view them over a period of time in a graph - this document tells you how to do that.

The NCV (Name-Colon-Value) and SPLITNCV methods

In many cases it is quite trivial to collect some data and send them to Xymon in format like this:

  Name: Value

e.g. if you have a device that collects weather information, it might look like

  Temperature: 19.2
  Humidity: 53
  Wind: 9.6

In Xymon, this is known as NCV - Name, Colon, Value - formatted data, and Xymon has built-in support to pick up data formatted this way, and collect the data for graphs.

Make a script to collect the data

First create your test data. Typically, this is an extension script that sends in some data to Xymon, using a status or data command. If you use status, it will show up as a separate column on the display, with a green/yellow/red color that can trigger alerts. If you use data, Xymon just collects the data into a graph - you must go to the trends column to see the graph. For this example, we'll use status.

So we create an extension script. Here is an example script; it picks two numbers out of the Linux kernel's memory statistics, and reports these to Xymon.


	#!/bin/sh

	cat /proc/slabinfo | \
	   egrep "^dentry_cache|^inode_cache" | \
	      awk '{print $1 " : " $3*$4}' >/tmp/slab.txt

	$XYMON $XYMSRV "status $MACHINE.slab green `date`

	`cat /tmp/slab.txt`
	"

	exit 0

Get xymonlaunch to run the script

Save this script in ~xymon/client/ext/slab, and add a section to the ~xymon/client/etc/clientlaunch.cfg to run it every 5 minutes:


	[slabinfo]
        	ENVFILE /usr/lib/xymon/client/etc/xymonclient.cfg
	        CMD /usr/lib/xymon/client/ext/slab
		INTERVAL 5m
(On the Xymon server itself, you must add this to the file ~xymon/server/etc/tasks.cfg)

Check that the script data arrives in Xymon

After a few minutes, a slab column should appear on your Xymon view of this host, with the data it reports. The output looks like this:


	Sun Nov 20 09:03:44 CET 2005

	inode_cache : 330624
	dentry_cache : 40891068

Arrange for the data to be collected into an RRD file

This is obviously a name-colon-value formatted report, so we'll use the NCV module in Xymon to handle it. Xymon will find two datasets here: The first will be called inodecache, and the second dentrycache (note that Xymon strips off any part of the name that is not a letter or a number; Xymon also limits the length of the dataset name to 19 letters max. since RRD will not handle longer names). To enable this, on the Xymon server edit the ~xymon/server/etc/xymonserver.cfg file. The TEST2RRD setting defines how Xymon tests (status columns) map to RRD datafiles. So you add the new test to this setting, by adding slab=ncv at the end:


TEST2RRD="cpu=la,disk,<...lots more stuff...>,xymond,mysql=ncv,slab=ncv"

slab is the status column name, and =ncv is a token that tells Xymon to send these data through the built-in NCV module.

By default, the Xymon NCV module expects data to be some sort of counter, e.g. number of bytes sent over a network - it uses the RRD DERIVE datatype by default, which is for data that is continuously increasing in value. Some data are not like that - the data in our test script is not - and for those data you'll have to make an extra setting to tell Xymon what RRD data type to use. The RRDtool rrdcreate(1) man-page has a detailed description of the various RRD datatypes. It is available online at http://www.mrtg.org/rrdtool/doc/rrdcreate.en.html

Our test script provides data that goes up and down in value (it is the number of bytes of memory used for a Linux kernel bufffer), and for that kind of data we'll use the RRD GAUGE datatype. So we add an extra setting to xymonserver.cfg:


	NCV_slab="inodecache:GAUGE,dentrycache:GAUGE"

This tells the xymond_rrd module that it should create an RRD file with two datasets of type GAUGE instead of the default (DERIVE). The setting must be named NCV_<columnname>.

In some cases it can be useful to use multiple RRD files - one for each dataset - instead of putting all of the datasets into one RRD file. E.g. if you want to add or remove datasets over time - if they are all stored in one RRD file then you have to dump, modify and reload the data from the RRD file. If you store each dataset in a separate file, then you can just delete the file. Xymon supports this if you call this setting SPLITNCV instead of NCV. Then Xymon will store each dataset in an RRD file column,dataset.rrd, e.g. slab,inodecache.rrd, and the name of the dataset will be "lambda". Apart from this, the setup is identical for the NCV- and SPLITNCV-methods.

The xymonserver.cfg file is not reloaded automatically, so you must restart Xymon after making these changes. Or at least, kill the xymond_rrd processes (there are usually two) - xymonlaunch will automatically restart them, and they will then pick up the new settings.

Check that the RRD collects data

The next time the slab status is updated, Xymon will begin to collect the data. You can check this by looking for the slab.rrd file in the ~xymon/data/rrd/HOSTNAME/ directory. If you want to check the data it collects, the rrdtool dump ~xymon/data/rrd/HOSTNAME/slab.rrd will tell you what it got:


	<!-- Round Robin Database Dump -->
	<rrd>
		<version> 0001 </version>
		<step> 300 </step> <!-- Seconds -->
		<lastupdate> 1132474725 </lastupdate> <!-- 2005-11-20 09:18:45 CET -->

		<ds>
			<name> inodecache </name>
RRD datatype------>	<type> GAUGE </type>
			<minimal_heartbeat> 600 </minimal_heartbeat>
			<min> 0.0000000000e+00 </min>
			<max> NaN </max>

			<!-- PDP Status -->
current value----->	<last_ds> 330624 </last_ds>
			<value> 0.0000000000e+00 </value>
			<unknown_sec> 0 </unknown_sec>
		</ds>

If you go and look at the status page for the slab column, you should not see any graph yet, but a link to xymon graph ncv:slab. One final step is missing.

Setup a graph definition

The final step is to tell Xymon how to create a graph from the data in the RRD file. This is done in the ~xymon/server/etc/graphs.cfg file.


	[slab]
		TITLE Slab info
		YAXIS Bytes
		DEF:inode=slab.rrd:inodecache:AVERAGE
		DEF:dentry=slab.rrd:dentrycache:AVERAGE
		LINE2:inode#00CCCC:Inode cache
		LINE2:dentry#FF0000:Dentry cache
		COMMENT:\n
		GPRINT:inode:LAST:Inode cache \: %5.1lf%s (cur)
		GPRINT:inode:MAX: \: %5.1lf%s (max)
		GPRINT:inode:MIN: \: %5.1lf%s (min)
		GPRINT:inode:AVERAGE: \: %5.1lf%s (avg)\n
		GPRINT:dentry:LAST:Dentry cache\: %5.1lf%s (cur)
		GPRINT:dentry:MAX: \: %5.1lf%s (max)
		GPRINT:dentry:MIN: \: %5.1lf%s (min)
		GPRINT:dentry:AVERAGE: \: %5.1lf%s (avg)\n

[slab] is the name of this graph, and it must match the name of your status column if you want the graph to appear together with the status. The TITLE and YAXIS settings define the graph title and the legend on the Y-axis. The rest are definitions for the rrdgraph(1) tool - you should read the RRDtool docs if you want to know in detail how it works. For now, all you need to know is that you must pick out the data you want from the RRD file with a DEF line, like


		DEF:inode=slab.rrd:inodecache:AVERAGE
which gives you an "inode" definition that has the value from the inodecache dataset in the slab.rrd file. This is then used to draw a line on the graph:

		LINE2:inode#00CCCC:Inode cache
The line gets the color #00CCCC (red-green-blue), which is a light greenish-blue color. Note that you can have several lines in one graph, if it makes sense to compare them. You can also use other types of visual effects, e.g. stack values on top of each other (like the vmstat graphs do) - this is described in the rrdgraph man-page. An online version is at http://www.mrtg.org/rrdtool/doc/rrdgraph.en.html.

The GPRINT lines at the end of the graph definition also uses the inode value to print a summary line showing the current, maximum, minimum and average values from the data that has been collected.

Once you have added this section to graphs.cfg, refresh the status page in your browser, and the graph should show up.

Add the graph to the collection of graphs on the trends column

If you want the graph included with the other graphs on the trends column, you must add it to the GRAPHS setting in the ~xymon/server/etc/xymonserver.cfg file.


	GRAPHS="la,disk,<... lots more ...>,xymonproxy,xymond,slab"
Save the file, and when you click on the trends column you should see the slab graph at the bottom of the page.

Common problems and pitfalls

If your graph nearly always shows 0

You probably used the wrong RRD datatype for your data - see step 4. By default, the RRD file expects data that is increasing constantly; if you are tracking some data that just varies up and down, you must use the RRD GAUGE datatype. Note that when you change the RRD datatype, you must delete any existing RRD files - the RRD datatype is defined when the RRD file is created, and cannot be changed on the fly.

No graph on the status page, but OK on the trends page

Make sure you have ncv listed in the GRAPHS setting in xymonserver.cfg. (Don't ask why - just take my word that it must be there).

More advanced: Sending a "trends" message

The NCV method works fine in many cases, but you may run into a situation where it isn't really suitable. One possible problem with this method is that you can only store data in a single RRD file using the NCV method, and there may be situations where you want to use multiple RRD files for flexibility - e.g. if you are reporting performance for a number of applications, then it is useful to have one RRD file for each application. And since there are different performance metrics for each application, you cannot use the SPLITNCV method.

Xymon supports a different method for collecting data in these cases - you can send a "trends" message to Xymon with the data you want to put into a graph. All hosts appearing on the Xymon server already have a "trends" status column, but if you send a "trends" status message to Xymon, it will not show up in the "trends" column - instead, it will be used to create/update an RRD file with data. And inside the "trends" message, you can define exactly what RRD files you want to use, how they are formatted, what data goes into the RRD file and so on. Here is an example of a "trends" message, using the same data that we used in the example above for collecting some data about the current weather:

data berlin.trends
[weather.rrd]
DS:temperature:GAUGE:600:U:U 19.2
DS:humidity:GAUGE:600:0:U 72
DS:wind:GAUGE:600:0:U 9.6

This creates an RRD file for the host "berlin", called "weather.rrd". The RRD file has three datasets: temperature, humidity and wind, all of which are of the GAUGE datatype. For more information about the DS definitions, see the .I rrdcreate(1) manpage. The current values for each of the datasets is specified after the DS definition.

If the RRD file already exists, then it just updates the data.

You still need to create graph definitions on the Xymon server, and if you want the trend graphs displayed on the "trends" status page then you must also add the graph name to the "TEST2RRD" and "GRAPHS" settings in .I xymonserver.cfg(5) but it is not necessary to restart the xymond_rrd program.

If you want to create more than one RRD file, you just add more data in the "trends" status message. E.g. if you have three applications with performance metrics:

data appserver.trends
[salaryapp.rrd]
DS:usercount:GAUGE:600:0:U 210
DS:payrollgeneration:GAUGE:600:0:U 29
[bulkmailapp.rrd]
DS:customercount:GAUGE:600:0:U 1922
DS:mailsize:GAUGE:600:0:U 61293
DS:transmissiontime:GAUGE:600:0:U 88

This will create 2 RRD files, salaryapp.rrd with performance metrics from the Salary application, and bulkmailapp.rrd with performance metrics from the bulkmail application. Note that the metrics collected are quite different - you have total control over which RRD files get created, what datasets they contain etc.

To view the graphs, you still need to setup a definition for generating the graphs in the graphs.cfg configuration file, and the graph definition must be listed in both the TEST2RRD- and GRAPHS-settings in xymonserver.cfg - then the graph will appear on the "trends" page.

xymon-4.3.30/docs/editor-nohost.jpg0000664000076400007640000001026211070452713017434 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀqƒ"ÿÄÿÄ3!1"#23Aa$BQSq‘’“±ÿÄÿÄ$!Að1BQq‘ñÿÚ ?þ©"ÉÈDŒù2ó¦•}6d…Q±ÒvQ&ÏÁY•Ÿ°Æªé¢3Tàˆ™ôJ#²²ŒÙ‰o¸JQ$¼%%jQŸ‚IòffDEþf!#1ÇñY8¼/5%*ÍæÚ[î°HR’å’ˆÓ¹PiI^—îb\)¹ˆQ¢ã×I/áÉÿÄ$ÿì¢þR3œŸì¿Wxç!CL,|´©ud•Z’?êdêëýŒ|v÷ºQ7fÖx¦'ö#Èþ»lÙ«\âôg^ÄKY®DC"K‡îëgø/ÿ%ïþFF_À²Ù×ݼ£v§áš’’òã'åiþ¦U±²ˆ¿!mÔ>ÊiD¤,ˆÈÈýÈz»éNá¦Ïºž%«SfmUöö8î›òV=›73J¹ øŠó˜Ü0„”‹‹ØA›´âˆ5F“Aÿ*"ìC˜ôï”ôæüôB…£ÊiĦJ–ºLÉZëjlÔ•}4d¥xëñä|ân.^iè¸ÌÃñý~o-S:ÜnÚKËêkC'4ihYÚ‘ïEf.¹Öyî7ÇU”ŽVIã—+q’ñ6kSò`©FFEFåù÷ª²÷(î ŽËäfIs'•#§ÌàGuv‰$—e ÖV”¥'¢“²Hˆì]ò DlÜ¡Ê[¨m¹‘¥‘´dG»¶ú ɃSi#þ†td~@aù_©«ãS#ârÑøÔ<ÁÃ9²™È“’lÜZ–œq¢7\VŠñ¢R“ðjòFvóiyW 'Š`Ó•)¨ùgNDÂŒMÇn¢OÒ­œVŽROT–¾TVB×=ÆQ’Ê'+3”ÂÏé(î¿M[ÍIBÒê“£RŒŒˆ”[*Èød¸{¥Æ™7šÇKj"a="4„›’˜I™’]7«23Q’ÓªÈÖªQX þGÎ&âåæž‹LÌ?׿òÕ3­Æí¤¼¾¦´2sF–…©ôVcÔžk6>W“©ì#-à¸Ê•ñùM>Ť¡·$úÙ&Ïc.ÂI’–’ª23;IIÏp\v_#2K™<¬h¹>g;¨(ó´I$»-²´¥)=’DGbÍo§ iô9%œûÆìæ24Æj9¥4Dd“CI÷3;5yö" Ž/#ŸŸêî ç¸q*.;’q’jwĉR ZUô'U¦ŠÈ¶/¨©Gæ¢æ§=Õüîw/‡ÅÈÄñî;kr×)J“µ|i¸ã-Uºú -Óô!'²¶4'MÇøK8žC:÷ ÎåeF€î=‚œóJCl­m,ÊÚmDl§ê35žÆ¯e/ã&d²Óe¡ÇË-Žk-…™u©–Íó"""»?ˆpϱ&«Í‘˜Èsܶ•qváJ‹‚•šˆÃYâÜt¤ÜmjëO[„klމeõÙÑF._ ‘…‘&n 9ô¥E‰ó-*-HÐN¸M}µ¬”I'ˆ¬^ˆý;Ç¿ÉÂÉç3™CŸŠw—å<ѹ3¥KKf–Ȭé&jY)FhM™ÐÚ¸ä<ç,ÉðïJ³™d)¹‰yži-MÕ2IÌD£ípú’Mš”¥!)Y$‹é5{ \.Zô̦/“êI¾@æ*Cqò+S-8Xçe%d¢J{mšKU¤©J%U „ü …Šƒ‚‚YLœ¸øKæ×ÙGÃ9,ÚI©´¡Õ]®êÔdT$dq¿>ùÏ|¿ˆù¿ÍõÝ:w|ÁkZÞ~jïo7_H"«Ó®rï.”ú-µØl£&NËŽvDMÉ`Гeggàeô™_µÁÉNäý\Ζ*µqìjÝø‰ÿ ”dO¤‘’f¥YÑQÒv¢ñz gžùÓù¬¾VSqW9Îqµ|;*RT¤¡ R¬Ð©ÃZ¼{ù;´ˆŒÏ$›žJÝ93!LjâLËBC+yi2*»3}wçøO‚óee‘ÎçeY€¾)ÇK*©hù—“&iF6Øn¤'è^Î+­ÏªK_*+!+êkMËÃ' ãe±Ìd#½’É}.Þ­3hR\zˆŒÐjAÉóçÄòôïÆ7 œÎbÎ)¬BŸŠóDä¨Í!.›2²µ)•­TebF{‚ãò¸¦pÉÊeqødCDqÑ\o¡æTH=Ð¥'ÇiQ•yðTḞ{‘=Éù£yÆq­aq9n;蘥8Ò $gI&Ž”‘¤ÉÅ8j5™¥J4))% ^¢f CÀÅÉB€äì¤dMÌŽA0 ]Î,Ѷiqä'TšLÑþ5¨Ìh9O ~l~Gò¬´–¡-MŠêQÊÒÓ.<“&ÍÂs¡½H¶Ôάˆþ¢Ë¸|~HÊ¢HÌebcžŽQ¥Aжə Yý*%!Fs-›4*«Ï‚¢³<ÛÕÜGäkËÃõâI³žR³ Ç”­Ð—?»°i3xÉ Iû¢Ìé6eB~_œf¢dyÆâìÈÄñÙ-µ>Z²&—TÙÇeõ­¦‰¥l¤%Ó3I©7©Q™ÆSˆ·+-'# ;šÄÝNsP]m(’iI$”­Ð¥!Z’S³fƒ¤—Ÿ,±¸Xeæd ÜtòòÊT”;F’Q0Ó’¯ÇVRtwäÏø¢"3Ü»–³"Ö9ˆ.MacU"C3TÏR¤Îe–õ‘ÚÖ¤Ù¥“#Kž&à¹S3™|¢`Úù2ß„s×67YR³&t­;¤^ûY^µäGÄú…ÆñÒÁ³' ã%‹;¹×R§MQœel·¶µ¢I†ÑUz—¾Æj±œYœnuìŒ,¾U¨¯>ä•ã Ä|)¼åîåi¿“Q«]õØöÖü‚²œ3ÕÜG%äxìleáÔÎTÝ(%0ÛòËD)Ï¿)#dQþJ£¢V¦t:XÍà8‹xIl<îhñ±¶(¸µºßÃ0FFD’¤ŠIøJ–¢**/Z@|›’ÆÉvdì”4¥4ƒÿÈŽ‹þD€¨ÌLd‰Ä«"rN1 P™+VŠŒ×Ž“²”gjR©º³Q™Ÿõ3¹)|rg$‡›þÐæZ\V”ÙEn<´Æskò´uy2¿è_äCUÔßúhÿ€êký4Ô‡Î\é«UÌÌ×<ùòë\Ço?È0¤á-¼‹¤¤‘ü¾WƒÿÔ=ñÛR¦Æˆ•ü½§n)©µ"i#4‘(ˆÈ’£RJÈŽˆ…çS_é£þ¤=%)Oâ’/ö!·kéû[mÙ¹n¹ç²^ÕMÚq0ýï¹@<®Y3®bãñéRô$©o6“KM¥N“ek[‰%(‹ušQ±’[;"56•Åc;)έødæ·ÓmÞgííÕwRñí]Õþ‡*í¾Ë„NŒì§:·á“šßM·yŸ··UÝH?ǵwWú«¶û ge9Õ¿ œÖúm»Ìý½º®êAþ=«º¿Ðå]·ØTàXÎÊs«~9­ôÛw™û{u]Ôƒü{Wu¡Ê»o°ÆvS[ðÉÍo¦Û¼ÏÛÛªî¤ãÚ»«ýUÛ}83²œê߆Nk}6Ýæ~ÞÝWu ÿÕÝ_èr®Ûì1”çVü2s[é¶ï3öö껩øö®êÿC•vß`NŒì§:·á“šßM·yŸ··UÝH?ǵwWú«¶û ge9Õ¿ œÖúm»Ìý½º®êAþ=«º¿Ðå]·Ø€c¸*‘ȹÎa–ɶ±máqS"0…!zªAÉRÔn!K%™’+JÔ¤>æg±Ú¯P3OtÖñc§³ª¶§dž»õ•Ö×]‹­¯FöÙÙ íW¨§ºkx±ÓÙÕ[S²O]úÊëk®ÅÖ×£{lìáeYlîW='”ãjÆÆz<$M™.{ } ¡Å­ !-¡h5§LÌÔD’Ix;ñA‘õì$xÚ¢FuœúðùSe+q*?vKFÁ~[9ý܉'±ÚÍ>N”4™þ?’:Œ÷Ì3‹É|1Dâaœ–h”jA)´+dš—©’‹óU‘øªÇ=;….,²òÓ”Rr¯dòg":M3–äG£5ºBR—¯åDÑ“=…Eÿ‘ž™ٙؑ w/hÐÑju†ëÁ:½*Yû™$ˆ“íj­ŽàSqLDÜ7qïåÝÉCBÿ¹|B ßeªýkscí¯áFDª«5“¹@Ì}(w¿æžîîìã8vvöoi–{oØî×ï}Ž_¾ëü§céC½üï4÷wwgÀ«³·³{L³Û~Çv¿{ìrý÷_ä}8Ys̼_Rrçs%ÆxsWIÝ®I9µ)´ºN¡#$œ$¨Ž¶*¥¸š$¸²TF1^¦³Õ¦#ŽVšïËòнzªí“Ûô"îö·.û\ß§£˜±Šõ5ž­1pú´×~_”UëÕWlžß¡wµ¹wÚææ1^¦³Õ¦#ŽVšïËòнzªí“Ûô"îö·.û\ß§ƒ˜±Šõ5ž­1pú´×~_”UëÕWlžß¡wµ¹wÚææ1^¦³Õ¦#ŽVšïËòнzªí“Ûô"îö·.û\ß§bÆ+ÔÖz´ÄqÃêÓ]ù~QW¯U]²{~„]ÞÖåßk›˜ÅzšÏV˜Ž8}Zk¿/Ê*õê«¶OoЋ»ÚÜ»ís~œ9‹¯SYêÓÇ«MwåùE^½UvÉíúw{[—}®ncêk=Zb8áõi®ü¿(«×ª®Ù=¿B.ïkrïµÍúpÂzqÇy.7’fs<‰¬[(íÃÈ¿1Ußµ8ãÍ¥FfN§ÉšŒÌŒÌüØÿÙxymon-4.3.30/docs/editor-diskchanged.jpg0000664000076400007640000023617011070452713020376 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀª"ÿÄ ÿÄj  !1QV“Ó"ATU”•²ÑÒ2357RSqu‚’£Ô#a¡¥BDWƒ–¢¤³Â$46rt‘±%Cbs„´ Áðdv…¦µÄ&8EceáãÿÄÿÄ: !1Q24ARSq’Ñða‘"B¡3ÁáCbr±ÂñÿÚ ?ééòå¦t„¦SÉI:¢"'ÄW1cvÌð·ùà ÂóUÿS†•AÝúWÅUN²°Ws×âÿÚ“ÞË6.X•ú$îuß-ó'ôˆîŒýϺ>ilæqDgªlSX¬©é/·!ÆÒÓªYGq !¦4ËQªÏÂúJlñ1RbQéÊŠˆ–2ÐìD¬Öµ-&¾íN)¤dRH”Ùß6ÒÊÆ"®*±S¤5VÞöÝÅlRZšL¶j†Â©ŒÉ2NdšMJtÔ‚5’¶º[Ä@6†í™áoó†¶g…¿ÎÒ’qv(ƒN«Àf±&¶óx¹V§Ef"eÂÓÆE¬40nk3"ëÙ™gdû”lzÆ7•‹H~¥.‘*F'rœ¹/· ékˆT÷¤~‘,›Œ¡ÜÉ"+[bR£M”i0ÛÛ¶g…¿ÎnÙžÿ8cÇ §†ËÉvS¶”)÷I$·LŠÆµ )¹ðžR"Û°ˆ¶ UŠ|Jµ&].{DôIl­‡ÂBˆÈËþF dwlÏ œ1j%YrÚS±jjÚ\[F¦ŸÌD´(д܅*J’eÞ22=¤5iO›^¤ÁÑä÷ÔíT¥.mÎ.|Š[§ÿž…°ŸéÕor,M®bùtˆ¯Â¨KÕ7T­7)4â„™¦ÔyÎ4έ2KV¦Ð„ÙÂ>ãmÌîConÙžÿ8a»fx[üáŒ>œÝS RêmJÝmˆËéU«Ö’ÐJ%äþ ï{w¯a‘vÌð·ùÜs¤&0†çßUdkYzJ÷1‘êXg&µÕfZn”ë±9”wØ“±ˆTJ=#³ˆçÕh´Jþ%‰U’Ö笿‘KÆLeVG ”›#J;¥(ÌÏi™a± YŒG‡ðÛ‘¢T S@‡ZjiòŽ8•dq×ê "QSMÑ•}ÂŒÕ݃znÙžÿ8c\ŨäʪVU¸ÐÞšáªRõ ‘® êQ'2ob?t’á2ûTeb~¦ZiN®ŠŽ\ç79$ìk‹¬Seœ•ܪæ“ïØÎÆGc/–äTéøV©@rµ*§ü_’ûÒ[dœ}ÆÊ16£6„–T¼âH’DFFW¹•ÀmýÛ3Âßç 7lÏ œ1`%vÌð·ùà Û3Âßç sv ¢.™‚´sXN”D¾ºA*³M’gQYª"%£PÝõ¦d— X»%k>ê×®¸ëÛ¯~úà,to.ñjɪÝZŒÙ²ëu¹?Ò/›._àÛh”6¾í™áoó†¶g…¿ÎÓÕ\Eˆ¬šÛx´¡‘âö(»Ï¹˜4½ ]I75‹jî_5‰ ؒآ¥úŽ6<>þ#c­*äb5¦•ݳ&I'ö‘¥E´Î%¢|U\F‹Û”fQœÃØI‡aÐõdnOJb%H’¥™\УNT¥³+ÉFjîRßvÌð·ùà Û3Âßç iÅxâÄUŸ©dN™T‰.¡½—D–Fƒaœ^v1Ÿé VÊ’5k ¯‡àÔ A6êu™i+^u:ëM6H¹dB[Jl‚23,Ù•´î£Ù`ÌnÙžÿ8a»fx[üá‹TR¨;¿Jøª©ÖVªîzü_ûR{ÙfÅË¿Dλå¾dþ‘ÑŸ¹÷F{vÌð·ùà Û3Âßç k1töðje9Ue5%c-éMÒÙ(ÙßN«-¸w7~Ù­Ý^ûGŽ-W7MëìNóÌ-r”TÓ†Á2q•VT$‘¨‘¬Î”™(”EÜ‘ÜÌ6*¼UX«“¢ûÍ"CÑ”¬ËMœeÕ4âlvàZWà;\®V1uú²Øv;OÔÔÓ’\6˜JßÊn¬’¥šRF}ÑåB•bï$Ï€ŒiÍTëÍC QÜ;ª¥ièζÓk~¤gQ”J6ÍÄ) KFetØÔg”̉ïÓ£):F´Q©Sª› ¾—ÛgôlïKî“ 46›%.2ƒ#;¯a‘¨Ë` ¿»fx[üá†í™áoó†5F Äué20}Nf )éÄúÝÓKÔ4”ÓìÂÝý¥$¿Ñ©Êó©WRËÜð x«‹ —£ºÍ_½U,NÓmÌŠ¸l4ÓF¸ÉJÛ4 ”J»6;¨ÒyŒÈ“°ˆ6Þí™áoó†¶g…¿ÎÓš6ÅxÒµU¡TgÇ©"ŸW7ŠSR•NDhÆM­iL}[§!KJHR\#;ŒÉl%Zr»?Q«õüA"«.­L‹)HTvZi“[d£ÈM Žç˜³f3+—rI-€';¶g…¿ÎnÙžÿ8bÀ×ÓdbF4¿[ë~•I¨f S5Ûº¤äLŸé ¹r0îk÷W¾[X¸o°6õe°ìvŸ©©§$¸m0•¿”ÝY%K4¤Œû£Ê…*ÅÞIŸ»»fx[üáC†jµèØÒS3Z‰EGîiñâ¾rZSe‡ÐêRN-´+Ý4Ò®IIÜŒ¶•ï«cŒboÐ$ÑꘒL*쌚ã‡Im¥²i5‘ã¤ãfj$¤·A¨¿HDw^T¨7ÔêñA•4ª‹í»Pq¢§2ÏXá4㦛—pÒÎçbîmÂdGêݳ<-þpÆ£§O®Í©á«íIDˆ˜µöTµÅ9+kz%¬âŒµ4•Ýj+®IJ²–agFxJ§à*G•uXš1”È»™†ÓIŒ§MÄjÒJ,«A6²Q¨³8V$ì ‹vÌð·ùà Û3Âßç X _ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÃvÌð·ùÃýÛ3Âßç 7lÏ œ1`_ݳ<-þpÇžUeÈë&Üœþ±Df”†jU»ÅúϽÆ?Fÿëßö†çÿ켫ÿ£ïð „=ð1’PÖ²[ì8é™% tÎöï‘ñw¾›å/þ!d¿XÁí½!׈ò)ZÌÉ&jjæWཋþD:‚½“XÆ£S»¯ú,Ü6ýWÙ{ð_õÛh厯Üûñƒõ¹sîI9²ð_3w·êG\ÕjtÖê’Ûr¡ KË%%O$ŒŒ”{h…»Fo|gL‡¤Ú¥?vÈ7Ýj:)dœÖ$–ÕE5*ÈJF¥)YP’3; ÌÝèí¹¶àÂJ\QoM„Gÿ–-v>Ñïòyƒ?«ñ:1Ùxb;è~:èìºvE ÛJ“®Y8팸3¬‰JùJ"3¹J^ˆ‰È‰NÃQÓPB›š–˜a%%*#%%ËvFFw#½î?{h÷ù<ÁŸÕøv>Ñïòyƒ?«ñ:0K/¾Ô¯ÂçÓë ö¥xÎ>ŸXÄv>Ñïòyƒ?«ñ:0ì}£ßäóWât`12hŒ¹:¡&6’êP‘=õ<ó,7KÈfi$‘ª)©VBP‚5š*RFgaM¹–ÝAšIê[ ³L¦#’ˆ9RIGì‚Ixˆ¶ Ý´{üž`ÏêüNŒ;h÷ù<ÁŸÕøÚÌ Z’™UˆXr¢úS)v[Lº´¶¢2RÔFyLŒî\sb8Ô¥£‰tœž´¸ú¤ÇjCO-$‚#u³2Öw-¥LŽÄV2±Z®ÇÚ=þO0gõ~'F´{üž`ÏêüNŒ3P0ÍΤM™B¨7Qr&4ˆí3G‘ ¥bê$¡(m "3W¹¹™™ŒÍ>>§F‹žÍÝ7£4ÂZm,8iR h"Ø•V¤Ü¶ÙF]ó{h÷ù<ÁŸÕøv>Ñïòyƒ?«ñ:0}ö¥xÎ>ŸXµ6£N~Ì5\b#Ž6¤%öžhÖÑ™X–’Y)7.ÌF[6‘–Áì}£ßäóWâtaØûG¿Éæ þ¯ÄèÀ`[ÃL7Rv¤Þ”jÈœóiiÙ)bN¸„ÜÒ•+r\È®v#=—1Ÿ¨Óð5J"!ÔaaÉ‘òä%—ÚeÄ%Õ¨Ö· &FD¥)JQŸ ™™žÓ´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ³uJChJQ‚”$ˆ’”¼‚"."Ú?wÚ•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€‰Ö° ·-©uœy"¥!¢³n˃Fyh/Ôj†fBHÝ=uÉœC*÷<Ú“1ò;«–\ˆJSm„YR[¯sÚ=´{üž`ÏêüNŒ;h÷ù<ÁŸÕø!ïbFbœŠkÒš‚Û$Â#!m“Il‹) ’[ $[-k[`ñGãÓÓNbj#½1ÐÓ)m,¼d§[$‘X³"5'FE{‹Oà=°Ã»£ì–ÛI­GÖüC±\ÿîÄ'º›~cE¾k…Ñ‚[C}©^3…ϧÖ-M¨ÓŸ†ó Wˆã© }§š5´fV%¤–JMË„³–ͤe°kMþêmùù®FýÔÛó-ó\.ŒÚ>Œð¥r'Ò1S¥¢ù‹L¢4âoÃe& ÖçÁÛù¿ºŠûeÉ»²5º2ÚÖÖ{«[e® ýÔÛó-ó\.Œ7û©·æ4[æ¸] Õs Ñ*øÑšìоK-ÈbJ‰)«S&•!+=õyЕåË}–Ím‚WŸ n]Ëž¹÷FéÕ]¼šín·Yn úÎï7në‡h×[ýÔÛó-ó\.Œ7û©·æ4[æ¸] ‰1X^féÝgF‘ºÙKu¦ÚõÍ$ÔiBïî’Fµ™ì,Êã1v‹£×ilRœ¤áeÓã,Üb*£°l´£áRQk$ÿY…ï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6K°ó!‰¶ž[HeN!m’´3-¹Rk]‹€³*Ü&,°XQ…BSEhà2lC4j“¹›2"ÈݽÂl”•ŠÅb.!¯7û©·æ4[æ¸]o÷SoÌh·Ípº0ˆ”¼‘†£¦ …75-0ÂJJTFJK–.쌌îG{Üf7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬Zbm‡d:ĺkNIp}Hq 7VIJ J2÷G• Mϼ’.!­7û©·æ4[æ¸]o÷SoÌh·Ípº0×°겪îãÇÜ©-HZ¥ªÞ5!D¤¯qæºT”™mØi#.8φ7.åÏGÜû£tê®ÞMv·[¬·}gw›‡7uôk­þêmùù®FýÔÛó-ó\.ŒÃ2†–ReE4±%RÙ/ÑY·Ô¥)N§‰f¥¬ÍE´ÍF}ó©ñpe;)SãP"e”©…¨C(³êA¡Nìþ Í&®#2½„º›~cE¾k…цÿu6üÆ‹|× £?ƒ@ªIªÁbƒ¡/ýbS(i½¶ýÚËj¶ñ˜¼ÒðÃ,Aa¥ÑÛjŸmÄÚM²Lk Û-YÈR“²ÝÊŒ¸ k­þêmùù®FýÔÛó-ó\.Œö4L²íj4l>ÅQâ2vkm²—Ü¿e—tÎcÝ m6a×M†ÒÓ,´â†Ð’²R”–Â"""".­7û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^3…ϧÖ#5ZdyuÙ5hzDJrCm´¦â&šdHEò§3±Öá‘–«)GcZ­b;®ÿu6üÆ‹|× £ þêmùù®F9 DˆéõYñU&âÌ\÷–Ô$-Ùq’¼ì6×NbYžFìi$™+8Å/0™Éb†šMCýtÃR{ÿ¤±wÏqßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀOéì`êth±©ìÐb1 Óv3L%¤%…šTƒR¶%F•©7-¶Q—|Æ+P0~¢Ó¢Ãr„uÔö!H¨´ÓL½(šm)̳#3Û–ö3;q˜Šï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6†ûR¼g ŸO¬7Ú•ã8\ú}cWï÷SoÌh·Ípº1˜Âq´‹*Цa¬?£ª´Ä4§–ÔZ45šMˆÖ«7ܤŒÈ®v+™ ÆûR¼g ŸO¬7Ú•ã8\ú}cØÏ'øÌð}á­à­Ñb7*¥ð+ ;%˜­™Pá¬ÔëÎ%¦ÒD–ÌÎëZK‚Å´ÎÄFdÀÏoµ+Æp¹ôúÃ}©^3…ϧÖ1´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ¾ûR¼g ŸO¬7Ú•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€Ëïµ+Æp¹ôúÃ}©^3…ϧÖ1´{üž`ÏêüNŒ;h÷ù<ÁŸÕø ¾ûR¼g ŸO¬7Ú•ã8\ú}cØûG¿Éæ þ¯Äèñö“Ìý_‰Ñ€Ëïµ+Æp¹ôúÃ}©^3…ϧÖ0¯à=°Ã»£ì–ÛI­GÖüC±\ÿîÄ'º›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>°ßjWŒáséõ_¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ÚíJñœ.}>±ç•*…!dã•ZÄ‘’VRJMûå·„»ÜC[ï÷SoÌh·Ípº0ßî¦ß˜Ñošát`6¡FCZÊœ'ÜhÌÒµ>’µûÄWàïý71Ë_2#ɬa'#>ÓÈ(òHÔÚÉDG™½›ñ¡? íUŠU£zŒ÷ïª Çdš”d’nö$‘™ŸxˆÌöÐ]J«…X¡aú-·’· Nf6°ó6E›V’Ínõïk¸LLuC´j?IÿÍWýLEªõj„¸S¥*Üí;i&Œäó©IÙ¦’^ìó\ÀYŽäRJôtJr|W ICÆãj4ŒˆîGcï×x–¡7ÀS5&ˆÙa“(ï²’Co%)Ø‹Yµì൅=ô–_”ïÞ³o6ã—®{2¼­©½§µºˆåëžßÒøõ¸Šz,wÑ.;òU‘²zÍ¥K$š$¥$ŠöJ‡¼2bI VηNœó,¢;RJBÏuÎÄÛˆ""ÈŸœ¿xN¦Çn\7¢º§RÛÍ©µN©¥‘XÍ+A’’{v)&F\$dcѤ¹zå½N'/N†õû¶æ«ôíœôý—E™rYˆÁ¾ú(%%;j35m;™‘Îpk¸:.<œSˆq$‰2æé«Î[êm²3Õ¶”™šSdŸt¢"5ªæv,©Nz½ù”Å3&´œmÄ’ÔdG‘Ī×";{ž!ë{^IµK”ÖàJÒÚ[Zœ)ÖÚV« ’œÊ"±™¶•ø6ÈSæ³5µyãg•Ö–V[jâ2ÿçÀ|$!“ŠU)æ–Ò[7’£oVé¸j4šHÊÙHïÝÏaø2·ITeþ‰Z³m ŒÉ7¿t}óý…Þï™Ìàg€XŸ3!»O>É8›kpдŸxÈË€ÿú;±C€ªm9¸®L“5ÒÚãϸjRÕßµÌì\D_´îgQû]©F£ÑåÕ%™“YS«· ‘~³àê‹*U—Z}ªü˜¤óš¶ÐÌ4¦2œù´­ÖO9ßg»,Ýâ.–éIT1”˜ÑeK4IR‰£#BYuÂ#Ö%I"Ì„íÞ´i QÆ}2*±ØBWOeO7QÞ±’–jm(Ùcï_eömÙô¾HÒÑú?©UTÌúûtåÎxäùß*ê§õ¢Ô\š1,þó×ü%J£[‘‰jPª³"Èi£¾ÂX`Û$f[ÈUîfw=Yí2.ã9X†h² ÓNz­%¬²e+!(žqÌÌ¥G’Ƴ32Ú£#Ù|×± ˜Èò–Î&¨·ˆÄz½Q=?v¶‚.pôþ¤ægž~3–TÉÓ$¸Å4"d–jÕ¥&µå;(ì¢=„{8.gÁ³‡ÌÝJ¡S"¡®\gÒjN±(#4— “”‹ƒˆËim/×C•*¸§ä°óŠinºÊU³š–f“¿Éî¬vÚGÞ2=¾\C0ë’YyžjbÙSN!Gt(íb4_iÛŸóp™íòaëKÈÈÈŒ¶‘ð%Z{tøÉqHSŽ8âZe¤ì7W¹MÏa}'À=,¥”$ö$ˆÿä1øž#3hÎG“åG7[Í З¥m-¶#ꊪŒS8”ÄÄs–»P©A†No²Ês·KM¥- Uö™æFlˆ¹\ÍEÔgbÉa êêÑœ9´±T‹b’ÒHÉ*#÷."ûr*Çn##.ú‹) è⫈(²Û3ZÓQ_›wÉ ›¤Ñeö—°ø÷.êÓ#ÕfÓªfìI—A‹»`“d¼«›‰ÙîNäWOê.!æÐè¯i¬ÏëÜšëÏ9õ|!{·©¹WôSˆÿ,µ{à9ÿðÎz&1øSÄÁ=L¸&µ!Ôùáú\xq ÒB¤<¸í’S}¦IIfZ̉F–Ðⲫ-†B½ðÿøg=÷azÖ$êDÀáæ_•Q£Ri•Da¼ÎIFá6\J,dy’‡ÖáFÙ$ˆÍD4ôt[®ýÝœS3žÑžró_ªºmÕ4Fg‹XV:¢1ªJ¨BÆvÜA”&(ìî'­À”¡I\ƒmd•]IxÌû³B’DDž‘ê|ÒŒ}(`åÎu¨ñkKìºJBŒÒJCí•ÍDÒÊöÍÀ¤8’5äÌ|—™T}zq £nÆyˆ™¶Îº»·ê ÁõZ>­âÚš_e¬@¨É‚ÛÍ’TìvRá¦EÈøSë",©¹6K+¥iqþ§ò^ƒI£¢«4Å5rÆ1Î>UÕüÿžlO%ju.ÕÌÌ~þ¯ñ Ỻ1ÅS î\»‚›vèÖ_Yº”Œ™m³.æ½îwÏÀVÛìf©êäª#oæŸ32Ÿk"»†žS©mWµŽêaÒ±Ë.Û\¯¬`Z&)Òõv^'íÔà¦1r™53¬Ýs%ûbIM˺A,¬e›lKFXZœæ'£OƸ(åU«8‘Ù³hJy[­ JDÔHtÛ2ijim6¢tÓœˆ‘¶ÙGÁ·Û¦…T\¡À­ÒßÝ*›•ÜŠN±§JB¬¢#+¤ÈìdGÆ=£›#Ѱí3E:(¢ÎÁ3ZDZë ×é­QeÙ2Û£Ê'Ü6òÊ+¤KI,œJLˆÕ´†ÁÁ”ØQð…E0½]8uÜQú)1œiè­Ñ5njLÒ¦šD¤¸ù¤È²¶GtÛ¹8ªbª 3}÷lý^óÇnDë2µjælžå'™Gû”Ý\;¢¾hihßöþäþ]øÉsÿO÷³ÿq{Ÿý£õ˜óo+½w_­š·^ývnüÜNj·¯ug˺­“W¸ÿC©Í|ûrò`<ä˜1ä=ènºÒV¸ï ÆLÊæ…¤š‹€ò©ErØf[FÃc¦é±r"PdMTšŒ×¦TfО&"—“)ùµRX5P†lf”©v4µ¡¼ËÕ ;?á•©úVÃlÅ9ñÑå´rÔá,¬—Û=_þ4f. ÛCsÀyÉ0cÈz#ÐÝu¤­qÞ4Œ™•Í 4)I5åRŠå°Ì¶Œf2®õ»Hb¡¹wV¶¥MfKn™lÇÏ{¹Öæ·-®W¹h9Øn\l€å?†'UkQ0u:#t™øyùMèoºCo¶i:|‹”êìDD’vÚšcaÌCC{ "U‚©Pd<óL¨šq•ÕÖ’“¾fÐÊ–»["T…_nÀØ 4Ö"Á0iïcz":“‡%R©PÍ"œkirJT­~VSbrí·m=Òv±šŠøXP17Ä­al$ˆUUi0!"ê{oÇ• ”Æášã¡2 …-'bÊÂ×bÍpü=ÍÁø‚¥L•G®SêÓ›¡L¢Ð¡ÉR¬™ªÌ<ô’Zv™ntÆÎ²÷*eÓ3îvO(”¸˜ ã9<1)Š43ÚJ…ÜÈ”•Î×%†ÊÉSÊB#‘¤¬ffÝýÑ ~;®õ¯ëØ›rî½è¦È¹õ™5º¦”¼™¬yo–×±Úüz»¾õ|GOܺä©"}fmvh‘ägµ‹/úÆ[m÷¾Û•Óµ™ñ´ŠÝ[Öëõ¹ÔóN• šìK[‘)6êÉ“'Éå)&i7²"%ß(ÊÍ¡V¥lEV®R*\æ!ae˜ëUŸÞønb›"3’ÊV…"Årmh5YF“6ÃdV1”8¾‘†XFê›6rbÉ"5$¢¥q%ÈBï–Ë3ÜŠNR22%¼J“ Xyœg&‰YŸLr£N¬c©s$§"”ÙCb2#å¶KÕ4v>åFõŽù¬µ<2tȵzBpÜ×0d,fÓÏRbCZÛvœªc&¢i„—é)‹Î¦ÐFG‘±ØÈÕÄ5Ýè«áÊ~å×oÝIpsë2êrÄ‘#=¬y¿ÕòÛg»½öX؆»½|9Oܺíû©.}f]NX’$gµ7ú¾[l÷w¾Ë•ªÐZ]ˆoàÚÛø=årâÒNuNF§oc홪1t2r Åj%t¸”eî‰&ªPYU†o`ÊÛø=årâÒMtÜOÞÇÛ3Tb,èdäŠÕJéq(ËÝL7쇜ièÈDGŸKΚ¶Í– "•y”FiºI=É(î´ìË™Eb…T\¡À­ÒßÝ*›•ÜŠN±§JB¬¢#+¤ÈìdGÆ5*Z葆eµ…Æ2݉L™IDjrè²™Q8ÊËôM-õ9d,ˆˆžBlW"m ÑgÓt1A£áTü%X†Ìvk%RÃo^”ˆèKëÈK`ÝR”Iý9)iVS+™íHm`_Q55V‹A‘X™&£ÌåО^åd’ÚVìjŠHa´)je{V¢YZË+áZÃx€´¦¹u›U^¹·S™Â’Ÿ¸¢èk|JA0†umM©nêÈR¬¥AÕ¸›N‹ç¹\Ã71bª³]n´¨)£„¥8l$¥[!6L›mês\–WÉü!†Átg™ÀµˆÌ;T¦é%T ,O¬? Æ“&y¦ÄæéQÌïvƒI«"n]džåžó‘ ÈÌG¦:ÓJZ#²h'2+’kRRJ>̤•Ïi‘müiŒ a·¢C4nª„©0ÛLb5&Í?6;ò\#NÔ‘)÷‰J+X™¹™nt 62®õ»Hb¡¹wV¶¥MfKn™lÇÏ{¹Öæ·-®W¹kK„£?Œé8G? ‡"ŸE’¸TÖ–äÚdÞ†I6Nµq›BTI±žd_jˆÏˆ¨,ÈÂ8¥8_VâáWêG¤1Nv¯:ÕA ˜ã1ÔH[i6µDj²Jí­\P ÕŒ«½nÒ¨n]Õ­©@ƒ“Y’Û¦[1óÞÇîu¹­ßËk•îY9¯8Ã)[Q”£u´4ˆ”²I¬ó©%•$f£Û{$ò’•dž‚ÄTda,Tœ/ƒ+qp«õ ˜¤1Mv¯:ÕA ˜ë1ÔH[i6µDj²Jí­WµÔ2-ÑIqªÊÂ^¥IÃNW0Ó‘`*˜ìOÓ³SmrßDu%*m½V§2²¤Tµp]F–TX†äºsúö[’üU+"“gXylº›(ˆû—ZoÀv¹\ŒŒ{F©Ñ&fƒAÄÔl-B§ájúk3¹R0ë…èêŸ!ÈÖ4E!)Ž¢JI~ŽäFEîNôœOÄÚQªÈÆ´8µ¦Ñ†)QÑ!ÈjLUÈ'ç›Êi*R‰+NfÌ»¥-²Yw]ÕÌ&ð뻣U0Îå˸)°çneõ›¡ÙHÉ–Û2îkÞç|üm¹‘Î1(XÊaQ*uº]j}%8/#Óu+Dª‚Ñ»ÖîewÚ–•9b–K">‹½¤œ7YŒêò˜nCQzÙ”Þ—P“ a•‡›}´CY.Reêô12ñëDdFãdòn ŒÊêEÈ®[v×5쉓\Æ)Õ¬P¥Spü–¨5­Õ¹jßvËM4fh"+\µÅ˜ìei)ÔœÆXã I¦Q+p£Q$?2lª•5Øv%Æu’Ž’u)7 ÔêVf‹ µEÝ\Èb‘°ŒÚƒ0ãO–á>ñ0Ä­í’PÝpÕ”’‰&Þ¥FjØVYÜö±MÒn¨WDŒÎ&ÝêÕšw TšÕ¥Õ)-­Ã\r&ÐjBË:Œ“Ü+orv…áçª4YôjF ‡ L•žU3Ͼ”´¢uR™Q>Ñ ÍûLÒ²2ŽÒ‹fà ¬SAN4,ª‚Jºp ¢QMµ•ãšÔ‚Y.ÙLó%E–ù¶ÚÛF2¡¤lUv#ÕW\‘ArUcÂ}õ¶äµäŽ„¥´¸¥¯¹²3ð€1HÅx«9Šš¤#C¢Ñ]ŒsÚq˜ç-©$KŽk$™šÛª+‘rëK±Ý7Ãb,X B­²H¬?!Q°´™•Jm=rvR+rdLy”j׬R3ë2d^Tš.“+†ëÖˆ·F÷Æ­3¹òçß4¸Í{eÝ #?¹;å½¶^×+æF³¤&e{ W!SëxÏIVçÈÞ!bFÉÝ™žªLxL»´ˆÍYI~å)<¤³»áLKMÄñ&Ô(ûž3yó¹Ù±SËt(‹ýCIiͦEÝe÷E´ˆÏ×zâ¤?PÜ»—URŸ&³=÷4·£ç½‹Ýj³[½š×;\ó#F;E$F¤«áz•[ 7[Ä®J€šc²ÿLõMÅÄ}q•)ÆÍ­vUeQµ ౕI¢¼ÞÁÅ0ÝZ«†#ïž¶–¨nOr>±òU;^ jsW;g±YT¤™ð\ƒxˆf&Ç[ˈfÒw¯_¹w“ô›£.mñ¨9ƒ)ÛW«ÏÃÝ^ÝÍ®5þ•)¥>}* 0Z]€TFJ•9.²¦ÜºËs¥ ¼„Äu)ÈfòÖF¬ÄY¿GrÆï#®á˜ˆ®Ò+HŸ@ÀÍÔ l:—TëuG\–J2"RVÚU|‚;¸@t( 1‰pƒÔgñ'áçáPäSè²W šÑ²Ü›L“»ÐÉ&ÉÖ®3hJ‰63Ì‹íQù‘‡ MøՊ¹@Â2›§îXLQÜijÛªT— d…›JN¡+A$ÂC–#3¹†ã¨Õ SæSbLTõNIņœŠ=c¤ËnEbý.*çbîmÂdGMWøð”j ‡zN¨3ƒáSQGÅ2ÔÔˆÔw)ÄpÜ¥>…:˜Î™®2Vñ´…7r%)´®ÛHmê¯ðÿáÿ(‰Ö·0uqÀ­bÊ 2ZRJ6%ÔZeÂ#à<ªQŒEô—X¤W0­}©§ñU!ü9 y³QNfå™&ertÇ¢\3¤èÐJ°NÅ— Ô›r㑆Öb5´wá#+ÛäžÒï‘ÚÒE&BÁx^HˆÜ811%¦l¬HIMkþgß3=¦w3Y±„_Wç·PU.ŠÓJ}³h¤>êMIiN«+hJKjÖ£þ Ȉ¶™•ÊòÄOª…ŠMÙDi6«  Ó½å“FÊ]h夘ÎIá2YÚö;x<¡z»V³Gx‰žÑÝàòúìÙÝOxÌö‚.©Aœ”U߉6!º–^u¨«ŒôU™‘±¥)FEs"=¤i¹\­s)ÄÙq¡BzlÉ GŒÃfã¯:¢J‚+šŒÏa|k=!V_ǘøt†`È}¥Æh²‘Ê6ÖYTãÊ#±!f¢-¤Gk™‘ †’iÓ*˜FDj|}Ôûr#J(Ù‰;¡,ÈmÕ3sÙÝ¥»;­»?'^ªæøš·SÊzgÿÇŸÉzšï~¤nÝLO)ïßø~Ññ­Pj G§%çï¨94Ù1ÐýˆÔzµ¸ÚR½„gÜ™ì#1ŒÂ¸ƒOÆõJ]R¹©‘õú—·­äÈé%¯Ò¨Íë[3sôdZ¼¹Us1åMz©YÆôÑOE„N­x3hÇ*Z&2^µÖIJs]¨M›pÓbàá1Àñ*èÒœÎÞ•¹!öëΔ˭ â¼d‰pÓ,µ‰o»$™¬yŠäJÓÃYºÝ¨Âj±·­6Lwd²ÖSî›iM¥j½¬V7›+Üól½ŽØò¯8X®ŸBršë ™t¢q×t”g˜h»”šˆÉÂ|–Gr2""4‘™’cxÊ‹HsKV½SÃh¨%¸Rb"Zig)Qä›ñWJRP£l“•ó'ÉFem,ǦT£ccò)òÙitçqÆT”§]WeÆ®f[3 IùI#2¹Ÿ×¾Ÿÿ ç¢c €*ë¦è«Få"ºí˜ŒÜÉo!-Ö™„”ÜÜB»Î¯ap™—êš÷ÀsÿáœôL@ÕC©âM`j5ÇP‘£¯ôt¬N)%M^KžÎë.]»6íÏ'Ú¢íø¢äâ™Îg·)çòyõsTZ™§¯ý§ MÒ$ºj*ð¢N(klÝDiSã39iÚiýä4%J+%N®D¬¦FBEƒçU]¯MƒQ~rКd)‰jb'X[«KB¤’NÚ¤—mìf#ÍigÌÂç6-R‰N­ ˆŸ¤Wgîc¸VÎÚÈÒk¹m"2I‘ìTiËa¬Bš¦;¬u½P¬P)Ϧ©Ó]Si3éwdÆU•žJLÒge¡Ä"º-Ë{jš6Æf:ÏoÞgù_KM¨ßš¦g³>¼Çüe½@Y%¹°cÌe/%§ÚK¨KÌ­—”W"RD¤+nÔ¨ˆÈö‹Ã‹ <¿õdý¿ð–8cÿˆØKþO¤Øîzßú²~ßøK1ÿÄ áÌ%ÿ 'ÒlWÖŸS°ª?IÿÍWýLy$°Ì–ĆëK+) MÈþ’GPÒ¾”·d¯UMÇkU™Ž’¹Ïa4D_AéKK}ìw7›g£M¬ÿHkôtÓUù¦˜«8Í]q×Õû¸×¨·O*Ø„¥$$¬’+ÑÂ=”´»Ë¹œÛ]ü쥥î]ÌæÚèÆtùô}?Ïý+ÅZîîðÙKKü»—͵ÑÎÊZaåÜ®m®ŒR|‘z?ºŸåÊZjåÛœÛ}ü쥦¾]¹Í·ÑŠð—½“‰µí;ÜvRÓ_.ÜæÛèò–šùvç6ßF%ïdâm{Nær…GrIÉ]::ž3¹¬Ñ¶ÿýk,2Ͻ4„w¶àÎÊZkåÛœÛ}vRÓ_.ÜæÛèÃ…½>£ˆµÝݵfœ~•-†“™ÇZWµÌÒdC!£rs hó áÉBvM*“ Î4ㆅ­¦R…nÙŒÒv¹à.ÊZkåÛœÛ}vRÓ_.ÜæÛèÂ4·£ûN"×w~L¡`i¸…8ŽfÃkIu·SQvW$–݉ 'M¬Ù“•6;ܲ•¸ƒ~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£Ã_öN"×wÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û'k»è}Eê]Be6\ÆXuêd“• ZçKVé²ã&«l£yÄØî]ÕøHŒ½»ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ý“ˆµÝô>"è±7ä¦Ò£îU&©³NçiYs6Ý›îRyr+rž"Ýúk¾¿`|ã쥦¾]¹Í·Ñ‡e-5òíÎm¾Œ8kþÉÄZîú9¿Mq±÷×ìý5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿdâ-w}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿ²q»¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ù8‹]ßG7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿ìœE®ï£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_öN"×wÑXéð!3h1b°‚m–%!¶ÒEbJRM؈‹¼Bþý5ÆÇß_°>qöRÓ_.ÜæÛèò–šùvç6ßF5ÿdâ-w}ߦ¸Øûëö~šãcï¯Ø8û)i¯—nsmôaÙKM|»s›o£ÿ²q»¾ŽoÓ\l}õû¿Mq±÷×ìœ}”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ù8‹]ßG7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿ìœE®ï£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_öN"×w~ášFÓŸ›JˆH’ûidÜ~|™ CI32i½i+VÙÜ‹'õ Ä9ôøM­¸q ÆBÝ[ËKD¤œZKY‘7µJQ™™ð™™™]”´×Ë·9¶ú0쥦¾]¹Í·Ñ‡ Ù8‹]ßG7é®6>úý€ß¦¸ØûëöÎ>ÊZkåÛœÛ}vRÓ_.ÜæÛèÆ¿ìœE®ï£›ô×}~ÀoÓ\l}õûçe-5òíÎm¾Œ;)i¯—nsmôaÃ_öN"×wÑÍúk¾¿`7é®6>úýó²–šùvç6ßF”´×Ë·9¶ú0á¯û'k»èæý5ÆÇß_°ô×}~ÀùÇÙKM|»s›o£ÊZkåÛœÛ}p×ý“ˆµÝôs~šãcï¯Ø úk¾¿`|Ù©é‡L´øéyìrú’¥e"CMÞÆ}öÿPÇvyÒç-fó,û•tWDâ§Jk¦¨Ì>›ïÓ\l}õû¿Mq±÷×왞t¹ËY¼Ë>ÀvyÒç-fó,û¼Öäúo¿Mq±÷×ìý5ÆÇß_°>dvyÒç-fó,ûÙçKœµ›Ì³ì3“é¾ý5ÆÇß_°ô×}~Àù‘ÙçKœµ›Ì³ìg.rÖo2ϰÎO¦ûô×}~ÀoÓ\l}õûæGg.rÖo2ϰžt¹ËY¼Ë>Às9>›ïÓ\l}õû¿Mq±÷×왞t¹ËY¼Ë>ÀvyÒç-fó,ûÌäúo¿Mq±÷×ìý5ÆÇß_°>dvyÒç-fó,ûÙçKœµ›Ì³ì3“é¾ý5ÆÇß_°ô×}~Àù‘ÙçKœµ›Ì³ìg.rÖo2ϰÎO¦ûô×}~ÀoÓ\l}õûæGg.rÖo2ϰžt¹ËY¼Ë>Às9>›ïÓ\l}õû¿Mq±÷×왞t¹ËY¼Ë>ÀvyÒç-fó,ûÌäúo¿Mq±÷×ìý5ÆÇß_°>dvyÒç-fó,ûÙçKœµ›Ì³ì3“é¾ý5ÆÇß_°1xš¼¸Ô‰s!Ó^ªÉDu6Ô(Ž%.<¥šKbž6ÐD\&f®;ˆþnvyÒç-fó,ûÙçKœµ›Ì³ì3“¶ºïÆ_É=ÎtïÌ 6*—Œ±JhôóÑÍ^šÛ5Ê|Çd¿P‚´6Û2›qfd‡ÍGÜ¥\gÞ°ãîÏ:\å¬ÞeŸ`;<és–³y–}dËè¢C,ÈŽ¸òYiö+-§PKB‹õ¤öùáÙçKœµ›Ì³ìg.rÖo2ϰdœKèM6N¦4¦i”Ø0YÝH‰ ¥GúÉW‘ó·³Î—9k7™gØÏ:\å¬ÞeŸ`DQˆÄ"")ŒC轞t¹ËY¼Ë>ÀvyÒç-fó,ûvÊrú$çog.rÖo2ϰžt¹ËY¼Ë>Àm“/¡fœ~•-†“™ÇZWµÌÒdCóQbS0&¢ÕœiÊ… ŒÅ8äC%’3KM¥ÌªBRf“SI=¼E°‡ÏŽÏ:\å¬ÞeŸ`;<és–³y–}€Û=U4Õª2ú=¹i>QóÜïXðÍÃX6}^™V©R˜©N¤È)T÷§Ì‘$ã:De™ÂV^=œ*Cj÷M Óó¿³Î—9k7™gØÏ:\å¬ÞeŸ`D[ˆœÄB´Û¢ŽtÆM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}nkò}7ߦ¸Øûëö~šãcï¯Ø2;<és–³y–}€ìó¥ÎZÍæYö™Éôß~šãcï¯Ø úk¾¿`|Èìó¥ÎZÍæYö³Î—9k7™gØg'Ó}úk¾¿`7é®6>úýó#³Î—9k7™gØÏ:\å¬ÞeŸ`9œŸM÷é®6>úý€ß¦¸ØûëöÌŽÏ:\å¬ÞeŸ`;<és–³y–}€ær}7ߦ¸Øûëö~šãcï¯Ø2;<és–³y–}€ìó¥ÎZÍæYö™Éôß~šãcï¯Ø úk¾¿`|Èìó¥ÎZÍæYö³Î—9k7™gØg'Ó}úk¾¿`7é®6>úýó#³Î—9k7™gØ#©Ïé+IºD<3UÒ-b…é$ôf#šÈÛ±ÚÊEŒŒ¯ÅÞg'tN©3!“I­”Ø”e”ÖffhRH¶¤¸Çñøs ÃIô›ë±Î#þYñ‡›áû""þ„(šKÇ5\=Œñ¶0««A‰"<›ÄŽw”§ÉHÊLªäEs>µÎ#¨åÉÞð¯ d©´­ÝDªÔ‘g©ÉiÕ1“Ý´¥êÔ¼×Ù•jh­m¹øJÛq³½á_@Ìຜ*]k5Q2M’ñf%„’œÕ¸ƒNd’ŒˆÔ“ʲ#2+¤‡öõÖGMýý:œoŒ²0TÒ¦°ìMÑ.c›ˆœe Ò¥6û­¤ÔkÍ}SI]ò岕˜Ó”³ãäajÛ,¸ùÆeÖQrMÖ%4ê ´­(Q’£%MiºHÌÈŽæVÚ%Ô#ƧÔ+“×j]JªÜ†š6›q¶ci±ÍWt¨Ò™HÊ•$Òy g 31Å-Uº*ä™ÔXÊ™­5E‡L55% iâCQû“^DìZ”{I;m¿Îw\ÏGQŽ¨Ë˜+77q.ñI6c>–³§2“ ÐLå+÷JQ­%”¶–Û‘e;x1} b"T .±mëqåµ!›š}ÛJRot™^åm¢cWÒ&ûƦªIM‰=º¹Ê•*)¤––òÝe-\ýÚ!û_aY®-˜ Õ©Š´i†VDÜRnL…Âj"¥;j7M–ŒÐƒÊ¤§aòf=¦bÔÍyçª)Ç$lG0ßàšu~‘LzErT9õj”ŠtQO'YÎÓl,ÖëºÔ›i=zJä…X’fb?LÃUª”DJ‡ C¦²e*Ú|ÒWQ6…(”á—þ=»8DƒcÙ4,E\ÅF\ù®ÕaëM LŽû1›JÇîËTé’Œ»“RL¯´†cé™K¦Óc0óñ×CS…Ow­ê|§ŸI¾·£yìËŽ²7 »aˆÈ¯{ñ™®2ëD¢s0F%‰Kßá0–w+s2Öñ°â´ºMÍÃFU$ÍYl[okªoâ—„ÓTö\zd†c¶Â&0§[qÕ[K¨%æg1™„’Ú$ØŽ·†)õê°§ÍVs D§*:lâ¡NR›Œáë‰ÃQ©¥£VVZlg°zhøÿ S1»Ø½ Õ—V©Ç—RŠq›Kq‰¬Ëp™^°ÍÃ52INd¢Ägs¾¼f!;hÏ9E¢`j‹ø>­ˆU6˜ÑÓd°Êã9PŒ•¨œe×LÊîç"BH›"5)F´‘fmdX¼I†«uL¢®Ã,-ÓRI´JiÕ¡I¶d8”(͵–bºVDe~ë¡Õ)HÁ•Ê IsYrTˆÓb»”ºFë ÈA6²RÓ•*×û¢Ìe—ÜÇ»Hø‚^D€s%ÍmO.UBd6c¾ù+&D/T£'MVzÕYJÏ´ŠÄ/Vìz•˜§nPðÀ|„WˆhÕŠ†ï(ª‚ßú3FÖc”é6ë¦ÙË/èÙpï·nR·tB0'ØGÓpÕ&…œ5 ¦ü9ÎO’ôÕ>“Kª4¤’Þ©ä¥IÕ¡>ø“+©EkÞ•ÍXþ•¨ˆÏ7‡F¸n*Ä4fdj˜¥Í¨³×9†[jq)pÙKŠÌ∌ýÊU·½ÞÑ£œ^¸K*|RiÈíJºª1’m°ê´:á—m³%'»YHÎÆd{b¬᪤ү¡¼34Žã2£“3! qJp²,µŠ#I‰V"Ìžˆ¨âÊtýÈÌ²ß 5M¤µt§¹z6áÎ¥w^à÷+–2¹íMÈ®v¦ê÷r_al´qŠfŠz·C5Mœäã2*‘™$©fƒRÜ$çÌGdÞê+(ˆÒdg™¬â ĬaÚ[t¦¤Sš˜´¡hŽË})h—ÉjmÃ";fͶ×1ií Å{ “d³‹QM!4­ST 5 £î|Ç5Do§28Sc=¦D¤•­ÇuÎθ£»Ç‹ôe]¦â:¬j\T»Nfl¶©æüèå"SLHu“4·˜”âÈÚUÉ)¾ËÚÆB761Æ8BF*Ãøá™•5ϊ쪄jz#4¤\êÓ$4ÛëÖÝ¥Yi3I!}ʈÈöÜi‘6ªªcú‘r)‰äêæÁã?‚ÚÿÏ/EB"%ØÏà¶¿óËÑPˆŒ]wû­mû@#Ô õÔ%ñèSLôHhQ»º‹i‘+:az›?tîg¨Òµ…[±–dD•[XÒ’²#µŽÊ+•ÈîFd"GQW´}ªR‹bi'qG†Z¦)EJ5±¨3,èYë‹1ªÄf«Ü“ke+Kôeñ×>©£zS†3±†ñu_úËTüÈ»¡jE6‡¥œsN¥0û1ÑJ£ªÏN‘)Ff¹Æg÷¢úȶp\Ìΰ— Î÷…}Âu& øȽcÝ;ÞôÛœ#ô—•|“§ò…‹sz'úfq‰ï³2õ1U|ÙMõòÿ‘zÇáÕ£ðÿ‘zÆ Å #{ý?££¤Oòˆ±D³'WŒ_À{þEë‡YŠ_÷oȽc¡mC.ï’tôô‰þW5 é×"ýÛÿt½cðë± þíÿº^±P¡C6îŽÕ=ám¤[ÿæŸû¥ëpBù©t½b6bƒ –é§¢cKm&ë†ÍHû¥ëqBù©t½b0b‘䮩މá-¥qÁù©u>°ë–ÍIû©õˆ©ŠO„yk¿\tO m+ëšÍIû©õιà|ÌŸºŸX‰˜¤yjÖÝ„ðv’î¹à|ÌŸºŸXuÏædýÔúÄDq×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÒ]×<™“÷Së¹à|ÌŸºŸXˆ€q×NÓ;ˆ+ªË-¼•%ÂQšÈˆ­c.ñþ±‚{—*¹VêíÛ‹qˆs\ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï ú÷@8r&#ÂXú:©ª€„SÍö¥¶òÛ|“‘K÷j$í¹pN÷…}[¡¬aIÂøKÇ™TrF¡(¦›hs:žKo‘YH#Èd¥¢Æf\?¨~ÿRQz¿$ÌX‰Ýºœc>Õ=¹ãg‡—êóI°&ŒªX{GØúV3Ã0þõ)Ês¯ê$-µ!§ÍJA¤Ôh23Aßgq–ÑThTz…kâH®¬ÓIŠäu:©k•ÌŒ‰ÙntžùØ{ôu¤t·ñÍ7âzŒ©U i±Ln[H̳i䨒}Ñ"æ¤\ÎÅÁų)EÆøµBÁbZ´ÊUG©&†N¦Y ‘”’¤ìO½ öÛ¾]û„ÔÕå;7nÍYçTfi¦f<Î[bsË8‰žùèéNÙˆ~h“Gf“¨– ,ª4èhi©r™K‰Š¥4ù“¨Q‘šJÙUr±Ø‹¾B8±CÄø±«aÊÕZ3Döæ4%G­I)µ¶»ì2%Þ%‘ FÒv¨Ut•?É~šÆ"ŽÓYC*qÕ¶†]jÅ”$¬¦tdW>˜ÇU1ƦS´{„¨•gêÊešŒú‹‘VÕ¬é¨ìƒ,ÇmbÎÅ~"¸Ë¹V·õªÌOõc1Ž^gQŠO„xn%IŠEF)ú¬  ­Ôïƒèùxƒâ–W&†àî·£$̵ª²ÔW±•ȉµ®W;w®G“ÆËD8³ÔPŒŒ-_Že½»¤ž»ˆÖ¤¥)¶Ë*æW#+ˆæ‚ñõ?ÕªpëÐÝ™A­Å8“ÛkÝ‘m"QÊåe(Œ®[rà±ÈqlíP°=J3Öj$IjLöÖG o ¥¶Ûe#¹Úæd‰ôOJú=£âº–7e—*ô™ ©êÎã¦Ò&ID³+wFF³""Ù°ï³tÓ4o†Ó›´üE È\|:Ô¨ÔêuPã¹y.%N©:Ťԋ%=Ñ÷Dálî.zcMx¿b,£šU£º¥Ñ©fÅA½KˆÔ¹ªŽ›]I"VÔ,®“2ÙúÈm :bÀMu@±‰Û«¸ýÌ5½®JDGKTöé7v¤ÒJ2±Ò#÷Eúì%áJLm㥧B®SáUYiš“´59ÌÛÔMº§.ÒINršöVÞïg’N„w.35ÅÚ(ÇÇb:M5X´ƒ†í˜ËIºñf4©/r”’–£Û{•®[ Œ!z0Ñ¥3EŠ©˜Ò%2l×”ÔX,D\ÇÎÆE™Ô ËR›žÅ.Åm¼u€´Ñ´ÇEÄúeN}”…Å’ät¸m£Èq+lÔWA™d=›nEÄ,èHX èÖ 7ª“(U¨•4˨nHFãµVµ),çàJL);™{“ÙÝËÕt•VÒܦ1 ]F%£Çf›ho‘¸ê":ÒwAe<Ƨbî‹nði}Rèu­%Péx‘Òn—"FW®¼„£Êf„÷‰J$§ùÇCé*…©4ê´*æ…‰Deµ”ZÕ ,:ñ[Õ‘dSd\=Ñ™wŒs•E‡‰ IÄtÕÔ©wý.2R´&Gr½Ëi\Êǰt…/IÚ'Á´šŒœ=‰q-a2#©è3ë‘Ø3àJMÄ÷%Þ3έ—á¤±^÷§G8wSªÇS…WQ²ò 6¬â¾Eïfy•›jVW±{’Ù´K›Ð,·q… #0UIt³©Ô[\[î”å+,õŠ5(Ëø>æýñ!êN•µF®a,AOR!:Íe§V_£aÆÖ“23ïåIÛ¾D¾3úf=¥VtéPÅø†·]¢Ã}KLITµ$a%d¶•¥IVdd+(‰'s;ñ€õAÑŽ…Žp¤uãÚef™Pª",¸ÛLËBîyZ\|úÄ%Å'Wœí—9ì&h¦•[Ó‡ZØ&£;Î6NN‚PÖÓT¶Ë6V~MÌÙ»ž;í¸ôi/I8&\Ü6=G®JÕ®ÄÉõ–é§n0Úójò™Ìûž —Ið^ÃÕ#Iø&‡§õãê]aúµ>µrÔD'\"JJL³ÛYshŒíÀWáÙp×xãEñèø5X¿ b¨˜šŽÄ³‡-Ö£)…0îÂ÷*3ºndW¿ð’er;‰C©æŸFÂÎijS¢©øL*š²qÓNcUÈ–iJH“rQªçÝY=ÎÛZ`ÒD ¦‘A‹¤ZÆ+‘5ôšÐt–!Æi¤­+"]Ù'²4–Ô¨ˆûö-‡šÄÚMÁ:¥ð¾0[ÏCƒJ\y2·+Å‘ÃL’"ÈhÎ~ø¤F[Q€…MЪ›ÂøŠ|,_M¨UðÚ ujs /+D¥§bRˆ’­„›]&Wé†xJ\Äxò‡×Zc_ ÅR˜¶RZIÇÍICfi2ØA\ÈÆK cì' ³Fê«júåÝ;ÑþŽéîœû«/{‹ëQîòðþ£¶oDºCÀt,%M‡TÆõ…DDe"£@©ÓŠ[.¬ÓÀÂÒßèÑšæIRŒŒŽÇnñQŠpªa›ì>l:¦Ö%¶¼¦e™ -ŠIÚäeÂCpAÐ3Žou&~2§ÀÅU(G2-q–« ˆÎÊtŽÉ=‡r±û•Zö1©qˆ2ëÕ Tȧ Òr3ÿtѨÍ(þb2/æ8­9P*ñ`U]ÇÕŒ8¦¡ä›F‰Giç|¯Ý¶ó­)#3µ„ˆ½ÉÜšÀš.z·LÄ5ŒA\g Òè.›ä=Ož¸ŽÆ‚JLaØŽ×;¨¬F7cÑ£âMR©tì0§¥Ó¥”©NR“"4Õ7 £Ö8‚4·<ÊI©Ddj¿cÜ/VÁ˜ßã¬ÊS5ú‚ªLOÜÚõ¦´¬Éim$W»h=„”Õîv ‹úLÑÓ8¿ER W^:fƒ.<Ž â[¨ˆi²QO1™¦Ç“1¶€¡`4cŽêUª•:5œE",Š›‡ Ì’”´Ó$£îTYL²ŸrOe3<† xOBåRÃôJ•{B ÉÄ+ËG†äe:©k–e‘"û-Ãî“ß; lq*ø3HøN©ˆ]¥¢·ˆäTàÌ(.¼—ZS­­ÉÈÏT^êÖÍú¬.P1ö+¸{½Škhõ<¤š#· o&a ‘”’¤ìMõM™æ·ð‹¿pl¡YÕŠ†1§Vk¬Q$át Þ5G7Zt”—J͘)ÊÙìgepl°×š6Ÿ\“W*Ä̵3J:™×¤ŒÏ"ŒÍ632ÛÄ7e#Jør¢½.Ôª’UMÀC¨êekS™#¼ÒHÍd“ÚÝîdWWÁ @üêM¦á™4|qTÄÔJeMŠdxòæEmíZI2¼¹ÈírI^ÜEÄ$zÑÝ •¤ŒWÑ ÏŠUS¥Ó™£ÞÜ“˜’¢2¾©ÛÿˆÆ·Ð¦.ÃØwi—Y¨nY•šQG§·©qzç5Rk¥&IÚâ6¨È¶þ£Êv˜p³ØG¦T73pX}ü@öæpÿÒŽçA™LÖ{-tßb‹ˆÀBœÑƒ5ü]k2j°°Æ¢V%2äÌn%yD–ÛiØDi+¸RDF-+B“›Ò] ¹]atÚüw$@«0Á­.! )Ï{5݉ٛDw>ž¥ãüT¤\^ªÈ§Rq qúŒ £QVég’¤ælˆ—·VÙÚÝó#°É#J¸5:UÀ-ƘûXc Á~&ø<Âó:kŒm²$Vî. ÜÏa½_BL±BÅ3)ÚZvS‡>qŒˆNc¹¬ÎÙ²¥Fi"2##NmƒO é…±ö…Ù£uU²u˺w£ýÓÝ9÷V^÷Ö£ÝåáýGh…qØݹx¾«Hy…°òЉÉ™‘“„…‘™m³mŒíÄa/Âtj;ýIؾ´õ* •Hõ†Ûfjã ßm¸—J\2ÌEÝ+aðŒÅªÎ„·»L´MuÍ­ßH*—»·µV'.¯Y·ÞxsºàÙ·+¤,c£J.ˆjG“*$Ug&SîÈmI&l¤(ÊêJLýé ""=—3;ðÌÒNŠªºRÃZE™‰fÄ™œ¨ŽÁÞçT–htó-d[KôªMJ¹šOa€×Ý Å‘‡±Ujn3N‡koÒÞ[ðThq )nÝ+3#2^Ä*æDWÛriwG+À[Í)ŠÓšef1ȇ)¶M£Q$Îé3;–ƒ#¿¼&õÜ}„äè›IT6*Ùª¬Rôú{;Ò×0§ØY/1¦ÉîP£²ŒgÁi³aìG€4sK£T7TÊ5(ãÔÔ¸Kš¨éµÔ’%mm{Rf[?YÉhn“A¤hƒi&­A§×$A˜Ô8Ñç5¬e$jh–yOa™ë‹o{.Îz¾Œðüªz]ˆ1‘C~.ú»Ä’™JHœ#FUl4šÐ[e•n ‚¢,_…Q£ŒC£ÌaP~•§!¹mMn:ž$©*lÔ“JvíÕ"Çn>ýÝ"ã, ¤M3C½W‹†[Š˜lIˆ”“Å”ÍDµ%IWrjRö^ÆGÆ@)ꇣÕc5H©«à¸4WÖöᙆ™$¡òQ•’ò‹b”D–+m]¯ÞüêuôiÐñŽ+¬Ó#U‡)J’ÄI)ÌÊÜ48¢5'øEfŒ¬+èi_anÆ8wGJ¢ýf-.Bå=Qv2˜Î£7 ’”«oýê¯ô{É |gCÃ¨ÄØ>ôJV#§*#’ÚhÜ6•i%Ki•œW~ß̽£ì)ZÒ>Œg¢™™MÅNTÈQ¿FÎvÙKÆ”‘{’Vt¦ÅoùÅ­0áj OFX›ÂÂÐ0üÌ3ˆ§4¨ljŠTbZ%,¸fnæÿÃúÄoH˜÷ Õ1V¦SjUbÃø^3q÷Ê"52 DHIºÚVGkjÐv2¹ØËˆÆSLzQ¤Ô43 R±]G=Rœ—Ü™*F(ÑÑ”ÐÎRJIJÌ’3Q$ˆîgÄ_Upf€X-hÇ4éi¯êΤM/H%j³k,áÜËX¿tH÷³þmƒ¥Ü;©ÝO¶†—PýlÚß9 ¤¥IJJBf«\jlŒ“°¬E²ãXch8%=…k3§Õ$EÍZfB ‘ìžT¶›–cp¶½Émã–bl]‡¦u4a|¡ž¹ª¹bê\,š¤™sNC÷Äl#3ÛúŒÓÀ¸/1@Ñíü%O«#SäH¨ÔhÔüu¥„º’C…µTiÙosÇq¤â`::äã˜õ_ ‘# -äD$‘ž¤´¥‘ZN÷m%°•µe³chŸIXW àúBÞÆø*€N®N\TºÜ‡ &I&ž$Fó«*”{{Û.zμˆÑŒë¸Ê±6Zxœ—Hb2 MȽjÍ =Z¬œú²ÚiØ£Ûľ¦\D—Z§Vñ|V$³Suè´h2'%m´¥ºò’­†„M%°Ë2‹ˆxðÆÀstÙ‰#bYš<|LPi´ˆ­’JQ»)Äv{–IMÈ­°ÈˆËa³Dšjf!ÃPqM Ä¥RbDUSMqsBYRS•d¥•bVTØó+a\FkøÚ“WÓí?nje>‘ ¶Û›¢55¯aÍÐêv©N©'uˆÎŲà<½Rê}+Lõè¸1`ÃksêØŒÒ[mŒÑ’’"+™™ý&bö‡ëX^™ \7°bq>,Ÿ%¶iKŽ—¢%&i#%$Õ|Çum±ð'iǃOuúN'ÒÍj¹C—ºéòu—µjFl¬6…w*"2²’e´»ÂOÔçYÀ¸_}kÕüFÕ.¾mª5,ݧ½%1ÉIîž2AXÌï–ÙˆìJï ñh×Ïê¡v‡ K…J*„Êz}é/æ$’-ÞM–Úòðm·ÁÆøVŒ°Vñ}*‰€ýz²T™LÓÚ&Ú2[Î!*$ð–¬ö÷ómà!‹ÀØËhÿM%_N-‘‹iõ(‹EJ¢PŽâqy¸YÝV4!FeÞQ‘ʬu¤3HÃ8/ `™ÏÖ"áÚžú.[±ÔÁ8á8¥¡•mþîvâáïóàüQ£iSpµ2˜ö ƒT9±ÛÊû™˜SÊ'½‰2Û~ðÜ £ØT܆…ƒð¶"›Z§¹6iV$ê¤=™ [mÆ<ªÊdJÚv"ÙÂFw,6:Òž:4ªaÚŒÉuœcḕ&)¤xkê°€}u |zÔÓ=o®¡/Cúšg¢B$‡qŒŒ¾:ñçÕ4oJpÏ Œ¾:ñçÕ4oJp¤%Ás½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âaIŠO„Tb“á‰Rb‘QŠG†¾«(7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœ"I;ÞôÛœ#õ-ïGŒ³®yëf(P¬Å 7¨ZžŠ-¨\P¶¡…¨u…µ +P¡Cúð Å+1AŒ›«B“ŠŒR3®&ðÃJ¸…EÂB±Î‹ÜŒÉ3…“B¸‡æ­|_´_äûsëŸÏ’7ÊÆ­|_´5kâý¢øðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_ðë]çóäo•Zø¿hj×ÅûEðµÞ>FùXÕ¯‹ö†­|_´_w©ïG8GR1m[Ôª´øT§!-%fÍ/)Å(µš¬M‘$¯Ãðs»£³j‰®©œ~~ÉŠ¦ZoV¾/Úµñ~ѹ4…@Ð,,:N ÆÕú•y½ËK*Kn]Ä’îg5º-¤\<уñ&&¯P¤bJ%V©“Š9ÑÖÚ\$êV¶ÕcÌiJ””‘“cͳ„‡/ÐÓÅ]S1ñåÿg-7«_í Zø¿hÝ2tOê/U—‰'T)˜¥tJl’• 0Ïý!–—‰JK¦áë=ÒRHº“ÀD«yú 45/F{ß6²*g›m—gº¦Ñyj7LÛKdy‰9Gs¹píï6tµUîœÏÀÍM=«_í Zø¿hښьLg­ˆñl¨xbŽEºåHÖµ_"o°¬V¹ØøRDG}™=+hÓÓ0$|m£ìfuzj¤nw#ÍRRùªö3AeBŒÈÌ®“Mìwà64Ñsôó9ÿ휜e¦5kâý¡«_íM:Ç´š½?®|/5Šc³¢G¨³#Š'ž&É-™¬ÓœÏa_a‘ªÄwŠ_SÉÖªXÛp³\§±Fm,Ò¡Îz*äÉ–¨©wVâÛY¶”’–ÖÒØip¶‘¥V­V´”óßþcóÖœÔçMZø¿hj×ÅûFÐÆZñ\…"Æ–jÛ¿Õž±ÐÍMg«_í Zø¿h™â cj#¦áêÅø•›Èfâ ­J$’Rá(Ѥ‘÷[.W°ÌMÐŽ•!±9÷ðtÍ\»Æ‡ZY™e%w•¹°ÿ›mË„Œ…§K¦Œ__Þ Õ5¦­|_´5kâý¢kŠôgŽðµ šæ ÃràSÞ2J]Y ò™ðÒ“5 ÏÿȆ´šxw®´fî N»6±½fK^ú¬ÚÎ ¾ä8]63¿üÁºZëV¾/Úµñ~Ñ|_µÞ>Hß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|ò±«_í Zø¿h¾áÖ»ÏçÈß+µñ~ÐÕ¯‹ö‹àk¼þ|òóšEs-‚‘}ß{1`gê¬Óf¸¦žËS9y–úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃð¸HV(½Žã÷9~±®SM<åB kÄcóZž#M¨þäm•Àõ©â0Ö§ˆÃгíep½jxŒ5©â0â¬ûFÙ\oZž# jxŒ8«>ѶW[Ö§ˆÃZž#*Ï´m•Àõ©â0Ö§ˆÃгíep½jxŒ5©â0â¬ûFÙ\oZž# jxŒ8«>ѶW[Ö§ˆÃZž#*Ï´m•Àõ©â0Ö§ˆÃгíep½jxŒ5©â0â¬ûFÙ\oZž# jxŒ8«>ѶW[Ö§ˆÃZž#*Ï´m•Àõ©â0Ö§ˆÃгíep½jxŒ5©â0â¬ûFÙ\7Ô;¾;Ѥèܻ娉¹7VmN»,œšÌ½ÖLÖ½¶ÚöÁ­O†µ¦þÐ Ê>(Ñ,Ñ4ÊÄZEJ©! =%YPêËTy/ô²œ6Q™ØÆJz!¤hã·&¹‹cÊÅoÈJY§Ã²šÕÏ1öÜÆDW±[¾4Þµª­EÖ¯P•Ó–HÍÜÝS—s·ëÈŸù”)•Tô“§Œ; m.©T£Cju8”)Õ=hÙs"¶e Œø åqÅÔñkSÄcÏú6vE?©Ò1Ó÷‰ÿ…³=C8ÚÃMº1:ëD–©xÔ·s{dµ&f°¶l?r|"½>Ðq;•ÌeŽàãtü+R¤0Ôu&RVšŠI(#Œ‚#3+¨–«‘XóZö5[–õ©â0Ö§ˆÅé¢Õ5nýHë>®óŸÉG>ÎÑÐmK¢` ETzÞ댦&U*U˦›ÊÜ8­š¬›¸£Eˆ¯°øÊѼcغÓCO4¦”xáå’TVîU&"’A¤ÈËõå-jxŒ5©â1Hµk~ù¹ë‰éÚsÜÌã£bu>¥Õé6cc4áfÚÊ<åÇKÍ­{?D´©IM”Wá>"µÌ‡Hi‚ Õ¢ @ö–•„©·÷Že5+Kî;cɱer3V[’ ÊÙ¯°‡ëSÄa­OŽ·âÕÛ‘_êc·?äŒÄc¶ÐÃT]&`<%X¯Êm4}1[­NÞFKf¶ŒÿQáù¥ñˆþ‡qž'Æ:LÇ•Jk4 ŒjËdOѪ“ÙqÒKCm²¢J‹2PyUšÅÝ—ÒZÙ:X…MÑtœ…p‹GjL4Õ^¤Só“ )"Q’TE•Ýw$fDJQm¸ÖZÔñãE6ªßº¬Dôý£9õwŸÝ<ù:úd >êŠÑ±oôöR¸²µ´z…På"’¥Æ4!´)J<¤¥$ˆŽÇ­²ÃóGL7†tÇ¥J ~,tÔ±=2Ó‰ØÊÝdÙ:“3mKΞè¬gmƒµ©â0Ö§ˆÅ¦Õ©§sÕóŸÏþQ™ìëLi-Ê|­a)xj“‡\Š!=uõÔeÇk]e%wlˆ’f¤™±\DV#Ë%ÁÒå;Õ£c9!Õ2Õ¤¶Ù¨ò¤²ÃVÂúV£ûGÆ8›Zž# jxŒDس4ÌoëÌç<å9žÎ†ÂòäÏê.Çrf>䇕_Bn(Ôw7!¨ÎçÆj3þsmP*8—*³Œ*hî±F»XË Wœiµ •}RÐdƒ=½ÝŒ”ž#Iì=­O†µ©£zS†x`teñ×>©£zS…!. ï úmÎ$ï úmÎú–÷£ÇÆY×<õ³(Vb…›Ô-OE Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)×e;2ªÌ0ú3¶¬×+™^É3ï VðR<ñë¬/ðìoµè˜œŒESrZ¾·é ø‹õη¨þ ø‹õŒ¨2X®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPŠëzàŸˆ¿Xu½GðOÄ_¬e@+­ê?‚~"ýaÖõÁ?~±•®·¨þ ø‹õ‡[ÔüEúÆTbºÞ£ø'â/ÖoQüñëPÄ4jlZ;ò#ÆÈâråVu®¢.ùˆˆžâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔùë@Îe+Tc¦SéS£QTã†ÛdœÌÒIjA’ó!%|èZ{“W¸3à23V¨ÇL§Ò¦F¢©Æ9 ¶É9™¤’Ôƒ%æBJùд÷&¯pgÀdg°=• sð¢S¤º¦ÔŠ„cÑ$ÎéI:ãVVÎÍ(ö_a—Ð^0Y¡=hÿašCˆÈMbTE¾ÓmÆoô­2ˆÄâÍFÙ•ÉR[á;žm„v3-ØGž®eŽŒ@àÐåØGž®eŽŒx«:Ñurê1ÔÃ.Ib*U¹™UÝ}ä2Òl–Œû§BoÀW¹ØˆÌHá ËFÐÆ‹«Ü—NާÙnKñT­ÌÊlë-—Se4GܸÚÓ~µÊädcÛØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,taØGž®eŽŒ€ï.Àz<ðs,tc‘ôùF§aý,Vhô¨è2c“hIÎ;jQض\ÌÌöq€‚€˜OÀ¨ƒ¾«áö÷ºaB•ÜL=[Ǭ²vGÛïNm+—sô¯®SŸ£Ö§Rd©µ¿ K‘ÜSff“Ri3#2#µËˆ„EQ#Æ=”:sõŠÔLe6‡æÉn;jpÌ’JZ‰$fdFv¹ñ‘ãÇ/@)†ŸezÌ͸‚RNͨÊä{8HxrÖt1¢ê<6åÔc©†\’ÄT«s2«ºûÈe¤Ù-÷N8„߀¯s±˜¿ AÚ2šÊž†ËrZK®2¥´˜ËI-µšƒ2oÝ%iRL¸HÒd{H €îVt1¢ç«’¨ÇR§ÄŒÌ§ÚÜÌ÷ <§RÚ¯ª±ÝL:V#¹eÛk•ý½€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF€ôyà æXèÀphòì£ÏW2ÇF9—ª— Ñ°Ž Ò¨qS9ÒÐê씑­fóŘò‘ì”–Â.©Àw´¬Ú}M§ás"· %ž/÷E®³°G!°·šYöEw'Þ=g`ŽCao4³ì‡YØ#Ø[Í,û!º 88xõ‚9 …¼Òϲg`ŽCao4³ì†è0ààÍJ hò«r``Ì,óHôe+yÚMœeÕ4âli.¡E~µÊåc¾³°G!°·šYöCtpp ÕÌ(úD[ú]:›¶2%ˆQÃ}ËŽÌ’Eu¶™íþb".°•‚°;O©´à|.dVᤳÅþ蜘pHñë;r y¥Ÿd:ÎÁ†ÂÞigÙº 88xõ‚9 …¼Òϲg`ŽCao4³ì†è0ààãÖvä6óK>Èç.ªht¸‚•D¤Ò™m.¦ 41¬3KJºÍ$YiÚüî¼ÄäÃM€”‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Ñãã,ëžzÙŠ+1B‡Íê§¢… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&'" …þö½‘‘©óÖ€ šU*aaœ(Ôœ9K©¬én(”䔩%»ew%ªu ¶Ëð_iíà¶I*‰Q¬à×L‡•D’¨ÐÛζô¿4ÙEœR”¬Î’6ÍVàØ ³êµJ„h±§Ô¦Kb"5q›yõ-,¦ÄYPFvIY)+qÙµj¬æ"G›S›%˜iÉ·ŸRÒÂlEd’VJv¸ ˆSh’F±Yµ×1™RÑ-n7e©MH7’Z´í"6ÍÓ4ÎàŽÛ‡ʨ¿Kݵò˜DMYJ£O`”ŠwéE¹J6#²xt)GÝZã]Õ+5zªZMR«:q4Vl¤È[™ õf3°ý[¬Î„ÔÕyò¢³ïL=%kmBLì_ÌD§Uñ;øO S¢U+Ã]Ó~;R6Ô†åI#Ì’;RÚR[vR]â!¯¡´ï~®Šõ*ð›5kµn£ÛwÓ˜ŠÉWx‹fÍ‚ÓUŠ»4·)MU'7Op²iGÆh½þCÏ*\©z­Õ%çõ-Mk5dAp%7àIwˆ¶ ˆÀê ÕePpý"¹)K•NÁUél0dg­[h¤-(Ù·i‘ó†æ(ÄxdêœJXÚøF]y«Çe·™ÕêÐJSvžÖ+)+2¿D®èûΦXðÛÑ.t¨­”¢k$wÖÍÖM-¦3¥*µò©M&ä[ Û+û’¶Â Ñðµto —JÝKÏ#qBC:å|¥dIf=§´øÄˆŒª¤ü?€§U¥é ÊÓµ lÈje­¥>é6J‘&— D–ÍÓQ$ÊêRÈŒ„%ÌK]¨·YÃU·+ª•^Â’[U\ ´îŠ»dh^áQµbÔŠä•÷gr¶S=½ `ØP'SááÚ,hu5MŽÕ=´7$Ï„ÜI&Ëþ{ÊfÁT¸ç™†èY3eFÜzsm¤Í— ÖŽÉIpášÓòTfecÚ$k,6æ%¡a÷1\LùÁV=—éB™“_v2ÍK4ku„n©dd²NÂ#Ií3ÈõÓˆ÷o\r§']ûÁÖîçgW©Ý{›>lºín¯ý&ùòäÙ–ÛFÊÜ”-Ǹ÷-ͺw^§sM~»]­ËkgÖþ“7~ê÷Ú,o>뇮-å¥ïÖL›ã¸‘ºrÚÙu¹sZÛ-pŒR½ 9I¬â:¤8õYÓáÒœ€Õ=èY[CªBPf“}¹-¥•­%6jB“m¤C3ÔçDM`íÑW™R×Qa:Ò–Ks$ã6Z”jЋ¡6;ó/iÝGÞ’E£aHµç«ñ¨”¦*ò•éíÂBd8\Jp“˜Ëé1z‰ÐÙ}Š%21©ªCè‡,¥×TDJqD’+¨ÈŠê=§bâ–cvGùÏì˜nÈÿ9ý“|Ùç?²a»#üçöLð7dœþɆìóŸÙ0ÀXÝ‘þsû&²?ÎdÀ_cvGùÏì˜nÈÿ9ý“|Ùç?²a»#üçöLð7dœþɆìóŸÙ0ÀXÝ‘þsû&²?ÎdÀ_cvGùÏì˜nÈÿ9ý“|Ùç?²a»#üçöLñÀ}Sÿx‹ÿMÿµhw®ìóŸÙ1Á]Sÿx‹ÿMÿµhVÅÅgëzø3oI‰MÁ.Oj¯W¤ÍUAMH“L†—KDÚ ´šÍÖÍ´©Fïžl»}ɃUZ£4§©-T¦7N}zÇb%õ.+gt¤_)Ÿr¦]â┺J• äÒêà¾e”ÜŒò›U¸®“#šr6&°£âª,F¬ë€O˨"3,L`Í䤥%¢qV3N­'ÝŒ–¥ì#¸¦,Ê’t¯¦¹TÝ*yq ¹ÉmL?!•HZo‘™™¬ÈÖƒ;™)¦Gs×ìÕª¬TΦÍNksÔfg%¨3>ÎGÚ-LŸ:dã.l™Ôd£}×T· Ë€óÞâ»ÏÄ›]«Öiòq*Þ(fî¶Ìwä<¥:iMÔ”/i–S4¨È¸Šü#óE¿íÝ;ú_ð–1’1 ~Döj+•7¦2“KR-jq²222JŒîEc>1•ÑCn;¤ [M!N8µ8”¥%sQ›k±wÌ[uF2ªVkÙªLÅ¥„i-4C$ŒŒUÙJ,¬ºÝj’Ú_¾|¹bOð†F¡ˆ±ÄÚ,I0j“uMÕëíMM0 &z™‹Pu–5h”Z¥6†Ó•f]Ùž¯mÌÌö,¼=ƒeÖ·îV£?U»g»]§¶§îÚ’¦ÏXiÍÜ©)2Û°ÒF\?*˜{Õa" SÑgEnC’PÄš{n6—–³ZÜ$©&Dµ)JQ«„ÌÌÏi‹ G;TKH,I¥Ô‘!ÂÔ=‰¸iqÚŠ½IÜ’·MYSŸôhQ÷WîR­ôÊÛ(mn­Õ%$Fâȳ(˾v"+Ÿê"!~}2Rý: ©—1$â¤ÉæŸ+K¹wH-c–Iì,êÙ´Ç­‡¡Ga¶$4Ói$!FT¥$V"""ØD]à 7dœþɆìóŸÙ0ÀXÝ‘þsû&²?ÎdÀ_cvGùÏì˜nÈÿ9ý“|qgVÇÆÌ©ÛÿñÙ›²?ÎdÇuk+JðGr:3f\ûà:†¡þ¸¿æÿ¡ ¤Ê«U*2I4*‘4—Ì蕇 M¾¯ô›»©»X®…‘kO€ìbQ[ÄÔ8µWã½=$ãj$¬’…(ˆìW+‘\¿`Á×*x»¢ÖاÕ#¤óS È#ã²eqÏÖ²ö"r„“OÂÔ(òˆÊ•5Škì>ˆË65¦¨Ê}HdˆÈ›A‰$KZ‹!«aûQ‰13UQª²*ñ*K­ït=[T÷ª2Plk‰*$8qZwÝíVÃJ/”ei2j8S¢&==4³NC„P ˜4ÞöÕäËk÷¬,ktq¼[ý´é¾mý…¹ï{ßW“/ê"4lQŠë,À£µY›O’œ\íD·Ø†ä•0šk’Œ–Mg`œ%X®Á]>é"ML•X•‹ª0ŸÅÎÄb…"RŽãóT m4³yÓÈFFµ8¦ÓªÈD¤Ã÷#Ýv§¡¤@‹Mˆ–^×´LSòÕj³•‘±Z¾âå·/sÁ°U2¥fÕ#Uf1O“P‰²4§`ÞgýÅš.Ÿæ0ʘ‚C]z6!{q«J†t³ŒÎ¥M?[r:Ì×—YœÃY,‹aSÚg·Äc~ðfåܿ蛟tnVãVMv·[¬¶[gÖwy¸sw\;G¯®ì=ãÁsÙËQŸ/ÿå«ügGeÔ?×üßô!ÆP7#H+}•fmÆMh;Zän¸dc­ëxš‡ªüw§¤œmD•’P¥Šår#+—ì=/H4™]&á“$¢Ô¡Ñj’ <«åCÉ~,‹… J”…ÉQÚÇc(íWJj¡‹ñ *"Ú©1D¢Å~2òἩӚp•IAä%šÈÔ¤ È‰W$ÆÄ^$«˜ÜÅHiRZmm6ñÆY­Y¤Ô’V[‘¡eßÊž"SYÁi•6RS ¤OBQ1Ò„yä%$d”¸yn²"3"#½ˆÏŒ@‰Dľ?R“:9ÓT#«”È–k5¥Q–ˆJYViI!D”¬Ô»/)‘ãæÊ­âéø>¥*»PÃÒÈŒªtV£šéÊM>]‰fëKÌé‘pûƒKÝÉp±3¥¿£ª[)f™O¤Ái/„¢=7V’tˆÈ–D”uc2¿ÓÕfèþ¬ÓíUaÓ'·$Ðo¦M;ZNš/ÔJAæËsµø/°¼rïUûYíÿ†Èèn»°÷Œ?Ïds—U¸óñ qÖ2½fUe2½ÑÃÛÂBiêKN€ºŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔùë@Î{¥U¥3Vv›1ºsëÕµ-L(™q[{”®ÙLû•l#ïñ‰ÿ‹Š7Öõða.‚©Õ”#{7ɦзdä”te"±)nÄ$”i¹Ü¯Ár3#žYzõ•­ê„ö ÒãMžìiȦOLÆÓfÉ›‰Q-Ã%etû“QŸrGm¢Ö2§@AL†¨1b8s ¸ói³ŽLWšÊ£RVjZ.ß!‘w7,×IXDU"2~;„܆\ef„¸IZM&iRIIU¼i22>ù¶&zK©B~{1šÃôÈ®ª™NYIiÉâHá²d‚%:h±å+¤ÎÄW3;™â0ìhrh•R!¶ëñ`5&3æµ’šVêe³""Q$ÈÒꯘ€­m·E\²0`$µœAª2:¤oŒ¶df[¶”†Ói%‘/g¾­7F]–ïí:¬0ö‘¦`¸XyY]MÈ LÝN©ö—¬4$ö«! •m†›åþö†á¯¢£m6cª0äC”ݳ²ûFÚÓr#+¤ÈŒ®FGôΡ4š-—"]Ьš›KfûΡ,¶—VÑ%$Ú“Ý]µš®V4ìá¾^¿ ™úCi1i.O„Ý" »Ùi`’ÙAd’n:v$‘¦çÜ߀ŒŒÈÉ»˜‹’X~,—cIeÆefÛ¸“J¢;LiË f.¥Å¦À£Vw®”ÊŸ”ûOC‡QÝq–M*.í­IÌN™sßaZä3‘ˆKµj:©0 ¥ºœçdIfCˆqôµ­Z‰JuÃm¬‡Ý$ˆÎüaÆ·ˆPfÎ×î(r$îvTûÚ–z¶Óî–«Ä•Êæ{Kq Ð<**D\Še0+­J9k$š 瘳fÌ›’«—¼38åŠVrÒâãïeGZ–ÎÊ4n'îDg{„îå‘&Ri5š%NLJ+¹Æ›Z‡ZlÝCF•ŠQ滉24™‰[8-œTZ ^*ú°Å;yŠO%|«“V¯.mvlÚâ=—¶¬Œí~è7 z=†nöï–㑸uÚÓª=V²Ù²fµ³[m¯{mfG€Ý6ˆõzSÚÍÓ™Rw5•dwg±y‹nÎü5"\\zlÎ$Õ jÙ[ŠB z©žï!’Œ­}„dw¶Ñ3<„LÙŒ?K«â*玘*t×g?22¥•H%¥.:g””QÎÆ³<¹¶ˆ~b < L˜¨T Tˆ¹Ê`WZ”rÖI45Î+1fÍ™6+%W. Fè Q0»øÖ‘‡[ÃL2Š»4òuäÊ|ÕÉ,4£6®³,¤§/eç>½­l¨Í`š•J}‰ÒâÔb´ÂÖó¨%%Öß5!d••ÒZ’2Ë•W?te°7ê"¾¸.ÍKwŽÓˆik¹lRÉF’·ÒB¿åô ª0fÓf9 £D9MÛ;/´m­7"2ºLˆÊädA‰ Lèµ)TªSè RÜf¥ ¦‰¹.ºiK‘ÞÖ&ëQ‘¤ÖÉ,®Y‹1–c+ &' ™IM~¥G‰W9tÊ[§œ-Êe ›¸æ©Ä™f²‰)WºÊgr"î£w1¬Ò“R‰)#5؈‹iŒF]¦ÄDº¥:ö!×â­´+è3"#ZdÙ4Ú”ZŒ'uR¢¼‡™^RVU¤ÉI;Èìd[`’a÷j-@¬â*£ï.¸¯Å3yf{µ÷d’+û£BŒœ3ïd.ù•í300(õipŸ—:D6=ùö£©M·ßî”EbþqE.›QªÉ8Ôº|¹Ï’sq™SŠ·’Fvu2»AM5çL*|'"¥dD·C®X¿[‹]øø³´Õ*•R‡K=Tgq4æ\&ÎĦØ&õ$¨µŽÝ"ã·%QœeÄ>•ä6Ô“%¯k[†÷ï]V‹X¥%µÕ)3à¥ß{91ÖÙ/èÌEq:„pÖ†+µIQ)¼/ºó67”áL8ɱŸ¬¥˜ïou¶Ã /WPÂ&Õ TØôõUXDˆU M-)}hwTé=•’2'IW$‘XŒÌöZ7¼rçÊDH1_•!òe³ZÕôm0\ K‰:+ñd6v[O6hZ~’=¤$íÀ—BÂÕñS¯CaK‡5©¨^½KI­¥(Šêe»•ïÁÞ2¾S "<øxf]YåÅ:¡%ÓN±IjoPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<é‚%aŠ Z<¬3GžÌgy>¹IY­Ì„£=[É.ÐVµ¬ž33;«Æœ– ª5)˜M@8)uL¸É¼§Œ”kp×}b³\”V±ZÖ ¶•Ìa%,ÓƒH¥SŽ—PÝð×›pÉ#εÈÍ´usîlFE°y+X…u*‚Å*›LŽãå!äCK„N¸D¢J:Õk×bM‹º=ƒ ¶n£ˆœL(Ò©›£PÌuNÕ¬ßSmR‚Ú£Bl”$®”‘™ŒÎç-®õ"CÎ7<¦¤2lH!&mºÙ™SÊdeÝ%&FFFFE´c€1AQÄY¦Á¡9“L‡ZaæÐ÷ú98HJÈû¥š‘Ü%FfJ^͇mƒ7ñƒ.ã ÄúDjD‡’ê£Ušaä=ªY»•šRK$žSV¯5ÈÌŒö(à€#l Í7*5=¸3)Tê£ ©JŽRÒåÙ5på4-&dg·*®W¹ÛißÛ/ΗZr©"›KZ¤AnÆ5K&e6‚A$Ô’Wr£oÜb-·Œ€°3•¬E¾TXô„Q©pcÆ’ä†N1:JA­)JÓu-Yˆò ¬DFE°_¨âù’æ•Aºm.õI9OÊe•’22V|êQU™WBI);í#±Z8¶n~"Sôשð©Ê[R '$â%ÌÏå;‘(ÜZ¬›Øò¦År-›YÂÕÙv¦ºŒH±qÝa³…)-ëhR‰$dFyT¢²‰IÚw#ÙlP# ÌÔ±¤ÓÜ•N¥°ò’¹.]ãOcqj2"3¾Tدc¶Â¶CÏ…… Ñ«GV§³-Ù‹’L-¤­j²PD•‘Y)¹÷®â¬gkœXld¹û¢™â„ÎäÖ~¦²ºöu_ôŠ¿unâ!èY60ÄÊ÷CZ%InB¤¨Ü×!M’‰$›,‘b%¸[R~ìø“lXrF&’´Ñw4(P¤0l4ëDâÔš”³ÖÔ¤Ô· Ȉˆó™ZÖ"üŸˆ”ý5ê|*E2–ÔƒIÉ8‰s3ùNäJ7«&ö<©±\‹fÂ@ @’+;×u;·E¥´ý= %˜é7Í“6RIiJ»†£4’QÀ¢#ÈW#º¯çˆ[f‹R¤•–¦'I)”©˜RR´¶H2vÖA8»f%_7ušÅlØHÕ“c L ït5¢T–ä*JÍrÙ(’I²É"[…µ'îω6Ì7pªOÌV¢­)íSÝŒ£’l©¶ÒHA™k®j$¥s=™ Ee]GÛó!©­ÈTV]B%› Í«Qß!ØÉYOƒaÞÝþø“Öq¹UT·$aL>—w2ã2´”“Lt)ŸÑ¶§´™f3.æÄ«®"@#?NÅRbFŠ…Ói²äÂ,°åÈiJv9\ÔDVQ%V33,éU»Ûš“^zR#ɇ©C„ëŒL%šM½–JB’¢VÓàVÛí¾Á‰Ä ÂñõÖŽ¦´FUÚ&1µú I')5—䨋¿{í½öŠkÅÏ„Üôø4ÈHs[¹âò­Ë[2”┥È®v+ˆ®cˆYêS’cÇ—Cz¹¤$Í·Sr2¾S%‘‘LŒ¸ö˜¿/Nz£\v£BDË;=SI¹™•”j5\Ìï˜ÌÎö=›3UB©ç`C¥Sil¾¤ªNäK™ŸÊw"Q­j2"=¹Sb¹Í…o ¥&•8¥Æ&ÔyÛºœÈq +) .ùÿ2±‘ñ€byÜQ12éÏSbB¥·N’Rã± 4Äi<êÖ)JQ÷)á3""±\ÅS±BÞjIC¢R)oKA·!ø¸KZUî’Dµ©(#à<„›8 ÈGÀ6ÀôSfɧObt75rY-µXŽÆ\d{ ¿Qì1‘ªâÌ€¨1©têdw\'_L4,µÊ+ØÔkRŒˆ®vJl¼ $¬ã U9&ª•JR”J)3£´´ºîb²ŽÆ³BMDgsJRgsã1‡Ýÿö&õî(_ë;£uj¿OîrêóßÜwín£Æ3˜‡·X§Â†š.žP‘ªaȪj&ÍkY õެŒn)Wµø öØ=bù.3K¤ÒU> Çb¡ª^¹(m$”lÏ«5$ˆˆ”h3Ø[vØØØÕf›>¡Ã|æfrk3ÌåUÿF«÷9¸†ä=x^ºš ï¾Tz}AÇ™[$râÈ…¶¶Ü$êÜGºJÌŒÎæ[-cp ±Mb¤ÂpÍCu ¡Òyr»–µˆpšNW‹¹%6“#;«fÕøD`H V,øOØôÈ@„÷|'ìzd @7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœ"I;ÞôÛœ#õ-ïGŒ³®yëf(P¬Å 7¨ZžŠ-¨\P¶¡…¨u…µ +P¡Cúð Å+1AŒ›«B“ŠŒR3®&/ðìoµè˜ØiÒæ¶§Ü„”«)ë§0É™Øa8´™–Þ[‡ˆk¼/ðìoµè˜œŒOž´2{ÅQùTÏ;DéCxª?*™çh(Æó¥“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ=â¨üªg¢t¡¼U•Ló´N”cOxª?*™çh(oGåS<í¥À“Þ*ʦyÚ'JÅQùTÏ;DéF0d÷Š£ò©žv‰Ò†ñT~U3ÎÑ:QŒ,yP©R£­èï))iF¦'F£J­™; Êö;\®G´ÆºÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#np‰$ïxWÐ#npÔ·½>2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢cfÒ0æ!«ÆTšM©Pa+4)رu$¢"3IšHÊö2;~²Ë ü;íz&76‡n­µ&­˜„Õ (ž’—T“=TÎäµHYßmö•¶Þ ãêç/ÌèràJ\YÑ_Šú=ÓO6hZ~’=¤? Å~tæ!EoY"C‰i¤\‹2”v"¹ì-§ßªcôzž$ÁøjCÝp°‰ûžKï­¥M¾´$›AÝ.eGt¢3·t³Ùn&“†*¸–‹EV’EY†Tú¦HÎã 3mIYȳ]IQ)9H±‘™.ïØB€HiSiØeºÜÚcUG¥Lr+,¾ëˆi²m ©jV­IQ™ëREÝ•ÃÞÌÒ©T×¢¼ý,ݦԨRç¦9¾²\e´ÛçÜ,Œ®yã³’‹*¶‘žÑ3V.Wæ<¦£7imÇL®EÜ¡µÞ$¤Ïù…*aôÆD•2á0âÔÚ4žU)$“RHø È”“2ïf.2Ú$Œ?Z}P‹ BˆãtÚ‹«u¹r™HŒ§ZY%N”•4wÚiQ,û„b¢©B£;oaúdÕNz ÇÜJ#ÕÅ<ýé+ÙD\²²ùMÂ}FƒD𯩫Á*s-È*Áë¤]Å2œÊ3=orf… Ó—)Ôe´¶œÆéS¨³!¸Ò×0ÒŠcm,ÒÛ&›’ÉÅ܈ûœ¦f}û„U‘!‡:šÚ®Ñ˜ªÄ«- ?›*]D¢Ê£IÞÍp‘÷Ç7¢š2D—t] ¨rJÚ–^[zͳq̪4ܳŽ×+ñ°ÑªŽxå>SÿüE©Kz„’œ­$“Ǻ¶‚7®UKI“0³ØŠ±[žëÒ—W¥" ¾—„îl­5¯dÈܺȖ’³vYç|Iþ ýwÈDŽ`ígãö¼°ºÒ6†)¸W×*íWS*U)¸ë[ ½¬±¼òP’WèÓm†£á¾ÂÙc#+é'Ót¢Æ‰¢ÝÝ»3;¤UƒDeÇI‘)å«Pz¼™’KNÓ#RH³gA«É¦_ö'J?þþ"D¥ÊÀ,€b±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÆÍY60ÄÊ÷CZ%InB¤¨Ü×!M’‰$›,‘b%¸[R~ìø“me…þö½‘‘ªŒÖ´2nªå½ °ÌXò^„ò^i·ódΩ3ʤžÃ±Úö¹m¹\ÑL®¦›ŠââTz{JŠòf%ÞS ZH²ž× ge*Æ»_õlpl%™_8©“tŠtª{ïå ýi¶ÊöØÐ¢Y8V#·»;‘ïbˆX²KÅÕ^¦S¥Þ›Œâ\C,²´f”kI—p¥•ÌÏÝû­¢<ˆŠu4ŠÌš‹4z{é}—Ù(ÏÚ¦êM $åp—©Fv;ðØÊº>"rŸMDiTʃm>¹Îck^¥Å¥ Q‘‰*¹6‹%sÁÂ0€)—>'9F¤ÖŽzªÊaù©K l£äEõG˜»£Ö(îi¹6“ïØ°[¿þÄ޽Šýgtn­WéýÎ]^{ûŽý­Ã´xÀ"}ÑŒr—¢øqë̓;ٸˆ‡™Ç éQmJŠû ¸ |ê›4›PáâD²ÃIÊ„&ŸÄ\ÞÓý}ñ#·pîE2¹¿“ñj½QDeÄaꊙ-ÎÊÔ…-K-¶žèÛlÍFF£È¢ö=ªÓèô5L©JDfs J¹š”f[‹ižÃ;xŒøqg}+r«÷|nŒ;;é[•_»ãtbMuÿ„¼mýÝßdk­(T"U4u¤Ùð×Gwz²/)¦öy{ ˆøHƪìï¥nU~ïÑŒn(ÒÎ15 E¹_Ýtù9uÌî6›*‰iî’‚2î’G°ûÂ"0œ à,€b±gÀ~ǦB'¸³à ?cÓ!¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>zÐó¤ŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔùë@Î{¨¹ª³4È«i=›*œ3$•’j;ØŒø ˆlÁ:CñZ¼þŒE´[þÝÓ¿¥ÿ cè<Ä.áº%C§•J£&S0àB7µ[¡÷I$šì¬©"̵*Çd¡Gc°'ì¤?«ÉßèðNüV¯'£vxÅú«:9©RÔ¸‘«õU³::Ò•))*t×Tʌ˹Re$fV; Ë€Ì%¢úÜš¦‰0¶#®LB¤Ë Ä›:JÉ-¤Ö¸è[‹2"$¤®f{ˆ¿P2ì¤?«ÉßèðNüV¯'£] I”z®éñ)Õw¢·‡j59û® ‘SfÞ„M>Jy 3o+Ùi<‡´îyJÙ¶t‘ƒÜbkÎO™0ZKï”Êd¨Ê&T²A:”ºÚMm‘™]Ä‘¥<&d[@q·`!ø­^NÿF‚t‡âµy;ýí¬E‹°îylÕê%ÄFÝJI2· ›Ö!¤û”Ÿt§”¥>égrIŽÞ¬7^¦â+™MT¬ºm8‰0ÝŒëk"#ʦÝJV“²’{H®FF†ûéÅjòwú0ì¤?«ÉßèÇ{€ì¤?«ÉßèÆ)ýâ[ʦ´ëj4- qÂRTGc##FÃ!ô0j¼cŒé¸OÄšƒ‘ Æ•4ò¡vS«9oåB ûT|ûlDf"RäNÆUÏ¥sËöáÎ ©±N­´–¤?¤!%˜!­hÚJ"2;¡[ ¸¾:/iF’:šqmn:KKÞ‰ ̆·ÌÜŽ³lÈЫp¤ÈÎÇÀdI«[ã^ÔÍÿŽøDP V,øOØôÈ@„÷|'ìzd @7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœ"I;ÞôÛœ#õ-ïGŒ³®yëf(P¬Å 7¨ZžŠ-¨\P¶¡…¨u…µ +P¡Cúð Å+1AŒ›«B“ŠŒR3®&/ðìoµè˜œˆ6øv7ÚôLmì;…Ú­áz¥MŠŠÑ> ¨B!œr4¾JmÇ;—3\”IeÓË—m’Dfg³U8©xF€gðV)Ä,SYAajB]’mç&ó­(Gsr¹šÔ”Úýû÷ŒcâR¦Tê/E¡BŸS$šÔS7M{¤ Õ—e®W2.3|Àðö3Jª="Lvi³z#jvKhaF¦PŸt¥‘ÒEr¹ŸýªQêÔ¢hꔹÐIâÌÖ鎦ó—f"¿óGˆš„jâÙ¸σ€‡º—…ëI§»'לƒ)ä¥* f§“cR‰£2²•‘*2ú øÃ00@=ð(µšƒ~&|¶\{s¡Æc-iS¹sd#"±«.ÛpÛhóÍ…2 Å›Di(2%2óf…¤Ï¼i=¤'"À ³øc0JSøz¬Ñ%…HQ®‰³I¶gåîJåupÈS„¨Ïâ,OM¡Ç7¹²PÉ­ †ÚLû¥å.Jn£Ú[öŒÇQ‹N­Ä’ëul=]a(ˆôƒIBZV”¥'g ”[%š3+¼F}û,<=_šËáÔäµ!+[+j"Ö—ƒ²Í&E´’fDf\ÂŒì~•TbœÝIúlÆ¡8¬É[ &”®"Q•ŒöÏÔ+‡E¬M€ìøt™òb3}kíGZÛE¸s(ŠÅüá‘à $Ú-ÿnéßÒÿ„±ÝØÇž,Å´ÉUiR[£R£¸äfàÔdDsî Ã[*B‰)k:JÊÛ®]Ëa_„t[þÝÓ¿¥ÿ cnÑêºAªÐªµx¸Æ±ª¦jõ­*¨ù8¼ä³î ö;%µ¨îeb+ímZýLóÆ®ÝýŽªLELE6[jÃÔìDºÓ ˘óòQ®)‡ÑÌÆ»¾ú]º–fzÇ.ed’²ô|ùh.Žª’ÛCå†QE•"1š’•nRekEÈŒÊ÷2¹ðprr©¤ðŠ12ña1-1PÙÕÖ¨Í+2Yí’í­7¿ O`óÊ­i6,ˆ±¤Õ±{Ë2(͹"JTñ™‘ Œî«™‘lã¸Iöœx¨ìß}l駈ÓX¨ÊÃty°ÍB‘ ús®¾´Ê}q”‰•¶‚$‘±}]Ï-‹ºVc˃¥á Xj¸þ.Òúd<<Õ]2zfbiÕ$¸©F²¯(’†Ò½Z“‘ IÝI.îå—NTq’)Í2õB·‹!¶ùfeoÊÙ8\i3=¿Ì=tJÖ1¨Ó¥ÔÒ-B™+Í2¥Ê¨K<ËpœRH‰¤¬øUïnðžqœœ\gn\‚jr4O%uv™«V+ G47X5¶h†Â‹r2âYÛq(,æ²#R^qj±ÚÂg£ %v…C•½,[³ôXåPzqCdЂ&JCäN;Ý%jºˆ­Ÿ)lIaMsHÏ"Kð1(Ÿ:œÍ.4™JdÒÝJ¹ØÈˆ&yˆŒ‰Er+5Kc8•1:ìÄéÔ¼¶í"cÍ:YLÊËFsÊ­›Ss±ì¹‡=Î.;;HõíŒù]_ó“ÞÐuíŒù]_ó“ÞО ®èã)ìí¡§ªµÜOt˜Ô½UjÑ›™,ŠZ*PC¦rž3Ê—_JìWµÔ’ÚGk•Œô7^ØÏ•Õÿ9=í‚ÑÛïIÑõ L—œy÷c¸·qF¥-Fû†j3=¦f{n<÷ìM¨‰™v³~.LÄC_i𷋦h›G›£š::éR5’œ«ÓV–ˆg˜Ò™£ààIŸxŒö'V·Æ¼©›ÿñ¸týñ)Œ>©Ñ1§ºµ¾5à}LßøïŽ»ËF€²ŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½§ ¦­ G•JäòR˜•Ê{©’–ŒÐ…!¹;MV¶Ãq²?÷Ò_Â+él/ðìoµè˜œŒ}Tf¥á³pÔÊdœy…éØU‡”ÜÊÌj”æÑÝ¥%dz’ãm¤ë›‰FgîF 2¯3¹D¥B–ºœz£ª¨ÁmµkÍ$„%»·îŒ¢xgrjÛkˆx6Ñ´(lÕ]Ætö¢5&Urš™ŠŽ“uÄ=¨’MšoÝVÃïY<;jj”Öf*<§¢³Y†­vE)3jA8y¸ j™#ýjEøHE6•*Ÿ>&‘؇.˜òdabe–hз:9´I"=¦zÂ4[å— U.‡[‡E¬PÊñë²Ê3¨‰Á!ÈÄn“ä÷YZ¥d2Ìd›ÚÛD(m3 è7‰ôIõV#Uõ®0i5:ÄRq¥%+.å4¾»NûÆ'·ˆËJ”J]Eª¢e*µT¨!d¼ÉY/X´Û’ G˜ËbLÏ€B@6‰•:nŒ±1î)ñÛMZyfl­$œˆ’KBÎÛ,µ4FGÀjI ³MK…3Ï©4ôU?Cˆ²¤¤Ð~²QGVelîsÇQy&ƒà°Öâì7Õ[2P†œS.%ÂC­’У#½”“Ø¢ã#Øa4‰Í6“‰iX3a‰ã¿•Rn“ye2?é“Ú¢"3#Qlî‹nÑÑÛ­±¤ 8ûÎ%¶›ªÅZÖ£±$‰Ô™™Ÿ¦£ˆŽDá£Ó)MÉ˺N"\Ìñæ$™¸µeNb#²lW"â!„8œ‰Ö Âx–!q©49í¼õ"§‘“dÍÓ-Èâò{¢#[ˆI•”j±\ÅË^FŒ°ú¡D¨rkÒ•4Òì뺸Ék)‘mQ©.’mÂiQˆ`'#hâXU©“Ji\)î6³-J-¤¦²¦ÏƒajIj#ù£-—DaºŠh3i4,E-áGBeÁ«6Ìx®¥%­5‘°­Oé3¨ÍJÛ|ÜCV‰J&“òŲi´zc´Â–…9 ¬µCA¼­Y2£Ê¬ª÷&yv‘È„\Z#H“h·ý»§KþÆÌÂÕæè”I&ƒJåo¤7Òˆò¼Ê’‡RgkXÉԤ˄É[8 k=ÿ·tïéÂXìš¾ÐÍ#ѰíF˜˜õ:Þ»{™T™fOjI&çtJÊ›Ó{Ìz,]¦ŒÅ^¼8_µUxš}M/Sr¡×"1âU©ŽÅ§æ7?Ñ£¦FrÍb#3S„g{\Ögn_¤Ö(ôŠ•,žÄ;êƒÄQjNÈ&]-ÎÓf¬æ¢RHÍjÌFd’Q~Œ¶˜Ü)ÀšV4<šbU](Q8¥&YÚ9-(5šóe#̤–[æÚGkmžÃz7äç÷Ù í:‹_»„iî~Îd‰XlðÄö'¹»%9V‰-,>k2u)D‚tÍI22¹©²;(”wÙÁrõSñ+0¨5„Â…K‰"\èkj"¡”¦I¶ÚKRJF²Ç™hÚg~èí²ä]#ØoFüœþû#¤Yš8Ѽ|qKÃ=ifÝôÙ“·FøÈ-^çv*2eÏ·6é½îVÉÀwÙiÔÛŸT¢4×#×|©V V‰O×’_:¬¹rm½[dKn9!D”‘ Šépˆ‹ƒˆˆÈXÆÓcTqr¡ ÍliU2¼¦Y§¤i\Œ¸GRvÑ¿'?¾Èé°Þù9ýöGHª·©DénO®ˆ®û èß“ŸßdtØoFüœþû#¤ã(í(á+ïD;£/‹l;ÿ¯ñœîÃz7äç÷Ù …½€j©i¦é¹B¦±"CàES¶Cî$ˆqÖ³¹‘ÔµÞ+yuWé»ôiìÕnfeù§ï‰LaõKþ‰=Õ­ñ¯êfÿÇ|Oô]€kÓq”q\ÚC4÷—221©æÉ™ #ŠE˜ø im2Ú\"Õ­ñ¯êfÿÇ|yiz¥£@J‰C©VTá@m“KF’[Ém†Òj¾R5¸¤¦çc±^çcâè†4¢§ M6¥*5­T¨¯-—‘˜••i3JŠår;ÒØ<à:Óõ£ÒdT¦O^¥„æQ!‡J3;éxLÌ‹m‹nÓ"”áÊÀ&:hÃ0–’ª˜z™›rÄKs™™©†Ö£ÚfvÌ£Ùs°‡ @Ðä)-ÓY¨­«E}çmy‹º[d…,­ÂV'·ƒnÎpÓz!ÐfƘ"jB÷3ÊBáYÅæV© 5lpˆ®jà°—v°a? ü'z`l²{X0Ÿ†þ½0v°a? ü'z`l²{X0Ÿ†þ½0v°a? ü'z`l®åu9à¸Î›nͲ¿òžéG–^€° HJ‘QÈË-©Ç¨|ì’+™Ø¿ÊpäàNXZ…kÔhô2t£O£³<õ—½ÜqËl5*ÝÊRV¹í#üJ¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<é›E¿íÝ;ú_ð–;[JxVn'Æôvâ%ØëcÔÕ¡«3n$Ò•Mv2”¢+æeG—…IB˂㈴y6;ÓåÔ$¦,T)dãÊB”H%!I#2IŒ®eÀF;;¶#E<¤þã'¢Œ™ƒñ”ZÔŠ‹DƒÅul3ˆVô膳k«§¦#)uI+PÊI9ˆŒõkU‹m°ÕJ wð®0k`ºÝ Ø¥|G©G\Ú‚ÛNç$¡I#}ä‘>Ju$¬ÚÄ–ew¥±)å'÷=vÄh§”ŸÜdô@)Ä8%ê~C::¤ïKõ!Wirc Ð‡'¥Q "ÞsO]o™-G˜Ë9ÜìvÑ©TÈø¹SðNŽq=¶pMU‰-= úqJ˜§!šÖ™$õêȲ7Òfjá%«!å“vÄh§”ŸÜdôAÛ¢žRq“ч`l+"³‹&R†š=«‡e&[Ôü'*ŠÛsPücaJ7ÜVµôfqIs*/eìy'ú]g'¯ÌLË(š¨ÅL€–Žíê›UŸŽ"}äæ/ÿ¶Û?¬`ëúqÐív‘"“PÄ’w,‚$ºQÑ::̈ÈìN4„¬ˆíc"2¹\ŽäfCÑOš§Áu¸ñc4–Ye¸I-¡%d¤‹U°ˆˆˆß©»b4SÊOî2z íˆÑO)?¸Éè€m‘©±´ ARÂS£ajáÑ+ªj¢Ê6uŠ[ýÊÒ´¨²Ÿ™Ë„¸Û¢žRq“Ñ }]Çz/©ÔߘΙ±-§[‰‰ "ËYÖ¥¨“ž”wR”}ÒŒöÚö""‰KËˆéØæSV,^«åV­È¥>ãˆC ¶ÜRÈvm&Ú˜øÌï·al+œ?«[ã^ÔÍÿŽøÖk:%¬ReÒªzpÇ’¡KeL¾Êã5e¡Ec/õ.!êŸÅØi[ Ïݱ¦!…¹©q»8Nº£M–’>'m­´D@ÕB_@ªÊ£JÒj ÈêЋôðYxû¶e_jÐgü±ÿêµ³*ñ”_©A¢Ê£1¸Î¥ëK°YuF¬¦’Q-h5$È”«eÌ£+˜š£0„–]x¨Ô¬'%ŠCÎÓMÉ'&˜Ó‰H”ûi%–^­‘ÊËW}F,KšÝE2•‹M›èq__;)O6•¨‰Ã,豨ÐY 6ËÇq©×êUT:d½Æ¨ÐMÇÉ–ÜBK1åÖ%³+©J23;¨ÍGsÚ/S±MrŸ ¨±e¶HfäÂ×¥ºÅÎÿ£qI5·´Ìû“-§q]¢FöæÃôlS,:tÕSq 1¡É“ §””šeŽêIæ#&Qܪé#ÚDG´z¦®Šìš*(´¶"É Ez¸©Ö&AÓ·Vd.Ù’^Ì„d›w„%šÕAªš"áJy/¼JŒÚœRÓîLœ4ç+\Ëb‹Ý+å*þþ¼«Ûó¾úÊ~ëÜ{‹6õÆÉ©Ë“.M^_qÜ^×ËÜß.Áe(øˆwå*«2ƒÔóQ®SÒK™N¤Ô%ÇI¦än7­ZJÝý¤Cò‰J]#ÅÂéÄ5Ú­:·‡%I˜äš£Î8—šr;dëNfÎɸ™ ØÙ¤ˆÛ#I$ÈfôW¹œÑÅ=‰¥¡iy+mv2Q«¹ fÂX[ :óÔXêeÇ[C&·¦»!Hi4´ƒujÕ¶W;!6IqîèÌ5ŽqJ—R¯»H‚’¥2ÜêìÉͽ!'žC¤RYSÈÑXÉHt»ãÉ2%sbuÐñ-zU"U/ Úê¨sžŒÁÎ}ró©;’œm³Žœ¨ré³ÒLÆÀ¡Sé4:S4ºZ[b#97Mgu(Ô£5(ÍJQ¨ÌÌÌÌÌÌÌÄ~vp<ÊM*”õ<Ó•4ø¨f ûFQI)N¡jBÉN·d&èpÔGm¤`!´)U= 7~+•Z.LM¬÷Ì\Oô¹zíc‹Èeœ›Ô&ÈUÑÝÒ{ÅÑÅVe{G˜n¹PA"eF“\„’lD㌥j+w¶™6&Á¸Kîmô†JÜìª:74Çc]•[3+Õ-9Ú;ÛUÓ³€HYTVYC,©–ÛBI(BLˆ’E°ˆ‹¼@5ž–Œ£M‘[¤¿Zg+F©6³jBI;[%%hȳÙešnV;æN¸QÒcCU ¾ Riråj8î¶ë ëµìî*ËVÃÈDF’.ëº3JvV"ÄŠbµ%†°æ#––ÔI×G§¨ÛY‘ò™™\¯r¿÷®V1Æ•YÕ¬3.™ bd<öLªrœ¢IYiQÞÆgÀ\B‹9ëªãÏé¿ö­ j6WTÿÇž"ÿÓíZÔ]TÌ«s`èÆŽË,Ó“©ÏlÍúlw•m\S¾e ÌŽë>ê÷±$¯d¤‹ò\Öèr)”¨´ZlØÏCŠûúøˆqÙJy´­DNgEF‚Èi¶^;Œ%Öhñ·=>KM œ7PkŒÛŠiÃ"#[jZLÛU‰;Rd{ ˆ…tìS\§Ãj,Ym’¹0µÆin±s¿èÜRMmí3>äËiÜShóbˆ,S1-R›Ãuˆ“aµ™ß2P³Ió‘ p™™™™™žÓ3xåÔµñMýä€Ð¿E„qô•Ä‚¨PMι^RrLk)¥jÙ$(õm¿¬6ו¤¤’„«1t_ÍÔºãhÑ<2RÒ“º6Ûþá¡#Â:<ÂRK/P¬ÆK+qÄG^#œôsRóg52ãêmFf£;šOi߇h~•SB4q‰Ý®UeÌÆ÷Ú,‰‹r:5ž”Z¶”f†uKi-–BMÉGšç´g±uºÆ/ÃøV»Qv iMÕ§:tiESÈaöQ³u&— Z™µ’LˆÖÙÚéØ3ÔL„¨µÇ+4èdÔµk2f˜ë1¬Vg5-)fÛ9Œ®­ZS~øü¨`¼%6˜Ý=Ø«m¦¦ÈžÓ‘ç¼ÃÍ>ûŽ8òÐëkK‰Î§\¹ˆ¬«ZÄD A•SÄë¸b«\ª¦ïî¾TI‹‹"nàšˆ¬fu£Jû¤,Ü<¦Y;v\„ãDÓæÔ0C+¨Krcñ¦Î‚R\±­ôG–ó ¸£.) ¥F}ó;‹• „¦ÐéÔeÃ(ñ)–Ü;Žc±]ÜšO#­-.&äfGewW;ÜfhðétzTj]1¨ñaElše–̉(Ipÿï¾'¤TÖÕ aaÇiíUµ&q=¥®9¬”ge’•Xø.G²÷²­”õ&«i^¹ƒñ,í#Q¨”6‹&Ÿ)šŒf[\’y¦ßRŠÍ6²<Æ”Øö™jÕ|·,Þ8XpÞŠRäÖitøÎ¸¦ã9%N–èÊv3A% Q&ÿÂQ$»Ü$vnƒ!„§É‘WŒôÈŸ¤¶—¤"CŠ,ÍÒƒZ”šTEÃu‹)(^sJ]VDZΪ¡椬Ù7T´!RPÙäÌÚr8•ÉV<Žl½ÎѺ`™A[Ž™-üCDŒÕM‚v)º·ˆÔyÔ… È›3I¥I25‘Ä£˜vk³çÅ”ìzziË4LzJŒ›eD¬¹O)(ÔfddD’3;ð˜Ð0à3µÌ4å*‰°ujdÈÓ$-˜Ån)NdJMk²YHi+*ʹìM¶ŒDäH÷P)r+Ufi‘VÒ{6U8fI+$Ôw±ðØ=‚t‡âµy;ý‹h·ý»§KþÇzi+=ƒÙ¢:Íê¶øÔŽ#²æWi1Ÿã©NSÖ)(Ž«6V5ØŽû 8Ó°NüV¯'£Á:CñZ¼þŒv£Øºq"žÒ£»O©Q¦UÓQ)M¡¦$|4¨¥fÍr±#¿{—’¤¬>;òª<„2L­[¢†¦Þp›mÔ%Ä­£Zˆµ‰#Ap™‘mÆÝ‚t‡âµy;ýüV‚ô‚’º©Š"ýl?ю╉(q–⨶kj Í5Ä jD—I†Ì’FdfN øˆŽædDf=uƒ4ÀpÈÌŒˆÌŒ¾ƒ8G°n?ñwà¿Ñ=KC8âŸL™Q• ;’]RêHÚ jÚ¤^É>þÞÑøÛM×UDÄø’U6z[K¤ÚàÊQ) àRT–Í*-†WIŒŒ¸Hȼ¸æ¢åA¬Hî¶QÇ^˜óMÈBÛR3Þ÷mdJBŒ‰7#"2±–Á)ÃGºK‘Z«3LжóÙ²©Ã2IY&£½ˆÏ€¸‡„I´[þÝÓ¿¥ÿ bÈJ{éÅjòwú0ì¤?«ÉßèÇeé+=ƒÙ¢:Íê¶øÔŽ#²æWi1Ÿã©NSÖ)(Ž«6V5ØŽûÒö.€œEH§´¨îÓêTi•tÔJAhi…ÅI*)Y³\¬HïÞäWØ'H~+W“¿Ñ‡`!ø­^NÿF;&¤¬>;òª<„2L­[¢†¦Þp›mÔ%Ä­£Zˆµ‰#Ap™‘m‰X’‡n!Ú‹f¶ª Ó\JÖ¤IthlÉ$fFd∈îfDF`8{°NüV¯'£Á:CñZ¼þŒw¸àŽÁ:CñZ¼þŒ;éÅjòwú1Þà‚;éÅjòwú0ì¤?«ÉßèÇ{€=iŽÇN2?ÖÃýv Çþ.üú1Ú˜ÆfàmrR ¶›[‹&[‹Q%$vJF¥ŸRFgÀDf5– ÓFÆ•ÔÑ0Æ$•Rž¦Ô鶈2’IBxT¥)²JKiÔes2.":å.vÆÇ¥œ žU|Yˆ#5+XÜd"§%6&É,ª4™–›l·ŒöAǼ·Ä¾uÚª×_ÑöŸ}պ늪-kZJRöÌÌÌøLϾ4°²Gv^Æ1]~‡Œ± æÒÍ lªr”²±$Ìì›ìî‹h‘õ•§þQâ-ì‰oPß¾Õ?Ý{ÿÛçFÇh™¤ZÖ—LT$Â’˜°f›Ù‘5ÒŠÄ—µ‹"Ò‰ 2MÏ1%f^äÈ rÿYZå(òÙÞÈu•§þQâ-쎟¤J+t4ÔªÉ~"Ý«T)±âÆaÙ¾q%<––ÙA¬ÈÉœçd™$•c3á<Œ|q…$CvkU¸çšiU|ÉIm1LÖZÌÆVØm¨>é6ÚEr¸rYZå(òÙÞÈ ÓùÏâr/øÙÞÈìXµXªó),?žd&ÚrB ²îlÕ²™žEl#¹Œír¿­ïz_û¦„jšÒuVs“êh“:[¶Ö?$¤¸âìDEu)³3±ÐD<½ƒ±÷‹ÿþŒu’t‰‡p [—Šªò©Ñd¾¶™u1_y¼å·)›hQ$Ì®dGk‘*×ÊvÂ6¦c:6¬aº¤Ét¹†3:Õ°ó {*ŒÎÄâRkI(‹i–d™^é;FRãzÝ:Mµ:‘4’R Èr3Ä•\‰hQ¥V>ù\Œy—Jß8³ë¹Ÿã¬F… ô kŒ©ðÚ…×¢Ee9ZeŠ‹¨B ˆ’J±Ð/öAǼ·Ä¾uÚ %ìƒyo‰|êÿ´qï-ñ/_ö„hI{ ãÞ[â_:¿íd{Ë|KçWý¡^È8÷–ø—ίûAÙòßùÕÿhF€ºµX«Öå&]f«:¥!&Òì¹ yd‚32IŒÎ×3;~³¬YðŸ±é î,øOØôÈ@€ož¡e¡½8­Ç”!4Y¦¥(ìDD‚ÚcC ¿Ô•N§Õ´ ý>©,ønÒÝÖG’Ò\mv[fWJˆÈìdGô‘ž„;Ç}©^3…ϧÖ1z+y§ôÍŽÝaÔ:Ú©4k) ##îçwÈDû`Ca4±ìƒ¡Ü;‡è;ë¼T*e+_©×n(³¬ËŸ.l„WµÎ×๊B_>g{¾s„I'{¾s„~¥½èññ–uÏ=lÅ ˜¡Cæõ SÑB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½bƒå9/–#U°Ô…)æÝ6TÖTå4©¤)iY+=îV24ðXï©ð¿Ã±¾×¢br1õQš×„åÊõ1ì[ù5~Ô‰0%ÔÔÊ‹^ó¬¾Ù:¢¶s"'P“3,ÆH½®vh]nÒÎdvët§ç-¶”Ìù”LjÝzÆÉ mJ32Õ™-M÷”V-†pÀm£d.±Ds`j“µúiµKÈSÜbžät4mJqîå¶Ú"²’²$å+™ÜÔI¹˜Šaùðþ;¥M\ægÄ><…¿.eZR´­YIÄ¥W+m"Ú\[F)ÀÉVàÓ`¥”Á­±TqyÃa‡†Ëf]®%&f{nYlV-§}™'Nœþ¢ÀߨmËMRK¯²¶Þ» º†•¨É³I‘jTfI5”›È£`'{WD“^Ò ¶«Ðͪ¢¨l¿þk–ÔŒ¥ú>äÉ-šO6RÌec4ÝEŽªmÈ)µÄÓÔÄXñåE8î-Õj[KdmRh<ÉBOºRlf}í¢&"œ }N­«‡q<ÇgÆ>¥\f{pMšÍR3YDŒœ2 ×QlB¿ðæ÷RgQ#W´}-Úô2j–„*y“/žç4KvFSýtf— %—1f#¹’l£mj6õ.‡W J®D‰¬ŸC2ÖËÊiÔ´™VRJ dg­I–d–Â;ØÅÙB«Ó ÃU}¸JK±¹Q]´–M底‘6KÊ¿Ò(*±l.èÄPh1Q£U%bRr³–Ìš\Zt%Liã7I—#Ùj&¼½Äs3ýk"+í2ÂáW`7DÄÍ˩LjôšrYŒÛˆuFòÊCNØQÆL®£"º“Þ¹”|h’b§J¦aHÑëPÖ¶`œyg«xŠ*•%×n»·Ý%â#É›jk÷&¬ÝZE:¹^ÆPâÏÖ@ŸP*«U¢¼¶šJV嵩É)´ƒIžS²ˆ¸Hî ÑO6)2©ó$CŸrëš_A‘Ü&‘'űaÀÀ˜~,Y»°Îtç”é4¦Ð¼ÈŒ’R dJ4wW2+šU³`ˆMJ¡>§(åԦɛ!EcvCªqf_JŒÌy„Äb€ 6‹Ûºwô¿á,}ÅTIUZîÆRÕ®äÙá™)HTQÈ‘b;«;è=¶+¶ÞÄ;°]º#‰Uv*¥6•™”»«5‘¤ÒdJ²¬{xlc¡ûm$r#÷©t6­WE³¥â*œVj1£áY˜z­MŽÉfÝÝž¸Æá ­”Ù-B–E˜ŒÃIR+zd`¬OŠ˜î0:$%•EŒš[Î:K9Ò–úhF¬ÈØo* 6[«º=ƒPöÚHäGïRè¶ÒG"?z—@há Wi¸¦‹\ªT >¥•*ólç³ÕC'‰ jäWl“)Ä÷V2&±l;lÚÏÁîÿºô1Ì=¶’9ûÔºä¬uQ¢­Nz?-Èϧ+ˆEhÛ5|®–Hì|WÚW#Ø nJÞ Öê4ª^“lºDƒ“×›%*;†VÌŸØv=™’…{¤¤Ê)¤õÜ]ÿÜi¿õPÓ}—°OòSÿæ½ù+L¸u4:Ì FŽ÷¹ú¥9ø ‘¿N;‘.¦ÆyTÝŽÇcïppˆ„´Ð“h·ý»§KþÄdep]º#‰Uv*¥6•™”»«5‘¤ÒdJ²¬{xlbÈ}ÅTIUZîÆRÕ®äÙá™)HTQÈ‘b;«;è=¶+¶ÞÄpª®‹gKÄU8¬ÔcG³0õZ›’ͺ!»=qÂA[)²Z…,‹1†’,¤VÕ]¶’9ûÔºí´‘ÈÞ¥ÐÛÒ0V'ÅLw‹Ê¢ÆM-ç%œƒiK}F´#Vdl7•›-ÕÝÁâÂ2®ÓqM¹T©@}J7*UæÙÏgª†OÕÈ®Ù&S‰î¬dL1bØvÕݶ’9ûÔºí´‘ÈÞ¥Ðê «Ûi#‘½K ÛIˆýê]ªʽ¶’9ûÔºí´‘ÈÞ¥Ðê «Ûi#‘½K ÛIˆýê]ˆÅþßóÿЄB‰†è4JV£H¤Ä….¯ ¤Ïu–É*á³+ö‹fe-^éJ3Ðø›ª ‹‰dµ"·£•Ë[I4·zóˆJHøl”¶EsÙsµÎÅÄCÙ{ÿ%?þa{ؘI§ß‹}ÿøŸøÍ2'ÚWÒiM¡S©ØoxâÑ÷FDn㓟\hQíRHÊÆ“ãáïX@Eê¡¿}ªº÷ÿ·½ÌäÅc™) *¯Yf§L“Ì݆ãp¢2‡6‘,œŽ£¶Ò4™ìR’8ÿB:Z-·/-U7d¬­ÚL’R¬—#-Z®}Ám¹wÆÌí´‘ÈÞ¥ÐÚ˜ãz$:%a£Ã³q9¥Kй/5ÖêwQšÕ)iR –ÔÈÖWàPµ+EåÀðå΀ëi“1x‰²B‰™“,¦­–ŠÇtëЄYVýœïXvÚHäGïRè¶ÒG"?z—@|h› Tð¥k©ìÔ'È•}ÐÙ¨ó0ÓHaŒÆdGŸTÒ®öu.×½Î`÷½/ýÓ¯Ûi#‘½K ‡Õg ÈÈðFÃÿü©t 7./¢Rq6£C®Aju:ffßaÒØ¢½Èî[HÈÈŒ”V22###"1Åq£Bo C‡¨Ñ˜­Ãi–ZA! ¡7$¥)-„DDDD\C?¦<ûî>þ‹–ë®(Öµ¯>¥)Fw334m3>ø®™ð„)¬L¢Ý[ì8—ZVÿºyT“¹»ÒïŠíK\i[ãG}w3üuˆÐÉbº®þâšµsQ¹÷ÆkÒõ9ójõ‹5åÍb½¯kØ®1¢Èb±gÀ~ǦB'¸³à ?cÓ!ºz~7×õ[þ’–§¨×ã}U¿é Dô!ÙÂ[£¯ãÿÑÿ˜D„·G_Çÿ£ÿ0¤uL¾sN÷…}6ç’N÷…}6çýK{Ñãã,ëžzÙŠ+1B‡Íê§¢… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&6}&†©°N|ª” \=i²‡¥›†N,ˆŒÒ”¶…¨ìJI™Úضíà ü;íz&6í%é‘p²^¨P›©ÐU5Ä6µ-HS227Ÿ*ÐwIšu~è'm„fGl}Wœ¼-JÂsØ©3 ¥A}/ÓÞ¨±!—MM:ËHuj2;\ô+MŒˆî[mÂ0aáÖW‡ñcR(RªPSP󤥥:i}“ÜÒ2¡JI'7vÒ“±_¸;ØxéÓñÑ*Õ÷eTž®cZÖú!™ºN8ÚÕ´ˆ––Ó˜¸3_i.é€3 ͨ;‰ôV!ôÖ$ÕõN>j4ºüSq¤¥K>f5>‹Ÿ JÇr!މPÄ«tÌF¹ §Åƒ%nGu6j©AêuiànîêÐYmrQ–Ò0Ü €$š,}øúJÃNGyÆVuH횣IšTâR¤Ü»Æ“22ï‘™ ´\Q]^©N:ƒÉ•§¨o$츸ܓZ2ÚÚOT‚²lV/ÖbffÄ‘X¶©PŒÒWVëz$è¤M‘š¤¸Äeºá'åVòïÞ2¿ \ê^fnµU›-u8õF“NœãŠ×šI S–sÝ!DÉ–ÞäղרCÅå¶ÁAiÔÉÍ!N-+g!–D‘$ҬܘÍEnö_ÖCfW+u9úHÆ92–º]ªæPïúSM>âHà%çBU›„Îûvˆ¬¹Ó[Ñöu¹’ä:¼ýÊ´ºdlYYýÏtf­ó3á1TÈÁ×)ÏÑëS©2TÚß…%Èî)³3I© 4™‘™ÚåÄCÆ6•jUn­¥Š³) >%Rr`±%kv2d^8ÍUt÷JJH“ß-œèîe²ÆV!f©=½$»5Ruçð¡.Iº£YH=æ',åýÙÒ•*÷2# ÓÔk Ù•ZoGó¤Uæ¿9èuHÇuõšÖÚjI­g´’fÒܺPÄ i’›A¦.AÐÛ©3¹¡’oâÈÐö_rfh²óðßmîV¤rKïÊ’ì™/8ûï,ÜqÇjRÔgsQ™í33Ûql\›E¿íÝ;ú_ð–;ª£ƒtwMTTÔcĆs$&,b~{ëÞQ¥´]e™fI3$–Ó±ñÑoûwNþ—ü%ŽßÓ& v«€©&ز± Èp‰F•ý“P2RL¶¥DdFJ-¤dF[H@È/à4Nj à2™o4·š`æ¸N-4’ÖIÏsJMÄ™l#ZoÂB÷c¬âï/{c]Uk8¥Œu¼èmRñ…WŽ#š¢ËP3vžq_"àºÔƒJ“ÞZEÜå3Å`7±& UJ ÂTç9:¶qdʫɨ4ëKeO±Ú(©Wv‡¹‰V$%Bp6×c¬âï/{aØëøŸûËÞØ×•ìYˆ±V®c\&äèÑbC¨ŒM¨jœM).»M×äJQL(æÒÉlYDös²2–’#I06¿c¬âï/{aØëøŸûËÞØÄèzžëÌÕñê½ftÇ«•˜­·&¢òØa†êO¡ ¡“V¬²“I"V\ÄWI'¹0"ްo‰ÿ¼½í‡c¬âï/{bVìuƒ|Oýåïlyê?ÁìFS©£íIÿ¬»·aÿâ1ã¬üïû§ÿC#_u±„üCýíßX‡ifŸ‰ipèM2láYÓ‰å¾ã‡Ÿ"’"QØ­Ýì{mk[oƒJ:0ħÓ*ô"âl9 N*Ñ"TžJi);-„’²¶áØ’{2íÏlÉ2sÙ#·ñ ÕBu^¡*c$IjCÒV·DfdIQÊÆf{8Ì~K­ÖfTY¨Ë«Ï‘5ƒJšì•©ÖÍ'r4¨ÎåcÚVˆF±!fªõYªõQº‹èÕ»-2Ü'œNÎåK¾c.å; ûÅÄ<îÕjR™¤»R˜å9…눧Ôl¶­½ÒQ|¤}Ò¶‘wÏŒxÀ1Ý>³X¨2Ã3êÓåµczBÖ–¿Ý#>çù‚©Y«ÕRÒj•YÓ‰¢³e&BÜÈ_«1‡„2Šåj³ªßŠÅB£©¾«uI[¹/kåÌgkدn"Žº±Fùo—\•Ý©ÔnÜæ·W|Ù3f¾[íµí}£ˆƪµFiORZ©LnœúõŽÄKê&\VÎéH¾S>å;L»ÅÄ$ô¼pšm:Q"Uô2Bšk}Ü8ZäXÉÓŽi>ë1¬K$ß½m‚4Ä€ $Ñ“¬³Ži«‘!ˆíæZMÇÝKhI›j"º”dDW2Úf;˲†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í è·e r×ùÑl;(hó–¸wÎŒ{cçHú-ÙCGœµÃ¾tcÛ æ7nEZC´ìk£vâ¬ÑH¬fs)®¬¦Esµì\µÏ„ø `uÝ~¸uªCôÉXóFˆeì¹”Ý^Ê+(”V¹™p—нQu]2WgÓ'FÝÏ«~3©qµÚ;DvRLÈìdeô‘|€¥Ôïð}F0bUqM…ªv¢Ê’&›NԚOaâÐ>‹vPÑç-pïöò†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í è·e r×ùÑl;(hó–¸wÎŒ{cçHú-ÙCGœµÃ¾tcÛÊ<å®ó£ØùÒ>‹vPÑç-pïöǃé+?GÝ/aELRLš)5vRÙìº*3±^ö"Ûk\¸KçÀ쮼dòçEþv?ha±jœí#TêxÓH}ü12xôê¢V·¤š’D•ÌÌî[‹`äà„äM:Ë8æš¹ŽÞe¤Ü}Ô¶„™¶¢+©FDEs-¦b6Pú-ÙCGœµÃ¾tcÛÊ<å®ó£ØùÒ>‹vPÑç-pïöò†9k‡|èǶ>t€¢Ý”4yË\;çF=°ì¡£ÎZáß:1í µë˜Ý¹iÓ±®Ûˆj³E"±™Ì¤Vº²™Î×±p^×>Á×ë‡Z¤?L•4h†^Ë™MÕ좲‰Ek™— qDN[ª.¡«¦JìúdèÓ¢;¹õoÆu.6»GhŽÊI™ŒŒ¾’1¯€ ¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëøÿôæ!-Ñ×ñÿèÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|õ çH‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'¡ÎÝþüÂ$%º:þ?ýù…#ªeóšw¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ1´hØj©V¦»QˆtôÅeâaÅÉ©G•j#RJÎ-'´‰V>þU[€í«°¿Ã±¾×¢crá–énàÚjÓ&Dc} W*_Q«U3a¥N ˆ­}·ïÍ»1õsŠ—†·F©Qiº„ro\Œí8‡Pën&öºVƒ4¨¯³a˜Ç‰ìª}.i`ê4 /»C•PZU5â$:N¸¶PêT‚¹#*RÙ‘fQwW¾Û¢kt‰ÌTâ*~[,Æyر鴹I’›I©%¬8é5seŠ2"3=†C˸k ´Ã] QaS©’hºÇ©ò¢j'¡ÍFc”‡q7ý)$—cF̶Ú0g-4 =Fv>!Ú‹.?!épÛ‘î^[dÑg#$‘ WM•Ýð𠊆2dÊ|éñÐÚØ€„9&ï!*JT²A(g™E™I#4‘Û1^×!ã©PãAs5­CNP¢H&HÌÉ“vDÞݽɬӷnÁí!¹u*^,vHÞøÔ×W5„Ó#¥•:Í’mš LÜRÙ;Ú宨eb´nà†PcaúmG|°¬)•Mt™EP¥­ã÷å ÚPÂÛmH½“•]×x‰#ñ´S)s±ŠbÓàLŒÕ.<¸äü5ZuOF+·®I8H-rȈìKN\Ä¢°nøF½Wr°ôwž…NжX&OqDDt»e)YÔ”'7uk‘ÄOšÝ Úm*%›2;У>ù¿;%O6•¨‰Ã,豨ÐY >çŽâÙà&¤üX¸¯I½—„Kܬœ‰ s™e³AK-’³¹Åÿ 0ıV)”Y¸…Ú=w@(КKTöÐÑ“†òÔúÚ"Õ©e•(¹¦ÖQl¹ŠÅBaa²‹;ળôÚrŸW83Üêl–ÉgÕd+“ÊNÂ"#EÊÇ´GðËd¼7‹ìV&©ìº‡ÂT¶œ)l +2Ì‹¥k#"2¹ÛØ­;„tâ¯XU3 agcQhºé4Õœ‰ÓY½’Kí¤Œ6ÌIBn²"YÜ®g°cq:CPjKSiÈ ÈŠÌcIêd:ËnkÏ·V“Z’ÂØA †…°å;ãvhµ6ó2ú”ÔY§PœÝÉ‘‰G²ã¤ûX0Ÿ†þ½0нL_4ÿ÷›ÿ¡Ó»ñSí>ßÍô™¾ýak÷nèVèÝ;‚ùõ—ͬϷ5ï›õ‰ÎÖ 'á¿„ïL¬Oà ޘIñN3ÇëôáÒ¢à׳*;ñžT™­¢yn¤–N[WéTIVU‘ì#IXÍWêøÝü5+ÖJ§ª™JÄLCœˆ¬fKK° ©—ug^%F‰¯¢RM,¬®‚AÉDFDv´Ž¦¼èÌÈ«2˲6c¡Âq*yd…,Ђ7»¥dBÕbÛd¨øÅîÖ 'á¿„ïL2‘k˜«WôSˆêGEE±Vzl(±Úq2c%T™Êm.-K4¸f…c$£*ŠÝÕîWpþ3Ò„ü=€êïõ¡ÿñ›m!¦QBw × ÉZÕ(Ý=jr2¿Ñ‘ ÈÔ’Îv5Ãv°a? ü'z`í`Â~øNôÂ_ÖÄtŠ%zeF/rì¶b­(":3ÓPû ZÔm8iZ[;©]Êœ+÷[<øã‰ð0g'ª1e LxžmØŽ* ²Ò£qn(–“K*#NTšMEÝ*ÆfŽÖ 'á¿„ïL¬Oà ޘoР»X0Ÿ†þ½0v°a? ü'za¿@‚í`Â~øNôÁÚÁ„ü7ðé†ý µƒ øoá;ÓkðßÂw¦ôh.Ö 'á¿„ïL¬Oà ޘoРWÔɃÙ"uÙ*q´¨³%)q&e}¤G­;뱎7Oçÿª/ù¿êCæ V,øOØôÈ@„÷|'ìzd @7OQ¯Æúþ«Ò@ÒÃtõüo¯ê·ý$ž„;8Ktuüú?ó–èëøÿô掩—ÎiÞð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÆÉb³=Š šj¸d¼—IÅiK5§bLœ4ç+™‘YJùJ¾¶ÂÿÆû^‰‰ÈÈÔùëCÝ­9ŠCô¦Ülâ>â]Rʤ¬¸…{,f“+–ùlÜU]— èKk#å•÷¤<ù^öqÔ¤–½¤GÝÜay± fÜÅuç)‰§.bÒc”b^æk\L‘X›ÖåÖd¶Ì¹­mœÍ#U©qN,W˜SÍÄ·"+O¥ 2"5 œJ²+amMaq P ecb´tURtêÈ4M\ˆí¼·K6ot´š’y¬«¤È HÊÃ5j‹4WèÍÊR`Hu/:ÍŠÊZxö¹}v;ø Þ @ÊÒ1R—ãÅv:ÙÎkKrb5!(QØI'¢J¶Ò±ì.!v*­Â“P‡ãHv¥b–©Ù’n‘+5Z…X³‹¾”ü’¶i‡q-:$y5 ³OÆÍÜ¢gÎÆ£;2òìä}‡üÛn¢á°…€LdHOU›­VêQQY}NÊmøLÉI‘¸neý*³5ŽÅkšRgÀVÅÑ곩2ô’ƒqBÛK¸›‘åRF•ÈŽÆG´ˆx€1!Q­TçÎfl‰FOG"&5HKIdˆîD„ ‰(+™žÂ-§q‘‘Œñ ìLaÉ1 ©¬›RŠ|t“ÄfJÌ¢$ÖF’2Y÷D{HÈgðþˆq•z’ÅN—c<„¬”Ûn¯.d’¬f”ØËeÇ¿°NüV¯'£ @ÀMÅÛ–A§Ñe8ᆦ¤·:šÂÛC¦óŽçhÖk±þ”ÓšÉ;!'ß²pk•hÒ§ÊjjÍú‹.1-Å‘-N¡ÃºÈÍD{NÜ%·õ‰÷`!ø­^NÿF‚t‡âµy;ýˆˆ¦3"ÒÅ<ÌìDmÜÿ§hv'c¬ »wFâ{U¯Ý‹|änflù·.³Q|Ý׸áÚ9‘¡Ý+QæÚB'SåM$ôR’ÒÈ„³%²; ÏYZå(òÙÞȑֳpæ™OÄ4ù1›\lGŸ}‘º[£4tGVÒUÑv›B{›p_„ÌÇáa¼4U¥Öw+jš¹§=KSëRwF¡¸ú܆¬¤¢i¤ ŽÛ 5¬jQŸ%õ•§þQâ-ì‡YZå(òÙÞÈdv ŸI£Gz=1 Æe××!M¥Ó4Öy–i#;$ŒîvMŠægk™ˆíGX‘V§Õ Áu)Ž-Êy9SëPó6¶Ô–Z[††ÐhqE‘)$ðlºSn`ë+Oü£Å[;Ù²´ÿÊ4fÑdÞ”n…žçËqÓ´ÕuÙ§žêü7á"1É]eiÿ”x£Ëg{!ÖVŸùGŠ<¶w²kÖæß}öÜÍîÝòßMfè_úÖäÜzËf·¼wm—¿lÛBÃéøzŸ3h‡2oJ7BÏs厸éÚjºìÓ‹Ou~ð‘䮲´ÿʳIUWœ¸ïÀ§ÖZ[iLF’áÅ#ÛÉ$¤Ô’Q¬“Â[ÿ¨^ݸUf±JbUiµ?-‰sÄiÂV¥—SݨœN\ëyG°•”’[Vf'˜óU¨t†¨Ój”ŠÛõ¢Ìµu´¼Êܾՙ’’¦–ƒM­°Œ”w±†‰Ù6¡N7T€©Ž-öue·Ríì¥fJu+Vm†eü=‚Þ¨R“F¨Ñk ˜ÌyO1!Åi.­4N$ˆÐ¥$ŒŒWðŠÆEÂ2²ñ‰}ÚcÖÔ {ôél¾” ÜiŽ™HY(û¥%õì4÷&EµAÍ lÊNM5ª„Oþ"™Êª¥œŠÕéGæ²Ô”F‡â BÖ•©VZÉI2m{nG³ƒhÇUisé{—w1©Ýq‘)Ží*ÎÒï•[ í{ÃÚ2§RÛÀÕ*[¯L*Œ‰Ñä4”ÇI³•¤:›)yÉDg®QìIû‚ù]Î>«½_è»×»Õ‘º·N_ÛŸ&_àpZûxn&2;A8ŽU'Ft*E"”UZÍIF¨Ñ×#PÒ[j;Ç\s*(I­´ìJŒÍi".)ìêþ)j«ƒcTéñèÏT1°¦3Reµ!„Óe¾“CŠBTE¬iµ(UÐeîOn»Ðe±#aÜK‡ê´Ä9sÎZ̘ï±ÜA­ R›VfZQ+*½É•¶Ü¶SÔ|UYŸ…ªU¶è±¤VÝœëä:êR IŽ”¥Å!&âõ’ŒÍ(,·ï—uhú.:ÂÕŠÙÑéÕ»(ÍÂiJˆòmœ&^R ·'ÂM©VÛqMazÕ]ªU>|…¾ú¸Ër í1))+™°òÐM¼D[F¥lÛÁ´B4q¢Ú†­PÛ”†¦@ ç(s]Ä•) Q+e&PœVçeydf“QXÕ•)¹e±†tuŽXƘ^µ^©±/yæ<üÙJÄäìñ$2KDE¤£Ç<Τò ŽÅr%‘”\+¤¬Š%AEª>ùÔY7 ¸å>C-JI'1“n8ÚPµ\Í)3Rlw"±ÚDõR5È´GË>\g¥0ÖEwm2¦’â¯k”ûEc;žm—±Ú‡°MR…´[KuøFöÔîõ!jÊæJdˆŠÕw7;¸òOº$÷$gÃb<Ž2£â5âº.(Ã-R¥Jd¢T$¹5!qÖkKˆmÃ%%Q‘°Óc%ÒûSÒN§®#oÔ¤¸ôÇf³˜Ôé2ypÞ&d¥(mµ(ò8v=›HEt‘˜‘Q*”úÕ&5V•)¹p¥6N2ò8GûHûÆG´ŒŒŒiº}áÌm„"GF¨W7)%>ëœDšœGˆ²mjB‹\Ž+I¾ÒPÚ:=¡IøUšlÙ ¿1R$Ë’¶Rio]!÷q(#Û”ê‰7Ûb l%¤ªT=`Úž-ª¼åV©‡¢Te)ˆ¼®é”)ÇÜK2i¼Ê;¨É(/Õa$Äë P—5 ’Œå0r[ܱ]’DÁZï,ÚJµmm/Ò*Éýb‡°F6”Š!P•‡fÏo ÓèÍêiÈ©^Wš4¶£q&o9t(‘˜‰ÒvŒv"aZ(j–ô:æKJÃQ¨Fu·ÜdÕ¸³êÜh…ë\V½wbé5ز«a€¿?J'c ¯SñNŸ@§áVklÈërCðäìÉtž½Q(šCm6´¥4k^v󒤦1jPÆÏb*¢ 2¾Ä(K·2®Ÿ Òim&·Tn<á‘)]Õ‹a; èëHÑ4êS‡$ʾ)˜q¶¤)I6%´Äį[dG%r¹÷*Ù°¯˜ÅÚ7©Ö­Lj[I}ÜNÍrmÔ$ÄΔSY„¦ÜyŒ®4g•Ó#A«ø##R@JWð¢0ûU³¨HTge$4˜(ä›;˜‘®Ö%FhÉr"3µ¶ŒÝ© µKf¥OqÇ#=›)¸ÒÚYTiRT…‘)*####"22;pÖj à·á õEúÁT–ÌŒIRuD¢a,’ÓPYét’’"RPE–éË´ÔsmÓ+|# ^¨o…A£pÜ{\·l•8¥!ÅÙNdA¥ÔD¥eÌ{LÀ`XÒ–N¦nêÓ³¥Ê£Æ«éôYj'#µ; Y£ÎfdVJLÎÖ;gcšV-ïÖ4Ã(÷[͸£ý*N±—MJJHÒ¶M\®E˜Ós4˜´î’ðk[K©JÕ>Û.åM’l°N¥*o^á7‘ƒ4­gMD¢3"¸ÄbI“*Ÿ¿úsTjã)D§ ´²SinÄdjÊo4w2î_QÞé"<—´sŽ1j±$:uJ: ÔáãwO„Ü °HSj‹:·ÉK̬Î(ìK±¡D›lXøÏIÅÒ°¤i2Ÿ«Cp›”ÛP[qÔl¥äë$jÐJB’djQŸrWQžÒ1Tª•šÕ]öé˜uœ=O©ÆCŠ%Pôª‚ ìÄ’Q›±ÉlgdÜÌÍ^ŒKG®Ñðö‘¥Óº'â)¨U0¢¡Kq£rHiRÈ‹fGZÎ×"A\̶ÚÕsG2žz¦šDˆqcoM5-æQ!êl¹R—EïjÎÒv³ì+ÂIaYtJ•a5%Ç‹Lÿ^)‘Œô{‘s4êáf#,½Ïu}—0¦4ø¢tèyRU2žÛ.K& ñ]a.šÉ¼Èy QfÕ¬ík؈øFpÚîÄ5 ^'Äxú=2¦ûtçc±ÇeFe4çÕ)³qfÚæw¢VT’lE˜Ëm«OÄÚCÅø™ç(’!»O¦Aeú4¥JŠkeRÖ´êB5ª-z Ì’DYÉ<)3µ€‰ÿê‹þoúù€>ŸÏÿT_óԇ̬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëøÿôæ!-Ñ×ñÿèÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|õ çH7¾:¡Õ‚°”Z 8MRÍ¢NwޤH%¨”Ü“©;’[.}ñ%í´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0Ó¶’9ûÔºí´‘ÈÞ¥Ðc9Ûi#‘½K ÛIˆýê]æ0ÓNuX¼â À÷Ið–ú—B9”+|'ìzd B{‹>“ö=2 §¨×ã}U¿é iaºz~7×õ[þ’OBœ%º:þ?ýù„HKtuüú?ó GTËç4ïxWÐ#np‰$ïxWÐ#npÔ·½>2ι筘¡B³(|Þ¡jz(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ19Ÿ=hyÒuW­ÊTJ5*uJBn)¨‘ÖòÉdF£$‘®dWýdÂKØûò#ù©ÿd;cÞDb_5?쀒ö>ǼˆÄ¾jÙÇØ÷‘—ÍOû #@$½±ï"1/šŸöC±ö=äF%óSþÈÐ /cì{ÈŒKæ§ýì}y‰|Ôÿ²4KØûò#ù©ÿd;cÞDb_5?쀒ö>ǼˆÄ¾jÙÇØ÷‘—ÍOû #@$½±ï"1/šŸöE©xÄŠì¹x?ÇŽÊã®»My(mW5(Í6""+™˜ø V,øOØôÈ@„÷|'ìzd @7OQ¯Æúþ«Ò@ÒÃtõüo¯ê·ý$ž„;8Ktuüú?ó–èëøÿô掩—ÎiÞð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>zÐ󤳨ÜÌ´•V2;Pž±ÿLÀÒcvu|dÕþ¢{üfHê={ß<çÞ1ä¥VªÅ\˜y¤Hz2•Ý&Î2êšq6;p- +ð®W+¾5å¶æ‡S¢Ï WäM*­BT]ÇLyö¤¢D§_nΡ&ÚÎ’O:“c#ïmY<£V¬QáUéÓ~èíÉŽïtœí­$¤ªÊ±•ÈÈìdF=z÷¾yϼcŸX Ñéu¸´L]…ç×dS°- ’‰©\´²êÖf“Ê験ewI¾ÜýJ’ò\¤uÿA©b%# ÅŽÁÅŠ¹Zš’sî…]z§vr¼yH²+º.ølÜ_{a . Èä]ó§±3S­5êµ­¥ysX¯lÖ½Šöà!ëj°Ëµ‰4„LpæÆŽÔ—šî»–ÝS‰B¯Àw6\+ܲíµÊú"M"rð† ¥Tpš[R Däì=*¦hMå[)m6˜®&É3qf“<ÄW,›$4£´Æ1¢×1wjN”EQv’¥8ÜÖÛR‰×²¥ÃBšAç4šˆ‰;lDn-{ß<çÞ0×½óÎ}ã3E´ Ü,]GzªFÅaƒ{~g HeS M¬]9o©§‘¬Ê´åIÉ$IA\ŠqŒpÌE¤Œ:uŠ:*T¸ôŠ–±/³¬­S°²%de”ÌÈœ2J¸r‘w7 ëÞùç>ñ†½ïžsïÑP+e¤uÉžFÕK® ÐÌÆ°Ô‡ŸT-uÒÞï'É”5©²…$­ÝY U”rœ |m5ÊÆ¨/*¥-ÆêÇ Å4q¥›))ÈH&´j¯|å|¿Â¶V½ïžsïkÞùç>ñ3£ÚC‘«˜`ÙÃõ88†.»®ª‹Ñm.ÊÒ«¼¢Ë#3æÚєՕ)?sÀ,Ѱt*FˆðY;…žSjn˜¢#pÔ¹R›LU–G["Ö:M¼´¶dvJTD›l6µ ¾õN©^…‘Æ·¢ ˆyõ¦­nhÌ?šÖ,¾ÿ–Û}Íï¶ÅÓ܉Œêh×»•m8•§9ÙEªYØøö‘󳡈,ÂN,8TIÔzlŠöº yQ–Á›[Ž*s! "4£2TD›[e±L‹÷OŸÕü·?Áp=iqŠ€‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'¡ÎÝþüÂ$%º:þ?ýù…#ªeóšw¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<éËêvÆ\‹jµjÛÊm§iÇd’Ú”kuN´džäŽÅd¨î|]ó±´YÙû ñ‹Ñgì'Åþ/D9LvÂrê´Ùš¬I«¡‹M“¨Ï;îé¶”â›jìV7œ;‘\óm½ŠÞ¾ÏØO‹ü^ˆr˜Ø2êÎÏØO‹ü^ˆ;?a>/ñz!Ê``Ë«;?a>/ñz ìý„ø¿Åè‡)€mƒ.¬ìý„ø¿Å胳öâÿ¢¦¶ º³³öâÿ¢ÏØO‹ü^ˆr˜Ø2êÎÏØO‹ü^ˆFô“¥ì1‰°„ÚTwuO-§5}ˇ™FÚ’EµEµ\7îvÁ ¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH=vp–èëøÿôæ!-Ñ×ñÿèÿÌ)S/œÓ½á_@¹Â$“½á_@¹Â?RÞôxøË:çž¶b… ÌP¡óz…©è¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âa‘ÂÿÆû^‰‰Èƒa‡c}¯DÄädj|õ çH‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'¡ÎÝþüÂ$%º:þ?ýù…#ªeóšw¼+è·8D’w¼+è·8Gê[Þg\óÖÌP¡YŠ>oPµ=([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOž´<é{JÁX§ÔÚp>2+pÒYâÿtpHú'Pÿ\_óÐ…jL#½g`ŽCao4³ì‡YØ#Ø[Í,û";ŒètJþ”ðÔ:õ"ŸTŒÝªêZ›!+'éäJ"QØÌ¯Ã´ÄnlÇ臉)ئ˜”öªH±Ö’) Ó"jZ’Ò«‘'T¦LÐVÊn–S1^ccu‚9 …¼Òϲg`ŽCao4³ìˆ]êë5çð÷_Ri¨¦Ñ“Q:„ˆÑMÉk[¯ë VH&š&ÐFHJUgu_iâ£b´¨Å…å}ÕH֚ԙꓑ¢+¹²“¶óÌl³°G!°·šYöC¬ìÈl-æ–}‘ƒ­â:©è*v.e;ßVëeÊ’•¹ßܦáU‘åWxÈø6Œ>1Ÿ‹hRèT*µÊ¬Šª¤¾ü¸LS›}³m-Y†Iü Ö¥wZÇ,“ÚesLsN³°G!°·šYöC¬ìÈl-æ–}‘ \Å5V0½}Tèê¨*TÆS×–¨Î¥¶Û-®²—•Š"Í—V´•¬vôÖªU‰UÅR˜ÆRƒ@f¥»ÛŽÂ“9kS‰RÏXJ"iÒTd‹鋺-—s®³°G!°·šYöG’uGe@+afݨH8ÑS¼í±ÂiÇM7$ìîYÜì]͸Lˆã¸R­‰qN'„ëµyxIÔš«ôö#²f·ä.I¸Ú–â¢Eš$™•°¬¤ï¤ÔjµzÖŒk•,LR•V¨È”ªN¥¤¦"÷º]ÐÙ¥$¿Ñæ6לÔf£/sÀÆËë;r y¥Ÿdq¶•Í“ÒP㇠£Sf–"0–šl´lJRV"ÿ¯ ÜöŽã5¥/öî£ýøH¦IFEÈÍ¡é-4ãíÇBÖIS®-‘žÕR5X¸vŸ¶ÈL:ÅG\}nõ߇÷Óvn-FIžýŸ&\ÛŸ/ºÙ{ÛõˆxظÚtzŽ<Äøz¥ª¥Pª;4´:é=­9i2WéSdjÊi<¤‹g=¤WIãðªë“ P’J…5¹Qš7”M¡µ¨áÚöîT¤/õ¸}óЧ”¡@6‹x‰ªÄÜI^v±XjDSŸ)† T–!–r5wh32o2ÉW»‡òÌÅtÉfxßÔØ›X~dŠ¢[]BdtFvK&ëi±’Z–]Ó‰5ªÙˆòíÊvoý†« ¶ÃÓ˜jTÍn%.½×«IYKiضظD®n§\ÃXš5NRäF‹¹1XQþŽ2÷[ þ‰<,Ž,¬›Œx´Xûñô•†œŽóŒ¬ê‘Û5!F“4©Ä¥I¹w&deß#2žR‡†…D]Q‰¨Á¦Ä޶ÚrD³^B[™ ²¥\É > $îd<îAb=}TÙUû©FócÝæ²’ò›¨µi·tVá!! VjôíV›§ÕgCAÕ¡$ÒÄ…¶FKfVr±ð²"üyS~M>ü}%a§#¼ã+:¤vÍHQ¤Í*q)Rn]ãI™wÈ̃3ÌaÙ§>íUY*l˜%˜ëI™æ5:—T“"µ­fU}½òáÛoO“„»÷Y¯·5ï{í¸˜žr/W)ÏÑëS©2TÚß…%Èî)³3I© 4™‘™ÚåÄCÆ6•r·SŸ¤ŒaC“)k¥Ú®eÿ¡%4Óî!dŽ^t%Y¸Lï·hÅa‡&Q°ý9}qÖ)èª:·˜b—MKæí–mš\Q¸Þm¨ØÙšŠÇ{mµŠ¹s 0Œ¨˜ƒ"¨Ò¢F¬ntT©‰I¹ µ¯’Ë™'«Y'i¤ÊÆÚKmÈŽ'¤]××t¥N\WSL(ÜŽÑ´—ÙA¥fƒÚ•¨Œ”¢ùF¡1VdGÆAºSŽaÇ«h•Ûbcq\cºÖ¤ÜBÖ…ûœ¦“Õ¬½Õî[JÆF$°ªÊE+ =)•Ì'7Fæ#»òI多]½ÙdÑä;—vgm¦,ÔÜ}Ü1ŠÝ•4g׈¢)Öc[TÚ®”X̲‘ì+ì¶Ó  gdn¶ó½Ö®».ä·ú6÷Ûßòû›êû½g öÞã Þ!­S4iEM>§**ÓUž†ÝiÓK ›Š¬ˆQmJMKR%b3Úb7H…ÙqʱÅFt…:̳Ãñg0¸Ñû…%Èñ–ãˆhÔ’5Yo/„­cQm [ɪ³C˜•Vq<½üa˜îUbµ^G|Ñó›ËRÈÌ›áîQs¹–m­ãZŸcy³gá7\:¬ÚŒFªˆmHªÆÉ.š·,ÚJ4›fDyˆ­cJ;”ßlR¾†Ó½úº+Ô«ÂlÕ¬ZÕºmßNb+%]â-›6 ‰È»„påCU·²™ª993¥+ÍÝwIIHÌÌÍE²ÂoØ'H~+W“¿Ñ‡SÆÍ?ýæÿÇhw¸‘ó;Ð*8^¿"‡UB2:[S‰I™‘Е§„ˆïeÃ-ƒ6WTÿÇž"ÿÓíZÔH V,øOØôÈ@„÷|'ìzd @7OQ¯Æúþ«Ò@ÒÃtõüo¯ê·ý$ž„;8Ktuüú?ó–èëøÿô掩—ÎiÞð¯ FÜáIÞð¯ FÜá©oz<|esÏ[1B…f(Pù½BÔôP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>zÐó¤÷[ÄÔ8µWã½=$ãj$¬’…(ˆìW+‘\¿`à@1‘Û8‚FŽñ°x‚ŸI«î|ÚÝM×ê³[6\è;_*onô3VÁ Óš¦²Ü&á2´8ÔtA2i BÉhRRI±T’Qp–Ò<6§.Ý­T0lØ:ÔjuKs«;®žoj•ÆœÈ;ÂÚC=Œ TŲëÕ“§Õì(‘™.˜n“ aÉ Ö$Ô“Ú{¢Û­“„ï³€6™wLÌI…fÃzÉ ÉŠûjiæ]Œµ¡Ä(¬¤©&›‘‘ð‹š¾ ­A85”B©DQ’‰pÖÌË€ò©&C‡@6™vÜÉz>™Gj..E1«já»NÎÂ-Ád2•¾€ªËÑõU¨­U!Rç7 Èã&M;XLZÙ H<¼ÁÄ8i—t£aTLrb$2™.¶†œx£,–´ ÔhI«-ֳ̈"ïfWŒ|y;VU^=>’ÍIn›Ê–ŠnW”á¥I5šÉ³eZŠ÷½”eß1ÄÀL»¿®ì=ãÁsÙm¥/öî£ýøH€#>üY-IŒóŒ>ÊÉÆÜmF•!Dw%–Ò2=·ÀJ¾1¯,1œžö†$©PÝ7bIz;ŠB›54³IšTFJM˼dfF]ò1db _2d H—Sñ$#Ü:ˆ…§è2ÚCÕ¿µ½÷Mc~j;ä’2LÍÒ½q\ŒŽË¾n2áà1Ž8k•¦w~¦±Po|o»²ÉYn«ÞúͽÝó+Ý_ÝóÓ§M¦Ìnm:dˆr›¾G˜tÛZnFGe‘•È̾ƒp £x·dfëÕD15kr[i–á&B–VZ–W²E°Ìï~øñÓ§M¦Ìnm:dˆr›¾G˜tÛZnFGe‘•È̾ƒpˆuÚÜ)Ò'C¬TcË’fo¾Ô•¡ÇLÎæjQÕsÛ´y“%‰ˆ˜Ì‡[’Û„êBÌ–•‘Ü”J-¤wÛqhàeÄx…š«Õf«ÕFê/£Vì´Ëpžq;;•.ùŒ»”ì3ïµ·Y ØPjõ±^¾µ–d­]öwI#±ÿ8ðŒ@Ê7ˆñ u7jתˆžñ]”™n®—{ˆˆ¶ŸxcŸyÙ­÷Ý[®¸£RÖµ”£>3>`{iµŠµ1§š¦Õ'Bmò³©!M“…Ä¢I•ÿœ~5Uª5Jz’ÕJctç׬v"_Q2â¶wJEò™÷)ÚeÞ.!ãÀ÷ïÕgz·§}§ï‚î…êxoî/oØ(v«Tz”Í%Ú”Ç)Ì/XÔE>£eµmî’‹å#î•´‹¾|cÆïŸ[¬Ô'µPŸWŸ.c$IjCòV·DfdD£;•ŒÌöq˜¦§X«U$7&¥T5öÊÈrD…8¤ý£3!âÄuV³W«j·Ö«:~¨¬Þé·2f3°óÊ—*^«uIyýKDÓZÇ Y\ Mø]â-‚È ÀÊá\EWÂõdÕhr“b•.)”:DW#÷+#+܈ïm–^ÎúVåWîøÝÖ %Š+Õ\M]‘\®JÝu 9uÏjÒŒÙRHOr’".å$[ ¼1 ‹>“ö=2!=ÅŸIû™ ëÔ;©zn6^Ï«:L¥C">ä’®#â(ož¡e¡½8­Ç”!4Y¦¥(ìDD‚Úb$‡nïm/ææséö­ÕušCÅ8y–5q)Ôút„-kÌâÖò¥®dDYHšEŠ×¾m§r"Ö5íhÒ³¥(¸ö[ðŽCEødê5_#,ެ¯Â[n\ <¦|šs¢·šLØíÖC­ª“F²¢2>îw|…a-„´.Î,¢.®Ìº$ë2;qܧJyIK2]dŒÖSFfMßbK„{Ï©ž)ðÕhh™ùñ³´ñx­ª¿þ£$athReâsåRqŒ‡[«4U'k¦ªq!ä6„îc•À”¥-‘j6(ˆËaf~;å9ŒN¦¼ï«î¬ÑLú®ÖXž5 y¦gçÇçk$?P<Ó3óã;WÒ–$6–ˆ.Óg1V’qÛ\l5Ty¨ÝœÎÛÉ,³K+j+6H3¹+bIFYö1–-™O£Ç‰ ,z„Úúég&¡J•§YL7dkÛaÓK¥î 9ĽҲ%m%9ò¶¾z߯ꟺvÓÙ¯fõ6Ò¡C~dÚæ†ÔëÏ;L˜„6„•Ô¥(çØˆˆŒÌÏ€]íbƒã:šfþ|J´­VÅ“°?…êå£R‡P7#8—%º¸IuŵúC&RIy9R­a™‘‘¨¸Fz^$¨±Z¬Ré©1ê±;T¶$¸Â²ý˜Ì•<ù%Dn,• ¬i¹%´Ü­qIò޲zݫꟹ¶;5·kÐ<Ó7óãðú—éþ2 yªoçÆâÑýb·S{B¯ïqʤUw ‚…¡£sGx”d¥(ÉFoËìØ[ms”Žs­ÔÏ[•2œCœûW©Þ2 yªoçÇçjå;ÆT5MüøèÐMéë\ÿ2båÚ¹MñÍS>?;Véž1 yªoçÇG¬Þ¹?Ý?ɇ;Eêbƒô¾ÅN€‡{ôÍ;\­ßž=ݯ ñÝÌÒÿ<7Ø MUOYµá~; yš_烵á~; yš_ç†û”´'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌ Úð¿Ð<Í/óÁÚð¿Ð<Í/óÃ}€fF„íx_Žèf—ùàíx_Žèf—ùá¾À3#Bv¼/Çt3Küðv¼/Çt3Küðß`‘¡;^㺙¥þx;^㺙¥þxo° ÈЯ ñÝÌÒÿ<¯ ñÝÌÒÿ<7ØdhN×…øîæiž×…øîæižì24'kÂüw@ó4¿ÏkÂüw@ó4¿Ï ö™µá~; yš_烵á~; yš_ç†ûÌŽ—Ôà‰QÕEf€¶ÕlÉÞye{ûÓ†?µb•ã šæþ|t€dsjÅ+Æ5Íüøv¬R¼a@ó\ßÏŽÌŽoíX¥xÂæ¹¿ŸÕŠWŒ(k›ùñÒ‘Íý«¯P<×7óáÚ±Jñ…Ís>:@29¿µb•ã šæþ|;V)^0 y®oçÇHfG7ö¬R¼a@ó\ßχjÅ+Æ5Íüøé Èæ½Nøf·‰ñ\JKtªt-eTÖQ*<É.¸Ia—3©i–Ù_ô¶±'¼3=SðŒé.Á©áGyD†¤aYjÍIY›r[‰#Ì„™ˆöl>²ð¬…C«iRZLbi&üL§ÿÈzêsdD¡™Å¦Ë[féGaÕ$­)õXˆ®]õ)DW;\ïkØÇ‡[«®Æ"Šs2Î×ëjÓâ(§3(=7FeQJÕ ý:h;-=Ž#¥HâÌ“xŒ¿œ†ÌÐæ™‡÷Öõ -Ñ©ÿg°Ôjf|¹ý÷kšËfîx2Ý\9¶Dë*†ñ… =Å;)‡X‰=üê2ã«J]Øg±$j¹pHnl%ügìó=點±Ê]ô׿í3˜ç¥ªtñx­ª¿þ£$KiTèT¨«KKô•'1ªî<êqW3>­Gn½ŠÅblJ¦F¤G¦Ãe+Ї”M°”’–²Îµ‹j”¥)F|&ff{Lfw?c›!ÛKPGÑÞqÛ¦½ª4’ZB§>¢ŒD¢QYê,dGú,¼ÄC!O´8)„LÆ}k…1SYuùo<æ½L­“Z–µ–zµ©=ÑžËq¶~â‡àŒsdŠ‚1Íœ IŠ0ÄÏIv³Nuó–É1) Ìy”HA‘kÚÒ•šnyMDf–2±ÜQ…aN¤Ué“¥µ9zùO2J}m²Y:ÙçeZ¶’’R8 ¯c¹ßmn(~Ç6A¸¡ø#ٟц{ Òê)’–“R¨.sÍ1!ÇÐÚ¶Û"ֻݸyZI©j"3Q¨ì%‚i¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c›!°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ0!`&›Š‚1Ín(~Ç6A 4ÜPüŽlƒqCðF9² X ¦â‡àŒsdŠ‚1Í`BÀM7?c› ÜPüŽlƒi¸¡ø#Ùâ‡àŒsd°MÅÁæÈ7?c› À…€šn(~Ç6A¸¡ø#Ù,ÓqCðF9² ÅÁæÈ04Æmâ}%´êIh^,y*Ið(—!ù¼g…'©T&wÖ¸n ŒË½œ–¤–bùD{mÞàC S)¨‹:B)ñôª”·d8L¤”êÉå ”£µÔyP„ÜûÉ"à"ÅÁæÈs¹f›˜™ë7lSw=c¤´NÂ5W«¨®b"KFÓ†ëQó’Ö·NýÛ†WNË™‘žÛÊÖ=Á„¿Œýþc-¸¡ø#Ù Œ²Ë7Õ4ÛwáÊ’+‰³j›QŠSjÕ6©ÛKÿÙxymon-4.3.30/docs/xymon-mrtg.html0000664000076400007640000001301612603243142017140 0ustar rpmbuildrpmbuild Integrating MRTG data into Xymon

Integrating MRTG data into Xymon

This document describes one way of integrating MRTG graphs into Xymon. It's simple, doesn't require any additional scripts, and provides all of your MRTG graphs as part of the "trends" column that is already present for all hosts in Xymon.

Another way of doing this is the bb-mrtg.pl script. This is an extension script that gives you some more options for controlling where the graphs show up, and also lets you generate alerts based on data collected by MRTG.

Simple Xymon-MRTG support

MRTG by default uses its own fileformat for the data files, and continuously generates PNG- or GIF-images of the data. This is a waste of resources - most of the time, these images are never seen. This was in fact one of the reasons that RRDtool was developed, to separate the data-collection from the graph generation.

Xymon uses the RRDtool format for all of its data. You can configure MRTG to save data using the RRDtool data format, instead of the default MRTG log-file format. This lets your MRTG save the data directly into the Xymon RRD directory, in the same format that all of the other Xymon RRD files use. You can then use the normal Xymon graph tools to view the graphs.

To configure MRTG to use the RRDtool format, you must setup the mrtg.cfg file like this at the top of the file:

# For Xymon integration
WorkDir: /usr/local/xymon/data/rrd
LogFormat: rrdtool

Note that the WorkDir setting points to the top-level RRD directory, i.e. the one defined via the XYMONRRDS setting in xymonserver.cfg. The Logformat: rrdtool makes MRTG save data using the RRDtool data format.

Each of the network interfaces you monitor have a target-definition in the mrtg.cfg file. You need to modify this slightly, to make it save the RRD data file in a subdirectory matching the hostname you have in the hosts.cfg file, and with a filename that begins with "mrtg.". Like this:

Target[mrtg.myrouter.eth0]: /10.0.0.1:public@myrouter.sample.com:
Directory[mrtg.myrouter.eth0]: myrouter.sample.com

This defines an MRTG target, where it monitors the interface on myrouter.sample.com that has the IP-address 10.0.0.1. It uses the community name public to query the SNMP daemon on the router.

The Directory[mrtg.myrouter.eth0]: myrouter.sample.com instructs MRTG to save the data file in this directory relative to the WorkDir directory, i.e. the final directory for the RRD datafile will be /usr/local/xymon/data/rrd/myrouter.sample.com which is where Xymon expects all of the RRD-files for the myrouter.sample.com host to be. The name of the RRD data-file will be mrtg.myrouter.eth0.rrd - i.e. the name of the target.

The reason for naming the data file mrtg.*.rrd is that the showgraph tool has a built-in definition for generating graphs from this type of files. So if you stick to this naming convention, the graphs will automatically show up on the Xymon "trends" page. If you have more than one device that you collect data from, you'll need to modify this; you can use any name for the target as long as it is of the form mrtg.*.DEVICE - i.e. first "mrtg.", then some random text (e.g. the hostname), then a dot and the device-name. The device-name is used as a legend on the graphs, so you probably want to make this something recognizable, like the name of the network interface, or some sensible description like "DSL", "LAN", "T1" or whatever you know your devices as. Note the MRTG converts this to lower-case.

Here is the full mrtg.cfg configuration used to track traffic on my Internet gateway (currently a 4 Mbit/512 Kbit ADSL). Note that even though MRTG does not use the Title and MaxBytes settings, they are required - MRTG will not run without them:

# For Xymon integration
WorkDir: /var/lib/xymon/rrd
LogFormat: rrdtool

# The external interface on my router
Directory[mrtg.fenris.dsl]: fenris.hswn.dk
Target[mrtg.fenris.dsl]: /80.62.63.88:public@fenris:
Title[mrtg.fenris.dsl]: Traffic Analysis for External DSL
MaxBytes1[mrtg.fenris.dsl]: 500000
MaxBytes2[mrtg.fenris.dsl]: 62500

# The internal interface on my router
Directory[mrtg.fenris.lan]: fenris.hswn.dk
Target[mrtg.fenris.lan]: /10.0.0.1:public@fenris:
Title[mrtg.fenris.lan]: Traffic Analysis for internal LAN
MaxBytes[mrtg.fenris.lan]: 1250000

With this setup, I have the MRTG graphs readily available on the "trends" page, together with all of the other Xymon graphs.

Running the MRTG data collector from xymonlaunch

Normally there is a cron job that runs the mrtg command every 5 minutes to collect the MRTG data. But you can run it from xymonlaunch - this also has the benefit that the RRD files will be owned by the xymon user.

All that is needed is to add a section for MRTG to Xymon's tasks.cfg file. Mine looks like this:

[mrtg]
	CMD /usr/bin/mrtg --lock-file $XYMONSERVERLOGS/mrtg.lock /etc/mrtg.cfg
	INTERVAL 5m
	LOGFILE $XYMONSERVERLOGS/mrtg.log

Some Linux distributions setup MRTG with the expectation that it will always be run by the root user. So you may have to change permissions on some files and directories e.g. to permit the xymon user to read the mrtg.cfg file. Check the mrtg.log file for errors.

xymon-4.3.30/docs/bb-to-xymon.html0000664000076400007640000001313412603243142017173 0ustar rpmbuildrpmbuild Upgrading from Big Brother to Xymon

Upgrading from Big Brother to Xymon

First, you should realize that this is not a fully automated process. You will need to do some work yourself - especially with the handling of alerts.

First step: Install Xymon

To begin, install Xymon as described in the Xymon installation guide. I recommend that you configure Xymon to use the same user-ID as your current Big Brother installation, but have it use a different directory for the server- and data-files. The default is to use ~/server and ~/data respectively, which is unlikely to clash with the directories where you have Big Brother installed. If you do need to change the directories, you must edit the top-level Makefile and change the XYMONHOME and XYMONVAR settings near the top of the file.

Step two: Move the configuration files

A couple of configuration files can be copied directly from Big Brother to Xymon:

  • The bb-hosts file, must be renamed to hosts.cfg
  • The bb-services file. You need only copy this if you have used bbgen before, and added custom network tests to the bb-services file. You must rename it to protocols.cfg.
  • The cookies file. You may not have this file - it is only present if you have used bbgen before and have setup HTTP tests that require cookies.
  • The bbcombotests.cfg file. You may not have this file - it is only present if you have used bbgen before and have setup the bbcombotest tool. Copy it to combo.cfg.

The bbwarnrules.cfg and bbwarnsetup.cfg files cannot be copied over. Xymon uses a very different configuration file for the alert configuration, so you will have to re-write your alert configuration for Xymon. See the Xymon alert configuration to learn how Xymon alerts are configured.

Any server-side extension-scripts can be copied from the $XYMONHOME/ext/ directory to the ~/server/ext/ directory. You must also add entries for them to the Xymon tasks.cfg file. Beware that many scripts rely on environment variables that Big Brother defines, but which Xymon does not define - in that case, you need to setup those environment variables in the xymonserver.cfg file. It is probably easiest to save this until you start running Xymon, and can look at any error-output from the scripts.

If you have modified the webpage header- and footer-files in $XYMONHOME/web/ then you can copy the modified files over directly to the ~/server/web/ directory. Note that Xymon has a number of header- and footer-files for the various CGI scripts that are not present in Big Brother, so you may need to setup a few extra files to get a consistent look across your new Xymon installation.

Step three: Stop Big Brother

You are now going to move over the data files. To avoid confusion about files being updated by Big Brother while they are being moved over to Xymon, I recommend that you stop Big Brother now.

Step four: Move the history logs

You may want to save the historical logfiles and the history of your status changes. To do that, move all of the files or directories in the $XYMONVAR/hist/ to the ~/data/hist/ directory, and all of the files or directories in $XYMONVAR/histlogs/ to the ~/data/histlogs/ directory. If you prefer to keep them in the Big Brother directory, you can copy them over with "cp -r" or "tar" instead of moving them.

Step five: Move the RRD files

The RRD files are used to generate the graphs, if you have installed the LARRD add-on to Big Brother. Xymon has RRD support built-in, and it is obviously nice to keep the historical data that has been collected over time.

The filesystem layout of the RRD files is different from Big Brother+LARRD to Xymon. Instead of having all of the RRD files in one big directory, there is a subdirectory for each host holding only the RRD files for data from that host. This is easier to manage, and also speeds up the graph generation when you have many hosts. Unfortunately, it makes migrating from Big Brother to Xymon slightly more complicated.

In the Xymon source-tree, you will find a script xymond/moverrd.sh. This script moves or copies the RRD files from the Big Brother+LARRD structure into the Xymon structure. You must edit a couple of settings at the beginning of the file, especially to set the correct directory where Big Brother stores your current RRD files (the SRCDIR setting). By default the script copies the files over to the new structure, if you would rather just move them then change to "OP" setting to "mv".

After setting up the script, run it and it should copy all of the RRD-files that relate to a host currently in the hosts.cfg file to the new directory structure.

Step 6: Start Xymon

Start Xymon with the ~/server/xymon.sh start command. Look at the logfiles in the /var/log/xymon directory (or elsewhere, if you did not choose the default logfile directory when configuring Xymon) and fix any problems that show up.

Look at the webpages generated. For the first few minutes, there will be some missing columns and icons for each host, since it takes some time for all of the tests to report a status to the new Xymon daemon. After 5-10 minutes all of the standard tests should appear.

xymon-4.3.30/docs/xymon-config.html0000664000076400007640000004103711535462534017453 0ustar rpmbuildrpmbuild Configuring Xymon Monitoring

Configuring Xymon Monitoring

The Xymon configuration is kept in the files in the ~/server/etc/ directory. If you look at this directory, you will see these files:

  • hosts.cfg is the one you will change the most. This file contains a list of all the hosts you are monitoring, including information such as their IP-address, what network services you are monitoring on the host, what URL's you are checking, what subpage in the Xymon web-pages this host is shown on etc. The name of the file - "hosts.cfg" - was chosen so it is compatible with the Big Brother system which uses the same filename and file format.
  • analysis.cfg is the configuration file for data reported by the Xymon clients installed on the hosts you are monitoring. This defines the color of the cpu-, disk-, memory- and procs-columns, based on the information that is sent to Xymon by the clients.
  • alerts.cfg holds the alerting configuration. In this file, you setup the rules for sending out alerts about services going down: Who gets the alert, how is it sent, how often, whether to send alerts 24x7 or only between 10 AM and 4 PM on weekdays etc.
  • xymonserver.cfg is the configuration file for the Xymon server. This file defines a lot of environment variables that are made available to all of the Xymon programs when they run. Some environment variables that are defined in the Big Brother system are also setup by Xymon, so that Big Brother extension scripts will work.
    The initial configuration of xymonserver.cfg is setup by the configure script when you install Xymon, and in most cases you will not need to change it.
  • tasks.cfg is the configuration file for the xymonlaunch tool. xymonlaunch is the master program in Xymon, it is the only program you start to run the Xymon server. xymonlaunch reads the tasks.cfg file, and starts the programs listed here to run the server. Some of the programs may run as daemons, some of the programs may run at regular intervals. If you want to use some of the advanced options for the xymongen or xymonnet programs, you change the tasks.cfg file to add these options to the command line.
  • graphs.cfg is a configuration file for the showgraph CGI. It defines how the graphs are generated from the data in the RRD files.
  • protocols.cfg is a configuration file for the xymonnet program. It defines how network services are checked.

Setting up monitoring of hosts

The hosts.cfg file defines which hosts Xymon monitors. When you install Xymon, a simple configuration is setup that just lists the Xymon server:
Simple Xymon hosts.cfg file

There are a few things to notice here:

  • Lines that begin with a # are comments.
  • Each host you monitor is on a line by itself, with the IP-address and the hostname of the host.
  • You can add extra tags to each host definition, by putting in a #-mark and then some keywords. These keywords define how Xymon handles the host.

The hosts.cfg file shown in the example has only one host defined: www.hswn.dk which is the server running Xymon. There are a few extra keywords thrown in:

  • BBDISPLAY, BBPAGER, BBNET are compatibility settings for extensions written for Big Brother. Xymon doesn't use these, but puts them in the hosts.cfg file to avoid problems if you mix Xymon and Big Brother modules.
  • bbd is the name of a network test. This keyword causes the Xymon network-tester xymonnet to check if the bbd network service is running on this host, and send a status report to the Xymon server with the information about this service. So you'll get a (hopefully!) green icon on the Xymon webpage for this host, showing the status of the bbd network service.
    Network services are defined in the protocols.cfg file, so this file must have an entry for bbd defining what TCP port to check, and possibly also what data to send to the service and what to expect as a response.
  • http://www.hswn.dk/ is a URL, obviously. This also triggers a network test, the Xymon network tester will try to request this URL, and send in a status report showing if the URL was accessible or not.

By default, Xymon will always check if the host is up and running by trying to "ping" it. This results in a conn column on the Xymon webpage for this host, showing if the ping-test succeeded. If you have a host that does not respond to ping - e.g. because there is a firewall that filters out such requests - then you can disable the ping-test by putting a "noconn" keyword on the line in hosts.cfg.

As you can see, the syntax is pretty straight-forward. Need to monitor an extra URL for this server ? Just add the URL to the line. Need to check if ssh (Secure Shell) is running ? Just add ssh to the line. The full set of keywords you can use is described in the hosts.cfg man-page. Many of the keywords relate to the way Xymon displays the information about the host on the web-pages, other keywords deal with how the uptime percentage is calculated for availability reports, and some keywords - like the bbd and http://... mentioned above - describe the network services that are tested for this host.

Monitoring network services

As shown in the example above, adding a network test for a host is as simple as putting the right keyword into the hosts.cfg file. The default set of network tests configured in Xymon 4.0 is as follows:

connSimple ping test. Enabled by default, you can disable it by putting "noconn" into hosts.cfg.
httpWeb-server test. Enter the URL to request from the webserver.
ftpFTP server test.
sshSSH (Secure Shell) server test. Supports ssh1 and ssh2.
telnetTelnet server test.
smtpSMTP (Mail server) test.
pop3POP-3 test.
imapIMAP test. IMAP version 2 and 4 are supported, for version 3 use "imap3".
nntpNNTP (News) server test.
ldapLDAP (Directory server) test. Enter the full LDAP URI if Xymon is configured with LDAP support.
rsyncrsync server test
bbdXymon network daemon test (historically named after the Big Brother daemon, bbd).
clamdCLAM anti-virus daemon test.
spamdSpamAssassin anti-spam daemon test.
oratnsOracle TNS listener test. Will attempt to do an oratns "ping".
qmtpQMTP server test. For qmail's qmtpd service.
qmqpQMQP server test. For qmail's qmqpd service.

If Xymon is built with OpenSSL support, the following SSL-enabled services can also be checked:

httpsWeb-server test. Enter the URL to request from the webserver.
ftpsSecure FTP server test.
telnetsSecure Telnet server test.
smtpsSecure SMTP server test.
pop3sSecure POP-3 server test.
imapsSecure IMAP server test.
nntpsSecure NNTP (News) server test.
ldapsSecure LDAP (Directory) server test. Enter the full LDAP URI if Xymon is configured with LDAP support. Note that this is only possible when Xymon is built with the OpenLDAP v2.x client library, and only for LDAP servers that support LDAP version 3 and the "starttls" command. LDAP server that use the older non-standard method of tunnelling LDAP through SSL on port 636 will not work.

There are a few network tests that Xymon can run for you, by using external programs. This is not a very effective way of testing, so it is only done this way for a few very specialised tests:

ntpNTP (Network Time protocol) server test, using the "ntpdate" command.
rpcRPC service test. This queries the portmapper service on the server, using the "rpcinfo" command. See the hosts.cfg(5) man-page for details on how to test for specific RPC services.

Monitoring host-specific data with clients

You can install a client on each of the hosts you monitor, to check host-specific data such as CPU utilisation, disk usage, if certain processes and services are running etc. Xymon includes clients for most Unix-like operating systems. A client for Windows is planned but the programming has not yet started.

First, make sure you have installed the Xymon client on all of the hosts you want to monitor, and you have these hosts listed in your hosts.cfg file. The Xymon client will pick up the hostname of the box it is running on automatically, but it is not uncommon for the name it finds to be different from what you've put into hosts.cfg. So if you know that the client is running but no data appears, check that the hostname used by the Xymon client is the one you expect. See this FAQ item for details.

With the Xymon client running and reporting data into Xymon, you should see the cpu-, disk-, memory- and procs-columns appear. The color of these status columns is determined by settings in the analysis.cfg configuration file. Here is an example of how to setup a host:

As you can see, there's first a definition of what hosts the following criteria applies to. Here, it is only a single host: voodoo.hswn.dk - but you can use various filters on hostnames, pagenames and time of day to determine what the thresholds should be for each of the criteria monitored with the client data. The analysis.cfg man-page describes this in detail.

After the host filter comes the criteria used to determine the color of each of the status columns.

UP Sets the cpu column color, based on how long the host has been up. After the UP keyword you put two time limits: The first one (30m in the example) defines how long after a reboot the cpu column is yellow. The second (optional) value causes the cpu column to go yellow after the host has been up for this long - it may be useful, if you need to reboot your servers regularly.
LOAD Sets the cpu column color, based on how much load is on the system. After the LOAD keyword you put two limits: The first number is the limit where the cpu column goes yellow; the second is the limit where the cpu column goes red.
For Unix systems, this threshold is matched against the 5-minute load average value, as reported by the "uptime" command - it is therefore a positive number.
For Windows systems, this threshold is matched against the CPU utilisation - this is a percentage between 0 and 100.
DISK Sets the disk column color based on how full the filesystem is. This takes three parameters: The name of the filesystems; the threshold where it goes yellow; and the thresholds where it goes red.
The name of the filesystem is the mount point. You can specify this either with the full path, or you can use * meaning "all filesystems". You can also use regular expressions by prefixing the expression with a percent sign, e.g. "%^/ora.*" would match all filesystems that are mounted on a path beginning with "/ora" - "/ora/db/vol1" for instance. As shown in the example, you can have multiple specifications with different thresholds - these are evaluated from top to bottom, so it is best to put the most specific ones first, and the general ones last.
The yellow and red thresholds are percentages - they trigger when the filesystem has filled up to the percentage you specify.
PROC Sets the procs column color based on what processes are running. This takes at least one parameter: A string that is (part of) the command line that the process runs. You can have a simple string here or a regular expression - Xymon will scan the "ps" output for the string or expression, and count how many times it appeared in the ps listing.
The process count is then matched against the thresholds that are the second and third parameter - the second parameter is the minimum count (by default: 1), and the third parameter is the maximum count (default: -1, meaning unlimited). Note: If you want to set a maximum count, then you must also set a minimum count - even if it is 1.
The last parameter defines the color used for the procs column, if the process count does not fall within the thresholds. By default it will go red - you can put "yellow" as the last parameter.
You can have several PROC entries for the same host, if you need to monitor multiple processes.
MEMPHYS
MEMACT
MEMSWAP
Set the memory column color based on the thresholds for memory utilisation. Each of these keywords takes two parameters: The first is the warning (yellow) threshold - in percent - of memory used. The second is the panic (red) threshold - in percent - of memory used.
By using one of the three keywords, you can set thresholds for the physical memory (RAM), the swap space, and - on platforms supporting this, e.g. Linux - the actual amount of memory used for applications.
LOG Set the msgs column color. This takes at least two parameters: The first is the name of the logfile, the second is a pattern defining which logentries trigger a change of color.
Optionally, this can be followed by a third parameter defining which color this LOG entry causes, and fourth parameter which is an "ignore" pattern you can use to filter out lines which do match the first pattern of lines that trigger a change in color, but that you really do not want to trigger a color change.

More about logfile monitoring

Configuring the LOG entries in the analysis.cfg file is only one half of the configuration - you also need to tell the Xymon client running on the monitored system that it must send in some data from that logfile in the first place. For that, you must configure the client-local.cfg file with the name of the logfile.

xymon-4.3.30/docs/install.html0000664000076400007640000006700112603243142016470 0ustar rpmbuildrpmbuild Installing Xymon

Installing Xymon

This describes how to setup a Xymon server for monitoring your systems. It assumes that you are setting up a full Xymon server - i.e. either you do not have a Big Brother server, or you will replace it completely with Xymon.

Note to Big Brother users: Although some of the Xymon tools have evolved from the bbgen toolkit that was used on top of a Big Brother server installation, the Xymon versions of these tools now require that you run Xymon - not Big Brother. If you are migrating from Big Brother to Xymon, then you should follow the migration guide.

Prerequisites - before you install Xymon

You may want to check the list of common systems which has brief instructions for installing Xymon for these types of systems.

There are a few things you should check before you begin to install Xymon. Don't be scared of the number of items here - it is likely that you already have most or all of it in place.

A webbrowser capable of handling HTML 4, JavaScript and CSS

This includes most browsers available today - Internet Explorer 5 or later, all Mozilla/Firefox versions, Konqueror, Netscape 6 and several others. The old Netscape 4.x browsers are known NOT to work.

A Unix-like operating system

Xymon is written for Unix-based systems, e.g. Linux, FreeBSD, or Solaris. It will probably work on any Unix-like system that supports the Unix System V IPC mechanisms (shared memory, semaphores) - that should be just about anything Unix-like you are likely to have.

Sufficient SYSV IPC resources on your system

Xymon uses 8 shared memory segments, ranging in size from 32 KB to 512 KB (2336 KB total) in the default configuration; and 8 sets of 3 semaphores. Experience shows that some systems need tuning to provide the necessary IPC resources that Xymon uses. Specifically, when installing on Solaris you must increase the "shmseg" kernel parameter from the default 6 to at least 8. Since other programs on your system may also use shared memory, a higher value may be required. See http://www.xymon.com/archive/2005/08/msg00183.html for more information about these issues.

A webserver

Xymon is designed with a web-based front-end. So you should have a webserver such as Apache running on the server where you install Xymon.

A working C compiler, GNU make.

Xymon is written in C, so you need a working C compiler, e.g. gcc. You will also need a "make" utility - many systems have one by default, but you need to use the GNU make utility. On some systems, this is pre-installed as "gmake" or "gnumake". The configure-script checks this for you.

HP-UX users should note that the HP-supplied C compiler is known to mis-compile the lib/environ.c file, and produces an output file lib/environ.o of length 0 bytes. HP-UX users on the Xymon mailing list agree that the default C compiler shipped with HP-UX should not be used to compile Xymon - it is only for re-building the HP-UX kernel. The GNU C compiler works fine on HP-UX. More details in this e-mail from the Xymon mailing list.

PCRE, RRDtool, OpenSSL, OpenLDAP libraries.

Xymon relies on a number of Open-Source libraries - these must be installed before you start building Xymon. On many systems you already have these pre-installed - they are commonly installed by default on Linux systems, and FreeBSD has all of them in the "ports" collection.

Note: Although many systems have these libraries pre-installed, they often include only the run-time libraries and not the files that are needed to compile and build programs such as Xymon. So if you think you have all of these libraries installed but Xymon will not build, do check that you have the development files installed as well. Often these are in packages called "something-dev".

  • PCRE - Perl Compatible Regular Expression library - is a library for matching text-strings. It is available from http://www.pcre.org/
  • RRDtool is a library for handling the Round-Robin Databases used to hold the historical data Xymon gathers. It is available from http://www.mrtg.org/rrdtool/. Xymon has been tested with version 1.2, 1.3 and 1.4 of RRDtool, so use one of these - many Linux- and *BSD-systems have pre-packaged versions of it.
    Note that RRDtool requires various graphics-libraries. RRDtool 1.2.x uses libpng, newer versions rely on the Cairo graphics library.
  • OpenSSL is a library for communicating with network services, that use SSL encryption - e.g. secure websites. Although this library is not absolutely required for Xymon, I strongly recommend that you install it because sooner or later you will probably need it anyway. It is available from http://www.openssl.org/. Note: If you are building on Solaris, you should check that you have a random-data generator, either the prngd daemon (available on Sun Freeware) or the Solaris /dev/random driver from Solaris patch 112438.
  • OpenLDAP is used to query LDAP directory servers. If you would like to test that your directory server is up and running, you will need this library. It is available from http://www.openldap.org/

The configure-script will attempt to locate all of these libraries on your system, and complain if the required ones are missing.

A "xymon" userid on your system

A core element of Xymon is a network daemon. To keep your system secure and limit the amount of damage that can be done if someone finds a security problem in Xymon, I strongly recommend that you create a dedicated userid for the Xymon programs. This user should not be a member of any other groups on your system.

Xymon will install the xymonping tool as setuid-root(only on the Xymon server). This program requires root privileges to be able to perform network "ping" tests. It will drop root privileges immediately after obtaining the network socket needed for this, and will not run with root privileges at all while handling network traffic or doing file I/O.

Building Xymon

After unpacking Xymon from the tar-file, run the configure script. This script asks a series of questions, but all of the questions have a reasonable default response. So if you are in doubt about what to answer, use the default setting. You can see what it looks like.

When the configure script finishes, it tells you to run make to build the Xymon programs. If your default "make" tool is not GNU make, you should use the command for running GNU make instead, e.g. gmake. You will now see a lot of commands being run to build the programs, it usually takes a minute or two.

When it is finished, you finish the installation by running make install.

The first time you run make install, besides installing the Xymon programs it also creates the default directory structure used by Xymon, and installs an initial set of configuration files that you can use as the basis for setting up monitoring of your entire network.

It is safe to run make install when upgrading a Xymon server. It installs the programs, adds new template-files that were not present in your previous version, and updates your configuration files with any new sections that have been added. Any changes you have made yourself are preserved.

Configuring your webserver

Xymon uses a web-based front-end. So you need to configure your webserver so that it knows where the Xymon webpages can be found, and what CGI scripts can run as part of Xymon. This usually means adding a few lines to your webserver configuration that sets up a URL which points at the ~/server/www/ directory, and which tells your webserver that the ~/cgi-bin/ directory holds CGI scripts that the webserver should run when they are requested.

If you are using the Apache webserver, you will find the necessary additions to the Apache configuration in ~/server/etc/xymon-apache.conf - it looks like this. After changing the webserver configuration, you probably need to restart the webserver.

If you configured Xymon to put the Administration CGI scripts into a separate directory (recommended for better security), you will also need to setup the password-file that controls access to this directory. Use the htpasswd command both to create the password file and to add or delete users:


	# /usr/sbin/htpasswd -c /usr/local/xymon/server/etc/xymonpasswd admin
	New password:
	Re-type new password:
	Adding password for user admin
	#

The -c option should only be used the first time, to create the password file. See the Apache documentation for details about how to use htpasswd.

Starting Xymon

You can now login as the "xymon" user, and run the command ./server/xymon.sh start to start Xymon. After a few seconds, it should have started and you now have the following processes running:
Xymon processes

Quite a few, but all of them controlled by the master xymonlaunch process. A quick run-down of what each of them does:

  • xymond is the network daemon that receives status updates from the clients and the network test tool. It also provides the current status of all your systems to the tool that generates the webpages.
  • xymond_channel provides the communication between xymond and all of the helper modules that implement other server-based functions.
  • xymond_history takes care of recording the history of status changes for each item you monitor. This is used to track what has happened with a single status over time - when it was red, when it was green, what the error reported at 2:51 AM last Friday looked like. The history file format is compatible with the format used by the Big Brother package.
  • xymond_filestore stores files with information about the current status of the systems monitored by Xymon. There may be several of these running, but normally you will only need the one that stores information about hosts that have been disabled, which is the one you see here.
  • xymond_alert takes care of sending out alerts when your servers begin to report a critical status.
  • xymond_rrd updates the RRD database files with the numeric data collected from the status reports, to track e.g. how the disk utilization of a server changes over time. There are two of these processes, because the data can arrive in two different ways.

After a couple of minutes, you should have data available for the Xymon server itself. If you open a webbrowser with the Xymon URL - usually http://your.server/xymon/ - you should see something like this:
Xymon main window

Each of the little faces indicate an item that is being monitored for this host. Here you see the default set of items that the Xymon installation sets up for a Xymon server:

  • bbd is the availability of the Xymon network daemon.
  • conn is a simple "ping" test of the host.
  • http is the status of the HTTP-server running on the Xymon server.
  • info contains information about how the host is configured in Xymon, such as what IP-address it has, what network tests are being run against this host etc.
  • trends is a collection of the various RRD graphs available for this host.
  • xymond is the status of the Xymon daemon, with statistics about how many monitored items are being tracked.
  • xymongen is the status of the xymongen tool, which updates the webpages.
  • xymonnet is the status of the xymonnet network tester that performs all of the network tests you configure in Xymon.

You can click on each of the green icons to see a more detailed status.

Next steps

Congratulations, you now have a running Xymon server!

The next step is to configure it to monitor your servers and applications, and to set up the alerts to send you e-mail, call a pager, or send an SMS in case of trouble. For that, see the Xymon configuration guide.

Appendix: Installing on common systems

This appendix details how to install Xymon on some of the more common types of systems.

Red Hat Enterprise Linux 6 / CentOS 6

RHEL6 has all of the necessary tools except fping included in the core distribution.

groupadd xymon
useradd -g xymon -m xymon

yum install gcc make

wget http://fping.org/dist/fping-3.2.tar.gz
tar zxf fping-3.2.tar.gz
cd fping-3.2
./configure
make && make install
cd ..

yum install pcre-devel openssl-devel openldap-devel rrdtool-devel
cd xymon-4.3.10
./configure --server
make && make install

Copy rpm/xymon-init.d to /etc/init.d/xymon and make sure it is executable. Edit /etc/init.d/xymon and change "/usr/lib/xymon" in the DAEMON line to the directory where you installed Xymon - e.g. "/home/xymon".

Configure Apache with the Xymon definitions:
ln -s /home/xymon/server/etc/xymon-apache.conf /etc/httpd/conf.d/

To enable automatic start of Xymon and apache:

chkconfig httpd on
chkconfig --add xymon
chkconfig xymon on

Red Hat Enterprise Linux 5 / CentOS 5

RHEL5 does not include RRDtool in the core distribution. So download it and install it in /usr/local/rrdtool. Also, fping is not included.

groupadd xymon
useradd -g xymon -m xymon

yum install gcc make

wget http://fping.org/dist/fping-3.2.tar.gz
tar zxf fping-3.2.tar.gz
cd fping-3.2
./configure
make && make install
cd ..

yum install freetype-devel libpng-devel libart_lgpl-devel tcl-devel
wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.30.tar.gz
tar zxf rrdtool-1.2.30.tar.gz
cd rrdtool-1.2.30
./configure --prefix=/usr/local/rrdtool
make && make install
cd ..

yum install pcre-devel openssl-devel openldap-devel
cd xymon-4.3.10
./configure --server
make && make install

Copy rpm/xymon-init.d to /etc/init.d/xymon and make sure it is executable. Edit /etc/init.d/xymon and change "/usr/lib/xymon" in the DAEMON line to the directory where you installed Xymon - e.g. "/home/xymon".

Configure Apache with the Xymon definitions:
ln -s /home/xymon/server/etc/xymon-apache.conf /etc/httpd/conf.d/

To enable automatic start of Xymon and apache:

chkconfig httpd on
chkconfig --add xymon
chkconfig xymon on

Red Hat Enterprise Linux 4 / CentOS 4

RHEL4 does not include RRDtool in the core distribution. So download it and install it in /usr/local/rrdtool. Also, fping is not included and some of the development files are in a non-standard location.

groupadd xymon
useradd -g xymon -m xymon

yum install gcc make

wget http://fping.org/dist/fping-3.2.tar.gz
tar zxf fping-3.2.tar.gz
cd fping-3.2
./configure
make && make install
cd ..

yum install freetype-devel libpng-devel libart_lgpl-devel tcl-devel
wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.30.tar.gz
tar zxf rrdtool-1.2.30.tar.gz
cd rrdtool-1.2.30
./configure --prefix=/usr/local/rrdtool
make && make install
cd ..

yum install pcre-devel openssl-devel openldap-devel
cd xymon-4.3.10
./configure --server --pcreinclude /usr/include/pcre --sslinclude /usr/include/openssl
make && make install

Copy rpm/xymon-init.d to /etc/init.d/xymon and make sure it is executable. Edit /etc/init.d/xymon and change "/usr/lib/xymon" in the DAEMON line to the directory where you installed Xymon - e.g. "/home/xymon".

Configure Apache with the Xymon definitions:
ln -s /home/xymon/server/etc/xymon-apache.conf /etc/httpd/conf.d/

To enable automatic start of Xymon and apache:

chkconfig httpd on
chkconfig --add xymon
chkconfig xymon on

Red Hat Enterprise Linux 3 / CentOS 3

Follow instructions for RHEL4.

Fedora 17

Follow instructions for RHEL6.

Debian 6 (Squeeze)

NOTE: Pre-compiled Debian packages are provided on Sourceforge, along with the source distribution file.

Debian 6 has all of the necessary tools included in the core distribution.

apt-get install apache2 rrdtool librrd-dev libpcre3-dev libssl-dev ldap-utils libldap2-dev fping

# Enable mod_rewrite in Apache
cd /etc/apache2/mods-enabled/
ln -s ../mods-available/rewrite.load .
/etc/init.d/apache2 reload
cd

tar zxf xymon-4.3.10.tar.gz
cd xymon-4.3.10
./build/makedeb.sh 4.3.10
mv debbuild/*.deb ../
cd ..
dpkg -i xymon*deb

Ubuntu 12.04 LTS (Precise Pangolin)

Follow instructions for Debian 6.

FreeBSD 7,8 and 9

Perform a standard install, make sure to install the "ports" collection. FreeBSD - in a minimal configuration - does not install any of the Xymon prerequisites, so starting from a minimal configuration you must run these commands to install the various tools and libraries needed. For those packages that have some configuration items, the defaults work fine:

cd /usr/ports/devel/gmake; make; make install
cd /usr/ports/devel/pcre; make; make install
cd /usr/ports/databases/rrdtool12; make; make install
cd /usr/ports/security/openssl; make; make install
cd /usr/ports/net/openldap23-client; make; make install
cd /usr/ports/net/fping; make; make  install
cd /usr/ports/www/apache22; make; make install

Next, run the "adduser" utility and setup the "xymon" user.

After this you are ready to build and install Xymon:

setenv PATH ${PATH}:/usr/local/bin
setenv MAKE gmake
cd ~
gzip -dc xymon-4.3.10.tar.gz | tar xf -
cd xymon-4.3.10
./configure	# All defaults, except group-ID for webserver is "www"
gmake && gmake install
chown 0:0 /home/xymon/server/bin/xymonping
chmod u+s /home/xymon/server/bin/xymonping

ln -s /home/xymon/server/etc/xymon-apache.cnf /usr/local/etc/apache22/Includes

To enable automatic start of Xymon when the server is booted, you must create the /etc/rc.d/xymon script:


#!/bin/sh

. /etc/rc.subr

name="xymon"
start_cmd="${name}_start"
stop_cmd="${name}_stop"

xymon_start()
{
	su xymon /home/xymon/server/xymon.sh start
}

xymon_stop()
{
	su xymon /home/xymon/server/xymon.sh stop
}

load_rc_config $name
run_rc_command "$1"

Make sure the script is executable with
chmod 755 /etc/rc.d/xymon
and add the line
xymon_enable="YES"
to the file /etc/rc.conf

A similar script can be used to start/stop Apache automatically. Use the commands
/usr/local/sbin/apachectl start
and
/usr/local/sbin/apachectl stop
in the apache_start() and apache_stop() functions, respectively.

OpenBSD 4 and 5

All of the necessary packages are available from the OpenBSD "ports" collection. Note that when installing OpenBSD, you must install the "xbase" package, since this contains a library that is needed by RRDtool.

After installing the core OpenBSD system, use the ports-collection to install the necessary packages. See OpenBSD FAQ for details about using this.

export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/
pkg_add -v gmake pcre rrdtool openldap-client fping apache-httpd

Note: Check permissions on /usr/local/sbin/fping* - they must be suid root. On OpenBSD 4.6 it has been observed that this is not the case by default, so you must run
chmod u+s /usr/local/sbin/fping*
for them to be usable by the xymon user.

Run the adduser utility to setup the "xymon" user.

Configure, build and install Xymon with these commands. Configuration can use all defaults, except that the webserver group-ID is "_apache2".

gzip -dc xymon-4.3.10.tar.gz | tar xf -
cd xymon-4.3.10
MAKE=gmake ./configure # All defaults except webserver group is "_apache2"
gmake && gmake install

In /etc/apache2/httpd2.conf, add this line at the bottom:
Include /home/xymon/server/etc/xymon-apache.conf

To enable automatic startup, add these commands to /etc/rc.local:
/usr/local/sbin/apachectl2 start
su xymon /home/xymon/server/xymon.sh start

Solaris 10/x86 (using OpenCSW)

All of the necessary libraries and tools for building Xymon are available in the OpenCSW archive. This appears to be a newer collection of Open Source tools, replacing the Sun Freeware archive which is now a commercial project. See below for instructions on installing Xymon using the SFW packages.

Follow the "Getting Started" instuctions on setting up your system to use the CSW archive. Briefly, this means running these commands (as root):

pkgadd -d http://get.opencsw.org/now
PATH=$PATH:/opt/csw/bin
export PATH
pkgutil -i -y cswpki
cswpki --import
vi /etc/opt/csw/pkgutil.conf	# Define mirror, enable use_gpg and use_md5
pkgutil -U

After setting up the CSW archive tool, you can install the necessary tools and libraries that Xymon will use:

pkgutil -i -y gcc4core gcc4g++ gmake
pkgutil -i -y pcre libpcre_dev
pkgutil -i -y rrdtool rrdtool_dev
pkgutil -i -y openssl libssl_dev
pkgutil -i -y openldap_client openldap_dev
pkgutil -i -y fping

The "fping" tools must be installed suid-root so that the xymon user can run them:

chmod u+s /opt/csw/sbin/fping*

Now, create the xymon user:

groupadd xymon; useradd -g xymon -d /export/home/xymon -m xymon

Configure and build Xymon. All tools and libraries should be automatically detected, but it is necessary to explicitly point at the CSW OpenSSL libraries, overriding the default Solaris version of OpenSSL:

PATH=$PATH:/usr/ccs/bin
export PATH
cd xymon-4.3.10
MAKE=gmake ./configure --server --sslinclude /opt/csw/include --ssllib /opt/csw/lib
gmake && gmake install

Install Apache and add the Xymon webserver configuration:

pkgutil -i -y apache2
ln -s /export/home/xymon/server/etc/xymon-apache.conf /opt/csw/apache2/etc/extra/
Add
  Include etc/extra/xymon-apache.conf
to /opt/csw/apache2/etc/httpd.conf.

The CSW Apache implementation supports the Solaris SMF (svcadm) setup, but conflicts with the default Apache version that is installed with Solaris. So disable the default version, and enable the CSW version:

/etc/init.d/apache stop
rm /etc/rc?.d/*apache
svcadm clear cswapache2

To enable automatic startup of Xymon when the server boots, put this into /etc/init.d/xymon:

#!/bin/sh
su xymon /export/home/xymon/server/xymon.sh $*
exit $?
and then enable this via the "legacy" startup scripts by running these commands:
ln -s /etc/init.d/xymon /etc/rc3.d/S80xymon
ln -s /etc/init.d/xymon /etc/rc0.d/K20xymon
ln -s /etc/init.d/xymon /etc/rc1.d/K20xymon
ln -s /etc/init.d/xymon /etc/rcS.d/K20xymon

Solaris 10/x86 (using Sun Freeware)

All of the necessary libraries and tools for building Xymon are available in the Sun Freeware archive. You must install these packages to build Xymon:

  • db (SMCdb47)
  • freetype (SMCftype)
  • gcc (SMCgcc)
  • libart_lgpl (SMClibart)
  • libpng (SMClibpng)
  • libtool (SMClibt)
  • libiconv (SMCliconv)
  • libintl (SMClintl)
  • make (SMCmake)
  • openldap (SMColdap)
  • openssl (SMCossl)
  • pcre (SMCpcre)
  • rrdtool (SMCrrdt)
  • sasl (SMCsasl)
  • zlib (SMCzlib)

After installing these, you must set PATH and LD_LIBRARY_PATH to pick up the new tools, then you can compile Xymon the usual way:

groupadd xymon
useradd -d /usr/local/xymon xymon
PATH=$PATH:/usr/local/bin:/usr/ccs/bin; export PATH
LD_LIBRARY_PATH=/usr/local/lib; export LD_LIBRARY_PATH
./configure
make
make install

The SunFreeware libraries are installed in /usr/local/lib, which is NOT searched by default by the Solaris runtime linker. You must either set LD_LIBRARY_PATH globally to include /usr/local/lib, or you can use the "crle" utility to add /usr/local/lib to the set of directories searched by default. Typically this means running this command:

	crle -c /var/ld/ld.config -l /usr/lib:/usr/lib/secure:/usr/local/lib 

The latter method using "crle" is the recommended method, since LD_LIBRARY_PATH settings can be difficult to setup so they work for all invocations of the Xymon binaries.

Mac OSX 10.6, 10.7 and 10.8

Xymon is available for OSX 10.6, 10.7 and 10.8 through the macports project.

The ports can be found here:http://www.macports.org/ports.php?by=name&substr=xymon, and there's a page on how to make xymon server on a Mac.

xymon-4.3.30/docs/xymon-hosts.png0000664000076400007640000014503311535414771017167 0ustar rpmbuildrpmbuild‰PNG  IHDRÞ±Š,úY pHYs  ÒÝ~ü€IDATxÚìýhSiÞ?þ÷î͸#$¢¼“¹š¢LïL—æ0…5‡t\hªÃÇD…i.ÛÆÛŽË´Õ›u’.Œi§í°N[aµñ5)¬6~M|óqIÊ­$½›r;4}Oò¾°Ûœ/Óýþñòèé&­9IOLëó›uN®ž\çuýÈ9W®suñªø`¼Š†af0qñÌ`â@& šdA€,0hM²À  ¼F:Àͤ½îsæ^7Ã̧x;ˆ4 ·ÝÝn3nܻٸѸqÏ?7²†Çì„ëhÁu´ø`Þ¿ïWæý¥\õøÖVõ8E‰ݻٸ1Ü©·­ìgiÖoÿV³^ŠÈtδ':gŒŠ½›Œ †)SH1KíG–þ@êö| •ùî`âû¦ÁDëЉ©Ö¡â—~fiRÍó^»7æ};»ÍzÍ׋k]©ñØGozì‹Ûàž6n¤í¥™çBúÒÒì—¯'Òõ]«¥–@)[¯ŠÆ«rÿºPì½Ô°÷’Þ¥»£wÑö÷ã1N#ÛvN#CX ¬Çæb'cs´%¨¿³!¨ïœ9ÅuΞÝþ9ðlå>kû·šõ±¹‡ÇøÏZ†+/ž® êïî êû.ûMß%á»æýo7ïïœ>ÅuN³aÃ#6üfK3Î>Æÿ_ÆÑë÷?‰^G /Ôͧ @ ï¸|~x‡Ò¡Ø£t$;S·“¶©ƒ¶©¶Ѷ£bO™QQJQ] m9÷z"õñ–r-€R6˜¸xf0!z¦ ]r¨ƒêzuP¸=s¸$Ùùt4Ùi›²6Ú¦„ó,&}÷÷MúgåBû`‚¨þ;;A)éò8—w3E¤KYú­’O¿ïWæý´}Qž×k¾Ö¬§Ë*Ê›®g÷]]nIt6\ýœ ǸÇ=1.¿Xñê¯fú8*NË™Ÿ•™7s*Æñ»w³q££¢Kí¨Èü¥7÷üЧÐ0¥¡¡üâc¶ì{ßl ¤n> ¤„·ÑQÇÙÄ…8+.É<ÆåkËÊJv>ŸHvjd[Ž/®ù¹×ÀÜK„Ž”n’¢#ÖUªÃ™Û…{ Ò\™}¿2ïóÞøqÌk›:ò‡¥Ë:—RNf#é€pŸo¶.õºû­½nGùi™£œ†Kh;ý›¶ó7-•‡W¹Í,»åkZ~Ѧ-\`v‚ пÅöT™-"÷¿Í½6J-ó( ©½Kí?—R=hÒ ú¼¿Aeܸ§Ì¸±áÝÆïÞ®¼üýpeæjmC퉶¡fëï/7[iVEï¥s÷^²j·¦týFë::võÚŒ]¥”ôËp.ïfjjÿ?mC¶Iëç¶IJOÿ¦í”\`>Å42Íi,ðìæ“À³ÁŸÎÿ~ð§Î™ÓòÎ)ÂM·rhÍÛÎiÍùÅŠŽ¢AUßÕ ¢”Ùösàf¸ÀòŸÞ9sêÿ×9Ólmìo¶ÒñjÍÛÏiÍ™›{~(†:—îŽÎEû¤¡üâC´z×îzט÷æSþÂÛc÷ÞòØëzk÷Öõ.¿±µ%wt¤ü9Õg'L?ÚlÚH—ßùÕÀÜK„>]T¦ú®Þxè»:¼cè«áÔ© ·gÖaW}ÁUÜuç—Á]”+Wý7;\õGß­ÿÓÑw›­¿w/.ë¶¡S|n—/eH­ë?ø»ºþ¶/|m5–·ÕXÞl]Š´=ØiΆÒ»vß×»¢¾©ÃQ_f´fíE­™rKm-³ì^ÓkåmÚ"3¾³KfÎD+¤§Êýos¯…´Ì×\VJ*¤ö.•Ÿ\J@ôí9„~“¤ß‡+Ýç‡+5²íßjdÂ[*´Ÿh/j?QUÿ0'%Ù9IvFZî¾i¡-táG§æ–ÞÚ-½u½ûv×õÒ Ë¿›9õš~¼~ßäu¹QV.7ÒI¹ö“×´ŸD¯Gó·QðKÓÂ_­Ö±RÓÅi "¡£N°‰ vìê_ÿcìªðr.÷XQÊpK¤:Ü"<:>ÏÂ8ä™Ì¿Í=?tŒñªØÉxÕJ­xBëMÐ/á}—úö]¢‹«ÞKç~Ó{©Ò¼óZ¥y©c\¾¶"ó³(‡4£ÁÛ4úƒ·I| ̵D–ª«|üu/nÅ™u˜V#¢¹ öéh‚•Ë2cÔ7u$êÓšwüeñ@ž°¬—*eÊ•FV~Z#£Á£ÌaŽ7U—øD/ŽXfÞ„%By˜ž{xlznù²[¾¦í̲˽§ÊÖêsÿÛ\kcámgùºš™¾°xþãÞr/ex›Ñí9eùý1]&i&Ëͤ¥·öŠ¥Wß³û‰¾'3åØÕÇ®ò'¦ Ã0L óÓ²(+?ÿýàOAkhkÐêÑŒxôÃýîÆá~oÓÈoÓòï®D(¤ZÜ”Në_übܼǴ –_ø—Áò>÷·æ>÷ 3ôÕ èXS.ù¡cdæÊÌŠ­`¶|¼ÝléìiOtöÐ4{î]î;î]ápÉ’ÕZòÚò -ŽÛÐÖ´¯¡a˜cÅ(“¬«2£¬\fdææuñ·úâ†ýý¯ßµû—ú]̳ù'Ì35³•Q34³`Ñþe½|)ë\»ïë\>ãÍrŸ‘-¯–±å¥P—t®÷®é\áéH<zÓûâéÕ##ÕtÓÇ› wƒê³®UœÅYá]÷¹ÇŠŽBxt4/ƒ&œ/ÿéŸ÷ÆCßËÛ^®ÝÍö·¹çG ti͆«gÙ°ýÐÿý¥·v¯¥7—¿[[ A¿~kd[Z¯i’{ ̽D ÷r5¢Ïøƒ‰‹ß &ůú·0=Í&ËeÏÝõßìè®§µK覕R¨K ªÆþ­[AÇ.Œ=ÊnmrÛ­™›Ù¾¨¤r¯i…DûÅàQѳ6–BíÍ¥”DšðËó òÑš½—zªz=ë„î9§'¡ÑÚ}ô,۽貪ùбÿ§ù¥1müøÿ2m¤'¤äòn&W}×ÿpÕWº¿®¤¿¢ÓöRz³µér³U‡ÜcEG1˜jLPÊHÛý}‘¶3–E—v}îsæ>7-|õÝÿmÔ§p¼³Káȯì¤C%4ý¾®×òÚÕLò«-¹Ë\—ÖM XåWs/‘ÂÑí3æýµñËÓNúîÿvÒxv{>ðŒn5 å¾ÿ¾Kç>î»i{ðÛHݲôfë­«BkUÔõ×~T×OŸNÿ¦!þAگЀEŒ‹Šq”¾Ï}¾©ÏM%•{M+$ÚFÅÞÍF­›SÌ~©˜µñÍÖÞÜK Ï5M`5£eË CÏžLœoLWå”ÈÛ §}³µ1àfÒ}GºµEPÊ‹‚Ö4Õ‹~­Mu¦n§:™ FÍT üÔÿ/?!2(€7[M÷n6mlèý¬«¡—a˜(ÊÞ4Ì4X„fšüÈ„A€,0hM²À  @e´, „Gd±naaaaa*£ÿ«ë³ì­ëC8àmæiöÞô4GZ'ª#­eÂ7¼öÑ[^;o›Ì{qÊrIP ÜÚËçÝÚâ|V «‹Ùòñv³…aæ“ Ãèó©Wïϧ&˜O¥/·$ùqù¦Œ´ÝßiËü”_ Й0hÅŠ šDZï½i]·nݺuë„“^Þ”RËO©)$>¥[”>3M rT]ßuT]!ל®ËMrܤtn¶(´=Õ‘ºê(dÿœ6ÂùmQk£-*7mÐñû':c”ÂaʉðµmðD´m°ðãõ6Œx›Íû÷ýʼŸ¶P~ØHõ,ÁðÄRjêÌÛkꜚ?©œD£Ôâ›:Ówï~ ïF}XK*Ök¾®X_È0hR…cS­Â1võÚݱ«i:–öÇ«b'ãUé7“Ôõ[öÖõ²û¡–ýP‚M %Ød{|(Ù½ù zÝ]yù¼»r0þ}Ó`<ó¯Òþçá´ŸòC¯®†o´®†BrB@¶©#'lSÓ§ÒÓ´=^ŠW9ÊO¥å¨™h0+¨m ê[ŽÝh@LJ-ž\`6Â"m÷vFÚ¤øC}(õøÖVõ8ý»¡IMœš3Z§FR׫C4?Â=rÂåü\Œó S& {“ÒXfR*Ê=J'ÍŒ0)?ÚlRÆÒ?‹¥3÷ßÝpÖÐÝÀï_®‘›Ô¡­-êÐ`üB{¶A„¾áï¬}Ã4'‚^½Í£7½Í…) FhkÞ»¦­¡-2Ó;:™ÉnmrÛ­Ô T¾ûžO2ÌpåÅ3ÕŽòÓ2G9íYÚÒ¢ 5[¿¸ÑlísŸoês§¼âìãž8˸. wí¼¦wñÇ[¦™ŒÊ½›J†)S–“TÇSoª£®ïÓOëúø™5Ê=JçR3eøúóÑf“’jÍúñØÿzÏc/…†Ú9sZÞ9Ó6Ðj ,¤>ÓÌ#šÇÄ·—åÚ—pþÍΊ¢8ó)'ª#­´·ÌýP{¡¿-N~ò‹§ØüÐç²Õg'ø-ô‹giR?ó«Põ¸º.ªX¿½WüЉ$ƒ&“¾è‘I_l.v26¯zÔ¯Šq¿ˆqmC'¦Ú†„)éñ?Žò.•£<Ù‘¼ìH¶'ÉvUPõ™*X×ðw‹gjÐErÛPËxÛ·i䊷‰fRÐü ½Kw‡¿˜Ju¦n§:“O¼ÉŽfëçýÍÖÌœ¬¬@êö| e¿ßÎo±ôÌ©Xš)^D£Ï²—¿¤Ô¹vÝѹ¢¾û¢¾,U$´µU¢Ë9þrq6²ørQlyidÛÎid4³f01Ô>˜ íœ>µôžÅªë·¾,qšYC¥fTTÏ™é-ý-ýÙ–ãͯ ·Ü}/ÜâóÞøÑç}³ 5:ö`_tŒjB³õØfkf±õ™fúĸ™S1.6;›K¶?ñ&Û©†Ó~–ÊÏpåÈÈp%Ň>¥súÄ$?cH׽뎮[TÕ«ƒ™Ñ®¼üýp¥uò`£u²8ùÉ/žbóCŸÜuç—Á]ü–œ¥UHý›(ÄRÃ%B¢‡N,½µZz…[Ä ·Üý·p íaz.vrzNø®§Éûƒ§‰.¹sÙS¦XœŸxU|0^EÛ~újà§ô­çáô­åó“lâI¶ó{ý+´ ÿ³þÛÿŒŽtòzôÐäõ|ãù`q@.†w¸ÿ<¼ƒ®‚éZ ^õį¢óvþõQw¼Š®ùׇvþ•®Gø×ûŸL^§} ?…®,rši’¹°èòé5ò-Ç5‹¦ñkd[kd©Î§£©NávŸçÚ]Ÿ‡³átzãÆ·72Ì|jñžU!U½*äiºrÅÓ䮼ø»RÙ¥®WvUÖh/VÖø<7ú<™ùQ8{Nþ"¿L!3òïd_¿@ìñòÇrã¡ÏC¿Eû®^ûßUmÍŽ‹üm;b)ïìR8èßJ‡bÒ1~xlúÅÍJÉÎçÉNº”£ðéFZmÄk½éµ^^t#ÒàOßÿ~ð'ÚBÃ[ôK¾¥ÿÀ§–<×p‰³‰ q–ÏOùéÅùy]úìù/|œ2ÎÆ‡âll.z86½=½®ªëÕAvbÏ?³šõÛ¿Õ¬×ȶ¶,þ,ZXÔç½ñÐçm8m[rÝŠÜë³ðxÙ‰êYv‚Z ½Öì·|T³ŸÖæXê³´5Ûν®6ÒàšÏ{í®ÏK³“¨æhÍ;þ¢5 kWqò“{< ÏÏÊÖÏüꔚ²\eNS_^,ýøl,-¼´ˆqÎÆ8…cÓwü@@ÂJjÆ-­5ãž&÷yO“¥¯Ökéc:Ê”LG y{>4m4þ³i#?´ñj½ K_í^KŸ¥¯vÞÒGï:5R;5¶)«Á6•d’· [ËQìñÒê ï6]nx7ðìÆžé"ï?ÖE ÉEOf”]—é6ƒóƒYˡڢ5¿wMk.¼äR^K¡Û:::Onèè|Q^ ̳ 6ê ê3ua˜¿ñ·&iäÛ¾]úÒtqúìùgæ£Â"#\@Wfb™©•ù2ÚÊ´~É´òkX^üï%GÅi¹£¢Ùú{w³UÑ Ð*^³o.õùåñ^gZlXáÜdá‡W Å\k~ïwZ³×~-èµÓ9¶Ië¬m’a˜hFü%ÍOîñ,,?¯_‹Glý,¤>@édM“ΙS\ç -»HO]qýFë:Ú :üeƒŠÒÐóeh.‰Â¡øµÂA—.4˜â¬øZæ¬ÈÜ3½K¿ÀóË:ÒO™‚adF™æÕ,’bèþî`ß0 —wÝþ9¸K×ýþÝk\J«d.«¹X™’al“‡¿´MÒâ‘ôË?­‚Ñ}´ÇÐ}´ÙÚØÏ¯Œ@KTÒåœp‹³âOjg…Ùòñ6³¥ò¢Eyéy=\`>ÅÿbÏù¹ÎO³$t®÷ïë\ùE’æ\{7mCíÿ§mˆ_‡e>ÉÏâÉLO79+NËœ”’ŽÚQÑ¥vT¿9Q”¼ökw½öÎéÑ¥Wè[ŸiÀlÙ÷¾ÙÒ|¨e¼ùðÖT+hð®ð£°MZ?·Möºû­½nZßÄ6yðsÛ¢ÕLŠ“ŸÜãYH~ÔÁMµê ý;¤»·3¤+¼~æW ÔH2hBOWѬ×|­Y¯ßÚ¢¯4kÿRi¦_) Í  5#lSGþ`›¢aŒ÷n6n4[öíÎ~‘?Ÿâ¹Uvm¶(»è¯<ö+#;-¥YÌðÙ5ýOû!º9Eß³û¾'—[{¸ã1næßcÜò8í½Ôc轤 nªUéÆ í'º¿i?¡%9ÔŸ÷7¨)e²sv"ÙiÚ¸w³i#Ý’ ×|­W86YŽÁŸ†Úùjò+/ºEˆnÖ 2z±½k³EÙãŸqž¦‘+ž‚âïirÿÙÓD1¡ã¥§Ñò™™é½M—Ï{›èÓé¹'£bÏ?½naN)Ðð-6œÛLqõ™ædɲr¹‘nzùü—Yv"ê›:œma`±hˆ$¤ÿÛ†Þ®zdÓ­^YËKÒüˆg~ù¡£ë˜>™î˜6ïß÷+ó~z’½R?Å×(-ëhz2‹×>zËk§- ,…«ïÙýŸúZ8³ð‡ ¯v4ǧò“×*?‰Í=<›£¹ ¨-ogïÖJ±gkô`£õŲ‘Ö‰êHkÙj ”ºi¡{YèF4ÍœJûŸŸNû Äõ@j4ÀAK4p†á‹&3Ÿb˜t`>•~ù8ˆW÷yˆ³ñ q6Á&†læ§üb­† 4ȃ&Y`Ð šd±bƒ&ôÚuëÖ­[·N¸&í›Rjù)5…ı-<&RÇeP8Ì4)ÈQu}×Qu…\sºB.7É5r“Ò¹Ù¢tÒöTGêvª£ýsþÙç·E­¶¨Ü´AÇï¿3ÖžèŒ S /’)'Â×¶ÁѶÁÂ×Û<2âm6ïß÷+ó~ÚBùa#Õ³ldµ\œGǦGÇôÝ»èñÈdÄ`I4)ˆÂ±©Vá»zíîØÕ´?KûãU±“ñªt€›Iêú-{ëú Ù¿ýPKÈ~ˆžl%Û£×#D¯»+/ŸwWÆ¿oŒgþUÚÿ<œöS~èÕÕðÖÕPHNhÈ6uä„mªsúTºsš¶Ç«âCñ*Gù©´£|µ”˜pHÛ½‘6ÌÂ@ü–"É ‰SsFëÔ¨CêzuˆæGØ¢GNØ¢œŸ‹q~aÊ„áqOÂ`RËLJ¥S¹G餙&åG›MÊXúÇc±tæþ»ÎºøýË5r“:´µEŒ_hÏ6ˆÐ7üµo˜æDЫ·yô¦·¹ð#¥ÁmÍ{×´5´EfzG'3Ù­Mn»5º³!ÊwßóI†®¼xf¸ÒQ~Zæ(§=«B[ZT¡fë7š­}îóM}îâ”Wœ}Üg¹7Ãô®×ô.þxË2“Q¹w³QÉ0eÊÂr’êxêMuÔõ}úi]?³F¹Gé\j¦ŒØúCï²Õg'ø-ô‹gå³þç—^¬Üë?ų¦Î¼½¦Nš9µT~roùÅ_l{X)’ šLú¢G&}±¹ØÉØ\¼êQO¼*Æ=ü"Ƶ ˜j¦LæS連¼Kå(Ov$o';’íÉ@²]T}¦ ÖõüÝâ™tQ×6Ô2Þ6äm¹âm¢™4ÿBïÒÝá/æ…R©Û©ÎdÇo²£Ùúy³53'++º=HÂïß7„óÛC,=s*–¦AŠÑè³ì­ë£wu®]wt®¨ïÁ¾¨/óoÕ¡­­ê]îò—ß³‘¥/¿s)/lÛ9ŒfÖ &†Ú´óϧVâžÔõ[_–8ͬ¡R3*ªgŠÌôbëÕ–à®;¿ îâ·ü㬜bÖÿüÒ‹•{ý7ï¯ýȼŸJ9ÙþÄ›lÍ=<›£R»+¤=Š~í`¥H2hÂÏŒid&…S±Gál8m®¼üýp¥0¥F^~Z#7Dª"´…þÊnmì·[#mÕ‘¶Åû.S𯓾‡_Lúh8@áÜdQ8uÝ»î責’Ðlý½»ÙJÿ®±üöýKŒûñ‹'ű’7Ÿ’®£çÌ®£ƒ?]øjð§üö“êœHu¾']J£²‹tè7¿ãMC C uói åªïú®zšYCÇn®Û·Û\—ùWâëO1ä^ÿóK/V.õŸâO·Ì,ÎÏ&Ë«üŒŒüc~òibH½€åä4h’¹°èòé5ò-Ç5òE[d[kd©Î§£¯†a|žkw}6bxÌFøÛ+6èä&ãÆ·72Ì|jñžU!U½*äiºrÅÓ䮼ø»RÙ¥®WvUÖh/VÖø<7ú<™ù¡ Qú·ÌX¦ùw²¯§ öxùc¹ñÐ硹¾«×þÃwU[³ã"ÛŽX Ç;»ú·Ò¡Ø£tL§›~q³I²óùD²Sf”•óÇBÇ(üDº‘‡VñÚGozí…—݈4øÓ÷¿çƒhÖÍe°ôøÔ’ç.q6q!Îòù)?½8?KÇ\\ý)ŽÜã™_z±õ3—ú¿8þ¹æ'¿ö˜;©÷°¼œM„“çs¹…!–~|vñZ1îÑÙGÓþi ý²]³ßòQÍþ¶–PÛÝ>ö?¤ýcWÿzwì*ÿ×ÿ8´aé«Ýkéó'óþdÚŸ ¤ý¶Iëç¶IÛ”µÑ6UxPÄ/=SÆ6uä¶©À³ÿx&œû8 a‘ÌÛph‹ÖüÞ5­¹ðãÍ¥¼–B¿öwLŸä:¦Cúñ­!}~yPUŸ©ƒ|~fNe[ËF¨úSøÚ++O±éÅÖOññ—ñíQ\ü¥nïK‘äöœÎ™S\ç -IO]qýFë:Ú :üeƒŠÒÐóeh.€Â¡øµÂA—Rt1ì¬øZæ¬ÈÜ3½K¿0óËRÒX™‚adF™æÕ¯èÅÐ7üÝÁ¾á†w›.7¼K·®èºßðº[¢cöEÇèAÅK§*S2Œmòð—¶ÉΙÓòκ1né>Úcè>Úlmìço» %T…à ´ÅYñ'µ³Âlùx›ÙRHyÑ¢ªô¼.0Ÿâo âüÜ ç§Y:×û÷uy®1As ŒŠ½›ŒŠ¶¡öÿÓ6įÃ2ŸägñÓçWˆ:¸©– éîí éŠ_ÿ I/Š?•àRù±M8`›,¼=æÿRkïð¶‘dЄž®¢Y¯ùZ³^=¾µE=^iÖþ¥ÒL vRšIáªï©rÕÓ ºÑÀ¸qïfãF³eßîìùó)†qTœ–;*”]›-Ê.ú+ýʈÇNKE3|öCMÿÓ~ˆnNÑ÷ì~ ïÉåÖ .ÀŸ@Œ›ù÷·ü#W{/õz/©‚›jUAº1Aû‰îoÚO¬“­“ êÏûÔ”2Ù9;‘ì4mܻٴ‘nQQk¾V+›, ÇàOCíK¯®’KyÑ-Bt›•Ñ‹í]›-Ê®÷ølŒó4\ñO“ûÏž&Š /=í…̷֦þ0 ãRÇôÉtÇ´yÿ¾_™÷Ó“Yèµ8õ¿ôÒ¡L°‰ –JV³^sZ³^#Û~N#sÕ³ÃU_x{ÿÒjïð¶Y·°°°°°@ yzí£·¼vÚ‚ÐÀR"­÷Þ‹´ê{vÿ§¾gaáçg Rßð@ÜÚËçÝZkô`£5J÷Xp†á‹×µœOñO\}¹åå”áýq6~!Î&ØÄP‚¥}ÒöHëDu¤õoC@aeÑ-Hüà†K`m  @4ȃ&Y`Ð šdA€,D šØ¢ÖF[Ôç¹v×牴Þ{/ÒÊFªgÙ‚kˆA“þîÎ^ïÚ}_ï êïî êÙ°áF`íÉiÐ$Õ‘ºêH¸X:  ©êU¡ >´5¨gû`ÐÖ¢²åß–›6èä&†™O1 ×5ŸâºäÆ ·åF.0;Á¼ÆÑ]^#cªïbLiÿóHÚ€ÀÚðš™&4Òl=æk¶ö^ê©ê½›{x,6§‘•ÿQ#£w1\kON·çõw6õl¸z– Ó¿ áêYnÌ€5kÉÛsøs†aèfÖX½‹5r®‘ Ȧʲ)93zSÎ`¦ ¬=KÎ4¡¡O“û¼§ÉÒ{à€¥—¶hd[Žkd±¹ØÉ؆K`­zÍB°^ûèM¯½NQûa"Zþ`_´\áØô'…CÕªzOÕŠðÀZõšA“øPû@üå62L¸æ.®Aà`mûB ƒ&Y`Ð šdA€,0hM H춦Ëv›Ü$×ÈMôºTÊHëDu¤uù4o³µŸ•®óI†îmݺuëÖ­£í«ëxߎ:|ï½Hkîe$6=ú“•ŠÞJ|:úóÕ]‚ bÐĵ6Ú¢>ϵ»>}…³‘êY6’ß OlÑ#'lQổ5;¯UÖ¼©S„èØÔá蘾{÷}7ªHá†Ç= CŸû;kŸ;Üù Ü’ö§ciÿRéuÝ»î躗O³–ˆ­o«=>ÒÔ‡2%ÃPšà®;¿ îZ½Ç[ –¿H[]—pbÛ úÿåëƒpàOß­»£ï¦a‘Rî¯ É¿ÔPßJŸˆA“þîÎ^ïÚ}_ï êïî êÙ°á.<Qßý}Qý›.0¸Àl„ ¼© Ð§GÚî팴áWÂÅÙ§£q–þ­­ÙvN[ƒ˜¼Íõím«¨ÿhkIÚÿ<œöÓ ˆÙ²o·Ùb›:Øh›BþQßÖªœMR©Û©Žt€‹¥ªª^ êC[ƒz6¼ûÁJ š°aÃc6Òo é<öÑ›;Êd¦¤!“ÒXfR*Ê=J'ý^dR~´Ù¤Œ¥<KgþUwÃYCwƒ:¤®W‡(½:´µEŒ_hŒ SÒ»ìDõßÙ ~Ë=ÿ«TæcÎ?áüGÕõ]GÕ|~6èä&š;Ãù¹·è·5áï]Þæ‘os…\sºBN{®ëûôÓº¾B"™êxêMuÐ~('”«¶ÁѶÁ¥âYSgÞ^S'LOG$Ì¿0çÝ g´Ý Jçf‹ÒI¯ÞæÑ›ÞæÌýóñ4<ÎÏlé7èÄÜ^‘0$†*}aÉÒñ ÷°Ôoã¹ÿ¢žKy‰­Ÿbë›øøH[¾bI]ÄÛ~¥>ÞÜË«8ý‰XbóOœš3Z§†ïŸ_ÿÜÓ‹­?bÛc~ñÉ¥ȯ=òûÕR}ðØÿzÏc—¢Äk,æm5–¨oêÿ³Gqúóâä?¿þ?÷úŸ_}ëþÎÚ7œK}(µó€Õë5ƒ&ô«W׫ÇlâB‚¥-îÊ‹gÜ•¶©ú.Ûm)$f˾÷Í–1ï_ïy}Þ?ú¼fËÇÛ² š¤ó©tÀQÞ¥r”';’·“Éöd Ù® ª>Sëúþ®®_˜žNbÚ†ZÆÛ†¼M#W¼MôûRôzäƒèu½KwGïZ´ÿŒéýÂ_¥2'Û¦Žœ°MŸ™S1.6;›K¶?ñ&ÛS©Û©NúÜ¥Žz¸rdd¸2Ür÷=~º~çô‰ÉÎéB"Y×o}d{|(ÙžìxâMvÕ³FE–Èï¯ýȼ_áØT«pPÎcsÅæ&}Ñ#“¾¥òϸ =7[?ïo¶¶ ˜Ê–rùxfKÿ<"æö Û”µÑ6¥ nªU©&D¯ßß½ÔßÙÔ¯lSÉ¥¼ÄÖO±õMl|¤._±¤®bÒ~¥8ÞüÊKºþDtOžWþéÝØ\ìdl.^õ¨'^ã~ã–ªu¹§[ĶGÑõAdÿ ¶=Zú6Zú5²-Ç52Ê9ÕúV]éÒžO2ŒÇî½é±ËŒ²r™quõç¹ä_lû[ÿó«oÔ;åRJíü`[XXXXX°ôÖ~hénjør²u ÷Ò¹ßô^ŠWÅãUYù5²…„[îþ[¸…>1}+=¾¥síúu.£bÏ?Âw~~öº½ñ§eŠÅù§ÜÒöŸ†¾ø)}ëy8}+÷¼-õéÉö'žd;¥¡u „ïúŸýðßþgtò´Ôž'¯GM^_X!ü‘2 ÃLÏ=´OωI;¹8½§Éûƒ§I˜aÎéØùȇþ•?á+$žbÓç’á–ÚçòŸµRåµTý|³ñY©ò-¤í¯Ôñ§ýJw¼bËKêþD¸g™ñ]2cæ«ðˆ ©oR¤/f}+\fÿ ¶=ŠíW¢>ÈÊù׎é¯âÓÅìÏ‹“ÿÜÛW~í7÷øˆ­¥v~ …áî?ï Ów_¼ê‰'^EßËüë£îx};ó¯íü+}ßÑ«ÿYàgÿ3á> }“æt{ýÎÆ«gÙ0ýÛ®ž5¬À9/NbLe ™I#Ûþ­FfTìÝ”mN¡ehÙˆá1N75nüx»q#Ã̧§§›‰2âµ~cާùÊOsGì«DG,ó]ºÛ™¾ìÛZBm4=•NâÇ®þõîØU>í?^ÚYúj÷ZúüÉÀ¼?I'L¶Iëç¶Iš œ-/eÊ×åVT}¦Ò¿ãU±“ñ*áEÿZ¼çóKϜʶ¶ËÒéŸ]œ>Æ=:ãè—¨Ò¬¸¹ä?—2Mv>ŸH®À‰l!õ3—ú&E|J¹| ó*žœ>•m]ŒÒn¿k³=.•©ÓRVJaýƒýáÊ  x»µÉm·º+/ï®”®þ¬öü/]?¥íÿK¡Xí–4¡¯UO“û¼§ÉÒ{à€¥—¶ÐýÒt?9m)NFÓn& ßâů:Õ “QgÅ×2gEæ_Ñ»4£„_öŒNPÊ #3Ê4ÙîdV7Õò'!ݽ!]f…s“Eá¤ÕXšµŒ7¢årùÏ}Ü“0ÐRjʼnÍ©¡y:mCíÿ§mˆ£SðÌ95”^çzÿ¾ÎÕ9sŠëœ¡øÐQ¸Ž~£uµM8`›,ÍŠKù7„?xnwδ'þ1ÿ=×Qaz­yÛ9­™Ê]X¦^ûèMï ,‘˜_ý̽¾åŸÕ[¾…–õR«9”fû]íí1¿ü/•¾AuøËUáéÅ’¢=Ò?ˆí§eÎ êùiipGE—ÚQÁH€Ja¸Òýýp¥FV~:ßù bûóÒÌ~õ_ŠúVjýÀj÷šÛsè’²®·öúÞèØƒ}Ñ1…c“Eá S„bf”n9qÕ÷T¹êmSGþ`›¢Ý÷n6n\êi;t’ê¨8-wT(»6[”]ôWû•–†ÍüUhK‹*Ô1}2Ý1mÞ¿ïWæýô¤z¦¤A%¹QV.7jÖoÿV³þåzø³ìDÔ7u8ÛšüÒñ4¹ÿìi¢Óeº‰VפnÏRÙÒ\ñ4Ñ¿ÍzÍiÍzlû9ÌUÿÍW}1ó/öiT‚ öéh‚Uv)Ê.}‡ž‰À§*S2ŒÌôŽNfrÕw©\õT¦l¤z–¼éú)®¾‰O©•¯ÔõPYïújxGûß5¼ûb?%^zíwu—W~ù×»v^Ó»4ë5_kÖ«Ç·¶¨Ç+ÍÚ¿TšiÁÔBÒçWroÅérçmº|ÞÛãŸqt¤ÚOtÓ~B+…­\«¤¾Z$žž>3vuô‡Wóe¤íÏ‹“ÿâÔ)ê[iöo«×:Zमϲ·®Ïk½åµÓ„V¯@òæ“@’&Ãs>¬,ôçÉ­½|Þ­µF6Z£4»– 0 X¼NÜ|Š‚áË-/o…æó)~…¯8¿glb(ÁÒ>i{¤u¢:Òú‹·! °VÑäön| ?¥™&!;+ÎT:+,½ûvóÏ„€R†þJM`£•Þýü»†wùéÖ[[Ôã ‡bÂÑw©ÿ`ß%D  ô¡?€ÒT†ÀêE+LŽÝg&džهˆ¬NèÏ 4a¦ @4ȃ&Y`Ð ƒ&¶¨µÑõy®Ýõy"­÷Þ‹´²‘êY6‚ ÀÚ#bÐ$¤¿»3¤×»vß×»‚ú»;ƒz6lxĆDX{r4Iu¤n§:Ò.–¨BªzU(¨m êÙðî4€µ¨lù·å¦ :¹‰aæS Ãuͧ¸.¹qÃm¹‘ ÌNp¯qt—×Șê»SÚÿ<’ö# °6¼f¦ …4[ùš­½—zªz/Åæ‹ÍidåÔÈè] —ÀÚ“Óí9Aý A=®žeÃôoC¸zÖ€s`ÍZòöþƆaº‡5Vïb\€k䲩2…lJΌޔ3˜ikÏ’3Mh(ÄÓä>ïi²ô8`é¥-Ù–ãYl.v26‡áX«^³¬×>zÓk¯SÔ~X§ˆ–?Ø-W86ýIáPµªÞSµ"|°V½fÐd >Ô>ùŸ ®¹Ë„k8XÛ~d  @4ȃ&Y`Ð šd±jM"­÷Þ‹´®[·nݺu 3Ÿ÷·Õ‘V¹I®‘›Jçˆì¶¦Ëvåjù¼å–ÿù$Ã÷–_¬J¿4‹OXÛJ«½¬½þ `m1hb‹ZmQŸçÚ]Ÿ‡NñÙHõ,É—+‹–Ìí…¤®{×]wÚŸŽ¥ý¥ô„áqOÂÐçþÎÚç·D>·,Ÿ·Üò_¦dJÜuç—Á]oO%–&ž°¶¯½DǦGÇôÝ»軥Ø?ê3€tD š„ôww†ôz×îûzWPwgPφ Øp~L§ø™-iÿó0¿}­^ÄÙ§£q–þ­­ÙvN[ƒŠˆxÂZÅf#\ Òvog¤­4g~ÀRr4Iu¤n§:Ò.–¨BªzU(¨m êÙðîùš¢oø;kß°Ò¹Ù¢tÒ«·yô¦·93¥Ü´A'~ú}wÃYCwƒ:¤®W‡èoÕ¡­-êÐ`üBû`¼œÓÞØ ÃcvâeõKÏ©É/ÿ¹ãü³ÎT]ßuT­t*÷(ô‰¶è‘¶(ççb\AƒV4Ĥüh³IIGQ!ל®{ì½ç±žéâ)¼]¢»áŒ¶»!—ú–_<¥«ob÷Ÿ{þù[B6èä¦Ìã¢øPYa)x›GFø}ÒQÔõ}úi]_¶úf,3)ùýË5rÕÀXúÇc±t1{*¾~Vÿ=[ý\ª–JÑ¿åWŸ†ÄÐâöK5§mðD´mp©O[Ÿi&N…|û·‹k @)xÍ  ”«ÇÕõêñ›¸`i‹»òâw¥mª¾Ë6E[Š™éTgêvª3ÙñÄ›ìh¶~Þßlm:1Õ6”™2í3ýž.ºÚ†ZÆÛ†¼M#W¼M4Û%z=òAôºÞ¥»£w’óågÖž±lSGNئbÜÌ©›‹ŠÍ%ÛŸx“íaŠC!û·ôl´ôkd[Žkdt¤á–»ï…[|Þ?ú¼…ç§8ñä\Œ äRßÄæ_êú&vÿ¹çŸn QUõê`fiW^þ~¸Ò:y°Ñ:¹Rõm¸rdd¸’êEçô‰ÉÎéEå˜O¥Žò.•£<Ù‘¼ìH¶'ÉvUPõ™*X×ðwuýÅì©ò›I']ÿ&¾>[mSªà¦ZU"½~_ôzPgCP¿Rý'Íĉq?~ã0J΂¥·öCK¯p‹PëÀ—“­½—Îý¦÷R¼*>¯ÒÈÊÿ¨‘-¬pËÝ ·ðŸþó³×¥I¶?ñ$Ûi{pWè_ù †BöOèè¦LÁ0? }5ðSúÖópúÖŠÊ=?Ò¥§RZDø®ÿÙÿí¦plªU8ò;F>’ Ã0Ós±“ÓsÂw=MÞS†¹Î0ñªØÉx•¹ÉÂ_JîåþÿÆ0±ôã³±´F^~š¿ôŠqÎÆ8†a>*V~¤VHþ¥®o¹ì?¿ükäÛ¾Õȵæ÷~§5{íׂ^;ݘc›´ÎÚ&†‰«|iõšqKk͸§É}ÞÓdé«õZú˜Ž2%ÓHÞž$MÿlÚÈ ¼j#¹´—•j«®>çØ~×Vÿ ðÊ’3Mh(äÅåGï–^ÚBëSÄæb'csko¸„.½èQ~YJºà)S0ŒÌ(Ó¼úU¶tiÍÛÎiÍ”ç¥V¡KV³eßûfKó¡–ñæC´Ü/‡Ç= -½™_è7gCøƒç†°³â´ÌYA—O©Ž§ÞT‡£¢Kí¨(f~¤–_þ¥®o¹ï¿øÛ&­ŸÛ&{ÝýÖ^7Õ7ÛäÁÏm“Å,ßt€›Ih.‰Â¡øµÂAGJpV|-sVÒ^ ¡nªUéß!ݽ!]é÷!ÂöÛ9Ӟ蜡úC¥æ:Úcp]©þ3:ö`_t,sÙ`€RðšÛsh²}]oí‡u½tj«pl²(tJ]ú‡'þéó)†qTœ–;*”]›-Ê.Jã±_ñØiiÃÒÎ?Ã0ŒÌôŽNfÞ1ôÕðކw¿kx÷Å~"Õ³lD˜’ÅäFY¹Ü¨Y¿ý[Íú—Ÿ8ËND}S‡£¾Bòïmº|ÞÛãŸq”sí'º¿i?1*öü“Q‘™^êüäÏ܉ϿÔõMÜþó‹? ‘„ôÛÒÂU aUhKK¶þAºò¥y®úž*W½mêÈlS´gãÆ½›Í–}»Í–¥þ6÷ö’ŠFÇôÉtÇ´yÿ¾_™÷Ó“eèµ”ë3Õût4Á*»”Fe—¾GwGßSc1o«yOá<š|ê3-Lãfþ Á@éYG œÔõYöÖõyí£·¼vÚ‚Ð@¦@òæ“@’V¢Y{ó  ô¹µ—Ï»µÖèÁFk”îfà ïc8ŸâŸ°ùrËËŸè¸À|Š_Q1ÎÆ/ÄÙ›J°´OÚi¨Ž´þâm(ˆE·Û„tã[ø[ŠèögÅ™Jg…¥wßnþ™kkM Z)¦áÝÏ¿kx—–WomQ+Š= Gߥþƒ}—%XÛÊÈD+ÅLŽÝg&džهˆÀÛ3M²À  @4ȃ&Yˆ4±E­¶¨Ïsí®Ïi½÷^¤•TϲÖƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6Œ ÀÚ“Ó Iª#u;Õ‘p±t@RÕ«BA}hkPφw?À  ¬EeË¿-7mÐÉM 3Ÿb®k>ÅuÉnË\`v‚ x£»¼FÆTßŘÒþç‘´€µá53Mh(¤ÙzÌ×lí½ÔSÕ{)6÷ðXlN#+ÿ£FFïb¸ÖžœnÏ êïlêÙpõ,¦ÂÕ³ܘkÖ’·çð7æ0 ÃÐÍ8¬±zkä\#M•)dSrfô¦œÁLX{–œiBC!ž&÷yO“¥÷ÀK/mÑȶ×Èbs±“±9 —ÀZõš…`½öÑ›^{¢öÃ:E´üÁ¾h¹Â±éO ‡ªUõžªá€µê5ƒ&ñ¡öøËÿld˜pÍ]&\ƒÀÀÚö „ M²À  @4ȃ&Y`Ð ‹U9hb·5]¶ÛºÎºP„¹ˆ´Þ{/ÒºnݺuëÖ1Ì|²°ô‘Ö‰êH«Ü$×ÈMk5°¶kxé×gêå(WËç-·üÏ'F¸7´…µQ{‹UÖ~ÄPOXýZHAÄ ‰-jm´E}žkw}êDØHõ,)<u}–½u}J§rÒ™KÇÔ9}*Ý9í¨8-sTpþÙç/<ÂnQx¢©ïÖÝÑwÓת ÑuﺣëNûÓ±´Ñ(\tlêptLß½û¾ù)~~J­>' {†>÷wÖ>w¸%òA¸eù¼å–ÿ2%ÃPšà®;¿ îB»[«¤©?+ôç«+?°<±ýÊÖ*ƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6\x&ŒŠ=eFEߥþƒ}—rI¯ ©êU!6lx̆Ú+”´ÿy8í§/ ³eßn³Å6u°Ñ6…êRà³.i»·3ÒV ¿c ?oVœ}:géßÚšmç´5h#€ú³Z ÿ\]ù”/@.r4Iu¤n§:Ò.–ЀEPÚÔ³áÝVbФÙvìF³MkÞ~NkÎý¯ŒŠ½›Œ ¯ýÚ=¯]ºÕXÌÛj,QßÔ‘¨O¸ÝÛ]8TD¯ôÕ’-2ǃ­|'ûªÀh€‰ IŠ*¯JP¦àÊ…òOB˜ÞÓäýÁÓ$Œ­ØôbKJ˜FøÅ¶T©’±å»Rù¡K¸lU¦`:ÅIßzNßZ©šŸßþ¥h‰ùÅGºüˆ-ßÕ©ÓóýØ«“xá»ü€õÊ”oîrïoÅÖO©MÄöo…Ä_êA“\Ú—ÔõýyéôŸ™2ÏO ©Ÿ…[*?œÐéòR{(f}¦ {aä3·Ò¿I÷ý˜{úüÚ£tå%õù'H§˜ƒ&9ÝžÔßÙÔ³áêY6Lÿ6„«g +pcN!Òç‘t€fš¬ðžýÉ¿¦I¼*>¯Šq{bMê¦lPÕw5¨†+GF†+i²ßpååï‡+ŠêçF…*´¥E*$'´ì.MÎN/4nüx»q#Ã̧ø”q6q¿]#ßr\³hšºF¶õ¸F&Ü"6}!NÅ…“*Sð3•„S=Wc~ROGSÂítóš§éÊO“»òâ7îJe—º^ÙUY£½XYãóÜxèó’s©÷Ÿ»üâS¹”ïj1Ë—¨že'ø©ÚtrSÍ~ËG5ûéÞõbæ*÷þ¶Ôêg!ýséÄ?¿þSêü£?Sýgîç'ÅQH~–_ý§˜õYf*SÈLÂÈgn)¤“îûqeûÃåûç•-¯bžÀêµä ‰°‹ éÇ·†ôÔõÔõ[ëú½ö‘¯Þ}SY´=øm¤MïÚý@ï’îSè ÆnmrÛ­îÊËß»+…ïjkÞ»¦­Ñš·Óš½öÑ›^û`â/g ªÏºT…|.­îA{Û@K¨m ÙñÄ›ìHûŸGÒþ±«½;v•O;ŸduPõ™:HÿK?>»øÞÝ÷èlŒn›^j«1?ôKEæßZúj÷ZúüÉÀ¼?Ip¶Iëç¶IÛ”u‰å„Ë”bò&~ÿb½>?…ÄGŠü“ôñ—Ú«xrþùT¶ûð…寊ŒWQϳøµØÏ[ɽ¿_?³×±dçó‰ä ¬Ò?—Nüó;ÞRÈ?úó•%öü¤´óóvÕgé½ùó±åUjçŸPš–4¡nÅÓä>ïi¢»i‹F¶å¸F›‹ŒÍÑ–Â3A¿rù?îK§òË/¬HÝ|HYz÷½ÏßX$þ÷L÷÷ÕYùélãÍôû§£¢Kí¨ˆú¦G}±B>7àfÒúm„ŸMS¦äOœ_ËœÂôô›Ý“é¬8-sVÐÉAªã©7ÕAy+$½Ô„ùéœiOtÎPäib×уëhñóC÷²vΜâþ1?ßh]Gm“Ø&…E¥C¿òµ—N h= ™æÕ¯:¯¨ƒ›jù/ìîÞÎn©\å·±rÉO~ñ‘.?ÅQœøK(Ï>ï}ÞÌ4 ç&‹ÂùâÞïC-ã͇¨dù8<îIh)¾Ì¿]ÙÅSóëoÅÖOaL„uŒ†fV¶Ë¥¿-$þ¥ Ôòþ|eûO±ç'¥œŸ·§>G)œ?ˆ-¯R;€ÒôšÛsè”±®·öúÞèØƒ}Ñ1…c“Eá .f¥2!ÿP^!ÿ0üï—kn(¯H¯™éé‹0¨m êm“‡O¬ô¿â÷ܤW׫Çéé9cWGxõ{Å+”Jcé­Ýké•™dYAsp4òòÓ¹«¾§ÊUo›:òÛ­æmܸw³q#=9Ky5]>ïmŠqÏÆ8: í'º¿i?¡¥° O/õê÷Þ¦‘+Þ¦ût4Á*»”Fe—¾GwGßCÏ0âSoÞ§i䊧)Á&.$Xe×f‹²K³^sZ³^#Û~N#sÕ³ÃU¿ø/æS ã¨8-wTPzЉÇ~eÄc§£Ëüº­ cúdºcÚ¼߯ÌûéI ôZøþÅÊ=?âã#m~Ä·t±õ¹ñ—2ÿ Ã02Ó;:™ixÇÐWÃ;Þmü®áÝû‰Tϲ‘Ååë>ïi’eår£fýöo5ë_~â,;A™ûçÜ à— _ùÖš{›{ý¤˜¸ê»T®zªc™Ñ(œØþ6¿øK]ÄôŸÒæýù›ê?ó;?)Íü¼Mõ¹ýCéœ?ˆ-/±ý3¼mÖÑ'u}–½u}^ûè-¯¶”r¦í¶¦Ëvu¬­ƒÇC­ƒ¥+zx›§ÉýgO“Q¹w³±¤n)XÝÉ›OIš|»Ró›@ NÍŸTNMŒ{øEŒˆµÄ¥øô·o3·öòy·Ö=ØhÒì0.À0\`ñ:Vó)†IæSé—+O½š-¼Ó%ÎÆ/ÄÙ›J°´OÚi¨Ž´þb5¨w¸ÿ`ïpé — Æ¿oŒ+ïìR:pú^šCÒoá§tÒ¤JgÅ™Jg…¥wßn)oÅ€ÂÑbátûG ÅT†‚náQ8ÞÑ)Ã?¹Û‡BL Aw&7ìÿü»†ý1ÓŒ.öbò§Ùññ³£ïRÿÁ¾KŒ“a'bPšÆ<¾‡c’<õý-M ‚[EVÝ™<9vŸ™cf"<ô·P|«òö©aÐ šdA“"­÷Þ‹´®[·nݺuÂáx =¨In’kä&Ô4ÄíV ƒ&¶¨µÑõy®Ýõyè…TϲQ Ë_®®KD]÷®;ºî´?ËmÇèØÔá蘾{÷}wqrXSgÞ^SçÔüIåÔ^^4üA¯únÝ}7 ‹¬T|¤®obó/µâ×"bÐ$¤¿»3¤×»vß×»‚ú»;ƒz6lxĆDXY\`6Â"m÷vFÚ¤¢Á‚ >´%¨o8v£u ð}¦ýÏÃi? ‚˜-ûv›-¶©ƒ¶©ÕÿRË1ë€PNƒ&©ŽÔíTG:ÀÅÒUHU¯ õ¡­A=Þý`-š85g´N:¤®W‡ä¦ :¹É=rÂåü\Œ{1ÀÛý´®¯ú™_}èþÎÚ7¬tn¶(ôJ­53%çŸp~útÊÉòõYìñÀj÷šAº„P«ëÕã 6q!ÁÒwåÅ3îJÛT}—mж¬¥ Lú¢G&}±¹ØÉØ\¼êQO¼*Æ=ü"Ƶ ˜j¢4–¾}ï[ú¸7ÃÉÛóEªƒ‰‹g ªzgƒª˜97ï¯ýȼ_áØT«p$ÛŸx“í±¹‡ÇbstDmC-ã|þÅo~éÓþç‘´?¸ëÎ/ƒ»rÉ?Ín¦ÎzXÙX¢cöEÇ©ÛóT³õØfëJ—Æ|’aMu ·7¨ê»Tô›3M殼üýp¥QQýܨP…¶´¨B…ç'íOÒ~Àâç&ÜþyñÜ„8›¸gÅæ¿8éK -,êóÞxèó¶ œˆ¶ ¬ìþùòJÇÒþxU|(^ã÷Ä8ºé#¿}æR¾o6ÿÚšmç´5…ä¥êpøCf,S¼š#óêÆ%a~؉êYv‚¿UjƒNnªÙoù¨f?­¥’ßñÀÚ°ä ‰ð"¤ßÒÓ¥E]¿µ±®ßkñÚ×Þ9$–~|6–^´…{t6ÆÑmÂíÚš÷®ik´æmç´f¯}ô¦×>˜øË™ÁDƒê³®âÞ˜£ª>SÅæ¿8éÅ+SJ+GÅi¹£‚æ#/°¥@û·[›Üv«»òò÷îJéÊwµçéú³òõA˜ŸxUìd¼J8(É¿¾Éç@)XrЄ.zËk§-XôpSO“ûÏž&£rïf£1)±ôÌ©Xºò“×*?¡'¶¬¥¿@òæ“@’VâX«ó¿ˆ[{ù¼[kl´Fé!\€a¸€ðqôït`>•~¹R᫟0¹À|Š_Á0ÎÆ/ÄÙ›J°´OÚi¨Ž´þâm¨Ôãß7 Æ•Žwv).)MyùiœVïp =ƒ&¤ßÂߢB7•8+ÎT:+,½ûv[VËV š„na 5~jø 1é¤ÜL:Ððîçß5¼Ëß>³µE=®p(ö(}—úö]B”VJBPÜ ÅDóe&Çî3“c ÃìCD¤„™&Y`Ð šd±*M춦Ëv[wÃYCwŠ0‘Ö{ïEZ×­[·nÝ:ác–òKO^’›ä¹ ±…·¡E u‚¾µé[cùï©¿_Vûþíåm«o¥÷}=Ÿdaéà\àm bÐĵ6Ú¢>ϵ»>ual¤z–òñGÕõ]GÕrÍé 9u=Jçf‹ÒIÛéqª™Õ9}*Ý9í¨8-sTpþÙ·K± ;eaW¨ïÖÝÑwÓת ÑuﺣëNûÓ±Õ¶®°”éÁ½kû«®ÔŽ÷m‹?êêâ“0<îIúÜßYûÜá–Èá–å¿;¤þ~»ÿèØÔá蘾{÷}·û(åö"5±í«4”)†bÜuç—Á]oOý\å°2D š„ôww†ôz×îûzWPwgPφ Øp!¯plªU8Æ®^»;v•: xUìd¼Š­Z×oÙ[ןùWªª^bÆÇlx0q¡}0±²AIûŸ‡Ó~ÊÙ²o·Ùb›:Øh›BuÈ]œ}:géßÚšmç´5«+ÿ\`6Â"m÷vFÚ0œh/h_o3”¼Ír4¡éKhÀ"¨m êÙðî… š¸¾Ñº´5ï]ã¿d¦wt2“ÝÚä¶[©;©¥þ֨ػɨðÚ¯ÝóÚ¥ Pż­ÆõM‰ú„۽ͣ7½ÍêÐÖu(ó¯Üڋ߸µòíßVÈ ùtúÍÁ¤4–™”J§rÒIó_LÊ6›”±ôÇbélé?ÚlRRJšÅã±ÿõžÇ¾ôþsM/7mÐå6QøiwÃmwÍ!¢WŠ^¶ü$†ç‡"Ü6x"Ú6XÌ_Y…ùç'ÊnÐÉM4¾Nù\‰òw¼4¯Šæañûß “›lÑ#'lQÎÏŸ5øÛ&݈§©ëÕ!a”ãÚã™å%ŒX.Ózš3Z§†ßöx¢>”±ñ–š·ydÄÛ,œÕX×÷é§u}™åUSgÞ^SG‘¤¨R„—ª¹Ô·üêôñ×ÿ‹­o´OvÂð˜xù ¢_úv©¿_rßÿâüWÿ=[þ3Bìþó«o¹oîý§Ôò;_’®=¢½äR¤þ~Û¾HßðwÖ¾áRȾõçõç¥Ù^ò+/€5eaaaaaÁÒ[û¡¥W¸…ÈŒïì’eFY¹ÌÈ0e †¡-”’÷]2ãŠr”ŸþG¹!\õÈ^*ÿÙÿí¦p(~­pþ‰á–»ÿná#ðó³…zmør²u€"°ø/~~¶°@3eüÏ?ûŸ ߣGy×ÿp”’«é¹ØÉé¹à®Ð¿wÑ–ô­ôtú–uòð—ÖIëýû:—0½!üÁsC¸Aõ™³AE9L¶?ñ$Û)åâ£Ë'ýÒ±Z.žTš´½cú«xÇ´F¶íœF–ùWFÅž2*¬“?·NÒ‘&Û“d;Õ„å?qe-•ʽ^^b—Ú)ý¥¤¿2[ö½o¶4[ïn¶.¬!ñªGÝñ*ŠM‚¥íTKiêòòu2—íT:™ño¶óññD}(bã#,5Kï–^ª9Âw…û§Y\žx^Õ‡Wñ,¤¾å^¤&¶ÿϯ¾åò}Qœïéò“_úüê[îÇ›{ÿ)½|Η¤kh/¹ÔŸâ|¿¼ ù'bÎJ·½¬l›(Üð÷Ÿ‡wп©ÎÇ«žxâUñªøà«×GÝñ*jƒüëC;ÿ:y=zhò:½R‹ù‘Â-¯4!4pÐ{éÜoz/ÑÇkdå\ú¤¤üPȦZ…ƒ`©”Ôõ,•çB:>áP½Rל-2ǃ­ü—è«£&*$)¢ÄßEY¦àÊ…òOB˜ÞÓäýÁÓ$ìæÄ¦Ûi Ó/T–*µBò#aþ)o´}ìªï¿Æ®Šª+¼¼øzÅ0 “y²+l5k©+ä£T¦`˜Ÿ†¾ø)}ëy8}kùò{»Tü…ñD}(š ®–Úòß&¹ì©ú ¶¾^ŠÏBê›Ô¹|¿H±é ©o¹oîýgqä~¾$u{D{Y¾þóûåmÈÿò2ÏJ¹½`ÐJM1Mrº='¨¿³!¨gÃÕ³l˜þmWÏ º1'“Ïsã¡ÏS×oý]]¿ïêµÿð]ÕÖ츸ôýœéÀóH:@§›+›“´?à×4‰WŇâU1îqOŒ£I}” ªú®ÕpåÈÈp%M~®¼üýp¥QQýܨP…¶´¨B…ÅäÚ]Ÿ‡³áôBãÆ·72Ì|ŠOgøû`5ò-Ç5‹¦íid[kdÂ-bÓBáTìQ8ù©2?SI8ý¯˜ùKÚTË—£:¸¹VLu¦þWªóM•;Q=ËNðSs7è䦚ý–jöÓ½¦ÌB7zš®\ñ4¹+/~ã®Tv©ë•]•5Ú‹•5Ôcþ)KÅ?Õùt4[)£>_áýÃò«ä²ÿ¥êƒtýIéij”ë[.ß/«±>/Ußr?ÞâôŸ¹Ëý|©˜íí%³þ ÿRÈý|`µ·€µjÉAaÒo é©ë©ë·6Öõ{í##^;½[x&ènsÛÔ‘?ئÏnüWà™!RõØðšçòDÚü6Ò¦wí~ wI ê iwååïÝ•Âwi5­yÛ9­Ùk½éµ&þrf0Ñ ú¬«AUÈçÒ]îÔ¹· ´„Ú’O¼ÉŽ´ÿy$í»ú×»cWù´óI†QUŸ©ƒôß±ô㳋×JˆqÎÆ8á±é¥VjùY\OGùâì“Ñ8›9TWÌòz±X²ÿy$í_üº6Ÿ×`é«Ýkéó'óþ$ hÚ&­ŸÛ&mSVÁòÌeÊl›ì|>‘|͉ÂRñ§_fPJÔýC.û_\ò¯o¹ÔŸR‹çÛÜÿ,UÖÅ­oR÷ŸÅûùR1Û#ÚËòÇ+}þ¥m_ÅÌ?çŸOe['Eìù@i·—•//€ÕbÉAjÌž&÷yOÝ N[4²-Ç5²Ø\ìdl޶òñ}Ãßìnx·érûÁ]·îÒu¿ÿ@—Óƒ¬©›O)Kï¾÷ù‹¤Àﺿ®ÔÈÊOgû=“ƃ]jGEÔ7u8꣈ò¹ôü {æO©Ë”|çë¬øZ欦§ß”èž[gÅi™³‚:ßTÇSoªƒòVHz© óÓ9Ӟ蜡ÈÓ"Ä®£=×Ñ7ÕHß7ñOh®¼xf¸Ò¨Ø»Ù¨X©òÊåxÎM…󎸇ZÆ› ÈM €ÑàcáÇ»²‹ç‚¢G¿ˆò˘Ñ6­¯$Óð¿2щméîí éh;j,ÿ)3§¸Œÿ7Z×ÑÕá/³ }¢>ŸÔýíŸî _ª>Ø&°M^ßr©?ÅŒg.ý1ë[©Q7Õò$².f}“ºÿ,f{Ïå|©˜íí%S1ó/Eû*fþ…uÏç½ñ£Ï›™Fìù@)·)Ê `µxÍí9Ô„êzk?¬ëŽ=ØS86Yj¢…¼ýPÓÿ´Ju¦n§:õ=»è{„ë0/µ3u4A}hKPo›<|¢°‹LüŠÐtr“z\]¯§§çŒ]ýáÕxð+”Jcé­Ýké•™dYAsp4òòÓ¹«¾§ÊUOsp(Æ{77Òƒ³”WÓåóÞ¦÷ølŒ££Ð~¢û›öZ «ðôR¯žím¹âmJ°OG¬²KiTvé{twô=ô #>U±Ç¹“Ï#ÉNªQßÃ/¢¾¾K=U}—V¢¼Ä/ bʲr¹Q³~û·šõ/Kd– /Ô— p3\€_òùÍþª0ŸbGÅi¹£Bٵ٢ì¢ãõدŒxì=JGOÝrÕw©\õæýû~eÞÏFªgÙH.Ÿ¡wí¼¦wiÖk¾Ö¬WomQWšµ©4;Ê»TŽrÔ‡Ò©R÷ž¦‘+ž¦›¸`©¾iÖkNkÖkdÛÏid®úov¸ê ¯o¹ÔŸbÅS\ÿ/u}“úû%¿ýÓ4øŽé“éŽi*kz ½²ÿÜë›Ôýg1Û{îçKÅih/K÷‡Åø~ɽ}•fþ©î ïújxGûß5¼ûâS50¿óÒl/Ò•À*@ œ,¿l©¡U ©*\ñ+]ÿðß~,´Â(ªR<§i)ov±«â¯­Ê.\~ PJ¹>¼Ùø”~ý(µöŽó%´€Â•ÜB°¥¦w¸ÿ`ïpëàñPë`)äg0þ}Ó`\éxg—ÒaTîÝlÄy¢9D!Ýø~ÊM/tVœ©tVXz÷í–òV,/¡ÅžiR(ê$êCéÔ‡·­X{íçKh/«QBPšb­p¼£S8†r·ÿ„˜‚îülØÿùw ûc¦]ìÅD³ãã=fGߥþƒ}—'Ã0N¯tÆ<¾‡cž êÿ[^Þ¶þ ø¤kï8_@{X½ÖÑ´“º>ËÞº>¯}ô–×N[(5níåón­5z°Ñ¥Å¹¹ÃpÅñžO1L:0ŸJ¿|Ðø«eιÀ|Šyœ_ˆ³ 61”`iŸ´=Ò:Qi]•·çH ƒ&Y`Ð š¬»­é²ÝFO_§×b~z¤õÞ{‘ÖuëÖ­[·Nx§ÖZ%öx ‰ÝÉVü2]=eø ý">Pº¥¿Úëê?êÿR¥/õ÷oáû—ºö¢u@qˆ4±E­¶¨Ïsí®ÏC©že#bÂð¸'aèsgísÓ“œÓþt,í_©ýGǦGÇôÝ»è»WKL^÷5¿š¾ätÝ»îèºs/Óâ—WMy{MSó'•SSxy þôݺ;ún:mZ©øH]ßÄæ_j«±ýäýÛ›%õ÷o)|¿”ƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6Œ ÆÙ§£q–þ­­ÙvN[³²ûç³.i»·3Ò†qôÒWÌò¢Á‚ >´%¨o8v£u ð}¦ýÏÃi?$™-ûv›-¶©ƒ¶©ÕÿRË?Ú/¬UèßàmÓ Iª#u;Õ‘p±t@RÕ«BA}hkPφw?X[ƒ&4g„~·§g¤+Ê=JçQu}×Q5ççbÜ¢±vú5›0_[ÿsÿþåo±Ù “›2óIõ‡>«°ïwqùO©û‡üú·šºß£”ÔºÙˆá1¡-TÛŶÇ|ûÏbŸ_¼m^3hB [=®®W'ØÄ…K[Ü•ϸ+mSõ]¶)Ú²6ÂaÞ_û‘y¿Â±©VáH¶?ñ&ÛcsÅæ&}Ñ#“¾¶¡–ñ¶!azú5;¸ëÎ/ƒ»ø-¯~å.1Ù9-]ÿðfÛo.Ç›;£¢zÖ¨ Áô¥ÒðCíÕ³üP{~ùÛÞÕAõgê ÕU­yû9­¹u¨e¼5KÊt`>•8Ê»TŽòdGòv²ƒj©*¨úL¬ë?ø»ºþBê³Øã¥“lÚîm¹âm¢’Š^|½®wéîè]ÅìŸÅƇp.Ær©Ï–þƒ–~lËqŒZ ÕOŸ÷Æ>ïJEîí+÷öž_ý/üçWßÄöoR×çüêgîý¡ÔçKbëîß¿t‹:¨ªW3÷6\yùûáJëäÁFëd!ßïbó/6žR÷ùÕGùi™£¼÷RÿÁÞKÝGϲÝGû.}û›¾K´Åu´Çà:š_{Û÷ü à­´°°°°°`é­ýÐÒ+Ü"Ô:ðådë@ï¥s¿é½¯ŠÆ«4²ò?jd kE`z.vrzNø®§Éûƒ§‰:»Ì¿ ·Üý·p ½ŸŸ­tÞrÙ¿0M²ý‰'ÙNÛƒ»BÿÊá ÓSÚNë°ßõ?ûá¿ýÏ–:^±y–ßÙ%3f¾ Hlü…û—"}!å+u}àÛì–ÞŽé¯âÓ+[Çø2’•ó¯ËJ.Ç›Kù±üò/ü«ÉëÑC“×ßTÿPœö›ûñŠEßT'i‹Îõþ}ËUßS媧£f˜2tbó_H{§²£ícW}ÿ5vUáPüZLÏÆ_6”)øR[Ÿó+/þSÊ 3ðÓÐW?¥o=§o•Ú·gf|ÄÖçbö+•ay‰­ÿ¥–ÿBê[îßwoª>gÖO±ý¡ÔçK…ÔÿÜãï(?ý/Žra-MßJO§oÑ·äRâû]l<¥î éß(†Â–˜¹¥óÛRè?JÙð÷Ÿ‡wûêxÕO¼ŠÚÿú¨;^E­ƒ}hç_©÷£Wÿ³ÀÏþgÂ}ò­2òA¸%§Ûshœ’~!¡ÂÕ³†5ucNœM\à×%ÑÈ·×,𦍑m=®‘¥:ŸŽ¦:KÿXNÅ…“¿€,S¼úýÕÄ<áñ²Õ³ì?sƒNnªÙoù¨f?Ý«\x~Òþd í§_-øß.nÿ¼ø·‹Bâ/uúRC ïù¼7ú¼m'¢m+»¾¼Ò±´?^ŠWŸÇ=1Ž&ÍJ×¾Þlþ—_¨˜ýCqÚïÊ®¾Ä;„¶õt;'m¤n> ¤hr¸FV~Z#S87YÎBò/6þªÐ¦ZUˆþ­n®US©ÿ•-%-sN“«…ÓÅ?ÞnÜÈ0ó©|ës~ÇK7Ãzš®\ñ4¹+/~ã®Tv©ë•]•5Ú‹•5>χ>O1{žÜãSH}–ºX©üë›Øú_jù/N}“zÿùÕO±ý¿çKÅ©ÿÖɃŸ['}Þkw}^º5Æk½éµkÍ;þ¢5kkv\Ì÷Aêþ°8ñɯþÈLe ™IØ3·rþPjý'ÀÛlÉAaÒo é©k«ë·6Öõ{í##^ûZº1GT}¦Ò¿céÇgßûãq4ü&rW¦”òxãU±“ñ*á ÿZ¼õÒ ‰¿ÔéK¡¼„§åŽŠfëïÝÍVáªhÿvk“ÛnuW^þÞ])]ù®öü/]Ö~û¥éß4­z0q¡}0Ñ :òeƒŠ¦û¼7Ÿú¼†°á?Ô^HþÅÆ?ax:ʯ`gŸŒÆYši²8Mb(a “uZ!ˆ¦CSNÆ®þõîØU>í|R|}.äx-}µ{-}þd`ÞŸ¤AÛ¤õsÛ$MÆ.NùŠÏjéVª½‹­ÿ¥–ÿÂ꛸þMŠú\Ìú)E[œú¯‘oûV#ך߻¦5{í×îzítcŽmÒÚh›”º¾O©ãS ý[!知Ö¬UKšPgáirŸ÷4Ñt>ÚB÷Òýä´em‚~¡)µ3§¸ÎZ–‰~5rýFë:j›F÷ÓÒh¥ÿ¥Ò7¨Ù *<})”¡¥Èèt§súD4ß(rGQ®t?\I¿”R¾†ðÏ áΙöÄ?ÆÿÕ}¿¥œÿüêçÛÐ~ 6çw¼ôéô <¿L ] –)Ff”i²­Ô#ÅÝÅÆ§þÁYqZ欠œ§:žzSŽŠ.µ£‚)¢üÚ{îõ¿4óŸ_}˽Ëoÿ¥P?¥îo‹Yÿiˆª×ÝoíuÓj ¶ÉƒŸvf+6ÿbã)u|ŠÓ¿Iw}ñ¦Î¯Þ6¯¹=‡&ïÕõÖ~X×K O*›, 5ѵOÓÈO-y«ìÚlQviÖkNkÖkdÛÏid®úov¸ê‹Ÿ+UhK‹*Ô1}2Ý1mÞ¿ïWæý´ò<½v¼îóž&¹QV.7jÖoÿV³þåzø³ìDÔ7u8Û3GJ-þz×Îkz—f½ækÍzõøÖõx¥Yû—J3-èUHúüž ]yѳrh1°Â§y/…?ÆW‹@ÓÓgÆ®Žþðê÷–|âC‹ÿ%ا£ VÙ¥4*»ô=º;úzÆ ŸªÐy¹ç¿8õóíi¿FEõs£âE~äÛ¾ÕÈé‘Ï16\ý|ñ˜ùå_l{Ov>$;©>D}¿ˆúú.õTõ]¦ÑÈËOkä´…mêÈlS”ãÆ½›é(2÷,¶>‹?Þù?³Œê¥÷دŒxìô陹âÜ à×Z™YNùÅG,oÓåóÞ¦÷ølŒ£V¬ýD÷7í'FÅž*ÖpC!í]lý/½ïÓ|ꛘþ-Ÿý—Ný”º¿[ÿó;?¡!’þoBzC¸ê‘!L%XøþÅæ_l<¥ëŠU¤½¾(ÎùÀÛl-pR×gÙ[×çµÞòÚi BP:bé™S±tå';¯U~B+®¯¥Ë@òæ“@’&Ç®¥ùkð¦Ðl }ÏîÿÔ÷¼\†³h'‹o¶>;5R95ôD¡øPû@QK ¥çW°¶¹µ—Ï»µÖèÁFk”fŸq†á‹×!šOñOÈz¹åå<\.0Ÿzµ‚RüBœM°‰¡Kû¤í´6Ù/Þ†€¬vôK}á­ÞášìÒoá§pÓôQgÅ™Jg…¥wßnþ^¨Ïù¡ÅÚTõ]+q³!”>œ_H ƒ&P$tçpûŸ×ð.ûÌÖõ¸Â¡Ø£pô]ê?¸ø¦ Ôg±Æ<¾‡cCäƒYCeð6Àù€ÔÊ(š/39vŸ™cf"ÒÐu¿ÿ@׽нÀ,t£>ÀÚ†ï#©a¦ @4ȃ&Y`Ð$OôHËuëÖ­[·Nøà"È«‰êH+=÷Ñ@}CüŸBâ‰þñA{€b1hb‹ZmQŸçÚ]Ÿ‡N)ØHõ,»×çŽMŽŽé»w?Ðw¯½£+>]÷®;ºî´?ÃóáíýMägù‹ÀÕu‰(¶?)~ùÖÔ™·×Ô95R95…— Ы¾[wGßMÃ"+)’ÿ·­½Ã›…ú¹1hÒßÝÒë]»ïë]AýÝA=6´5¨gû¬­Aú5Œ¨þ;;ÁoÙ ç%[jÂsßðwÖ¾a¥s³Eé¤WoóèMosfJÎ?áüGÕõ]GÕJ§rÒIOS·Eœ°E9?ãòümŸ’½A'7eî‡òS!ל® ·' {“ÒXfRòù‘kä&“ò£Í&e,ýã±Xzñ§¼úýÐÛ<2Âï“þª®ïÓOëúÇsƒŽ[.¿cS~èwZú[ÊELx\Ký6žËoæÝ g Ý êº^¢¼©C[[Ô¡Áø…öÁx~ñ§=„tã[Bº¥ÒØm_ܰÛÚ[Bmƒ…Ô§æŒÖ©áóŸ=½0v[Óe»RÒïi Cb(aX*þ¹×Ú½+ŒdÛà‰hÛ`f)äw¼R”WqÚ»Øxæ—éäÞÅÖÏüÒ‹íOŠÏΙÓòΙ¶–PÛ€ÌôŽN¶Âû¯±˜·ÕX¢¾©#Q_¶ãÛߊk¿Rç_ì÷‹ØúYjßïbW|û•ª漻ጶ»¡â#u[jß_PL¯4¡¯õ¸º^=ž`,mqW^<ã®´MÕwÙ¦hËÚýÜuç—Á]ü–W¿’-5á9Õ™ºêLv<ñ&;š­Ÿ÷7[Û†NLµ e¦´M9a›Šq3§b\l.v*6—lâM¶ÓÚ†ZƳýU.hJ¶:¨ªW}Þ?ú¼Âw‡+/?\i<Øh\t¼ùT:à(ïR9Ê“ÉÛÉŽd{2lWUŸ©‚uýW׿Ô'WŽŒ W†[î¾n¡ÈtNŸ˜ìœ^Ïç‘Åñ\žyíGæý ǦZ…ƒ"›{x,67é‹™ôB'U´oÓÈoå¯ÒÈÊÿ¨‘-¬Qá–»ÿná£ñó³×¥I¶?ñ$Ûi{pWè_ù/`azJCÛÃ-‘Â-ÂwýÏ~øoÿ3:ù+$çŽòÓÿâ(·ô8`é¥-é[ééô-:I¼=4y=—ýð§eŠÅG!<êÜ÷–K<©^Qšé¹ØÉé9Ở&ïž&a|–ÚçòŸÅJ™‚a~újà§ô­çáô­Âë µaäu®÷ïë\®úž*W=å„>—j‚Øú <.±ñ¡£¦ícW}ÿ5vUáPüZLMˬ¹”—°ò«ÿÒ•—Ôí=¿ö•{~ 9F™ñ]2cæ«ð iR¤/$>RÄ3µýŽé¯âÓÒ”—¬œ]þSVª¿-$bùå?÷ï±õ³4¿ßóû>Í…ÔýóêŠOáým)¼Í†w¸ÿ<¼ƒþM}u¼ê‰'^E=0ÿú¨;^E߆üëC;ÿJß/ôêøÙÿL¸OB=N·çÐïô 9ýÛ®ž5¬ÁÕLò£p*ö(œü b™âÕoh¯&¾ÆÙÄ…8Kÿf'ªgÙ ~*õÜT³ßòQÍ~º·¶œX'~nôy¯Ýõyi*©×>zÓkךwüEkÖÖ츨­¦§e}Ùˆá1N75nüx»q#Ã̧–þ,mͶs‹÷Va|4ò-Ç5‹n#Òȶ×ÈROGS…| Ý\æiºrÅÓ䮼ø»RÙ¥®WvUÖh/VÖø<7ú<ùí™o¡-A=ÝÎFÛ©›O)ºyJ#+?­‘)œ›, g!õAl|T¡Mµªý[Ü\«¦:Sÿ+[ÊÜëC.åµTùæ~¼Ò•—Ôí½ðö%´?HûiV?7áöÏ‹ç&Ò¥N_jh!IŸ÷ÆCŸ·màD´m`e÷Ï—W:–öÇ«âCñª÷¸'ÆÑMÒõ·o6ÿË¿çû"÷ö^ø÷{ñ¿O ïŸK->Òõ·kéû ò³ä ‰ð+!¤ßÒÓWE]¿µ±®ßkñÚ×Ò9‹•)Wzê ê3uþ¯ŠŒW /Zø×B§‹käÛ¾Õȵæ÷®iÍ^ûµ»^;ݘc›´6ÚݘCw;Ó—=ÝOÓk)'cWÿzwì*Ÿ¶K£ ãK?>»øÞã÷èlŒ£_r–/£dçó‰äkN”-}µ{-}þd`ÞŸ¤zÛ¤õsÛ$MfÎ/ÿt{MÓL\hL4¨Ž|Ù ¢©Ë>ïͧ>¯!lxÄ5Rr‹°¬ŸŽò+˜ÄÙ'£q–fšRr)¯•ªÿR”—Ôí½°öµòù‘¾=æ_?Ŧ/…òrTœ–;*š­¿w7[…R ýÛ­Mn»Õ]yù{w¥tå»Úó¿týY­ßïÒ•¯Ôù—zÿR÷·¥ýýÅ°ä  } xšÜç=M4ñ˜¶hd[Žkdtÿ9mY{AQ7Õò_!ݽK/í™;š_`¶ì{ßli>Ô2Þ|H8î}¥¥Î ÿ,úJîu÷[{Ý´¾‰mòàç¶XÍ„›Iè·þºLÉŸ|8+¾–9+ŠsúM†niéœ9ÅuÎвj%×Ño´®£¶Éø£Ðš·Óšiâ«°ŒhfÍRŸBGG¿ðð覄 S™‚adF™æuwÚ/ ³aÊ­Ùòñ6³Å¨ØSfTôºÏ™{Ý´îIáõa©ø4¨Ù ÊL?˜ø¾i0Aÿ®¼xf¸Ò¨Ø»™ÏI~õÊËþà¹!Ü9ÓžøÇüô\G ¯ÿR——tí½ö%E~¤n…ÔO±éK¡| --IÃÓÓ'¢…­@‘ ŠÒp¥ûûáJš¹VHùæÞ~K3ÿùÕÏÕþý.EùJ©÷/u[Ìï/Z)sÙ~x³^s{]‚ÖõÖ~X×K]¹Â±É¢pÐWòZ Š*´¥Eê˜>™î˜6ïß÷+ó~Zùœ^ Ù3 Bɲr¹Q³~û·šõ/×oŸe'¢¾©ÃÙž)  ‘„ôÛÒÂU a:"a¼ü´FN+nئŽüÁ6E91nܻٸ‘ YxNÄ®Nïi¹âi¢%‡•]›-Ê.ÍzÍiÍzlû9ÌUÿÍW=¥¤'S¸ê»T®z*#6R=ËF^—£ùÿË0íŸòà±_ñØi©¶BŽ×¨¨~nT¼(_ù¶o5rŠ$®~¾øiSùÕ½kç5½K³^óµf½z|k‹z¼Ò¬ýK¥™ÀËLŸì|IvÒ¼°¨ïáQ_ߥžª¾K…׊X‚}:š`•]J£²Kߣ»£ï¡gdð©^ýŽ'þx¥-/éÚ{!íKºþG|•k{,¤~æž>¿§ŸHOzV-~I—UR”Œ¯e§§ÏŒ]ýáÕïçùÄGlû•:ÿÅ©Ÿ«ýû=wÒ÷Ï¥Ÿâô·Åùþ¢Ù©1næßc P:ÖÑ'u}–½u}^ûè-¯¶ 4«=¬Qß³û?õ=/—¡-ÚMäÍ'$M–^«óÑàmKÏœŠ¥+?Ùy­òzbËZú!íwmCùÀÚàÖ^>ïÖZ£­ÑTÇSoªƒ 0 X¼ŽÕ|ŠÂÚË-/‡¤¹À|Š_‘*ÎÆ/ÄÙ›J°´OÚNkSþâm(H¦‡tã[ø)Í4iÙYq¦ÒYaéÝ·›&ÀZB¿lÓçê.Aû]ÛP¾+ƒ&'º“¼áÝÏ¿kx—Ÿ~¿µE=®p(ö(}—ú.¾ Ð~å °º”!k®ûýºî…îf¡[ºO¡ßÛ'Çî3“c ÃìCÜV´_”/ä3M²À  @4ÈbUšØmM—í¶î†³†îa±Ì'Fn’kä&z]·nݺuë„m*eôÞÕ•ç7{tÔÊ„%¾ô§OTGZ—OSØÑ­îýÃÛÖ~×vo#¶€â×·¡Âê­bóƒöR¶è‘¶è`üû¦ÁøJí×k°–ˆ4±E­¶¨Ïsí®ÏC] ©že#…|<= Oß­»£ï¦ÕÝéô‹³á£ò„:§O¥;§§eŽ Î?áü+º|¢ã¢œ(Ê=J'm‰¥<K¿­U¥LÉ0i:–öwÝùepWéä,:6u8:¦ïÞý@ß]:¹Z½†Ç= CŸû;kŸ;Üù ÜBå¾Tz]÷®;ºîåÓBìþÅÖ©óð6÷Bø¾F<¡ÔÊ—®}©ÛóTƒú3gƒzñ»¯•„åôÚ6x"Ú6¸Ôž¥»^(>ƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6\ÈÇkÍÛÎi;«×îú®¦ýÏ#iÚÿ<œö×XÌÛj,æýû~eÞŸùWªª^bÆÇlx0q¡}0Qx 8?ãüÆ{77Öõþvw]/å$Ù‘¼ìè®?³£»ž ÔpÙˆ´ÝÛiïj…‹³OGãì‹Z³íœ¶õÖFÿoúgÄJ­|ûÜç>îs7¨ŸhP-¥CWF4PN¯®†o´®%g‘Hq½ð¦ä4h’êHÝNu¤\, Ô‡¶õlx÷ƒÂMÎM…SÚÒ¢ ½è üó)ΟüœJÔÁMµêàRkTìÝdTxí×îyí…"ÆýøEŒKu>Mu6[ïn¶ ;C¤ê±!Bðþ›U×wUÓœš/C“Üh †Rò·lÐÉMÂíÄÛééô-ëäá/­“:×û÷u®låõêS~~¶°bèéÓ)'”C¸ê‘!œy¼¹çG˜ÆQ~ú_å´bNåRxùŠ¿X†ðÏ áÕgÎ)íŸâ–±ùϯ|¥‹¿tùÉ/}îõ3¿ãW=êŽWÑ_ÑMp´>…úÉBê¸PͤŽwìê_ÿcìjfúÜû‡BÊ7·ïˆWû_ÿdàUüù×çüê¿tíQêú#õñJ×^ŠÓŠØïÇÜÛW1ÛKîû[^ùõWÒ?ˆ%6ÿbëOé´ÇRëOÄöçùõÿo[{Éoÿ¿ö·KåAT}¦ ÒµìÔY8IÁIDAT×-ge¯×„†w¸ÿ<¼CXÛãUO<ñ*Cà_uÇ«è;}hç_'¯GM^§Wÿ³ÀÏþgÂ}ò­ òA¸å5ƒ&¤uàËÉÖÞKç~Ó{‰>^#+ÿca_êK¡Nºéå;A:•Y*Ïù¡QG@]íŸNŽé]aÁл™ßAlª]ÜAPwL'U´…ºZ–*|ÿ®M¸7±øUKÊÙb+ÅIÕ+Ú'Uhá»4Ì”y¼¹çG˜FøÅ°T-z³ñÏ/>Âä—ÿüÊWŠøK±éÅÖÏüŽ—ÿ”2à ü4ôÕÀO¹œŽˆ¯?í‹ó_xÿPHùæB¸ÿ\â_Hý—¢=J]¤>^©Û‹ÔýçÊÆ'³þ‹m_Ål/¹ì?¿òʯ¿*¥A“\ó/¶þ”Z{,µþDl.6ýÛÙ^òÛÿäõûŸL^§ýÓõH¶úŸ $Û…}2]‚Ò•‘uòàçÖÉ×õ™+½@Š9h’Óí9Aý A=®žeÃôoC¸zÖPÐ9KQ8{Nß]þþ·tày$ ‘Ë•útmÍŽ‹Úšaí_¾ÖÆ ñ¡¸‚«t(÷(uý>­ë§”q6q¿¯›¨že'ø©þtrSÍ~ËG5ûé^Dáþ©sñy¯Ýõyiê£×>zÓk§™5ôé…ìñ±¼þnsZÖ—–ÝN¿4nüx»q#Ã̧Š5ãIx¼ù–ã‹oƒÒȶ×Èèæ©•ªcül©2?¿IxkFq⿲ñY*}~ù—N.ñ/5…ÔÏÜ—n~ô4]¹âirW^üÆ]©ìR×+»*k´+k|ž}ž•Èÿ?Þf¸²ýƒÔå›Kü¥®ÿ…´G)êO©µ÷ÂûséúÏÜã“{ýϯ}§½ˆ­?¹——týUqäž±õgµÿ3ÿbû±é3.]«í%¿ý+Š=Ê×PK•)ÅDx…B‹*8ÊO¥åt³|Þ¤¸^(¾%M„]dH?¾5¤§®³®ßÚX×﵌xíô®”Ù[î¢=Òöà·‘6½k÷½KºÐ Pçô‰hçtÔ÷à·QmWUŸñë­Ä«b'ãU/²¼þã34òmßjäZó{×´f¯ýÚ]¯}¸òò÷Õ¶Ik£mR˜2¿ýç.aH % ôå×6ÐjHv<ñ&;hÏcWÿzwìêËRÈ8u{µÚ ­ASxœ…ÇK?>»ø^ñ÷èlŒ£‘ûl½ò ôJ)âSÊù/.iëƒøú)Ž¥¯v¯¥ÏŸ Ìû“i2öÛ&­ŸÛ&mSÖFÛÔJäæÔëÖ**¬V.ñ—ºþÒ¥¨?«±¿Z©ö"E|ÄÖ±í«ÔR^âû«ÒZP?—ü‹­?Åm«ûüGl}›^¸déJå¹”Û‹ØýÓð g„Ûîÿ6Ü&E++Îõ€Ô–4¡nÑÓä>ïizq®ÿy$í×ȶ×Èbs±“±9ÚRÈÇ÷ ûqßptìÁ¾èm¡¥ÔœR;+Ì–}»Í–¥þ6ºù4²ôî{Ÿ¿±¨´¨-¡D'L|~R·S½îóM½náê´„í‹{;µŒ7¢”ô.-EKÙe~ua½î~k¯Ûç½ñ£Ïk›<øùâA“BöŸ‹t€›IhXŠý-Sò'‹ÎНeΊ¥þ–žyD“)ÿ…ÇŸÆÈ)Â3§¸ÎZF‹ŽÚuô­ë¨mòÀÅQ"ƒCº{;³=¦Z,©ãŸ_|h2¤³â´ÌYA'ëÔ^]jGE)翘¤¨…ÔÏÜQë£_„øeä脉֓’i^ýê•OþiÍ…¶¡öÿÓ6Ä?üo>É0™¿AÒ?Hm©ø7¨Ù *NýÛ¥®?¥Ù_IÝ^¤‹Øú/¶}•šüÊ+¿þJlÿ,\xe‡hsÏ¿ØúSÌö¸ÚÏréÏ Iÿö´—BÎêzk÷ÖõÒUUæ»ô½&^|¥öñ¶¥¯ÔÈÊ^¯¼)¯¹=‡¦]ÕõÖ~X×KC Ç&‹ÂA]Fáãb§bMv¥‰sšõÛ¿Õ¬W·´¨‚ƒ?ÿýàOKu A}hKPo›<|b%N¼äÆwtr#=¥\ûÉÎëÚOøühNkÖÓ¤5ßÕÑ|W…EƒJr£¬\n¤œ¿\ïz–ˆú¦ó3S„hˆ$¤ÿÛ†ž–Œ>?¨ðýç‚fиê{ª\õ¶©#°MÑžé¡ËËWÉLïèd¦áC_ ïhx·ñ»†w_ä*R=ËF )OÓÈOS‚M\H°Ê®ÍeÅ_#Û~N#sÕ³ÃUŸùW½Žé“éŽizL5­N¯…åGªøçÇÛtù¼·)Æ=>ãhuí'º¿i?¡5€ŠŸ©Ÿ†ßþs¯b÷Ÿ_ýc>Å0ŽŠÓrGíŸòà±_ñؽM#W¼MÖç?{šèƒ&îÒÓ¨ß[©þAjz×Îkz—f½ækÍzõøÖõx¥Yû—J³£¼Kå(/fýߥ­?¥Ö_Iß^¤ŠO~õ?÷öUšÄ—W>ý•Øïk.ÀÍpþA+;«B\þŶ¯â´ÇÕ~þ“{ž_ú·©½äþÐlýâF³u0qñ›ÁDæÐd²sv"ÙiÚ¸w³i#Ýa ×|­§ëÁÁŸ†Ú³]©)®×Þ”u´ÀI]Ÿeo]Ÿ×>zËk§-¥œi»­é²ÝFSëàñPë `-qjþ¤rjbÜÃ/bÜ@|¨} Ž˜H–l êÏûÔ…ï×k 5·öòy·Ö=ØhÒ(.À0\`ñó)†IæSé—«ö¼äó©W+RÅ/ÄÙ›J°´OÚi¨Ž´–­Æõ÷ìfæ * ÀZDèœnïêœf¦†ƒ’¸^ƒµdUšÀÚ6æñ=+éaàmð „ M²À  @4ȃ&Yˆ4±E­¶¨Ïsí®Ïi½÷^¤•TϲÖƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6Œ ÀÚ“Ó Iª#u;Õ‘p±t@RÕ«BA}hkPφw?X+ƒ&4wfݺuëÖ­«©ûíîš:¹I®‘›Ú[BmƒlÄð˜Ð–†îú«„áqOÂ`RËLJ¥S¹Gé¤4&åG›MÊXúÇc±tæþ»Îh»”ÎÍ¥“^½Í£7½Í+•»­é²Ý&7mÐÉMúîÝôÝ Cb(aÈü«ÜóϧO % ô.¥T‡¶¶¨Cmƒ'¢mƒôé 3ŸäÓsþÙç?ª®ï:ªæ÷¿A'7Ù¢GNØ¢œŸ‹q~4B(M¯4¡K\õ¸º^=ž`,mqW^<ã®´MÕwÙ¦hËZ Š£ü´ÌQÞ{©ÿ`ï¥î£gÙî£}—¾ýMß%Úâ:Úcp¥”éÀ|*p”w©åÉŽäídG²=H¶«‚ªÏTÁºþƒ¿«ëÏÜ?àb\ ÙñÄ›ìh¶~Þßlm:1Õ6´RùWÕŸ©ƒiÿóHÚ¯5o?§5·µŒ·fÙ¿ØüÛ¦¬¶)UpS­*H)£×ïï‹^êïlê3÷o›:rÂ6ãfNŸØ\ìTl.ÙþÄ›lOu¦n§:Û†ZÆWî¨VÖkMè»ÙzÌ×lí½ÔSÕ{)6÷ðXlN#+ÿ£FFïÒëZ ŠÖ¼ã/Zs¥Yû—J3¿å½kü–ûøl‚¥íyùiÜ©zlx±¶‹Ì$ÓÈLvkc¿Ýi›¨Ž´eî¿Ùú{w³•þ]cùíû5–÷ã1n¥òß ú¼¿AEÿ¶MþÒ6éóÞxèóf¦Ì=ÿ4Ç$ºýÿR4ÈB)NÅ…³màD´m@¸çTÇSoªÃk½åµ»ê{ ®zJIÕ:pÌ×:0\922\‰F¥)§Ûsh®žeÃôoC¸zÖ°fW3‘™Ê2“ÌX¦—ÚBhY\ºyGxû‰qãÇÛf>•mÿ4|ðbÏ‹öùêÆ!ºFøº|þU¡Mµªý[Ü\«¦:Sÿ+Õ™™2÷üÇÙÄ…øË¡¢-Ç5rá~4²­Ç52áazv¢z– =ÓkÍ~ËG5û¹Àl„  @i*[ê áM7\`v‚ °Æê]¬‘ p\@6U¦MəћrfíÍ4Éͼ¨·´ÖŒ{šÜç=M–¾Z¯¥é(S2äíù@Ò´ÑøÏ¦K …ä.íOÇÄD8ax:š0Ðê3qöÉhœUlT4*6’uPõ™:È0Ìß&–~|6–¦Y*´·÷èlŒcæ#~ÿ/Ó_g˜xUìd¼JáÜdᇊJß’3Mh(äÅåtï–^Ú¢‘m9®‘Åæb'csoçpÉ‹ø¸™t€æb(Š_+ S¦ä#œ_Ëœo*oƒ‰ï›ôïáÊ‹g†+н›ŠBòOC0†ðÏ áΙöDç -ãJ‹ ×y!4Db¶ì{ßli>Ô2Þ|ˆRÒ»´­·yd$Ûò·Ñ±û¢crÍé 9š(¼)¯¹=Çk½éµ×õÖ~X×K—² Ç&‹ÂA—Ðosàhž…«¾§ÊUo›:òÛÝ8cܸw³q£Ù²o·Ùò¦ò–ì|IvÒ\¡¨ïáQ_ߥžª¾K…çßÛ4rÅÛ”`ŸŽ&Xe—Ò¨ìÒ÷èîè{j,æm5/Ó—)ùÑ ›Ü(+—5ë·«YOŸB7ìD}S‡£¾ÌO¡…rcÜ̿ǸÂçéägÝÂÂÂÂÂB]Ÿeo]-ÛI[šÕ…9¬ïÙýŸúž……ŸŸ-,/¤HÞ|HÒJ%oóü#š[{ù¼[kl´Fé!$\€a¸ÀâuEçSüc_nyù“<˜Oñ+lÆÙø…8›`C –öIÛ#­Õ‘Ö_¼ …•B7ï„tã[B:ÚB7Ý8+ÎT:+,½ûv[z%X0h"ÐJ( ï~þ]ûtûz|k‹z\áPìQ8ú.õ\|ÀêU†¬ ºî÷躺˜…né>…VB™»ÏLŽ1 ³q€µ 3M²À  @4ȃ&Yˆ4±E­¶¨Ïsí®Ïi½÷^¤•TϲÖƒ&!ýÝ!½Þµû¾ÞÔßÝÔ³aÃ#6Œ ÀÚ“Ó Iª#u;Õ‘p±t@RÕ«BA}hkPφw?À  ¬EeË¿-7mÐÉM 3Ÿb®k>ÅuÉnË\`v‚ x£»¼FÆTßŘÒþç‘´€µá53Mh(¤ÙzÌ×lí½ÔSÕ{)6÷ðXlN#+ÿ£FFïb¸ÖžœnÏ êïlêÙpõ,¦ÂÕ³ܘkÖ’·çð7æ0 ÃÐÍ8¬±zkä\#M•)dSrfô¦œÁLX{–œiBC!ž&÷yO“¥÷ÀK/mÑȶ×Èbs±“±9 —ÀZõš…`½öÑ›^{¢öÃ:E´üÁ¾h¹Â±éO ‡ªUõžªá€µê5ƒ&ñ¡öøËÿld˜pÍ]&\ƒÀÀÚö „ M²À  @4ȃ&Y`Ð š¼"­÷Þ‹´®[·nݺu 3ŸÄñŠg·5]¶Ûä&¹Fn¢×¥?}¢:Òº|xù$ãýöÔ^ôÅ?ÞBâƒö¾ÖëÒj,ßBûÏÜ¿ïÐÿÀÛ@Ä ‰-jm´E}žkw}ú d#Õ³lDü‡Î'¦B¾ýÛ ywÃYCwC¶Ï:r­©ûíîš:R©‰ŽMŽŽé»w?Ðw¿ Ç›0<îIúÜßYûÜá–Èá–´?Kû—J¯ëÞuG×½|Ô‡×)S2 Å0¸ëÎ/ƒ»ŸµÔ—¿ˆZ]—XbÛûÛÖ®v«³|óï?Å~ß¼ D š„ôww†ôz×îûzWPwgPφ ذø-S2ÌÀOýÿ÷ÀOŽŠÓ2GEª#u;ÕAïÑé²×>2âµ÷^:÷qï%R©á³.i»·3Òö6üjgŸŽÆYú·¶fÛ9m êÀÛ\J->ˆ?ê |W ¾ï2å4hBƒéKT!U½*Ô‡¶õlx÷ƒ|M†aŒÊ½›J£bO™QÑ9sŠëœ¡í͇Ž7êœnwNkäå§5rá_Ño 5uæí5urÓܤt*÷(GÕõ]GÕœŸ‹q/~Yê·Ê•ú S¸Ÿî†3Úî¥s³Eé¤WoóèMosæ_qþÙç§ÜRÎé(hf0ÿù¥§ø˜”m6)iJm…\sºBî±ÿõžÇ^xu¡}²Õg'ø-ôüôÝÌI¼¹—W~įØxòÇkxœíx³Ågƒ.·éÐÅ©?ùÆÓXfRòû—kä&Šp,ýã±Xºú µ|ÛK®ÇKh~œ:¤®W‡(½:´µEŒ_hŒ3>ùí¿oø;kßp)Ô·üê§ØþÄ©9£ujøòz}þsOŸ{{/f{ɽ~Š-_a¯åmñ6SKŸR×÷é§u}|Jº¥eƒNnÊÜÕ7úÛâä'ßöUŒò•®¼òíOrý¾ËtýØúPjý”²× šÐWˆz\]¯O°‰ –¶¸+/žqWÚ¦ê»lS´%¿ï»tîã¾Kƒ‰ íƒ §æk™S“`÷$ØÖ/£­™éÍûk?2ïW86Õ*Éö'Þd{lîá±ØÜ¤/zdÒ×6Ô2Þ6Tü r.Æ’O¼ÉŽfëçýÍÖ¶¡SÙrb›:rÂ6ãfNŸØ\ìTlŽŽ"Õ™ºêÌÌ¿Øô–þƒ–~lËq,íNûÃ-wß ·ø¼7~ôy ?ÒÌé¾ô)´=s¯Ôå%öxÅÆsùãÍŸçñÓ¡¥«?¢Ë70ŸJå]*Gy²#y;Ù‘lO’íª ê3U°®ÿàïêú ©R]¾"—.Úi?Þ¦‘+Þ&:ÆèõÈÑëz—îŽÞUÌøä·ŠF)Ô7±òëOèÝØ\ìdl.^õ¨'^ã~ã–:êÜÓ‹mïR×±õ³ò®®¤þ–>¥súÄdç4½K·´¨ƒªzu0³7®¼üýp¥uò`£u²8ùÉ·}I[¾Å,¯Âó¿R­¸8ýO.õ¡Ôú7(i –ÞÚ-½Â-B­_N¶ô^:÷›ÞKñªø`¼J#+ÿ£F¶°Bå§ÿÅQNŸ>vÕ÷_cW3ÓÐçRšé¹ØÉé9Ở&ïž&:™¦-á–»ÿnáèçg|Ê¥¶‹%ÜO²ý‰'ÙNÛƒ»BÿÊŸpÓSÚN÷ ßõ?ûá¿ýÏ„ù›>—ø~Ô¹ÇPly‰%öxÅÆSìñŠM/uýYYüit™"[ÿ°Rmªx®l|–:^¾Ö•)fà§¡¯~JßzNß*<ÿRǧÔê›0?2ã;»dÆÌWáÒÿK‘^êþ¡°^ñõõ3¿òæ|òzôÐäõåóCßì–Þ,½´%}+=¾%3ÊÊeFናéÚW~é¥.¯Ò©ŸÅér¯oöûVÊð÷Ÿ‡wп©oW=ñÄ«è–}Ô¯¢³;þõ¡¥ï zõ? üì&Ü'¡oв\V‚ú;‚zÛ¥ïfm—è߆¡êYÊÁ›-o3[:{Nýgg¹nï&s–Å_ãlâBœeƆ×È·_|ÛŽF¶õ¸F–ê|úŸ©N¦ƒa˜Žb<)œŠ= 'P¦™ æ3üTÞ2åËü3 Ã0ìDõ,;Á˜ó3tæS/òÞ‘gúeãS̘H]^bWlŘÌvf#ÃÌO”À8ïrõAd|Ä/Ýœèi¾²ÕÓÜWùíÇ}•vý7ìzMÏ–M«¾§ÊUo®ûx»¹¤—¯.úFÒþd í§Ï%4Í^ØÍè…÷'R§/¹×ÏÂË7—Õ.¬“?·N:>éºîø„Û1ávxí×îzíÚ£;þ¢=ª­ÙQÍï¡8ùy›Ëëmë–¯k)žPKšoºá³\€5Vïb\€k䲩2…lJΌޔ¿˜Â*uFÕAÕgê Ã0c˜XúñÙXZ¸âIŒ{t6Æ)›¾S8^š2Û~’Ï'’LóÏLO1ý2ÿ×&^;¯R87YøS‡L¿L|†ùh…ªråËkåëƒðxÅÆ³ÔHÿ„!1”0ÔŒ[ZkÆ=Mîóž&K_­×ÒÇt”)™Ž@òö| iÚhügÓFá©mîõa¥êçŸOq~™©L)3ŸBŽ×ÒW»×Ògé«·ôÑ»NÍŸÔNmÊj°M%™äí¤èö"u{,µú&E{_ª?‘:})”—P.õ³8å«‘oûV#ךßûÖìµ_ zítcŽmÒ:k›d&ºVúçBÊWúòz}ÿYj¤®k«¾@1,¹¦ …¼¸œè=pÀÒK[hýºß»8Ã%„~“ѹ޿¯sѱ´L-Rë:úÖuÔ6yà€íÅ=ÒZó¶sZ3M| éîí éh»×>zÓk/~ é+ÙlÙ÷¾ÙÒ|¨e¼ùð™Ato3-]–_zŠ!üÁsCØYqZ欠ӯTÇSoªƒ~K_©cQ7Õªƒôoal )¯üêCîÇ+6ž¥Fêü§ÜL:@¿­)Š_+tªMƒ Ί¯eΊBêC!„my©ÕjÄÆ'¿ã¥w}ž}~™@º )S0ŒÌ(Óð7•3>Rì¿ÔÚK!ýÉRéT‡¿lPž¾ÊKlý,fùÚ&­ŸÛ&{ÝýÖ^7µ_ÛäÁÏ—ÔjïŸó+ßâ”W.ýg©‘º>²ÿèØƒ}ѱÌeŒ`m{ÍB°4ÄP×[ûa]/}U(›, Â?»ž¦‘+ž&Z’Vٵ٢ìҬל֬×ȶŸÓÈ\õßìpÕSJ™éÌäªïR¹êÍû÷ýʼŸTϲ‘7n„’eår£fýöo5ë_®·?ËNÐ …¤÷6]>ïmŠqÏÆ8Z÷^û‰îoÚOŒŠ=ÿdT¬ÔQ¨B[ZT¡Žé“éŽiŠ-­üO¯ù•W~įØxŠ%õÓ1¤Ë?ý®NÂmSGþ`›¢=7îÝlÜh¶ìÛm¶^òCmyxÇÐWÃ;Þmü®áÝGÑ¢sO¾Ç;ŸbGÅi¹£‚ê3ý•Ç~eÄc§¥‹éö/u{‘®ÿÒ»v^Ó»4ë5_kÖ«Ç·¶¨Ç+ÍÚ¿TšiàBÒç×Þ¥¬âêgqÊ—†HBú¿mé áªG†0E ôë›ôå[Œòʽÿ,5RׇüöO ·Ç¸™qxd8ÀÛc-pR×gÙ[×çµÞòÚi B¥Æ­½|Þ­µF6Z£t·`îÅ\rÞ|ŠbæË-/‡¼_¬fÈ0 ÃÄÙø…8›`C –öIÛ#­Õ‘Ö_ Ü™0hM²À  @4ȃ&Y`Ð šdA€,0hM²À  @4ȃ&Y`Ð šdA€,0hM²À  @4ȃ&Y`Ð š¬€Hë½÷"­ëÖ­[·nÃÌ'lÑ@”`yb¿)Vö›¥ð½á›PÄFQ‚Ò÷šA“n|KHÇF ÙˆÜ$×ÈMrÓÜTS÷ÛÝ5u±ôÌ©XZ˜žóÏF8¿-jm´E)¥Ò¹Ù¢tvÆÚ±•Èð|’aì¶/nØmJ§rÒI¯¶è‘¶hfê£êú®£ê ¹æt…œòOù¡í©ŽÔíTG1óCñÔwëîè»)>”+Š0½[HnÄ–—ØôPš¨×õy®ÝõyèäƒTϲ‘üö&<}á{¹Fn¢¾+Ò:Qi]ÙôÔsš”Æ2“2¼ù$å”I¸çÌÏÊvÕ|„ŸB[béñýÛRù§ôKõ‡ùä¥:žzSôWÙÊh>É0òíßVȻ겕õ‘¶(åjµ”o.ñÌ->ÿh0þ}Ó`¼²F{±²†>EÚÚ¢u7œÑòÑ[*?ÿÿöî?´‰|ßø×óôp'{\˜ˆò$> MÙÓg…&¬‡&á:==<¦ëBS=|:vºMj~µþz¿ ¡L¾™|ç;ßL&Ÿù|¿£~”bSI¥×¥+Oß•¡‰[ûBù|Z׳ýéȰz¿Í¶}V>›îµ82g+41{(4aîÙuËܳå×_Uíݪš.Ã7º.ÃZ”@ÿõ‘6hBáaSåaS•ýÃ÷«ì‰ÉGÓ‰ÉX{d8Öλø=¼«f º²f@ý*çÁ–€ó`ÔŽZ©dèRðw¡KžÒs§<¥tr“OuÛ†ŽÎ¶ Iñ+¤øtËõ÷¦[b±©XGÿÙÞòþ³+Ëó®ÍÕ¼kbôâõ‰ÑÄd"œ˜Œ”‡¿Š”'$y>!Õ ØQÿµ®ÑöÎ £Í7zñºo41ù(˜˜¤V­²ÛÞ©²Ûöïû­mn5Évå¶àå0_ß0›Ý»nšÝ~óõ~³uÚrÇ:ÿšéÈ@ÇO›}ß.›½n¶öpÝlaËÇ:î{cÍŽÏ.7;jþøÇšõ4¥d"œ˜ô—]ý¿lå{©KÊ“rX9¾Õô}¸«¦Oy—ØT¬£§þ/;zê+Ò>¯þá'·? ?á]M…;Ž9ÇsšÜeÿfrÌ×¶Ì&Pž/Ò26xoàÞs•tr®upŸ~Üz.x}gOìí;ûªìßÌÛóyí³„Î(ºJºu]%cMÎ5Ñ»[Û‚-ô-¶z}Ô‚vO‘ M_þÑtbÒì6]5»kjî›q­Ûßë¼xÝëŒZîöF-ÙÖ']û¨—§û<®üTB&déqP–‚m?í ¶eŠÍ¶üz¢ã•ߨæ7·~v¹u°°åÐ`]-,,,,,ØûªoïS/™¹tóƒ™K´$ñã£éÄ *“¥§“+â•ò O.,pWÌ ô%ª.ï®ï-w×›Üïß4¹òÀ Ë8abÔ÷Ÿ£ù¬GùšW×ÿÅÔ'ñcb.ñcÇÜW‰Ž9£mÇ£-·õd»¿²ß¿kKçßö¹Îï/ üå=G­Ùñ™¯ÙÑ:ø¹¿up­Ëg[ÿé–ëÿsº…Ú³ïì‰ÿÕw–vô8ÖäýëXSº×Ò§Cç×}¬óÓ'ˆj;xoøËÁ{¹µº>îúã;Üõ™×'s‘ò;=‘r¯Ü,ðTsWü õgåxòôaªVR/§òô3)Ö~,Ö¾‹µÇ¤X;õZâ˜9ô…cf¬éüù\÷rº=E=PýMQØòÄUÜùw®bêW™×-óãa¶ëTÿ,̶&+Ùì{ß±ÙéSI}^ýIW£ïeú\ÓËôïY¦©}òé3/vÿ¦kÏlÛ‡Ž™™ôól÷Túí-Ì™Ãz¶³ãSÏòﵕkË­'çó)È|®âîÿî*V¾7–qßèÜ)·ò¹}åVÿÌϨôH¯U/¡ÇÜʯìÔ2tN) EÊÓmËÌ¥ÐÁ™Kî.Ûv°Ù÷½o³g~¼JWç‡8?Ìäü0Ûþ¯‡‘žÙAÿS‰”ß‹”Ó‘My¼Ó)Ÿ{þjî‰òxÛ©<ÒQŽé÷¯zJÿ þnº%m¦‰±jÇcuÓ~ÏIG¿‡bØ”¡0=Ý>mÐú¢AGå)ÕV–äyY¢wM¿½²¦Ÿž5¹Ë®šÜ!ß­}!_nÁeýoÈRÄz÷Ûˆ•˜)Ý—Þ+Ýõ¨•¤øTRŠ[¦ß¿i™^ÿúP2íâðœßkJ4¿§+‡Òé§ÒÃÜê“íþʶüZøÝÞol÷›Ó•¡g­Ó»[§×º|>ÛãSqQ¹rþÉ@³£møèlÛðÊ’tõ¯m¸åZÛ°·éÂyïâ•RÊÏ¢«š¹µz¹,ÉaYʤ>Ù²Ô¶¸mŸ8ºÆHùV>ïåŸ}ÞLÖÐ6t4Ô6D奇SIé!ßµÙÎw½¶Qê‚¢cˆþš¾^-jžŽZi‰§ô‡¿xJëfë»ëfiI!Þ-clÌé½2æTŸ¦®üËtùË4]/Ê­®®¸ÓÀñ.þïyWÍ€ãpÍ€oìòmßX¶C2éînšñ…Ÿ„¿ ?‰”ß锇åÛGÂrºo±ÌËçÿý•QŸÏø| ÛÌÜ2}ô~ýÇz?e:mïž0ÚZ‡[®µ¦= L–°üó‘°œy& a£3mȨ̂<Îq~¸úùa¶ý GAY™iB(CQLõ«è¤ay¤?ø;%FH¯RG¦—Gs¡^?$ÑõUºŠHñEz\}=“ÿú'R<•¢J/¶>ô*ZƒúŠbn2ß_¹•_;}·÷8`ï£%t „¢ìu¦ë{G\ëòÙ÷‡¥®^Cº+J$>2)§÷¥ë鮊g[ÿÜê“9¥æKŸwõ³t¥By—ÔW¨·SßË$Òiüb¦uzíºž“Ï:Õ{Š®Iª¯^vÌ}é˜+Tù•×rWÿ¾ÈüÊ6áé:3…ò•ãÛïY¦ÕÇÿTõßXÆ ôMA?àéŠDn5Q_¡š(ßGÒÓɇÔJ鎷tÝŒÞ%ÿ,Ëõß¿™·gæí£þþ]~MòËHǽ—:$]}Ôô]œ®<­Žºê’¯Ê狾;( cõL“LÚ'ŸOA¶í“îû…úRnåsûþZëóÜÚ3“òê2ê¼:žPp¹°ßJÔßVöÌÜÊãü燅íoð:y)2M(¢\±©rKÅ&§£ÉãtPç¦/N÷î G#Ï©4ïÚX¦ŒÖºø=Z×\âögs‹Ó¼ÅÄG7bb¶×ÕÔëoü<Ð:Èwñ{ø.®b£‰«hüÌ×:Hs‹¤[]i¬pü©fÀ7zño¾QcÕŽŒU/ª>‹ëéâ÷ð]ôQ§kA¹†¿²Û_Ù—_[ÿ¦kËê«aÔ†”›³xõ¸k³ïZëòùl íSå´ˆ_êó¿¼J£ èêuJ/÷”þpÜSªíÖ×k»iRCê±¹µOnõÉ\Ä=±ÒÿÍ¶Ï õ³nûçnõ5„|³…|t‹®¼VÑèuä7_}[¹‚Dÿ[¦w?.Ü•ðÄdLR®[FÊ#Ñò°|·7,§›î:Ûò+ÅÄØTLT~¬æŽŽð#Æ3ÇGŒKd8b¡/K­K»Gëª8òø¦ÔÿQP™iebÌw{bÌ yç»åý<[4[eOÐA»û‘2O„Ï{ñ§T×ß(İøMåf[ +¨µÞ¿™·gæí£ž¯D}_âÜÑq®ÏsÂÖç‘¥d\–žWŸLÛg­¥û~‰‹ÆãbnåóÿþÊÜZ|ÿæCØ\­ Ðÿzÿ–j½?.Æÿ5UKæ†&¦õy/ßöyÛ†Úó/óCœª¿äãWé;âÏGB”’§L¨S¤U>`ô3[deÐw4Y9 ‡–mï]4Úr«(­Ÿb¥Ùò6_¸àm®›ýèÏu³ÒÃËÿ)=´ËïZ‚ù4\>õI/Ïõ•Ùî¯l˯5SOÙUS%.*ƒƒ>ú¢AG©ƒ”°m™¶©›©›u<›Þïe«¿Þ¯ûX¿xÝ>œ¸ûíò»`„å;߆åÕ×01ú/›í?;PÛ¶n¶þ›ºÙ¨%:œÙT… Ü{ëm“¦‚&Ë´ÞØýØzƒ†¢Ðp¿Â ÌY¢>>xJÏ}ï)-ly²¸EÓ–»Ö÷g:n‹sGCâ\ÈwëÃ\‡‹f/cŒNì¨6løµvÆ 4%6аÖ1çø•1ç‹íWë³óoÚ”“²zRzáZf³ïrwr®bqþ˜,οZíoêyÿ–©‡òGJÏüe¤”½"Ò}¿PæHnåóÿþZK©'¨.Tù¨åÁ¸ò=±ÞX)Ó¤Pµw•tj\%4sJ&¶LÊãüç‡éγíoùH41pÛZ Az¿ÛÛÓ¸|΋SMCQš¸TyE‘–±º™C_Ô͈óqžJÒ¨¼žÆ^KOc³ãð@ª‘f4n œ¾ªEZÆ38f\%Ç®Z?Ý%fåP_¡"ý#'kûG¶6kØJWŸèÔaõFYËú|··D}ÃBãÝUò¾«„fÂÏ­>Ùî¯ì÷ïz ŸIîÆãFw£2¦}O‘ÀÓõ1·¹žå³é¹ ¯ºb@=G9*âãΰüJ{nõÏV&ÛK×@h˜CWI'×UBý‡ú³«¤[ï*Yý]¸Š"ž«p„j;B´-ê“X]ûkòœk¢ÄTZBã‡icÌÛ<~ÅÛìn쵸)ÿ.·zÒí„é–½ê“-º ×ç9ÕÔç¡æÂµL2®ÿՋေ+|côã?ñcLJü¸°ð4¶°@#;ÎüãȺËÉ‹½ÿÅZîßÕäÖ>t]‘Fà«o ½v?zíýÕ¿·÷ÇÄøTL¤¾újµ¿8×óÌi]o¢¢-¥Ï/}¦›s-“òù­½sµòƒ3`úigÀTØòCÑï›”½?RúÃ_FJ¾rKú3‡ÌÏè3HŸS L¶<Îq~˜OÿÈ߯ÒwÙ&®‚¢}cNïcNMÅÛfM¥‡…å»ß†å‰Ññ¿NŒª_Õw¶×ÒwVçß\­óSIã¦7~à˜©=ì˜iÐ2Р_ù^ Ëóÿ𼉦(î¨÷ëëõ‹ë×vo±k»)ÝtdÇð—#;Ôå›þÙyâ¯æÞ]·Ì½š AS¡~\Ïú„åð±°,lÚû®°‰ÞÝðÖ»ßÞÒù·µèüC÷N}:t/·úd»¿rÛ¿kMàw?xÀkJÞ¦@MøgÞýhù•çµ.ŸmÈ^2®DÊ©çP¯sž¿0椩¿ò¯¶2ß^oÓ¹SÞ&ê-ÔèóžíÔŒC÷j‡îѧ£Ëð®Ë€Cs&h‚Ìš¾êß×ôÑ© ïÚlç]tÊR¨w¡=«žt–RgÓr-¯4ýžïöö{(!yå-`éÓa½±û¿¬7–¿ö—Gr°Ñ¤(­×øÁÎKƔ㭡Óð%ýúFÇÿê+Øñ¦ô^ù(†;5b˜rè䎽ê×Úûª+í}2Xy£åµ¶Öû7³žœKû´}hjv4yš4Ô”örÛpK m˜Æó¯¼¯î3êÇÌZ¾HËevÐ ¡_­ö·Õì}×V³zx%¿ö)<³{çE³Ûð–ákÃ[úkÛ[ô×JmÆ3¥6Wq·N™ë'·ò…úþ*,]`[‹.@w ±íß÷[Û~}@_¯Ðcþåcâ£`L¤þòÝ>òõŸí-ïO{óòÌÏèr)M&šÉ0–lËãüç‡êóÃlû@þ6Ð't·¯süG¯“– i^]ÁÖŸÞ ¶š{wý‡¹÷Ù´ Ú­Ÿî&YúÁ΋¥„ŸÜþ,üdõÀ}¶åÐ ñÜ)‘ò’(›I–“¥åS^$ãŒ%¤d<ñl>¯¥Ÿzž¯ˆ5r:bZ£ÃQ+­“–ÓÜ@EhnÈÍ1”˜|Ô™Ù€ÐlË ÿÀËàWh€•4x Ñ ”¡÷…˜ðæ@Ð MR@Ð MR@Ð MR@Ð MR@Ð MR@Ð MR@Ð MR@Ð MR@Ð …"4¼ 6lذaÆÌË/,,,,, Ý`í Ó MR(XÐ$ØúÓ{ÁVeE2ö¢7ìe«ÏË&ŸöAÛÀ›™&yiÔ×w7êK4†Î¦BcÐTh»¶Øµ]´<ÞŸŠwä³~yòqPž¬ 9×…4o›”õ‹áö¨V—T2¨&êǶ¡£¡¶¡ü·×Û|á‚·Ù¶ßomûi ÕÇÜýØD^'˜6/¼ks5ïšÐ]<:¡3V½6VQ˜£Á~ødƒ½Æj?Vcì’’“]¹­ßy°%à<•£ÃQ96¹‹ñ©¸huí>euæ QÃ\ƒþ“½úU‰ÉGÓ‰IÆŠ´…ÛR ÕÍ~t´nÖ=×[îžs²&æd‘òÈp¤Ü_|5á/F€×Éšdštþbì2èúz}€ò#êB­ É“rXžT—ŒZîöF-Z¡¨B«íÒîÑvQfD…ö[*´áÄÏŸ…+×ßÓð­¥§AY¿Æ ©Ð¶·èC‘ÓíC‘•åûGN:úG('‚½ÍãW¼Íùo©»á¸ÑÝ`¬zï¢±Š–pM\…ÓÑäq:¤øÕ·¥x®ëNÆ)ýá/#¥®âNÎULkÖ¶µèÍŽ#—›ýžSMýžõÙ_ëÝÞˆU–äyY2»w^4»•í-â¹ A[¹EÐ6Lðb­IÐdÆúhÆ~þ*ü$R~§7R–o ËmÃGgÛ†Õ%R2ž\ÅÝ:Wq¬#6눵ǤX»Î¯ûX篨ýSÍ€º<YÚ†[®µ {›.œ÷6%&áÄdèRðw¡Kf·éªòc^²3b÷½±ŽfÇ'ÍŽ•5),)>•”â–é÷oZ¦s[C81,œ  ÅbkôÛ+kúéY“»ìªÉòÝÚò­|­>°½U  ”þx\®Êv¸wN8ʬŠ·Ei¹<™Œ§_3À«kM‚&Jfgà*ø.~ßÕ6x4Ô68Rzîû‘RuIƒ¦¸Ó ±ËïZ‚´„^åtp:‚m7vÛ–¯»ˆWg|·Ìø(Àwm¶ó]¦ž²«¦ž•õiv|êivÐÿUö߯²‡åŸ„嵨v)vå¾s7ž°¹‡îþrè^n뉋oÄÅg[­e,ØvóC¥5´®·Ë´. ©,¶$÷ÎwnæRèàÌ¥ˆ%2±„.Ýܺ–ÃÇÂrÃÖÃ'¶æ³¿èYÙÔSÙt[p÷´R“n­ í¦€…´ð¡€×CFA“•‹®^Þ Ùö¹A³l ·ýsŒ/cÌ7vñºo̴ܵ•á9o›4¦½ï ›KÆ—¯YÐÕëcMçÏ5yJ8î)ÕvëëµÝ¥UÆJ«|c—oûÆVÖ‡ô?'ñœ <“zâÒl·WÙ–Ë·}c5Ž?Õ øF/þÍ7j¬Úñƒ2l'[¼kcï¢ÿµ.~Ö5—¸ýÙÜâ`¥˜øèFLä®XÙÚFõ;Ò@Wñ±„«Øë¿âuæ¿¿h Òнï?U‚Aþ²«¿ñ—Q.}àÀíøPÀë!£  Q?®^>œ¸ûíò¹HÂòoÃ2 î %QKt8j©ÚoÿCÕþ¶Á–@Û ŸIL> &&'FÿåúĨòê_†6ìýÕ•öþɘ”œŒ%&cRb²nÆñIÝLݬãpÝlþ’íöÒ=eêf?úsݬôðòJÕ¹3¹¡ ‹¬†CKŒ¶÷.mùoo&û+Êîé˜ûJî˜ ˜¯m˜ñ¡€×Ú ÏçÉâ´—wo±k»ÃòÝoÃòXÓ…ócëÚþkgÃÂÂÂÂÂMäéuŽÿèuÒ4 ¤lýé½`«¹wט{ž>\XÈÿfÃ6lذaCæåÑKÞLã¹S£#T{Ø¢1²Ä˜,-Ÿ5WîØûlɳ”õø‰ˆ5r:bZ£ÃQ+­“–[oì¶þêMhP(,‚¤„-ò —¼œ4HA€ŠÐð2À%ð²A¦ @ 𤀠 @ 𤀠 @ 𤀠 @ 𤀠 @ 𤀠 @ 𤀠 @ 𤀠 @ 𤀠 @ EhxÉR2.K©ž)âÓE¼Fx¶¨XùG³øÇc_„E|éÖ  ¼b<Æs§<ƬÈʆ™5Ý“šÀ+Æfßû®ÍÎX2Ƙ,Ñ_2¾ô|2ÎXBJÆÏòP’1å¿åù)É8cÁ¶›û‚m+ßs𤀠 @ š¤€9Mà•§¿¦oÐ_[¶è­Å¿_˜¹:8s)“u"Ó^y‘òÈP¤|õ2sOn;çžd¾NMà5‘.t’m¸„ h¯•Hù%t2÷$üUöá‚  ¼†ò —MR@Ð MR@Ð …"4¼Z|ÞË·}ÞU ldŒ™ÙFf~¶d[öï²,h²°°°°°€¦€—“#T{ØZŸ÷Ú€@ €Z°õÆî`kQÔŽZÐ?]@W¯   õÑ&bžŽXÑ&ð2Û) EÊÑ — «“âSI).ð{Š­/¿´ÁúÍí~óúWÈ:m¹cΤ$ýÃ.\ê½—@¶=¡xU¤šP¸ÄÞ_]iï_ÿ yŒçNyŒ«ÿ Â® ío‚eAu¸$ÞŸŠw¬…Ô×¢6ãF›Þ¯ûXï§gÕ?×1'‹bdFfd’oêäs°Zæ@“Àk¨¨°«ã»ÎÒv3Æ‹wTWÆÚóY[LŒMÅD½MwFoîzL·EOó.­kcW‘äyy’±dœ«%9Lÿ3&K‰°,1–Œs‚,Éóô?c1QV/«–Ï'¤¸Ž‹âÜÑhÈÍ*A“dìy/æ».\ÐvÓÿñŽ–B$ɸ²¾küÇ¥2Õ¿Ï/Œ¯ —X‚ï|ÇXhböW±>Æ;´®"ž+â㾞¨<ç¦åŒ1Æ œïbŒÉ“Ì^´‹ïb¬ˆ—'õ~]½Nãr}Í…]ÌÁ˜€v€|ä˜i¢„K>=gà»¶-,ó]ãZZ¢ó3Ƙ㻾oÒšÛu“1ÆÊ®šÜ|×÷MÚ¶:‰Xå°Óº6Wó]…ÍqˆZÃÇâb³ãðºÕó(-ÏWá7w[Í.Ãc’ùêÛ’G–e)á|úSb±…ãâã`\¤6OHo$$Y’Ãòl\||#¾_çß\­ó1OýHu˜n»¾sº­m¸=Ú6¬ìw9,Kö¾ì}mƒ-¶A*ixËðµá­ð“ðWá'ùo{&kÓ_ÛÞª¿f³Wn¶Ù‡î 9toùÞýÎðVøÉíÏ QŸ†­õß4l ùB‡B>Nà œÀ Mœà®?¾Ã]_j3ž)Ež¼¡ÒMd‰þR‹Zˆ”ë'kõ×ûônƒŽ±rf´1Ƙi‡òúOÂgcÌofìd­§”^¥<ûbP¸dMrü_saëc»ââÊ÷n»¹oº­§±[ßÓ(Kɸ,Q&ŽÀï}Wà›‡š§±Þ°ÜµÞð—¶ùËòßÞ®­p’q®‚þÓEZNÐóÅZWƒPÌ„~ö}S?Ó¿æ5BB’ƒ ‰ãê“¡ˆ×²È˜,rB¯°¸fƘQÊ´΃G.;ö¨í;kv›®šÝ¬Œmceᾟw…ûÇN0îEµm×t[p÷tÛô½àîé{‹5\u3µŸÔÍe•›…2ö=eýsWCþ9çÁ¦ ó Ä¦Ø û°¼`« ω?ïÅQKuåRèd×M6ÌØû·¦yÆãÆ®m«ÚÏØÍ—ïP°àEzQ9â|{Tœï™;Î÷Ì›ŒçM´<,‡-aùMëv‹y=5Œq IÇEfOi¹°ü`<,SÈ &&æc"c,¼<„—’ñ„Ä$Ƙô,ügLÞ‘Œ±æÌëãS1Qï×_Ñûc+Ë Ü;' \úþó8˜jjÿT3Ðìhò4;ªì{ß©²×Í:×͆å;ß*õÏ?_CœkˆsbôØÿ£>v‘ùÒ–¤ì•º™C_ÔÍÐtήâc²«Ø:½ûÑónà-ð•›—ßÉäÞuÓäŽôF¯FzÙ%vˆ]ÂÞL¿ÊçźÀøý5Æ>=× cìý[îzÆ‹‰Œ1–+¿Ûw–±O3êÙO^´9þâN½¿AWûIƒNYþk^#P&å8<+Ïkže¨r*{^ö …c(È¢^nà é¢Ó«¶~Üݰ•îDË›~z®ù`Í@ueÍ@ÍÀ?Ö P™°|ûÈ«‚Q‡ä’qƤø•R|¤t¸}¤”B!1 „E~ù*ey"ÌcòhÐ ›ö ›¶>Ù°u¤ôÜ÷#¥éÂ…d¡pIÛà_Û …KèYw}¯Å]ï/»ú™ôpê©ôÂ%mÃGgÛ†sk£š¾jú¨Pû¤ï'ɸ,™Ü¦«&·ôðÊ}éa&á’tú=µý¯Ü‚[JÀ›-Ç ÉR¸„æ4Š2ö}ý8¬›eŒ1W c'kûé=O)cŸž3¹u‹?é¯½Ø Væ.aŒ±Å–Œ3–£§•„ô4ž”ò+r—'ãòb¦ƒ<ùüIsëfj×ÍTí·ÿ¡j?ýsz¯Œ9ÓM¸cbÃÖOÏ5lmÐÕw7èèFËô¬«¸óï\ÅcMãWƚƚ.œkçÚ£âœ8ßɉó/·SfQöHÄ–ïö†e­kKµÖµ´w”|ŸÅ ‰îŸŠ‹´$&Ê”B{$–MhÖßèåÛ¾QßýXàGJÏ)m>Ør­ùàÊò5Õ¨玆Ĺ•ÙëÞˆÕ>Pýû€õÆîÿ²Þpl:ç<òÍ ùòi+qîXBœç;5ÏÛ³5}ûvÕôåó^cÎñ+cN¯ó¯“ú‘ð&[%h²xœ”Q˾]‘rÆNÖ†eÆ‚»‹Zö¾CK¢VÆNÖÌJ™ë;cìdm°M)³Úš×Þ‹ÉqhÐhÐ5yN5Y¦ß¿i™¦Ÿ¦é~ 7nýø›Æ­4Ä:½ûñò¬¨5z:jmØúÉɆ­”oBš†åŸ_‘L“¥ü¥õ–ÄÄûã1‘‚#ëƒñˆ•FÑP)ÚØRò}“%Z_¶Ã¿ \q§£-~’âWî§Êé A+>ï•û>ïÊgi†P£ä›\¹/=Ì¿WS°Œr””\˜•m¹4#On&¼šðö47ö4R0Nëâ÷(,€7SÖ™&­ÃíÑÖáÖᣳ­ÃúÀö]]èêÛŽZ®”Zú\ lwÌPš×ƒ^»¼üúy±9zÿö½¿¦ïjú†îþrèžzКɽó_LnšŸ"Ý^ Š’orîŸÆš–z^^²ôø†* S‚ kätÄJÁ‘˜øøFLTf–YÊ ’¥dìÙ<&‹÷0ZÜ ñlêà7_}{yÛ†|¡B>­k³=U° §þøŽžú˜ø`<&ºÝêg©¶z¿þcýâð«¡èLJ¢…Ú#”o²ò}óGáÊQ¢°‘Þ¯{¶o²´AŠ¢~¤`LjñÌñ#Ý•î<2bþrÄHC(8NTnž{’Iy*£~—õØè‘ãà7¶-ÿ‰>ã»}dƧ÷o®NõUœ;&‹sqñÁx\¤9&ÔÏRàFýãv¤ôü…T9¯Nˆ‹Ñᥠwåù¥ …Hh«)DB=Ë2†bŒ)y™†N†¢§Û‡¢tw!aÓž_ ›([§ïloyßÙt¯ê?{boÿÙ`Û­ƒm}žGßâ~qK¸Šmû«ÿ`Û/lªÜ"l¢'pÅKý-wt÷³{×M³[¹ öóÙöïû­mÿêe·6kÜJíV7{èÏu³Ô¶ý{ß}Þk^oE¹½Œ«à ÊtªÄäÞyÌä›׌Íç_~í<Ëq¨ä*Ô9žE9(‹êí)rÄdœ-þ¼×°·™f)ÇA“þ}i0N|üXLÁn¶ˆçf]Å‘ô3G¸Š»u®âfñ³šÅ!÷Ó»A÷ÑÑÍÇÑà©ÿ¦Á£åkg­˸ÕS¨Ÿèk-¡Ê‰‹oÄŘOÞóÊVy^¶*wÆ¡2ꌒ§qÆs|¤dŒIêðÁâ^(Ym/¨Q •1ÆoµË»Ïs³ûlÙÍ}ÃOÂ_…Ÿ<ûÈðŒì8ó#;˜ƒyØâ¢iÒÖv€Õ°ÅõÆØ®g­ªcŒé‡·ècº„”ì^ÊE’ÃŒ1cÌ¡ø°¸¾y|¨ 0V š,ÍÓ±x«Ýc,Báõ=eÔŒ¶wOm¡È¨ê$Çá:‰m-âÙVJÆYHs°ˆ×T†áñŒ1g2Μ‹ëŸKÆØc¬x-7øeÈq€/|,&ÆçâS<3Š;ÃÆ*fcÌX•b^+zÖÂnúñ™wŸõRŽÝd!¿ù狌Å>Ø+K¬žqØŸŒ2M#gŽF¢–ùcQKBb,±x™•ÿk…&­Ð1×É:æ4Ó©Êè4BbޱDÚåŒ%ë±ÉÈqxñlö=EaÄwîTHd^y>«»Þ˜Ó,÷1ÆXƒpà'0Æ.2Üùò’QÐ$41{(4Œ_ߌ33[úÙZÐÿ-Ó–˜ez­7xÍsÑ©ž¯Ôf<ÃX)3Vü¦¶6„K 0ÒM–ß*u) à:ê­EU(4£alMG¹X§MWãb¿ïû#AÆj‰G-kQ-ã÷h™ŸJJq_W¯ók]Ú=Zcìcì(X_)2M~O‘ÀSðbý+¤—èýºõ~ì$Xi‡çmÆŒ¶˜›Š‰ëY!„Kàe6hBa ½MwF¿ÞS›>w0Ž. «×tLW¯Ã|aL=eÌÔƒv€×Õ†Hyd(RކPûš`¥ÿH¯°:QyIEND®B`‚xymon-4.3.30/docs/upgrade-to-430.txt0000664000076400007640000001512511535424634017262 0ustar rpmbuildrpmbuildUpgrading from Hobbit 4.0 / 4.2 / 4.3.0 beta 1 / 4.3.0 beta 2 ============================================================= Xymon was renamed from "Hobbit" to "Xymon" during the 4.3.0 development cycle. That meant there were quite a few names being used for Xymon for historical reasons: - "Big Brother" or "BB" (really the original software from Quest) - "bbgen" (the precursor to Xymon, which used the Big Brother server) - "Hobbit" and finally "Xymon". This was evident in the names of configuration files, programs, tools, commands, webpages, status columns etc. etc. The forced change of name from Hobbit to Xymon was seen as a good time to clean up this spaghetti of various names. So with the 4.3.0-beta3 release, all references to the old names have been eliminated from Xymon. However, that means upgrading involves a bit of renaming stuff. A script has been provided to help with this task. For it to work, it is essential that you perform the upgrade like this: 1) Make sure you have a backup. It is not necessary to backup the data in the hist/, histlogs/, hostdata/ and rrd/ directories (if you use the default directory layout, then that means the entire data/ directory need not be backed up). 2) Configure Xymon 4.3.0 using a directory layout that is identical to your previous version. Make sure you keep the directory names exactly as they were in the version you are currently running, even though that may include "hobbit" in the directory name. 3) Build Xymon 4.3.0 (run "make") 4) Stop Hobbit (the current version). 5) Using the "bbcmd" utility from your current version, run then "./build/upgrade430.sh" script. I.e. run a command like ~hobbit/server/bin/bbcmd ./build/upgrade430.sh This will perform almost all of the file renaming and configuration file updates that are needed when going to version 4.3. A few updates cannot be done automatically, you will be notified what else is needed after the script completes. 6) Install Xymon 4.3.0 (run "make install"). Your installation should now be upgraded to version 4.3.0. Run your normal startup-script to launch Xymon, or the ~hobbit/server/xymon.sh start command. If you don't feel comfortable doing the upgrade using the script, the rest of this document describes what must be done. It assumes that you perform a clean installation of Xymon 4.3.0, and then move your old configuration and data over manually. The ~xymon/server/etc/ directory ================================ Copy over the existing configuration files, then rename them as follows: Old name New name -------- -------- mv bb-hosts hosts.cfg mv bbcombotest.cfg combo.cfg mv hobbit-alerts.cfg alerts.cfg mv hobbit-nkview.cfg critical.cfg mv hobbit-rrddefinitions.cfg rrddefinitions.cfg mv hobbitgraph.cfg graphs.cfg mv hobbit-holidays.cfg holidays.cfg mv hobbit-clients.cfg analysis.cfg mv hobbit-snmpmibs.cfg snmpmibs.cfg mv bb-services protocols.cfg Four files will require special attention: "hobbitcgi.cfg" is renamed to "cgioptions.cfg". Three settings in that file have been changed also: CGI_HOBBITCOLUMN_OPTS is now CGI_COLUMNDOC_OPTS, CGI_HOBBITGRAPH_OPTS is now CGI_SHOWGRAPH_OPTS, and CGI_HOBBITCONFREPORT_OPTS is now CGI_CONFREPORT_OPTS. "hobbitlaunch.cfg" is renamed to "tasks.cfg". However, most of the programs have also been renamed, so it is probably easiest if you use the standard tasks.cfg file as the starting point, and the merge your local modifications into that file. If you have too many local modifications, see the "docs/Renaming-430.txt" file for a list of all the new program names. "hobbitserver.cfg" is renamed to "xymonserver.cfg". However most of the settings inside that file have also been renamed. As with hobbitlaunch.cfg, I would recommend that you start with the default xymonserver.cfg file and use that as the basis for merging in your local modifications. If that is not possible, then you can use the xymond/etcfiles/xymonserver-migration.cfg file together with your current hobbitserver.cfg file. "hobbitclient.cfg" is renamed to "xymonclient.cfg". As with xymonserver.cfg, a lot of settings have been renamed, but since this file has very few it is probably easiest to setup this file from the standard file. Finally, if you use the "nobb2" tag in your hosts.cfg, then this has been deprecated. Please change it to "nonongreen". The ~xymon/server/bin/ directory ================================ Most of the programs have changed names, so if you have custom scripts that use some of the programs then these will probably break. I recommend that you setup symlinks for the following programs in ~xymon/server/bin : ln -s xymon bb ln -s xymoncmd bbcmd ln -s xymongrep bbhostgrep ln -s xymoncfg bbhostshow ln -s xymondigest bbdigest The ~xymon/server/web/ directory ================================ Some of the web template files have been renamed, and since the menu system has also been completely changed it is not possible to automatically migrate your local changes to the templates over. In the docs/Renaming-430.txt file you can see what the new templates are called. The ~xymon/data/rrd/ directory ============================== Some of the Xymon-servers' own status-messages have changed names, and therefore the RRD graphs have also been renamed. So if you would like to keep the history of your Xymon server before the upgrade, you must renamed some of the RRD files. In your ~xymon/data/rrd/XYMONSERVERNAME/ directory: mv bbgen.rrd xymongen.rrd mv bbtest.rrd xymonnet.rrd mv hobbit.rrd xymon.rrd mv hobbit2.rrd xymon2.rrd mv hobbitd.rrd xymond.rrd mv bbproxy.rrd xymonproxy.rrd If you have multiple servers running Xymon tasks, do this in each of these servers' RRD-directory. The Xymon internal statuses =========================== If you have alerts defined for the internal Xymon statuses, then you will have to change them since the names of the internal statuses have changed. So in alerts.cfg, check if you have any alerts for the "bbgen", "bbtest", "hobbitd" or "bbproxy" statuses. If you do, then change them: bbgen is now xymongen bbtest is now xymonnet bbproxy is now xymonproxy hobbitd is now xymond The Xymon webpages ================== The three top-level Xymon webpages have also been renamed, so if you use links directly to the "bb.html", "bb2.html" or "bbnk.html" webpage, then these will have to be changed: bb.html is now xymon.html bb2.html is now nongreen.html bbnk.html is now critical.html xymon-4.3.30/docs/editor-makeclone.jpg0000664000076400007640000002304511070452713020063 0ustar rpmbuildrpmbuildÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀº†"ÿÄ ÿÄT  !1"2QUV”¥Óã37A³#5t´$6BRau²%4Crs„±SWbcqv‘•–£¤ÑÔÒÿÄÿÄ1!ÿÚ ?ÁHPi¥Q’öóÆÄX̪D—I9#"äW+™©IIÈ®¢¹‘sÈÊtL¨²›ÿ-S$·ÅÇuç‘!·œJLÒƒJ[I£#+^ê"¿>\ǯGgkNø!‰Ž?U€N©•,œQ¼Rdɤ¹Ñ'™•ísïD Z¶«R┩L°¦3&ÔäyM>”,ÈÌ’³mJÁ\’¬|Ì=ïè}JËŠmpã›dêLæ·h%’šI,ÍÔâwº2.ÿÄŒ:‚¶FD©UÒêá4ÖÓ6'~Cl4ƒ;Øn))#;Š÷;ú7§k «;Kè˜IiŽn:„6„XŒ–n(Ƀ¹YW±Ü¬|È6 úå£E”Üz”rin´O4iq.!Ä™’´™¥I¹\ŒË‘Õ‰Q«%ÕÃi¢i›?!¶AìF·”Üìv+Üìa³Ñͦtœ©Ú©tZ™&nj짉rZhÔ„4n!k¥eÅ6¸qͲu ¦s [È4ÉM$–fêq;ÝâF#(ÔJ•].®Mm3bqçä6ÃH3½ˆÖâ’’3±Ø¯s±†ÁÓS.›5pç0¦_EŒÒfGr2¹r22222ädw!<ΓzNŒƒ]&]~T–ÜCõ8ÌÙ ¥“M’µ’²º×rævÀìD¢5-V[dh÷æShShŒ&¡q™9”fú_u¥%£V_m*À²QdDf|ŒCÁ¥ÉT ÛÎ@K‡¤ÙÈKnEQ¼„ç¶g’ùÝDFI5‘¹PE›oJWœ¦*¢Ü$)”Ç9*AHox™"¾æÖ[˜[žXÚÜïaØL–•%·`–FâY!JMù‘(ÈȎߎÞc ÑólÕº&§I¬V›ˆÆä*|—’’\–ŽFÂiKŠhŒ—c+X‘s¿pˆ¤iÚµR)ÊŠË c3m.H”Ó ZȈÍ(7œÕ̹&ç̼áÔÍ@%`éÚÄÉr¢¢*Yr"°’ržDt´«™T§”’ŒÈìW¹ØüÂJ¤fÊÕ(54)1 É¤;%¦|dGSøËá 4 h8ƒY‘J\—#¾œv”K$§ÉqG—Š£îG+”W_Ó…òªšShKfl",Æ¥8úÿ¢œ[Qš ÎkµŠüŒìG`eø´åèç¥N„Mª‰*#Ž3%*+9+-(3R %!µØÈ¼»Òd[eG=2Ÿiù#ÇXú12 Ê]IÇÿHÛIm©%’”µ¥ "É¢.õy–oªÅ "hv²ÔÊ…:Cµ[b;1&7 üWáºx’H‰›*Êñû»ÄâI ñJ¸íJ˜qã·J7_ME…2ÚYe¤ºFá,ÒFFÛ…kÜùX"½ó³Äù)ßù”OþÇâŸÀHêxú~eBT)oÄvbRrÙtÍ–Üi Qm¥V27‘bQ¦üì|ŽÓq§žŒzqÍ<í?ON¤ëÊMB ¦[ZT„"íºÛͶ«jïQÜ–FŸÄ{Ó1‡kˇ^™d™¢UD3s¡IVù8qÍç3¹_"s2+¶I.VQç¢Ã®Ê'Af¨³pÒ—cµ3¤³ÃZÌÛiË™9’ù‘)jæ}ãëLi Õ<ÈQ¦Åžì“D©(Ž—ãm¤Œ–³$ÝÙò3#ý'+óσB¤ª3Ú‚=ª•9J§éɰޒìÆÙiÇ\jI%)[ŠI*Ê} òþ©Ÿ’W,®<—c¸m©m,Уmĸ“2;”“4¨¿´ŒÈÿó“¿SÓ ªäJ¬Z¥#itú|fÛr{iuN¦;,­&ƒ; ’¤¨ÍKÅ6+ߺòî’%qƒT¼š•0ØÝUM>º‹ eļéd’á¯37+ܹ܋¶rr.´›GÓ:NG†!@[Z÷”ò_m×b%E’ò™%gb6\>d^IY7kDBj‚²½*,çg%FÅ"¡¿J ý2›%¨›RLÈ’W.N+Å+ P"ËÃdµ ê)Q"™S'%.I–Üt渮6‚%8¤•ÍkIZþsî#2SÛ%pÒ°g&TuHn!•Jm/)(nBV¤¶jÌÈÖù‘~'ýUZ´Ø4;ÄëëÇ…i¾ é?k¥£åѶoÿÑßmÎöæ?zUPœ£ÐܨT)+–k’Sz-B•g–¯Ñ,îýÄÙ æ³.]ã9žE›M°šŽ‘«R™<·'—)¸éShnJVd¥™™¨å{ùØyæØúMèI­ÓdS›«*ÑZY®8MÛ}$i%mšy™—?Ââ°Q3¥eÆeu&©C8ª|ÈÌšQ8‡P£"çŽm¤Ž×2#3±÷«úp¡Ã~UB³Jm lÍ„E˜Ô§_ôS‹j3AyÍv±_‘ˆì\Ð q³"”¹.G}8í(–IO’â/GÜŽV!°öTsÓ)öŸ’21Æ_‹N^ŽzTèDÚ¨’¢8ã2Pò¢¸ó’±RÒƒ5 ÒR]Œˆû˽&EQ@Óµ–¦T)Ò¨²ÛÙ‰1¹⼇ ÓÀÌ’DH4ÙVWÝÞ7~ÊŽze>ÓòC²£ž™O´üÅd‰$3Åý*ãµ*aÇŽÝ(Ý}5Ëie–’鄳In¯såb<Šþ<ôcÓŽiçiúztèµ'^Rj2ÚÒ¤!mÖÞmµXÛWzŽä²4þ#iì¨ç¦Sí?$;*9é”ûOÉ‘€ëé1ߨBÁ¤Q!%…"žn)”+5¬ÒKqk7-²½¿äDgè§Ân±¢`Aj§LˆäJœ·¤tÉhgÜj1%D“<—Í¥òA(ùws!»vTsÓ)öŸ’•ôÊ}§ä‹Ÿ©c¸å#FÇfd¬éêkOdö\T§œ"rÊýŠëff¼mÎüÒ«MV›iÝEÄÇš¨R”Ô”8¸Ê*ƒ|•5—Ó·ãøç¶…“s#,NÊ2#×{*9é”ûOÉÊŽze>ÓòDädŽªèi•2¡Iw)4ÍB$݉ÉscŠã³5¤ôF¬ è畹 ö3+‘%¨í›i[«$$Üq-¤ŒÎÅu(É)/í3"/ÄtïeG=2Ÿiù!ÙQÏL§Ú~H²b2GI¸Áª^MJ˜lHnª¦Ÿ]E„²â^aÔ²Ip׉™›•ˆî\îE‰Ú â&¿§hÍC¨S£»NeÆ$3.cqÏÆyn©ÌÈ”FK$Ù7W‰ÝÜ7~ÊŽze>ÓòC²£ž™O´ü‘9VHÌØµ)µ¦ãK¢Îg-J›½–M¥HCªZ ##2#23'OÍcð0õ5¾"ÊDzŠUÚlˆ="VhC‹€¶’Þê¬F„­DÚTv,RGÜ6®ÊŽze>ÓòC²£ž™O´üäs]fšº\”Gr\.)²Zú$„¼–ÌÌüSZn“;Šf\ËîE=R„ÝSKPå3S¦4Šu1Öd!éhK»…&C„„µ|ÔjKˆ±’q¹ó2±Ûvì¨ç¦Sí?$;*9é”ûOÉ âuõã´ßôΟµÒÑ¿òèÛ7ÎÿèïŽ6ç{s]ÙÿR6|)  xK.’zFîÕ·mká‹{Úÿ€èŽÊŽze>ÓòC²£ž™O´ü‘\¼¨{*9é”ûOÉÊŽze>ÓòF‘ËÀ:‡²£ž™O´üì¨ç¦Sí?$/êÊŽze>ÓòC²£ž™O´ü¼¨{*9é”ûOÉÊŽze>Óò@rð¡ì¨ç¦Sí?$;*9é”ûOÉËÀ:‡²£ž™O´üì¨ç¦Sí?$/êÊŽze>ÓòC²£ž™O´ü¼¨{*9é”ûOÉÊŽze>Óò@rð¡ì¨ç¦Sí?$;*9é”ûOÉËÀ:‡²£ž™O´üì¨ç¦Sí?$/êÊŽze>ÓòC²£ž™O´ü¼¨{*9é”ûOÉÊŽze>Óò@rð¡ì¨ç¦Sí?$;*9é”ûOÉËÀ:}Ee¡ QÖSb+ŸòŸ’9×XÒÛ¡êêͧTótùïÅCŠ+É·’3þÓ° Çпï ßÝù/ŒoBÿ¼7wä¾³„F®ýTÇ÷Œâšâ·Ä·e1£ä=Æ[–܈ªao6n6•”†Í&¤’’jMír%$Ì¿ï )uçõRjqSC£µ&j%I[’™lÜ#þŠIk#+wÞÝöü;üQIEô€¦Óо¨Ï¹dGoåy\ŒËÿÝž(zó@ÿÓjÿõ žÐu"¸‚zQê87#Ñß‚Ëqij‹buøë5›Ë½¶­k”|Ç8Ó‰Àtd¢ð—ù¥Äû·?ø c°µO§Ò&W߇§:‡¦pðÜÕNÚu«²‡×²ÖNàˈZ®´wز2»ô[¢EÔµšÞœœãÍĪÁvëdÈœJ! 4™‘‘*Ê;\Œ¯øêíGú]n©>SµjÄHuM¿ S£<ÙF¨`’InäƒY] J¶¤d”‘ÈßëEbf°›G¢éæ¦À¥Éf-Nk³É•¶ã¡Û4Þ ÜÅ·[Z®¤rU“‘•„cŠÑéâ>ž¨5§™DŠ“Tä3õ‰•U3uÂm·:$ÿF¥)'É̉*ÈÒV2+4Áê·5*Õbš©.4ìøq]l£Í[DIBœ% ÖGŠR“ÁHÉ)"UÈCHám1Ùêpµ¡j«MÖüÛ¬&?KL”É5ín)*q74©fEsÄ’d“ ¡é‰u¸šÒ‚t Dj¤ÇÖÈÛ“4â´Ú|<ÁšÖ²BÔEÈŠÉBŽê.⹕æ7ªu8Txô]2Óõê‚ç¥ØRª,Fè/ôy&§’ÚÍDNš›#ÆÈŒñ+Ún…¢©TzÄZ¤iVôo `—“IøBb%½{$Åq²$ó䛑ä|ljþSÊ4oVk4©ÑfÏ˜ÄøŽ4o#¦È[ïµgSjlÖ¢±)e‚÷+€ƒ­ñg¡PèsÛ¤Aˆº“²ØºÍP¡D„üWv]er ·ÖnÉb%w+nÔzơũô§©´¶ôú(TÙ¸G'ã­ó™’’”²ipÔ¶‰[¸’[JÒfkR Mݽ9‡IÔ5ê;1RêVìWšZån«'Mâyµ¥JRJ5bJ#R¬esZ.†§Pë4Ú…¡R‚ÔTzJ¡¡M­™Q£“„Â\5¡Kº Õ™“3?"äÔ??ÍÜÿPÿà?œ]V©.§=Ýés[﹉'7£RŽÄDEs3äEaæÇпï ßÝù/ŒoBÿ¼7wä¾³…o‰_Ìù´Eþ!±d¾%3ä~Ñø†Ä¾Bš/õ„ÙÏühbsEþ°‘û9ÿ_Ïà¼} þðÝýß’øÁÆñô/ûÃw÷~Kà;8Vø•üÏ‘ûD_âA[âWó>GíˆlKá!9¢ÿXHýœÿÆ'4_ë ³ŸøÐ1üþÑÇпï ßÝù/ŒoBÿ¼7wä¾³„\2¨è4’Ý— 5w\ä´\ÄøˆÕߪ˜þñƒüSAE+À‹ô„?ýÏÿ€ Ì‹NÖíéå>OÌ—J~jM¤«6ÓÌ ò5s3x¬DGäªöår©eV""º˜0–«J%²Ú¶ÒEsRn“33µ­~ó/ûÇ’Ÿ¤ 1(SŠIi)äJ]²?åyˆŠÿöçÃÀ: Zú2jý;£ulŠ–£©& ”š ÙuÃYàâl[iW?¿’€ííŸY?ø2~ðj:ð¦¯Ivk0Vµ!mÉãq•¡d´©$ã A™)$vRL¼äcˆ@O}káŸüüëÿfkÿÀ=úO[ð†ƒª>±¿Å-I\š˜Àlªq Hm·iÅ[j#g{²Žó2.|¹ŽR2.€*lá¯ÛÖ›©ÜÕþéÛ¶àÝÜ0uMù[…{ã~âß^ú=ÒÚ˜¨ª×Uq.fhÒò‹™´W%’Í&_¦G{œ;Ù§1ø±À:;ÛXkбnáŽzFRm–Õ¯u?n‹ÞØÙËÛiÌ&˜ÂnìpŽöÖâ¬[¸cž‘”›eµkÝEÛ¢÷¶6röÚs£½µ†¸«îç¤e&ÙmZ÷Qcöè½íœ½¶œÁ¦0€»£½µ†¸«îç¤e&ÙmZ÷Qcöè½íœ½¶œÀÇèïma®*Å»†9éI¶[V½ÔXýº/{cg/m§0iŒ îÇèïma®*Å»†9éI¶[V½ÔXýº/{cg/m§01À:;ÛXkбnáŽzFRm–Õ¯u?n‹ÞØÙËÛiÌc»±À:;ÛXkбnáŽzFRm–Õ¯u?n‹ÞØÙËÛiÌ pŽöÖâ¬[¸cž‘”›eµkÝEÛ¢÷¶6röÚs˜ÂnìpŽöÖâ¬[¸cž‘”›eµkÝEÛ¢÷¶6röÚs£½µ†¸«îç¤e&ÙmZ÷Qcöè½íœ½¶œÁ¦0€»£½µ†¸«îç¤e&ÙmZ÷Qcöè½íœ½¶œÀÇèïma®*Å»†9éI¶[V½ÔXýº/{cg/m§0iŒ îÇèïma®*Å»†9éI¶[V½ÔXýº/{cg/m§01À:;ÛXkбnáŽzFRm–Õ¯u?n‹ÞØÙËÛiÌcÐT¿£>¢Á½^KBKR4ãÌ+ÆBV^+Ž$û–D|¹(”“²’¢,£ŠšJ.ŠÕ‰XUY)d–·Î.ÁòRM$œ•r,{ù~<­ÌÚ*€(Ðú;ýÆiŸ÷¿â^;Cèï÷¦ÞÿŠtO׋H™ˆÞª¬OOG‰IÊyݬrB"3u_mòM¯“½ØæVÛn+Fjê’éÕo®ìC¥N¦Gn úY%Æd£¹™™¡Hyµr3ḧ®D>Õ]6Þ¡ðÍ6V @zµDÆ•å5¦ã°{ffÚ2J”„’•w®”©Ù·ç™Ã /Òð52C‹2šuN=>l”ÆA )&DiQ‘ØEý+Œ*=½l©@€ôøº 2>›©OŠ‚R†Ým.ÃÅì[ZŠéNç%Yi%Ȳçö¦j¹5n'R#¹L­Ñbx¡)lÏ$!–ü"mÛ!j+¤Â²¬´’ÎäYsúž‚ªÔê=ªõ;uhˡ̢› Sú1›R “[†­ÅÝË5c±NåbMŽñÚEë,Èœö¥j­8èÒ(‘Ûf bà‰.ÇÎB”§Uu¥-ŽÖ#±b’2²ˆ’ÒZþEYÊl(3æÂb¦¥Dm´±$‡K*qN8G‘!²5]GÌÒ“æI’¡ëš}Z¥;tÚ¤x•YSj¶‚8ГQíÙf²ºR¥iNII™\HRôûTýM2¯ÒK2)éíÆ&ìM&:ä(+ó¹Hµ¬VüïÊ©¢xYMÒµÈrà1§SemPn~*JIrQ(ÍV%w’¥[Æ3¹Ü¯­;ŠpgA£ÎoJj„F­¡'KZã3ü­fÙ¸M‘¦i%=PªeÈyøËjShI±!¤%Ãef•f¦Õ¸œMI4¤Îý×ùÊ×0Q!q`RªµI}1è¬Gˆ†²l’wœJ–´¤…(›3R“ã‘‘ò¿•zS” ¹\O‡åTÑUðšbY IBP„YÏÈÛm-šMff“UÕs¸òêRªTz D"™"E§eUzb'°ñ9‰º§R“u©HJ²J’w¿y‘¾*ß§jñ+´v*‰Ô´é©&‡Q‹­ 4- /ÁIRT“/9¤êýfº¯ utú4 Ô[ N“O«RÛo`Ò±q¥%f´ì¤š’ƒ2曑\\4…½=§bÒL$¥ŒÎÐá¢+$jZ–d†‘Éu+™þ&fffu¤hZ¡hЦ‹V¥iTWéÒ©èð}ŒÚÐhA¸½Ë;‚y"åßsæA!^×TêEJdg)µY1iØxN|vqàæD¢ÜºÉgd©*<¬Rdgaæ¬ñ2}i…Ы¯Å¡:”Tç²ËG2TËoffn”’C„g‚T¢±™•¬gùÔšmRUi˜µääj |/P÷rÍ%•í;™y´„ î•÷\¬cÕVÑÝ>‡®)žÛúÕ»úM‹ô\á5»/ÛY÷§Ê·ás|ªþ¹§Ò*#®›T•œH:œèí Ø‚JI(·2Y(ì“%ž ^)23°ú«XGVª“§âQêÓ Ö™™)„4lÆ[‰J’J#Y8eŠÒf¤¡I+ó2±Ú¿ªøYM­jyÕ´1§VåGlåR€Ô÷’¤!-’™qj,æ`Ðlnô0eu$ÜÖ-«¹|Ö$/bKbŠ—ê8ØðûøŒ^´¨ñK´–a.žÂ£¥…UU &«$œRГ%’È)‘ÌÃqîÙöÿ8a»fwÛüá]Q­Ö0ÛØ–—QIJæ¢$Jl˜³\‚¤%R¤<ƨ’‚m³3S)$)Ed›—VbNØ‹›HNã †jN/6âCD–‰LÐ÷^±Fd¤ºzÒiM$‰•— XY$h5ÿݳ;íþpÇ–^*Å^Q}øS£·&;¹–œí­$¤ªÊ±•ÈÈìdF5þ¨b|CŒ#¢MiT¨ŒaúUJLhŽò\û’uˆÖšWvÌ™$žCÚDF•Ó8–‰ñUq/nQ™Fsa&‡CÕ‘¹=)ˆ•"J–esB9R–̬w%«‚Þû¶g}¿ÎnÙöÿ8cH+Çð®"¨¼ýK"p¬Ê¤Iu ìº$´‚4Œâó´yŒÿHJ¶T‘¨óXm|?¡ ·S¬È«IZó©×Zi²EÈ‹"ÚSd‘™fÌ­§uËcvÌï·ùà Û3¾ßç X¢•AÝúWÅUN²°Ws×âÿÚ“ÞË6.X•ú$îuß-ó'ôˆáûŸta··lÎûœ0ݳ;íþpưsOo¦S•VSRV2Þ”Ý-’ùÔê²ÛswmšÜ+ßhñŪâÆé½s½‰Þy‚Å®RŠšpØ&N2ªÊ„’55™Ò“#%ˆ¸$FFw3 £J¯V*äÀ¨¾óHôe+2ÓguM8›¸–…øŽ×+•Œ]~¬¶ŽÓõ54ä— ¦·ò›«$©f”‘Ÿò¡J±wgÄF4æ*uŠf¡† ¨îŒÕR´ôg[iµ¿R3¨Ê%fâ„¥£2ºlj3ÊfDwéÑ”Š#GÚ(ŠŠÔ©UM†ßKí³ú6w¥÷I„šM’—A‘×°ÈÔe°ßݳ;íþpÃvÌï·ùãb:ô™>§3ôâ}né¥êJiöanþŒÒ’_èÔ‚eyÔ«©eîx…¼ UÅ…KÑÝf¯‰Þª–'i¶æE\6i£\d¥mšJ%]›Ôi<ÆdIØDovÌï·ùà Û3¾ßç iÍb¼iZªÐª3ãÔ‘O«›Å)©J§"4c&Ö´¦>­Ó¥¥H$).FdŒ¶­¹]Ÿ€¨Õúþ ‘U—V¦E”¤*;-4É­²Qä&ÐGsÌY³•Ë‚I-€';¶g}¿ÎnÙöÿ8bÀ×ÓdbF4¿[ë~•I¨f S5Ûº¤äLŸå ¹r0îkð¯|¶±qß`l7êËaØí?SSNIpÚa+)º²J–iIð*«q&|Dbîí™ßoó†5ª×£cILÍj$ o¹§ÇŠùÉiM–C©I8¶Ð¯tÓJ¹%'r2ÚW¼f­Ž1‰¿@“GªbI0«²2kŽ%¶–ɤÔNDCŽ“™¨’’Ý¢ý!ÝyR ßS«ÅTÒª/¶íBAÆŠœË=c„ÓŽšn\\–w;ÜfD~­Û3¾ßç j:túìÚžj¾Ô”H‰‹_a¥K\S’¶·¢ZÈÞ(ËSI]Ö¢±Z䔫)ftgˆñª~©ÔqiWU‰£L‹¹˜m1Ô˜ÊtÜF­$¢Ê´k%‹3…bN¸·lÎûœ0ݳ;íþpÅ€•ýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç 7lÎûœ1`_ݳ;íþpÃvÌï·ùÃýÛ3¾ßç yåV\޲mÉÏëFiA8f¥[¸_¬ûœ£ôaÿþ½ÿhnþËËú¿ú>ï˜Cß9% k%¾ÃŽ™’P§Lïné'sé¹Rÿâ&KõŒÛÒq(Ò•¬Ì’f¦®e~+Ø¿ÜC¨+Ù5Œj5;ºÿ¢ÍÇoÕ}—¿ÿ]¶ŽXêýÏ¿?[—>ä“›/ó7{~¡1ÌuÍV§Mn©-·*´¼²RTòHÈÉG°öˆ[´f÷ÆtÈzMªS÷lƒ}Ö£¢–IÍbImTSR¬„¡jR•• #3°ÌÍÑÞŽÛ˜ûhÑÞ $¥ÅðDØDøb×cíÿG˜3û¿£=‘׆#¾‡ã®ŽË¨×dZ ´©:哎ØË‹:È”¯”¢#;˜ñD¥à(ˆœˆ”ì55)¹©i†RR¢2R\±pÈÈÎäw½ÇïcíÿG˜3û¿£ÇÚ=þ0g÷~'F e÷Ú•á8\ú}a¾Ô¯ ÂçÓëŽÇÚ=þ0g÷~'F´{ý`ÏîüNŒ&M—'T$ÆÒ]J'¾§že†éy Í$’#5E5*ÈJF³QåJHÌì2 £àw#RÛ¨3@©=Ka¶bÉ”Äcq²A§*I(â½I"îÁ{±ö£Ìý߉чcíÿG˜3û¿£ûYëRS*± T_CJe.Ëi—V–ÔFJAˆÏ)‘ˈîbŒGƒT¢Ô`1.€Ó“Ö—T˜íHiå¤Dn¶fZÎ iFÓ#±Œ¬V«±ö£Ìý߉чcíÿG˜3û¿£ŒÂ 3Eó©fPª Ôd‰";LÅQäCiBº‰(JBHŒÕînffc3Oƒ©Ñ¢Å§³A†Ä7MèÍ0–›KTƒZ¶%F•©7-¶Q—tÅžÇÚ=þ0g÷~'F´{ý`ÏîüNŒ_}©^…ϧÖ-M¨ÓŸ†ó Wˆã© }§š5´fV%¤–JMËŒ³–ͤe°c{h÷ú<ÁŸÝøv>Ñïôyƒ?»ñ:0ðÓ Ô©7¥²'<ÚZvJX¤®!74¥JÜ—2+ˆÏeÌgê4ü RˆˆuXrdd<¹ eö™q uj5­ÂI‘‘)JR”gÆffg´ÇçcíÿG˜3û¿£ÇÚ=þ0g÷~'F,ÝRÚ„T`¥ "$¥/ ˆ‹¶Ýö¥xN>ŸXÄv>Ñïôyƒ?»ñ:0ì}£ßèówât`"u¬B­Ëj]gH©Hh¬Û²àÑžZ õ¡™’7GÂD€ÝrE'Ê}Ï6¤ÌE<ŽË.D%)¶Â,©-„W¹íŽÇÚ=þ0g÷~'F´{ý`ÏîüNŒ÷±#±NE5‡éMAm’a¶É¤¶E”I-„’-–µ­°x£ÀÀñéé§1 µ ÞŒ˜èi”¶–^2S­’H¬HY‘“Ä£"½Å§ðŽXaÇÝÑö Km¤Ö£ë~!؈®êÄ'º›~cE¾k…Ñ‚[C}©^…ϧÖ-M¨ÓŸ†ó Wˆã© }§š5´fV%¤–JMËŒ³–ͤe°kMþêmùù®FýÔÛó-ó\.ŒÚ>Œð¥r'Ò1S¥¢ù‹L¢4âoÇe& ÖçÁÛù¿ºŠûeÉ»²5º2ÚÖÖ{«[e® ýÔÛó-ó\.Œ7û©·æ4[æ¸] Õs Ñ*øÑšìоK-ÈbJ‰)«S&•!+=õyЕåË}–Ím‚WŸ n]Ëž¹÷FéÕ]¼šín·Yn,úÎn<Ü.=£]o÷SoÌh·Ípº0ßî¦ß˜Ñošát`6$Åay›§uFëe,IÖ›k×4“Q¥ ¿ºIÖdG°³+”Æ=Ú.]¥±Jr“…—OŒ³qˆªŽÁ²ÒIE¬“ýdB¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€Ù,JÃÌHT†$RÚym!•8…¶J6Ðj4 ̶åI­v."Ì«q˜²ÁaF L£€É± ѪNælÈ‹#v÷ ²RV+ˆ¹¼ßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀN"RðDNDJvŽš‚ÜÔ´Ã ))Q).X¸ddgr;Þã1¾Ô¯ ÂçÓ뿺›~cE¾k…цÿu6üÆ‹|× £´7Ú•á8\ú}bÓh,;!Ö%ÓZrK„ëêCˆIº²JPJQ—º<¨Jn}Ä‘q i¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ö½€¨/U•Ww>åIjBÕ-P(¦ñ© % Í{5Ò¤¤ËnÃIq Æ|1¹w.z>çݧUvòkµºÝe¸³ë8y¸óp¸öu¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ØfXPÒÊL¨¦–$ª[%ú+6ú”¥)Ôò,Ôµ™¨¶™¨ÏºbÕ>. §e*|jL²•0µe}H4)ÝŸË4¤ÕÆdfW°€ï÷SoÌh·Ípº0ßî¦ß˜Ñošát`'ðcàèI5X,PbÔ%ÿœJe !׶߆²Ú­¼¦/4¼0ËXitvÚ§Ûq6“l“È6ËV_Ȳ¤ì·F\F5Öÿu6üÆ‹|× £ þêmùù®F{& ‹Yvµ6b¨ñ;5¶ÙKî_2Ë„ÖcÝ m6a×M†ÒÓ,´â†Ð’²R”–Â"""".!­7û©·æ4[æ¸]o÷SoÌh·Ípº0C}©^…ϧÖ#5ZdyuÙ5hzDJrCm´¦â&šdHEò§3±Öá‘–«)GcZ­b;®ÿu6üÆ‹|× £ þêmùù®F9 DˆéõYñU&âÌ\÷–Ô$-Ùq’¼ì6×NbYžFìi$™+8Å/0™Éb†šMCüôÃR{¿¤±pÿ®â¿ÝM¿1¢ß5Âèú›~cE¾k…Ñ€ŸÓØÁÔèÑcSÙ Äb¦ìf˜KHK 4©¤lJ+Rn[l£.éŒV `ü!E§E†åê1©ìB‘Qi¦™zQ4ÚS™fFg·-ìfvå1ßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošáta¿ÝM¿1¢ß5ÂèÀm ö¥xN>ŸXoµ+Âp¹ôúƯßî¦ß˜Ñošátc1„ãh;ULÃXGUiˆiO-¨´hk46›­Vo‚’3"¹Ø®d\f@'íJðœ.}>°ßjW„áséõŒc<ýà_3Áö†·‚´cEˆÜª–À¬4ì–b¶eC†³S¯8–›I[3;­i.+Ó;“=¾Ô¯ ÂçÓë ö¥xN>ŸXÄv>Ñïôyƒ?»ñ:0ì}£ßèówât`2ûíJðœ.}>°ßjW„áséõŒGcíÿG˜3û¿£ÇÚ=þ0g÷~'F/¾Ô¯ ÂçÓë ö¥xN>ŸXÄv>Ñïôyƒ?»ñ:0ì}£ßèówât`2ûíJðœ.}>°ßjW„áséõŒGcíÿG˜3û¿£ÇÚ=þ0g÷~'F/¾Ô¯ ÂçÓë ö¥xN>ŸX¿€ôrÃ>î°b[m&µ[ñÄEsÿV!;ýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ†ûR¼' ŸO¬jýþêmùù®FýÔÛó-ó\.ŒÐßjW„áséõ<©T) '¨BÖ$Œ’²’RoÝ-¼eÜäߺ›~cE¾k…цÿu6üÆ‹|× £°  2ÖTá>ãFf•©ô•¯Ü"¿w鹎\êù‘Mc 9öžAG’F¦ÖJ"<ÍìØ7 ý×j¬R¨´}Ôg¿}TxÔhn8»$Ô£$“w±$ŒÌû„Fg°†„êè¢P¨u\*Å Ñhí¸Ä•¸Tês1µ‡™²,Ú´–kw/{\íÆbcš£QøBOþ*¿êb-W«T%˜xu)VçiÛI4g'JNÍ4’÷g˜¬jâ."Ìw"’W£¢S“â¸jJ7Q¤ìdGr;pƻĵ ¸v™©4FË ™G}”’y)NÄXŠÍ¯g¬|iý'~õ›y·ÞÙèÊô¶¦öžÖê#»Û=?:¥ñëqôXï¢\wä«#dô7›J–I5IJIì•pdÄ“@­n9æYDv¤”…žê5‰·DE‘?9~>àMŽÜ¸oEuN¥·›Sj6SK"2±šVƒ%$öìRLŒ¸ÈÈÇ£IrõÊ3zœN^ ë÷mÍWéÛ9åû.‹2䳃}õPJJv$Ôfj2"""Úw3"à×pu:\y8§âId)ÍÓWœ·ÔÛdg«m)34¦É>ˆˆÖ«™Ø²¥9êôWæSÌlšÒq·KQ‘G«\ˆíîy­íy&Ôe.S[+Kimjp¤G[iZ®‚Js(ŠÆdjÚWâÚC!OšÌÖÔmæCžWZYYm«ËÿŸñ†N)T§˜f[IlÞJ½[¦á¨Òi#+e#¿¸†{Á•ºJ£/ôJÕ›hh¬fI½øGÝ?Ø]ÎéœÎx‰ñ“2±”ó쓉¶±— I÷ Œ¸ÿ£¹ 8 ¦Ó›ŠäÉ3]-®<û†¥-]Û\ÎÅÈEûNæuµÚ”j=]RY™1•:»q™që>!®©Ø²¥Yu§Ú¯ÉŠO9«m ÃJc)Ï›JÝdóö{²ÍÜ"â)n•AƒéIT³D•(š24%—\"=bT’,ÈIÞÝÁ«F•gÓ"«„%töTóq•ë)f¦Ò–>åö_fÝŸKè-£ú•QLÏ·§.è˜ÆsûÇsç}+ªŸÖ‹QrhÄ}3ûÏ?ð”a*nF%©BªÌ‹!¤BŽû aƒl‘™o!W¹™Üõdg´È¸‹”åb¢È+M9ê´–²É”¬„¢yÇ32•KÌÌËjŒeó^Ä&c#Ò[8š¢Üb#ìöDDòýÚÚ¹ÃÓú“™žüüç,,©“¦IqŠi:DÉ,Õ«JMkÊvQÙD{öq\Ï‹g™º•B¦EC\¸Ï¤ÔbPFi.5')!–ÒÚ_®†*UqOÉaçÒÝu”4«g5,Í'“±ÛipÈöùq îIeäFy©‹eM8…УµˆÑ}¤[nÕÆg·É‡­/##"2ÚGÄ<•iíÓã%Å!N8ã‰i–“°Üq^å7=…ôŸô°F–P“Ød’#ÿpÇâxŒÍ£9Lc•Üio4\kB\J”E´¶ØŒsª*ª1LâSß,v¡Rƒ œße”çn–›JZ&«í3ÌŒÙr¹šŠÿ¨ÎÅ’ÂÕÕ£9sib©Å%¤‘’TGî\EöäUŽÜ†F\d1õSAÑÅWQe·:fµ¦¢¿6ï’7I¢Ê;ì%/añî\cÕ‡&GªÍ§TÍØ’'.ƒv8Á&ÉyW7³ÜÈ®ŸÔ\ƒÍ¡Ñ^ÓYŸ×¹5מùö|¡{·©¹WôSˆÿ,µ{à9ÿùg=ü)‹â`ž¦\ZÆê|ðý.<8„é!R\vÉ)¾Ó$¤³-fD£KhqYU–Ã!^øþYÏDƽÆ^µ‰:‘0øy—åThÔšeEo3’Q¸M—‹d¡õ¸DD£Q¶I"3Q =ë¿E7gÌÆg¤g¾^kõWMº¦ˆÌâqók ÇTF8UIUXÀîÛˆ2„ÅÄõ¸’”)+m¬’«©/Ÿ Ф‘'¤zŸ4£J9sj'úÈ‹*nM’ÊéZGÜ©ý ÒhèªÍ1M]ØÆ;ãé]_Ïùïbz+S¨¹v¨®fc÷öˆouÝÑŽ*˜gråÜØs·F²úÍÐì¤dËm™w5ïs¾~"¶ßc5HW%Q4ø‘™”ûYÀiå:–Õ{Xî¦+ܲíµÊð:Æ¢b/Weâ|:ÝNaÚcW)“S:ÍÑP72_ƒ¬I)³¹pK+fÛÑ–§9‰èÓñ® 9UjΤGvlÚžVëC‘56ÌšZš[M¨4ç"$m¶Qðmöé¡U W(p+t·÷D „fåEw"“¬iÄ’«(ˆÊé2;òhæÈôl;LÑNŠ(³°LÖ‘ºÃ5úkTGYvL¶èò‰÷ ¼„rŠé#RÒK'“"5m!°pe6|!QDŒ/WNwD~…JLgz+DôM[š“4©¦‘).>i2,­‘Ý6à€œU1U™¾û¶~¯yã·"u™ZµHs6Or“Ì£È|Ý\[8E|ÐÒÑ¿íýÉü®»ñ’æ/ÿ!O÷³ÿa{Ÿý£õ˜óo+½w_­š·^ývnüÜNj·¯ug˺­“W¸ÿC©Í|ûr(ò`<ä˜1ä=ènºÒV¸ï ÆLÊæ…¤š‹ˆò©ErØf[FÃc¦é±r"PdMTšŒ×¦TfО&"—“)ùµRX5P†lf”©v4µ¡¼ËÕ ;?á•©úVÃlÅ9ñÑå´rÔá,¬—Û=_ýôf.,ÛCsÀyÉ0cÈz#ÐÝu¤­qÞ4Œ™•Í 4)I5åRŠå°Ì¶Œf2®õ»Hb¡¹wV¶¥MfKn™lÇÏ{¹Öæ·w-®W¹h9Øn\l€å?†'UkQ0u:#t™øyùMèo„†ßlÒtù;)ÕØˆ‰$íµ4ÆÃ˜††öE«!R Èyæ™Q4ã+ª7­$-'|Í¡•-v¶D© ¾Ý°@i¬E‚`ÓÞÆô:Eu'J¥R$¡šE8ÖÒ䔩Zü¬¦ÄåÛn9:ÚxJAÚÆj+áa@ÄtÜ#µ…°’!T!U¤À„ˆTw©í¿Td6R7†kŽ„È&´‹+ ]‹5Àoð÷7â •2U¹O«Nn…2‹B‡%H^²dB«0óÒIiÚe¹Ó:ËÜ©—Lσ²yD¥ÄÀX¯È¡á‰LP ÁžÔ T. ‰I\írXl¬•<¤"9JÆfmßÝ€—ãºïZø½‰·.ëÞŠl‰ÛŸY“[ªiKɚǖùm{¯Äa‡«»ïWÄtýË©ÞJ’ çÖf×f‰F{X²ÿœe¶ßq{í±i];PYŸH­Õ°mn¿[O4áyP©®ÉÔµ¹“i Œ™2|žR’f“q+""]òŒ¬Úa:VÄUjå"¡UÁÎbP޵Yýæ)²#9,¥hR,W&ÖƒU”i3l6Ec@ƒ‹ée„n©³g&,’#RJ*W\„.ùl³=Ȥå##"Q(û„©0Ò‡™Ærh•™ôÇ*4êÆ:—2Jr)M”6)Ó"0n[a4½SGcà¨Þ±ß5ö§†N™¯HNšæ …ŒÚyêLHk[nÓ•LdÔM0’ý#%1yÔÚÈò8V;Ú¸†»½|9Oܺíû©.}f]NX’$gµ7ù¾[l÷w¾Ë×w¢¯‡)û—]¿u%ÁϬ˩ËDŒö±æÿ7Ëmžî÷ÙcÒµZ K¢Ñ ü[£®\ZB)ΩÈÔíì}³5F"ΆNA¸­Q¤®—Œ¼"Iª”UD¡›Ø2¶þF9\¸´„S]7#S÷±öÌÕ‹:9âµF’º\J2ð‰&öCÎ4ôd"#Ï¥çM [f‚K‘JμÊ#4Ý$ž (î´ìË™Eb…T\¡À­ÒßÝ*›•ÜŠN±§JB¬¢#+¤ÈìdGÊ5*Z葆eµ…Æ2݉L™IDjrè²™Q8ÊËôM-õ9d,ˆˆžBlW"m ÑgÓt1A£áTü%X†Ìvk%RÃo^”ˆèKëÈK`ÝR”Iý9)iVS+™íHm`_Q55V‹A‘X™&£ÌåО^åd’ÚVìjŠHa´)je{V¢YZË+áZÃx€´¦¹u›U^¹·S™Â’Ÿ¸¢èk|JA0†umM©n¥YJ‚«p=6Ïr¹†*nbÅUfºÝiPSG JpØIJ¶Bl™6ÛÔæ¹,¯“ùC ‚èÏ3k)˜v©MÒJ¨XŸX~&LóM‰ÍÒ¢$?™Þ &¬‰¹p8Œ7,÷œD†b=1ÖšRÑ“A8ñ‘\“Z’’Qñe$®{L‹hãLe ½£uT%I†Úc©6iù±â¦¬¦E•R¢IØÕ”ȸŒËDb M ù5¨'Ö¨ò$hҾÑ¥½É2TpÉ($)$o;}†âIYÌÓe*Û&¸Ö’æ0“‹e&$™Œ~EB%·{Øýη5»¹mr½ËXâ\ õügIÂ8yøT9ú,•¦´l·&Ó$îô2I²u«ŒÚ¢MŒó"ûTFx’œ‡‘‰iº•¢UAhÝÆëw2»ŠmKJœ±K%‘EÞÒN¬ÎÆuy aL7!¨½lÊo˨I€„°‚ÊÃ;Ú!¬ž'dêRGrÌ¥!»ñÝw­|^ÄÛ—uïE6DíϬɭÕ4¥äÍcË|¶½Ž×â1zEn,JŒh3Ûz#³g(á“-eR ÑÕ•$†Ý/Òd;´«­§j 3ãiº¶ ­×ës©æœ/*5Ù:–·"Rm!Ô“&O“ÊRLÒn%dDK¾QíÆØZŸ/Ì­âlºÕ..9)’苞¥D^eƒRJ§Ý)d*L³4F{Q°7°ÃbîôUðå?rë·î¤¸9õ™u9bH‘žÖ<ßæùm³ÝÞû,x*%ºÞ®á·a×[m¸Ðä®TH&ú%HUÚJîö]EÝh¶›nÍdC_Q0¹Vé8R•;µŠÆ1y×H~ŸøÅJ’Dúâ8f¨í©Õf…Y+=¶ý%Œ7.$¯S0ôLª9 ã¤ËHÙ.¸³#<¨m¤©j;%G°a÷š‹‹põeÚsTʉH]J4‰QRM-&¦Øq¶ž½È²) u 4ªÊ¹™[‚«CiÙ˜[ i6ú\XrŸv‚Ì~¸ÛIÓ#9þJÁšRçùA½fÈÉ&¼É¹mµ5\%Œu„iør©] ÀƒC«“µM²úÔã²`/+«Ó©5¸¢uÃ3"Z ;Ø”y3QaÌ©D™Qf3”¸MOšnÝb;†êPâ–e–Æl;ݹeÛk•üoá¼CP:}:\¤ËÕèbdâ-ÖˆÈÆÉä ÜA•Ô‹‘\¶í!®kØ;&¹ŒS«X¡J¦áù,;Pj;[«rÔ%¾ì4)–šhÌÐDV2¹k‹1ØÊÒS©9Œ±Æ“L¢VáF¢H~dÙU*k°ìKŒë%$êRn©Ô¬ÍAj‹…s ˆZFÂ3j Ã>[„ûÄ÷¶ICuÃVRJ$›z•«aYgsØBÅ7I¸Z¡\M38›w«TjiÜ-RkV—T¤¶· qÈ›A© ,ê2O[x'h^z£EŸF¤`ÃÇMÆj[Ý¡VhǸaÃÎDæIfÑ[VÞcA%÷Í)I‘ܧt¨’‘¦G9qžLG°ý%–Ÿ6Ì›ZÑ"¢kA+ˆÔ’qd[H–›ñ ô¬w„ê˜ ìu®—ðó]–ì²eÂ44ÚMKQ¶iÎFI#;e¹•¬Gr¼AЍ *›W¨&4º»ÚˆM›kV±wJvšHÉ%™hMÕbÌ´•îdG¤ê˜kÐú›Yr‘C¨È•UÀR«4v£,䔓§“-<–­›X•Y§kš,gïDG%ÅX7ãÌAŠ'GªSèp”ÉQ©åQ£<ûéKJ'U)•í ß±¤Í+#(í(¶l0Ù Å4ãBÁª¨$«§ª%ÛY^9­H%’í”Ï2TYo›a­´c*FÁÐeWb=UuÉ!µQf<'ß[nK^HèJ[A›ŠZø6Fc#Øv)¯bg1ST“¤bHtZ+±Ž{N3åµ"¤‰qÍd“3B›uEr#àºÒìwMðØ‹Ö(«l’+ÈTl-&eR›O\‡]”ŠÜ™eµëŒúÌ™•&‹¤ÊÄaºðÆ%§b-ѽñ«Lî|¹÷Æ.ó^ÙwCHÏîNùom—µÊù‘¬é ™^ÃÈTúÞ3ÄRU¹ò7ˆX‘†²pÌÏU&<&]ÚDf¬¤¿r”žRYÝ‚p¦%¦âx“j}ϼùÜìX©åºEþM!¤´æÓ"áe÷E´ˆ‚£¤l#¡"‰òÏr¸mI’Í6K±c¬½Ò\†Í¤wIJ+wl3ôê¤ „Ê”Hoë^¦I(³‘E«tÙmâM̬£yµ\®\+q‘‘j\@õFƒ>¬Œxê%]s_ÅÚ1È¥L}ǵ,äF–[qfk3'Ñ—9ž[ðG¦›B§Q1V•$@ÀêUz¡®›øÔõÆÝÌ. R[)œ„‘!K”‡ ÒK%æ3rÜj·€réQ«Ž@Æ1¨Ø\â©`*ÃN³LÁó)(~u™&[R^qG!ë-ÒJ‰ 5]V5í˱ñ z_ÎŽ©;ÒýGUÚ\˜è4!ÉéTBˆ·œâS×[æKQæ2Îw;ƒaL®î|qKÃ;—6ï¦Ìº5–Õîwb£&[mͺo{•²qöfF€£R©‘ñr§àâ {làš«Zzôâ•1NC43­2IëÕ‘do¤ÌÕÆKVCË*5qÈÆ5 œXU,XiÖi˜>e%γ$ËjKÎ(ä=eºIQ!&«ªÆ½¹C¨‡‚«ü¿ü£ßáäá(˜á4Ph»š†ÑO\¢ˆœ¥»–ÓIjKöÚá›HÙ­W<Î"ûl&5_åÿåÿ‰Ö·0uqÀ­bÊ 2ZRJ6%ÔZeÂ#â<ªQŒEô—X¤W0­}©§ñU!ü9 y³QNfå™&ertÇ¢\3¤èÐJ°NÅ— Ô›r㑆Öb5´wã#+ÛäžÒî‘ÚÒE&BÁx^HˆÜ811%¦l¬HIMkýçÝ3=¦w3Y±„_Wç·PU.ŠÓJ}³h¤>êMIiN«+hJKjÖ£þMȈ¶™•ÊòÄOª…ŠMÙDi6«  Ó½Å“FÊ]h夘ÎIã2YÚö;x=!z»V³GX‰ž‘ÕàôúìÙÝOXÌô‚.©Aœ”U߉6!º–^u¨«ŒôU™‘±¥)FEs"=¤i¹\­s)ÄÙq¡BzlÉ GŒÃfã¯:¢J‚+šŒÏatk=!V_ǘøt†`È}¥Æh²‘Ê6ÖYTãÊ#±!f¢-¤Gk™‘ †’iÓ*˜FDj|}Ôûr#J(Ù‰;¡,ÈmÕ3sÙÃJ vp¶ìýz«›âjÝLOtòÏÿÇŸÑzšï~¤nÝLOtõëü?høÎV¨5#Ó’ó÷Ôšl˜è~Äj=ZÜm)^Â3à™ì#1ŒÂ¸ƒOÆõJ]R¹©‘õú—·­äÈé%¯Ò¨Íë[3sôdZ¼¹Us1åMz©YÆôÑOE„N­x3hÇ*Z&2^µÖIJs]¨M›pÓbâã1Àñ*èÒœÎÞ•¹!öëΔ˭ â¼d‰pÓ,µ‰o†I25XóÈ•§†³u»Q„Õb5!oZl˜îÉe¬§Âm¥6•ªö±XÞl¬gsͲö;cʼábº} Êk¬*d9Ò‰Ç\MÒQža¢à¤ÔFNä²;‘‘¤ŒÌ“ÆTZCšXµêžEA-“ÓK9J$ߊ¸ÊR’…dœ¯™8vJ3+if;ø°52¥Ó‘O–ËHë§;Ž2¤¥:ê».5s2ÙjOÊI•Èþ½ðÿü³ž‰Œ6«®›¢­”Šë´zb0;s%¼„´{ZfSsq î:½…Æf_¨fkßÏÿË9蘪‡SÄšÀÔj5Ž¡#G_äè5XœRJš¼—=œ,¹vìÛ´{=j‹·â‹“Šg9žÓßôyõsTZ™§Ÿý§ MÒ$ºj*ð¢N(klÝDiSã39iÚiýä4%J+%N®D¬¦FBEƒçU]¯MƒQ~rКd)‰jb'X[«KB¤’NÚ¤—wmìf#ÍigÌÂç6-R‰N­ ˆŸ¤Wgîc¸VÎÚÈÒk¹m"2I‘ìTiËa¬Bš¦;¬u½P¬P)Ϧ©Ó]Si3épÉŒ«+<”™¤ÎËC‰;Eu:[–öÕ4mŒÌsžŸ¼Ïò¾–›Q¿5LÎ;³>ÜÇüe½@Y%¹°cÌe/%§ÚK¨KÌ­—”W"RD¤+nÔ¨ˆÈö‹Ã‹ <¿ódý¿á,pÇÿ/‡0—þZO¤Øîzßù²~ßð–8cÿˆØKÿ-'ÒlWÚŸc°ª?IÿÅWýLy$°Ì–ĆëK+) MÈþ’GPÒ¾”·d¯UMÇkU™Ž’¹Ïa4D_AéKK}Ìw7›g£M¬ÿHkôtÓUù¦˜«8Í\ñÏÙû¸×¨·OuNìBR„VIˆ‡èáÊZ]ñîg6×F?;)i{ǹœÛ]ΟBÞï§ùÿ¥x«]]Þƒû)iǹ|Û]ü쥦åsmtb“è‹ÑýÔÿ)â­uwk¬2êзB”‹åQ–Ò¿…ÁÁ½”´ÇãÜžm®ŒJZdîc¹Û]ç>‹½ØþN&×WyàÎÊZeñíþm®Œ~vRÓ7oómôb³èëÑÓùOk«ºªTè5$²™Ñ[–'š%•É+"2%}63ã˜|ÎÛÞD×Ì«&y»äýƒ‰»)iŸÇ·¹¶ú1ùÙKM=½Í·Ñ‹ÓcWn1MXùKU髜Չú;Í´%´’JKˆˆT8+²–š|{w›o£”´ÕãÛ¼Û}á:+Ý8›]]á.$Yh$JŽÛÉ#¹ÒGcâS ÄY®4FšQñškŽ쥦¯ÜæÛèÇçe-5øöç6ßF+Â^÷N&×¼ïpÙKM~=¹Í·Ñ‡e-5øöç6ßF%ïtâm{Îær…GrIÉ]::ž3¹¬Ñ¶ÿýk,2Ͻ4„w6àÎÊZkñíÎm¾Œ;)i¯Ç·9¶ú0áoO°â-uwmY§¥Ka¤æqÆ„•ís4™ÈhÜœÃZ<ÃxrcГJ¤Å‚ó8á¡ki”¡F›¶Gc4®D8 ²–šü{s›o£ÊZkñíÎm¾Œ#Kz?´â-uwäÊ›ˆSˆæa,1&´—[u5`%rImØ¢tÚÍ™9Sc½Ë)[ˆH7é®V>úýó²–šü{s›o£ÊZkñíÎm¾ŒO Ý8‹]_G7é®V>úý€ß¦¹XûëöÎ>ÊZkñíÎm¾Œ;)i¯Ç·9¶ú0á¯û§k«è}Eê]Be6\ÆXuêd“• ZçKVé²ã&«l£yÄØî\+ñ‘{wé®V>úýó²–šü{s›o£ÊZkñíÎm¾Œ8kþéÄZêútX›rSiQ÷ *TÙ§s´¬¹›nÍðRyr+<„=»ô×+}~ÀùÇÙKM~=¹Í·Ñ‡e-5øöç6ßF5ÿtâ-u}ߦ¹Xûëö~šåcï¯Ø8û)i¯Ç·9¶ú0쥦¿ÜæÛèÆ¿îœE®¯£›ô×+}~ÀoÓ\¬}õûçe-5øöç6ßF”´×ãÛœÛ}p×ýÓˆµÕôs~šåcï¯Ø úk•¾¿`|ã쥦¿ÜæÛèò–šü{s›o£ÿºqº¾ŽoÓ\¬}õû¿Mr±÷×ìœ}”´×ãÛœÛ}vRÓ_nsmôaÃ_÷N"×WÑÍúk•¾¿`7é®V>úýó²–šü{s›o£ÊZkñíÎm¾Œ8kþéÄZêú+}>&`À,VM²Ã$¤6ÚH¬IJI»w_ߦ¹XûëöÎ>ÊZkñíÎm¾Œ;)i¯Ç·9¶ú0á¯û§k«èæý5ÊÇß_°ô×+}~ÀùÇÙKM~=¹Í·Ñ‡e-5øöç6ßF5ÿtâ-u}ߦ¹Xûëö~šåcï¯Ø8û)i¯Ç·9¶ú0쥦¿ÜæÛèÆ¿îœE®¯£›ô×+}~ÀoÓ\¬}õûçe-5øöç6ßF”´×ãÛœÛ}p×ýÓˆµÕôs~šåcï¯Ø úk•¾¿`|ã쥦¿ÜæÛèò–šü{s›o£ÿºqº»÷ Ò0ΜüÚTBD—ÛK&ãóäÈRI™“MëIZ¶ÈÎä„Y?¨f!ϧÂmmÃ2êÞZZ% ”âÔjZ̉½ªRŒÌÏŒÌÌÌ|ê쥦¿ÜæÛèò–šü{s›o£ÿºqº¾ŽoÓ\¬}õû¿Mr±÷×ìœ}”´×ãÛœÛ}vRÓ_nsmôaÃ_÷N"×WÑÍúk•¾¿`7é®V>úýó²–šü{s›o£ÊZkñíÎm¾Œ8kþéÄZêú9¿Mr±÷×ìý5ÊÇß_°>qöRÓ_nsmôaÙKM~=¹Í·Ñ‡ Ý8‹]_G7é®V>úý€ß¦¹XûëöÎ>ÊZkñíÎm¾Œ;)i¯Ç·9¶ú0á¯û§k«èæý5ÊÇß_°ô×+}~Àù³SÓ™iñÒóØåõ%JÊD†š3½Œû­þ¡Žìó¥Ïfó,û•tWDâ§Jk¦¨Ì>›ïÓ\¬}õû¿Mr±÷×왞t¹ã¬ÞeŸ`;<ésÇY¼Ë>À¯zÝϦûô×+}~ÀoÓ\¬}õûæGg.xë7™gØÏ:\ñÖo2ϰçsé¾ý5ÊÇß_°ô×+}~Àù‘ÙçKž:ÍæYö³Î—dvyÒ玳y–}€ìó¥Ïfó,ûÞw>›ïÓ\¬}õû¿Mr±÷×왞t¹ã¬ÞeŸ`;<ésÇY¼Ë>ÀwϦûô×+}~ÀoÓ\¬}õûæGg.xë7™gØÏ:\ñÖo2ϰçsé¾ý5ÊÇß_°ô×+}~Àù‘ÙçKž:ÍæYö³Î—dvyÒ玳y–}€ìó¥Ïfó,ûÞw>›ïÓ\¬}õû¿Mr±÷×왞t¹ã¬ÞeŸ`;<ésÇY¼Ë>ÀwϦûô×+}~ÀoÓ\¬}õûæGg.xë7™gØÏ:\ñÖo2ϰçsé¾ý5ÊÇß_°1xš¼¸Ô‰s!Ó^ªÉDu6Ô(Ž%.<¥šKbž6ÐD\ff®";ˆþnvyÒ玳y–}€ìó¥Ïfó,ûÞw;k®üeý×üçNüÀÃb©x˦O=Õé­³\§ÌvKõ+Cm³)·fH|Ô|«ˆŒû–}ÙçKž:ÍæYö³Î—|vyÒ玳y–}€ìó¥Ïfó,û¶y"ªiª1Teô{rÒ{æ£ç¹Þ±á›†°lú½2­R¥1RIR©ïO™"IÆtˆË25„¬¼d{8Ô†Õî›A§çg.xë7™gØÏ:\ñÖo2ϰ"-ÄNb!ZmÑG}1‡Ó}úk•¾¿`7é®V>úýó#³Î—ÀvyÒ玳y–}€ï;ŸM÷é®V>úý€ß¦¹XûëöÌŽÏ:\ñÖo2ϰžt¹ã¬ÞeŸ`;ÎçÓ}úk•¾¿`7é®V>úýó#³Î—ÀvyÒ玳y–}€ï;ŸM÷é®V>úý€ß¦¹XûëöÌŽÏ:\ñÖo2ϰ6GSž7ÒV“tˆxf«¤ZÄ7 ÒIèÌG5‘·cµ”‹_“¸çsº'T™É¤ÖÊlJ2Êk334)$[R\£‰¿ø|9„¿òÒ}&Æúìsˆÿ¦|aæø~Ȉ¿¡ &’ñÍWc–³§2“ ÐLå+ð”£ZK)m-·"Êvðb ,úÄD¨]bÛÖ$ãËjB 74û¶”¤Þé22½ÊÛDƯ¤M÷MT’›{us•*TSI-,%åºÊZ¹û´*Cö¾Â³\›0:A«R+hÒ) ¬‰¸¤Ü™ „ÔEJw:Ôn›-¡•INÃ;äÌ{LÅ©šóߪ)Çr6£˜oƒpM:¿H¦="¹*úµJE: (§“¬çi¶kuÝjM´ž½%rB¬I31¦aªÕJ"%CŠ…¡ÓY2•Hm>i+¨›B”JpËþéÝœbA‡1ìš ‡‡¢®b£.|×j°õ¦†&G}˜Í¥c÷eªtÉF\RL¯´†cé™K¦Óc0óñ×CS…Ow­ê|§ŸI¾·£yìËŽ²7 ¸:Â+‘^÷ã3\eÖ"‰Dæ`ŒK—¾/Âa,îVæd)¬)ãaÄ%itš%›†ŒªI𲨶ÞÖ;TÞÅ.9 ¦©ì¸ôÉ Çm„LaN¶ãª$¶—PKÌÎc2"7 %´I±o Sê-ÕaO›:¬æ‰NTt0ÙÅBœ¥7Ã׆£R J#F¬¬´ØÏ`ôÑñþ¦cw±z«;.­S.¥ã6–ã!Y–á2½a›†jd’œÉEˆÎæ#}xÌBvÑžùE¢`j‹ø>­ˆU6˜ÑÓd°Êã9PŒ•¨œe×LÊîç"BH›"5)F´‘fmdX¼I†«uL¢®Ã,-ÓRI´JiÕ¡I¶d8”(͵–bºVDe~!ë¡Õ)HÁ•Ê IsYrTˆÓb»”ºFë ÈA6²RÓ•*×û¢Ìe—ÜÇ»Hø‚^D€s%ÍmO.UBd6c¾ù+&D/T£'MVzÕYJÏ´ŠÄ/Vì{˜§nPðÀ|„WˆhÕŠ†ï(ª‚ßù3FÖc”é6ë¦ÙË/èÙpï·nR·„`O°Ž=¦áªM +8jMøsœŸ%éª}&—TiI%½SÉJ“«B}ñ&WRŠÖ3½+š±ý+Qž÷‡F¸n*Ä4fdj˜¥Í¨³×9†[jq)pÙKŠÌ∌ýÊU·¹ÜÑ£œ^¸K*|RiÈíJºª1’m°ê´:á—m³%'†²$‘ŒÈö þÅX&!ÃUI¥_Cxfi&#ÆeG&:f.Bâ”ádYkF’%¬E™ •)%™•–æ…ð/WÛÄoaé ÓãTÙÎN3"©’Já¶h5-ÂN|ÄvMˆ&FyšÎ#Âõ8–œÌi´øóŸ…2Ç„ÑߎÃÍ«;d´¥¤º§”³Èj$q(‡±¼a…žÆx¾½2žöj­MÉ”ç¦Ç˜¦›S®-M©§•«J”JG‡—!ØŽâwWùôFÚH:3«½M¤Kyøí=:¶í!Ø%&6êihq†ø--ä©k5¼¢4\¤”©FIY(GúÔ®ï&ünVw6«]“u5¯Õ|æ£6·'ýü¹m¶ö³ÇøfF/f½!vŠ6‘ˆc4Üf×®a÷£©HY›…‘iK+f#5Zä\!ƒë¦…—~­QßÍäÞ}ɨFå˸÷·[Ÿ5õ|,™=×ò¬"*¯ÚM4{¬C1E<Ǫkp»ª–ÛsXuØç›)ÛBÍII«a(È’w+Ü„hM+X²7é Ó2ÒÖ%Öî4©)ÌÞzƒ2KYÂÙÀiE³7˹´¡c¥TÇõ)TDOpê€TÆÖ郄÷ÆÛ⦅å:ŸzÝ2ç¹ÍÂÉ®·fË}—ÙŒN­*™¾­AÉÈr'¢;„ÖlæŽ3Í–Ö#>-¢oLÒÍj5ÃS#â JÆ¥·JjE9©‹Jˆì°‡Ò–‰y –¦Ü2#¶lÛmsžÒ W°Ù6K8µÒJÕ5@€£Z >çÌsTFús#63ÚdJIZÜw\èëŠ:¼x¿FUÚn#ªÆ¥ÅK´æfËjžoÎŽR%4ćY3Ky‰N,¥\’›ì½¬d Cscc„$b¬?Ž™S\ø®Ê¨F§¢3JEέ2CM¾½mÚU–“4’ÁQÛ2&ÕULR.E1=À®` 3ø-¯ürôT""]Œþ kÿ½ˆÅ׺ÖÑÿ´ò=@ß]B_‡õ4ÏD†…»¨¶™³¦©³÷Næz+XQå»fDIUµ)+";X좹\ŽäfB$u{GØÚ¡¥(¸Ö&’wxeªb”T£[ƒ2Î…ž¸³¬Fj±É6¶R´¿F_xóêš7¥8c;`Uÿ¼µOÌ‹º¤ShzYÇ4êS³ª:¬ôé”fkœfyßqj/ Œ‹gÌÌë pÌïxWÐ<'R`¿çû‹Ö=Ó½á_@¹Æ?IzWÑ:HX·7¢¦gž¸òf^¦*¯½”ßXÿ!ß÷¬~Z1!ß÷¬b P¡ò7¿Óú:9Dÿ(‹K2uxÅü‡¿Ü^±øu˜¥þ­ï÷¬a-¨eÝôNžžQ?Êñ¦¡:äBÿVÿÝ/Xü:ìBÿVÿÝ/X¨P¡›wGjžKp¶Ò-ÿ‡óOýÒõθ!|Ôº^±1AËtÓÉ1¥¶“uà æ¤}Òõθ¡|Ôº^±1HòWTÇ$ð–ÒŽ¸àüÔºŸXuËæ¤ýÔúÄTÅ'Æ<µß®9'„¶•õÍæ¤ýÔúÇç\ð>fOÝO¬DÌR<µknÂx;Iw\ð>fOÝO¬:çó2~ê}b"8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§i.ëžÌÉû©õ‡\ð>fOÝO¬D@8ë§iĈÕHe–ÞJ’á(ÍdDV±—pÿXÁ=Ë•\«uNöíŸÄ9® õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}{ 9á,}TˆU ‰@B)æûHRÛym¾IÈ¥ûƒ5vܸ‹@§{¾-ÐÖ0¤á|%Žc̪9£P€”SM´9O%·È¬¤ä2RÑc3.?Ô?Fÿ©(½_¢f,DîÝN1ŸzžøÇ?Ùáîý^ô›hÊ¥‡´}¥c<3 ïRœ§:þ¢BÛR|Ô¤MFƒ#4öq ‰aF…G¨V±L:$ŠêÍ4˜®GSªv¹\ÈÈ‘}–ã÷IGZGKxÓq~'¨Ê•P¦›Æå¸ôŒË6žJ‰'Â$\Ô‹™Ø¸¹6e(¸ßÖ¨X!ìKV™J¨àõ$ÐÂ")ÔË$2’T‰÷¤ÛwK»qðšš½'fíÙ«=õFfšfcÁݶ'=ÙÄLõÏ'JvÌCóD˜;04@İieQ§CCMK”Ê\LU)§ÌBŒŒÒVÊ«•ŽÄ]ÒÄèÝŠ'À•ˆÕX˜“VªÑš'·1¡*=jIM­µßa‘(¶ò(ŒˆJ0¾“°•B«¤©ø–KôÖ1v˜ŠÊSŽ­´2ëV,¤i%e4{£"¹ñØŒÆ:©Ž0}2£Ü%D«?P¦Pë,ÔgÔ\ж­gMGdf;kv+ñÆ]ʵ¿­Vb«Œwx;ñ?µ]ÝÒéÃÝ¥Së8Ûž«Ò¢Ô!ÆjStÑ »4M Œó’•)Dg”ˆýÒL̳Áôª–´w&µ¼l@©bŽëÒS^áÉÊÓ’åÔ•©rœ¹’wàmLÒ>éïé‘]™>«6ž˜qán‡Ho†KQ“vÐFJ"2Ê£+Ü„F>Ã0tC£úIÍ[µJ$n£2"^d²—Ÿ]ÉFDƒ;-;û¿¨ÆdΦmSLç»ã¿Ã9ö{'ëweƒê“Ãøgièøzk)Z‰"–Ô54˜6e¬œ3Øæ{šŽÜG{í1«Llލ:¦Ä8íÜK†«Š¨¦¢”ìª#ŒîcCm¶Eu‘g¾S=…°ks·ŸÑ§vsiíRb‘QŠG–á LR|b£ŸðÜJ“ŠŒR<5óX@[©ßÐ+òñ#Å,®M ÁÝoFI™kUe¨¯c+‘k;\®vî\'Œ1–ˆqf¨¡5Z¿Ë{wI=w!­IJSm–2UÌ®FWÍãê~ «Táס»2ƒ[Šq'¶×»"ÚD¢+•ÊÊQ\¶*åÅcâÙÚ ¡`z” f!¬ÔH’Ô™í¬ŽÞ23J-m¶ÊGsµÌÈ7èž•‡t{GÅu,nË.Ué…2$SÕÇM¤8L’‰fVá̈‹fþÍÓLѾNnÓñ,7!qðëR£S©ÔUCŽå丕:¤ë“R,”ð„NÎÏLi¯áìE€4sJ£TwTº5,ب7©q—5QÓk©$JÚ…•Òf[?Y ¡'LX ®¨1;uw£9†·µÉHˆéjžÝ&îÔšIFV"ÚD~è¿]‚¼)I \cT¡ÔèUÊ|*«-3Rv‚¦§9›r‰·TåÚI)ÃNSAÞÊÛÃÙä“¡ÅKŒÍOÓ bitõÔ£¼Ê’FÚHÌÉOåJ¬GÆV¹Ó"3’Ę* ¤ÓªÐ«šv%–ÖQkT4°ëÅn'VE‘M‘qðŒË¸c˜°|ª, ¤ÔdáìK‰k ‘HA˜§\ŽÁŸRn'‚]Ã<êÙ~0Kèÿzts‡qµ:¬u8Uu/ £jÎ+ä^ög™Y¶¥e{¹-›D¹½ËwQp¢1#T—K:EµÅ±AnéNR²ÏX£RŒ¿“îoݤéQkTjæÄTõ"¬ÖZueú6mi3#>áT»¤Kå1¦cÚUgN• _ˆkuÚ,7Ô´Ä•KRIÖVKiZT•fFB²ˆ’w3¿(TáXç G^=¦Vi• ¢"˹ÔÌ´.ç•¥ÇϬB\RuyÎÙs‘žÁ˜ÒfŠiU½8u­‚j1#¼ãdäè% m5Ki ³egâtÜÍ›ƒÄgc=·%é'Ë›‚&ǨõÉZ£ÕØ™>²Ý4â-Æ^m^S"¹Ÿ‹eÒ|W°õHÒ~ ¡éýxú—X~­O­Cܵ‘ Æ×’†R“,öÖ\Ú#;qøö\5Þ8Ñ|z> V/ÃXª&&£±,áËu¨ÊaL;°½ÊŒî›™ïü¤™\ŽâgPêy§Ãư³šF†š”èª~ ¦¬œtÓ˜Õr%šR’$Ü”j¹ð¬žÛZ`ÒD ¦‘A‹¤ZÆ+‘5ôšÐt–!Æi¤­+"]Ù'²4–Ô¨ˆû¶-‡šÄÚMÁ:¥ð¾0[ÏCƒJ\y2·+Å‘ÃL’"ÈhÎ~ø¤F[Q€…MЪ›ÂøŠ|,_M¨UðÚ ujs /+D¥§bRˆ’­„›]&Wé†xJ\Äxò‡×Zc_ ÅR˜¶RZIÇÍICfi2ØA\ÈÆK cì' ³Fê«júåÝ;ÑþNéîœû«/xÖ£ÝåãýGlÞ‰t‡€èXJ›©ë ˆˆÊEFS§¶]Y§‰…¥¿Ñ£5Ì’¥ŽÜ`9â£áT$Ã7Ø|ØuM¬8KmyLË2[“µÈËŒ†àƒ gÞêLüeOŠªPŽdZ:ã-WA”é’{åc÷*µìcRâ eת©‘N$¥:äfýSF£4£úˆÈ¿¨tâ´å@«ÅUwV0⚇’m%§œyò¿ ·œmiI¬|dEîNà4ÖÑsÕºf!¬b ã8n—AtØ—!èê|õÄv4Rd{Äv¹ÝEb1¸ëhz•K§a…=.,¥Jr”™¦©¸m±Ä Ý¹æRMJ##UùHà#áz¶ Æø?ÕfR™¯ÔRb~æ×¨5¥fKKi"½ÛAì$¤î¯s°L_ÒfŽ™Åú*‘ºñÓ0äqæ-èoØ%DCM’ˆ’yŒÍ6<™ˆ¹m´ èû¹£wR­T©Ôé¬â)dTؤ8h¦d”„¥¦™%E”Ë)ðIì¦gÄ è\ªX~‰R¯bèT8…yhðÜŒ§U írÌ¢2$_e¸ýÒ{§a#Ž0%_i Õ1 ´´VñŠœ…×’ëJuµ£‚Er3Õºµ³~« ” }£ÊîÀ/bšÄÚ=O)&ˆíÃ[ɘH$e$©;}Sfy­ü¢îÜ[èVub¡ŒiÕšëI8](7QÍÖ%%ųf#Jr¶G{Ù\[,5Æ&‡M§×$ãÕʱ³-LÒŽ¦uÄi#3È£3MŒÌ¶ò ÙHÒ¾¨¯Kµ*¤•S_İÅ*:™ZÔæHï4’3A$ö·{™Õǰh¿:“i¸fMU15™Sb™<‚9‘[{V’L…/.r;\’W·!r …´wB¥i#ÅÄth3â•TétƦGC¨÷·$æ$¨Œ¯ªB6ÿÞ1­ô)‹°öÀG¥Öj–ef”Qéíê\^¹ÍT„ÚéI’v¸ª2-¿¨Äò¦,ö#ÑÄ©• ÌÜ=¹œ?ò£‡¹ÐfD“5žË]7Ø¢ä0§4`ÍcÚÌš¬,1…蕉L¹'s‰EžQ%¶ÚE¶JÅn4‘‹JФæô—@®WX]6¿É*Ì0kKˆCJsÞÍE·bvfâQψg©xÿÕ iWª²)ÔœC\~£¨ÔUºE™ä©9›"%íÕ¶v·tÈì2HÒ® N•p q¦>ÖÂp_‰¾0¼ÎšãD¬‰#U¸ —îg°ˆ^¯¡&X¡b™”Œm­; ©ÃŸ ¸‹FD'1ÜÖglÙR£4‘‘§6Á§†ôÂØû ÂìѺªÙ:åÝ;ÑþNéîœû«/xÖ£ÝåãýGh…qØݹx¾«Hy…°òЉÉ™‘“„…‘™m³mŒíÈa/Âtj;ýIؾ´õ* •Hõ†Ûfjã ßm¸—J\2ÌEÂVÂ?å)‹U ov™hš:ë›[¾U/wn j¬O]^³o¼ñæ/uųnWHXÇF”]Ô0&T*HªÎL§ÝÚ’LÙHQ•Ô”™ûÒDD{.fwã˜?¤Ut¥†´‹3͉2%9Qƒ½Î©,(ÐéæZȶ—éT› •s4žÂ#®)º‹#bªÔÜgÖߥ¼·à¨ÐâRݺVfFd½ˆ"ܯ¶åÒîŽW€·šS¦+4ÊÌc‘Sl›F¢"IÒfv+-G~ïpMë¸û ÉÑ6’¨lU³T+X¥éôöw;¥®aO°²^cM“ÁBŽÊ2=œ\C¦Ì]‡±ÑÍ.PÝS(Ô£PoRâ5.j£¦×RH•µµíI™lýd%¡ºM‘¢ Q¤šµŸ\‘cPãGœÖ±”‘©¢Yå=†g®-½Ì»8ÌIêú3Ãðz©étv ÆE ø»êìGJe)"pU°ÒkAl=–U¸¶Vˆ±~FŽ11…AúTœ†åµ5¸êx’¤©³RM)Û·T‹¹x»·t‹Œ°6‘4Ìu Bõ^.n*a±&"ROS5Ô•%\R—°Šö2>ROT=«ªEMXÁ¢¾·· Ì4É%’Œ¬—”[¢$ì±[jí~ççS®£N‡Œq]f™¨Œ9JT–"INfVá¡Å©?Ê+4ecù_@£Jø» v1ú8ÂUë1ir)ꋱ”Æu¸d”¥[ÖªÿAq÷<šÆt<:ŒM‡ñ#ïD¥b:r¢9-¦ÃaYV’Q¤¶™YÅqwmýA°+Ú>•­#èÆz)‘é”ÜYåL…ôlçm”¼iI¹%gJlVÿyÜZÓ Ôôe‰± ,-ÌÃ8ÊsJ†Æ¨¥F%¡²RˉFfáoû¿¬Fô‰p­S`ze6¥V,?…ã7|¢#S ÔD„›­¥dv¶­c+Œ¹ e4Ç¥MCGó0¥+ÔqcÕ)É}É’¡”bM å$¤”¬É#5HŽæ|€5¶(ÁÔÊm3 ½GÅp+sk¬¥R!±•OpÒÙ“nYj;ÝÅÒO¸=œ›ŸN¸EØ:§ aœ õ"™3seÆŽ÷aIÊ¥8¥&Ä’2"½î£I¨øŽãLbˆ:=‰L¯ЪõJŒ§ÙJñ ,‡y[3CF¦Ò\féÝeÁ/ëØMbà}âÊn ®Uk2±4Vãi‘M ˆœ‹JkÊ”¨ÿH£,¥òKõ€™à,ƒ©Ômẖ¦TÞÆPdÊ™6CyŸo+ y$򿄱d[-Å~1¦#`::åã¨õ _ þ[ȇI#YRR ÒÈ‹­'{¶’ØJÚ²Ù˳ð.”ð!P°]ST&Ĭàè’#5 ¸Šp¦Ú&’iYpSÁJ}Ñ–Û÷6WKsâN½+ØÆ¯:›XY.‘:MH‘!zÕšdÚ¬Yµe´Óîo Nz™p=]j[ÅñX’ÍMעѠÈhœD•¶Ò–ëÊJ¶I4–Ã,Ê.AïÑöîãÝ,Ö%PàÔ:Úrc”Ú[Ç3'4–¬¶­)"â,ß@ðh“MLÃÄ8j)£a˜”ªLCˆŠªi®.cK*Jr¬”£#R¬JÊ›el+…7H¸rn˜kÕç+N`öV‡ãÓªTJyjä–µjK²™Zn­d¤¨ÎÉ;¤¸i'ª3 R©laOJ¥3H,EL) °œ­²ñ%µ+*“ï¤Vÿ»úÌbô?ZÂôÈRὃ‰ñdù-³Lj\t½)3I)&«æ;«m‰;H®/iûÂÆSh”údÙUthz“Ÿ%½Zæ<¬ºÇrÿ$"vëýC%ÔçYÀ¸_}kÕüFÕ.¾mª5,ݧ½%1ÉIácÒ²;’5‹5[ú®7OP—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜãIÞð¯ aàÒêu#p©´é“uvÖnvæKÞ×ÊGkØÿÜ?R_˜+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=Qà²1Šõ#_¨:ÈÆ>+Ö<~ ì­wÁ¯íŸ#}=^ˆúBÆQðY`Øõ×™¡’VÊÛhMÒµ”“Y'9‘šŽägm¶âa!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕ!ë#ø¯Xò5úƒ¬Œcâ½cÈ×êÊ×|þÙò7ÓÕë¨KãÐþ¦™èÒzlêDõÀ©F\iHJ¶—î’JI)7ä;(¶q—í¿¨KãÐþ¦™èð×MTLÓTbaxwÀèËã¯}SFô§ ðÀèËã¯}SFô§P—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× LR|b£ŸðÜJ“ŠŒR<5óX@¾º„¾=êiž‰ 7×P—Ç¡ýM3Ñ!C¸ÆF_xóêš7¥8g†F_xóêš7¥8Rà¹Þð¯ FÜãIÞð¯ FÜã©oz¼|åsƶb… ÌP¡óz…©ä¡BÚ…Å jZ‡X[P¡Bµ 1o¯ Pb³ɺ´)1H¨Å#:âaIŠOŒTb“ã‰Rb‘QŠG†¾k(7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœbI;ÞôÛœcõ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L)1IñŠŒR|cÃq*LR*1Hð×Í`úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾sŒI'{¾sŒ~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰…Üûgóèò±«_'í Zù?h¾;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÀ;:×YüúåcV¾OÚµò~Ñ|³­uŸÏ¡¾V5käý¡«_'íÆÝê{ÑÎÇŒ[VÅõ*­>†d)ÈKIY³KÊqJ#mf«DdI+ññìîèìÚ¢kªgŸ²b©–›Õ¯“ö†­|Ÿ´nM!P4 Γ‚ñµ~¥^F¯rÆ’Ê’Û—q$»™ÇG Gî‹i´G üI‰«Ô)’‰U……êdâŽtu¶— :•­µXóR¥%$F¤Øólã!Ëô4ñD×TÌ|û¿àÌå¦õkäý¡«_'í¦N‰â=AÅê£Òñ$ê…3®‰M’R¡¦ÿ”2Òñ)ItÜ=gºJIRxˆ•o?T†¥èÏ{æÃvEBŒóm²ì÷TÚ/-Fé›il1'"îw.=½À¦Î–ª¢Ó™ù©§µkäý¡«_'íSBÚ1‰ŒàÕ±#­• QÈ·\¢IÖ£+äMöŠ×;Hˆï³'¥m`zf´}ŒÎ¯MTÎäyªJ_5^Æh,¨Q™•Òi½ŽüBfÆš.~žg?ã=3ƒ3Œ´Æ­|Ÿ´5käý£i§B˜ö“W§õÏ…æ±LvtHòdcqDóÄÙ%³5šs™ì+ì#25XŽâqKêy:ÕKnk”ö(Í¥šT9ÏE\™2Õ.êÜ[k6Ò’RÚÚ[ .Ò4ªÕªÖ’žýÿæ?=©ÍNtÕ¯“ö†­|Ÿ´m e£ÄáÍS«Ó(õøÕ¥Õž§LyÙ1ÖÚä!Hm-¨ÝÎFÉÔYO*ìv4ß^ÑV¨Xh±[ Ì‹LÊ•)Õ)¦Èøh%Ð[KÝ”é´Õw·á¥Õ¯“ö†­|Ÿ´Oðƈô‰h)®Ñp¼™Tõ‘›n›­·¬"Øf”­D¥ÎáÌÑtqK“ÔÿŠ1ìçjlVèÕTÁDlÉK$Yã¥YÒh͘µËþQqÎ;ªÓi£»tóˆçä̵>­|Ÿ´5käý£ah3GǤ¬tš§îíG\©.’s/V“Jl’=™ŒÖ’ÛÄW=¶°™ãh8^«;iKªÒÈÍÈu¡•H2Úhl–†Ôj±¬J¹Ø»·¯O§¢½“3ŸÎ}Ægh­Zù?hj×ÉûDŸà¼M„jQ)Ø‚–¨²f2—ã%6ñ:…‘TÚ”G´¸¯~.R¾ÃúGµ(’IK„£G’GÂÙr½†bn„t© ‰Ï¿ƒ¦jà•Þ4:ÒÌË)+€IQ››ù¶Ü¸ÈÈZtºhÇõóýàÝSZj×ÉûCV¾OÚ&¸¯Fxï P™®b 7.=ã$¥Õš)Ÿ-)3R ÿïr hkI§‡zàëFnàÔë³kÖdµïªÍ¬âÛîC…Óc;ÿÌ¥®µkäý¡«_'íÀuìë]góèò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß+µò~ÐÕ¯“ö‹àk¬þ} ò±«_'í Zù?h¾ÙÖºÏçÐß/9¡DW2Ø)Ý÷³~ªÍ6kŠièµ3™`o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8Ä’w¼+è·8Çê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜~ űÜ~ç/Ö"ÕÊi§¾QT*F±<†?5©ä1yÔÚîFÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•ÁÓ}C»ã½AÞ˾Zˆ›“ufÔë²ÉɬËÂÉš×¶Û^Ø5©ä0Ö§ÇŸS]›ö¦ÞøŒù¦"brëî¨^̽‡ëuõƒ¼ßäû§{7^éÿ8o.MgÝe½û—î‰L8rñ™°;Ãõ½iï‘’Úe¤ŒÜ4:z¢n÷5XÐfD[5'{X‡ kSÈa­O!'èZÙ¶.G·ÙÖ1ÕlÏGTâ¯ÿ—ý5÷îOþî(ÁumSeNÄÔ.1^Ÿh8Êæ2ÇpqŒ:~©Rj:“)+ME$”ÆA™•ÔKUȬy­{­ËzÔòkSÈbôÑjš·~¤sŸgYÏ䣿£´tE§Rè˜G•·ºã)‰•J•G2醦ò·+f«&î(Ñb+ì>R´oÇv.€ôÐÓÍ)¥8yd•¸*“I? ÒdeúŒr–µ<†Ôò¤Zµ¿|ÜöÄòé9êfqɱ:ŸRêô› 1±špŒ³merã¥æÖ½Ÿ¢ZT¤¦Ê+ñŸZæC¤4ÁjÑ {KJÂÔÛŽ{Ç2š•¥÷±äز¹«-ÉelרCŠõ©ä0Ö§Ç[ñjíȯõ1Û¿ù#1í´0ÕI˜ V+ò›DÍLVëSŸë#%³[F¨ ñüÒùDC¸Ïã&cÊ¥5šF5e²'èÕIŠŽì¸é%¡¶ÙQ%E™(<ªÍbá—ÒZÙ:X…MÑtœ…p‹GjL4Õ^¤Só“ )"Q’TE•Âà‘™)DE¶ãYkSÈcÚ«~ê±ËöŒçÙÖt÷÷:úd >êŠÑ±oôöR¸²µ´z…På"’¥Æ4!´)J<¤¥$ˆŽÇ­²ÃóGL7†tÇ¥J ~,tÔ±=2Ó‰ØÊÝdÙ:“3mKΞ.XÎÛ!kSÈa­O!‹M«SN&ç³ç?Ÿý£3ÑÖ˜Ò[”ùZ(ÂRðÕ'¹Bz4ëë¨ËŽÖºÊJîÙ$ÍI2=b¸ˆˆ¬G–Kƒ¥Êw«GÆrCªeªIm³QåIe†­…ô­Gö”q6µ<†Ôò‰±fi˜ßÎ&?™Î{å9žŽ†ÂòäÏê.Çrf>䇕_Bn(Ôw7!¨ÎçÊj3þ³mP*8—*³Œ*hî±F»XË Wœiµ •}RÐdƒ=¼;)ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïep½jy 5©ä0â¬ûÆÙ\oZžC jy 8«>ñ¶W[Ö§ÃZžC*ϼm•Àõ©ä0֧ʳïeúx°.­ÂRLˆŒZZë”×r&™ÏrôÆ ãXë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ1$ï úmÎ1ú–÷«ÇÎYו0ê0åN1Èm¶IÌÍ$–¤/2WÎ…§‚j÷|FFq‘‹ ÙP§? %:KªmH¨F9 L®5elãÌÒeö}ã×: ÑN Åš=…TªSѺr¶Ù›lµÂýj¹æA™™šmÄç°;Á\ËÁ ;˰;Á\ËvÑçx+™c£84r×´1¢ê}n©QàSã9*S»™•jÚm&¥ªÉhÌì’3±Ÿ ööÑçx+™c£Á ;˰;Á\Ëñ=¡3\‹Dr:“>\g¥0Öæg†Ó*i.*ú«”ûEc;žm—±Ø8hyvÑçx+™c£Àz<ïs,t`84vHÐvŒ£=™ ¶Ë²6c¡ÄÆJžY!K4 ¾²!j±m²T|Db÷`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱ч`=w‚¹–:0¼»èó¼̱юGÓå‡ô±Y£Ò£¢<8ÉŽM¡$DW8í©GbÙs33ÙÊ a?¢øn¬_‡ÛÞé… WaêÞ=e“²>ßzsi\¸<{Jñºå9ú=ju&J›[ð¤¹Å6fi5!F“23";\¹DU<`ÙC§?X­A¤ÆSh~l–ã¶§ É$¥¨’FfDgkŸ!‰0!Ѽxòñ¤ò˜iöW¬ÌÛˆ%$ìÚŒ®G³Œ€G€w—`=w‚¹–:0ì£ÎðW2ÇFƒ@w—`=w‚¹–:0ì£ÎðW2ÇFƒ@w—`=w‚¹–:0ì£ÎðW2ÇFƒ@w—`=w‚¹–:0ì£ÎðW2ÇFƒ@w—`=w‚¹–:0ì£ÎðW2ÇFƒ@w—`=w‚¹–:1̽T¸^„t•CŠ˜ñΖ‡Wd¤k7ž,Ç”ˆ¯d¤¶q N½¥`¬Óêm8 ™¸é,ò²-u‚Ènƒ±º¢…H‹bŸK§Sc¶ÆD± 2o‚ã…s$‘]Gm¦{¨ˆ‹¬%`¬Óêm8 ™¸é,ò²'&¼zÎÁ#ao4³ì‡YØ#Äl-æ–}‘ Ãƒ€wYØ#Äl-æ–}ë;x…¼Òϲ Ãƒ€wYØ#Äl-æ–}‘Î]TÐép1:%*‰I¥2Ú\#LhcXf–•ušH³Óµø»œgy‰É†›(+|'ìzd B{‹>“ö=2 ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ1$ï úmÎ1ú–÷«ÇÎY׫T¨F‹}Jd¶"#W·ŸRÒÊlE•gd•’’±r ý›VªÎb$yµ9²Y†œ‘[yõ-,&ÄVAÙ%d§a[ˆ¹6‰!Ôkœ+]sÉ•-ÖãvQš”Ôƒy%«AžÒ#lÝ3AlàÛ`ãYUéx–¾S‰«)Tiì‘Ný2·#‰Q¦ÄvOn…(øV¸×uJÍ^ª–“TªÎœM›)2æBýYŒì?gVë3¡5u^|¨¬ûÓIZÛGГ;õÑ)Ä|NþÃTè•Jð×Dtߎԇ µ!¹RHó$ŽÆ”¶”–Ý„”—pˆF«èm;ß«¢½J¼&ÍZÅ­[¨öÝôæ"²UÜ"Ù³`´Õb®Í-ÊSUIÍÓÜ;®*d,šQòš/cÿpóÊ—*^«uIyýKDÓZÇ Y\IMø’]Â-‚b0:¯FxyUýádpõT™'Lðýqõ7}Ø‹ú[Wu5kÛY<{ìc0¨‘jSpm:€ä̺v3•\jKѤÆjAÒ$9…<ÊÑ—!’ $„$×HÑœ‰IÊè‡@­hjPéõHª4:ÓSá¥öÏô-b%¤ËŒŒ¯úŒly8{ÉÃèÃÒpíê3fFŠ{”öÕ&Gr2lÓ”¶™÷e¦<{^ÃÒ1=R‹R®<Öm ~J”‰i2#£BÃñcÁ–ië5Âm¸©Jc(Ф›"+ ò­i¹[bÔ\F`5Üþ(cEÂÒqòMœ`íÚ‚£0—ߌª“j"A6KKŠFÔ¡$z²¹XÔGéÑv3®âœJ¸) F2×Öš±WѬS{­¼ÅÀd²¤ò¤Ìó-'|†ƒrq&›†å-ÕÉ¥SŸS¯‡ ȉQ­ÓgPk;–Õ?¢¿NÁè6¨æäG,lðÈÊ*µvÓ”Én Ó³e¶lcvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_Õ?ñ爿ôßûV‡zîÈÿ9ÿ Ž êŸøóÄ_úoý«@"°>.+?[Óÿƒ0fð„˜”ÜäöªõzLÕTÔ‰4ÈiyÔ´M ÛI¬ÝlÛJ”nñæË·Üˆ5Uª3Jz’ÕJctç׬v"_Q2â¶p”‹å3à§i—p¹å.§R¥H94º„¸/™e7#<¦ÕnK¤ÈÅfœ‰¬(ø…ê‹«:àòêŒË3y))IhœUŒÓ«Ið‰FKRöÜSeI:WÀÓ\ªn•<¸„Ü䶦ʤ- 7ÈÌÌÖdkAÌ”‚NÓ#¹ëöjÕV*gSf§5¹ê33’‡ÔN™Ÿç#¿í¦O2qΗ6L‰j2Q¾ëª[†eÄyŒïq]‰gâM®Õë4ù8Šo3w[f;òR4¦êJ´Ë)šTd\…~1ù¢ßôîý¯ð–1’1 ~Döj+•7¦2“KR-jq²222JŒîEc>.Q•ÑCn;¤ [M!N8µ8”¥%sQ›k±wL[vþ ©V+uùÕY¸¬£°Åfm1a‚FVâf£N·Z¤ Ÿ÷Yr*Ù”"š&Åž]3Fõj¦4N"V,ˆe:åŽÚ"©1ñºÞ© Qe[dÒÉF¢ÌéX‘°†Ñ*^,@x„©Ò¬›z£¨4î“E­—Y—5­Ü¸ÂhÛáŒ@¥Ãƒ˜u8”Èð%U§¡—æM¥–dF­¹Hìj;r˜°á|mR†´:·ë,»RÄz½õI%²\Œ´©.½Á"àe} ß)Œ²ì#2=¨#°pÞ VU^¢E¨­ã}RÙ§6‡ÃJ’k5’sf4­e{ÞÊQwLf÷dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_cvGùÏøL7dœÿ„À_YÕ±ñ³êvÿŽøìÍÙç?á1Æ]ZÆJҼ܎ŒÙ—>ø¡¨ž/ú¿èC_é2†ªÕJŒ’M ¤M%ó:%aãCo«ý&Ä®ênÖ+¡dZÓâ;”Vñ5-UøïOI8Ú‰+$¡J";ÊäFW/Ø0uÊž®Å(µ¶)õHé<ÄÔÈòùl¤\sö¬…½ˆœ£a$ÓðµÊ<…b2¥Mbšû¢2Íiª2ŸR"2&ÐD¢IÖ¢ÈjØ~ÔbLLÆTj¬Š¼J’ë{ÝVÕ=ꌔâJ‰V÷{U°Ò‹å#YZLšŽEè‰OM,Óá& 7½µy2ÚýË Ýoðïm#zo›pïan{Þ÷ÕäËÇúbºË0(íVfÓä§;G‘-ö!¹%L&šä£%“YØ' V+£g®Ÿt‘&¦J¬JÅÕOâçb1B‘)Gqˆùª¶šY¼éä##ZœSiÕd"Raû‘î;ÓÐÒ E¦ÄK/kÚ&)ù êµYÊÈØ­_å·/‹`ªeKͪFªÌbŸ&¡diNÀ5¼Ïû 4]?Ô`!”1†ºôlBöãV4• égJš~¶äu™¯.³9†²2YÂ,§´ÏoˆÆýàÍ˹É7>èÝ:­Æ¬šín·Yl¶Ï¬áæãÍÂãÚ=}waï~ žÈXêŒøÉÿ _Ætv]CüñÕÿBaÕór4‚·ÙVfÜdÖƒµ®Fë†F:Þ·‰¨qj¯ÇzzIÆÔIY% QØ®W"2¹~Á3ÈBôƒI‘UÒn8J-J©*ʾT<—àȸФ©HQ|•¬v2ŽÕq¤¦ª¿Ò¢-ª“J,Wã/!®Ê9§ YÔ”BY¬JJ ˆ•rIÜlEâL*¹ÌT†•%¦ÖÓoešÐ…šMI%e¹šf]Ü©ä!e5œ™Se%0ÊDô%(GžBRFIK‡–ë"#2";ØŒùD”LA‹àQ1õ)3£1¥B:¹A\‰f³ZUh„¥‘%f”’IJÍK±ò™>lªÞ.ŸƒêR«µ = ñ,ˆÊ§Ej9®œ¤Ó娖n´¼Î™¸4½Á#à,Léoèê–ÊY¦Sé0ZKÅ!(MÕ¤"2%‘%±™_iŠê³tViöª°é“Û’h7Ó&­'MÈj% óe¹ÚüWØ^9wªÇý,‡öÿ†Èèn»°÷„?Ïds—U¸óñ qÖ2½fUe2½ÑÃÛÆBiæKN€ºŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾sŒI'{¾sŒ~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&'" …þö½‘‘©ñ­:@Æ©UG©OUš¦ÌrœÂõnËK 6[VÎ —l¤|$ì3î—(ñ‰‹ŠÏÖôÿàÌÊ EάĊˆNÎÎéfŽÓ„…8’Ú¢%'‚GÂ22.3âžcÄkŠè‘›ÂÎÕÓL¤Ó^b{1‰ºuY3âCªºÈpТ6¸î’<ÇbØ=ž•Cf…R~›Feømj÷¾« iº³ºÒ_åMšÏVjFn$&ʱm#¸ð ΰû-²ã¬¸ÚF±¥)&Dâss$û¥™*+—tŒ»‚ؙ⊔"ÂX^1áúb]D™&äcfS$¤Í%­És25Òeu¬V"Ä`¨ÐæT¦F› ¹(:\ç5-i6œn3Ž¡iÊ¢¹’Ee\ŒŒöq3Ý‘ƒœ¸¡1PÛ)‘ª‘ZD’Rónµ Ôƒ,Ùmv’dyo´ö™X‹;ˆÞ´ê¼HiÂlêdÁ‡"J‘-üí)èí¸¢bë2",û3’öß¹b Ýøaè›lFí‡"6èe/³®hѬm^åi¹mIØìe°Ä¢u&Ÿ…Ùšìø,Ö_EZM5¤<ãˆi$ÆLë2mIQ™ënY\}Ëøˆõ9X)šm*C¬;L5$?eÙFâIÃ#Ê[e‹iÞÆ„ \ÃñÜ&ä2ã+4%ÂJÒi3J’JJ¬}ÃI‘‘÷HÈÄÇÑ#7…«¦™I¦¼Äöctê²f%Ä8‡Uu‘:á¡DmqÝ$yŽÅ°{1J¡×±u‚Í—éñ©-&ckklœŒÁYNš2¤”Eµ7±ÌÎæmÃ_E: Ú”ÆáS¡È™)Ëäe†ÅªÄfvI™ØˆÏè!8©P©k‡Pl P)ÍGaÇbÊk°ü‡ j$¸‚yD³Y[! ²Œ»—!ѧÆ>úÞ'ñ’³+ˆšovÓaÑlD~Liiâ^¥µ8dé)FƒÌ”(¸)MŒË¹°dèÐh“XÃÕ5aø%Ne¹X=t‹¸¦S™Fg­à™¡H4åÊFµm-5`@@d¦7LzœíE™ Æ–¹†”Sif–Ù4Ü–N(ÎäGÁÊfgݸƋÅbÏ€$ýL„OqgÀ~ǦB}u |zÔÓ=o®¡/Cúšg¢B$‡qŒŒ¾:ñçÕ4oJpÏ Œ¾:ñçÕ4oJp¤%Ás½á_@¹Æ$“½á_@¹Æ?RÞõxùË:çlÅ ˜¡Cæõ SÉB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔøÖ€ å·N¢È¤¿@¥Ô˜‘%©JJÌ„©("6ÝAX‰Å÷6æ;ÞÅoJ±{íoziÔjU9˜NHp™džqkÛCn’õ®,Ì$ØŒ¶÷Dhm ‰Ó"….ŒÆ£Â%æŸ3ŽOgCç"Q)n(Î䵕r"=„G´\®bù•V§šé´È²jF[¾TvÖ—$Ùd¾Í)ºÒ•D¦æB6¶m¼DáQZ¦½J¦I[ 9<§›Zeµ©K2IfÉ|ËY’&¢3Øeb·†‰R‘H©µPŠM©ÆÉI4¸œÈZT“J’¢î‘¥FGúŒx€1A;Š ª#4:L8rjA%„½™§PJ,éRœ3;¥jI’³íÌU‰áG©@ÞæhU¥D§Ce‰ÇòS i”!E•y¾¢Î…”_ì” m˜§b ÛÌØq*Ñä=¯q©¹Ìµ½Õ’¤¬Œï¶Ê±ì½ìCÝ/Ï~e*ZiÔÈîSc¹²i•޳]ÚZMFF›8´Üˆ”d£¹™ØÄdí ‰Ó"….ŒÆ£Â%æŸ3ŽOgCç"Q)n(Î䵕r"=„G´S+H~Mïm9¹­´Ã%PJº22I&ÈŒÔiI‘!%™)#2+í;à@6À?Š^\i)H¥C•-µ7&dv–N¸•{¢"5š›ˆò%; ˈì1ønªå½ °ÌXò^„ò^i·ódΩ3ʤžÃ±Úö¹m¹\ˆé˜ç£ICª\Ðh•*3kKޤÎê+#îäJoÅÄfC×.|*N rI­õU”ÃóR–ÙGÈ‹ê1pX£¹¦ädÚO»b‹mìÝÿö&õî(_ç;£uj¿OîrêóßÜwmn=£Æ$+|'ìzd B{‹>“ö=2 ë¨KãÐþ¦™èУ}u |zÔÓ=$;Œ`teñ×>©£zS†x`teñ×>©£zS…!. ï úmÎ1$ï úmÎ1ú–÷«ÇÎY×èS£Ôñ&ÃRë…„OÜò_xm*mõ¡$Úés*8J#;p–{-ÇäÂ’pÅWÑhªÂ1²H«0ÊŸTÉÜafm©+"Yk©*%')¢Ö23!åÝûP 1ªm; ·[›Lj¨ô©ŽEe—Ýq 6M¡µ-JÕ©*3=jH¸DEeq÷34ªUuè¯?K7iµ*¹éŽo¬—m6ùðFW<ñÎÙÉE•[HÏh™«+óSQ›Î´¶ã¦W"ࡵÞD¤Ïú…*aôÆD•2á0âÔÚ4žU)$“RHøŒÈ”“2îf.RÚ$Œ?Z}P‹ BˆãtÚ‹«u¹r™HŒ§ZY%N”•4wÚiQ,ø;ÅER…F4vÞÃôɪ:œô¹ ”G«Šyø¤¯eqZÈNËæ57` õ kz¦¬?©Ì· «®‘wÊs(Ìõ¼4)œ¹HÖ£-¥°Dæ7LzœíE™ Æ–¹†”Sif–Ù4Ü–N(ÎäGÁÊfgݸEYÑÒs©­ªíЬJ²ÐÃù²¥ÙJ,ª4ìÑ—tsxú+£IwEðÛ‡!ä­© eå·¬Kk7Ê£MË1Øír¿) Ú¨ç†Så?ÿÄZ‘Ô·¨I)ÊÒI<»«gðFíÁò«Œim xžV'§F‚kŸ"Lf83 hÕ²•2„$ó6n(ТRIlÌød%X“üÀÿúî‰ÁÚÏÃíyat"+¤m Sp®®UÚ®¦TªSqÖ¶{Ycyä¡$¯Ñ¦Û GÇ}…²ÆF6V!ÒN=¦éEŒ E»»vfvH«ˆËŽ“"SËV õy3$–¦F¤‘f΃W“L¿èN”ü#øˆ—+²ŠÅŸIû™žâÏ€$ýL„úêøô?©¦z$4(ß]B_‡õ4ÏD„Iã|uãϪhÞ”áž|uãϪhÞ”áHK‚ç{¾sŒI'{¾sŒ~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&6ljɱ†&PwºÑ*Kr%Fæ¹ l”I$Ùd‹-ÂÚ“÷gÈ›k,/ðìoµè˜œŒTfµ¡ÃuW(uèU†bÇ’ô'’óM¿›&tíIžU$öŽ×µËmÊä~Šeu4ÜWB£ÓÚTWó1.ò˜JÒE”ö¸k;(‰V5Úÿ«`Àóa,Ì ùÅL˜ë¤S¥Sßxß(OëM¶W¶Æ…ɱ½Ù܈¯{ôBÅ’X®.ªõ2.ðÜ„Ügâe• Û4 ›ZL¸ Y\ÌýÑŸºÚ#À˜¡WSH¬É¨³G§¾—Ù}’Œñ½ªi¤Ð¢NW ~áJI”gc¿Œ«£â')ôÔ@v•L¨6Óë‘æ6µê\ZP•(’«“hزQpx¸Æ%2ç¤àÇ(ÔšÑÏUYL?5)am”|ˆ¾¨óõŠ;šnFM¤û¶,ïÿ±7¯qBÿ9Ý«Uús—Wžþã»kqí0€D´qSôQ &I„¹ Hi2c)$ë&§,è5‘(¯r¹\ŠäcçhØp4Ù¤ØÚ‡%–NT!4øÖ"æöŸë£¼ ¬ãbÚõNžÛjJ"Nj –¥Ó[1ÛqnÞêRÏ1©Fw=¥ÇµZ}†©•)HŒÎbA)W3RŒËam3ØgbîŸ#ìï¥o¿wÆè󾕼jýߣ:k¯ü%áoùw}‘®´¡P‰TÑÖ“gÀ{]Ýêȼ¦›Ùäì2#ã#«³¾•¼jýߣÜQ¥ bjŠr¿ºéòrë™Ül#6UÓÂJË„’=‡Ü„åd‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##SãZt€1X³à ?cÓ!ÜYðŸ±éß]B_‡õ4ÏD†…ë¨KãÐþ¦™è‰!Üc£/޼yõMÒœ3ã/޼yõMÒœ) p\ïxWÐ#nq‰$ïxWÐ#nqÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÄäA°¿Ã±¾×¢br25>5 çH=Ô \ŠÕYšdU´‡žÍ•N’JÉ5ìF|EÈ6`!ø-^NÿF"Ú-ÿNéßÚÿ bu†©H«TTËòŽ$VY[òdjóê›Bng–ås3²H®W5Ölþ¦{ñ‡·OÙËØ'H~ W“¿Ñ‡`!ø-^NÿF${ÂÜ'1\I‰KîÓ!%Èî¤Ì’fr£ œ+ÒSn¯}Š¿‡ÓÙ‡Ž+4ªs &X©?;)3Q’Rê’”•îfv".éŽÑ¤‰þïðã:¹íÿ,G`!ø-^NÿF‚t‡àµy;ý•HÂáaiOË‚…ÔU‰6¢B;­¹¶Œ›Q‘/2ZàŸ¶q\ïs ×RävÓ‡ÎBͶÎ<Æ^#Y'6C4,É+±lIØÏ¸F${ߟÊx©÷X^Á:CðZ¼þŒ;éÁjòwú1ï¥PêµFÒä¦êö¤ŒÖ”–lŠYû£-„”™™ñ$¸Ì®BÍZ›.—%,K&s)´)—Ðò›™\–ƒ4žÒ2Ø}Á<g•âçž×›°Nü¯'£Á:CðZ¼þŒRx/ý¿ÁÆëþUv Ò‚Õäïôcþ‹q -‡åSZuµ…¸á)*#±‘‘£aÉŽ†¤c:nÐe'VjDƒÏ*e:³y̨A_jˆ¿mˆŒÇ ö?J"s—k7ÿVf0æ>ÆUÎÿ¥sËöáÎ ©±N­´–¤?¤!%˜!­hÚJ"2;¡[ ¹º:/iF’:šqmn:KKÞ‰ ̆·ÌÜŽ³lÈЫq¤ÈÎÇÄdI«[ã^ÔÍÿñç‰z4 ¬YðŸ±é î,øOØôÈ@€o®¡/Cúšg¢CBõÔ%ñèSLôHDî1Ñ—Ç^<ú¦éNáÑ—Ç^<ú¦éN„¸.w¼+è·8Ä’w¼+è·8Çê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ1·°îj·…ê•6*+Dø.¡†qÈÒù)·๚ä¢K.ž\»l’#3=˜ú©ÅKÂ4?€°Ú±N!b˜rÊ Rì“o97iB87+™­IM¯Ý¿pÆ>%*eN¢ôZ)õ2I¨ÐME3tÐG±JB YvZås"å1çÌc4ª£Ò$Çf›1Ç¢6§d¶†je ÷JY]$W+™ñÚ¥­J&Ž©Kž,Ín˜êo9r–b+ÿPdx€I©ØF¡SÄÏÐãSªÑ䯧®KÌ= FòVˆúÃI ¬d•¹d¤ÏmœGíºÕU4—hµ&ê NdÅTU“Ê.RE®eýAº4½4JʪåGM" u#½¡”eëŽÅsà[7ñq÷Rð½qé4÷dáÚóe<”¥Q¡,ÔòljQ4fVR²%F_AŸf¾³PaÀ¤Ï–Ënt8Ìe­*w.l„dV5eÛn;my°¦A˜¸SbH%D¦^lд™÷ '´„äX– bF JUš$°© 5Âq6i6ÌáܽÉ\®®"¹ p•üE‰é´8æâW6J5¡£pÛIŸ yKŒ’›¨ö–Â=¤#1ÌbÀgS†+q$ºÝ[WXJ"= ÒP–•¥)IÙÃ%ÆÉfŒÊîŸvÃËWæ²Ãðèu9-HJÖÊÚˆµ¥Ä ì³I‘m$™‘—ñ†`c{¥U§7R~›1¨N+#rV‰¥+”ec=‡³õ áÑk`;>&|˜ŒßZûQÖ¶Ñn<Ê"±XdxH 6‹Óºwö¿ÂXØ´@TJ$Æ`²ÒçÍu yRb4ûDÂxY .ˆÌ×”Îå³V›ÓëE¿éÝ;û_á,vÖ'ìk‡q~ÃULÝýyF}¦ †£i6uGcNe¼Úb;©DGmƒ½›±o9ŒåÂõ©¯—=OÅQj©Š–ÂÓT•JM=Å3¶ÙV®K.6¬©±&Ͷh±'ù(å;xgâÏHò1T6¦÷ÝUZvÄfZãq)U®D|Dv¸é6OF¯i-ÜÖ ¥®¤Í5u*S•´“hÕǬ³í.Ùm•dwÛaí§ÆÑ B Bt04¸”Ô©SßaVÜRI¨ÝQlA™æµˆŒwUìq5sís~ûá8t£š´öž«Åœûr†Òl¶—IM]+QšYlÛ/ÈVÛ‘™]f¯Nn‡…£L~ªº›#xÑ $ÒÙfLÔ£Nr<Ê3ØF|ú‰MÑUrL¨ÔX.¦ü5d”Ü6c<¦·bÉ$f“Ø||ƒ‹#`úr›D‡¢ÆkÓê¤ÊCTè«i…2•©G!Æ‹ÝHlˆˆÌøùq4ôO WV„ÄØ†XÙ¤Á[`@[¹—’²SîëœI+‚¤š)$ÎÆÚRW.1€Æ5 mJ¢ËÔÖ C‡8­Æ×¹™Fnj›3B6JÄg|·ã1ÔŽDÑtW Ã¬Qp©5 tÙÍÃD’[Æim¼¤fJQ©+Id5”…MVúÁ•* Z˜M{ª3oæ…™Õ™$«¶î­:Ämà¯)f+Šöªc؉ÓU>×í®²pgŠ46³ì‡Y83Å›YöE¸Úz+ÁÕÕÄ£|`Êî'‹‚hq©z>ªÕ£7É2ÑR€Ê3qfyRëé]Šöº’[Hír±žâë'x£@ók>ÈAa˜ÐS3-²ÃRe¡¶ÛI%(IKx‰$E°ˆ‹e‡›S~.ÄDC½‹nffZ›LÕ¼]3Dت<ÝÔéÑ×J‘¬”å^š´´Dƒ<Æ”È5HÌû„g°A:µ¾5à}Lßñ߇OߘÃê—ý{«[ã^ÔÍÿñæ¥é–d‹>“ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLnœ6š´-U+#ÉJbW)î¦JZ3B†äí5ZÛ ÆÈÿÛI(¯¥°¿Ã±¾×¢br1õQš—†ÍÃS)’qæ§aVSs+1ªSšCGv”•‘êK•¶“¬VnEŸ¹(4ʼÌå• Zêqꎪ£¶Õ¯4’–îߺ2B‰â=œVÛ\CÀy¶¡Cfªî3§µ©2«0ÔÔÌTt›®!íD’hŒÓ~%l7þՓǰF¡F©IÑ]fb£Êz+5˜j×dRƒ6¤‡›ˆ¶©’?Ö¤_Œ„PhÙR©óâiˆráI&F&YiÖ qã›D’#Úg¬#E¾QqÅRèu¸tZÅ ¡?»,£:ˆœRŒFé8ÞOu˜ÕªVC,ÆI½­´B€Fѳ0Ì:ƒxŸGô™ÑßUb5_Zã“S¬E'RR²ãNSKë±ñ$ï°Œbp;xŒ´©D¥ÔZª&R«QeJˆòKÌ•’õ‹Aí¹ ÔyŒ¶$Ìø„$h™S¡VàèË⟴աG–fÊÒIȉ$´,í²ËSDd|F¤‘ñË4Ô¸S0<ú“OESô9‹*JM ×ë%ufVÎxê#î$Ð|VÜ]†ú¢ËfJÓŠeĸHu²Zdw²’{\¤{ &‘9¦Òq-+c¬12wಢjMÒo,¦Gý"R{TDFdj-œ"Û´G´vëli>ó‰m¦ê±Vµ¨ìI"u&fgÈ)¨â#‘øp¨ôÊSrr—3¨Q*Üšô£eM4»:î®2ZÊd[TjK¤›qšTEÄb‰ÈÚ8–jF$ÒšW {°…,ËR£Ki)¬©³âØZ’ZˆþA(ËeÅQn¢š ÚM KD8QЙpjͳ+©IkMdl+SúLê3R¶ß7Õ€#bR‰¤ü†qlšm˜í0¥¡NH+-PÐo+VL¨ò«*½Éž]¤Er!ˆÂ$Ú-ÿNéßÚÿ c¸ô‰ƒ_Ř²8•µN,?S†¹ˆRsÅ’äˆGZRgsRN:ÖFEb6ÊæW+ðæ‹Óºwö¿ÂXúWÅ4F#£aÚA1êu½v÷2¦Ödö¤’npˆ²¦Ä´û£+ÞÅs®j3®“ŽGf¤RfÔ°æ P­d&o>kµJÕ’”¤¤Ê’’,ÙRÊHÎö¿á|Q‰hX€âà’ÃŽ§Ô(1¡œ¨Ç»d<”j’ƒmf”´Þ­II¸h?Ó+‚’¸ÚIÅ4cCÁ©¨%UÒ€uŠM¬í–”ÍvÊG™I,·Í´ŽÖÚ3 !u.ùcú<Ê;;×Oc Ôi«— -%Q–·arJFG”›|Ót)%c#.ZÀRª¸Ë .«VÄ(4ÚEM™6êgO’§ž~šBα™9t¬IËú4š¸V3ØÃ 2»¹ñÅ/ î\Û¾›2vèÖ[W¹ÝŠŒ™m·6é½îVÉÄwØjU?J*ÑÃRá§Si¦>ù¾ñ›OMS¨5­Fáœ`ÍJ>™ÌÈíìÑ=.}E˜J‰TcsϧÑ!E”Öt«Vël!+MÒfGe•È̹˜@Ú÷¥ÿç&ÿïÁ¥k:»X©ÌžÎ‘k”xë›,™‡s“m¤¤ºGkÆZŽêÌ{Tg·¸V"­I‡›OߘÃê—ý{«[ã^ÔÍÿñ?Ò>v¯MÄzQÅsi ÓÞ\ÈÈ8Ƨ›$d$Ž)câ-¥´ËiqˆV·Æ¼©›þ;áI-2TJJ²§ lšZ4’Ü~Kl6“Uò‘­Å%7;Š÷; ·$1 =8Riµ)Té­j¥Eyl¼ŒÄ¬«IšTW+‘ØÈö–ÁçÖ˜G©ã ×ðôZ¾³skóþ‹+«Ë•jO´¯Å~!•í`Â}ûøNôÂìžÖ 'ß¿„ïL¬O¿ Þ˜Hã`“ÚÁ„û÷ð郵ƒ ÷ïá;Óã`pïS¶ iÃmɶQq–©î”x+š Ñõ“"¥2zõ,'2‰ “ö=2!=ÅŸIû™ õÔ%ñèSLôHhQ¾º„¾=êiž‰’Æ0:2øëÇŸTѽ)Ã<0:2øëÇŸTѽ)—Î÷…}6ç’N÷…}6çýK{Õãç,ëž5³(Vb…›Ô-O% Ô.([PÂÔ:ÂÚ… ¨P¡‹}xPbƒ˜ ÆMÕ¡IŠEF)× Žøv7ÚôLND ü;íz&'##SãZt€M¢ßôîý¯ð–;[JxVn'Æôvâ%ØëcÔÕ¡«3n$Ò•Mv2”¢+æeG—IBˊ㈴y6;ÓåÔ$¦,T)dãÊB”H%!I#2IŒ®eÄF;;¶#E>2ÈÉè€c&`üeµ"¢Ñ ñ][ â½:!¬ãGšêééˆÊ]RJÄ”2’Nb#=ZÕbÛl5Rƒü+ŒÀ˜.·E‚ö©DŸêcÑ×6 ¶Ó¹É(RHßy$O’I+6±%™]ÉglFŠ|dÿ‘“ÑlFŠ|dÿ‘“ѧà—¨ù èꓽ/Ôp…]¥ÉŽƒBž•D(‹yÎ%=u¾dµc,çs±Ú7F¥S#âåOÁ:9ÄöÙÁ5V$´ô7éÅ*bœ†hgZd“׫"ÈßI™«Œ–¬‡–MÛ¢Ÿ?ädôAÛ¢Ÿ?ädô@!Ø ȬâÉ”ƒ¡¦CªáÙI–õ? Ê¢¶ÜÔ?ØR÷­}œR\Ê‹ÙFF»Iþ†YÅ ëó2Ê&ª1S %£»z¦Õgä#Ÿy9‹ÿí¶Ïë:þœt;]¤H¤Ô1$Ë ‰.”tN޳"2;!+";XÈŒ®W#¹ô@Óæ‡éðcÀ…]n22œ3ƒp–Ý;× ‹t²˜în™ŽÉ³)¾VS­Z²4YŽÍ¦É+ñ ˆþÒ6‡½V«ÃªPdM’ª„ç%>ÃÑ—Pk3Õ“…!wBlÑ•’[GŠdJæ$Äë¡âZôªDª^‡5ÕPç=ƒœúä!çRw%8Ûg9PåÓg8I3Ü'„°¶u稱ÔËŽ¶†MoMvBÒ.iiêÕ«l®vBl’ä)Ú=Àó)4ªSÔóLJTÓ⡚ƒíE$¥:…© %:Ý›¡ÃQ¶‘€†Ð¥Tô‚tÝø®Uh¹0]6°[ß1q?Êå뵎/!–roP›!WG î“Ø6.Ž*³+Ú<ÃuÊ‚ *4˜²ä$“b'e+Q[¹´Ìy±6 ÂXso¤2VçeQѹ¦;ìªÙ™^©iÎÑØ®Ú®œBBÊ¢²ÊeL¶ÚIBdD’-„D]¬ô°¼`ÍlŒ Ý%úÓ9\j5Iµ›RIÚÙ)+FEžË(ÌÓr±Ø2uÄ Ž«¨Uô…“K—+P¸°!Çu·XoX¯gqVZ¶B"4‘p¸FiNÊÄX‘LV¤°ÖÄrÒÚ‰:èôõk2"¾S3+•îWâ>åÊÆ"øÒ«:µ†eÓ"áLL‡žÉ•NS”I+-*;ØÌø‹Qg=uOüyâ/ý7þÕ¡­FÊêŸøóÄ_úoý«CZ‹ª™•nlÑÙešbÒu9홿MŽò­«ŠwÌ´‘Ýg½ìI+Ù)"ü—5ºŠe*-›63Ðâ¾þ¾"vRžm+Q†YÑcQ ²m—–ã Eĵš$g¢°î´ø <¦”âm{ÔÃGs+–]–¹ßPÁxJm1º{±VÛMM‘=§#Ïy‡š}÷qå¡ÖÖ—N¹r%YVµˆˆƒ*§‰×…pÅV¹UL3ßÝ|¨“DÝÁ5XÌëF•ð³pò™f4íÙrO›PÁ ®¡-ÉÆ›: IrÆ·Ñ[Ì6⌸Ԥ6•÷Lî.T0n›C§Q— £Ä¦[pî9ŽÅv?Òyiiq7#2;+…s½Æf—G¥F¥ÓVɦYlÈ’„—þû "zEMmP¦vžÕ[RgSÚZãšÉFvY!IUŠä{/{*ÙOR`J¶•ë˜?ÎÒ5‰Ca¸²cƇ‡ C‹A(”â”n­$ÞÃ$Ø=ó’ršöŽ5ĸ¨ìЫµJ 3°à©ÆîfgbVÂ3±—Ëm¸ÈÈ£Êü©ÔIЙÂX¥.HŒãH5SŒˆI2+íâÚ(—>uM|=„û© Òtjq¶ú¨uŒI…X}µ´ëxZ…¤ÉIQ-Ò22>#!©Ñ V,øOØôÈ@„÷|'ìzd @7×P—Ç¡ýM3Ñ!¡Fúêøô?©¦z$"HwÀèËã¯}SFô§ ðÀèËã¯}SFô§ B\;ÞôÛœbI;ÞôÛœcõ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜ÜxnœÉá·*ŒPˆ%&JÛ~:”îX­PiqIiIWÔ¢ÌgbÉúÆ>ªqRðŠ€šPàá|AˆÉ¨ì•!„Ñ¥½!©N:¶Ó%¶^Qf‚Rò&ÈrÊÛÀYp¶°mQ#=Sr#XŽŒl4εs§›j×"ÊD¶ÉÅ+ilJ øÏˆŽÞmÃA ÊS(ˆ¨ÓÿíL›Šfg ‡s(О$ÊëI£jJÇÇb#1•˜Bø–ŠÅB¿DÓõf!Ë„ÛÏkH”ffž ,dyMУ"RÓs";’jˆ êİ\m1k0*„²3R¢¡ä’?Që[Aÿºã)Nª—E‡W]r‘4·ÜŒ[¡n’›u"ˆ›>2ZTJ+¤ˆøF“Ø'0# $5\%:›rß™r©Ê" ·oG#Y ”®C,Æ’<ª3#Q\ˆ~BÂÏÈb1½U¥Â“1$¸±$º´¸òL쓹$Ђ>æu&ü|FF GÀgé˜ZDÊ\ÚƒÕ*|àKDYˆ”n%lš‰F•%˜ŒÐ¤Ù7UËjH¶E/ ÊgQ)©—H‘»ÜiÈO¼N.$‚5™$”DŒùT´š %c½ìW0Ý0Q‡èTº† ©TeÖ)ôùLÔc2Ú䔃ȅ6ú”Viµ‘æ4¦Ç´ËV«å¹fñÂÆôR—&³K§ÆuÅ7É*t·FS±š (R‰7þR‰%Üã#³t  %>Lмg¦@„ý%´½!QfhÖ”Ф¤Ò¢,è>;¨”YIBó˜x¢Rê²"ÖpýU§5%fɺ¥¡ ’†Ï&fӑĨFJ±äseîvÐ#$È ÜtÉoâ$fªl±MÕ¼F£Î¤)DÙšM*I‘¨ìŽEðÄó]Ÿ>,§cÓÓNY¢cÒTdÛ*%eÊyIF£3#"$‘™ØÏˆŒÄa§)THµƒ«S&F™!lÆ(ËqJs"Rk]”‚ÊDkIYVUÏbm´`‚' @ºK‘Z«3LжóÙ²©Ã2IY&£½ˆÏˆ¹Áì¤?«ÉßèÄ[E¿éÝ;û_á,w¦’±ƒØ=š#¬Ñ^«oHâ8Û.eq¦“ù:”å=b’ˆê³ecQˆï°Ã;éÁjòwú0ì¤?«ÉßèÇj=‹ 'R)í*;´ú•e]5DÚaqRGÅcJŠVl×+;·¹y)ÚJÁ“ã¿!š£ÈC$ÊÕº HaJmç ¶ÝB\AÚ5¨‹X’4™ÐmØ'H~ W“¿ÑÅh/H)+ª˜¢/ÖÃýî)X’‡n!Ú‹f¶ª Ó\JÖ¤IthlÉ$fFdâˆîfDFc×X3L ŒÈÈŒÈËè1„{ãÿ~ ýóÔ´3Ž)ôÉ•Pˆñ#¹%Õ)¤‰  Ö­ªAì“îíâ´Ñp]uTLO‰%Sg¥´ºM® ¥®%%IlÒ¢Øet™ØÈËŒŒ‹ËŽj.TÄŽëeuàI4Ü„-µ#=ïvÖD¤(È“r2#+lœ8Ô{¨¹ª³4È«i=›*œ3$•’j;ØŒø‹xD›E¿éÝ;û_á,Y O`!ø-^NÿF‚t‡àµy;ýì½%c°{4GY¢½Vß‘Äq¶\ÊãM&3òu)ÊzÅ%ÕfÊÆ£;ßaú^ÅЈ©ö•Ú}J2®š‰H"m 0¸©#â±¥E+6k•‰Û܃ŠûéÁjòwú0ì¤?«ÉßèÇdÓ´•ƒ'Ç~C5G†I•«t@”ÛÎmº„¸‚5´kQ±$h.32-£1+Pã-Ä;QlÖÕAšk‰AÔ‰.’ ™$ŒÈÌœAòÌȈÌv Ò‚ÕäïôaØ'H~ W“¿ÑŽ÷Ø'H~ W“¿Ñ‡`!ø-^NÿF;ÜpG`!ø-^NÿF‚t‡àµy;ýïpÀÇ Í ØéÆGúØ£Á¸ÿÁß‚ÿF;SÌÜ ®QªA6ÓkqdÃkqj$¤ŽÉBÔ³äJHÌøˆŒÆ²Á:hÀ¸Òºš&Ä’ªSÔÚ6ÑRI(O”¥6IIm"ºŒ®fEÆdG\¥ÎØØô³cSʯ‹1f¥kŒ„Tä¦ÄÙ"å•F“"²Óm–ãäžÈ8÷Ç|KçWý¡±:¡uýhù÷Ý[®¸ª¢Öµ¨Ô¥(ßlÌÌÏŒÌû£K !´pGeìc×èx˾m,Цʧ)K+LÎɾÎm>²´ÿã(òÙÞÈ–õ ûíSý—¿ý¸Þtlv‰šE­atÅBL))‹i½™](¬Iq»X²-(“$ÜóVeîLŠ/õ•§ÿñG–ÎöC¬­?øÇŠ<¶w²:~6‘(­ÐÓR«%ø‹v­P¦Ç‹‡f>ùÄ”ó Z[e³#&s’d’UŒÏŒò1ñÆ‘ Ù­VãœVi¥Tqó%%´Å3Yk3[a¶¢4û¤ÛiÊáÉýeiÿÆ­¥éõH1gÃv–î²<–’ãk²Û2ºTFGc"?¤ˆDò!Þ;íJðœ.}>±‹Ñ[Í?¦lvë¡ÖÕI£YHQwt„O±æñ y¥dláÜ?Aß]â¡S)ZýN»qDmf\ùsd"½®v¿ÌRùó;ÞôÛœbI;ÞôÛœcõ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ1¶(1éS’ùb5Qk HQ’žmÓeMeNSJšB–•’³Þåc#OŽúŸ ü;íz&'#U­xN\¯Sű_“Q7íH“]ML¨µï:Ë퓪+g2"u 32Ìd‹Úçaf…Öí,æGn·J~rÛiLÏ™LqèØ×¬l¶Ô£3-Y’ÔßqEbØg æÚ6BëG1–©;_¦›T¼…=Æ)îGCFÔ§à¶ÛDVRVDœ¥s;š‰73L?"Çt©«œÌø'Ç·â¥Ì«JV•«)8”ªåc-¤[K“hÁE8*Ül²˜5¶*Ž/1¸l0âÙl˵ĤÌÏmË-ŠÅ´ï³$éÓŸÀÔXõ ¹iªIuöVÛ×a·Pµ6i2-JŒÉ&£²“b3¹làOjó¨’kÚA–ÕzµTBÕÍ—ÿÊ rÚ‘”¿GÁ2Kf“Í”³XÍ7Qc¤*[rJmq4õ1æÑN¾§VƒUøžc³ãFŸR®3=¸&‡Mf‚)¬¢FN9k¨¶!_÷s{©3¨‘«Ú>–íz5KB<É—Ïsš%»#)þ„f— %—1f#¹’l£mj6õ.‡W J®D‰¬ŸC2ÖËÊiÔ´™VRJ dg­I–d–Â;ØÅÙB«Ó ÃU}¸JK±¹Q]´–M底‘6KÊ¿Ò(*±l.ˆ Ñ:b£FªJĤåf=-™4¸´èJ˜ÓÆn“.G²ÔM!yxÌÏõ¬ˆ¯´Ë …]€Ý7.§#ÒiÉf3n!ÕË) ;b4!D[2ºŒŠêOræQð ¢Iˆ*™…#G­CZÙ‚qåž­â(ªT—]ºî߉/LÛP«_‚jÍÕ¤S«•ìe,ýd õªµPj+Ëi¤¥n[Zœ™Ò›H4™å;(‹ŒŽâ=ùÓiÒ“*Ÿ2D9 ÷.°é¡eôÂi|[ ‡âÅ›» çNyN“Jm ̈É% –D£GÊæEsJ¶lé©T'Ô应Ù3d(¬nÈuN,ËéQ™0˜Œ@&ÑoúwNþ×øK@1UUV»„çGq”µF«¹6A8fJRTr$XŽêÎúmŠÄ­·±Îì#Wn…ˆâU]Š©M°¥fe.êÍdi4™¬«Þ;è~ÛI$~õ.€Õªè¶t¼ESŠÍF4|+3U©±Ù,Û¢³×Ü$²›%¨Rȳ‘¸i"ÊEoLŒ‰ñC“ÆD„¢Ãò¨±“KyÇIg ÚRßQ­Õ™ åAfËup`Ô=¶’çˆKM 6‹Óºwö¿ÂXŒŒ®«·BÄq*®ÅT¦ØR³2—uf²4šL‰VUoŒY¢8ª‰*«]Âs£¸ÊZ£UÜ› œ3%) ƒ*9,Gug}¶ÅbVÛØŽUÑléxЧšŒhøVf«Sc²Y·D7g®1¸H+e6KP¥‘f##pÒE”ŠÚ«¶ÒG‰½K ÛI$~õ.€Þ‘‚±>(rc¸Àè”X~U2io8é,äJ[ê5¡³#a¼¨,Ùn®ì,!£*í7Ñk•J”Ô£r¥^mœöz¨dñ!m\Ší’e8žŒ‰†,[Ú»¶ÒG‰½K ÛI$~õ.€Uå^ÛI$~õ.€;m$x‘ûÔºT•{m$x‘ûÔºí´‘âGïRèuPUí´‘âGïRè¶ÒG‰½K Ñ£ßÛþ¿úˆQ0݉QªÔi˜¥Õä™î²Ù%R"¶e~Ó±lÌ¥«Ý)FzuAQq,–¤Vôr¹ki&–ï^q I’–È®{.v¹Ø¹b;/`Ÿè§ÿÌ/{³ 4ûño£¿ÿþ3cL‰ö•ô…ShTêvÞ8´}Ñ‘¸äç×{T’2±¤ùxû–d:‡¨oßjŸì½ÿíÆïs¹1XÀ¦JC «ÖY©Ó$Ç37a¸Ü(Œ¡Í¤DK'#¨í´&D{¤Ž?ÐŽ–‹FmËË@UMÙ«+v“$”«%ÈËV«Ÿ¶Ü»£fvÚHñ#÷©t6¦ÁxÞ‰‰XhðìÜEEiRâ®KÍDuº„ÝÔf‡uJZTƒCeµr5•ø”-JÑDùp0ì9s :ÚdÌ^"l¢D¦dË)«e¢±Ý:ô!U¿D§;§cÖ¶’«9FG‚6ÿåK¡¹q}“ˆéµr S©Ó36û–ÅîGrÚFFDd¢±‘‘Œ+xR8íFŒÅnL²Ò m ¹%)Il"""""âý1àçßq÷ô\·]qFµ­x‰õ)J3¹™™£i™÷EptÏ„!MbdmêßaĺҷýÓʤÈìmØö—tWjZãJß8³ë¹ŸÇX –+ªïî)«W5Ÿ|f½/SŸ6¯X³^\Ö+Úö½Šã,€+|'ìzd B{‹>“ö=2 §¨×ã}U¿é iaºz~7×õ[þ’O"œ%º:þýŸø„HKtuüÿû?ñ G4Ëç4ïxWÐ#nq‰$ïxWÐ#nqÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÆÏ¤ÐÕ6 Ï•RK‡­6Pô³pÉÅ‘šR–е‰I3;X³Ý£Xa‡c}¯DÆÝ¤½2.KÕ u: ¦¸†Ö¥© fFFóåZé3N¯Ý¤í°ŒÈíªñ/ R°œö*LÃ)P_Kô÷ª,HeÓSN²ÒZŒŽ×#ý Óc";–ÛqŒØxu•áüXÔŠª”Ô0ìé)iNš_d÷4Œ¨R’IÍÃi IدÀ;ØxéÓñÑ*Õ÷eTž®cZÖú!™ºN8ÚÕ´ˆ––Ó˜¸³_i.é€3 ͨ;‰ôV!ôÖ$ÕõN>j4ºüSq¤¥K>5f5>‹ŸJÇr!މPÄ«tÌF¹ §Åƒ%nGu6j©AêuiânîêÐYmrQ–Ò0Ü €$š,}øúJÃNGyÆVuH횣IšTâR¤Ü»†“22î‘™ ´\Q]^©N:ƒÉ•§¨o$츸ܓZ2ÚÚOT‚²lV/ÖbffÄ‘X¶©PŒÒWVëz$è¤M‘š¤¸Äeºá'åVòïÜ2¿ \ê^fnµU›-u8õF“NœãŠ×šI S–sÝ!DÉ–Þ «e®P‡‹Ëm‚‚Ó©“šBœZVÎC,‰"I¥Y¸1šŠÝÌ¿¬†Ì®Vêsô‘Œ(re-t»UÌ¡ßô$¦š}Ä,‘ÄK΄«7öíYs¦·£ì6ës$!Èuyû•itÈØ²",²ø<#5lˆŠ¦F¹N~ZI’¦Öü).GqM™šMHQ¤ÌŒÈŽ×.B1´«R«um,U˜©H¨Tiñ*““‰+[±“ ’ñÆh’«§„¤¤‰=ÒÙÄ#ÇQ¬Vp­uÌG&T´DK[ÙFjSR ä–­{H³tͳ€Gmp½1¶y)'t ÛmF¼†›(ÐF¤ØþJŒÓ~í¯Ý|qŒ1,z¡Gf±% K¡ÂnZs\¤ë`µ¬S—÷j<ÇÂ;™l±•ˆdªOoI.ÍT§]yü(K’n¨ÖRy‰Ë9vF´¥FJ½ÌˆÃtóȶeV£[Ñüéy¯ÎzR#qÝ}fµ¶‡’kAí$™´ƒ·Á. T1d¦Ði‹t6êLîhd›Ç8„²4=—Ü™š,¼üwÛ{„Õ©\’ûò¤»&KÎ>ûË7qÅ”µÜÔf{LÌöÜ[&ÑoúwNþ×øKÕQÁº;¦ª*j1âC9’1?=Æõï(ŒÒÚ.²Ì³$™’KiØù è·ý;§kü%ŽßÓ& v«€©&ز± Èp‰F•ý“P2RL¶¥DdFJ-¤dF[H@È/à4Nj à2™o4·š`æ¸N-4’ÖIÏsJMÄ™l#ZoÆB÷c¬àù—½±®ªµœRÆ:Þt6©x‡‚«ÇÍQe¨»O8¯‘q]jA¥Iî- "àå3Å`7±& UJ ÂTç9:¶qdʫɨ4ëKeO±Ú(©W 3r%¬H"J„àm®ÇX7Àÿó/{aØëøþeïlkÊö,ÄX«W1®rth±!Æ6µmå[4ºƒªÊ…žf[=Y(µ!M½dìxj}N¯3ÖØ§bæ7µ¬?+Ô|Q&®ìU=Ri©ºÞiÂA¤µW^[®äIY$Øs±Ö ð?üËÞØÁKÂXM‰ kxóe¶ÝÖéw?ÚÊ%6="˜Í:+³]e¬ÙW.c²;¨ÔyœuJZ¶™Úæv+Xˆˆk,a§q]m"5z­A–¬«>›%lºË„†yœèÛcAŒ¸¬¢Jв˜cq7 Q0ÔÊ›uºÊH•Ìw.e(’FvVÒ#;Ûeík—æ©‘ iž»)e†“(Bxˆ·3_ï?×ݪ «àí T#â,SVÄ•©:‡&I™9×ÚmDâlÛ)pÏ* ç±)g´ìYR9Õ?ñ爿ôßûV‚’ZÔv¿SÆ Wte]Vè} m´«\´Ù$Ëgk%D\fcŠyu-|SCÿiÀhJˆØcF2pùâÇNzŒ–VùÔ©©Q‰´_2õ„æ\¥c¹ÞÅcäÇX7Àÿó/{cHImxC©@§0…¿€ܶÒW(s—N$¡â.â<¨W#™üµ˜ÌiZ¹Š#齫”ê3ÑÊ9áÛ‰¥@K…©B”¤Ãj;ˆ›wÄ)&jU’I$£b•8_±Ö ð?üËÞØv:Á¾ÿ™{Û*ÍJµÔthÝFyL­NLºtÒyzÖ)®š—++—ºTÒëh2>¾9«5ÌN­).<ºå>ŸTF&Ô5N&”—]¦ëò%(¦sid¶,¢{9ÙG™KI¤˜_±Ö ð?üËÞØv:Á¾ÿ™{ÛSÝyš¾"W¬Î˜õr³¶äÔ^[ 0ÝIô!´2jÕ–Ri$J˘Šé#$ðFÁ §c¬àù—½°ìuƒ|ÿ2÷¶%`NÇX7Àÿó/{cÏPÑþb2MjHÏüåÝ»þð™gà÷Ù?ú‰û­Œ'àù·}b¤8}š~%¥Ã¡4ɳ…gN'–ûŽ|ŠBH‰Gb·ïcÛkZÛ|Qц Å8¶™W éaÈjp‘V‰¤òPãIIÙl$••·ēٗn{fI“žÌi¸‡‰â´§TÛ8 [i7]S«2,ÄF¥¬ÍJ=›T£3>331XYÇBM¢ßôîý¯ð–#"M¢ßôîý¯ð–/*»ª£ƒtwMTTÔcĆs$&,b~{ëÞQ¥´]e™fI3$–Ó±ò «À¸ š‚¸ ¦[Í-æ˜9®‹B $µ’sÜÒ“qf[Ö›ñÇ銓»UÀTŠ“FìYX…ä8D£J‹þɨ)&[R¢2#%Ò2#-¤"ZÎ)co:T¼aCÁUãˆæ¨²Ô ݧœWȸ®µ Ò¤÷…‘pr™°6/c¬àù—½°ìuƒ|ÿ2÷¶5.{bT Ðq|%HÞs“«gLª¼šƒN´¶Tñ;¢Š•pÐã7"Q*Ä‚$¨eëØ³b¬!\ƸMÉѢćxÚÕ·•n<Òê«*y™lõd¢BÔ…6õ’w±°6c¬àù—½°ìuƒ|ÿ2÷¶5>§W™ƒëlS±sÚÖê>(“Wv*ž©4Ô‚Ýo4ƒá ÒZ«¯-×r$¬’{î‰MH¦3NŠì×Yk6U˘ì§Nê5gR–­¦v¹ŠÄV"" ¼%„ئ·6[mÝn—sý¡ƒÆ4Ü1DÃS*laÔ:ë)"BW1ܹ”¢IÙ[HŒïm—µ®\c%¥Œ4î+£M¤F¯U¨2Õ•q§Ód­—Yp“°Ï"“lh3±—”IQkˆ6¯ƒ´5Pˆ±M[V¤ê™&dç_iµ‰³l¥Ã<¨+Ÿ Ä¥žÓ±eJh³JõHDLõØpÙK,4˜ÉBÄE¹šÿyþ¾è׃euOüyâ/ý7þÕ¡­EÕ+|'ìzd B{‹>“ö=2 §¨×ã}U¿é iaºz~7×õ[þ’O"œ%º:þýŸø„HKtuüÿû?ñ G4Ëç4ïxWÐ#nq‰$ïxWÐ#nqÔ·½^>rιã[1B…f(Pù½BÔòP¡mBâ…µ -C¬-¨P¡Z… ·×…(1YŠ dÝZ˜¤Tb‘q0Èá‡c}¯DÆÇ¤Ök…-Tš´úy¯Ýi k7Ó”Êã\a‡c}¯DÄädj|kCÕ¾5 òß=ß+wóîrµ¹¹s^÷ýw•\­ªªUeV* ¨––rW®.绽ÿhÇ€óa,å½ÀÄ•s™Vv$”IQ.Q“Ž©™$n(•²äWÙ´®[8ËÍU­Ôg2PUR©¹Lifq¢I˜§RÊ’]ÄÜ‹eÉ%ôÆb¢:m6csiÓ$C”Ýò<æÚÓr2;(ŒŒ®Feôô9\­9T'+Řñ¿)•IY¡÷ ÈÍkMì¥\ˆî{nEÈ1à'!>·ZŸPj¡:¯P•1’$µ!é+[ˆ"32$¨Îåc3=œ¦?%Öë3*,ÔeÕçÈšÁ¥MHvJÔëf“¹Tgr±í+Ä £X³Uz¬Õz¨ÝEôjÝ–™nÎ'gK¾c. v÷ yݪÕ¥3Iv¥1Ês Ö5O¨Ùm[xIEò‘ð•´‹º|£ÆˆéõšÅA–ŸVŸ-¨ÛCÒ´µþÉð¨*•š½U-&©U8š+6Rd-Ì…ú³Øx@1!X®V«:­ø¬T*:›ê·T•»’ö¾\Æv½Šöä!èë«o–ùuÉXÝÚFéÝÎkuwÍ“6kå¾Û^×Ú0àìj«Tf”õ%ª”ÆéϯXìD¾¢eÅlá)ÊgÁNÓ.ár =/&›N†ÔH•D= ¦šßw¹2tãšO…˜‰V%’oܶÁ šb@€’hÉÖYÇ4ÕÈÄvó-&ã$͵]J2"+™m3åÙCGž:áß:1í è·e xë‡|èǶ”4yã®ó£ØùÒ>‹vPÑ玸wÎŒ{aÙCGž:áß:1í è·e xë‡|èǶ ÌnÜŠ´‡iØ×FíÄ5Y¢‘XÌæR+]YLŠçkظ¯kŸñ@ÀëºýpëT‡é’±æËÙs)º½”VQ(­s2ã.A¡z¢ê*ºd®Ï¦N:#»ŸVügRãk´vˆì¤™‘ØÈËé#ø#;K©ßàúŒ`Īâš9 $+TíE”-$M6©5Ý'tžÃ!Å $}ì¡£Ïpïöò†þ™ê[BLÛQÔ£""¹–Ó1(}ì¡£Ïpïöò†tøèml@B“w•%*Y ”H3̢̤‘šH혯kñ‰Ô¨q ¹ŒšˆÖ¡§(Q$$fdÉ»" ŠonÞ ¬Ó·nÁí!¹u*^,vHÞøÔ×W5„Ó#¥•:Í’mš LÜRÙ;Ú宨eb´nà†PcaúmG|°¬)•Mt™EP¥­ã÷å ÚPÂÛmH½“•\.áGãh¦RçcŧÀ™ª\yqÉøj4´êžŒWo\’pZ周–œ¹‰E`Ü5ð z®åaèï= l°LžâˆˆévÊR³©("Nn®D[BA>kt7i´¨”zlÈïBŒûæüD8ì•<ÚV¢' ³¢Æ£Ad4ûž[‹dC€lš“ñbâ½$ôR\f/r²pZ$0mÎe–ÍI,¶JÎä[ü¬ÃÅX¦Qfâhô]Ý£Bi-SÛCFNËSëh‹V¥–T¢æ›YE²äF+` …†Ê,ìC‚ªÏÓiÈv}\àÌcr7¨}²[%ŸTe®O);ˆ+ÑÃ-’ðÞ,K±Xpš§²ê[ RÚp¥°‚4¬Ë2.•¬ŒˆÊä{ob´îÐнaTÌ5…E¢ë¤ÓVr$;LeföI/¶’24Û1% ºÈ‰gr¹žÁÄèPq A©-La§ 7"+1'©ë-¸M¯>ÝZMjIÿ+aT2ÔìWÙ¢ÔÛÌËèJRwQdRBspLŒìJ=—'ÚÁ„û÷ð醅êbøÙ§ÿ´ßñÚ;¿>ÓíüßI›ïÖ¿vî…nÓ¸/ŸY|ÚÌûs^ù¿X‘í`Â}ûøNôÁÚÁ„û÷ð鄟ã"1{µƒ ÷ïá;Ó ¤Zæ*Ä•ýâ:‘ÑQE¬Už› ,vœL˜ÉU&r›K‹RÍ.¡G˜É(Ê¢· ÷+¸éB~ÀuwúÐÿøÍ¶Ó(‰!;…k†ä­j”nžµ9_èÈdjIg;€a»X0Ÿ~þ½0v°a>ýü'za/Škb:E½ ‰2£ ¹Hv[1V”é¨}„­j6œ4­-Ô® œ+ð¶yð3Çà` Î$NTbʘð#<Û±Te¥FâÜQ-&–TFœ©4š‹„«˜F;X0Ÿ~þ½0v°a>ýü'za¿@‚í`Â}ûøNôÁÚÁ„û÷ðé†ý µƒ ÷ïá;ÓkïßÂw¦ôh.Ö 'ß¿„ïL¬O¿ Þ˜oР»X0Ÿ~þ½0v°a>ýü'za¿@_S&d‰×d©ÆÒ¢Ì”¥Ä™•ö‘´ì®Æ8Ü}?Ÿþh¿êÿ©˜1X³à ?cÓ!ÜYðŸ±éÝ=F¿ëú­ÿIK ÓÔkñ¾¿ªßô"yìá-Ñ×óÿìÿÄ"B[£¯çÿÙÿˆR9¦_9§{¾sŒI'{¾sŒ~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&6K™ìPdÐÛT}Ã%ä¼êN+JY­;dá§9XŒÈˆŒŠÊWÊUõ¶øv7ÚôLNFF§Æ´=ÑêÓ˜¤?JmÆÎ#î%Õ!l¡jJˉHQ‘©²Æi2¹l;öÍÅUÙpžˆô¶²>Y_qšCÏ•ïgJIkÚD|#;Œ 6!,Û˜®¼å14åÌBšLrŒKÜÍk‰’+z̖ܺٗ5­³ˆY¤b*µ.)ÅŠó c9¸–äEiô¡fDF¤‰VEl-©±ì.AŠÄ ¬lCVŽŠ¢JCNY‰«‘·–éfÍî–“RO5•t™Ò“ãIXf­QfŠý¹JL ¥çY±YKOÞ×/ ŽÇb¿[ˆZF ªRãœx®Ç[9ÍinLF¤% ;©$âTIVÂÚV=…È.ÀÅU¸RjüiÔ¬RÕ22MÒ%f±ëP«b#±wRŸ’V€bM0î%§C¢Ä&¡ViøÙ¸(ó±¨Î̼»9aÿ'6Û¨¸ì!`ÆfëUº”TAAÖ_S²›~2Rdn™J…lÍc±Zæ”™ñ±tz¬êL…½ä ÜFG¶Òãn&äyT…‘¥Er#±‘í" @ÈTkU9ó™›"Q“ÑȉRÒY";‘!("J æg°‹iÜddcX뎦«®Í8´ð¯Ç~2#•ÖVŸücÅ[;Ù²´ÿã(òÙÞÈdv~¹Ÿoïk™ùÖþñ0ë+Oþ1â-ì‡YZñylïd2;?\Ïη÷ˆ5Ìüëx‡u•§ÿñG–ÎöC¬­?øÇŠ<¶w²Ÿ®gç[ûÄæ~u¿¼CŒ:ÊÓÿŒx£Ëg{!ÖVŸücÅ[;Ù ŽÏ×3ó­ýâ s?:ßÞ!ÆeiÿÆoPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ1·iΑhÖ²Í K*¤6Òò¢¶§’•·!JJ\4çI²ÞÂ>áü¥_Qa‡c}¯DÆÕ…:–Þ©RÝzaTdN!¤¦:Mœ­!ÔÙKÎJ#=rbOÜÊàãêüKÃ2î£oäJ,|Hû“j,Çv UN$¤Íö¶ÐéëOV£5‘pIeÄwäÅÑ(0$QX«Õ$@ˆäµDmlC×åZR•¹ÃNDÙek\Îʱl=þÃÍi…^iú£”êz ›¹¡¶—”¨Í¡J5¦›+T“¹¨­˜ö^¼/\£QãºÛ³IUWœ¸ïÀ§ÖZ[iLF’áÅ#ÛÉ$¤Ô’Q¬“Æ[ÿ¨^ݸUf±JbUiµ?-‰sÄiÂV¥—SÃQ8œ¹Öòa+)$¶¬ÌOxóU¨t†¨Ój”ŠÛõ¢Ìµu´¼Êܾՙ’’¦–ƒM­°Œ”w±†‰Ù6¡N7T€©Ž-öue·Ríì¥fJu+Vm†eü’=‚Þ¨R“F¨Ñk ˜ÌyO1!Åi.­4N$ˆÐ¥$ŒŒWòŠÆEÆ2²ñ‰}ÚcÖÔ {ôél¾” ÜiŽ™HY(øJKëØià™ÕzÙ”œ:škUxçÛ)h%‡!%¹J‰Fn¶a“‰,¦[T¦’;^âKT¤ÐOL›ÛF«O%xl Š’Ñ5zã&òºËI/)m$ðvÛù"#WVnžˆôrŸ&BÎä™m¥£BHŒ‰´¡+QÌîj3¾Â±ÛÉ ¿„» ÆÅ¦åoZºÉTä7¹šÊÑÍÃi¬ý!šò–s4X®yT{NRŽÒ)¥ª«W¨»¼qÚÔF'ÝuÂI)VI©d’“s5º+÷24ü%Mx©Ë¬“q¤S^ŸaG3C‰m Y’Ë1 ôN$̳YIØF[Gšê´·(uê(†ÄÇ$–Äd)ÎR•Ú7¸DÛg±|#÷Wn ¡¦ºÑÈ:Œj\:<šl][yåk›u&µ‘­\'Ü]ˆÏˆ“ÿx¦r†*©F§"†uzEQù¬µ%¤!ø„Âе¥jA•–²RL›^Û‘ìâÚ1ÕZ\ú^åÝÌjw\dJc†•giwÊ­†v½aíS©màj•-צFDèòJc¤ÙÊÒM”¼ä¢3×(ö$ýÁ|®>«½_ä»×»Í‘º·N_ÛŸ&_äqZûxî&2;7©š»¹ðöÃ;—6ï§Iº5–Õît@FL¶Û›tÞ÷+dâ;ìØµLkM¤bÝ>¬E&›råÝK7SòYKDÚRj5fŽ’+\Ôn\¶êQk®àœ7Š0Þ÷=P§0ô5ÄžêÙiö$3 Jý"³B‰QÛ2<Š+f+m¹Nd`üAWcU1,>ýN¯F©¥!åDm˜®¸êß$%Ía­ç œJ !’ ˆòí´ c¬2XyÊë’å1¹M¿OÔqÛ+EH'MfJI’I222#!’Ãuê^"¦ï…&BÞdœSKKŒ­—q'e!m¸IZ]Ô¨ˆöÖÒ4o‰ª2<*LÎt îúÓ¢zr’ËZƒgsòË$Ëôެ—k‘¨“•I+ÃEønF¤NDȌŕ>qËy-Õ¥ÔŒÏTÛdj‘+ô‹VVÒ\I""""ØfaŸ¥–*:<—‰)íÔh…NÄ‘ Ërm5ö‘¹·á1\Q)æ’J52•š’›©£^UYDF&”ü{…fÓ*uÔ]ŠÅ))TäΆôGXJˆÍ*6ÞBWeXò™•c"¹ˆÛx3+Nï ¢§³[‡%2œ5ºÉÖ  òlÚ"B’›¡6RÉgkä±ö¦âzŽ&u3šŒÍN™If*ë¨q/™&OÛ4©(QºÒs!D¢áZÆDf¼/‰èØ•¹*¤¿ ×d‰ IˆôWš3+§3O%+"2ÚFecî\b0Ö?¦Vq.)¢.B áéjaÙRaHn;ˆK 8¥›«m-¤ÈÞ2$æ3RNТ1æÑv‡æÕj58LÆ•9¶3N!ŸWqHhÝ2Ìì»JîªÈJJ×UÍW+Y›ƒjó¤i%PQBÅÍ-e-¹ ÝQÝ\!š5Y2šr²k%ë/s"ËÝ ÈÁÒN ™KªT›ª¼Üj\Teð$2­Ê”šô%h%:Ý’vSd¢>"¹™vƘsJz-k®>ÓI{#ñŽn4£2K­ëPcfe±hºXÖºN¡â·´Œ±+M3”ü V¦Æj–óŽ¥íkI[ެքd÷†É-–k]\#¸šaš*{ÇÄ8¤¨±ÕN¥»MŠÝ1×'õ®2·^t'Wï ’[,ùn®€Ëâlc‡°ÜÆ!Õ¦<‰¶§RÓ¤4“"7VM%Z¶ÈÏj×d—(³\ÇxV‹Z*=J¤¶¥¯ZiŠóŒÇÖ›×:”læ>-b“~àñWèØ¢.7wa„Ѥªu5š|¶j/8Ñ2L¸êÛu³BŸßÜ% òæ²xea„Æ8'TÅÔªS´c¢ã ›¾D—\L˜WŒÜg5HJ .ݶ’iºÑ•Fg­i7QêÕ ]BªûR)Ž¡ª‚“O¶¡šÛCˆ7KfÛi4¸“Î¥xÊ÷I‘TÆ’pkÑj’ЍûLÒà9R§àHk4Tšßk;e®lˆ½Óy‹ir•ñ¸ƒU*_JT¶_„—ñv»p)kQ%¼ôÈñ­2MÊÎ4£à’¸&GÇr&•ðMS”¦? ’Ö¨ˆ×­I³ó7.©G•'À-Bó\¬G¶ÁéN•°:žÔ&£PT…#Xà £Ì7e#å°‚k3èåSd¢"±™íñöj¬ÜùãÔRµED($¾á É.¥¤)ÂÈfIUÒYLÈ•cØ/N¡HH´\F…G()ฃ3ÖßzÐi+[)wö‘íMˆîv„Ô°&1n‘:twXEZ±2T&«ré„òeÍrDunˆè7HÛBÌ»Tk>ŒÂU;I:$zKʪ?#~yú{q H’ì„4hK¹[i ^d›‰ºL³ gV½'áF(têÉT‘¦¥"bÂ~Cï)7ÎDËhS—NSÍÁàØóXFtc£ú晇ŸªL… é±k­>¦ä<ꔩÕd´d§nµY ¨”kQ«1–ÕÜÔ?aà¼QD~X£eJúáœYr\e‡#T'œ¤™8–Ö¤¸‚CDeËjÊüJ˜Ñ–*:æ¤âyRÝŸ5±²ìxÊZ×™ÒÉ!¶Ó™fM6‚"$š•nêm¬)¤ÚcF´Ìm=©Ô–&µñÞƒ Ü7Ým &™I´K’W]’¶’¤®Æiâ;d4WA«a¼šeqè/TPŸ1åÂÌLÿ”Lyò$’ˆŒ¬N‘[¸desã8Åbè:=£M}ðl† n·U{MD\[º­Q)•©¸vJ\$©);«iO°Õz•ˆé›ãH’o°N)¥’Ú[N6âNÊBÛYТ>4¨ˆËkÝcµâ îJ•[©µ»ñ ºtZ|ü>ôv’Û7#l8¦›=j‘Xḧ2 ³KjQ vè•JSU™õµC*•j¤sä3 j[ ¥¦RÚ¤¤×d2ƒ5SuŽÄ0´¬U‹Öæ²D#Þ¼]V­¿•já1+|uiOjËv5˜ŽÄYWc;Ã#…t•ƒ1D¨1èµGß:‹&ô§Èe©I$æ2mÇJ¢+™¥&jMŽäV;aê:H¥Ô1¾¡aÚ«®nÚÔˆòïij)† ËZµO-‡ /6ÕÔÒŽÆDFv3#¿‡°MR…´[KuøFöÔîõ!jÊæJdˆŠÕpnwq䟓Á#>;âpæÆ&à:\¥aó àé ÕHm÷N\ÆŠˆÍ Û$¶²'S˜³¨•µW+L&Ø«aü3> >­&QM¨6ó±#E€ü§_KF‚s*B”fjÖ½ŒÏˆŒÊ×_xW®^·wÉ{»tn\Û•íϯ˛S¯ÉªÖÛý^|ߨ]ŸC“#HÔ\F•±¹`RjœBŒõ†ãîÃZ %kXŠ;„gr=©±ÎÑ.²qFéÞm­®¹7ÿvk\Ý·Ý›·QªÉ“߸:Íg¸Ù–û@H*HÁ°+…F•Ty2ŽsTâR`È[)Õ¥c\”zË­7Nk¤®fDDfYNºh[Ѿۻü‹|·¯Yª_ùÖëÜz»ZþÿÀÍl½ÛåÚ4æ*]F £È3ðüĽ"V ‚}Íó&—Pns·c&RmYëóšr§&RWš^ Ç;›­Ø‡‡N„X­ºîërKÅ)MQ3ÜgTMå%DKÎddDF”ÜÔA2V:ÂÉÄoE{»^QsGŽ9>iÌL›ù5Dí¿ÕçÍú‡«bªEvc‘Ñ:QCŠMÆuõ¼ñ¡niKiRF–×b¶Ó""ÚdG¯ÑmB6/qìN¤¹^:Ñ:þ$©7©YÉÝ&À…nuš\¾U¤¶$Ô…lÞ™ ¬u \¨'­M"bÔ†WjdóRT¤’7I‰*±™ŽÖ•‘¤|ÅaÚ£ÅlåSØIA|ß9IBÖl$b\³kà©$w"+\ÈŽ©ºEÂ0¦Ç‡2¡&;Ï6˪ÖS¤%1‰ïz) 6íJ¿¹xШ`éX&ºuz]v¨í1»]¨1Å©¦t·`¡¶”¤­EvTjRQsÎv-„vqŽ Å±u*”íè¸Ã&ï‘%×&ã7ÍRƒK·m¤šn´eQ™ð€KªÇAÄmaçæ;‘5i"—„ð~)fUØø‚Dˆëj ·óifƵd…4Ù©dYRá–m›âC¤º¤ú>‰.œþ¡ç+t˜ªVDªí?QŽË©²ˆË„Û‹MøÊ÷+ˆ~‘ðF4©SñÝ# «®0Ž­kõÝmÈŽœDF2JPÚ‰Ä) Èó$УQÙ|B[¥L,¼gƒ•‡‰hCoT <ù©Õ´fË3yÒJ‘ÂJÍ ¨’en–Òã ­¬cDŸSƒ™XedåUtå™ÃuÄIyÞuM4éY¤ê”¥.ëIjÔÙ‘-EhÎ…qMwn øºµ¸"T_è‹Ê“»5îpH½Ö©¾¹,»®w¿EÁx‚ á*kÒioSpµ]OÄ}m<ô3*:¶Ò‚A:•>‚3I’T”š¬“àÝમÜ{ã"ºŒ#E¢+s­J»ð÷VµE™%À=z2ŸÙW"ÙpÆb½&©Ü3¥(ôXµ:}_ Á›¹¥»MRµµ ·‰Â[Y‰nØ›3Q­(' #ê;ÂÕ¹R#A¨¸—#Ç9jÝQŒ•°Gcyµ:„“–Î IÚ[vâ\‰gÀÒm!Rw/†ú¢IvS‰u‰+§³ ›[dÑ–¯ô9ÍÂY¨¯l‡Æ2˜÷;Škj”Üj{Øf­D}I3×%S*ÐV±’R×¹–ÓMˆîv ðô“ƒeÓ*•&ê·—u*~†Lâ¥&£}´­o7dŸ ²QÂ.2dé[©íBj5HR5Œ0š<ÃvR>[&³>ŽU6J"+žÑ N‹+ò0î$…)˜-T'a™ÔHrÞÄÕ:‰)R’Í’MÓ³RjJIÅl++e•²'P¤?¤Z.#B£”H‰ð\A™ë o½ h4•­”Š;„{Hö¦Äw;NW¦×¨ñêô™I• BLÛp’i½ŒÈÈÈÈ&FFFFDddddFCÜ#ø‰+Ф@˜ã qÚ½JjM“3I7&sò-¤\"C©#î‘ØÌ¶œ€XŸþh¿êÿ©˜éüÿóEÿWýH|ÀŠÅŸIû™žâÏ€$ýL„éê5øß_ÕoúHXnž£_õýVÿ¤ȇg nŽ¿Ÿÿgþ!Ý?þÏüB‘Í2ùÍ;ÞôÛœbI;ÞôÛœcõ-ïWœ³®xÖÌP¡YŠ>oPµ<”([P¸¡mC Pë j(V¡B†-õáAŠ Vbƒ7V…&)¤g\L28_áØßkÑ19l/ðìoµè˜œŒOhyÒ ï£N¨u`¬%‚ÎT³h“ã© j$%7$êNÅd–ËŸtI{m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€séÎÛI$~õ.€;m$x‘ûÔºÌ`§;m$x‘ûÔºí´‘âGïRè1€œí´‘âGïRè¶ÒG‰½K Æ:s¶ÒG‰½K ÛI$~õ.€sé§:¬^q…à{¤øË}K¡Ê‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'‘ÎÝ?þÏüB$%º:þýŸø…#šeóšw¼+è·8Ä’w¼+è·8Çê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ19ŸÐó¤ê-¯[”¨”jTꔄ ÜSQ#­å’ÈFI#;\ȯúÈ„—±ö=ñ#ù©ÿd;cß1/šŸö@F€I{cß1/šŸöC±ö=ñ#ù©ÿdh—±ö=ñ#ù©ÿd;cß1/šŸö@F€I{cß1/šŸöC±ö=ñ#ù©ÿdh—±ö=ñ#ù©ÿd;cß1/šŸö@F€I{cß1/šŸöC±ö=ñ#ù©ÿdh—±ö=ñ#ù©ÿdZ—ñ¬H®Ë—ƒñ xì¡N:ë´×’†ÐEsRŒÓb""¹™€€ÅbÏ€$ýL„OqgÀ~ǦBtõüo¯ê·ý$ ,7OQ¯Æúþ«Ò@‰äC³„·G_Ïÿ³ÿ‰ nŽ¿Ÿÿgþ!Hæ™|æï úmÎ1$ï úmÎ1ú–÷«ÇÎY×±A£Òëqh˜» Ϯȧ`Z<4&'%R¹i;d#Õ¬Í'•Ó±&Êá&ûsõ*KÉr‘×ý¥ˆ”Œ7;*åjjIϺtêœ]ÙÊñå"È®wCfàÚûØ‹QqG"ï=‰ši¯U­m+ËšÅ{fµìW·[U†]¬I¤"c‡64v¤¼× ‚Ûªq(UøŽæË…b;–]¶¹_DI¤N^Á´ªŽC«c Ahœ‡¥TÍ ¼«e-¡ÆÓÄÙ&n,Òg˜Šå“dƒF”v˜Æ4Zæ"Ã.ïíC Òˆª.ÒT§šÛr Q:öCÔ¸hSH<æ“Q'mˆ ů{çœûÆ÷¾yϼcFh¶[…‹¨ïUHج0ooÃÌá© ªa©µ‘ë§-õ4ò5™Vœ©3¹$‰(+‘N1Žƒˆ´‘‡N±GEJ—‘RÖ%öu‘õªvD¬Œ²™™†IWC2. È'z÷¾yϼa¯{çœûÆ4cT Ùirg‘µRëƒt31¬5!çÕ ]t·»Éòe jl…!I+p¬…*Ê9N>6šåcÔ‰•R–ãuc†âš8ŠRÍ””‹d$FÚ5W¾r¾_å[+^÷Ï9÷Œ5ï|óŸxÆ™Ñí!ÈÕÌ0láúœC]×UEèŽ6‰—eiUÞQe‘™ómhÊjÊ”Ÿ¹âhØ:#Dx,ÂÏ)µ7ÌQ¸j\©M¦*Ë#­‘k&ÞZ Û2;%*"M¶Z…_z§T¯BÈã[ÑPD<úÓV·4fÍk_Ëm¾æ÷ÛbŒiîDŽÆu4kÝʶœJÓœì¢Õ,ì|»HúˆYÐÄa'*$ê=6E{]<¨Ë`Í­Ç9…Q™*"M‹-²Ø&Eû§Ï‹j‡þŸÁp=©qŠ€‹>“ö=2!=ÅŸIû™ ÓÔkñ¾¿ªßô4°Ý=F¿ëú­ÿI'‘ÎÝ?þÏüB$%º:þýŸø…#šeóšw¼+è·8Ä’w¼+è·8Çê[Þ¯9g\ñ­˜¡B³(|Þ¡jy(P¶¡qBÚ†¡ÖÔ(P­B… [냬Å2n­ LR*1Hθ˜dp¿Ã±¾×¢br Ø_áØßkÑ19ŸÐó¤/©ÛQpN-ªÕ«o)¶¤;’KjQ­Õ:Ñ’x$v+%Gsäîˆõ êÎÏØO“ø½v~Â|ŸÅè‡)€®ØN]BÖ›03U‰5t1i²cµçs½Âm¥8¤&Ú»çäW<Ûob·¯³öäþ/D9Lluggì'Éü^ˆ;?a>OâôC”À6Á—Vv~Â|ŸÅ胳öäþ/D9Lluggì'Éü^ˆ;?a>OâôC”À6Á—Vv~Â|ŸÅ胳öäþ/D9Lluggì'Éü^ˆFô“¥ì1‰°„ÚTwuO-§5|2µ$‹j‹j¸î9Üíƒ @1X³à ?cÓ!ÜYðŸ±éÝ=F¿ëú­ÿIK ÓÔkñ¾¿ªßô"yìá-Ñ×óÿìÿÄ"B[£¯çÿÙÿˆR9¦_9§{¾sŒI'{¾sŒ~¥½êñó–uÏÙŠ+1B‡Íê§’… j-¨ajamB… Ô(Pž¼(1AŠÌPc&êФÅ"£Œë‰†G ü;íz&'" …þö½‘‘©ñ­:@¬YðŸ±é î,øOØôÈ@€nž£_õýVÿ¤¥†éê5øß_ÕoúH<ˆvp–èëùÿöâ!-Ñ×óÿìÿÄ)Ó/œÓ½á_@¹Æ$“½á_@¹Æ?RÞõxùË:çlÅ ˜¡Cæõ SÉB…µ ŠÔ0µ°¶¡B…j(bß^ Åf(1“uhRb‘QŠFuÄÃ#…þö½‘ÂÿÆû^‰‰ÈÈÔøÖ€ ïiX+´ú›NÂæEn:K<ŸìŽ Dêç‹þ¯ú­I„w¬ìâ6óK>Èu‚´¨Å…å}ÕH֚ԙꓑ¢+¹²“¶óÞ6YØ#Äl-æ–}ë;x…¼Òϲ0u¼GU=NÅ̧{êÝl¹RBr·;û”Ü"Ê¢2<ªîчÆ3ñm ] €ÅV¹U‘UT—ß— Šso¶m¥«0É?‘¢AšÔ®±Ë$ö™\ÓâiÖvñ y¥Ÿd:ÎÁ#ao4³ìˆd æ)ª±…èóê§@—PEAR¦2˜®¼µFu-¶Ùmu”¸´¨ÜQlºµ¤­c·¦µR¬J®*”Æ4jÄ5-ÞÜv™ËZœJ–zÂQH&’£$XÿL\"Ùwx•u‚’°Ó‘Þq•R;f¤(Òf•8”©7.á¤ÌŒ»¤fBsÝ(xhTEÕ‘)ÚŒlHëm§$K5ä%¹˜Ð›!*U̳â±NæCÎä#×ÕM•Q¹Ú”l;6=Þk)/)º‹XÖ›pŠÜd$4 Í^£JÓtú¬èh:´$šX¶ÈÉlÊÎV#þVD_—*oÄCÉ¢Çߤ¬4äwœegTŽÙ© 4™¥N%*M˸i3#.éf{ÆšsîÑeU’¦ÉˆÒYŽ´™žcS©uI2+ZÖeWÛÝ.=¶óÆmIi§n:²Jp”ilŒö¨ò‘ªÅǰŒùÄ» Vk´ÝÖGªÔ¡¨ªðr”Y lømJ%[)—º47~\©ä!œ™Hšú'%äÊKŠ'Éâ2p—~kíÍ{Þûn&'¾Eêå9ú=ju&J›[ð¤¹Å6fi5!F“23";\¹xÆÒ®Vêsô‘Œ(re-t»UÌ¡ßô$¦š}Ä,‘ÄK΄«7öí¬0äÊ6§/®:Å=GVó Ré©|ݲͳKŠ7͵3QXïbͶ±WwxÙ„eDÄà¡F•5cs¢¥LJMÈe­|Ö\É=ZÉ;M&V6Ò[nDq="î¾»¥*râ¸úšaFäv¤¸FÊ +4Ô­Dd¥Ê5 г">2 Òœs=[D¨æÛŠã-jMÄ-h_¹Êi=ZËÝ^å´¬dbK ¡\¤Q0â°³Ò™\Âstnb;¿$žZI¥ÛÝ‘6MC¹pÌí´Å𛻆1[²£ÆŒúñE:Ìkj›Q¢uÒ‹–R=…c=–Úa¸Dlý×SìÖÞwºÕ×eÜ–ÿ&Þû{þ_s}_YÇ}·¸Â·ˆkTÍQSO©ÊŠ´Õg¡·ZtÒãh&â«"[R“RÔ£IXŒö˜Ò!@6\r†¬qQ!N³,ðüYÌ.4D>áIr1b³WÁ5¨'²ˆU(Š2Q±.ºÙ™qU$ÈpèÓ.Û™/GÓ(íQ¥Â¥È¦5m\7iÙØE¸¬ƒFR·ÐYz>ªµª¤*\æá™dɧk ƒ+[!)—ˆ¸¹m2î”bL*‰ŽLD†S%ÖÐÓe’Ö„ 5e¹‘Öd]ÌÊå1#GqêʫǧÒY©-ÓyRÑMÊòœ4©&³Y#6l«Q^÷²Œ»¦8˜i—wõ݇¼!ø.{#´¥þÔ²þdÄ`ÈÏ¿KRc<ã²²q·Q¥HQÉDe´ŒmŰ„ƒ¯Œkㆠó“ÞÐÂÄ•*¦ìI/GqHSf¦–i3JˆÉI¹w ŒÈ˺F,€ŒD ð&L)àJ~$„{‡Ypдý[Hz·ö·¾é¬oÍG|’FI™ºW®+‘‘ÙwÍÄf\|F1À' Ír´ÎïÔÖ* ï÷vY+-Õ{ßY·‡|Ê÷W÷GÊ<ôéÓi³›N™"¦ï‘æ6Ö›‘‘ÙDder3/ Çœ(Þ#Ä-Æ™ºõQ MZÜ–Úe¸I¥•–¥•ì£Ql3;ߺàÇ>ó²[ﺷ]qF¥­j5)F|ff|f(ÀöÓkjcO5MªN„ÛågSB›' ‘D“+ÿXüj«Tj”õ%ª”ÆéϯXìD¾¢eÅlá)ÊgÁNÓ.ár¿~«;Õ½;í?{û×t/SÇq{~ÁCµZ£Ô¦i.Ô¦9NazÆ¢)õ-«o (¾R>¶‘wO”xÀ0=óëuš„öªêóåÌd‰-H~JÖâŒÌˆ”gr±™žÎSÔëj¤†äÔª“¦¾ÙYH§Ÿ Ôfd<@îªÖjõmVúÕgOÕ›Ý2æBä,ÆvyRåKÕn©/?©hškXá«" ‰)¿K¸E°Y8\+ˆªø^¬š­RcLBr¥Å2‡HŠä~åde{‘í²ÂkÙßJÞ5~ïÑj2X¢½UÄÕÙÊä­×P“—\ö­(Í•$„ðRDEÁIÂî hÅbÏ€$ýL„OqgÀ~ǦBzõÆj^›—³êΓ)GÈ‚IW‘ò 7ÏP²ÐÞœVãŠJš,ÓR”v""Am1C·w¶—ós9ôûÖjºÍ!âœ<˸”ê}:BµæqkyR‰W2",¤M"Åkß6Ó¹köŠ4iYÒ”\{-øG!¢Îü2u‰/‘–GVWã-·.%S>#Í9Ñ[Í?¦lvë¡ÖÕI£YHQwt…a-„´.Î,¢.®Ìº$ë2;qܧJyIK2]dŒÖSFfMßbKŒ{Ï©ž)ñÕhh™ùñ³´ñx­ª¿þ£$athReâsåRqŒ‡[«4U'k¦ªq!ä6„îc•Ä”¥-‘j6(ˆËaf}»é9ŒN¦¼ó«ÍY¢™ö!]¬±<+@óLÏÏÎÖH~ y¦gçÆv¯¥,Im-]¦Îb­$㶸Øj¨óQ¸ s;o$²Í,­¨¬Ù Îä­‰%gØÆX¶e>$(±êk륜š…*TVe0Ý‘¯m‡M.—¸$å323JÈ•´”\çÒÚùç~¿º|Ó¶ž{7©¶• ó&×0ÜhÌ6§^yÚdÄ!´$®¥)G>ÄDDff|Bïk Ð<Ó7óâU¥j¶,€±ü(ïP÷-ì:¹Ĺ-ÕÂK®-¯Ò2’KÉÊ•k ÌŒEÆ3Òñ%EŠÕb—H…IP•‰Ú¥±%ÆÿìÆd©çÉ*#qd„©cMÉ-¦åkŠO¤u“Îí_tù›c£[v°@ðÍ3>?©~Ÿá*š¦þ|n-Ö+u7±*þ÷ªEWp¡È(Zê74w‰FJRŒ”fñì¾Í…¶×9Hç:ÝLó¹Wó)Ä9ϵzá*š¦þ|~v®S¼%@óTßÏŽIÔÞžuÏó&!Î]«”ßÐ<Õ7óãóµn™áš¦þ|tp Íë“ýÓü˜s´^¦(1_KìTèq7±ïLÓµÊÝÙãÝÚð¿ Ð<Í/óÃ}€¤ÕTó‘¡;^ẙ¥þx;^ẙ¥þxo°™KBv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° ÈЯ ðÝÌÒÿ<¯ ðÝÌÒÿ<7ØdhN×…ønæiž×…ønæižì24'kÂü7@ó4¿ÏkÂü7@ó4¿Ï ö™µá~ yš_烵á~ yš_ç†ûÌ Úð¿ Ð<Í/óÁÚð¿ Ð<Í/óÃ}€fF„íx_†èf—ùàíx_†èf—ùá¾À3#Bv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° ÈЯ ðÝÌÒÿ<¯ ðÝÌÒÿ<7ØdhN×…ønæiž×…ønæižì24'kÂü7@ó4¿ÏkÂü7@ó4¿Ï ö™µá~ yš_烵á~ yš_ç†ûÌ Úð¿ Ð<Í/óÁÚð¿ Ð<Í/óÃ}€fF„íx_†èf—ùàíx_†èf—ùá¾À3#Bv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° ÈЯ ðÝÌÒÿ<¯ ðÝÌÒÿ<7ØdhN×…ønæiž×…ønæižì24'kÂü7@ó4¿ÏkÂü7@ó4¿Ï ö™µá~ yš_烵á~ yš_ç†ûÌ Úð¿ Ð<Í/óÁÚð¿ Ð<Í/óÃ}€fF„íx_†èf—ùàíx_†èf—ùá¾À3#Bv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° ÈЯ ðÝÌÒÿ<¯ ðÝÌÒÿ<7ØdhN×…ønæiž×…ønæižì24'kÂü7@ó4¿ÏkÂü7@ó4¿Ï ö™µá~ yš_烵á~ yš_ç†ûÌ Úð¿ Ð<Í/óÁÚð¿ Ð<Í/óÃ}€fF„íx_†èf—ùàíx_†èf—ùá¾À3#Bv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° ÈЯ ðÝÌÒÿ<¯ ðÝÌÒÿ<7ØdhN×…ønæiž×…ønæižì24'kÂü7@ó4¿ÏkÂü7@ó4¿Ï ö™µá~ yš_烵á~ yš_ç†ûÌ Úð¿ Ð<Í/óÁÚð¿ Ð<Í/óÃ}€fF„íx_†èf—ùàíx_†èf—ùá¾À3#Bv¼/Ãt3Küðv¼/Ãt3Küðß`‘¡;^ẙ¥þx;^ẙ¥þxo° Èçù}N•QäVh mVÌç–W±ß¹8cûV)^ y®oçÇHfG7ö¬R¼!@ó\ßχjÅ+Â5Íüøé ÈæþÕŠW„(k›ùðíX¥xB湿Ÿ ™ßÚ±Jð…Ís>«¯P<×7óã¤3#›ûV)^ y®oçõb•á šæþ|t€dsjÅ+Â5Íüøv¬R¼!@ó\ßÏŽÌŽa‹Ôï†kxŸĤ·J§A¢ÖUMe£Ì’ë„–s:–™m•ÿKk{ƒ1CÐu?Î’ìžqטÔHjF‘QF¬Ô•‘)·%¸’<ÈI‘ØfÃã/ ÈT:¶•% ˆÔÆ&âoÅtÁŠü‡®§6DJœZlµ¶n”vRJÒŸUˆŠåÝR”EsµÎö½Œxuººìb(§3,í~¶­>"Šs2ƒÓtfU­PßÑc¦ƒ²ÓØâ:TŽLÉ7ˆËúÈlÍ`Y˜}oP ÂÝŸô{ F¦gËŸßv¹¬¶n[«6ÈeQðÞ0£A§¸§e0ë'¿FRuiK» ö$W".#I Í„¿œýþcѧ½7bsÎ;¥ßM~nÓ9Žøî–©ÐgÅâ>¶ªÿúŒ‘-¥S¡R¢®4u-.CÒTœÆ«¸óªuÅ\ÌøÖµ¸Šö+ˆI°E*™R‘› ”®*Q6ÂRJZË:Öv-ªR”¥ñ™™™í1™ÜPûÑŽl‡l=-AGxFôc› ÜPûÑŽl„àjLQ€°®&zKµšs¯œ¶I‰HncÌ¢BŒ‹X†Ö”¬ÓsÊj#4챕ˆ~âŒ+ u"¨ˆtèÏL-©Ë×Êy’SèCm’ÉÖÏ;*Õ´”’‘Äe{ÎûkqCïF9² ŽæÈ04þŒ0³Ø^—QL”°Üš•Asži‰>†Ôm¶ÙµÞ‡•¤š–¢#5ŽÂX&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒi¸¡÷£Ùâ‡ÞŒsd°MŽæÈ7>ôc› À…€šn(}èÇ6A¸¡÷£Ù,ÓqCïF9² ŽæÈ0!`&›Šz1Ín(}èÇ6A 4ÜPûÑŽlƒqCïF9² X ¦â‡ÞŒsdŠz1Í`BÀM7>ôc› ÜPûÑŽlƒL`6Ðî'Ò[N¤–…âÇ’¤Ÿ‘‰r‘›ÆxRz•Bg}a«‰êÌ»™ÉjIf/”G¶ÝÎ!´0¥2šˆ³¤"Ÿ/J©KvC„ÊIN¬žR J;]G•Mϸ’."!˜ÜPûÑŽl‡;–i¹‰žpãvÅ7q3Î9KDá<#UzºŠæ"$´m8nµ9-ktïÃpÊéÙs2"3Ûc¹ZǸ0—óŸ±ÿÌe·>ôc›!q–Yfú¦›nüyREq6mSj1JmZ¦Õ;iÿÙxymon-4.3.30/docs/known-issues.html0000664000076400007640000001600113033575046017472 0ustar rpmbuildrpmbuild Known issues in Xymon

Known issues in Xymon

This describes some known problems you may encounter when using Xymon to monitor servers.

How to report bugs

If you think you have found a bug in Xymon, please report it to the Xymon mailing list at xymon@xymon.com. You can do a lot to help getting bugs fixed by providing detailed information about the bug:

  • Always include the version number of Xymon you're using
  • If one of the Xymon tools crashes and leaves a core-file (usually in the ~xymon/server/tmp/ directory), please use the gdb tool to pinpoint where the crash occurred:
    • Login as the Xymon user
    • $ cd ~/server
      $ gdb bin/PROGRAMFILE tmp/COREFILE
      then at the gdb> prompt, execute the command
      gdb> bt

Internet Explorer complains about Javascript errors in Enable/Disable

This happens for some, but works for most people. One workaround is to disable the Javascript validation code in the enable/disable function: Edit ~xymon/cgi-bin/enadis.sh script and add the option "--no-jsvalidation" to the hobbisvc.cgi command - this disables Javascript validation on the "info" page - and edit the file ~xymon/server/web/maint_form so you remove the text 'onClick="validateDisable(this.form)"' from the input-tag near the end of that file.

DNS error reported for network tests

The xymonnet network tester uses the built-in ARES library for DNS lookups. There have been reports that this library fails on some systems; one confirmed case is on "OSF1 V5.1". So if you suddenly get a lot of failed network tests that report "DNS error", try running xymonnet with the "--no-ares" option to use the standard DNS lookups instead.

Network tests fail sporadically, or report long response times

The xymonnet network tester runs many tests in parallel; by default it will typically run up to 256 tests concurrently. This may be more than your network test server or network infrastructure can handle; if you see sporadic timeouts of network tests or the graphs show increased responsetimes, you can lower the number of concurrent tests by adding the "--concurrency=N" option to xymonnet in the ~/server/etc/tasks.cfg file. This has been especially important for sites doing many http checks, since these typically have much more traffic going on while testing than simple TCP services such as smtp.

Network tests fail on Solaris with "Failed to find enough entropy"

OpenSSL uses random data to initialise a key that is negotiated when a new SSL-encrypted connection is being setup. Solaris 8 and earlier doesn't have a standard way of getting random data, so OpenSSL cannot get all of the randomness it needs. Solaris patch 112438 solves this by adding a /dev/random device that provides random data to applications.
Thanks to Scott Kelley for the pointer to the Solaris patch.

Asif Iqbal notes: Patch 112438 only works for Solaris 8. For Solaris 6 and 7 you need to either install SUNWski pkg or ANDIrand pkg. See http://www.cosy.sbg.ac.at/~andi/SUNrand/. I have been using ANDIrand since that did not require a reboot and easily available.

Xymon fails on FreeBSD with "Could not get sem: No space left on device"

Xymon uses some kernel resources - semaphores and shared memory. If you get the following error message in xymonlaunch.log when trying to start Xymon:


2005-05-29 20:25:14 Setting up xymond channels
2005-05-29 20:25:14 Could not get sem: No space left on device
2005-05-29 20:25:14 Cannot setup status channel
2005-05-29 20:25:14 Task xymond terminated, status 1

then you need to increase the number of semaphore sets and individual semaphores available to applications.

The current settings for your kernel can be found with "sysctl kern.ipc.semmni" (semaphore sets) and "sysctl kern.ipc.semmns" (total number of semaphores). Xymon uses 6 semaphore sets, with a total of 18 semaphores.

To increase this, put these two lines in /boot/loader.conf on your system:


kern.ipc.semmni="40"
kern.ipc.semmns="100"

Adjust the values to something reasonable for your system - considering the current settings (from the sysctl output), and Xymon's needs (6 sets with 18 semaphores).

More information about tuning the FreeBSD kernel parameters is available in the FreeBSD Handbook

Xymon on Solaris compiles but aborts with some "ld.so" error

This info was contributed by sladewig, with a few modifications:

The system loader/linker can't find your lib.

Assuming you have the .so lib in /usr/local/lib, You can add -R to the Makefile

    PCRELIBS = -L/usr/local/lib -R/usr/local/lib -lpcre

The -R "hard code" the path to the library into the executable so env variable (LD_LIBRARY_PATH, ed.) will not be needed. The -L told it where to find it while compiling.

Or use crle to add /usr/local/lib to system wide runtime linking environment. See man crle. Be VERY CAREFUL with this or you will end up booting from cdrom to repair. Be sure to include the existing library paths!

Command line:

    crle -c /var/ld/ld.config -l /usr/lib:/usr/lib/secure:/usr/local/lib

I usally use the latter as nowadays gcc uses a .so for all its generated programs and then dragging around the LD_LIBRARY_PATH isn't needed.

Note: This information only applies if you are using the Solaris linker. The GNU linker uses the "-rpath" option which is defined differently: Add

    RPATH = -Wl,--rpath=

at the bottom of the top-level Makefile.

xymon-4.3.30/docs/xymon-tips.html.DIST0000664000076400007640000004165512603243142017722 0ustar rpmbuildrpmbuild Xymon Tips and Tricks

Xymon Tips and Tricks

Here you will find out how to do some common questions raised with Xymon.


What do the little red/yellow/green icons mean ?

ColorRecently changedLast change > 24 hours
Green: Status is OKGreen - recently changedGreen
Yellow: WarningYellow - recently changedYellow
Red: CriticalRed - recently changedRed
Clear: No dataClear - recently changedClear
Purple: No reportPurple - recently changedPurple
Blue: DisabledBlue - recently changedBlue

My client-side tests don't show up on the webpages

Did you install a client ? The Xymon client package is installed automatically only on the Xymon server - on other systems, you must build the client package by running Xymon's configure-script with the "--client" option and build the client package on the hosts you want to monitor.

If you did install a client, then the two most probable causes for this are:

  • The client is using another hostname than what is in the hosts.cfg file.
    Xymon only cares about the hosts that are in the hosts.cfg file, and discards status-reports from unknown hosts. If you check the "xymond" column on the webserver display for the Xymon server, you will see a report about these unknown hosts.
    Either reconfigure the client to use the same hostname as is in the hosts.cfg file, or add a CLIENT:clienthostname tag in the hosts.cfg file so Xymon knows what host matches the client hostname. The Xymon client can be started with a "--hostname=MYHOSTNAME" option to explicitly define the hostname that the client uses when reporting data to Xymon.
  • A firewall is blocking the client access to the Xymon server.
    Clients must be able to connect to the Xymon server on TCP port 1984 to send their status reports. If this port is blocked by a firewall, client status reports will not show up.
    If possible, open up the firewall to allow this access. Alternatively, you may setup a proxy using the xymonproxy tool (part of Xymon) to forward status messages from a protected network to the Xymon server.
    Other methods are also possible, e.g. bbfetch (available from the www.deadcat.net archive.

My silly clients are using a hostname different from the one in hosts.cfg

Add a CLIENT:clienthostname tag to the host entry in the hosts.cfg file, or re-configure the client to use the proper hostname.


Where are the bbrm and bbmv commands from Big Brother ?

They have been integrated into the Xymon network daemon. See the next three questions.


I accidentally added an 'ftp' check. Now I cannot get it off the webpage!

Use the command

    ~/server/bin/xymon 127.0.0.1 "drop HOSTNAME ftp"

to permanenly remove all traces of a test. Note that you need the quotes around the "drop HOSTNAME ftp".


So how do I get rid of an entire host in Xymon?

First, remove the host from the ~/server/etc/hosts.cfg file. Then use the command

    ~/server/bin/xymon 127.0.0.1 "drop HOSTNAME"

to permanenly remove all traces of a host. Note that you need the quotes around the "drop HOSTNAME".


How do I rename a host in the Xymon display?

First, change the ~/server/etc/hosts.cfg file so it has the new name. Then to move your historical data over to the new name, run

    ~/server/bin/xymon 127.0.0.1 "rename OLDHOSTNAME NEWHOSTNAME"

Getting the Apache performance graphs

Charles Jones provided this recipe on the Xymon mailing list:


From: Charles Jones
Date: Sun, 06 Feb 2005 21:28:19 -0700
Subject: Re: [hobbit] Apache tag

Okay, first you must make the indicated addition to your apache
httpd.conf (or you can make a xymon.conf in apaches conf.d directory).
[ed: See the hosts.cfg man-page for the "apache" description]

Then, you must restart apache for the change to take effect
(/etc/init.d/httpd restart).

Then, manually test the server-stats url to make sure it's working, by
using your browser and going to
http://your.server.com/server-status?auto  (you can also go to
http://your.server.com/server-status/ to get some nice extended apache
performance info).  You should get back something like this:

Total Accesses: 131577
Total kBytes: 796036
CPULoad: 1.0401
Uptime: 21595
ReqPerSec: 6.09294
BytesPerSec: 37746.7
BytesPerReq: 6195.16
BusyWorkers: 43
IdleWorkers: 13

Scoreboard: RR__RWR___RR_R_RR_RRRRRRRRR_RRRRRRR__RRR_RRRRCRRRRR_RRRR........................................................................................................................................................................................................

Now, assuming you are getting back the server-status info, time to make
sure your hosts.cfg is correctly configured to collect and graph the
data.  Heres what I have in mine:

1.2.3.4    my.server.com  # conn ssh http://1.2.3.4 apache=http://1.2.3.4/server-status?auto TRENDS:*,apache:apache|apache1|apache2|apache3

 From what you said of your setup, I'm guessing your only problem is
 using the wrong url for the apache tag (you used
 "apache=http://192.168.1.25/xymon/" which just won't work - that's the
 kind of URL you would use for the http tag).

 Hope this helped.

 -Charles

How can I add MRTG graphs to the Xymon webpages?

There is a special document for this, describing how you can configure MRTG to save data in a format that Xymon can handle natively.


I need the web-pages to update more frequently

The ~/server/etc/tasks.cfg defines the update interval for all of the Xymon programs. The default is for network tests to run every 5 minutes, and webpage updates to happen once a minute.

Note that if you run the xymonnet-again.sh tool on your network test server (this is the default for a new Xymon server), then network tests that fail will run every minute for up to 30 minutes after the initial failure, so usually there is little need to change the update interval for your network tests.


I want my temperature graphs in Fahrenheit

Edit the file server/etc/graphs.cfg, and change the [temperature] definition from the default one to the one below that shows Fahrenheit graphs.


How do I remove the HTML links from the alert messages?

Configure your alerts in server/etc/alerts.cfg to use FORMAT=PLAIN instead of TEXT.


I cannot see the man-pages on the web

A common Apache configuration mistakenly believes any filename containing ".cgi" is a CGI-script, so it refuses to present the man-pages for the CGI scripts. Stephen Beaudry found the solution:

   This occurs because by default, apache associates the cgi-script
   handler with any filename containing ".cgi".  I fixed this on my server
   by changing the following line in my httpd.conf

   AddHandler cgi-script .cgi     ->to->    AddHandler cgi-script .cgi$

My alert emails come without a subject

Xymon by default uses the system mail command to send out messages. The mail-command in Solaris and HP-UX does not understand the "-s SUBJECT" syntax that Xymon uses. So you get mails with no subject. The solution is to change the MAIL setting in etc/xymonserver.cfg to use the mailx command instead. Xymon needs to be restarted after this change.


Does Xymon support receiving SNMP traps?

Not directly, but there is other Open Source software available that can handle SNMP traps. A very elegant method of feeding traps into Xymon has been described in this article by Andy Farrior.


How can I create a custom test script?

Anything that can be automated via a script or a custom program can be added into Xymon. A lot of extension scripts are available for Big Brother at the www.deadcat.net archive, and these will typically work without modifications if you run them in Xymon. Sometimes a few minor tweaks are needed - the Xymon mailing list can help you if you don't know how to go about that.

But if you have something unique you need to test, writing an extension script is pretty simple. You need to figure out some things:

  • What name will you use for the column?
  • How will you test it?
  • What criteria should decide if the test goes red, yellow or green?
  • What extra data from the test will you include in the status message ?

A simple client-side extension script looks like this:


   #!/bin/sh

   COLUMN=mytest	# Name of the column
   COLOR=green		# By default, everything is OK
   MSG="Bad stuff status"

   # Do whatever you need to test for something
   # As an example, go red if /tmp/badstuff exists.
   if test -f /tmp/badstuff
   then
      COLOR=red
      MSG="${MSG}
 
      `cat /tmp/badstuff`
      "
   else
      MSG="${MSG}

      All is OK
      "
   fi

   # Tell Xymon about it
   $XYMON $XYMSRV "status $MACHINE.$COLUMN $COLOR `date`

   ${MSG}
   "

   exit 0

You will notice that some environment variables are pre-defined: XYMON, XYMSRV, MACHINE are all provided by Xymon when you run your script via xymonlaunch. Also note how the MSG variable is used to build the status message - it starts out with just the "Bad stuff status", then you add data to the message when we decided what the status is.

To run this, save your script in the ~xymon/client/ext/ directory (i.e. in the ext/ directory off where you installed the Xymon client), then add a new section to the ~xymon/client/etc/clientlaunch.cfg file like this:


   [myscript]
	ENVFILE $XYMONCLIENTHOME/etc/xymonclient.cfg
	CMD $XYMONCLIENTHOME/ext/myscript.sh
	LOGFILE $XYMONCLIENTHOME/logs/myscript.log
	INTERVAL 5m


Server-side scripts look almost the same, but they will typically use the xymongrep utility to pick out hosts in the hosts.cfg file that have a special tag defined, and then send one status message for each of those hosts. Like this:


   #!/bin/sh

   HOSTTAG=foo          # What we put in hosts.cfg to trigger this test
   COLUMN=$HOSTTAG	# Name of the column, often same as tag in hosts.cfg

   $XYMONHOME/bin/xymongrep $HOSTTAG | while read L
   do
      set $L	# To get one line of output from xymongrep

      HOSTIP="$1"
      MACHINEDOTS="$2"
      MACHINE=`echo $2 | $SED -e's/\./,/g'`

      COLOR=green
      MSG="$HOSTTAG status for host $MACHINEDOTS"

      #... do the test, perhaps modify COLOR and MSG

      $XYMON $XYMSRV "status $MACHINE.$COLUMN $COLOR `date`

      ${MSG}
      "
    done

    exit 0

Note that for server side tests, you need to loop over the list of hosts found in the hosts.cfg file, and send one status message for each host. Other than that, it is just like the client-side tests.


How can I make the menus work on my iPad ?

The menu system uses the CSS "hover" tag, but this is not supported on tablets and other touch-screen interfaces like the iPad. Mark Hinkle provides this solution to the problem:

In the ~xymon/server/etc/xymonmenu.cfg file, I added the '<a href="javascript:;">' anchor around the top-level menu items. Like:
  <span class="menutag"><a href="javascript:;">Views</a><span class="invis">:</span></span>


How can I send data to Xymon without installing the client?

If you cannot install any "foreign" tools on your system, then sending data to Xymon may be a challenge. But if you have access to either Perl, BASH or telnet on the system then it is possible.

Perl version:

#!/usr/bin/perl
#
sub sendToXymon {
	use IO::Socket;
	my($server,$port,$msg) = @_ ;
	my $response;
	my $sock = new IO::Socket::INET (
			PeerAddr => $server,
			PeerPort => $port,
			Proto => 'tcp',
		);
	die "Could not create socket: $!\n" unless $sock;
	print $sock $msg;
	shutdown($sock, 1);
	while ($response=<$sock>)
	{
		print "$response";
	}
	close($sock);
}

$host = $ARGV[0];
if ($#ARGV != 2) {
  $port = 1984;
  $msg = $ARGV[1];
}
else {
  $port = $ARGV[1];
  $msg = $ARGV[2];
}

sendToXymon($host, $port, $msg);

BASH version:

#!/bin/bash
#
HOST="$1" ; shift
if test $# -gt 1; then
  PORT="$1"
  shift
else
  PORT="1984"
fi
MSG="$1"

exec 3<>/dev/tcp/$HOST/$PORT || exit 1
echo "$MSG" >&3

exit 0
NOTE: The BASH support for using TCP sockets may be disabled at compile-time - some believe it is a security risk to have such an easy way of doing network I/O without requiring any special tools.

Bourne / Korn shell (requires telnet):

#!/bin/sh
#
HOST="$1" ; shift
if test $# -gt 1; then
  PORT="$1"
  shift
else
  PORT="1984"
fi
MSG="$1"

( echo "$MSG"; sleep 1 ) | telnet $HOST $PORT 2>&1 >/dev/null | grep -v "closed by foreign host"

Both of these take 2 or 3 parameters: The Xymon host (hostname or IP-address), optionally the portnumber (1984 by default if not specified), and the message that will be sent to Xymon. The Perl version will both send data to Xymon and print out any response that is sent back - the shell-versions can only be used to send data to Xymon.

Oyvind Bjorge provided the core of the Perl script, and Jeremy Laidman provided the core of the shell-scripts in this thread on the Xymon mailing list.


xymon-4.3.30/docs/Makefile0000664000076400007640000000151712271166170015602 0ustar rpmbuildrpmbuildall: cat xymon-tips.html.DIST | sed -e 's!@XYMONHOSTURL@!$(XYMONHOSTURL)!g' >xymon-tips.html clean: rm -f xymon-tips.html *~ install: mkdir -p $(INSTALLROOT)$(INSTALLWWWDIR)/help/manpages cd manpages; tar cf - . | (cd $(INSTALLROOT)$(INSTALLWWWDIR)/help/manpages; tar xf -) cp -f *html *txt *png *jpg $(INSTALLROOT)$(INSTALLWWWDIR)/help/; rm -f $(INSTALLROOT)$(INSTALLWWWDIR)/help/man-index.html cp -f man-index.html $(INSTALLROOT)$(INSTALLWWWDIR)/help/manpages/index.html ifndef PKGBUILD chown -R $(XYMONUSER) $(INSTALLROOT)$(INSTALLWWWDIR)/help chgrp -R `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLWWWDIR)/help # These may fail if no files installed (find $(INSTALLROOT)$(INSTALLWWWDIR)/help/ -type d | xargs chmod 755 ) || /bin/true (find $(INSTALLROOT)$(INSTALLWWWDIR)/help/ -type f | xargs chmod 644 ) || /bin/true endif xymon-4.3.30/docs/xymon-clients.png0000664000076400007640000010354011535414771017465 0ustar rpmbuildrpmbuild‰PNG  IHDR'S=ùçƒ pHYs  ÒÝ~ü€IDATxÚíÝ{@TÕÞ?~AðÆUQ#T‘£25A9BB– ¤ÈÉ[FXJÒ Í5¯uJL£¼2/xÉPB/Š`àQ‘;¨ß?ÞÏù=ëùígæÌ0 2ø~ýÑ™³fÍžµ×Þƒë³×M«¾¾¾¾¾¾Q¢SWWWWWÇŠ """"¢ŽD›U@DDDDDC"""""ê€êQÄP‡ˆˆˆˆˆ: †:ÔFNžï%éòÜsÏ=÷Üs£G=z4JþÌü5ëPD©©©©©©¯¼òÊ+¯¼Ò»wïÞ½{ãõñãÇ?®)gñꫯ¾úê«ÏÚuT¤äêû«Ûñ~ DDÊR:Ô™3gΜ9sÐBØsæÌ™3gÎèëëëëë/[¶lÙ²eíçôîÝ»wïÞ=ͽ<÷$ ÜÝÝÝÝÝçÍ›7oÞJ‡:.\¸páÂŒ3f̘ѭ[·nݺáYþéÝ·oß¾}ûÄü÷ïß¿ÿ>zÐ#áëëëëëûàÁƒˆ9ÑÆ3K333333<LOOOOOoYNés¬;wîܹsgòäÉ“'OÆóoŸÊÊÊÊÊJégׯ_¿~ýú_|ñÅ_Ä7âÛŸÖ322222úè£>úè£ÜÜÜÜÜÜ–ÕöÝ»wïÞ½ëíííííÝ¿ÿþýûÇÅÅÅÅÅI¿QZ‡žžžžžžƒ 4hÐ?ÿùÏþóŸÒœŠ—Ÿ]½zõêÕ«ÝÜÜÜÜÜÔ]“ï½÷Þ{ï½·cÇŽ;vHßýé§Ÿ~úé'ä‘UŠß‡m ¿ÊÀÀÀÀÀÀ[·nݺu«e÷¿âW)Û¶mÛ¶m›µµµµµ5òã¯AZZZZZÚСC‡*딞 Ü'ëÖ­[·n]~~~~~þßÿþ÷¿ÿýïHG'Ý Lñû'&&&&&féÒ¥K—.mÿw)êaùòåË—/Ǧ®]»víÚuìØ±cÇŽˆˆˆˆˆøê«¯¾úê+i9ùå—_~ùåùçŸþùç'L˜0aÂ\ý–Ýê\#ñž‘¾Väo¬¬»N‘Ï*~'·Ò²©þ‘õ-ŠÜ'DDšKéPgüøñãÇÇ?½h&bUçÎ;wî,R…H|‰0é‹/¾øâ‹/ÄœhV®ZµjÕªUeeeeeeŸ|òÉ'Ÿ|‚'š-Ë)…~'4ï®_¿~ýúȗՅÆbVVVVVÖ÷ßÿý÷ß‹Íß¶‡ñîÛ·oß¾};zZVÛȉ殞+R wÂÅ‹/^¼ˆ¾&iNÅËh|§¤¤¤¤¤¨»&'Mš4iÒ¤Ó§OŸ>}]¤WUUUUUafš¼²Ž Ê}¨> øm~øá‡~øaËîů2 oáܹsçÎ[³fÍš5k0d)h¨Éú¡<î”êµ×^{íµ×Ð +)))))ÁÈÿú¯ÿú¯ÿú/eï±iˆ{²ýߥ¸?äHßEÃ÷ªô]ôXâªùûûûûûþùçŸþyËîaU®‘ØG!í¯Påo¬"ŸUöNnŸZë7Ò²û„ˆHsi)ÛQŽüh WáüùóçÏŸÇp ØØØØØXä[TTTTT$}©î²ž8â™.ž¼¢A‰>ek{È!C† Aõ€†¯½½½½½½xvÒóÅ,—ŒŒŒŒŒ cccccã›7oÞ¼yÓÎÎÎÎÎNÌ©xyð-‰c¶Íà³Ï>ûì³ÏP‡³fÍš5kL………………+V¬X±b…¬zPü>lûû¢£££££çÎ;wî\eïů2Ê€áIèhnnnnnÆk4Ëð]²j}Œ‡>|ø0†âμzõêÕ«WÑÃ3{rèQƒsY÷Òñ÷j×®]»víB/S—.]ºtéÒþïRÔ!‚â“x”™ûõëׯ_¿‡>|øpøðáÇúŠßíu¤wŽ"cUù¬âwrÛÿB¥ÿ¶ªû7"ýEî""Í¥t¯þ8®]»víÚµ˜,‹lÞ}÷Ýwß}÷ý÷ßÿý÷Åüø°ñÙ^½zõêÕKÚEŽ0 ƒFðl Í2é0-ÅsJá½ØðÂkéñ|ŸÖåAiQ6 ©Â0ƒ-[¶lÙ²E r”­mäÔÓÓÓÓÓC ™P¤TååååååJ‡<ç–æT¼<ЖAàù=ÁHAHPPPPPüϪrªã>ÔmBBBBBÂÆ7nÜØ²û_ñ« ˜×„×ÄãË/?ž"ûí·ß~û- ¨[¼‹PD\–á“â÷–gëGSîR”G:”pÕdý²´´´´´ÄküÒ¥ÍzÅïáÖºF­û7V‘Ï*{'«û*¥ÈÔWÿŠÜ'DDšKGÙ ÷ÃðgO1VxåÊ•+W®óã/žŒêêêêêêÊ:2šJIIIIIIx.õ¯ýë_ÿú—ŸŸŸŸŸŸø„IñœR(Æ1wïÞ½{÷îÕÕÕÕÕÕ&&&&&&íó"iiiiiia¬ùíÛ·oß¾Á Òy&Š×6vx†ghhhhhˆŸ"åA]¡y„f²j[‘ò<-X?÷ð¯¿þú믿¢iŽŸüϪrªêË?H›,ŠßÿŠ_eñ.mY™ããããããѯ‚¢>ч‰çÖøkƒ•ñćŠ@£ð»ï¾ûî»ï0œ ³5Úÿ]ŠëxäÈ‘#G޼ýöÛo¿ý¶ø.Ò1CúYÌQÁ“~ôÝáuËîau_#õQöNnŸÔWÿŠÜ'DDšKé^LhÞ´iÓ¦M›ðÔͦ 6lذAº¾FHcp †[üøã?þøã¸qãÆ'ætuuuuuÅÓh Õ5TLñœRcÆŒ3fÌ¡C‡:„òà8íÿ‚a$:ê ”–Õöĉ'Nœ¸wïÞ½{÷âŸLôÔ)R]´äVñò<]3gΜ9sfXXXXX˜âóT¹Õ³¹0 ïå—_~ùå—[vÿ+~•U‡'îüñÇüÐ K`þÚÔ×××××c–â-ûí ¿Ë«´ÿ»444444ð0§×¯¶a¡ég1e×îçŸþù知»Z)~«~p|Å©´–¶¼“ÕG}¿Eî""Í¥t¨ƒÑÿèÇ?“x.Ž1Á›7oÞ¼y³˜Ýî‘‘‘‘‘‘SŽç©Äœlƒ~! 0@Ó¶–å”B£9ûöíÛ·o_üƒ!k rû„5—PæÚÚÚÚÚZeky8pàÀÌIÀE¾«W%'''''ãS¨Iq8œ²åyºÐÂ@¼VäSªÜ‡­KÜWÃ¥M:Åïů²êP‡èÆ^FþùçŸþyD€óÂ0N ãQö[0¬5€9Zíÿ.Åoó믿þú믗,Y²dÉÜ¥¸:¨qn¤ç‚5Ç0CI\wNÙ{Xõk„Ѓ¯Ú²ÛòNVõýF¹Oˆˆ4—Gå’*ššššššvîܹsçNôIûšˆW™ÚR{è]ä¬,ôÉ`e?œê^ô™÷ = tX¤,|¸4B[ˆ>Q/!I!È7nܸqã;<<4777777  ¬±&¿HûYªd"""""zV0Ô!""""¢ˆ¡u@ uˆˆˆˆˆ¨]055555m­£1Ô!""""¢§¬W¯^½zõÂk333333ÕÉP‡ˆˆˆˆˆž1È©ð0Ô!""""¢§ÀÄÄÄÄÄD~žÞ½{÷îÝ»eÇ×aQÛ«¬¬¬¬¬wé”îÛ©ÊžìÕ!""""¢ˆ¡u@ uˆˆˆˆˆ¨â\"""""R»‡>|ø°-¿Q¡PGKKKKK‹—‡ˆˆˆˆˆ”Õ¿ÿþýûgfffffªãȲÞý¡Ž*+=-ÀFDDDDDjTRRRRR2f̘1cÆ´î‘SSSSSS‡>|øpé» uˆˆˆˆˆHí:wîܹsçæææææfY;çÈßWG|ýèÑ£GÉÿF…V`Ó’Ÿˆ±œœœœœœºtéÒ¥KGGGGGG¤‹9Ïž={öìÙ‘#GŽ9²k×®]»vµ²²²²²Ú¹sçÎ;-,,,,,ä—G–Ž}»hÊ™>;W¤eõÀú!"""R…BEâ*ñuzzzzzzddddddlllllluuuuuõ¶mÛ¶mÛ¶lÙ²eË–:uêÔ©SÈïãããããóÕW_}õÕWÈyéÒ¥K—.!@BЬRÉ;6M9SÎø’_¬""""uP˾:ÑÑÑÑÑщ‰‰‰‰‰ÎÎÎÎÎÎZÐÃóË/¿üòË/+W®\¹r¥ø©‹/^¼xñþýû÷ïß×ÓÓÓÓÓ{ë­·Þzë-é²tŠ4 Å<={öìÙ³§¬ž¼‹œòû…d½ÛØØØØØ¸hÑ¢E‹Y[[[[[8pàÀ ,X°`ACCCCCƒxeó×ÔÔÔÔÔ¢ìÂ… .\ž»ºË£ŠcÇŽ;v¬oß¾}ûöÅ]‘ æA ÞE=ã~puuuuuEŸ"×E‘ô7nܸÑÔÔÔÔÔTVy”¥ìõ’z6{)‰ˆˆˆZ—Ò¡Ž"ͯüüüüü|4¥ïš›››››çååååå!CÚ222222Ð(DGÈÍÍÍÍÍUå$ïÝ»wïÞ½'2à]äD šÔ(x¤¸¹¹¹¹¹‰¡ÔâÅ‹/^loooooåÊ•+W®\½zõêÕ«H £l~¤ ‰_YYYYY™’’’’’rèСC‡IÏWÝåQErrrrrrAAAAAÁž={öìÙãïïïïï/æ ôòòòòòÂhÎòòòòòò%K–,Y²äÁƒ<óãZôîÝ»wïÞb`ŒtÜK?Ät¼.++++++-----•Ue){½¤¾ûî»ï¾ûõ€3bÏ‘ÒV¬X±bÅŠúúúúúú©S§N:éÒ@ñt4òžÈ5hРAƒÉz÷Î;wîÜùüóÏ?ÿüs1´EVÙÀÈÈÈÈÈHV à]1ÿáÇ>tèСC‡Ê:‚™™™™™Yxxxxxø™3gΜ9£Jy0(NVÕã]1ÿ¸qãÆWWWWWWwB€€ÐÃÃÃÃÃCÌ/MúíÒô–å—æ”5´LÝåQ…ŽŽŽŽÎX÷oÒ¤I“&M°:„[èÙð &L˜0Aú)‡ýû÷ïß¿)*9xðàÁƒ·åãe¯—ƒ6ÏŸ?þüyüÔù8†ˆˆˆ¨eÔêDDDDDDx{{{{{ggggggãY~NNNNN!@ƒü'Nœ8qâÚµk×®]‹Fá¾}ûöíÛ‡•ÙÚ¾j¢¢¢¢¢¢"H‘æ زeË–-[Ät,É€wUÉïççççç·fÍš5kÖˆºbbbbbbÚ¾<¢—­UóèÁƒù0·gÈ!C† ‡¢‰0ÜîÀ@ ¢|›Ö*›"ç«ìõ½÷Þ{ï½÷f½ýöÛo¿ý¶tÀ)B‰Å¦íîîîîîŽÀ 88888ÓÊ1÷`ùòåË—/}}}}}ý™3gΜ9sÆ 6lÀüŠÍ›7oÞ¼ù‡~øá‡”-›ê0 JD4zôèÑ£GKs®^½zõêÕ˜ßòœ °°°°°朗f¼‹¡\J7}úôéÓ§KÏ]Ýå¡fPK­uÿ ÇïôéÓ§OŸÆ`H¼‹Y4˜Q#ýôê`®^ÿùçŸþù§4ÔQ¶<Êž¯²×Kú](?º_1€Ë)K ãØBCCCCCñü>>>>>>¾u‡-ѳ Ó 0I¤u·ÍÌÌÌÌÌĨ1¤§¥¥¥¥¥av·ö³SÅDDDDDôì`¨CDDDDDC"""""ê€êQÄP‡ˆˆˆˆˆ: †:DDDDDÔ1ÔÑZʦwéÒ¥K—.ØÝ¥´´´´´´=Ÿï¥K—.]º4mÚ´iÓ¦uëÖ­[·n(BBBBB‚4ÿï¿ÿþûï¿c×&,5(žµ¬OQǦÃ*hÿ°‚8šïÒ•ÅIÇúå;)~§µîݨŽ;\„ß5~ãÒßÔ·ß~ûí·ßŠù±kÖ´iÓ¦M›Ö­[·nݺ)ò÷A}åIIIIII‘æG ÞåoˆˆÚ›Œ@Ü¡¯SSSSSS?üðÃ?üPVƒ[mJ?+Ý‚[v~õÕW_}õUuuuuu5Ohš E~yð:.....nÆŒ3fÌhݾ‚7nܸqÁ‚ ,ŸS•=j4K=zôè¡îúT–âõ¯Jù¥÷^kålû£IùûûûûûcC^q‹Ø|(ÿ³8pàÀÞ½{÷îÝÛZϼÿý÷ßÿÝÆÆÆÆÆÆÜÜÜÜÜ\šçÎ;wîÜqqqqqqAÉŒŒŒŒŒfÏž={öìššššš1¿‰‰‰‰‰‰¡¡¡¡¡¡˜®¯¯¯¯¯ß«W¯^½z‰éâ“éÇ>|=]øF4àÄüجMOkkkkkë8¡ECCCCCƒ¬ã£á8}úôéÓ§H7QEÉëêêêêê”íIS¤>Å£!(255555•ÕW lý+[~!(((((Ÿuttttt¼páÂ… déÑ£G=ªHÍH{-p®®®®®®èá”_«Z2´ìžojjjjjÂÆ¯Òz;sæÌ™3gÄôß~ûí·ß~1bĈ#¢£££££óâ‹/¾øâ‹ªÿ•-Ï£G=z$½îüNDDmƒ¡Ž333333CCD•ã (#####H4bÐÀÍÍÍÍÍÍ•õY|jíÚµk׮ݵk×®]»ÐÌj­s\³fÍš5k>úè£>úHVž… .\¸pÓ¦M›6mBCª¼¼¼¼¼Ü×××××wþüùóçÏóŸ;wîܹsîîîîîî7oÞ¼yóæµk×®]»6|øðáÇK›nâS|~¥¥¥¥¥¥‘‘‘‘‘‘è[ó/^¼xñâÅööööööW®\¹råÊÕ«W¯^½Š”°°°°°0YÇG™'L˜0a„bþªªªªª*ñ³"ÕëS"{#:qâĉ'0ÌéÈ‘#GŽ;vìØ±cÅ<Æ#¦cÞUý‡á|/_¾|ùòe4@U©Oe)[ÿÊ–ßÏÏÏÏÏéâ3  R½üè5ÊÎÎÎÎÎÆ „}ûöíÛ·/ëÒ9'¢÷Þ{ï½÷ÞÃŒ¦·ß~ûí·ßVdÀ›|¨C1ÆÜ¹sçÎ;kÖ¬Y³f‰ï¢O©     )û÷ïß¿?êJõúQ¶<×¥ Tూú‚y""¢ÿ°µÒ«†f"–Èú–~ÓÅœ˜žŽéùçŸþùç1E{ôèÑ£G–®¤$=¦ø.žcbwËνI?ÿüóÏ?ÿ¬H~ÌVÂÊr½{÷îÝ»7¬–öÅ_|ñÅb~ !ð+1)ò˜eeeeeeõéÓ§OŸ>˜×„ÀỈ_ ½HÁ»òëSVÝŠÄaEè•7nܸqãЫ¦J}Ê*ƒ¬teë_Ùò£_H\ªýÒYd-«U ÑÄ\#1t—õ+Süÿ£¼ôÒK/½ô7`F4NNNNNÎ+¯¼òÊ+¯ gR‘¿ê+tÀ›âµˆˆ¨£zZØþ{—•ÐÐÐÐÐP}úôéÓíg׬©¥Y¿‹ö\ŸDDDôìÀ£.<>ø±M%}-ÿ]¼F;'33333[§ =----- ³muž*¦öϤ±ˆvû)•t›TM xÚg}µ †:Dÿ{8‰ˆˆˆ4‡²QÄP‡ˆˆˆˆˆ: †:DDDDDÔ1Ô! €}WœœœœœœÙ³…XŸDDDD u4€–ö½Áö‹²>õß«‰KH·ø<{öìÙ³g±WvD±²²²²²Ú¹sçÎ;-,,,,,ä—G~ºê°@!69årÉê®Ou\Áö,%%%%%¿)é¯ ï*ò«Äž?ùùùùùùª”¿kiyàÛo¿ýöÛoÛ²}út<•ÿøã?þøc1?J^WWWWW§lOš"õ)Â~Ã}ûöíÛ·¯¬¾DÅÏW,çºuëÖ­[‡sÄæ_[·nݺu+® ø-Ê^_ea2éq Úò×ÝÔÔÔÔÔ4eÊ”)S¦H¯û™3gΜ9ÿDDDŠ`¨£ÁÌÌÌÌÌÌÐ0Rå8è#ÊÈÈÈÈÈptttttD£ÊÔÔÔÔÔ477777WÖgñ©µk×®]»v×®]»víÒÑÑÑÑiµýšÖ¬Y³fÍš>úè£>’•gáÂ… .Ü´iÓ¦M›Ð0-/////÷õõõõõ?þüùóÅüçÎ;w»»»»ûÍ›7oÞ¼yíÚµk×® >|øðáÒ¦¤ØËÀ¯´´´´´422222}kbþÅ‹/^¼ØÞÞÞÞÞþÊ•+W®\¹zõêÕ«W‘&ëø(ó„ &L˜€&¾‡‡‡‡‡‡˜¿ªªªªªJü¬t_aUêS”œœœœœ\PPPPP€~ih­øùJKøÃ?üðÞžžžžž999999è¿EÙ뫬-[¶lÙ²åwÞyçw¦M›6mÚ4\SôOÊ0†¡žÊ+U„®®®®®®xœ²²²²²²˜˜˜˜˜˜£G=z´-ËCDD¤Á0s£¾¾¾¾¾~êÔ©S§NEújgd]E®—²×ìÏ?ÿüóÏ?wsssss“uÌ#FŒ1""""""B:äFyyyyyyÞÞÞÞÞÞòsÊÊ…¾é§JJJJJJT¼þú믿þzqqqqq±ü:D¨ƒüjÐ/!æ466666F/˜Ž¡€xW‘ã·î5U¼>Åã#–ÿ½Êž¯ôòSZv}‡~3Ô˜Žø“O>ùä“O9ú÷¨¨R̤ÂqpŽèEDæåååååÕ–å!""RÆþ sïÞ½{÷îU î ******Êw·x`#‹ß…1)ˆqØ«£Á0v_lµô…‡‡‡‡‡Ë0ƒÛ 7r?~üøñ㪗aõêÕ«W¯V¤ÿaذaÆ “õÓ’5ýÖ½{÷îÝ»wîܹsçÎÊ–S:+Iüvi~YébÃ]w‹âõ)R¤N•óUDË®¯â~üñÇüQ:§ÅÁÁÁÁÁ½LЧÿþýû÷W½—C×0,çˆ?åè‘C€Ý–å!""Ò\ u4†aöúRT9ú%°†¢a~ž}ûöíÛ‡•Ùd}ÖÒÒÒÒүь–®ð¦¬[·nݺu«°°°°°³’äç?~üøñã1Óãúõëׯ_—¿(†«Íœ9sæÌ™Û·oß¾};>"{#:qâĉ'š›››››9räÈ‘±cÇŽ;VÌ€aQb:f1á]Õïq˜Î÷òåË—/_FƒX•úT–ºÏWÙë«,„—ÒKƒOWWWWW×èèèèèh”鸪?z xæÎ;wîÜY³fÍš5«-ËCDD¤Á8€­ý“^54_0ÐEÖ§°Ì€ô³˜˜.æÄôt„LÏ?ÿüóÏ?Qþ£G=z´te*é1ÅwñLÓÇ[v¾èMúùçŸþùgEòã¹5V–ëÝ»wïÞ½1oÃÒ¾øâ‹/¾øBÌ!U%¦#Eþ³¬¬¬¬¬¬>}úôéÓóš8‰9ñkÂ’Þ¤à]ùõ)«nEâ0'ôJ7nܸqèUS¥>e•AVºâç«È‘Å”–]_eIŒÉÿ•!œÀÜ, ø¯R¸Ž±^z饗^z ¾ûî»ï¾ûNš_Ýå!""RÝÓÀöß»¬„†††††âùk|||||<²2¤¶„AexJ}úôéÓ§O·Ÿ]t0Õ[³~í¹>‰ˆˆèÙGoxœ‡Ñ1b›JúZþ»xvÖqÅÖ)HOKKKKK;uêÔ©S§tž*¦ö³e°ˆvû)•t›TM xÚg}µ †:Dÿ{8‰ˆˆˆ4‡²QÄP‡ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡ŽÐ’À¾7Ø"PÖ§þ{5q éŸgÏž={ö,öîÀŽ%VVVVVV;wîܹs§………………üòÈOW¡¡¡¡¡¡úêS¤££££ó¿–ëÀNDXÊPñ« ˆ”””””Mz•ñ®"g­`óóóóóóù«!"""â l+€‰ËŸ8qâĉâ>ôظSüÔ§ùK$£ùŽ-D‡ 6lØ°ÆÆÆÆÆÆääääääêêêêêjùåAz\\\\\\jjjjjê¶mÛ¶mÛ¦ÊYãŒLMMMMM±áTHHHHH6R=ÀÖFiiiii)6¦ÓçÌ™3gάÚÞ³gÏž={"=#####+ÄKkIq¢°U«XÞºuëÖ­[ÎÎÎÎÎÎØ$K‘³ """"`¯ŽFzõÕW_}õUì—âïïïïï¯ú1/^¼xñâÅû÷ïß¿_OOOOOï­·Þzë­·fÈÿì8€ÝjccccccUïÕAà„>–!C† 2;Áûí·ß~û­*G–lß¾}ûöíb õõõõõõbè«©©©©©Q¥<ØKzœGÞóDDDDÊb¨£ÁÌÌÌÌÌÌššššššT9úaÐGáèèèèèˆcèQÉÍÍÍÍÍ•õY|jíÚµk׮ݵk×®]»¤ÀZ¦°°°°°ñ¾ùæ›o¾ùæÌ™3gΜéÝ»wïÞ½[·&ü ¸š9sæÌ™3Åw¯_¿~ýúuõ]Ç-[¶lÙ²åwÞyçw¦M›6mÚ´?üðÃ?œ1cÆŒ3d…vj¨ì°F"""¢gCê4pàÀnݺuëÖ­7nܸqãÆÕ«W¯^½úÁ|ðÁï¿ÿþûï¿/볡¡¡¡¡¡#FŒ1bľ}ûöíÛ×Z¥êܹsçÎÇŽ;vìØQ£F5jðàÁƒ¾råÊ•+WZ·0§oß¾}ûö}á…^xáñ]u÷«¤§§§§§ÿðÃ?üðÂů¾úꫯ¾Z³fÍš5kN:uêÔ)é§Ð×ôD€à°µzùˆˆˆˆ4C öàÁƒèêêêêê¶î‘Ñ_޾Y91h K çñãÇ?®z,X°`Á¤|ýõ×_ýµµµµµµuëž/fµìª„C?þøã?þˆAzÒ@_“"Çéß¿ÿþýUïå#"""êêh$ sqqqqqÁrª +wMœ8qâĉŠÖÐÐÐÐЀ^ÌH‘õYKKKKKK¼þè£>úè#é oªhݵפ0éÈ‘#GŽÁÜ$ižîÝ»wïÞu.¦c®JøøñãÇ·¬ úúúúúúµµµµµµbz]]]]]ÞÓ]]]]]]££££££ÅÁuº¦ŽÐ—ˆˆˆHq6 ]ÐÍY9Òµ×àÒ¥K—.]zñÅ_|ñEñ³¬…… ŽÆ4æ¨|üñÇüqDDDDD„»»»»»;VÉ/Pa –4À1UY—¬m`A…É“'Ož<¹G=zôæÙ±cÇŽ;0ˆ}&˜Å„¹1U 0V­ZµjÕ*,{ öɈWYÌž4\)\_±OõЗˆˆˆ¨c`¨£Z¶ °"ŸÅ¢Æxíççççç§Jy~ùå—_~ùESêöm¬<&±·:Ê ìñÑ“†Œ¿""""Y8€ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡u@ uˆˆˆˆˆ¨b¨CÔ!é³P""""E0ÔÑZØÑeìØ±cÇŽ------•Ÿ_GGGGGç7Þxã7¤ù!55555ÕÉÉÉÉÉ ÇwtttttDº˜‹MoذaÆ Xø¸oß¾}ûö4iÒ¤I“°»¯šâ°ý(® vCBͳ<­ûÛQG~"""jÏêhq¼®­­­­­]¸páÂ… §OŸ>}útùùëêêêêê° ¦4zzzzzzddddddlllll,¶þܶmÛ¶mÛ–-[¶lÙ²S§N:u ùׯ_¿~ýú+W®\¹r%77777÷úõëׯ_ AÙxÕwþüùóçÏŸ;wîܹs¶¶¶¶¶¶/^¼xñ"Ë#¥ìÝ¥ìžT-ÛʈˆˆÚ'†: ½4žžžžžžYYYYYYòóëêêêêꆇ‡‡‡‡KóGGGGGG'&&&&&:;;;;;£W=<ØtåÊ•+W®DþÍ›7oÞ¼yéÒ¥K—.555555Eº—————Â$UÎÙœ9sæÌ™chhhhhhaaaaa±}ûöíÛ·÷ëׯ_¿~b~ñI|eeeee%Â9ƒ?þøã?óc³ÎE‹-Z´ÈÚÚÚÚÚzàÀ\°`Á‚ dãÆ7nÄY£–T9_ô™Lž}úôéƒüwîܹs王‹‹‹‹‹žžžžžž‘‘‘‘‘ÑìÙ³gÏž]SSSSSÓ–õ£Êý#Ö§¬t"""j- u4æN$%%%%%!8‘ŸáÇîÝ»wïÞ=nܸqãÆ‰ïæççççç‹A‹ÈÜÜÜÜÜó‹Oâ}}}}}}'L˜0aÂ4‘=<<<<<Äü‹/^¼x±½½½½½=ú¦®^½zõêU¤„……………É:~YYYYYwíÙ³gÏž=þþþþþþ¼'wòäÉ“'Oº»»»»»cæ˜1cÆŒƒ»ÚÁÁÁÁÁáèÑ£GE~ô^nÚ´iÓ¦MÈS^^^^^Žk=þüùóç·eù[vÿà÷"Þ½HG0ßöÑ3aÅŠ+V¬¨¯¯¯¯¯Ÿ:uêÔ©S‘þ„Úñªikkkkk»¹¹¹¹¹¡±%??ØÙÙÙÙÙUTTTTTˆ9­¬¬¬¬¬äû Aƒ „×xÝÔÔÔÔÔ¤Ž3Å3û`, `Ë–-[¶lÓQ~¼Ë»EÝ<>|øðá˜u† 0`À1çøñãÇ¿uëÖ­[·b ¬÷´JÞ²ûÃÛ8pàÀ¤à)ð~ ""R†:@:•¹eùñO—Å™6˜5§éèùÁ<™ÀÀÀÀÀÀåË—/_¾|äÈ‘#GŽD~?~~~~~~lLLLLLL°°êÓô1+³tÌÌÌÌḬ̀˜5æ­^½zõêÕòÏWþToó+ž*rü–]E®š¬syZwºËƒ€ý“èá‘•óµ03 CÚ°¢ ú‚T/¿âù•½¿; 7Åë?ÿüóÏ?ÿd¨CDD¤>ZxB‰àxßñ†ñQ{ƒÑ·xÍ:!""êx06‹ca’‚kH_˯1å!33333⑞–––––†RtXõDÔö¤½% uˆˆˆ¨u1Ô!¢§€ýÆDDD¤n uˆˆˆˆˆ¨MaÎ*^2dÈ!x]PPPPP€×âŒVÌwÅkù닸,=²VîU6]†:DDDDDÔ¦°í6àӱ㶒ӭ­­­­­±ý¨âßÂP‡ˆþ¬pÂò‘fa¨£¤{ÅtéÒ¥K—.cÇŽ;vliiiii©üü::::::Ø¢QšRSSSSSœœœœœp|GGGGGG¤‹91¡[|ZZZZZZbß›I“&Mš4Iܱ‡×KÇß±cÇŽ;´µµµµµÅûAõtâ>¹téÒ¥K—p'<­úloåiË{ãéî­DDD¤> ÄtÌÕ¹|ùòåË—ÅtÌÕÁ.vŠ C ]M¼¶¶¶¶¶váÂ… .œ>}úôéÓå篫««««Ã–‹Òüéééééé‘‘‘‘‘‘Øñ‰Û¶mÛ¶m6vÄÚäÈ¿~ýúõë×ã†ËÍÍÍÍÍÅö!!!!!!(¯WË>«HíÍ›7oÞ¼yÉÉÉÉÉÉø®={öìÙ³Çßßßßß_õòŸ?þüùóçÎ;w­­­­íÅ‹/^¼ø´ê³½•GÙë¥Ê½Áuꈈ¨cS÷\NØB´¾¾¾¾¾~êÔ©S§NEújg¤×0uëÖ­[·nŠäÇU–æóÍ7ß|óÍòòòòòréqnݺuëÖ­É“'Ož<)Xõ¢¬¬¬¬¬L}çûþûï¿ÿþû—‰2£WêÈ‘#GŽ‘ž):tèСCææææææÃ‡>|øµk×®]»¦ÊñÑœ 600000Àñ ¢GKVý£O }_ººººººØBKÌyûöíÛ·o£´ø”¡¡¡¡¡á¬Y³fÍš…°S~]áNxùå—_~ùå¶¹÷ÚÛoAõ£ÁÑ£G=š’’’’’"¦[XXXXX´ÖõR¶üòó744444|ðÁ|ð~› 0`ÀüùóçÏŸ_½¬ó,+ˆˆHu{÷îÝ»wïÇ>|ˆù6•‚»‚ŠŠŠŠŠŠrÁÁmÁÍ›7oÞ¼‰#‹ßuìØ±cÇŽ!Æa¯ŽFÂ\…¤¤¤¤¤$ggggggùùÑüÚ½{÷îÝ»±O­øn~~~~~¾©©©©©©ô³hÖçååååå!¥¨¨¨¨¨HÝÕV­ZµjÕ*t_VUUUUU-Y²dÉ’%ÞÞÞÞÞÞ²jø a°ú©>üðÃ?üP•㇆††††êééééé•””””” ôõõõõõñ²Î}/芕Õ÷‚Þ¹M›6mÚ´ W?l______4Xå×v>xðàÁƒùëPÖÉ“'Ož<éîîîîîŽA¡cÆŒ3f ®…ƒƒƒƒƒB Öº^­kñâÅ‹/¶·····G_ëÕ«W¯^½Š”°°°°°0éï¿_ñîE:Â¶šššššÞDD¤ñØ«£)Ä«†ynnnnnnhÜÈÏvvvvvvˆ•ÅœVVVVVVò¿O‹ñ3ššššššÔq¦µéááááá£{÷îÝ»wÇùʺ?‘ަRpW£F•ãa%e¯—´–¤ÇïÑ£G=dýBPÉú„Rxª¡î{Ow²,mY@¿% %.....>[ëzµ¬üòó#8Óñ€ïJ?…pNì¿:{öìÙ³gûõëׯ_?þ½%"¢Ö%íÕIˆ½:bºØ«#¦³W§ÃÂ%ij䌌ŒŒŒ ù›(‰C°Š‹‹‹‹‹Å<˜ÿ€ÛKz T€HÁvNb?Oëš2eÊ”)SÆ?~üxô¢ Ñ–˜˜˜˜˜¨ìÑ0©]•㣶1HLÙoÇ‚òó 6lذa²þ4Èê5úþûï¿ÿþ{ UÂð*ͺ‡åkûR}ùå—_~ù%f¦aHXttttttTTTTT”ê׫mêSÖ»ÒtôVíß¿ÿþýHÁÐJ,ñÉ¿´DDÔ6¸¯µ ¼Á³j1="""""·²³³³³³Ñ‘“““““ããããããŽüˆ’‘‚±¤ÒÓÅ$\a•-ôÉ`À–CÿÙ'Nœ8qa fÝ`H’*ÇÇÀ$¬8‡ xCÓPõÅtmݺuëÖ­XàAž‰~úé§Ÿ~ú nqa®Ó¥ ó˜ãéééé鉹[&U¹^ê°eË–-[¶ˆéø=â]é§0¼íÀ@ žŠ‰w‘ú´Í¾:À¦¤WM•üh™™™™™™‰éÊ‚èÑ:|øðáǥ߂Iù‡a`^^^^^^˜'£ÊùîÚµk×®]}úôéÓ§ ˜8qâĉ1§HÖy!%+++++ ŸÅ¹H—%PöøxN„Mð{A¿PËž¬#å§Ÿ~úé§ŸbE×®]»víúú믿þúë_|ñÅ_|!Ãídý¢Õwשã[Ú[y05|ãÆ7nHó({½ZV~Åóã¯7æõÈZ–ðPGC^¯[·nݺuü«KDD­ëi-K …ÿÁÄk<ÿ‹GVFœ¤)ЧÁû–Tƒ?¦xÍ:!""RÆÂ`q,Œ¾§B 2dÈ!x->zÆX´îð8阾)™™™™™™…„w±\6JÑaÕ“¦n1à!Õï"`¨CDD¤n˜ø éŠté06¤+>Œ¡i<6Ä»ˆˆˆH³´Í\.K@DDDDD{uˆˆˆˆˆ¨MaŸC¼çê`ãu¼×•ÎÕQä[Ø«CDDDDDO÷Õ!¢V†KX"""zZ8W‡þ›–D—.]ºté‚Í1±üü::::::ØQšRSSSSSœœœœœp|ìKƒt1'&pcKMKKKKK˾}ûöíÛwÒ¤I“&Mž¼jí6¸Äu¿téÒ¥K—peYžÖýmª#?©‚¡Ž׆ÂëÚÚÚÚÚÚ… .\¸púôéÓ§O—Ÿ¿®®®®®nÔ¨Q£F’æOOOOOOŒŒŒŒŒÄ눰±Iè²eË–-[†µÉ‘ýúõëׯLjÉÜÜÜÜÜ\삲ñªµçÏŸ?þü¹sçÎ;gkkkkk{ñâÅ‹/²}úôA~lб¿¸ŒŒŒŒŒŒfÏž={öìšššššš¶¬ŸÆÆÆÆÆÆE‹-Z´õ8pà‚ ,XÐÐÐÐÐРÈ}.ÿ×ADDô,`¨£‘0·!))))) Á‰üü?vïÞ½{÷nìS+¾‹]iÅ Ednnnnn.îh[TTTTT¤¾jœ°Ÿnyyyyyù’%K–,Y"ŽÝÄ3r„(âqâæææææ&>MWüøŠFpIIIII j@______ºé¬ZµjÕªU—/_¾|ùrUUUUUŽïííííí-æËVVVVVV†Á]{öìÙ³g¿¿¿¿¿?ïyÅ|Z1)GŽ9räˆ*ÇÇ3~„@Š”‹'zxxxxx @B¯®—¬ß—²éªßKê¸3eiËòzp­‘‡œbÎ=zôèÑCVÉжnùåç766666Fp"¦ãÞ•~ áz±pü³gÏž={½ŽüûIDDO×Þ½{÷îÝ‹GrXZ RpW€–j¹àŽà¶àæÍ›7oÞÄ‘Åï:vìØ±cÇã°WGÃàâÙ3z-ä¯,.^øààààààâââââb1æKàö’ý X%)”%öó´.,o€a|øðáÇcVV 0`À€ÄœJ·nݺuëV,°5âžVɶlÙ²eË1¿/¼+ý†·8pàÀHÁS.qó5""¢g C jܲüx§¿âLÌj@`€ž »Âœ–åË—/_¾|äÈ‘#GŽD~?~~~~~~l0 ½ªO£G#õôéÓ§OŸÆà:”Af°H?…Õw¥Ô‘_þqÚò>|ºÇyZ{u Ø{ .]ºtéÒ%üÒYÍý @DD²0ÔÑÒÕÄkkkkkk.\¸páÂéÓ§OŸ>]~þººººº:l‰(ÍŸžžžžž‰Ù««««««·mÛ¶mÛ6l¼ˆµÉ‘ýúõëׯÇf…¹¹¹¹¹¹Øc>$$$$$eSå|QBGZZ©‚‚‚‚‚‚/¾øâ‹/¾ÈÉÉÉÉÉA™±å¢üúTß•RG~UŽƒm1ÛòìÔwu\AÕëGSœ?þüùóçÎ;w­­­­íÅ‹/^¼ÈòH)û×ìiý ""™°…h}}}}}ýÔ©S§NŠô'ÔÎH¯ 6`êÖ­[·nÝÉ«,Íÿæ›o¾ùæ›ååååååÒãܺuëÖ­[“'Ožøàƒ>À¹0`À€óçÏŸ?>jUzäk×®]»víå—_~ùå—»wïÞ½{÷iÓ¦M›6íáÇ>T%?9räÈ‘#âoYÖ™Èú Í@wæÌ™3gÎÄg_z饗^z MÒÖúû xý+{¾8ކœ¸—FŒ1bĈçŸþùçŸW¥~Zv?ÀÝ»wïÞ½ûî»ï¾ûî»úúúúúú‹/^¼x±¬üG=zôhJJJJJŠ˜naaaaa¡¾¿-ííoêGS¼>oß¾}ûöíáÇ>ïΚ5kÖ¬Yøu´nùåçWå~¬È½MD¤>{÷îÝ»w/Z5÷îÝ»wï^¥à® ¢¢¢¢¢¢\pGp[póæÍ›7oâÈâw;vìØ±cˆqØ«£‘0–=)))))ÉÙÙÙÙÙY~~üó¼{÷îÝ»wcŸZñÝüüüüü|SSSSSSégÍÍÍÍÍÍóòòòòòRTTTTT¤ú@5Y0·)zf‚±4ÿñãÇ?nggggg‡Aþw%'''''£_hÏž={öìñ÷÷÷÷÷ó 1jooooo¾¬«W¯^½z)aaaaaaÒ#ïØ±cÇŽ‰‰‰‰‰‰èõêׯ_¿~ýЧz~ü¤åŸcUUUUU•¬Æ4?ÎÈÊÊÊÊÊ €Ð4>>>>|ëÖ§ô,¤÷¿±±±±±1b:H¼+=‚´´È>UòË:Õó@Ïž={öì)íMƒ„¶¬eÏÄ^kkkkkk ÅT¥~”½ÄãË꣓B?*Î)qqqqqqÒ©Ž¿-êøK%K[–GÙú”?”}q­[~ùù[v¿!œû¯Îž={öìY<@yBDÔæØ«C Á%ijƌŒŒŒŒ !Š4)‚ƒƒƒƒƒ‹‹‹‹‹‹Å<ÛKz T:tèСC‘bccccc#öó´®Ï>ûì³Ï>ì,30cÆŒ3f`NQë~lP¼Y&ë]E¾ Ó¯¦ª#ëÞcÒt ¤iûúWúÑĀƠ     ô¨¨^?-»ÐPVä[¾üòË/¿ü³ÎPóÑÑÑÑÑÑQQQQQQíÿo”|m_*ÅësذaÆ “Ur±Ÿ¤íëSñû ½Uû÷ïß¿?R0°sðàÁƒnÏ÷Qëb¨ó ÁÀ <ËÓ#"""""¼½½½½½³³³³³³ñ¬Á†Oxxxxx8ò#JF <@³K¸¸¸¸¸¸´V™•]¢@¶lÙ²eË1ç‹w¥ŸÂ»xꀧhZùùùùùù©ž_YèåÀŠv¢._¾|ùòå5kÖ¬Y³F̉oDº8,&&&&&¦ýßçè•Âܵk×®]»b…À!C† 2DÖÐÅë§e÷ƒ²ðp3F<=====öcžÿš©¯>Ç?~üø­[·nݺCIq?<­’·ì~Ãð¶8p)xê‰U¼ˆèÂlíŸôª©’ÿdš™™™™™‰éê€e^ÑìÃ?–‡>|ø°ô[°>ÅaahÌŽÀ¢±­uîÊ.Q J}ÊJǯcô{ ¤Ó‚ÅÏ¢÷ –ÀdtqZ³²ù..«&qeq|ÌÚÂL'ésk–>‡'ÄèQü>l­úWö|1°s-Äù]ò—=P¼~¿Zv¥DžŠòܸqãÆêû«¢ú•mÿåQ¤>ñ çÓO?ýôÓOqe0¿þú믿þ:VzT½üŠçWö~„ú8~¿x½nݺuëÖñ_U"j{Ok›þ'44444χ0/Y =-èIÃwMéUc}‘)â1"ÆŒˆ±†ôµüwñ:2333331 éiiiiii˜«óìT1‘¦n+ɦ9듈ˆ”ÅP‡ˆ¨Ýa¿:듈ˆTÇe ˆ¨…°€–zõêÕ«W/Öµ%öêQ aZ!눈ˆÚ'öêQÄP‡:”3gΜ9s†õ@Ï2¬HÃz ""b¨£¤3ºtéÒ¥K—±cÇŽ;ûØÈÏ=é±ež4?¤¦¦¦¦¦:99999áøØcébNLðݰaÆ °o ¶hÄ.õØóA•óÅ6ŽØ«¯ùÔ¯¿þú믿âøàƒ>øç>`À€ÈÚ­G¾víÚµk×^~ùå—_~»³O›6mÚ´iØ'X•üpäÈ‘#GŽˆ¿eYgj````` ë/€4?Ý™3gΜ9Ÿ}饗^zé%4©Uÿû ~;öE~÷Ýwß}÷]}}}}}ýÅ‹/^¼X•üê.¿~‰¸víóoEk]¯£G=z4%%%%%EL·°°°°°@~ì`=|øðáÇã]CCCCCÃY³fÍš5 W§uË/?Ë~¿Ò߈"¿""’eïÞ½{÷îE«ËU î ******Êw·7oÞ¼yó&Ž,~×±cÇŽ;†‡½: cñ“’’’’’œåçGób÷îÝ»wïÆ>µâ»ùùùùùù¦¦¦¦¦¦ÒÏš›››››çååååå!¥¨¨¨¨¨Hõj²` nSôÌ ‰4ÿñãÇ?nggggg‡AþwáÙ<ú…d=›GcÚÞÞÞÞÞ}YW¯^½zõ*R¤GÆ0§ÄÄÄÄÄDôzõëׯ_¿~è‹S=¿‡‡‡‡‡~ÒòϱªªªªªJVãLšgdeeeee…?@hÚ:tèСCª__ñ{}}}}}}'L˜0aÂü Ãy©’_Ýå—®Ìò‡Mj®“'Ož|Xú-XŸ ƒâ°0´—————½m­sWv‰UêSV:~˜cÐ[ Ö,~½gü°Ì&Ó‹Ó²•ͯøs}Y5‰+‹ãcÖf:IŸ»#°Äð9<áÆbŠß‡-ë‘P=¿ºËÚS¼ýôÓO?ý¿”®]»víÚõõ×_ýõ×±Rb[ÞŠÿ~Ex胣áþÁëuëÖ­[·Žÿ*)ëi `ÓÂÿ„†††††âùæE +CA""ôŒáMéå#"¢ö\ñ˜c.ÄXCúZþ»x ™™™™™™…„t,„RtXõDD$ŸtxC""jÿêÑÀ~~""ÒD\–€ˆZË:k) W¯^½zõbQ[b¯µ¦²ˆˆˆ¨}b¯u@ uˆˆˆˆˆ¨b¨£¤3ºtéÒ¥K—±cÇŽ;ûØÈϯ£££££ƒ-ÿ¤ù!55555ÕÉÉÉÉÉ ÇÇ;Hsb‚ò† 6lØ`iiiiiÙ·oß¾}ûNš4iÒ¤IسBSê³=‡ˆˆˆˆÔ¡Ž®&^[[[[[»páÂ… b«DùùëêêêêêF5jÔ(iþôôôôôôÈÈÈÈÈHì Žm+±Iè²eË–-[†µÉ‘ýúõëׯÇf‚Ø–{¢‡„„„„„ lšRŸíá8DDDD¤ u4zi<=====³²²²²²äç×ÕÕÕÕÕ —æŽŽŽŽŽNLLLLLtvvvvvF¯zx°åÓÊ•+W®\‰ü›7oÞ¼yóÒ¥K—.]jjjjjjŠt//////„Iªœ]BBBBBÊ€>======WWWWWW++++++Uò‹°Ÿ.z¥pMÌSSSSSSdhhhhhˆþ® .\¸pw#QûÄPG#awؤ¤¤¤¤$'òó#üؽ{÷îÝ»±O­øn~~~~~¾´ˆÌÍÍÍÍÍóòòòòòRTTTTT¤¾jœ°Ÿnyyyyyù’%K–,YòàÁƒ¨’_”œœœœœ\PPPPP°gÏž={öøûûûûû‹yÂÂÂÂÂÂ2UVVVVV¦¤¤¤¤¤:tèСC¼‰ˆˆˆÚ'.6­aÐk¡­­­­­=bĈ#FÄÅÅÅÅÅÉÏ×vvvvvvÇ?~ü¸˜GÙXÈp ýK­{Ž;wîܹs§¯¯¯¯¯/Žobbbbb‚½Y¤†²ùEè­Â§¦L™2eÊ”¦¦¦¦¦&1B ’’’’’äDXˆ{üñÇÌ;“ˆˆˆ¨½a¨£aZ–à5æØ‹[:ÚÚÚÚÚÚÞ½{÷îݻҭËÊÊÊÊʆ:tèP¤ØØØØØØ ŸÇÁÁÁÁÁ¡uÏË466666bðöoùñÇüñÇ &L˜0AÜÑEÙüÿë @¨&«ÎxOµOÀö Á2Ò^ ˆˆˆˆˆoooooïìììììlôlääääääøøøøøø`žò¯X±bÅŠHÁ‚3°¤‹‹‹‹‹‹*åìÙ³gÏž=Q’®]»víÚsi† 2dÈ3ªäW–ŸŸŸŸŸßš5kÖ¬Y#‹‰‰‰‰‰á}EDDDÔ>1ÔÑâ 4E–6–•¯Ñ#δqwwwwwŠŠŠŠŠ Æ´~ÌY¾|ùòåËGŽ9räHäGðƒ Œaaé´~e¡éôéÓ§OŸÆ ”³h0œL•üòëGúANaaaaa!ÎË|‹kÙqÉi"""¢öF OèCCCCCCâããããã¹.©+úbq,Œ‘‘nŽ"¾–ÿ.^cÞxfffff&Ä#=----- ¥°W‡ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡u@ uˆˆˆˆˆ¨b¨CDDDDDC  %Ñ¥K—.]º`w—ÒÒÒÒÒRùùutttttÞxã7ÞxCšRSSSSSœœœœœp|GGGGGG¤‹9±Ì߆ 6lØ`iiiii‰-;'Mš4iÒ$qÇõÕïÖ‘| u4€t5ñÚÚÚÚÚÚ… .\¸PÜÈRVþººººººQ£F5Jš?======22222266666¶ºººººzÛ¶mÛ¶m[¶lÙ²e˰69ò¯_¿~ýúõW®\¹råJnnnnnîõëׯ_¿‚²©»x?´ì³ê»:DDDDí C„^OOOOOϬ¬¬¬¬,ùùuuuuuuÃÃÃÃÃÃ¥ù££££££Ñ«ƒlù´råÊ•+W"ÿæÍ›7oÞ¼téÒ¥K—šššššš"ÝËËËËË a’*gWSSSSSdhhhhhˆþ¥ .\¸pAš_ì娏qãÆQ*œEBBBBB‚˜)xŸÒÓÓÓÓÓsuuuuuµ²²²²²ó#Pœ3gΜ9sP ‹íÛ·oß¾½_¿~ýúõ“–jîܹsçε±±±±±éÞ½{÷îÝG=zôè£G=zTõãñcÇŽ;†^5Yç{çÎ;w¸¸¸¸àLŒŒŒŒŒfÏž={ölÔ6SDDDÔñ0ÔÑHØ6))))) Á‰üü?vïÞ½{÷nìS+¾›ŸŸŸŸŸ/-"sssssó¼¼¼¼¼<¤©o ZXXXXXBŽÊÊÊÊÊÊ””””””C‡:tHš_ìå(+++++à ½={öìÙ³Çßßßßß_̈À ûõ–—————/Y²dÉ’%”–jÕªU«V­º|ùòåË—«ªªªªªp|ooooooÕÉÉÉÉÉɲν›6mÚ´i¯¯¯¯¯ïüùóçÏŸÏßu@+V¬X±bE}}}}}ýÔ©S§NŠô'ÔΈWM[[[[[ÛÍÍÍÍÍ Éäç;;;;;»ŠŠŠŠŠ 1'‚ ùß>hРAƒá5zBššššššÔq¦={öìÙ³'šøbº„È:_EÒ"¢§ ˜˜˜˜X[[[[[c¨ž˜} øvEÊÿçŸþùçŸ`Ыƒë%-²ÇÏKz¤ÇïÑ£G=dý@@Åß©ÏÞ½{÷îÝ‹Öݽ{÷îÝ»W)¸+@Kµ\pGp[póæÍ›7oâÈâwaÌ böêh\B<›ÏÈÈÈÈÈ@"??‹ylmmmmmq{I€~’¡C‡:)”%öó¨ã¥é ªË'466666¢¿ 3Ž0dn„ &Ló£¶Ñÿ£Èñ§L™2eÊ”ñãÇ?½4ø ”æWöø" e”ŸgذaÆ “õ§G~¯‘æb¨ó Á@¦¸¸¸¸¸81="""""«²³³³³³ÑW“““““ããããããƒy>È()˜g‚°K`Nˆ*åôóóóóó[³fÍš5kÄf111111ª×zp¦]»víÚµ+æº 2dÈ!Ò¹+è…ç‚i˜Å$0†àó‹ 0 Ë9HË£ìñ•… këÖ­[·nÅ?~üø1DDDÔ±1ÔÑâ²ÂŠ,1,+?^;88888ˆ3mÜÝÝÝÝÝ£¢¢¢¢¢ÐóƒaW˜Ó²|ùòåË—9räÈ‘Èà  C¯…tZ¼²äâÈXV[\;Nþ9ʪӧOŸ>}ƒ÷ð.‚ Ìx˃Y.èŸ133333Ch„¹O«W¯^½zµ˜ÿ›o¾ùæ›oP{Xfàƒ>øàƒ¤åQöøÊž/‚R„[˜Ù…!mX‘‹RðWFDDDžÐcb4šbññññññ²)cU°8Æìˆ±†ôµüwñS233333ñ éiiiiii˜}Í^"""""ê€êQÄP‡ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡u@ u4€–D—.]ºté‚ÝfJKKKKKåç×ÑÑÑÑÑyã7Þxã i~HMMMMMurrrrrÂñ± &ÒÅœXæ[^ZZZZZZb˜I“&Mš4IܱG}õ Hz{¾Ž¼«‰ˆˆˆÔ¡Ž®&^[[[[[»páÂ… ŠkÊÊ_WWWWW‡-#¥ùÓÓÓÓÓÓ######cccccc««««««·mÛ¶mÛ¶eË–-[¶ k“#ÿúõëׯ_åÊ•+W®äæææææ^¿~ýúõë!!!!!!(›ºëA‘ôö|‰ˆˆˆHÝêh$ôÒxzzzzzfeeeeeÉϯ«««««.͘˜˜˜˜èìììììŒ^ôð`˧•+W®\¹ù7oÞ¼yóæ¥K—.]ºÔÔÔÔÔÔé^^^^^^“T9»šššššš      CCCCCCô/]¸páÂ… ò?{ìØ±cÇŽ¡— g‘ æAà7gΜ9sæàøÛ·oß¾}{¿~ýúõë'æ{c>|øðaäwqqqqqù믿þúë¯Ö*?µV&Âî°IIIIIINäçGø±wïÞ½{÷bŸZñÝüüüüü|1h™›››››çååååå!¥¨¨¨¨¨H}Õ¬¬¬¬¬¬*+++++ïß¿ÿþ}ô2ÉÿlrrrrrrAAAAAÁ‘#GŽ9âïïïïïßØØØØØˆ<¡¡¡¡¡¡zzzzzz%%%%%%]»víÚµë8ððáÇŠÇDo B¼‹A€ø®?üðÃ?D@¨zù‰ˆˆˆ¨µh­X±bÅŠhüÄÇÇÇÇÇs°M»»TÂmmmmmí#FŒ1".....nРAƒ ’•ììììììŽ?~üøñ^½zõêÕ é/¼ð /¼P\\\\\,ëÛ­­­­­­1h ߎàýK­{¦&&&&&&Bôõõõõõ‘^UUUUUeddddd$½?q¾MMMMMMb©.æ766666ÆñÑë¢xý#ÔA©ÌÌÌÌÌÌP6UÊODDDÔQá¡0¸777777K'\ˆ¯å¿‹×xôŸ™™™™™éãããããƒô´´´´´4L¾`¯Ž†Q¶‰,æÇ„4b¨ckkkkk{÷îÝ»wïŠéPVVVVV6tèСC‡"ÅÆÆÆÆÆý<msŽ-äV‘Ð ? üÌT/íãÇ?~ÜZå'"""¢Ö¹:Ï,c€^ 1="""""ÂÛÛÛÛÛ;;;;;;}#999999ˆ’1ÏùшÌ{A–4À UÊéççççç·fÍš5kÖ )/////‰‰‰‰‰Q½|}}}}}±‚RÐß‚ç ð&ë³'Nœ8qâJ…rX¯-ËODDDDŠ`¨£Ä¡hŠ,U,+?^£FœiãîîîîîŒy,Ë—/_¾|ùÈ‘#Gމü~РG`ƒ![XØ@º €²$âÈ'ĵã䟣ü×›6mÚ´i˜aø–1ؽ{÷îÝ»W¯^½zõjYeÃŒ¦çŸþùçŸÇšuè+S¥üDDDD¤œ«C¤ØOE2燈ˆˆˆñ´æê°W‡è?P¶WˆˆˆˆÚ.K@ô°'‡ˆˆˆH±W‡ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡u@ u4€–D—.]ºté‚ÝZJKKKKKåç×ÑÑÑÑÑyã7Þxã i~HMMMMMurrrrrÂñ‘.æÄ4}lÁiiiiii‰}i&Mš4iÒ$qÇÕÏW}5Ù–%i›uÛÔWoDDDDšˆ¡Ž®&^[[[[[»páÂ… ŠSÊÊ_WWWWW7jÔ¨Q£FIó§§§§§§cCÌØØØØØØêêêêêêmÛ¶mÛ¶mÙ²eË–-ÃÚäÈM3¯\¹råÊ•ÜÜÜÜÜÜëׯ_¿~=$$$$$ek­óU_M¶eI9N=zôèÑ>눈ˆH1ÔÑHè¥ñôôôôôÌÊÊÊÊÊ’Ÿ_WWWWW7<<<<<\š?::::::11111ÑÙÙÙÙÙ½:èáÁ–O+W®\¹r%òoÞ¼yóæÍK—.]ºt©©©©©©)Ò½¼¼¼¼¼&µÖ™;vìØ±cè5B©Ä<‹-Z´h‘µµµµµõÀ¸`Á‚ 444444Hü×_ýõ×_#FŒ1bÂŒwÞyçwÞ‘U~eó=zôèÑ£Šô´"•öÈIó×ÔÔÔÔÔá³è»páÂ… øë """†: »Ã&%%%%%!8‘ŸÍñÝ»wïÞ½ûÔŠïæççççç‹A‹ÈÜÜÜÜÜ>>>>žƒaÚÝ¥žñkkkkkk£‡!.....nРAƒ ’•ììììììŽ?~üøñ^½zõêÕ é/¼ð /¼P\\\\\,ëÛÑ[‚@ߎ¾ô/©ï|›šššššÄoAºxöìÙ³gÏž7nܸqã†8 ½èºwïÞ½{÷Ä#ܾ}ûöíÛbÀ†übø¡l~Yç"ÿ7¥H011111))))))Ñ×××××G:Ê`dddddÄß/µ%„îÍÍÍÍÍÍÒ âkùïâ5ýgfffffúøøøøø =----- “/tž*îT™m‚96iÄPÇÖÖÖÖÖöîÝ»wïÞÓ¡¬¬¬¬¬lèСC‡EŠ úyÔw¾Š„Ròû@¯±Ç?~üœ:ò«û5TˆˆˆèÙÄlÏ µB/˜áííííí¾”œœœœœDɘçƒüè D f˜ ‡K¸¸¸¸¸¸´åy¡7rË–-[¶lÓQ¼+ýÞE_ ú|0gÉÏÏÏÏÏOõüÊÂ|*ÌDBuùòåË—/¯Y³fÍš5bN|#Òñ\¤¼¼¼¼¼<&&&&&†÷90ÔÑâP4E––•¯Ñ#ÄrwwwwwŠŠŠŠŠ ÖÓÓÓÓÓ \¾|ùòåËGŽ9räHäGðƒ7 ©Â<é²­u¾²^¯^½zõêÕ˜Ÿóœ °°°°°ïJ?…E°@6–ÌÆ œ¯¾úꫯ¾jY~éYHË,ë Š3‘0, Ë*HCG98;Ô<–×Öã’ÓDDDDœ«CDDDDDjô´æê°W‡ˆˆˆˆˆ: †:DDDDDÔ1Ô!""""¢ˆ¡u@ÜW‡ˆˆˆˆˆÔîáÇ>lËod¨CDDDDDjÔ¿ÿþýûcµ4uYÖ»À¦´$ºtéÒ¥Kì¦RZZZZZ*?¿ŽŽŽŽŽÎo¼ñÆoHóCjjjjjª“““““Žïèèèèèˆt1'–ùÛ°aÆ °ÃLß¾}ûöí‹=gÄ{T?_õÕd[–D}»Ü¨¯®ÚçýÏ¿DDDšhРAƒ ’–( GÑeåa¯Ž@h¦^c=òƒ|øðáÒ<ìÕÑHè¥ñôôôôôÌÊÊÊÊÊ’Ÿ_WWWWW7<<<<<\š?::::::11111ÑÙÙÙÙÙ½:èáÁ–O+W®\¹r%òoÞ¼yóæÍK—.]ºt)‚¤{yyyyyUWWWWW·Ö™;vìØ±cè5B©Ä<‹-Z´h‘µµµµµõÀ¸`Á‚ 444444Hü×_ýõ×_#FŒ1bÂŒwÞyçwÞ‘U~eó=zôèÑ£ŠôHÖÕÕÕÕÕI{äZ«&çÎ;wî\›îÝ»wïÞ}ôèÑ£GF9Åœ²¾]‘ô7nܸw…¬ë…33gΜ9spîÛ·oß¾}{¿~ýúõë§Êý@DDDí ‚l!Ї˜x ß$h4ÜÜÜÜÜÜpdYßËPG#áVHJJJJJBp"??šã»wïÞ½{7n2ñÝüüüüü|1h™›››››çååååå!¥¨¨¨¨¨HõjŠHNNNNN.(((((سgÏž={üýýýýýÅ<‹/^¼x1z¢®\¹råÊô8!%,,,,,Lzä;vìØ±Þõëׯ_¿ŽFöÂ… .\¨z~Eúsªªªªªªðú‰DkÕäªU«V­ZuùòåË—/ã—,Y²dÉoooooo1§¬ïU$½¬¬¬¬¬ ƒ$e]¯ÐÐÐÐÐPôâÏî(}}}}}}ù¹ˆˆˆˆþ5Õ×××××O:uêÔ©HBíŒxÕ´µµµµµË¢q¯HÙÎÎÎÎή¢¢¢¢¢BÌieeeee%ÿÛ1RJ„8[Ýç+ýéýilllll\SSSSS#¦#ÀûÒ#ܾ}ûöíÛÒüªä—u.ªçiÙgÿüóÏ?ÿü¡ ôêàþ‘õYõ¥=xðàÁƒê¸ˆˆˆ¨½Ù»wïÞ½{ñ@óÞ½{÷îݫܠ¥Z.¸#¸-¸yóæÍ›7qdñ»01{u4 .!zu222222äOÆ/|ppppppqqqqq±˜ÇÖÖÖÖÖ·—ôxN?tèСC‡"ƒ Ä~õÁP=Eêd½«Èw¡ a¤:ò?-S¦L™2eÊøñãÇ^iè¡Rü88_ÕË#vO«ã~ """†:Ï µŠ‹‹‹‹‹Ó#"""""0);;;;;ÏÎsrrrrr||||||0Ïù%#ó.0zK¸¸¸¸¸¸´åylÙ²eË–-b:ʃw¥ŸÂ»x*€§ ˜³äççççç§z~ea>fž ¨À`³5kÖ¬Y³F•##XÅzzèƒÂ€1,/¡HynݺuëÖ- |øðáÃÒoÙ¶mÛ¶mÛ0(â°,æi¨ã|e¥ãî?þüùó{ ‚w¥G@ï3 èz÷Ýwß}÷]ôx´,¿ü³ÑÐGÍãø˜U…µòT9þ®]»víÚÕ§OŸ>}útëÖ­[·n'Nœ8q"æhÉúÊÓµk×®]»b>B_ů‹¬tt^áÏ0üýA¿“*÷µ7Š `“þË®ú6-üž×âùw|||||<²2²$"""""Uà*ãb»k˜˜˜˜˜˜Èú,‚¼?…!ñØ–£ŽON:uêÔ)`#""""¢§@~ª¬úË ¾DDDDDô`›ØW#ESZv|öêQÄP‡ˆˆˆˆˆ: †:DDDDDÔq®©›nËod¨CDDDDDjÔ¿ÿþýûcahuYÖ»ÀFDDDDD{uˆˆˆˆˆHJJJJJJÆŒ3f̘Ö=rjjjjjêðáÇ.}—¡©]çÎ;wîÜÜÜÜÜÜ,kçùûꈯ=zôèÑ#ùßÈlDDDDDÔ1Ô!""""¢ˆ¡u@œ«CDDDDDO‰‰‰‰‰‰"9ïܹsçÎeÏ^"""""z *+++++åçiY uˆˆˆˆˆè©¹{÷îÝ»w¥éååååå媙¡=ebÀ£z uˆˆˆˆˆ¨]¨¨¨¨¨¨h­£1Ô!""""¢ˆ¡u@ uˆˆˆˆˆ¨â¾:DDDDD¤Fýû÷ïß¿ÿ‘#GŽ9âæææææ¦ú1333333qdYyê‘ 4hРAxEõc"È,õ„:Ož êäääääÄ ÖÞœ;wîܹs¬""""jN:uêÔ)GGGGGGqbÞhŸ…njjjjjzùå—_~ùe^Âö +++++ëÌ™3gΜamQ{€ 1ŽÖ½{÷îÝ»×þ ýÍ7ß|óÍ7ÎÎÎÎÎÎ xž.1Èyÿý÷ßÿ}Ö µ72C¬¬?þÈξpáÂ…K—Ú²@öööövv/¿ìâòMWBÀZWWWWWÇKØ–0\ ½ rˆˆˆˆ¨=û?V`ƒœààÙ³çÌiËmÙûÝwx-+à!""""¢ö©°°°°°°¤¤¤¤¤¤m¾QÖÂÓÿG¨ƒ gÖ¬Y³‚ƒ>¬©©©i˪ñöþÛß||ýõ—_êi 1È7nܸqãÚæ{±9)^‹Ì-DŸÿš¾}ýµwï'O´µ»v½qcòäÒRe Úº»úœ~ÜÔÔÔôøqSScã“'HÁ»MM 5666>yÒЀœ 7444wîܹsç~òÉ'Ÿ|òÉĉ'Nœ˜1}úôéÓ§óFDDDDíMFFFFFFZ‰éýõ×_ý%M—ÏÒÒÒÒÒRÖ»-ìÕùŸ su~ü±S§¯_‰Ú IDAT¿F¯ÎìÙÍÍÍÍ‘‘Ož|óMDÄ“'™™»w77Ï™ãìŒO=­lÍÍMM÷ï—–––––ŠAúj033y>|øðáæ¦ÆÆ¦&1øS¼Wá ‚¨ï¿ÿþûï¿9räÈ‘#ðœ?þüùóÒOmÚ´iÓ¦MññññññØ8UìQÁ&žS¦L™2eJ×®]»ví:uêÔ©S§Þ¿ÿþýûü ÑÓ"«=/9ådddddd$9b:Æ.YXXXXX`çä0`À€ÿ½r‹{uþï]½:aBiéÀ_ݯŸ4¥sg-­òò¢¢ñ㋊ 8|xÀsçΜAù="ê[–@K Êÿ NC`€¦^Ð À€7±6þÝ«£hpÁÖ®]»víZ¤ |BØóþûï¿ÿþûX®@üTNNNNN–¸sçÎ;wúöíÛ·o_¼[^^^^^Ž#`€\^^^^^ZDDDDÔˆ­z9/¼ð /¼€0ïææææææJÓ1–Jz4<úW¼›Df¨ƒ àñã'Oþ*ÀgŸ-[þ?ÿÚ´¿:yòãwîtwðøñ»ïž8ñÖ[bñhQQÿøÇ—_þïÓxüø£*š›=ú÷‘;uêܽ7!Ø4 š$þg@[§NŠ—ïâÅ‹/^ÄJkÿûßÿþ÷¿¯\¹råÊ•ÒOa¸Úwß}÷Ýwß}ñÅ_|ñÅ?ÿùÏþóŸx}8&L˜0af!Æ1bĈ#ÔwËr®)A&qˆéx¬/MGk£®´x·¢¢¢¢¢¢ªªªªªÊØØØØØé­Ð«³|yddDÄÎ;wî܉ž1rrrrrò;ï$$tê´|ù矯\¹|ù²eááòó#pB~ùmlŠ×=zôä úCÄ9MMMróeæê`Qi H B¨ƒwww÷ÿ ÿÿÞ{ï½÷Þ{oÛ¶mÛ¶mCï½½½½½=fø`hºð>ÿüóÏ?ÿœ?'""""jÄV=:0íBÌ#MGƒ¶:ôB˹¦¦¦¦¦SQ0Ù ŒaMcYePb®Žø®¾ÄàÁƒ,=1Åó«g®Îÿ `«©©­­­E5‰CÔehnnjjnF؃€Çùw¯Ž¢eÀÎ9¸0®®®®®®N°4ÂæÍ›7oÞ,본„ÿøÇ?þñ|öÙgŸ}öÒñ),c=lذaÆIÇ,µ=i{-p¼{i¤éèÕA7&q\»víÚµk………………rÌÌÌÌÌÌþ§ B…^ÇŸ<ùüó¨¨%KdõÏšÚ˜(õÙgŸ~ªlþÈÈÏ>‹ŽnÝP§¡¡¾þßUàà`ook;dÈ€=z<–á‘ x#•-B;ôá(’_ºÝçXRþ&sbe6ùG#""""jK;wîüï‰$b¨#+­îäéÝ»wïÞ½±Ž13ÿ½J/K Æ^Rb_Í;ï¼óÎ;ï(^êèÕ)))-­®¾u«¼üÉ''g熆æfggôЈk©=zô?¯Å”ÿ=9Ožtêtþ|QÑãÇ••·o×Ö>k·)çê‘"Ķ=BôÕˆK ÈJÇÐ5é‚aHAWD«ì«óäÉ“'èŸ)*****’JèÁÀ4ze«£¾¾¡¡µCoïqãôôöîýå—‚‚G°ýgëÿý÷gÌ01áMLDDDD$’¶·Ò ˜WW“¦ëêêêêê"î@xƒø½:èÉA¨#.K ‹B¡ö~ÁÜõUŠ‹ËË/»»·n¨cook«§‡ÿò¶#""""jb«^ i¤ØÄô7nܸq[³˜›››››c“P¬½†uÛ0º´B¯Ž˜>sæÌ™3gª£:.^¼té楅 uˆˆˆˆˆèiÁ¢\ЧcÛPôäôéÓ§OŸ>˜3t¬EŒUÚÉÿön!ªmÿ¤,ÎÕ!""""õ1H×X³(r´ÿ#Ô±····³KHøå—Ÿ~íµ×^5 évv/¾èäôÇÙÙ¹¹ê;½ßÿý÷ß~Cx±‰ˆˆˆˆ4Eÿþýû÷––––ææææææÖ6ß›™™™™™‰oÓÿPçå—]\†ÇkmYArÄ2Qû7hРAƒá5¶ù^9â·ƒÌl6r‘â žnIt4«â×®]»víZ''''''ÞLméܹsçÎÃU`mQ{¦a¡Ž8æÍn^¶„ §-G^µŒÖ½{÷îݻNJ """"¢ŽD›U@DDDDDC"""""ê€þb|ÞÕ›m§IEND®B`‚xymon-4.3.30/docs/configure.txt0000664000076400007640000001063412603243142016656 0ustar rpmbuildrpmbuildConfiguration script for Xymon This script asks a few questions and builds a Makefile to compile Xymon Checking your make-utility Checking pre-requisites for building Xymon Checking for fping ... Found fping in /usr/bin/fping Checking to see if '/usr/bin/fping 127.0.0.1' works ... 127.0.0.1 is alive OK, will use '/usr/bin/fping' for ping tests NOTE: If you are using an suid-root wrapper, make sure the 'xymon' user is also allowed to run fping without having to enter passwords. For 'sudo', add something like this to your 'sudoers' file: xymon: ALL=(ALL) NOPASSWD: /usr/local/sbin/fping Checking for RRDtool ... Found RRDtool include files in /usr/include Found RRDtool libraries in /usr/lib Linking RRD with PNG library: -L/usr/lib -lpng Checking for PCRE ... Found PCRE include files in /usr/include Found PCRE libraries in /usr/lib Checking for OpenSSL ... Found OpenSSL include files in /usr/include Found OpenSSL libraries in /usr/lib Xymon can use the OpenSSL library to test SSL-enabled services like POP3S, IMAPS, NNTPS and TELNETS. If you have the OpenSSL library installed, I recommend that you enable this. Do you want to be able to test SSL-enabled services (y) ? y Checking for LDAP ... Found LDAP include files in /usr/include Found LDAP libraries in /usr/lib Xymon can use your OpenLDAP LDAP client library to test LDAP servers. Do you want to be able to test LDAP servers (y) ? y Enable experimental support for LDAP/SSL (OpenLDAP 2.x only) (y) ? y Setting up for a Xymon server What userid will be running Xymon [xymon] ? Found passwd entry for user xymon:x:1000:100:Xymon user:/usr/lib/xymon: Where do you want the Xymon installation [/usr/lib/xymon] ? OK, will configure to use /usr/lib/xymon as the Xymon toplevel directory What URL will you use for the Xymon webpages [/xymon] ? Where to put the Xymon CGI scripts [/usr/lib/xymon/cgi-bin] ? What is the URL for the Xymon CGI directory [/xymon-cgi] ? ********************** SECURITY NOTICE **************************** If your Xymon server is accessible by outsiders, then you should restrict access to the CGI scripts that handle enable/disable of hosts, and acknowledging of alerts. The easiest way to do this is to put these in a separate CGI directory and require a password to access them. If your Xymon server is on a secure network (Intranet) and you trust your users, then you can keep all the CGI scripts in one directory. Where to put the Xymon Administration CGI scripts [/usr/lib/xymon/cgi-secure] ? What is the URL for the Xymon Administration CGI directory [/xymon-seccgi] ? ** Note that you may need to modify your webserver configuration. ** After installing, see /usr/lib/xymon/server/etc/xymon-apache.conf for an example configuration. To generate Xymon availability reports, your webserver must have write-access to a directory below the Xymon top-level directory. I can set this up if you tell me what group-ID your webserver runs with. This is typically 'nobody' or 'apache' or 'www-data' If you don't know, just hit ENTER and we will handle it later. What group-ID does your webserver use ? www-data Where to put the Xymon logfiles [/var/log/xymon] ? What is the name of this host [osiris] ? osiris.hswn.dk What is the IP-address of this host [127.0.0.1] ? 172.16.10.100 Where should I install the Xymon man-pages (/usr/local/man) ? The Xymon history webpage by default displays a 1-day graph of the history. It can also show a 1-week, 4-weeks and 1-year graphs, or any combination of these. Which graphs to show by default (1d/1w/4w/1y/all) [all] The Xymon history webpage can use a new method to create the summary graphs on the history page. This method gives a more accurate view (more detailed), but uses a fixed-width graph instead of the standard Big Brother graph that automatically resizes to fit your browser window. Use the new detailed Xymon history graph (y/n) [y] ? Tell me the display width (in pixels) to use for the history graph. This could be anything, but to eliminate as many rounding errors as possible, it is best to use a multiple of 24. The default value (960) is good on 1024x768 displays What width should I use for the graph [960] ? Using Linux Makefile settings Created Makefile with the necessary information to build Xymon Some defaults are used, so do look at the Makefile before continuing. Configuration complete - now run make (GNU make) to build the tools xymon-4.3.30/rpm/0000775000076400007640000000000013534041774014011 5ustar rpmbuildrpmbuildxymon-4.3.30/rpm/xymon-client.init0000664000076400007640000000353512652231300017314 0ustar rpmbuildrpmbuild#! /bin/sh # # xymon-client This shell script takes care of starting and stopping # the Xymon client. # # chkconfig: 2345 80 20 # description: Xymon is a network monitoring tool that allows \ # you to monitor hosts and services. This client reports local \ # system statistics (cpu-, memory-, disk-utilisation etc) \ # to the Xymon server. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/lib/xymon/client/runclient.sh NAME=xymon-client DESC=xymon-client test -x $DAEMON || exit 0 CMD="$1" # Include xymon-client defaults if available DMNOPTS="" if [ -f /etc/default/xymon-client ] ; then . /etc/default/xymon-client else echo "Installation failure - missing /etc/default/xymon-client" exit 1 fi if [ "$XYMONSERVERS" = "" ]; then echo "Please configure XYMONSERVERS in /etc/default/xymon-client" exit 1 fi set $XYMONSERVERS if [ $# -eq 1 ]; then echo "XYMSRV=\"$XYMONSERVERS\"" >/var/run/xymonclient-runtime.cfg echo "XYMSERVERS=\"\"" >>/var/run/xymonclient-runtime.cfg else echo "XYMSRV=\"0.0.0.0\"" >/var/run/xymonclient-runtime.cfg echo "XYMSERVERS=\"$XYMONSERVERS\"" >>/var/run/xymonclient-runtime.cfg fi if [ "$CLIENTHOSTNAME" != "" ]; then DMNOPTS="${DMNOPTS} --hostname=${CLIENTHOSTNAME}" fi if [ "$CLIENTOS" != "" ]; then DMNOPTS="${DMNOPTS} --os=${CLIENTOS}" fi set -e case "$CMD" in start) echo -n "Starting $DESC: " su -c "$DAEMON $DMNOPTS start" - xymon echo "$NAME." ;; stop) echo -n "Stopping $DESC: " su -c "$DAEMON $DMNOPTS stop" - xymon echo "$NAME." ;; status) su -c "$DAEMON $DMNOPTS status" - xymon ;; restart) echo -n "Restarting $DESC: " su -c "$DAEMON $DMNOPTS stop" - xymon su -c "$DAEMON $DMNOPTS start" - xymon echo "$NAME." ;; *) N=/etc/init.d/$NAME # echo "Usage: $N {start|stop|restart}" >&2 echo "Usage: $N {start|stop|restart}" >&2 exit 1 ;; esac exit 0 xymon-4.3.30/rpm/xymon.spec0000664000076400007640000001320312266740721016035 0ustar rpmbuildrpmbuildName: xymon Version: @VER@ Release: 1 Group: Networking/Daemons URL: http://xymon.sourceforge.net/ License: GPL Source: xymon-@VER@.tar.gz Source1: xymon-init.d Source2: xymon.logrotate Source3: xymon-client.init Source4: xymon-client.default Summary: Xymon network monitor BuildRoot: /tmp/xymon-root #BuildRequires: openssl-devel #BuildRequires: pcre-devel #BuildRequires: rrdtool-devel #BuildRequires: openldap-devel Conflicts: xymon-client %description Xymon (previously known as Hobbit) is a system for monitoring your network servers and applications. This package contains the server side of the Xymon package. %package client Summary: Xymon client reporting data to the Xymon server Group: Applications/System Conflicts: xymon %description client This package contains a client for the Xymon (previously known as Hobbit) monitor. Clients report data about the local system to the monitor, allowing it to check on the status of the system load, filesystem utilisation, processes that must be running etc. %prep rm -rf $RPM_BUILD_ROOT %setup USEXYMONPING=y \ ENABLESSL=y \ ENABLELDAP=y \ ENABLELDAPSSL=y \ XYMONUSER=xymon \ XYMONTOPDIR=/usr/lib/xymon \ XYMONVAR=/var/lib/xymon \ XYMONHOSTURL=/xymon \ CGIDIR=/usr/lib/xymon/cgi-bin \ XYMONCGIURL=/xymon-cgi \ SECURECGIDIR=/usr/lib/xymon/cgi-secure \ SECUREXYMONCGIURL=/xymon-seccgi \ HTTPDGID=apache \ XYMONLOGDIR=/var/log/xymon \ XYMONHOSTNAME=localhost \ XYMONHOSTIP=127.0.0.1 \ MANROOT=/usr/share/man \ INSTALLBINDIR=/usr/lib/xymon/server/bin \ INSTALLETCDIR=/etc/xymon \ INSTALLWEBDIR=/etc/xymon/web \ INSTALLEXTDIR=/usr/lib/xymon/server/ext \ INSTALLTMPDIR=/var/lib/xymon/tmp \ INSTALLWWWDIR=/var/lib/xymon/www \ ./configure %build PKGBUILD=1 make %install INSTALLROOT=$RPM_BUILD_ROOT PKGBUILD=1 make install mkdir -p $RPM_BUILD_ROOT/etc/init.d cp %{SOURCE1} $RPM_BUILD_ROOT/etc/init.d/xymon cp %{SOURCE3} $RPM_BUILD_ROOT/etc/init.d/xymon-client mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d cp %{SOURCE2} $RPM_BUILD_ROOT/etc/logrotate.d/xymon mkdir -p $RPM_BUILD_ROOT/etc/default cp %{SOURCE4} $RPM_BUILD_ROOT/etc/default/xymon-client mkdir -p $RPM_BUILD_ROOT/usr/bin cd $RPM_BUILD_ROOT/usr/bin && ln -sf ../lib/xymon/server/bin/{xymon,xymoncmd} . mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d mv $RPM_BUILD_ROOT/etc/xymon/xymon-apache.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/ rmdir $RPM_BUILD_ROOT/usr/lib/xymon/client/tmp cd $RPM_BUILD_ROOT/usr/lib/xymon/client && ln -sf /tmp tmp rmdir $RPM_BUILD_ROOT/usr/lib/xymon/client/logs cd $RPM_BUILD_ROOT/usr/lib/xymon/client && ln -sf ../../../../var/log/xymon logs mv $RPM_BUILD_ROOT/usr/lib/xymon/client/etc/xymonclient.cfg /tmp/xymonclient.cfg.$$ cat /tmp/xymonclient.cfg.$$ | sed -e 's!^XYMSRV=.*!include /var/run/xymonclient-runtime.cfg!' | grep -v "^XYMSERVERS=" >$RPM_BUILD_ROOT/usr/lib/xymon/client/etc/xymonclient.cfg rm /tmp/xymonclient.cfg.$$ %clean rm -rf $RPM_BUILD_ROOT %pre id xymon 1>/dev/null 2>&1 if [ $? -ne 0 ] then groupadd xymon || true useradd -g xymon -c "Xymon user" -d /usr/lib/xymon xymon fi if [ -e /var/log/xymon/xymonlaunch.pid -a -x /etc/init.d/xymon ] then /etc/init.d/xymon stop || true fi %pre client id xymon 1>/dev/null 2>&1 if [ $? -ne 0 ] then groupadd xymon || true useradd -g xymon -c "Xymon user" -d /usr/lib/xymon xymon fi if [ -e /var/log/xymon/clientlaunch.pid -a -x /etc/init.d/xymon-client ] then /etc/init.d/xymon-client stop || true fi %post chkconfig --add xymon %post client chkconfig --add xymon-client %preun if [ -e /var/log/xymon/xymonlaunch.pid -a -x /etc/init.d/xymon ] then /etc/init.d/xymon stop || true fi chkconfig --del xymon %preun client if [ -e /var/log/xymon/clientlaunch.pid -a -x /etc/init.d/xymon-client ] then /etc/init.d/xymon-client stop || true fi chkconfig --del xymon-client %files %attr(-, root, root) %doc README README.CLIENT Changes* COPYING CREDITS RELEASENOTES %attr(644, root, root) %doc /usr/share/man/man*/* %attr(644, root, root) %config /etc/xymon/* %attr(644, root, root) %config /etc/httpd/conf.d/xymon-apache.conf %attr(755, root, root) %dir /etc/xymon %attr(755, root, root) %dir /etc/xymon/tasks.d %attr(755, root, root) %dir /usr/lib/xymon/server/download %attr(755, root, root) %dir /etc/xymon/web %attr(755, xymon, xymon) %dir /var/log/xymon %attr(755, root, root) /etc/init.d/xymon %attr(644, root, root) /etc/logrotate.d/xymon %attr(-, root, root) /usr/lib/xymon %attr(-, root, root) /usr/bin/* %attr(-, xymon, xymon) /var/lib/xymon %attr(775, xymon, apache) %dir /var/lib/xymon/www/rep %attr(775, xymon, apache) %dir /var/lib/xymon/www/snap %attr(644, root, root) %config /var/lib/xymon/www/menu/xymonmenu-grey.css %attr(644, root, root) %config /var/lib/xymon/www/menu/xymonmenu-blue.css %attr(755, xymon, xymon) %dir /usr/lib/xymon/client/ext %attr(664, xymon, apache) %config /etc/xymon/critical.cfg %attr(664, xymon, apache) %config /etc/xymon/critical.cfg.bak %attr(4750, root, xymon) /usr/lib/xymon/server/bin/xymonping %attr(750, root, xymon) /usr/lib/xymon/client/bin/logfetch %attr(750, root, xymon) /usr/lib/xymon/client/bin/clientupdate %files client %attr(-, root, root) %doc README README.CLIENT Changes* COPYING CREDITS RELEASENOTES %attr(-, root, root) /usr/lib/xymon/client %attr(755, root, root) /etc/init.d/xymon-client %attr(644, root, root) %config /etc/default/xymon-client %attr(755, xymon, xymon) %dir /var/log/xymon %attr(755, xymon, xymon) %dir /usr/lib/xymon/client/ext %attr(750, root, xymon) /usr/lib/xymon/client/bin/logfetch %attr(750, root, xymon) /usr/lib/xymon/client/bin/clientupdate xymon-4.3.30/rpm/xymon-client.default0000664000076400007640000000134412603243142017774 0ustar rpmbuildrpmbuild# Configure the Xymon client settings. # You MUST set the list of Xymon servers that this # client reports to. # It is good to use IP-addresses here instead of DNS # names - DNS might not work if there's a problem. # # E.g. (a single Xymon server) # XYMONSERVERS="192.168.1.1" # or (multiple servers) # XYMONSERVERS="10.0.0.1 192.168.1.1" XYMONSERVERS="" # The defaults usually suffice for the rest of this file, # but you can tweak the hostname that the client reports # data with. # CLIENTHOSTNAME="" # Red Hat EL version 3 uses a different vmstat layout # than all other Linux versions. So for a client running this # particular OS, set CLIENTOS as below. # Do NOT set this on any other Red Hat version. # CLIENTOS="rhel3" xymon-4.3.30/rpm/xymon.logrotate0000664000076400007640000000042211535462534017103 0ustar rpmbuildrpmbuild# # Logrotate fragment for Xymon. # /var/log/xymon/*.log { weekly compress delaycompress rotate 5 missingok nocreate sharedscripts postrotate /etc/init.d/xymon rotate endscript } xymon-4.3.30/rpm/xymon-init.d0000664000076400007640000000244112652231300016254 0ustar rpmbuildrpmbuild#! /bin/sh # # xymon This shell script takes care of starting and stopping # xymon (the Xymon network monitor) # # chkconfig: 2345 80 20 # description: Xymon is a network monitoring tool that allows \ # you to monitor hosts and services. The monitor status is available \ # via a webpage. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/lib/xymon/server/bin/xymon.sh NAME=xymon DESC=Xymon test -x $DAEMON || exit 0 # Include Xymon defaults if available if [ -f /etc/default/xymon ] ; then . /etc/default/xymon fi set -e case "$1" in start) echo -n "Starting $DESC: " su -c "$DAEMON start" - xymon echo "$NAME." ;; stop) echo -n "Stopping $DESC: " su -c "$DAEMON stop" - xymon echo "$NAME." ;; status) su -c "$DAEMON status" - xymon ;; reload|force-reload) echo "Reloading $DESC configuration files." su -c "$DAEMON reload" - xymon echo "$NAME." ;; restart) echo -n "Restarting $DESC: " su -c "$DAEMON restart" - xymon echo "$NAME." ;; rotate) echo -n "Rotating logs for $DESC: " su -c "$DAEMON rotate" - xymon echo "$NAME." ;; *) N=/etc/init.d/$NAME # echo "Usage: $N {start|stop|restart|status|reload|force-reload}" >&2 echo "Usage: $N {start|stop|restart|status|force-reload}" >&2 exit 1 ;; esac exit 0 xymon-4.3.30/xymonproxy/0000775000076400007640000000000013534041774015467 5ustar rpmbuildrpmbuildxymon-4.3.30/xymonproxy/xymoncgimsg.c0000664000076400007640000000260411615341300020163 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon CGI proxy. */ /* */ /* This CGI can gateway a Xymon message sent via HTTP PORT to a Xymon */ /* server running on the local host. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymoncgimsg.c 6712 2011-07-31 21:01:52Z storner $"; #include "libxymon.h" int main(int argc, char *argv[]) { int result = 1; cgidata_t *cgidata = NULL; sendreturn_t *sres; cgidata = cgi_request(); if (cgidata) { printf("Content-Type: application/octet-stream\n\n"); sres = newsendreturnbuf(1, stdout); result = sendmessage(cgidata->value, "127.0.0.1", XYMON_TIMEOUT, sres); } return result; } xymon-4.3.30/xymonproxy/xymonproxy.80000664000076400007640000001736213534041732020037 0ustar rpmbuildrpmbuild.TH XYMONPROXY 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonproxy \- Xymon message proxy .SH SYNOPSIS .B "xymonproxy [options] \-\-server=$XYMSRV" .SH DESCRIPTION .I xymonproxy(8) is a proxy for forwarding Xymon messages from one server to another. It will typically be needed if you have clients behind a firewall, so they cannot send status messages to the Xymon server directly. xymonproxy serves three purposes. First, it acts as a regular proxy server, allowing clients that cannot connect directly to the Xymon servers to send data. Although xymonproxy is optimized for handling status messages, it will forward all types of messages, including notes- and data-messages. .br Second, it acts as a buffer, smoothing out peak loads if many clients try to send status messages simultaneously. xymonproxy can absorb messages very quickly, but will queue them up internally and forward them to the Xymon server at a reasonable pace. .br Third, xymonproxy merges small "status" messages into larger "combo" messages. This can dramatically decrease the number of connections that need to go from xymonproxy to the Xymon server. The merging of messages causes "status" messages to be delayed for up to 0.25 seconds before being sent off to the Xymon server. .SH OPTIONS .IP "\-\-server=SERVERIP[:PORT][,SERVER2IP[:PORT]]" Specifies the IP-address and optional portnumber where incoming messages are forwarded to. The default portnumber is 1984, the standard Xymon port number. If you have setup the normal Xymon environment, you can use "\-\-server=$XYMSRV". Up to 3 servers can be specified; incoming messages are sent to all of them (except "config", "query" and "download" messages, which go to the LAST server only). If you have Xymon clients sending their data via this proxy, note that the clients will receive their configuration data from the LAST of the servers listed here. This option is required. .IP "\-\-listen=LOCALIP[:PORT]" Specifies the IP-adress where xymonproxy listens for incoming connections. By default, xymonproxy listens on all IP-addresses assigned to the host. If no portnumber is given, port 1984 will be used. .IP "\-\-timeout=N" Specifies the number of seconds after which a connection is aborted due to a timeout. Default: 10 seconds. .IP "\-\-report=[PROXYHOSTNAME.]SERVICE" If given, this option causes xymonproxy to send a status report every 5 minutes to the Xymon server about itself. If you have set the standard Xymon environment, you can use "\-\-report=xymonproxy" to have xymonproxy report its status to a "xymonproxy" column in Xymon. The default for PROXYHOSTNAME is the $MACHINE environment variable, i.e. the hostname of the server running xymonproxy. See REPORT OUTPUT below for an explanation of the report contents. .IP "\-\-lqueue=N" Size of the listen-queue where incoming connections can queue up before being processed. This should be large to accommodate bursts of activity from clients. Default: 512. .IP "\-\-daemon" Run in daemon mode, i.e. detach and run as a background process. This is the default. .IP "\-\-no\-daemon" Runs xymonproxy as a foreground process. .IP "\-\-pidfile=FILENAME" Specifies the location of a file containing the process-ID of the xymonproxy daemon process. Default: /var/run/xymonproxy.pid. .IP "\-\-logfile=FILENAME" Sends all logging output to the specified file instead of stderr. .IP "\-\-log\-details" Log details (IP-address, message type and hostname) to the logfile. This can also be enabled and disabled at run-time by sending the xymonproxy process a SIGUSR1 signal. .IP "\-\-debug" Enable debugging output. .SH "REPORT OUTPUT" If enabled via the "\-\-report" option, xymonproxy will send a status message about itself to the Xymon server once every 5 minutes. The status message includes the following information: .IP "Incoming messages" The total number of connections accepted from clients since the proxy started. The "(N msgs/second)" is the average number of messages per second over the past 5 minutes. .IP "Outbound messages" The total number of messages sent to the Xymon server. Note that this is probably smaller than the number of incoming messages, since xymonproxy merges messages before sending them. .IP "Incoming - Combo messages" The number of "combo" messages received from a client. .IP "Incoming - Status messages" The number of "status" messages received from a client. xymonproxy attempts to merge these into "combo" messages. The "Messages merged" is the number of "status" messages that were merged into a combo message, the "Resulting combos" is the number of "combo" messages that resulted from the merging. .IP "Incoming - Other messages" The number of other messages (data, notes, ack, query, ...) messages received from a client. .IP "Proxy resources - Connection table size" This is the number of connection table slots in the proxy. This measures the number of simultaneously active requests that the proxy has handled, and so gives an idea about the peak number of clients that the proxy has handled simultaneously. .IP "Proxy resources - Buffer space" This is the number of KB memory allocated for network buffers. .IP "Timeout details - reading from client" The number of messages dropped because reading the message from the client timed out. .IP "Timeout details - connecting to server" The number of messages dropped, because a connection to the Xymon server could not be established. .IP "Timeout details - sending to server" The number of messages dropped because the communication to the Xymon server timed out after a connection was established. .IP "Timeout details - recovered" When a timeout happens while sending the status message to the server, xymonproxy will attempt to recover the message and retry sending it to the server after waiting a few seconds. This number is the number of messages that were recovered, and so were not lost. .IP "Timeout details - reading from server" The number of response messages that timed out while attempting to read them from the server. Note that this applies to the "config" and "query" messages only, since all other message types do not get any response from the servers. .IP "Timeout details - sending to client" The number of response messages that timed out while attempting to send them to the client. Note that this applies to the "config" and "query" messages only, since all other message types do not get any response from the servers. .IP "Average queue time" The average time it took the proxy to process a message, calculated from the messages that have passed through the proxy during the past 5 minutes. This number is computed from the messages that actually end up establishing a connection to the Xymon server, i.e. status messages that were combined into combo-messages do not go into the calculation - if they did, it would reduce the average time, since it is faster to merge messages than send them out over the network. .SH "" If you think the numbers do not add up, here is how they relate. The "Incoming messages" should be equal to the sum of the "Incoming Combo/Status/Page/Other messages", or slightly more because messages in transit are not included in the per-type message counts. The "Outbound messages" should be equal to sum of the "Incoming Combo/Page/Other messages", plus the "Resulting combos" count, plus "Incoming Status messages" minus "Messages merged" (this latter number is the number of status messages that were NOT merged into combos, but sent directly). The "Outbound messages" may be slightly lower than that, because messages in transit are not included in the "Outbound messages" count until they have been fully sent. .SH SIGNALS .IP SIGHUP Re-opens the logfile, e.g. after it has been rotated. .IP SIGTERM Shut down the proxy. .IP SIGUSR1 Toggles logging of individual messages. .SH "SEE ALSO" xymon(1), xymond(1), xymon(7) xymon-4.3.30/xymonproxy/xymonproxy.c0000664000076400007640000010310212603243142020071 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message proxy. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonproxy.c 7678 2015-10-01 14:42:42Z jccleaver $"; #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #include "libxymon.h" enum phase_t { P_IDLE, P_REQ_READING, /* Reading request data */ P_REQ_READY, /* Done reading request from client */ P_REQ_COMBINING, P_REQ_CONNECTING, /* Connecting to server */ P_REQ_SENDING, /* Sending request data */ P_REQ_DONE, /* Done sending request data to server */ P_RESP_READING, P_RESP_READY, P_RESP_SENDING, P_RESP_DONE, P_CLEANUP }; char *statename[P_CLEANUP+1] = { "idle", "reading from client", "request from client OK", "request combining", "connecting to server", "sending to server", "request sent", "reading from server", "response from server OK", "sending to client", "response sent", "cleanup" }; typedef struct conn_t { enum phase_t state; int csocket; struct sockaddr_in caddr; struct in_addr *clientip, *serverip; int snum; int ssocket; int conntries, sendtries; int connectpending; time_t conntime; int madetocombo; struct timespec arrival; struct timespec timelimit; unsigned char *buf, *bufp, *bufpsave; unsigned int bufsize, buflen, buflensave; struct conn_t *next; } conn_t; #define MAX_SERVERS 3 #define CONNECT_TRIES 3 /* How many connect-attempts against the server */ #define CONNECT_INTERVAL 8 /* Seconds between each connection attempt */ #define SEND_TRIES 2 /* How many times to try sending a message */ #define BUFSZ_READ 2048 /* Minimum #bytes that must be free when read'ing into a buffer */ #define BUFSZ_INC 8192 /* How much to grow the buffer when it is too small */ #define MAX_OPEN_SOCKS 256 #define MINIMUM_FOR_COMBO 2048 /* To start merging messages, at least have 2 KB free */ #define MAXIMUM_FOR_COMBO 32768 /* Max. size of a combined message */ #define COMBO_DELAY 250000000 /* Delay before sending a combo message (in nanoseconds) */ int keeprunning = 1; time_t laststatus = 0; char *logfile = NULL; int logdetails = 0; unsigned long msgs_timeout_from[P_CLEANUP+1] = { 0, }; void sigmisc_handler(int signum) { switch (signum) { case SIGTERM: errprintf("Caught TERM signal, terminating\n"); keeprunning = 0; break; case SIGHUP: if (logfile) { reopen_file(logfile, "a", stdout); reopen_file(logfile, "a", stderr); errprintf("Caught SIGHUP, reopening logfile\n"); } break; case SIGUSR1: /* Toggle logging of details */ logdetails = (1 - logdetails); errprintf("Log details is %sabled\n", (logdetails ? "en" : "dis")); break; } } int overdue(struct timespec *now, struct timespec *limit) { if (now->tv_sec < limit->tv_sec) return 0; else if (now->tv_sec > limit->tv_sec) return 1; else return (now->tv_nsec >= limit->tv_nsec); } static int do_read(int sockfd, struct in_addr *addr, conn_t *conn, enum phase_t completedstate) { int n; if ((conn->buflen + BUFSZ_READ + 1) > conn->bufsize) { conn->bufsize += BUFSZ_INC; conn->buf = realloc(conn->buf, conn->bufsize); conn->bufp = conn->buf + conn->buflen; } n = read(sockfd, conn->bufp, (conn->bufsize - conn->buflen - 1)); if (n == -1) { /* Error - abort */ errprintf("READ error from %s: %s\n", inet_ntoa(*addr), strerror(errno)); msgs_timeout_from[conn->state]++; conn->state = P_CLEANUP; return -1; } else if (n == 0) { /* EOF - request is complete */ conn->state = completedstate; } else { conn->buflen += n; conn->bufp += n; *conn->bufp = '\0'; } return 0; } static int do_write(int sockfd, struct in_addr *addr, conn_t *conn, enum phase_t completedstate) { int n; n = write(sockfd, conn->bufp, conn->buflen); if (n == -1) { /* Error - abort */ errprintf("WRITE error to %s: %s\n", inet_ntoa(*addr), strerror(errno)); msgs_timeout_from[conn->state]++; conn->state = P_CLEANUP; return -1; } else if (n >= 0) { conn->buflen -= n; conn->bufp += n; if (conn->buflen == 0) { conn->state = completedstate; } } return 0; } void do_log(conn_t *conn) { char *rq, *eol, *delim; char savechar; rq = conn->buf+6; if (strncmp(rq, "combo\n", 6) == 0) rq += 6; eol = strchr(rq, '\n'); if (eol) *eol = '\0'; for (delim = rq; (*delim && isalpha((unsigned char) *delim)); delim++); for (; (*delim && isspace((unsigned char) *delim)); delim++); for (; (*delim && !isspace((unsigned char) *delim)); delim++); savechar = *delim; *delim = '\0'; errprintf("%s : %s\n", inet_ntoa(*conn->clientip), rq); *delim = savechar; if (eol) *eol = '\n'; } int main(int argc, char *argv[]) { int daemonize = 1; int timeout = 10; int listenq = 512; char *pidfile = "/var/run/xymonproxy.pid"; char *proxyname = NULL; char *proxynamesvc = "xymonproxy"; int sockcount = 0; int lsocket; struct sockaddr_in laddr; struct sockaddr_in xymonserveraddr[MAX_SERVERS]; int xymonservercount = 0; int opt; conn_t *chead = NULL; struct sigaction sa; int selectfailures = 0; /* Statistics info */ time_t startuptime = gettimer(); unsigned long msgs_total = 0; unsigned long msgs_total_last = 0; unsigned long msgs_combined = 0; unsigned long msgs_merged = 0; unsigned long msgs_delivered = 0; unsigned long msgs_status = 0; unsigned long msgs_combo = 0; unsigned long msgs_other = 0; unsigned long msgs_recovered = 0; struct timespec timeinqueue = { 0, 0 }; /* Don'T save the output from errprintf() */ save_errbuf = 0; memset(&laddr, 0, sizeof(laddr)); inet_aton("0.0.0.0", (struct in_addr *) &laddr.sin_addr.s_addr); laddr.sin_port = htons(1984); laddr.sin_family = AF_INET; for (opt=1; (opt < argc); opt++) { if (argnmatch(argv[opt], "--listen=")) { char *locaddr, *p; int locport; locaddr = strchr(argv[opt], '=')+1; p = strchr(locaddr, ':'); if (p) { locport = atoi(p+1); *p = '\0'; } else locport = 1984; memset(&laddr, 0, sizeof(laddr)); laddr.sin_port = htons(locport); laddr.sin_family = AF_INET; if (inet_aton(locaddr, (struct in_addr *) &laddr.sin_addr.s_addr) == 0) { errprintf("Invalid listen address %s\n", locaddr); return 1; } if (p) *p = ':'; } else if (argnmatch(argv[opt], "--server=") || argnmatch(argv[opt], "--bbdisplay=")) { char *ips, *ip1; int port1; ips = strdup(strchr(argv[opt], '=')+1); ip1 = strtok(ips, ","); while (ip1) { char *p; p = strchr(ip1, ':'); if (p) { port1 = atoi(p+1); *p = '\0'; } else port1 = 1984; memset(&xymonserveraddr[xymonservercount], 0, sizeof(xymonserveraddr[xymonservercount])); xymonserveraddr[xymonservercount].sin_port = htons(port1); xymonserveraddr[xymonservercount].sin_family = AF_INET; if (inet_aton(ip1, (struct in_addr *) &xymonserveraddr[xymonservercount].sin_addr.s_addr) == 0) { errprintf("Invalid remote address %s\n", ip1); } else { xymonservercount++; } if (p) *p = ':'; ip1 = strtok(NULL, ","); } xfree(ips); } else if (argnmatch(argv[opt], "--timeout=")) { char *p = strchr(argv[opt], '='); timeout = atoi(p+1); } else if (argnmatch(argv[opt], "--lqueue=")) { char *p = strchr(argv[opt], '='); listenq = atoi(p+1); } else if (strcmp(argv[opt], "--daemon") == 0) { daemonize = 1; } else if (strcmp(argv[opt], "--no-daemon") == 0) { daemonize = 0; } else if (argnmatch(argv[opt], "--pidfile=")) { char *p = strchr(argv[opt], '='); pidfile = strdup(p+1); } else if (argnmatch(argv[opt], "--logfile=")) { char *p = strchr(argv[opt], '='); logfile = strdup(p+1); } else if (strcmp(argv[opt], "--log-details") == 0) { logdetails = 1; } else if (argnmatch(argv[opt], "--report=")) { char *p1 = strchr(argv[opt], '=')+1; if (strchr(p1, '.') == NULL) { if (xgetenv("MACHINE") == NULL) { errprintf("Environment variable MACHINE is undefined\n"); return 1; } proxyname = strdup(xgetenv("MACHINE")); proxyname = (char *)realloc(proxyname, strlen(proxyname) + strlen(p1) + 1); strcat(proxyname, "."); strcat(proxyname, p1); proxynamesvc = strdup(p1); } else { proxyname = strdup(p1); proxynamesvc = strchr(proxyname, '.')+1; } } else if (strcmp(argv[opt], "--debug") == 0) { debug = 1; } else if (strcmp(argv[opt], "--version") == 0) { printf("xymonproxy version %s\n", VERSION); return 0; } else if (strcmp(argv[opt], "--help") == 0) { printf("xymonproxy version %s\n", VERSION); printf("\nOptions:\n"); printf("\t--listen=IP[:port] : Listen address and portnumber\n"); printf("\t--server=IP[:port] : Xymon server address and portnumber\n"); printf("\t--report=[HOST.]SERVICE : Sends a status message about proxy activity\n"); printf("\t--timeout=N : Communications timeout (seconds)\n"); printf("\t--lqueue=N : Listen-queue size\n"); printf("\t--daemon : Run as a daemon\n"); printf("\t--no-daemon : Do not run as a daemon\n"); printf("\t--pidfile=FILENAME : Save process-ID of daemon to FILENAME\n"); printf("\t--logfile=FILENAME : Log to FILENAME instead of stderr\n"); printf("\t--debug : Enable debugging output\n"); printf("\n"); return 0; } } if (xymonservercount == 0) { errprintf("No Xymon server address given - aborting\n"); return 1; } /* Set up a socket to listen for new connections */ lsocket = socket(AF_INET, SOCK_STREAM, 0); if (lsocket == -1) { errprintf("Cannot create listen socket (%s)\n", strerror(errno)); return 1; } opt = 1; setsockopt(lsocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); fcntl(lsocket, F_SETFL, O_NONBLOCK); if (bind(lsocket, (struct sockaddr *)&laddr, sizeof(laddr)) == -1) { errprintf("Cannot bind to listen socket (%s)\n", strerror(errno)); return 1; } if (listen(lsocket, listenq) == -1) { errprintf("Cannot listen (%s)\n", strerror(errno)); return 1; } /* Redirect logging to the logfile, if requested */ if (logfile) { reopen_file(logfile, "a", stdout); reopen_file(logfile, "a", stderr); } errprintf("xymonproxy version %s starting\n", VERSION); errprintf("Listening on %s:%d\n", inet_ntoa(laddr.sin_addr), ntohs(laddr.sin_port)); { int i; char *p; char srvrs[500]; for (i=0, srvrs[0] = '\0', p=srvrs; (i 0) { /* Parent - save PID and exit */ FILE *fd = fopen(pidfile, "w"); if (fd) { fprintf(fd, "%d\n", (int)childpid); fclose(fd); } exit(0); } /* Child (daemon) continues here */ setsid(); } setup_signalhandler(proxynamesvc); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigmisc_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); do { fd_set fdread, fdwrite; int maxfd; struct timespec tmo; struct timeval selecttmo; int n, idx; conn_t *cwalk, *ctmp; time_t ctime; time_t now; int combining = 0; /* See if it is time for a status report */ if (proxyname && ((now = gettimer()) >= (laststatus+300))) { conn_t *stentry; int ccount = 0; unsigned long bufspace = 0; unsigned long avgtime; /* In millisecs */ char runtime_s[30]; unsigned long runt = (unsigned long) (now-startuptime); char *p; unsigned long msgs_sent = msgs_total - msgs_total_last; /* Setup a conn_t struct for the status message */ stentry = (conn_t *)calloc(1, sizeof(conn_t)); stentry->state = P_REQ_READY; stentry->csocket = stentry->ssocket = -1; stentry->clientip = &stentry->caddr.sin_addr; getntimer(&stentry->arrival); stentry->timelimit.tv_sec = stentry->arrival.tv_sec + timeout; stentry->timelimit.tv_nsec = stentry->arrival.tv_nsec; stentry->bufsize = BUFSZ_INC; stentry->buf = (char *)malloc(stentry->bufsize); stentry->next = chead; chead = stentry; sprintf(runtime_s, "%lu days, %02lu:%02lu:%02lu", (runt/86400), ((runt % 86400) / 3600), ((runt % 3600) / 60), (runt % 60)); init_timestamp(); for (cwalk = chead; (cwalk); cwalk = cwalk->next) { ccount++; bufspace += cwalk->bufsize; } if (msgs_sent == 0) { avgtime = 0; } else { avgtime = (timeinqueue.tv_sec*1000 + timeinqueue.tv_nsec/1000) / msgs_sent; } p = stentry->buf; p += sprintf(p, "combo\nstatus+11 %s green %s - xymon proxy up: %s\n\nxymonproxy for Xymon version %s\n\nProxy statistics\n\nIncoming messages : %10lu (%lu msgs/second)\nOutbound messages : %10lu\n\nIncoming message distribution\n- Combo messages : %10lu\n- Status messages : %10lu\n Messages merged : %10lu\n Resulting combos : %10lu\n- Other messages : %10lu\n\nProxy resources\n- Connection table size : %10d\n- Buffer space : %10lu kByte\n", proxyname, timestamp, runtime_s, VERSION, msgs_total, (msgs_total - msgs_total_last) / (now - laststatus), msgs_delivered, msgs_combo, msgs_status, msgs_merged, msgs_combined, msgs_other, ccount, bufspace / 1024); p += sprintf(p, "\nTimeout/failure details\n"); p += sprintf(p, "- %-22s : %10lu\n", statename[P_REQ_READING], msgs_timeout_from[P_REQ_READING]); p += sprintf(p, "- %-22s : %10lu\n", statename[P_REQ_CONNECTING], msgs_timeout_from[P_REQ_CONNECTING]); p += sprintf(p, "- %-22s : %10lu\n", statename[P_REQ_SENDING], msgs_timeout_from[P_REQ_SENDING]); p += sprintf(p, "- %-22s : %10lu\n", "recovered", msgs_recovered); p += sprintf(p, "- %-22s : %10lu\n", statename[P_RESP_READING], msgs_timeout_from[P_RESP_READING]); p += sprintf(p, "- %-22s : %10lu\n", statename[P_RESP_SENDING], msgs_timeout_from[P_RESP_SENDING]); p += sprintf(p, "\n%-24s : %10lu.%03lu\n", "Average queue time", (avgtime / 1000), (avgtime % 1000)); /* Clear the summary collection totals */ laststatus = now; msgs_total_last = msgs_total; timeinqueue.tv_sec = timeinqueue.tv_nsec = 0; stentry->buflen = strlen(stentry->buf); stentry->bufp = stentry->buf + stentry->buflen; stentry->state = P_REQ_READY; } FD_ZERO(&fdread); FD_ZERO(&fdwrite); maxfd = -1; combining = 0; for (cwalk = chead, idx=0; (cwalk); cwalk = cwalk->next, idx++) { dbgprintf("state %d: %s\n", idx, statename[cwalk->state]); /* First, handle any state transitions and setup the FD sets for select() */ switch (cwalk->state) { case P_REQ_READING: FD_SET(cwalk->csocket, &fdread); if (cwalk->csocket > maxfd) maxfd = cwalk->csocket; break; case P_REQ_READY: if (cwalk->buflen <= 6) { /* Got an empty request - just drop it */ dbgprintf("Dropping empty request from %s\n", inet_ntoa(*cwalk->clientip)); cwalk->state = P_CLEANUP; break; } if (logdetails) do_log(cwalk); cwalk->conntries = CONNECT_TRIES; cwalk->sendtries = SEND_TRIES; cwalk->conntime = 0; /* * We now want to find out what kind of message we've got. * If it's NOT a "status" message, just pass it along. * For "status" messages, we want to try and merge many small * messages into a "combo" message - so send those off the the * P_REQ_COMBINING state for a while. * If we are not going to send back a response to the client, we * also close the client socket since it is no longer needed. * Note that since we started out as optimists and put a "combo\n" * at the front of the buffer, we need to skip that when looking at * what type of message it is. Hence the "cwalk->buf+6". */ if (strncmp(cwalk->buf+6, "client", 6) == 0) { /* * "client" messages go to all Xymon servers, but * we will only pass back the response from one of them * (the last one). */ shutdown(cwalk->csocket, SHUT_RD); msgs_other++; cwalk->snum = xymonservercount; if ((cwalk->buflen + 40 ) < cwalk->bufsize) { int n = sprintf(cwalk->bufp, "\n[proxy]\nClientIP:%s\n", inet_ntoa(*cwalk->clientip)); cwalk->bufp += n; cwalk->buflen += n; } } else if ((strncmp(cwalk->buf+6, "query", 5) == 0) || (strncmp(cwalk->buf+6, "config", 6) == 0) || (strncmp(cwalk->buf+6, "ping", 4) == 0) || (strncmp(cwalk->buf+6, "download", 8) == 0)) { /* * These requests get a response back, but send no data. * Send these to the last of the Xymon servers only. */ shutdown(cwalk->csocket, SHUT_RD); msgs_other++; cwalk->snum = 1; } else { /* It's a request that doesn't take a response. */ if (cwalk->csocket >= 0) { shutdown(cwalk->csocket, SHUT_RDWR); close(cwalk->csocket); sockcount--; cwalk->csocket = -1; } cwalk->snum = xymonservercount; if (strncmp(cwalk->buf+6, "status", 6) == 0) { msgs_status++; getntimer(&cwalk->timelimit); cwalk->timelimit.tv_nsec += COMBO_DELAY; if (cwalk->timelimit.tv_nsec >= 1000000000) { cwalk->timelimit.tv_sec++; cwalk->timelimit.tv_nsec -= 1000000000; } /* * Some clients (bbnt) send a trailing \0, so we cannot * rely on buflen being what we want it to be. */ cwalk->buflen = strlen(cwalk->buf); cwalk->bufp = cwalk->buf + cwalk->buflen; if ((cwalk->buflen + 50 ) < cwalk->bufsize) { int n = sprintf(cwalk->bufp, "\nStatus message received from %s\n", inet_ntoa(*cwalk->clientip)); cwalk->bufp += n; cwalk->buflen += n; } cwalk->state = P_REQ_COMBINING; break; } else if (strncmp(cwalk->buf+6, "combo\n", 6) == 0) { char *currmsg, *nextmsg; msgs_combo++; /* * Some clients (bbnt) send a trailing \0, so we cannot * rely on buflen being what we want it to be. */ cwalk->buflen = strlen(cwalk->buf); cwalk->bufp = cwalk->buf + cwalk->buflen; getntimer(&cwalk->timelimit); cwalk->timelimit.tv_nsec += COMBO_DELAY; if (cwalk->timelimit.tv_nsec >= 1000000000) { cwalk->timelimit.tv_sec++; cwalk->timelimit.tv_nsec -= 1000000000; } currmsg = cwalk->buf+12; /* Skip pre-def. "combo\n" and message "combo\n" */ do { nextmsg = strstr(currmsg, "\n\nstatus"); if (nextmsg) { *(nextmsg+1) = '\0'; nextmsg += 2; } /* Create a duplicate conn_t record for all embedded messages */ ctmp = (conn_t *)malloc(sizeof(conn_t)); memcpy(ctmp, cwalk, sizeof(conn_t)); ctmp->bufsize = BUFSZ_INC*(((6 + strlen(currmsg) + 50) / BUFSZ_INC) + 1); ctmp->buf = (char *)malloc(ctmp->bufsize); ctmp->buflen = sprintf(ctmp->buf, "combo\n%s\nStatus message received from %s\n", currmsg, inet_ntoa(*cwalk->clientip)); ctmp->bufp = ctmp->buf + ctmp->buflen; ctmp->state = P_REQ_COMBINING; ctmp->next = chead; chead = ctmp; currmsg = nextmsg; } while (currmsg); /* We don't do anymore with this conn_t */ cwalk->state = P_CLEANUP; break; } else if (strncmp(cwalk->buf+6, "page", 4) == 0) { /* xymond has no use for page requests */ cwalk->state = P_CLEANUP; break; } else { msgs_other++; } } /* * This wont be made into a combo message, so skip the "combo\n" * and go off to send the message to the server. */ cwalk->bufp = cwalk->buf+6; cwalk->buflen -= 6; cwalk->bufpsave = cwalk->bufp; cwalk->buflensave = cwalk->buflen; cwalk->state = P_REQ_CONNECTING; /* Fall through for non-status messages */ case P_REQ_CONNECTING: /* Need to restore the bufp and buflen, as we may get here many times for one message */ cwalk->bufp = cwalk->bufpsave; cwalk->buflen = cwalk->buflensave; ctime = gettimer(); if (ctime < (cwalk->conntime + CONNECT_INTERVAL)) { dbgprintf("Delaying retry of connection\n"); break; } cwalk->conntries--; cwalk->conntime = ctime; if (cwalk->conntries < 0) { errprintf("Server not responding, message lost\n"); cwalk->state = P_REQ_DONE; /* Not CLENAUP - might be more servers */ msgs_timeout_from[P_REQ_CONNECTING]++; break; } cwalk->ssocket = socket(AF_INET, SOCK_STREAM, 0); if (cwalk->ssocket == -1) { dbgprintf("Could not get a socket - will try again\n"); break; /* Retry the next time around */ } sockcount++; fcntl(cwalk->ssocket, F_SETFL, O_NONBLOCK); { int idx = (xymonservercount - cwalk->snum); n = connect(cwalk->ssocket, (struct sockaddr *)&xymonserveraddr[idx], sizeof(xymonserveraddr[idx])); cwalk->serverip = &xymonserveraddr[idx].sin_addr; dbgprintf("Connecting to Xymon server at %s\n", inet_ntoa(*cwalk->serverip)); } if ((n == 0) || ((n == -1) && (errno == EINPROGRESS))) { cwalk->state = P_REQ_SENDING; cwalk->connectpending = 1; getntimer(&cwalk->timelimit); cwalk->timelimit.tv_sec += timeout; /* Fallthrough */ } else { /* Could not connect! Invoke retries */ dbgprintf("Connect to server failed: %s\n", strerror(errno)); close(cwalk->ssocket); sockcount--; cwalk->ssocket = -1; break; } /* No "break" here! */ case P_REQ_SENDING: FD_SET(cwalk->ssocket, &fdwrite); if (cwalk->ssocket > maxfd) maxfd = cwalk->ssocket; break; case P_REQ_DONE: /* Request has been sent to the server - we're done writing data */ shutdown(cwalk->ssocket, SHUT_WR); cwalk->snum--; if (cwalk->snum) { /* More servers to do */ close(cwalk->ssocket); cwalk->ssocket = -1; sockcount--; cwalk->conntries = CONNECT_TRIES; cwalk->sendtries = SEND_TRIES; cwalk->conntime = 0; cwalk->state = P_REQ_CONNECTING; break; } else { /* Have sent to all servers, grab the response from the last one. */ cwalk->bufp = cwalk->buf; cwalk->buflen = 0; memset(cwalk->buf, 0, cwalk->bufsize); } msgs_delivered++; if (cwalk->sendtries < SEND_TRIES) { errprintf("Recovered from write error after %d retries\n", (SEND_TRIES - cwalk->sendtries)); msgs_recovered++; } if (cwalk->arrival.tv_sec > 0) { struct timespec departure; getntimer(&departure); timeinqueue.tv_sec += (departure.tv_sec - cwalk->arrival.tv_sec); if (departure.tv_nsec >= cwalk->arrival.tv_nsec) { timeinqueue.tv_nsec += (departure.tv_nsec - cwalk->arrival.tv_nsec); } else { timeinqueue.tv_sec--; timeinqueue.tv_nsec += (1000000000 + departure.tv_nsec - cwalk->arrival.tv_nsec); } if (timeinqueue.tv_nsec > 1000000000) { timeinqueue.tv_sec++; timeinqueue.tv_nsec -= 1000000000; } } else { errprintf("Odd ... this message was not timestamped\n"); } if (cwalk->csocket < 0) { cwalk->state = P_CLEANUP; break; } else { cwalk->state = P_RESP_READING; getntimer(&cwalk->timelimit); cwalk->timelimit.tv_sec += timeout; } /* Fallthrough */ case P_RESP_READING: FD_SET(cwalk->ssocket, &fdread); if (cwalk->ssocket > maxfd) maxfd = cwalk->ssocket; break; case P_RESP_READY: shutdown(cwalk->ssocket, SHUT_RD); close(cwalk->ssocket); sockcount--; cwalk->ssocket = -1; cwalk->bufp = cwalk->buf; cwalk->state = P_RESP_SENDING; getntimer(&cwalk->timelimit); cwalk->timelimit.tv_sec += timeout; /* Fall through */ case P_RESP_SENDING: if (cwalk->buflen && (cwalk->csocket >= 0)) { FD_SET(cwalk->csocket, &fdwrite); if (cwalk->csocket > maxfd) maxfd = cwalk->csocket; break; } else { cwalk->state = P_RESP_DONE; } /* Fall through */ case P_RESP_DONE: if (cwalk->csocket >= 0) { shutdown(cwalk->csocket, SHUT_WR); close(cwalk->csocket); sockcount--; } cwalk->csocket = -1; cwalk->state = P_CLEANUP; /* Fall through */ case P_CLEANUP: if (cwalk->csocket >= 0) { close(cwalk->csocket); sockcount--; cwalk->csocket = -1; } if (cwalk->ssocket >= 0) { close(cwalk->ssocket); sockcount--; cwalk->ssocket = -1; } cwalk->arrival.tv_sec = cwalk->arrival.tv_nsec = 0; cwalk->bufp = cwalk->buf; cwalk->buflen = 0; memset(cwalk->buf, 0, cwalk->bufsize); memset(&cwalk->caddr, 0, sizeof(cwalk->caddr)); cwalk->madetocombo = 0; cwalk->state = P_IDLE; break; case P_IDLE: break; case P_REQ_COMBINING: /* See if we can combine some "status" messages into a "combo" */ combining++; getntimer(&tmo); if ((cwalk->buflen < MINIMUM_FOR_COMBO) && !overdue(&tmo, &cwalk->timelimit)) { conn_t *cextra; /* Are there any other messages in P_COMBINING state ? */ cextra = cwalk->next; while (cextra && (cextra->state != P_REQ_COMBINING)) cextra = cextra->next; if (cextra) { /* * Yep. It might be worthwhile to go for a combo. */ while (cextra && (cwalk->buflen < (MAXIMUM_FOR_COMBO-20))) { if (strncmp(cextra->buf+6, "status", 6) == 0) { int newsize; /* * Size of the new message - if the cextra one * is merged - is the cwalk buffer, plus the * two newlines separating messages in combo's, * plus the cextra buffer except the leading * "combo\n" of 6 bytes. */ newsize = cwalk->buflen + 2 + (cextra->buflen - 6); if ((newsize < cwalk->bufsize) && (newsize < MAXIMUM_FOR_COMBO)) { /* * There's room for it. Add it to the * cwalk buffer, but without the leading * "combo\n" (we already have one of those). */ cwalk->madetocombo++; strcat(cwalk->buf, "\n\n"); strcat(cwalk->buf, cextra->buf+6); cwalk->buflen = newsize; cextra->state = P_CLEANUP; dbgprintf("Merged combo\n"); msgs_merged++; } } /* Go to the next connection in the right state */ do { cextra = cextra->next; } while (cextra && (cextra->state != P_REQ_COMBINING)); } } } else { combining--; cwalk->state = P_REQ_CONNECTING; if (cwalk->madetocombo) { /* * Point the outgoing buffer pointer to the full * message, including the "combo\n" */ cwalk->bufp = cwalk->buf; cwalk->madetocombo++; msgs_merged++; /* Count the proginal message also */ msgs_combined++; dbgprintf("Now going to send combo from %d messages\n%s\n", cwalk->madetocombo, cwalk->buf); } else { /* * Skip sending the "combo\n" at start of buffer. */ cwalk->bufp = cwalk->buf+6; cwalk->buflen -= 6; dbgprintf("No messages to combine - sending unchanged\n"); } } cwalk->bufpsave = cwalk->bufp; cwalk->buflensave = cwalk->buflen; break; default: break; } } /* Add the listen-socket to the select() list, but only if we have room */ if (sockcount < MAX_OPEN_SOCKS) { FD_SET(lsocket, &fdread); if (lsocket > maxfd) maxfd = lsocket; } else { static time_t lastlog = 0; if ((now = gettimer()) < (lastlog+30)) { lastlog = now; errprintf("Squelching incoming connections, sockcount=%d\n", sockcount); } } if (combining) { selecttmo.tv_sec = 0; selecttmo.tv_usec = COMBO_DELAY / 1000; } else { selecttmo.tv_sec = 1; selecttmo.tv_usec = 0; } n = select(maxfd+1, &fdread, &fdwrite, NULL, &selecttmo); if (n < 0) { errprintf("select() failed: %s\n", strerror(errno)); if (++selectfailures > 5) { errprintf("Too many select failures, aborting\n"); exit(1); } } else if (n == 0) { /* Timeout */ if (selectfailures > 0) selectfailures--; getntimer(&tmo); for (cwalk = chead; (cwalk); cwalk = cwalk->next) { switch (cwalk->state) { case P_REQ_READING: case P_REQ_SENDING: case P_RESP_READING: case P_RESP_SENDING: if (overdue(&tmo, &cwalk->timelimit)) { cwalk->state = P_CLEANUP; msgs_timeout_from[cwalk->state]++; } break; default: break; } } } else { if (selectfailures > 0) selectfailures--; for (cwalk = chead; (cwalk); cwalk = cwalk->next) { switch (cwalk->state) { case P_REQ_READING: if (FD_ISSET(cwalk->csocket, &fdread)) { do_read(cwalk->csocket, cwalk->clientip, cwalk, P_REQ_READY); } break; case P_REQ_SENDING: if (FD_ISSET(cwalk->ssocket, &fdwrite)) { if (cwalk->connectpending) { int connres, connressize; /* First time ready for write - check connect status */ cwalk->connectpending = 0; connressize = sizeof(connres); n = getsockopt(cwalk->ssocket, SOL_SOCKET, SO_ERROR, &connres, &connressize); if (connres != 0) { /* Connect failed! Invoke retries. */ dbgprintf("Connect to server failed: %s - retrying\n", strerror(errno)); close(cwalk->ssocket); sockcount--; cwalk->ssocket = -1; cwalk->state = P_REQ_CONNECTING; break; } } if ( (do_write(cwalk->ssocket, cwalk->serverip, cwalk, P_REQ_DONE) == -1) && (cwalk->sendtries > 0) ) { /* * Got a "write" error after connecting. * Try saving the situation by retrying the send later. */ dbgprintf("Attempting recovery from write error\n"); close(cwalk->ssocket); sockcount--; cwalk->ssocket = -1; cwalk->sendtries--; cwalk->state = P_REQ_CONNECTING; cwalk->conntries = CONNECT_TRIES; cwalk->conntime = gettimer(); } } break; case P_RESP_READING: if (FD_ISSET(cwalk->ssocket, &fdread)) { do_read(cwalk->ssocket, cwalk->serverip, cwalk, P_RESP_READY); } break; case P_RESP_SENDING: if (FD_ISSET(cwalk->csocket, &fdwrite)) { do_write(cwalk->csocket, cwalk->clientip, cwalk, P_RESP_DONE); } break; default: break; } } if (FD_ISSET(lsocket, &fdread)) { /* New incoming connection */ conn_t *newconn; int caddrsize; dbgprintf("New connection\n"); for (cwalk = chead; (cwalk && (cwalk->state != P_IDLE)); cwalk = cwalk->next); if (cwalk) { newconn = cwalk; } else { newconn = malloc(sizeof(conn_t)); newconn->next = chead; chead = newconn; newconn->bufsize = BUFSZ_INC; newconn->buf = newconn->bufp = malloc(newconn->bufsize); } newconn->connectpending = 0; newconn->madetocombo = 0; newconn->snum = 0; newconn->ssocket = -1; newconn->serverip = NULL; newconn->conntries = 0; newconn->sendtries = 0; newconn->timelimit.tv_sec = newconn->timelimit.tv_nsec = 0; /* * Why this ? Because we like to merge small status messages * into larger combo messages. So put a "combo\n" at the start * of the buffer, and then don't send it if we decide it won't * be a combo-message after all. */ strcpy(newconn->buf, "combo\n"); newconn->buflen = 6; newconn->bufp = newconn->buf+6; caddrsize = sizeof(newconn->caddr); newconn->csocket = accept(lsocket, (struct sockaddr *)&newconn->caddr, &caddrsize); if (newconn->csocket == -1) { /* accept() failure. Yes, it does happen! */ dbgprintf("accept failure, ignoring connection (%s), sockcount=%d\n", strerror(errno), sockcount); newconn->state = P_IDLE; } else { msgs_total++; newconn->clientip = &newconn->caddr.sin_addr; sockcount++; fcntl(newconn->csocket, F_SETFL, O_NONBLOCK); newconn->state = P_REQ_READING; getntimer(&newconn->arrival); newconn->timelimit.tv_sec = newconn->arrival.tv_sec + timeout; newconn->timelimit.tv_nsec = newconn->arrival.tv_nsec; } } } /* Clean up unused conn_t's */ { conn_t *tmp, *khead; khead = NULL; cwalk = chead; while (cwalk) { if ((cwalk == chead) && (cwalk->state == P_IDLE)) { /* head of chain is dead */ tmp = chead; chead = chead->next; tmp->next = khead; khead = tmp; cwalk = chead; } else if (cwalk->next && (cwalk->next->state == P_IDLE)) { tmp = cwalk->next; cwalk->next = tmp->next; tmp->next = khead; khead = tmp; /* cwalk is unchanged */ } else { cwalk = cwalk->next; } } /* khead now holds a list of P_IDLE conn_t structs */ while (khead) { tmp = khead; khead = khead->next; if (tmp->buf) xfree(tmp->buf); xfree(tmp); } } } while (keeprunning); if (pidfile) unlink(pidfile); return 0; } xymon-4.3.30/xymonproxy/Makefile0000664000076400007640000000255512050700262017120 0ustar rpmbuildrpmbuild# xymonproxy Makefile XYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(ZLIBLIBS) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) PROGRAMS = xymonproxy xymoncgimsg.cgi PROXYOBJS = xymonproxy.o MSGCGIOBJS = xymoncgimsg.o all: $(PROGRAMS) xymonproxy: $(PROXYOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(PROXYOBJS) $(XYMONCOMMLIBS) $(XYMONTIMELIBS) $(XYMONLIBS) xymoncgimsg.cgi: $(MSGCGIOBJS) $(XYMONCOMMLIB) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(MSGCGIOBJS) $(XYMONCOMMLIBS) $(XYMONLIBS) ################################################ # Default compilation rules ################################################ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f *.o *.a *~ $(PROGRAMS) install: install-bin install-man install-bin: ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ install-man: mkdir -p $(INSTALLROOT)$(MANROOT)/man8 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man8 *.8 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man8 *.8 chmod 755 $(INSTALLROOT)$(MANROOT)/man8 chmod 644 *.8 endif cp -fp *.8 $(INSTALLROOT)$(MANROOT)/man8/ xymon-4.3.30/xymonproxy/xymoncgimsg.cgi.80000664000076400007640000000305513534041732020662 0ustar rpmbuildrpmbuild.TH XYMONCGIMSG.CGI 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymoncgimsg.cgi \- CGI utility used for proxying Xymon data over HTTP .SH SYNOPSIS .B "xymoncgimsg.cgi" .SH DESCRIPTION .I xymoncgimsg.cgi(8) is the server-side utility receiving Xymon messages sent by the .I xymon(1) utility over an HTTP transport. The \fBxymon\fR utility normally sends data over a dedicated TCP protocol, but it may use HTTP to go through proxies or through restrictive firewalls. In that case, the webserver must have this CGI utility installed, which takes care of receiving the message via HTTP, and forwards it to a local Xymon server through the normal Xymon transport. The CGI expects to be invoked from an HTTP "POST" request, with the POST-data being the status-message. \fBxymoncgimsg.cgi\fR simply collects all of the POST data, and send it off as a message to the Xymon daemon running on IP 127.0.0.1. This destination IP currently cannot be changed. The CGI will return any output provided by the Xymon daemon back to the requestor as the response to the HTTP POST, so this allows for all normal Xymon commands to work. .SH SECURITY \fBxymoncgimsg.cgi\fR will only send data to a Xymon server through the loopback interface, i.e. IP-address 127.0.0.1. Access to the CGI should be restricted through webserver access controls, since the CGI provides no authentication at all to validate incoming messages. If possible, consider using the .I xymonproxy(8) utility instead for native proxying of Xymon data between networks. .SH "SEE ALSO" xymon(1), xymonproxy(8), xymon(7) xymon-4.3.30/RELEASENOTES0000664000076400007640000005710213534024677015037 0ustar rpmbuildrpmbuild <<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>> * * * Release notes for Xymon 4.3.30 * * * <<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>> This documents the important changes between Xymon releases, i.e. changes you should be aware of when upgrading. For a full list of changes and enhancements, please see the Changes file. Changes for 4.3.30 ================== Various crashes and bugs relating to string handling changes have been fixed, including problems with hostnames with dashes in them. Combostatus tests propagated up from other combostatus tests should now display properly. Changes for 4.3.29 ================== Several buffer overflow security issues have been resolved, as well as a potential XSS attack on certain CGI interfaces. Although the ability to exploit is limited, all users are urged to upgrade. The assigned CVE numbers are: CVE-2019-13451, CVE-2019-13452, CVE-2019-13455, CVE-2019-13473, CVE-2019-13474, CVE-2019-13484, CVE-2019-13485, CVE-2019-13486 In addition, revisions have been made to a number of places throughout the code to convert the most common sprintf statements to snprintf for safer processing, which should reduce the impact of similar parsing. Additional work on this will continue in the future. The affected CGIs are: history.c (overflow of histlogfn) = CVE-2019-13451 reportlog.c (overflow of histlogfn) = CVE-2019-13452 csvinfo.c (overflow of dbfn) = CVE-2019-13273 csvinfo.c (reflected XSS) = CVE-2019-13274 acknowledge.c (overflow of msgline) = CVE-2019-13455 appfeed.c (overflow of errtxt) = CVE-2019-13484 history.c (overflow of selfurl) = CVE-2019-13485 svcstatus.c (overflow of errtxt) = CVE-2019-13486 We would like to thank the University of Cambridge Computer Security Incident Response Team for their assistance in reporting and helping resolve these issues. Additional Changes: On Linux, a few additional tmpfs volumes are ignored by default on new (or unmodified) installs. This includes /run/user/, which is a transient, per-session tmpfs on some systems. To re- enable monitoring for this (if you are running services under a user with a login session), you may need to edit the analysis.cfg(5) file. After upgrade, these partitions will no longer be alerted on or tracked, and their associated RRD files may also be removed: /run/user/ (but NOT /run) /dev (but NOT /dev/shm) /sys/fs/cgroup /lib/init/rw The default hard limit for an incoming message has been raised from 10MB to 64MB The secure apache config snippet no longer requires a xymongroups file to be present (and module loaded), since it's not used by default. This will not affect existing installs. A --no-cpu-listing option has been added to xymond_client to suppress the 'top' output in cpu test status messages. The conversation used in SMTP checks has been adjusted to perform a proper "EHLO" greeting against servers, using the host string 'xymonnet'. If the string needs to be adjusted, however, see protocols.cfg(5) "Actual" memory usage (as a percentage) may be >100% on some platforms in certain situations. This alone will not be tagged as "invalid" data and should be graphed in RRD. Changes for 4.3.28 ================== OpenSSL 1.1.0 is now supported. Specific TLS variants (1.0, 1.1, and 1.2) can be selected for an HTTP test using new protocol tags (see hosts.cfg(5)) OpenSSL 1.0.1+ is required. The bundled version of c-ares (for hosts without a system lib) has been updated to 1.12.0 Xymond_alert should now provide more stable behavior when hosts are dropped or alerts go stale between launches. Summary messages are properly working again. SCRIPT message sizes are now limited only by environment memory and can be increased by adding a MAXMSG_ALERTSCRIPT variable to your xymonserver.cfg file A number of typos have been corrected. The RRD definition for the netstat graph has been tweaked to give a more readable layout. Changes for 4.3.27 ================== Fixes for CGI acknowledgements and NK/criticalview web redirects. Xymon should now properly check for lack of SSLv3 (or v2) support at compile- time and exclude the openssl options as needed. Completely empty directories (on Windows) are no longer considered errors. Changes for 4.3.26 ================== This is mostly a bug fix release for javascript issues on the info and trends pages, along with the enable / disable CGI. Several browsers had difficulty with the new CSP rules introduced in 4.3.25. XYMWEBREFRESH is now used as the default refresh interval for dynamic status pages and various other xymongen destinations. Non-svcstatus pages can be overridden by altering the appropriate *_header template files, but svcstatus refresh interval uses this value. (default: 60s) Set in xymonserver.cfg(5). Incoming test names are now restricted to alphanumeric characters, colons dashes, underscores, and slashes. Slashes and colons may be restricted in a future release. Unconfigured (ghost) host names are now restricted to alphanumerics, colons, commas, periods, dashes, and underscores. It is strongly recommended to use only valid hostnames and DNS components in servers names. Files matched multiple times by logfetch in the client config retrieved from config-local.cfg (such as a file matching multiple globs) will now only be scanned once and only use the ignore/trigger rules from its first entry. (Note: A future version of Xymon may combine all matching rules for a file together.) CLASS groupings in analysis.cfg and alerts.cfg will now reliably work for hosts with a CLASS override in hosts.cfg. Previous, this class was not used in favor of the class type sent in on any specific client message. Changes for 4.3.25 ================== Several security issues have been resolved relating to "config" messages and Cross-Site-Scripting vulnerabilities in the web interface. We would like to thank Markus Krell for reporting the following security issues and for his assistance in working with us to resolve them. (CVE-2016-2054) - Buffer overflow when handling "config" file requests. (CVE-2016-2056) - Shell command injection vulnerability in useradm.sh and chpasswd.sh. (CVE-2016-2055) - Credential leakage with "config" file requests. The default suggested location for htpasswd files used in securing the CGI interface had been $XYMONHOME/etc/ and documentation did not mention that this file should ONLY be readable by the apache/webserver user. Administrators should verify this file is not readable by the xymon user and modify ownership and permissions as needed. Additionally, the following restrictions have been added to files requested via "config" messages sent to xymond: - They must be regular files as returned by stat (no symlinks) - They must end in ".cfg" The restriction on file names ending in ".cfg" can be overridden by setting ALLOWALLCONFIGFILES="TRUE" in xymonserver.cfg and restarting xymond. Note that config files are processed through normal xymon file reading, so features such as "include" and "directory" still work when retrieving files over the network. These included files are not subject to the same restrictions. (CVE-2016-2057) - The xymond feedback queue (or BFQ) had been being created using insecure permissions, allowing any local user to write messages into the queue. This has been resolved and the queue is now created 0620 to the xymon user. If present xymond will attempt to re-create it using the correct permissions, but this process may not succeed on all OS's. Administrators should verify queue permissions using ipcs and delete the key manually with ipcrm if needed. (CVE-2016-2058) - Dynamic and historical status pages generated by the CGI interface now include Content-Security-Policy headers to prevent javascript execution from the payload of status messages themselves. The built-in functionality can be overridden by setting XYMON_NOCSPHEADER in xymonserver.cfg, if you wish to override this via an apache configuration. Additional changes: A bug introduced in 4.3.22 that could cause xymond_alert to fail to alert after seeing an unknown (newly added) host alert for the first time has been fixed. Additionally, xymond_alert now regularly reloads the hosts.cfg file to pick up changes. The "Actual" memory value on Windows systems will be reported more accurately. (Thanks, John Rothlisberger) A trends_header and trends_footer have been added in the /web/ templates directory for use on trends display pages. The xymonclient.cfg file now has a section for passing options to xymond_client and logfetch without having to edit the script. The logfetch command now accepts --noexec as an option to inhibit running commands from the client config used to list files to scan for messages. The logfetch command can use a file glob(7) in client-local.cfg (or localclient.cfg) indicated by angle brackets. This is more efficient and more secure than executing an `ls` command when matching known file or log patterns. The xymon.sh script now better matches LSB exit code expectations. The --processor argument to xymond_rrd, allowing RRD data (ie, metrics) to be easily sent to an external system such as OpenTSDB has been properly documented. All users of previous versions are strongly urged to upgrade. Changes for 4.3.24 ================== Fixes a bug introduced in 4.3.22 where the non-excepted HTTP status codes were always seen as Critical instead of OK/Warning as intended. All users are urged to upgrade. Changes for 4.3.23 ================== Fixes a bug in 4.3.22 where RRD tracking of number of matching processes or ports open on a client was not being performed. Changes for 4.3.22 ================== The default rules for HTTP response codes have been simplified and made more generic: 1xx = Warning (when the final code received) 2xx = OK 3xx = Warning (except 302/303/307 = OK) 4xx = Critical 5xx = Critical The specific changes from previous versions are: - 401 and 403 response codes are now considered Critical (were OK) - 301 Permanent Redirect response code is now considered a Warning (was OK) - "Extended" or new HTTP status codes in the 4xx and 5xx range are now considered Critical (unknown codes were previously a Warning) In the case of 301, 401, and 403 HTTP codes, if you're expecting to receive this HTTP status from a URL query, you should add the code explicitly to the check by using the "httpstatus" syntax (see hosts.cfg(5)). Basic HTTP Authentication is supported for testing logins to a site. *** Special note: Many vendor-supplied default "Welcome" pages on unconfigured apache servers are actually generated by a 403 error handler. Generically testing for these pages will now show a red status instead of a green one. To fix, simply place an index.html page at the root of the site so that 403's are not generated. The 'sslcert' test will now indicate the signature algorithm and cipher that was actually used in the connection, instead of a list of all ciphers. Use --showallciphers to restore the previous behavior. On new installs, the default apache configuration no longer requires a trailing slash when accessing the xymon pages. http://www.example.com/xymon will work. NTPDATEOPTS, FPINGOPTS, and TRACEROUTEOPTS variables are now present in xymonserver.cfg and will override the default options for the associated xymonnet calls. Note: The suggested options to 'traceroute' were never actually used as the default on a standard installation. In a future release, '-n -q 2 -w 2 -m 15' may be used unless overridden or otherwise specified. Darwin clients (Mac OS X) now exclude AFS and read-only volumes (which are usually just mounted disk images) from processing, properly handle volumes with spaces in their names, and correctly process inode details. A chpasswd.sh file is now provided which allows a logged-in user to change their own .htpasswd password (after verification). Because it verifies their existing password first, it requires the '-v' option to htpasswd, which is only available in Apache 2.4.5 or higher. By default, it is installed in the /xymon-seccgi/ directory, but can be moved to the /xymon-cgi/ directory to allow all users to change their password. Basic input validation is provided, but this CGI should be used with caution and only with relatively-trusted user bases. xymongen used to skip over host groups on pages when it calcuated that there were no test results to be displayed in that table. These groups are now displayed, but you can restore the previous behavior by passing it the --no-showemptygroups option. Changes for 4.3.21 ================== RSS feeds should now display the short description of the event again. Changes for 4.3.20 ================== Remote summaries display had been broken for a while but should now be working again. Summaries are now also displayed on the nongreen.html page The "Actual Used" memory figure on recent Linux kernels is now taken from the "Available" memory reported back from free (or /proc/meminfo), which should give a more accurate response. Physical Memory Used is still reported as the combination of Kernel Physical Use + buffers/cache, however this may change in a future release. Documentation for various directives in hosts.cfg(5) has been added pulldata=IP:PORT directives are honored, if the defaults for the host are incorrect cgiwrap is now installed via hardlinking (or as packaged); FollowSymLinks is no longer needed for the xymon cgi-bin directories and can be removed. Planned downtime settings are now applied to 'purple' statuses as well http checks can now be performed using a HEAD request if desired. Which RRD graphs are displayed on a status page can now be customized on a per-test basis through the use of environment variables. For example, GRAPHS_cpu="la,vmstat1" will cause an additional graph to be shown on cpu tests. (Submitted by Werner Maier) A new column will be displayed on all xymon pages allowing direct access to a server's raw clientlog (similar to the special info and trends columns). This can be disabled with a "noclient" tag in hosts.cfg Additional sample protocols.cfg services are present, for svn, amqp(s) and ircd. (Note that different ircd servers respond differently and the included protocol conversation may require modification to work on your server.) Changes for 4.3.19 ================== This is mostly a bugfix release (see the Changes file for a full list), but there are some enhancements: Apache 2.4 syntax is now supported by the sample xymon.conf file. EXTIME= syntax in analysis.cfg and alerts.cfg files is now supported. Note that this exclusion is applied *after* any normal TIME= specifiers. (If a TIME= modifier is present, then times outside of that range are already excluded.) An Acknowledgements report CGI is now available, similar to the Notifications report. (Thanks, Andy Smith) Client logs with multiple trigger lines found are guaranteed to have all the sections returned, even if this exceeds the "maxbytes" specified (up to the compiled-in limit). Additionally, the "current" location of new log data written since the last time xymonclient was run is now marked for reference. (Thanks, Franco Gasperino) A new "deltacount" option is available in client-local.cfg. It functions similarly to "linecount" for a given log: entry, but only counts matching lines written in the log file since the last run. Additional filtration options are available for the xymondboard command, including the full body of the message, and acknoweldgement and disable comments. Also, inequalities can be used to filter an epoch timestamp against any of: lastchange, logtime, validtime, acktime, or disabletime. See the xymon(1) man page for details. The process list visible in the 'procs' test of Linux and FreeBSD clients is now generated in ASCII "forest" mode for increased legibility. Changes for 4.3.18 ================== 4.3.18 fixes a buffer overflow vulnerability in the acknowledge.cgi script (CVE-2015-1430). All users are encouraged to upgrade. Thank you to Mark Felder for noting the impact and Martin Lenko for the original patch. In previous versions, the Xymon web CGI programs were run through a shell-script wrapper, which took care of setting up the environment for the Xymon programs. In light of the bash 'Shell shock' bug, this is no longer the case. Instead, a binary 'cgiwrap' utility is used to load the xymonserver.cfg and cgioptions.cfg files before invoking the CGI programs. This means that the cgioptions.cfg file is no longer parsed as a shell script, so if you rely on this then it will no longer work. In that case you must replace the symlink(s) in xymon/cgi-bin/ with shell script wrappers which source the cgioptions.cfg file. Changes for 4.3.15 - 4.3.17 =========================== No significant changes. Changes for 4.3.14 ================== In previous Xymon versions, a client-only configuration (i.e. one configured with "./configure --client") would place the client files in a "client" subdirectory below the directory specified during configuration. This is the same directory layout as a server installation, where the server and client parts of Xymon are in separate subdirectories. In 4.3.14, the default has changed so a client-only installation now installs in the directory given during the configure-step. The "/client" has been eliminated, so if you are upgrading an existing client you must either move the old client installation one level up from the "client/" directory, or change the Makefile generated by "configure --client" and add "/client" to the XYMONTOPDIR setting. The SNI support added in 4.3.13 causes problems with some older webservers, whose SSL implementation cannot handshake correctly when SNI is used. The failed handshake causes Xymon to report the site as down. In 4.3.14, the default is changed so SNI is disabled. A new "--sni" option was added to xymonnet to control the default setting, and two new tags "sni" and "nosni" can be used in hosts.cfg to control SNI for each host that is tested. Changes for 4.3.13 ================== This is mostly a bugfix release. Apart from simple bugs (see the Changes file), there are some enhancements: Alerts sent via e-mail have line-endings converted to plain , since the carriage-return characters would cause some mailers to send alerts as a (binary) attachment to an empty mail message. https-URL's can be forced to use TLS only, by using "httpst://..." similar to how SSLv2 and SSLv3 can be chosen. SSL connections (e.g. for https URL's) now use the TLS "Server Name Indication" (SNI) if your OpenSSL library supports it. This allows testing of systems that have multiple SSL websites located on the same physical IP+port (i.e. virtual name-based hosts). Changes for 4.3.12 ================== NOTE: This release includes a bugfix for a security issue in the xymond_history and xymond_rrd modules. A "drophost" command sent to the xymond port (default: 1984) from an IP listed in the --admin-senders access control list can be used to delete files owned by the user running the xymond daemon. This is allowed by default, so it is highly recommended to install this update. Changes for 4.3.2 - 4.3.11 ========================== See the Changes file for a list of significant changes. These releases are mostly to fix bugs. NOTE: Some configuration parameters have changed, so you must regenerate the top-level Makefile by running the "configure" script before compiling the new version. The inode-check introduced in 4.3.8 and 4.3.10 requires that you update both the Xymon server installation and the Xymon client on the systems where you want to monitor how many inodes are being used. Changes for 4.3.1 ================== This is a SECURITY BUG FIX release, resolving a number of potential cross-site scripting vulnerabilities in the Xymon web interface. Thanks to David Ferrest who reported these to me. Changes for 4.3.0 ================== IMPORTANT: Most files and internals in Xymon have been renamed with the 4.3.0-beta3 release. If you are upgrading from a version prior to 4.3.0-beta3, you MUST read the file docs/upgrade-to-430.txt and make sure you follow the steps outlined here. That also applies if you are upgrading from 4.3.0-beta2. Xymon 4.3.0 is the first release with new features after the 4.2.0 release. Several large changes have been made throughout the entire codebase. Some highlights (see the Changes file for a longer list): * Data going into graphs can now be used to alter a status, e.g. to trigger an alert from the response time of a network service. * Tasks in xymonlaunch can be be configured to run at specific time of day using a cron-style syntax for when they must run. * Worker modules (RRD, client-data parsers etc) can operate on remote hosts from the xymond daemon, for load-sharing. * Support for defining holidays as non-working days in alerts and SLA calculations. * Hosts which appear on multiple pages in the web display can use any page they are on in the alerting rules and elsewhere. * Various new network tests: SOAP-over-HTTP, HTTP tests with session cookies, SSL minimum encryption strength test. * New "compact" status display can group multiple statuses into one on the webpage display. * Configurable periods for graphs on the trends page. * RRD files can be configured to maintain more data and/or different data (e.g. MAX/MIN values) * SLA calculations now include the number of outages in addition to the down-time. * Solaris client now uses "swap -l" to determine swap-space usage, which gives very different results from the previous "swap -s" data. So your Solaris hosts will appear to change swap-utilisation when the Xymon client is upgraded. TRACKMAX feature removed ------------------------ For users of the TRACKMAX feature present in 4.2.2 and later 4.2.x releases: This feature has been dropped. Instead, you should add a definition for the tests that you want to track max-values for to the rrddefinitions.cfg file. E.g. to track max-values for the "mytest" status column: [mytest] RRA:MAX:0.5:1:576 RRA:MAX:0.5:6:576 RRA:MAX:0.5:24:576 RRA:MAX:0.5:288:576 Changed behaviour of http testing via proxy ------------------------------------------- The Big Brother behaviour of allowing you to specify an http (web) proxy as part of the URL in a test has been disabled by default, since it interferes with URL's that contain another URL as part of the URL path. If you need the Big Brother behaviour, add "--bb-proxy-syntax" to your invocations of bbtest-net. BBGHOSTS setting removed ------------------------ Setting BBGHOSTS in the xymonserver.cfg file no longer has any effect. Instead, you must use the "--ghosts" option for hobbitd. The default ghost handling has also been changed from "ignore" to "log". xymonproxy: Alert support for Big Brother servers removed --------------------------------------------------------- The xymonproxy tool no longer supports forwarding "page" messages. This means that if you are forwarding messages from an old Big Brother client to a Big Brother server that is sending out alerts, then these alerts will be dropped. Status updates will be forwarded, only alerts triggered from the Big Brother server are affected. Webpage menu: New menu code --------------------------- The Javascript-based menu code ("Tigra") has been replaced with a menu based on CSS/HTML4. This means that any menu customization will have to be manually transferred to the new menu definition file, ~xymon/server/etc/xymonmenu.cfg. The new menu-system is known NOT to work with Internet Explorer 6 (IE 7 and newer are fine). If you must have a menu system that works with the ancient browsers, then the old Tigra menu can be downloaded from http://xymon.svn.sourceforge.net/viewvc/xymon/sandbox/tigramenu/?view=tar together with instructions for using it with Xymon 4.3.0. xymon-4.3.30/configure.client0000775000076400007640000001537713457402722016412 0ustar rpmbuildrpmbuild#!/bin/sh # Configure script for Xymon client # $Id: configure.client 8052 2019-04-22 18:20:02Z jccleaver $ echo "" echo "Configuration script for Xymon client" echo "" while test "$1" != "" do OPT="$1"; shift case "$OPT" in "--help") cat <&1 | head -n 1 | awk '{print $1 " " $2}'` if test "$MAKEVER" != "GNU Make" then echo "GNU make is required to build Xymon." echo "If it is available as \"gmake\", run configure as: 'MAKE=gmake $0'" exit 1 fi echo "Xymon normally keeps all of the client configuration files" echo "on the Xymon server. If you prefer, it is possible to use" echo "a local client configuration file instead - if so, answer" echo "'client' to the next question." echo "NB: Local configuration requires the PCRE libs on each host." echo "" echo "Server side client configuration, or client side [server] ?" if test -z "$CONFTYPE" then read CONFTYPE fi if test -z "$CONFTYPE" then CONFTYPE="server" fi echo "" if test "$CONFTYPE" = "client" then echo "Checking for the PCRE libraries" . build/pcre.sh echo "" fi echo "" MAKE="$MAKE -s" ./build/lfs.sh if test $? -eq 0; then LFS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" else LFS="" fi echo ""; echo "" MAKE="$MAKE -s" . ./build/clock-gettime-librt.sh echo ""; echo "" echo "What userid will be running Xymon [xymon] ?" if test -z "$XYMONUSER" then read XYMONUSER fi if test -z "$XYMONUSER" then XYMONUSER="xymon" fi if test -z "$XYMONTOPDIR" then if test "`uname -s`" = "Darwin" then # Use "dscl" for locating user information. From Isaac Vetter # http://www.xymon.com/archive/2008/02/msg00173.html USERDATA="`dscl . -list /Users | grep $XYMONUSER`" if test "$USERDATA" != "" then echo "Found Directory entry for user: $USERDATA" else echo "FAILURE: The user $XYMONUSER does not exist locally. Create user and try again." exit 1 fi echo ""; echo "" HOMEDIR="`dscl . -read /Users/$XYMONUSER | grep HomeDirectory | awk '{print $2}'`" else USERDATA=`getent passwd $XYMONUSER 2>/dev/null || ypmatch "${XYMONUSER}" passwd || grep "^${XYMONUSER}:" /etc/passwd` if test $? -eq 0 then echo "Found passwd entry for user $USERDATA" else echo "FAILURE: The user $XYMONUSER does not exist. Create user and try again." exit 1 fi echo ""; echo "" HOMEDIR="`echo $USERDATA|cut -d: -f6`" fi else HOMEDIR="$XYMONTOPDIR" fi echo "Where do you want the Xymon installation [${HOMEDIR}] ?" if test -z "$XYMONTOPDIR" then read XYMONTOPDIR fi if test -z "$XYMONTOPDIR" then XYMONTOPDIR=${HOMEDIR} fi if test -d "$XYMONTOPDIR" then echo "OK, will configure to use $XYMONTOPDIR as the Xymon toplevel directory" else echo "WARNING: $XYMONTOPDIR does not exist." fi echo ""; echo "" echo "What is the IP-address of your Xymon server [127.0.0.1] ? " if test -z "$XYMONHOSTIP" then read XYMONHOSTIP fi if test -z "$XYMONHOSTIP" then echo "** NOTE: Using 127.0.0.1 (loopback), but it is probably not what you want **" XYMONHOSTIP=127.0.0.1 fi echo ""; echo "" XYMONHOSTOS=`uname -s | tr '[A-Z]' '[a-z]'` echo "# Toplevel Makefile for Xymon" > Makefile echo "BUILDTOPDIR=\`pwd\`" >>Makefile echo "CLIENTONLY = yes" >>Makefile if test "$CONFTYPE" = "client" then echo "LOCALCLIENT = yes" >>Makefile else echo "LOCALCLIENT = no" >>Makefile fi echo "" >>Makefile echo "# configure settings for Xymon" >>Makefile echo "#" >>Makefile echo "# Toplevel dir" >>Makefile echo "XYMONTOPDIR = $XYMONTOPDIR" >>Makefile echo "" >>Makefile echo "# Xymon settings follows" >>Makefile echo "#" >>Makefile echo "# Username running Xymon" >>Makefile echo "XYMONUSER = $XYMONUSER" >>Makefile echo "# Xymon server IP-address" >>Makefile echo "XYMONHOSTIP = $XYMONHOSTIP" >>Makefile echo "# Large File Support settings" >>Makefile echo "LFSDEF = $LFS" >>Makefile echo "LIBRTDEF = $LIBRTDEF" >>Makefile echo "" >>Makefile if test -r build/Makefile.`uname -s | tr '/' '_'` then echo "include build/Makefile.`uname -s | tr '/' '_'`" >>Makefile echo "" echo "Using `uname -s | tr '/' '_'` Makefile settings" echo "" else echo "include build/Makefile.generic" >>Makefile echo "" echo "Using GENERIC Makefile settings (uname -s is `uname -s`)" echo "" echo "If this fails, change the compile settings in Makefile" echo "" echo "I would appreciate it if you send the changes to" echo "xymon-owner@xymon.com so I can include it in the next version." echo "" fi echo "" >>Makefile if test "$INSTALLBINDIR" != ""; then echo "INSTALLBINDIR = $INSTALLBINDIR" >>Makefile fi if test "$INSTALLETCDIR" != ""; then echo "INSTALLETCDIR = $INSTALLETCDIR" >>Makefile fi if test "$INSTALLEXTDIR" != ""; then echo "INSTALLEXTDIR = $INSTALLEXTDIR" >>Makefile fi if test "$INSTALLTMPDIR" != ""; then echo "INSTALLTMPDIR = $INSTALLTMPDIR" >>Makefile fi if test "$INSTALLWEBDIR" != ""; then echo "INSTALLWEBDIR = $INSTALLWEBDIR" >>Makefile fi if test "$INSTALLWWWDIR" != ""; then echo "INSTALLWWWDIR = $INSTALLWWWDIR" >>Makefile fi echo "" >>Makefile if test "$CONFTYPE" = "client" then if test "$PCREINC" != ""; then echo "PCREINCDIR = -I$PCREINC" >>Makefile fi if test "$PCRELIB" != ""; then echo "PCRELIBS = -L$PCRELIB -lpcre" >>Makefile echo "RPATHVAL += ${PCRELIB}" >>Makefile else echo "PCRELIBS = -lpcre" >>Makefile fi fi echo "#" >>Makefile echo "# Add local CFLAGS etc. settings here" >>Makefile echo "" >>Makefile echo "include build/Makefile.rules" >> Makefile echo "" >> Makefile echo ""; echo "" echo "Created Makefile with the necessary information to build Xymon" echo "Some defaults are used, so do look at the Makefile before continuing." echo "" echo "Configuration complete - now run $MAKE (GNU make) to build the tools" exit 0 xymon-4.3.30/debian/0000775000076400007640000000000013534041774014435 5ustar rpmbuildrpmbuildxymon-4.3.30/debian/xymon.preinst0000664000076400007640000000163611535462534017223 0ustar rpmbuildrpmbuild#! /bin/sh # preinst script for Xymon set -e case "$1" in install|upgrade) # stop the client when the server is installed invoke-rc.d xymon stop || true if test "$2" && dpkg --compare-versions "$2" lt 4.2.0.dfsg-2 && test -d /var/lib/xymon/www ; then if test -e /etc/logrotate.d/xymon-client && ! test -e /etc/logrotate.d/xymon-client.dpkg-old ; then mv /etc/logrotate.d/xymon-client /etc/logrotate.d/xymon-client.dpkg-old fi # we want to replace directories with symlinks, prod dpkg to do it move_dir () { test -d "$1" || return test -h "$1" && return test -e "$1.dpkg-old" && return mv "$1" "$1.dpkg-old" } cd /var/lib/xymon/www move_dir gifs move_dir help move_dir menu fi #446982 if test "$2" && dpkg --compare-versions "$2" ge 4.2.0.dfsg-1 && dpkg --compare-versions "$2" lt 4.2.0.dfsg-6 ; then chown root:root /tmp chmod 1777 /tmp fi ;; esac #DEBHELPER# exit 0 xymon-4.3.30/debian/xymon-client.postrm0000664000076400007640000000205611535462534020334 0ustar rpmbuildrpmbuild#! /bin/sh # postrm script for xymon # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' overwrit>r> # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # Before deluser so debconf still works #DEBHELPER# case "$1" in purge|disappear) rm -rf /var/lib/xymon /var/log/xymon /var/run/xymon /etc/xymon \ /etc/default/xymon-client if test -x /usr/sbin/deluser ; then deluser xymon || true fi if test -x /usr/sbin/delgroup ; then delgroup --only-if-empty xymon || true fi ;; remove|upgrade|failed-upgrade|abort-install|abort-upgrade) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac exit 0 xymon-4.3.30/debian/xymon-client.config0000664000076400007640000000151411535462534020253 0ustar rpmbuildrpmbuild#!/bin/sh CONFIGFILE=/etc/default/xymon-client set -e . /usr/share/debconf/confmodule if [ -e $CONFIGFILE ]; then . $CONFIGFILE || true fi # if there is no value configured, look for debconf answers if [ -z "$XYMONSERVERS" ] ; then db_get xymon-client/XYMONSERVERS XYMONSERVERS="$RET" fi # still nothing? set a default if [ -z "$XYMONSERVERS" ] ; then XYMONSERVERS="127.0.0.1" fi # in any case, store the value in debconf db_set xymon-client/XYMONSERVERS "$XYMONSERVERS" if [ -z "$CLIENTHOSTNAME" ] ; then db_get xymon-client/CLIENTHOSTNAME CLIENTHOSTNAME="$RET" fi if [ -z "$CLIENTHOSTNAME" ] ; then CLIENTHOSTNAME="`hostname -f 2> /dev/null || hostname`" fi db_set xymon-client/CLIENTHOSTNAME "$CLIENTHOSTNAME" db_input high xymon-client/XYMONSERVERS || true db_input medium xymon-client/CLIENTHOSTNAME || true db_go || true xymon-4.3.30/debian/docs0000664000076400007640000000007411070452713015301 0ustar rpmbuildrpmbuildREADME README.CLIENT Changes CREDITS RELEASENOTES docs/TODO xymon-4.3.30/debian/copyright0000664000076400007640000000063311535462534016372 0ustar rpmbuildrpmbuildThis package was debianized by Henrik Stoerner on Fri, 29 Oct 2010 22:31:25 +0200. It was downloaded from http://sourceforge.net/projects/xymon/ Copyright: Henrik Stoerner Upstream author: Henrik Stoerner License: GNU GPL On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. xymon-4.3.30/debian/init-common.sh0000664000076400007640000000257611535424634017233 0ustar rpmbuildrpmbuild# common init functions for Xymon and Xymon-client create_includefiles () { if [ "$XYMONSERVERS" = "" ]; then echo "Please configure XYMONSERVERS in /etc/default/xymon-client" exit 0 fi umask 022 if ! [ -d /var/run/xymon ] ; then mkdir /var/run/xymon chown xymon:xymon /var/run/xymon fi set -- $XYMONSERVERS if [ $# -eq 1 ]; then echo "XYMSRV=\"$XYMONSERVERS\"" echo "XYMSERVERS=\"\"" else echo "XYMSRV=\"0.0.0.0\"" echo "XYMSERVERS=\"$XYMONSERVERS\"" fi > /var/run/xymon/bbdisp-runtime.cfg for cfg in /etc/xymon/clientlaunch.d/*.cfg ; do test -e $cfg && echo "include $cfg" done > /var/run/xymon/clientlaunch-include.cfg if test -d /etc/xymon/xymonlaunch.d ; then for cfg in /etc/xymon/xymonlaunch.d/*.cfg ; do test -e $cfg && echo "include $cfg" done > /var/run/xymon/xymonlaunch-include.cfg fi if test -d /etc/xymon/xymongraph.d ; then for cfg in /etc/xymon/xymongraph.d/*.cfg ; do test -e $cfg && echo "include $cfg" done > /var/run/xymon/xymongraph-include.cfg fi if test -d /etc/xymon/xymonserver.d ; then for cfg in /etc/xymon/xymonserver.d/*.cfg ; do test -e $cfg && echo "include $cfg" done > /var/run/xymon/xymonserver-include.cfg fi if test -d /etc/xymon/xymonclient.d ; then for cfg in /etc/xymon/xymonclient.d/*.cfg ; do test -e $cfg && echo "include $cfg" done > /var/run/xymon/xymonclient-include.cfg fi return 0 } xymon-4.3.30/debian/xymon-client.lintian-overrides0000664000076400007640000000011111535424634022433 0ustar rpmbuildrpmbuildxymon-client: package-contains-empty-directory usr/lib/xymon/client/ext/ xymon-4.3.30/debian/changelog0000664000076400007640000015235013534025035016305 0ustar rpmbuildrpmbuildxymon (4.3.30) stable; urgency=high * rev 8010 * Fix reports with dashes or underscores not visible in history logs (Thanks, Tom Schmidt) * Really fix do_temperature.c report parsing for parentheses (Thanks, Tom Schmidt) * Fix truncation on exec strings causing missing custom RRD titles (Thanks, Tom Schmidt) * RPC buffer calculation on snprintf taking improper sizeof (Thanks, Tom Schmidt) * Don't crash on a missing allevents file * Fix assorted crashes with xymongen report generation after string changes * Add guards around GCC diagnostics pragma to allow for building on older vers * xymonclient-linux: Provide wide/untrimmed IP support in netstat port list * Fix problems with meta-combostatuses (Thanks, Dominique Delporte) -- Japheth Cleaver Thu, 05 Sep 2019 13:00:00 -0800 xymon (4.3.29) stable; urgency=medium * rev 8070 * Security Fixes: A number of potential buffer overflows have been resolved CVE-2019-13451, CVE-2019-13452, CVE-2019-13455, CVE-2019-13473, CVE-2019-13474, CVE-2019-13484, CVE-2019-13485, CVE-2019-13486 * Deal with Set-Cookie deprecation on normal pages (Thanks, Erik Schminke) * Support glibc->tirpc migration on newer distributions * Fix certain flags not being set on GCC 8/9 * Fix wrong doc for --merge-clientlocal option (Thanks, Thomas Eckert) * Fix CSP errors on trends pages (Thanks, John Thurston) * Accept minimum libcares version >= 1.5.1; update bundled to 1.15.0 * Fix RRD parsing for recent netstat (net-tools) on Linux * Ensure Content-Type always set in HTML headers (Thanks, Christoph Berg) * Ignore additional common tmpfs partitions on recent Linux * Fix NONETPAGE parsing (Thanks, John Horne) * Increase hard max xymon message size from 10MB to 64MB to match 4.4-alpha * Fix line-off-by-one error in logfetch retrieval when triggers are used (Thanks, Toshimitsu FUJIWARA) * Fixes to do_temperature parsing (Thanks, Michael Pins) * Add support for GNU Hurd and GNU/kFreeBSD * Don't require apache authz_groupfile module by default when not needed * Add --no-cpu-listing option to xymond_client to block 'top' output in cpu test (Thanks, John Horne) * Double-quote the display name of host titles handed to RRD * Ensure NTP checks not hung for unreachable hosts (Thanks, Tom Schmidt) * Standardize xymonnet SMTP/s protocol conversation (Thanks, Tom Schmidt) * AIX: Report Actual Memory and Phys/Entitled CPU capacity (Thanks, Stef Coene) * snmp: Fix parsing error with SNMPv3 config parsing (Thanks, Jeremy Laidman) * RRD: Fix parsing error with DS files containing commas - http* only (Thanks, John Horne) -- Japheth Cleaver Tue, 23 Jul 2019 08:30:00 -0800 xymon (4.3.28) stable; urgency=medium * rev 8005 * Catch addition possible errors during SSL handshake for standard TCP checks * Fix misparsing of --timelimit and --huge options in xymonnet (Reported by Foster Patch) * Fix memory leak when processing netapp test reports (Reported by Peter Welter) * The included version of c-ares has been bumped to version 1.12.0 * Fix for building on OpenSSL 1.1.0 (Thanks, Axel Beckert) * Add TLS variant specification to http checks, using newer funcs in OpenSSL 1.1.0 (From Henrik) * Fix overflow when skipping >2G pending data in logfetch (Reported by Sergey, a_s_y at sama.ru) * xymond_alert will no longer exit and be relaunched if started while there's no actual alertable condition. (Thanks, Franco G.) * Fix mis-parsing of PCRE regex's in client-local.cfg when char ranges are present (Reported by Erik D. Schminke) * The size limit of message data passed to SCRIPT alerts is configurable with the MAXMSG_ALERTSCRIPT variable. * Summary messages should work again (Thanks, Axel) * Many typos in comments and man pages have been corrected (Thanks, Axel et al. at Debian) * Change netstat RRD numbers to be slightly more human-readable (Thanks Roland Rosenfeld) -- Japheth Cleaver Tue, 17 Jan 2017 16:30:00 -0800 xymon (4.3.27) stable; urgency=medium * rev 7957 * Don't treat empty (0 byte) directory size as invalid (Reported by Bert Willekens) * Fix looping redirect on criticaleditor.sh * Allow NK-critical acknowledgements from status pages * Fix redirect to criticalview.sh, which is just a regular CGI * Properly recognize https URLs as summary links (Thanks, David Steinn Geirsson) * Add compile-time check for SSLv3 support -- Japheth Cleaver Thu, 24 Mar 2016 15:00:00 -0700 xymon (4.3.26) stable; urgency=medium * rev 7906 * Fix javascript failures on info/trends pages caused by CSP fixes * Fix incorrect HTTP refresh on rejected enadis.sh POSTs * Do not auto-refresh info or trends svcstatus pages * Revert default svcstatus page refresh interval from 30s back to 60s * Re-introduce XYMWEBREFRESH variable to control refresh interval * HTML encode most fields on info page * Restrict characters allowed for hostnames and testnames * HTML encode error log output on xymond/net/gen pages * HTML encode ghost hostnames output on xymond/ghostlist pages * logfetch: only evaluate the first config of a given type seen for the same file name * xymongen/reports: fix vague error message around missing history files and properly exclude clientlog statuses (Reported by Magdi Mahmoud) * Ensure configured CLASS overrides in hosts.cfg are always passed on to client workers, regardless of 'class' for that specific message (Reported by Steve Hill) -- Japheth Cleaver Fri, 19 Feb 2016 15:00:00 -0800 xymon (4.3.25) stable; urgency=high * rev 7890 * Resolve buffer overflow when handling "config" file requests (CVE-2016-2054) * Restrict "config" files to regular files inside the $XYMONHOME/etc/ directory (symlinks disallowed) (CVE-2016-2055). Also, require that the initial filename end in '.cfg' by default * Resolve shell command injection vulnerability in useradm and chpasswd CGIs (CVE-2016-2056) * Tighten permissions on the xymond BFQ used for message submission to restrict access to the xymon user and group. It is now 0620. (CVE-2016-2057) * Restrict javascript execution in current and historical status messages by the addition of appropriate Content-Security-Policy headers to prevent XSS attacks. (CVE-2016-2058) * We would like to thank Markus Krell for reporting the above issues, and for working with us to resolve them. * * Fix "TRENDS" entries in hosts.cfg improperly handling partial matches with other graph names (Reported by Jeremy Laidman) * A possible crash in when loading confreport.cgi has been fixed (Thanks, Axel Beckert) * Improve error handling slightly in the CGI wrapper * Fix missing network interface graph data on FreeBSD (Niko ) * In xymonnet, a rare SSL error state that could occur after a connection is opened will now be considered "service down" * Fix a crash in xymonnet when handling certain malformed SSL certificates (Reported by Thomas Leavitt, originally via Jeremy Laidman) * Add new trends_header and trends_footer for use on associated Trends pages * "Jump to page" redirect functionality fixed on findhost.sh (Reported by Francois Claire) * When a note is present for a host, the info page no longer has a spurious hostname on the text link * xymonclient.cfg: Add variables in for overriding config files for xymond_client and logfetch when in local mode without editing xymonclient.sh * xymonclient: Allow LOCALMODE to be set in xymonclient.cfg w/o passing --local option * logfetch: Add --noexec option to ignore commands to dynamically list files for scanning (Suggested by Jeremy Laidman) * Add file globbing capabilities to logfetch to avoid need to fork commands to create dynamic lists (Suggested by Jeremy Laidman) * The "Valid Until" time for an acknowledgement is now displayed on the ack log report page (Thanks, Dominique Frise) * The xymon.sh and runclient.sh scripts are themselves now more LSB compliant (Thanks, Nikolai Lifanov) * Windows systems now have a better calculation of "Actual" memory usage (Thanks, John Rothlisberger) * A bug in xymond_alert that could cause pages about hosts.cfg not present at inital start to cause inconsistent alerting has been fixed * xymond_alert now reloads its hostlist at regular intervals -- Japheth Cleaver Fri, 05 Feb 2016 13:00:00 -0800 xymon (4.3.24) stable; urgency=high * rev 7774 * Fix occasional crash in xymond when handling group names (Thanks, Franco Gasperino) * Fix non-special HTTP <400 status codes red instead of yellow >.< -- Japheth Cleaver Mon, 23 Nov 2015 17:40:00 -0800 xymon (4.3.23) unstable; urgency=high * rev 7740 * Fix broken 'TRACK' and 'OPTIONAL' identifiers in analysis.cfg * Prevent logfetch from segfaulting if a file we're tracking line matching deltacounts for wasn't found * Fix a type mismatch compiler warning in display group name alert matching -- Japheth Cleaver Thu, 12 Nov 2015 12:00:00 -0800 xymon (4.3.22) unstable; urgency=medium * rev 7723 * Ensure we don't leave xymond_hostdata or xymond_history zombies lying around after dropping host records (Reported by Scot Kreienkamp) * Fix up HTML list layout to reflect current standards (Thanks, hallik@calyc3.com) * Fix documentation incorrectly describing multigraph syntax as (e.g.) GRAPH_cpu. Should be GRAPHS_cpu (Thanks, Galen Johnson) * Supports scientific notation for NCV data (Thanks, Axel Beckert) * Increase resolution of xymonnet poll timing results (Thanks, Christoph Berg) * New clock skew RRD files will allow for negative delta values (Thanks, Axel Beckert) * Fix lots of typos! (Debian) * Don't skip over "mailq.rrd" (Roland Rosenfeld) * The signature algorithm used on an SSL-enabled TCP test run by xymonnet is now shown on the sslcert page. (Thanks, Ralph Mitchell) * The cipher list displayed in 'sslcert' tests will now be limited to the cipher that was actually used on the SSL connection. The --showallciphers option to xymonnet will restore the previous behavior. (From idea from Ralph Mitchell) * Provide configurable environment overrides in xymonserver.cfg for standard xymonnet options to fping/xymonping, ntpdate, and traceroute binaries. In regular installs, the intended default options to traceroute (-n -q 2 -w 2 -m 15) were not actually used. This may change in a future release, so it's suggested that users move any custom options to the new TRACEROUTEOPTS setting in xymonserver.cfg. (Orig. thanks, Axel Beckert, ntpdate issues pointed out by Matt Vander Werf) * Enable latent additional SHA digest strengths (sha256, sha512, sha224, sha384) * Don't crash generating wml cards for statuses w/ very long lines (Reported by Axel Beckert) * Flip SenderIP and Hostname columns on ghostlist pages to allow easier cutting and pasting to hosts files * Fix multiple disk volumes reported in on Darwin (OS X) clients. (Thanks, Axel Beckert) * Fix COMPACT parsing; update docs to match expected syntax (Thanks, Brian Scott) * Trailing slash no longer required for URL alias ("http://www.example.com/xymon" should work) * A new XYMONLOCALCLIENTOPTS variable in xymonclient.cfg allows options (e.g., --no-port-listing) to be given to xymond_client when running in local client mode. * Add a method to indicate lines which should be skipped by the NCV RRD processor or which mark the end of data-to-be-processed in the message. * Ensure that nostale is passed down during graph zooming (Thanks, Stef Coene) * Add missing XMH_DATA in loadhosts (Thanks, Jacek Tomasiak) * Search in more locations for default environment files when using xymoncmd * Add a "noflap" override to disable flap detection for any/all tests on a given host (Thanks, Martin Lenko) * Simplify default HTTP error code settings for xymonnet (2xx = green; 3xx = yellow; 4xx/5xx = red) * The protocol.cfg entry for RDP network tests has been updated and should work again (Thanks, Rob Steuer) * Add UDP ports to netstat output returned from darwin clients (Mac OS X) * Fixes to df/inode parsing on darwin clients (Mac OS X) (Thanks, Jason White et al.) * Add httphdr= tag to hosts.cfg to inject arbitrary headers into xymonnet HTTP tests for that host. * Turn memory test yellow if nonsensical numbers are found (>100% used for 'Actual' or Swap) * "optional include" and "optional directory" support actually added * xymongrep: load from the hosts.cfg file and error if unable, unless --loadhostsfromxymond is specified * Collect number of total cores in client data * combostatus: Fix parenthesis processing (Thanks, Andy Smith) * Add per-group anchors to generated pages when a group title is present (Thanks, Thomas Giordmaina) * xymongen: Display group tables even if group has no test results yet unless --no-showemptygroups given * Add chpasswd CGI for user-level htpasswd file updates. Requires Apache 2.4.5 or later (Thanks, Andy Smith) * Fix memory/display on multihost hostgraphs.cgi reports; remove multi-disk (which won't work as-is) * Add ACK_COOKIE_EXPIRATION for environment control of cookie validity duration (Noted by Thomas Giordmaina) * combostatus: fix core dumps on Solaris when dealing with erroneous config -- Japheth Cleaver Fri, 6 Nov 2015 06:00:00 -0800 xymon (4.3.21) unstable; urgency=medium * rev 7668 * RSS feeds should now display the short description of the event again. -- Japheth Cleaver Fri, 22 May 2015 18:15:00 -0700 xymon (4.3.20) unstable; urgency=medium * rev 7661 * Summaries should be properly displayed again, and will display on the nongreen.html page as well. * An icon for green acknowledged states is now included -- ironically, the original icon that the other checkmarks were based off of. * The various utilities in cgi-bin and cgi-secure are now hardlinked to cgiwrap at install time instead of softlink, to allow for FollowSymLinks-less apache configurations * The protocol section of URLs in hosts.cfg is now case-insensitive, and ftps URLs (FTP-over-SSL, not sftp) are recognized as a protocol. * hosts.cfg docs have been clarified to include delayyellow and delayred as allowable options (Reported by John Thurston) * 'optional include' and 'optional directory' syntax has been documented * pulldata directives in the hosts.cfg file now honor a given IP address and port * confreport.sh not displaying time-restricted alerts properly has been fixed (Reported by Gavin Stone-Tolcher) * Planned downtime settings are now applied to 'purple' statuses as well (Thanks, Torsten Richter) * Column documentation links should be working again (Reported by Andy Smith) * Fix missing null termination in certain logfetch situations (Reported by Johan Sj�berg) * New httphead tag to force an http request using HEAD instead of GET * Fix a memory leak introduced in parsing Windows SVCS test data * A divide-by-zero condition when systems erroneously report 0MB of physical memory has been corrected (Reported by John Thurston) * Parse either critical config or xymond-formatted acknowledgements on the report page, and add documentation for the --ack-log option in xymond (Thanks, Andy Smith) * The graphs to be displayed on a specific status page can be customized with environment variables - see xymonserver.cfg(5). From Werner Maier. * When clients are in "server" mode (sending raw data to the xymond server to be centrally processed), a 'clientlog' column will now be shown on xymon pages (similar to trends and info columns). This can be disabled on a per-host basis by adding a 'noclient' tag to the hosts.cfg line, or globally by adding that to the .default. host. * Add protocols.cfg entries for amqp(s), svn, ircd, and mail (submission). (Note that smtp testing here may suffer the same occasional issue as regular smtp conversations with regard to out-of-order commands.) * Fix a crash on non-glibc systems when testing xymond_alert configs with a host not in hosts.cfg (Reported by John Thurston) * On newer Linux kernels with recent procps-ng, use the "Available" memory reported by the kernel to give a more accurate reading for "Actual Used" in the client's memory status. (Reported by Dominique Frise) -- Japheth Cleaver Fri, 15 May 2015 08:15:00 -0700 xymon (4.3.19) unstable; urgency=medium * rev 7619 * Don't crash when receiving an AAAA DNS response (BSD, thanks Mark Felder) * xymonclient.sh running in --local mode was generating reports that were marked as duplicates (and thus being ignored). Reported by Guillaume Chane. * Building with old versions of libpcre not supporting PCRE_FIRSTLINE should once again work * Memory reporting on FreeBSD and OpenBSD has been fixed (Mark Felder) * The process list visible in the 'procs' test of Linux and FreeBSD clients is now generated in ASCII "forest" mode for increased legibility. * clientlog, hostinfo, and modify messages are now tracked in xymond stats * In environment config files (xymonserver.cfg, xymonclient.cfg, and cfgoptions.cfg) an initial "export " line (as if it were actually a shell script) will be ignored and the remainder of the line parsed as normal. * headermatch will now match the headers of an HTTP response even if the body is empty (eg, matching for a 302 Redirect) * --debug mode in most daemons should cause *much* less of a performance hit, and output will be timestamped in microseconds * xymondboard can now be used to PCRE-match against the raw message, and acknowledgement and disable comments. Inequalities can be specified against the lastchange, logtime, validtime, acktime, disabletime fields (in epoch timestamps). The existing net= and tag= filters have been documented. * The sample xymon.conf apache snippet now supports apache 2.4 syntax * Fix missing newline when returning upcoming 'schedule' commands. * EXTIME= syntax in analysis.cfg and alerts.cfg has been added. This is applied after any TIME= filter. Use (e.g.) to exclude Wednesday afternoons on a line which is already restricted to 9:00a to 5:00p on weekdays only. * The included version of c-ares has been bumped to version 1.10.0. * Support for older EGD (entropy gathering daemon) has been removed (Thanks, Bernard Spil) * A crash when xymond_rrd was run in --debug mode on non GNU/glibc systems has been fixed * The msgs and procs tests are now HTML-encoded to ensure that lines with brackets are properly displayed * An acknowledgements.sh log report has been added in (Submitted by Andy Smith) * A number of logfetch issues have been addressed: - --debug syntax is now supported. (If modifying the command line in xymonclient.sh, use --debug=stderr to prevent spurious lines being sent in the client report.) - Invalid POSIX regular expressions for ignore or trigger lines will now be reported but should not cause crashes - Null characters in a log file will no longer cause further processing to stop (Thanks, Franco Gasperino.) - All lines matching a 'trigger' regex will be reported back, even if the total size exceeds the "maxbytes" limit. (Up to the maximum compiled buffer size.) As much of the final section as can be fit in the space remaining will be included, similar to the previous behavior if maxbytes was exceeded but no trigger lines were given. (Thanks, Franco Gasperino.) - The current location (where the previous run left off) is now marked in the status report. - The '<...SKIPPED...>' and '<...CURRENT...>' texts can be overridden by specifying values for LOGFETCHSKIPTEXT and LOGFETCHCURRENTTEXT in xymonclient.cfg - The "scrollback" (number of positions in previous "runs" back) that logfetch starts at can now be specified with the LOGFETCHSCROLLBACK variable, from 0 - 6 (the default) * "deltacount" can be used to count the number of lines matching a specific regex in client-local.cfg, counting only since the last run. These will be shown on the trends page. NOTE: Unlike the "linecount:" option, deltacount is specified after a specific "log:" line. See the client-local.cfg file for details. * ifstat and netstat output from the new Windows PowerShell client is now graphed properly. * Hostnames beginning with a number (allowed by RFC1123) are now supported in combo.cfg * When a Windows service's status has been changed (ie, stopped or started), the relevant line in the 'svcs' test will now be updated to reflect this. (Reported by Gavin Stone-Tolcher and Neil Simmonds) * Various build issues, compiler fixes, and valgrind complaints have been fixed. -- Japheth Cleaver Mon, 30 Mar 2015 22:39:17 -0700 xymon (4.3.18) unstable; urgency=medium * rev 7494 * Fix CVE-2015-1430, a buffer overflow in the acknowledge.cgi script. Thank you to Mark Felder for noting the impact and Martin Lenko for the original patch. * Mitigate CVE-2014-6271 (bash 'Shell shock' vulnerability) by eliminating the shell script CGI wrappers * Don't crash in XML board output when there is no sender for status * Fix IP sender-address check for maintenance commands, when the target host is listed with IP 0.0.0.0 in hosts.cfg. * Linux client: - Generate 'raid' status from mdstat data - Include UDP listen ports in netstat data - Include full OS version data from SuSE clients * FreeBSD client: Handle 'actual' memory item, once the client starts reporting it. * Additional bugfixes: - xymond_capture: Fix exclude-test pattern handling - xymonlaunch: Guard against cron-times triggering twice in one minute - xymond_client: Fix DISPLAYGROUP handling in analysis.cfg rules - xymonnet: Handle AAAA records in dns checks - xymond_channel: Fix matching in --filter code - xymond: BFQ id may be zero - xymond: Fix bug in hostfilter matching code - xymond: Fix memory leak - xymond: Fix list manipulation for "modify" commands - xymond_rrd: Fix restart of external processor - Linux client: Set CPULOOP for correct top output - AIX client: vmstat behaves differently -- Japheth Cleaver Tue, 3 Feb 2015 11:35:11 -0800 xymon (4.3.17) unstable; urgency=low * rev 7446 * Fix crash in xymond when using 'schedule' command * Configure/build/install fixes: - Allow specifying location of the PCRE include/library files for client-side configuration build. - Pass IDTOOL to client installation (for Solaris). - Fix broken configure+Makefiles for client-side configuration - C-ARES: Fix wrong call to Makefile.test-cares during configure - Dont error out if www-dir or man-dir is empty. Mostly an issue when building packages with non-standard layouts. * Fix wrong timestamp on a new status arriving with a non-green status while DOWNTIME was active. Such a status would appear to have been created on Jan 1st, 1970. * Fix hostgraphs so it obeys RRDWIDTH / RRDHEIGHT settings * Add upper limit to showgraph CGI when generating self-referring URI's From Werner Maier * Extra sanity check on extcombo message offsets. * The Enable/Disable webpage now permits filtering on CLASS value. From Galen Johnson -- Henrik Stoerner Sun, 23 Feb 2014 10:44:18 +0100 xymon (4.3.16) unstable; urgency=low * rev 7394 * Fix xymonnet crash on sending http test results * Fix xymond crash if client-local.cfg contains empty sections * Fix RPM-based initscript for clients with explicit hostname * Fix misleading error-message when testing for C-ARES library * Fix client-local.cfg handling, so by default it will not merge sections together, i.e. behave like previous 4.x releases. NOTE: The new regexp matching can still be used. * Add "--merge-clientlocal" option for xymond, which causes it to merge all matching sections from client-local.cfg into one. * Use native POSIX binary-tree handling code -- Henrik Stoerner Sun, 9 Feb 2014 10:16:02 +0100 xymon (4.3.15) unstable; urgency=low * rev 7384 * Fix xymond_alert crashes introduced in 4.3.14 * Fix missing C-ARES build files * client-local.cfg: Support expression matching of sections * acknowledge.cgi: Acks are enabled for all ALERTCOLORS, not just red and yellow -- Henrik Stoerner Fri, 31 Jan 2014 13:49:02 +0100 xymon (4.3.14) unstable; urgency=low * rev 7376 * Fix critical ack not working for hosts where the display-name is set (via "NAME:" tag). From Any Smith. * SNI (Server Name Indication) causes some SSL connections to fail due to server-side buggy SSL implementations. Add "sni" and "nosni" flags to control SNI for specific hosts, and "--sni" option for xymonnet to control the default. Reported by Mark Felder. * Fix build process to fully obey any XYMONTOPDIR setting from the top-level Makefile. NOTE: Client-only builds no longer install the client in a "client/" subdirectory below XYMONHOME. * Fix showgraph so it silently ignores stale rrdctl files when trying to flush RRD data before showing a graph. * Fix xymond_alert crashing when trying to strip characters from the alert message. Bug introduced in 4.3.13. * Fix Solaris client to report memory even when no swap is configured. * Fix bug where alerts that were initially suppressed due to TIME restrictions are delayed until REPEAT interval expires. * Fix crash in xymonlaunch when trying to find tasks.cfg * Fix HTML generated by acknowledge.cgi (missing '>') * Fix Linux client reporting garbled client data if top output ends without a new-line (causes CPU load and other vmstat graphs to stop updating) * Fix Debian installation so it enables Apache mod_rewrite * Fix merge-lines utility crashing when first line was an include * Fix "make install" failing when server/www/help was a symlink * Document existing OPTIONAL setting in analysis.cfg for file-checks on files which may not exist. * Document existing CLASS setting in alerts.cfg * Add new INFOCOLUMNGIF and TRENDSCOLUMNGIF settings so the icons used for these pages are configurable. * Enhance Solaris client to correctly handle Solaris zones. * Add new search facilities to xymond to select hosts with the 'xymondboard' and 'hostinfo' commands. * New --ack-each-color option for xymondd changes ack behaviour so a yellow ack does not apply when status changed to red, but a red ack applies if status goes yellow * New "headermatch" tag for http tests so content checks can look at HTTP headers in addition to the HTML body. * Use system-wide c-ares library. NB: Now requires libc-ares2. -- Henrik Stoerner Sun, 26 Jan 2014 13:49:02 +0100 xymon (4.3.13) unstable; urgency=low * rev 7339 * Fixes to FreeBSD client code, from Mark Felder (FreeBSD maintainer) * Fix crash on "client" data sent via status channel when host is unknown * HTTP tests now use "Cache-control" header for HTTP/1.1 (default) and "Pragma" for HTTP/1.0, so it is protocol compliant. * xymonnet network tester supports Server Name Indication (SNI) for SSL enabled virtual websites. * Strip carriage-return from text sent to mail alerts, to avoid mail programs treating the message as binary and putting it in an attachment * netbios-ssn, snpp and lpd protocol.cfg entries (Tom Schmidt) * "temperature" status strips html tags from sensor names (Tom Schmidt) * Extra "total network I/O" line on ifstat graph (Tom Schmidt) * New "backfeed" queue for high-speed transmission of Xymon status updates between modules located on the same server as xymond. Note: This is disabled by default, see the README.backfeed file. * New "extcombo" message type allows for combo messages of all types (usually "status" and "data"). * New setting IMAGEFILETYPE removes hardcoded ".gif" on the various image-files in the "gifs" directory. Directory name is unchanged, though. * New modifier for https tests for selecting only TLSv1 as protocol * CGI's now return a proper HTTP status code in case of errors (e.g. "404" when requesting a status for a non-existing host). * Fix problem with xymond_rrd dying if an external processors crashes (from J. Cleaver) * Fix configure/build problem with detecting POSIX realtime-clock functions. * Fix for FreeBSD 5+ vmstat reporting (from Jeremy Laidman) * Fix for "make install" not setting correct file/directory permissions * Re-add the "--hf-file" option for criticalview CGI (removed in 4.3.7) -- Henrik Stoerner Wed, 8 Jan 2014 16:43:32 +0100 xymon (4.3.12) unstable; urgency=high * rev 7211 * Security fix: Guard against directory traversal via hostname in "drophost" commands. * Fix crash in xymongen introduced in 4.3.11 * SCO client: Fix overflow in memory calculation when >2 GB memory * Fix so "include" and "directory" definitions in configuration files now handle after the keyword * Fix for the Xymon webpage menu on iPad's and Android (touch devices) * Fix "drophost" handling so the host data directory is also cleared * xymond_rrd now processes data from "clear" status messages * Xymon clients now report the version number in the client data * Linux clients now align "ps" output so it is more readable. * New "generic" client message handler allows log/file monitoring from systems that are not known to Xymon. * The Xymon client now works if invoked with a relative path to the runclient.sh script * Other minor / internal bugfixes -- Henrik Stoerner Wed, 24 Jul 2013 10:24:01 +0200 xymon (4.3.11) unstable; urgency=low * rev 7188 * Fix wrong file permissions when installing * Linux client: Fix handling of root filesystem when mounted on "/dev/root" * trends webpage: Fix case where hostname disappears after zoom. * FreeBSD client: Memory patch for FreeBSD 8.0+ * xymond_alert: Fix problem with UNMATCHED rules triggering when there are actual recipients, but their alerts are suppressed due to a REPEAT setting not having expired. * xymond_rrd: Dont crash if called with an empty status/data message * xymond_channel: Report cause when channel-child exits/crashes * xymongen: Geneate an overview page with only reds (like non-green) * xymongen: Optionally define env. variable BOARDFILTER to select hosts/tests included in the generated pages * links: Add pdf, docx and odt as known document formats * Fix potential crashes after an alert cookie expired * Fix potential crash after deleting/renaming a host * Speedup loading of the hosts.cfg file, noticeable with very large hosts.cfg files (100.000+ hosts) -- Henrik Stoerner Sun, 21 Apr 2013 15:24:01 +0200 xymon (4.3.10) unstable; urgency=low * rev 7164 * Fix build problems with "errno" * Fix build problems with OpenSSL in non-default locations * Fix build problems with certain LDAP configurations * Fix build problems with RRDtool on FreeBSD / OpenBSD * Fix problem with ifstat data from Fedora in graphs * "inode" check on FreeBSD, OpenBSD, OSX, Solaris, HP/UX, AIX in addition to existing support for Linux * Document building and installing Xymon on common platforms (Linux, FreeBSD, OpenBSD, Solaris) * Enhance xymoncfg so it can be used to import Xymon configuration settings into shell-scripts. -- Henrik Stoerner Sat, 4 Aug 2012 13:47:00 +0200 xymon (4.3.9) unstable; urgency=low * rev 7120 * Fix crash when XYMSRV is undefined but XYMSERVERS is * Fix error in calculating combo-status messages with forward references * Fix error in disable-until-TIME or disable-until-OK code * Fix documentation of DURATION in alerts.cfg / xymond_alert so it is consistenly listed as being in "minutes". * Permit explicit use of ">" and ">=" in alerts.cfg * Permit building without the RRDtool libraries, e.g. for a network-tester build, but with trend-graphing disabled. * Full compiler-warning cleanup * Various configuration/build-script issues fixed. -- Henrik Stoerner Tue, 24 Jul 2012 18:21:00 +0200 xymon (4.3.8) unstable; urgency=low * rev 7082 Bugfixes * Workaround for DNS timeout handling, now fixed at approximately 25 seconds. * "hostinfo" command for xymond documented * confreport only shows processes that are monitored * analysis.cfg parsing of COLOR for UP rules was broken * RRD handlers no longer crash after receiving 1 billion updates * Using .netrc for authentication could crash xymonnet * "directory" includes would report the wrong filename for missing directories. * useradm CGI would invoke htpassword twice * "include" and "directory" now ignores trailing whitespace * SSLv2 support disabled if SSL-library does not support it * Minor bugfixes and cleanups of compiler warnings. Enhancements * Service status on info page now links to the detailed status page. * Add RRDGRAPHOPTS setting to permit global user-specified RRD options, e.g. for font to showgraph CGI * Add check for the size of public keys used in SSL certificates (enabled via --sslkeysize=N option for xymonnet) * Optionally disable the display of SSL ciphers in the sslcert status (the --no-cipherlist option for xymonnet) * Improved build-scripts works on newer systems with libraries in new and surprising places * Reduce xymonnet memory usage and runtime for ping tests when there are multiple hosts.cfg entries with the same IP-address. * Add code for inode-monitoring on Linux. Does not currently work on any other client platform. * Added the ability to disable tests until a specific time, instead of for some interval. Disabling a test also now computes the expire time for the disable to happen at the next closest minute. -- Henrik Stoerner Sun, 15 Jul 2012 17:00:00 +0200 xymon (4.3.7) unstable; urgency=low * rev 6803 * Fix acknowledge CGI (broken in 4.3.6) * Fix broken uptime calculation for systems reporting "1 day" * Workaround Solaris breakage in the LFS-support detection * Fix/add links to the HTML man-page index. * Fix "Stop after" value not being shown on the "info" page. * Fix broken alert texts when using FORMAT=SMS * Fix wrong description of xymondboard CRITERIA in xymon(1) * Fix missing columnname in analysis.cfg(5) DS example * Fix missing space in output from disk IGNORE rules in xymond_client --dump-config * Fix overwrite of xymon-apache.conf when upgrading * Fix installation so it does not remove include/directory lines from configuration files. * Add client/local/ directory for custom client script -- Henrik Stoerner Tue, 13 Dec 2011 13:15:00 +0100 xymon (4.3.6) unstable; urgency=low rev 6788 * Optionally choose the color for the "cpu" status when it goes non-green due to uptime or clock offset. * Allow for "include" and "directory" in combo.cfg and protocols.cfg * New INTERFACES definition in hosts.cfg to select which network interfaces are tracked in graphs. * New access control mechanism for some CGI scripts returning host-specific information. Access optionally checked against an Apache-style "group" file (see xymonwebaccess(5) CGI manpage). * New "vertical" page-definitions (vpage, vsubpage,vsubparent) for listing hosts across and tests down on a page. * Fix hostlist CGI crash when called with HTTP "HEAD" * Fix svcstatus CGI crash when called with non-existing hostname * Fix "ackinfo" updates being cleared when host hits a DOWNTIME period. * Fix compile-errors on Solaris due to network libraries not being included. * Fix "logrotate" messages not being sent to some channels. * STATUSLIFETIME now provides the default time a status is valid (in xymond). * Critical systems view: Use priority 99 for un-categorised priorities (imported from NK tags) and show this as 'No priority' on the webpage. * useradm CGI: Sort usernames * New xymond module - xymond_distribute - can forward administrative commands (drop, rename, disable, enable) from one Xymon server to another. * New tool: appfeed CGI provides data for the Android "xymonQV" app by Darrik Mazey. -- Henrik Stoerner Mon, 5 Dec 2011 08:00:00 +0100 xymon (4.3.5) unstable; urgency=medium rev 6755 * Fix crash in CGI generating the "info" status column. * Fix broken handling of IGNORE for log-file analysis. * Fix broken clean-up of obsolete cookies (no user impact). * Devmon RRD handler: Fix missing initialisation, which might cause crashes of the RRD handler. * Fix crashes in xymond caused by faulty new library for storing cookies and host-information. * Fix memory corruption/crash in xymond caused by logging of multi-source statuses. * New "delayred" and "delayyellow" definitions for a host can be used to delay change to a yellow/red status for any status column (replaces the network-specific "badFOO" definitions). * analysis.cfg and alerts.cfg: New DISPLAYGROUP setting to select hosts by the group/group-only/group-except text. * New HOSTDOCURL setting in xymonserver.cfg. Replaces the xymongen "--docurl" and "--doccgi" options, and is used by all tools. * xymond_history option to control location of PID file. * Critical Systems view: Optionally show eventlog for the hosts present on the CS view. * Critical Systems view: Multiple --config options can now be used, to display critical systems from multiple configurations on one page. * Detailed status display: Speedup by no longer having to load the hosts.cfg file. * xymongen / xymonnet: New "--loadhostsfromxymond" option. -- Henrik Stoerner Fri, 9 Sep 2011 10:35:00 +0200 xymon (4.3.4) unstable; urgency=medium rev 6720 * Fix crashes and data corruption in Xymon worker modules (xymond_client, xymond_rrd etc) after handling large messages. * Fix xymond lock-up when renaming/deleting hosts * Fix xymond cookie lookup mechanism * Fix xymond_client crash if analysis.cfg contains invalid configuration entries, e.g. expressions that do not compile. * Fix showgraph CGI crash when legends contain colon. * CGI utils: Fix potential security issues involving buffer- overruns when generating responses. * CGI utils: Fix crash when invoked with HTTP "HEAD" * CGI utils: Fix crashes on 64-bit platforms due to missing prototype of "basename()" function. * svcstatus CGI: Fix crash if history log is not a file. * Critical systems view CGI: Fix cross-site scripting * Fix recovery-messages for alerts sent to a GROUP * xymonnet: Include hostname when reporting erroneous test-spec * Webpages: Add new HOSTPOPUP setting to control what values from hosts.cfg are displayed as a "comment" to the hostname (either in pop-up's or next to the hostname). * RRD "memory" status handler now recognizes the output from the bb-xsnmp.pl module (for Cisco routers). * Web templates modified so the menu CSS can override the default body CSS. * Acknowledge web page now allows selecting minutes/hours/days * Enable/Disable webpage enhanced, so when selecting multiple hosts the "Tests" column only lists the tests those hosts have. -- Henrik Stoerner Mon, 1 Aug 2011 23:26:00 +0200 xymon (4.3.3) unstable; urgency=high rev 6684 * SECURITY FIX: Some CGI parameters were used to construct filenames of historical logfiles without being sanitized, so they could be abused to read files on the webserver. * SECURITY FIX: More cross-site scripting vulnerabilities. * Remove extra "," before "History" button on status-view * Critical view: Shring priority-column to 10% width * hosts.cfg loader: Check for valid IP spec (nibbles in 0-255 range). Large numbers in a nibble were accepted, triggering problems when trying to ping the host. * Alert macros no longer limited to 8kB -- Henrik Stoerner Mon, 6 May 2011 07:51:00 +0200 xymon (4.3.2) unstable; urgency=medium rev 6672 * Bugfix for problems caused by the XSS fixes. -- Henrik Stoerner Mon, 4 Apr 2011 07:34:00 +0200 xymon (4.3.1) unstable; urgency=medium rev 6667 * Web UI: SECURITY FIX - fix potential cross-site scripting vulnerabilities. Initial report by David Ferrest (email April 1st 2011). * Solaris Makefile: Drop guessing of what linker is being used, since we get it wrong too often. * configure: Add missing include to fix compile failure on some systems. * get_ostype(): Check that we have a valid OS identifier. Dont assume we can write to the string passed us. * xymond user messages: Improve error message for oversize messages. Document the MAXMSG_USER setting. * combostatus: Make the set of error-colors configurable. Change default set so BLUE and PURPLE are not considered errors (only RED is an error by default). * xymon(1) manpage: Add missing description of some fields available in the xymondboard command. * hosts.cfg manpage: Fix wrong NOPROP interpretation. From Thomas Brand. * Demotool: Change Hobbit->Xymon -- Henrik Stoerner Sun, 3 Apr 2011 12:03:00 +0200 xymon (4.3.0) unstable; urgency=medium * Critical view and other webpages: Make the 'All systems OK' message configurable. Also allow the header/footer for the Critical Systems view to be configurable. Suggestion and preliminary patch from Buchan Milne. * xymonnet: Improve error report when HTTP tests get an empty response - 'HTTP error 0' sounds weird. * report / snapshot CGI's: Fix buffer overrun in the HTML delimiter generated in the "please wait..." message. Also, fix potential buffer overrun in report CGI if invoked with a large value for the "style" parameter. Reported by Rolf Biesbroek. * Graph definitions (graphs.cfg): Multi graphs cannot use a regex pattern. Problem report by Brian Majeska * Solaris interface statistics: Filter out "mac" and "wrsmd" devices at the client side. Update RRD handler to also filter "wrsmd" at the server side, like we already did for "mac" devices. Cf. http://www.xymon.com/archive/2009/06/msg00204.html * Documentation: Document the XMH_* fields available in xymondboard commands. * Documentation: Document SPLITNCV and "trends" methods of doing custom graphs. * RRD definitions: Allow override of --step/-s option for rrdcreate, from template supplied in rrddefinitions.cfg. Suggestion from Brian Majeska. * mailack: Remove restriction on how long a subjectline/message body can be. * Build procedure: Add notice about running upgrade script before installing the new version. * xymond_alert: Document --trace option * Alerts: For recovery messages, add information so you can tell whether the recovery was due to the service actually recovering, or if it was merely disabled. * xymond_alert: Fix missing element in array of alert status texts used for tracing. Spotted by Dominique Frise. * Add support for FreeBSD v8 modified ifstat output * Documentation: Update information about the Xymon mailing lists following move to Mailman and new archive URL. * HP/UX client: Use "swapinfo" to extract memory utilisation data, instead of the hpux-meminfo utility. By Earl Flack http://lists.xymon.com/pipermail/xymon/2010-December/030100.html -- Henrik Stoerner Fri, 4 Mar 2011 11:08:00 +0100 xymon (4.3.0-0.20110120.rc1) unstable; urgency=low * 4.3.0 RC1 release - rev 6627 * hosts.cfg badldap documentation: Document that for LDAP URL's you must use 'badldapurl'. Reported by Simo Hmami. * xymond flap detection: Make number of tracked status changes and the flap-check period configurable. Change the defaults to trigger flapping at more than 5 status changes in a 30 minute period. * sendmessage: Enhanced error reporting, to help track down communication problems. * xymond_client: Fix Windows SVC status handling to avoid coredumps, memory corruption and other nasties. Will now report the real name of the service, instead of the pattern used in the analysis.cfg file. NOTE: Slight change to status message format. * Client handler: Fix owner/user check parsing. Reported by Ian Marsh http://www.xymon.com/archive/2011/01/msg00133.html (also broken in 4.2.3). * xymongen: Fix broken --doc-window option handling. Reported by Tom Schmitt. * Xymongen: Fix documentation of the --doc-window/--no-doc-window options. * Webpage background: Use a CSS and a new set of gif's to implement a background that works on all displays, regardless of width. Uses a new xymonbody.css stylesheet which can also control some other aspects of the webpage. From Francois Claire. * Documentation: The xymon 'rename' command should be used AFTER renaming a host in hosts.cfg, not before. From Tom Georgoulias. * Memory status: Add some sanity checks for the memory utilisation reported by clients. Occasionally we get completely bogus data from clients, so only act on them if percentages do not exceed 100. * Critical systems view: Add "--tooltips" option so you can save screen space by hiding the host descriptions in a tooltip, like we do on the statically generated pages. Feature request from Chris Morris. * Solaris client: Report "swap -l" in addition to "swap -s" for swap usage. Backend prefers output from "swap -l" when determining swap utilisation. * Webpage menu: Use the CSS and GIF's by Malcolm Hunter - they are much nicer than the ones from Debian. Distribute both the blue and the grey version, and configure which one to use in xymonserver.cfg. * Graph zoom: Use float variables when calculating the upper/lower limits of the graph. Fixes vertical zoom. * xymond: Make sure we do not perform socket operations on invalid sockets (e.g. those from a scheduled task pseudo-connection) * Installation: Remove any existing old commands before creating symlinks * xymonproxy: Fix broken compatibility option '--bbdisplay' * Fix eventlog summary/count enums so they dont clash with Solaris predefined entities * History- and hostdata-modules: Dont save data if there is less than 5% free space on the filesystem. Also, dont save hostdata info more than 5 times per hour. * Historical statuslog display: Work-around for crash when status-log is empty * fping.sh configure sub-script: Fix syntax error in suggested 'sudoers' configuration, and point to the found fping binary. From Steff Coene. * namematch routine: Fix broken matching when doing simple matching against two strings where one was a subset of the other. http://www.xymon.com/archive/2010/11/msg00177.html . Reported by Elmar Heeb who also provided a patch, although I chose a different solution to this. * Xymon net: Fix broken compile when LDAP-checks are disabled. Reported by Roland Soderstrom, fix from Ralph Mitchell. * xymon(7) manpage: Drop notice that renaming in 4.3.0 is not complete * Installation: Setup links for the commonly used Hobbit binaries (bb, bbcmd, bbdigest, bbhostgrep, bbhostshow) * Upgrade script: Setup symlinks for the old names of the standard webpages * xymonserver.cfg.DIST: Missing end-quote in compatibility BBSERVERSECURECGIURL setting. From Ralph Mitchell * xymongrep: Fix broken commandline parsing resulting from trying to be backwards-compatible. Reported by Jason Chambers. -- Henrik Stoerner Sun, 23 Jan 2011 12:36:00 +0100 xymon (4.3.0-0.20101114.beta3) unstable; urgency=low * Beta-3 release - rev 6590 -- Henrik Stoerner Sun, 14 Nov 2010 19:00:00 +0100 hobbit (4.3.0-0.beta2) unstable; urgency=low * Xymon version 4.3.0 BETA 2 Core changes: * New API's for loadhosts and sendmessage, in preparation for the full 5.0 changes. * Always use getcurrenttime() instead of time(). * Support for defining holidays as non-working days in alerts and SLA calculations. * Hosts which appear on multiple pages in the web display can use any page they are on in the alerting rules and elsewhere. * Worker modules (RRD, client-data parsers etc) can operate on remote hosts from the hobbitd daemon, for load-sharing. * Various bugfixes collected over time. * New client support: z/OS, z/VSE and z/VM. Network test changes: * Merged new network tests from trunk: SOAP-over-HTTP, SSL minimum cipher strength * Changed network test code to always report a validity period for network tests, so it it possible to run network tests less often than every 30 minutes (e.g. once an hour). * Make the content-type setting in HTTP POST tests configurable. * Make the source-address used for TCP tests configurable. * Make the acceptable HTTP result codes configurable. * Use and save HTTP session cookies. Web changes * Support generic drop-down lists in templates. * "NOCOLUMNS" changed to work for all columns. * New "group-sorted" definition to auto-sort hosts in a group * Use browser tooltips for host comments * "Compact" status allows several statuses to appear as a single status on the overview webpages. * Trends page can select the time period to show. Buttons provided for the common selections. * Ghost list report now lists possible candidates for a ghost, based on IP-address or unqualified hostname. * Enhanced eventlog and top-changing hosts webpage Report changes * Number of outages as SLA parameter Miscellaneous * hobbitlaunch support for running tasks only on certain hosts, and for a maximum time. -- Henrik Stoerner Fri, 24 May 2009 10:39:00 +0200 hobbit (4.2.3-1) unstable; urgency=low * Xymon version 4.2.3 release * Time-out code changed to use clock_gettime() with CLOCK_MONOTONIC * Bugfix for hobbitd/hobbitd_worker communication going out-of-sync resulting in "garbled data" being logged and worker modules stopping. * NCV module now works with negative numbers. * Several bugfixes in DNS lookup code - could lead to crashes when performing DNS tests. * Switch to C-ARES 1.6.0 - drop support for older versions. * Run more TCP tests in parallel by not waiting for very slow connections to complete before starting new ones. * Added "hostlist" web utility for spreadsheet-reporting of the hosts in Hobbit. -- Henrik Stoerner Mon, 09 Feb 2009 10:46:00 +0100 hobbit (4.2.2-1) unstable; urgency=low * Xymon version 4.2.2: 4.2.0 plus all-in-one patch * BBWin support added * Project renamed to "Xymon" - preliminary changes in documents and web templates, but no filename changes. -- Henrik Stoerner Thu, 28 Sep 2008 14:52:00 +0100 hobbit (4.2.0-1) unstable; urgency=low * Hobbit version 4.2: New upstream release. -- Henrik Stoerner Wed, 09 Aug 2006 21:48:00 +0200 hobbit (4.2-RC-20060712) unstable; urgency=low * Release candidate of 4.2 -- Henrik Stoerner Wed, 12 Jul 2006 23:13:00 +0200 hobbit (4.2-beta-20060605) unstable; urgency=low * Beta release of 4.2 -- Henrik Stoerner Mon, 05 Jun 2006 16:53:00 +0200 hobbit (4.2-alfa-20060404) unstable; urgency=low * Alfa release of 4.2 -- Henrik Stoerner Tue, 04 Apr 2006 23:30:00 +0200 hobbit (4.1.2p1-1) unstable; urgency=low * New upstream release -- Henrik Stoerner Thu, 10 Nov 2005 17:32:00 +0100 hobbit (4.1.2-1) unstable; urgency=low * New upstream release -- Henrik Stoerner Mon, 10 Oct 2005 22:30:00 +0200 hobbit (4.1.1-1) unstable; urgency=low * New upstream release. -- Henrik Stoerner Mon, 25 Jul 2005 17:49:00 +0200 hobbit (4.1.0-1) unstable; urgency=low * New upstream release. -- Henrik Stoerner Sun, 24 Jul 2005 23:27:00 +0200 hobbit (4.0.4-1) unstable; urgency=low * New upstream release. -- Henrik Stoerner Sun, 29 May 2005 12:08:00 +0200 hobbit (4.0.3-1) unstable; urgency=low * New upstream release. -- Henrik Stoerner Sun, 22 May 2005 09:34:57 +0200 hobbit (4.0.2-1) unstable; urgency=low * New upstream release. -- Henrik Stoerner Sun, 10 Apr 2005 19:39:15 +0200 hobbit (4.0.1-1) unstable; urgency=low * Build problems fixed on Solaris, HP-UX * Zoomed graphs could lose the hostname in the title. -- Henrik Stoerner Fri, 1 Apr 2005 07:43:42 +0200 hobbit (4.0-1) unstable; urgency=low * Upstream release of version 4.0 -- Henrik Stoerner Wed, 30 Mar 2005 21:31:03 +0200 xymon-4.3.30/debian/xymon-client.init0000664000076400007640000000472211535462534017755 0ustar rpmbuildrpmbuild#! /bin/sh # # xymonclient This shell script takes care of starting and stopping # the Xymon client. ### BEGIN INIT INFO # Provides: xymon-client # Required-Start: $remote_fs $network # Should-Start: $all # Required-Stop: $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Xymon system monitor client # Description: Client to feed system data to a remote Xymon server. ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON="/usr/lib/xymon/client/bin/xymonlaunch" NAME=xymonclient DESC="Xymon Client" PIDFILE="/var/run/xymon/clientlaunch.pid" XYMONCLIENTHOME="/usr/lib/xymon/client" test -x $DAEMON || exit 0 . /lib/lsb/init-functions . /usr/share/xymon/init-common.sh # Include xymonclient defaults if available if [ -f /etc/default/xymon-client ] ; then . /etc/default/xymon-client fi [ -z "$MACHINE" ] && MACHINE="$CLIENTHOSTNAME" [ -z "$MACHINEDOTS" ] && MACHINEDOTS="`hostname -f`" export XYMONSERVERS XYMONCLIENTHOME CLIENTHOSTNAME MACHINE MACHINEDOTS case "$1" in start) # do not run the client script on the server [ -x /usr/lib/xymon/server/bin/xymond ] && exit 0 create_includefiles log_daemon_msg "Starting $DESC" "$NAME" start-stop-daemon --exec $DAEMON --chuid xymon --umask 022 --start \ -- \ --config=/etc/xymon/clientlaunch.cfg \ --log=/var/log/xymon/clientlaunch.log \ --pidfile=$PIDFILE log_end_msg $? ;; stop) log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --exec $DAEMON --pidfile $PIDFILE --stop --retry 5 log_end_msg $? ;; status) if test -s $PIDFILE then kill -0 `cat $PIDFILE` if test $? -eq 0 then echo "Xymon client running with PID `cat $PIDFILE`" exit 0 else echo "Xymon client not running, removing stale PID file" rm -f $PIDFILE exit 1 fi else echo "Xymon client does not appear to be running" exit 3 fi ;; restart) if [ -x /usr/lib/xymon/server/bin/xymond ] ; then log_action_msg "Xymon server installed. Please restart 'xymon' instead" exit 0 fi $0 stop sleep 1 $0 start ;; reload|force-reload) [ -x /usr/lib/xymon/server/bin/xymond ] && exit 0 create_includefiles kill -HUP `cat /var/run/xymon/clientlaunch.pid` ;; rotate) for PIDFILE in /var/run/xymon/*.pid do test -e $PIDFILE && kill -HUP `cat $PIDFILE` done ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload|status|rotate}" >&2 exit 1 ;; esac exit 0 xymon-4.3.30/debian/rules0000775000076400007640000001117711535462534015524 0ustar rpmbuildrpmbuild#!/usr/bin/make -f CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif Makefile: configure dh_testdir # Add here commands to configure the package. USEXYMONPING=y \ ENABLESSL=y \ ENABLELDAP=y \ ENABLELDAPSSL=y \ XYMONUSER=xymon \ XYMONTOPDIR=/usr/lib/xymon \ XYMONVAR=/var/lib/xymon \ XYMONHOSTURL=/xymon \ CGIDIR=/usr/lib/xymon/cgi-bin \ XYMONCGIURL=/xymon-cgi \ SECURECGIDIR=/usr/lib/xymon/cgi-secure \ SECUREXYMONCGIURL=/xymon-seccgi \ HTTPDGID=www-data \ XYMONLOGDIR=/var/log/xymon \ XYMONHOSTNAME=localhost \ XYMONHOSTIP=127.0.0.1 \ MANROOT=/usr/share/man \ INSTALLBINDIR=/usr/lib/xymon/server/bin \ INSTALLETCDIR=/etc/xymon \ INSTALLWEBDIR=/etc/xymon/web \ INSTALLEXTDIR=/usr/lib/xymon/server/ext \ INSTALLTMPDIR=/var/lib/xymon/tmp \ INSTALLWWWDIR=/var/lib/xymon/www \ ./configure build: build-stamp build-stamp: Makefile dh_testdir # Parallel building does not work as of 4.3.0~beta2 PKGBUILD=1 $(MAKE) -j1 touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp [ ! -f Makefile ] || $(MAKE) distclean dh_clean # debconf-updatepo S=$(CURDIR)/debian/xymon C=$(CURDIR)/debian/xymon-client install-clean: dh_prep install: install-server install-client install-server: build install-clean #################### Installing server ######################## dh_testdir dh_testroot dh_install -a dh_installdirs -a PKGBUILD=1 INSTALLROOT=$S/ $(MAKE) install # Static content in /usr/share cd $S/var/lib/xymon/www && \ mv gifs ../../../../usr/share/xymon && ln -s ../../../../usr/share/xymon/gifs . && \ mv help ../../../../usr/share/xymon && ln -s ../../../../usr/share/xymon/help . && \ mv menu ../../../../usr/share/xymon && ln -s ../../../../usr/share/xymon/menu . # We depend on the -client package rm -rf $S/usr/lib/xymon/client # This needs root chmod 4755 $S/usr/lib/xymon/server/bin/xymonping mv $S/etc/xymon/xymon-apache.conf \ $S/etc/apache2/conf.d/xymon # Make xymonserver.cfg use the settings we have configured during installation echo "include /etc/default/xymon-client" > $S/etc/xymon/xymonserver.cfg.debian sed -f debian/xymonserver-setup.sed $S/etc/xymon/xymonserver.cfg >> $S/etc/xymon/xymonserver.cfg.debian rm $S/etc/xymon/xymonserver.cfg mv $S/etc/xymon/xymonserver.cfg.debian $S/etc/xymon/xymonserver.cfg # Autogenerated on first install rm $S/etc/xymon/hosts.cfg install-client: build install-clean #################### Installing client ######################## dh_testdir dh_testroot dh_install -a dh_installdirs -a PKGBUILD=1 INSTALLROOT=$C/ $(MAKE) install-client cd $C/usr/lib/xymon/client && mv etc/* $C/etc/xymon && rmdir etc && ln -s ../../../../etc/xymon etc cd $C/usr/lib/xymon/client && rmdir logs && ln -s ../../../../var/log/xymon logs cd $C/usr/lib/xymon/client && rmdir tmp && ln -s ../../../../var/lib/xymon/tmp # the only command needed in /usr/bin is xymoncmd, its PATH includes our private .../bin # but install xymon also, since it is used so much. cd $C/usr/bin && ln -s ../lib/xymon/client/bin/xymoncmd xymoncmd cd $C/usr/bin && ln -s ../lib/xymon/client/bin/xymon xymon cp debian/xymon-client.default.dist $C/usr/share/xymon/xymon-client.default # dynamic list of installed client extensions echo "include /var/run/xymon/clientlaunch-include.cfg" >> \ $C/etc/xymon/clientlaunch.cfg rm $C/usr/lib/xymon/client/runclient.sh binary: binary-arch binary-indep #binary-indep: # #################### Building dummy packages ######################## # dh_testdir -i # dh_installchangelogs -i # dh_installdocs -i # dh_compress -i # dh_gencontrol -i # dh_builddeb -i binary-arch: build install-server install-client #################### Building .deb files ######################## dh_testdir -a dh_testroot -a dh_installchangelogs -a Changes dh_installdocs -a dh_installexamples -a # ignore missing dh_lintian for older dh versions -dh_lintian -a # move some files into the client package dh_movefiles --sourcedir=debian/xymon -a cd $S/usr/lib/xymon/server/bin && \ for f in * ; do \ if [ -f $C/usr/lib/xymon/client/bin/$$f ] ; then \ rm -v $$f ; ln -s ../../client/bin/$$f ; \ fi \ done rmdir $S/usr/share/man/man7 dh_installdebconf -a # use the old file names for now dh_installlogrotate --name=xymon-client -a dh_installinit --name=xymon -p'xymon' -- defaults 98 02 dh_installinit --name=xymon-client -p'xymon-client' -- defaults 98 02 dh_installman -a dh_link -a dh_strip -a dh_compress -a dh_fixperms -a -Xbin/xymonping dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a .PHONY: build clean binary-indep binary-arch binary install install-server install-client xymon-4.3.30/debian/xymon.dirs0000664000076400007640000000011612266740721016467 0ustar rpmbuildrpmbuildetc/apache2/conf.d etc/xymon/graphs.d etc/xymon/xymonserver.d usr/share/xymon xymon-4.3.30/debian/xymon-client.install0000664000076400007640000000004611535424634020452 0ustar rpmbuildrpmbuilddebian/init-common.sh usr/share/xymon xymon-4.3.30/debian/xymon-client.files0000664000076400007640000000063311535424634020110 0ustar rpmbuildrpmbuildusr/share/man/man1/xymon.1 usr/share/man/man1/xymoncmd.1 usr/share/man/man1/xymondigest.1 usr/share/man/man1/xymongrep.1 usr/share/man/man1/xymoncfg.1 usr/share/man/man5/clientlaunch.cfg.5 usr/share/man/man1/clientupdate.1 usr/share/man/man7/xymon.7 usr/share/man/man5/xymonclient.cfg.5 usr/share/man/man8/xymonlaunch.8 usr/share/man/man1/logfetch.1 usr/share/man/man8/msgcache.8 usr/share/man/man1/orcaxymon.1 xymon-4.3.30/debian/xymon.init0000664000076400007640000000434611535462534016503 0ustar rpmbuildrpmbuild#!/bin/sh # Startup script for the Xymon monitor # # This starts the "xymonlaunch" tool, which in turn starts # all of the other Xymon server programs. ### BEGIN INIT INFO # Provides: xymon # Required-Start: $remote_fs $network # Should-Start: $all # Required-Stop: $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Xymon system monitor server # Description: Xymon system monitor, server part. # (Also monitors the local host.) ### END INIT INFO PIDFILE=/var/run/xymon/xymonlaunch.pid DAEMON=/usr/lib/xymon/server/bin/xymonlaunch NAME="xymond" DESC="Xymon Server" test -x $DAEMON || exit 0 . /lib/lsb/init-functions . /usr/share/xymon/init-common.sh # Include xymonclient defaults if available if [ -f /etc/default/xymon-client ] ; then . /etc/default/xymon-client fi case "$1" in "start") create_includefiles log_daemon_msg "Starting $DESC" "$NAME" start-stop-daemon --exec $DAEMON --chuid xymon --umask 022 --start \ -- \ --config=/etc/xymon/tasks.cfg \ --env=/etc/xymon/xymonserver.cfg \ --log=/var/log/xymon/xymonlaunch.log \ --pidfile=$PIDFILE log_end_msg $? ;; "stop") log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --exec $DAEMON --pidfile $PIDFILE --stop --retry 5 log_end_msg $? ;; "status") if test -s $PIDFILE then kill -0 `cat $PIDFILE` if test $? -eq 0 then echo "Xymon (xymonlaunch) running with PID `cat $PIDFILE`" exit 0 else echo "Xymon not running, removing stale PID file" rm -f $PIDFILE exit 1 fi else echo "Xymon (xymonlaunch) does not appear to be running" exit 3 fi ;; "restart") if test -s $PIDFILE then $0 stop sleep 1 $0 start else log_action_msg "xymonlaunch does not appear to be running, starting it" $0 start fi ;; "reload"|"force-reload") if test -s $PIDFILE then create_includefiles log_action_msg "Reloading xymond config" kill -HUP `cat /var/run/xymon/xymond.pid` else log_action_msg "xymond not running (no PID file)" fi ;; "rotate") for PIDFILE in /var/run/xymon/*.pid do test -e $PIDFILE && kill -HUP `cat $PIDFILE` done ;; *) echo "Usage: $0 start|stop|restart|force-reload|reload|status|rotate" break; esac exit 0 xymon-4.3.30/debian/compat0000664000076400007640000000000211535462534015633 0ustar rpmbuildrpmbuild7 xymon-4.3.30/debian/xymon-client.postinst0000664000076400007640000000402411535462534020670 0ustar rpmbuildrpmbuild#! /bin/sh # postinst script for xymon # # see: dh_installdeb(1) # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # . /usr/share/debconf/confmodule set -e case "$1" in configure) getent group xymon > /dev/null || addgroup --system xymon getent passwd xymon > /dev/null || adduser --system \ --home /var/run/xymon --no-create-home \ --ingroup xymon --disabled-password --disabled-login \ --gecos "Xymon System Monitor" xymon test -d /var/run/xymon || mkdir /var/run/xymon chown xymon:xymon /var/run/xymon test -d /var/lib/xymon/tmp || mkdir /var/lib/xymon/tmp chown xymon:xymon /var/lib/xymon/tmp test -d /var/log/xymon || mkdir /var/log/xymon chown xymon:adm /var/log/xymon ; chmod 2755 /var/log/xymon # Do the debconf stuff db_get xymon-client/XYMONSERVERS XYMONSERVERS="$RET" db_get xymon-client/CLIENTHOSTNAME CLIENTHOSTNAME="$RET" db_stop # Update configuration file CONFIGFILE=/etc/default/xymon-client test -e $CONFIGFILE || cp /usr/share/xymon/xymon-client.default $CONFIGFILE if grep -q "^XYMONSERVERS=" $CONFIGFILE ; then sed -i -e "s/^XYMONSERVERS=.*/XYMONSERVERS=\"$XYMONSERVERS\"/" \ $CONFIGFILE else echo "XYMONSERVERS=\"$XYMONSERVERS\"" >> $CONFIGFILE fi if grep -q "^CLIENTHOSTNAME=" $CONFIGFILE ; then sed -i -e "s/^CLIENTHOSTNAME=.*/CLIENTHOSTNAME=\"$CLIENTHOSTNAME\"/" \ $CONFIGFILE else echo "CLIENTHOSTNAME=\"$CLIENTHOSTNAME\"" >> $CONFIGFILE fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 xymon-4.3.30/debian/xymon-client.templates0000664000076400007640000000114411535462534021003 0ustar rpmbuildrpmbuildTemplate: xymon-client/XYMONSERVERS Type: string Default: 127.0.0.1 Description: Xymon server: Please enter the network address used to access the Xymon server(s). If you use multiple servers, use a space-separated list of addresses. . Using host names instead of IP addresses is discouraged in case the network experiences DNS failures. Template: xymon-client/CLIENTHOSTNAME Type: string Default: Description: Client hostname: Please enter the host name used by the Xymon client when sending reports to the Xymon server. This name must match the name used in the hosts.cfg file on the Xymon server. xymon-4.3.30/debian/control0000664000076400007640000000313412271200770016027 0ustar rpmbuildrpmbuildSource: xymon Section: net Priority: extra Maintainer: Henrik Stoerner Build-Depends: debhelper (>= 7), libc-ares-dev, librrd2-dev, libssl-dev, libldap2-dev, libpcre3-dev Standards-Version: 3.8.3 Homepage: http://xymon.sourceforge.net/ Package: xymon Architecture: any Conflicts: hobbit, hobbit-client Provides: xymon Replaces: hobbit, hobbit-client Depends: xymon-client, ${shlibs:Depends}, ${misc:Depends} Description: monitoring system for systems, networks and applications Xymon (previously called Hobbit) is a network- and applications- monitoring system designed for use in large-scale networks. But it will also work just fine on a small network with just a few nodes. It is low-overhead and high-performance, with an easy to use web front-end. It handles monitoring of network services, and through client packages it can also be used to monitor server- specific items. Alerts can trigger when monitoring detects a problem, resulting in e-mails or calls to your pager or mobile phone. . Xymon has a great deal of inspiration from the non-free Big Brother package, but does not include any Big Brother code. Package: xymon-client Architecture: any Conflicts: hobbit, hobbit-client Provides: xymon-client Replaces: hobbit, hobbit-client Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, lsb-base Description: client for the Xymon network monitor Client data collection package for Xymon (previously known as Hobbit). This gathers statistics and data from a single system and reports it to the Xymon monitor. You should run this on all systems if you have a Xymon server installed. xymon-4.3.30/debian/xymon.postinst0000664000076400007640000000477012263613525017421 0ustar rpmbuildrpmbuild#! /bin/sh # postinst script for Xymon # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in configure) # Setup permissions for the newly created "xymon" user to write # data where he needs to. # And for the Apache-run CGI's to generate reports. test -d /var/run/xymon || mkdir /var/run/xymon chown xymon:xymon /var/run/xymon test -d /var/log/xymon || mkdir /var/log/xymon chown xymon:adm /var/log/xymon ; chmod 2755 /var/log/xymon cd /var/lib/xymon; chown xymon:xymon . acks data disabled hist histlogs hostdata logs rrd tmp www cd /var/lib/xymon/www; chown xymon:xymon html notes wml rep snap; chgrp www-data rep snap; chmod g+w rep snap cd /etc/xymon; chgrp www-data critical.cfg critical.cfg.bak; chmod g+w critical.cfg critical.cfg.bak if ! test -e /etc/xymon/hosts.cfg ; then if test -e /etc/default/xymon-client ; then . /etc/default/xymon-client || true fi cat > /etc/xymon/hosts.cfg <&2 exit 1 ;; esac #DEBHELPER# exit 0 xymon-4.3.30/debian/xymon-client.default.dist0000664000076400007640000000115011535424634021367 0ustar rpmbuildrpmbuild# Configure the Xymon client settings. # You MUST set the list of Xymon servers that this # client reports to. # It is good to use IP-adresses here instead of DNS # names - DNS might not work if there's a problem. # (Internally this will be translated to XYMSRV and XYMSERVERS # variables in /var/run/xymon/bbdisp-include.cfg) # # E.g. (a single Xymon server) # XYMONSERVERS="192.168.1.1" # or (multiple servers) # XYMONSERVERS="10.0.0.1 192.168.1.1" XYMONSERVERS="" # Hostname used by the client for its reports. # Must match the name for this host in the Xymon servers' # hosts.cfg file. CLIENTHOSTNAME="" xymon-4.3.30/debian/default0000664000076400007640000000114011535462534016000 0ustar rpmbuildrpmbuild# Configure the Xymon client settings. # You MUST set the list of Xymon servers that this # client reports to. # It is good to use IP-adresses here instead of DNS # names - DNS might not work if there's a problem. # # E.g. (a single Xymon server) # XYMONSERVERS="192.168.1.1" # or (multiple servers) # XYMONSERVERS="10.0.0.1 192.168.1.1" XYMONSERVERS="" # The defaults usually suffice for the rest of this file, # but you can tweak the hostname that the client reports # data with, and the OS name used (typically needed only on # RHEL or RHAS servers). # CLIENTHOSTNAME="" # CLIENTOS="rhel3" xymon-4.3.30/debian/xymon.lintian-overrides0000664000076400007640000000034511535424634021170 0ustar rpmbuildrpmbuildxymon: package-contains-empty-directory usr/lib/xymon/server/download/ #446982 xymon: possibly-insecure-handling-of-tmp-files-in-maintainer-script preinst:30 xymon: setuid-binary usr/lib/xymon/server/bin/xymonping 4755 root/root xymon-4.3.30/debian/xymonserver-setup.sed0000664000076400007640000000031311535424634020665 0ustar rpmbuildrpmbuilds!XYMONSERVERHOSTNAME="localhost"!XYMONSERVERHOSTNAME="$CLIENTHOSTNAME"! s!XYMONSERVERWWWNAME="localhost"!XYMONSERVERWWWNAME="$CLIENTHOSTNAME"! s!XYMONSERVERIP="127.0.0.1"!XYMONSERVERIP="$XYMONSERVERS"! xymon-4.3.30/debian/xymon-client.dirs0000664000076400007640000000016511535462534017750 0ustar rpmbuildrpmbuildetc/default etc/xymon/clientlaunch.d etc/xymon/xymonclient.d usr/bin usr/share/xymon var/lib/xymon/tmp var/log/xymon xymon-4.3.30/debian/xymon.postrm0000664000076400007640000000225111535462534017055 0ustar rpmbuildrpmbuild#! /bin/sh # postrm script for Xymon # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' overwrit>r> # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in purge|disappear) rm -f /etc/xymon/hosts.cfg /etc/xymon/xymongroups /etc/xymon/xymonpasswd \ /etc/default/xymon if test -e /usr/share/debconf/confmodule ; then . /usr/share/debconf/confmodule db_purge fi ;; remove) ;; upgrade) # The server package doesn't use debconf anymore if dpkg --compare-versions "$2" lt 4.2.0.dfsg-2 && test -e /usr/share/debconf/confmodule ; then . /usr/share/debconf/confmodule db_purge fi ;; failed-upgrade|abort-install|abort-upgrade) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 xymon-4.3.30/debian/xymon-client.logrotate0000664000076400007640000000044611535424634021010 0ustar rpmbuildrpmbuild# # Logrotate fragment for Xymon (client and server). # /var/log/xymon/*.log { weekly compress delaycompress rotate 5 missingok nocreate sharedscripts postrotate /etc/init.d/xymon rotate endscript } xymon-4.3.30/configure.server0000775000076400007640000003721113457402722016431 0ustar rpmbuildrpmbuild#!/bin/sh # Configure script for Xymon server # $Id: configure.server 8052 2019-04-22 18:20:02Z jccleaver $ echo "" echo "Configuration script for Xymon" echo "" while test "$1" != "" do OPT="$1"; shift case "$OPT" in "--help") cat <&1 | head -n 1 | awk '{print $1 " " $2}'` if test "$MAKEVER" != "GNU Make" then echo "GNU make is required to build Xymon." echo "If it is available as \"gmake\", run configure as: 'MAKE=gmake $0'" exit 1 fi echo "Checking pre-requisites for building Xymon" echo "" . build/fping.sh echo ""; echo "" . build/pcre.sh echo ""; echo "" . build/c-ares.sh echo ""; echo "" . build/rrd.sh if test "$RRDOK" = "NO" then ENABLERRD="n" else ENABLERRD="y" fi echo ""; echo "" . build/ssl.sh if test "$SSLOK" = "NO" then ENABLESSL="n" SSLDEF="" else echo "" echo "Xymon can use the OpenSSL library to test SSL-enabled services" echo "like https-encrypted websites, POP3S, IMAPS, NNTPS and TELNETS." echo "If you have the OpenSSL library installed, I recommend that you enable this." echo "" echo "Do you want to be able to test SSL-enabled services (y) ?" if test "$ENABLESSL" = "" then read ENABLESSL fi if test "$ENABLESSL" = "" -o "$ENABLESSL" = "y" then ENABLESSL="y" SSLDEF="-DHAVE_OPENSSL" if test "$OSSL2OK" = "Y" then SSLDEF="$SSLDEF -DHAVE_SSLV2_SUPPORT=1" fi if test "$OSSL3OK" = "Y" then SSLDEF="$SSLDEF -DHAVE_SSLV3_SUPPORT=1" fi else ENABLESSL="n" SSLDEF="" fi echo "" fi echo ""; echo ""; . build/ldap.sh if test "$LDAPOK" = "NO" then ENABLELDAP="n" LDAPDEF="" else echo "" echo "Xymon can use your $LDAPVENDOR LDAP client library to test LDAP servers." echo "" echo "Do you want to be able to test LDAP servers (y) ?" if test "$ENABLELDAP" = "" then read ENABLELDAP fi if test "$ENABLELDAP" = "" -o "$ENABLELDAP" = "y" then ENABLELDAP="y" LDAPDEF="-DHAVE_LDAP" else ENABLELDAP="n" LDAPDEF="" fi echo "" fi echo ""; echo ""; . build/clock-gettime-librt.sh echo ""; echo "" if test "$SNMP" = "1" then . build/snmp.sh echo ""; echo "" else DOSNMP=no fi MAKE="$MAKE -s" ./build/lfs.sh if test $? -eq 0; then LFS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" else LFS="" fi echo ""; echo "" # Pre-requisites completed. echo "Setting up for a Xymon server" echo ""; echo "" echo "What userid will be running Xymon [xymon] ?" if test -z "$XYMONUSER" then read XYMONUSER fi if test -z "$XYMONUSER" then XYMONUSER="xymon" fi if test -z "$XYMONTOPDIR" then if test "`uname -s`" = "Darwin" then # Use "dscl" for locating user information. From Isaac Vetter # http://www.xymon.com/archive/2008/02/msg00173.html USERDATA="`dscl . -list /Users | grep $XYMONUSER`" if test "$USERDATA" != "" then echo "Found Directory entry for user: $USERDATA" else echo "FAILURE: The user $XYMONUSER does not exist locally. Create user and try again." exit 1 fi echo ""; echo "" HOMEDIR="`dscl . -read /Users/$XYMONUSER | grep HomeDirectory | awk '{print $2}'`" else USERDATA=`getent passwd $XYMONUSER 2>/dev/null || ypmatch "${XYMONUSER}" passwd || grep "^${XYMONUSER}:" /etc/passwd` if test $? -eq 0 then echo "Found passwd entry for user $USERDATA" else echo "FAILURE: The user $XYMONUSER does not exist. Create user and try again." exit 1 fi echo ""; echo "" HOMEDIR="`echo $USERDATA|cut -d: -f6`" fi else HOMEDIR="$XYMONTOPDIR" fi echo "Where do you want the Xymon installation [${HOMEDIR}] ?" if test -z "$XYMONTOPDIR" then read XYMONTOPDIR fi if test -z "$XYMONTOPDIR" then XYMONTOPDIR=${HOMEDIR} fi if test -d "$XYMONTOPDIR" then echo "OK, will configure to use $XYMONTOPDIR as the Xymon toplevel directory" else echo "WARNING: $XYMONTOPDIR does not exist." fi echo ""; echo "" echo "What URL will you use for the Xymon webpages [/xymon] ? " if test -z "$XYMONHOSTURL" then read XYMONHOSTURL fi if test -z "$XYMONHOSTURL" then XYMONHOSTURL="/xymon" elif test "$XYMONHOSTURL" = "/" then # For Xymon as the root URL, we must clear this setting. # Otherwise, gifs, menus etc stop working because we generate # URL's begining with "//" XYMONHOSTURL="" fi echo ""; echo "" echo "Where to put the Xymon CGI scripts [$XYMONTOPDIR/cgi-bin] ? " echo "(Note: This is the filesystem directory - we will get to the URL shortly)" if test -z "$CGIDIR" then read CGIDIR fi if test -z "$CGIDIR" then CGIDIR=$XYMONTOPDIR/cgi-bin fi echo ""; echo "" echo "What is the URL for the Xymon CGI directory [/xymon-cgi] ? " echo "(Note: This is the URL - NOT the filesystem directory)" if test -z "$XYMONCGIURL" then read XYMONCGIURL fi if test -z "$XYMONCGIURL" then XYMONCGIURL="/xymon-cgi" fi echo ""; echo "" echo "********************** SECURITY NOTICE ****************************" echo "If your Xymon server is accessible by outsiders, then you should" echo "restrict access to the CGI scripts that handle enable/disable of" echo "hosts, and acknowledging of alerts. The easiest way to do this is" echo "to put these in a separate CGI directory and require a password to" echo "access them." echo "Even if your Xymon server is on a secured, internal network, you" echo "may want to have some operations (like disabling a host) be password-" echo "protected - that lets you see who disabled or acknowledged an alert." echo "" echo "Where to put the Xymon Administration CGI scripts [$XYMONTOPDIR/cgi-secure] ? " echo "(Note: This is the filesystem directory - we will get to the URL shortly)" if test -z "$SECURECGIDIR" then read SECURECGIDIR fi if test -z "$SECURECGIDIR" then SECURECGIDIR=$XYMONTOPDIR/cgi-secure fi echo ""; echo "" if test "$CGIDIR" != "$SECURECGIDIR" then echo "What is the URL for the Xymon Administration CGI directory [/xymon-seccgi] ? " echo "(Note: This is the URL - NOT the filesystem directory)" if test -z "$SECUREXYMONCGIURL" then read SECUREXYMONCGIURL fi if test -z "$SECUREXYMONCGIURL" then SECUREXYMONCGIURL="/xymon-seccgi" fi else SECUREXYMONCGIURL="$XYMONCGIURL" fi echo ""; echo "" echo "** Note that you may need to modify your webserver configuration." echo "** After installing, see $XYMONTOPDIR/server/etc/xymon-apache.conf for an example configuration." echo ""; echo "" echo "To generate Xymon availability reports, your webserver" echo "must have write-access to a directory below the Xymon" echo "top-level directory. I can set this up if you tell me" echo "what group-ID your webserver runs with. This is typically" echo "'nobody' or 'apache' or 'www-data'" echo "" echo "What group-ID does your webserver use [nobody] ?" if test -z "$HTTPDGID" then read HTTPDGID fi if test -z "$HTTPDGID" then HTTPDGID="nobody" fi echo ""; echo "" echo "Where to put the Xymon logfiles [/var/log/xymon] ? " if test -z "$XYMONLOGDIR" then read XYMONLOGDIR fi if test -z "$XYMONLOGDIR" then XYMONLOGDIR=/var/log/xymon fi echo ""; echo "" echo "What is the name of this host [`uname -n`] ? " if test -z "$XYMONHOSTNAME" then read XYMONHOSTNAME fi if test -z "$XYMONHOSTNAME" then XYMONHOSTNAME=`uname -n` fi echo ""; echo "" echo "What is the IP-address of this host [127.0.0.1] ? " if test -z "$XYMONHOSTIP" then read XYMONHOSTIP fi if test -z "$XYMONHOSTIP" -o "$XYMONHOSTIP" = "127.0.0.1" then echo "** NOTE: Using 127.0.0.1 (loopback), but it is probably not what you want **" XYMONHOSTIP=127.0.0.1 fi echo ""; echo "" XYMONHOSTOS=`uname -s | tr '[A-Z]' '[a-z]'` if test "$XYMONVAR" = ""; then XYMONVAR=$XYMONTOPDIR/data fi echo "Where should I install the Xymon man-pages (/usr/local/man) ?" if test -z "$MANROOT" then read MANROOT fi if test -z "$MANROOT" then MANROOT=/usr/local/man fi echo ""; echo "" echo "# Toplevel Makefile for Xymon" > Makefile echo "BUILDTOPDIR=\`pwd\`" >>Makefile echo "" >>Makefile echo "# configure settings for Xymon" >>Makefile echo "#" >>Makefile echo "# Toplevel dir" >>Makefile echo "XYMONTOPDIR = $XYMONTOPDIR" >>Makefile echo "# Server data dir for hist/ etc." >>Makefile echo "XYMONVAR = $XYMONVAR" >>Makefile echo "# CGI scripts go in CGIDIR" >>Makefile echo "CGIDIR = $CGIDIR" >>Makefile echo "# Admin CGI scripts go in SECURECGIDIR" >>Makefile echo "SECURECGIDIR = $SECURECGIDIR" >>Makefile echo "# Where to put logfiles" >>Makefile echo "XYMONLOGDIR = $XYMONLOGDIR" >>Makefile echo "# Where to install manpages" >>Makefile echo "MANROOT = $MANROOT" >>Makefile echo "# How to run fping or xymonping" >>Makefile echo "FPING = $FPING" >>Makefile echo "" >>Makefile echo "# Username running Xymon" >>Makefile echo "XYMONUSER = $XYMONUSER" >>Makefile echo "# Xymon server hostname" >>Makefile echo "XYMONHOSTNAME = $XYMONHOSTNAME" >>Makefile echo "# Xymon server IP-address" >>Makefile echo "XYMONHOSTIP = $XYMONHOSTIP" >>Makefile echo "# Xymon server OS" >>Makefile echo "XYMONHOSTOS = $XYMONHOSTOS" >>Makefile echo "" >>Makefile echo "# URL for Xymon webpages" >>Makefile echo "XYMONHOSTURL = $XYMONHOSTURL" >>Makefile echo "# URL for Xymon CGIs" >>Makefile echo "XYMONCGIURL = $XYMONCGIURL" >>Makefile echo "# URL for Xymon Admin CGIs" >>Makefile echo "SECUREXYMONCGIURL = $SECUREXYMONCGIURL" >>Makefile echo "# Webserver group-ID" >>Makefile echo "HTTPDGID=$HTTPDGID" >>Makefile echo "" >>Makefile echo "# C-ARES settings" >>Makefile if test "$CARESOK" = "YES" then echo "SYSTEMCARES = yes" >>Makefile if test "$CARESINC" != ""; then echo "CARESINCDIR = -I$CARESINC" >>Makefile fi if test "$CARESLIB" != ""; then echo "CARESLIBS = -L$LIB -lcares" >>Makefile echo "RPATHVAL += ${LIB}" >>Makefile else echo "CARESLIBS = -lcares" >>Makefile fi else echo "SYSTEMCARES = no" >>Makefile fi echo "" >>Makefile echo "# PCRE settings" >>Makefile if test "$PCREOK" = "YES" then if test "$PCREINC" != ""; then echo "PCREINCDIR = -I$PCREINC" >>Makefile fi if test "$PCRELIB" != ""; then echo "PCRELIBS = -L$PCRELIB -lpcre" >>Makefile echo "RPATHVAL += ${PCRELIB}" >>Makefile else echo "PCRELIBS = -lpcre" >>Makefile fi fi echo "" >>Makefile if test "$ENABLERRD" = "y" then echo "# RRDtool settings" >>Makefile echo "RRDDEF = $RRDDEF" >>Makefile if test "$RRDINC" != ""; then echo "RRDINCDIR = -I$RRDINC" >>Makefile fi if test "$RRDLIB" != ""; then echo "RRDLIBS = -L$RRDLIB -lrrd $PNGLIB" >>Makefile echo "RPATHVAL += ${RRDLIB}" >>Makefile else echo "RRDLIBS = -lrrd $PNGLIB" >>Makefile fi echo "DORRD = yes" >>Makefile fi echo "#" >>Makefile echo "# OpenSSL settings" >>Makefile if test "$ENABLESSL" = "y" then echo "SSLFLAGS = $SSLFLAGS" >>Makefile if test "$OSSLINC" != ""; then echo "SSLINCDIR = -I$OSSLINC" >>Makefile fi if test "$OSSLLIB" != ""; then echo "SSLLIBS = -L$OSSLLIB -lssl -lcrypto" >>Makefile echo "RPATHVAL += ${OSSLLIB}" >>Makefile else echo "SSLLIBS = -lssl -lcrypto" >>Makefile fi echo "DOSSL = yes" >>Makefile fi echo "#" >>Makefile echo "# OpenLDAP settings" >>Makefile echo "LDAPFLAGS = $LDAPDEF" >>Makefile if test "$ENABLELDAP" = "y" then echo if test "$LDAPINC" != ""; then echo "LDAPINCDIR = -I$LDAPINC" >>Makefile fi if test "$LDAPLIB" != ""; then echo "LDAPLIBS = -L$LDAPLIB -lldap $LDAPLBER" >>Makefile echo "RPATHVAL += ${LDAPLIB}" >>Makefile else echo "LDAPLIBS = -lldap $LDAPLBER" >>Makefile fi echo "DOLDAP = yes" >>Makefile fi echo "#" >>Makefile echo "# clock_gettime() settings" >>Makefile echo "LIBRTDEF = $LIBRTDEF" >>Makefile echo "" >>Makefile echo "# Net-SNMP settings" >>Makefile echo "DOSNMP = $DOSNMP" >>Makefile echo "" >>Makefile echo "# Large File Support settings" >>Makefile echo "LFSDEF = $LFS" >>Makefile echo "" >>Makefile if test -r build/Makefile.`uname -s | tr '/' '_'` then echo "include build/Makefile.`uname -s | tr '/' '_'`" >>Makefile echo "" echo "Using `uname -s | tr '/' '_'` Makefile settings" echo "" else echo "include build/Makefile.generic" >>Makefile echo "" echo "Using GENERIC Makefile settings (uname -s is `uname -s`)" echo "" echo "If this fails, change the compile settings in Makefile" echo "" echo "I would appreciate it if you send the changes to" echo "xymon-owner@xymon.com so I can include it in the next version." echo "" fi echo "" >>Makefile if test "$INSTALLBINDIR" != ""; then echo "INSTALLBINDIR = $INSTALLBINDIR" >>Makefile fi if test "$INSTALLETCDIR" != ""; then echo "INSTALLETCDIR = $INSTALLETCDIR" >>Makefile fi if test "$INSTALLEXTDIR" != ""; then echo "INSTALLEXTDIR = $INSTALLEXTDIR" >>Makefile fi if test "$INSTALLTMPDIR" != ""; then echo "INSTALLTMPDIR = $INSTALLTMPDIR" >>Makefile fi if test "$INSTALLWEBDIR" != ""; then echo "INSTALLWEBDIR = $INSTALLWEBDIR" >>Makefile fi if test "$INSTALLWWWDIR" != ""; then echo "INSTALLWWWDIR = $INSTALLWWWDIR" >>Makefile fi echo "" >>Makefile echo "# Add local CFLAGS etc. settings here" >>Makefile echo "" >>Makefile echo "include build/Makefile.rules" >> Makefile echo "" >> Makefile echo ""; echo "" echo "Created Makefile with the necessary information to build Xymon" echo "Some defaults are used, so do look at the Makefile before continuing." echo "" echo "Configuration complete - now run $MAKE (GNU make) to build the tools" exit 0 xymon-4.3.30/client/0000775000076400007640000000000013534041775014472 5ustar rpmbuildrpmbuildxymon-4.3.30/client/xymonclient-osf1.sh0000775000076400007640000000325411615341300020235 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # OSF1 client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-osf1.sh 6712 2011-07-31 21:01:52Z storner $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[memory]" vmstat -P echo "[swap]" swapon -s echo "[df]" df -t noprocfs | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[mount]" mount echo "[ifconfig]" ifconfig -a echo "[route]" cat /etc/routes echo "[netstat]" netstat -s echo "[ports]" netstat -an|grep "^tcp" echo "[ps]" ps -ef # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[top]" $TOP -b -n 1 fi fi # vmstat nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/xymonclient-sco_sv.sh0000775000076400007640000000347111615341300020662 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # SCO_SV client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # Copyright (C) 2006 Charles Goyard # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-sco_sv.sh 6712 2011-07-31 21:01:52Z storner $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who -x echo "[df]" df -Bk echo "[mount]" mount -v echo "[memsize]" /etc/memsize echo "[freemem]" sar -r 1 2 | tail -1 echo "[swap]" swap -l echo "[ifconfig]" ifconfig -a echo "[ifstat]" ifconfig -in echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" netstat -an | grep "^tcp" echo "[ps]" ps -A -o pid,ppid,user,stime,s,pri,pcpu,time,vsz,args # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[top]" $TOP -b -n 1 fi fi # vmstat nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/xymonclient-openbsd.sh0000775000076400007640000000427512611270023021023 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # OpenBSD client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-openbsd.sh 7707 2015-10-19 22:34:59Z jccleaver $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" df -k -tnonfs,kernfs,procfs,cd9660 | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[inode]" df -i -tnonfs,kernfs,procfs,cd9660 | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' | awk ' NR<2{printf "%-20s %10s %10s %10s %10s %s\n", $1, "itotal", $6, $7, $8, $9} NR>=2{printf "%-20s %10d %10d %10d %10s %s\n", $1, $6+$7, $6, $7, $8, $9}' echo "[mount]" mount echo "[meminfo]" $XYMONHOME/bin/openbsd-meminfo echo "[swapctl]" /sbin/swapctl -s echo "[ifconfig]" ifconfig -A echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ifstat]" netstat -i -b -n | egrep -v "^lo|$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/netbsd-meminfo.c0000664000076400007640000000505211615341300017530 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon memory information tool for NetBSD. */ /* This tool retrieves information about the total and free RAM. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: netbsd-meminfo.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int hw_physmem[] = { CTL_HW, HW_PHYSMEM64 }; int64 physmem; int hw_pagesize[] = { CTL_HW, HW_PAGESIZE }; int pagesize; int vm_vmtotal[] = { CTL_VM, VM_METER }; struct vmtotal vmdata; size_t len; int result; int swapcount, i; struct swapent *swaplist, *s; unsigned long swaptotal, swapused; len = sizeof(physmem); result = sysctl(hw_physmem, sizeof(hw_physmem) / sizeof(*hw_physmem), &physmem, &len, NULL, 0); if (result != 0) return 1; len = sizeof(pagesize); result = sysctl(hw_pagesize, sizeof(hw_pagesize) / sizeof(*hw_pagesize), &pagesize, &len, NULL, 0); if (result != 0) return 1; len = sizeof(vmdata); result = sysctl(vm_vmtotal, sizeof(vm_vmtotal) / sizeof(*vm_vmtotal), &vmdata, &len, NULL, 0); /* Get swap statistics */ swapcount = swapctl(SWAP_NSWAP, NULL, 0); swaplist = (struct swapent *)malloc(swapcount * sizeof(struct swapent)); result = swapctl(SWAP_STATS, swaplist, swapcount); s = swaplist; swaptotal = swapused = 0; for (i = 0, s = swaplist; (i < swapcount); i++, s++) { if (s->se_flags & SWF_ENABLE) { swaptotal += s->se_nblks; swapused += s->se_inuse; } } free(swaplist); /* swap stats are in disk blocks of 512 bytes, so divide by 2 for KB and 1024 for MB */ swaptotal /= (2*1024); swapused /= (2*1024); // printf("Pagesize:%d\n", pagesize); printf("Total:%d\n", (physmem / (1024 * 1024))); printf("Free:%d\n", (pagesize / 1024)*(vmdata.t_free / 1024)); printf("Swaptotal:%lu\n", swaptotal); printf("Swapused:%lu\n", swapused); return 0; } xymon-4.3.30/client/xymonclient-freebsd.sh0000775000076400007640000000467712634277577021043 0ustar rpmbuildrpmbuild#!/bin/sh # #----------------------------------------------------------------------------# # FreeBSD client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-freebsd.sh 7847 2015-12-16 15:13:03Z jccleaver $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" # The sed stuff is to make sure lines are not split into two. df -H -tnonfs,nullfs,cd9660,procfs,devfs,linprocfs,fdescfs | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[inode]" # The sed stuff is to make sure lines are not split into two. df -i -tnonfs,nullfs,cd9660,procfs,devfs,linprocfs,fdescfs | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' | awk ' NR<2{printf "%-20s %10s %10s %10s %10s %s\n", $1, "itotal", $6, $7, $8, $9} NR>=2{printf "%-20s %10d %10d %10d %10s %s\n", $1, $6+$7, $6, $7, $8, $9}' echo "[mount]" mount echo "[meminfo]" $XYMONHOME/bin/freebsd-meminfo echo "[swapinfo]" swapinfo -k echo "[vmtotal]" sysctl vm.vmtotal echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[ifstat]" netstat -ibnW | egrep "$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/xymonclient-netbsd.sh0000775000076400007640000000366012611270023020645 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # NetBSD client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-netbsd.sh 7707 2015-10-19 22:34:59Z jccleaver $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" df -P -tnonfs,kernfs,procfs,cd9660,null | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[mount]" mount echo "[meminfo]" $XYMONHOME/bin/netbsd-meminfo echo "[swapctl]" /sbin/swapctl -s echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ifstat]" netstat -i -b -n | egrep -v "^lo|$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/hpux-meminfo.c0000664000076400007640000000244711615341300017242 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon memory information tool for HP-UX. */ /* This tool retrieves information about the total and free RAM. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: hpux-meminfo.c 6712 2011-07-31 21:01:52Z storner $"; #include #include main(int argc, char *argv[]) { struct pst_static sbuf; struct pst_dynamic dbuf; unsigned long pgsizekb; unsigned long kpages; pstat_getstatic(&sbuf, sizeof(sbuf), 1, 0); pstat_getdynamic(&dbuf, sizeof(dbuf), 1, 0); pgsizekb = sbuf.page_size / 1024; kpages = dbuf.psd_free / 1024; printf("Total:%ld\n", sbuf.physical_memory/256); printf("Free:%lu\n", pgsizekb*kpages); } xymon-4.3.30/client/README-local0000664000076400007640000000116111671476413016442 0ustar rpmbuildrpmbuildThis directory - the client/local/ directory - can be used to install Xymon client add-on scripts. The Xymon client will run all files in this directory that are executable, and include the output from each script in a separate section in the Xymon client message which is sent to the Xymon server. This output will have to be processed on the Xymon server; there is no default processing done by Xymon on the output from these scripts. They are merely added to the client data. If you want to install an add-on script that direcly generates a status column in Xymon, this should go in the client/ext/ directory instead. xymon-4.3.30/client/xymonclient-aix.sh0000775000076400007640000000426012411752470020155 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # AIX client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-aix.sh 7472 2014-09-28 09:30:32Z storner $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" # The sed stuff is to make sure lines are not split into two. df -Ik | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[inode]" /usr/sysv/bin/df -i | sed -e 's!Mount Dir!Mount_Dir!' | awk ' NR<2 { printf "%-20s %10s %10s %10s %10s %s\n", $2, $5, $3, $4, $6, "Mounted on" } NR>=2 && $5>0 { printf "%-20s %10d %10d %10d %10s %s\n", $2, $5, $3, $4, $6, $1} ' echo "[mount]" mount echo "[realmem]" lsattr -El sys0 -a realmem echo "[freemem]" vmstat 1 2 | tail -1 echo "[swap]" lsps -s echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" netstat -an | grep "^tcp" echo "[ifstat]" netstat -v echo "[ps]" # I think the -f and -l options are ignored with -o, but this works... ps -A -k -f -l -o pid,ppid,user,stat,pri,pcpu,time,etime,pmem,vsz,args # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[top]" $TOP -b 20 fi fi # vmstat nohup sh -c "vmstat 300 1 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/logfetch.c0000664000076400007640000013444413453063373016441 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon client logfile collection tool. */ /* This tool retrieves data from logfiles. If run continuously, it will pick */ /* out the data stored in the logfile over the past 6 runs (30 minutes with */ /* the default Xymon client polling frequency) and send these data to stdout */ /* for inclusion in the Xymon "client" message. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: logfetch.c 8046 2019-04-09 09:33:47Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Some systems do not have the S_ISSOCK macro for stat() */ #ifdef SCO_SV #include #define S_ISSOCK(m) (((m) & S_IFMT) == C_ISSOCK) #endif #include "libxymon.h" /* Set via xgetenv */ static char skiptxt[512]; static char curpostxt[512]; /* Is it ok for these to be hardcoded ? */ #define MAXCHECK 102400U /* When starting, don't look at more than 100 KB of data */ #define MAXMINUTES 30 #define POSCOUNT ((MAXMINUTES / 5) + 1) /* 0 = current run */ #define DEFAULTSCROLLBACK (POSCOUNT - 1) /* How far back to begin processing data, in runs */ #define LINES_AROUND_TRIGGER 5 /* Default = use default */ int scrollback = -1; static int allowexec = 1; typedef enum { C_NONE, C_LOG, C_FILE, C_DIR, C_COUNT } checktype_t; typedef struct logdef_t { #ifdef _LARGEFILE_SOURCE off_t lastpos[POSCOUNT]; off_t maxbytes; #else long lastpos[POSCOUNT]; long maxbytes; #endif char **trigger; int triggercount; char **ignore; int ignorecount; char **deltacountpatterns; char **deltacountnames; int deltacountcount; int *deltacountcounts; } logdef_t; typedef struct filedef_t { int domd5, dosha1, dosha256, dosha512, dosha224, dosha384, dormd160; } filedef_t; typedef struct countdef_t { int patterncount; char **patternnames; char **patterns; int *counts; } countdef_t; typedef struct checkdef_t { char *filename; checktype_t checktype; struct checkdef_t *next; union { logdef_t logcheck; filedef_t filecheck; countdef_t countcheck; } check; } checkdef_t; checkdef_t *checklist = NULL; FILE *fileopen(char *filename, int *err) { /* Open a file */ FILE *fd; #ifdef BIG_SECURITY_HOLE get_root(); #endif fd = fopen(filename, "r"); if (err) *err = errno; #ifdef BIG_SECURITY_HOLE drop_root(); #endif return fd; } /* * A wrapper for fgets() which eats embedded 0x00 characters in the stream. */ char *fgets_nonull(char *buf, size_t size, FILE *stream) { char *in, *out, *end; if (fgets(buf, size - 1, stream) == NULL) return NULL; end = memchr(buf, '\n', size - 1); if (end == NULL) end = buf + (size - 1); else end++; for (in = out = buf; in < end; in++) { if (*in != '\0') *out++ = *in; } *out = '\0'; return buf; } char *logdata(char *filename, logdef_t *logdef) { static char *buf, *replacement = NULL; char *startpos, *fillpos, *triggerstartpos, *triggerendpos, *curpos = NULL; FILE *fd; struct stat st; size_t bytesread, bytesleft; int openerr, i, status, triggerlinecount, done; char *linepos[2*LINES_AROUND_TRIGGER+1]; int lpidx; size_t byteslast, bytestocurrent, bytesin = 0; regex_t *deltaexpr = NULL, *ignexpr = NULL, *trigexpr = NULL; #ifdef _LARGEFILE_SOURCE off_t bufsz; #else long bufsz; #endif char *(*triggerptrs)[2] = NULL; unsigned int triggerptrs_count = 0; dbgprintf("logfetch: -> logdata (%s)\n", filename); if (buf) free(buf); buf = NULL; if (replacement) free(replacement); replacement = NULL; fd = fileopen(filename, &openerr); if (fd == NULL) { buf = (char *)malloc(1024 + strlen(filename)); sprintf(buf, "Cannot open logfile %s : %s\n", filename, strerror(openerr)); return buf; } if (debug) { for (i = 0; (i < POSCOUNT); i++) dbgprintf(" - fn: %s, pos %d, loc %lu\n", filename, i, logdef->lastpos[i]); } /* * See how large the file is, and decide where to start reading. * Save the last POSCOUNT positions so we can scrap 5 minutes of data * from one run to the next. */ fstat(fileno(fd), &st); if ((st.st_size < logdef->lastpos[0]) || (st.st_size < logdef->lastpos[POSCOUNT-1])) { /* * Logfile shrank - probably it was rotated. * Start from beginning of file. */ errprintf("logfetch: File %s shrank from >=%zu to %zu bytes in size. Probably rotated; clearing position state\n", filename, logdef->lastpos[POSCOUNT-1], st.st_size); for (i=0; (i < POSCOUNT); i++) logdef->lastpos[i] = 0; } /* Go to the position we were at scrollback times ago (default corresponds to 6 -- 30 minutes when 5m per run) */ #ifdef _LARGEFILE_SOURCE fseeko(fd, logdef->lastpos[scrollback], SEEK_SET); bufsz = st.st_size - ftello(fd); if (bufsz > MAXCHECK) { /* * Too much data for us. We have to skip some of the old data. */ errprintf("logfetch: %s delta %jd bytes exceeds max buffer size %u; skipping some data\n", filename, (intmax_t)bufsz, MAXCHECK); logdef->lastpos[scrollback] = st.st_size - MAXCHECK; fseeko(fd, logdef->lastpos[scrollback], SEEK_SET); bufsz = st.st_size - ftello(fd); } #else fseek(fd, logdef->lastpos[scrollback], SEEK_SET); bufsz = st.st_size - ftell(fd); if (bufsz > MAXCHECK) { /* * Too much data for us. We have to skip some of the old data. */ errprintf("logfetch: %s delta %zu bytes exceeds max buffer size %u; skipping some data\n", filename, bufsz, MAXCHECK); logdef->lastpos[scrollback] = st.st_size - MAXCHECK; fseek(fd, logdef->lastpos[scrollback], SEEK_SET); bufsz = st.st_size - ftell(fd); } #endif /* Calculate delta between scrollback (where going to start looking at data) and end of the most recent run. * This is where we place our "CURRENT" marker */ byteslast = logdef->lastpos[scrollback]; /* If lastpos[0] is 0, then all of the positions are 0 because we rotated above */ bytestocurrent = logdef->lastpos[0] - byteslast; /* Shift position markers one down for the next round */ /* lastpos[1] is the previous end location, lastpos[0] will be the end of this run */ for (i=POSCOUNT-1; (i > 0); i--) logdef->lastpos[i] = logdef->lastpos[i-1]; logdef->lastpos[0] = st.st_size; dbgprintf("logfetch: Current size (ending): %zu bytes. Last end was %zu. Looking %d spots before that, which is %zu. bytestocurrent: %zu\n", logdef->lastpos[0], logdef->lastpos[1], scrollback, byteslast, bytestocurrent); /* * Get our read buffer. * * NB: fgets() need some extra room in the input buffer. * If it is missing, we will never detect end-of-file * because fgets() will read 0 bytes, but having read that * it still hasnt reached end-of-file status. * At least, on some platforms (Solaris, FreeBSD). */ bufsz += 1023 + strlen(curpostxt); startpos = buf = (char *)malloc(bufsz + 1); if (buf == NULL) { /* Couldnt allocate the buffer */ return "Out of memory"; } /* Compile the regex patterns */ if (logdef->deltacountcount) { int i, realcount = 0; deltaexpr = (regex_t *) malloc(logdef->deltacountcount * sizeof(regex_t)); for (i=0; (i < logdef->deltacountcount); i++) { dbgprintf(" - compiling DELTACOUNT regex: %s\n", logdef->deltacountpatterns[i]); status = regcomp(&deltaexpr[realcount++], logdef->deltacountpatterns[i], REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status != 0) { char regbuf[1000]; regerror(status, &deltaexpr[--realcount], regbuf, sizeof(regbuf)); /* re-decrement realcount here */ errprintf("logfetch: could not compile deltacount regex '%s': %s\n", logdef->deltacountpatterns[i], regbuf); logdef->deltacountpatterns[i] = logdef->deltacountnames[i] = NULL; } } logdef->deltacountcount = realcount; } if (logdef->ignorecount) { int i, realcount = 0; ignexpr = (regex_t *) malloc(logdef->ignorecount * sizeof(regex_t)); for (i=0; (i < logdef->ignorecount); i++) { dbgprintf(" - compiling IGNORE regex: %s\n", logdef->ignore[i]); status = regcomp(&ignexpr[realcount++], logdef->ignore[i], REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status != 0) { char regbuf[1000]; regerror(status, &ignexpr[--realcount], regbuf, sizeof(regbuf)); /* re-decrement realcount here */ errprintf("logfetch: could not compile ignore regex '%s': %s\n", logdef->ignore[i], regbuf); logdef->ignore[i] = NULL; } } logdef->ignorecount = realcount; } if (logdef->triggercount) { int i, realcount = 0; trigexpr = (regex_t *) malloc(logdef->triggercount * sizeof(regex_t)); for (i=0; (i < logdef->triggercount); i++) { dbgprintf(" - compiling TRIGGER regex: %s\n", logdef->trigger[i]); status = regcomp(&trigexpr[realcount++], logdef->trigger[i], REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status != 0) { char regbuf[1000]; regerror(status, &trigexpr[--realcount], regbuf, sizeof(regbuf)); /* re-decrement realcount here */ errprintf("logfetch: could not compile trigger regex '%s': %s\n", logdef->trigger[i], regbuf); logdef->trigger[i] = NULL; } } logdef->triggercount = realcount; } triggerstartpos = triggerendpos = NULL; triggerlinecount = 0; memset(linepos, 0, sizeof(linepos)); lpidx = 0; /* * Read data. * Discard the ignored lines as we go. * Remember the last trigger line we see. */ fillpos = buf; bytesleft = bufsz; done = 0; while (!ferror(fd) && (bytesleft > 0) && !done && (fgets_nonull(fillpos, bytesleft, fd) != NULL)) { int force_trigger = 0; /* Mark where we left off */ bytesin += strlen(fillpos); if (!curpos && (bytesin > bytestocurrent)) { char *t; dbgprintf(" - Last position was %u, found curpos location at %u in current buffer.\n", logdef->lastpos[1], bytesin); t = strdup(fillpos); /* need shuffle about to insert before this line */ strncpy(fillpos, curpostxt, strlen(curpostxt)); /* add in the CURRENT + \n */ strncpy(fillpos+strlen(curpostxt), t, strlen(t)); /* add in whatever this line originally was */ *(fillpos+strlen(curpostxt)+strlen(t)) = '\0'; /* and terminate it */ xfree(t); /* free temp */ curpos = fillpos; /* leave curpos to the beginning of the CURRENT flag */ force_trigger = 1; /* We'll force this to be saved as a trigger later on, so it always gets printed */ } if (*fillpos == '\0') { /* * fgets() can return an empty buffer without flagging * end-of-file. It should not happen anymore now that * we have extended the buffer to have room for the * terminating \0 byte, but if it does then we will * catch it here. */ dbgprintf(" - empty buffer returned; assuming eof\n"); done = 1; continue; } /* Begin counting lines once we've reached the end of the last run */ if (curpos && logdef->deltacountcount) { int i, match = 0; for (i=0; (i < logdef->deltacountcount); i++) { match = (regexec(&deltaexpr[i], fillpos, 0, NULL, 0) == 0); if (match) { logdef->deltacountcounts[i]++; dbgprintf(" - line matched deltacount %d: %s", i, fillpos); } // fgets stores the newline in } } /* Check ignore pattern */ if (logdef->ignorecount) { int i, match = 0; for (i=0; ((i < logdef->ignorecount) && !match); i++) { match = (regexec(&ignexpr[i], fillpos, 0, NULL, 0) == 0); if (match) dbgprintf(" - line matched ignore %d: %s", i, fillpos); // fgets stores the newline in } if (force_trigger) { /* Oops. We actually wanted this line poked through */ /* At the moment, we're only entering this state when we've added 'CURRENT\n' to the existing line */ /* Since we're guaranteeing to downstream users that we're ignoring this, just skip the line */ /* until the first newline. If we start using force_trigger for other purposes, we might have to change */ /* the logic here. */ char *eoln; eoln = strchr(fillpos, '\n'); if (eoln && *(eoln + 1)) fillpos = eoln + 1; // skip first line } else if (match) continue; } linepos[lpidx] = fillpos; /* See if this is a trigger line */ if (force_trigger || logdef->triggercount) { int i, match = 0; if (force_trigger) { match = 1; dbgprintf(" - line forced as a trigger: %s", fillpos); } else { for (i=0; ((i < logdef->triggercount) && !match); i++) { match = (regexec(&trigexpr[i], fillpos, 0, NULL, 0) == 0); if (match) dbgprintf(" - line matched trigger %d: %s", i, fillpos); // fgets stores the newline in } } if (match) { int sidx; sidx = lpidx - LINES_AROUND_TRIGGER; if (sidx < 0) sidx += (2*LINES_AROUND_TRIGGER + 1); triggerstartpos = linepos[sidx]; if (!triggerstartpos) triggerstartpos = buf; triggerlinecount = LINES_AROUND_TRIGGER; if (triggerptrs == NULL || (triggerptrs_count > 0 && triggerptrs[triggerptrs_count - 1][1] != NULL)) { dbgprintf(" - %s trigger line encountered; preparing trigger START & END positioning store\n", ((triggerptrs_count == 0) ? "first" : "additional")); /* Create or resize the trigger pointer array to contain another pair of anchors */ triggerptrs = realloc(triggerptrs, (sizeof(char *) * 2) * (++triggerptrs_count)); if (triggerptrs == NULL) return "Out of memory"; /* Save the current triggerstartpos as our first anchor in the pair */ triggerptrs[triggerptrs_count - 1][0] = triggerstartpos; triggerptrs[triggerptrs_count - 1][1] = NULL; if (triggerptrs_count > 1 && (triggerstartpos <= triggerptrs[triggerptrs_count - 2][1])) { /* Whoops! This trigger's LINES_AROUND_TRIGGER bleeds into the prior's LINES_AROUND_TRIGGER */ triggerptrs[triggerptrs_count - 1][0] = triggerptrs[triggerptrs_count - 2][1]; dbgprintf("Current trigger START (w/ prepended LINES_AROUND_TRIGGER) would overlap with prior trigger's END. Adjusting.\n"); } dbgprintf(" - new trigger anchor START position set\n"); } else { /* Do nothing. Merge the two trigger lines into a single start and end pair by extending the existing */ dbgprintf("Additional trigger line encountered. Previous trigger START has no set END yet. Compressing anchors.\n"); } } } /* We want this line */ lpidx = ((lpidx + 1) % (2*LINES_AROUND_TRIGGER+1)); fillpos += strlen(fillpos); /* Save the current end-position if we had a trigger within the past LINES_AFTER_TRIGGER lines */ if (triggerlinecount) { triggerlinecount--; triggerendpos = fillpos; if (triggerlinecount == 0) { /* Terminate the current trigger anchor pair by aligning the end pointer */ dbgprintf(" - trigger END position set\n"); triggerptrs[triggerptrs_count - 1][1] = triggerendpos; } } bytesleft = (bufsz - (fillpos - buf)); // dbgprintf(" -- bytesleft: %zu\n", bytesleft); } if (triggerptrs != NULL) { dbgprintf("Marked %i pairs of START and END anchors for consideration.\n", triggerptrs_count); /* Ensure that a premature EOF before the last trigger end postion doesn't blow up */ if (triggerptrs[triggerptrs_count - 1][1] == NULL) triggerptrs[triggerptrs_count -1][1] = fillpos; } /* Was there an error reading the file? */ if (ferror(fd)) { buf = (char *)malloc(1024 + strlen(filename)); sprintf(buf, "Error while reading logfile %s : %s\n", filename, strerror(errno)); startpos = buf; goto cleanup; } bytesread = (fillpos - startpos); *(buf + bytesread) = '\0'; if (bytesread > logdef->maxbytes) { if (triggerptrs != NULL) { size_t triggerbytes, nontriggerbytes, skiptxtbytes, lasttriggeroffset; char *pos, *lasttriggerptr; size_t size; /* Sum the number of bytes required to hold all the trigger content (start -> end anchors) */ for (i = 0, triggerbytes = 0, skiptxtbytes = 0; i < triggerptrs_count; i++) { triggerbytes += strlen(triggerptrs[i][0]) - strlen(triggerptrs[i][1]); skiptxtbytes += strlen(skiptxt) * 2; } /* Find the remaining bytes allowed for non-trigger content (and prevent size_t underflow wrap ) */ nontriggerbytes = (logdef->maxbytes < triggerbytes) ? 0 : (logdef->maxbytes - triggerbytes); lasttriggerptr = triggerptrs[triggerptrs_count - 1][1]; lasttriggeroffset = (fillpos - lasttriggerptr); dbgprintf("Found %zu bytes of trigger data, %zu bytes available space for non-trigger data; last trigger ended %zu bytes from end. Max bytes allowed is %zu.\n", triggerbytes, nontriggerbytes, lasttriggeroffset, logdef->maxbytes); /* Allocate a new buffer, reduced to what we actually can hold */ replacement = malloc(sizeof(char) * (triggerbytes + skiptxtbytes + nontriggerbytes + 1)); if (replacement == NULL) return "Out of memory"; dbgprintf("Staging replacement buffer, %zu bytes.\n", (triggerbytes + skiptxtbytes + nontriggerbytes)); /* Iterate each trigger anchor pair, copying into the replacement */ for (i = 0, pos = replacement; i < triggerptrs_count; i++) { dbgprintf("Copying buffer content for trigger %i.\n", (i + 1)); strncpy(pos, skiptxt, strlen(skiptxt)); pos += strlen(skiptxt); size = strlen(triggerptrs[i][0]) - strlen(triggerptrs[i][1]); strncpy(pos, triggerptrs[i][0], size); pos += size; } /* At this point, all the required trigger lines are present */ *(pos) = '\0'; if (nontriggerbytes > 0) { char *finalstartptr; /* Append non-trigger, up to the allowed byte size remaining, of remaining log content, starting backwards */ /* Figure out where to start copying from */ finalstartptr = (fillpos - nontriggerbytes); if (finalstartptr < lasttriggerptr) { /* * FIXME: We could have included inter-trigger data here too. * At the moment, duplicate lines are the worse of two evils, so just start from there. */ finalstartptr = lasttriggerptr; nontriggerbytes = (fillpos - finalstartptr); dbgprintf("logfetch: More space was available than between last trigger and eof; reducing to %zu bytes\n", nontriggerbytes); } /* We're already skipping content; so don't send a partial line. Be sure to decrement the subsequent length we feed to strncpy */ while (*(finalstartptr-1) != '\n') { finalstartptr += 1; nontriggerbytes -= 1; } dbgprintf("logfetch: Delta from end of final trigger to beginning of final section: %zu bytes\n", (finalstartptr - lasttriggerptr) ); if (finalstartptr > lasttriggerptr) { /* Add the final skip for completeness */ strncpy(pos, skiptxt, strlen(skiptxt)); pos += strlen(skiptxt); } /* And copy the the rest of the original buffer content */ dbgprintf("Copying %zu final bytes of non-trigger content\n", nontriggerbytes); strncpy(pos, finalstartptr, nontriggerbytes); *(pos + nontriggerbytes) = '\0'; /* re-terminate */ } /* Prune out the last line to prevent sending a partial */ if (*(pos = &replacement[strlen(replacement) - 1]) != '\n') { while (*pos != '\n') { pos -= 1; } *(++pos) = '\0'; } startpos = replacement; bytesread = strlen(startpos); } else { /* Just drop what is too much -- buf+bytesread was terminated above */ startpos += (bytesread - logdef->maxbytes); memcpy(startpos, skiptxt, strlen(skiptxt)); bytesread = logdef->maxbytes; } } /* Avoid sending a '[' as the first char on a line */ { char *p; p = startpos; while (p) { if (*p == '[') *p = '.'; p = strstr(p, "\n["); if (p) p++; } } cleanup: if (fd) fclose(fd); { int i; if (logdef->deltacountcount) { for (i=0; (i < logdef->deltacountcount); i++) { if (logdef->deltacountpatterns[i]) regfree(&deltaexpr[i]); } xfree(deltaexpr); } if (logdef->ignorecount) { for (i=0; (i < logdef->ignorecount); i++) { if (logdef->ignore[i]) regfree(&ignexpr[i]); } xfree(ignexpr); } if (logdef->triggercount) { for (i=0; (i < logdef->triggercount); i++) { if (logdef->trigger[i]) regfree(&trigexpr[i]); } xfree(trigexpr); } if (triggerptrs) xfree(triggerptrs); } if (debug) { for (i = 0; (i < POSCOUNT); i++) dbgprintf(" -- fn: %s, pos %d, loc %lu\n", filename, i, logdef->lastpos[i]); } dbgprintf("logfetch: <- logdata (%s)\n", filename); return startpos; } char *ftypestr(unsigned int mode, char *symlink) { static char *result = NULL; char *s = "unknown"; if (S_ISREG(mode)) s = "file"; if (S_ISDIR(mode)) s = "directory"; if (S_ISCHR(mode)) s = "char-device"; if (S_ISBLK(mode)) s = "block-device"; if (S_ISFIFO(mode)) s = "FIFO"; if (S_ISSOCK(mode)) s = "socket"; if (symlink == NULL) return s; /* Special handling for symlinks */ if (result) free(result); result = (char *)malloc(strlen(s) + strlen(symlink) + 100); sprintf(result, "%s, symlink -> %s", s, symlink); return result; } char *fmodestr(unsigned int mode) { static char modestr[11]; if (S_ISREG(mode)) modestr[0] = '-'; else if (S_ISDIR(mode)) modestr[0] = 'd'; else if (S_ISCHR(mode)) modestr[0] = 'c'; else if (S_ISBLK(mode)) modestr[0] = 'b'; else if (S_ISFIFO(mode)) modestr[0] = 'p'; else if (S_ISLNK(mode)) modestr[0] = 'l'; else if (S_ISSOCK(mode)) modestr[0] = 's'; else modestr[0] = '?'; modestr[1] = ((mode & S_IRUSR) ? 'r' : '-'); modestr[2] = ((mode & S_IWUSR) ? 'w' : '-'); modestr[3] = ((mode & S_IXUSR) ? 'x' : '-'); modestr[4] = ((mode & S_IRGRP) ? 'r' : '-'); modestr[5] = ((mode & S_IWGRP) ? 'w' : '-'); modestr[6] = ((mode & S_IXGRP) ? 'x' : '-'); modestr[7] = ((mode & S_IROTH) ? 'r' : '-'); modestr[8] = ((mode & S_IWOTH) ? 'w' : '-'); modestr[9] = ((mode & S_IXOTH) ? 'x' : '-'); if ((mode & S_ISUID)) modestr[3] = 's'; if ((mode & S_ISGID)) modestr[6] = 's'; modestr[10] = '\0'; return modestr; } char *timestr(time_t tstamp) { static char result[20]; strftime(result, sizeof(result), "%Y/%m/%d-%H:%M:%S", localtime(&tstamp)); return result; } char *filesum(char *fn, char *dtype) { static char *result = NULL; digestctx_t *ctx; FILE *fd; unsigned char buf[8192]; int openerr, buflen; if ((ctx = digest_init(dtype)) == NULL) return ""; fd = fileopen(fn, &openerr); if (fd == NULL) return ""; while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen); fclose(fd); if (result) xfree(result); result = strdup(digest_done(ctx)); return result; } void printfiledata(FILE *fd, char *fn, int domd5, int dosha1, int dosha256, int dosha512, int dosha224, int dosha384, int dormd160) { struct stat st; struct passwd *pw; struct group *gr; int staterror; char linknam[PATH_MAX]; time_t now = getcurrenttime(NULL); *linknam = '\0'; staterror = lstat(fn, &st); if ((staterror == 0) && S_ISLNK(st.st_mode)) { int n = readlink(fn, linknam, sizeof(linknam)-1); if (n == -1) n = 0; linknam[n] = '\0'; staterror = stat(fn, &st); } if (staterror == -1) { fprintf(fd, "ERROR: %s\n", strerror(errno)); } else { char *stsizefmt; pw = getpwuid(st.st_uid); gr = getgrgid(st.st_gid); fprintf(fd, "type:%o (%s)\n", (unsigned int)(st.st_mode & S_IFMT), ftypestr(st.st_mode, (*linknam ? linknam : NULL))); fprintf(fd, "mode:%o (%s)\n", (unsigned int)(st.st_mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)), fmodestr(st.st_mode)); fprintf(fd, "linkcount:%d\n", (int)st.st_nlink); fprintf(fd, "owner:%u (%s)\n", (unsigned int)st.st_uid, (pw ? pw->pw_name : "")); fprintf(fd, "group:%u (%s)\n", (unsigned int)st.st_gid, (gr ? gr->gr_name : "")); if (sizeof(st.st_size) == sizeof(long long int)) stsizefmt = "size:%lld\n"; else stsizefmt = "size:%ld\n"; fprintf(fd, stsizefmt, st.st_size); fprintf(fd, "clock:%u (%s)\n", (unsigned int)now, timestr(now)); fprintf(fd, "atime:%u (%s)\n", (unsigned int)st.st_atime, timestr(st.st_atime)); fprintf(fd, "ctime:%u (%s)\n", (unsigned int)st.st_ctime, timestr(st.st_ctime)); fprintf(fd, "mtime:%u (%s)\n", (unsigned int)st.st_mtime, timestr(st.st_mtime)); if (S_ISREG(st.st_mode)) { if (domd5) fprintf(fd, "%s\n", filesum(fn, "md5")); else if (dosha1) fprintf(fd, "%s\n", filesum(fn, "sha1")); else if (dosha256) fprintf(fd, "%s\n", filesum(fn, "sha256")); else if (dosha512) fprintf(fd, "%s\n", filesum(fn, "sha512")); else if (dosha224) fprintf(fd, "%s\n", filesum(fn, "sha224")); else if (dosha384) fprintf(fd, "%s\n", filesum(fn, "sha384")); else if (dormd160) fprintf(fd, "%s\n", filesum(fn, "rmd160")); } } fprintf(fd, "\n"); } void printdirdata(FILE *fd, char *fn) { char *ducmd; FILE *cmdfd; char *cmd; char buf[4096]; int buflen; struct stat st; int staterror; ducmd = xgetenv("DU"); staterror = stat(fn, &st); if (staterror == -1) { fprintf(fd, "ERROR: %s\n", strerror(errno)); return; } else if (!S_ISDIR(st.st_mode)) { fprintf(fd, "ERROR: Not a directory\n"); return; } /* Cannot handle filenames with a quote in them (insecure) */ if (strchr(fn, '\'')) return; cmd = (char *)malloc(strlen(ducmd) + strlen(fn) + 10); sprintf(cmd, "%s '%s' 2>&1", ducmd, fn); cmdfd = popen(cmd, "r"); xfree(cmd); if (cmdfd == NULL) return; while ((buflen = fread(buf, 1, sizeof(buf), cmdfd)) > 0) fwrite(buf, 1, buflen, fd); pclose(cmdfd); fprintf(fd, "\n"); } void printcountdata(FILE *fd, checkdef_t *cfg) { int openerr, idx; FILE *logfd; regex_t *exprs; regmatch_t pmatch[1]; int *counts; char l[8192]; logfd = fileopen(cfg->filename, &openerr); if (logfd == NULL) { fprintf(fd, "ERROR: Cannot open file %s: %s\n", cfg->filename, strerror(openerr)); return; } counts = (int *)calloc(cfg->check.countcheck.patterncount, sizeof(int)); exprs = (regex_t *)calloc(cfg->check.countcheck.patterncount, sizeof(regex_t)); for (idx = 0; (idx < cfg->check.countcheck.patterncount); idx++) { int status; status = regcomp(&exprs[idx], cfg->check.countcheck.patterns[idx], REG_EXTENDED|REG_NOSUB); if (status != 0) { /* ... */ }; } while (fgets(l, sizeof(l), logfd)) { for (idx = 0; (idx < cfg->check.countcheck.patterncount); idx++) { if (regexec(&exprs[idx], l, 1, pmatch, 0) == 0) counts[idx] += 1; } } fclose(logfd); for (idx = 0; (idx < cfg->check.countcheck.patterncount); idx++) { fprintf(fd, "%s: %d\n", cfg->check.countcheck.patternnames[idx], counts[idx]); regfree(&exprs[idx]); } free(counts); free(exprs); } int loadconfig(char *cfgfn) { FILE *fd; char l[PATH_MAX + 1024]; checkdef_t *currcfg = NULL; checkdef_t *firstpipeitem = NULL; /* Config items are in the form: * log:filename:maxbytes * ignore ignore-regexp (optional) * trigger trigger-regexp (optional) * deltacount label deltacount-regexp (optional) * * file:filename */ fd = fopen(cfgfn, "r"); if (fd == NULL) return 1; while (fgets(l, sizeof(l), fd) != NULL) { checktype_t checktype; char *bol, *filename; int maxbytes, domd5, dosha1, dosha256, dosha512, dosha224, dosha384, dormd160; { char *p = strchr(l, '\n'); if (p) *p = '\0'; } bol = l + strspn(l, " \t"); if ((*bol == '\0') || (*bol == '#')) continue; if (strncmp(bol, "log:", 4) == 0) checktype = C_LOG; else if (strncmp(bol, "file:", 5) == 0) checktype = C_FILE; else if (strncmp(bol, "dir:", 4) == 0) checktype = C_DIR; else if (strncmp(bol, "linecount:", 10) == 0) checktype = C_COUNT; else checktype = C_NONE; if (checktype != C_NONE) { char *tok; filename = NULL; maxbytes = -1; domd5 = dosha1 = dosha256 = dosha512 = dosha224 = dosha384 = dormd160 = 0; /* Skip the initial keyword token */ tok = strtok(l, ":"); filename = strtok(NULL, ":"); switch (checktype) { case C_LOG: tok = (filename ? strtok(NULL, ":") : NULL); if (tok) maxbytes = atoi(tok); break; case C_FILE: maxbytes = 0; /* Needed to get us into the put-into-list code */ tok = (filename ? strtok(NULL, ":") : NULL); if (tok) { if (strcasecmp(tok, "md5") == 0) domd5 = 1; else if (strcasecmp(tok, "sha1") == 0) dosha1 = 1; else if (strcasecmp(tok, "sha256") == 0) dosha256 = 1; else if (strcasecmp(tok, "sha512") == 0) dosha512 = 1; else if (strcasecmp(tok, "sha224") == 0) dosha224 = 1; else if (strcasecmp(tok, "sha384") == 0) dosha384 = 1; else if (strcasecmp(tok, "rmd160") == 0) dormd160 = 1; } break; case C_DIR: maxbytes = 0; /* Needed to get us into the put-into-list code */ break; case C_COUNT: maxbytes = 0; /* Needed to get us into the put-into-list code */ break; case C_NONE: break; } if ((filename != NULL) && (maxbytes != -1)) { checkdef_t *newitem; firstpipeitem = NULL; if (*filename == '`') { /* Run the command to get filenames */ char *p; char *cmd; FILE *fd = NULL; cmd = filename+1; p = strchr(cmd, '`'); if (p) *p = '\0'; if (allowexec) fd = popen(cmd, "r"); else fprintf(stderr, "logfetch given --noexec option but config told to run command '%s'\n", cmd); if (fd) { char pline[PATH_MAX+1]; while (fgets(pline, sizeof(pline), fd)) { checkdef_t *cwalk = NULL; p = pline + strcspn(pline, "\r\n"); *p = '\0'; for (cwalk = checklist; (cwalk); cwalk = cwalk->next) { if ((cwalk->checktype == checktype) && (strcmp(cwalk->filename, pline) == 0)) { dbgprintf("logfetch: file %s already seen in config; ignoring this entry\n", cwalk->filename); break; } } if (cwalk) continue; newitem = calloc(sizeof(checkdef_t), 1); newitem->checktype = checktype; newitem->filename = strdup(pline); switch (checktype) { case C_LOG: newitem->check.logcheck.maxbytes = maxbytes; break; case C_FILE: newitem->check.filecheck.domd5 = domd5; newitem->check.filecheck.dosha1 = dosha1; newitem->check.filecheck.dosha256 = dosha256; newitem->check.filecheck.dosha512 = dosha512; newitem->check.filecheck.dosha224 = dosha224; newitem->check.filecheck.dosha384 = dosha384; newitem->check.filecheck.dormd160 = dormd160; break; case C_DIR: break; case C_COUNT: newitem->check.countcheck.patterncount = 0; newitem->check.countcheck.patternnames = calloc(1, sizeof(char *)); newitem->check.countcheck.patterns = calloc(1, sizeof(char *)); break; case C_NONE: break; } newitem->next = checklist; checklist = newitem; /* * Since we insert new items at the head of the list, * currcfg points to the first item in the list of * these log configs. firstpipeitem points to the * last item inside the list which is part of this * configuration. */ currcfg = newitem; if (!firstpipeitem) firstpipeitem = newitem; } if (fd) pclose(fd); } } else if (*filename == '<') { /* Resolve the glob to get filenames */ char *p; char *fileglob; glob_t globbuf; int n, i; fileglob = filename+1; p = strchr(fileglob, '>'); if (p) *p = '\0'; dbgprintf(" - searching file glob: %s\n", fileglob); /* Some of these are GNU extensions */ #if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) n = glob(fileglob, GLOB_MARK | GLOB_NOCHECK , NULL, &globbuf); #else n = glob(fileglob, GLOB_MARK | GLOB_NOCHECK | GLOB_BRACE | GLOB_NOMAGIC , NULL, &globbuf); #endif if (n) errprintf("Error searching glob pattern '%s': %s\n", fileglob, strerror(errno)); else { for (i = 0; (globbuf.gl_pathv[i] && (*(globbuf.gl_pathv[i]))) ; i++) { checkdef_t *cwalk = NULL; dbgprintf(" -- found matching path: %s\n", globbuf.gl_pathv[i]); for (cwalk = checklist; (cwalk); cwalk = cwalk->next) { if ((cwalk->checktype == checktype) && (strcmp(cwalk->filename, globbuf.gl_pathv[i]) == 0)) { dbgprintf("logfetch: file %s already seen in config; ignoring this entry\n", cwalk->filename); break; } } if (cwalk) continue; newitem = calloc(sizeof(checkdef_t), 1); newitem->checktype = checktype; newitem->filename = strdup(globbuf.gl_pathv[i]); switch (checktype) { case C_LOG: newitem->check.logcheck.maxbytes = maxbytes; break; case C_FILE: newitem->check.filecheck.domd5 = domd5; newitem->check.filecheck.dosha1 = dosha1; newitem->check.filecheck.dosha256 = dosha256; newitem->check.filecheck.dosha512 = dosha512; newitem->check.filecheck.dosha224 = dosha224; newitem->check.filecheck.dosha384 = dosha384; newitem->check.filecheck.dormd160 = dormd160; break; case C_DIR: break; case C_COUNT: newitem->check.countcheck.patterncount = 0; newitem->check.countcheck.patternnames = calloc(1, sizeof(char *)); newitem->check.countcheck.patterns = calloc(1, sizeof(char *)); break; case C_NONE: break; } newitem->next = checklist; checklist = newitem; /* * Since we insert new items at the head of the list, * currcfg points to the first item in the list of * these log configs. firstpipeitem points to the * last item inside the list which is part of this * configuration. */ currcfg = newitem; if (!firstpipeitem) firstpipeitem = newitem; } } globfree(&globbuf); } else { checkdef_t *cwalk = NULL; for (cwalk = checklist; (cwalk); cwalk = cwalk->next) { if ((cwalk->checktype == checktype) && (strcmp(cwalk->filename, filename) == 0)) { dbgprintf("logfetch: file %s already seen in config; ignoring this entry\n", cwalk->filename); break; } } if (!cwalk) { newitem = calloc(sizeof(checkdef_t), 1); newitem->filename = strdup(filename); newitem->checktype = checktype; switch (checktype) { case C_LOG: newitem->check.logcheck.maxbytes = maxbytes; break; case C_FILE: newitem->check.filecheck.domd5 = domd5; newitem->check.filecheck.dosha1 = dosha1; newitem->check.filecheck.dosha256 = dosha256; newitem->check.filecheck.dosha512 = dosha512; newitem->check.filecheck.dosha224 = dosha224; newitem->check.filecheck.dosha384 = dosha384; newitem->check.filecheck.dormd160 = dormd160; break; case C_DIR: break; case C_COUNT: newitem->check.countcheck.patterncount = 0; newitem->check.countcheck.patternnames = calloc(1, sizeof(char *)); newitem->check.countcheck.patterns = calloc(1, sizeof(char *)); break; case C_NONE: break; } newitem->next = checklist; checklist = newitem; currcfg = newitem; } } } else { currcfg = NULL; firstpipeitem = NULL; } } else if (currcfg && (currcfg->checktype == C_LOG)) { if (strncmp(bol, "ignore ", 7) == 0) { char *p; p = bol + 7; p += strspn(p, " \t"); if (firstpipeitem) { /* Fill in this ignore expression on all items in this pipe set */ checkdef_t *walk = currcfg; do { walk->check.logcheck.ignorecount++; if (walk->check.logcheck.ignore == NULL) { walk->check.logcheck.ignore = (char **)malloc(sizeof(char *)); } else { walk->check.logcheck.ignore = (char **)realloc(walk->check.logcheck.ignore, walk->check.logcheck.ignorecount * sizeof(char **)); } walk->check.logcheck.ignore[walk->check.logcheck.ignorecount-1] = strdup(p); walk = walk->next; } while (walk && (walk != firstpipeitem->next)); } else { currcfg->check.logcheck.ignorecount++; if (currcfg->check.logcheck.ignore == NULL) { currcfg->check.logcheck.ignore = (char **)malloc(sizeof(char *)); } else { currcfg->check.logcheck.ignore = (char **)realloc(currcfg->check.logcheck.ignore, currcfg->check.logcheck.ignorecount * sizeof(char **)); } currcfg->check.logcheck.ignore[currcfg->check.logcheck.ignorecount-1] = strdup(p); } } else if (strncmp(bol, "trigger ", 8) == 0) { char *p; p = bol + 8; p += strspn(p, " \t"); if (firstpipeitem) { /* Fill in this trigger expression on all items in this pipe set */ checkdef_t *walk = currcfg; do { walk->check.logcheck.triggercount++; if (walk->check.logcheck.trigger == NULL) { walk->check.logcheck.trigger = (char **)malloc(sizeof(char *)); } else { walk->check.logcheck.trigger = (char **)realloc(walk->check.logcheck.trigger, walk->check.logcheck.triggercount * sizeof(char **)); } walk->check.logcheck.trigger[walk->check.logcheck.triggercount-1] = strdup(p); walk = walk->next; } while (walk && (walk != firstpipeitem->next)); } else { currcfg->check.logcheck.triggercount++; if (currcfg->check.logcheck.trigger == NULL) { currcfg->check.logcheck.trigger = (char **)malloc(sizeof(char *)); } else { currcfg->check.logcheck.trigger = (char **)realloc(currcfg->check.logcheck.trigger, currcfg->check.logcheck.triggercount * sizeof(char **)); } currcfg->check.logcheck.trigger[currcfg->check.logcheck.triggercount-1] = strdup(p); } } else if (strncmp(bol, "deltacount ", 11) == 0) { char *p; p = bol + 11; p += strspn(p, " \t"); if (firstpipeitem) { /* Fill in this trigger expression on all items in this pipe set */ checkdef_t *walk = currcfg; char *name, *ptn = NULL; name = strtok(p, " :"); if (name) ptn = strtok(NULL, "\n"); if (name && ptn) { do { walk->check.logcheck.deltacountcount++; walk->check.logcheck.deltacountnames = realloc(walk->check.logcheck.deltacountnames, (walk->check.logcheck.deltacountcount)*sizeof(char *)); walk->check.logcheck.deltacountpatterns = realloc(walk->check.logcheck.deltacountpatterns, (walk->check.logcheck.deltacountcount)*sizeof(char *)); walk->check.logcheck.deltacountnames[walk->check.logcheck.deltacountcount-1] = strdup(name); walk->check.logcheck.deltacountpatterns[walk->check.logcheck.deltacountcount-1] = strdup(ptn); walk = walk->next; } while (walk && (walk != firstpipeitem->next)); /* Initialize buckets since we may not re-walk this later */ if (walk->check.logcheck.deltacountcount) walk->check.logcheck.deltacountcounts = (int *)calloc(walk->check.logcheck.deltacountcount, sizeof(int)); } } else { char *name, *ptn = NULL; name = strtok(p, " :"); if (name) ptn = strtok(NULL, "\n"); if (name && ptn) { currcfg->check.logcheck.deltacountcount++; currcfg->check.logcheck.deltacountnames = realloc(currcfg->check.logcheck.deltacountnames, (currcfg->check.logcheck.deltacountcount)*sizeof(char *)); currcfg->check.logcheck.deltacountpatterns = realloc(currcfg->check.logcheck.deltacountpatterns, (currcfg->check.logcheck.deltacountcount)*sizeof(char *)); currcfg->check.logcheck.deltacountnames[currcfg->check.logcheck.deltacountcount-1] = strdup(name); currcfg->check.logcheck.deltacountpatterns[currcfg->check.logcheck.deltacountcount-1] = strdup(ptn); } /* Initialize buckets since we may not re-walk this later */ if (currcfg->check.logcheck.deltacountcount) currcfg->check.logcheck.deltacountcounts = (int *)calloc(currcfg->check.logcheck.deltacountcount, sizeof(int)); } } } else if (currcfg && (currcfg->checktype == C_FILE)) { /* Nothing */ } else if (currcfg && (currcfg->checktype == C_DIR)) { /* Nothing */ } else if (currcfg && (currcfg->checktype == C_COUNT)) { int idx; char *name, *ptn = NULL; name = strtok(l, " :"); if (name) ptn = strtok(NULL, "\n"); idx = currcfg->check.countcheck.patterncount; if (name && ptn) { currcfg->check.countcheck.patterncount += 1; currcfg->check.countcheck.patternnames = realloc(currcfg->check.countcheck.patternnames, (currcfg->check.countcheck.patterncount+1)*sizeof(char *)); currcfg->check.countcheck.patterns = realloc(currcfg->check.countcheck.patterns, (currcfg->check.countcheck.patterncount+1)*sizeof(char *)); currcfg->check.countcheck.patternnames[idx] = strdup(name); currcfg->check.countcheck.patterns[idx] = strdup(ptn); } } else if (currcfg && (currcfg->checktype == C_NONE)) { /* Nothing */ } else { currcfg = NULL; firstpipeitem = NULL; } } fclose(fd); return 0; } void loadlogstatus(char *statfn) { FILE *fd; char l[PATH_MAX + 1024]; fd = fopen(statfn, "r"); if (!fd) return; while (fgets(l, sizeof(l), fd)) { char *fn, *tok; checkdef_t *walk; int i; tok = strtok(l, ":"); if (!tok) continue; fn = tok; for (walk = checklist; (walk && ((walk->checktype != C_LOG) || (strcmp(walk->filename, fn) != 0))); walk = walk->next) ; if (!walk) continue; for (i=0; (tok && (i < POSCOUNT)); i++) { tok = strtok(NULL, ":\n"); #ifdef _LARGEFILE_SOURCE if (tok) walk->check.logcheck.lastpos[i] = (off_t)str2ll(tok, NULL); #else if (tok) walk->check.logcheck.lastpos[i] = atol(tok); #endif /* Sanity check */ if (walk->check.logcheck.lastpos[i] < 0) walk->check.logcheck.lastpos[i] = 0; } } fclose(fd); } void savelogstatus(char *statfn) { FILE *fd; checkdef_t *walk; fd = fopen(statfn, "w"); if (fd == NULL) return; for (walk = checklist; (walk); walk = walk->next) { int i; char *fmt; if (walk->checktype != C_LOG) continue; if (sizeof(walk->check.logcheck.lastpos[i]) == sizeof(long long int)) fmt = ":%lld"; else fmt = ":%ld"; fprintf(fd, "%s", walk->filename); for (i = 0; (i < POSCOUNT); i++) fprintf(fd, fmt, walk->check.logcheck.lastpos[i]); fprintf(fd, "\n"); } fclose(fd); } int main(int argc, char *argv[]) { char *cfgfn = NULL, *statfn = NULL; int i; checkdef_t *walk; #ifdef BIG_SECURITY_HOLE drop_root(); #else drop_root_and_removesuid(argv[0]); #endif for (i=1; (i 1)) { fprintf(stderr, "Unknown option %s\n", argv[i]); } else { /* Not an option -- should have two arguments left: our config and status file */ if (cfgfn == NULL) cfgfn = argv[i]; else if (statfn == NULL) statfn = argv[i]; else fprintf(stderr, "Unknown argument '%s'\n", argv[i]); } } if (scrollback == -1) { char *p; p = getenv("LOGFETCHSCROLLBACK"); if (!p) p = getenv("LOGFETCH_SCROLLBACK"); /* compat */ if (!p || (strlen(p) == 0) ) scrollback = DEFAULTSCROLLBACK; else { int scroll; scroll = atoi(p); /* Don't use DEFAULTSCROLLBACK here in case we change or lower the default in the future */ if ((scroll < 0) || (scroll > (POSCOUNT-1)) ) { errprintf("Scrollback requested (%d) is greater than max saved (%d)\n", scroll, (POSCOUNT - 1) ); scrollback = DEFAULTSCROLLBACK; } else { dbgprintf("logfetch: setting scrollback to %d\n", scroll); scrollback = scroll; } } } if ((cfgfn == NULL) || (statfn == NULL)) { fprintf(stderr, "Missing config or status file arguments\n"); return 1; } if (loadconfig(cfgfn) != 0) return 1; loadlogstatus(statfn); snprintf(skiptxt, sizeof(skiptxt), "%s\n", xgetenv("LOGFETCHSKIPTEXT")); snprintf(curpostxt, sizeof(curpostxt), "%s\n", xgetenv("LOGFETCHCURRENTTEXT")); for (walk = checklist; (walk); walk = walk->next) { int idx; char *data; checkdef_t *fwalk; switch (walk->checktype) { case C_LOG: data = logdata(walk->filename, &walk->check.logcheck); fprintf(stdout, "[msgs:%s]\n", walk->filename); fprintf(stdout, "%s\n", data); if (walk->check.logcheck.deltacountcount) fprintf(stdout, "[deltacount:%s]\n", walk->filename); for (idx = 0; (idx < walk->check.logcheck.deltacountcount); idx++) { fprintf(stdout, "%s: %d\n", walk->check.logcheck.deltacountnames[idx], walk->check.logcheck.deltacountcounts[idx]); } /* See if there's a special "file:" entry for this logfile */ for (fwalk = checklist; (fwalk && ((fwalk->checktype != C_FILE) || (strcmp(fwalk->filename, walk->filename) != 0))); fwalk = fwalk->next) ; if (fwalk == NULL) { /* No specific file: entry, so make sure the logfile metadata is available */ fprintf(stdout, "[logfile:%s]\n", walk->filename); printfiledata(stdout, walk->filename, 0, 0, 0, 0, 0, 0, 0); } break; case C_FILE: fprintf(stdout, "[file:%s]\n", walk->filename); printfiledata(stdout, walk->filename, walk->check.filecheck.domd5, walk->check.filecheck.dosha1, walk->check.filecheck.dosha256, walk->check.filecheck.dosha512, walk->check.filecheck.dosha224, walk->check.filecheck.dosha384, walk->check.filecheck.dormd160); break; case C_DIR: fprintf(stdout, "[dir:%s]\n", walk->filename); printdirdata(stdout, walk->filename); break; case C_COUNT: fprintf(stdout, "[linecount:%s]\n", walk->filename); printcountdata(stdout, walk); break; case C_NONE: break; } } savelogstatus(statfn); return 0; } xymon-4.3.30/client/mq.sh0000775000076400007640000000152411535424634015446 0ustar rpmbuildrpmbuild#!/bin/sh # Xymon data collector for MQ # # # Collect data from the MQ utility "runmqsc": # - queue depth # - channel status # for all of the queue managers given as parameters. # # Wrap this in a client data message, tagged as # coming from an "mqcollect" client collector. # # Requires Xymon server ver. 4.3.0 # # # Called from xymonlaunch with # # CMD $XYMONHOME/ext/mq.sh QUEUEMGR1 [QUEUEMGR2...] # # where QUEUEMGR* are the names of the queue managers. # # $Id: mq.sh 6648 2011-03-08 13:05:32Z storner $ TMPFILE="$XYMONTMP/mq-$MACHINE.$$" echo "client/mqcollect $MACHINE.mqcollect mqcollect" >$TMPFILE while test "$1" -ne "" do QMGR=$1; shift (echo 'dis ql(*) curdepth'; echo 'dis chs(*)'; echo 'end') | runmqsc $QMGR >> $TMPFILE done $XYMON $XYMSRV "@" < $TMPFILE rm $TMPFILE exit 0 xymon-4.3.30/client/xymonclient.sh0000775000076400007640000000733012651601152017373 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # Xymon client main script. # # # # This invokes the OS-specific script to build a client message, and sends # # if off to the Xymon server. # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient.sh 7878 2016-01-26 05:21:46Z jccleaver $ # Must make sure the commands return standard (english) texts. LANG=C LC_ALL=C LC_MESSAGES=C export LANG LC_ALL LC_MESSAGES if test $# -ge 1; then if test "$1" = "--local"; then LOCALMODE="yes" fi shift fi if test "$XYMONOSSCRIPT" = ""; then XYMONOSSCRIPT="xymonclient-`uname -s | tr '[ABCDEFGHIJKLMNOPQRSTUVWXYZ/]' '[abcdefghijklmnopqrstuvwxyz_]'`.sh" fi MSGFILE="$XYMONTMP/msg.$MACHINEDOTS.txt" MSGTMPFILE="$MSGFILE.$$" if test "$LOCALMODE" = "yes"; then if test -z "$LOCAL_CLIENTCONFIG"; then LOCAL_CLIENTCONFIG="$XYMONHOME/etc/localclient.cfg" fi if test -z "$LOCAL_LOGFETCHCFG"; then LOCAL_LOGFETCHCFG="$XYMONHOME/etc/logfetch.cfg" fi # If not present, fall back to dynamic logfetch location below if test -f "$LOCAL_LOGFETCHCFG"; then LOGFETCHCFG="$LOCAL_LOGFETCHCFG" fi fi if test -z "$LOGFETCHCFG"; then LOGFETCHCFG=$XYMONTMP/logfetch.$MACHINEDOTS.cfg fi if test -z "$LOGFETCHSTATUS"; then LOGFETCHSTATUS=$XYMONTMP/logfetch.$MACHINEDOTS.status fi export LOGFETCHCFG LOGFETCHSTATUS rm -f $MSGTMPFILE touch $MSGTMPFILE CLIENTVERSION="`$XYMONHOME/bin/clientupdate --level`" if test -z "$CLIENTVERSION"; then CLIENTVERSION="`$XYMON --version`" fi if test "$LOCALMODE" = "yes"; then echo "@@client#1|1|127.0.0.1|$MACHINEDOTS|$SERVEROSTYPE" >> $MSGTMPFILE fi echo "client $MACHINE.$SERVEROSTYPE $CONFIGCLASS" >> $MSGTMPFILE $XYMONHOME/bin/$XYMONOSSCRIPT >> $MSGTMPFILE # logfiles if test -f $LOGFETCHCFG then $XYMONHOME/bin/logfetch $LOGFETCHOPTS $LOGFETCHCFG $LOGFETCHSTATUS >>$MSGTMPFILE fi # Client version echo "[clientversion]" >>$MSGTMPFILE echo "$CLIENTVERSION" >> $MSGTMPFILE # See if there are any local add-ons (must do this before checking the clock) if test -d $XYMONHOME/local; then for MODULE in $XYMONHOME/local/* do if test -x $MODULE then echo "[local:`basename $MODULE`]" >>$MSGTMPFILE $MODULE >>$MSGTMPFILE fi done fi # System clock echo "[clock]" >> $MSGTMPFILE $XYMONHOME/bin/logfetch --clock >> $MSGTMPFILE if test "$LOCALMODE" = "yes"; then echo "@@" >> $MSGTMPFILE $XYMONHOME/bin/xymond_client --local $LOCAL_CLIENTOPTS --config=$LOCAL_CLIENTCONFIG <$MSGTMPFILE else $XYMON $XYMSRV "@" < $MSGTMPFILE >$LOGFETCHCFG.tmp if test -f $LOGFETCHCFG.tmp then if test -s $LOGFETCHCFG.tmp then mv $LOGFETCHCFG.tmp $LOGFETCHCFG else rm -f $LOGFETCHCFG.tmp fi fi fi # Save the latest file for debugging. rm -f $MSGFILE mv $MSGTMPFILE $MSGFILE if test "$LOCALMODE" != "yes" -a -f $LOGFETCHCFG; then # Check for client updates SERVERVERSION=`grep "^clientversion:" $LOGFETCHCFG | cut -d: -f2` if test "$SERVERVERSION" != "" -a "$SERVERVERSION" != "$CLIENTVERSION"; then exec $XYMONHOME/bin/clientupdate --update=$SERVERVERSION --reexec fi fi exit 0 xymon-4.3.30/client/msgcache.c0000664000076400007640000003411612603243142016401 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon client message cache. */ /* */ /* This acts as a local network daemon which saves incoming messages in a */ /* memory cache. */ /* */ /* A "pullclient" command receives the cache content in response. */ /* Any data provided in the "pullclient" request is saved, and passed as */ /* response to the first "client" command seen afterwards. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: msgcache.c 7678 2015-10-01 14:42:42Z jccleaver $"; #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #include "libxymon.h" volatile int keeprunning = 1; char *client_response = NULL; /* The latest response to a "client" message */ char *logfile = NULL; int maxage = 600; /* Maximum time we will cache messages */ sender_t *serverlist = NULL; /* Who is allowed to grab our messages */ typedef struct conn_t { time_t tstamp; struct sockaddr_in caddr; enum { C_CLIENT_CLIENT, C_CLIENT_OTHER, C_SERVER } ctype; enum { C_READING, C_WRITING, C_DONE } action; int sockfd; strbuffer_t *msgbuf; int sentbytes; struct conn_t *next; } conn_t; conn_t *chead = NULL; conn_t *ctail = NULL; typedef struct msgqueue_t { time_t tstamp; strbuffer_t *msgbuf; unsigned long sentto; struct msgqueue_t *next; } msgqueue_t; msgqueue_t *qhead = NULL; msgqueue_t *qtail = NULL; void sigmisc_handler(int signum) { switch (signum) { case SIGTERM: errprintf("Caught TERM signal, terminating\n"); keeprunning = 0; break; case SIGHUP: if (logfile) { reopen_file(logfile, "a", stdout); reopen_file(logfile, "a", stderr); errprintf("Caught SIGHUP, reopening logfile\n"); } break; } } void grabdata(conn_t *conn) { int n; char buf[8192]; int pollid = 0; /* Get data from the connection socket - we know there is some */ n = read(conn->sockfd, buf, sizeof(buf)-1); if (n <= -1) { /* Read failure */ errprintf("Connection lost during read: %s\n", strerror(errno)); conn->action = C_DONE; return; } if (n > 0) { /* Got some data - store it */ buf[n] = '\0'; addtobuffer(conn->msgbuf, buf); return; } /* Done reading - process the data */ if (STRBUFLEN(conn->msgbuf) == 0) { /* No data ? We're done */ conn->action = C_DONE; return; } /* * See what kind of message this is. If it's a "pullclient" message, * save the contents of the message - this is the client configuration * that we'll return the next time a client sends us the "client" message. */ if (strncmp(STRBUF(conn->msgbuf), "pullclient", 10) == 0) { char *clientcfg; int idnum; /* Access check */ if (!oksender(serverlist, NULL, conn->caddr.sin_addr, STRBUF(conn->msgbuf))) { errprintf("Rejected pullclient request from %s\n", inet_ntoa(conn->caddr.sin_addr)); conn->action = C_DONE; return; } dbgprintf("Got pullclient request: %s\n", STRBUF(conn->msgbuf)); /* * The pollid is unique for each Xymon server. It is to allow * multiple servers to pick up the same message, for resiliance. */ idnum = atoi(STRBUF(conn->msgbuf) + 10); if ((idnum <= 0) || (idnum > 31)) { pollid = 0; } else { pollid = (1 << idnum); } conn->ctype = C_SERVER; conn->action = C_WRITING; /* Save any client config sent to us */ clientcfg = strchr(STRBUF(conn->msgbuf), '\n'); if (clientcfg) { clientcfg++; if (client_response) xfree(client_response); client_response = strdup(clientcfg); dbgprintf("Saved client response: %s\n", client_response); } } else if (strncmp(STRBUF(conn->msgbuf), "client ", 7) == 0) { /* * Got a "client" message. Return the client-response saved from * earlier, if there is any. If not, then we're done. */ conn->ctype = C_CLIENT_CLIENT; conn->action = (client_response ? C_WRITING : C_DONE); } else { /* Message from a client, but not the "client" message. So no response. */ conn->ctype = C_CLIENT_OTHER; conn->action = C_DONE; } /* * Messages we receive from clients are stored on our outbound queue. * If it's a local "client" message, respond with the queued response * from the Xymon server. Other client messages get no response. * * Server messages get our outbound queue back in response. */ if (conn->ctype != C_SERVER) { /* Messages from clients go on the outbound queue */ msgqueue_t *newq = calloc(1, sizeof(msgqueue_t)); dbgprintf("Queuing outbound message\n"); newq->tstamp = conn->tstamp; newq->msgbuf = conn->msgbuf; conn->msgbuf = NULL; if (qtail) { qtail->next = newq; qtail = newq; } else { qhead = qtail = newq; } if ((conn->ctype == C_CLIENT_CLIENT) && (conn->action == C_WRITING)) { /* Send the response back to the client */ conn->msgbuf = newstrbuffer(0); addtobuffer(conn->msgbuf, client_response); /* * Don't drop the client response data. If for some reason * the "client" request is repeated, he should still get * the right answer that we have. */ } } else { /* A server has asked us for our list of messages */ time_t now = getcurrenttime(NULL); msgqueue_t *mwalk; if (!qhead) { /* No queued messages */ conn->action = C_DONE; } else { /* Build a message of all the queued data */ clearstrbuffer(conn->msgbuf); /* Index line first */ for (mwalk = qhead; (mwalk); mwalk = mwalk->next) { if ((mwalk->sentto & pollid) == 0) { char idx[20]; sprintf(idx, "%d:%ld ", STRBUFLEN(mwalk->msgbuf), (long)(now - mwalk->tstamp)); addtobuffer(conn->msgbuf, idx); } } if (STRBUFLEN(conn->msgbuf) > 0) addtobuffer(conn->msgbuf, "\n"); /* Then the stream of messages */ for (mwalk = qhead; (mwalk); mwalk = mwalk->next) { if ((mwalk->sentto & pollid) == 0) { if (pollid) mwalk->sentto |= pollid; addtostrbuffer(conn->msgbuf, mwalk->msgbuf); } } if (STRBUFLEN(conn->msgbuf) == 0) { /* No data for this server */ conn->action = C_DONE; } } } } void senddata(conn_t *conn) { int n, togo; char *startp; /* Send data on the connection socket */ togo = STRBUFLEN(conn->msgbuf) - conn->sentbytes; startp = STRBUF(conn->msgbuf) + conn->sentbytes; n = write(conn->sockfd, startp, togo); if (n <= -1) { /* Write failure */ errprintf("Connection lost during write to %s\n", inet_ntoa(conn->caddr.sin_addr)); conn->action = C_DONE; } else { conn->sentbytes += n; if (conn->sentbytes == STRBUFLEN(conn->msgbuf)) conn->action = C_DONE; } } int main(int argc, char *argv[]) { int daemonize = 1; int listenq = 10; char *pidfile = "msgcache.pid"; int lsocket; struct sockaddr_in laddr; struct sigaction sa; int opt; /* Don't save the output from errprintf() */ save_errbuf = 0; memset(&laddr, 0, sizeof(laddr)); inet_aton("0.0.0.0", (struct in_addr *) &laddr.sin_addr.s_addr); laddr.sin_port = htons(1984); laddr.sin_family = AF_INET; for (opt=1; (opt < argc); opt++) { if (argnmatch(argv[opt], "--listen=")) { char *locaddr, *p; int locport; locaddr = strchr(argv[opt], '=')+1; p = strchr(locaddr, ':'); if (p) { locport = atoi(p+1); *p = '\0'; } else locport = 1984; memset(&laddr, 0, sizeof(laddr)); laddr.sin_port = htons(locport); laddr.sin_family = AF_INET; if (inet_aton(locaddr, (struct in_addr *) &laddr.sin_addr.s_addr) == 0) { errprintf("Invalid listen address %s\n", locaddr); return 1; } } else if (argnmatch(argv[opt], "--server=")) { /* Who is allowed to fetch cached messages */ char *p = strchr(argv[opt], '='); serverlist = getsenderlist(p+1); } else if (argnmatch(argv[opt], "--max-age=")) { char *p = strchr(argv[opt], '='); maxage = atoi(p+1); } else if (argnmatch(argv[opt], "--lqueue=")) { char *p = strchr(argv[opt], '='); listenq = atoi(p+1); } else if (strcmp(argv[opt], "--daemon") == 0) { daemonize = 1; } else if (strcmp(argv[opt], "--no-daemon") == 0) { daemonize = 0; } else if (argnmatch(argv[opt], "--pidfile=")) { char *p = strchr(argv[opt], '='); pidfile = strdup(p+1); } else if (argnmatch(argv[opt], "--logfile=")) { char *p = strchr(argv[opt], '='); logfile = strdup(p+1); } else if (strcmp(argv[opt], "--debug") == 0) { debug = 1; } else if (strcmp(argv[opt], "--version") == 0) { printf("xymonproxy version %s\n", VERSION); return 0; } } /* Set up a socket to listen for new connections */ lsocket = socket(AF_INET, SOCK_STREAM, 0); if (lsocket == -1) { errprintf("Cannot create listen socket (%s)\n", strerror(errno)); return 1; } opt = 1; setsockopt(lsocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); fcntl(lsocket, F_SETFL, O_NONBLOCK); if (bind(lsocket, (struct sockaddr *)&laddr, sizeof(laddr)) == -1) { errprintf("Cannot bind to listen socket (%s)\n", strerror(errno)); return 1; } if (listen(lsocket, listenq) == -1) { errprintf("Cannot listen (%s)\n", strerror(errno)); return 1; } /* Redirect logging to the logfile, if requested */ if (logfile) { reopen_file(logfile, "a", stdout); reopen_file(logfile, "a", stderr); } errprintf("Xymon msgcache version %s starting\n", VERSION); errprintf("Listening on %s:%d\n", inet_ntoa(laddr.sin_addr), ntohs(laddr.sin_port)); if (daemonize) { pid_t childpid; reopen_file("/dev/null", "r", stdin); /* Become a daemon */ childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork\n"); exit(1); } else if (childpid > 0) { /* Parent - save PID and exit */ FILE *fd = fopen(pidfile, "w"); if (fd) { fprintf(fd, "%d\n", (int)childpid); fclose(fd); } exit(0); } /* Child (daemon) continues here */ setsid(); } setup_signalhandler("msgcache"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigmisc_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); do { fd_set fdread, fdwrite; int maxfd; int n; conn_t *cwalk, *cprev; msgqueue_t *qwalk, *qprev; time_t mintstamp; /* Remove any finished connections */ cwalk = chead; cprev = NULL; while (cwalk) { conn_t *zombie; if (cwalk->action != C_DONE) { cprev = cwalk; cwalk = cwalk->next; continue; } /* Close the socket */ close(cwalk->sockfd); zombie = cwalk; if (cprev == NULL) { chead = zombie->next; cwalk = chead; cprev = NULL; } else { cprev->next = zombie->next; cwalk = zombie->next; } freestrbuffer(zombie->msgbuf); xfree(zombie); } ctail = chead; if (ctail) { while (ctail->next) ctail = ctail->next; } /* Remove expired messages */ qwalk = qhead; qprev = NULL; mintstamp = getcurrenttime(NULL) - maxage; while (qwalk) { msgqueue_t *zombie; if (qwalk->tstamp > mintstamp) { /* Hasn't expired yet */ qprev = qwalk; qwalk = qwalk->next; continue; } zombie = qwalk; if (qprev == NULL) { qhead = zombie->next; qwalk = qhead; qprev = NULL; } else { qprev->next = zombie->next; qwalk = zombie->next; } freestrbuffer(zombie->msgbuf); xfree(zombie); } qtail = qhead; if (qtail) { while (qtail->next) qtail = qtail->next; } /* Now we're ready to handle some data */ FD_ZERO(&fdread); FD_ZERO(&fdwrite); /* Add the listen socket */ FD_SET(lsocket, &fdread); maxfd = lsocket; for (cwalk = chead; (cwalk); cwalk = cwalk->next) { switch (cwalk->action) { case C_READING: FD_SET(cwalk->sockfd, &fdread); if (cwalk->sockfd > maxfd) maxfd = cwalk->sockfd; break; case C_WRITING: FD_SET(cwalk->sockfd, &fdwrite); if (cwalk->sockfd > maxfd) maxfd = cwalk->sockfd; break; case C_DONE: break; } } n = select(maxfd+1, &fdread, &fdwrite, NULL, NULL); if (n < 0) { if (errno == EINTR) continue; errprintf("select failed: %s\n", strerror(errno)); return 0; } if (n == 0) continue; /* Timeout */ for (cwalk = chead; (cwalk); cwalk = cwalk->next) { switch (cwalk->action) { case C_READING: if (FD_ISSET(cwalk->sockfd, &fdread)) grabdata(cwalk); break; case C_WRITING: if (FD_ISSET(cwalk->sockfd, &fdwrite)) senddata(cwalk); break; case C_DONE: break; } } if (FD_ISSET(lsocket, &fdread)) { /* New incoming connection */ conn_t *newconn; int caddrsize; dbgprintf("New connection\n"); newconn = calloc(1, sizeof(conn_t)); caddrsize = sizeof(newconn->caddr); newconn->sockfd = accept(lsocket, (struct sockaddr *)&newconn->caddr, &caddrsize); if (newconn->sockfd == -1) { /* accept() failure. Yes, it does happen! */ dbgprintf("accept failure, ignoring connection (%s)\n", strerror(errno)); xfree(newconn); newconn = NULL; } else { fcntl(newconn->sockfd, F_SETFL, O_NONBLOCK); newconn->action = C_READING; newconn->msgbuf = newstrbuffer(0); newconn->tstamp = getcurrenttime(NULL); } if (newconn) { if (ctail) { ctail->next = newconn; ctail = newconn; } else chead = ctail = newconn; } } } while (keeprunning); if (pidfile) unlink(pidfile); return 0; } xymon-4.3.30/client/runclient.sh0000775000076400007640000001054312652231300017020 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # Xymon client bootup script. # # # # This invokes xymonlaunch, which in turn runs the Xymon client and any # # extensions configured. # # # # Copyright (C) 2005-2011 Henrik Storner # # "status" section (C) Scott Smith 2006 # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: runclient.sh 7884 2016-01-27 21:12:32Z jccleaver $ # Default settings for this client MACHINEDOTS="`uname -n`" # This systems hostname SERVEROSTYPE="`uname -s | tr '[ABCDEFGHIJKLMNOPQRSTUVWXYZ/]' '[abcdefghijklmnopqrstuvwxyz_]'`" # This systems operating system in lowercase XYMONOSSCRIPT="xymonclient-$SERVEROSTYPE.sh" # Command-line mods for the defaults while test "$1" != "" do case "$1" in --hostname=*) MACHINEDOTS="`echo $1 | sed -e 's/--hostname=//'`" ;; --os=*) SERVEROSTYPE="`echo $1 | sed -e 's/--os=//' | tr '[ABCDEFGHIJKLMNOPQRSTUVWXYZ/]' '[abcdefghijklmnopqrstuvwxyz_]'`" ;; --class=*) CONFIGCLASS="`echo $1 | sed -e 's/--class=//' | tr '[ABCDEFGHIJKLMNOPQRSTUVWXYZ/]' '[abcdefghijklmnopqrstuvwxyz_]'`" ;; --help) echo "Usage: $0 [--hostname=CLIENTNAME] [--os=rhel3|linux22] [--class=CLASSNAME] start|stop" exit 0 ;; start) CMD=$1 ;; stop) CMD=$1 ;; restart) CMD=$1 ;; status) CMD=$1 ;; esac shift done XYMONCLIENTHOME="`dirname $0`" if test `echo "$XYMONCLIENTHOME" | grep "^\."` then # no full path, so add current directory to XYMONCLIENTHOME # This may give you "XYMONCLIENTHOME=/usr/local/xymon/./client" - if you # run this script from /usr/local/xymon with "./client/runclient.sh" - # but it works fine. XYMONCLIENTHOME="`pwd`/$XYMONCLIENTHOME" fi export MACHINEDOTS SERVEROSTYPE XYMONOSSCRIPT XYMONCLIENTHOME CONFIGCLASS MACHINE="`echo $MACHINEDOTS | sed -e 's/\./,/g'`" export MACHINE case "$CMD" in "start") if test ! -w $XYMONCLIENTHOME/logs; then echo "Cannot write to the $XYMONCLIENTHOME/logs directory" exit 1 fi if test ! -w $XYMONCLIENTHOME/tmp; then echo "Cannot write to the $XYMONCLIENTHOME/tmp directory" exit 1 fi if test -s $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid; then echo "Xymon client already running, re-starting it" $0 --hostname="$MACHINEDOTS" stop rm -f $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid fi $XYMONCLIENTHOME/bin/xymonlaunch --config=$XYMONCLIENTHOME/etc/clientlaunch.cfg --log=$XYMONCLIENTHOME/logs/clientlaunch.log --pidfile=$XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid if test $? -eq 0; then echo "Xymon client for $SERVEROSTYPE started on $MACHINEDOTS" else echo "Xymon client startup failed" fi ;; "stop") if test -s $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid; then kill `cat $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid` echo "Xymon client stopped" else echo "Xymon client not running" fi ;; "restart") if test -s $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid; then $0 --hostname="$MACHINEDOTS" stop else echo "Xymon client not running, continuing to start it" fi $0 --hostname="$MACHINEDOTS" --os="$SERVEROSTYPE" start ;; "status") if test -s $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid then kill -0 `cat $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid` if test $? -eq 0 then echo "Xymon client (clientlaunch) running with PID `cat $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid`" exit 0 else echo "Xymon client not running, removing stale PID file" rm -f $XYMONCLIENTHOME/logs/clientlaunch.$MACHINEDOTS.pid exit 1 fi else echo "Xymon client (clientlaunch) does not appear to be running" exit 3 fi ;; *) echo "Usage: $0 start|stop|restart|status" break; esac exit 0 xymon-4.3.30/client/xymonclient-irix.sh0000775000076400007640000000353012611270023020335 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # Irix client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-irix.sh 7707 2015-10-19 22:34:59Z jccleaver $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" df -Plk echo "[mount]" mount echo "[swap]" swap -ln echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" netstat -na -f inet -P tcp | tail +3 netstat -na -f inet6 -P tcp | tail +5 echo "[ifstat]" netstat -i -n | egrep -v "^lo|$XYMONTMP/xymon_sar.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_sar.$MACHINEDOTS.$$ $XYMONTMP/xymon_sar.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_sar.$MACHINEDOTS; then echo "[sar]"; cat $XYMONTMP/xymon_sar.$MACHINEDOTS; rm -f $XYMONTMP/xymon_sar.$MACHINEDOTS; fi exit xymon-4.3.30/client/clientupdate.c0000664000076400007640000002120112000773065017302 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon client update tool. */ /* */ /* This tool is used to fetch the current client version from the config-file */ /* saved in etc/clientversion.cfg. The client script compares this with the */ /* current version on the server, and if they do not match then this utility */ /* is run to fetch the new version from the server and unpack it via "tar". */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: clientupdate.c 7085 2012-07-16 11:08:37Z storner $"; #include #include #include #include #include #include #include #include #include "libxymon.h" #define CLIENTVERSIONFILE "etc/clientversion.cfg" #define INPROGRESSFILE "tmp/.inprogress.update" void cleanup(char *inprogressfn, char *selffn) { /* Remove temporary- and lock-files */ unlink(inprogressfn); if (selffn) unlink(selffn); } int main(int argc, char *argv[]) { int argi; char *versionfn, *inprogressfn; FILE *versionfd, *tarpipefd; char version[1024]; char *newversion = NULL; char *newverreq; char *updateparam = NULL; int removeself = 0; int talkstat = 0; sendreturn_t *sres; #ifdef BIG_SECURITY_HOLE /* Immediately drop all root privs, we'll regain them later when needed */ drop_root(); #else /* We WILL not run as suid-root. */ drop_root_and_removesuid(argv[0]); #endif versionfn = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(CLIENTVERSIONFILE) + 2); sprintf(versionfn, "%s/%s", xgetenv("XYMONHOME"), CLIENTVERSIONFILE); inprogressfn = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(INPROGRESSFILE) + 2); sprintf(inprogressfn, "%s/%s", xgetenv("XYMONHOME"), INPROGRESSFILE); versionfd = fopen(versionfn, "r"); if (versionfd) { char *p; if (fgets(version, sizeof(version), versionfd) == NULL) *version = '\0'; p = strchr(version, '\n'); if (p) *p = '\0'; fclose(versionfd); } else { *version = '\0'; } if (chdir(xgetenv("XYMONHOME")) != 0) { errprintf("Cannot chdir to XYMONHOME\n"); return 1; } for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--level") == 0) { /* For checking what version we're at */ printf("%s\n", version); return 0; } else if (strcmp(argv[argi], "--reexec") == 0) { /* * First step of the update procedure. * * To avoid problems with unpacking a new clientupdate * on top of the running one (some tar's will abort * if they try this), copy ourself to a temp. file and * re-exec it to carry out the update. */ char tmpfn[PATH_MAX]; char *srcfn; FILE *tmpfd, *srcfd; unsigned char buf[8192]; long n; struct stat st; int cperr; if (!updateparam) { errprintf("clientupdate --reexec called with no update version\n"); return 1; } if ( (stat(inprogressfn, &st) == 0) && ((getcurrenttime(NULL) - st.st_mtime) < 3600) ) { errprintf("Found update in progress or failed update (started %ld minutes ago)\n", (long) (getcurrenttime(NULL)-st.st_mtime)/60); return 1; } unlink(inprogressfn); tmpfd = fopen(inprogressfn, "w"); if (tmpfd) fclose(tmpfd); /* Copy the executable */ srcfn = argv[0]; srcfd = fopen(srcfn, "r"); cperr = errno; sprintf(tmpfn, "%s/.update.%s.%ld.tmp", xgetenv("XYMONTMP"), xgetenv("MACHINEDOTS"), (long)getcurrenttime(NULL)); dbgprintf("Starting update by copying %s to %s\n", srcfn, tmpfn); unlink(tmpfn); /* To avoid symlink attacks */ if (srcfd) { tmpfd = fopen(tmpfn, "w"); cperr = errno; } if (!srcfd || !tmpfd) { errprintf("Cannot copy executable: %s\n", strerror(cperr)); return 1; } while ((n = fread(buf, 1, sizeof(buf), srcfd)) > 0) fwrite(buf, 1, n, tmpfd); fclose(srcfd); fclose(tmpfd); /* Make sure the temp. binary has execute permissions set */ chmod(tmpfn, S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); /* * Set the temp. executable suid-root, and exec() it. * If get_root() fails (because clientupdate was installed * without suid-root privs), just carry on and do what we * can without root privs. (It basically just means that * logfetch() and clientupdate() will continue to run without * root privs). */ #ifdef BIG_SECURITY_HOLE get_root(); chown(tmpfn, 0, getgid()); chmod(tmpfn, S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); drop_root(); #endif /* Run the temp. executable */ dbgprintf("Running command '%s %s ..remove-self'\n", tmpfn, updateparam); execl(tmpfn, tmpfn, updateparam, "--remove-self", (char *)NULL); /* We should never go here */ errprintf("exec() failed to launch update: %s\n", strerror(errno)); return 1; } else if (strncmp(argv[argi], "--update=", 9) == 0) { newversion = strdup(argv[argi]+9); updateparam = argv[argi]; } else if (strcmp(argv[argi], "--remove-self") == 0) { removeself = 1; } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--suid-setup") == 0) { /* * Final step of the update procedure. * * Become root to setup suid-root privs on utils that need it. * Note: If get_root() fails, we're left with normal user privileges. That is * OK, because that is how the client was installed originally, then. */ #ifdef BIG_SECURITY_HOLE get_root(); chown("bin/logfetch", 0, getgid()); chmod("bin/logfetch", S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); drop_root(); #endif return 0; } } if (!newversion) { errprintf("No new version string!\n"); cleanup(inprogressfn, (removeself ? argv[0] : NULL)); return 1; } /* Update to version "newversion" */ dbgprintf("Opening pipe to 'tar'\n"); tarpipefd = popen("tar xf -", "w"); if (tarpipefd == NULL) { errprintf("Cannot launch 'tar xf -': %s\n", strerror(errno)); cleanup(inprogressfn, (removeself ? argv[0] : NULL)); return 1; } sres = newsendreturnbuf(1, tarpipefd); newverreq = (char *)malloc(100+strlen(newversion)); sprintf(newverreq, "download %s.tar", newversion); dbgprintf("Sending command to Xymon: %s\n", newverreq); if ((talkstat = sendmessage(newverreq, NULL, XYMON_TIMEOUT, sres)) != XYMONSEND_OK) { errprintf("Cannot fetch new client tarfile: Status %d\n", talkstat); cleanup(inprogressfn, (removeself ? argv[0] : NULL)); freesendreturnbuf(sres); return 1; } else { dbgprintf("Download command completed OK\n"); freesendreturnbuf(sres); } dbgprintf("Closing tar pipe\n"); if ((talkstat = pclose(tarpipefd)) != 0) { errprintf("Upgrade failed, tar exited with status %d\n", talkstat); cleanup(inprogressfn, (removeself ? argv[0] : NULL)); return 1; } else { dbgprintf("tar pipe exited with status 0 (OK)\n"); } /* Create the new version file */ dbgprintf("Creating new version file %s with version %s\n", versionfn, newversion); unlink(versionfn); versionfd = fopen(versionfn, "w"); if (versionfd) { fprintf(versionfd, "%s", newversion); fclose(versionfd); } else { errprintf("Cannot create version file: %s\n", strerror(errno)); } /* Make sure these have execute permissions */ dbgprintf("Setting execute permissions on xymonclient.sh and clientupdate tools\n"); chmod("bin/xymonclient.sh", S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); chmod("bin/clientupdate", S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); /* * Become root to setup suid-root privs on the new clientupdate util. * Note: If get_root() fails, we're left with normal user privileges. That is * OK, because that is how the client was installed originally, then. */ #ifdef BIG_SECURITY_HOLE get_root(); chown("bin/clientupdate", 0, getgid()); chmod("bin/clientupdate", S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP); drop_root(); #endif dbgprintf("Cleaning up after update\n"); cleanup(inprogressfn, (removeself ? argv[0] : NULL)); /* * Exec the new client-update utility to fix suid-root permissions on * the new files. */ execl("bin/clientupdate", "bin/clientupdate", "--suid-setup", (char *)NULL); /* We should never go here */ errprintf("exec() of clientupdate --suid-setup failed: %s\n", strerror(errno)); return 0; } xymon-4.3.30/client/xymonclient-unixware.sh0000775000076400007640000000357313462677634021263 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # SCO Unixware client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # Copyright (C) 2006 Charles Goyard # # Copyright (C) 2009 Buchan Milne # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $$ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who -x echo "[df]" df -P echo "[mount]" mount -v echo "[memsize]" /etc/memsize echo "[freemem]" sar -r 1 2 | tail -1 echo "[swap]" swap -l echo "[ifconfig]" ifconfig -a #echo "[ifstat]" #ifconfig -in echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" netstat -an | grep "^tcp" echo "[ps]" #ps -A -o pid,ppid,user,stime,s,pri,pcpu,time,vsz,args ps -A -o pid,ppid,user,pcpu,time,vsz,args # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[top]" $TOP -b -n 1 fi fi # vmstat #nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & #sleep 5 #if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/xymonclient-darwin.sh0000775000076400007640000000442512611270023020652 0ustar rpmbuildrpmbuild#!/bin/sh # #----------------------------------------------------------------------------# # Darwin (Mac OS X) client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-darwin.sh 7707 2015-10-19 22:34:59Z jccleaver $ # Use LANG=C, since some locales have different numeric delimiters # causing the Xymon load-average calculation to fail LANG=C export LANG echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who FILESYSTEMS=`mount | sed -E '/[\( ](nobrowse|afs|read-only)[ ,\)]/d;s/^.* on (.*) \(.*$/\1/'` echo "[df]" (IFS=$'\n' set $FILESYSTEMS df -P -H $1; shift while test $# -gt 0 do df -P -H $1 | tail -1 | sed 's/\([^ ]\) \([^ ]\)/\1_\2/g' shift done) | column -t -s " " | sed -e 's!Mounted *on!Mounted on!' echo "[inode]" (IFS=$'\n' set $FILESYSTEMS df -P -i $1; shift while test $# -gt 0 do df -P -H $1 | tail -1 | sed 's/\([^0123456789% ]\) \([^ ]\)/\1_\2/g' shift done) | awk ' NR<2{printf "%-20s %10s %10s %10s %10s %s\n", $1, "itotal", $6, $7, $8, $9} (NR>=2 && $6>0) {printf "%-20s %10d %10d %10d %10s %s\n", $1, $6+$7, $6, $7, $8, $9}' echo "[mount]" mount echo "[meminfo]" vm_stat echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ifstat]" netstat -ibn | egrep -v "^lo| "$XYMONHOME/etc/logfetch.cfg" ## # # The file defines a series of rules: # UP : Changes the "cpu" status when the system has rebooted recently, # or when it has been running for too long. # LOAD : Changes the "cpu" status according to the system load. # CLOCK : Changes the "cpu" status if the client system clock is # not synchronized with the clock of the Xymon server. # DISK : Changes the "disk" status, depending on the amount of space # used of filesystems. # MEMPHYS: Changes the "memory" status, based on the percentage of real # memory used. # MEMACT : Changes the "memory" status, based on the percentage of "actual" # memory used. Note: Not all systems report an "actual" value. # MEMSWAP: Changes the "memory" status, based on the percentage of swap # space used. # PROC : Changes the "procs" status according to which processes were found # in the "ps" listing from the client. # LOG : Changes the "msgs" status according to entries in text-based logfiles. # Note: The "client-local.cfg" file controls which logfiles the client will report. # FILE : Changes the "files" status according to meta-data for files. # Note: The "client-local.cfg" file controls which files the client will report. # DIR : Changes the "files" status according to the size of a directory. # Note: The "client-local.cfg" file controls which directories the client will report. # PORT : Changes the "ports" status according to which tcp ports were found # in the "netstat" listing from the client. # DEFAULT: Set the default values that apply if no other rules match. # # All rules can be qualified so they apply only to certain hosts, or on certain # times of the day (see below). # # Each type of rule takes a number of parameters: # UP bootlimit toolonglimit # The cpu status goes yellow if the system has been up for less than # "bootlimit" time, or longer than "toolonglimit". The time is in # minutes, or you can add h/d/w for hours/days/weeks - eg. "2h" for # two hours, or "4w" for 4 weeks. # Defaults: bootlimit=1h, toolonglimit=-1 (infinite). # # LOAD warnlevel paniclevel # If the system load exceeds "warnlevel" or "paniclevel", the "cpu" # status will go yellow or red, respectively. These are decimal # numbers. # Defaults: warnlevel=5.0, paniclevel=10.0 # # CLOCK maximum-offset # If the system clock of the client differs from that of the Xymon # server by more than "maximum-offset" seconds, then the CPU status # column will go yellow. Note that the accuracy of this test is limited, # since it is affected by the time it takes a client status report to # go from the client to the Xymon server and be processed. You should # therefore allow for a few seconds (5-10) of slack when you define # your max. offset. # It is not wise to use this test, unless your servers are synchronized # to a common clock, e.g. through NTP. # # DISK filesystem warnlevel paniclevel # DISK filesystem IGNORE # If the utilization of "filesystem" is reported to exceed "warnlevel" # or "paniclevel", the "disk" status will go yellow or red, respectively. # "warnlevel" and "paniclevel" are either the percentage used, or the # space available as reported by the local "df" command on the host. # For the latter type of check, the "warnlevel" must be followed by the # letter "U", e.g. "1024U". # The special keyword "IGNORE" causes this filesystem to be ignored # completely, i.e. it will not appear in the "disk" status column and # it will not be tracked in a graph. This is useful for e.g. removable # devices, backup-disks and similar hardware. # "filesystem" is the mount-point where the filesystem is mounted, e.g. # "/usr" or "/home". A filesystem-name that begins with "%" is interpreted # as a Perl-compatible regular expression; e.g. "%^/oracle.*/" will match # any filesystem whose mountpoint begins with "/oracle". # Defaults: warnlevel=90%, paniclevel=95% # # MEMPHYS warnlevel paniclevel # MEMACT warnlevel paniclevel # MEMSWAP warnlevel paniclevel # If the memory utilization exceeds the "warnlevel" or "paniclevel", the # "memory" status will change to yellow or red, respectively. # Note: The words "PHYS", "ACT" and "SWAP" are also recognized. # Defaults: MEMPHYS warnlevel=100 paniclevel=101 (i.e. it will never go red) # MEMSWAP warnlevel=50 paniclevel=80 # MEMACT warnlevel=90 paniclevel=97 # # PROC processname minimumcount maximumcount color [TRACK=id] [TEXT=displaytext] # The "ps" listing sent by the client will be scanned for how many # processes containing "processname" are running, and this is then # matched against the min/max settings defined here. If the running # count is outside the thresholds, the color of the "procs" status # changes to "color". # To check for a process that must NOT be running: Set minimum and # maximum to 0. # # "processname" can be a simple string, in which case this string must # show up in the "ps" listing as a command. The scanner will find # a ps-listing of e.g. "/usr/sbin/cron" if you only specify "processname" # as "cron". # "processname" can also be a Perl-compatiable regular expression, e.g. # "%java.*inst[0123]" can be used to find entries in the ps-listing for # "java -Xmx512m inst2" and "java -Xmx256 inst3". In that case, # "processname" must begin with "%" followed by the reg.expression. # If "processname" contains whitespace (blanks or TAB), you must enclose # the full string in double quotes - including the "%" if you use regular # expression matching. E.g. # PROC "%xymond_channel --channel=data.*xymond_rrd" 1 1 yellow # or # PROC "java -DCLASSPATH=/opt/java/lib" 2 5 # # You can have multiple "PROC" entries for the same host, all of the # checks are merged into the "procs" status and the most severe # check defines the color of the status. # # The TRACK=id option causes the number of processes found to be recorded # in an RRD file, with "id" as part of the filename. This graph will then # appear on the "procs" page as well as on the "trends" page. Note that # "id" must be unique among the processes tracked for each host. # # The TEXT=displaytext option affects how the process appears on the # "procs" status page. By default, the process is listed with the # "processname" as identification, but if this is a regular expression # it may be a bit difficult to understand. You can then use e.g. # "TEXT=Apache" to make these processes appear with the name "Apache" # instead. # # Defaults: mincount=1, maxcount=-1 (unlimited), color="red". # Note: No processes are checked by default. # # Example: Check that "cron" is running: # PROC cron # Example: Check that at least 5 "httpd" processes are running, but # not more than 20: # PROC httpd 5 20 # # LOG filename match-pattern [COLOR=color] [IGNORE=ignore-pattern] [TEXT=displaytext] # In the "client-local.cfg" file, you can list any number of files # that the client will collect log data from. These are sent to the # Xymon server together with the other client data, and you can then # choose how to analyze the log data with LOG entries. # # ************ IMPORTANT *************** # To monitor a logfile, you *MUST* configure both client-local.cfg # and analysis.cfg. If you configure only the client-local.cfg # file, the client will collect the log data and you can view it in # the "client data" display, but it will not affect the color of the # "msgs" status. On the other hand, if you configure only the # analysis.cfg file, then there will be no log data to inspect, # and you will not see any updates of the "msgs" status either. # # "filename" is a filename or pattern. The set of files reported by # the client is matched against "filename", and if they match then # this LOG entry is processed against the data from a file. # # "match-pattern": The log data is matched against this pattern. If # there is a match, this log file causes a status change to "color". # # "ignore-pattern": The log data that matched "match-pattern" is also # matched against "ignore-pattern". If the data matches the "ignore-pattern", # this line of data does not affect the status color. In other words, # the "ignore-pattern" can be used to refine the strings which cause # a match. # Note: The "ignore-pattern" is optional. # # "color": The color which this match will trigger. # Note: "color" is optional, if omitted then "red" will be used. # # Example: Go yellow if the text "WARNING" shows up in any logfile. # LOG %.* WARNING COLOR=yellow # # Example: Go red if the text "I/O error" or "read error" appears. # LOG %/var/(adm|log)/messages %(I/O|read).error COLOR=red # # FILE filename [color] [things to check] [TRACK] # NB: The files you wish to monitor must be listed in a "file:..." # entry in the client-local.cfg file, in order for the client to # report any data about them. # # "filename" is a filename or pattern. The set of files reported by # the client is matched against "filename", and if they match then # this FILE entry is processed against the data from that file. # # [things to check] can be one or more of the following: # - "NOEXIST" triggers a warning if the file exists. By default, # a warning is triggered for files that have a FILE entry, but # which do not exist. # - "TYPE=type" where "type" is one of "file", "dir", "char", "block", # "fifo", or "socket". Triggers warning if the file is not of the # specified type. # - "OWNERID=owner" and "GROUPID=group" triggers a warning if the owner # or group does not match what is listed here. "owner" and "group" is # specified either with the numeric uid/gid, or the user/group name. # - "MODE=mode" triggers a warning if the file permissions are not # as listed. "mode" is written in the standard octal notation, e.g. # "644" for the rw-r--r-- permissions. # - "SIZEmin.size" triggers a warning it the file # size is greater than "max.size" or less than "min.size", respectively. # You can append "K" (KB), "M" (MB), "G" (GB) or "T" (TB) to the size. # If there is no such modifier, KB is assumed. # E.g. to warn if a file grows larger than 1MB (1024 KB): "SIZE<1M". # - "SIZE=size" triggers a warning it the file size is not what is listed. # - "MTIME>min.mtime" and "MTIME86400". # - "MTIME=timestamp" checks if a file was last modified at "timestamp". # "timestamp" is a unix epoch time (seconds since midnight Jan 1 1970 UTC). # - "CTIME>min.ctime", "CTIME0 MTIME<600 yellow # # Example: Check the timestamp, size and SHA-1 hash of the /bin/sh program: # FILE /bin/sh MTIME=1128514608 SIZE=645140 SHA1=5bd81afecf0eb93849a2fd9df54e8bcbe3fefd72 # # DIR directory [color] [SIZEminsize] [TRACK] # NB: The directories you wish to monitor must be listed in a "dir:..." # entry in the client-local.cfg file, in order for the client to # report any data about them. # # "directory" is a filename or pattern. The set of directories reported by # the client is matched against "directory", and if they match then # this DIR entry is processed against the data for that directory. # # "SIZEminsize" defines the size limits that the # directory must stay within. If it goes outside these limits, a warning # will trigger. Note the Xymon uses the raw number reported by the # local "du" command on the client. This is commonly KB, but it may be # disk blocks which are often 512 bytes. # # "TRACK" causes the size of this directory to be tracked in an RRD file, # and shown on the graph on the "files" display. # # PORT [LOCAL=addr] [EXLOCAL=addr] [REMOTE=addr] [EXREMOTE=addr] [STATE=state] [EXSTATE=state] [min=mincount] [max=maxcount] [col=color] [TRACK=id] [TEXT=displaytext] # The "netstat" listing sent by the client will be scanned for how many # sockets match the criteria listed. # "addr" is a (partial) address specification in the format used on # the output from netstat. This is typically "10.0.0.1:80" for the IP # 10.0.0.1, port 80. Or "*:80" for any local address, port 80. # NB: The Xymon clients normally report only the numeric data for # IP-addresses and port-numbers, so you must specify the port # number (e.g. "80") instead of the service name ("www"). # "state" causes only the sockets in the specified state to be included; # it is usually LISTEN or ESTABLISHED. # The socket count is then matched against the min/max settings defined # here. If the count is outside the thresholds, the color of the "ports" # status changes to "color". # To check for a socket that must NOT exist: Set minimum and # maximum to 0. # # "addr" and "state" can be a simple strings, in which case these string must # show up in the "netstat" at the appropriate column. # "addr" and "state" can also be a Perl-compatiable regular expression, e.g. # "LOCAL=%(:80|:443)" can be used to find entries in the netstat local port for # both http (port 80) and https (port 443). In that case, portname or state must # begin with "%" followed by the reg.expression. # # The TRACK=id option causes the number of sockets found to be recorded # in an RRD file, with "id" as part of the filename. This graph will then # appear on the "ports" page as well as on the "trends" page. Note that # "id" must be unique among the ports tracked for each host. # # The TEXT=displaytext option affects how the port appears on the # "ports" status page. By default, the port is listed with the # local/remote/state rules as identification, but this may be somewhat # difficult to understand. You can then use e.g. "TEXT=Secure Shell" to make # these ports appear with the name "Secure Shell" instead. # # Defaults: state="LISTEN", mincount=1, maxcount=-1 (unlimited), color="red". # Note: No ports are checked by default. # # Example: Check that there is someone listening on the https port: # PORT "LOCAL=%([.:]443)$" state=LISTEN TEXT=https # # Example: Check that at least 5 "ssh" connections are established, but # not more than 10; warn but do not error; graph the connection count: # PORT "LOCAL=%([.:]22)$" state=ESTABLISHED min=5 max=20 color=yellow TRACK=ssh "TEXT=SSH logins" # # Example: Check that ONLY ports 22, 80 and 443 are open for incoming connections: # PORT STATE=LISTEN LOCAL=%0.0.0.0[.:].* EXLOCAL=%[.:](22|80|443)$ MAX=0 "TEXT=Bad listeners" # # # To apply rules to specific hosts, you can use the "HOST=", "EXHOST=", "PAGE=" # "EXPAGE=", "CLASS=" or "EXCLASS=" qualifiers. (These act just as in the # alerts.cfg file). # # Hostnames are either a comma-separated list of hostnames (from the hosts.cfg file), # "*" to indicate "all hosts", or a Perl-compatible regular expression. # E.g. "HOST=dns.foo.com,www.foo.com" identifies two specific hosts; # "HOST=%www.*.foo.com EXHOST=www-test.foo.com" matches all hosts with a name # beginning with "www", except the "www-test" host. # "PAGE" and "EXPAGE" match the hostnames against the page on where they are # located in the hosts.cfg file, via the hosts' page/subpage/subparent # directives. This can be convenient to pick out all hosts on a specific page. # # Rules can be dependent on time-of-day, using the standard Xymon syntax # (the hosts.cfg(5) about the NKTIME parameter). E.g. "TIME=W:0800:2200" # applied to a rule will make this rule active only on week-days between # 8AM and 10PM. # # You can also associate a GROUP id with a rule. The group-id is passed to # the alert module, which can then use it to control who gets an alert when # a failure occurs. E.g. the following associates the "httpd" process check # with the "web" group, and the "sshd" check with the "admins" group: # PROC httpd 5 GROUP=web # PROC sshd 1 GROUP=admins # In the alerts.cfg file, you could then have rules like # GROUP=web # MAIL webmaster@foo.com # GROUP=admins # MAIL root@foo.com # # Qualifiers must be placed after each rule, e.g. # LOAD 8.0 12.0 HOST=db.foo.com TIME=*:0800:1600 # # If you have multiple rules that you want to apply the same qualifiers to, # you can write the qualifiers *only* on one line, followed by the rules. E.g. # HOST=%db.*.foo.com TIME=W:0800:1600 # LOAD 8.0 12.0 # DISK /db 98 100 # PROC mysqld 1 # will apply the three rules to all of the "db" hosts on week-days between 8AM # and 4PM. This can be combined with per-rule qualifiers, in which case the # per-rule qualifier overrides the general qualifier; e.g. # HOST=%.*.foo.com # LOAD 7.0 12.0 HOST=bax.foo.com # LOAD 3.0 8.0 # will result in the load-limits being 7.0/12.0 for the "bax.foo.com" host, # and 3.0/8.0 for all other foo.com hosts. # # The special DEFAULT section can modify the built-in defaults - this must # be placed at the end of the file. DEFAULT # These are the built-in defaults. UP 1h LOAD 5.0 10.0 DISK * 90 95 MEMPHYS 100 101 MEMSWAP 50 80 MEMACT 90 97 xymon-4.3.30/client/xymonclient-sunos.sh0000775000076400007640000001432613033575046020552 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # Solaris client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-sunos.sh 7999 2017-01-06 02:00:06Z jccleaver $ # Work out what type of environment we are on # # this will return the zone name on any non-global solaris zone # or the word "Global" on any global solaris zone # or the word "global" on any standalone solaris platform, including LDOMS (/usr/sbin/zoneadm list 2>/dev/null || echo 1) | wc -l | grep '\<1\>' > /dev/null 2>&1 && ZTYPE=`/bin/zonename 2>/dev/null || echo global` || ZTYPE='Global' echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" # Bothersome, because Solaris df cannot show multiple fs-types, or exclude certain fs types. # Print the root filesystem first, with the header, and those fs's that have the same type. ROOTFSTYPE=`/bin/df -n / | awk '{print $3}'` /bin/df -F $ROOTFSTYPE -k # Then see what fs types are in use, and weed out those we don't want. case $ZTYPE in global|Global) FSTYPES=`/bin/df -n -l|cut -d: -f2 | awk '{print $1}'|egrep -v "^${ROOTFSTYPE}|^proc|^fd|^mntfs|^ctfs|^devfs|^objfs|^nfs|^lofs|^tmpfs|^sharefs"|sort|uniq` ;; *) # zones are frequently type lofs so deal with them specially FSTYPES=`/bin/df -n -l|cut -d: -f2 | awk '{print $1}'|egrep -v "^${ROOTFSTYPE}|^proc|^fd|^mntfs|^ctfs|^devfs|^objfs|^nfs|^tmpfs|^sharefs"|sort|uniq` ;; esac # $FSTYPES may be empty for fst in $FSTYPES; do case $ZTYPE in global|Global) /bin/df -F $fst -k | grep -v " /var/run" | tail +2 ;; *) /bin/df -F $fst -k | egrep -v "( /var/run|^(/dev|/platform/))" | tail +2 ;; esac done # This only works for ufs filesystems echo "[inode]" (if test -x /usr/ucb/df then /usr/ucb/df -i else df -o i 2>/dev/null fi) | awk ' NR<2{printf "%-20s %10s %10s %10s %10s %s\n", $1, "itotal", $2, $3, $4, $5} NR>=2{printf "%-20s %10d %10d %10d %10s %s\n", $1, $2+$3, $2, $3, $4, $5}' echo "[mount]" mount echo "[prtconf]" case $ZTYPE in global|Global) /usr/sbin/prtconf 2>&1 ;; *) # provided by the firmware (PROM) since devinfo facility not available # in a zone /usr/sbin/prtconf -p 2>&1 ;; esac echo "[memory]" case $ZTYPE in global|Global) vmstat 1 2 | tail -1 ;; *) # need to modify vmstat output in a non-global zone VMSTAT=`vmstat 1 2 | tail -1` # cut out the useable parts VMFR=`echo $VMSTAT | cut -d " " -f1,2,3` VMBK=`echo $VMSTAT | cut -d " " -f6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22` # get the total memory for the platform TMEM=`/usr/sbin/prtconf 2>&1 | grep Memory | cut -d" " -f3` TMEM=`expr $TMEM "*" 1024` # get the total allocated and reserved swap SUSED=`swap -s | cut -d "=" -f2 | cut -d "," -f1 | cut -d " " -f2 | cut -d "k" -f1` # work out the RSS for this zone TUSED=`prstat -Z -n 1,1 1 1 | \ nawk ' NR == 4 { do { if ($4 ~ /G$/) { sub(/G$/,"",$4); print $4*1024*1024; break; } if ($4 ~ /M$/) { sub(/M$/,"",$4); print $4*1024; break; } if ($4 ~ /K$/) { sub(/K$/,"",$4); print $4; break; } print "unknown" } while (0)}'` TUSED=`expr $TMEM "-" $TUSED` echo "$VMFR $SUSED $TUSED $VMBK" ;; esac echo "[swap]" /usr/sbin/swap -s # don't report the swaplist in a non-global zone because it will cause the # server client module to miscalculate memory case $ZTYPE in global|Global) echo "[swaplist]" /usr/sbin/swap -l 2>/dev/null ;; esac echo "[ifconfig]" ifconfig -a echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" netstat -na -f inet -P tcp | tail +3 netstat -na -f inet6 -P tcp | tail +5 echo "[ifstat]" # Leave out the wrmsd and mac interfaces. See http://www.xymon.com/archive/2009/06/msg00204.html case $ZTYPE in global|Global) /usr/bin/kstat -p -s '[or]bytes64' | egrep -v 'wrsmd|mac' | sort ;; *) # find out which nics are configured into this zone MYNICS=`netstat -i |cut -f1 -d" " | egrep -i -v "Name|lo|^$" |paste -s -d"|" - ` /usr/bin/kstat -p -s '[or]bytes64' | egrep "$MYNICS"| sort ;; esac echo "[ps]" case $ZTYPE in global) /bin/ps -A -o pid,ppid,user,stime,s,pri,pcpu,time,pmem,rss,vsz,args ;; Global) /bin/ps -A -o zone,pid,ppid,user,stime,class,s,pri,pcpu,time,pmem,rss,vsz,args | sort ;; *) /bin/ps -A -o pid,ppid,user,stime,class,s,pri,pcpu,time,pmem,rss,vsz,args ;; esac # If TOP is defined, then use it. If not, fall back to the Solaris prstat command. echo "[top]" if test "$TOP" != "" -a -x "$TOP" then "$TOP" -b 20 else prstat -can 20 1 1 fi # vmstat and iostat (iostat -d provides a cpu utilisation with I/O wait number) nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & nohup sh -c "iostat -c 300 2 1>$XYMONTMP/xymon_iostatcpu.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_iostatcpu.$MACHINEDOTS.$$ $XYMONTMP/xymon_iostatcpu.$MACHINEDOTS" /dev/null 2>&1 & nohup sh -c "iostat -dxsrP 300 2 1>$XYMONTMP/xymon_iostatdisk.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_iostatdisk.$MACHINEDOTS.$$ $XYMONTMP/xymon_iostatdisk.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi if test -f $XYMONTMP/xymon_iostatcpu.$MACHINEDOTS; then echo "[iostatcpu]"; cat $XYMONTMP/xymon_iostatcpu.$MACHINEDOTS; rm -f $XYMONTMP/xymon_iostatcpu.$MACHINEDOTS; fi if test -f $XYMONTMP/xymon_iostatdisk.$MACHINEDOTS; then echo "[iostatdisk]"; cat $XYMONTMP/xymon_iostatdisk.$MACHINEDOTS; rm -f $XYMONTMP/xymon_iostatdisk.$MACHINEDOTS; fi exit xymon-4.3.30/client/Makefile0000664000076400007640000001037712263072434016134 0ustar rpmbuildrpmbuildOSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]') #ifeq ($(OSTYPE),hpux) # EXTRATOOLS=hpux-meminfo #endif #ifeq ($(OSTYPE),hp-ux) # EXTRATOOLS=hpux-meminfo #endif ifeq ($(OSTYPE),freebsd) EXTRATOOLS=freebsd-meminfo endif ifeq ($(OSTYPE),netbsd) EXTRATOOLS=netbsd-meminfo endif ifeq ($(OSTYPE),openbsd) EXTRATOOLS=openbsd-meminfo endif XYMONCLIENTLIB = ../lib/libxymonclient.a XYMONCLIENTLIBS = $(XYMONCLIENTLIB) XYMONCLIENTCOMMLIB = ../lib/libxymonclientcomm.a XYMONCLIENTCOMMLIBS = $(XYMONCLIENTCOMMLIB) $(SSLLIBS) $(ZLIBLIBS) $(NETLIBS) $(LIBRTDEF) PROGRAMS=xymonlaunch logfetch clientupdate orcaxymon msgcache COMMONTOOLS=xymon xymoncmd xymongrep xymoncfg xymondigest all: $(PROGRAMS) $(COMMONTOOLS) xymonclient.cfg clientlaunch.cfg $(EXTRATOOLS) xymonclient.cfg: xymonclient.cfg.DIST cat xymonclient.cfg.DIST | sed -e 's!@XYMONHOSTIP@!$(XYMONHOSTIP)!g' >xymonclient.cfg ../build/bb-commands.sh >>xymonclient.cfg clientlaunch.cfg: clientlaunch.cfg.DIST ifeq ($(LOCALCLIENT),yes) cat clientlaunch.cfg.DIST | sed -e 's!@CLIENTFLAGS@!--local!g' >clientlaunch.cfg else cat clientlaunch.cfg.DIST | sed -e 's!@CLIENTFLAGS@!!g' >clientlaunch.cfg endif logfetch: logfetch.c $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ logfetch.c $(XYMONCLIENTLIBS) clientupdate: clientupdate.c $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ clientupdate.c $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) orcaxymon: orcaxymon.c $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ orcaxymon.c $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) msgcache: msgcache.c $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ msgcache.c $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) hpux-meminfo: hpux-meminfo.c $(CC) -o $@ hpux-meminfo.c freebsd-meminfo: freebsd-meminfo.c $(CC) -o $@ freebsd-meminfo.c openbsd-meminfo: openbsd-meminfo.c $(CC) -o $@ openbsd-meminfo.c netbsd-meminfo: netbsd-meminfo.c $(CC) -o $@ netbsd-meminfo.c install: if test ! -d $(INSTALLROOT)$(XYMONHOME) ; then mkdir -p $(INSTALLROOT)$(XYMONHOME) ; chmod 755 $(INSTALLROOT)$(XYMONHOME) ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/bin ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/bin ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/bin ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/etc ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/etc ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/etc ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/tmp ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/tmp ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/tmp ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/logs ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/logs ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/logs ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/ext ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/ext ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/ext ; fi if test ! -d $(INSTALLROOT)$(XYMONHOME)/local ; then mkdir -p $(INSTALLROOT)$(XYMONHOME)/local ; chmod 755 $(INSTALLROOT)$(XYMONHOME)/local; fi if test ! -f $(INSTALLROOT)$(XYMONHOME)/etc/localclient.cfg ; then cp localclient.cfg $(INSTALLROOT)$(XYMONHOME)/etc/ ; chmod 644 $(INSTALLROOT)$(XYMONHOME)/etc/localclient.cfg; fi if test ! -f $(INSTALLROOT)$(XYMONHOME)/local/README; then cp README-local $(INSTALLROOT)$(XYMONHOME)/local/README ; chmod 644 $(INSTALLROOT)$(XYMONHOME)/local/README; fi chmod 755 runclient.sh $(PROGRAMS) xymonclient*.sh $(COMMONTOOLS) $(EXTRATOOLS) cp -fp runclient.sh $(INSTALLROOT)$(XYMONHOME) cp -fp $(PROGRAMS) xymonclient*.sh $(COMMONTOOLS) $(EXTRATOOLS) $(INSTALLROOT)$(XYMONHOME)/bin/ ../build/merge-sects clientlaunch.cfg $(INSTALLROOT)$(XYMONHOME)/etc/clientlaunch.cfg ../build/merge-lines xymonclient.cfg $(INSTALLROOT)$(XYMONHOME)/etc/xymonclient.cfg chmod 644 $(INSTALLROOT)$(XYMONHOME)/etc/clientlaunch.cfg $(INSTALLROOT)$(XYMONHOME)/etc/xymonclient.cfg ifndef PKGBUILD chown -R $(XYMONUSER) $(INSTALLROOT)$(XYMONHOME) chgrp -R `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONHOME) chmod 755 $(INSTALLROOT)$(XYMONHOME) endif install-localclient: chmod 755 xymond_client cp -fp xymond_client $(INSTALLROOT)$(XYMONHOME)/bin/ ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONHOME)/bin/xymond_client chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONHOME)/bin/xymond_client endif clean: rm -f $(PROGRAMS) $(COMMONTOOLS) xymond_client xymonclient.cfg clientlaunch.cfg $(EXTRATOOLS) *~ xymon-4.3.30/client/openbsd-meminfo.c0000664000076400007640000000511312465557020017715 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon memory information tool for OpenBSD. */ /* This tool retrieves information about the total and free RAM. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: openbsd-meminfo.c 7505 2015-02-08 03:54:56Z jccleaver $"; #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int hw_physmem[] = { CTL_HW, HW_PHYSMEM }; unsigned int physmem; int hw_pagesize[] = { CTL_HW, HW_PAGESIZE }; int pagesize; int vm_vmtotal[] = { CTL_VM, VM_METER }; struct vmtotal vmdata; size_t len; int result; int swapcount, i; struct swapent *swaplist, *s; unsigned long swaptotal, swapused; len = sizeof(physmem); result = sysctl(hw_physmem, sizeof(hw_physmem) / sizeof(*hw_physmem), &physmem, &len, NULL, 0); if (result != 0) return 1; len = sizeof(pagesize); result = sysctl(hw_pagesize, sizeof(hw_pagesize) / sizeof(*hw_pagesize), &pagesize, &len, NULL, 0); if (result != 0) return 1; len = sizeof(vmdata); result = sysctl(vm_vmtotal, sizeof(vm_vmtotal) / sizeof(*vm_vmtotal), &vmdata, &len, NULL, 0); /* Get swap statistics */ swapcount = swapctl(SWAP_NSWAP, NULL, 0); swaplist = (struct swapent *)malloc(swapcount * sizeof(struct swapent)); result = swapctl(SWAP_STATS, swaplist, swapcount); s = swaplist; swaptotal = swapused = 0; for (i = 0, s = swaplist; (i < swapcount); i++, s++) { if (s->se_flags & SWF_ENABLE) { swaptotal += s->se_nblks; swapused += s->se_inuse; } } free(swaplist); /* swap stats are in disk blocks of 512 bytes, so divide by 2 for KB and 1024 for MB */ swaptotal /= (2*1024); swapused /= (2*1024); // printf("Pagesize:%d\n", pagesize); printf("Total:%d\n", (physmem / (1024 * 1024))); printf("Free:%d\n", (pagesize / 1024)*(vmdata.t_free / 1024)); printf("Swaptotal:%lu\n", swaptotal); printf("Swapused:%lu\n", swapused); return 0; } xymon-4.3.30/client/xymonclient-hp-ux.sh0000775000076400007640000000553712006523030020431 0ustar rpmbuildrpmbuild#!/bin/sh # #----------------------------------------------------------------------------# # HP-UX client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-hp-ux.sh 7156 2012-08-02 16:08:56Z storner $ echo "[date]" date echo "[uname]" uname -a echo "[uptime]" uptime echo "[who]" who echo "[df]" # The sed stuff is to make sure lines are not split into two. df -Pk | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' echo "[inode]" # HPUX once again proves they never do things like everyone else df -il | sed -e 's![():]! !g' | awk ' BEGIN{ t="Filesystem Mounted_on itotal ifree iused iused%" } { if ($1 ~ /^[0123456789]/) { t=sprintf("%s %s",t,$1) } else { t=sprintf("%s\n%s %s %s",t,$2,$1,$3) } } END{ print t }' | awk ' NR<2 { printf "%-35s %10s %10s %10s %10s %s\n", $1, $3, $4, $5, $6, "Mounted on"} NR>=2 { printf "%-35s %10d %10d %10d %10s %s\n", $1, $3, $4, $5, $6, $2} ' echo "[mount]" mount echo "[memory]" # $XYMONHOME/bin/hpux-meminfo # From Earl Flack http://lists.xymon.com/archive/2010-December/030100.html FREE=`/usr/sbin/swapinfo |grep ^memory |awk {'print $4'}` FREEREPORT=`echo $FREE / 1024 |/usr/bin/bc` TOTAL=`/usr/sbin/swapinfo |grep ^memory |awk {'print $2'}` TOTALREPORT=`echo $TOTAL / 1024 |/usr/bin/bc` echo Total:$TOTALREPORT echo Free:$FREEREPORT echo "[swapinfo]" /usr/sbin/swapinfo -tm echo "[ifconfig]" netstat -in echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ifstat]" /usr/sbin/lanscan -p | while read PPA; do /usr/sbin/lanadmin -g mibstats $PPA; done echo "[ports]" netstat -an | grep "^tcp" echo "[ps]" UNIX95=1 ps -Ax -o pid,ppid,user,stime,state,pri,pcpu,time,vsz,args # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[top]" # Cits Bogajewski 03-08-2005: redirect of top fails $TOP -d 1 -f $XYMONHOME/tmp/top.OUT cat $XYMONHOME/tmp/top.OUT rm $XYMONHOME/tmp/top.OUT fi fi # vmstat nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/client/orcaxymon.c0000664000076400007640000000543711615341300016647 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon ORCA data collector. */ /* This tool grabs the last reading from an ORCA logfile and formats it in */ /* NAME:VALUE format for the client message. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: orcaxymon.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { time_t now; char *prefix = NULL, *machinename = NULL; char datestr[12], fn[PATH_MAX]; int i; FILE *fd; char headerline[32768]; char vals[32768]; int gotvals = 0; char *hp, *hdr, *vp, *val; char msgline[4096]; strbuffer_t *msg; machinename = xgetenv("MACHINE"); for (i=1; (i < argc); i++) { if (strncmp(argv[i], "--orca=", 7) == 0) { prefix = argv[i]+7; } else if (strncmp(argv[i], "--machine=", 10) == 0) { machinename = argv[i]+10; } else if (strcmp(argv[i], "--debug") == 0) { debug = dontsendmessages = 1; } } if (!prefix || !machinename) return 0; /* * ORCA logfiles are names PREFIX-%Y-%m-%d-XXX where XXX is a * number starting at 0 and increasing whenever the columns * change. * We will look for the first 20 index numbers only. */ now = getcurrenttime(NULL); strftime(datestr, sizeof(datestr), "%Y-%m-%d", localtime(&now)); i = 0; fd = NULL; while ((i < 20) && !fd) { snprintf(fn, sizeof(fn), "%s-%s-%03d", prefix, datestr, i); fd = fopen(fn, "r"); } if (!fd) return 1; /* Grab the header line, and the last logfile entry. */ if (fgets(headerline, sizeof(headerline), fd)) { while (fgets(vals, sizeof(vals), fd)) gotvals = 1; } fclose(fd); msg = newstrbuffer(0); sprintf(msgline, "data %s.orca\n", machinename); addtobuffer(msg, msgline); /* Match headers and values. */ hdr = strtok_r(headerline, " \t\n", &hp); val = strtok_r(vals, " \t\n", &vp); while (hdr && val) { sprintf(msgline, "%s:%s\n", hdr, val); addtobuffer(msg, msgline); hdr = strtok_r(NULL, " \t\n", &hp); val = strtok_r(NULL, " \t\n", &vp); } sendmessage(STRBUF(msg), NULL, XYMON_TIMEOUT, NULL); return 0; } xymon-4.3.30/client/freebsd-meminfo.c0000664000076400007640000000350112465557020017674 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon memory information tool for FreeBSD. */ /* This tool retrieves information about the total and free RAM. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: freebsd-meminfo.c 7505 2015-02-08 03:54:56Z jccleaver $"; #include #include #include #include #include int main(int argc, char *argv[]) { int hw_physmem[] = { CTL_HW, HW_PHYSMEM }; unsigned long physmem; int hw_pagesize[] = { CTL_HW, HW_PAGESIZE }; int pagesize; int vm_vmtotal[] = { CTL_VM, VM_METER }; struct vmtotal vmdata; size_t len; int result; len = sizeof(physmem); result = sysctl(hw_physmem, sizeof(hw_physmem) / sizeof(*hw_physmem), &physmem, &len, NULL, 0); if (result != 0) return 1; len = sizeof(pagesize); result = sysctl(hw_pagesize, sizeof(hw_pagesize) / sizeof(*hw_pagesize), &pagesize, &len, NULL, 0); if (result != 0) return 1; len = sizeof(vmdata); result = sysctl(vm_vmtotal, sizeof(vm_vmtotal) / sizeof(*vm_vmtotal), &vmdata, &len, NULL, 0); // printf("Pagesize:%d\n", pagesize); printf("Total:%lu\n", (physmem / (1024 * 1024))); printf("Free:%d\n", (pagesize / 1024)*(vmdata.t_free / 1024)); } xymon-4.3.30/client/xymonclient-linux.sh0000775000076400007640000000643213533264442020541 0ustar rpmbuildrpmbuild#!/bin/sh #----------------------------------------------------------------------------# # Linux client for Xymon # # # # Copyright (C) 2005-2011 Henrik Storner # # # # This program is released under the GNU General Public License (GPL), # # version 2. See the file "COPYING" for details. # # # #----------------------------------------------------------------------------# # # $Id: xymonclient-linux.sh 8097 2019-09-02 19:10:26Z jccleaver $ echo "[date]" date echo "[uname]" uname -rsmn echo "[osversion]" if [ -x /bin/lsb_release ]; then /bin/lsb_release -r -i -s | xargs echo /bin/lsb_release -a 2>/dev/null elif [ -x /usr/bin/lsb_release ]; then /usr/bin/lsb_release -r -i -s | xargs echo /usr/bin/lsb_release -a 2>/dev/null elif [ -f /etc/redhat-release ]; then cat /etc/redhat-release elif [ -f /etc/gentoo-release ]; then cat /etc/gentoo-release elif [ -f /etc/debian_version ]; then echo -n "Debian " cat /etc/debian_version elif [ -f /etc/S?SE-release ]; then cat /etc/S?SE-release elif [ -f /etc/slackware-version ]; then cat /etc/slackware-version elif [ -f /etc/mandrake-release ]; then cat /etc/mandrake-release elif [ -f /etc/fedora-release ]; then cat /etc/fedora-release elif [ -f /etc/arch-release ]; then cat /etc/arch-release fi echo "[uptime]" uptime echo "[who]" who echo "[df]" EXCLUDES=`cat /proc/filesystems | grep nodev | grep -v rootfs | awk '{print $2}' | xargs echo | sed -e 's! ! -x !g'` ROOTFS=`readlink -m /dev/root` df -Pl -x iso9660 -x $EXCLUDES | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' -e "s&^rootfs&${ROOTFS}&" echo "[inode]" df -Pil -x iso9660 -x $EXCLUDES | sed -e '/^[^ ][^ ]*$/{ N s/[ ]*\n[ ]*/ / }' -e "s&^rootfs&${ROOTFS}&" echo "[mount]" mount echo "[free]" free echo "[ifconfig]" /sbin/ifconfig 2>/dev/null echo "[route]" netstat -rn echo "[netstat]" netstat -s echo "[ports]" # For some reason, the option for Wide/unTrimmed display of IPs # changed in netstat versions and no one provided backwards compat, # so exactly ONE of these should work successfully: netstat -antuW 2>/dev/null netstat -antuT 2>/dev/null echo "[ifstat]" /sbin/ifconfig 2>/dev/null # Report mdstat data if it exists if test -r /proc/mdstat; then echo "[mdstat]"; cat /proc/mdstat; fi echo "[ps]" ps -Aww f -o pid,ppid,user,start,state,pri,pcpu,time:12,pmem,rsz:10,vsz:10,cmd # $TOP must be set, the install utility should do that for us if it exists. if test "$TOP" != "" then if test -x "$TOP" then echo "[nproc]" nproc --all 2>/dev/null echo "[top]" export CPULOOP ; CPULOOP=1 ; $TOP -b -n 1 # Some top versions do not finish off the last line of output echo "" fi fi # vmstat nohup sh -c "vmstat 300 2 1>$XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ 2>&1; mv $XYMONTMP/xymon_vmstat.$MACHINEDOTS.$$ $XYMONTMP/xymon_vmstat.$MACHINEDOTS" /dev/null 2>&1 & sleep 5 if test -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; then echo "[vmstat]"; cat $XYMONTMP/xymon_vmstat.$MACHINEDOTS; rm -f $XYMONTMP/xymon_vmstat.$MACHINEDOTS; fi exit xymon-4.3.30/include/0000775000076400007640000000000013534041774014636 5ustar rpmbuildrpmbuildxymon-4.3.30/include/libxymon.h0000664000076400007640000000600512503132277016643 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LIBXYMON_H__ #define __LIBXYMON_H__ #include #include #include typedef struct htnames_t { char *name; struct htnames_t *next; } htnames_t; typedef struct strbuffer_t { char *s; int used, sz; } strbuffer_t; #define STRBUF(buf) (buf->s) #define STRBUFLEN(buf) (buf->used) #define STRBUFAVAIL(buf) (buf->sz - buf->used) #define STRBUFEND(buf) (buf->s + buf->used) #define STRBUFSZ(buf) (buf->sz) #define IP_ADDR_STRLEN 16 #include "version.h" #include "config.h" #include "../lib/osdefs.h" #ifdef XYMONWINCLIENT #include "../lib/strfunc.h" #include "../lib/errormsg.h" #include "../lib/environ.h" #include "../lib/stackio.h" #include "../lib/timefunc.h" #include "../lib/memory.h" #include "../lib/sendmsg.h" #include "../lib/holidays.h" #include "../lib/rbtr.h" #include "../lib/msort.h" #include "../lib/misc.h" #else /* Defines CGI URL's */ #include "../lib/cgiurls.h" #include "../lib/links.h" /* Generates HTML */ #include "../lib/acklog.h" #include "../lib/eventlog.h" #include "../lib/headfoot.h" #include "../lib/htmllog.h" #include "../lib/notifylog.h" #include "../lib/acknowledgementslog.h" #include "../lib/reportlog.h" #include "../lib/availability.h" #include "../lib/calc.h" #include "../lib/cgi.h" #include "../lib/color.h" #include "../lib/crondate.h" #include "../lib/clientlocal.h" #include "../lib/digest.h" #include "../lib/encoding.h" #include "../lib/environ.h" #include "../lib/errormsg.h" #include "../lib/files.h" #include "../lib/xymonrrd.h" #include "../lib/holidays.h" #include "../lib/ipaccess.h" #include "../lib/loadalerts.h" #include "../lib/loadhosts.h" #include "../lib/loadcriticalconf.h" #include "../lib/locator.h" #include "../lib/matching.h" #include "../lib/md5.h" #include "../lib/memory.h" #include "../lib/misc.h" #include "../lib/msort.h" #include "../lib/netservices.h" #include "../lib/readmib.h" #include "../lib/rmd160c.h" #include "../lib/run.h" #include "../lib/sendmsg.h" #include "../lib/sha1.h" #include "../lib/sha2.h" #include "../lib/sig.h" #include "../lib/stackio.h" #include "../lib/strfunc.h" #include "../lib/suid.h" #include "../lib/timefunc.h" #include "../lib/timing.h" #include "../lib/tree.h" #include "../lib/url.h" #include "../lib/webaccess.h" #include "../lib/xymond_buffer.h" #include "../lib/xymond_ipc.h" #endif #endif xymon-4.3.30/include/version.h0000664000076400007640000000145113534024416016467 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor */ /* */ /* Copyright (C) 2002-2019 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __VERSION_H__ #define __VERSION_H__ #define VERSION "4.3.30" #endif xymon-4.3.30/xymonnet/0000775000076400007640000000000013534041774015074 5ustar rpmbuildrpmbuildxymon-4.3.30/xymonnet/xymonping.10000664000076400007640000000713713534041732017210 0ustar rpmbuildrpmbuild.TH XYMONPING 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonping \- Xymon ping tool .SH SYNOPSIS .B "xymonping [\-\-retries=N] [\-\-timeout=N] [IP\-addresses]" .SH DESCRIPTION .I xymonping(1) is used for ping testing of the hosts monitored by the .I xymon(7) monitoring system. It reads a list of IP addresses from stdin, and performs a "ping" check to see if these hosts are alive. It is normally invoked by the .I xymonnet(1) utility, which performs all of the Xymon network tests. Optionally, if a list of IP-addresses is passed as command-line arguments, it will ping those IP's instead of reading them from stdin. xymonping only handles IP-addresses, not hostnames. xymonping was inspired by the .I fping(1) tool, but has been written from scratch to implement a fast ping tester without much of the overhead found in other such utilities. The output from xymonping is similar to that of "fping \-Ae". xymonping probes multiple systems in parallel, and the runtime is therefore mostly dependent on the timeout-setting and the number of retries. With the default options, xymonping takes approximately 18 seconds to ping all hosts (tested with an input set of 1500 IP addresses). .SH SUID-ROOT INSTALLATION REQUIRED xymonping needs to be installed with suid-root privileges, since it requires a "raw socket" to send and receive ICMP Echo (ping) packets. xymonping is implemented such that it immediately drops the root privileges, and only regains them to perform two operations: Obtaining the raw socket, and optionally binding it to a specific source address. These operations are performed as root, the rest of the time xymonping runs with normal user privileges. Specifically, no user-supplied data or network data is used while running with root privileges. Therefore it should be safe to provide xymonping with the necessary suid-root privileges. .SH OPTIONS .IP \-\-retries=N Sets the number of retries for hosts that fail to respond to the initial ping, i.e. the number of ping probes sent in addition to the initial probe. The default is \-\-retries=2, to ping a host 3 times before concluding that it is not responding. .IP \-\-timeout=N Determines the timeout (in seconds) for ping probes. If a host does not respond within N seconds, it is regarded as unavailable, unless it responds to one of the retries. The default is \-\-timeout=5. .IP \-\-responses=N xymonping normally stops pinging a host after receiving a single response, and uses that to determine the round-trip time. If the first response takes longer to arrive - e.g. because of additional network overhead when first determining the route to the target host - it may skew the round-trip-time reports. You can then use this option to require N responses, and xymonping will calculate the round-trip time as the average of all of responsetimes. .IP \-\-max\-pps=N Maximum number of packets per second. This limits the number of ICMP packets xymonping will send per second, by enforcing a brief delay after each packet is sent. The default setting is to send a maximum of 50 packets per second. Note that increasing this may cause flooding of the network, and since ICMP packets can be discarded by routers and other network equipment, this can cause erratic behaviour with hosts recorded as not responding when they are in fact OK. .IP \-\-source=ADDRESS Use ADDRESS as the source IP address of the ping packets sent. On multi-homed systems, allows you to select the source IP of the hosts going out, which might be necessary for ping to work. .IP \-\-debug Enable debug output. This prints out all packets sent and received. .SH "SEE ALSO" xymon(7), xymonnet(1), fping(1) xymon-4.3.30/xymonnet/contest.c0000664000076400007640000013421613034012341016705 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of a TCP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: contest.c 8004 2017-01-06 22:06:25Z jccleaver $"; #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymonnet.h" #include "contest.h" #include "httptest.h" #include "dns.h" /* BSD uses RLIMIT_OFILE */ #if defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) #define RLIMIT_NOFILE RLIMIT_OFILE #endif #define MAX_TELNET_CYCLES 5 /* Max loops with telnet options before aborting banner */ #define SSLSETUP_PENDING -1 /* Magic value for tcptest_t->sslrunning while handshaking */ #define SLOWLIMSECS 5 /* How long a socket may be inactive before deemed slow */ /* See http://www.openssl.org/docs/apps/ciphers.html for cipher strings */ char *ciphersmedium = "MEDIUM"; /* Must be formatted for openssl library */ char *ciphershigh = "HIGH"; /* Must be formatted for openssl library */ unsigned int tcp_stats_total = 0; unsigned int tcp_stats_http = 0; unsigned int tcp_stats_plain = 0; unsigned int tcp_stats_connects = 0; unsigned long tcp_stats_read = 0; unsigned long tcp_stats_written = 0; unsigned int warnbytesread = 0; static tcptest_t *thead = NULL; int shuffletests = 0; int sslincludecipherlist = 1; int sslshowallciphers = 0; int snienabled = 0; /* SNI disabled by default */ static svcinfo_t svcinfo_http = { "http", NULL, 0, NULL, 0, 0, (TCP_GET_BANNER|TCP_HTTP), 80 }; static svcinfo_t svcinfo_https = { "https", NULL, 0, NULL, 0, 0, (TCP_GET_BANNER|TCP_HTTP|TCP_SSL), 443 }; static ssloptions_t default_sslopt = { NULL, SSLVERSION_DEFAULT, NULL }; static time_t sslcert_expiretime(char *timestr) { int res; time_t t1, t2; struct tm *t; struct tm exptime; time_t gmtofs, result; memset(&exptime, 0, sizeof(exptime)); /* expire date: 2004-01-02 08:04:15 GMT */ res = sscanf(timestr, "%4d-%2d-%2d %2d:%2d:%2d", &exptime.tm_year, &exptime.tm_mon, &exptime.tm_mday, &exptime.tm_hour, &exptime.tm_min, &exptime.tm_sec); if (res != 6) { errprintf("Cannot interpret certificate time %s\n", timestr); return 0; } /* tm_year is 1900 based; tm_mon is 0 based */ exptime.tm_year -= 1900; exptime.tm_mon -= 1; result = mktime(&exptime); if (result > 0) { /* * Calculate the difference between localtime and GMT */ t = gmtime(&result); t->tm_isdst = 0; t1 = mktime(t); t = localtime(&result); t->tm_isdst = 0; t2 = mktime(t); gmtofs = (t2-t1); result += gmtofs; } else { /* * mktime failed - probably it expires after the * Jan 19,2038 rollover for a 32-bit time_t. */ result = INT_MAX; } dbgprintf("Output says it expires: %s", timestr); dbgprintf("I think it expires at (localtime) %s\n", asctime(localtime(&result))); return result; } static int tcp_callback(unsigned char *buf, unsigned int len, void *priv) { /* * The default data callback function for simple TCP tests. */ tcptest_t *item = (tcptest_t *) priv; if (item->banner == NULL) { item->banner = (unsigned char *)malloc(len+1); } else { item->banner = (unsigned char *)realloc(item->banner, item->bannerbytes+len+1); } memcpy(item->banner+item->bannerbytes, buf, len); item->bannerbytes += len; *(item->banner + item->bannerbytes) = '\0'; return 1; /* We always just grab the first bit of data for TCP tests */ } tcptest_t *add_tcp_test(char *ip, int port, char *service, ssloptions_t *sslopt, char *srcip, char *tspec, int silent, unsigned char *reqmsg, void *priv, f_callback_data datacallback, f_callback_final finalcallback) { tcptest_t *newtest; dbgprintf("Adding tcp test IP=%s, port=%d, service=%s, silent=%d\n", textornull(ip), port, service, silent); if (port == 0) { errprintf("Trying to scan port 0 for service %s\n", service); errprintf("You probably need to define the %s service in /etc/services\n", service); return NULL; } tcp_stats_total++; newtest = (tcptest_t *) calloc(1, sizeof(tcptest_t)); newtest->tspec = (tspec ? strdup(tspec) : NULL); newtest->fd = -1; newtest->lastactive = 0; newtest->bytesread = 0; newtest->byteswritten = 0; newtest->open = 0; newtest->connres = -1; newtest->errcode = CONTEST_ENOERROR; newtest->duration.tv_sec = newtest->duration.tv_nsec = 0; newtest->totaltime.tv_sec = newtest->totaltime.tv_nsec = 0; memset(&newtest->addr, 0, sizeof(newtest->addr)); newtest->addr.sin_family = PF_INET; newtest->addr.sin_port = htons(port); if ((ip == NULL) || (strlen(ip) == 0) || (inet_aton(ip, (struct in_addr *) &newtest->addr.sin_addr.s_addr) == 0)) { newtest->errcode = CONTEST_EDNS; } newtest->srcaddr = (srcip ? strdup(srcip) : NULL); if (strcmp(service, "http") == 0) { newtest->svcinfo = &svcinfo_http; tcp_stats_http++; } else if (strcmp(service, "https") == 0) { newtest->svcinfo = &svcinfo_https; tcp_stats_http++; } else { newtest->svcinfo = find_tcp_service(service); tcp_stats_plain++; } newtest->sendtxt = (reqmsg ? reqmsg : newtest->svcinfo->sendtxt); newtest->sendlen = (reqmsg ? strlen(reqmsg) : newtest->svcinfo->sendlen); newtest->silenttest = silent; newtest->readpending = 0; newtest->telnetnegotiate = (((newtest->svcinfo->flags & TCP_TELNET) && !silent) ? MAX_TELNET_CYCLES : 0); newtest->telnetbuf = NULL; newtest->telnetbuflen = 0; newtest->ssloptions = (sslopt ? sslopt : &default_sslopt); newtest->sslctx = NULL; newtest->ssldata = NULL; newtest->certinfo = NULL; newtest->certissuer = NULL; newtest->certexpires = 0; newtest->sslrunning = ((newtest->svcinfo->flags & TCP_SSL) ? SSLSETUP_PENDING : 0); newtest->sslagain = 0; newtest->banner = NULL; newtest->bannerbytes = 0; if (datacallback == NULL) { /* * Use the default callback-routine, which expects * "priv" to point at the test item. */ newtest->priv = newtest; newtest->datacallback = tcp_callback; } else { /* * Custom callback - handles data output by itself. */ newtest->priv = priv; newtest->datacallback = datacallback; } newtest->finalcallback = finalcallback; if (newtest->errcode == CONTEST_ENOERROR) { newtest->next = thead; thead = newtest; } return newtest; } static void get_connectiontime(tcptest_t *item, struct timespec *timestamp) { tvdiff(&item->timestart, timestamp, &item->duration); } static void get_totaltime(tcptest_t *item, struct timespec *timestamp) { tvdiff(&item->timestart, timestamp, &item->totaltime); } static int do_telnet_options(tcptest_t *item) { /* * Handle telnet options. * * This code was taken from the sources for "netcat" version 1.10 * by "Xymon" . */ unsigned char *obuf; int remain; unsigned char y; unsigned char *inp; unsigned char *outp; int result = 0; if (item->telnetbuflen == 0) { dbgprintf("Ignoring telnet option with length 0\n"); return 0; } obuf = (unsigned char *)malloc(item->telnetbuflen); y = 0; inp = item->telnetbuf; remain = item->telnetbuflen; outp = obuf; while (remain > 0) { if ((remain < 3) || (*inp != 255)) { /* IAC? */ /* * End of options. * We probably have the banner in the remainder of the * buffer, so copy it over, and return it. */ item->banner = strdup(inp); item->bannerbytes = strlen(inp); item->telnetbuflen = 0; xfree(obuf); return 0; } *outp = 255; outp++; inp++; remain--; if ((*inp == 251) || (*inp == 252)) /* WILL or WON'T */ y = 254; /* -> DON'T */ if ((*inp == 253) || (*inp == 254)) /* DO or DON'T */ y = 252; /* -> WON'T */ if (y) { *outp = y; outp++; inp++; remain--; *outp = *inp; outp++; /* copy actual option byte */ y = 0; result = 1; } /* if y */ inp++; remain--; } /* while remain */ item->telnetbuflen = (outp-obuf); if (item->telnetbuflen) memcpy(item->telnetbuf, obuf, item->telnetbuflen); item->telnetbuf[item->telnetbuflen] = '\0'; xfree(obuf); return result; } #if TCP_SSL <= 0 char *ssl_library_version = NULL; /* * Define stub routines for plain socket operations without SSL */ static void setup_ssl(tcptest_t *item) { errprintf("SSL test, but xymonnet was built without SSL support\n"); item->sslrunning = 0; item->errcode = CONTEST_ESSL; } static int socket_write(tcptest_t *item, unsigned char *outbuf, int outlen) { int n = write(item->fd, outbuf, outlen); item->byteswritten += n; return n; } static int socket_read(tcptest_t *item, unsigned char *inbuf, int inbufsize) { int n = read(item->fd, inbuf, inbufsize); item->bytesread += n; return n; } static void socket_shutdown(tcptest_t *item) { shutdown(item->fd, SHUT_RDWR); if (warnbytesread && (item->bytesread > warnbytesread)) { if (item->tspec) errprintf("Huge response %u bytes from %s\n", item->bytesread, item->tspec); else errprintf("Huge response %u bytes for %s:%s\n", item->bytesread, inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname); } } #else char *ssl_library_version = OPENSSL_VERSION_TEXT; static int cert_password_cb(char *buf, int size, int rwflag, void *userdata) { FILE *passfd; char *p; char passfn[PATH_MAX]; char passphrase[1024]; tcptest_t *item = (tcptest_t *)userdata; memset(passphrase, 0, sizeof(passphrase)); /* * Private key passphrases are stored in the file named same as the * certificate itself, but with extension ".pass" */ sprintf(passfn, "%s/certs/%s", xgetenv("XYMONHOME"), item->ssloptions->clientcert); p = strrchr(passfn, '.'); if (p == NULL) p = passfn+strlen(passfn); strcpy(p, ".pass"); passfd = fopen(passfn, "r"); if (passfd && fgets(passphrase, sizeof(passphrase)-1, passfd)) { p = strchr(passphrase, '\n'); if (p) *p = '\0'; } else *passphrase = '\0'; if (passfd) fclose(passfd); strncpy(buf, passphrase, size); buf[size - 1] = '\0'; /* Clear this buffer for security! Don't want passphrases in core dumps... */ memset(passphrase, 0, sizeof(passphrase)); return strlen(buf); } static char *xymon_ASN1_UTCTIME(ASN1_UTCTIME *tm) { static char result[256]; char *asn1_string; int gmt=0; int len, i; int century=0,year=0,month=0,day=0,hour=0,minute=0,second=0; len=tm->length; asn1_string=(char *)tm->data; result[0] = '\0'; if (len < 10) return result; if (asn1_string[len-1] == 'Z') gmt=1; for (i=0; i '9') || (asn1_string[i] < '0')) return result; } if (len >= 15) { /* 20541024111745Z format */ century = 100 * ((asn1_string[0]-'0')*10+(asn1_string[1]-'0')); asn1_string += 2; } year=(asn1_string[0]-'0')*10+(asn1_string[1]-'0'); if (century == 0 && year < 50) year+=100; month=(asn1_string[2]-'0')*10+(asn1_string[3]-'0'); if ((month > 12) || (month < 1)) return result; day=(asn1_string[4]-'0')*10+(asn1_string[5]-'0'); hour=(asn1_string[6]-'0')*10+(asn1_string[7]-'0'); minute=(asn1_string[8]-'0')*10+(asn1_string[9]-'0'); if ( (asn1_string[10] >= '0') && (asn1_string[10] <= '9') && (asn1_string[11] >= '0') && (asn1_string[11] <= '9')) { second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0'); } sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d %s", year+(century?century:1900), month, day, hour, minute, second, (gmt?"GMT":"")); return result; } static void setup_ssl(tcptest_t *item) { static int ssl_init_complete = 0; struct servent *sp; char portinfo[100]; X509 *peercert; char *certcn, *certstart, *certend, *certissuer; const char *certsigalg; int err, keysz = 0; strbuffer_t *sslinfo; char msglin[2048]; item->sslrunning = 1; if (!ssl_init_complete) { /* Setup entropy */ if (RAND_status() != 1) { char path[PATH_MAX]; /* Path for the random file */ /* load entropy from files */ RAND_load_file(RAND_file_name(path, sizeof (path)), -1); /* shuffle $RANDFILE (or ~/.rnd if unset) */ RAND_write_file(RAND_file_name(path, sizeof (path))); if (RAND_status() != 1) { errprintf("Failed to find enough entropy on your system"); item->errcode = CONTEST_ESSL; return; } } SSL_load_error_strings(); SSL_library_init(); ssl_init_complete = 1; } if (item->sslctx == NULL) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L item->sslctx = SSL_CTX_new(TLS_client_method()); #else item->sslctx = SSL_CTX_new(SSLv23_client_method()); #endif switch (item->ssloptions->sslversion) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L case SSLVERSION_TLS12: SSL_CTX_set_min_proto_version(item->sslctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(item->sslctx, TLS1_2_VERSION); break; case SSLVERSION_TLS11: SSL_CTX_set_min_proto_version(item->sslctx, TLS1_1_VERSION); SSL_CTX_set_max_proto_version(item->sslctx, TLS1_1_VERSION); break; case SSLVERSION_TLS10: SSL_CTX_set_min_proto_version(item->sslctx, TLS1_VERSION); SSL_CTX_set_max_proto_version(item->sslctx, TLS1_VERSION); break; #elif OPENSSL_VERSION_NUMBER >= 0x10001000L case SSLVERSION_TLS12: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1)); break; case SSLVERSION_TLS11: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_2)); break; case SSLVERSION_TLS10: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)); break; #ifdef HAVE_SSLV2_SUPPORT case SSLVERSION_V2: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)); break; #endif #ifdef HAVE_SSLV3_SUPPORT case SSLVERSION_V3: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)); break; #endif #else case SSLVERSION_TLS10: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3)); break; #ifdef HAVE_SSLV2_SUPPORT case SSLVERSION_V2: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1)); break; #endif #ifdef HAVE_SSLV3_SUPPORT case SSLVERSION_V3: SSL_CTX_set_options(item->sslctx, (SSL_OP_NO_SSLv2|SSL_OP_NO_TLSv1)); break; #endif #endif default: break; } if (!item->sslctx) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Cannot create SSL context - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } /* Workaround SSL bugs */ SSL_CTX_set_options(item->sslctx, SSL_OP_ALL); SSL_CTX_set_quiet_shutdown(item->sslctx, 1); /* Limit set of ciphers, if user wants to */ if (item->ssloptions->cipherlist) SSL_CTX_set_cipher_list(item->sslctx, item->ssloptions->cipherlist); if (item->ssloptions->clientcert) { int status; char certfn[PATH_MAX]; SSL_CTX_set_default_passwd_cb(item->sslctx, cert_password_cb); SSL_CTX_set_default_passwd_cb_userdata(item->sslctx, item); sprintf(certfn, "%s/certs/%s", xgetenv("XYMONHOME"), item->ssloptions->clientcert); status = SSL_CTX_use_certificate_chain_file(item->sslctx, certfn); if (status == 1) { status = SSL_CTX_use_PrivateKey_file(item->sslctx, certfn, SSL_FILETYPE_PEM); } if (status != 1) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Cannot load SSL client certificate/key %s: %s\n", item->ssloptions->clientcert, sslerrmsg); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } } } if (item->ssldata == NULL) { item->ssldata = SSL_new(item->sslctx); if (!item->ssldata) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("SSL_new failed - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; SSL_CTX_free(item->sslctx); item->errcode = CONTEST_ESSL; return; } /* Verify that the client certificate is working */ if (item->ssloptions->clientcert) { X509 *x509; x509 = SSL_get_certificate(item->ssldata); if(x509 != NULL) { EVP_PKEY *pktmp = X509_get_pubkey(x509); EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(item->ssldata)); EVP_PKEY_free(pktmp); } if (!SSL_CTX_check_private_key(item->sslctx)) { errprintf("Private/public key mismatch for certificate %s\n", item->ssloptions->clientcert); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } } #if (SSLEAY_VERSION_NUMBER >= 0x00908070) if (item->sni) SSL_set_tlsext_host_name(item->ssldata, item->sni); #endif /* SSL setup is done. Now attach the socket FD to the SSL protocol handler */ if (SSL_set_fd(item->ssldata, item->fd) != 1) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Could not initiate SSL on connection - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); item->errcode = CONTEST_ESSL; return; } } sp = getservbyport(item->addr.sin_port, "tcp"); if (sp) { sprintf(portinfo, "%s (%d/tcp)", sp->s_name, item->addr.sin_port); } else { sprintf(portinfo, "%d/tcp", item->addr.sin_port); } if ((err = SSL_connect(item->ssldata)) != 1) { char sslerrmsg[256]; switch (SSL_get_error (item->ssldata, err)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: item->sslrunning = SSLSETUP_PENDING; break; case SSL_ERROR_SYSCALL: ERR_error_string(ERR_get_error(), sslerrmsg); /* Filter out the bogus SSL error */ if (strstr(sslerrmsg, "error:00000000:") == NULL) { errprintf("IO error in SSL_connect to %s on host %s: %s\n", portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); } item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; case SSL_ERROR_SSL: ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Unspecified SSL error in SSL_connect to %s on host %s: %s\n", portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; default: ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Unknown error %d in SSL_connect to %s on host %s: %s\n", err, portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; } return; } /* If we get this far, the SSL handshake has completed. So grab the certificate */ peercert = SSL_get_peer_certificate(item->ssldata); if (!peercert) { errprintf("Cannot get peer certificate for %s on host %s\n", portinfo, inet_ntoa(item->addr.sin_addr)); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); return; } sslinfo = newstrbuffer(0); certcn = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0); certissuer = X509_NAME_oneline(X509_get_issuer_name(peercert), NULL, 0); #if OPENSSL_VERSION_NUMBER < 0x10100000L certsigalg = OBJ_nid2ln(OBJ_obj2nid(peercert->sig_alg->algorithm)); #else certsigalg = OBJ_nid2ln(X509_get_signature_nid(peercert)); #endif certstart = strdup(xymon_ASN1_UTCTIME(X509_get_notBefore(peercert))); certend = strdup(xymon_ASN1_UTCTIME(X509_get_notAfter(peercert))); { BIO *o = BIO_new(BIO_s_mem()); long slen; char *sdata, *keyline; #if OPENSSL_VERSION_NUMBER < 0x0090700fL X509_NAME_print_ex(o, X509_get_subject_name(peercert), 8, XN_FLAG_COMPAT); #else X509_print_ex(o, peercert, XN_FLAG_COMPAT, X509_FLAG_COMPAT); #endif slen = BIO_get_mem_data(o, &sdata); if (slen > 0) { keyline = strstr(sdata, " Public-Key:"); if (!keyline) keyline = strstr(sdata, " Public Key:"); if (keyline) { keyline = strchr(keyline, '('); if (keyline) keysz = atoi(keyline+1); } } BIO_set_close(o, BIO_CLOSE); BIO_free(o); } snprintf(msglin, sizeof(msglin), "Server certificate:\n\tsubject:%s\n\tstart date: %s\n\texpire date:%s\n\tkey size:%d\n\tissuer:%s\n\tsignature algorithm: %s\n", certcn, certstart, certend, keysz, certissuer, certsigalg); addtobuffer(sslinfo, msglin); item->certsubject = strdup(certcn); item->certissuer = strdup(certissuer); item->certexpires = sslcert_expiretime(certend); item->certkeysz = keysz; xfree(certcn); xfree(certstart); xfree(certend); xfree(certissuer); X509_free(peercert); /* We list the available ciphers in the SSL cert data */ if (sslincludecipherlist) { int b1, b2; b1 = SSL_get_cipher_bits(item->ssldata, &b2); certsigalg = OBJ_nid2ln(X509_get_signature_type(peercert)); snprintf(msglin, sizeof(msglin), "\nCipher used: %s (%d bits)\n", SSL_get_cipher_name(item->ssldata), b1); addtobuffer(sslinfo, msglin); item->mincipherbits = b1; if (sslshowallciphers) { int i; STACK_OF(SSL_CIPHER) *sk; addtobuffer(sslinfo, "\nAvailable ciphers:\n"); sk = SSL_get_ciphers(item->ssldata); for (i=0; imincipherbits == 0) || (b1 < item->mincipherbits)) item->mincipherbits = b1; } } } item->certinfo = grabstrbuffer(sslinfo); } static int socket_write(tcptest_t *item, char *outbuf, int outlen) { int res = 0; if (item->sslrunning) { res = SSL_write(item->ssldata, outbuf, outlen); if (res < 0) { switch (SSL_get_error (item->ssldata, res)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: res = 0; break; } } } else { res = write(item->fd, outbuf, outlen); } item->byteswritten += res; return res; } static int socket_read(tcptest_t *item, char *inbuf, int inbufsize) { int res = 0; char errtxt[1024]; if (item->svcinfo->flags & TCP_SSL) { if (item->sslrunning) { item->sslagain = 0; res = SSL_read(item->ssldata, inbuf, inbufsize); if (res < 0) { switch (SSL_get_error (item->ssldata, res)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: item->sslagain = 1; break; default: ERR_error_string(ERR_get_error(), errtxt); dbgprintf("SSL read error %s\n", errtxt); break; } } } else { /* SSL setup failed - flag 0 bytes read. */ res = 0; } } else { res = read(item->fd, inbuf, inbufsize); if (res < 0) { dbgprintf("Read error %s\n", strerror(errno)); } } if (res > 0) item->bytesread += res; return res; } static void socket_shutdown(tcptest_t *item) { if (item->sslrunning) { SSL_shutdown(item->ssldata); SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); } shutdown(item->fd, SHUT_RDWR); if (warnbytesread && (item->bytesread > warnbytesread)) { if (item->tspec) errprintf("Huge response %u bytes from %s\n", item->bytesread, item->tspec); else errprintf("Huge response %u bytes for %s:%s\n", item->bytesread, inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname); } } #endif static int tcptest_compare(void **a, void **b) { tcptest_t **tcpa = (tcptest_t **)a; tcptest_t **tcpb = (tcptest_t **)b; if ((*tcpa)->randomizer < (*tcpb)->randomizer) return -1; else if ((*tcpa)->randomizer > (*tcpb)->randomizer) return 1; else return 0; } static void * tcptest_getnext(void *a) { return ((tcptest_t *)a)->next; } static void tcptest_setnext(void *a, void *newval) { ((tcptest_t *)a)->next = (tcptest_t *)newval; } void do_tcp_tests(int timeout, int concurrency) { int selres; fd_set readfds, writefds; struct timespec timestamp; int absmaxconcurrency; int activesockets = 0; /* Number of allocated sockets */ int pending = 0; /* Total number of tests */ tcptest_t *nextinqueue; /* Points to the next item to start testing */ tcptest_t *firstactive; /* Points to the first item currently being tested */ /* Thus, active connections are between firstactive..nextinqueue */ tcptest_t *item; int sockok; int maxfd; int res; socklen_t connressize; char msgbuf[4096]; struct rlimit lim; /* If timeout or concurrency are 0, set them to reasonable defaults */ if (timeout == 0) timeout = 10; /* seconds */ /* * Decide how many tests to run in parallel. * If no --concurrency set by user, default to (FD_SETSIZE / 4) - typically 256. * But never go above the ressource limit that is set, or above FD_SETSIZE. * And we save 10 fd's for stdio, libs etc. */ absmaxconcurrency = (FD_SETSIZE - 10); getrlimit(RLIMIT_NOFILE, &lim); if ((lim.rlim_cur > 10) && ((lim.rlim_cur - 10) < absmaxconcurrency)) absmaxconcurrency = (lim.rlim_cur - 10); if (concurrency == 0) concurrency = (FD_SETSIZE / 4); if (concurrency > absmaxconcurrency) concurrency = absmaxconcurrency; dbgprintf("Concurrency evaluation: rlim_cur=%lu, FD_SETSIZE=%d, absmax=%d, initial=%d\n", lim.rlim_cur, FD_SETSIZE, absmaxconcurrency, concurrency); if (shuffletests) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); srandom(tv.tv_usec); } /* How many tests to do ? */ for (item = thead; (item); item = item->next) { if (shuffletests) item->randomizer = random(); pending++; } if (shuffletests) thead = msort(thead, tcptest_compare, tcptest_getnext, tcptest_setnext); firstactive = nextinqueue = thead; dbgprintf("About to do %d TCP tests running %d in parallel, abs.max %d\n", pending, concurrency, absmaxconcurrency); while (pending > 0) { int slowrunning, cclimit; time_t slowtimestamp = gettimer() - SLOWLIMSECS; /* * First, see if we need to allocate new sockets and initiate connections. */ /* * We start by counting the number of tests where the latest activity * happened more than SLOWLIMSECS seconds ago. These are ignored when counting * how many more tests we can start concurrenly. But never exceed the absolute * max. number of concurrently open sockets possible. */ for (item=firstactive, slowrunning = 0; (item != nextinqueue); item=item->next) { if ((item->fd > -1) && (item->lastactive < slowtimestamp)) slowrunning++; } cclimit = concurrency + slowrunning; if (cclimit > absmaxconcurrency) cclimit = absmaxconcurrency; sockok = 1; while (sockok && nextinqueue && (activesockets < cclimit)) { /* * We need to allocate a new socket that has O_NONBLOCK set. */ nextinqueue->fd = socket(PF_INET, SOCK_STREAM, 0); sockok = (nextinqueue->fd != -1); if (sockok) { /* Set the source address */ if (nextinqueue->srcaddr) { struct sockaddr_in src; int isip; memset(&src, 0, sizeof(src)); src.sin_family = PF_INET; src.sin_port = 0; isip = (inet_aton(nextinqueue->srcaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0); if (!isip) { char *envaddr = getenv(nextinqueue->srcaddr); isip = (envaddr && (inet_aton(envaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0)); } if (isip) { res = bind(nextinqueue->fd, (struct sockaddr *)&src, sizeof(src)); if (res != 0) errprintf("WARNING: Could not bind to source IP %s for test %s: %s\n", nextinqueue->srcaddr, nextinqueue->tspec, strerror(errno)); } else { errprintf("WARNING: Invalid source IP %s for test %s, using default\n", nextinqueue->srcaddr, nextinqueue->tspec); } } res = fcntl(nextinqueue->fd, F_SETFL, O_NONBLOCK); if (res == 0) { /* * Initiate the connection attempt ... */ getntimer(&nextinqueue->timestart); nextinqueue->lastactive = nextinqueue->timestart.tv_sec; nextinqueue->cutoff = nextinqueue->timestart.tv_sec + timeout + 1; res = connect(nextinqueue->fd, (struct sockaddr *)&nextinqueue->addr, sizeof(nextinqueue->addr)); /* * Did it work ? */ if ((res == 0) || ((res == -1) && (errno == EINPROGRESS))) { /* This is OK - EINPROGRES and res=0 pick up status in select() */ activesockets++; tcp_stats_connects++; } else if (res == -1) { /* connect() failed. Flag the item as "not open" */ nextinqueue->connres = errno; nextinqueue->open = 0; nextinqueue->errcode = CONTEST_ENOCONN; close(nextinqueue->fd); nextinqueue->fd = -1; pending--; switch (nextinqueue->connres) { /* These may happen if connection is refused immediately */ case ECONNREFUSED : break; case EHOSTUNREACH : break; case ENETUNREACH : break; case EHOSTDOWN : break; /* Not likely ... */ case ETIMEDOUT : break; /* These should not happen. */ case EBADF : errprintf("connect returned EBADF!\n"); break; case ENOTSOCK : errprintf("connect returned ENOTSOCK!\n"); break; case EADDRNOTAVAIL: errprintf("connect returned EADDRNOTAVAIL!\n"); break; case EAFNOSUPPORT : errprintf("connect returned EAFNOSUPPORT!\n"); break; case EISCONN : errprintf("connect returned EISCONN!\n"); break; case EADDRINUSE : errprintf("connect returned EADDRINUSE!\n"); break; case EFAULT : errprintf("connect returned EFAULT!\n"); break; case EALREADY : errprintf("connect returned EALREADY!\n"); break; default : errprintf("connect returned %d for test %s, errno=%d, %s\n", res, nextinqueue->tspec, errno, strerror(errno)); } } else { /* Should NEVER happen. connect returns 0 or -1 */ errprintf("Strange result from connect: %d, for test %s, errno=%d, %s\n", res, nextinqueue->tspec, errno, strerror(errno)); } } else { /* Could net set to non-blocking mode! Hmmm ... */ sockok = 0; errprintf("Cannot set O_NONBLOCK\n"); } nextinqueue=nextinqueue->next; } else { int newconcurrency = ((activesockets > 5) ? (activesockets-1) : 5); /* Could not get a socket */ switch (errno) { case EPROTONOSUPPORT: errprintf("Cannot get socket - EPROTONOSUPPORT\n"); break; case EAFNOSUPPORT : errprintf("Cannot get socket - EAFNOSUPPORT\n"); break; case EMFILE : errprintf("Cannot get socket - EMFILE\n"); break; case ENFILE : errprintf("Cannot get socket - ENFILE\n"); break; case EACCES : errprintf("Cannot get socket - EACCESS\n"); break; case ENOBUFS : errprintf("Cannot get socket - ENOBUFS\n"); break; case ENOMEM : errprintf("Cannot get socket - ENOMEM\n"); break; case EINVAL : errprintf("Cannot get socket - EINVAL\n"); break; default : errprintf("Cannot get socket - errno=%d\n", errno); break; } if (newconcurrency != concurrency) { errprintf("Reducing --concurrency setting from %d to %d\n", concurrency, newconcurrency); concurrency = newconcurrency; } } } /* Ready to go - we have a bunch of connections being established */ dbgprintf("%d tests pending - %d active tests, %d slow tests\n", pending, activesockets, slowrunning); restartselect: /* * Setup the FDSET's */ FD_ZERO(&readfds); FD_ZERO(&writefds); maxfd = -1; for (item=firstactive; (item != nextinqueue); item=item->next) { if (item->fd > -1) { /* * WRITE events are used to signal that a * connection is ready, or it has been refused. * READ events are only interesting for sockets * that have already been found to be open, and * thus have the "readpending" flag set. * * So: On any given socket, we want either a * write-event or a read-event - never both. */ if (item->readpending) FD_SET(item->fd, &readfds); else FD_SET(item->fd, &writefds); if (item->fd > maxfd) maxfd = item->fd; } } if (maxfd == -1) { /* No active connections */ if (activesockets == 0) { /* This can happen, if we get an immediate CONNREFUSED on all connections. */ continue; } else { errprintf("contest logic error: No FD's, active=%d, pending=%d\n", activesockets, pending); continue; } } /* * Wait for something to happen: connect, timeout, banner arrives ... */ if (maxfd < 0) { errprintf("select - no active fd's found, but pending is %d\n", pending); selres = 0; } else { struct timeval tmo = { 1, 0 }; dbgprintf("Doing select with maxfd=%d\n", maxfd); selres = select((maxfd+1), &readfds, &writefds, NULL, &tmo); dbgprintf("select returned %d\n", selres); } if (selres == -1) { int selerr = errno; /* * select() failed - this is BAD! */ switch (selerr) { case EINTR : errprintf("select failed - EINTR\n"); goto restartselect; case EBADF : errprintf("select failed - EBADF\n"); break; case EINVAL: errprintf("select failed - EINVAL\n"); break; case ENOMEM: errprintf("select failed - ENOMEM\n"); break; default : errprintf("Unknown select() error %d\n", selerr); break; } /* Leave this mess ... */ errprintf("Aborting TCP tests with %d tests pending\n", pending); return; } /* selres == 0 (timeout) isn't special - just go through the list of active tests */ /* Fetch the timestamp so we can tell how long the connect took */ getntimer(×tamp); /* Now find out which connections had something happen to them */ for (item=firstactive; (item != nextinqueue); item=item->next) { if (item->fd > -1) { /* Only active sockets have this */ if (timestamp.tv_sec > item->cutoff) { /* * Request timed out. */ if (item->readpending) { /* Final read timeout - just shut this socket */ socket_shutdown(item); item->errcode = CONTEST_ETIMEOUT; } else { /* Connection timeout */ item->open = 0; item->errcode = CONTEST_ETIMEOUT; } get_totaltime(item, ×tamp); close(item->fd); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } else { if (FD_ISSET(item->fd, &writefds)) { int do_talk = 1; unsigned char *outbuf = NULL; unsigned int outlen = 0; item->lastactive = timestamp.tv_sec; if (!item->open) { /* * First time here. * * Active response on this socket - either OK, or * connection refused. * We determine what happened by getting the SO_ERROR status. * (cf. select_tut(2) manpage). */ connressize = sizeof(item->connres); res = getsockopt(item->fd, SOL_SOCKET, SO_ERROR, &item->connres, &connressize); item->open = (item->connres == 0); if (!item->open) item->errcode = CONTEST_ENOCONN; do_talk = item->open; get_connectiontime(item, ×tamp); } if (item->open && (item->svcinfo->flags & TCP_SSL)) { /* * Setup the SSL connection, if not done already. * * NB: This can be triggered many times, as setup_ssl() * may need more data from the remote and return with * item->sslrunning == SSLSETUP_PENDING */ if (item->sslrunning == SSLSETUP_PENDING) { setup_ssl(item); if (item->sslrunning == 1) { /* * Update connectiontime to include * time for SSL handshake. */ get_connectiontime(item, ×tamp); } } do_talk = (item->sslrunning == 1); } /* * Connection succeeded - port is open, if SSL then the * SSL handshake is complete. * * If we have anything to send then send it. * If we want the banner, set the "readpending" flag to initiate * select() for read()'s. * NB: We want the banner EITHER if the GET_BANNER flag is set, * OR if we need it to match the expect string in the servicedef. */ item->readpending = (do_talk && !item->silenttest && ( (item->svcinfo->flags & TCP_GET_BANNER) || item->svcinfo->exptext )); if (do_talk) { if (item->telnetnegotiate && item->telnetbuflen) { /* * Return the telnet negotiate data response */ outbuf = item->telnetbuf; outlen = item->telnetbuflen; } else if (item->sendtxt && !item->silenttest) { outbuf = item->sendtxt; outlen = (item->sendlen ? item->sendlen : strlen(outbuf)); } if (outbuf && outlen) { /* * It may be that we cannot write all of the * data we want to. Tough ... */ res = socket_write(item, outbuf, outlen); tcp_stats_written += res; if (res == -1) { /* Write failed - this socket is done. */ dbgprintf("write failed\n"); item->readpending = 0; item->errcode = CONTEST_EIO; } else if (item->svcinfo->flags & TCP_HTTP) { /* * HTTP tests require us to send the full buffer. * So adjust sendtxt/sendlen accordingly. * If no more to send, switch to read-mode. */ item->sendtxt += res; item->sendlen -= res; item->readpending = (item->sendlen == 0); } } } /* If closed and/or no bannergrabbing, shut down socket */ if (item->sslrunning != SSLSETUP_PENDING) { if (!item->open || !item->readpending) { if (item->open) { socket_shutdown(item); } close(item->fd); get_totaltime(item, ×tamp); if (item->finalcallback) item->finalcallback(item->priv); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } } } else if (FD_ISSET(item->fd, &readfds)) { /* * Data ready to read on this socket. Grab the * banner - we only do one read (need the socket * for other tests), so if the banner takes more * than one cycle to arrive, too bad! */ int wantmoredata = 0; int datadone = 0; item->lastactive = timestamp.tv_sec; /* * We may be in the process of setting up an SSL connection */ if (item->sslrunning == SSLSETUP_PENDING) setup_ssl(item); if (item->sslrunning == SSLSETUP_PENDING) break; /* Loop again waiting for more data */ /* * Connection is ready - plain or SSL. Read data. */ res = socket_read(item, msgbuf, sizeof(msgbuf)-1); tcp_stats_read += res; dbgprintf("read %d bytes from socket\n", res); if ((res > 0) && item->datacallback) { datadone = item->datacallback(msgbuf, res, item->priv); } if ((res > 0) && item->telnetnegotiate) { /* * telnet data has telnet options first. * We must negotiate the session before we * get the banner. */ item->telnetbuf = item->banner; item->telnetbuflen = res; /* * Safety measure: Don't loop forever doing * telnet options. * This puts a maximum on how many times * we go here. */ item->telnetnegotiate--; if (!item->telnetnegotiate) { dbgprintf("Max. telnet negotiation (%d) reached for host %s\n", MAX_TELNET_CYCLES, inet_ntoa(item->addr.sin_addr)); } if (do_telnet_options(item)) { /* Still havent seen the session banner */ item->banner = NULL; item->bannerbytes = 0; item->readpending = 0; wantmoredata = 1; } else { /* No more options - we have the banner */ item->telnetnegotiate = 0; } } if ((item->svcinfo->flags & TCP_HTTP) && ((res > 0) || item->sslagain) && (!datadone) ) { /* * HTTP : Grab the entire response. */ wantmoredata = 1; } if (!wantmoredata) { if (item->open) { socket_shutdown(item); } item->readpending = 0; close(item->fd); get_totaltime(item, ×tamp); if (item->finalcallback) item->finalcallback(item->priv); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } } } } } /* end for loop */ } /* end while (pending) */ dbgprintf("TCP tests completed normally\n"); } void show_tcp_test_results(void) { tcptest_t *item; for (item = thead; (item); item = item->next) { printf("Address=%s:%d, open=%d, res=%d, err=%d, connecttime=%u.%06u, totaltime=%u.%06u, ", inet_ntoa(item->addr.sin_addr), ntohs(item->addr.sin_port), item->open, item->connres, item->errcode, (unsigned int)item->duration.tv_sec, (unsigned int)(item->duration.tv_nsec/1000), (unsigned int)item->totaltime.tv_sec, (unsigned int)(item->totaltime.tv_nsec/1000)); if (item->banner && (item->bannerbytes == strlen(item->banner))) { printf("banner='%s' (%d bytes)", textornull(item->banner), item->bannerbytes); } else { int i; unsigned char *p; for (i=0, p=item->banner; i < item->bannerbytes; i++, p++) { printf("%c", (isprint(*p) ? *p : '.')); } } if (item->certinfo) { printf(", certinfo='%s' (%u %s)", item->certinfo, (unsigned int)item->certexpires, ((item->certexpires > getcurrenttime(NULL)) ? "valid" : "expired")); } printf("\n"); if ((item->svcinfo == &svcinfo_http) || (item->svcinfo == &svcinfo_https)) { http_data_t *httptest = (http_data_t *) item->priv; printf("httpstatus = %d, open=%d, errcode=%d, parsestatus=%d\n", httptest->httpstatus, httptest->tcptest->open, httptest->tcptest->errcode, httptest->parsestatus); printf("Response:\n"); if (httptest->headers) printf("%s\n", httptest->headers); else printf("(no headers)\n"); if (httptest->contentcheck == CONTENTCHECK_DIGEST) printf("Content digest: %s\n", httptest->digest); if (httptest->output) printf("%s", httptest->output); } } } int tcp_got_expected(tcptest_t *test) { if (test == NULL) return 1; if (test->svcinfo && test->svcinfo->exptext) { int compbytes; /* Number of bytes to compare */ /* Did we get enough data? */ if (test->banner == NULL) { dbgprintf("tcp_got_expected: No data in banner\n"); return 0; } compbytes = (test->svcinfo->explen ? test->svcinfo->explen : strlen(test->svcinfo->exptext)); if ((test->svcinfo->expofs + compbytes) > test->bannerbytes) { dbgprintf("tcp_got_expected: Not enough data\n"); return 0; } return (memcmp(test->svcinfo->exptext+test->svcinfo->expofs, test->banner, compbytes) == 0); } else return 1; } #ifdef STANDALONE int main(int argc, char *argv[]) { int argi; char *argp, *p; int timeout = 0; int concurrency = 0; if (xgetenv("XYMONNETSVCS") == NULL) putenv("XYMONNETSVCS="); init_tcp_services(); for (argi=1; (argihost = hostitem; testitem->testspec = testspec; strcpy(hostitem->ip, ip); add_url_to_dns_queue(testspec); add_http_test(testitem); testitem->next = NULL; httptest = (http_data_t *)testitem->privdata; if (httptest && httptest->tcptest) { printf("TCP connection goes to %s:%d\n", inet_ntoa(httptest->tcptest->addr.sin_addr), ntohs(httptest->tcptest->addr.sin_port)); printf("Request:\n%s\n", httptest->tcptest->sendtxt); } } else if (strncmp(argp, "dns=", 4) == 0) { strbuffer_t *banner = newstrbuffer(0); int result; result = dns_test_server(ip, argp+4, banner); printf("DNS test result=%d\nBanner:%s\n", result, STRBUF(banner)); } else { add_tcp_test(ip, atoi(port), testspec, NULL, srcip, NULL, 0, NULL, NULL, NULL, NULL); } } else { printf("Invalid testspec '%s'\n", argv[argi]); } } } do_tcp_tests(timeout, concurrency); show_tcp_test_results(); return 0; } #endif xymon-4.3.30/xymonnet/httpcookies.h0000664000076400007640000000234611630612042017571 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2008-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HTTPCOOKIES_H__ #define __HTTPCOOKIES_H__ typedef struct cookielist_t { char *host; int tailmatch; char *path; int secure; char *name; char *value; struct cookielist_t *next; } cookielist_t; extern cookielist_t *cookiehead; extern void *cookietree; extern void init_session_cookies(char *urlhost, char *cknam, char *ckpath, char *ckval); extern void update_session_cookies(char *hostname, char *urlhost, char *headers); extern void save_session_cookies(void); extern void load_cookies(void); #endif xymon-4.3.30/xymonnet/xymonnet.h0000664000076400007640000001730013462431333017121 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __XYMONNET_H__ #define __XYMONNET_H__ #include #define STATUS_CONTENTMATCH_NOFILE 901 #define STATUS_CONTENTMATCH_FAILED 902 #define STATUS_CONTENTMATCH_BADREGEX 903 #define MAX_CONTENT_DATA (1024*1024) /* 1 MB should be enough for most */ /* toolids */ enum toolid_t { TOOL_CONTEST, TOOL_DNS, TOOL_NTP, TOOL_FPING, TOOL_HTTP, TOOL_LDAP, TOOL_RPCINFO }; /* * Structure of the xymonnet in-memory records * * +->service_t * | testname * | namelen * | portnum * | toolid * | items --------------> testitem_t <----------------------------------------------+ * | next +------- service | * | | host ---------------+ * +-----------------------+ testspec | | * dialup +-->testedhost_t <------------+ | * reverse hostname | | * silenttest ip | | * alwaystrue dialup | | * open testip | | * banner nosslcert | | * certinfo dodns | | * duration dnserror | | * badtest pingerror | | * downcount repeattest | | * downstart noconn | | * privdata ----+ noping | | * next | badconn | | * | downcount | | * | downstart | | * | routerdeps | | * | deprouterdown --------+ | * | firsthttp -----------------+ * | firstldap -----------------+ * | ldapuser * | ldappasswd * | sslwarndays * | sslalarmdays * | * +---------> */ typedef struct service_t { char *testname; /* Name of the test = column name in Xymon report */ int namelen; /* Length of name - "testname:port" has this as strlen(testname), others 0 */ int portnum; /* Port number this service runs on */ enum toolid_t toolid; /* Which tool to use */ struct testitem_t *items; /* testitem_t linked list of tests for this service */ } service_t; enum multiping_t { MULTIPING_BEST, MULTIPING_WORST }; typedef struct ipping_t { char *ip; int open; strbuffer_t *banner; struct ipping_t *next; } ipping_t; typedef struct extraping_t { enum multiping_t matchtype; ipping_t *iplist; } extraping_t; typedef struct testedhost_t { char *hostname; char ip[IP_ADDR_STRLEN]; int dialup; /* dialup flag (if set, failed tests report as clear) */ int testip; /* testip flag (don't do dns lookups on hostname) */ int nosslcert; /* nosslcert flag */ int hidehttp; /* hidehttp flag */ int dodns; /* set while loading tests if we need to do a DNS lookup */ int dnserror; /* set internally if we cannot find the host's IP */ int pingerror; /* set internally if host does not answer ping */ int repeattest; /* Set if this host goes on the quick poll list */ char *hosttype; /* For the "Intermediate HOSTTYPE is down" message */ /* The following are for the connectivity test */ int noconn; /* noconn flag (don't report "conn" at all */ int noping; /* noping flag (report "conn" as clear=disabled */ int badconn[3]; /* badconn:x:y:z flag */ int downcount; /* number of successive failed conn tests */ time_t downstart; /* time() of first conn failure */ char *routerdeps; /* Hosts from the "router:" tag */ struct testedhost_t *deprouterdown; /* Set if dependent router is down */ int dotrace; /* Run traceroute for this host */ strbuffer_t *traceroute;/* traceroute results */ struct extraping_t *extrapings; /* The following is for the HTTP/FTP URL tests */ struct testitem_t *firsthttp; /* First HTTP testitem in testitem list */ /* The following is for the LDAP tests */ struct testitem_t *firstldap; /* First LDAP testitem in testitem list */ char *ldapuser; /* Username */ char *ldappasswd; /* Password */ int ldapsearchfailyellow; /* Go red or yellow on failed search */ /* The following is for the SSL certificate checks */ int sslwarndays; int sslalarmdays; int mincipherbits; /* For storing the test dependency tag. */ char *deptests; } testedhost_t; typedef struct testitem_t { struct testedhost_t *host; /* Pointer to testedhost_t record for this host */ struct service_t *service; /* Pointer to service_t record for the service to test */ char *testspec; /* Pointer to the raw testspec in hosts.cfg */ int reverse; /* "!testname" flag */ int dialup; /* "?testname" flag */ int alwaystrue; /* "~testname" flag */ int silenttest; /* "testname:s" flag */ int senddata; /* For tests that merely generate a "data" report */ char *srcip; /* These data may be filled in from the test engine private data */ int open; /* Is the service open ? NB: Shows true state of service, ignores flags */ strbuffer_t *banner; char *certinfo; char *certissuer; time_t certexpires; int mincipherbits; int certkeysz; struct timespec duration; /* For badTEST handling: Need to track downtime duration and poll count */ int badtest[3]; time_t downstart; int downcount; /* Number of polls when down. */ /* Each test engine has its own data */ void *privdata; /* Private data use by test tool */ int internal; /* For internal use, not to be reported back to Xymon server */ struct testitem_t *next; } testitem_t; typedef struct dnstest_t { int testcount; int okcount; } dnstest_t; /* Custom list of status code => color overrides */ typedef struct httpstatuscolor_t { int statuscode; int color; struct httpstatuscolor_t *next; } httpstatuscolor_t; extern char *deptest_failed(testedhost_t *host, char *testname); extern int validity; #endif xymon-4.3.30/xymonnet/httpcookies.c0000664000076400007640000001263613515623702017600 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2008-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: httpcookies.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include "libxymon.h" #include "httpcookies.h" cookielist_t *cookiehead = NULL; void * cookietree; typedef struct hcookie_t { char *key; char *val; } hcookie_t; void init_session_cookies(char *urlhost, char *cknam, char *ckpath, char *ckval) { hcookie_t *itm; unsigned int keylen = strlen(urlhost) + strlen(cknam) + strlen(ckpath) + 3; itm = (hcookie_t *)malloc(sizeof(hcookie_t)); itm->key = (char *)malloc(keylen); snprintf(itm->key, keylen, "%s\t%s\t%s", urlhost, cknam, ckpath); itm->val = strdup(ckval); xtreeAdd(cookietree, itm->key, itm); } void update_session_cookies(char *hostname, char *urlhost, char *headers) { char *ckhdr, *onecookie; if (!headers) return; ckhdr = headers; do { ckhdr = strstr(ckhdr, "\nSet-Cookie:"); if (ckhdr) { /* Set-Cookie: JSESSIONID=rKy8HZbLgT5W9N8; path=/ */ char *eoln, *cknam, *ckval, *ckpath; cknam = ckval = ckpath = NULL; onecookie = strchr(ckhdr, ':') + 1; onecookie += strspn(onecookie, " \t"); eoln = strchr(onecookie, '\n'); if (eoln) *eoln = '\0'; ckhdr = (eoln ? eoln : NULL); onecookie = strdup(onecookie); if (eoln) *eoln = '\n'; cknam = strtok(onecookie, "="); if (cknam) ckval = strtok(NULL, ";"); if (ckval) { char *tok, *key; unsigned int keylen; xtreePos_t h; hcookie_t *itm; do { tok = strtok(NULL, ";\r"); if (tok) { tok += strspn(tok, " "); if (strncmp(tok, "path=", 5) == 0) { ckpath = tok+5; } } } while (tok); if (ckpath == NULL) ckpath = "/"; keylen = strlen(urlhost) + strlen(cknam) + strlen(ckpath) + 3; key = (char *)malloc(keylen); snprintf(key, keylen, "%s\t%s\t%s", urlhost, cknam, ckpath); h = xtreeFind(cookietree, key); if (h == xtreeEnd(cookietree)) { itm = (hcookie_t *)malloc(sizeof(hcookie_t)); itm->key = key; itm->val = strdup(ckval); xtreeAdd(cookietree, itm->key, itm); } else { itm = (hcookie_t *)xtreeData(cookietree, h); xfree(itm->val); itm->val = strdup(ckval); xfree(key); } } xfree(onecookie); } } while (ckhdr); } void save_session_cookies(void) { FILE *fd = NULL; char cookiefn[PATH_MAX]; xtreePos_t h; hcookie_t *itm; snprintf(cookiefn, sizeof(cookiefn), "%s/etc/cookies.session", xgetenv("XYMONHOME")); fd = fopen(cookiefn, "w"); if (fd == NULL) return; for (h=xtreeFirst(cookietree); (h != xtreeEnd(cookietree)); h = xtreeNext(cookietree, h)) { char *urlhost, *ckpath, *cknam; itm = (hcookie_t *)xtreeData(cookietree, h); urlhost = strtok(itm->key, "\t"); cknam = strtok(NULL, "\t"); ckpath = strtok(NULL, "\t"); fprintf(fd, "%s\tFALSE\t%s\tFALSE\t0\t%s\t%s\n", urlhost, ckpath, cknam, itm->val); } fclose(fd); } /* This loads the cookies from the cookie-storage file */ static void load_cookies_one(char *cookiefn) { FILE *fd; char l[4096]; char *c_host, *c_path, *c_name, *c_value; int c_tailmatch, c_secure; time_t c_expire; char *p; fd = fopen(cookiefn, "r"); if (fd == NULL) return; c_host = c_path = c_name = c_value = NULL; c_tailmatch = c_secure = 0; c_expire = 0; while (fgets(l, sizeof(l), fd)) { p = strchr(l, '\n'); if (p) { *p = '\0'; p--; if ((p > l) && (*p == '\r')) *p = '\0'; } if ((l[0] != '#') && strlen(l)) { int fieldcount = 0; p = strtok(l, "\t"); if (p) { fieldcount++; c_host = p; p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_tailmatch = (strcmp(p, "TRUE") == 0); p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_path = p; p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_secure = (strcmp(p, "TRUE") == 0); p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_expire = atol(p); p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_name = p; p = strtok(NULL, "\t"); } if (p) { fieldcount++; c_value = p; p = strtok(NULL, "\t"); } if ((fieldcount == 7) && (c_expire > getcurrenttime(NULL))) { /* We have a valid cookie */ cookielist_t *ck = (cookielist_t *)malloc(sizeof(cookielist_t)); ck->host = strdup(c_host); ck->tailmatch = c_tailmatch; ck->path = strdup(c_path); ck->secure = c_secure; ck->name = strdup(c_name); ck->value = strdup(c_value); ck->next = cookiehead; cookiehead = ck; } } } fclose(fd); } void load_cookies(void) { static int initdone = 0; char cookiefn[PATH_MAX]; if (initdone) return; initdone = 1; snprintf(cookiefn, sizeof(cookiefn), "%s/etc/cookies", xgetenv("XYMONHOME")); load_cookies_one(cookiefn); snprintf(cookiefn, sizeof(cookiefn), "%s/etc/cookies.session", xgetenv("XYMONHOME")); load_cookies_one(cookiefn); } xymon-4.3.30/xymonnet/c-ares-shim.sh0000775000076400007640000000100012524545555017536 0ustar rpmbuildrpmbuild#!/bin/sh # Separate $CFLAGS and $CPPFLAGS for c-ares, which is now a bit more strict about things # # This will be moot if we get around to autoconfiscating the build process. # for i in $CFLAGS; do if [ `echo $i | grep -c '\-I'` -eq 0 -a `echo $i | grep -c '\-D'` -eq 0 -a `echo $i | grep -c '\-L'` -eq 0 ]; then CFF="$CFF $i" elif [ `echo $i | grep -c '\-L'` -eq 0 ]; then CPF="$CPF $i" else echo "REJECTING '${i}' in CFLAGS" fi done CFLAGS="$CFF" CPPFLAGS="$CPF" $* xymon-4.3.30/xymonnet/ldaptest.c0000664000076400007640000004052613515623702017063 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of an LDAP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: ldaptest.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymonnet.h" #include "ldaptest.h" #define XYMON_LDAP_OK 0 #define XYMON_LDAP_INITFAIL 10 #define XYMON_LDAP_TLSFAIL 11 #define XYMON_LDAP_BINDFAIL 20 #define XYMON_LDAP_TIMEOUT 30 #define XYMON_LDAP_SEARCHFAILED 40 char *ldap_library_version = NULL; static volatile int connect_timeout = 0; int init_ldap_library(void) { #ifdef HAVE_LDAP char versionstring[100]; /* Doesnt really do anything except define the version-number string */ snprintf(versionstring, sizeof(versionstring), "%s %d", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); ldap_library_version = strdup(versionstring); #endif return 0; } void shutdown_ldap_library(void) { #ifdef HAVE_LDAP /* No-op for LDAP */ #endif } int add_ldap_test(testitem_t *t) { #ifdef HAVE_LDAP testitem_t *basecheck; ldap_data_t *req; LDAPURLDesc *ludp; char *urltotest; int badurl; basecheck = (testitem_t *)t->privdata; /* * t->testspec containts the full testspec * We need to remove any URL-encoding. */ urltotest = urlunescape(t->testspec); badurl = (ldap_url_parse(urltotest, &ludp) != 0); /* Allocate the private data and initialize it */ t->privdata = (void *) calloc(1, sizeof(ldap_data_t)); req = (ldap_data_t *) t->privdata; req->ldapdesc = (void *) ludp; req->usetls = (strncmp(urltotest, "ldaps:", 6) == 0); if (req->usetls && (ludp->lud_port == LDAPS_PORT)) { dbgprintf("Forcing port %d for ldaps with STARTTLS\n", LDAP_PORT ); ludp->lud_port = LDAP_PORT; } req->ldapstatus = 0; req->output = NULL; req->ldapcolor = -1; req->faileddeps = NULL; req->duration.tv_sec = req->duration.tv_nsec = 0; req->certinfo = NULL; req->certissuer = NULL; req->certexpires = 0; req->certkeysz = 0; req->skiptest = 0; if (badurl) { errprintf("Invalid LDAP URL %s\n", t->testspec); req->skiptest = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = "Cannot parse LDAP URL"; } /* * At this point, the plain TCP checks have already run. * So we know from the test found in t->privdata whether * the LDAP port is open. * If it is not open, then don't run this check. */ if (basecheck->open == 0) { /* Cannot connect to LDAP port. */ req->skiptest = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = "Cannot connect to server"; } #endif return 0; } #if (LDAP_VENDOR != OpenLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT) static void ldap_alarmhandler(int signum) { signal(signum, SIG_DFL); connect_timeout = 1; } #endif void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int querytimeout) { #ifdef HAVE_LDAP ldap_data_t *req; testitem_t *t; struct timespec starttime; struct timespec endtime; /* Pick a sensible default for the timeout setting */ if (querytimeout == 0) querytimeout = 30; for (t = ldaptest->items; (t); t = t->next) { LDAPURLDesc *ludp; LDAP *ld; int rc, finished; int msgID = -1; struct timeval ldaptimeout; struct timeval openldaptimeout; LDAPMessage *result; LDAPMessage *e; strbuffer_t *response; char buf[MAX_LINE_LEN]; req = (ldap_data_t *) t->privdata; if (req->skiptest) continue; ludp = (LDAPURLDesc *) req->ldapdesc; getntimer(&starttime); /* Initiate session with the LDAP server */ dbgprintf("Initiating LDAP session for host %s port %d\n", ludp->lud_host, ludp->lud_port); if( (ld = ldap_init(ludp->lud_host, ludp->lud_port)) == NULL ) { dbgprintf("ldap_init failed\n"); req->ldapstatus = XYMON_LDAP_INITFAIL; continue; } /* * There is apparently no standard way of defining a network * timeout for the initial connection setup. */ #if (LDAP_VENDOR == OpenLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT) /* * OpenLDAP has an undocumented ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv) */ openldaptimeout.tv_sec = querytimeout; openldaptimeout.tv_usec = 0; ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &openldaptimeout); #else /* * So using an alarm() to interrupt any pending operations * seems to be the least insane way of doing this. * * Note that we must do this right after ldap_init(), as * any operation on the session handle (ld) may trigger the * network connection to be established. */ connect_timeout = 0; signal(SIGALRM, ldap_alarmhandler); alarm(querytimeout); #endif /* * This is completely undocumented in the OpenLDAP docs. * But apparently it is documented in * http://www.ietf.org/proceedings/99jul/I-D/draft-ietf-ldapext-ldap-c-api-03.txt * * Both of these routines appear in the file * from OpenLDAP 2.1.22. Their use to enable TLS has * been deciphered from the ldapsearch() utility * sourcecode. * * According to Manon Goo , recent (Jan. 2005) * OpenLDAP implementations refuse to talk LDAPv2. */ #ifdef LDAP_OPT_PROTOCOL_VERSION { int protocol = LDAP_VERSION3; dbgprintf("Attempting to select LDAPv3\n"); if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) { dbgprintf("Failed to select LDAPv3, trying LDAPv2\n"); protocol = LDAP_VERSION2; if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) { req->output = strdup(ldap_err2string(rc)); req->ldapstatus = XYMON_LDAP_TLSFAIL; } continue; } } #endif if (req->usetls) { dbgprintf("Trying to enable TLS for session\n"); if ((rc = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) { dbgprintf("ldap_start_tls failed\n"); req->output = strdup(ldap_err2string(rc)); req->ldapstatus = XYMON_LDAP_TLSFAIL; continue; } } if (!connect_timeout) { msgID = ldap_simple_bind(ld, (t->host->ldapuser ? t->host->ldapuser : ""), (t->host->ldappasswd ? t->host->ldappasswd : "")); } /* Cancel any pending alarms */ alarm(0); signal(SIGALRM, SIG_DFL); /* Did we connect? */ if (connect_timeout || (msgID == -1)) { req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = "Cannot connect to server"; continue; } /* Wait for bind to complete */ rc = 0; finished = 0; ldaptimeout.tv_sec = querytimeout; ldaptimeout.tv_usec = 0L; while( ! finished ) { int rc2; rc = ldap_result(ld, msgID, LDAP_MSG_ONE, &ldaptimeout, &result); dbgprintf("ldap_result returned %d for ldap_simple_bind()\n", rc); if(rc == -1) { finished = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; if (result == NULL) { errprintf("LDAP library problem - NULL result returned\n"); req->output = strdup("LDAP BIND failed\n"); } else { rc2 = ldap_result2error(ld, result, 1); req->output = strdup(ldap_err2string(rc2)); } ldap_unbind(ld); } else if (rc == 0) { finished = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup("Connection timeout"); ldap_unbind(ld); } else if( rc > 0 ) { finished = 1; if (result == NULL) { errprintf("LDAP library problem - got a NULL resultcode for status %d\n", rc); req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup("LDAP library problem: ldap_result2error returned a NULL result for status %d\n"); ldap_unbind(ld); } else { rc2 = ldap_result2error(ld, result, 1); if(rc2 != LDAP_SUCCESS) { req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); } } } } /* ... while() */ /* We're done connecting. If something went wrong, go to next query. */ if (req->ldapstatus != 0) continue; /* Now do the search. With a timeout */ ldaptimeout.tv_sec = querytimeout; ldaptimeout.tv_usec = 0L; rc = ldap_search_st(ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldaptimeout, &result); if(rc == LDAP_TIMEOUT) { req->ldapstatus = XYMON_LDAP_TIMEOUT; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); continue; } if( rc != LDAP_SUCCESS ) { req->ldapstatus = XYMON_LDAP_SEARCHFAILED; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); continue; } getntimer(&endtime); response = newstrbuffer(0); snprintf(buf, sizeof(buf), "Searching LDAP for %s yields %d results:\n\n", t->testspec, ldap_count_entries(ld, result)); addtobuffer(response, buf); for(e = ldap_first_entry(ld, result); (e != NULL); e = ldap_next_entry(ld, e) ) { char *dn; BerElement *ber; char *attribute; char **vals; dn = ldap_get_dn(ld, e); snprintf(buf, sizeof(buf), "DN: %s\n", dn); addtobuffer(response, buf); /* Addtributes and values */ for (attribute = ldap_first_attribute(ld, e, &ber); (attribute != NULL); attribute = ldap_next_attribute(ld, e, ber) ) { if ((vals = ldap_get_values(ld, e, attribute)) != NULL) { int i; for(i = 0; (vals[i] != NULL); i++) { snprintf(buf, sizeof(buf), "\t%s: %s\n", attribute, vals[i]); addtobuffer(response, buf); } } /* Free memory used to store values */ ldap_value_free(vals); } /* Free memory used to store attribute */ ldap_memfree(attribute); ldap_memfree(dn); if (ber != NULL) ber_free(ber, 0); addtobuffer(response, "\n"); } req->ldapstatus = XYMON_LDAP_OK; req->output = grabstrbuffer(response); tvdiff(&starttime, &endtime, &req->duration); ldap_msgfree(result); ldap_unbind(ld); ldap_free_urldesc(ludp); } #endif } static int statuscolor(testedhost_t *host, int ldapstatus) { switch (ldapstatus) { case XYMON_LDAP_OK: return COL_GREEN; case XYMON_LDAP_INITFAIL: case XYMON_LDAP_TLSFAIL: case XYMON_LDAP_BINDFAIL: case XYMON_LDAP_TIMEOUT: return COL_RED; case XYMON_LDAP_SEARCHFAILED: return (host->ldapsearchfailyellow ? COL_YELLOW : COL_RED); } errprintf("Unknown ldapstaus value %d\n", ldapstatus); return COL_RED; } void send_ldap_results(service_t *ldaptest, testedhost_t *host, char *nonetpage, int failgoesclear) { testitem_t *t; int color = -1; char msgline[4096]; SBUF_DEFINE(nopagename); int nopage = 0; testitem_t *ldap1 = host->firstldap; int anydown = 0; char *svcname; if (ldap1 == NULL) return; svcname = strdup(ldaptest->testname); if (ldaptest->namelen) svcname[ldaptest->namelen] = '\0'; /* Check if this service is a NOPAGENET service. */ SBUF_MALLOC(nopagename, strlen(svcname)+3); snprintf(nopagename, nopagename_buflen, ",%s,", svcname); nopage = (strstr(nonetpage, nopagename) != NULL); xfree(nopagename); dbgprintf("Calc ldap color host %s : ", host->hostname); for (t=host->firstldap; (t && (t->host == host)); t = t->next) { ldap_data_t *req = (ldap_data_t *) t->privdata; req->ldapcolor = statuscolor(host, req->ldapstatus); if (req->ldapcolor == COL_RED) anydown++; /* Dialup hosts and dialup tests report red as clear */ if ((req->ldapcolor != COL_GREEN) && (host->dialup || t->dialup)) req->ldapcolor = COL_CLEAR; /* If ping failed, report CLEAR unless alwaystrue */ if ( ((req->ldapcolor == COL_RED) || (req->ldapcolor == COL_YELLOW)) && /* Test failed */ (host->downcount > 0) && /* The ping check did fail */ (!host->noping && !host->noconn) && /* We are doing a ping test */ (failgoesclear) && (!t->alwaystrue) ) /* No "~testname" flag */ { req->ldapcolor = COL_CLEAR; } /* If test we depend on has failed, report CLEAR unless alwaystrue */ if ( ((req->ldapcolor == COL_RED) || (req->ldapcolor == COL_YELLOW)) && /* Test failed */ failgoesclear && !t->alwaystrue ) /* No "~testname" flag */ { char *faileddeps = deptest_failed(host, t->service->testname); if (faileddeps) { req->ldapcolor = COL_CLEAR; req->faileddeps = strdup(faileddeps); } } dbgprintf("%s(%s) ", t->testspec, colorname(req->ldapcolor)); if (req->ldapcolor > color) color = req->ldapcolor; } if (anydown) ldap1->downcount++; else ldap1->downcount = 0; /* Handle the "badtest" stuff for ldap tests */ if ((color == COL_RED) && (ldap1->downcount < ldap1->badtest[2])) { if (ldap1->downcount >= ldap1->badtest[1]) color = COL_YELLOW; else if (ldap1->downcount >= ldap1->badtest[0]) color = COL_CLEAR; else color = COL_GREEN; } if (nopage && (color == COL_RED)) color = COL_YELLOW; dbgprintf(" --> %s\n", colorname(color)); /* Send off the ldap status report */ init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s", validity, commafy(host->hostname), svcname, colorname(color), timestamp); addtostatus(msgline); for (t=host->firstldap; (t && (t->host == host)); t = t->next) { ldap_data_t *req = (ldap_data_t *) t->privdata; snprintf(msgline, sizeof(msgline), "\n&%s %s - %s\n\n", colorname(req->ldapcolor), t->testspec, ((req->ldapcolor != COL_GREEN) ? "failed" : "OK")); addtostatus(msgline); if (req->output) { addtostatus(req->output); addtostatus("\n\n"); } if (req->faileddeps) addtostatus(req->faileddeps); snprintf(msgline, sizeof(msgline), "\nSeconds: %u.%.9ld\n", (unsigned int)req->duration.tv_sec, req->duration.tv_nsec); addtostatus(msgline); } addtostatus("\n"); finish_status(); xfree(svcname); } void show_ldap_test_results(service_t *ldaptest) { ldap_data_t *req; testitem_t *t; for (t = ldaptest->items; (t); t = t->next) { req = (ldap_data_t *) t->privdata; printf("URL : %s\n", t->testspec); printf("Time spent : %u.%.9ld\n", (unsigned int)req->duration.tv_sec, req->duration.tv_nsec); printf("LDAP output:\n%s\n", textornull(req->output)); printf("------------------------------------------------------\n"); } } #ifdef STANDALONE /* These are dummy vars needed by stuff in util.c */ hostlist_t *hosthead = NULL; link_t *linkhead = NULL; link_t null_link = { "", "", "", NULL }; char *deptest_failed(testedhost_t *host, char *testname) { return NULL; } int main(int argc, char *argv[]) { testitem_t item; testedhost_t host; service_t ldapservice; int argi = 1; int ldapdebug = 0; while ((argi < argc) && (strncmp(argv[argi], "--", 2) == 0)) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strncmp(argv[argi], "--ldapdebug=", strlen("--ldapdebug=")) == 0) { char *p = strchr(argv[argi], '='); ldapdebug = atoi(p+1); } argi++; } /* For testing, don't crash in sendmsg when no XYMSRV defined */ dontsendmessages = 1; if (xgetenv("XYMSRV") == NULL) putenv("XYMSRV=127.0.0.1"); memset(&item, 0, sizeof(item)); memset(&host, 0, sizeof(host)); memset(&ldapservice, 0, sizeof(ldapservice)); ldapservice.portnum = 389; ldapservice.testname = "ldap"; ldapservice.namelen = strlen(ldapservice.testname); ldapservice.items = &item; item.host = &host; item.service = &ldapservice; item.dialup = item.reverse = item.silenttest = item.alwaystrue = 0; item.testspec = urlunescape(argv[argi]); host.firstldap = &item; host.hostname = "ldaptest.xymon"; host.ldapuser = NULL; host.ldappasswd = NULL; init_ldap_library(); if (ldapdebug) { #if defined(LBER_OPT_DEBUG_LEVEL) && defined(LDAP_OPT_DEBUG_LEVEL) ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldapdebug); ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldapdebug); #else printf("LDAP library does not support change of debug level\n"); #endif } if (add_ldap_test(&item) == 0) { run_ldap_tests(&ldapservice, 0, 10); combo_start(); send_ldap_results(&ldapservice, &host, "", 0); combo_end(); } shutdown_ldap_library(); return 0; } #endif xymon-4.3.30/xymonnet/contest.h0000664000076400007640000001517513005713337016727 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of a TCP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CONTEST_H_ #define __CONTEST_H_ #include #include #include #include #include #include #ifdef HAVE_OPENSSL /* * OpenSSL defs. We require OpenSSL 0.9.5 or later * as some of the routines we use are not available * in earlier versions. */ #include #include #include #include #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x00905000L) #error SSL-protocol testing requires OpenSSL version 0.9.5 or later #endif #else /* * xymonnet without support for SSL protocols. */ #undef TCP_SSL #define TCP_SSL 0x0000 #define SSL_CTX void #define SSL void #endif #include "libxymon.h" extern char *ssl_library_version; extern char *ciphershigh; extern char *ciphersmedium; extern unsigned int warnbytesread; extern int shuffletests; extern int sslincludecipherlist; extern int sslshowallciphers; extern int snienabled; #define SSLVERSION_DEFAULT 0 #define SSLVERSION_V2 1 #define SSLVERSION_V3 2 #define SSLVERSION_TLS10 3 #define SSLVERSION_TLS11 4 #define SSLVERSION_TLS12 5 typedef struct { char *cipherlist; int sslversion; char *clientcert; } ssloptions_t; typedef int (*f_callback_data)(unsigned char *buffer, unsigned int size, void *privdata); typedef void (*f_callback_final)(void *privdata); #define CONTEST_ENOERROR 0 #define CONTEST_ETIMEOUT 1 #define CONTEST_ENOCONN 2 #define CONTEST_EDNS 3 #define CONTEST_EIO 4 #define CONTEST_ESSL 5 typedef struct tcptest_t { struct sockaddr_in addr; /* Address (IP+port) to test */ char *srcaddr; struct svcinfo_t *svcinfo; /* svcinfo_t for service */ long int randomizer; int fd; /* Socket filedescriptor */ time_t lastactive; time_t cutoff; char *tspec; unsigned int bytesread; unsigned int byteswritten; /* Connection info */ int connres; /* connect() status returned */ int open; /* Result - is it open? */ int errcode; /* Pick up any errors */ struct timespec timestart; /* Starttime of connection attempt */ struct timespec duration; /* Duration of connection attempt */ struct timespec totaltime; /* Duration of the full transfer */ /* Data we send */ unsigned char *sendtxt; unsigned int sendlen; /* For grabbing banners */ int silenttest; /* Banner grabbing can be disabled per test */ int readpending; /* Temp status while reading banner */ unsigned char *banner; /* Banner text from service */ unsigned int bannerbytes; /* Number of bytes in banner */ /* For testing SSL-wrapped services */ ssloptions_t *ssloptions; /* Specific SSL options requested by user */ char *sni; SSL_CTX *sslctx; /* SSL context pointer */ SSL *ssldata; /* SSL data (socket) pointer */ char *certinfo; /* Certificate info (subject+expiretime) */ time_t certexpires; /* Expiretime in time_t format */ char *certsubject; char *certissuer; int certkeysz; int mincipherbits; /* Bits in the weakest encryption supported */ int sslrunning; /* Track state of an SSL session */ int sslagain; /* SSL read/write needs more data */ /* For testing telnet services */ unsigned char *telnetbuf; /* Buffer for telnet option negotiation */ int telnetbuflen; /* Length of telnetbuf - it's binary, so no strlen */ int telnetnegotiate; /* Flag telling if telnet option negotiation is being done */ /* For testing http services */ void *priv; f_callback_data datacallback; f_callback_final finalcallback; struct tcptest_t *next; } tcptest_t; #define CONTENTCHECK_NONE 0 #define CONTENTCHECK_REGEX 1 #define CONTENTCHECK_DIGEST 2 #define CONTENTCHECK_NOREGEX 3 #define CONTENTCHECK_CONTENTTYPE 4 #define HTTPVER_ANY 0 #define HTTPVER_10 1 #define HTTPVER_11 2 #define CHUNK_NOTCHUNKED 0 #define CHUNK_INIT 1 #define CHUNK_GETLEN 2 #define CHUNK_SKIPLENCR 3 #define CHUNK_DATA 4 #define CHUNK_SKIPENDCR 5 #define CHUNK_DONE 6 #define CHUNK_NOMORE 7 typedef struct { tcptest_t *tcptest; char *url; /* URL to request, stripped of configuration artefacts */ int parsestatus; weburl_t weburl; int gotheaders; int contlen; int chunkstate; unsigned int leftinchunk; unsigned char *headers; /* HTTP headers from server */ unsigned int hdrlen; unsigned char *output; /* Data from server */ unsigned int outlen; int httpstatus; /* HTTP status from server */ char *contenttype; /* Content-type: header from server */ int contentcheck; /* 0=no content check, 1=regex check, 2=digest check */ void *exp; /* data for content match (digest, or regexp data) */ digestctx_t *digestctx; /* OpenSSL data for digest handling */ char *digest; /* Digest of the data received from the server */ long contstatus; /* Pseudo HTTP status for content check */ /* Used during status-reporting */ int httpcolor; /* Color of this HTTP test */ char *errorcause; char *faileddeps; /* List of failed dependency checks */ } http_data_t; extern unsigned long tcp_stats_read; extern unsigned long tcp_stats_written; extern unsigned int tcp_stats_total; extern unsigned int tcp_stats_http; extern unsigned int tcp_stats_plain; extern unsigned int tcp_stats_connects; extern char *init_tcp_services(void); extern int default_tcp_port(char *svcname); extern void dump_tcp_services(void); extern tcptest_t *add_tcp_test(char *ip, int port, char *service, ssloptions_t *sslopt, char *srcip, char *tspec, int silent, unsigned char *reqmsg, void *priv, f_callback_data datacallback, f_callback_final finalcallback); extern void do_tcp_tests(int timeout, int concurrency); extern void show_tcp_test_results(void); extern int tcp_got_expected(tcptest_t *test); #endif xymon-4.3.30/xymonnet/protocols.cfg0000664000076400007640000001271613462707351017610 0ustar rpmbuildrpmbuild# protocols.cfg # # $Id: protocols.cfg 8063 2019-05-03 00:44:25Z jccleaver $ # # This file defines the way TCP services are tested by xymonnet # # A service definition looks like this: # [NAME] # send "HELLO" # expect "OK" # options banner,ssl,telnet # port PORTNUMBER # # The NAME is the name of the test, and of the TCP service. If # multiple tests share a common definition (e.g. ssh, ssh1, ssh2) # then these may be given as "[NAME1|NAME2|NAME3]" # # If the send-string is defined, this data is sent to the service # immediately after a connect. # # If the expect-string is defined, any data returned by the service is # matched against this. If it matches, the status will be green; if it # does not match, the status will turn yellow. Only if the service does # not respond at all will the status go red. If a expect-string is not # defined, the status will always be green if it is possible to connect # to the service. # # The options can include "banner" (to grab the banner from the # service), "telnet" (telnet options are to be negotiated), and # "ssl" (perform an SSL/TLS handshake and pick up the SSL certificate). # # The "port" is the TCP port used for this service. This OVERRIDES # any port number listed in /etc/services - but this also means that # you need not define "unusual" port-numbers in /etc/services. # Of course, you can always define your test in hosts.cfg to use a # specific portnumber. # # The send/expect string definitions must be in double quotes. # The sequences "\r", "\n", "\t" and "\xNN" are recognized and # converted into a carriage-return (ASCII 13), line-feed (ASCII 10), # TAB (ASCII 8), and any byte respectively (NN=hex value). [ftp] send "quit\r\n" expect "220" options banner port 21 [ftps] send "quit\r\n" expect "220" options ssl,banner port 990 [ssh|ssh1|ssh2] send "SSH-2.0-OpenSSH_4.1\r\n" expect "SSH" options banner port 22 [telnet] options banner,telnet port 23 [telnets] options ssl,banner,telnet port 992 [smtp] send "ehlo xymonnet\r\nquit\r\n" expect "220" options banner port 25 [smtps] send "ehlo xymonnet\r\nquit\r\n" expect "220" options ssl,banner # No default port-number assignment for smtps - nonstandard according to IANA [submission|msa] send "ehlo xymonnet\r\nquit\r\n" expect "220" options banner port 587 [pop2|pop-2] send "quit\r\n" expect "+OK" options banner port 109 [pop|pop3|pop-3] send "quit\r\n" expect "+OK" options banner port 110 [pop3s] send "quit\r\n" expect "+OK" options ssl,banner port 995 [imap|imap2|imap4] send "ABC123 LOGOUT\r\n" expect "* OK" options banner port 143 [imap3] send "ABC123 LOGOUT\r\n" expect "* OK" options banner port 220 [imaps] send "ABC123 LOGOUT\r\n" expect "* OK" options ssl,banner port 993 [nntp] send "quit\r\n" expect "200" options banner port 119 [nntps] send "quit\r\n" expect "200" options ssl,banner port 563 [ldap] port 389 [ldaps] options ssl port 636 [rsync] expect "@RSYNCD" options banner port 873 [bbd] # send "ping" # expect "xymond" send "dummy" port 1984 # The AV scanning daemon from the ClamAV antivirus package [clamd] send "PING\n" expect "PONG" options banner port 3310 # SpamAssassin spamd [spamd] send "PING SPAMC/Xymon\n" expect "SPAMD" options banner port 783 # From Mark Felder [svn] expect "( success" options banner port 3690 # From http://www.mail-archive.com/whatsup_forum@list.ipswitch.com/msg06678.html [oratns] send "\x00\x57\x00\x00\x01\x00\x00\x00\x01\x36\x01\x2C\x00\x00\x08\x00\x7F\xFF\xA3\x0A\x00\x00\x01\x00\x00\x1D\x00\x3A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00(CONNECT_DATA=(COMMAND=ping))" options banner port 1521 # qmail "Quick Mail Transfer Protocol" [qmtp] port 209 # qmail "Quick Mail Queuing Protocol" [qmqp] port 628 # Advanced Message Queuing Protocol [amqp] send "PING\r\n\r\n" expect "AMQP" options banner # Advanced Message Queuing Protocol over SSL [amqps] send "PING\r\n\r\n\r\n\r\n" expect "AMQP" options ssl,banner # vnc "Virtual Network Computing" - method from bb-vnc.tar.gz # From Richard Finegold [vnc] send "RFB 000.000\r\n" expect "RFB " options banner port 5900 # CUPS print server. It answers to HTTP requests. [cupsd] send "GET /printers\r\n" expect "HTTP/1.1 200 OK" port 631 # AJP (Apache JServ Protocol) 1.3 - sends an AJP "ping" request. # Ref: http://tomcat.apache.org/connectors-doc/common/ajpv13a.html # From Charles Goyard [ajp13] send "\x12\x34\x00\x01\x0a" expect "\x41\x42\x00\x01\x09" port 8009 # Microsoft Terminal Services / Remote Desktop Protocol # Originally From Chris Wopat (http://www.xymon.com/archive/2010/01/msg00039.html) # Updated By Rob Steuer for current versions of RDP [rdp] port 3389 send "\x03\x00\x00\x13\x0e\xe0\x00\x00\x00\x00\x00\x01\x00\x08\x00\x0b\x00\x00\x00" expect "\x03\x00\x00\x13\x0e\xd0\x00\x00\x12\x34" # NETBIOS Session Service for NT Authentication [netbios-ssn] port 139 # Simple Network Paging Protocol (SNPP) [snpp] send "quit\r\n" expect "220" options banner port 444 # Internet Relay Chat [ircd] send "NICK xymonnet\r\nUSER xymond 0 * :Xymonnet\r\nTIME\r\nVERSION\r\nQUIT\r\n" options banner port 6667 # de facto ircd port is 6667 # line printer spooler (lpd) [lpd] port 515 xymon-4.3.30/xymonnet/dns2.c0000664000076400007640000003644513515623702016116 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: dns2.c 8069 2019-07-23 15:29:06Z jccleaver $"; /* * All of the code for parsing DNS responses and formatting these into * text were taken from the "adig.c" source-file included with the * C-ARES 1.2.0 library. This file carries the following copyright * notice, reproduced in full: * * -------------------------------------------------------------------- * Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. * -------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include #include #include #include "dns2.h" /* Some systems (AIX, HP-UX) don't know the DNS T_SRV record */ #ifndef T_SRV #define T_SRV 33 #endif static char msg[1024]; static const unsigned char *display_question(const unsigned char *aptr, const unsigned char *abuf, int alen, dns_resp_t *response); static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen, dns_resp_t *response); static const char *type_name(int type); static const char *class_name(int dnsclass); struct nv { const char *name; int value; }; static const struct nv flags[] = { { "usevc", ARES_FLAG_USEVC }, { "primary", ARES_FLAG_PRIMARY }, { "igntc", ARES_FLAG_IGNTC }, { "norecurse", ARES_FLAG_NORECURSE }, { "stayopen", ARES_FLAG_STAYOPEN }, { "noaliases", ARES_FLAG_NOALIASES } }; static const int nflags = sizeof(flags) / sizeof(flags[0]); static const struct nv classes[] = { { "IN", C_IN }, { "CHAOS", C_CHAOS }, { "HS", C_HS }, { "ANY", C_ANY } }; static const int nclasses = sizeof(classes) / sizeof(classes[0]); static const struct nv types[] = { { "A", T_A }, { "NS", T_NS }, { "MD", T_MD }, { "MF", T_MF }, { "CNAME", T_CNAME }, { "SOA", T_SOA }, { "MB", T_MB }, { "MG", T_MG }, { "MR", T_MR }, { "NULL", T_NULL }, { "WKS", T_WKS }, { "PTR", T_PTR }, { "HINFO", T_HINFO }, { "MINFO", T_MINFO }, { "MX", T_MX }, { "TXT", T_TXT }, { "RP", T_RP }, { "AFSDB", T_AFSDB }, { "X25", T_X25 }, { "ISDN", T_ISDN }, { "RT", T_RT }, { "NSAP", T_NSAP }, { "NSAP_PTR", T_NSAP_PTR }, { "SIG", T_SIG }, { "KEY", T_KEY }, { "PX", T_PX }, { "GPOS", T_GPOS }, { "AAAA", T_AAAA }, { "LOC", T_LOC }, { "SRV", T_SRV }, { "AXFR", T_AXFR }, { "MAILB", T_MAILB }, { "MAILA", T_MAILA }, { "ANY", T_ANY } }; static const int ntypes = sizeof(types) / sizeof(types[0]); static const char *opcodes[] = { "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA", "ZONEINIT", "ZONEREF" }; static const char *rcodes[] = { "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE" }; void dns_detail_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { int id, qr, opcode, aa, tc, rd, ra, rcode; unsigned int qdcount, ancount, nscount, arcount, i; const unsigned char *aptr; dns_resp_t *response = (dns_resp_t *) arg; clearstrbuffer(response->msgbuf); response->msgstatus = status; /* * Display an error message if there was an error, but only stop if * we actually didn't get an answer buffer. */ switch (status) { case ARES_SUCCESS: break; case ARES_ENODATA: addtobuffer(response->msgbuf, "No data returned from server\n"); if (!abuf) return; break; case ARES_EFORMERR: addtobuffer(response->msgbuf, "Server could not understand query\n"); if (!abuf) return; break; case ARES_ESERVFAIL: addtobuffer(response->msgbuf, "Server failed\n"); if (!abuf) return; break; case ARES_ENOTFOUND: addtobuffer(response->msgbuf, "Name not found\n"); if (!abuf) return; break; case ARES_ENOTIMP: addtobuffer(response->msgbuf, "Not implemented\n"); if (!abuf) return; break; case ARES_EREFUSED: addtobuffer(response->msgbuf, "Server refused query\n"); if (!abuf) return; break; case ARES_EBADNAME: addtobuffer(response->msgbuf, "Invalid name in query\n"); if (!abuf) return; break; case ARES_ETIMEOUT: addtobuffer(response->msgbuf, "Timeout\n"); if (!abuf) return; break; case ARES_ECONNREFUSED: addtobuffer(response->msgbuf, "Server unavailable\n"); if (!abuf) return; break; case ARES_ENOMEM: addtobuffer(response->msgbuf, "Out of memory\n"); if (!abuf) return; break; case ARES_EDESTRUCTION: addtobuffer(response->msgbuf, "Timeout (channel destroyed)\n"); if (!abuf) return; break; default: addtobuffer(response->msgbuf, "Undocumented ARES return code\n"); if (!abuf) return; break; } /* Won't happen, but check anyway, for safety. */ if (alen < HFIXEDSZ) return; /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); qr = DNS_HEADER_QR(abuf); opcode = DNS_HEADER_OPCODE(abuf); aa = DNS_HEADER_AA(abuf); tc = DNS_HEADER_TC(abuf); rd = DNS_HEADER_RD(abuf); ra = DNS_HEADER_RA(abuf); rcode = DNS_HEADER_RCODE(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); /* Display the answer header. */ snprintf(msg, sizeof(msg), "id: %d\n", id); addtobuffer(response->msgbuf, msg); snprintf(msg, sizeof(msg), "flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); addtobuffer(response->msgbuf, msg); snprintf(msg, sizeof(msg), "opcode: %s\n", opcodes[opcode]); addtobuffer(response->msgbuf, msg); snprintf(msg, sizeof(msg), "rcode: %s\n", rcodes[rcode]); addtobuffer(response->msgbuf, msg); /* Display the questions. */ addtobuffer(response->msgbuf, "Questions:\n"); aptr = abuf + HFIXEDSZ; for (i = 0; i < qdcount; i++) { aptr = display_question(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the answers. */ addtobuffer(response->msgbuf, "Answers:\n"); for (i = 0; i < ancount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the NS records. */ addtobuffer(response->msgbuf, "NS records:\n"); for (i = 0; i < nscount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the additional records. */ addtobuffer(response->msgbuf, "Additional records:\n"); for (i = 0; i < arcount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } return; } static const unsigned char *display_question(const unsigned char *aptr, const unsigned char *abuf, int alen, dns_resp_t *response) { char *name; int type, dnsclass, status; long len; /* Parse the question name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; aptr += len; /* Make sure there's enough data after the name for the fixed part * of the question. */ if (aptr + QFIXEDSZ > abuf + alen) { xfree(name); return NULL; } /* Parse the question type and class. */ type = DNS_QUESTION_TYPE(aptr); dnsclass = DNS_QUESTION_CLASS(aptr); aptr += QFIXEDSZ; /* * Display the question, in a format sort of similar to how we will * display RRs. */ snprintf(msg, sizeof(msg), "\t%-15s.\t", name); addtobuffer(response->msgbuf, msg); if (dnsclass != C_IN) { snprintf(msg, sizeof(msg), "\t%s", class_name(dnsclass)); addtobuffer(response->msgbuf, msg); } snprintf(msg, sizeof(msg), "\t%s\n", type_name(type)); addtobuffer(response->msgbuf, msg); xfree(name); return aptr; } static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen, dns_resp_t *response) { const unsigned char *p; char *name; int type, dnsclass, ttl, dlen, status; long len; struct in_addr addr; struct in6_addr addr6; /* Parse the RR name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; aptr += len; /* Make sure there is enough data after the RR name for the fixed * part of the RR. */ if (aptr + RRFIXEDSZ > abuf + alen) { xfree(name); return NULL; } /* Parse the fixed part of the RR, and advance to the RR data field. */ type = DNS_RR_TYPE(aptr); dnsclass = DNS_RR_CLASS(aptr); ttl = DNS_RR_TTL(aptr); dlen = DNS_RR_LEN(aptr); aptr += RRFIXEDSZ; if (aptr + dlen > abuf + alen) { xfree(name); return NULL; } /* Display the RR name, class, and type. */ snprintf(msg, sizeof(msg), "\t%-15s.\t%d", name, ttl); addtobuffer(response->msgbuf, msg); if (dnsclass != C_IN) { snprintf(msg, sizeof(msg), "\t%s", class_name(dnsclass)); addtobuffer(response->msgbuf, msg); } snprintf(msg, sizeof(msg), "\t%s", type_name(type)); addtobuffer(response->msgbuf, msg); xfree(name); /* Display the RR data. Don't touch aptr. */ switch (type) { case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_NS: case T_PTR: /* For these types, the RR data is just a domain name. */ status = ares_expand_name(aptr, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.", name); addtobuffer(response->msgbuf, msg); xfree(name); break; case T_HINFO: /* The RR data is two length-counted character strings. */ p = aptr; len = *p; if (p + len + 1 > aptr + dlen) return NULL; snprintf(msg, sizeof(msg), "\t%.*s", (int) len, p + 1); addtobuffer(response->msgbuf, msg); p += len + 1; len = *p; if (p + len + 1 > aptr + dlen) return NULL; snprintf(msg, sizeof(msg), "\t%.*s", (int) len, p + 1); addtobuffer(response->msgbuf, msg); break; case T_MINFO: /* The RR data is two domain names. */ p = aptr; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.", name); addtobuffer(response->msgbuf, msg); xfree(name); p += len; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.", name); addtobuffer(response->msgbuf, msg); xfree(name); break; case T_MX: /* The RR data is two bytes giving a preference ordering, and then a domain name. */ if (dlen < 2) return NULL; snprintf(msg, sizeof(msg), "\t%d", (aptr[0] << 8) | aptr[1]); addtobuffer(response->msgbuf, msg); status = ares_expand_name(aptr + 2, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.", name); addtobuffer(response->msgbuf, msg); xfree(name); break; case T_SOA: /* * The RR data is two domain names and then five four-byte * numbers giving the serial number and some timeouts. */ p = aptr; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.\n", name); addtobuffer(response->msgbuf, msg); xfree(name); p += len; status = ares_expand_name(p, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t\t\t\t\t\t%s.\n", name); addtobuffer(response->msgbuf, msg); xfree(name); p += len; if (p + 20 > aptr + dlen) return NULL; snprintf(msg, sizeof(msg), "\t\t\t\t\t\t( %d %d %d %d %d )", (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3], (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7], (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11], (p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15], (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]); addtobuffer(response->msgbuf, msg); break; case T_TXT: /* The RR data is one or more length-counted character strings. */ p = aptr; while (p < aptr + dlen) { len = *p; if (p + len + 1 > aptr + dlen) return NULL; snprintf(msg, sizeof(msg), "\t%.*s", (int)len, p + 1); addtobuffer(response->msgbuf, msg); p += len + 1; } break; case T_A: /* The RR data is a four-byte Internet address. */ if (dlen != 4) return NULL; memcpy(&addr, aptr, sizeof(struct in_addr)); snprintf(msg, sizeof(msg), "\t%s", inet_ntoa(addr)); addtobuffer(response->msgbuf, msg); break; case T_AAAA: /* The RR data is a 16-byte IPv6 address. */ if (dlen != 16) return NULL; memcpy(&addr6, aptr, sizeof(struct in6_addr)); addtobuffer_many(response->msgbuf, "\t", inet_ntop(AF_INET6,&addr6,msg,sizeof(msg)), NULL); break; case T_WKS: /* Not implemented yet */ break; case T_SRV: /* * The RR data is three two-byte numbers representing the * priority, weight, and port, followed by a domain name. */ snprintf(msg, sizeof(msg), "\t%d", DNS__16BIT(aptr)); addtobuffer(response->msgbuf, msg); snprintf(msg, sizeof(msg), " %d", DNS__16BIT(aptr + 2)); addtobuffer(response->msgbuf, msg); snprintf(msg, sizeof(msg), " %d", DNS__16BIT(aptr + 4)); addtobuffer(response->msgbuf, msg); status = ares_expand_name(aptr + 6, abuf, alen, &name, &len); if (status != ARES_SUCCESS) return NULL; snprintf(msg, sizeof(msg), "\t%s.", name); addtobuffer(response->msgbuf, msg); xfree(name); break; default: snprintf(msg, sizeof(msg), "\t[Unknown RR; cannot parse]"); addtobuffer(response->msgbuf, msg); } snprintf(msg, sizeof(msg), "\n"); addtobuffer(response->msgbuf, msg); return aptr + dlen; } static const char *type_name(int type) { int i; for (i = 0; i < ntypes; i++) { if (types[i].value == type) return types[i].name; } return "(unknown)"; } static const char *class_name(int dnsclass) { int i; for (i = 0; i < nclasses; i++) { if (classes[i].value == dnsclass) return classes[i].name; } return "(unknown)"; } int dns_name_type(char *name) { int i; for (i = 0; i < ntypes; i++) { if (strcasecmp(types[i].name, name) == 0) return types[i].value; } return T_A; } xymon-4.3.30/xymonnet/dns.h0000664000076400007640000000275512603243142016027 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DNS_H__ #define __DNS_H__ #include /* dnslookup values */ #define DNS_THEN_IP 0 /* Try DNS - if it fails, use IP from hosts.cfg */ #define DNS_ONLY 1 /* DNS only - if it fails, report service down */ #define IP_ONLY 2 /* IP only - don't do DNS lookups */ extern int use_ares_lookup; extern int max_dns_per_run; extern int dnstimeout; extern int dns_stats_total; extern int dns_stats_success; extern int dns_stats_failed; extern int dns_stats_lookups; extern FILE *dnsfaillog; extern void add_host_to_dns_queue(char *hostname); extern void add_url_to_dns_queue(char *hostname); extern void flush_dnsqueue(void); extern char *dnsresolve(char *hostname); extern int dns_test_server(char *serverip, char *hostname, strbuffer_t *banner); #endif xymon-4.3.30/xymonnet/xymonping.c0000664000076400007640000003476513463114301017273 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is an implementation of a fast "ping" program, for use with Xymon. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonping.c 8064 2019-05-03 19:38:41Z jccleaver $"; #include "config.h" #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #define PING_PACKET_SIZE 64 #define PING_MINIMUM_SIZE ICMP_MINLEN #define SENDLIMIT 100 typedef struct hostdata_t { int id; struct sockaddr_in addr; /* Address of host to ping */ int received; /* how many ICMP_ECHO replies we've got */ struct timespec rtt_total; struct hostdata_t *next; } hostdata_t; hostdata_t *hosthead = NULL; int hostcount = 0; hostdata_t **hosts = NULL; /* Array of pointers to the hostdata records, for fast access via ID */ int myicmpid; int senddelay = (1000000 / 50); /* Delay between sending packets, in microseconds */ /* This routine more or less taken from the "fping" source. Apparently by W. Stevens (public domain) */ int calc_icmp_checksum(unsigned short *pkt, int pktlen) { unsigned short result; long sum = 0; unsigned short extrabyte = 0; while (pktlen > 1) { sum += *pkt++; pktlen -= 2; } if (pktlen == 1) { *(unsigned char *)(&extrabyte) = *(unsigned char *)pkt; sum += extrabyte; } sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */ sum += ( sum >> 16 ); /* add carry */ result = ~sum; /* ones-complement, truncate*/ return result; } char *nextip(int argc, char *argv[], FILE *fd) { static int argi = 0; static int cmdmode = 0; static char buf[4096]; if (argi == 0) { /* Check if there are any command-line IP's */ struct sockaddr_in ina; for (argi=1; ((argi < argc) && (inet_aton(argv[argi], &ina.sin_addr) == 0)); argi++) ; cmdmode = (argi < argc); } if (cmdmode) { /* Skip any options in-between the IP's */ while ((argi < argc) && (*(argv[argi]) == '-')) argi++; if (argi < argc) { argi++; return argv[argi-1]; } } else { if (fgets(buf, sizeof(buf), fd)) { char *p; p = strchr(buf, '\n'); if (p) *p = '\0'; return buf; } } return NULL; } void load_ips(int argc, char *argv[], FILE *fd) { char *l; hostdata_t *tail = NULL; hostdata_t *walk; int i; while ((l = nextip(argc, argv, fd)) != NULL) { hostdata_t *newitem; if (strlen(l) == 0) continue; newitem = (hostdata_t *)calloc(1, sizeof(hostdata_t)); newitem->addr.sin_family = AF_INET; newitem->addr.sin_port = 0; if (inet_aton(l, &newitem->addr.sin_addr) == 0) { errprintf("Dropping %s - not an IP\n", l); free(newitem); continue; } if (tail) { tail->next = newitem; } else { hosthead = newitem; } hostcount++; tail = newitem; } /* Setup the table of hostdata records */ hosts = (hostdata_t **)malloc((hostcount+1) * sizeof(hostdata_t *)); for (i=0, walk=hosthead; (walk); walk=walk->next, i++) hosts[i] = walk; hosts[hostcount] = NULL; } /* This is the data we send with each ping packet */ typedef struct pingdata_t { int id; /* ID for the host this belongs to */ struct timespec timesent; /* time we sent this ping */ } pingdata_t; int send_ping(int sock, int startidx, int minresponses) { static unsigned char buffer[PING_PACKET_SIZE]; struct icmp *icmphdr; struct pingdata_t *pingdata; int sentbytes; int idx = startidx; /* * Sends one ICMP "echo-request" packet. * * Note: A first attempt at this kept sending packets until * we got an EWOULDBLOCK or a send error. This causes incoming * responses to be dropped. */ /* Skip the hosts that have already delivered a ping response */ while ((idx < hostcount) && (hosts[idx]->received >= minresponses)) idx++; if (idx >= hostcount) return hostcount; /* * Don't flood the net. * By enforcing a brief sleep here, we force a delay * between sending packets. It is easiest to do before sending * a packet, because if done after the send completes, then * it affects the RTT measurements. */ if (senddelay) usleep(senddelay); /* Build the packet and send it */ memset(buffer, 0, PING_PACKET_SIZE); icmphdr = (struct icmp *)buffer; icmphdr->icmp_type = ICMP_ECHO; icmphdr->icmp_code = 0; icmphdr->icmp_cksum = 0; icmphdr->icmp_seq = htons(idx+1); /* So we can map response to our hosts */ icmphdr->icmp_id = htons(myicmpid); pingdata = (struct pingdata_t *)(buffer + sizeof(struct icmp)); pingdata->id = idx; getntimer(&pingdata->timesent); icmphdr->icmp_cksum = calc_icmp_checksum((unsigned short *)buffer, PING_PACKET_SIZE); sentbytes = sendto(sock, buffer, PING_PACKET_SIZE, 0, (struct sockaddr *) &hosts[idx]->addr, sizeof(struct sockaddr_in)); if (sentbytes == -1) { if (errno != EWOULDBLOCK) { errprintf("Failed to send ICMP packet: %s\n", strerror(errno)); idx++; /* To avoid looping indefinitely trying to send to this host */ } } else if (sentbytes == PING_PACKET_SIZE) { /* We managed to send a ping! */ if (debug) { dbgprintf("Sent a ping to %s: index=%d, id=%d\n", inet_ntoa(hosts[idx]->addr.sin_addr), idx, myicmpid); } idx++; } return idx; } int get_response(int sock) { static unsigned char buffer[4096]; struct sockaddr_in addr; int n, pktcount; unsigned int addrlen; struct ip *iphdr; int iphdrlen; struct icmp *icmphdr; struct pingdata_t *pingdata; int hostidx; struct timespec rtt; /* * Read responses from the network. * We know (because select() told us) that there is some data * to read. To avoid losing packets, read as much as we can. */ pktcount = 0; do { addrlen = sizeof(addr); n = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &addrlen); if (n < 0) { if (errno != EWOULDBLOCK) errprintf("Failed to receive packet: %s\n", strerror(errno)); continue; } getntimer(&rtt); /* Check the IP header - we need to have at least enough bytes for an ICMP header. */ iphdr = (struct ip *)buffer; iphdrlen = (iphdr->ip_hl << 2); /* IP header always aligned on 4-byte boundary */ if (n < (iphdrlen + PING_MINIMUM_SIZE)) { errprintf("Short packet ignored\n"); continue; } /* * Get the ICMP header, and our host index which is the sequence number. * Thanks to "fping" for this neat way of matching requests and responses. */ icmphdr = (struct icmp *)(buffer + iphdrlen); hostidx = ntohs(icmphdr->icmp_seq)-1; if (debug) { dbgprintf("Got packet from %s: type=%d, index=%d, id=%d\n", inet_ntoa(addr.sin_addr), icmphdr->icmp_type, icmphdr->icmp_id, hostidx); } switch (icmphdr->icmp_type) { case ICMP_ECHOREPLY: if (ntohs(icmphdr->icmp_id) != myicmpid) { /* Not one of our packets. Happens if someone else does ping simultaneously. */ break; } if ((hostidx >= 0) && (hostidx < hostcount)) { /* Looks like one of our packets succeeded. */ pktcount++; hosts[hostidx]->received += 1; pingdata = (struct pingdata_t *)(buffer + iphdrlen + sizeof(struct icmp)); /* Calculate the round-trip time. */ rtt.tv_sec -= pingdata->timesent.tv_sec; rtt.tv_nsec -= pingdata->timesent.tv_nsec; if (rtt.tv_nsec < 0) { rtt.tv_sec--; rtt.tv_nsec += 1000000000; } /* Add RTT to the total time */ hosts[hostidx]->rtt_total.tv_sec += rtt.tv_sec; hosts[hostidx]->rtt_total.tv_nsec += rtt.tv_nsec; if (hosts[hostidx]->rtt_total.tv_nsec >= 1000000000) { hosts[hostidx]->rtt_total.tv_sec++; hosts[hostidx]->rtt_total.tv_nsec -= 1000000000; } } break; case ICMP_ECHO: /* Sometimes, we see our own packets going out (if we ping ourselves) */ break; case ICMP_UNREACH: /* We simply ignore these. Hosts get retried until we succeed, then reported as down. */ break; case ICMP_REDIRECT: /* Ignored - the IP stack handles this. */ break; default: /* Shouldn't happen */ errprintf("Got a packet that wasn't a reply - type %d\n", icmphdr->icmp_type); break; } } while (n > 0); return pktcount; } int count_pending(int minresponses) { int result = 0; int idx; /* Counts how many hosts we haven't seen a reply from yet. */ for (idx = 0; (idx < hostcount); idx++) if (hosts[idx]->received < minresponses) result++; return result; } void show_results(void) { int idx; unsigned long rtt_usecs; /* Big enough for 2147 seconds - larger than we will ever see */ /* * Print out the results. Format is identical to "fping -Ae" so we can use * it directly in Xymon without changing the xymonnet code. */ for (idx = 0; (idx < hostcount); idx++) { if (hosts[idx]->received > 0) { printf("%s is alive", inet_ntoa(hosts[idx]->addr.sin_addr)); rtt_usecs = (hosts[idx]->rtt_total.tv_sec*1000000 + (hosts[idx]->rtt_total.tv_nsec / 1000)) / hosts[idx]->received; if (rtt_usecs >= 3000) { printf(" (%.1f ms)\n", rtt_usecs / 1000.0); } else { printf(" (%lu usec)\n", rtt_usecs); } } else { printf("%s is unreachable\n", inet_ntoa(hosts[idx]->addr.sin_addr)); } } } int main(int argc, char *argv[]) { struct protoent *proto; int protonumber, pingsocket = -1, sockerr = 0, binderr = 0; int argi, sendidx, pending, minresponses = 1, tries = 3, timeout = 5; char *srcip = NULL; struct sockaddr_in src_addr; /* Immediately drop all root privileges. */ drop_root(); for (argi = 1; (argi < argc); argi++) { if (strncmp(argv[argi], "--retries=", 10) == 0) { char *delim = strchr(argv[argi], '='); tries = 1 + atoi(delim+1); } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { char *delim = strchr(argv[argi], '='); timeout = atoi(delim+1); } else if (strncmp(argv[argi], "--responses=", 11) == 0) { char *delim = strchr(argv[argi], '='); minresponses = atoi(delim+1); } else if (strncmp(argv[argi], "--source=", 9) == 0) { char *delim = strchr(argv[argi], '='); srcip = strdup(delim+1); } else if (strncmp(argv[argi], "--max-pps=", 10) == 0) { char *delim = strchr(argv[argi], '='); senddelay = (1000000 / atoi(delim+1)); } else if (strncmp(argv[argi], "--debug", 7) == 0) { char *delim = strchr(argv[argi], '='); debug = 1; if (delim) set_debugfile(delim+1, 0); } else if (strcmp(argv[argi], "--help") == 0) { if (pingsocket >= 0) close(pingsocket); fprintf(stderr, "%s [--retries=N] [--timeout=N] [--responses=N] [--max-pps=N] [--source=IP]\n", argv[0]); return 0; } /* fping compatibility options */ else if (strncmp(argv[argi], "-i", 2) == 0) { char *val = argv[argi] + 2; if (isdigit((int) *val)) senddelay = atoi(val); } else if (strncmp(argv[argi], "-r", 2) == 0) { char *val = argv[argi] + 2; if (isdigit((int) *val)) tries = atoi(val); } else if (strncmp(argv[argi], "-S", 2) == 0) { char *val = argv[argi] + 2; srcip = strdup(val); } else if (*(argv[argi]) == '-') { /* Ignore everything else - for fping compatibility */ } } proto = getprotobyname("icmp"); protonumber = (proto ? proto->p_proto : 1); if (srcip != NULL) { /* Setup the source address */ src_addr.sin_family = AF_INET; src_addr.sin_addr.s_addr = inet_addr(srcip); src_addr.sin_port = htons(0); } /* Get a raw socket. Requires root privs. */ get_root(); pingsocket = socket(AF_INET, SOCK_RAW, protonumber); sockerr = errno; if ((pingsocket != -1) && (srcip != NULL)) { /* Bind to a specific source address */ if (bind(pingsocket, (struct sockaddr *) &src_addr, sizeof(src_addr)) == -1) binderr = errno; } drop_root(); if (pingsocket == -1) { errprintf("Cannot get RAW socket: %s\n", strerror(sockerr)); if (sockerr == EPERM) errprintf("This program must be installed suid-root\n"); return 3; } if ((srcip != NULL) && (binderr != 0)) { errprintf("Cannot bind to source address %s: %s\nUsing default address\n", srcip, strerror(binderr)); } /* Set the socket non-blocking - we use select() exclusively */ fcntl(pingsocket, F_SETFL, O_NONBLOCK); load_ips(argc, argv, stdin); pending = count_pending(minresponses); while (tries) { int sendnow = SENDLIMIT; time_t cutoff = getcurrenttime(NULL) + timeout + 1; sendidx = 0; /* Change this on each iteration, so we don't mix packets from each round of pings */ myicmpid = ((getpid()+tries) & 0x7FFF); /* Do one loop over the hosts we havent had responses from yet. */ while (pending > 0) { fd_set readfds, writefds; struct timeval selecttmo; int n; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_SET(pingsocket, &readfds); if (sendnow && (sendidx < hostcount)) FD_SET(pingsocket, &writefds); selecttmo.tv_sec = 0; selecttmo.tv_usec = 100000; n = select(pingsocket+1, &readfds, &writefds, NULL, &selecttmo); if (n < 0) { if (errno == EINTR) continue; errprintf("select failed: %s\n", strerror(errno)); return 4; } else if (n == 0) { /* Time out */ sendnow = SENDLIMIT; } else { if (sendnow && FD_ISSET(pingsocket, &writefds)) { /* OK to send */ sendidx = send_ping(pingsocket, sendidx, minresponses); sendnow--; /* Adjust the cutoff time, so we wait TIMEOUT seconds for a response */ cutoff = getcurrenttime(NULL) + timeout + 1; } if (FD_ISSET(pingsocket, &readfds)) { /* Grab the replies */ int count = get_response(pingsocket); pending -= count; sendnow += count; if (sendnow > SENDLIMIT) sendnow = SENDLIMIT; } } /* See if we have hit the timeout */ if ((getcurrenttime(NULL) >= cutoff) && (sendidx >= hostcount)) { pending = 0; } } tries--; pending = count_pending(minresponses); if (pending == 0) { /* Have got responses for all hosts - we're done */ tries = 0; } } close(pingsocket); show_results(); return 0; } xymon-4.3.30/xymonnet/httpresult.h0000664000076400007640000000253112174246412017457 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of a HTTP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HTTPRESULT_H_ #define __HTTPRESULT_H_ #include #include #include extern void show_http_test_results(service_t *httptest); extern void send_http_results(service_t *httptest, testedhost_t *host, testitem_t *firsttest, char *nonetpage, int failgoesclear, int usebackfeedqueue); extern void send_content_results(service_t *httptest, testedhost_t *host, char *nonetpage, char *contenttestname, int failgoesclear); #endif xymon-4.3.30/xymonnet/xymonnet.10000664000076400007640000005700713534041732017042 0ustar rpmbuildrpmbuild.TH XYMONNET 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonnet \- Xymon network test tool .SH SYNOPSIS .B "xymonnet [\-\-ping|\-\-noping] [\-\-timeout=N] [options] [hostname] [hostname] .br (See the OPTIONS section for a description of the available command-line options). .SH DESCRIPTION .I xymonnet(1) handles the network tests of hosts defined in the Xymon configuration file, hosts.cfg. It is normally run at regular intervals by .I xymonlaunch(8) via an entry in the .I tasks.cfg(5) file. xymonnet does all of the normal tests of TCP-based network services (telnet, ftp, ssh, smtp, pop, imap ....) - i.e. all of the services listed in protocols.cfg. For these tests, a completely new and very speedy service- checker has been implemented. xymonnet has built-in support for testing SSL-enabled protocols, e.g. imaps, pop3s, nntps, telnets, if SSL-support was enabled when configuring xymonnet. The full list of known tests is found in the .I protocols.cfg(5) file in $XYMONHOME/etc/protocols.cfg. In addition, it implements the "dns" and "dig" tests for testing DNS servers. xymonnet also implements a check for NTP servers - this test is called "ntp". If you want to use it, you must define the NTPDATE environment variable to point at the location of your .I ntpdate(1) program. Note: xymonnet performs the connectivity test (ping) based on the hostname, unless the host is tagged with "testip" or the "\-\-dns=ip" option is used. So the target of the connectivity test can be determined by your /etc/hosts file or DNS. By default, all servers are tested - if XYMONNETWORK is set via .I xymonserver.cfg(5) then only the hosts marked as belonging to this network are tested. If the command-line includes one or more hostnames, then only those servers are tested. .SH GENERAL OPTIONS .IP \-\-timeout=N Determines the timeout (in seconds) for each service that is tested. For TCP tests (those from XYMONNETSVCS), if the connection to the service does not succeed within N seconds, the service is reported as being down. For HTTP tests, this is the absolute limit for the entire request to the webserver (the time needed to connect to the server, plus the time it takes the server to respond to the request). Default: 10 seconds .IP \-\-conntimeout=N This option is deprecated, and will be ignored. Use the \-\-timeout option instead. .IP \-\-cmdtimeout=N This option sets a timeout for the external commands used for testing of NTP and RPC services, and to perform traceroute. .IP \-\-concurrency=N Determines the number of network tests that run in parallel. Default is operating system dependent, but will usually be 256. If xymonnet begins to complain about not being able to get a "socket", try running xymonnet with a lower value like 50 or 100. .IP "\-\-dns\-timeout=N (default: 30 seconds)" xymonnet will timeout all DNS lookups after N seconds. Any pending DNS lookups are regarded as failed, i.e. the network tests that depend on this DNS lookup will report an error. .br Note: If you use the \-\-no\-ares option, timeout of DNS lookups cannot be controlled by xymonnet. .IP \-\-dns\-max\-all=N Same as "\-\-dns\-timeout=N". The "\-\-dns\-max\-all" option is deprecated and should not be used. .IP \-\-dns=[ip|only|standard] Determines how xymonnet finds the IP addresses of the hosts to test. By default (the "standard"), xymonnet does a DNS lookup of the hostname to determine the IP address, unless the host has the "testip" tag, or the DNS lookup fails. .br With "\-\-dns=only" xymonnet will ONLY do the DNS lookup; if it fails, then all services on that host will be reported as being down. .br With "\-\-dns=ip" xymonnet will never do a DNS lookup; it will use the IP adresse specified in hosts.cfg for the tests. Thus, this setting is equivalent to having the "testip" tag on all hosts. Note that http tests will ignore this setting and still perform a DNS lookup for the hostname given in the URL; see the "xymonnet tags for HTTP tests" section in .I hosts.cfg(5) .IP \-\-no\-ares Disable the ARES resolver built into xymonnet. This makes xymonnet resolve hostnames using your system resolver function. You should only use this as a last resort if xymonnet cannot resolve the hostnames you use in the normal way (via DNS or /etc/hosts). One reason for using this would be if you need to resolve hostnames via NIS/NIS+ (a.k.a. Yellow Pages). .br The system resolver function does not provide a mechanism for controlling timeouts of the hostname lookups, so if your DNS or NIS server is down, xymonnet can take a very long time to run. The \-\-dns\-timeout option is effectively disabled when using this option. .IP \-\-dnslog=FILENAME Log failed hostname lookups to the file FILENAME. FILENAME should be a full pathname. .IP \-\-report[=COLUMNNAME] With this option, xymonnet will send a status message with details of how many hosts were processed, how many tests were generated, any errors that occurred during the run, and some timing statistics. The default columnname is "xymonnet". .IP \-\-test\-untagged When using the XYMONNETWORK environment variable to test only hosts on a particular network segment, xymonnet will ignore hosts that do not have any "NET:x" tag. So only hosts that have a NET:$XYMONNETWORK tag will be tested. .br With this option, hosts with no NET: tag are included in the test, so that all hosts that either have a matching NET: tag, or no NET: tag at all are tested. .IP \-\-frequenttestlimit=N Used with the .I xymonnet\-again.sh(1) Xymon extension. This option determines how long failed tests remain in the frequent-test queue. The default is 1800 seconds (30 minutes). .IP \-\-timelimit=N Causes xymonnet to generate a warning if the run-time of xymonnet exceeds N seconds. By default N is set to the value of TASKSLEEP, so a warning triggers if the network tests cannot complete in the time given for one cycle of the xymonnet task. Apart from the warning, this option has no effect, i.e. it will not terminate xymonnet prematurely. So to eliminate any such warnings, use this option with a very high value of N. .IP \-\-huge=N Warn if the response from a TCP test is more than N bytes. If you see from the xymonnet status report that you are transferring large amounts of data for your tests, you can enable this option to see which tests have large replies. .br Default: 0 (disabled). .IP \-\-validity=N Make the test results valid for N minutes before they go purple. By default test results are valid for 30 minutes; if you run xymonnet less often than that, the results will go purple before the next run of xymonnet. This option lets you change how long the status is valid. .IP \-\-source\-ip=IPADDRESS On multi-homed hosts, this option can be used to explicitly select the source IP address used for the network tests. "IPADDRESS" must be a valid IP-address on the host running xymonnet. .IP \-\-loadhostsfromxymond Instead of reading the hosts.cfg file, xymonnet will load the hosts.cfg configuration from the xymond daemon. This eliminates the need for reading the hosts.cfg, and if you have xymond and xymonnet running on different hosts, it also eliminates the need for copying the hosts.cfg file between systems. Note that the "netinclude" option in hosts.cfg is ignored when this option is enabled. .SH OPTIONS FOR TESTS OF THE SIMPLE TCP SERVICES .IP \-\-checkresponse[=COLOR] When testing well-known services (e.g. FTP, SSH, SMTP, POP-2, POP-3, IMAP, NNTP and rsync), xymonnet will look for a valid service-specific "OK" response. If another response is seen, this will cause the test to report a warning (yellow) status. Without this option, the response from the service is ignored. .br The optional color-name is used to select a color other than yellow for the status message when the response is wrong. E.g. "\-\-checkresponse=red" will cause a "red" status message to be sent when the service does not respond as expected. .IP \-\-no\-flags By default, xymonnet sends some extra information in the status messages, called "flags". These are used by xymongen e.g. to pick different icons for reversed tests when generating the Xymon webpages. This option makes xymonnet omit these flags from the status messages. .IP \-\-shuffle By default, TCP tests run roughly in the order that the hosts are listed in the hosts.cfg file. If you have many tests for one server, this may result in an exceptionally large load when Xymon is testing it because Xymon will perform a lot of tests at the same time. To avoid this, the \fB\-\-shuffle\fR option reorders the sequence of tests so they are spread randomly across all of the servers tested. .SH OPTIONS FOR THE PING TEST Note: xymonnet uses the program defined by the FPING environment to execute ping-tests - by default, that is the .I xymonping(1) utility. See .I xymonserver.cfg(5) for a description of how to customize this, e.g. if you need to run it with "sudo" or a similar tool. .IP \-\-ping Enables xymonnet's ping test. The column name used for ping test results is defined by the PINGCOLUMN environment variable in .I xymonserver.cfg(5). .br If not specified, xymonnet uses the CONNTEST environment variable to determine if it should perform the ping test or not. So if you prefer to use another tool to implement ping checks, either set the CONNTEST environment variable to false, or run xymonnet with the "\-\-noping". .IP \-\-noping Disable the connectivity test. .IP "\-\-trace" .IP "\-\-notrace" Enable/disable the use of traceroute when a ping-test fails. Performing a traceroute for failed ping tests is a slow operation, so the default is not to do any traceroute, unless it is requested on a per-host basis via the "trace" tag in the .I hosts.cfg(5) entry for each host. The "\-\-trace" option changes this, so the default becomes to run traceroute on all hosts where the ping test fails; you can then disable it on specific hosts by putting a "notrace" tag on the host-entry. .IP \-\-ping\-tasks=N Spread the task of pinging the hosts over N processes. If you have a very large number of hosts the time it takes to ping all of them can be substantial, even with the use of tools like fping or xymonping that ping many hosts in parallel. This option causes xymonnet to start N separate ping processes, the IP's that are being ping'ed will be divided evenly between these processes. .SH OPTIONS FOR HTTP (WEB) TESTS .IP \-\-content=CONTENTTESTNAME Determines the name of the column Xymon displays for content checks. The default is "content". If you have used the "cont.sh" or "cont2.sh" scripts earlier, you may want to use "\-\-content=cont" to report content checks using the same test name as these scripts do. .IP \-\-bb\-proxy\-syntax Adhere to the Big Brother syntax for a URL, which allows specifying a HTTP proxy as part of a URL. See \fB"HTTP Testing via proxy"\fR in the .I hosts.cfg(5) file for details. Beginning with Xymon 4.3.0, this behaviour is disabled by default since URL's that include other URL's are now much more common. This option restores the old Big Brother-compatible behaviour. .SH OPTIONS FOR SSL CERTIFICATE TESTS .IP \-\-ssl=SSLCERTTESTNAME Determines the name of the column Xymon displays for the SSL certificate checks. The default is "sslcert". .IP \-\-no\-ssl Disables reporting of the SSL certificate check. .IP \-\-sslwarn=N .IP \-\-sslalarm=N Determines the number of days before an SSL certificate expires, where xymonnet will generate a warning or alarm status for the SSL certificate column. .IP \-\-sslbits=N Enables checking that the encryption supported by the SSL protocol uses an encryption key of at least N bits. E.g. to trigger an alert if your SSL-enabled website supports less than 128 bits of encryption, use "\-\-sslbits=128". Note: This can be enabled on a per-host basis using the "sslbits=N" setting in .I hosts.cfg(5) .IP \-\-sslkeysize=N Enables checking of the length of the public key in SSL certificates. N is the minimum size of the SSL public key, typically such keys are 2048 bits, but some older certificates may use keys with 1024 bits or less. If you specify this, SSL certificates with keys less than N bits will result in the "sslcert" status going yellow. Default: 0, i.e. this check is disabled. .IP \-\-no\-cipherlist Do not show encryption cipher details on the "sslcert" status. .IP \-\-showallciphers List ALL locally available encryption ciphers on the "sslcert" status. .IP \-\-sni=[on|off] Sets the default for whether SSL connections use SNI (Server Name Indication). This can also be set with the "sni" or "nosni" options in hosts.cfg for each host - the hosts.cfg entries override this option. Default: off .SH DEBUGGING OPTIONS .IP \-\-no\-update Don't send any status updates to the Xymon server. Instead, all messages are dumped to stdout. .IP \-\-timing Causes xymonnet to collect information about the time spent in different parts of the program. The information is printed on stdout just before the program ends. Note that this information is also included in the status report sent with the "\-\-report" option. .IP \-\-debug Dumps a bunch of status about the tests as they progress to stdout. .IP \-\-dump[=before|=after|=both] Dumps internal memory structures before and/or after the tests have executed. .SH INFORMATIONAL OPTIONS .IP "--help or -?" Provide a summary of available command-line options. .IP "--version" Prints the version number of xymonnet .IP --services Dump the list of defined TCP services xymonnet knows how to test. Do not run any tests. .SH USING COOKIES IN WEB TESTS If the file $XYMONHOME/etc/cookies exist, cookies will be read from this file and sent along with the HTTP requests when checking websites. This file is in the Netscape Cookie format, see http://www.netscape.com/newsref/std/cookie_spec.html for details on this format. The .I curl(1) utility can output a file in this format if run with the "--cookie-jar FILENAME" option. .SH ABOUT SSL CERTIFICATE CHECKS When xymonnet tests services that use SSL- or TLS-based protocols, it will check that the server certificate has not expired. This check happens automatically for https (secure web), pop3s, imaps, nntps and all other SSL-enabled services (except ldap, see LDAP TESTS below). All certificates found for a host are reported in one status message. Note: On most systems, the end-date of the certificate is limited to Jan 19th, 2038. If your certificate is valid after this date, xymonnet will report it as valid only until Jan 19, 2038. This is due to limitations in your operating system C library. See http://en.wikipedia.org/wiki/2038_problem . .SH LDAP TESTS ldap testing can be done in two ways. If you just put an "ldap" or "ldaps" tag in hosts.cfg, a simple test is performed that just verifies that it is possible to establish a connection to the port running the ldap service (389 for ldap, 636 for ldaps). Instead you can put an LDAP URI in hosts.cfg. This will cause xymonnet to initiate a full-blown LDAP session with the server, and do an LDAP search for the objects defined by the URI. This requires that xymonnet was built with LDAP support, and relies on an existing LDAP library to be installed. It has been tested with OpenLDAP 2.0.26 (from Red Hat 9) and 2.1.22. The Solaris 8 system ldap library has also been confirmed to work for un-encrypted (plain ldap) access. The format of LDAP URI's is defined in RFC 2255. LDAP URLs look like this: .nf \fBldap://\fP\fIhostport\fP\fB/\fP\fIdn\fP[\fB?\fP\fIattrs\fP[\fB?\fP\fIscope\fP[\fB?\fP\fIfilter\fP[\fB?\fP\fIexts\fP]]]] where: \fIhostport\fP is a host name with an optional ":portnumber" \fIdn\fP is the search base \fIattrs\fP is a comma separated list of attributes to request \fIscope\fP is one of these three strings: base one sub (default=base) \fIfilter\fP is filter \fIexts\fP are recognized set of LDAP and/or API extensions. Example: ldap://ldap.example.net/dc=example,dc=net?cn,sn?sub?(cn=*) .fi .sp All "bind" operations to LDAP servers use simple authentication. Kerberos and SASL are not supported. If your LDAP server requires a username/password, use the "ldaplogin" tag to specify this, cf. .I hosts.cfg(5) If no username/password information is provided, an anonymous bind will be attempted. SSL support requires both a client library and an LDAP server that support LDAPv3; it uses the LDAP "STARTTLS" protocol request after establishing a connection to the standard (non-encrypted) LDAP port (usually port 389). It has only been tested with OpenSSL 2.x, and probably will not work with any other LDAP library. The older LDAPv2 experimental method of tunnelling normal LDAP traffic through an SSL connection - ldaps, running on port 636 - is not supported, unless someone can explain how to get the OpenLDAP library to support it. This method was never formally described in an RFC, and implementations of it are non-standard. For a discussion of the various ways of running encrypted ldap, see .br http://www.openldap.org/lists/openldap-software/200305/msg00079.html .br http://www.openldap.org/lists/openldap-software/200305/msg00084.html .br http://www.openldap.org/lists/openldap-software/200201/msg00042.html .br http://www.openldap.org/lists/openldap-software/200206/msg00387.html When testing LDAP URI's, all of the communications are handled by the ldap library. Therefore, it is not possible to obtain the SSL certificate used by the LDAP server, and it will not show up in the "sslcert" column. .SH USING MULTIPLE NETWORK TEST SYSTEMS If you have more than one system running network tests - e.g. if your network is separated by firewalls - then is is problematic to maintain multiple hosts.cfg files for each of the systems. xymonnet supports the NET:location tag in .I hosts.cfg(5) to distinguish between hosts that should be tested from different network locations. If you set the environment variable XYMONNETWORK e.g. to "dmz" before running xymonnet, then it will only test hosts that have a "NET:dmz" tag in hosts.cfg. This allows you to keep all of your hosts in the same hosts.cfg file, but test different sets of hosts by different systems running xymonnet. .SH XYMONNET INTERNALS xymonnet first reads the protocols.cfg file to see which network tests are defined. It then scans the hosts.cfg file, and collects information about the TCP service tests that need to be tested. It picks out only the tests that were listed in the protocols.cfg file, plus the "dns", "dig" and "ntp" tests. It then runs two tasks in parallel: First, a separate process is started to run the "xymonping" tool for the connectivity tests. While xymonping is busy doing the "ping" checks, xymonnet runs all of the TCP-based network tests. All of the TCP-based service checks are handled by a connection tester written specifically for this purpose. It uses only standard Unix-style network programming, but relies on the Unix "select(2)" system-call to handle many simultaneous connections happening in parallel. Exactly how many parallel connections are being used depends on your operating system - the default is FD_SETSIZE/4, which amounts to 256 on many Unix systems. You can choose the number of concurrent connections with the "--concurrency=N" option to xymonnet. Connection attempts timeout after 10 seconds - this can be changed with the "--timeout=N" option. Both of these settings play a part in deciding how long the testing takes. A conservative estimate for doing N TCP tests is: (1 + (N / concurrency)) * timeout In real life it will probably be less, as the above formula is for every test to require a timeout. Since the most normal use of Xymon is to check for services that are active, you should have a lot less timeouts. The "ntp" and "rpcinfo" checks rely on external programs to do each test. .SH ENVIRONMENT VARIABLES .IP XYMONNETWORK Defines the network segment where xymonnet is currently running. This is used to filter out only the entries in the .I hosts.cfg(5) file that have a matching "NET:LOCATION" tag, and execute the tests for only those hosts. .IP MAXMSGSPERCOMBO Defines the maximum number of status messages that can be sent in one combo message. Default is 0 - no limit. .br In practice, the maximum size of a single Xymon message sets a limit - the default value for the maximum message size is 32 KB, but that will easily accommodate 100 status messages per transmission. So if you want to experiment with this setting, I suggest starting with a value of 10. .IP SLEEPBETWEENMSGS Defines a a delay (in microseconds) after each message is transmitted to the Xymon server. The default is 0, i.e. send the messages as fast as possible. This gives your Xymon server some time to process the message before the next message comes in. Depending on the speed of your Xymon server, it may be necessary to set this value to half a second or even 1 or 2 seconds. Note that the value is specified in MICROseconds, so to define a delay of half a second, this must be set to the value "500000"; a delay of 1 second is achieved by setting this to "1000000" (one million). .IP FPING Command used to run the .I xymonping(1) utility. Used by xymonnet for connectivity (ping) testing. See .I xymonserver.cfg(5) for more information about how to customize the program that is executed to do ping tests. .IP TRACEROUTE Location of the .I traceroute(8) utility, or an equivalent tool e.g. .I mtr(8). Optionally used when a connectivity test fails to pinpoint the network location that is causing the failure. .IP NTPDATE Location of the .I ntpdate(1) utility. Used by xymonnet when checking the "ntp" service. .IP RPCINFO Location of the .I rpcinfo(8) utility. Used by xymonnet for the "rpc" service checks. .SH FILES .IP "~/server/etc/protocols.cfg" This file contains definitions of TCP services that xymonnet can test. Definitions for a default set of common services is built into xymonnet, but these can be overridden or supplemented by defining services in the protocols.cfg file. See .I protocols.cfg(5) for details on this file. .IP "$XYMONHOME/etc/netrc - authentication data for password-protected webs" If you have password-protected sites, you can put the usernames and passwords for these here. They will then get picked up automatically when running your network tests. This works for web-sites that use the "Basic" authentication scheme in HTTP. See .I ftp(1) for details - a sample entry would look like this .br machine www.acme.com login fred password Wilma1 .br Note that the machine-name must be the name you use in the http://machinename/ URL setting - it need not be the one you use for the system-name in Xymon. .sp .IP "$XYMONHOME/etc/cookies" This file may contain website cookies, in the Netscape HTTP Cookie format. If a website requires a static cookie to be present in order for the check to complete, then you can add this cookie to this file, and it will be sent along with the HTTP request. To get the cookies into this file, you can use the "curl --cookie-jar FILE" to request the URL that sets the cookie. .sp .IP "$XYMONTMP/*.status - test status summary" Each time xymonnet runs, if any tests fail (i.e. they result in a red status) then they will be listed in a file name TESTNAME.[LOCATION].status. The LOCATION part may be null. This file is used to determine how long the failure has lasted, which in turn decides if this test should be included in the tests done by .I xymonnet-again.sh(1) .br It is also used internally by xymonnet when determining the color for tests that use the "badconn" or "badTESTNAME" tags. .sp .IP $XYMONTMP/frequenttests.[LOCATION] This file contains the hostnames of those hosts that should be retested by the .I xymonnet-again.sh(1) test tool. It is updated only by xymonnet during the normal runs, and read by xymonnet-again.sh. .SH "SEE ALSO" hosts.cfg(5), protocols.cfg(5), xymonserver.cfg(5), xymonping(1), curl(1), ftp(1), fping(1), ntpdate(1), rpcinfo(8) xymon-4.3.30/xymonnet/dns.c0000664000076400007640000002250613515623702016025 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: dns.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include #include #include "dns.h" #include "dns2.h" #ifdef HPUX /* Doesn't have hstrerror */ char *hstrerror(int err) { return ""; } #endif static ares_channel mychannel; static int pending_dns_count = 0; int use_ares_lookup = 1; int max_dns_per_run = 0; int dns_stats_total = 0; int dns_stats_success = 0; int dns_stats_failed = 0; int dns_stats_lookups = 0; int dnstimeout = 30; FILE *dnsfaillog = NULL; typedef struct dnsitem_t { char *name; struct in_addr addr; struct dnsitem_t *next; int failed; struct timespec resolvetime; } dnsitem_t; static void * dnscache; static void dns_init(void) { static int initdone = 0; if (initdone) return; dnscache = xtreeNew(strcasecmp); if (use_ares_lookup) { struct ares_options options; int status; /* ARES timeout backported from Xymon trunk 20120411 - this should give us a ~23 second timeout */ options.timeout = 2000; options.tries = 4; status = ares_init_options(&mychannel, &options, (ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES)); if (status != ARES_SUCCESS) { errprintf("Cannot initialize ARES resolver, using standard\n"); errprintf("ARES error was: '%s'\n", ares_strerror(status)); use_ares_lookup = 0; } } initdone = 1; } static char *find_dnscache(char *hostname) { struct in_addr inp; xtreePos_t handle; dnsitem_t *dnsc; dns_init(); if (inet_aton(hostname, &inp) != 0) { /* It is an IP, so just use that */ return hostname; } /* In the cache ? */ handle = xtreeFind(dnscache, hostname); if (handle == xtreeEnd(dnscache)) return NULL; dnsc = (dnsitem_t *)xtreeData(dnscache, handle); return inet_ntoa(dnsc->addr); } static void dns_simple_callback(void *arg, int status, int timeout, struct hostent *hent) { struct dnsitem_t *dnsc = (dnsitem_t *)arg; struct timespec etime; getntimer(&etime); tvdiff(&dnsc->resolvetime, &etime, &dnsc->resolvetime); pending_dns_count--; if (status == ARES_SUCCESS) { memcpy(&dnsc->addr, *(hent->h_addr_list), sizeof(dnsc->addr)); dbgprintf("Got DNS result for host %s : %s\n", dnsc->name, inet_ntoa(dnsc->addr)); dns_stats_success++; } else { memset(&dnsc->addr, 0, sizeof(dnsc->addr)); dbgprintf("DNS lookup failed for %s - status %s (%d)\n", dnsc->name, ares_strerror(status), status); dnsc->failed = 1; dns_stats_failed++; if (dnsfaillog) { fprintf(dnsfaillog, "DNS lookup failed for %s - status %s (%d)\n", dnsc->name, ares_strerror(status), status); } } } static void dns_ares_queue_run(ares_channel channel) { int nfds; fd_set read_fds, write_fds; struct timeval *tvp, tv; int loops = 0; if ((channel == mychannel) && (!pending_dns_count)) return; dbgprintf("Processing %d DNS lookups with ARES\n", pending_dns_count); while (1) { /* Loop continues until all requests handled (or time out) */ loops++; FD_ZERO(&read_fds); FD_ZERO(&write_fds); nfds = ares_fds(channel, &read_fds, &write_fds); if (nfds == 0) { dbgprintf("Finished ARES queue after loop %d\n", loops); break; /* No pending requests */ } /* * Determine how long select() waits before processing timeouts. * "dnstimeout" is the user configurable option which is * the absolute maximum timeout value. However, ARES also * has built in timeouts - these are defined at ares_init() * using ARES_OPT_TIMEOUTMS and ARES_OPT_TRIES (default * 5 secs / 4 tries = 20 second timeout). */ tv.tv_sec = dnstimeout; tv.tv_usec = 0; tvp = ares_timeout(channel, &tv, &tv); select(nfds, &read_fds, &write_fds, NULL, tvp); ares_process(channel, &read_fds, &write_fds); } if (pending_dns_count > 0) { errprintf("Odd ... pending_dns_count=%d after a queue run\n", pending_dns_count); pending_dns_count = 0; } } void add_host_to_dns_queue(char *hostname) { dnsitem_t *dnsc; dns_init(); dns_stats_total++; if (find_dnscache(hostname)) return; /* Already resolved */ if (max_dns_per_run && (pending_dns_count >= max_dns_per_run)) { /* Limit the number of requests we do per run */ dns_ares_queue_run(mychannel); } /* New hostname */ dnsc = (dnsitem_t *)calloc(1, sizeof(dnsitem_t)); dbgprintf("Adding hostname '%s' to resolver queue\n", hostname); pending_dns_count++; dnsc->name = strdup(hostname); getntimer(&dnsc->resolvetime); xtreeAdd(dnscache, dnsc->name, dnsc); if (use_ares_lookup) { ares_gethostbyname(mychannel, hostname, AF_INET, dns_simple_callback, dnsc); } else { /* * This uses the normal resolver functions, but * sends the result through the same processing * functions as used when we use ARES. */ struct hostent *hent; int status; hent = gethostbyname(hostname); if (hent) { status = ARES_SUCCESS; dns_stats_success++; } else { status = ARES_ENOTFOUND; dns_stats_failed++; dbgprintf("gethostbyname() failed with err %d: %s\n", h_errno, hstrerror(h_errno)); if (dnsfaillog) { fprintf(dnsfaillog, "Hostname lookup failed for %s - status %s (%d)\n", hostname, hstrerror(h_errno), h_errno); } } /* Send the result to our normal callback function */ dns_simple_callback(dnsc, status, 0, hent); } } void add_url_to_dns_queue(char *url) { weburl_t weburl; dns_init(); decode_url(url, &weburl); if (weburl.proxyurl) { if (weburl.proxyurl->parseerror) return; add_host_to_dns_queue(weburl.proxyurl->host); } else { if (weburl.desturl->parseerror) return; add_host_to_dns_queue(weburl.desturl->host); } } void flush_dnsqueue(void) { dns_init(); dns_ares_queue_run(mychannel); } char *dnsresolve(char *hostname) { char *result; dns_init(); if (hostname == NULL) return NULL; flush_dnsqueue(); dns_stats_lookups++; result = find_dnscache(hostname); if (result == NULL) { errprintf("dnsresolve: name '%s' not in cache. You probably have a NULL IP setting and the 'testip' flag set.\n", hostname); return NULL; } if (strcmp(result, "0.0.0.0") == 0) return NULL; return result; } int dns_test_server(char *serverip, char *hostname, strbuffer_t *banner) { ares_channel channel; struct ares_options options; struct in_addr serveraddr; int status; struct timespec starttime, endtime; struct timespec *tspent; char msg[100]; SBUF_DEFINE(tspec); char *tst; dns_resp_t *responses = NULL; dns_resp_t *walk = NULL; int i; dns_init(); if (inet_aton(serverip, &serveraddr) == 0) { errprintf("dns_test_server: serverip '%s' not a valid IP\n", serverip); return 1; } options.flags = ARES_FLAG_NOCHECKRESP; options.servers = &serveraddr; options.nservers = 1; /* ARES timeout backported from Xymon trunk 20120411 - this should give us a ~23 second timeout */ options.timeout = 2000; options.tries = 4; status = ares_init_options(&channel, &options, (ARES_OPT_FLAGS | ARES_OPT_SERVERS | ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES)); if (status != ARES_SUCCESS) { errprintf("Could not initialize ares channel: %s\n", ares_strerror(status)); return 1; } tspec = strdup(hostname); tspec_buflen = strlen(tspec) + 1; getntimer(&starttime); tst = strtok(tspec, ","); do { dns_resp_t *newtest = (dns_resp_t *)malloc(sizeof(dns_resp_t)); char *p, *tlookup; int atype = T_A; newtest->msgbuf = newstrbuffer(0); newtest->next = NULL; if (responses == NULL) responses = newtest; else walk->next = newtest; walk = newtest; p = strchr(tst, ':'); tlookup = (p ? p+1 : tst); if (p) { *p = '\0'; atype = dns_name_type(tst); *p = ':'; } dbgprintf("ares_search: tlookup='%s', class=%d, type=%d\n", tlookup, C_IN, atype); ares_search(channel, tlookup, C_IN, atype, dns_detail_callback, newtest); tst = strtok(NULL, ","); } while (tst); dns_ares_queue_run(channel); getntimer(&endtime); tspent = tvdiff(&starttime, &endtime, NULL); clearstrbuffer(banner); status = ARES_SUCCESS; strncpy(tspec, hostname, tspec_buflen); tst = strtok(tspec, ","); for (walk = responses, i=1; (walk); walk = walk->next, i++) { /* Print an identifying line if more than one query */ if ((walk != responses) || (walk->next)) { snprintf(msg, sizeof(msg), "\n*** DNS lookup of '%s' ***\n", tst); addtobuffer(banner, msg); } addtostrbuffer(banner, walk->msgbuf); if (walk->msgstatus != ARES_SUCCESS) status = walk->msgstatus; xfree(walk->msgbuf); tst = strtok(NULL, ","); } xfree(tspec); snprintf(msg, sizeof(msg), "\nSeconds: %u.%.9ld\n", (unsigned int)tspent->tv_sec, tspent->tv_nsec); addtobuffer(banner, msg); ares_destroy(channel); return (status != ARES_SUCCESS); } xymon-4.3.30/xymonnet/xymonnet-again.sh.10000664000076400007640000000245113534041732020521 0ustar rpmbuildrpmbuild.TH XYMONNET\-AGAIN.SH 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonnet\-again.sh \- Xymon network re-test tool .SH SYNOPSIS .B "xymonnet\-again.sh" .SH DESCRIPTION \fBxymonnet\-again.sh\fR is an extension script for Xymon that runs on the network test server. It picks up the failing network tests executed by the .I xymonnet(1) program, and repeats these tests with a faster test cycle than the normal xymonnet schedule. This means that when the server recovers and the network service becomes available again, this is detected quicker resulting in less reported downtime. Only tests whose first failure occurred within 30 minutes are included in the tests that are run by xymonnet\-again.sh. The 30 minute limit is there to avoid hosts that are down for longer periods of time to bog down xymonnet\-again.sh. You can change this limit with the "\-\-frequenttestlimit=SECONDS" when you run xyxmonnet. .SH INSTALLATION This script runs by default from your .I tasks.cfg(5) file. .SH FILES .IP $XYMONTMP/TESTNAME.LOCATION.status Temporary status file managed by xyxmonnet with status of tests that have currently failed. .IP $XYMONTMP/frequenttests.LOCATION Temporary file managed by xymonnet with the hostnames that xymonnet\-again.sh should test. .SH "SEE ALSO" xymonnet(1), xymon(7), tasks.cfg(5) xymon-4.3.30/xymonnet/dns2.h0000664000076400007640000000200011615341300016065 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DNS2_H__ #define __DNS2_H__ typedef struct dns_resp_t { int msgstatus; strbuffer_t *msgbuf; struct dns_resp_t *next; } dns_resp_t; extern void dns_detail_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); extern int dns_name_type(char *name); #endif xymon-4.3.30/xymonnet/xymonnet-again.sh.DIST0000664000076400007640000000050011535462534021123 0ustar rpmbuildrpmbuild#!/bin/sh # This extension script picks up the $XYMONTMP/frequenttests.$XYMONNETWORK # file generated by xyxmonnet. It then re-does the network tests # with the same parameters. REDOFILE=$XYMONTMP/frequenttests.$XYMONNETWORK if test -r $REDOFILE then @RUNTIMEDEFS@ $XYMONHOME/bin/xymonnet `cat $REDOFILE` fi exit 0 xymon-4.3.30/xymonnet/protocols.cfg.50000664000076400007640000000506313534041732017742 0ustar rpmbuildrpmbuild.TH PROTOCOLS.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME protocols.cfg \- Configuration of TCP network services .SH SYNOPSIS .BR $XYMONHOME/etc/protocols.cfg .SH DESCRIPTION \fBprotocols.cfg\fR contains definitions of how .I xymonnet(1) should test a TCP-based network service (i.e. all common network services except HTTP and DNS). For each service, a simple dialogue can be defined to check that the service is functioning normally, and optional flags determine if the service has e.g. a banner or requires SSL- or telnet-style handshaking to be tested. .SH FILE FORMAT protocols.cfg is a text file. A simple service definition for the SMTP service would be this: .br .sp [smtp] .br send "mail\\r\\nquit\\r\\n" .br expect "220" .br options banner .br .sp This defines a service called "smtp". When the connection is first established, xymonnet will send the string "mail\\r\\nquit\\r\\n" to the service. It will then expect a response beginning with "220". Any data returned by the service (a so-called "banner") will be recorded and included in the status message. .sp The full set of commands available for the protocols.cfg file are: .IP "[NAME]" Define the name of the TCP service, which will also be the column-name in the resulting display on the test status. If multiple tests share a common definition (e.g. ssh, ssh1 and ssh2 are tested identically), you may list these in a single "[ssh|ssh1|ssh2]" definition, separating each service-name with a pipe-sign. .IP "send STRING" .IP "expect STRING" Defines the strings to send to the service after a connection is established, and the response that is expected. Either of these may be omitted, in which case .I xymonnet(1) will simply not send any data, or match a response against anything. The send- and expect-strings use standard escaping for non-printable characters. "\\r" represents a carriage-return (ASCII 13), "\\n" represents a line-feed (ASCII 10), "\\t" represents a TAB (ASCII 8). Binary data is input as "\\xNN" with NN being the hexadecimal value of the byte. .IP "port NUMBER" Define the default TCP port-number for this service. If no portnumber is defined, .I xymonnet(1) will attempt to lookup the portnumber in the standard /etc/services file. .IP "options option1[,option2][,option3]" Defines test options. The possible options are .br banner - include received data in the status message .br ssl - service uses SSL so perform an SSL handshake .br telnet - service is telnet, so exchange telnet options .SH FILES .BR $XYMONHOME/etc/protocols.cfg .SH "SEE ALSO" xymonnet(1) xymon-4.3.30/xymonnet/xymon-snmpcollect.c0000664000076400007640000007361713515623702020745 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor SNMP data collection tool */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* Inspired by the asyncapp.c file from the "NET-SNMP demo", available from */ /* the Net-SNMP website. This file carries the attribution */ /* "Niels Baggesen (Niels.Baggesen@uni-c.dk), 1999." */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymon-snmpcollect.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include "libxymon.h" /* ----------------- struct's used for the host/requests we need to do ---------------- */ /* List of the OID's we will request */ typedef struct oid_t { mibdef_t *mib; /* pointer to the mib definition for mibs */ oid Oid[MAX_OID_LEN]; /* the internal OID representation */ size_t OidLen; /* size of the oid */ char *devname; /* Users' chosen device name. May be a key (e.g "eth0") */ oidds_t *oiddef; /* Points to the oidds_t definition */ int setnumber; /* All vars fetched in one PDU's have the same setnumber */ char *result; /* the printable result data */ struct oid_t *next; } oid_t; /* Used for requests where we must determine the appropriate table index first */ typedef struct keyrecord_t { mibdef_t *mib; /* Pointer to the mib definition */ mibidx_t *indexmethod; /* Pointer to the mib index definition */ char *key; /* The user-provided key we must find */ char *indexoid; /* Result: Index part of the OID */ struct keyrecord_t *next; } keyrecord_t; /* A host and the OID's we will be polling */ typedef struct req_t { char *hostname; /* Hostname used for reporting to Xymon */ char *hostip[10]; /* Hostname(s) or IP(s) used for testing. Max 10 IP's */ int hostipidx; /* Index into hostip[] for the active IP we use */ long version; /* SNMP version to use */ unsigned char *community; /* Community name used to access the SNMP daemon (v1, v2c) */ unsigned char *username; /* Username used to access the SNMP daemon (v3) */ unsigned char *passphrase; /* Passphrase used to access the SNMP daemon (v3) */ enum { SNMP_V3AUTH_MD5, SNMP_V3AUTH_SHA1 } authmethod; /* Authentication method (v3) */ int setnumber; /* Per-host setnumber used while building requests */ struct snmp_session *sess; /* SNMP session data */ keyrecord_t *keyrecords, *currentkey; /* For keyed requests: Key records */ oid_t *oidhead, *oidtail; /* List of the OID's we will fetch */ oid_t *curr_oid, *next_oid; /* Current- and next-OID pointers while fetching data */ struct req_t *next; } req_t; /* Global variables */ req_t *reqhead = NULL; /* Holds the list of requests */ int active_requests = 0; /* Number of active SNMP requests in flight */ /* dataoperation tracks what we are currently doing */ enum { GET_KEYS, /* Scan for the keys */ GET_DATA /* Fetch the actual data */ } dataoperation; /* Tuneables */ int max_pending_requests = 30; int retries = 0; /* Number of retries before timeout. 0 = Net-SNMP default (5). */ long timeout = 0; /* Number of uS until first timeout, then exponential backoff. 0 = Net-SNMP default (1 second). */ /* Statistics */ char *reportcolumn = NULL; int varcount = 0; int pducount = 0; int okcount = 0; int toobigcount = 0; int timeoutcount = 0; int errorcount = 0; struct timeval starttv, endtv; /* Must forward declare these */ void startonehost(struct req_t *r, int ipchange); void starthosts(int resetstart); struct snmp_pdu *generate_datarequest(req_t *item) { struct snmp_pdu *req; int currentset; if (!item->next_oid) return NULL; req = snmp_pdu_create(SNMP_MSG_GET); pducount++; item->curr_oid = item->next_oid; currentset = item->next_oid->setnumber; while (item->next_oid && (currentset == item->next_oid->setnumber)) { varcount++; snmp_add_null_var(req, item->next_oid->Oid, item->next_oid->OidLen); item->next_oid = item->next_oid->next; } return req; } /* * Store data received in response PDU */ int print_result (int status, req_t *req, struct snmp_pdu *pdu) { struct variable_list *vp; size_t len; keyrecord_t *kwalk; int keyoidlen; oid_t *owalk; int done; switch (status) { case STAT_SUCCESS: if (pdu->errstat == SNMP_ERR_NOERROR) { unsigned char *valstr = NULL, *oidstr = NULL; size_t valsz = 0, oidsz = 0; okcount++; switch (dataoperation) { case GET_KEYS: /* * Find the keyrecord currently processed for this request, and * look through the unresolved keys to see if we have a match. * If we do, determine the index for data retrieval. */ vp = pdu->variables; len = 0; sprint_realloc_value(&valstr, &valsz, &len, 1, vp->name, vp->name_length, vp); len = 0; sprint_realloc_objid(&oidstr, &oidsz, &len, 1, vp->name, vp->name_length); dbgprintf("Got key-oid '%s' = '%s'\n", oidstr, valstr); for (kwalk = req->currentkey, done = 0; (kwalk && !done); kwalk = kwalk->next) { /* Skip records where we have the result already, or that are not keyed */ if (kwalk->indexoid || (kwalk->indexmethod != req->currentkey->indexmethod)) { continue; } keyoidlen = strlen(req->currentkey->indexmethod->keyoid); switch (kwalk->indexmethod->idxtype) { case MIB_INDEX_IN_OID: /* Does the key match the value we just got? */ if (*kwalk->key == '*') { /* Match all. Add an extra key-record at the end. */ keyrecord_t *newkey; newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); memcpy(newkey, kwalk, sizeof(keyrecord_t)); newkey->indexoid = strdup(oidstr + keyoidlen + 1); newkey->key = valstr; valstr = NULL; newkey->next = kwalk->next; kwalk->next = newkey; done = 1; } else if (strcmp(valstr, kwalk->key) == 0) { /* Grab the index part of the OID */ kwalk->indexoid = strdup(oidstr + keyoidlen + 1); done = 1; } break; case MIB_INDEX_IN_VALUE: /* Does the key match the index-part of the result OID? */ if (*kwalk->key == '*') { /* Match all. Add an extra key-record at the end. */ keyrecord_t *newkey; newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); memcpy(newkey, kwalk, sizeof(keyrecord_t)); newkey->indexoid = valstr; valstr = NULL; newkey->key = strdup(oidstr + keyoidlen + 1); newkey->next = kwalk->next; kwalk->next = newkey; done = 1; } else if ((*(oidstr+keyoidlen) == '.') && (strcmp(oidstr+keyoidlen+1, kwalk->key)) == 0) { /* * Grab the index which is the value. * Avoid a strdup by grabbing the valstr pointer. */ kwalk->indexoid = valstr; valstr = NULL; valsz = 0; done = 1; } break; } } break; case GET_DATA: owalk = req->curr_oid; vp = pdu->variables; while (vp) { valsz = len = 0; sprint_realloc_value((unsigned char **)&owalk->result, &valsz, &len, 1, vp->name, vp->name_length, vp); owalk = owalk->next; vp = vp->next_variable; } break; } if (valstr) xfree(valstr); if (oidstr) xfree(oidstr); } else { errorcount++; errprintf("ERROR %s: %s\n", req->hostip[req->hostipidx], snmp_errstring(pdu->errstat)); } return 1; case STAT_TIMEOUT: timeoutcount++; dbgprintf("%s: Timeout\n", req->hostip); if (req->hostip[req->hostipidx+1]) { req->hostipidx++; startonehost(req, 1); } return 0; case STAT_ERROR: errorcount++; snmp_sess_perror(req->hostip[req->hostipidx], req->sess); return 0; } return 0; } /* * response handler */ int asynch_response(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) { struct req_t *req = (struct req_t *)magic; if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) { struct snmp_pdu *snmpreq = NULL; int okoid = 1; if (dataoperation == GET_KEYS) { /* * We're doing GETNEXT's when retrieving keys, so we will get a response * which has nothing really to do with the data we're looking for. In that * case, we should NOT process data from this response. */ struct variable_list *vp = pdu->variables; okoid = ((vp->name_length >= req->currentkey->indexmethod->rootoidlen) && (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0)); } switch (pdu->errstat) { case SNMP_ERR_NOERROR: /* Pick up the results, but only if the OID is valid */ if (okoid) print_result(STAT_SUCCESS, req, pdu); break; case SNMP_ERR_NOSUCHNAME: dbgprintf("Host %s item %s: No such name\n", req->hostname, req->curr_oid->devname); if (req->hostip[req->hostipidx+1]) { req->hostipidx++; startonehost(req, 1); } break; case SNMP_ERR_TOOBIG: toobigcount++; errprintf("Host %s item %s: Response too big\n", req->hostname, req->curr_oid->devname); break; default: errorcount++; errprintf("Host %s item %s: SNMP error %d\n", req->hostname, req->curr_oid->devname, pdu->errstat); break; } /* Now see if we should send another request */ switch (dataoperation) { case GET_KEYS: /* * While fetching keys, walk the current key-table until we reach the end of the table. * When we reach the end of one key-table, start with the next. * FIXME: Could optimize so we don't fetch the whole table, but only those rows we need. */ if (pdu->errstat == SNMP_ERR_NOERROR) { struct variable_list *vp = pdu->variables; if ( (vp->name_length >= req->currentkey->indexmethod->rootoidlen) && (memcmp(req->currentkey->indexmethod->rootoid, vp->name, req->currentkey->indexmethod->rootoidlen * sizeof(oid)) == 0) ) { /* Still more data in the current key table, get the next row */ snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT); pducount++; /* Probably only one variable to fetch, but never mind ... */ while (vp) { varcount++; snmp_add_null_var(snmpreq, vp->name, vp->name_length); vp = vp->next_variable; } } else { /* End of current key table. If more keys to be found, start the next table. */ do { req->currentkey = req->currentkey->next; } while (req->currentkey && req->currentkey->indexoid); if (req->currentkey) { snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT); pducount++; snmp_add_null_var(snmpreq, req->currentkey->indexmethod->rootoid, req->currentkey->indexmethod->rootoidlen); } } } break; case GET_DATA: /* Generate a request for the next dataset, if any */ if (req->next_oid) { snmpreq = generate_datarequest(req); } else { dbgprintf("No more oids left\n"); } break; } /* Send the request we just made */ if (snmpreq) { if (snmp_send(req->sess, snmpreq)) goto finish; else { snmp_sess_perror("snmp_send", req->sess); snmp_free_pdu(snmpreq); } } } else { dbgprintf("operation not successful: %d\n", operation); print_result(STAT_TIMEOUT, req, pdu); } /* * Something went wrong (or end of variables). * This host not active any more */ dbgprintf("Finished host %s\n", req->hostname); active_requests--; finish: /* Start some more hosts */ starthosts(0); return 1; } void startonehost(struct req_t *req, int ipchange) { struct snmp_session s; struct snmp_pdu *snmpreq = NULL; if ((dataoperation < GET_DATA) && !req->currentkey) return; /* Are we retrying a cluster with a new IP? Then drop the current session */ if (req->sess && ipchange) { /* * Apparently, we cannot close a session while in a callback. * So leave this for now - it will leak some memory, but * this is not a problem as long as we only run once. */ /* snmp_close(req->sess); */ req->sess = NULL; } /* Setup the SNMP session */ if (!req->sess) { snmp_sess_init(&s); /* * snmp_session has a "remote_port" field, but it does not work. * Instead, the peername should include a port number (IP:PORT) * if (req->portnumber) s.remote_port = req->portnumber; */ s.peername = req->hostip[req->hostipidx]; /* Set the SNMP version and authentication token(s) */ s.version = req->version; switch (s.version) { case SNMP_VERSION_1: case SNMP_VERSION_2c: s.community = req->community; s.community_len = strlen((char *)req->community); break; case SNMP_VERSION_3: /* set the SNMPv3 user name */ s.securityName = strdup(req->username); s.securityNameLen = strlen(s.securityName); /* set the security level to authenticated, but not encrypted */ s.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; /* set the authentication method */ switch (req->authmethod) { case SNMP_V3AUTH_MD5: s.securityAuthProto = usmHMACMD5AuthProtocol; s.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid); s.securityAuthKeyLen = USM_AUTH_KU_LEN; break; case SNMP_V3AUTH_SHA1: s.securityAuthProto = usmHMACSHA1AuthProtocol; s.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid); s.securityAuthKeyLen = USM_AUTH_KU_LEN; break; } /* * set the authentication key to a hashed version of our * passphrase (which must be at least 8 characters long). */ if (generate_Ku(s.securityAuthProto, s.securityAuthProtoLen, (u_char *)req->passphrase, strlen(req->passphrase), s.securityAuthKey, &s.securityAuthKeyLen) != SNMPERR_SUCCESS) { errprintf("Failed to generate Ku from authentication pass phrase for host %s\n", req->hostname); snmp_perror("generate_Ku"); return; } break; } /* Set timeouts and retries */ if (timeout > 0) s.timeout = timeout; if (retries > 0) s.retries = retries; /* Setup the callback */ s.callback = asynch_response; s.callback_magic = req; if (!(req->sess = snmp_open(&s))) { snmp_sess_perror("snmp_open", &s); return; } } switch (dataoperation) { case GET_KEYS: snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT); pducount++; snmp_add_null_var(snmpreq, req->currentkey->indexmethod->rootoid, req->currentkey->indexmethod->rootoidlen); break; case GET_DATA: /* Build the request PDU and send it */ snmpreq = generate_datarequest(req); break; } if (!snmpreq) return; if (snmp_send(req->sess, snmpreq)) active_requests++; else { errorcount++; snmp_sess_perror("snmp_send", req->sess); snmp_free_pdu(snmpreq); } } void starthosts(int resetstart) { static req_t *startpoint = NULL; static int haverun = 0; struct req_t *rwalk; if (resetstart) { startpoint = NULL; haverun = 0; } if (startpoint == NULL) { if (haverun) { return; } else { startpoint = reqhead; haverun = 1; } } /* startup as many hosts as we want to run in parallel */ for (rwalk = startpoint; (rwalk && (active_requests <= max_pending_requests)); rwalk = rwalk->next) { startonehost(rwalk, 0); } startpoint = rwalk; } void stophosts(void) { struct req_t *rwalk; for (rwalk = reqhead; (rwalk); rwalk = rwalk->next) { if (rwalk->sess) { snmp_close(rwalk->sess); } } } /* * This routine loads MIB files, and computes the key-OID values. * We defer this until the mib-definition is actually being referred to * in snmphosts.cfg, because lots of MIB's are not being used * (and probably do not exist on the host where we're running) and * to avoid spending a lot of time to load MIB's that are not used. */ void setupmib(mibdef_t *mib, int verbose) { mibidx_t *iwalk; size_t sz, len; if (mib->loadstatus != MIB_STATUS_NOTLOADED) return; if (mib->mibfn && (read_mib(mib->mibfn) == NULL)) { mib->loadstatus = MIB_STATUS_LOADFAILED; if (verbose) { errprintf("Failed to read MIB file %s\n", mib->mibfn); snmp_perror("read_objid"); } } for (iwalk = mib->idxlist; (iwalk); iwalk = iwalk->next) { iwalk->rootoid = calloc(MAX_OID_LEN, sizeof(oid)); iwalk->rootoidlen = MAX_OID_LEN; if (read_objid(iwalk->keyoid, iwalk->rootoid, &iwalk->rootoidlen)) { /* Re-use the iwalk->keyoid buffer */ sz = strlen(iwalk->keyoid) + 1; len = 0; sprint_realloc_objid((unsigned char **)&iwalk->keyoid, &sz, &len, 1, iwalk->rootoid, iwalk->rootoidlen); } else { mib->loadstatus = MIB_STATUS_LOADFAILED; if (verbose) { errprintf("Cannot determine OID for %s\n", iwalk->keyoid); snmp_perror("read_objid"); } } } mib->loadstatus = MIB_STATUS_LOADED; } /* * * Config file syntax * * [HOSTNAME] * ip=ADDRESS[:PORT] * version=VERSION * community=COMMUNITY * username=USERNAME * passphrase=PASSPHRASE * authmethod=[MD5|SHA1] * mibname1[=index] * mibname2[=index] * mibname3[=index] * */ static oid_t *make_oitem(mibdef_t *mib, char *devname, oidds_t *oiddef, char *oidstr, struct req_t *reqitem) { oid_t *oitem = (oid_t *)calloc(1, sizeof(oid_t)); oitem->mib = mib; oitem->devname = strdup(devname); oitem->setnumber = reqitem->setnumber; oitem->oiddef = oiddef; oitem->OidLen = sizeof(oitem->Oid)/sizeof(oitem->Oid[0]); if (read_objid(oidstr, oitem->Oid, &oitem->OidLen)) { if (!reqitem->oidhead) reqitem->oidhead = oitem; else reqitem->oidtail->next = oitem; reqitem->oidtail = oitem; } else { /* Could not parse the OID definition */ errprintf("Cannot determine OID for %s\n", oidstr); snmp_perror("read_objid"); xfree(oitem->devname); xfree(oitem); } return oitem; } void readconfig(char *cfgfn, int verbose) { static void *cfgfiles = NULL; FILE *cfgfd; strbuffer_t *inbuf; struct req_t *reqitem = NULL; int tasksleep = atoi(xgetenv("TASKSLEEP")); mibdef_t *mib; /* Check if config was modified */ if (cfgfiles) { if (!stackfmodified(cfgfiles)) { dbgprintf("No files changed, skipping reload\n"); return; } else { stackfclist(&cfgfiles); cfgfiles = NULL; } } cfgfd = stackfopen(cfgfn, "r", &cfgfiles); if (cfgfd == NULL) { errprintf("Cannot open configuration files %s\n", cfgfn); return; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *bot, *p, *mibidx; char savech; sanitize_input(inbuf, 0, 0); bot = STRBUF(inbuf) + strspn(STRBUF(inbuf), " \t"); if ((*bot == '\0') || (*bot == '#')) continue; if (*bot == '[') { char *intvl = strchr(bot, '/'); /* * See if we're running a non-standard interval. * If yes, then process only the records that match * this TASKSLEEP setting. */ if (tasksleep != 300) { /* Non-default interval. Skip the host if it HASN'T got an interval setting */ if (!intvl) continue; /* Also skip the hosts that have an interval different from the current */ *intvl = '\0'; /* Clip the interval from the hostname */ if (atoi(intvl+1) != tasksleep) continue; } else { /* Default interval. Skip the host if it HAS an interval setting */ if (intvl) continue; } reqitem = (req_t *)calloc(1, sizeof(req_t)); p = strchr(bot, ']'); if (p) *p = '\0'; reqitem->hostname = strdup(bot + 1); if (p) *p = ']'; reqitem->hostip[0] = reqitem->hostname; reqitem->version = SNMP_VERSION_1; reqitem->authmethod = SNMP_V3AUTH_MD5; reqitem->next = reqhead; reqhead = reqitem; continue; } /* If we have nowhere to put the data, then skip further processing */ if (!reqitem) continue; if (strncmp(bot, "ip=", 3) == 0) { char *nextip = strtok(strdup(bot+3), ","); int i = 0; do { reqitem->hostip[i++] = nextip; nextip = strtok(NULL, ","); } while (nextip); continue; } if (strncmp(bot, "version=", 8) == 0) { switch (*(bot+8)) { case '1': reqitem->version = SNMP_VERSION_1; break; case '2': reqitem->version = SNMP_VERSION_2c; break; case '3': reqitem->version = SNMP_VERSION_3; break; } continue; } if (strncmp(bot, "community=", 10) == 0) { reqitem->community = strdup(bot+10); continue; } if (strncmp(bot, "username=", 9) == 0) { reqitem->username = strdup(bot+9); continue; } if (strncmp(bot, "passphrase=", 11) == 0) { reqitem->passphrase = strdup(bot+11); continue; } if (strncmp(bot, "authmethod=", 11) == 0) { if (strcasecmp(bot+11, "md5") == 0) reqitem->authmethod = SNMP_V3AUTH_MD5; else if (strcasecmp(bot+11, "sha1") == 0) reqitem->authmethod = SNMP_V3AUTH_SHA1; else errprintf("Unknown SNMPv3 authentication method '%s'\n", bot+11); continue; } /* Custom mibs */ p = bot + strcspn(bot, "= \t\r\n"); savech = *p; *p = '\0'; mib = find_mib(bot); *p = savech; p += strspn(p, "= \t"); mibidx = p; if (mib) { int i; mibidx_t *iwalk = NULL; char *oid; SBUF_DEFINE(oidbuf); char *devname; oidset_t *swalk; setupmib(mib, verbose); if (mib->loadstatus != MIB_STATUS_LOADED) continue; /* Cannot use this MIB */ /* See if this is an entry where we must determine the index ourselves */ if (*mibidx) { for (iwalk = mib->idxlist; (iwalk && (*mibidx != iwalk->marker)); iwalk = iwalk->next) ; } if ((*mibidx == '*') && !iwalk) { errprintf("Cannot do wildcard matching without an index (host %s, mib %s)\n", reqitem->hostname, mib->mibname); continue; } if (!iwalk) { /* No key lookup */ swalk = mib->oidlisthead; while (swalk) { reqitem->setnumber++; for (i=0; (i <= swalk->oidcount); i++) { if (*mibidx) { SBUF_MALLOC(oidbuf, strlen(swalk->oids[i].oid) + strlen(mibidx) + 2); oid = oidbuf; snprintf(oidbuf, oidbuf_buflen, "%s.%s", swalk->oids[i].oid, mibidx); devname = mibidx; } else { oid = swalk->oids[i].oid; oidbuf = NULL; oidbuf_buflen = 0; devname = "-"; } make_oitem(mib, devname, &swalk->oids[i], oid, reqitem); if (oidbuf) xfree(oidbuf); } swalk = swalk->next; } reqitem->next_oid = reqitem->oidhead; } else { /* Add a key-record so we can try to locate the index */ keyrecord_t *newitem = (keyrecord_t *)calloc(1, sizeof(keyrecord_t)); char endmarks[6]; mibidx++; /* Skip the key-marker */ snprintf(endmarks, sizeof(endmarks), "%s%c", ")]}>", iwalk->marker); p = mibidx + strcspn(mibidx, endmarks); *p = '\0'; newitem->key = strdup(mibidx); newitem->indexmethod = iwalk; newitem->mib = mib; newitem->next = reqitem->keyrecords; reqitem->currentkey = reqitem->keyrecords = newitem; } continue; } else { errprintf("Unknown MIB (not in snmpmibs.cfg): '%s'\n", bot); } } stackfclose(cfgfd); freestrbuffer(inbuf); } void communicate(void) { /* loop while any active requests */ while (active_requests) { int fds = 0, block = 1; fd_set fdset; struct timeval timeout; FD_ZERO(&fdset); snmp_select_info(&fds, &fdset, &timeout, &block); fds = select(fds, &fdset, NULL, NULL, block ? NULL : &timeout); if (fds < 0) { perror("select failed"); exit(1); } if (fds) snmp_read(&fdset); else snmp_timeout(); } } void resolvekeys(void) { req_t *rwalk; keyrecord_t *kwalk; oidset_t *swalk; int i; SBUF_DEFINE(oid); /* Fetch the key data, and determine the indices we want to use */ dataoperation = GET_KEYS; starthosts(1); communicate(); /* Generate new requests for the datasets we now know the indices of */ for (rwalk = reqhead; (rwalk); rwalk = rwalk->next) { if (!rwalk->keyrecords) continue; for (kwalk = rwalk->keyrecords; (kwalk); kwalk = kwalk->next) { if (!kwalk->indexoid) { /* Don't report failed lookups for the pseudo match-all key record */ if (*kwalk->key != '*') { /* We failed to determine the index */ errprintf("Could not determine index for host=%s mib=%s key=%s\n", rwalk->hostname, kwalk->mib->mibname, kwalk->key); } continue; } swalk = kwalk->mib->oidlisthead; while (swalk) { rwalk->setnumber++; for (i=0; (i <= swalk->oidcount); i++) { SBUF_MALLOC(oid, strlen(swalk->oids[i].oid) + strlen(kwalk->indexoid) + 2); snprintf(oid, oid_buflen, "%s.%s", swalk->oids[i].oid, kwalk->indexoid); make_oitem(kwalk->mib, kwalk->key, &swalk->oids[i], oid, rwalk); xfree(oid); } swalk = swalk->next; } rwalk->next_oid = rwalk->oidhead; } } } void getdata(void) { dataoperation = GET_DATA; starthosts(1); communicate(); } void sendresult(void) { struct req_t *rwalk; struct oid_t *owalk; char msgline[1024]; char *currdev, *currhost; mibdef_t *mib; strbuffer_t *clientmsg = newstrbuffer(0); int havemsg = 0; int itemcount = 0; currhost = ""; for (rwalk = reqhead; (rwalk); rwalk = rwalk->next) { if (strcmp(rwalk->hostname, currhost) != 0) { /* Flush buffer */ if (havemsg) { snprintf(msgline, sizeof(msgline), "\n.\n", itemcount); addtobuffer(clientmsg, msgline); sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL); } clearstrbuffer(clientmsg); havemsg = 0; itemcount = 0; snprintf(msgline, sizeof(msgline), "client/snmpcollect %s.snmpcollect snmp\n\n", rwalk->hostname); addtobuffer(clientmsg, msgline); } currdev = ""; for (mib = first_mib(); (mib); mib = next_mib()) { clearstrbuffer(mib->resultbuf); mib->haveresult = 0; snprintf(msgline, sizeof(msgline), "\n[%s]\nInterval=%d\nActiveIP=%s\n\n", mib->mibname, atoi(xgetenv("TASKSLEEP")), rwalk->hostip[rwalk->hostipidx]); addtobuffer(mib->resultbuf, msgline); } for (owalk = rwalk->oidhead; (owalk); owalk = owalk->next) { if (strcmp(currdev, owalk->devname)) { currdev = owalk->devname; /* OK, because ->devname is permanent */ if (*owalk->devname && (*owalk->devname != '-') ) { addtobuffer(owalk->mib->resultbuf, "\n<"); addtobuffer(owalk->mib->resultbuf, owalk->devname); addtobuffer(owalk->mib->resultbuf, ">\n"); itemcount++; } } addtobuffer(owalk->mib->resultbuf, "\t"); addtobuffer(owalk->mib->resultbuf, owalk->oiddef->dsname); addtobuffer(owalk->mib->resultbuf, " = "); if (owalk->result) { int ival; unsigned int uval; switch (owalk->oiddef->conversion) { case OID_CONVERT_U32: ival = atoi(owalk->result); memcpy(&uval, &ival, sizeof(uval)); snprintf(msgline, sizeof(msgline), "%u", uval); addtobuffer(owalk->mib->resultbuf, msgline); break; default: addtobuffer(owalk->mib->resultbuf, owalk->result); break; } } else addtobuffer(owalk->mib->resultbuf, "NODATA"); addtobuffer(owalk->mib->resultbuf, "\n"); owalk->mib->haveresult = 1; } for (mib = first_mib(); (mib); mib = next_mib()) { if (mib->haveresult) { addtostrbuffer(clientmsg, mib->resultbuf); havemsg = 1; } } } if (havemsg) { sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL); } freestrbuffer(clientmsg); } void egoresult(int color, char *egocolumn) { char msgline[1024]; char *timestamps = NULL; init_timestamp(); combo_start(); init_status(color); snprintf(msgline, sizeof(msgline), "status %s.%s %s snmpcollect %s\n\n", xgetenv("MACHINE"), egocolumn, colorname(color), timestamp); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "Variables : %d\n", varcount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "PDUs : %d\n", pducount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "Responses : %d\n", okcount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "Timeouts : %d\n", timeoutcount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "Too big : %d\n", toobigcount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "Errors : %d\n", errorcount); addtostatus(msgline); show_timestamps(×tamps); if (timestamps) { addtostatus(timestamps); xfree(timestamps); } finish_status(); combo_end(); } int main (int argc, char **argv) { int argi; SBUF_DEFINE(configfn); int cfgcheck = 0; int mibcheck = 0; for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--no-update") == 0) { dontsendmessages = 1; } else if (strcmp(argv[argi], "--cfgcheck") == 0) { cfgcheck = 1; } else if (strcmp(argv[argi], "--mibcheck") == 0) { mibcheck = 1; } else if (argnmatch(argv[argi], "--timeout=")) { char *p = strchr(argv[argi], '='); timeout = 1000000*atoi(p+1); } else if (argnmatch(argv[argi], "--retries=")) { char *p = strchr(argv[argi], '='); retries = atoi(p+1); } else if (argnmatch(argv[argi], "--concurrency=")) { char *p = strchr(argv[argi], '='); max_pending_requests = atoi(p+1); } else if (argnmatch(argv[argi], "--report=")) { char *p = strchr(argv[argi], '='); reportcolumn = strdup(p+1); timing = 1; } else if (*argv[argi] != '-') { configfn = strdup(argv[argi]); configfn_buflen = strlen(configfn)+1; } } add_timestamp("xymon-snmpcollect startup"); netsnmp_register_loghandler(NETSNMP_LOGHANDLER_STDERR, 7); init_snmp("xymon-snmpcollect"); snmp_mib_toggle_options("e"); /* Like -Pe: Don't show MIB parsing errors */ snmp_out_toggle_options("qn"); /* Like -Oqn: OID's printed as numbers, values printed without type */ readmibs(NULL, mibcheck); if (configfn == NULL) { configfn = (char *)malloc(PATH_MAX); snprintf(configfn, configfn_buflen, "%s/etc/snmphosts.cfg", xgetenv("XYMONHOME")); } readconfig(configfn, mibcheck); if (cfgcheck) return 0; add_timestamp("Configuration loaded"); resolvekeys(); add_timestamp("Keys lookup complete"); getdata(); stophosts(); add_timestamp("Data retrieved"); sendresult(); add_timestamp("Results transmitted"); if (reportcolumn) egoresult(COL_GREEN, reportcolumn); xfree(configfn); return 0; } xymon-4.3.30/xymonnet/beastat.c0000664000076400007640000002320113515623702016655 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor BEA statistics tool. */ /* */ /* This is used to collect statistics from a BEA Weblogic server */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: beastat.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "version.h" typedef struct bea_idx_t { char *idx; struct bea_idx_t *next; } bea_idx_t; static bea_idx_t *bea_idxhead = NULL; static char msgline[MAX_LINE_LEN]; static int statuscolor = COL_GREEN; /* Set with environment or command-line options */ static char *location = ""; /* XYMONNETWORK value */ static int testuntagged = 0; static int default_port = 161; static char *default_community = "public"; static int extcmdtimeout = 30; static void find_idxes(char *buf, char *searchstr) { bea_idx_t *idxwalk; char *bol, *eoln, *idxval; /* If we've done it before, clear out the old indexes */ while (bea_idxhead) { idxwalk = bea_idxhead; bea_idxhead = bea_idxhead->next; xfree(idxwalk->idx); xfree(idxwalk); } bea_idxhead = NULL; bol = buf; while ((bol = strstr(bol, searchstr)) != NULL) { idxval = NULL; bol++; eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; bol = strchr(bol, '='); if (bol) bol = strchr(bol, '\"'); if (bol) idxval = bol+1; if (bol) bol = strchr(bol+1, '\"'); if (bol) { *bol = '\0'; idxwalk = (bea_idx_t *)malloc(sizeof(bea_idx_t)); idxwalk->idx = strdup(idxval); idxwalk->next = bea_idxhead; bea_idxhead = idxwalk; *bol = '\"'; } if (eoln) *eoln = '\n'; } } int wanted_host(void *host, char *netstring) { char *netlocation = xmh_item(host, XMH_NET); return ((strlen(netstring) == 0) || /* No XYMONNETWORK = do all */ (netlocation && (strcmp(netlocation, netstring) == 0)) || /* XYMONNETWORK && matching NET: tag */ (testuntagged && (netlocation == NULL))); /* No NET: tag for this host */ } char *getstring(char *databuf, char *beaindex, char *key) { static char result[4096]; char keystr[4096]; char *p, *eol; *result = '\0'; snprintf(keystr, sizeof(keystr), "\nBEA-WEBLOGIC-MIB::%s.\"%s\"", key, beaindex); p = strstr(databuf, keystr); if (!p) { /* Might be at the very beginning of the buffer (with no \n first) */ if (strncmp(databuf, keystr+1, strlen(keystr)-1) == 0) p = databuf; } else { p++; } if (p) { eol = strchr(p, '\n'); if (eol) *eol = '\0'; strncpy(result, p, sizeof(result)); if (eol) *eol = '\n'; } return result; } char *jrockitems[] = { "jrockitRuntimeIndex", "jrockitRuntimeParent", "jrockitRuntimeFreeHeap", "jrockitRuntimeUsedHeap", "jrockitRuntimeTotalHeap", "jrockitRuntimeFreePhysicalMemory", "jrockitRuntimeUsedPhysicalMemory", "jrockitRuntimeTotalPhysicalMemory", "jrockitRuntimeTotalNumberOfThreads", "jrockitRuntimeNumberOfDaemonThreads", "jrockitRuntimeTotalNurserySize", NULL }; char *qitems[] = { "executeQueueRuntimeIndex", "executeQueueRuntimeName", "executeQueueRuntimeParent", "executeQueueRuntimeExecuteThreadCurrentIdleCount", "executeQueueRuntimePendingRequestCurrentCount", "executeQueueRuntimeServicedRequestTotalCount", NULL }; void send_data(void *host, char *beadomain, char *databuf, char **items) { bea_idx_t *idxwalk; strbuffer_t *msgbuf; char *p; int i; msgbuf = newstrbuffer(0); for (idxwalk = bea_idxhead; (idxwalk); idxwalk = idxwalk->next) { snprintf(msgline, sizeof(msgline), "data %s.bea\n\n", commafy(xmh_item(host, XMH_HOSTNAME))); addtobuffer(msgbuf, msgline); if (beadomain && *beadomain) { snprintf(msgline, sizeof(msgline), "DOMAIN:%s\n", beadomain); addtobuffer(msgbuf, msgline); } for (i=0; (items[i]); i++) { p = getstring(databuf, idxwalk->idx, items[i]); snprintf(msgline, sizeof(msgline), "%s\n", p); addtobuffer(msgbuf, msgline); } sendmessage(STRBUF(msgbuf), NULL, XYMON_TIMEOUT, NULL); clearstrbuffer(msgbuf); } freestrbuffer(msgbuf); } int main(int argc, char *argv[]) { void *hwalk; int argi; strbuffer_t *statusmsg, *jrockout, *qout; for (argi = 1; (argi < argc); argi++) { if ((strcmp(argv[argi], "--help") == 0)) { printf("beastat version %s\n\n", VERSION); printf("Usage:\n%s [--debug] [--no-update] [--port=SNMPPORT] [--community=SNMPCOMMUNITY]\n", argv[0]); exit(0); } else if ((strcmp(argv[argi], "--version") == 0)) { printf("beastat version %s\n", VERSION); exit(0); } else if ((strcmp(argv[argi], "--debug") == 0)) { debug = 1; } else if ((strcmp(argv[argi], "--no-update") == 0)) { dontsendmessages = 1; } else if (argnmatch(argv[argi], "--timeout=")) { char *p = strchr(argv[argi], '='); extcmdtimeout = atoi(p+1); } else if (argnmatch(argv[argi], "--port=")) { char *p = strchr(argv[argi], '='); default_port = atoi(p+1); } else if (argnmatch(argv[argi], "--community=")) { char *p = strchr(argv[argi], '='); default_community = strdup(p+1); } } load_hostnames(xgetenv("HOSTSCFG"), "netinclude", get_fqdn()); if (first_host() == NULL) { errprintf("Cannot load file %s\n", xgetenv("HOSTSCFG")); return 1; } if (xgetenv("XYMONNETWORK") && (strlen(xgetenv("XYMONNETWORK")) > 0)) location = strdup(xgetenv("XYMONNETWORK")); else if (xgetenv("BBLOCATION") && (strlen(xgetenv("BBLOCATION")) > 0)) location = strdup(xgetenv("BBLOCATION")); init_timestamp(); combo_start(); statusmsg = newstrbuffer(0); jrockout = newstrbuffer(0); qout = newstrbuffer(0); for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { char *tspec = xmh_custom_item(hwalk, "bea="); char *snmpcommunity = default_community; char *beadomain = ""; int snmpport = default_port; char *p; char pipecmd[4096]; int jrockres, qres; clearstrbuffer(statusmsg); clearstrbuffer(jrockout); clearstrbuffer(qout); /* Check if we have a "bea" test for this host, and it is a host we want to test */ if (!tspec || !wanted_host(hwalk, location)) continue; /* Parse the testspec: bea=[SNMPCOMMUNITY@]BEADOMAIN[:SNMPPORT] */ tspec = strdup(tspec+strlen("bea=")); p = strchr(tspec, ':'); if (p) { *p = '\0'; snmpport = atoi(p+1); } p = strchr(tspec, '@'); if (p) { *p = '\0'; snmpcommunity = strdup(tspec); beadomain = strdup(p+1); } else { beadomain = strdup(tspec); } /* Prepare for the host status */ statuscolor = COL_GREEN; /* Setup the snmpwalk pipe-command for jrockit stats */ snprintf(pipecmd, sizeof(pipecmd), "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.302.1", snmpcommunity, beadomain, xmh_item(hwalk, XMH_IP), snmpport); jrockres = run_command(pipecmd, NULL, jrockout, 0, extcmdtimeout); if (jrockres == 0) { find_idxes(STRBUF(jrockout), "BEA-WEBLOGIC-MIB::jrockitRuntimeIndex."); send_data(hwalk, beadomain, STRBUF(jrockout), jrockitems); } else { if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW; snprintf(msgline, sizeof(msgline), "Could not retrieve BEA jRockit statistics from %s:%d domain %s (code %d)\n", xmh_item(hwalk, XMH_IP), snmpport, beadomain, jrockres); addtobuffer(statusmsg, msgline); } /* Setup the snmpwalk pipe-command for executeQueur stats */ snprintf(pipecmd, sizeof(pipecmd), "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.180.1", snmpcommunity, beadomain, xmh_item(hwalk, XMH_IP), snmpport); qres = run_command(pipecmd, NULL, qout, 0, extcmdtimeout); if (qres == 0) { find_idxes(STRBUF(qout), "BEA-WEBLOGIC-MIB::executeQueueRuntimeIndex."); send_data(hwalk, beadomain, STRBUF(qout), qitems); } else { if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW; snprintf(msgline, sizeof(msgline), "Could not retrieve BEA executeQueue statistics from %s:%d domain %s (code %d)\n", xmh_item(hwalk, XMH_IP), snmpport, beadomain, qres); addtobuffer(statusmsg, msgline); } /* FUTURE: Have the statuscolor/statusmsg be updated to check against thresholds */ /* Right now, the "bea" status is always green */ init_status(statuscolor); snprintf(msgline, sizeof(msgline), "status %s.%s %s %s\n\n", commafy(xmh_item(hwalk, XMH_HOSTNAME)), "bea", colorname(statuscolor), timestamp); addtostatus(msgline); if (STRBUFLEN(statusmsg) == 0) addtobuffer(statusmsg, "All BEA monitors OK\n"); addtostrstatus(statusmsg); finish_status(); } combo_end(); freestrbuffer(statusmsg); freestrbuffer(jrockout); freestrbuffer(qout); return 0; } xymon-4.3.30/xymonnet/httpresult.c0000664000076400007640000004761013515623702017462 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of HTTP service. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: httpresult.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" #include "xymonnet.h" #include "contest.h" #include "httpcookies.h" #include "httpresult.h" static int statuscolor(testedhost_t *h, int status) { int result = COL_YELLOW; /* Default behavior is to treat HTTP codes as follows: * <100 = connection error (clear if dialup, otherwise red) * 1xx = yellow (xymonnet will handle 100 Continues already, so if we're here then something went wrong) * 2xx = green * 3xx = yellow * 4xx/5xx = red * Exceptions are listed below. * * TODO: Site-specific defaults; extending 'httpstatus' to be layered ontop of other http modifiers */ switch(status) { case 200: /* OK - most common case */ case 302: /* Temp Redirect */ case 303: /* See Other */ case 307: /* Temp Redirect (HTTP 1.1) */ result = COL_GREEN; break; case 306: /* Defunct HTTP response */ result = COL_RED; break; case STATUS_CONTENTMATCH_FAILED: result = COL_RED; /* Pseudo status: content match fails */ break; case STATUS_CONTENTMATCH_BADREGEX: /* Pseudo status: bad regex to match against */ case STATUS_CONTENTMATCH_NOFILE: /* Pseudo status: content match requested, but no match-file */ result = COL_YELLOW; break; case 000: /* transport layer reports error */ result = (h->dialup ? COL_CLEAR : COL_RED); break; default: /* Unknown or custom status */ result = (status < 100) ? (h->dialup ? COL_CLEAR : COL_RED) : (status < 200) ? COL_YELLOW : (status < 300) ? COL_GREEN : (status < 400) ? COL_YELLOW : COL_RED; break; } return result; } static int statuscolor_by_set(testedhost_t *h, int status, char *okcodes, char *badcodes) { int result = -1; char codestr[15]; pcre *ptn; /* Use code 999 to indicate we could not fetch the URL */ snprintf(codestr, sizeof(codestr), "%d", (status ? status : 999)); if (okcodes) { ptn = compileregex(okcodes); if (matchregex(codestr, ptn)) result = COL_GREEN; else result = COL_RED; freeregex(ptn); } if (badcodes) { ptn = compileregex(badcodes); if (matchregex(codestr, ptn)) result = COL_RED; else result = COL_GREEN; freeregex(ptn); } if (result == -1) result = statuscolor(h, status); dbgprintf("Host %s status %s [%s:%s] -> color %s\n", h->hostname, codestr, (okcodes ? okcodes : ""), (badcodes ? badcodes : ""), colorname(result)); return result; } void send_http_results(service_t *httptest, testedhost_t *host, testitem_t *firsttest, char *nonetpage, int failgoesclear, int usebackfeedqueue) { testitem_t *t; int color = -1; char *svcname; strbuffer_t *msgtext; SBUF_DEFINE(nopagename); int nopage = 0; int anydown = 0, totalreports = 0; if (firsttest == NULL) return; svcname = strdup(httptest->testname); if (httptest->namelen) svcname[httptest->namelen] = '\0'; /* Check if this service is a NOPAGENET service. */ SBUF_MALLOC(nopagename, strlen(svcname)+3); snprintf(nopagename, nopagename_buflen, ",%s,", svcname); nopage = (strstr(nonetpage, nopagename) != NULL); xfree(nopagename); dbgprintf("Calc http color host %s : ", host->hostname); msgtext = newstrbuffer(0); for (t=firsttest; (t && (t->host == host)); t = t->next) { http_data_t *req = (http_data_t *) t->privdata; /* Skip the data-reports for now */ if (t->senddata) continue; /* Grab session cookies */ update_session_cookies(host->hostname, req->weburl.desturl->host, req->headers); totalreports++; if (req->weburl.okcodes || req->weburl.badcodes) { req->httpcolor = statuscolor_by_set(host, req->httpstatus, req->weburl.okcodes, req->weburl.badcodes); } else { req->httpcolor = statuscolor(host, req->httpstatus); } if (req->httpcolor == COL_RED) anydown++; /* Dialup hosts and dialup tests report red as clear */ if ((req->httpcolor != COL_GREEN) && (host->dialup || t->dialup)) req->httpcolor = COL_CLEAR; /* If ping failed, report CLEAR unless alwaystrue */ if ( ((req->httpcolor == COL_RED) || (req->httpcolor == COL_YELLOW)) && /* Test failed */ (host->downcount > 0) && /* The ping check did fail */ (!host->noping && !host->noconn) && /* We are doing a ping test */ (failgoesclear) && (!t->alwaystrue) ) /* No "~testname" flag */ { req->httpcolor = COL_CLEAR; } /* If test we depend on has failed, report CLEAR unless alwaystrue */ if ( ((req->httpcolor == COL_RED) || (req->httpcolor == COL_YELLOW)) && /* Test failed */ failgoesclear && !t->alwaystrue ) /* No "~testname" flag */ { char *faileddeps = deptest_failed(host, t->service->testname); if (faileddeps) { req->httpcolor = COL_CLEAR; req->faileddeps = strdup(faileddeps); } } dbgprintf("%s(%s) ", t->testspec, colorname(req->httpcolor)); if (req->httpcolor > color) color = req->httpcolor; /* Build the short msgtext which goes on line 1 of the status message. */ addtobuffer(msgtext, (STRBUFLEN(msgtext) ? " ; " : ": ") ); if (req->tcptest->errcode != CONTEST_ENOERROR) { switch (req->tcptest->errcode) { case CONTEST_ETIMEOUT: req->errorcause = "Server timeout"; break; case CONTEST_ENOCONN : req->errorcause = strdup(strerror(req->tcptest->connres)); break; case CONTEST_EDNS : switch (req->parsestatus) { case 1 : req->errorcause = "Invalid URL"; break; case 2 : req->errorcause = "Hostname not in DNS"; break; default: req->errorcause = "DNS error"; break; } break; case CONTEST_EIO : req->errorcause = "I/O error"; break; case CONTEST_ESSL : req->errorcause = "SSL error"; break; default: req->errorcause = "Xfer failed"; } addtobuffer(msgtext, req->errorcause); } else if (req->tcptest->open == 0) { req->errorcause = "Connect failed"; addtobuffer(msgtext, req->errorcause); } else if ((req->httpcolor == COL_RED) || (req->httpcolor == COL_YELLOW)) { char m1[100]; if (req->weburl.okcodes || req->weburl.badcodes) { snprintf(m1, sizeof(m1), "Unwanted HTTP status %d", req->httpstatus); } else if (req->headers) { char *p = req->headers; /* Skip past "HTTP/1.x 200 " and pick up the explanatory text, if any */ if (strncasecmp(p, "http/", 5) == 0) { p += 5; p += strspn(p, "0123456789. "); } strncpy(m1, p, sizeof(m1)-1); m1[sizeof(m1)-1] = '\0'; /* Only show the first line of the HTTP status description */ p = m1 + strcspn(m1, "\n\r"); *p = '\0'; } else { snprintf(m1, sizeof(m1), "Connected, but got empty response (code: %d)", req->httpstatus); } addtobuffer(msgtext, m1); req->errorcause = strdup(m1); } else { addtobuffer(msgtext, "OK"); if (req->weburl.okcodes || req->weburl.badcodes) { char m1[100]; snprintf(m1, sizeof(m1), " (HTTP status %d)", req->httpstatus); addtobuffer(msgtext, m1); } } } /* It could be that we have 0 http tests - if we only do the apache one */ if (totalreports > 0) { char msgline[4096]; if (anydown) { firsttest->downcount++; if(firsttest->downcount == 1) firsttest->downstart = getcurrenttime(NULL); } else firsttest->downcount = 0; /* Handle the "badtest" stuff for http tests */ if ((color == COL_RED) && (firsttest->downcount < firsttest->badtest[2])) { if (firsttest->downcount >= firsttest->badtest[1]) color = COL_YELLOW; else if (firsttest->downcount >= firsttest->badtest[0]) color = COL_CLEAR; else color = COL_GREEN; } if (nopage && (color == COL_RED)) color = COL_YELLOW; dbgprintf(" --> %s\n", colorname(color)); /* Send off the http status report */ init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s", validity, commafy(host->hostname), svcname, colorname(color), timestamp); addtostatus(msgline); addtostrstatus(msgtext); addtostatus("\n"); for (t=firsttest; (t && (t->host == host)); t = t->next) { SBUF_DEFINE(urlmsg); http_data_t *req = (http_data_t *) t->privdata; /* Skip the "data" reports */ if (t->senddata) continue; SBUF_MALLOC(urlmsg, 1024 + strlen(req->url)); snprintf(urlmsg, urlmsg_buflen, "\n&%s %s - ", colorname(req->httpcolor), req->url); addtostatus(urlmsg); if (req->httpcolor == COL_GREEN) addtostatus("OK"); else { if (req->errorcause) addtostatus(req->errorcause); else addtostatus("failed"); } if (req->weburl.okcodes || req->weburl.badcodes) { char m1[100]; snprintf(m1, sizeof(m1), " (HTTP status %d)", req->httpstatus); addtostatus(m1); } addtostatus("\n"); if (req->headers) { addtostatus("\n"); addtostatus(req->headers); } if (req->faileddeps) addtostatus(req->faileddeps); snprintf(urlmsg, urlmsg_buflen, "\nSeconds: %u.%.9ld\n\n", (unsigned int)req->tcptest->totaltime.tv_sec, req->tcptest->totaltime.tv_nsec); addtostatus(urlmsg); xfree(urlmsg); } addtostatus("\n\n"); finish_status(); } /* Send of any HTTP status tests in separate columns */ for (t=firsttest; (t && (t->host == host)); t = t->next) { int color; char msgline[4096]; SBUF_DEFINE(urlmsg); http_data_t *req = (http_data_t *) t->privdata; if ((t->senddata) || (!req->weburl.columnname) || (req->contentcheck != CONTENTCHECK_NONE)) continue; /* Handle the "badtest" stuff */ color = req->httpcolor; if ((color == COL_RED) && (t->downcount < t->badtest[2])) { if (t->downcount >= t->badtest[1]) color = COL_YELLOW; else if (t->downcount >= t->badtest[0]) color = COL_CLEAR; else color = COL_GREEN; } if (nopage && (color == COL_RED)) color = COL_YELLOW; /* Send off the http status report */ init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s", validity, commafy(host->hostname), req->weburl.columnname, colorname(color), timestamp); addtostatus(msgline); addtostatus(" : "); addtostatus(req->errorcause ? req->errorcause : "OK"); if (req->weburl.okcodes || req->weburl.badcodes) { char m1[100]; snprintf(m1, sizeof(m1), " (HTTP status %d)", req->httpstatus); addtostatus(m1); } addtostatus("\n"); SBUF_MALLOC(urlmsg, 1024 + strlen(req->url)); snprintf(urlmsg, urlmsg_buflen, "\n&%s %s - ", colorname(req->httpcolor), req->url); addtostatus(urlmsg); xfree(urlmsg); if (req->httpcolor == COL_GREEN) addtostatus("OK"); else { if (req->errorcause) addtostatus(req->errorcause); else addtostatus("failed"); } addtostatus("\n"); if (req->headers) { addtostatus("\n"); addtostatus(req->headers); } if (req->faileddeps) addtostatus(req->faileddeps); snprintf(msgline, sizeof(msgline), "\nSeconds: %u.%.9ld\n\n", (unsigned int)req->tcptest->totaltime.tv_sec, req->tcptest->totaltime.tv_nsec); addtostatus(msgline); addtostatus("\n\n"); finish_status(); } /* Send off any "data" messages now */ for (t=firsttest; (t && (t->host == host)); t = t->next) { http_data_t *req; char *data = ""; strbuffer_t *msg = newstrbuffer(0); char msgline[1024]; if (!t->senddata) continue; req = (http_data_t *) t->privdata; if (req->output) data = req->output; snprintf(msgline, sizeof(msgline), "data %s.%s\n", commafy(host->hostname), req->weburl.columnname); addtobuffer(msg, msgline); addtobuffer(msg, data); combo_add(msg); freestrbuffer(msg); } xfree(svcname); freestrbuffer(msgtext); } static testitem_t *nextcontenttest(service_t *httptest, testedhost_t *host, testitem_t *current) { testitem_t *result; result = current->next; if ((result == NULL) || (result->host != host)) { result = NULL; } return result; } void send_content_results(service_t *httptest, testedhost_t *host, char *nonetpage, char *contenttestname, int failgoesclear) { testitem_t *t, *firsttest; int color = -1; SBUF_DEFINE(nopagename); int nopage = 0; SBUF_DEFINE(conttest); int contentnum = 0; SBUF_MALLOC(conttest, 128); if (host->firsthttp == NULL) return; /* Check if this service is a NOPAGENET service. */ SBUF_MALLOC(nopagename, strlen(contenttestname)+3); snprintf(nopagename, nopagename_buflen, ",%s,", contenttestname); nopage = (strstr(nonetpage, nopagename) != NULL); xfree(nopagename); dbgprintf("Calc content color host %s : ", host->hostname); firsttest = host->firsthttp; for (t=firsttest; (t && (t->host == host)); t = nextcontenttest(httptest, host, t)) { http_data_t *req = (http_data_t *) t->privdata; void *hinfo = hostinfo(host->hostname); int headermatch = (hinfo && xmh_item(hinfo, XMH_FLAG_HTTP_HEADER_MATCH)); char cause[100]; SBUF_DEFINE(msgline); int got_data = 1; /* Skip the "data"-only messages */ if (t->senddata) continue; if (!req->contentcheck) continue; /* We have a content check */ strncpy(cause, "Content OK", sizeof(cause)); if (req->contstatus == 0) { /* The content check passed initial checks of regexp etc. */ color = statuscolor(t->host, req->httpstatus); if (color == COL_GREEN) { /* We got the data from the server */ regmatch_t foo[1]; int status = 0; switch (req->contentcheck) { case CONTENTCHECK_REGEX: if (headermatch && req->headers) { /* regex() returns 0 on success, REG_NOMATCH on failure */ status = (regexec((regex_t *) req->exp, req->headers, 0, foo, 0) == 0) ? 0 : (req->output && (regexec((regex_t *) req->exp, req->output, 0, foo, 0) == 0)) ? 0 : 1; regfree((regex_t *) req->exp); } else if (req->output) { status = regexec((regex_t *) req->exp, req->output, 0, foo, 0); regfree((regex_t *) req->exp); } else { /* output may be null if we only got a redirect */ status = STATUS_CONTENTMATCH_FAILED; } break; case CONTENTCHECK_NOREGEX: if (headermatch && req->headers) { status = ( (!regexec((regex_t *) req->exp, req->headers, 0, foo, 0)) && (!req->output || (!regexec((regex_t *) req->exp, req->output, 0, foo, 0))) ); regfree((regex_t *) req->exp); } else if (req->output) { status = (!regexec((regex_t *) req->exp, req->output, 0, foo, 0)); regfree((regex_t *) req->exp); } else { /* output may be null if we only got a redirect */ status = STATUS_CONTENTMATCH_FAILED; } break; case CONTENTCHECK_DIGEST: if (req->digest == NULL) req->digest = strdup(""); if (strcmp(req->digest, (char *)req->exp) != 0) { status = STATUS_CONTENTMATCH_FAILED; } else status = 0; req->output = (char *) malloc(strlen(req->digest)+strlen((char *)req->exp)+strlen("Expected:\nGot :\n")+1); sprintf(req->output, "Expected:%s\nGot :%s\n", (char *)req->exp, req->digest); break; case CONTENTCHECK_CONTENTTYPE: if (req->contenttype && (strcasecmp(req->contenttype, (char *)req->exp) == 0)) { status = 0; } else { status = STATUS_CONTENTMATCH_FAILED; } if (req->contenttype == NULL) req->contenttype = strdup("No content-type provdied"); req->output = (char *) malloc(strlen(req->contenttype)+strlen((char *)req->exp)+strlen("Expected content-type: %s\nGot content-type : %s\n")+1); sprintf(req->output, "Expected content-type: %s\nGot content-type : %s\n", (char *)req->exp, req->contenttype); break; } req->contstatus = ((status == 0) ? 200 : STATUS_CONTENTMATCH_FAILED); color = statuscolor(t->host, req->contstatus); if (color != COL_GREEN) strncpy(cause, "Content match failed", sizeof(cause)); } else { /* * Failed to retrieve the webpage. * Report CLEAR, unless "alwaystrue" is set. */ if (failgoesclear && !t->alwaystrue) color = COL_CLEAR; got_data = 0; strncpy(cause, "Failed to get webpage", sizeof(cause)); } if (nopage && (color == COL_RED)) color = COL_YELLOW; } else { /* This only happens upon internal errors in Xymon test system */ color = statuscolor(t->host, req->contstatus); strncpy(cause, "Internal Xymon error", sizeof(cause)); } /* Send the content status message */ dbgprintf("Content check on %s is %s\n", req->url, colorname(color)); if (req->weburl.columnname) { strncpy(conttest, req->weburl.columnname, conttest_buflen); } else { if (contentnum > 0) snprintf(conttest, conttest_buflen, "%s%d", contenttestname, contentnum); else strncpy(conttest, contenttestname, conttest_buflen); contentnum++; } SBUF_MALLOC(msgline, 4096 + (2 * strlen(req->url))); init_status(color); snprintf(msgline, msgline_buflen, "status+%d %s.%s %s %s: %s\n", validity, commafy(host->hostname), conttest, colorname(color), timestamp, cause); addtostatus(msgline); if (!got_data) { if (host->hidehttp) { snprintf(msgline, msgline_buflen, "\nContent check failed\n"); } else { snprintf(msgline, msgline_buflen, "\nAn error occurred while testing URL %s\n", req->url, req->url); } } else { if (host->hidehttp) { snprintf(msgline, msgline_buflen, "\n&%s Content check %s\n", colorname(color), ((color == COL_GREEN) ? "OK" : "Failed")); } else { snprintf(msgline, msgline_buflen, "\n&%s %s - Testing URL yields:\n", colorname(color), req->url, req->url); } } addtostatus(msgline); xfree(msgline); addtostatus("\n"); if (headermatch && req->headers) { addtostatus(req->headers); addtostatus("\n"); } if (req->output == NULL) { addtostatus("\nNo body output received from server\n\n"); } else if (!host->hidehttp) { /* Don't flood xymond with data */ if (req->outlen > MAX_CONTENT_DATA) { *(req->output + MAX_CONTENT_DATA) = '\0'; req->outlen = MAX_CONTENT_DATA; } if ( (req->contenttype && (strncasecmp(req->contenttype, "text/html", 9) == 0)) || (strncasecmp(req->output, "output, "output, "'); if (p) bodystart = (p+1); } else bodystart = req->output; bodyend = strstr(bodystart, "\n"); addtostatus(bodystart); addtostatus("\n\n"); } else { addtostatus(req->output); } } addtostatus("\n\n"); finish_status(); } xfree(conttest); } void show_http_test_results(service_t *httptest) { http_data_t *req; testitem_t *t; for (t = httptest->items; (t); t = t->next) { req = (http_data_t *) t->privdata; printf("URL : %s\n", req->url); printf("HTTP status : %d\n", req->httpstatus); printf("HTTP headers\n%s\n", textornull(req->headers)); printf("HTTP output\n%s\n", textornull(req->output)); printf("------------------------------------------------------\n"); } } xymon-4.3.30/xymonnet/httptest.h0000664000076400007640000000214411615341300017107 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of a HTTP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __HTTPTESTT_H_ #define __HTTPTEST_H_ extern int tcp_http_data_callback(unsigned char *buf, unsigned int len, void *priv); extern void tcp_http_final_callback(void *priv); extern void add_http_test(testitem_t *t); #endif xymon-4.3.30/xymonnet/Makefile0000664000076400007640000001131112473547104016530 0ustar rpmbuildrpmbuild# Xymon - xymonnet Makefile XYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(ZLIBLIBS) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) # ARES settings. c-ares is included ifeq ($(SYSTEMCARES),no) CARESINC = -I./c-ares CARESLIBS = libcares.a LOCALCARES = libcares.a endif PROGRAMS = xymonnet xymonping beastat EXTENSIONS = xymonnet-again.sh SNMPPROGRAMS = xymon-snmpcollect DBGTOOLS = contest ifeq ($(DOSNMP),yes) PROGRAMS += $(SNMPPROGRAMS) endif all: $(PROGRAMS) $(EXTENSIONS) $(DBGTOOLS) NETTESTOBJS = xymonnet.o contest.o httptest.o httpresult.o ldaptest.o dns.o dns2.o httpcookies.o PINGTESTOBJS = xymonping.o BEASTATOBJS = beastat.o xymonnet: $(NETTESTOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(XYMONLIBS) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(NETTESTOBJS) $(CARESLIBS) $(LDAPLIBS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(XYMONLIBS) $(PCRELIBS) xymonping: $(PINGTESTOBJS) $(XYMONTIMELIB) ../lib/libxymon.a $(CC) $(CFLAGS) -o $@ $(PINGTESTOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) xymonnet.o: xymonnet.c $(CC) $(CFLAGS) $(SSLFLAGS) $(LDAPFLAGS) $(SSLINCDIR) $(LDAPINCDIR) -c -o $@ xymonnet.c ldaptest.o: ldaptest.c $(CC) $(CFLAGS) $(LDAPFLAGS) $(LDAPINCDIR) -c -o $@ ldaptest.c httptest.o: httptest.c $(CC) $(CFLAGS) $(SSLFLAGS) $(SSLINCDIR) -c -o $@ httptest.c httpresult.o: httpresult.c $(CC) $(CFLAGS) $(SSLFLAGS) $(SSLINCDIR) -c -o $@ httpresult.c contest.o: contest.c $(CC) $(CFLAGS) $(SSLFLAGS) $(SSLINCDIR) -c -o $@ contest.c dns.o: $(LOCALCARES) dns.c $(CC) $(CFLAGS) $(CARESINC) -c -o $@ dns.c dns2.o: dns2.c $(CC) $(CFLAGS) $(CARESINC) -c -o $@ dns2.c libcares.a: c-ares/.libs/libcares.a ranlib c-ares/.libs/libcares.a || echo "ranlib failure - ignored" cp c-ares/.libs/libcares.a . c-ares/.libs/libcares.a: c-ares/Makefile (cd c-ares && $(MAKE)) c-ares/Makefile: c-ares/configure (cd c-ares && ../c-ares-shim.sh ./configure --disable-shared) c-ares/configure: c-ares-$(ARESVER).tar.gz gzip -dc $< | tar xf - mv c-ares-$(ARESVER) c-ares # Must touch "configure", or it will trigger a rebuild because it is older than the tar.gz file. touch c-ares/configure beastat: $(BEASTATOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(BEASTATOBJS) $(XYMONCOMMLIBS) $(XYMONTIMELIBS) $(PCRELIBS) beastat.o: beastat.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ beastat.c contest: contest.c httptest.o dns.o dns2.o httpcookies.o $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(CFLAGS) -o contest -I../include $(CARESINC) -DSTANDALONE contest.c httptest.o dns.o dns2.o httpcookies.o $(CARESLIBS) $(XYMONCOMMLIBS) $(XYMONTIMELIBS) xymon-snmpcollect: xymon-snmpcollect.o $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ xymon-snmpcollect.o `net-snmp-config --libs` ../lib/libxymon.a $(XYMONCOMMLIBS) $(XYMONTIMELIBS) xymon-snmpcollect.o: xymon-snmpcollect.c $(CC) $(CFLAGS) -I. `net-snmp-config --cflags` -c -o $@ xymon-snmpcollect.c ################################################ # Default compilation rules ################################################ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< %.sh: %.sh.DIST cat $< | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@RUNTIMEDEFS@!$(RUNTIMEDEFS)!g' >$@ chmod 755 $@ clean: rm -f *.o *.a *~ $(PROGRAMS) $(EXTENSIONS) $(DBGTOOLS) install: install-bin install-ext install-config install-man install-bin: $(PROGRAMS) ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ install-ext: $(EXTENSIONS) ifndef PKGBUILD chown $(XYMONUSER) $(EXTENSIONS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(EXTENSIONS) chmod 755 $(EXTENSIONS) endif cp -fp $(EXTENSIONS) $(INSTALLROOT)$(INSTALLEXTDIR)/ install-config: ../build/convert-bbservices $(INSTALLROOT)$(INSTALLETCDIR)/protocols.cfg ../build/merge-sects protocols.cfg $(INSTALLROOT)$(INSTALLETCDIR)/protocols.cfg ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLETCDIR)/protocols.cfg chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLETCDIR)/protocols.cfg chmod 644 $(INSTALLROOT)$(INSTALLETCDIR)/protocols.cfg endif install-man: ifndef PKGBUILD chown $(XYMONUSER) *.1 *.5 chgrp `$(IDTOOL) -g $(XYMONUSER)` *.1 *.5 chmod 644 *.1 *.5 endif mkdir -p $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 chmod 755 $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 endif cp -fp *.1 $(INSTALLROOT)$(MANROOT)/man1/ cp -fp *.5 $(INSTALLROOT)$(MANROOT)/man5/ xymon-4.3.30/xymonnet/httptest.c0000664000076400007640000005127613515623702017126 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of HTTP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: httptest.c 8069 2019-07-23 15:29:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "version.h" #include "libxymon.h" #include "xymonnet.h" #include "contest.h" #include "httpcookies.h" #include "httptest.h" #include "dns.h" int tcp_http_data_callback(unsigned char *buf, unsigned int len, void *priv) { /* * This callback receives data from HTTP servers. * While doing that, it splits out the data into a * buffer for the HTTP headers, and a buffer for the * HTTP content-data. * Return 1 if data is complete, 0 if more data wanted. */ http_data_t *item = (http_data_t *) priv; if (item->gotheaders) { unsigned int len1chunk = 0; int i; /* * We already have the headers, so just stash away the data */ while (len > 0) { dbgprintf("HDC IN : state=%d, leftinchunk=%d, len=%d\n", item->chunkstate, item->leftinchunk, len); switch (item->chunkstate) { case CHUNK_NOTCHUNKED: len1chunk = len; if ((item->contlen > 0) && (item->contlen >= len)) item->contlen -= len; break; case CHUNK_INIT: /* We're about to pick up a chunk length */ item->leftinchunk = 0; item->chunkstate = CHUNK_GETLEN; len1chunk = 0; break; case CHUNK_GETLEN: /* We are collecting the length of the chunk */ i = hexvalue(*buf); if (i == -1) { item->chunkstate = CHUNK_SKIPLENCR; } else { item->leftinchunk = item->leftinchunk*16 + i; buf++; len--; } len1chunk = 0; break; case CHUNK_SKIPLENCR: /* We've got the length, now skip to the next LF */ if (*buf == '\n') { buf++; len--; item->chunkstate = ((item->leftinchunk > 0) ? CHUNK_DATA : CHUNK_NOMORE); } else if ((*buf == '\r') || (*buf == ' ')) { buf++; len--; } else { errprintf("Yikes - strange data following chunk len. Saw a '%c'\n", *buf); buf++; len--; } len1chunk = 0; break; case CHUNK_DATA: /* Passing off the data */ if (len > item->leftinchunk) len1chunk = item->leftinchunk; else len1chunk = len; item->leftinchunk -= len1chunk; if (item->leftinchunk == 0) item->chunkstate = CHUNK_SKIPENDCR; break; case CHUNK_SKIPENDCR: /* Skip CR/LF after a chunk */ if (*buf == '\n') { buf++; len--; item->chunkstate = CHUNK_DONE; } else if (*buf == '\r') { buf++; len--; } else { errprintf("Yikes - strange data following chunk data. Saw a '%c'\n", *buf); buf++; len--; } len1chunk = 0; break; case CHUNK_DONE: /* One chunk is done, continue with the next */ len1chunk = 0; item->chunkstate = CHUNK_GETLEN; break; case CHUNK_NOMORE: /* All chunks done. Skip the rest (trailers) */ len1chunk = 0; len = 0; } if (len1chunk > 0) { switch (item->contentcheck) { case CONTENTCHECK_NONE: case CONTENTCHECK_CONTENTTYPE: /* No need to save output - just drop it */ break; case CONTENTCHECK_REGEX: case CONTENTCHECK_NOREGEX: /* Save the full data */ if ((item->output == NULL) || (item->outlen == 0)) { item->output = (unsigned char *)malloc(len1chunk+1); } else { item->output = (unsigned char *)realloc(item->output, item->outlen+len1chunk+1); } memcpy(item->output+item->outlen, buf, len1chunk); item->outlen += len1chunk; *(item->output + item->outlen) = '\0'; /* Just in case ... */ break; case CONTENTCHECK_DIGEST: /* Run the data through our digest routine, but discard the raw data */ if ((item->digestctx == NULL) || (digest_data(item->digestctx, buf, len1chunk) != 0)) { errprintf("Failed to hash data for digest\n"); } break; } buf += len1chunk; len -= len1chunk; dbgprintf("HDC OUT: state=%d, leftinchunk=%d, len=%d\n", item->chunkstate, item->leftinchunk, len); } } } else { /* * Havent seen the end of headers yet. */ unsigned char *p; /* First, add this to the header-buffer */ if (item->headers == NULL) { item->headers = (unsigned char *) malloc(len+1); } else { item->headers = (unsigned char *) realloc(item->headers, item->hdrlen+len+1); } memcpy(item->headers+item->hdrlen, buf, len); item->hdrlen += len; *(item->headers + item->hdrlen) = '\0'; check_for_endofheaders: /* * Now see if we have the end-of-headers delimiter. * This SHOULD be , but RFC 2616 says * you SHOULD recognize just plain . * So try the second form, if the first one is not there. */ p=strstr(item->headers, "\r\n\r\n"); if (p) { p += 4; } else { p = strstr(item->headers, "\n\n"); if (p) p += 2; } if (p) { int http1subver, httpstatus; unsigned int bytesindata; char *p1, *xferencoding; int contlen; /* We have an end-of-header delimiter, but it could be just a "100 Continue" response */ sscanf(item->headers, "HTTP/1.%d %d", &http1subver, &httpstatus); if (httpstatus == 100) { /* * It's a "100" continue-status. * Just drop this set of headers, and move on. */ item->hdrlen -= (p - item->headers); if (item->hdrlen > 0) { memmove(item->headers, p, item->hdrlen); *(item->headers + item->hdrlen) = '\0'; goto check_for_endofheaders; } else { xfree(item->headers); item->headers = NULL; item->hdrlen = 0; return 0; } /* Should never go here ... */ } /* We did find the end-of-header delimiter, and it is not a "100" status. */ item->gotheaders = 1; /* p points at the first byte of DATA. So the header ends 1 or 2 bytes before. */ *(p-1) = '\0'; if (*(p-2) == '\r') { *(p-2) = '\0'; } /* NULL-terminate the headers. */ /* See if the transfer uses chunks */ p1 = item->headers; xferencoding = NULL; contlen = 0; do { if (strncasecmp(p1, "Transfer-encoding:", 18) == 0) { p1 += 18; while (isspace((int)*p1)) p1++; xferencoding = p1; } else if (strncasecmp(p1, "Content-Length:", 15) == 0) { p1 += 15; while (isspace((int)*p1)) p1++; contlen = atoi(p1); } else { p1 = strchr(p1, '\n'); if (p1) p1++; } } while (p1 && (xferencoding == NULL)); if (xferencoding && (strncasecmp(xferencoding, "chunked", 7) == 0)) { item->chunkstate = CHUNK_INIT; } item->contlen = (contlen ? contlen : -1); bytesindata = item->hdrlen - (p - item->headers); item->hdrlen = strlen(item->headers); if (*p) { /* * We received some content data together with the * headers. Save these to the content-data area. */ tcp_http_data_callback(p, bytesindata, priv); } } } if (item->chunkstate == CHUNK_NOTCHUNKED) /* Not chunked - we're done if contlen reaches 0 */ return (item->contlen == 0); else /* Chunked - we're done if we reach state NOMORE*/ return (item->chunkstate == CHUNK_NOMORE); } void tcp_http_final_callback(void *priv) { /* * This callback is invoked when a HTTP request is * complete (when the socket is closed). * We use it to pickup some information from the raw * HTTP response, and parse it into some easier to * handle properties. */ http_data_t *item = (http_data_t *) priv; if ((item->contentcheck == CONTENTCHECK_DIGEST) && item->digestctx) { item->digest = digest_done(item->digestctx); } if (item->headers) { int http1subver; char *p; /* TODO: HTTP2 ? */ sscanf(item->headers, "HTTP/1.%d %d", &http1subver, &item->httpstatus); item->contenttype = NULL; p = item->headers; do { if (strncasecmp(p, "Content-Type:", 13) == 0) { char *p2, savechar; p += 13; while (isspace((int)*p)) p++; p2 = (p + strcspn(p, "\r\n ;")); savechar = *p2; *p2 = '\0'; item->contenttype = strdup(p); *p2 = savechar; } else { p = strchr(p, '\n'); if (p) p++; } } while ((item->contenttype == NULL) && p); } if (item->tcptest->errcode != CONTEST_ENOERROR) { /* Flag error by setting httpstatus to inverted error code. */ item->httpstatus = 0 - item->tcptest->errcode; } } void add_http_test(testitem_t *t) { http_data_t *httptest; char *dnsip = NULL; ssloptions_t *sslopt = NULL; char *sslopt_ciphers = NULL; int sslopt_version = SSLVERSION_DEFAULT; char *sslopt_clientcert = NULL; int httpversion = HTTPVER_11; cookielist_t *ck = NULL; int firstcookie = 1; char *decodedurl; strbuffer_t *httprequest = newstrbuffer(0); void *hinfo = NULL; /* Allocate the private data and initialize it */ httptest = (http_data_t *) calloc(1, sizeof(http_data_t)); t->privdata = (void *) httptest; decodedurl = decode_url(t->testspec, &httptest->weburl); if (!decodedurl) { errprintf("Invalid URL for http check: %s\n", t->testspec); return; } hinfo = hostinfo(t->host->hostname); httptest->url = strdup(decodedurl); httptest->contlen = -1; httptest->parsestatus = (httptest->weburl.proxyurl ? httptest->weburl.proxyurl->parseerror : httptest->weburl.desturl->parseerror); /* If there was a parse error in the URL, don't run the test */ if (httptest->parsestatus) return; if (httptest->weburl.proxyurl && (httptest->weburl.proxyurl->ip == NULL)) { dnsip = dnsresolve(httptest->weburl.proxyurl->host); if (dnsip) { httptest->weburl.proxyurl->ip = strdup(dnsip); } else { dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.proxyurl->host); } } else if (httptest->weburl.desturl->ip == NULL) { dnsip = dnsresolve(httptest->weburl.desturl->host); if (dnsip) { httptest->weburl.desturl->ip = strdup(dnsip); } else { dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.desturl->host); } } switch (httptest->weburl.testtype) { case WEBTEST_PLAIN: case WEBTEST_HEAD: case WEBTEST_STATUS: httptest->contentcheck = CONTENTCHECK_NONE; break; case WEBTEST_CONTENT: { FILE *contentfd; char contentfn[PATH_MAX]; snprintf(contentfn, sizeof(contentfn), "%s/content/%s.substring", xgetenv("XYMONHOME"), commafy(t->host->hostname)); contentfd = fopen(contentfn, "r"); if (contentfd) { char l[MAX_LINE_LEN]; char *p; if (fgets(l, sizeof(l), contentfd)) { p = strchr(l, '\n'); if (p) { *p = '\0'; }; httptest->weburl.expdata = strdup(l); } else { httptest->contstatus = STATUS_CONTENTMATCH_NOFILE; } fclose(contentfd); } else { httptest->contstatus = STATUS_CONTENTMATCH_NOFILE; } httptest->contentcheck = CONTENTCHECK_REGEX; } break; case WEBTEST_CONT: httptest->contentcheck = ((*httptest->weburl.expdata == '#') ? CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX); break; case WEBTEST_NOCONT: httptest->contentcheck = CONTENTCHECK_NOREGEX; break; case WEBTEST_POST: case WEBTEST_SOAP: if (httptest->weburl.expdata == NULL) { httptest->contentcheck = CONTENTCHECK_NONE; } else { httptest->contentcheck = ((*httptest->weburl.expdata == '#') ? CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX); } break; case WEBTEST_NOPOST: case WEBTEST_NOSOAP: if (httptest->weburl.expdata == NULL) { httptest->contentcheck = CONTENTCHECK_NONE; } else { httptest->contentcheck = CONTENTCHECK_NOREGEX; } break; case WEBTEST_TYPE: httptest->contentcheck = CONTENTCHECK_CONTENTTYPE; break; } /* Compile the hashes and regex's for those tests that use it */ switch (httptest->contentcheck) { case CONTENTCHECK_DIGEST: { char *hashfunc; httptest->exp = (void *) strdup(httptest->weburl.expdata+1); hashfunc = strchr(httptest->exp, ':'); if (hashfunc) { *hashfunc = '\0'; httptest->digestctx = digest_init(httptest->exp); *hashfunc = ':'; } } break; case CONTENTCHECK_REGEX: case CONTENTCHECK_NOREGEX: { int status; httptest->exp = (void *) malloc(sizeof(regex_t)); status = regcomp((regex_t *)httptest->exp, httptest->weburl.expdata, REG_EXTENDED|REG_NOSUB); if (status) { errprintf("Failed to compile regexp '%s' for URL %s\n", httptest->weburl.expdata, httptest->url); httptest->contstatus = STATUS_CONTENTMATCH_BADREGEX; } } break; case CONTENTCHECK_CONTENTTYPE: httptest->exp = httptest->weburl.expdata; break; } if (httptest->weburl.desturl->schemeopts) { if (strstr(httptest->weburl.desturl->schemeopts, "3")) sslopt_version = SSLVERSION_V3; else if (strstr(httptest->weburl.desturl->schemeopts, "2")) sslopt_version = SSLVERSION_V2; else if (strstr(httptest->weburl.desturl->schemeopts, "t")) sslopt_version = SSLVERSION_TLS10; else if (strstr(httptest->weburl.desturl->schemeopts, "a")) sslopt_version = SSLVERSION_TLS10; else if (strstr(httptest->weburl.desturl->schemeopts, "b")) sslopt_version = SSLVERSION_TLS11; else if (strstr(httptest->weburl.desturl->schemeopts, "c")) sslopt_version = SSLVERSION_TLS12; if (strstr(httptest->weburl.desturl->schemeopts, "h")) sslopt_ciphers = ciphershigh; else if (strstr(httptest->weburl.desturl->schemeopts, "m")) sslopt_ciphers = ciphersmedium; if (strstr(httptest->weburl.desturl->schemeopts, "10")) httpversion = HTTPVER_10; else if (strstr(httptest->weburl.desturl->schemeopts, "11")) httpversion = HTTPVER_11; } /* Get any cookies */ load_cookies(); /* Generate the request */ addtobuffer(httprequest, (httptest->weburl.postdata ? "POST " : (httptest->weburl.testtype == WEBTEST_HEAD) ? "HEAD " : "GET ")); switch (httpversion) { case HTTPVER_10: addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl)); addtobuffer(httprequest, " HTTP/1.0\r\n"); break; case HTTPVER_11: /* * Experience shows that even though HTTP/1.1 says you should send the * full URL, some servers (e.g. SunOne App server 7) choke on it. * So just send the good-old relative URL unless we're proxying. */ addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl)); addtobuffer(httprequest, " HTTP/1.1\r\n"); addtobuffer(httprequest, "Connection: close\r\n"); break; } addtobuffer(httprequest, "Host: "); addtobuffer(httprequest, httptest->weburl.desturl->host); if ((httptest->weburl.desturl->port != 80) && (httptest->weburl.desturl->port != 443)) { char hostporthdr[20]; snprintf(hostporthdr, sizeof(hostporthdr), ":%d", httptest->weburl.desturl->port); addtobuffer(httprequest, hostporthdr); } addtobuffer(httprequest, "\r\n"); if (httptest->weburl.postdata) { char hdr[100]; int contlen = strlen(httptest->weburl.postdata); if (strncmp(httptest->weburl.postdata, "file:", 5) == 0) { /* Load the POST data from a file */ FILE *pf = fopen(httptest->weburl.postdata+5, "r"); if (pf == NULL) { errprintf("Cannot open POST data file %s\n", httptest->weburl.postdata+5); xfree(httptest->weburl.postdata); httptest->weburl.postdata = strdup(""); contlen = 0; } else { struct stat st; if (fstat(fileno(pf), &st) == 0) { int n; xfree(httptest->weburl.postdata); httptest->weburl.postdata = (char *)malloc(st.st_size + 1); *(httptest->weburl.postdata) = '\0'; n = fread(httptest->weburl.postdata, 1, st.st_size, pf); if (n == st.st_size) { *(httptest->weburl.postdata+n) = '\0'; contlen = n; } else { errprintf("Cannot read file %s: %s\n", httptest->weburl.postdata+5, strerror(errno)); contlen = 0; } } else { errprintf("Cannot stat file %s\n", httptest->weburl.postdata+5); httptest->weburl.postdata = strdup(""); contlen = 0; } fclose(pf); } } addtobuffer(httprequest, "Content-type: "); if (httptest->weburl.postcontenttype) addtobuffer(httprequest, httptest->weburl.postcontenttype); else if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) addtobuffer(httprequest, "application/soap+xml; charset=utf-8"); else addtobuffer(httprequest, "application/x-www-form-urlencoded"); addtobuffer(httprequest, "\r\n"); snprintf(hdr, sizeof(hdr), "Content-Length: %d\r\n", contlen); addtobuffer(httprequest, hdr); } { char useragent[100]; char *browser = NULL; char *httpheaders = NULL; if (hinfo) browser = xmh_item(hinfo, XMH_BROWSER); if (browser) { snprintf(useragent, sizeof(useragent), "User-Agent: %s\r\n", browser); } else { snprintf(useragent, sizeof(useragent), "User-Agent: Xymon xymonnet/%s\r\n", VERSION); } addtobuffer(httprequest, useragent); if (hinfo) httpheaders = xmh_item(hinfo, XMH_HTTPHEADERS); if (httpheaders) { addtobuffer(httprequest, httpheaders); addtobuffer(httprequest, "\r\n"); } } if (httptest->weburl.desturl->auth) { if (strncmp(httptest->weburl.desturl->auth, "CERT:", 5) == 0) { sslopt_clientcert = httptest->weburl.desturl->auth+5; } else { addtobuffer(httprequest, "Authorization: Basic "); addtobuffer(httprequest, base64encode(httptest->weburl.desturl->auth)); addtobuffer(httprequest, "\r\n"); } } if (httptest->weburl.proxyurl && httptest->weburl.proxyurl->auth) { addtobuffer(httprequest, "Proxy-Authorization: Basic "); addtobuffer(httprequest, base64encode(httptest->weburl.proxyurl->auth)); addtobuffer(httprequest, "\r\n"); } for (ck = cookiehead; (ck); ck = ck->next) { int useit = 0; if (ck->tailmatch) { int startpos = strlen(httptest->weburl.desturl->host) - strlen(ck->host); if (startpos > 0) useit = (strcmp(httptest->weburl.desturl->host+startpos, ck->host) == 0); } else useit = (strcmp(httptest->weburl.desturl->host, ck->host) == 0); if (useit) useit = (strncmp(ck->path, httptest->weburl.desturl->relurl, strlen(ck->path)) == 0); if (useit) { if (firstcookie) { addtobuffer(httprequest, "Cookie: "); firstcookie = 0; } addtobuffer(httprequest, ck->name); addtobuffer(httprequest, "="); addtobuffer(httprequest, ck->value); addtobuffer(httprequest, "\r\n"); } } /* Some standard stuff */ addtobuffer(httprequest, "Accept: */*\r\n"); switch (httpversion) { case HTTPVER_10: addtobuffer(httprequest, "Pragma: no-cache\r\n"); break; case HTTPVER_11: addtobuffer(httprequest, "Cache-control: no-cache\r\n"); break; } if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) { /* Must provide a SOAPAction header */ addtobuffer(httprequest, "SOAPAction: "); addtobuffer(httprequest, httptest->url); addtobuffer(httprequest, "\r\n"); } /* The final blank line terminates the headers */ addtobuffer(httprequest, "\r\n"); /* Post data goes last */ if (httptest->weburl.postdata) addtobuffer(httprequest, httptest->weburl.postdata); /* Pickup any SSL options the user wants */ if (sslopt_ciphers || (sslopt_version != SSLVERSION_DEFAULT) || sslopt_clientcert){ sslopt = (ssloptions_t *) malloc(sizeof(ssloptions_t)); sslopt->cipherlist = sslopt_ciphers; sslopt->sslversion = sslopt_version; sslopt->clientcert = sslopt_clientcert; } /* Add to TCP test queue */ if (httptest->weburl.proxyurl == NULL) { httptest->tcptest = add_tcp_test(httptest->weburl.desturl->ip, httptest->weburl.desturl->port, httptest->weburl.desturl->scheme, sslopt, t->srcip, t->testspec, t->silenttest, grabstrbuffer(httprequest), httptest, tcp_http_data_callback, tcp_http_final_callback); } else { httptest->tcptest = add_tcp_test(httptest->weburl.proxyurl->ip, httptest->weburl.proxyurl->port, httptest->weburl.proxyurl->scheme, sslopt, t->srcip, t->testspec, t->silenttest, grabstrbuffer(httprequest), httptest, tcp_http_data_callback, tcp_http_final_callback); } if (hinfo && xmh_item(hinfo, XMH_FLAG_SNI)) httptest->tcptest->sni = httptest->weburl.desturl->host; else if (hinfo && xmh_item(hinfo, XMH_FLAG_NOSNI)) httptest->tcptest->sni = NULL; else httptest->tcptest->sni = (snienabled ? httptest->weburl.desturl->host : NULL); } xymon-4.3.30/xymonnet/c-ares-1.15.0.tar.gz0000664000076400007640000511014713443010711020110 0ustar rpmbuildrpmbuild‹‰Ï[ìþÝ9د™õçÙÎînc÷ ¶·WÃ~ûglÿÙWôÑ Ñ¿’Ï8Ãü>¼áA(<·ºû9IÓØÛ[Åÿúþ^ø¿SoìÕöêõÝgµú^£öŒ={âÿÿTßoXð?kyþ"W³ˆÕkµ=6Z°¶í î°~ÄÝ®,Ýó‚s¢„°ÈcqÈ+l ƒ+lîMÄþÚî„MDbGœE3ÒÀЛF· aÔAD!›xãxÎÝÈŽØÔ  eÁü8ð½PöºÑÌ‹#>圉ÍxÀ»«Àv#>©0?ðnÄ„O`;‚`àÈ»á„-ˆ»^$ÆÐäûܘp™í8ØEð&¢Á#/šÉoŃ© à§X‚ƾï‘p‰`Ù%VÒ©OמsæMÙiµ[Tq$(PÇ¥Ñöt1!@c@?9b,¢bÙÂÅçÀƒ„؈àY‚+2²Ðçc1ã » DŒê œ,¨JFsûÈãz,à>½Œ)Ë5„±ˆì‘p)oJƒ‰DÉÔ9®VëFÈÆ„mv¿¥hi<ùÎâšÅÜwt`ÈñEUÊáà-kö:ýáO^¿{~ÆvÙFý%ûÞvc;XC§þ[vÖ<íX¦Ucï·Ù.‘×Üx®(Ç1  ï¿;;¿èwûVÕZß wìÄξC€ÕÙ+Ë5@ZfÀûMs–’p#¶ù~ÚU¿ßO/ÊVu*h»ÓoõºÀÛÀ„ï§Ç™±»eèΦ±;&†^qP±m œÍó  X–çcì5¹ E¿‚……‘P˜ VÌ®H@«¬;e /f¾ „·­³Ë““ ò^žÙ 2s?B]óPTÅË'U‹ÖaôʼnXì#"õ½‘ˆ+Äböwrßl°#4$ó()sû?^`é¾sáÂ3ÅTߎÆ3õ Ê(hRFí„(Ša íÐÚ©Ö«»0)h»0¢…¤˜ñ;{*1·=Mí®¶S«×vYI74µýr•X·ÑïtXó¤ÒuÜcÄ6PÈÓ*é#Å©¤ÉúªöýØá Oþ§û÷ìÿõ½Üþ¿·³·û´ÿÿ9ûÿÎË—ÇýäŒ=ž~F ¦]0v"Â=Lå€g®çxWÒ$J­2Yàmøçå“'ñäI|žÄI÷¸×ì½¶N:Í³Ë ô(v^‚7ñ2ïMäl$zÒ’&»ô„£õ¶#þKk}?q㉠+š „-Å.Dõâ·_Ø} GZ‰#» F\îY”+lpNÞˆ44xq0桼^¢_1þ5èK€Þ€±´Ù)ßåvÆÝŒ/u‹¬I&ÏêG±‚vÏ… <$Pp8ÓÓ²1¢yÖê ÉyI!ÍÁÝAåp ÜGÀ©H‘»—b–f2á,¦`ƒP©N2G?…TJ?Y;-ÐK€»b(C¼RÆäÕ)ŸuÁ¦"@·S^ÃðZΑ,Ô5,ê«ÅKâ1³ÁÜ–òé”#æÑX$¤ÎPÀÑüHg“|½|M°o1~­*14©7C²C89ê à=ØÜ9Ø'¦d]4 ¦v<}H—£—Ú®š5Ð*;wÇ<ff‡j kýêÂx KÀ"PЦh´ÈMÔf4á*,"å|ˆâ ü gHn4­hÌ·i$ÔEâÂ3+o]&ÙBd ¬Å‘F»ƒŽç]Ç>™­€ÿó0ʨáäºÊ.$¡ÁÚ'Ü•€u áj³Q†“Pk‘ÅJHœ¢YÀí í)t|ñÉ,Ž tðòô‰÷X„æß¿¾!@$§•(Z ˆù2da2tÂ8 ¹2 !b’Àý4v&„”%9T(ÿ!±È>!7Șú^„R ’ØcÜËÎrë-VkXÞVËíÕvBØcZ=b;µÇ‘Äc­œYsò‚hÙšº@çÀ›+…’£YfÉ"cé.g§…b€9…:’qJŠVJƒ*À.”JA†Üd’íÿînýEcý €+ý¥öÉIhÈ7a¾^•p5Ò¤í8§à>úÙö(þòdОÄ@÷  çxãké#IÔ mäðy(C«æOÍîIó¸{Ò¼Ë) ÚtiòÀìH€Í*eÑ¡ßNõ ZR€‘äBžð)ñVú3>úlj!(E¸˜ÅùQ°²&PÍ—‡Ãhású2vÀ¸Ó7…Mê»2óˆÌÊ“g›ÐÛx€=a"ðÒ¥/‰‹åw£UÏ08}@?@#zH?ô‘-è»UŸ«‡*瀃¥}À€¢±8ÀœS‚ƒJÎÒÎz" ç»û˜¾CöRZÆý[$á:e¸;o7M½ÌÎ/7%µ%KÒ«–›Vx-|èµoåæJ©kÏa`ÜÆ“m)::G_Æ^0a¥^¯LÇü0‹"(ÊpIÙj‡L€Ô*ŽÂ­­,â0GÀLd Þë¡n¨x +ÄóÜ™(¨øù8†(ãaðƒ æ=<1ñÃÏ(àöõaòàƒ¦yJ9²â]¯·†mù’U0i-ʼ*ìõ†ƒw‰CÊeyÓN­“f¿¿Ü E ésÒ9ËõÐëMVV°jåË,9™ÖŒ¯qÞ[N™Lè‰G˜À¦£°ælð¯–ÐDzÓ”G¬Ž{þ<%ã a`1Ê/6Í-x“ èìgn/ÐíÇN$|‡«½ rÒuF9E§Ê: MYPÉ NªA}Ÿ6F{ñ@&¹{ÍTE‹²!! ŠøÓYCu „ž€N¦³ùöÂñìI5 ¨‡wytÒCTp5ù6ÂUi 0¦ÜŠ×jPúäM¸Ù _XÁ”9Vî„þÜÎб¤Ú¿ËÉ\¹œñ~ËyK©K×¥l¸.¿jšL¶eŽßb;(à™É—|³ß ¼µûE~…è/©@*‘¬é8Þkš°ÞʾâéÉ Jœ2ÙÝÉ£% YˆºRÍÐí÷h ;·>9¹%~ÇþOâŽò–ueØyþ±Ê9]õYÓë\œ¼+1áÔ£È|v~Ú9ý("/c ½Æ‡! {o¿rÑ—ºáüfüÛürùÝòBõ€íWÒŠ ÌBÒ:r$5v‰ƒé@ežŽráHqçˆ(gÈ L”ÑAý.E\(ÖnŒµv`—@¢ e(X:å<åmmÛ›9Ÿ}ˆK2*g‰QQ†±bP¯|X`Nñ 8Äp6G\åvrȹZÝiЧ!ß-][ÃÕüP¸]_žo_!t€-£¥0»-’Cf8“FSæÞ€žx:£ PIB&ê’¹ ÏYy‹¦K” =ÓYN1;'S‡ 켯¡Ý¥À Óíà'NºµÎ{WîJaÇYé©Ó±º €Ø’Ðqi³²:‚6%%z2mF\l¡Ã—d€§ËS$ôËð0ÕÅ<€‘8øù`YOAë2C…ö¡$™”Ï™HÉç$Ä\BEaT˜Æ)™±G­ÂJ*##5Aò+±§ÌÃ'¥‚ØŠlÆ#×°³j _àü'sàÿ°û?»z}éþÏþþÓùÏ×TÿûTÐûTÐû×*ètO;ç—º´Ï¾aAÑÎWò*k‡¼ÊÏí;1ç [†·¶ˆT½« >Ž»±u#HÁ/É‚‹™íºœjŽÔW¬éY±å¡ÂXÀ0ºyÔHvÿU$tî*Ò„KVÃf…Ü”µI(cT°pF¥BHAà)Öå ÷F¦†tµŒ*ÈRs½Õ¦«„ÞšãüÌ €[ºÄï@Øeâ&Å TPX`eè:b}ž˜&u¹-©Æ¼áŒê}t6ì<Ï –¦¦,¿ô=t p8)=r8ƒý{ªî•aJ PÈr“È[ðCÈPæâT1˜ü e)&ªšóªeu§¨‡¿ÆœJ eE¹¤¬4ô=sŠ«0•4Ô' ßä³»I«x@z™ïWNÏÉœ@æ\QG$3"!K¼Aá¦45ª84”hìec.±WÔãИ>}lV°w¡}¢ž¤p GwÍA”B•{ÕãD8”Mæ%QQÃ-é]¶Á©Rûsñ’dkšib[[jÖ5ÝRñ1)O>/¥Rx T:x‰Rž+(õᑹÀÿïŠSÞ[€sûœ¿{ý¿Ýún}_¿ÿi—žÃýƒ'ÿï÷ÿêµÚ>]Íð Êãkvʯá=9yONÞŸêä=¨PûMgÐïô~:~wqÞ {Td)嚇ÍÞ›~™ýþ;{/maöÛ£NÅ­¯X£Œó0uзoÐ9½ì4Ý1‘$“;éK†ô+wB¢¾Þ¬üh4 6œªÃ.(¡~*Fÿ\ÅèDÅ×8Þ$Ç 1ý¨Btáß4 »ȯ{o-:…z¯Jý C?ÇDåÈc¬¿àŽ/A”d9Zé©èÀ¼{2 †hôàïÞáŠÖ57°ù}ÕuãS{.œEò˱¯BýCç­‡¹pKšív$§1ìÓ?­ó‹Î°Û¶¾•ŠÈºÇ—¯ûÝŸµÞ¡êaIœ7-mLáó•ÿÔ÷÷«Æÿe¶Å€…$ÝŸ;e-PŸ¢r"ꑉC¥„+•Lé½I³{röšCX}€7s©üA5¯<ƒ–¯¢Ý€}(­¡ g`C’JÊ´õJ€tÒ¬n(ÀwYÐò@¾š‘ÕmÃ6R.&¥"iÛ$q«d¯>¨kQ]‡©dzçÝÖpÐ/Ç'ó½l¸YB'øS2ßÙîTXæw«8Ò\€á ¯HÈѹ… {ÕZ$:ÐPÇû ëªRÞg*©AÈæ 3@”_¾mQÀåN9#µé ú²t‡eÏ ]½j"eô‚àq§—Æ…\#U‹–D±¥ÐÞ~ÚCÕåž×´•Ùóç–Öcº„mJ¡—×R.çêòåâKE„)‡¶Ž¸Ô° °î¤Á#˜õX6 4Šk£ÙF1¶Uè6ßFÂЉ­"+¥ éÝÓ Yå]JÚd+‹²%ExèÄû€h†a<§üÄÜ6,Œ!ë•rô› 1{.§;ëOÎϸ¼@ªÛê Áت>oÏûEÙá÷£‚ZÜšø"–A/H”F’ÞeHo•A§«}Ö7î³`—Ð X¦ïîþR‘9A˜>)YS¿g9#ž³âå±ö9«Ýá–T¾oÛÐv"± hxï'ábßU—Áw…ÌZÖò|– ¹—žË´B†¡_ÌØ?¾tÂ!0®zeŠv±3œ]žvzÝ–1…Y¦H,>2Eû¿f[CðÀ%Ïr ›)ôIT¶™àÕòå™xA\ÿÃzt&¬($é¥_ƒ¯²©—|nûæ«lèå8ô¾Má8üÊvŒŠ}£Šé²DðŒzÛfum¶®¶È7Û¯Ošoú«ìÁ²hä+N)Åö«·/õfM ÝÈóKÚ¶VØsÓÔá÷ŠäD%q÷rxJcE‘+ÐêX=”Në¶Akð"’‘惜ž ®Y§Gù7JrŠô«œz,EÄËž?„.Š,rúŸ(Li%u¦W)Öle¤ykäKY8ÃÊIuMÈ*–EÞcí4Wræ./Õ’PD$ù~©[ºgd“ARJ=âgbÒ„cÕ¾ÿFÎàcÊCå7eëéKYÉúZæªh3U >N§©Tþñ ­æÜ~•8žG™h4× &¦^´I9:JÊ\{R»Bv5kQVø…+)‘NªÆè!Ù•ËrÿÒóP¡*EÍ&ÕIq¨ G9GF7 I-°KšéÏké}Ÿ• 5ª\Ñ«¸wüR¼PÑ$YaÖÚž•Ôl<”œ IÎÆz6>šž™Íàã(ª¬i#Gׯç&ì‡äˆæOʘ!áŠPΈ6ò=ÊZ• \¥b'É*Rè­##q”¹q´î>DÎåÔSEž—½¶’³0÷îT¦pgǯ30kö·ãPÕdåa·ò²kxÀ>WpOí#ðkT“ˆñK!ø!åâÙùëÛg`l—êô›%17ã3o*½´‰7Ç Ò9 ©à»Ø?±!E‘ŽF‹¤ UOÌ»uMåfs;HßÇ*o¦°’[šæÌ²ÊpîÝÈ›š‰ËóßtsP5ñ$QR XÓÀ±¾¿ÿËáR˦D/Ó Ì"b\"6ÀЬù¤hI-ì—>þ{_ÚØ¶‘$ú¾†¿Q<‘è”H]¶gCK´Í‰Ô’”ŒíåB$(!&†uäøï¯Žnt7rgfVÚXBWWßÕUÕu\-t½¶^.' 4Ò}ï¸À³JÆEÓ§aªß] ÷~n+áøÇÎŒÞ8éç'ÑnŪèþk·œàE6t¾#Îì%ÈPöF—Þ~ƈV°¥qîQYŽÄïSŒ¦ÃðÆáŸè#7qEØ %ºáz`uÿQÁs‚BñR€´Ï˜èEz¨EU΋îy瘵Ù;QJ†)Ê‹ I¹(ÌQ²è£.°dMvBŽ1Èž¾_³%ÇLúW¤Fî-$ÆDÄtÖ(N[ó:”#SþþpþÝŸ”êåí¦'fy=“LlJŸb²hZ›Šeþ|O_Ä-ëÏBó…úú“ šeydÐ9?\iƒ¨8ÚA%ìáŒèíÎÖÓ=£Æ»çP… Ã?ÙyYpÎ8Ò¤ßp†^»¤!t:¦ÍÌ$¦i8ÏÏÌM³×–ãùZüh¥¢è ²p£° ’㣣,$ãÑ(‰$4$ÈÕK¨ ¶n|†O[êÌ:&Aáéý:p“Uy­õÚü¥Ì—Š•jd„t/¶&1£‘ Þ÷4¨ŠEý¢dY´X*$‹ÎŠ91‡[qÚmºXNŽº¯‡­ŽN†'@è¤ÇÓ>>ù1_í¡ÿ9Å cׯœéŠ‘î&fòSÕJ™ú•]Úùƒ“Ÿ3‘ÂjÁÐXŸ`ίŸÐ¯ì uÔÈùuûÈÖà¤ÿ¥="ešô>)ÎàãÂ}¹!¨à6ÅäÇ!6¯['¸ ž ‡år¡Î»ý¸¬úhvî£Je{ØÌwŽ…ªßZð†d8)l(ºùI4¦XŸÐ%oèL"*°“¶[ÏÙf.â¾…“ˆB¬ým¹VÑÂ#AaÚ«€)¿AqDï¸j ë îá— #¶ñnäÛèÔz/üb16ùDñ ÷Òr<yy¥C¨þh,F˜¿±êéÌ;4À©‡f¶`® yôÞ¶þnk=þå¢=5V2à ÀîbŸ#|bPÑŒál™-¨ø |N/}N“˜|fÿ¢w´\øqë‡AWè)\zN§˜`8M§<‰f\ë×x¯1$ØÔ¡ÂEÃRÑèÅOWÎr¹;.[ßÉbck_#ZåøÛzÌ´,9 €âÔ·ûCZ Øÿ8é5O6ºaŽãÂãÕ:=ʯ¸âÙ™Ö­D¥uÊ—Ü5¤‘¢Ár’W3f-#2Ÿ _‹™©¿GÂ05)UOë{Шô–’$¨P;©v'4ä ì÷±sú¤²JC7hÔ…r2:Tœ9͘ÄÔ¸sŸj2ãñ¼Ìe±–ï=¹q­˜Ôqó³!ûòIFŸº°Ÿ`tˆ—3œÉgÁˆ¥R¢ºN£‘©«cÝÒ|lPÉ7²D2cæ—%ñb2Í b&Õòšæô^ô[¬Bdo¥K™¼QP·Š¯^Ø[lfA´ˆ7‡4¥ «Q@ÔÑÚ;ˆÖD­zVÐÉœªëÌdè^;elî“Ø9&„ÜÀ<5ð?õá…sɺf¤ïSЦ~C#ÿAÝä(‚:H A#ö±ÅÄjëá.ñ%]äùŠ"LÐS1À j.™­‡"uònkˆ€¦Ü¶´Wwüûr®Å%õi’a—:“>7»/ö¼þ £¯rs$×ñmLŸª²>C£Ö£É®šðå[øò £0Ï!Ì%€º'Ý7­ÞLutÀa‚’†Á¡a½/Q%Õ(ÇŒŠIò£ú7ßè¤dÔÐÿVt[àÜH ”c} G6 4>ÚœYÝoL³Ù¿ÊøÉ±]É\áZª¯•U¬«¨Ë«jÕR«‰?¶>EP¬ÿÛù_ô|ACÛ/€0ÿ¡``9ù_ííÿWßnlïíîíímíÿ¿­ú.”?øÿý5ñ¿8‡K}Ÿr¸øWžÕ]9è»ôæë!Ì׿nÞÞv§=6;ǽnû˜’÷n[}gÒVÎÊÞ«S¸”¾MQò‰|£«2­©Ÿü‹Ÿ0Á*†Îê×0ÙíÙÀQˆ®$ Q{¨å‰Ý0ÝUŒÆ~ºžmüݾ¶_ŸRä/ø“ñÞ'‡°Þk•H6 %œ‹MLe…~:2_Ñdb‰s),mtÀ'æY¤ñÄçî#çΧ6¹;Š/fODЭìÀ!‡âÒ+gVò|Ô²ÇË_[ñËÐôó.Lù°Q–ËñAˆõÄÚè.¿ŒÛ×s0ì7Ž·ÄrCüáµH#ˆÇÄ! ñÆÞ7œ‹°IÜ5Dͳ6°¬×Î`ʨH¤ Ø `¹Zª+;(±AªËY¡§@p1õQRä)¶·Gh± Ke -i»Ñ:åÝXçU¸bŒ6 ÛOëªÕ(‰ýKiEÂD×¶þÞi׬æ4ðÉÇjÒ%ú_¾éöDHþ”ä´ËÜ”Bè’S¢%.3& üéX O€ê5%‡”Ø~VWäW¶©÷wH`vƒ@Ÿ¨šõÊ¿Á7 ‘šÜHKãÜQ†T6GN?À–ž¹L)%/ŒÄ ÑñÁð´í¹p.íÅÛ/‰|¼E ƒ…È8ÉC¥ÿ;&ZÚR$ —W«¸ÖVŸx8ê´£‰òM ‡Ì ñ>¸„+‡æÛ±þ$†äW™T³Ö+h犙) ÇK’maC »Þ‰oÑzÚFÛ–;¹Kq¹´éV‡ã¦Ç»ÃhÀ½©r«d‰æ,Pþ÷A‰9ªíjµ©£ÈíŸ :µ%BAÄI§ "¢anÍ̹N!èjÚ…+ ÑHEÃÆ1ÍOð•}¨NøÕZS'eèàZ…ôk'¢™Mtâ×{-:}Xn¯ñkŠ|œý:óæG=Èï¤T€µ~Àç`ë'dÇàOŒý£°ˆÃºžI\¼¶àb&SGÖÀ ï ¯ ËŸ8û5šæwl‹ôd(]Š 9¡•rõ»—Nè6°Å(&ø×€»BýzÝêõ¥Ö‡{ôðL}ýGÙ|õªÖ#ÄÜøvp¿p½ñöjC"pŽ"¡ŒÂnP S1ŸD‹äI¡•„WW <^âÈ‚þ*oê½Ýz_ÖG¼úsz²åtNfîPWŦŠÂ”j­1g=æ„䵋"¢ÍtZÕömfÒ,^ÜÓ».óú2:mô(¨¹¤Õ0sÏ ÷xcm„XÓ4ã%6X¡Àï~W}J68)G@Úx¦HåhöDçE3Iüˆ8ÄHö#þ·¬x}HëDYÔ«!'L£ï S.¸vÔítZGƒöëöàÇ¡´:Ô¦C-S[Üz+‰•Kk òŠ€ñeh+f]¶+Ø\öf—$ߎ=EòÉW­¶€ÊJVKQ„,wmH’N$Jò(ç3¢‚:ØÏèOž‹Ž0œ3‹Ðš¤zTÛ#ʇXäöùiF„$bD3sÇ.‚8J¨D;€3¾2@c¾þÛ}sj{—›}z¡8,kŸxFÍR®8huB-J*„«OûêÇN[yl<ÙvÔx- (MU¢îµkk½=¥ ’FÃwã‰-ZEN/†ÔIe*ò4Úy˜A»¤Ê óÔŠã€QŠ_7Û'Íç혾ñ4Áº±1éÇ"@i*\øãåˆyåDZûúNmëþyä“2FE›Ó"iå³µZü¿@ÿµúŸ _ÿyg?ÿ¹^ßzÈÿþyôÿ¨GE&k­¾f­5ϘâÄ?uX†¨ÝAW£R¸†wU‹ÿYAƒÚ®&üÈüKpKù# ô>â‰åÈö™ S¨‚LáÞµÚ%õä»Iï}­VÃ{{ Â_©:LT!7Çc’„;Éj ¼`´pç¬"ƒ«›`O|ÿ%w¼b¥^nÿi–6ÌQØ^I ¤,E}WNÚÅÎáÑëþ»ÉóÑ;šV´p瀉ðÐÚ”Š×‘LvÇ#ä€iœapýwU`0z¥3šõp[pý,láÅòòRÅ®© WP¡bѯð‡3#‚c7˜Oí;–žñ# •έ«× ±˜ºs P ^³×*ƪËܳcgb/§!L‚ ?f5Ã&$ZŒ u?i08¶ ã²D­H5iyÊZgiBa‡ð‹4æyq8¤PÏ!¹Â|ŽM6‘ll‰pfÍ)ªÿ¦Ž6y•j(x ÅÏûŠ´ªÄ,z–3™ k‡ªò©²®œzŠ™4T%”ÿp/—"f-j@¥çk(YpWˆ7‚%f¬7®·Ý(ù‘ú±Ì;h­×B ¶Ýyi=?Ù_iLQaÃR=!N:LÉ=˜ò§õ* ç›À]úÓÚ•}{[ œMdsJñ•'þæHîgnN2ktlJ7 r ˆØc÷~á~uÏ~ìµ_¾˜;mñ0€z¦MwìØzÞR|bó'üª%Þ°€wÐr3°ù@¹‚ÔâN.êÄG5¦ˆÉLíÁOÔ€>æ)4ñ Z*ü šñZÊ}-ôüYJyþ¼ÏÓgI=}þgÏòŒ&¶tçÎøSg©èSgú3g)zæLå,øÂ [«ãÿ¾`uo´ û¹3ÖŸ^8œëfìÈ}k/õb#(G½‡jER‘û È^»ú|üßÞÖÞvœÿÛß{ˆÿüÄfilëi8Àm m{ =[}8: “]>‚~ý×fû@v]o9#E™™¾ú¼óN÷MÇz†3Ñté}ð(*f8%^ª1=H½¶_ÛbcP_¿÷šÓaW„±°9&X\‹Ô¤…ñEéµÓð©T§÷Â×úaP‰\iÒ’Ž¦·^OGHþîq+­ƒä±âáã_ZëiøNÈïìV 7}Aiø:ͳAO Œ¡ó0ÏïŠ ÜK]ànsÅûv&¾§<è·•:‹{ƒÁIÅʘÅ0œÊð}ÉšQÅ´š{T5¥&Ч­Nr+ÈH@zÈ@³¦1ÓÛdñ&±O¤Y~ʦ!¯IÞ9iÛ†œ%3öNÖfD%{´á†˜ÀŒïôq+ºüÈr„Þ]tëf&D·pRÔ{8£àà˜œP·*Rã¢iŠºEëE½°Gá’Çíè¸<®J÷cÓ$\•ã«.ûÈqeÙJ`Ýõ®áV¾˜:ë+FǶN¨Àú²`æpTZÁÀo\öP 6¥†@Xv ÍQ²ùeäß(+U“>@V#,œ‘ã^ãòáû¥­-Å´j¶'Ó©¸oõsLŒâÓËSE{†Ý1›4ëÚ] ÷¼b~N™yÉpq.cñáPä¥ççMmÎÆÕLĸ]šJþqXÊÊÀmI¸(Uú•Žò$œº E´fú#N‘>Ëü; ¯]‰0=·YÍëW¥ý‘2 è ÃùGûÇyæþ2î\’’wSrÑÞôáÑä?Ûÿ.-=–éiõSd€Ê{ÿÙMäÿ¤” òÿCþÏÀƒFàãó~мIŸ8ŸÑ}²’"cÄÑ)Œ¬Ao|4d 2³0ñ ÔÙ­µ Œ¸S‰¾˜Àcv¦ãd.Í6 w|ŒÅÆà™nÜ;VsFf#îÈ8ØŽÒˆ‡j(2¬¦-Œn£ö÷#BƧ6)9 ] íòFžž9ò…1î&ávñ”2J%Í@fèŒÔJöªÀAÔúŠ4-qd³ãvP„ ìbg,V÷çx>'ÞÔÒíÚ•!µÅ¨Í¼œ£“›àÙ3 ö÷—Žý÷=ª…Õk€ÌzMࡉì|S·¾+ŒVÔý†þzÄâžËV¿©G16ÇlK ÌÅ!1_íã@DdóÐï^:,ÿ\‰|—åFˆGüüVþ©‚Ⱦqf^±;!EĹð»ðä_1¤ÊçØiÚÍ“ö?[LJ¥g"cÿÃÑ¥¯KŒ’,¼:„èÃGU«¡<µ¹®‰r… !{)¶Ž[ƒæÑ«Ö±Z׸ÇdzóÍ0Æô7†ÈõÕì wAËy›Ïº¤š‡!ûMâ®×NWƬ¬¾µeTH±G;ÎÍË©aO{ÎdCRÜtß}mò]‰Ý¢kD÷Mfïiôëv€ãªYÿƲù›ÍCvº]9BÛ„çT6¶E'WpSbÙ‹¸Ûm¬eß keÃÏYÔ8\Kî–d>rü1žON@=9q~ï`6²rR'Àœ[úìÄ;›7;9Ó ÷±3uBçÄiÇ[Œ”zQ|SǦäþûÙ䪳Ö-•£.²d ÷ZÁÜñL^h¡¼‰œrÊ2¥õ­È¨Ó¿jÈÃ_h¸\ã5éÁ­Þ­•#ý4ûÍ\ûî±,(w:–œŠËí”i0±ï¢Š¬çýrm£éîœèüe!Šû WÉ…&/~ì:¦ÈŽEfRMï: žd×>ÉÜRE µDýƒØÔ ÒŠá]ÍDÜl¾¦Ä*¢÷°òVަÂZ­‹° èp åÄ鬵œ5“]?vV²ëÆ ü“.Z¥ãÒ*òlR¨An¾8?{zŠ‹TY¯@I9Rl­HTýüH‰ïÓŽðA°K™ÿc'8NÛbêª-U>Ì•€Mmç pÎÄ[û*1tC¼’Ïì[9óÅn(Qï±·œÉŠ«l¤½v ‹I€h›1" ¡õ>³T/0 D_‰‚ ða<Èû•œá³Ó$‰»*Ùcܶ±î¤¨?N•L¤¶j°…X´Ñn¶ ²Plô/K6TË—Ot„© m ²ÖQG³Šúu…Žó¬l§è´­ .ÜÀBÓük4e -é€ú^r>yÝ'o’†l©&‚-¦Á«¥Å¡ËŽi-2á¤ÎÃ@šJ59 e½IÛ%.LÓÃP§» '‡tbÊ AÌÁF”•àž½D'¥~ÍF³›Ñ,¡xÛ€1=ÌtÁ›%°¡T• üV›—ï¬1:MçæËcÔ>Uoh,×>À:*֙ŒŠue׎½ÐEˆ~³ÜñCç€ã•ÂÎK›sõüK¦,oYícL”½p"O ô&ÑíÒ"Þ—l2ƒ÷—Ø{ ïéø U8ÎU‚hßOÖˤÁJÖ‹u-û'nј†ýOKæíP‰Mi4œD'³ÇcÞù«GC{EȾµ¢>Éî/q±ž¶=£›¦JúM5ÊØ¾³6k)k—>75/6ëÅ„Ôúj"aþ¦,x#иÝ2QD Œ˜Ÿòã ƒ¤ÞpŸmZî·z)üýÍ7êRŒ˜¶Õ+›=e‚+(ºÖŒm•#7(2 Õ†WI"­XÑ<¨h¥ °Nf ±úiê!p%¡qý µJþKxÎ+xÊ/¬ÛÒ*eÒ·ÂÈb³èa| úû Å̈©–{H“…ä(D@Ñ®V¢ ~\ºBÚ¿¼P½âç’ÿZa.ýùåAºú”®þOˆ?_H9EÑ!ôðߦÄcÀÈ:µn¬UÖÊIù5ˆŠ²$†|H ù¯–ò¬Ùë·†>‡w£”[Ö çb±Ä¤M­­DZH“ðató3üB1®ð†ê¢(Í?/‡€Å¸8ð"HÙ2ÔZ2Cdí¹•LÉIB¬È´Ål>ݹ“+],'ï&gªˆƒp…#®/b1ßcüS?¦¦~Ô“™=Ð>â÷@¤Ã æÐ1‡'#c"(3ÄšÙ—5«†m!.ØÜ Tk“y ¶>ý)]º"監ð²aŠuæÈÀ¸ŸB_d~‹•fÎÌ‡Ž‘p¡Çƒ3±»®í…k_Le¼,JþuqýéQÏ­šEÝ‘HŒ›7ކ“aL]'ªDùOdÏ.M‹‚Z•ÚQÌN«·È1ºâÔjŒì%‡1ÚðÍ 1Eˆ8§—JÅA¡Àäòol—K”iÓå Ž¾L»î±@JZ¸Œ­€ÙèïBYÆ&± Ú+ýñ[õ]Ä¢ÛE•úι‘NA€Yßïx{kñÊHþ=KÖžÙSÎy¦Uët1°ŸYkìŽEæFŠz‡pR7¼+p(´“Óp¶NK§¼°içöÊ^¡œ¼d–>f~”Ä¢hÉQÞ¨毧öØ:v½åÔ FKëÛkø»6–o_» ›ü®+(F\8W0 ”-ôu»×´^Î.®,°ýææ¦—îéÿ/SN^}ÿÿ­z£¾…þÿ{Ûû[;;[»äÿ¿óàÿÿyâ?}åN<h¿GJÉWf¤Lí;Š)2a"œK²ƒ3<ú`_êçÑ=[ÇÅû·Öàòݱªj aºb};¦/ß‹|ßÕÖba;e_N›ïö¬zFa»ƒ…»é¥gÍÁÑ+k+µdÚd3ß~[ß+ÿö.Ke°‘lûÛoŸ®@Ýa9µ¯ýÜ¥|>9¨‘YÙúu»UßÚßÚ*cð!㈀D£Xžlœ´\À£“V³s~†°2®Ñ’vÊ*ÌùP­Š‡”I~þ²ø/cgŽ:ƒ?4îïîfÐÿݽ­FDÿ·1ÌV½ÞØÛ{ ÿŸãç«/­Í ×Û ®àèŠåÒ,3\ÛQöÜKÇs0- jý9ZǹN8i­Ê j‚R‰S- &âÐø'Õ­íêÖ~mkûÐúÊ:Á¡©?}J9žX/áíKñ…ÄDÈmoTÚtùÈ^a’;¬!…ÊCÌ$m1·ª)\zhØ¡‘5€Æ ‰Pqt5Œ7I/;çÖKíÔ:ãˆÍ' É# ƒ%I;¸"X@ƒ²ú|(ÓÉüz Ê­ äC/"smä©§v¨@SGª4–Yѯ| ÌJi~C=ü30ÖÀ€ ’ß´Ï<XÍÎÖ›f¯×ì ~BUhÛÏì»(ô ÜÞb‹¨P2”A¼å©Q¬»+"dÍg åìá|táĺO\K½Ôœ:·¨çv¬îÔ½¶­o}üçûñhT[zîÈžÍk œÐÇÖ£:4²ÖE0gtå[k¶¬ŽOo?€ e|¢ÖmYUJY¶®v ¦œBÑÉšUÿî룹…×ùòÿ©^Y¿aíÇÜ̆òí·ïZÝ¥óÕƒˆØ½å&Þã/âô½·ÎzÝ—½æ©õ¶Ù{Ù_*õ–žüÖ·ðùËGDWµ’E"K1 3Ñò@8ó=Š.>©@½™ˆ*mK¤÷Q°÷™x6€~ŒñË¿Ó΢´ß°&ëFg×kìHˆ®ô#rSN—Qé¸uvÜîq%N¡K‚0jZé.ä¬[ãAæØ èT’ê,+œÍ#؃ö¨š“p¸%I{ÁóZ£‡Ñ‹Ð÷§ÔÔ›+Gæ4§o˜ÿ5¦wp =¿ óK}ö-üRµá ¡:ó{A`§â.‰6Õ£ÿÒ6Õ5mªëÇúÞ•é‘qó­¥ap{„)züŒ¦1øîAâPæQôÖ HQã Ò*¯hûÀqtë5~|×b̧5‚WÞ޼¢ø} 3ï;.ɧm­o®«Pž2Íât`–‰ÕJ¡!E•ß`k'ã¨ãSüã2öãÙÿŠã^_ƒ‰ÄÅ©:ÖzðÛæÛÿÙ|ÿøÑo›¿­ÿï¡0%°Dú›&îw}ê‚ådâÞV‘¢ÍçH ¡E©6_5©“s‡õ×y0ø«1üÕõÿ©=Þüí·uþkó]ííÿÔ`$››ëÿËý¥;Gí[±½Q•å(Á© U–ùj“wí‹l€è•ŽxÃÓň䇪Á"Ñ«ŸZi•ކó·ÖJK ƒ‹gÍçGÇ­/_µÿþ“ÓN÷ì¿{ýÁùë7?üøÏÍÜ3ûbu/¯ÜŸ>Lgž?ÿy„Ëë›Û»_JcàîÂàÙV½±½³»·ÿäiɞίìg~%Ü¿?ú•P ;¶Üê¿ð¼"[²†Öê+s(±¼ÚêDèõ:ºË¸vE·“¬‘Ì’g=âÿ˜û+ÁÁëâ)òÁòbóÂ^Ô|Kÿãâ'ëÒçüVü•œùµ’Xtºø­*É¿‚õ[‰7'\oÿçÝ;º¾ÖýÊ S•°ý¾¾ùõo‡Áoïjï6èZxW~ô[íì]?ž¢Gð_¸ñ~/©]-ª?¢Få7]4 çfm𮾉xJiÛ÷#TzÉz8¯-m.G1£µÒåh4™Ú—Ϭ±\ÍèWDÐGZ>£PãdNC¤gê~pD:Z*ª¼¹¤ç– µ,&`€qxƒ×Oôö‡1‘‡ä|­‘EŸ¢f„€{á^23A¥xÂzáé4ª6Û±;pù%¥Çà€àÖ|<²=ûSÏlÂhDóÎÈÆÏJ6CÝåò•OEH(©ÐáY’û_ÛüϬ«y´¯¿²^©ëe‰o‚ÕSÚŘʗ26Û‹K$r¾«§Šûi/§6ƒ óÃ,Ç@ ´%g¦V†Vá$;§Öš_òX,m©«·z74ÔÑÝ%òSÃå³5ñ«U]â~«®¥wu\fÁ]°²›äpýŽæsÚ 7›ÀÚôš½Sªÿ®<ßCãÞ DpUu‚‘ÍŒ øâ°© °SºcoìŘ襀;˜Ü©Í„¼k4ÌuaÇWyÓ*fK—ôõ“ò3€ÃcR©ž¾H98t^µ^EÛåÒW_!k›Ô]t˜½ÉHÎ&Ú1ö|ð…«˜ ù+bÃol87–õ£}÷¥´t¦ki$ð䘂ZÊ õÚ¡ñÖy± qpfNág"A<åO U…¥áZx5 jœãL„KLˆ0½«¾ñyÿØ=y ¬+j¥lL¿Ü$Q[1 ~AØÃê‚×EÍ ³žòðs ºCè9&¦b^”0ÿʹÃúÊ„‰17j¤MÓÅL Ž@žÇ˜i$ 2% KÕYíQUÒiÁœ¾™GàêøÛ‹f·çßPÿ·GÀýU® G;³ÏÂ\ mŠ—ðI ˜ÕQkâa–øµGßSx:Юk9Ý8½Æõž5Kˆ tÆ™$‰gzåNBØái|y$ûê!׈8(Q>#M€<5ð“U…õØÒD„tÆTj° s¢À£^'F¢Õ€îâž§-Wˆ Éòƒ-lcü‹À‡‘“é}u»vk½<:Šî°€ö!Ò({ »Mi¼*^œÓ²öéóèxË4!p*D„g#p"#Ÿ11± Ølã^²J Ð?ÇMöÊTm@»uì(bâºûŽhFYÖŽ± *Äáðl€üyEþÁÛ²#‚VAîÂyÂó.R¸$Ópã¬yØ,il'@ÈĂcHÆIÈeŽ]T¢¼²¯…yÞ‚U ø_‘å#œÙËé]ëm¼q„d¨ËØgÒ„fòÞŒÈ8[ >L­W™G€V0pªZãVç¨Ýê»çƒ³óÎô)‘š­ú@Ú#E¯àtžVÈ|˜˜ `ÎæÀeAü#`Øí»2 ­ »£‚n&“ÇcäPB":ªô± “¹1è ë’°×x0ç¤;€N°J vÇÆl‘K u¡>¼AóË zàž5Ý€càñ¼C²!·£„"¶.´+í¸"ÏS˜7óJT#v`?ýq—º¸ª‹$ÖõîÝZ\Ò¥S OÊÉÂ~’ƒÁzc”µŽ»ýjÞM… ™,ݘa/Ük‡€t°”êkóÞþÏHâÖ¦µ¹nISY´þˆ„Çõ÷ï6u¸˜|n}gtø+Á y˜ªqî:|­ÍìKˆIÛÀZ¡5¡o°„¾QEZ¦òï(ã&)“m½ŽLbJ\ÀÇ´vFEtSR±Q18Üc6qõ$‰-l5%L r‰Ü„ws‘=8qdÎÅÒ2qäΔIBŠô)Ð.Ø£&‘D >S®uP—¤õ³¾\à˜Î°$ópgàr­eš)í„ÒšTRXÉ'>}Ù#”¼&¾Èê´~€úå.‹fð?qǸ%@øP";z—¤·È_H„âýLPi›É²3ê«y$çÓEÕÄâQÕŠº‚`OÜ[¡%|}Ö¼¢žÔt"p>p}F6¿V 5ZÀ$òk©0åkDÚLðíuþƒUߪ5¶hçϺNb¤øãœ°‘š‘Œü…˜\Ëz.sôRs!+ñ؈[V Øé …j{/Çô.²°ÖáÿÖyÓ„^L´ßôsøî*œé¯Íÿy´9^g•ÙoµÇ‚6<úí7Ö’mPqÇ£MëP|#éä y‹«yYÉ3ÄÉ $›cFw2ÊècŸìúqœlè¿á6gòâû4Ob¡¿$Ï?Ú÷Ò«Š|{ –è¡Ûs00æ%[z¬“…Ûaä[×Ñ•3ú 2 QSj"@pé–5ò¼öHðì(ÃÜ9F£™ DjWÀr>Ž©’¥8¬§KÌQòÏp7䪣q¾îï¦cKÚ6"ˆ¼bh_Ê×3qçúCíªË‘MÝ9¬ᯉ¸ˆÓØÐ©hˆT9¬pqÇ|d4¥ÅEží‰hp‚k¸•è…¨à;z»×þ¾Ü"¾Ó”uDS04ûµlŒ1’Ø'¿ÖRÕmìl=Ý“2ÅWŒ|¯ÖÀ*Ö“úÓR ñuWm¤F gÆž%3'µ|(°à˜©òUHÏ”`™×¿:ù(Ê%íxã(oU×.DË:õ"F#P{îH2l~U{l k¼®UüŒ[ù.±Ì´¾KY}ÙÀÇŠè'ˆž©`àøÆ›v}ý‰#“Dî@ãTâýÏUþ¯"‡ ôü›ÓCÛ½-G #ùZMØ´GiZL¾4ƒ„ÜCõ™‹ZJ–¤ ¤d:V¦MDs"K˜)‰pSà3¥Ê—pŒØ‹R½]G²6‰ýŠø|êȺ|HZsÆ +G¾ºÊw±ˆ;¢×TõDS:}e½¶[{<æ«=ô˜<Ãps¬½…GÚQ Þ•õ’ÚnõgøÈOÕµe¬¬ñ,ýû6Õ©v8„aP‡¦ïþÂe–m'ÊÄ­øÇ/ÀúšñgÃüs;ý~$ÍÚÖížX…â)õFµ¾þÚº@VO)}²Þ ÅY G‚ZÀ/ÖÆÀõîàÄÉ“VfË-è?œ´uV\½°ø™›´´'ܪ=­5öÑ‹ö§-Œ¸Ó(‹ù]…­Ç@¦þœn'[¾³Ì„½ >›`nÖ¿þÒÏ)I6‘Î(züÀ«ŽÝðKqù‘ò3D BJÉã|¬£’Ÿñ·…¡âÍž‹+zCFréY  Æ–<>{7’F°,1xÞ¶;E ¹þnø×Ãwê¯D³ô–Ž<Šì~™^ñŸFŸXìÑ‘³¤Ï²ÂÔøn¯TœÞ“æÚ$ªÍA9%Ò*Ë!ŠñÕ8 ëOœ¢0"ÏÌÀ–ÝÚ~º3²'û„g­…Ÿ6œaØk¤¯,fR—ù¹ôÂŒÁó½*Û e4à"¬ã’.'}·pN‘! ›0ð^((S1\‚dh‘wQ=² çà·ˆ'ý-É1$Ô!Mo¬¸ê·ÌOÌl 6I«ìƒë`[ëÔýƒuBÈï*E­!¨ãž4²¬Çï6€})ÿïýö®~ðÛ |Ö•öÊâÖǻܮ¾!y[—]¼!»_4`fúçû¤+œÙÞKÖBSXÁ‹a àxÁr!ăø[ i2Q¯ ÿr@ƒæ—’øžÁ¸§P¾h jøÜ=±_qØ‚]š |ã§ÝIƒ.“ŸMø†î²¾ZšY“Í`“©37. ݉âÀéhèdÁE¼š¯sRSôn…Ê~y1<ÊI‹ƒ}•÷WNi8xi#S ˆRúd!Á4TþvU’–D5GzÍǘÜR‰€d¢ªÕjŠ$+ıïð×*Æê+ë\hŒ¥ÍŽ\)èhŽÎ(Ӏ'Dìx¾Qàª[G=öX<öñ¼ÐàÆøâá×RØ8aåbز 6l\â‹Ù'ð=q,HùGVÙún`5©ŠÔS=ƒ‰·2¬K½³ç€ZCžq,zÌ(‹mA|o% %/;S%ÚZh˜1:SîÚkœ“­ÄÔççÐ D!îòN‘98°eñzöJRÈ¥áhd‰ tZqŠ9©âߤá‚í¢É’ëh}ÃGJ8­pFlb9‡=b¨0õ^Ì!Ô¨×5ûo¼­ºÕ°êÛèûg¡”.@0yVßÚÂ;ñÙ#ùþº¹¢9§KÒµª—!ÞciB7Cä¬#y!`«°ç«dh(bd2àšìÏšÕønØ­Mo9j7n$Jå¡=";GÞ XYÄC‹.xi]éŒDõITãyQýŸ%gª±øš $ã /ò-G·uT=kÛOtîDÛ £êK˜KÂpãòãKd Œw>ÐèÐ9þ2”}Ô¦¼:Öç Xèô… ˜:ΜVW„{ö¿øŽAÀVýÅwÁz ¶% J@Ðæ«û$b–vjrJÊAal¡0|ä¥ãÙãû&ÚX2£^°íX…‚Äpy(´=¬ÁÊ̂˟ÏÅ¥ñnÿ3F kWë¬S€UÕ ë@­áŸñuäÜô¿ø÷6ÞÑØ½{Y°~eýoÂ|»b¸ú¿ZùAÄ¢¹(?:U"æ°R€9üã/¤¼øOlæ'Ga1›ø¨ò®^9” ÿCÒõ •~þ3ÁG¨øJ#´v5_CRäýb‹0:›A,œYGß|S¦•zu¶Ž±Ó÷vĬD쿺ƒ6‰—l>ÇX24«þ"a>ÄT îoá"¬Úڼߠ¸:>$/8´ Ïñ¶bX8%ùd¼.{3%†ÞG$áÛC¬Ý5Kt|cH-‡ÃÑ]Nêt)9b¶ñ‚= \]c$æ½âÀÉ-ÒÓƒa‚Ëù³õGãT•Ž®'›z"žä|]Ñx…®HC¡»—N¨ˆRˆÿ¸èþzŸ>…ŒáWÒ)cÇcIícÆ»¦Ú€‰[oTýAôÃz¼¹™ül½{‡šódêÍã_çæ‡ß×s¤ÖÓ®'„Ôgxið¹Š)ªÙ0ˆß>Ë6¹ä vË‚³5éU|¡@"¶3UÑÍ´œU@Døø7¥fdÙ&?löœ1rü{µz…Ô{öÏÖÈ×{µFuwk©ÀŒ(ˆ”¸bmH"¿‚m¥äËlûk¢†Ž…¸¿”€Hã\pøàŒ?޾#0_Y'ÂàQ=ø4¢ž‚’‘ƒiÃâ ­èÄg±Cƒ|+»ñuaXµy‰S*˜$¼rñCR7ÉÉ#ݽ©„ñ†Àà+½P¢K(F]7-ʹpZF«g!}°|¼=Òú­™ 82“n =uÈ91&$$á['>à2ÃF…¹kŸü«#¥d†LêU©ÜšMîÀ„‘'dÂÖ¨¶‚¬c_£Ÿ¯4×ÝÜ‹DTÅmòÁ¹q§–ûF1–í¤œ›øóÅñ§¸“Òß/Æ¥˜DÆÉþ çãŽ{kC• áU¾JÏ䜗2/hwgê¦Í~ŠÁ3Ziý‹¾æ&d Jì=ÒKèVÍRž_/ŠÞ¾ëÿÃöÝì.‰€°Öz¢î¿‚™+Íâ¥9¨Ça'“‘¸Æ4#?dÒÙw€_nuÿ\Wá xq¡ ×ÑëïÀb‘¿b]‘¨?|hV[öh´œ¡ë¶>Fá ˆëÀW>j"–¨„ÀϬҎœÇlfÙ—Ê-”vòM_Ü ¿©GF#‘Í¿ äqÁ––@| ‡r£‘©c\®ªÂ¥\ÚÌØRŸ¿I‘ÒƒÍÍwõMúåÝ»Mt¥ØD¢ü.d¸×¨?ál}t€OAè»HÄ« K–ŠæÖGël£(ùI¾â£Z¿E¢ðZðÛÿHñ·ÿsÀ¿¡fµk²è·HéøÛZ wr3ST™?I©h* ?™bñ“ØB;bÝ5~;е ®ˆ4Å(d4Óuư …§Ý"))ä8–`…yô/=™HD<{v1M}ánM–SÈœFQ0Š—”ƒ‘Úý»óƒ¥º\R¥(ëÇþ ]ÏõülR'@%¹ó|`­­DMâ…a%œä"®îã#·T?ôtrúŽpä$Süÿ­½ýFãÿÕ{»uüco›ò¿lí>Äÿÿìñÿå·ªÕªˆ´ù;^¹ÎµwÉ0ÿ[O«[;ÕÆ“Z£®…ù—Ãñ!äÊ_`oûÊz±pñÌö¬o'â·ï‘-¬Ùnmæ†5g¼üÃdrXṴ̈]ÝÚ­Ö÷ૈ´Î4k¥¯dœ|éuŸ1n+öšâý¥bÍÙhzA )4þªÐäuæs8â€iPç[ WŸµ˜Ñ2¼§à ×¾@‰ºä,P™.ƒg[%˜Fâ7K¥%F ¶öN†"7çýmõê}zTò·Õ™uÚ=n½·0(7:F”x’ØG­oÇw¸ý°ŤYþœq¹¢½]¢ªRú¨)ýJ,:(8›bMJµFjı ¤ÝŶޖà¼cA£ew˜Ê]3?Rä°TªÒ˜Ç¢É•̪;bN«³rfª_@<³ÎZ½SK §:‡uÜù:þõ×Ö¯f»Ä_Êpô”F]ÄN§µTÏfó£….›ÚJ,ž5¶êª±¡?—PeÔ‘Ò%å4 0?^…y)®ÈP7±"*V¿Æ}⇵?›6 Ç!´ ­M¢£Ä̱÷Y%ÐîŠL3Q¨IeбG%/ˆ{ŒŒ7çW¼9·Ê<„-=¨{ߟËXOÖáRE¢ø” ˜À‰Ãi((]ƒ„±7/Èxí+ýÓH²ÔäUƒ|[…íÕØ#É Ù³ËFßD${.-%HEÛ5’Â+ñCÅÜŠ\øô(✛•ßë0‹†µöO*ËkL\{Þ³£ðJdêr9½]ë¤ ÐþÖVFH0ØbŽ¢©É-¯aü ‡õ·Ù}„”Ú_.gzÍfܘtƒf©¢Rë³+ÖIœ73ÕD䫬Z®YšTÚøîëzä‹ò%î•Úfj>]ÐÞÖðY«“ ‚‰^‰â† N׳: /õCgN³ß‘ ÿ`¯uB°ÑQinUž°´w !¡¹dZ: ¸VC2´îmIÖ×-E£ ÑâSë‘|aˆzr{Š}aà½QÓI#ÏØçý‘ð¯$@4û:œü¨?Ñ™~_?´PK¼–¿šR9qÏE©m´j“}ÉXnÌzîa?vJ]zF*g ±1ÐßÏ«>wkµÍ¨åÃÈ *RÅÈé~4V³ühœá,Ñ1“hòi‡ˆ™Pÿ‚ìÁ³MxG_5BlY>2Dà?Bk¶YÒÕK„Õ˜¤¿ŒU¤Éã8f¹¸vûhLQfqLÑ‹!•Gí?’¿‰Ñò äG9¾Ñ¢J0—„®Ä2ž1¿äÛC®enR¥ÒK0*@-'>ûa}ÆŠÎ-}¡ÊG¢²l·ÚZõ_´})kËNŽ®à³ÚÞZoDv g@mƒ¯ÀFï±yQª5oY)ø‚váb'F[’5­iëº)U‹|53#!þä*R^W) ;~þ2Ο Á1噤ÂÁ§³ó¿Öw»{˜ÿowgoo§¾ƒò½ñÿïóä=êwÏ{G­>ÐTÊþ;MýÀþèƒwûè |úâ’K'”YŒáûZ ²CŠNf~ÇÍ §ÉüйÂ|wl~akTÇvhÇ?!_èß™•Û9 ’ZZ²’Þ¥Y41Ôz–æ,–¤!q¼ëžKŒ „w@A x.JvŠð#ÆŸJàb˜1°^¬Yv©¹SEªcpÄ g8ãµ¹ÄSJ@¶³^ ‡ ©a@râp›ó†§Á*În³+zö<\dÖ”©ÊÓj®ªøÙ½ ×™eám˜V6µC$ï±^°¨m~T³¬¾±™eâ£7Ž ÈÔŒfs'|/çI`Þâ Á|ß*Ò]ßø(sRéRÔ¶þ…z²?ô¨A8ÄÿÍC­. } ðn`ÿf Ä0\¯^µšÇ­ž¤Hµ«4âq•¥*ˆ )”UŽ”Ø'/ˆ}‡ÚühŽÆè’;¿šÎí¹ÿz½ÃaœÐ«ä 5¡Å‘3?FûëÊÜ_î5¦b3>.0m|¬º¶o®RöM˜wÈUÚf¸JÙ WñÍ} ‹_goÁ õVéÏ¡AíªT:mvΚ/ÕÅ$nˆí,zµvM¤}Œè–Ž ‡¿ýEÖ¥²}©lÇ/•íä¥BÛn;ó®Ùκk¶cÛ&lóŸY@gȘymgßFÙECb ·3.«í´Ëj;yvðÌ'?ÓqÚN\mÛ_Ä?é«–óçl¯†×WI'Ôq|&­ŽaCjÀ¦v—A³ã¨4ª¯§îebÅ›ä;«Pû*ž„ˆ¨xJLjǿ+ZžZÂÜQ¢Ä S?f-sœªgkxW“v‚YIÜcX$}wÚ$ñ±J "ŸZÑùÔÒˆ–§–*jžZ¬zzqDÓS‹Y ÊŸŒô)2È{ “ ð‰*Hâ“u"Ÿ@¤“ù…{i…Y‡1Ní³«¦ŸÕtšon¾4ªŸ†&“ðg¢S´? DPÿxS’þǧB^ñï÷ßK¥³ãi÷À|<ɺ¨(y ¤޶‘‰/®~Ä™W€‰ o€8*uÄô?­Lo"üg‰evÏ$þejÌ«H ¢üÉ>á}Vt?­€È~¢À “kPýX…8Õ7»lýŒšÑÏ®.‰¾ !i~ ·IòÍ* ŠŸVü´ÂˆÞ§*rŸVª¨}jiDìÓJ­• R›ƒÔ‰1}¼Œ }â«7Nì“ΛÝ1É|vÙ^JYÆ‘‹ÓøÌŠ©2Â#ÌJŸ‚$“¾g!Sä= › ïñÁJòû.©{ì³$îð¹Tê7OÏNZ±Ç °â†Æ3U3¬ë'%*S«'Q]åi¼t•ÕƒuòŸlÿ[DðüÔï[ ~ÿ«7öv¶v ´ÿÝߪ×Þÿ>ÇOíÝZ©6xe5{­þ°ß ûÝ£À?GÝ΋öËó^kxÔ<9yÞ<ú‡µm­íY/œ «±U߃ZýWV§yÚ*åoë]Õê;”QŽ@¢hòôênI0BÙÿ±Ó=ë·û¥š7)Õž[_ÉAßòcÀw¥ÚÙ„wsgìLÐÎÉÚxÌì¢ù¨íòFT} ­w“¶¤¨ãw“³JÉ*úƒ Aml÷~)`öc¨º„»9K¨^–àÂü)äQ`\Ï™b7įù=ÉœÂ"~ÏG³r£û·¬ê³í¥ÚÄ¥åb³ä¸9PSŒKÑ8"td÷váS4º©Lbß]ÙÑÍÙ¶œ"S•DŒW/÷¡=Œš(ÝÌ1ÁWˆ1Hðò×lmÏrÇŽ=%»ŒÅ<‘‰d’ZѶd•D`[ÙyJb°pÂå‡ðünÜ>%×F'uã8¡¬#þB‚Vëù’Œë=ižÙåÐqúBSRbK>ͦ?w"øVËjžô»°½$—nml—+™¬ –’æëfû¤ù¼}ÒüX€"@5ëÃ#ŒÇl¨Ï÷÷P½¶Åϯº½RØyçÆjÞ9‹ÒÃýÿ9îÿ؋џmÿ³µ»¿³»ÿ·áׇûÿ³ÝÿïÖ¬#~· œÍõ§OŸÈͧvØ£+ ù!ê¶„n¸ )4êÀ]yþÔ¿¼«•$’3L²ÁÉ…9JwC@ÝUÐöÎÜU„9êI.–!'m¡Š? oÌQ¶–3Œ–Q¤>võî¬ùr1÷Gd] Ä«OrýÁ(ÚÐñË…ímiöÚS‚aKÏñÙFr¬TÙóCLº¡’ÜÛ”öfœ³Ã§hã/0µ²'ÒöÎÕ $ð Ÿyt¸ÀªÆ+ª)=[Ëi­]ÔDm*çzTÛÃ=º“3ŒW”ÞaÐýI$&{$RÐ.¦Qz*äª:èâ"âh@´Ì²Gœ)ÜC;}Ì'­b* /…ßÂÒ í wŠò'T™½‚eÓ±U‚9E˶†y½ÞZ²Ÿ"5ŽÃ9º ×^àŠË}(™Ù—-¸?úƒç?6{ȼ6v¬¿/§w´Áãì«Aó]m“žˆ#°À"ˆÈÊŒø8^•˜(Á¬"ZKø+{q‰Ü˜d7Ù¦•ø³Úó/$Ê<}Æä,ËQh Í$á¿§ó™ÆXWñ•ÈËÀÐUÏ^tÄ’=ÁoSÇÓ{<±gîô޾$š`:WlìåTîq€[÷yÊJÿçŠE ²VM&r£ó…¼žP1â’‹vÀä‡Îíµv/b;k%J'n/ FŃBÂXB¯ñ;LB 9V¦3¢9勜¾‹»CM‹Zìuu²4v¹9ÕOTEŸ"¡S á¸s~rbe ÍÒïåeõÕxŠSÒ2˶/Î¥õj9R¦íͤ!܃¶åÿ¦þGÎ×\ï³ømíã™7ÏcwïáýçóÄq'J¦ÃáqOÏÏÛ'ÇÃW¥¯à#îˆ/•6kÊ¢£²…±_ðJ:¶=„¥>\›ðØäy^²Ãÿ”f(¡BD…CyJ!D–¥º§NQ%ëÞS%Û}4B1m⺇Bh…21eꃬâÊ Äcêƒ>V„*¢ ²oÒV}ö 1@øiõ­Ýž=“ZGͳæó“–Õÿ±?höãÏgŒæSôðà,`¬úþZåqÔ:>=·)Ï7ìo,Øj‡ÎÎüø'¿cIû¹jpÙøè+¼¬g¬˜® ãPD€ìÇÞÂ?s¸[2H;EjÙE P8²'ˆ…ÜÆr‡s,“Šˆã„<¿PéˆkgêÏIÐ3Å]JJ„ÖUÎ67G8ôʾ½­Î&B´‰h·Éˆ6ÅPè½Räq§™ ®(œG¦§>w³ ˆ7AÜÍëôÊiï‰|®Ó‘\84=t8S!¢Îm Qô¹?.9o›ZðFÊ‚÷Ù¹á¨2ô×%y_ˆÈŒÔñØÝNë®}ª0Aäà.ãe_[i+Ž ‚ÊhEP–P@ØšSvd8Õ‹¥É‹ê%”½á+±¯B`â#s 4LʼnU—ÁØè'†b[Q&X‘Š©Ë”ö.Iš‚„ÉaD;•$ý¨¤Á¡íjº2‰mÃ(y|Q~Eµ— íþø“ãÖ‹v§Š «û¼jõ‘¾œ>ïžô­þ«&£°)¬Aó-ëì¤yiçÇ7¯Z@Z'ú)‰ð È&030øñ¬Õ}1deU÷è'­ÎpPúÊoÎk+ Äù÷3cŠË>é&Ó&™b¨´å‘JÀ7¤×lg<\ÑÊPDªŠJ_és'ŸtqZ? Z½NóÄjwà—8ýýÖ`Ðî¼Ì»º“?ñ;VbnE 8uÖŽ ‚ÒÅT·|5#m¦c,;¤Óº› ŽæîN™)i½pD:ç6thƒ@á†&@Ájˆè«¥§¶ËÙùÉÉðM¿18:kŸ!o©ï¥D!F¡ÊoÚíÆð¤Õì ›ãá)ü‚¥–YV9¯4¢‘1ÂÁßcbŸÑ>¡‘øú;}ß|‚N™b(ÚDmkð)æ6‡~ê$¥Úxµ.|ògŒ˜íB>Õ…ÉZÖ˜Uqlвƨۜzj¡?É—=‘÷%Öš:Þ0Lö(."ÖãÍ¡+ÙïŒò­p5«ìxàþâäv»ßþg«P§5l+ºÌèŒ*˜GæÛ‚6bò%b{PÊüµúÍ/û³è¶{ûqýÏþþöƒþ篱ÿa•N};E¥ó`èó`èó¯gèÓîÀí~6!iÛZ«ïKõí¸OD×о$@œW4mŸ]ï`3ðï^d¹ÁRf3@ …ë¡ìˆos÷³ûaL§h=6û°Æ2ö¤b€ X6†aù0Ã& ÀŠéYPð–!I*Æ%aS 'mcl¥w£wì%ɵ¯mªÅ»I;ê_DæZŸËÊÔZÌ_`˜»¸iJŸf/Æ4%}ÛÐr+ôà\,@F׿·F¯Çï&Ïí Ú†ÈGkK¼y™E¦ bH‘Í Vo¾ MAGMü®­,Öƒ3_bI5%|^ÑfC4 a´®ÞÉiÓŸ§P%ÌmÌdSr½¨2,]Fe[e4†¿XÝ@C‰ìáCmxˆ2ˆ¹Ý>gJö™s;ž¿¼¼BÔ”/9¥^ic»áx8¡³˜ŒŠUorħЉ ÿi™l\Øãû5´]Yø‚ý„+ÄñP`¦òƒãÌ­p&í´äBïࡊH ¼Þ Óå2löI€<³¢3Ù„±íaœXQëÙ3I«Òjá&Hýþ Ô²þf%¨Ë¡Lª±áÒÌX.Ã$”å~óI)R(û¾|pçª+[‡+aK …S=¾á œä¨*QyホLíË67Ñš'͗À²õ_ª÷°:s¨v`5ñ¹¯ÿOm-‘eBr°ž÷[¯ÊêÒ×ø…Œl†¼ïŸpSév:½Ö @pœ¤5¾µì/d˜ÔnìÈ=ÌóɈX¶ñµ<Çø‹wC …劚q:Ë…+‹ž‚ûV}±æØxÑÊp²‡è³Ömy>m×ðuó"Ë€RÊ¢|&pĦ úÂ?ÔpV›_«u× ¨ïÐú?¢ÓM‰R þ¸üü* Ó]QùÈŽ²§áUÄôú26jý¼tGÐ/KÒýÔ~Ò–Ï\WQõÙ,«Ý†ã÷àp€V&C|q%6€G’ùDÞkœDMòç‹¢¢ñ˜Ìÿ^Ã_Ú¢"‘ä`‘D Œ¾P€üýA÷¤ÿ“ÁÜ?“þo«QoÔãï¿Û{ù_?«ý¿`§ÙãM¯=h½Ö¼ÒKKÊÃåá¦ò0©Y+E'Uw|èôIÙ²] FèØºØ¼´Ég¼½Ù¥+Vhd\ØI#Ò{± þ^ØsÈW5ù½’`Bñgùnf£)¬:Dщ Oï  '!?ÄLhh6gX[é :b¡Ð©ÙÓ{Gb½ü2òðZ)#»­TŠð`½õŸpÿˈžŸëýo{k{/qÿï>ØýïÂök«šeöpa?\Øé…]칯Ùï·z‰Ç´póýLU9iŸ¶l8/+LÝ™± Ògec8DÇz¸kŸ´zeÌH« —ž{;–?é3$ÕMy!ĪF75ój³“ØGÙ7f€‡Oö×íÎK6Ûîtß4{á‘UOL¸ Ò爢ùƒV¥c˜\V5“¨>¹\âSTœúZ!aXEÜÈvÿ"k)Œ‘dYâ >ßd¶90ãqÚìÿcØï¿êö–µu»ÿâÅ‹t˜óæE&L¦ Õ.Œ'î<‚{±®Òí¼4ðd Œ%Âóõ˜œ=àþ+Øã§ÍVù|5˜5ü³—:_ %Œÿ¬À% ÎXä}QzüX=3 þU„9…¸ J¸ié9wãípùKèÓ »üÅ[ÎðaYøöÇÍöåÌFº‚$tc¾ ®Ê)ß®¢æÿàI}«Œ'‰ ‰êcP'L’JýBšŠJ²¦Ã-*#_¾¬ ìmyƒºf}m‰®–G|vñnû˜z˜Ûú=êàLÑ̑թš8÷_zâ ³9óüS§Mý¦O]ð/=uÔÝœÉ#úð ¦Om±Ü™ \š9¾æ_gÚŽ[ÏÏ_2Ó°ACƒ~ÃŽÍ(—~Í›óÏœN¢q«p0¥LpÁô_u2§©“I'›Ë¾òO8×bê mÈÊe’hÀ¿ü«Îì/+fV{}(Ÿq†#‚*çXÿ Möòß|²õa™õóO:ë‚àªÛ+"¹æ'ö.ÿ=i¯9žDøüáñÔ®~qöâÅ ùÍ’%ʰlkëÅ 4`1óþSxßóõZÌM@ædªã˜:§^è_=̩굘¢sZ\=ôð>òðýG&B}ž÷Ìöµ“ˆÿ¸óðþóàÿõð"ôð"ô)M8$Ÿ.I܆î|ÓÏvc/Ma÷ó_ܦ“²,wœ’. ¡ãJÜQêqä(…¿¡Ù=1­âîNäHÞàŽ¨NpÐütA Ë&ôô¹"1é_šôê^PèÂÚ|ôéÂÿæÒÿ:”õß­#ÜÑÿ­û¿Ïcÿ÷øÓý€p}¶ðrF¡<C`#åoýß¿á8˜›ö³ Ÿbüö¿Àb¯‡ð›õŽ âàÀ3ô~³øÿró`x—ÀþŽ Åo¨ú›ø†H6K_•8>ç³ïùßïK˜ˆa(?j|9VÆîâÙ÷üï÷%½ ¿©ß¿/•:p”D¨ƒÒyï$ A:&»Š(霧-ˆ‚;3(ìewÞèjá{˜Mð¸Ó—ù@DLËÒk¬ï_·zýv·ó}©çü¼tÓýZnŸðéˆ\¬jûѯª¿¿[ß‘#«Túƒæ }tÒ~þ}éĽ@ø“G¿ò˜=b‰Bý½ˆ½Ök¿nðQøyÿû)â߆ÿ‘)íÃgãÿ·öRâ¿ï?ÄÿLößæ4(P”ãq<0¢}B ©[¤J…br’Uô¥9À'R¼|)?žö»ý²¦¥¨£îéÑp(¢[¿±Ã‘?1¢mëx:=w£lQàâ1ɺ•J¸õ€4QÔãr%fŸw»'%èWó¬-ñX¯Ú n£–u…œŽßt{Ç"ÀqÅ:9{ÝmãŸäè4fv´•üPýÅ5Œ\G×^zç-âÓ’æ94]=;àÙþÜJ—Ôø*ûë' ¸úü7»u”ÿ·w÷wöövà÷­úöncïáüŽŸO•ÿ3™bH·¢>Dü7‰"Ø`Á]Øô‹Ñ™A'#jy±£$¡äËk#é÷§øt¥˜‹G L† ”~!„]"þUÄ?!&]C»‡xkàæpF>E\^X3wŠW ý]kWF)À9¼ bA'R‰®ðþˆ?¤ŒçĦ¡·,¢‡dv%!Q•0ÄgïXñÂ9^'Þ’®>޼ÔE÷´¿…"eìÏ`¯êˆþfŒ‚Èw•ÒÞ£«¶3]XÆ_‡‘Žñyˆ5Zïì9ùóx¶ÑsWõO›á~®z»ó ÃÕ!¹çDú'}#™1w«¬ó³­fIÙ9XYü¾¢¦HÓ €3;ø°*ß*ÅaLô—³vÆ’®â!@N CK.=ÌœI=’g¯‘‡Q¬çåse.Á –‡oEû”2ßl‘xD¹fêÀø\r Fø2ž òˆ\$§}½ËL Ë KžN·Ha¨2«¦e4eGvÑJJ(Ön1Ï'/LªB‰DE¼McYTÂY‘³¦ÂëÈt#È®óA䋦&¢wœ±/(E Ì\ÓÓ2[/s>‰²hvÏ¡_db_$H€àr¾ ð ˜#r8dÒ çʾƛ@ÄÇTû8X ­1)/•Ž¡¨.®!6#R£ÖÒº5hŸ¶ºç­c‚8F]pL4=Ä’V:ÀɨF³„ÀâÜš¡/Ü÷ǼCØCžW±ÄNó!e¶ÜhNB‘ 6úÌiMD€¸ôáF¼šÁPá,À:ÍülÌ3IùdI…¢Ÿà”èxpÝOïTèV8vÛW­Ì›¤%{9¥{o‚ɆŨjœ§†×ØÒšÂíÇ¡£ø4Äçð´ûd&‘2H„å¬×vkU³Ú/<ÿúõ‹P2fû_z:~èH®ÌXyjǪ‰æ@^ÿtˆñ4² ½˜9”9>çœd›Ú½\“h-Jܰƒì(/¢ÈðKN¥°Bö£¾aÐüî`Nµ$´•+v@¯Ý2V™ŠŒµ§2ƒ0á†%#ÒQ(04[lW”.˜w/ç"«¬>ó=…Чv²sÜè$f'£“X$È©ÌG!¸Tâï-f3¸Hº\ í”8*§Xܧàƒ1öî_콨­¼£%Ÿ]/`nsj)w´>ZÞ0æ:ðcSdgñÞSI¤àlóìÖß@ž›3Wyßr¼kwá{ŽXÞ•©Óv~|6<ëöˆ¸Æx?˜DÉóH9°X~‹×Q¾s\lÀ‡O_2@…ÆbgàN qw­úRàËqÉØÒqS“¾2u¯­dg‹ðý¥ãÁøs­^_KÖ±Ï0Á1GÃѶ¼h EÖ¡è2Œ\Lh:ö8Ê(@5ƒí›²ó0\á”;¹­)ì0êÝM$;Úòæw\ÜÊ%#»F ‚ŠÈìÞ³âIj1útĈʳ+ä^êzê$wO›íM¢,`†„,‘6wñ"ZhþÆAÄP`LÌ–„ÐgËÒf«$fKP˜"¸KT&{ëHÀ,böhšŒ•çö¤ÛýÇù™6$è·`±Í%çoØí¹ „{œÒyËàJ˜ýZÀ•·{á0«÷²ˆ~.CÉCk°Wp[¬]¬áò­MÖ0•šä¾€Ì3¦+—Ô¸êí õiéÅ¢Hð²Ø§@äVK; ݣРUkxôKH˜Û c  t(ßlˆ˜ú ÚU¬X þ­Qéù'™ÿBÝþU޶#Š·ABc4ÏM•}<Ú›œæ…†1K¶h[$?¤°ù¡C³uJfQæE¶NªusEf'îÊd ÅC¬/GU‹ÃÁ@s±ÀH OFc[Î5Æø#5"”ñQ9§cd*)Ù+9Vs"ãƒf¾a©TF ÌØ½ÁI»?Ф’àiÙXˆO%‘úMÐÔ¨c”:`Á Å)®"AŒø0"q(Å,œ l}oÄŒ ’G¸D> )-I቎ËÁD,€ ˆÊ1”xŒ^ $•#ž7 kÃF2ríÚ‘ôØ×NLzÞÆØ)óT"¾ÐjP>dòeÐ'¸¢†hb*t=F E}àVÙÎñóóÚ¼gè ²EqE,N,”ýš*2ye6Ú;zÚhŠfÊhW”dÓ¤ð¬ÿO­Y¡&R»/Y þíž¼Æä1é“q+vx¥s+xz¥,®_ÍDGIz!ú` K£ò„—I}E(ÐùP^¡óU{ì¹·°>8Ò㻓p›N8ÚÔï=9¹ —ö¥Íê…#ÕÔ¿ðe‰ówÈ>$²«€,PL?„,‘æÀ%ö¸Æó{v¶R¯bO_úÒ‘ºT*Q›µ2)ªáYLãë [×uo¥Hõ’T«4¶Íîâ­U’ùþÒWþ©u§ 3 /ʱ¿‰íÒ’–Êͧ«×H†¢y&õ}-­éNW4~ìÓ+Á<¥ªIÕC˜©û. m¦e,éý“:(zŒ`–XÌ?î9R‰)TûTFnHb +0S°,/HęĞžY+”˜U¼³ÔTý”Q|‘Fo ž5‚0ù°5r£¥®•už D•R_(ïƒ4ßU+^g™µœÀÎh¡¡¸c œ—¡GÊAôk©Ý<ëµO›½K]Ä'ÂÎFš ©ñŒÈ—kΖ٩ˆÛ/;ƒ£R{¢÷$ŠJɇZu$h0>cÞ J-ƒnF}'s6Ÿ² îzxck)†’m¤w ¶\ëè¼×öœÔÙ®A–ìå‡Ï…m½FÁ pó/ÃKŸ"-ózPàM㵫$f*Jç‹‹#¨¶R8_kćûk{Á ¦ Ä{˜DçhZÝIÉEiÜ ¼õÐú€±0µ $ÌLïjÖsøDQÔR°D­±DIä¿„Ô‹¾Iù„ÕÂQªKú§R¦\Û äN"%9“HÃ"*—2åÀÿØ=kuäŒÈƒ$¦™ç{+PÚi¥A¥Ìµ#'¿4^ø,1üâ,ü¬Eî·š½£W²EI&äMÀ"’‰Mç(å8AAÏÙ¢„Ú¨©kRµ“l­yÒnö[}ÙÞIL_uað\˜ªôIž=q¼Kг9=)Œ?¹B`øÎ:œÙ•£W­£Àßg²3c7¡@¯ÂFgFEïtíÓ³ Ò<6¸U4]±è*¯óðÚ}Ü©3[îí¨¤$(Ç¡O°ýÎî ÆÎ´k²œF9›©‹L¹Ô}‰Ìá%ù2RYˆ;ËKC"OŸ ºƒÛâÓæûÛšÎrìWñbZ.FÄRÁå`mô^Y½ý:™ôD ·eÏNEÕk Î{ëuóäV{ÅkrÆÒ Ú»[}qÔw¢n÷ÏŽZ}ì´xÃâcHPü,«ÐzÑ>i¡„'îbap€gDwšx{_(݃V™¢ä3ÛÆáƒ×-)ÖÌ™ùp PëÜ^w:©8”vù?a×U¯LoîšÁÞÜ9Ñ=OøðE»;€é|C¹{eÒTqLcÙ*¥ |Í”’ò"q@e9VWÊ ¦fiÜ%±’”ºT^µŠ8k,OE z¯ö“´[HDðÃn ¢QA)Ò*IÍÞ—¤ßc¢²p¦Ôa™»-¡•a–µh{¤\¸x@=Üãt“PÐx|a`Q K¯°QŒÔ[æüEf úsA…?0¶»åàaÁW×0[7Š!Öš±]Èžà9u"¥™.lì–K3ÛC&h¼wñ„oêSÿ¸œ›Ä6L©“A+Yê¼x’*õ|p/Î¥õj9&s½ÓöÀj«9°ú,‹ðÇÌš yfMµK;çû?g8 û÷ÇMsìwû[1ûߘãû¿'û¿ƒ¾ƒ¾-ƒ¾³&ˆJóAoØküˆ¶}]ëïK`]p‹ÇmûbTÍûÎðYöá’ ‘£† r̳ ÎUa“Ü3q¿Á‘MX¬©I×Pƒ|±œ°%ëí©ã‘µ û‚+E¯¨¸6`áoõP]à ¡ #á—1ü_Q²Ò+]XlêiŽ ";M#‘5—Ĭ™½Y³jBå)Ôwr›8%ñLSQº$n²{!‰7ʉõüºn é‘ŽßªD¿bþ—ŠÄËsefqI> ¿®`¢^çŽl¬„$L²ÔµÌQçD‚E XR«„Ê ‘iIO©,Ïlöt°²‰¨J¤Ë—;[H¡W˜®‰´4ád!·È™vÅéÇ¡-˜!U½åê‘Ö´D9zó‡†r"÷Gâ¿$ç’²bÖ–¼— ¸›ú¦¨1š½"os)³©Ê˜4‰Ú3{Ê|k˜V­Ó=nšf­±Ë2&©¼pQ=©¨ަ!4q¡èyš.b¦ÊÑ# “5O¬ÎgçÍ<÷þdþ?X\.þgk/Éÿï?ðÿüÿÿÿÀÿÿ1þ¿ß{­øÿ«¹¼ÄW˜ÆÖÖÓt "{…háqüQ‹iÿc+‡ãÏN«ù‡DM<&|ø'[4æé# ÷æéaz$O?u=´~’oÇhü“ÖIëSrùÌoZéŒp©8#l­`„Å|~rÙذæàmà¡´j—ÄQØ$Ý’åmädEw©Î&ºÕ/ùœÐ™BÚ¡ºXL{L¼Ã•çvÇ|UR†¾ÈÉd<³º93<°SçÚ™ÖÊ);kð¢{Þ9þ\s ¬°³ñ]hª°JºÓ<6@èf’v$Ð:ס‰>áAÎÏ¡›“c 8l‡[ÆÃʶžõÿË+íÄs§iáL–ÒY4}JÚ(‡Ã—™ñ_`›ë6é2zˆcļ†„Ù™ä6<êv:r’ã¸GÒa)r5IÛÆ+´iñ¶0öäÉ ´40Žá†§Ó´*ÀzçGQl¦´PExÊ_µ(0t©;ãCýÌkìZ´“rî|)”øäs€‘^šXDsÉÅ©|6‹” 1”£¾HOj™œ—V‘®J¤[O2$øB@ºù€×_hþ…ë&4 ÑexŬš÷Ô°=5#J‰*8:3•l‚&n,)L°Ø'–þ2ØâX3(@¢kÛȦýï¡c\d—)¡ûóÔ ¶» [YšTŸ{0ÅxøùCú_™áù3é·¶·ëqûÆöÞÖƒþ÷óÄ9¼[ÍãVO~é¿_EÙÁÓKKfòv¨o¡ƒD#-îëCª˜‡T1iªÊ•»"qø!Eè´VdÈ>ÌM}˜“ñøpußÃb iï™Sõ°hRÐÃ?9æañÜ“‡Ò?Þ?ëâáý“ ò¤|~Þ>9nw^uRx„ÉF–T%âÄO‚zFSbW.ÊñiÚ°Ë•‹rÙD‘@U·Ì©K¯Ž3eÖ§¹³±zl>á£^™&N«ÊÉ-crciú´Š˜Ãÿ5ÐÙ/Æÿíí?ðÿwvÒ .8‹ÔÊKŸ `J¬d=…‹´0Õô—|à%ÿ5Óì“H‡“–úFZ8˜CÍ'vxÞù\gŠøsûùÛÓè·Î@þvÔ*ýޱ"‚ lŠþ'«†ÐG~á$5‡%uûê¬uvøæ¨UŽòúý þ~q‡›Šø5üÅ4€ù }{ú…­¨ÇÕý/vÿG!ÆjöèÓ^Ù÷ÿîö^£ùö¶÷ÑhïÿúþÎÃýÿ9~šGó^«×úïFmwN>|Àø2oyg¼¯Xoys¼Gº#¾Yv)PÚòGI G¾¯R"ÄÌö6#”ˆÔ†ï¡‰ކÝ×½á?ÿ¹»¥~ßÛ*1yè¾nõzíãÖ°y>èRDìþÒ~9ì÷ŽŽÛ½·¥d~½W»Œªœ M_ðv®]1%¤4[1øÓæQ¯;$”³,9blàüèÕi÷¸Uší )KÙÆ[(ìƒdÒ {ç'­>NMìÓÆÛ;"’CÏg" ÷ð¸õüüeZþsÚþg+­ …7û©e0SÝ^ZÉÑyï$³¹þ§Ï»'ÃWmdÓZ?œuÑw†ò?öiÁ¸ü¬9xbçY³×@Ã¥±ŒYëoÓƱñé ïÛˆÈHGÄsLÝ‹÷×FÎ áj¿©pÊ@ B«Ëp¶lÀRã¶ÏzÝ—o¡Iœ|`QðàX†ô²Ì;ôl.ƒÅæ…ëñ/Ä ÿ„•ÁwN lUýÅZ{˜Ö0[}>³Ö"”kôfl=8í¿ÒŒo`ÓêEù-l´fÙž´Ã§€yÏãŒkÐôÄÅôÏŸ÷<ˆ2OáË^ëìsÏ!¶‰³w ŒÕEÄ¥O#ÿ]d±õûL$Â'f’†"¦²õyæ†" >3þfmÐx­jËZß°»(¯—­ï6ÇÎõ¦·Þ¾ñÝ×õøàé0ÁÙÛxK;i ÊPL¶&ñ­©pDÏO`¨Zb°Î4p¸X[Ó–\T'}U ¬+L¬±´­øÚ¶Š/®sßÕuR—·¥¯o³÷Q‹Kæèše/€•Y²€³¥È’£+gô—šl&¹’1 Íž"bãˆcÑÞ1ÁÆr hEÝî \=\{ñQkaYñ^h뀥/B|€7¿ÇØ‹5 K`¬Œ¹ƒàæ„»ùoéæË/JÏ™¡ ëù^U­…»ÇÆý«¦vb=ú5XŒ0ð¦d˜L ì6N8vB ÌÆÐ °!.Šº¼èTQ·»¥êÄ 4;ÝNû¨ wb·?`’Œ¡Ìé…\ÃH¶¸ÜzüHkÿ}Þ´Ž7ºý ¬È¯Øàïk°Ò£ù²:³GW WU»}Áòˆêðèˆ&ò‡¤²®Úcü³^߀mâ܆ï+o9Xš=Õ‘:mþCÌ8íg–ÜkØ<9ö»ç½£‡fûãV‡¿5FÐ]êç†,tizL ʹ^ÕDE Óy¯5¼ê—5ì7_´e½ðB½fgÀ­ðÉâ ”‹fì…Õ Ó耶×ýáI³÷’#+–Ð<Âz„39ôR@À …*nð¸,÷6OÿFk€¬jkP±ê0ç•—œ`΅ʃ„ÊŒ÷\ýð°äöˆ¦ô¤ýO)ª¥¯¬æ2ôQÙ€³2vyê2®¦Pׂšp^’»°œWrÁ•K Î÷©;s¥ÆÇ'‹Þèn" .±´c·D ó>ªnŽø72wD³–Yü ʵŽÛp'P:«À!õÙ•M1Îd–쎄7Å"¾!Ën¬>âk_‰³Ã–åQOÔñZ,=jN¢ÅÁÆñŒ<ÊF9"ÆØP20mTØuʼȀ†2¸à`}¨üƒëQ°ka•N)«\‘«÷ögŽD,@K׫Çgí£un‘aäz åYÀÎÉ”ðÆËL^BµX`,D`YêíÆUpz|ŸÝÅyæâ“Á¦ÊÐv On—Sܘò ¡`ööŒ‰Hl˜‘`h1[lçÉqJá*…Ó;Ýlo´Ë~à¤ÿÄN1ûÈ5Áõ‰y´lÌÌ“rìñlˆv…ž‹Å'87iÇ„šrûCìgò„ГƒŠÑ#Ý5d¢XÖµË)ô\Š¡=_†€FL’§Ñ54¤ã¤ið,g6ïtD2ÏÔ'Ÿ¶Œ)zqEf(b²°ÁÆ}Z7¹™¬•\æãOòC¨¤îuSœÉÅ&V»È¯ iÚpq¡lr˜üO؃o«âc¿5ˆ> Ÿ7ûí#ÔôÓJI™Y*™B‹Áåj­ÉIºt­ñðy8–#ÅÑ~¥±ÂZo9[³ªÀL¬Õ·¶¶tçϬúVí$™$µQ O±­ò>­bL‡) \ÎteKOÓz íÈ¥LoÇ­Ž1Ý‹;ZcæG…,lÚò _5áÎEELB¿4{½æÃ>Nz§õöïëV: pœƒîàÇ3¼ºû§ÍÁÑ«t8S+dÂDÚ¤Õ‹ *¨ßð+a¢WË Žæî¾a LOL y@Q>;òx"/«ÉrAÿŠÆ8Æ!3ñÒöf“=ʘÕiJ©†Õ®xÒbŸúÄe!~““ÔŽÇÁwSÍjâ+-Eª˜ÉÕÂ+DæNBN‡\ ?-]„½kôÀŽ»oúzI‡VTBÒÉÕµGöh8ºr,ô¡XŒ5W~¨ÒŽ'"Ö&$Z]ÚÈ*î7Ggí3.!’ÉVå#^»Ó<ÛºÝÚr%åË"wž—`(vÍðêÙšç¯e–7²ÄÓ")ëS{u"^±ö§Ý–(òü&ÃHÚ©K3ó£Œ-^0Å/ÿUŠŽÁ‹óÎцQ5ž–ûí«&ì°—­êžÿˆ®éÏÖêk1¨÷‰jê¨A?7 åе²ëcšý@K¸áð«:…6sà…Ðm|ÐnÿdÖ¬/ €nhÚ6sâe–!Î6G“m™SÁEy³Qpüæˆuˆ5–¬Ÿ„>9¯ß“Y±È/øÂA]åfNÙŽ^º@Úžw¯hçXH-*[ œ£8©úÕ°Ìì}@þ}î,ÐÃô>󙪀Nîl¶@1ûDý¡Ý PDšš’œ+ÚÑ\YT(4Ù'íÎ?†í­“~kã­Ôæœ4;/I-Ökžn¼åÏïßWÄo–Ù»ò¡ÀŽ”®ï”Jrzƒ£‚Ì5Ψéù¢"+6ÐR´Ò÷ÝÂRýLÉW˜ JQß`m㔯•áqÆ0(ñÌ®ÃÔ<­Že)íßUüó¸ú¸:ƒûüf»1rëGV¢C™ Vü©ïÿÃC…fUMüc»‘Z“n ü…¸â¼¡5²Æ–h±1” ÆÉút­‚‰)kkô@««v¸¶¡V0 `zýˆF¦ŒCò=IóþÌ ë c>fNZÍΰÙ9žÂ/‘!_jì¨(&{ù]¼%âO¨) V°LÏR)UÒjpnÙø'"«HR‚5Œá5^ÎfwHÓÆk­|¨Õ•Ó*úJB±’Xä`‰ˆFbªížEO´K’6)¿ºü!úrêbVÆíZ½¹×ªPGŠ’éÍÇVwŠ<íÿìùOe=æd¬*Mãs§ÛóÞŸÄ•“BÑL  {v k©Ù‡}´©ªé¿ ;÷s:kø˜µS‘ÐË *_9 ïѵÕ?ÒžâжVìN‹/@k€Ï†ƒa:}öªÛiYÏžY[p‰,Б>yfä#b}nÝkï¢ò˜BŠíÞxËV¿ä~³‹ÝâIÓc>VЧ4|%€êœä—lëð?çLÖë,"­:=ãȤ‘°ã«Hǯí„sÞ(“„Ø ¼Ê¬Ì¡œŸ$rŒ­ÄREÈËEN£Ô“‹N§É¼A¸@ns4›W¬J\Zõ*–‚*ÇdCæýð-Q,mFÁô"ý”¬l0!PKñEŠùº„àm%>ÄCG+µK¬‰kèÕ¼Ó:Ú·Û·ê[ÿõ)N `nÞ-g* ëV¤ÿè3™vo¤Óï S´dŠX$ŸÈOÛØoÿ}Þ­o­:Óêgš'J)õÓŽtÁÍ«åúÁ°¾õŒŠûìý™=¢®ÔêO±lŒ.¹p€þ¯[;’&N3¬ÐÑÕ·†õ†æê—}¯7hí„p‘‚)¶ÚY-©Õ×&ýnÀJ›»ÿ>ø„êͶÇ:iþ£P‡£) —hŽ#Õ33ßóC4J"YºDyD+1Ë{,X‘ÿ?GyЍ~ CO¬‹ååUŽ5=Ó³2Œ·6¥¿å]…K1U}Ò…9έ„AEÄI·­ÇFÝÊ쟊4`(äýÐ÷’ÌpÏsg/)ìÿhaW¨[,=ž{ì%ü᱕„å“$EŸšeõ?¸sº|àèßÓn§;@벨ë ‘ XÝþzPÓŸ¾ Âñ¥¢Êðïö‘N¶˜ºà–MBh»Z©§sõ¼À·õ5†WR½&†1A°¢Ð|ät‡Ûér4bÃz öÃV§ùü¤µÁŸ+øõUëälØô¨vµê§Rõ*ožcÔp¾/WJoùH¬=â:×öT¼³D¯,INðDœ¶y~õJâI$ãù&ê§4ý{­é‰®cP¤¹#_»¦°+ažáà‰ ™þÇu@àÂk‚üé.¼Úòñ΢æ^ÌP²Úû£!ÎæãÛ¸iùÃŦíÞΗ—ãMëx˜ðæ ÿr´^aÝ!œq8 gR» g¥ON¤žcä%Xø5Ρ½q©h“õ©VâOŸâÉ÷½Š¡édÚkÞió¶tZAë´Ûû1n h[çß’¨J½½|luH£QŠ¿mnÈ-ð›èχï±ïŒ@5âßgêŒÂÄWÒ–Ç¿ºþ(œÆ?R ÔøÇ%^ïê“€hb "¾ñ-%7]/ík8šÇ>oºý ÜÉžÑdÊ(ج9)Ð òRŸâsD&F%3 kú÷!ÚjØa¢S»â;‘íO90(›C—Þ¾™ŸeþzÁ4%S󊶫hYÑ7Ô›ÚnøNã~ÌZHd•h&¢:Ø7?Œ³µ/ö¥*«¨:"1qfš H§^}V˜àð zÜkÁÑøñ1…B¼päà,{Šh«œ„h¾kè.8h•Ølÿ`íÖê„l¯L2þ«,­aŠ8zF”–»^3†ßì5‡¨×裡KImÄÝÜH‰¦ôÝË«ÇÂ>“r+riöHG8Ú¤Ð:|Ë'2èš[¡A|P7 ²I|%ä^N]¿Nk€fÇÃvǨ§Ÿ§¨ÞûR9AÈ„çoPQyYöÉ–öFäP‹Qè<7brG>kýþJÖÛ²JºÐÏŒ ²*$ÜZ¶ï äåìÂYœœÐÅÜW<Š+;£~£5+t…Ï““û*‰Œi<‰ŒÓïÈ’'1a''Å4.¤%üJ»¯D|ŸØªŠ¯¨pa}~í¾àh5}Þ2Ïdh ¶K]ˆ~ÞïÙ'4îòð6³~Í,ýmañI›)…”t)z;v 4FŠÇ÷6Çú xâbÓþ¼Û=¢½ߺ„Ð¥ Œ‘Ô$7i º_ù$T~pLÝxeJá|û)ú éÊ5‹®\³ÀÊ5Í•‹-r®·7¤Õ*“¸¾Ìÿ;-£,ì}MàÈ¢;i=ói–þ>ò±ôr-r—^H&íÎ15«v€D$Q§aiŠC€|Ø ý^Ð×£è~ˆxZØ•z¤pÍÛzS°?ðM‹‡ú÷g ¢•Êš |Ú:}Þêm¤¡p³#î Ýq¥´²ãZËÆÿu‘[?VýOéþ"­ëd&l´ÍŽøV…^œö쟻gS© ® ºbk%cIÈšíɇ¯RhËK™äÛ=jé}¹ò°1þ´ñi…ÇÏãM±]bû{cXÐô7Þ^¸¡7šÍI¥-Þ;ýÉØ¾£î¨ÆØ¹ } KŠV†àÃñ32ÁßÖÒTgcÇ™ ¥é#º—%a\mF¬{ZæãCžµ¦ÙË–gâñ=õÜürÙ«á ‡nÖl':ÏvT¥œóƒšû*ŸÖk«úŠI;‚Ó¤Äßü›Þxá¶ú˜Òƒ<²1ïÈÔý€ÚéÙÞ›ÁFI»©ýáß•†¬—ïð ›(¾Ä¨"3ùÜ‘Š[奣®‹×(ΫÇñÙ„HV-f~õ6µµÈtL3L£‰â&´NqÏZ½Á¨ ˆìÓÄŒÂd¦b¯ë5m‚Ž8¤«‰·(R•ÀQ3YˆÜ¥êÁSŒ*Á fôó'ä(³½µ„j :‹jÒîð1>o¿luŽÛÍ¿Òi nb ¡xÈåJÅm½„Þ[0 È‚ +z(^ /ÜKL? .ž ß—ÅÖ«D á6BgÃ8“ìø(ÊÕvTúÁrÆqôÂpꈢ/QWnL$6¡ª*÷ÒæËŸÁ&ADùðþ¦=xµÁ%iÏîh;Råâgn%iÛö_nì"göCXkC<@=£ØVK†)ã=»£õàÎèž–$Â+z«—ÁŽ¢–ÌQÃÀЬëÆYG‹Ç…*j…ÝÙ0•"Úû aݬÂíhjє҆áÐ.e«21¡Ñ$ìF4ÒP ‡-­Œj¸æŽ}F}™LgqÚÆ5}1\9uFé{KÙ8ˆ_1/±ÏD4§h^u,hÿ9MÌè¡Ú}žï9šƒp—Á&é%-Þ›ãÖú»†Ám©ä‡Ø÷/ŸY?ŒMF‚Aƒ-ë¥qª¯ÁUbM«ÝûÖQ€§Yh“÷{ÙÙê°àkîhñ ’ú°Óí{0¤ad¿?,£Gcw«Ô;…ÞŒ©µù³µ9±ßuÎOÄ4R…ú”xNq<³cwQêS!†sÄš¨ytŸ19LÇ>]±½°ª³‰U½YÕ_&ðË/—øŸŸá€ýø@#‹g#`ò«7 ø}îZUß.ÂÉÌúZñÖÕ›ÑøYc«nU/Âg¸»ÆßÀÿH=ÿ2‹%‚Bw®fïGMˆÒ1;ƒãã¶œ ɲ»EN-°ek0WrWÃet"‘?-¸LÑqfÏ+díÜÚ#øÛAIDµY)ÖR‰1áÞ©Žé×guùõUNÔ7° MSQY6û .†l²§S±0z…­hõ¯)áf8vÝ…KFVŒ8' ý&;‹¡!áð…Û P‚N¯8Èápáûaù뢖»ÏÿŽQÊð0¾9yªù?•Hk‡ŽNœ*¿ßyïèPÔ0Y=sA˜Æ—C¨ ‚ž·¥E!ô]†Ž®EèuÃ!*—çε1[/{eT—V¿Œ®¾$rçü GC¶bгáŠ%ÕûÑ_Z§çýÕ ê>t,´ _Jõ¡Þ }R˜Ôqx×þAmô §¥áheyGãîèŸD¨At@äÒ²‚ìÌ0p攞C-‚¢å•IäŽì”q…RËJ›äRT—J¿‰Ú{T-eׄ5,É6¬”Šxiw¿Bš©‡FKŠˆ›‚òßcH³K°P®•uhø]ó2 Ïe«Æ‚^û¨ôÅ÷ü3ù›…o‚’†â ôEõÑÆé1 øŸïõßyZô8Zãogæ2­wV­õðŒýnçäÇÒ°îg\ÃxËÔDɼvôe‚ßåÄ”éòá“SFD'Ð*yJëûGïMLpDÌ@…Qíf¯lUÔ^XÕ‘†AÞcæàÀÞQìÔ´"\ÊK'R( Œ{2Þ[a°¤ ˆ¨”I`ýZ÷Ûï­ß#·[èuÅâà!ÔT)º€S‡@…ÿúcÐX‡ÔaÈòù‘Œ¦ŽíèGÎKï´llÍøGÜùÚ·Ô oçÒ55ƒº£©h?¤5«Ñ‡hVàÎÖ Ù¿à"ËÏŸ“¾³š‘¼ó!mçCÚÎÙ´‘¢ðý.p±ú0×pç†(Y¹¤ C¾¸ƒÈF ËÄ7ë±ø¥\ÂäŸèiå–ȬgC”T¿£ô› á±Nµ' ÇI–£å N׆ ²îÖ¡åZßZ¾|¢ó9|þæ›LTè­ûž°é½EyUõØÈ˜ý/»û ^sêû–óìey¼GîAô!ò5™õãp‡¥ßS–oƒs^ÙžçL-ñ¯±\–´Éûy‰ÉJÓ?ÚgÜÐóÇÎcþMxVã¯bX_F â 8¶ F˜`­¿ÞPÕï€ ±} Hj?Dh6ª[¹ U›øT¯ú',~JLÚ3 n‡¶Œ´˜hA¸Lý ô(ÛtŒ)Ç÷Àó/ælSo§újÄ.ìч ñ·½¸¬XÄ”·Ž[l4Ùîv*ÖVÅꜣ{åVô‘ÓÝâJÓDÜ1 Qü{dÙáHöÔ¹löGÄ_pF+7d¤ö3•QDDD- ‹nȦžH2 Žñ0¤À„™3lxþ ّШ™Îð.ºÁ¦à62ÖµœzÒivþ»}<àû6ùkg]®c±ÖDKË»áÏî©A9šÀŒ–Ñ¿¸{>øÄ­“­ã24{ =ÂåZK:+è % q$ºrt”"ü’R‰nŇÁ¥LŽÄñI¢¹ †~>*Ì"‘I€ä`2ˆd¢Ü 'ÖLñÙ´á’$èÚgõZ/›½ckМ€H!휣5*UlŸž´½B`u_ÐãL«wô ¾4Ÿ·OÚƒ©ÝíA§Õï#÷Õ+Ùj½F~©ÿŠAŸž·¬“6ªö¬pY’fçG«Ö:j7O*Ðã^ëh›¡#ëö,ŒžÓúïsÀ0Öqó´ù»Ð£ªâOÒ«æ ß…{;hà0ô˜uÒícŸ­ó~ ÚhšX¦ :Û¯@½Li;ÜìP—H)Œ éA¯‰ýè´^ž  èQ ëv©Â ÛÀ󾨀Šåvíž èZ{ ‘Ò¼ã B_¨­LÄi“¿0×!zcbM3Ç¢ƒùÅHR™/O껤¾ø˜ÄÇÒõèQlL+Ö¢byxܾ Èž°ó¡ ¸ñàC`± -P,L, (ØŽ¬ôíVÅúŽãnoI¿bôP±Â…ÍQÂkâÅÒ!x8³YÎ0ÞèdË~•cØ/tfŽ üUýi£¶ ÿרÙÚl<ÁHX{ë¶?d쌷)9fµüQè„Ô0SWþ‚Ú:³—Sëµ{ë:Öl¼rØuàL‘д¢uhr:F@DBf§O‘\¨?aÞc ãÒÁñÛôfñBjo+Ö)/¬g0i›Ö,¹Eûsg¦æüB¼5Y·h{óþf=)S&ýŠYK:Et¢‡QóÖÓz\ž–ß^Fq± j!¡H©É݃F¡§ß¡~ó¢Z•Šlì×4ùµµuûd«Œï9‹èÏr¤æD8éeßë‘Q~©Ö5í?êÛoŸYuþ¶ÐþÂrYi‹4ÂBWÿÀaý{êÿ8vó'QÿåñÆîv\ÿרß}àÿþý_éõƒþïAÿ÷Ÿ ÿcçnTÿíX/œ‹ÅÕK(Þ¤j™èE @¿þOÓü1þ æXÞMÚð÷*m_¤ÁÒ+³þ*®ò]õÜ£¶#ý`–jöMHO$?¼Ã•3ôÇUHAe.ëÏsÿÃSæ’O¦ÊóÿÞªïÄí÷w÷ÿçøÙLšïÖI·ûwÿ ÎîèÊÁûÖ·?ÁŸß{pJCwvcOǘ¢æ»sÞsÞMsÞøwIÒE96½häŽXo€f; ªãd“ÁÏ‚T„(º?ƲŠÈ_€I)†ÎÔ™IƒBX'µõC÷ÚöO\mêx‡ê/¶x‚o ÷CUø5û¿ghâô­l+²kR £6vÁ Éi[S bÏ%] ã­ûž“T°q©áøJ‹=%kˆì–«*Ù¼…z ®+"´¿Æ‘¯Bœ‘ ìTÀßtѲwêÎxíFæòPI`¬!2ÖˆW%¾ ˜²#ì0—¢`)ÙíßãýÕ éä¦L¾ ›i¬—ð!¥‹Ø:‚bÐ,aEœÜD³TqD"íͯl÷Wý2z¼¡Ï¬ë%f‡€+‚dÏl4 Çƈž^/óaôå1z§k©ÐNÎÈÓÿò°5ý\yCó i ˜6‰@ÄÅ¢Þo¬Ï)~ýM›fax‡9æ"(\dR<“íz4¿ª+ªh,¦ZØ+«(‚Wþ ÌT‡ó‡5¶*ö¸‹¼½ôU#O!ò\¸7±@Ú0,©…o¾‰:ÁHP°FoŽ7Œ/BöY#øË - ÌÜE¹¢Òe~/çr°K bÕ¼nbD¨\°(Ôá½@Ù°‚Ї)"¹‡®(Œ[Ú `æ#'Œ¶ñª5– Šâ“½›‘µÁóú˜vˆ?Ù =XŽ:ÌTg#‰_¨S‘ð$"†·[ï¡UcÃÃ)É\K &ßòO.ì—ÑÊJ”+××Âc ¼Ê’h~{Î|ŠàgÎjØåš´Ú×ÐB/×ßm­ÊŠÍñ˜Ø‚¹ïz""#ñb´J¸b×JT4|Œ>߸ßڼጭ¦¯&6€µáhàæ£vD?ñ´¬^K€PKIà…WRІÈX^í\nÅ×éUríh>Ü÷´#xj3 %Å a²)0˜ 7]±ÊŠUÏZp4¸'à÷±£)ªŠá‰YŠ@õ3ú«n«lÞ`ª/¦ËFÚ´fLlbj%#¡Ñ$¼”h´‰û]ˆ|q¾Úrcà L@ŸØ7#Ò•0aÐwØ“¤+¶+rÉ»ÏØ з—2Ðíbéˆ,fÆ©ØX8#{:ZNYyãpJZ€K]æžiW‹¸éJ™³š2£bè}°ÐÿÐøC)?‡ýw½^o ýOc{owoookŸì¿÷öô?ÿNößéNà[OÓœÀž‹ž‹þåž‹D¿a»Ó&sñúSØýôVô4þV¤H|,ÖÁ2p ~ví©û 1ùB”|R¶-:ê üúnÒ¦t"ô0”7œ9³8l"°»öÃïMøâd3CŒÈ7Xô-çÖäŠÈGP5Æ6£`M ª$ÛŒ*Gü§œþ†hdôþ<9Êè}ÎÉ‚Ø2àßh„HFÛ"PñX’9^À’\@:Wà/ÄÈ|,]8Ÿ(Îg=VonѼ¸+‰­ 2+‹hÙs‰Y»Å \õ„$h£&ІO>ùM³xÊvZ:ä²JIô‰ä,þfÙ£pIctn»‰(ÉÇö©zlǦjŒ.47zG9‰½åL&εŠÖ„‡)ô'â_K8Œý=UÊ5¢ðY Hðs%L¿=•"¡â~eí’Ù.~±ª˜Âg°¿¡¯v"jÒ¬4ö‘ ^!]› Í™[Ì÷¦¼Þw„ÔY*Ç®Êt.IK/ÚA°,ì–ŠI+Ä—¢y¨©Ù¶è–(E»ƒr/Ö ½¹™ ÑN-ÌãÁ÷&fJ­2}¿C¯I‰2›''äqL2Ô2ÐO5ó6EŠ‹È`x¥‰=¢n³.ªèæZ܉%Ð…?åÐòòˆÊ™sQ[yô‘ü©ãOYǃÈï"Šã‰'Mú|Øø3Û³/Yk \DäeZŠòùೌªû/À^…‰Êáó‚Äe+Þá0Hœ;Aë"¯60Ï¿ðs ¯(SA`O`¼?F9k|Žê z uʆš-Üœ9Æ \ÒÜÝiT‚ªé¤[¯q×Ü@QH̤Tº4÷Ñs¶¡µ@rëÆ£È^“rõ1—bO`,–Ž<ïØí%ší8‘ KçoFœ$EóâÁP Ü_®‚<bÂkYNàÒÃ)”ùÔq/£;p;!ïÀø˜yáñ˜NñÏ»Ò2‡n³1^Á®‡¡±1 ^ !Ý6iJKÓ€©ZäIr¼`I½ã¿é7û8ù@ q %±bt–£eŠ3Nhdx³po( îæÞrŽ0J>ÉÇ''|¦äEbWÌ6M,îýãéôi|t5À9ÇÙ@].žØ?ãå =†}ýY^ž%(»˜:3áÞÄIjƒ3k·|‚ˆ¨;DZàMï˜Vg¸€FìD;ÈüÆúàù7Ò¤&Qò›–†4šɪ˘†¢Óí´t òþpnÃ…­wøXè ³×œ÷:ÖëæÉy«t>÷‘o§»i²œRBŒxBG!1÷ežSùü m'òÆEAÈ.y¾WýÅYøÇ פ$G\‹(lF\xÞ;]³Z·#gN9‹"Ï6`í©PR,&÷ÆIð •ZÂÐJ«¶íN™T£YÐëfûD8ĸ Ztý"±çÝD,’hOfƒ¯×ök[°ò>Ì¿ŒŒ\¢ìL®”Mæ(KP|f˜ànváÓ玜a6Î×eÆ=[S¦Ä™ŒJ &;÷%å·-Ät\8@AÞ©”øÒÖ2_ÌìpDÛ&É×drEL ´ÀÓcGx²TXà! JDÖ1'®T¯Õ·j°—Zö¤…üX7D²cÞ£ˆ3¢—rú+1WÞJr9Õœ—“Ø‹ÀŸS:¥;xl‡x¿'¯8)âEgWÞWL“y¨ÜpN‡:âÂ= ÙnNÙ†·uê–’‚!6‰¢õŠ-»³"›`ó?½C ˜2;°„6\¸UÅvб“p¯õ6º4,[ÜÙôH’eŽ—d¡5×NíLëy?ÚÐAàÐTý1ÕŽaµ—§Úy0Òû7×ÿR8ëÑŸ ]¡ÿml%ò¿Ôë;þŸŸßþï£Â>>þËÆôœX_Š4ª$!”ÙŠG|¡”#åìTÀš¢vnob‰ù9žÎ×ÌL®± ÅìQ`VÉ1G{i_EÄüd;¿ÞKù ò“½ðä¬xz/ÏÏ0£SÂbr,L)-1a–0@]¯a€ô)0°5û-ôMkA˜&Z‘¦…ózeÞPm™Ÿ3[ì|L“ž¼â©V%Qö”ØQÜJViSØJÔÉ#ÌR˜»‰˜†AÅŠÇzÁ_ʇÂe`_:„ ­¿ØZÎõ6øà­¥áÝåµGψ2+þ•Þ®ð'ú K3”´˜|TvÜ›Œá¿Ðå©'m†m¾b.m2f“í jO†ŒÄÄÁ_µX§8vLùü8¼žW¬ðZ+r½!â¦vcq½=Uºw±ó~”sj¼éöŽ­›×Ìé÷@s´›xfa„x,ÜÐà+Úïdñ¦ß$ó›À>¡M55MmÅúZ@Bm’rˆn|-¦œB” #ê—íøxf¥…!x$Ô$‘U’¨ôå3VZôÏŽZý~,ú!Po/œ,ˆ‘‹ŠØôzÖß‚wÞZ%&<0òrÜÈ&2¬…8…ìš´ZÚ ½ˆ{°²6®‚ƒµ2ùWëfß8¥††H ¾ˆ'ÌZ¯DÊD™µ÷¤ñÅòRhMã†Å–u{ïÃa ]èˆÜù¿‰ ìž †ÇÝÓ&lƒC Wª&#€J3G³T¢ó¶8…e©é¬zKù‰7¯lÔ„SxyEwÞ&jW­ú{6%E2 ŰP†Ô‰ ‰#CBø2–Êš½V.ƒË¤zþâltðSã^a”Ë\|ç dGhÔa2œ?iWÚ¤‰DÙú,æ£ù]5ãªXQ#’KÈ! |©'ÀFÛ=}{æ(öþÐ(öŒQì©Qì}’aèÅg‹:%F¦a­MÉMõÆ–ÊEŸ›Ž|©ŸwôtxÛ3²6DýâxøÏV¯»ñµdwʉ’ˆý‰Š‡’‡~ÕfZ1M)ÕÈ씪n/ávJbì¥ÂÎÒ¿¯µ3G®ÎÔ…ÌÙ¥vAÖìFoªuì `ÉèðŸ"­|±Qþ¬Ê¨ûFøîtõs&Øo)Åš¥y}*®]óTy<§>3Ó.«Ež$ETÿDÔT²õ²mÕf˜¶6îìsõ»+â©)5Ìù¡5“JjŒ€.–“·;{ÈG¬ý×­ KqËR$ÈFpCÇÞÍ8’óJ„À %øAuUŒxíoÕíFð.ü[C•È($¸¤0‘[Ú~ŒZºp o·Þ§S;-ˆxôà [Ð^“«XkÆ m„7å¾Å·bã ,m$ª–A¤ Nv»ecm-:±½ª „´ç{…8a°õ¶Z¿Ú¿![õÛò÷÷Ö¯øõ7œÊß­Z­;ŠÚqn¥®—¬¿ôÿ¨ÿGS ÷²zC©u¯>þ¿±[ßMäÿjì×ôÿŸã'RžµšÇ­Þ_Ϻí—"¹ó«ÒWBM¶ ¦´™– $ÐŒL`–7öIb?Їƒ„r}ÕÛAÞë®Óßîùpðñ‘$?ÑÃAìÕ€cd~8Xñj@Zú¬‡«ø³½M/ŸåÙvì³?øƒx%l bôvÿ+2C[ØTGr)güÄ!I+2K ù½A<Õ?ø*ã‡é€E™7WÊ›Ÿª7ˆç˜‰°}w‘u䕞®ÍÂôUh˜)Ò±VD·È¨ßoõÃWV}%6`¥Âû­m>¾Uøbß½ÞÝ()PXTlcïmì}ÌþÌA[dŸÀG®"Q­ÎqÁý‰˜L¾ êÞ—èïëN\v‡Q;3韃@Ç;ÃÆ¢X«»w/еUñ]½Ͻ)Ö tÆNè í'=C”oì0¬n7,N6Ý9¾m‚ˆ%„ÃØ*ÂÌœ‰ñC™H"ˆNØî4{ýF;Z¹p¿:k‘eê·z$Õ¤•£EÂO¢JŽŸsYV9Õnw(QŽÜ¶àƒ^­ªb$û'ì²Ú?Ë)çlå³7Ä©Z „ýD „f ¥²iÄÝôïdA$K~6I7âqëШ³“æQë´Õô?³¬!ìH‡QBAC”\²¤3^§Ceœ%U5Ê‚®‡)çS?–>I¯è¯~òß“)“}.œ;z¦ï­8MTY0 ‡£ùtàÿø e6wÑ3MH¬ä^}ôÍ7øâˆl;¾?%Q9\œ°?ïvO†ƒÏ§F;ÀÂôïŸQÐü³GŧÖî¤9hÿ…â³4‰†Mêz?UÚ@:‚4„Ô8õL’Ùb¸LûR©¿TB¥ª*cdA­äy·wÒì'õ‡qrÖt{Í—­\ši%ž9ô]»¶u¿ž°IØFùãÝ5ÇKóúêÃ0dÀðlÝníA»Ú8FôZ!]â81p×3X’Ùrf],]è©€]9ŠÇºOߤš˜ŸÕá¿~Vó¯$G€ Üy… @¡ Ê­]Ô[û6YÞ6º´rn–ȹô¾Åëvô ªO` Þ“aãÈbÚªƒjÞ`ð É /¾3# ›æÌ™N¡Ñ#k·¶µE‹†a5ѲRM|Q•e«bÛ&žaÄã /¤ø ò£ÖQî»û,^¢Žšf,’†¥‘Gžòš ø•Ÿô· µ‚¾™ˆmnH¡^®Ém\!*äNiîæÐ"šA"8Óž¹Qybòbª˜®´‡)mÔT 3úh\¢v\TœQŽâˆVîLõ–µ5+«¯¬.LúîVý/èY6áhˆ ÷§÷ÇØe_e-˜Ü÷¢‹úù?uG M:0  f&À}¶ùOGí)öGÐÃ¥ Ù^÷䘄K½ äžíÐ{÷54ñÒ/ØÄgã–Ûg¯÷ˆ¿hÚ"ë_ÄW")@+á#E^]=5Óeä<o¾ðCr‹héì¾-m)ò*dÇÁdšp¼J\/ØNÄHCƒ÷m+&õç´§5Ä1q‚‘?wÜqñVµæ†}úÏQ÷¬5lÎ'gþyƒbmk5̧Ýý/Ú?œ¶¬&nEö%R¶Z#§v¥1›£…Cq·ý¸ò§c Œñ [*rš ¢3É<0 ºŽZQ"àÄírÔ2…)ÝžHgO[.&b†(ìö†hm÷`ø¢{Þ9Öû½#V’1 •Wé€îiëT" |;ùjß»½MØþÙ‘‚¦£yÒ>ä= ¹¤ìò* ÑËf…y(ÎÆƒ­õ¿¾ý÷,¸ A>«¹ÞèÓšF¯ÈÿVoììaü—½íÝü—ì¿ëñ¿?ý÷}é+‰c'tàæë s}^ ¤óåˆ,Œ`žö_E¡ÇJ÷o£ôeûEÕÉCj„XÉ/- ¸½>j“Nm`%µ2’'A­é€ç@¶±/ëè-E#F‘¾Üþà‘Ö"R‡Z?ùçÚõ—˜à<@¿huŽÛ/¨kDm×m¨”×Ð1nmÌÚ“úÞ“ÚÖZéˆXàþ°s~j=³ö¶ÃI¿µ3k>ÝÒ¸wÍ}jóÉ“F¼Þ~zOwöö>ªÞÓÝݬz°Þgîèç½pCŠ/wá^^:QCé‹Érx´QL|õ§Oå¤?ÐéÏÿkä/½pqW«¾ø_[ÛÛÛ{ñø_{ÿŸÏ“ÿãß§8èýh­Õ׬µæ|áNÉmþ1—!JÔ®è¡ðÅ^ÁøäŠÈ6~âã gÞñ@Ö½Þ‰ÄL8öä”W&Û1Ãã?·$ÚÒÛw“v—"¿¿›ôÞ×j5Œ½ˆVxð'ü•Cÿcæ)Ô.C›+ÔžŠ€Ù,úc¿ö,£ÏØ„µ‘ÑsT)”µîWT¸`ãËzÎb\°Ž;}‹cqP˜VT‡¹“;½M- <Ïñê*`ÆeÐSôóÑ;Z·ewÞèjá{x5Á7z(¾ã9á9£Ø»%¨ü®:†Šb´e›âÙœ\,//馔Y5Uá *`@køþp¦sDpìó©-bÂãGVüݺzÍk„|îX3Œd =» on››uUfhîîZ¯uÖí 0K÷óó—ýµRÏ!µ0ô.®bÂDÒË(º-`ƒWa8?ØÜùþ´veßÞÖgf¶·‰@ØØæHN7'l®ÑÌÛc÷r£^®°×,üÅÇÅ{~’\TŠˆ©·+ß”-hýc¯ýòÕÀ\^øõÂFÇ,Ø‹(9n¶°Kdìb‡­ÀŸ°Ç•p®º¸³´Ûþ¡\Ù FíF| |NqgÉì ¹ó#C~ϼ?ê–WÊçWÈ'¯”Ìï>y%å÷Âø}| ¿hbK÷àwÃ+Þ—îƒWŠ|ðÒ]ð f^­Õñefm5FSÓ_bƒÎÄÌ;rßÚK@½ØÊQïÄ¡ªÉèÝ`êX¯mÏ™=ð“ÿKÆ'þ,ùßëû[Û[û»”ÿk¯¾[ß'ù¿±õÀÿ}ŽŸ˜ãöGE€ý¼ŽßAc‚Æþ¹AcóòÃKú¸*Êꊜòú«€J«?œö»ýr)zºy=<;i^t{§¬M¢÷‘­LéqI·Y0iâÛȆ‰žh¶KÀtxÑØ9üÆê’_´È4Ý>jq@Á÷ãÖV7¸nÝê12é‹!“>pP úµ6¾,¬jßÇ|Ï"h³ d¾;ÏöåÌÆEÇý½1_WåÄWØòh@u°óôé^Ÿ0Du„_¬õ—N(:Ѻ}³~@Ù+Æ0)h­4ÆMR =ÀÉP>ŽP¯¸!¢K•¿£4-™òÔ¼ç´q» ôG ÉK?<ïü£Ó}Ó‘±ˆrçן—µ€[ísCöùLì‘ö8d C'&ö÷AZ¶ˆ¢7¥Ö’;>µòÓ¼ÊAj½Î §ÞQ+µÞQ+ª—ˆ™=Ç¿ëi„Ÿè‚EaÕ{"Ýáíf§i½qà6úåÊ9ó)ÃÓ›- |—޵U­o5¶uÛJ Ÿ†‡oZ''CêÍ¥qé KH{Î%\ nù¤€r§ºó8·TĽÖËvÐ굎bñr>¿ì.®Ñˆ( ¢¦½þÿë0QòJD<-,Œ,¶ƒ+ÔX@láßÃT„d…pXúýP¾äöœÉ%Dù›››šk{vÍ_\nïX)ó&⫲æ:àËCÄåJჷ1íW=N]êD—~] GóÙòv­b¼}ÿŠø~¯XõŠ…k¿WŠ@.Ç ^ðôœPKȆŽ3²ÎíÂ8·uœ‹ŸœØp4È]g.d„xS?*!÷uœ¹N¸)FöblKȧ:Î\Èâ8ƒQXt<’íc.;ÌÚ#ÆvÊU}µïÐ6;½ucñóA#¬?ûá8sþëÆRåƒFXgÁ<{§ÔŸèXóAÕî¿BÃF/cXÆÈ°NÂyul‡¶¾-k>è=°ª­°ÙSШÇzª÷ Tõ ®VÀÄ*4êA>¨êAèL Re»;Tõ`–2 ¨AÜòA#¬^pS8Y0ÎL>¨vf.«îhž¾eOÍ3“j`E¥]ê>ܮDZ®U´hÕ¡Ý6iQ.h„5I³tPc^óAÕýf¯ê€A‹òAÖé*PcµòA#¬—Ѓ+w¤.ÁޱZù j¿Ú+&kÇ8Ýù Vb¹Z…l¬«AVw”ìCjì¬|Pu æ³*¥Ö#Ðãä‚êX³vg7†5Ôèkàe0;{ñ¾®Õ浚¼"P“få‚FXíåØM0¨q¶òA°Gvlck ÆÙÊU'Ö©âÃduô!eî÷|>h„uj#¨¦Ã]ãÄæƒFXo½ š q¨q¶òAÕ¦wðŒÉÚ5©v.¨Ñ×ÑUèN¼¯«A#¬nàV/§Y ÆÙÊ5úšyÅíîÅûºÔÀŠû%ôIëjPýÄ& #нzìÄæ€ª;²ƒL¿gì¬|ÐëÍ•ïß|“ÑcgåƒjÒîµkÇ{î˜ânhŒºTÇ©~o7I]V*NóçéãW;+4Âzáûá<‹¼íT;ÔÄ:Ê}’ÀºTÍëd½gRí\PÅùó+ƒm0ôÕÎUgË ?Õzê1Ü7ÏV.hk#´‘‚uhëv:èv Ö q¬;é ;)XW€ªÆñ³Iƾq òA#¬×N޲’}c¿æƒ*ùØõ.³·‹±_óA#¬¨ÈÌÖc¿æƒ*úzs“Í>šXóAu¬ÕD'2±æ€Þc”Ô;IL«kò9¹ ŠƒvÃêlZ;×)ìÛãÄ䃪Û(œ¬˜Xó6Ê-Ø×Ýâ}5eˆÉÈ¿ð3‚'¦ ‘ aýà,.œ…Ÿ.r>1Îa>¨º9—UYx™vÉ>1Îa>¨¢D^àÞf1O½j¬ÖØ¿ÎP×㫵TÑâù ÁSóÞÈU30Zjrû¹ Vÿâ'ÌØ“1,ãäƒj{`>^f‘í§¦ž.TÓîߺNæÂš·Q.¨êë; «‹ëIÚ&|jðdù :Wê97AÆd=‰q¥9 j¿:¡}¹°g©Çð©©SÌÕx‡{4Ê``ë[æ%',¶SÑÖ·ê÷„ÕäC¿ö<¶a ˆ¹°ŠßœÏÝЛgÍ86`5¹kQõœ™Ñ‡SðÊ…U·Rà¯x>Ù2ŽNX /°}U/ÈèC o.l„w{äÏ`1Ì7TkʰJ»“ö* `cYVvϾ´³Äªú–q0 ÀFxçþ¼‘ý˜¶eͰ:ÞílØúV o¬F¡½E¦ X=jæÃ* 5rÇÙsV7ÎqXEÐÓ#‹ ×ÍçÒ„šçÁª9[%æÖëæµ–«h‰Øh­8¹K;uã €ð.—£yun›T°Æ*«ëFPûŸqÞÌçà°êòVΙq† À*Ú7ÏÃYôÁ|.«¬"’§B‡5ÎPXí•Óþp'h Ö|¾Í‡Uó»ê¹n>Ê€5öo¸ÀЊi{²±ß¿9°Jï–¨^§îIó¹·¬š‡[gìfi4ŒóV6Öß‘ï¥÷a?Ùß•°Š‡ ‚êíÔö Ö8o`ÕÝr3NØTh°æ•«Î›ŒüêijSǶmž·|ØÞ0 ¶žÄ»6†7¸ ÒaI¼+aÕ9í0Ȥ}æ³zXuz—è`bžzkœ·°ŠžÍgÉskœ·°jŸ-| 56ã¼€Õuž®˜œª‚Ý)=ó`xÇ—³¤­]Ý41(›À^ìÓ4¼+`ÕºÍ&n·NŠ`wŒóV6†wä…ÓTØzïJXõ^1­ºãY-1M Àªs‘²%5Xã¼€U|ÔÌ^qšæ`^Û^Á˜`MYz¾•q†L“ƒ°^wž¹ûq¼9°ÞŸìÅ¥Ÿy·˜f`_⌫»õFÖØŒóVVç«Ùò¦izPViÚYöJÝ4>(«ÎÛJYÄ4?(«æár¶ Ö¼ßòau:ŒªpŒÓhÉnü1+6†×Ô·k°»I¼+a y(~uk°ñÇâ¬Ò .§¡;Ÿ:·é°æs[>¬Ú¿ÓÍú GS~ˇUû÷;PÍÐW›¦`Õ<Eý9sOšÆ`•]ÅlÕ^ß7Î[X¥p¼…=ΛqÞ ÀªùÏFÙ2ä¾qÞ Àj÷üm„NMÝÉo¹°Šº\¥3ML ÀÞ¯2±X¸Á*ÿÓî5V #ž©SŽÁ‡³¬iRœ ÛHد†U×£ ×ÇlH¬q8 Àjx–í:¬ù"ž«™+ÏüЩ~pSÓ2¤¬bW¯±q8 Àjœî*Ø}ó3V»f ³F Öô%ˇUŽo“pUŒÃYV?{´â¢7-O ÀêJ±`î,üô½cÚž€Uû7XV½Yå)gœ·°ŠÙX¬bxLû“°J©°­X Ó¥¬f0´Wõ¦³*Д†Ò´A)kà f³êÂI…Ý‹ãÍUx§«Î¦i‡RVÇ[ù™ž“Obxó`µGª„Û´k2Ÿù°Ú>[±Æ Ó¥¬¢gauβ|ìLÕ°:^ï"KÑÕ0 W Àêx³ó¦áJXoÒG[ÁîÄðæÁêxwWôa7†7VÇû‹dÎÙ^ o¬ŽwEöcxó`u¼OVÀ>‰á̓U÷ÛJVÓÀ¤l„÷—í§µÝ­¬93 L ÀFxŸÖwF›—™°Æy+«=6'å Öl„÷¨ÙžºÙ°Æy+«î! Ñ™ÅË5Lc”°š{åJ·x“ŸÌ‡ÕgÙ¼gÃ4F)kdÓTóѲ¬‚`»±ŸñÙ0- Àjó{á…£ j^j Ö´ï·UJ›«ÉUö™7- À oÐ0“ ÀjÊâp¬9ù°ÊH XøÕ¸i‚5èdX%ÇΣ>¥Ãš>`µG*×õçYwlÌ7Vñ%‹‘Œgg3扛«…Ç+ æ£OXMé8[»c*3sa•R·zá{Nu”jÒˆ=úäÃjÁgVíÉØ£O>¬rÔWQ‰çŽœÔ>˜QJòau¼ gì‘ û$†7V»ßV(îæ£OX¥çrƒ¼ò~Â%°:»œ…i3¤Wd¬Ò‰9‹³ Tõ‹CÁš:±|XÅk`HJ 9g+æDÁšDù°šN7Ù™ò¼©ƒ.«9Ê/œÅOq@1ßÄ|XÅ#Þ®º/L]qX¥ƒ®^Lýч¬>˜† ù°ŠVû×6&Ó¾°?Œ–ñûxÛ”¥ Àª;Ë Ë 4Ãl(XóÎʇÕx‚Ù8óžß6eé°ên Üyõƹ°Ç3ÄCÁšº«|X%›ÓÙ<»ƹ(«Ñ(4°«SÿR‰‡ ÖôØÍ‡Õx{ê¢ÝÈ…&Îæ¶)K€U¼ç¬â5œ[{‘ »‹¶— «æa?¹mÊ`^û&Û)hÛ”! Àªs‘„ÔaóVVÝ›v¸ªÆy+«9eºÕàò&Ýø`Û”! ÀjáÂUkaòˆù°]ár ïæNÕNÒTÓðµlÞ‹ØzÞ,Xí>ö0¼ËX oXE×Cû²„N5¸H¡%¦AmX£¿pŒÒ#³Äð€U|Ô8Xq·˜†º`µþîÕë™gÈ4Ô-«…Æ*UµƒTç¨mÓP·¬f(æÛ^è£I  ¤`÷LC±\Xm7–kÆuʇU2ïÕ„›SÍ£`MGË|XM²XÁËÅ usaUG¾ÛðQ£ê_&ÏfÌP7VÓ]$Æ‚z(XÓP7V{k’v‘ Ö4ÔÍ‡Õ >çÃp ŒW¯aêl Àj¶T aWG³ËE¬ùv›«Ñ³+xSgSVñëãYvŒŸmSgSVÝ ž_‚Ü€¹LRöŽqÞ Àª7Ö ÷ÃåxžµÆÆy+«öÃ|Ô@•‚ás¤`Íè²ù°šž`l#±n¤Ò>ÓP·¬F'{1нÁ)XÓÑ2V½©aALœkœ·°êMÂA2#¦Û¶i¨[6Ž·‘»“‚w¬ÒŸÙA0ÍŠ"½mê€ÕBL®’ELCݰJ¾ðZƒn?³¦Ž4V{óY kÚ&åÃjŽjOŸŽ2ï,ÓP·¬7[&3õž`Õ~˜WGþtêŒB‘¤Q¦Þ³¬Ž.C ~ãªçÅ&R°Þ¬nãž¿Õé8ÅYyÛ´½-«èäJÙß´½-«ú»Ê^yÛ´½-«ø¾;JTÎÔ¾‹ë®žÆ2zäÂ&ñ^,üÒ¨@Á6RñfÃa¿v3i‰i{[Vsð¾˜V½qú»é¶i{[Vw´ÌvÖØ~w´ÌƒÕñ"g:+ؽÞVíß‘“í„·cÚÞ€ÕðNWÁšç-V³U æ+`Í@ù°zb‹å‡p™žëb+ž$Vó©˜UƒYæž4ß/òa ¼^6ìÓ8ÞX}ŸMmÊŸ–GÃ|/,«äÍÙ û‡ó½°¬q¿ÍéÒÒ\–lâ~ËÕ| Víó½°¬f7ñÇù‘S%f— «ô}«ìŠwÌ÷°jÜéµ³ÀôŸ¡2IT°¦K>¬¢ë^І‚5Î[X%ÜÍEõ2#_‰ù^XV“\gZÏ:Cæ{aXmŸÍÃì;À|/,kö·‘Õó½°¬‰w;¶‘À»V{GUòáþme4§`MßÉ|Ø^8ñ£IØ4¼+`Õ9Ù㪓yxÇ WV´·ƒqú›ÚŽ®¬Â{½˜ú£Ìµ0m-óaußÔáh¶ÌÛ“˜oj¬×Ά}Ç›«ø¾p6ÏæÍ@p` ¼£lØzo¬Úgv°‚72Á€Õ[®º³Ì÷ù°šüÂ:±€ Ö´uχ5ñbü´ ‚;f ¸°šï$>HdÍí˜ïd.¬žF5eò\f ¸°š~rry“ylÇô“¹°ÚûæÊ56“ŸæÃjrVøïìÄåäÂê|êõ,À¨‡³Ëä`‚+«Öíz4Ä áãôÜl¦]f>¬aŸš©{Ý1}* ÀÞ¯–ƒ3-¶¿Þ1£åÂj9 F =ºô¬nœdËÅĈy¥`ë1ã¤<Ø4¼3ŠïÓ¥¬šßéÜɾ´Lc”°J¹=·ƒà&3Y©qÞ À*æ~1^¡2QÜËÙüz{ê†i9;{±ì1—nhO«×zÐK“ «Îñþ²çãÔ>˜ù°Jéxå‡Ëx'k*3óa•rpUr ˜1J>¬Fwn1çí]êÙÜåÂjˆ7vn3Óךơù°êÑò§ätà¥÷Á8o`5¥ØÅÂWç~ÚÃÓŽiŒRV3¨†ÓêMºáÊŽiŒ"`+`ÞÑØ+34*¥`Íšù°±þNÆõô9ÛKöw%¬æ¸ïeÓ(Ó¥¬Â;²#,ï˜Æ(`5¥Â$ÉÍ)Xó±.VÇ›Œ“ 0oÅðæÁjt'yä5XÓù!Vs8ÅèënÆ`£€ÕŒÊæÙ.;¦1JXíñ t.6ðË)Ž_;Ob¹°ZFŸgq±\iTwLc”°êž¿vm/s¯ÇŒQòaÕ¹°'+0Lc”°FV‹Ì”;OY-r`5# ÄË%ôG* ¢‚EÙÏ…ÕånVOÒÉ›Æ(`µŒ¸É«Eƒ­›)qsaµGÖѤšù0b£€5ñf>`˜Æ(`µsq]]Ø;¦1JXãgFÞ1Q ÀjNb³êb^»Ah£€Õä/ü%ólÆÁåÃj‹ö,ûlšÆ(`ͬYi!w’Æ(9°^ûÃ,Ëazw+fl™ «ee™M2Ƕk£€ÕÑppÊô$&“íÆÁåÃêûwázAzöÀ]Ó¥¬–õ&´ÇYe»¦1JX#ºñ…[ÎRî¬]Ó¥¬z¤ºrg™rvMc”°š~g…ÁÑ®iŒRV¸NIœ¬`óVVÏ`¸p²aŸÆ2æÁ*'ÇU²Þ®iŒRVsö ‚K?ëlšÆ(`•ñâ­“ÍƒïšÆ(øèc‡™xM'¬– /XÁš%òaµ‡iw–}ÞbAãòaÕ^Ÿ¬¢;¦á fÕÈLn¿k®,ܹw™ÙÓp¥¬.“­êoÌÑ'Ö0ä_ddéÙ5 W Àj”+û3ÌÌ…Õ “Vœ v7f蘫9üÏæ~6¬©[ɇÕx£ÛUc3e½|XuÇ.ƒÐ½ÍÜ“¦£{>¬<ºšð¶W°OcÁ£ó`µ·¤˜ `ÀÆ2æÃêoTgáx©¤vc óauÃøì⻦áJXÓà>‹_ß®äÃFxo\o¼p2’“+`Õ~pýìwô]Óp¥l"ðÌø:u-öÒϬ€Uó»Ê˜u7–Á0VéÆþ,3ØÔ®i¸RV{tá2¨NÇ)Ω»¦áJX#SqöØLÕ°fäEŒKS°õDäÕ°ºÁÑÌYŒÒõ©»;qÞ3V½©¥1” Ö8o`Þ4†RÁšouù°‰7aµ’Î}»¦-JX¥¹ͯ÷ª£©«…JP°æ[]>loú»ÿnÌ%VÍÃdî”ù˜¯`Í·ñ|X-ëùdÕ^7ï·|X®ßTq$‚5mQ Àªsqwá 3xjñ]Ó¥¬f€v\-ª^˜ v7p%VÓá­pžÜ5mQ ÀžVÀîÄ=åÀê‰+x®X`”|ØXršI±Æ{Éä4+a ®ÂÐÇívM[”°ŠO{Á‡¬ »±À(ù°_íŒC;ö©ÉWçÂj9¾çêÛ¬i‹RVO€j°ñ·ñl|?\§:Aïš¶(`•®8L&Õ`óVVéYâi°fÃ|X-¹Ç(ÛYc×´E)«úëÙ+h‰i‹RVëïxUž˜ýÍ…Õ ù/²ßEL[”°Ú›,ò•c/ ǎ;—ìš¶(`Õþ¯Òµ™¶(`5[5Ô– W‹ø§`Íó–«ÙΠ/LP½N¥©¦-JX%¿9wÙvA»¦-JXãmæÆ_Œ«£«Ë”±íÅßfr`õ¤ 37\ßK[<éB¬È{ºjM=b>¬Ò¯ß9É\ Ö «ÙÀÙNL»¦ÍHX3»=MƱkÚŒ€Uó°cÐ83ÿƒ‚5ÎEX³¿ÀiTù,á ¾û4á“«æ7-ú®‚5m"óaõ€ñ ³ v70>Vwt_A«ŸÆNsaµ@È#Ïž9fr»oBÎ…Õ} 0–8ªlf—Û Ø'1_‚¬þ>4·®:׳Ա=½åÁ¦ßÇqÿ½ÆVæ}œ«%ñÍ«nÖž4í@ Àjó0ÚÀ&¦«ÜkÄÞÉra•^Ù¿¨ÞÄM¬éÓLª‹Ù(Ýv|Ï´Q6#uŠkÚDæÃêr÷p¬™üÒ‰PÁ6É/WÃj>WžÏE¢Ášç-VÝC7‹´Ä´)«î‹`…?ä^,¡O>¬vÞVѾØyË…5ì@ªÛú)¶{I;XµÏ+û`œ·°š>j|í:7ÕíqêÞ1ùÉ|XÅG]8·ÙkaÚ€U÷›ã8ÕYF‚Ó=Ó¤¬’³@Âñ«±T¯ Ö”ßòauú$½‚%rÌ…Uü™?¾^1gf@ó|XÍ®Ø[q†vcvʰšôŠD¯{¦HXÍþaEï=Ó¤¬f¯áMüiæZ˜IVóaõØ,Uœª:{ÁîÅ]åÂj‰VyÓ^£¬¢¿«’xí™ö`ÞåÂñ|7=¹Çži¯Q6M~KÆ¥Ú‹%²ùÞßMŒ3aµw'¯:Îò}Ø3í5 Àªý0þ9X1gf¬ž|Xuùþ¬(Þ°Z¬“`4õ³xZÓ¤¬fÿ€Ö¬™sfò“ù°Þ…ƒ ˆT]PÌ$V½ÏÛ£q0«7i¶€{¦HØ8^3O„‚­§à]«ðÎçAõçe†ŽÉ´)«ùzÎæÓøõ­`͘[ù°Ú;Ίd{¦HXµG«h”iRÖœßk7kÎöó»VÇ»‚VÇì@òa•||9©&ü¬iÇŸ«ÎÛÊ·Ó¤lB~³m;…®?I•ßVÀ¦à¥ÁÖÓñfª÷·É*Ç´)«'ð¾°«1»Kà›‚W g¨`wÒñfÂj÷Û¨*’ŽÍqöö̘$`¿¢Ó‹¡“SÇfœ·°FBl¾w)k¼Oˆ«ÉötV…í“*;™ö%`5?ŸU´/“$V»‡VѾ§±û-VÓï8·£«*º’º‘Ó§‚5íóaÍ€ñ7öµSu•Ñ»‚m$Ư†Õýê<ÇËν÷4vÞra5~½:š.³x Ó¾¤lB>6‚’*ØÝ4ùx¬Ú¿Ëà*[GjÚ—€Õü¨Üñ¥ãeÜ-¦}IX%LƒÅŠ=i4Ï‡Õø’‘è‘è/>$÷N̾$VÝC«îî}Ó¾¤¬ÒsÍVÂç­¬æë™¶û¦}IX5ÓQ¹wöM;°jÝÐN8Ë÷wß´)«'ÖÈÖìoÅkäÁª÷1µ½quü”ÔAï›v `ü·™æ¥`Ÿ¦ñ;+`“|”îuÁÖÓù³lXM¾À׿0=>í¾i¯QVéw.óIæÞ1í5 ÀšçâvžþÖ±oÚk€Mà ÒǶ“†w¬‰wzóKFvxWÃjï¼^ö›ð¾iƒõÊãY=å~ÛoÄâªåÂ&ñ6Ò`··RñfÃ&ñn§ÂÖSñfÃêx³ýïïÄñæÁêx£ ‹žíÄ}øó`•¯óÓY&¬é«‘«ð.rÃ`Y;)±÷Í7”°ZL´ƒÎìƒÉƒçÃj6ô‹ gᨧMÒIó ¥¬êïÄfÆqÙ7ßP¦¾=¶¯³úk¾¡D}pÓæÌ„/Wèâ÷Í÷–°Ê^cqµ‚×0ß[ Àjïd+aÍ÷–|Xí= 6Iƒ5íSóaÕÙ\åk¿o¾3€Õå–Uc‹Ù‰åªþ+â²î›ï`ÕºÝ:+ú`¾_€Uûlé‡vÖ›û¾ù~QVóGMxÐkÊ…ù°Jn™%"Éè°f¢«|Xåoê\™1·öcþ¦ù°z,qϹðýécÛÅσÕã~­Zã§±¸_y°ú{÷ÔeøØìÇÛçÃj~ù+|@öM½}Øä>KåKL½}XÓ*+nݾ©·Çt“»•°jVÅãßëíg¶ë…ÃñÅ8å2õö 3ø³‹Ì>ì¦á ¶ ˆ&¬:sö2ùSo_Vé¹–ÓкޥnJª`ÍØýù°Z/³ß÷M=xXMO{ Ƕ3óSlNŸ˜ú‡°z| wädÌÙ“­X‚§\X=¦d¥+Æo>pi—À¤Æý¸ÉÀ,1SSËU®˜å"üÛòÿbúÆ^ÿÓÿö¿þ§ÿÏüÛÿúŸÿûþñýÛÿñüøÿ÷ÿóÿúï?þýÿüÿó?þÓÿú¿ýßþ{mÌ50ÿãßþŸÿõ?þç¿ýû/¿˜eܶ~ŸúK×Q?”ÿ… ,ÉHÈDÐ=|À‘P†IƒÖ6ª{¼Í0éöÕä>î–µû*ÃÔrîã²dDL-os0ë§^†é=r9Tc9ó‹d&'ñï~³xÕ 0s•á°¾¿ßS²‡ ‡Qd'€‰·ß¥»‡xø€îþ2Lz³ºÜàÇÄD ÞÆœÉîõ0JÉp˜ƒ—6û80uzJíb›wãaÚóéªtr»aÖ0©L< ·ôçÆ°²&ÚÛ׬ì2…±¸ &êïÇâi¿âƒŸ¥) àp–mnðc¢¢ß믺¸ÓÜ­oVFµ&£nX¯æÆb3,WøÄ-—àpYzšº¹Ó}taÄ`»{w§sÃí˜Ô*žýµE=£½Ñ=ŒÎ3L:ÕÏÙÇÀòÕ˜ÕmVÚÅ?O\,ÃavOÏÉèD„ÈÃ0%pX‘ú¥BV×$–/L^”Àáfv²¯¯f˜ÔëÕÓ< }ê1Xc”2æ í²sPSË“¹%7 H`r³nÍò#?ÝטøÈ÷™^dÐ-IeÙI׈nn\†av±%E 8b¹ŽÂ§¸å4Lô=·Þ¼•ÿ{»óZ·fŸ2¼/Ýô=ƒb%À(‘Àaåw?z2ê9Ø1rTC‘„&÷î©Ñé#1“I`²[-9‰˜“‡ñ,*€Ã¹NO‡ù¿ÝºØÁ¥˜Ôòð½N ~KH`r›¸(7[UÇ',Ê%$0ñß–Ò¡ÉÇÀ9(€I÷j¿0öß͘ß_‘‚!0LrÅ<öÔX@ŸÀè¨ÀÄÛSºô’ËÊ^ à°Ã>½}Y“XrYvLnô³2®ù®X¢˜ò(é¹n¸Îªíh#ioÙ¹®G,WQx·œ†©Þn¸üeêh¯sÁ]kÝØºzÒÝ¥5“jo¨^ð0úpÜò¿D>&-'à¸å¹Ê|JZNÀáTpUºï}b‘aÁ9L-_;—Ü&XxNSË®KOX ÐI`Rug› \aÙ2Lú»õIÿ@,Ø!€Ãnå<¹ÇÀ–F˜ÜSêuAuïñžR†Ãxî§Uan ãÀ´ÎÈï\ORg”À¬À}&•rì·WYϤ >1ýASË«4h Ÿ™å"LªÌe2‹7&KÀ¤®y¥–ú$´ô…qÀaOi†‹ùUG/lAÆ}PG-Wx›²œ‚ƒÒcÊ9«7˜v)‰ÆÁßI“ÇË &^J`¢tó7¡Y*üywF)–Ž[®Öð1i9‡™²Ì'¥ãŠÆ9(€éyC7Ý·ƒ(2­6¬`öÕ½>Yú‰>Íê™7,ƒØ0­n¡4$Y q&š·\tƒB žyUãŸufŠ+’í­r?Ûø6±ÁDL f÷Ô<œš§>zÜ`*¦f–ë~nãðam93Ë>kËy˜Ô©¬'“¬,àà%~5µDëãsP“98Þ7×ó;¸n*6Ëp̲‹}”sÂr&ž@—ü¬ÁºË´P ‡7Ür _ðÙ-åÀT´?ž‡aJà௻ö¹MÕ,˜hmÛwîÕ¡çD“ ÈÞ>m¢k—‡÷(/ÃaÞ/ê¦góÒ±«ÇÕ,8D¥'Ûå~ ÌA LòÞ¾»˜æ)JàÖ(ÃÁò³Ë~n,"€ÃØxÌC?$ñ¨f‘ÀDé4t.éfÙ šE‡·ÑÌÃкäc jQÏöWnð¹ “: ®žì8'ެƒ÷Á³²õÃ$ ÌA LÆFcgõ™y\PÍ"©öÒ.t'øÈ´—E˜Ô$ºÚŸj2cüHŒj NŒÏyÝt•ÀxÀÁr«ÿNÖŽð÷ƒ¦q-¡bWoÿ6½{ÄÅT³Hàp‡µý8Œþ“t&Ì[ÔÀalø³i¥tíLô£ šEŒ¿|øóÔƒ–Ê'0z/pð^^s£ ªY$0QϺßb5tn5­PÍ"#–ã¯î·œ†ÃIæ²~ cC%Γ®[CI„aJ`Zƒî™YÌQÍ"IµzÝÎw5m»®Œèa,÷-€¹eìÒFà*b9 ‡3ÓäÛ¨f‘À¡Æ‡ë0`Ë`˜ƒ,ópÞsË%,ÿ’ÍEªY$0«˜fG×êèG9®K¦åádÙ-Nø_R§ú®çô¦‚Ú LOÛãËN)× j_$p8̵JV©ÚlPû"Á²Gì¯Cà ·\‚ÃÊØëÜTAí‹–Um{ÓiEŠo8œ\—´èߪÑ?3†ÀxrÀ¤î½s6U»ÆÃXà[-WcoƒJ~Ü5pxæÏå cú›™bó µ/8¬¹7«ÜØ¡öE“›Ø\ßunâm°&×e8Œ/÷³åÅ Œí2pø‚­ÕiÕ†þÀÄó«~çltZ¡öE“›˜™3‹9j_$0í2ÚùÃâ[égÌiŽÚ Ô¥ãÕeµ/˜Œ:Û,mæz7Ä‚g¦-Ãa·²O£ëipñC?j_$0É 1ýsìSj_$0©rUét j_$0ÍUëôÍÖ‰j_$0UñNöáÔDû ˜ypÊ0±ü×ðGÁñµ†Q&€ÃÞÝÙÆf^ÌA L;ò¦«HnªÞ’·‡/øðwXÿêœ&=¨ Œ"0ƒum=Ìç`&ýª]kkïéìa¼= `°<ÜÒðŽ[.ÁôT0L‡ë8ÌŠÖ•a¢[ïCÿ……FŒ^TLú%ÍÚé›I},!€I§W}{´­Ò6þ¯X zLzÞÖë oŸ±émžßÁe6 Š•5Àaœ¿¼¨&Ú»Éø àp®{Œ:÷0%p£¿ðÚ«‰§&V¨ª‘À!ªÿÖ:ýQPU#É*ªû¥g°ÚÄ_kH_†ÃؘýA­Þ'¶ã U5˜œS}£GŒ#žËpX7Ì4\Û% HéfuŒ¯PU#c–'3¯ásÂrž²ù÷5:ÖqS¡ªF‡±ñ2f~-IF‹³e c1LÎHSÆ™[U¬Ìa¾¯[NW¡ªF“Ncýß¹ÇØa«±2Þó¢«þòKúTß#ªj$0Éž½½¯¯T ¶BU&^5W݆”s¯BU&Uó‡ÉôujÓDUþcùoÓÏi\…ª ÔÒfZÎÃcü’^¡ªF“óFï–­jÇn5­PU#iœò¹ò¢xËâ”E˜ždüàT(ý"ðŽdŠpxƒó‡b÷åܳ^ËÁ+VÉE“Hó:ÖFáFšËpX‘\3¸íù#1D™öE“Yu«~&',j_$0éš¶nDaÖ6­ CƯ?pÛ¸t¯Bí‹&{Šcqt„YIÞ2L{ȹå®—”U¬Aˆ&3e²ºe2*ã­Mþ㽚ïÕq%è¯Pû"ã–«5¼OZNÀ¤'ÎWº¦œ‡aJ`R-‘À_“îB-|c›PLâÁSg2 ç &+¿ÓþQf]± ÂŽµæ-Ãä\×6_Ê¡6À¨}‘Àt<û¡›ôx=j_$0É{£Æ:žšX¡öE‡óó~ÏQ€aJ`RÛ]­”{ÆjJ˜Z®u}7êç#â‚«Pû"©e Ê1øÀ,á06îCý¹t•¬â 3÷0x‰û6ýêNÜK\‚™å¥Æ9bø¼¶œ‡Ã*zé”s©Â=+D.€‰ÂÝ'®•!0žp˜)ýìÔ0]‡Ö,F“oNžU¡öE“¼\ ëT¨}‘Àá™_G›|u80™ƒm;¾üº8~FýkN/€IÍ:ûêŽØF³ ÓüçÑ´ªs7à^oš¨f‘À¤Èl[=Ž©tÆ: e˜Ìn‡Žj„QÍ"I×ú•HGV=¶ ‡‚»¥>.< 1‚ €Ã3wuFÐ_¡šE‡ЦñGÿÑã®{T³Hà°Šú‹XÛšzâ?Ï¢˜Xît¯o©­©Y0É|jÕ±›1‚ €aÝøWt|Ä[¡šEÇ-¯ñ¨f‘Àaݰµ¿H¿"˪Y$0Sj&7ÍSDš‡ÉLY\8©2sªY$0]E›G=“¶ó*E˜ö½V?¯ïäܱÆ×E˜Ö²´WtÁ¡šEÓHúÃÎ!›Ã<’^„IM sìeMt‘A5‹&½ž—GÓ|¥~ VÀ¡&ÝK·Ÿü¸M`˜ƒ˜æü¥Ó0ªY$0i¶q9xuÞDbšY˜œ¾š>³i¢šE“NT³úœ.‹Ž×Ôëà «ä"€IÕ®™lòº„j V¤{®´G…j ÞóJ Ž0žE0Ñ»Ghã}P‡ïXg ÌA Lµj®¶éxfZµ",o«íw¯n[ÇûÙl¶¨f‘ÀD•¾UKa®ïØÜf ³áe8n¹ZÃUÒrcã:»dçN£_T“ÚÙC·”½E§ÕÕ,˜Ä€Tg?Si~[T³H`’Cµ4õê¿‹Á «Ef‹j L<®uGuKÆö¤8Ü­—îÉæaôÉà°Îú¦’ÐÕ,8ÌÁ‡ûüJ '¶¨f‘À¤{o·î!L`Ö¾· “¯U¦g)Þ®0Â[†ÃLéê£^¢\Í%ceOF]“éÕäaôÉ`’‰šk„°E5‹&7ú‹]J2ÖѰΖ©YpˆML³óç‡:ZÝ¢šEÕÐtÙ/—ô¥’Q †9(I-Ë·²µK¸Y¶LÍ"€Á²~_PŒ`T³H`rÓ̉=¶¨f‘ÀáÌ?`8c|P“êºu&´º­XuÝ2Loô³V]/žµ­Xl¢ Ëß…”çéÑ‘ˆ>Ñ/*€É=¥s6"Ù¢šE-D;Oæ†aJà°nø‹Xº8øÕ,˜ÞŽ›‹2殺ZdÉE5‹&{ÊdÌìW«©#Õ,˜Dÿg39ü¬ã‘³»¶ZMïQ]¢KÖˆ‘ÀäŒäÜkZ:e´¶^…϶¨“‘Àa(€ƒïk˜®ÇJÆìLæ`kÍ5¹˜óŽGeøåÿßü×Wþ„ò¦ÏÈáu2˜ž7~h+cïÙy£ß—ÿ­îô4ÛØUu2˜ø‘n—AO‰ÆK[ÔÉH`’µÚ÷mÝÚŒY~˜T1^{à(ÌZ@—a-íx £NF‡™bûL)±-êd$pˆwûǸúñ/ê´EŒ§‚f)tòóa¢)Û[ÔÉH`°¼ÒrxÇ-—`R•[³r½Nü@ÌòÀôôíMßy|°“>ˆY×êd$0É·ò×¥¾Ö.î²@ŒsOõÈÕP'#ÃíØ©[f¢NF‡uã» ù}°“sÓ«_H`¼ `ÒÉr¼[Žïƒ˜f&šÜcœYfb–íÏÌ…wÇt28¬u×5Ka<‹ `â ì’l²‚qÀܲ_c=v¨“‘À0SºŸKÚ¯‰¤öìP'#éxæÁÞ³ñ\„©´­j‡ÿ{{ŒÓBaêU»<>ç‡rÓsοCŒŽZ®"ð)e9G-o#ð9e9G-ïÖ0êd$pØußèöšZQ'#¡ïEcÜg<µc½”0‰<º‹v)9åu28¬u_KÓêäàg½”p¨Fb‡>³ä¢NF“îA6#™Û±ª/8x¨ÚA7™ˆ1zLVÑëRYw¶ôƒ˜u‚/ô–Enªx-‹"æàØ<2¯u28ÄÚn9‰þu2˜ô½x˜‹™¦/:šŒyô8Œ ·´òS‰Tµêd$0·Ü¥à]Är†¶¶uò1VgÑ s0Ý–x·]ÍÁF¾~pe½”0æ6q©AŒ¦7MëxÙW³~fe˜Y®’pµ¶œ‡I–ŸË]ÄX/%æ žjÝ%¯¨“‘À4çñm;:B NFÓÎ%Ùx`KŠ0ñ™O6³£NF‡gŽôL 0úE0Ñ€øsŸQWP†ÃmâuÍmš¨“‘Àp*ètª¤ón¿á§‚N¹³¹¹:9DQ'#ƒeÓ[“tƒïP'#Q={oZ x·RÏ`r~nsƒu2˜DÒuös£_Tï¥nír•N,¨“‘ÀáÄèW¯ËÏôçÆ^L×:wדÙ$à3[ëŠðÊr‡Q'#ééÇkjý­éG»&îP'#ƒ.w˜Ú&=øQ'#yïÔRÀt2˜œEÛ,,0;‹–ašŸ’‘ÚîP'#Éžbt¿ä^Æñ¨“‘À¤IÓ­îÒÆø Ë™K êd$pØ»uvùBŒñnmuÞ4™NFKß3êd$°ô=óz2ejgù;ú=õ[^;«ƒâjû&.œØ±z2˜Ü­Z»"M8P'#Ã{nŸþöx½¥~ Æè0ÜŽ{j¥´cõd0·Œc‰À§ˆå,LüÏf27ëæhZîŽëdÊ0Íh6Óu˜ñžÕ“ÀaݰSÎQÆt2˜h\góÉO'®PãZ†I<%ëÎBŒ¦ZâkûH5–Ú¡NF]î²ý<¦Ú$`˜ƒ˜zÌÃ8üp¤¢8ÌX„‰ê¾ö‹¿¸é™V¨“‘À¤_[í `ƒ±¦“&Y<ÎspÌ:³”aZã×Î¥ Á5Ÿyß"L2‡Þ¨Æ8{‹­ÚY¶{Æ®=ãÔ1Õ,˜få¦W³”á0ŸuÆ>b˜hãýš;¥®K¨f‘ÀÁ³}}çT¨f‘Àal|-{ÏâüÕýº<òÕ,8h‰ïùW‡Ù 8Üa[—q íQÍ"Áÿ\'_ÝÕ,˜ÔqµOlÿ´G5‹&àçZu)ûþƒu‚/ÃÁ¿ñ¼(“yu0%0é1ߦÛåîQÍ"ÃmbÎ¥óïQÍ"ÉLéÆÖ¼“?+/ `’w¬oÝÐ7©‚»•&Û.µnRn–=ªY$p8}=s‹ÌÕ,8ôÓôwÇt"êÕ,˜VlË/÷Þ ¾“ñü—ÝC5s,ýyj ³Ü¯‹¾îQÍ"úáð¿ê‘.oÆ(ž&9¼:7­PÍ"©å:™å"L,?³ªNL-gãÌ,a¢ïÔßvTÃõŠg˜U}Àá\W?.iûÕ,8¬Hþ¬65CâØ³G5‹†ÌËÞòÌ—LNæ·É¸¥$pf„2Lcm™"l{T³H`ðlf@¸š²,I*=29,ÀØoB?Rk³?cô˜Ü»õc¾Sjˆ¢²Z‡ñìßr×¥Õë Œj –ÛÅm½gjL<'Ó°$*›zŽ>óœ”a¢Ÿæ‡nÕØêÚ¬ ŒìQÍ"É3×ÓÐ=œ‰:Ø÷LÍ"€Ií¬qRX`Ì0ÀÜr"Umj Lª€º:s©Ù²* e8œ¾šœ¼aj qØv£þ$ÑvëÏ}æqØfJ“sÁíQÍ"©å*³£šE“N¶¹™^A¶1’.€ÃذÝE«äuGÀa<ûM¢æ‘9ÔÀ´ÓÐlúޝ®—¬ê‹Ï|¹èº~L´â>…q `âq—¦‚©i…j žù“­îQÍ"Ñ q\Üñ»gU_Ø ¸k28¬²¾™¸ƒ}j L22ênnUs‰?óžU¤/ÃPýl ðªúY ï¹_M*€q `¢‚«sî,T³H`â½|®³¶ Œf·™ì¬ÝñòŽ~n¼ à0S¦Ë’ þއÝ÷¨f‘À,¿ý9¾Í-õ¹aJàà…0—j)C‚±3‹&ë³ÿÜOÝ&`T³Hàà…ð©µó×ÓšWäÕ¡šE“9øëlo¶²?°9X†©^T_¦”èqj L;î)]R©¸c÷Š0õP5M{IM+T³H`ršLûÿIÀ¡²të¯3éÕ,˜ôuc§“—GT³H`Òe;{D5‹&7ú‹}'Ó7ö¬;’&gÑ‹ßלj,©ÅC`v-ä‚3ÛS³àpæŸ]=tê£Í)ö¨f‘ÀÄÿlÚÜcà}PSŸLÝš^CÏIsŸL¦•jšk;¼ÇT³H`’oå—î†#0övÀavëz¸ïS–SpÔò!R–SpÔò1S–SpÔò)ŸR–SpÔò9ŸS–Sp|¦|¬¦J_$pÜòf §ç`Ž[®Öpr¦àUi©e¡‰,Çm¬´TŽZŽ,(}‘À´Å|îp‚Ò Lßó0MH2G>¸ÊÁDH?<Æ—MHš(}‘Àô=g4Û”¾Hàp*ÐS=LcBÍr`…\0¦Éø—§Ü%Ó<œ>Vi2˜¤œ(“®Êu@鋦¥K¾ »^’_ÖÞ”¾H`” ÜYSzoWRLÞþnlüõ#ý? ôE‡g®úÉt©î¢”¾H`Rø¢úôŠ5<Àá™Ý_ó¨êyj£C¥/˜Y^¼æqø´¶œ‡ÃùÙNæ:¼“CËSàðÌ7õèšTôÿ€Ò \pÝèDùÿxtz½˜£ôE‡ñìæU¡G cy |“æd„J_$0µÜ½º4¼c–‹0µÜæà=³\„©åk—Ìr¦–]ºkü•ˆÀÄÛóÕÒPs$¥š |BoOŽY®bð9a9 ‡}ptjÒ×DÞÄ¥/8ìVU®ï¥/˜XÎU¤_Y.ÃÄ á>![ŽÁz!Êp_ü'¹¥’GÕHàPr¿vjÕëžÀ0»%0‘¾ØþæîÜx &ª)Ã!´jæ+ ³qf·A®¦[–|Fa,|!€Iã’Å{Ú$á6.)Ã$ÜÐÏS²Šþñƒ2Ê0)y4š Œ¢ Îüã¼xPÍäšuŒþˆ¢ LÁ/Å'w”QT#¡¨à¯gX±üH|DQ3ÅäjgQT#ú1<š•ä—À0%pðlwî–YQT#Éñ/uo˜˜…ÂèqÀáml«íâ¬^J~­·¶#Šj$ðʲ›õƒÏ1Ë9,/™‰µ&Ò²£¨F“Ä=[×ÉŽÕÇŠµ(Ãá™?sõ Ž(ª‘ÀtÝÈmÇ(ª‘À¤Ôðå[0ÔiRÊ•À˜ð+€Ã*Ú˜ÞŸ{}=Ž(ª‘À$ÉÂLVßYQÇŠ%Y”aL|§?Êq• Y€iyd?•Ž(ª‘À¤0ÑüÕ·éÇÀ}P“ònŸfþ; ³â3˜¦#Õõ˜†7,©³Æ%i¸Z7.ÉÃ$neÇô¥æ¸e‰Ne˜¬HÝR¬óÏÈ8nYÒ}&oÃ>¿ zŽÂ¬LS&ÑÒɘY-ÿ¡×Áñ#k¥$€ƒÌ¯m§“‡@ÕH`ríÌÍô /ñqË΢e˜&Ý뺦Imó¤û"|2ý’-H¬•’&놫åϪ»u+%ꑵRÀ¡XÇÿ>,i¶ UçE5˜øz©v©Éx{Å^êd$pxÏ×Y}¤_êd$0XÞdàŠ[.Á`¹ÊÀ[n¹ƒåmÞqË%,ï2ðž[.Á`yŸÜr ˇ |ä–K0X>fà·\‚ƒÿ¹«¿Sº‰NP'#W–Ý3Vÿùˆ: Lš»ùã6obD`L…À´U´?ÃBpÅZEá ËíüÁµŸ§!>¢NF‡ÛD;\t«š9Ú‹äˆ: N_¦³éúGT³Hàp^fº=ôÔØP]ÀXDBÓ{wco_K‰ÑéÏ…À\ÍR„ƒå»ž:½d·Å? ¶çÀ!n5~š/úAF5‹gÑÞщUY 0&° ààcÕ½¶©:TGT³H`¢XèÛtí#jN$0xÕ2®ÎÓªìX †Fªn·hœ#jN$0³ì/=YÁ|\[ÎÃa<»U€q¦`RʲmÓU2ލ9‘À´ISîRÃ4'8¬üz“ a3͉†R< ?S¸â¥xJ0ÑÔj.© -Óœ`šB¥Õ¥NM+ÔœH`²ÖY•îrrD͉§‚¥sÖljEsŒå7pðv:û¹Ñ(€I¾1 cSuL•¨“u)¡æñÌõÏE˜î)+UT€O¨9‘ÀäÞÝýLOØÓóÆ—aÈ·ºq“zŒŠç[•`¾úSàWd1?1eˆ&×\-‹kK$€©eµÔòKýÀ=³\„Ã|8ë_¦îKÿ `Òf+·˜ŸP"¹é9F]C§˜'0 ¯-oâð9j9Τûd£*C$pðÉÔÖô³ÕÊ‘âÒFO †rXdýçS†`fYé:Ú»á„Ê |_Kõ†‡MO¨ ‘Àa¦tãuN{N¨ ‘ÀaEÒSnð£2D‡÷üyQƒKUÑ?¡2D“}ð:™ÈöÁ2N¹­ž‡ô„Ê ¾`Íjo ŒÊ LÚzöý×wKóèR€Ê Lü¹„…SÅüe8œ‘z›KŸP"Ã{^'µS£Ž 'N¨ ‘À¤!Ýdê±VPšÀxÀ¤`{3g¦*C$0‰.ÙÜFÊ LŠwª«ýmL=¢¯K=`Òì{¶ŸZ™Î4VG^žrOŠOað–çâá0꾦¹M†°OL"€ÃžrŸÕ0r4O†À0%0-L´.PIà-+LT„éx~8?kSðŽç"Œ–»G›‚÷+˘(CŒr«S0S†”a¢U®ó&ý¹ÑÏ/€i‹yXøÄZÌa:S†ÑŸÔžC¬RÍiËïƒE8b¹ŠÁ»¸å4±¼Â›¸å4±¼‹ÂUÜrŽXÞGámÜr^íV ­qHà]l·ÊÁ¤–ŬWYÆ9(€Ãx~ôÎã­ûˆˆ÷„Ê LK†ª~˜í5ÚÃè„Ê LôÏÍP7ÖÅe'T†H`¬²,3 ø¼ªR€C (¿Ñ£2D‡µ.Û;ø„Ê ¼j¢5ý\Åšèå`b¹ñ¼çñžö¬=_1ÍGÓ|©fÒ¯è@B͉&QÁßÒ5ÍSˆ[E à•åÎÝ¢ð!f9“üîY×zœ‡)þ˜ß]†¹^TOŸqøÑ‹faª½ìôÕÌõÝý©Dá3Ó^á°"ùå«Ö­žh;À¬6‹*SO׿yÔ±¾¥'ÔœH`rÊu?[&†ª¨Æv ˜ørûœc5'˜ôçÖ¯Nm7±Ê¥'Þ–¨ ¿èœ} æ-ÃD_7u6í²@͉&g~?úÓWÔœH`²Šþm/­Á*ÞÆVј4zнÓuB@xB͉ŽÌÁ&R¥ùtLÌÁ4L”{ýð+y¯ýˆl@G–­S†c–71¸JXNÂä$Ó©¤ûjN$0±ì^zd³–À£ÀDÁî––¨jIΊ}ŒÑ à0»_~û]B8qB5‹¦1 —¹ü¨œÂG*Âa‡ºuMMÔÀôž2ß´íUß¹Ø@â÷Á"Ö §gÅåKF5‹†Hz÷Ó¯/Ö¸u‘ŸªY$pµûÙt©>'T³H`öÌÖA!o×Ïœ‡I^[§Çtˆu28|Ái^²rÇ_•mW‹9êd$09É 6ãºGŒ&§ÜÖ¼U›(ìyb:L22–db›èzybµY0õ™_¿”nü©ØDŽ—¨“‘ÀDéÔ~šþW§ôÈGAŒ¦MôÚæÓ|ýºO¯á k¢W„×–iÍWQË8ÌîV箥¨“‘ÀÁ³]ýöPP–À˜ƒ €ÃMÓ¿3«ñÇ5ÕF¶6T³H`OÑ«`,žR„ÃüêIMjZ¡šE“X[åæGc‡hÏĪY$0É©i2ÇøóË©)ÃäŒdëVÍfT:òϨf‘ÀË—(\Å-§aÒ¹ÿL‹=Ψf‘À‘g®£±‹?s&gþ[ö£`î)c×ä`ô^ `ÚøoÒKíÞè´:£šEŸÌ«Ï=ž0×™¿ÀùKàsDgž…i¦í¤/:|9£šE‡u#+™;£šE-„?Ç[{SjL"bn’iægT³H`²úãåÐùÕü)C}F5‹¦³M:(pF5‹ÞžE‘ÞëÄaûŒj ÎuCN’qf̓0½Ñ«>YìîŒj –›úž„ÏÜr ËW3M&š°pF5‹¦ï‹ˆ3xÃÞs&ÑÒÑø»ÇWb ¡šE“ÌD[›äÕãŒj êöX›Û€PÍ"I|ÐÕƒ?^~©˜«óÌÕ,e8¬·\gÃ3ªY$0Ô˜Ù¨ÚŽÑÕ,˜Ôt ;\ŒŠ2Næºo^öoå¾ü…©[¿:̘ÀÄÛãOð‹Û)z•>£šE‡=¥k\}7‰âgT³H`œ3%éΨf‘À¤ÂÕª#À[¬pU†ƒe‡q `Ò·ž†oå’ºÖnýQPÕ)€iͽº3ð±æ5÷Šp°üb ƒaJ`b¹n-ß5 ŒMÕp°üÌ?ÌA L,gÕ,˜¬ÏµÒ¶Ñ)U˜TöÈ.¹;Vs¯ ‡µÎ˜¯¡oT\ŒwF5‹ëF;8¿–Ý%V„íŒj LÞ³n‡›T¼J`¶–aR;ësl“NÔ3S³`R°ŸmoZ7Å«ÏLÍ"€Ã>øe*ÿ¯Ô Õ,˜¶ÓF»FÿlCP‘À¬™lŽX^Šô­àýGÜr†j«m—\QÍ"I%Þþ/— ¾œQÍ"IvÃh›dûyϲÊp8\¦L¿ã3ªY$0Xæ•à)¼ç–K0M´êÙ]UxŸQÍ"©7þýI|Äá#óÆá°"½¿/5©ªY$0mª>*ݶ)˜7U/ÂáÖ¦ý¼êõ-qTC5‹spvŠŸ[)ŒsPËVªK¥™ŸQÍ"i]5Z»cMgoY]µ"LZë¶¶Q+FkÏ à°[Ù§ÇU?vñÇ€9(‰öòáîé#1S³`Òo©ŸT£‡3ªY$0ñlÎöuòsc3YÌ-'ÒEϨf‘À¨%VSÊÕy\+« 0³ìoyC,ì~>®•Õ˜z¶Í´$÷Ô~ ¬‡(ªY$pXEýG§]¨f‘ÀäÞuü¢šE‡9X×V»;8 ŒsPSË“¹¥º?ŸQÍ"©eÝ4þšà.Ãð¹þ(Gf¹CŽØÏ6ýQNW«9÷ë *égÆÞ ýsøÔ˜DaìP¦ý˜«›äcX/lÒsf W–u—…¡NîÕ±Þ Sg{ÝR™9‡É}ðår–±nü}XŠ‚kHRa0ñlë‰kŒÚžÑŽæÖ0˜øE—R§^«Tãò¢‰+Òüeûë´\­¿`…ñ™ÓŸ›WªÉŽ:V©f®×ôR€ÚžoËîš´Œ•x¿Æ‰5 x¿~æ<f÷0Ì«ÐQã*€ù3«h‹¹åUÁ$”V¨í™LÛŽºþL:ìÝŸV¨íÑ—á1g>÷5'ýcô·ÿ¨T ú@m&³ÛCoS'~ j{Ëæ=êÞ١߬-c/¿!#Môp•´\­-Wümü·kx›´œ€ã–wkx—´œ€‰ro=Ž( sð=Ù‹K Ôö¸zÒ—KkR_}¹8X¾ëfx%ÂgF_®&ŠßKgç4|BÅo_ÁóÜ­PÛ#É©`éðP¥¾ Óöàpú.“_¼ôË!0j\pXŸ[?æ.^ ŒñLO¹Xþ–Á[vÊ-Âd<“énSbˆ¢¶G“nŒnñí%ûˆ à0»U3fN¹¨í‘À!;ŽmæÚ 2_.ùs.‹ú«& `šûÿw§Óqf¹ÿE˜t`ïÒ®ûêµ=£©°»‡7«¨G&Z›;™£¶GƒeuI´êðð–[.Áá”»Œþô„Ú ÎuÍõÑ×ÉÏÚ ÖŒû ¦q«ì@:²¸U¦–U7ôn±>1ËE˜ìݶ3u8Ü4¯ùˆyÇøYvõü¯Åî©LwQ˜­hÔIà°š½K¦dx+‰ `¢™ó—é§u}|á@‘&]šæÍÇ^5N=Æ&ò1®#€©rbØõ‰-5F8¬_ØûÞ¨1’Àaoëzë>¿R[,jŒ$0Y뻪Ç$Œ¾!L=8/ý4èn!0f) `èãÒùË´¾‘W^uˆ)Á´©éí£ƒ˜X€Qc$©¾¡ a®‡¹¾¡‡QWß”{%? jŒ$0Xö‡óæf¢[,jŒ$0X¶ãd Y:wÜr MÆØ'—/ÔIàpr}L:s”A‘¦ÏüÊ=ß‹pxæ§~ÌþVø§¹n×Cô„{J{ÊÓô3Öæ Ï|WÆÊô5‘Ë5F8X®3á%cΉ&ñà¯Õé‹Â¨µÀá^úvj)T =zï¥x­[u:6­Pc$éÊßÚ7HÞ³•¿3ˬ kËy8¬ünêô-y‰e#Lr¶k?§’ÎÔI`Roå¥'£¦á1Ç.±¨1’Àd­›‡Æ¸OÕ·]äÕ¡ÆH“®cF-ÅYC5F˜Üx¯Ãr†HLØÓù•aZÍß™ôåêÄ«ùaZ¬nKËøÛº„·‡w¬:X_°Ñ*ÙàÊèwÀaEêi9‹‡aJ`âS¶¹#1jŒ$0Ñ‘¨K{M?VÀ$Þ=Æ£H‡Д…Q $‰?+£ÎOŸ²[jÁmÓ õ:8¬ü—÷*´Ja¬b,€Á²~¤á·\‚Á²K»‰Q¯#ÁrcÓð[.Á4«ó:L?n?­y­¨×‘À, .!”ñði—‡CŒ¤ªöJ÷½y«Èõ:˜d)Û›ö Ø5V¸§Ú°ÎR8ì)sÝ)Wo>vqæ þcùo3Þ¿&…• sPsËu;ÇámÄræ–ïÑöÞE,gáp2·½uʲA½Ž–ÿÖia®‡±³”&YC=o0j0ÑëtµNµô0ÖÀaïžnCko÷9ñQð>(€I¯;—{u¬+’Óé¶=ÆügLNæÃ’Ž·Ô* ÇãYT“xðR\t˜ƒõ:˜Þ­îfù(ñå õ:8œù›\àjƒz Æs=¼ê.µµmP¯#IMº~Ö\ƒC`V“® £å¤¤lƒz Lkîßôl>#W¼ êu$ðË?M_g?êu$p¤»)?KàDw·4Lê=ÆZM¦£ùxfUŒËpxÏó¸ªKaôÉ`Zr^U¢"0«‡U†I<¥þôWÇxÁ/ï1žR†Ãmâs®õ¥]ª!Œ.òQ°–&7úÆÒüwy]¢¯ŽÕ¤+ÃÔïFómYl¢ “N<ª]U4'0ÖÃÀAËÕ䢉ÔëH`ê%ö«ÌÍ\ªè«cµx0Í%^Zñ𱋹g7¨×‘ÀáÄøÕ™Fý=ŽñÁz LÞ†éIÑö†u–Àaݘrbˆ êu$0UÕ¼†é:Æ£^GS…woꔫsÃ:K `’!é®úíÒZ{¶,÷² ‡uC;µ„2Ëêu$0XžÌ-õQ¯#ñ™y™oVÏ\€IÇÐn]µšÀX“N‡=å©þJ26¨×‘ÀÔòõúN?ÆŽY.ÂÔòhk›ü({f¹SËý0§ãÀ,ajy5B)|d–‹pˆ™Éúó¥zÔÑà êu$0µÍîË%ãÌbmE8ÜÚ¾zÝÙzÛÄsÔÉH`¢ð®W5)̺œ–a81>\¢à—‡+~b,Á¤Ú];Îuú1¶Xí® “<Æ& ³<Æ2Lò¾òðó¾Ê0É9É9«7{–ÇX†Ãé«orÛ1êd$pxæáQ/  u%0Æ0ɽ¼° ÂxÀä¼Q«jsøH QÔÉH`ny“‚7ËY˜ÔzZ7ÞM´¨“‡±Ã¢ŽXV!ôGàmÜr+RÓ;õܦFÔÉHà0žÕeè «ŸE`ÌßÀá$“+Èèa˜ƒ˜Äa_KˆÄê6þ,± ‡{·v_ji‹ªºÇ{}-EŒ&k¶}ú؃: LëèÍÏ4Œ: LÔ,××·ßPßbÎÔÉH`f™á®Ö–ó0ZžÌØÚZÇc»²\€Ñ²ž&ýH¨“‘Àa­³ÓZ D`ŒÑ `¨Ð—Ù€Ž^¡¯OàJ50ÌA L¢³Mr)@Œ§Ünj2IÔÉH`ÒDÝf•hÊUmP'#Ãì¾Ó‹'é5Û8œo=f¡2ý¢,¯š xË-—à°Ã>›ÜQ u28(«û%ïE5M<: LÎüú¡Ó‰éd0éÓÕ™ ‹:7%*ô­œ8F͉–Ÿ—G:tƒš VQר ãY“*l¯:c}7Ö~Tæ]ßuÝ4YÇ#LƳ¹ÁP1 N¯,ßMsÏ¢ÊB5xNÊU¡ÊB‡±1»,Œ· Lr/çZu:"©Pe!Ã>X©éÑC[i€±*Ц–×üŠÃ;f¹ÕИu°ŠJ`ÒÉr¨W‹ØÉ² ËÎ5É [}°™e˜X¶C>¡å2Ló¯jLÿÀ3Ëc,´'ŠNËÝ+TYH`Ò÷╹ÔT¨²À¤w£©‡qpñª,$pP,è6s$®Pe!ó˫Š"€‰ÆuÉO9Ê*TYHàp~žK©ûÎE®ª,$p8# ‹tü‰ÝjŒÕÁ0©äòèÿþ[§?ª,$0ÛŸ Næ}j‹0ZNþêce¹‡Q7ÔŸ¯¥/qíB¹@£ÚPÿ±üoóÝLÿÝÌÿÛýwƒaJàè3Wx›zæLîVVu·äàg* ž¹¶£²ó#±0¢ÊB‡ôàÆªfêÒÏq@ùl&Â\ÅŠ&"|d–‹pxÑßg@\ (Œn5Lš κ5}>cSÁ2ó0š‰ÐŒ2 LZàvú­]¯çWmY‰¾2–þ§SK/ª!¾æ¢ÌBCRM=}sÞò¤šLFÝä/Žc÷”U(³À´Ô²a«GïY¶"Lý}n§G™…—«q6õý[ï¾QÿJ£"0ÌA Lä,ö©•Äf) e˜\ôÍø0%> Ê,0iä—Æôée˜Î”Œ7¤b2 N­ü¡*®1ªPf!I1Ë›õc4u:A™…ã¹sëð Ñ­&€ÃH¹“+Ê,$pú›ô¬ÕRã=ܨ ŒrCfŠ¿G7ü”_rÏõ e˜Jس?ðÄ$ìE8Ì”k7æ†(^0™ƒ‹OÈåÛV¯µ¶ÕžÍÁ2LVþk&³ºb2 Æó_æ[¬é¢1¿ e8<óü\*”õj2?×þ¬ e˜ìVÖɺ\“Y`šàûÜ(³Àdúyu“Áæ`†öA­Qó[MïØ«;òöA%˜Íg—ûX&S©S£Æôa{ϤNeÅUJ9QEd˜& ³úNÇô”Ê,$ðÊò…V‡$p³œƒÃm¢~Õ×ôÕe˜¼ç÷þãCVm"‘Œ e8b¹ŠÂû¸å4Nלr¢B™…&ŽþyHöDõ0žE0I§œs[+G"€Išß§ùJ{CPf!‰ NO¬Ó…¬!CÏÜÕ:ÙÑÃ(³Àh9ý™ÌBË_K£›ºð2™…&{Êc{ä2ýýsôGËÔÕe˜Z®‡~É<‰$”YH`jY·zJ ~”YH`j™÷yxË,ajÙ_“’#”YH`´l[ÒháýÊr¦m!—ÔY3‘ònf>™2Îü½Îm@(³ÀP .³äžxúY¦-gÕÃçcŒ!°‰&©\ýé¥ðq¬Ž^Å `"¾]ZqU¡4D“SÁE¹y2º‹?îƒ8|Á±¹Üºþ–XdX9B~…¹//¯‹~,G"II %uY ³’@e8ˆ{îfÖŒ¥0ÊîpÏÕç÷VÜ þôºªÐ_¡PFÇ-Wkø”´œ€©‡j) ¹¸•kUM…B îVÏE€·¬}–ÇŸêu1‰²E¡Œ¦Å,¿Ñ»ÇHÜ8f-pË0)cä;jIbéõ±g‹B LdC³®ï‡Õã#€ÀxÀaEš•óÇíD/‹-+G"€ÃÔ£¿8^†7­·E`œƒ˜´× >bÛ±2LJ\ça<‹ `b9wáÝ¢PFË«Î,F¡Œ&…!–*µß_;hŒ÷A"ºÿHñ h‹B LÒVÇŒÛp‹B V¤I½ÌÅ}¹ÙtëJ[ÊH`²n˜Ú:£Ü5¦[Ý¢PF_îjËK¶ àØŠtÛVëÏ}L¬HI˜”ÉhL_,QA`, $€!vÜ.·^;œlQ(#‰—Ø\L«úø¥f‹B ¼ÄM«ÓÇË-ÊààU»æ‚‰[ÊHà?–·êW8Ù÷²Æt±EfUޤ '¶¨“‘À¤`n -{Œ: ÆÆÒœä0ж0‰Õê>¸ÔvŒ: LÚÉFö6³v²e˜D—ŒJ÷‚Û²r$,ƒËÁ{n¹C“󸥶‰U9’"Lf·1,ƒ `, $€‰zš‡^µº»˜ÈÕu28¬Ïþr·O`”æ çºÉý˜Ìͺ™xRŒ: LÖº!ã6ÜîX½2LÔ,KÏ%…=úŒ>L<³]|NC4;k»ciØe8h{ênUž‚Â0%pðB\rÕ“‘ÀD¿Ñ|—þûñ×`ûõ‘u2xmùJ Ðøµœ×–i³SŸ¢–3ðÚrcõ-Ÿ£–3p¸M¸KFµEŒ&–§,Œeš0±Üfá -—abyÌÂè“ÀÔò”EŒ&–›KÆû &ÍfÓvÉÃ6êd$0)žeï‹Â'!ð‹g•á°Ö=–ãerùBŒ–ÛǧIֲܢNF“óó{™°~…içÈ"s`‰e8œrÛMnÉEŒ&‘š›õÛ[ês£NF?’_·jšjÉMÀ£ÀákÕÒw>ù0%0Ù'“n½em{pÐóÛQ­Zxæ †VÃv9pû—9P¡NF5øRö•µµ%0&ñ à‡Ýªû…‡Œj ΢ÃÔ6/;%Õ,˜4Éìo§éo±~¹[T³H`иÞ&=ÞÛèUÕ,÷¯fJ§èoÌÒú§ºÏó©Ó´=mþ)LÊ‘¨¡Õc¢kÂöÄJ¨”any—‚·ËY˜øÌ)ìÃÄ{unY›“FÕzÔµcí¾¶¨+ð0(u8¼g–‹pPÏÚi~èvÖ4·€À˜ô(€ƒe§;ÄüNiÖaÔH`¢Îêõ}idzèÐÖ×RÔHà°"=ŸU‹ô›V¨+Àaº.SW}‹º Œ÷îEâMWÞ¬îݘÄÚêÙÖº…B‹Æ’š˜ÏÁDE³í96³0·\¥à]Är¦ëóùããV#ðž­ÏE8ì)§oÉÔž-ê $p81Ömº fÊt±s²Ë–àÀáüÜÓ ®M¼¢Ùu˜ž7~>NÅÍ;ÔH`¢XˆÜñŒû &sÐ}þ¤“S&Ù,ÃbËÛbÛ^šZa„±í¥&…/ëeõZ„‘ h‡º L56÷Qب “™b‡t­‡ê $0ͦ\®K&žˆºû`çç2LüünqƒÏC=DŽñ;¦+À4[ç»\4øgŒº L£KK6¥G²¹˜·ž-¤ùyŸYw¨+À86ÔÔYZA›ÀÛÕØ(ÀAdÌ×ЧÜ,;ÔH`-mü@R˜HE`l/€Ã©›3޲ê $0ÍÖggXÍ |ä÷”Lt.û¹™®  Ç´®Z ®v¨+À¤!Pû;“‘œŒº þØMF“z_N™.%oØ£NF‡Q÷5ëö©í| Rlc–ŸŽX~º.ã–ÓpÄòø·œ†I IíÒBÍ=êd$091æ¿{ÔÉHàðÌî¦N¤#íQ'#ñ6ÁjS¸ZÝ& 0m@ØØÞ“4Jà-k@X„ÃØ¨—Æ¥—™zn>Ö?ãƒ2ôOõŠ7¤Ûï÷‘Œæ,Ö [AP}Gî5ÆØ„^YŽ—ÜߣNF“¿­éü¤²ßõÖ¯î„5~Ë0ÑoäñìQ'#Ižæeâ1£NF“HÓö]׉Mu28øÌMk/Cú1°J†ãy^Ò…š×@»/}2˜èÕöããc©ëT±fgÑaj’Ù ûÃþŸÂdˆ:5Ö¯Ô>x`MšÊpxumNÿ¼Gé‹&NTÝÍSªQú¥/Ë×/‹´³±õ¥/8|n·nPF`”¾HàðžMžcÈO“Æ%Ù‚Ò LQn6n)HbÝ}5øQú"IK”¡þôu!Œ!?¾`{Ìþ@lV(€ÃÛ¨—¦,¹F”¾Hà˜å*–“pØ»‡Î ŒnníðgE'0ʰð:LU>EÃÁŠE7iÏÉùÌ‹E—`rõpó #m> ôEñ’«G^[šÀ¬iof–ÙjNàjm9ó}ß ¿bð6R / ‡uÃÕª®SºÜJ_$0Xý 9õQöÜr †¦cé~@‡¾a*MìM=Ûx¿¶Ã+"Q†ir–≉>±ä¬"LÒr— .å¤ÔU;°B.˜$°ON+æ60+ä"€ƒÇ¿´»_½Ÿ¥/8œ Fíƒ{ŒéH8¼ç®Ÿ—a˜¹ªç &ãÙ¿¼Áïò¶d­Pú"ƒôÅNæ[Ÿø((}À´0¾{Ù¹¾+Ó­¯¥‡ /Œ_„ÃìÖ1 ãÀô,:LvþRK÷nýQøY´‡ýô¨Mrk; ôE‡™2ºé»§šYú‰­¥/˜´lSzÔStð£ôESaÛdkéK®˜°­‡·Ñ5/ñ¥/˜Üa­ÎÁØœBoÏ«ÿl™³ŒÀ{ôö”á ¸ºüÕœ6‡ÔàG鋦nð»¹3ÙøG927x†¶ž¹Wwâm=K0 ­ÎzÒÉJ_$0³ Ñ o?Ö–ó0³ÜØÄ’‹Ò î°Ss[NTsF¿¨& ìß]ggÓ’FFÆFi8¬ÏŸji 9OþtR¯tŒV"F‡9¨ëÏËcêãY~”¾H`âoŸ™Å¥/8¼ç®VŽp£üL³B.ºÿzÝÍdÖ¯î´.ä’‡Ã*Úñò)cA3žYÛ‹r/ÞöÀJÄàpÓlZ•®t@é‹&¾\Í !Œ…=pXù—"pºKŒ(}‘Àô™Ÿn¸ÎÊŽoµ ùPú"¹¨fAë®YÃûˆ¨& “lͪý …ñ,*€ÉLéëtvð¥/˜Û\?ÌöúES_|Ba[·¶ÑÙ‘‡æŒò3Ä“uók¸=ú˜.÷€Ò ,_lï··D¸á€Ò Œ»Õ¨çû¨{³êÉu@鋯8lz1Gé‹&^ˆÉ´?ž}Mï6fa÷2LRÕní#™óx@é‹i_ºÏ‰Qú"¡Pmcÿ,õ=r©Aé‹Ë«ë#OÜr Ë?&˜;ìWÅuKpXùkôÝ0¥/8ˆ¥ÛU@€aJ`Ú8{‘#Õ Ÿ%0oœ]„¹å9o#–³p8‹ê%QGu?Õ-R3ä€Ò ±ÜGá}Ür«è{6½³‰Ðêu2˜€ÒS§êEŠ Öõ7¨“‘ÀQËu>¥,§`R¼Qg:ÏP'#ƒå¥ªtß>VeîÀJÄ`â |µöMj?3˜•J+ÃÁò=—Ÿr@Œ¦>F7/£]¬ÆÂu28ŒçWßg> êd$0¾0sJpu@Œ&7úÎ-:ÔŒ÷AVþ¥Êܼ”â݄ꗆ9(#–«(|Š[NÑó3©Bàsüüœ†¡œ¬Óã{ˆ_ñX‰L´=ý_nè.‰‚: LÒ¾šÖ¯3—¥”ѺÓýÕ,˜=³{¦c·~æ<Ì,×m Þ¯-çaþžo)øyÏY8ŒŸªµLþLa,ä"€Ã37ª¾}··Š$,ä"€¡XGûÕ¿S?ðÌ‹u”`*âíûŽõ‹ ð™EÒË0IÜû¾0¡‡À,q¯ “$ Ðvþžîâ0*Êp¯É±úƒã¹N“´¯qâQJ ï1í« Ó#×/~÷ ð)ÂáÌ¿Ô(ë»QQõ1±®3ÅÑìsLÔê< æD‡Ûñ·Çil®nûµÓ 5'8œ ~®›ªøˆš LbÇNM5mï‹0úù0X~_SGµ#jN$0X^•â%ð–[.Áø6L $)¼[½Lšèå.éÇÖD¯ Ó½»³Ó´t[éLs"€I{í¾:)fEQs"IÔ£ÿÒ½J,¹GÔœHà𞣙’ý4Ls"€IQÁ!#}9¢æDƒåtý#jN$pØ­†:h>¢æD“òÈËîsI\Ò¨9‘ÀÌrÓ¥àÝÚr^)÷âÙÁGÔœH`âËžZÙqñðÕ_̨9‘À¤ôß¿ÚzÆÂÁÇ +ýW†£–«õ„ešLò&ütŪ—ãÀA«ö©§´³úˆš LV~=ÍjiFßnu©9Vl,ÃDÛ3,Ý)Ÿ&šrD͉&ʽ¹¾7ÃMEEbGÔœHà Uæ1÷ê`J`Rneiz©Æy¬¢ÁÊ­”aR±ËT?;¢æDc[¢Å5Dõx^·%*ÀaÔýl¦Üc Ÿ_“¬(Û­ö £QO`ý]Ï|9ºFà-kÇP†ÃMók2jé,­ûHrÖ5'8ø‘ö¹zæGÔœH`âU»- Þõ|NX¹nµSËá¥'{ukÀT¥lª.!É8nyP&{wó²/‰ãD‹@`l¢'€Ã{žFu5¦Y$0±ˆ±6ÞFÓ*ÿ—j°NÝ^ëÇÀ’G8ÌÁ^Ͷ£'m„q `ŒM¤—\ÔœH`R¶÷’ü¨9‘ÀÔr•Y¾˜æD‡õù1½s0æ `’ù⯟„3䈚 <'ÓÅ:.2"0Æ»pX7Fÿÿšk$æ ¦ÿÆqh•{Míº#ê5'xeÙÿ+dÞø³œƒW–ëÞŶ¶Ý9f9Gžyš7ë¸ÿˆ?sŽZ޶Qs"I#x뾜®kãbÛ1jN$0)"¡Ü8¤’î¨9‘ÀDÏ?´­¿óÆûâQs"ITzœüo¡c÷•.Ã4Ö6¶¦[êùÍv}AØóX[³;Ûôˆš Ìß³›õüp‘tмç,Ì-ßânð#jN$0Ñ^^Öù˜ö² S5øÐ)AVÃ>X.^f–ç6^ÿùÈÊ­`2Ýç<Œªéc!’ãÍÁ2,ëY+Û»Ç ùY[" Åüõ£yŒ‰¸çÅüK0/¦äâõ‘ލ9‘ÀaïÖͺ—±ôŸ&–ëܵ5'˜¬uëÌ Ÿq­+Ã4oº'$Gž‹W„©e‡®M ެMm+Òc²—jN$pØa/ú³~Œ›ÔD¿¨æ–«¼‹XÎÂÄ÷5æ¶ ÔœHàð̶¹-ý™7ñ ‹š ¼²œpÏ¢æD_ÁËôþ.íÏòñ„šL¥Õj‘’¤> –À`9@͉>ÆûàLÛ¦\÷¨9‘ÀaEò3ö«Ñ_S4½îˆµY$p˜Ý֙̄E5‹oãõRI%YQÍ"É3תOVµ=¢šEƒå¡¯§1ñêÜr žm[×C;$ Æ&p¸M_fU׆ÀxÀ$´±éÄê#ªY$pxímœ†w¢ûóÕ,˜´\.wj27RÍ…À¨ûÀá=ïÕRî^·4kÀ0%0‰ˆYjí(IÌrñÊ0ÉÐ.åÌæÄ‘Õ,˜4ÑS³©ï©!zfMôÊpXëܨ¸—…ÂIÀÁ«Ö™¥ïct÷!ö¹a¦Hàðýñ+D« ~D5‹&ïùWP >øO¨f‘Àá™o¹ö Õ,˜žEí¬—2Mc¤Ï Õ,ÿ‚ý_'aZ¢|ú E$oY‰ò"nmÏI×%†è Õ,8ìƒþ†÷òÃÔ%« `¢¡½Mmm'T³H`jù»@lj ™å"š©vé´š|uØ?µÃ0®ŠHœPs"‰6¾Ë¤™ŸPs"IÔ£ýdÎ,€Y“2Œ–«$Ì뜔a´¼Mە化wi¸ZY.À¤™u÷& cL|2¹Z÷'ÔœH`°¬¸.À{n¹“óÒ}=?¡æD“6.ck_æ’‚ÑÇ(€ÃؘõtI@O¬Î‰–î°¨9‘ÀáT°UK 4õêX‹L-OTÅÅá ³\„©å»~}¦^jN$pðö4ë 1†9(Ã}p¬ÇEÛ¸â¡æD£e^ÍŸÀû•åL|ŒÝ8ª»i©ƒÀÌÇX†™åß.­Ÿ«­ 5'˜TšÕ¥­SÇÔœHàpb|çŠùŸ˜æDCcÖzèÝÐFñ¨9‘ÀáFo.¦s©”ÀjN$puFON}$‚\'ÔœH`Ò–hé·”*úzB͉&ÞËëÐ ÏÔ"ƒš LôÏ9IÆiÏôÏe˜t²pí“—GÔœH`ªf©ç6é²`uNp8Ô}ö”ÀÄǸ¨è;Ó ¤z Qs"€‰~C·£nÔs°µÙ¬ÔœHà¸åj o’–0©*pûîd>Ô1÷ 5'˜ÖÒSú¨vെŠpø‚nž†Î4KÕö~}]B͉&q«Y=ÇTiÖ«s"€Ãºñò§íÙ$ ôPs"iáW[ Úž<‚P„Éq4ã/!=é«F`Ô? `ApmºSçéÀ"e˜è‘ü¥&íøE͉&ë³Uî»|ãØ®‹HœPs"©6Þ¾Ó‡@ÔœHàð6Þ¿¾ˆYê!®T†Hà¸åõ"ƒÊ LºP95?úPÌŒÁè9À¤ªíÃÐÊ>bUÛ2V$=ª¡2DO`mú¥Ø°Šö•>¡2DÓ:'zt©Î³'T†H`’7árÛ1*C$0±œu, 2DËÙ#«s"€Ã™¿ÕîÞ¹D*C$0©5^Ûá•ü(XHÿ†ýýÀ´©ïI`Tg `rk›åmšøáÄnme˜¬µkÚárùŠÃ¬{]&Úø¡Ë}î3jãË0<Ö-'•!˜ôOéÍmº¾•iCpc÷:ÌÛˆ'Ê­œP"I5ó»?ÅIR>¡2D‡QwÑõã»&蜰‚ŠëÆ"sçõ°Œs˜Ü€†_aÛAm"•ñ0ë­£¦™Ö×%ðqÝ['Ó ­]6MU_#Œ3Ë(Ãád¾4y¸™.ž.zB͉&=¹lýéXœõ|F͉&¹x­ó£³î]Æîu˜Æèµmb1?ðÎYE˜Tɰs­]¢Pí™UPÀáü\=2TϨ9‘ÀÿȲó'ñßô6O£ŸEÓKr·™ÎÉ7}à=«K0uÂuf¾S—êÂOÐg”¨H`ÒÞmÈœFÏ(Q‘Àáàóè?—RíðˆxFÏ(Q‘ÀáàÓ°Ü3„Q¢"WmNSð&Öæ4‡å|\”p©»æ%*8<ó0,Å7 Á›Â(À¤Èbgø!‰Â;,²X†ÃütþÝ¥òVÏ(Q‘Àá=·OÛÿHuÉ8£DE3Ë©¾jg”¨H`"X¼=õÝ/¥£^UŽ?£DE‡£ëpÌ”HxtÀh¹Ñ©å %*ÜÕuÓ鸞å\m¸»º3Ëó”‚«µå<¼’=¾æ1R?øÌ ®`R$ÆÔÖõ´±ó×%*˜4̹ØÖ¨ëòoͪrü%*˜Ê—~ñTJà#“/ar1mü)©÷GÆÑÅ^й0 ú½•ß8±¸Y2Ì-ûsÿ;öQP¢"ÉA~ªý÷HÔÔAàýÚr&é=Co®+áÅm˜ì°þ ÒGbÖHàð6ì8êdžØ…5øå¿õô9<Ó0ÌA LNŒ®NkFÏ(¬‘À¤Ð¼›{Õ%²mÏ(¬‘ÀÁOü4ý×~ LbÀ«Oë"™«g&¬À1ËU Þ%,'a2ž§L »3 k$0‘Ùw—ÞŽQX#Itâ2´ImîùÌÒË0±¬[p„0˜Å=Ê0±¼Èœ–x°z¬õñgÖHà°n\j›ü(ÛÖHàØ3׫·,I1ĶS©ÅÜÃ¥À±g^×4ç–%p8×Ý2 <ŒéñÛVM‰*WÞ­ÚVàà½4½}¸6ÞÅÃ0»%pX7ìºA…ñ¦)€CÊè0?\7Çó= ³[‡smz{»ÏP7ŠÀ¨ÁÀÐr²Ÿ½‡Ï¼åd &Å×Q.£g´ýÍ_%â%ìÃáÌ?=Ül)ÓÆBó8X~¹Æ¥êüz“px¶Õ³ûüréºê9áaL¼Àá$3 Ÿfú-£ŒÞL¥«Ö_•æÄÝpéj–¿³?h§€±ñ˜¦¥!ûùËŽ"𑕆,¤ijþñ«6Þ:ÌåaŒj `*¦Sm~t·µÈÈÃl‡-Ã$þÍ-æ¨Á‘Àá,z›lÒ=ëa”® `²§ø÷–Þ4™G%ãÍÖ~4‡±Ùƒ¦ -?œKT¨ôðŽ%´áðž'3j5ékâbqO _P--_ú+2PÝ#ÿXþ?¬¹üóüo·nþñ¿¯?ª{$pÔòùo« ‹ê µüŸ#qNYNÁì ÖÚÅF¦îÀD1:Ö™ ‹ê LUT¯ah°û%ÙY´ “♾/fÅ/Êpˆâ¹nXJTjctì10ò(€‰ÇÕ=ÕmÉOŒ\·{£/Ááä—®V5nŒNXT÷H`Ú Ùé>ÑÚÃGÖ ¹“Æ ý¬?—J ñÇÀ}P“’…7ýŸMâx¹e% Ë0I„ëô<(7.ÍKÝj)@u&‰÷K¥“ÚD»gy˜%Þ—ááõÛ|oLj›@u&'Æ17­PÝ#銔…wlE*«„CFxK8ÌÁô ò €ì á0ÛÕ¡`œƒ8¬¢µGMÆœ8œdÜ+wDŽ7 ìY­çFŽ&Y­~)|Ʋ¡˜¤«ÕÊÿ³*ñêP#èsC§ø'06\ÀPœ¨î¯ßu8"‹ kz$€IŠÝ"@H$Cx‹_à°ò7­Ê\XÆÆ ïF7êÚ’Þ/Fœ^â%Úw1ºom¨À‘ÀAM¼8ÊRŽ_ÔÀ$ú?›)=,ú_†I)½‡ÿÃ&µ¡G“&åºî—žÇ´&/1•QSËÍmMÞ2ËE8ìV¼~ƒ±áŠ&Å=¿?Ëv!cà )£ó¬ë»kºÈàGŽ&ççûø×˜\̬ù_W·½øËÒœXrQ#©åÜá8˜´~»—e2ý£GÏIó}†Mq `´<ô–¦ÒS¸ZY.Àa­3uÊ<Œ‘GüÇòû2¼s0ÌA nšÓžU;ÔšüDÔÀÌr=ôW{‹,2¨À‘ÀëgVÎE‚\¨À‘Àü™¯·|Š­XinšíFµÏäò…  –'ýJmš¨À‘À`y6-êü¼å–K0ŒîêÚ%–\TàH`r²÷P¨s ãYT‡{·?^6—ÏeÑ5ýz ¡G“²tçU®Ó‰„¥mpXër•Œ< sP‡÷<*ªHâaŒ `2]îòxfs° ÿ±¼©——H¨À‘À¤Ûh›î§ZÊhEF¨“‘À+Ë“¹Å6MÔÉHàðu¯“‰!Æ™"€¡ý¹Óð·?/ÁdÝx¨‹­ýþC`ø9T®S¼5¥±õ¥çž{F|éaôH à°kŽKÛ£÷wôoP¡"©çw|6^MÜÃæù-ÂäîáZý4¨V#0æ `ÒTsê‡qÃØvOsˤm»ˆåÙv±ûÒ*µžšÕ©‘À˜$€¹eU’ |ˆXÎÂ$ÃÙ>UêÄÃXàP½Îð}Æ5‰!Š­/pX¿ÌäVÀ‘¸ `Zœ8ÝÍr»Ù°Öe8h@—ö›÷ÔÁnƒ  *¸/w{`;% cLîxÊÿ»rQ™Å*8X®»•â—¨Àá.]ÏfVÝRð$âdÜ BE3Ë,âMàÃÚrf–ÿ¶“>®-çá0S>W©KcT@ouõñññi&˜X†9(ÑòË\ÀÏ`T¨HààY˜'eºG«cõÿ<Œm÷pˆrE ìRfЦï—Ï'Þ±‚÷E8샛­Ò}r‘a:f÷üV—ï6ÉÑÕÏ—ÉÃèÕrN–V¶‰?ƙ眔`R¸z|Véå Õ˜>óe>;=}Æ>÷–ç×aR¸ZMÖ(Óßü†¿šV¨öÀ¤6‘ujÌØÙІ©=0)~™ oX»!LÎfZÞ]Ü1ºAµ‡g¤éqÉlm¨öÀáö8÷³Ú$',k7$€Ñr•†O+˘Vnß^âèÖ†j LW¶µš ðŽ)®ÊpØSº¡1]ò¢ÚC‡÷ÜÔêuWfˆ7¨öÀá”kôÓš”+pƒj ü†zÒýlÚVÇæ &gQ«Ú+K¹"0«õP†yK™*"-e²pø‚W;d6zT{H`Ò˜K-µ1À¸ à•åÄŠ©=0µ¬3ž#À¨öÀ+Ë.^Ú ÚC‡8¥±³Õý´Ô’ŒãQí!Ã<©_•é>A`œƒ˜Þ­¦Î&™=¿[áàÍ­Í-1øQí!i ‚ǤÓq`5Šp8lW)óK‹|Tÿ `â­~fœæ›=k»W†I–ÅÓÜ´¿Õ$>7ÎAÖg;*=Ž© ‹j nmC½iÓ[k7$€Ã{¾¶]æÕ¡ÚCS¡rzLmm¨öÀaÖ¯Õ˜dY,-±ÚTXÕ˜¨¥‡›á#‰À80©t:Žc“(€Ã{~õ»Ï‰Iêd$0±Ü¹[ÒU¡NF“Q7\t«ê&zy¬P'#‰ŸnÜœr:U¨“‘À4/×ÞR…/=¼ay¹E8Ü­²‰ÓÉà°ÖÝ­ûäÕŒÝÁ0i1ê–ÝWÆ9(€ÉÛйi…: L›Äêi)Þ ¢Ûêd$pÌò¸vÝW¨“‘ÀË:ú§¸å4±ü°1ø·œ†I=;tÃlãýŠUEÀ¤u¼¦dù†Šõ<ÀÁòRú¿I.¬ç‘&·ã¥=eJ[±žG8x{ãô5ý±2‘&kÔÕ$ck]{ÊsVþÃÌ `"0VEÀ`Û}#|ä–K0QõàT T¬*Š&=$r u2˜ÔήsÛêd$0ƒ®Ö}U{>‹pø‚w“û¨“‘À¤:˜Î}î=«V†Á²ÿ‘©Á: LbšïÃOf©P'#©Wmya˜W­sˉ"8êd$p8??MF”^¡NF“ÚR}ÝŒUò£`OLÎü‹„pÖÓÍÄ^«Š"€I§‡ÞÝu3¼âŸu2˜xN²K«Š"€‰²zh‡IÙNG¯Ò¨“‘ÀdÛäÖvXå•`rÊõSÍÈü"0f7`RëWµ‚ÄàgUQpu—¹Š54÷0öcÀDÏÕ­N ~ÔÉH`n">G,gaè„Q'#±F¹' èW¼*J^5·„tOÇ>…aJà°§¼»Ü„e:Lªu4¶Þ ™_…: LêBæÒŸ+ÔÉH`Ó|ÛEÇkkH¨“‘ÀaÝxÝVqf ã}P‡Ú%Ÿu—.RV¡NF‡g^4ÒIyC…: Lú^¬ëªu2îƒãœ|ŒÓê>X‚ÃYTÏÕõ‘ÀxÀ4´hÇ­[ôÁëÅ|Õ—¨‡>Ô³n?ÓvÔÉHàpÊ]30æ. àp*àmà sPÿódêù‰'yã}PƒÒ)³È NFÓÎu>³ÎE˜äþüRJa¦“Àd}¾«´ »BŒ¦õ f5¨IwÑ‚: üü7u]ú1`J`jùfÇ4¼c–‹pÏ_½Ûaø|ŒÑsPí¥½(—ùÜ0%pø‚_³iUªJ…: Þ†qŸ«Œ2clB“ýÔ×™ÏZ5Lô¢N]µ›áòÞ¢æD“ª/K.’õwÞº]K@·¨9‘ÀˤOwqËi˜èÍ<u£eÇ·¨9‘À¤[¡û™lpåa<× àÈÛ§µpb‹š ¼Ä½ËŸÝ¢æDƒeÝ<v‹š LW$­t]C-—£æD“™âŸcY ¦˜3d‹š L£þ²”ºJo7¬òr·¶u°`˜ƒ˜X¾.ypÝ¢æD“úȶÉ=æÃ àðž—*[5K $0ÆÚ0¹Mh›–4oQs"‰7~ZíÆF͉&Ñ¥¥+xJ»E͉+Òõjk³ÔÆ[j˜¬ÔœHàðž{çæ)9Ps"iŒþ‘H¨…ÀAÁ~Ñ™$¸-j!$p8™ßÆ9}pÝ¢BÓºjYºf}ËTÖåÌêªa8oÔºýÝ`ëë Þ~ðóF Ë‹,Jßlh­Fà ·\‚Ѳ?òÄ @m·«3R &'ÆZñ¾KF=’æ7ÍD+¸-j!$ðÊ2Ôb'ð>f9¯,/rì|ˆYÎÁ+˵žÛØçŽÝ»³pØSoH2 ¿eZŒ–Û4|^Y.Àh9½°š!-ßÓðfe¹‡è’¹ÌÖ¤a˜ƒ˜VªÛ¥oâD<9Þ²Š@E8¬üý¼ò‚S+\ `’)pm¦¯ã¡Õ-j!$0ÑÉônœú9ž4´E-„¦yš¦·o5Qyžf¦U_oƒ?A¨V»µë~Ë´˜ÔDõ[ÿ»ƒ¤[ì&j&ùV}ó´z~Æ? j!$puódÍ3%}Ù¢B“³èúVJaÔ# àð6ô<Ú1ýèûÀDÏoç¿’A-j!$ð*ºÔЖÞÇ¢K98Ü­Æ_m@ã͍…À$ž²ôÉõS!lQ !Ã*:º/7upê¡0ÆapXùoËR{¦ÚDµñ8Ô}æÂ:[ÔBH`jy]q’Àf¹‡“Ì_ÊfŽñ¨…ÀØ÷iÐ-ë#€Ã*:?M F-„&Q~öo.å A-„^=󨧹<Æ!öÌ9˜Vª©2 #FÒ%pˆÃê§ß4'tW¾ oã÷™‡\ðÆ/(€‰ç¤Ï´ßb$]?Ò¯Љiud}¶Ê0íÝèׯ”œr‹‘t Lj)ÛzS¢ô-FÒ%0©SÓÕ%aôöà`yQÝ=exoYLêl÷fx$#é8œ7ÙÙ=ü^kãºÅHº>7f‚‰[Œ¤K`ê“©[['àŽùdŠpèÁÖ¿ý¦Ùa\ÔÀá Ž“[éV ŒU@ØÙD]µ-FÒ—ÄÖiºxÛË-FÒ%p˜Ý—\sÊ-‹¤ `zÓ|]æ¤ëþÄee˜tX¬3Âã-FÒ%0‰¤?uŸvÝóHz3åjsƒ#é˜ÔÙþT³ÍÒ~³~uI—ÀQËUÞ¥,§`Œ[%CØÛU$½ÓºÄKO–°oøÀêar*üçRGIÀa¦˜©ö´mMÆÛ„& É.#}Ù².',§‹uì>>¸åL|­I7óÛaÅ ,¿õ¯D~*b"0TÆû´ZùÞo÷›ŒTpÔr)Ë)8œŸ—Ä=¨%‹0Œg üÇòÿãßþã?Éb¤;Œ¤K`¨Þ0LŸ­éc!ìݺzC ŽYŽÕvI—Àaï¶‹îó»úE F•9é]{i“…ãvI—Àa|æd~;Œ¤K`’71fÊaí0’.Ã{®m¯;óÛ#ɯ¥;Œ¤K`rêü °I$³ì0’.¡ÂUzÉÝa$]EYßé1óQ°šŸ&w«ë¬Kôw,’.€ƒŸÿZgR‰wI—À¤æžÎéw«æW†Ã{~¸Ë’Qo°Ãê 8ÌîyêrsPƒåtØ}‡Õ$pð¸ÞF—û(˜­#€IEÍOûä•Õ Ì*j–aksãÝLF¹þOº,ÖV„ƒïëU»Ü«CE™7ÍÚe‡(VoÀ$êÑX7jìK`V½AcÏ—6岨±.'8Ä&\Sg–/T,H`È>S®K4 Ø¡bA£éëäo·eªÎ2Lâƒ~ Êü@Ö² “QÇ{#Œþ Ì{ù5.#½ü²0©Çh'ݲ£+QQ&€ƒ‡jÊöÜ¡bA][ÞÚXXgÇ e˜FzSÏ¿»¬–/T,Hà•åx c‡Š fÊSõ}·¨uHå^£²Z=R¯[›r:íP± Ã~èsK.*$ðË[?_¯ú J ÔÀL5ÄŽòލ†òp°Ü×¹ÁŠ æà0?{ê1p `’ùâæabIÞ³l2LzEëÜQ  ˜x//ãâRö5ú¨XÀaOqõ#]xyǪ7à0SìªÀX½arÏÌÞ" szÎx‰w(BÀÔr¦»èE8L«íËöƒ»ÚøxF‚¦¥YÍmÒ‰* »=kàU†IƒÅ.£ûÚ¡Aƒe7#Ká ·\‚™åFýRž¬v+!H`°ìIxË-—`|Ï·I- h#'!Hà•åÚÒv½¢A‡‹Ø0}^Û!‘#¶C‚—ôÚÍ™E 2HàpÅ›ën©>ûÝðÏ/$0^ñ0Iø}Löòp©ˆIp8”9wR"0dÀh™×Ô$ðfe¹Ëúqs¿ßÝŸJ®†9(ã–«5¼MZNÀdlô³¿? ›ÀØDOS©€uzJÔRÞ¡ŒD‡Kú8v™Me$˜Ÿé27M”‘H`ÒÀëÑg&ì‘5ð*Ãá >&¹e Ϭ.殟vˆÜ&ÖÏ\‚‰ÓiZ'¥“ 0Y‘Ì|¦DU®J_$0 ­Ý›©µþjU¯ J_$p8}=Zÿ]RêÙJ_$pø‚­í~gÅb@(}‘Àav_œ?BŒÉÇ€uC‡÷lZ½*:A` `âºwWu¿¤ÖlE‡0å\Ïu2C‡Ò/˜…C8Ø©éÎÚQæ 'óy\j:%? 6zÀÄÍÒ>.“Mmô¬ˆ„ãù5åîÝLú"€ÃŠôlÝ<é¯hõàJ_$pحًJ_$0-áåÿÑ.õQPú"IQÁºÕ_fRtT˜,ÃË1µá¥/8¼Ñ/æfª¶Uü£`A3LŠü¸û¨]j)`E$pxõR¼30µŒaJLgw™Èã¥/˜”+ü®QV xƒå Ë0i!±ômÐmKeÊƤ{ÖgçI+å0ʰ04.Yüj]âîxã’LË®˜Þ³r…E˜7¨•ÿg‡Ôd®Ë0¨¸»â²mcóM ÞžI×KèKà÷ö”àpúš× ( sP‡¶s™ hr LÃÁKB3v¢"ð†…ƒ‹pû[cò°½g…/0 Ž×+‡+…1L)€ƒ{öáVk …±é˜FË‹Tylu¿RàìQ®#±qI­§x·‚=Êu$ð˧Jm6Êê1VÓir L¾àl¯~Z©ÎÝÖ[Ûå:8¬OO%½ñ{”ëÜtk[“NìQ®ón‡[Ìe±G¹Ž&%¶-ľbÅ Ê0)úê–¶îsü±G¹Ž¦Å”ߥýÞzÓD¹Ž&ž“nµzQ}¹8X¶. £/Wÿ†ž~>ìßq¥ÓžÀAÊõ;Wnüêçj²#8x/ƒß(¬Æø…9(#–ÉGàsÜrsðº¾Óå:8<óÐÎ6½n \G“FÃOÓ«©K\Q®#¹å&o#–³pHRžÚ&sŒG¹Ž¦i2­N/_¬ÙŠ&©j:Srr VÑ%Öiõ˾¢(בÀ¬tö¤›hÞÄå:8b9:­P®#ƒ_´ŸrW<”ëHàp~üškL“XQ®#ƒpB×íÒïÒÎC¤fõå:8¤×]—z…•/ sP?’™L“ìè´G¹Ž&bNgÛ(בÀ¤ü¬Â0S$0Ùaÿ¦ÌGÙã[†ÃØøüRó¤{_¾P#Ãúl&7ôºœúøX…ƒ÷¨À‘Àäž’ËOÙ³2 ˜x¨ægf›@Ž&ë†ý£‰m‚µDÀ$É¢VCo>M´·ûþÀ’,Ê0)ÞxY•ç§0k V†ƒ·GÏõÐ5æò¸Å?*p$0I·]æs3Ž£®3’¹=*p$°«gº|§°«ûcíÝC Πsݰö¨ª‘Àá.­i£ö5|b–‹pxw—›"⛌I阬õ¢:~NqGÒ‘•z,Ã$=ø¦§& £7D£esót®V– 0Ù5oÊﱤé2ÂØrO‡ˆQ§¯*Ùåtªšo¸fY ¦QÜ}äQ",wuÆBLe÷W{KõÙÚóâ,e˜¶ßЙMåÈ"se˜è¢ô¼m/©ãS¨`,êäh;ÄêèíQ¡"C‰«ë[/%FLïBøŠÀXâJ“‚&ç¾D…Š&·šÞ¼Õ Ó³¼Å[MÞ¥²[Rf±G…Š»f7NþÈ¡ÚÖE=’xmÙÅ?÷!j9‡/X·ix¤Â¨P‘À$¢ßÏ–ö2c0ªÄ04wÚ¦: ïQ¡"Éê©jçwä.Z¡o  |þÄ_¦2pö¨P‘ÀÜr¯ºG…Šgâ1× k  LöîÆj7êÚÄ_Fæpuw¿Ïë15D™BE‡Q÷R]7Üt—x T‰ àpÿßìrÇKT¨H`byŸ…12'€É-]/ºÜä=ã-½ “²¶þLÜhÓÑ–ÎàÃkÿ\†I[b¿¥™YÝHj ³ìe˜ù]n›/ëw zår= BESO™šêg" ဠ 7Þ¿ºwBt@…Ц%'jÝ)Ìa'0+õX†IBlkgæùLÀègÀô$S/›¦ÝÆ&ì*˜ŒgÓ7õÝúqZ‘‚:lLÚå6V¶ÑN…k£ŸE“¨í}XÕE 0*T$pø‚ö­s›Œ‰{¨P‘ÀÐÁŸäÇé;Ee5­P¡"I"½ö*,’Ia–H_†ÉÛ¸u«»±ä±†ö¬~×úYnT¨H`R¬s;, 'ç¡"‹ +(#€aïùõ˜ÀG¾w—àðý pYÌã—ôS¨à•å*Ÿc–s0i,­Æ´vü€  L-÷.o˜å"TéWÕNé!Š  Lb~v4‚« ‹  LRÇݬþb£Hk¿Q†I´mÍWúÕaÁ\öîgýëÐu”P¡"IFÙï–¯Q§ù*˜Œº¥k‚ßÛúX­‡k#€‰·º~Ž|"0¶½À¤ÄÕïÈ¿j.‘Ͻe…Ë0µÌÚ ÌÚ?—aÏuH¨P‘À$Þë×~زxC³»µ—î–º¤P¡"IôeÈ\j¨P‘ÀĿῈß9íìºØçf e˜¨ÿ|Lþ@Üp˜)þܳ(QQá×*8hšý=ì®Ó 栦ŠÇöwJͺâäaÇ‹á¨å*oR–SpXEï®Mom¨P‘À¤ØPc‡¿·[=ö BE}ÃÀ<¨ãYT“6®¹*ƦPÀ ¤wÓ3u-Å‚2x}ÓT·W >Foš8œ‘þÊ.Œ¨}‘Àa°ìe˜–?Ó½{u·.º˜£NF“ì,,]Ï`ÔÉH`Òb!»Ñ£NF‡WëÆÅ¯çiM`˜ƒ£xOýhi”„ÀÛU¯“BÛýï,^eÇz ³BÛe˜Œ¶'ýN Q¦“Àdïö3ª¦MãfUØÊpЭ.^,L>+@ `’?©æÖ¦œ!¨“‘Àänõš‡^5~!0+v_†I•¿¯}‡±£—¦“À¤£Sïã6µX;Æ2LW$Õé1Ñ¡ü€: Q<“¾J£NF“Fo7_“!?ÔÉH`Òç½n£G`l "€ÃɼïÆg•þØU“HM·œÕƇ‹IŒ¨“‘À1ËA JàSÂr&*¸\-ø«ä"€i‹…Ü u28ì)ú¦¿4‹Eõ¢rNZ¨ˆpÅsNJ0ÌÁoa=´‘ jN$0Ífñ?®ëhêË5'8¬¢/õKä߀Ps"I!×›©çvÔTÎE`Ï8èÇ^Ùú•ZrQs"Ãir~?¾aq?ð5'˜úkÓš)ÞVíøÁ}ŒE˜4 \çÔPÛl `Òzvø“{¼] Ñ#jN$pÔò.ïR–SpÔò>ïS–S0©˜£Ì3Ùóõˆš ¼²¬\| c–s0i¥Ü+ý+ÛÅ>7ÎALN2Ê6]Êsdš|þèpÓ³öAF͉&U_/¿…Ud;>nXuÝ2¼Ò¸*úÉ \Å4®98¬ü×yL‹¥¨9‘ÀôÞ=øÕ ‹w 8nXáø2LJÿó “ùûù(8pD—«j» èQs"¹eÿßãð1b9 “&uØ–À˜$€ÃIf9›ð¸;Qÿ,€ƒïëªÝ< j¹O¯…šGÔœH`©a‡)£Ÿ_Ëß¿NÛè±çˆš LòŸëû4ôMb1G͉'ÆÖþýR‡“#jN$0É"QK]</ qD͉&U~–†¬¤9Y£2ÖgÕ5ÌçÆêº˜X~ :c¼[‡Ûñ§_xs0ÔÀ¤žìÒ±„åî˜iN0­-•¹âQs"íM½ú>ýêPs"I¥­v^ªºøa5'˜Ìîe/f ŒñnN2¯Æf¶cÖÄH‡£SS—ì7yD͉«(^ÁV0vz0“[•×%ðéŸÂá"¦}}¿Ø©!Ýg ÓJ‰‘ÑÓ|1‰*G”‘Hàp„ørM—ôªQF"‰HlÎdSY_"L¿õÒyé»Ûcä,Š2 L®ÿî–Y7˜ŒD‡D§—Zò ãe$˜„HúÏ¥–KêÕ0DR†W–·6”‘H`Zê‘wkøÄJ=á0êìRÃø3 ãO“~íþ2ÁÛ¢˜õ%Àؽ¾~\âymG”‘H`’44þRuR'4QF"€iÂïü•L?¢ŒD‡Ë£íü02=Q%0ÀtvÿKäzoÇ5¼g³»SÂÐû9;ÆÏH(#‘ÀalL×܈2 Lį•‰Â˜V €ÃÁõí›ßÕnSü¢¤YGÙl:ÛŒ7Æ;¢ŒD‡÷ìôg—Ì8¢ŒDcS.¥q=¢ŒD‡cÏ ^úi’0ö©ÀáàÚÛïÄ5 µ6þˆ2 L܆“®ÍBÆ´ñG”‘H`*˜—ŽG‰%÷Àv«2LÊEµõÝÔŸM|ÉE±‡f‰!ÃÜF?Š=$0Ùûæk‰ÒèKìÕ¡ØC“.§Kô UËâˆb ž9«t:¢ØCËÍÝLõ£æ Qì!ÿXþÛæÚ¸Qì!I¡€±Kg Qì!ƒõYûùšÒQì!ƒtÜ^Œ2—äc`Ž_PÝ•Ó æ & ¿·ÞvÉã%Š=$p8#õÙ!ÊĘÈVëç`ëDu°#Š=$0-O¡æñ#ѹäˆb ܆¶S£IUó?2±‡–¯M¦wãÅ,/©¸ç–K0jΓ½Ýü¡Ø½"åÀ„šE88÷¬ÿqïäáŘŒ\Õ#Š=$pØa¿ÚÛ!v¼D±‡&¥lýy†O75‘ØŠ=$0i®ó[ºñ´ÍŸÂíÞ`s2LD5³Y%¨s8¬üõҺ䥧¨âˆEQ$0mæç2Î,Š"ÃYôëÒj—ÊÐ?¢@E“4™×Òÿ©÷"=²¶=8Ì”fÌþ@ `Òµ··¼,…±ð¥&FûpªùêIXšÀ80q)ßF—ôåžP "¡´túØsbm{pðœÜ›Ìv|BŠ£nèíϤ:ë„ ÞÆÏ%$•‹wbm{pXëêqqÁ%jàœP "‰¨ã5æÆà¸&³ûqëuz ±$¸2¨¨ú÷_8)PIÁÄ'3ÔM沜2Þs«éTå0 T$pxæ.wp=¡@ESùÙ ^C …2\1ùY&kݨlÒsÚ°veŸÙW·[=s&Ñ¥Þ=üOû¦w·Ê]:¡@EÓñÜúÁyŸçXN͉µíÀ¤éhØà##-ÃáÖ6-e¨Ôý_Q "I©?†Ú” î„ LR㳃*8ì°].§æ„ fw=fªŸŸP "Á²¿ˆ5»¤ŸP "Áò8´¶ŽV¸>¡@E“1¹*ó'¨H`Ú‚½{$/b§Š·`/ÂtEêÆôªbíëÊ0µlîé *-+óŽ_OÕye¹“F¼Sï¾Ü’1§o« À‰ T0ñªéqLfÚžP "ƒŸÿíb2|vBŠ3ÅŽ½â;=q `rú2õ¬' Ü#éxe9±˜³¢(˜¤oLŸ¦£Åë>`úF–?»Üˆ Ln.·M šE“sÝ[MIýó Õ,8¬¢­æÎúÿ‹QT³Hàà¿Ú©SînÇéáî[~D5‹+Ò½¶™MÕ,[†ð,1oW-C p8åö]îs£šE‡ÛñÒAB¹1®½<¡šEv®Ü Õ,˜´ûº¾Vž_ãÀTÒÜå>÷‰Iš‹0z¨z7N¦t³Ú€PÍ"è›;§.Ã0»¥ í F5‹ÆõÙcñàË Õ,˜ù1Êo›êW5ýõc _T˵N«:O¨f‘À¤”åôõi&?ã>(€‰Dß/kˆEà=JôË0”M˜ºäÁÕ,Ë#'ƒ'T³HàµeÕ k9åiŠZÎÀDéô̈jN¨f‘ÀT”»ˆ¡šEÓî®›á¥îÑã Õ,8¨Yìm)ãº4g Q¦fÀaåwþ£Ìu¢žù Õ,ßð£ÉÂhÙ1ÁƒC'ž=‡š[{»Õs,KiÓï±Íí±(~‘Àáòñ7¯#Ž0†ô0±<ÜÚô}e5˜ÔzÔ™“+«¡"€Ã‹žN/Îþ.îÜF]«î7Üà,À¨«‘Àa”>‡zI‡ÐÓcF?ªÏìï)é*'ÔÕH`Rfá6LMŸÚVPW#i©í·ƒ½aV\º “¦¡¿7:õ˜à €Ã€n¬Þ…q ààèÆzRß½$¯ZI&¡_p˜‡[­›Ôc`A?L‹‰9Gr8Ì‹‰áp>¹M™€é u5˜Äms½xO¨«‘ÀäöÑÌn“¼ª ®F‡»Ø4ö¹Ç€9(‰oáú«ã ]y ŒsP‡ÓÚ0^[àˆWx;¡®FÏ¡ý¹×ED¿'ÔÕH`¢¨ïv2˜GE`lø%€W–—3Ÿb–s0)¢Ò7Oµ¤eÄ*x•2Þs³,¸}è?€0êj$0Q×jìRâ½êj$pXùëZÙÎíh-ñêj$pø‚7«–>PøˆÀ¨/À$ÑO¯÷c³D¿2Œ–]—ÚŽY³!LËVÃá™ÃV¶ºƒeçîIøÈ-—`Z Á¦{ŸÎ¼áW&Þ¡gFpx:³„÷24„ÍücHΨ«‘À¤Í|çÒÁš3+ü"€©e]QW#üëÉ™9‘HrF]çç®·Kz[\@{F]& ‹T&•”qF]¦;ìð]´nA>°¶“¶ÃíauB~þ`…mË0i‚3NK3žNÇúaQW#‰ÂaºþžVõùèGÀ¤¸t?™o¯|t ±Â/˜Zö_d~Ä«—œQW#IFR7ï@.þ,#© CN=ͩϺ µü§ w)Ë)8ÜSüfN/_¬ð‹ÆÜêdŠ3+ü"€Ã3_çŒàŒº FÝç\ëKkº®•ŒÅ¥p˜Ý_£™lJ*sF]¦ù†ËíÚ&˜5À$ï~šÁO+Eš®xƒy÷e˜Ü­&µZÏ Œ± LÎuÝE¹KjZñÂ/e8ìVc«¾Óã[êj$pˆÛfegÔÕH`ê _ùã)|`žð"L3 ÿ%sµº{øÈ2 ‹0U¿,Á65¾ciç•®¦Ó"*ùžº.QW#ñ6±tV§Îߣ®FÏÉô»ycQMnÇ_½ZÒ'â—š3k6$€Ã*Úþúm‰Áº Lµš×.)Û>3]&w«_1±Nc죰fCe˜èjlëkïÔ«cºš2L4W߯®¡í )ŒÁ ,_~©—–ÀœÀ¤é^®wÉ™éjpð›zTýÐÄKCœQW#Ã>8tfùܺ]¦íês£®F‡Q75¹ˆº LêHÜrÛêj$0Ù»s ;gV%F“VéµnÒ—ôkÂ^†C&ãw/,ÓÜâGÔÕHàpïÎ •Ϩ«‘À$‚Ðè´›å¼c*Êp˜Ý“Í$ô‹ `r*èL÷èo‰i…º L³¨ì8^± ?7,‹ª‡ýV9ãœzâ!0æü `·úv… ó—ÀX¡B“J “É|î=+Æ[†Ã{®Æ¥\Ô£·s$½ôŒº îÝÏœðþŒº vØŸFA £¶Mƒåt8øŒº L[K›û@Ž >³ÖÒE8¬uÆå–\ÔÕH`â“ô›ÿ™O¦ ‡=åbs¯u58¼çû”H¨«‘ÀP-m¹â¥~àªZZ ³{¶Kõ¬yP}=®¯K(”‘À$£¿­?“ÝÁÎ(”‘ÀalŒ®K×B<£PF‡õY÷_¯»Y‰—~ífA¡Œ¦9eÍ"dO¸ ¬ba¦–'óL •Ϩ“‘ÀÌrªwöu28¼g¿õd¶ ÔÉH`ºn,µ³lw¢¢NF“ØñRYMOÿOàÆŽË0É ™Ü}H:CP'#‰rÕ½2Ëêd$0Xfu{>rË%˜Ä뇟Sõõ¦Üs}á=²ø`&>™WFN|>2ŸL&yp]nkCŒ&ªf=]­K$ŸQ'#Ã ÈæRTΨ“‘ÀÔrnkCŒ&þå`ò}™›Ñ/*€¹eÿf¾7kx±œ…¹å—û‡ËY˜dØ-ʳ6ÑûïÌt2˜V/Q\åGá«^R„IKzõóa¦/èYHà3¶¤/ÃÔr¦Bòu2˜Zv]íˆ á ³\„©å&÷³\„©åŒèñŒ: Lj¹o /¨Ä̪¥•aZkk]‡À¬El&‘Gÿëü~ì–³Úú*j fJÿÎ-Œ¨f‘ÀÁ¿ñ¬{3'N¨f‘À¤]Ô¤YOÁï>PÍ"i;¿Wù¥0kcT†Ã¹î]+7>'u\=ŒŠ2Ì,·Ix»¶œ‡Áò4Ø&õêvÜr Ë£íã‡@ï¹å¼zÏ©Ç8ÄÞs^½ç|Œ½ç ͳî‹Ú#¶äz˜GñŠ0Q:ÙÎuuÑÏ 0¹ÑwîÑßÔ£·y³­m÷±aIe8¬uíü;ø¹D+×0f7àð­nzN-¨f‘ÀäüܪäÁìBE&uQl,Ìåa¬q-€‰åVOV÷ª«µû—ÂÀ¨¬À ËÕ >¤-Çá„åí >¦-Çá„åÝ >¥-Çá„åý >§-ÇaÈdL^=v¨f‘ÀdEz?~é1ôúØãa¶–arÞÞ¹ÇÀHº&ÍÁûNý=ôаÀxkÀ¤Ýê¸I¦—zç &’§ù[:ž€qÀ$“Q5æò¸%–ÖÆH‡“ù;˜ó0ÌA LšÝÿ«e{DÞàa<‹ `ÒDýtézNNö«†æ%˜è‘ßý¾Ô&þ1H¯-Wqxµœ×–·qxµœÃìî\nZ¡æD‡ñ|í²06ŸÀ¡Uº?¿/£¨ØÃð[I`’¡¿ôÕ”`"0ê¾p°ì¾óžX=בëjN$0‰Jå¯ÿz¶d"0æ¤ `°ì8MàŠ[.Á`ù»mOü£ æDã3sšÀ»Õ3`RC÷³ýQ7cü10Þ-€IuV[ÌQs"iùÜ´:ð:óE˜Ü­®í|©]âRÃ4'˜V°¿±:.ŸYû"L<'v4é èÈ<'e˜h!.Ÿ1ù¬6‹&ýƒ–ÐÝ{®°P_ðüçÿ÷ÌÄ9(€I„÷çÃ.{íüe›Õ¥†iNp˜)f²]«ûÄFÏj³`¢ß˜ôxOÌIÀÄ'ã7ãÅÁß&X#çr's&#ñkÌ0´.õÏÿ§‚a²µVxa 0*C$ðÚ²r¦^o¨ ‘ÀÜ2é1‡p±œ…#–Ésx·œ†Iui¶nü–ã=»5Œâÿ¿;㜾©ìáa,.=GÚÌøÀJñ´‡ÉgÆTµ1;DQe±Ô¬‡)OAá„&I÷ÚÝÒ^5NHàðž—‚w³nÛø©…˜Xnn.½Š¢pB‡…ñù^>aí?ÃÁ˜$î¹égÚÄ Œ”á þŸo›ùXíNgõdr'”dH`âº_Ò¸žÖ¼¢ëJ2$0I9éÜÕ5)?“dà`y¬s%˜ÚüâüÝó.xOþÀ›Vh« “/ØŽê#56(ÉÀhy“†«•化«4¼]Y.Àhy›†w+Ë8ÌîûpÕÓØê¯ˆþÙØÔ)€ÉºÑ×÷ièm¬7«‡ñ@%€CðEeêªy›H `â6¬M›\d6(ÉÀa¦üóolP’!CÒP5ë[ú1P’!Ãú|›l“aJ`8oøÏØ;5­ã)”dH`lX0™DLs³Y7,(ÀaÔù3D÷³[Æè0EØ àpæor^µ J2$0MçŸæZOM¬ú¬‡,¿‡‰mÛ JÌ! sPSY”«ýÝ{NÀ\U„ÉEÌ=&«•kcJ§ J2$p8שËö :"ŒÂ .ã¤;—\ÌQ8!ƒc!Òî›Â0S$0M¬~V饀 '0MßXNSÊôÏák=D+VÒ¼ ‡3Ò’Ú¦ –fÀ!„ÝÛOó5NCâsÃL‘Àa¦<®¯ÌÖÆÊ€`byÕÝ `ñ à0ž¿kr%aNH`H9I_—6ÛUÊI &ocv?Ó%¶ NH`´¼H£^â '$0 _ç/uïl| ¡pB‡ÝªUÍEéyÖ$KŒÀ¸[ `f™@#ðam9¯,/}cqŒYÎÁt·šMªŸ¬‡ùnU„iZîüÎ Ñ3KË-ÂÄ=ÛLƒûqm¢ÞÍŽµ¸*Ãa}¶Ó|sÏ:1øQ8!‰åf¨30–(ÀÔ²›Ò¯…8®žSºV§‡± ŽcãV§ëåz¥¶˜ˆÄÞãrR‹VMôðEbe8œïu×}s7m™VX¬C“4—îúêa<× à?–ÿ}x™é?·fšUïx¥ÇÝ…8¹L¿dKÛÚüè‡ûÆ¢U˜„üìí¯çG` Ú àðÌ—V]üZÞÄ· NH`’οTöp©…‘ëÀÁsò÷”».¡pBÓóÆìw ÷hg¢(œÀhyé!ÔGÝ,(œÀh¹®“¯î´²\€Ã>è²×RÖG‡{·ííªÝ]€Q8!Ia©:>ëĈ L-/%sÛáö[Q8!IÛ‹Öÿ²ÑèÏѬêªy¥¶8byÑ­á]Ür¦©=•ò† '0ñÉ nÎÀôÉ”ar¼õ™ëëj#€CÁµ¶v‰F5ƪ˜”iæÜc ÑÃß3%¾>£p¢QµíM§UMBFáD×*÷ä÷6c œz°™Ï}¬þ)L|_uûpsÊÍ‚"„K‹zlPW0·ÊŽõRƒ0:aQ*ð2m;džùøOa²˜S§SÂã “ à?–ÿ›~?ºÿø÷$ I‡Cà<™{ ê $0©WP_Òi¹ÔH`Òbô˜ ŽoNlˆ–áàºïºÜ¨C]¦N'¿>;óÃ=BH…À;æt*ÂAÕYÙÇÀ¼ ŽjÃûW]Áe¬F¯ÿ®þÁf ÀxOÑ3tæðéŸÂdl˜ìDŽ5Ï´¢lsæP;>©i…ºý·™mÆ2ÆSX])Û›¨®À&’gV¥s<{ƒÂç —…m]ë.ú[ 4K`²µ5™Ï½Å@³f–Ù¥žÀÕÚr&5Qs»ÕÍ8\_™–ôÆN˜ÔWû…ñ"&€Ãµýí~k3eËrÿpp†XgëièÕÓE6ú-š%0ÏÝø^„ØŸDB`ìè$€‰Î|ýM(ŒbLt¹Ó4›w Æ@³_ðà\²µ‡ñÄè–Dú[âx¹eéüfšÚô„ÅpðÕŸˆ§Z'òÚ¶˜X-CâÞë>Ød`n‹ñA L%ÍòÛJ´£“‡+&i.Âh™b8¼]Y.Àd)h‡Ç”þx2Àá@e†[?8ëèêA`Xd$ðÚrâs¢–3p¸Ãê÷R:Ë\0ªY0³ÌjNø´¶œ‡Ã„}\ZûS/]æ‚È”À°ÈÜ´Õ™ à ˜ö|W;27¬çKFË~3N|A–§ùŽö‚ÿ Ó“y­Ûä„á Lv«^ÿÖ¢Æ6 ÌÓ”Àaåß-K^Ãô©ôZ²Å@†‰V÷m—œÝÈÀ´ ¨{øÍí+šf¾Å@†&ýÚ—>Æo1!CpÜýn™u˜+-€i˜R5æ‰+t€YÕqL:YÔ_ËWîYG>7«:.€ƒå¿?òsc C‡÷¼Wö»B_üÕa Cÿ±üÓ-¿nžt=b C3ËË´rsd‘Á@†f–µóûU>¬-çafÙ¯ŒM| ×–ó0³Ü?ê6ŸÖ–ó0M+¸,ExÚù³‹ýÀ3K+(ÂÄCåOIïè ðUþ¯û´¸t‹á}–ü‘f¤]Ãà½/“5×Ôž‚þg ó±ËÔߨ¢ÿY“mbœ†ó£ïMl‡Eÿ³ÛDUgÂî[V,ÚÃÜeÎa°¼ò¸ZY.Àá6aºzNÊ϶˜¸'IlªqN T¶è3Ÿ‡v6µq©gÞÿS8\l.u‹v Lê(7¾Ý3Ø¢7^3Ë͘Ø&Ð/Iʼn撙)è—ÀAà­ûEÜ£ ²s€Ñ{)IW5sÓ}*?e‹®N L¤ã/«l‡Ž c¦íOï$\ÅàqÚu´t‹®Îo8>Ûb¢ÓÒòuq ½qïÈcìyØN2íWnðc¢Sã+ðKáÝÇÇ?…‰ÓiS~¤s¢ `j¹nû9 WÌr¦–ΤcË,aj™ûµÞ1ËE˜Z^ÚŸ%cÏ,aø‚í˜þÜ«T‚Iã:]¥Ùèfi]]'=»uMT}±¿Ž+ÂŽåÔø+©âîÎoø hêOóuˆwèG’À¤õŒöÇ lÈsÊpÏëò"F—r»•ßåu¼$ݽÄ8 ¤il”ïðÆ¥`\ É~ÿÛúÕ¡KY“÷ìþÕf;6S°*—Ë£¾A‹ ï¹å –{co÷ËIUÛ£³Z‡­­Úø·¦6ïKtÝ`Òp°¼9,prlàÁUËÇ,ŒÛ±&‚ØI÷w½‰ïƒ<K`n¹JÁ›ˆå,Ls·Ö¢8µ?ÆŸƒÖû¬Õþº¤+¥ÇHîÒ¯x˜H_~Ãíp‰Áç¨å LëöÔmª¯ôî€R v+=Uã¾ÇïVÌy”À4ç1³>V9E88C†ÙØdæÓE%0mÁÖZŠJ0]TI†í­Ó)©ÀÓE%p8Œö3­%>`º¨&ë†mÔ4¦謖Àav?æaÔuòbî¿cÃ*-=°å˜_æÜ´bÕ°pxæáb[£Æ*ZÂë€np Lk, O½tKŸÂ¤%ð™ÕX(ÂÔÏß>š”®à€÷n LÎü}îÕá%]ÓÓ—[®õWôÕ¡îKS!ý{É[9ÄøøÁe$E˜[ƽÀ›ˆå,Ì-c=xWËY˜4ðúiœb5ͼUÔ´Q¹ûeQóô¨?—*}Ñ èˆ  L|uÕ£ºÞ^±Ç@Q͵¶™“ÌE5 œÖ19«Ö#¯»0êEpðÆ»nÖcF׽љºG”ëH`P)gå:ý›'{»Åƒ¶Ç-Ó?»aª]ò1˜W­™oX@àã?…Ãv¼ÈDµjÇ>þÌ©À´·ŽM¾8nYßÒ2ü,»z¦tr×<î>VÏQ€ÿ™ép{t¶»M ñË‘åù `Rô¨®Ó÷¶#S~-°rM\‘tdeGÓßG›|Œ-o|Q‚Ã7¼æúoQŸ%Ãj×åGŒÄJ`rˆ®þ0ÓéhLìÈIe8|A§3y$GŒ=J`rÜ2•¨Ž{”ÀÁrŸkÊ}ÄØ£×Çk£ºG;[E’>Œy ö«>WFâxZ×W,¿”Àx÷g‚zžZ5¶º_Õ}9âqÛÚœDåÄä8L«—©s0†šp°Üºìc`EFL=£zåî$0÷Œ~ÃpDap8%ý¥U??w)x‡Urcã„§$ ršõ¤3 ÐÝ#À[Væ§ ¯-oâð)j9¯-WqøµœÉžR?4×\÷ã_ð£ÉÁ!Ÿò18\¾N¸ÃJàpÀ|)í’y$'Üa%0­KüÀíúmäaúÌípK?ÆŽ=s&Õ³¦¥²tk/ÑÏÍ´NÚo™?lIE=¡ÖI“>®uf£?íX×2L]¿KкªSøÄ\¿E8jyh~bZ'¶¶G¯–ÐôÐý§M€ÙyC§²™._‹Ò¢µ‘‹é Ϙ֜¸~©Æ\·|à-Š0Éo˜L«¿¦+f)€¹åæUœ0°#I/å%ç¾þÑB€1°#IÖãdÒ=pNØ‘À´Ïlª£•¶OpÀ¤ÿs;o`ÀA“ÞnN×â=a áåš6]šè„1„»u­MºNpþ`®æ4Œ'ó®Ó0fÒwmF³pBüÝ>›‡D”þÄôà8¬u—Kî£0»cãË}É‚+'IààÂùÎyTØ‘‘À˜R&€ÃYôš¢g¼ H`’k;ýH§Á?X…Ñ›­“5Îxæok‡7®s0v™[²ˆ3ðîŸÂ¤‘KöÕaÓ*=»Zuwå\Ì©|Æ“¹ù©†ëu÷ìλ¾nœñ”+ã–7kx“´œ€ã–«5\%-'à$ñûqŸþ(x’‘ÀDi~Ñné%ÛÅZÁŸÙIF‡½ûu{­®ÞÆàª&™š·÷ìšD‰3óœàpúº,!=]ìIH:£j»®S?»D“Ÿ3N$09œ,°KÁüpR†Ãne._:Ù|æŒÐÍL÷:éž=ãžÒM9ñø™Eb0ø‘”3ßKÿfýQÐ5$£–«|JYNÁTY°tn#±88÷î«Ö©L 3Fb%0éú’ bŸ1+a;æU)|æÛq ¦%T»±5ï¥ÈAÏ?Êþƒ—.ÃkË´¤7Q˘è,2­†=ÌôYe˜ºî§¥½®_¼zÍë{xË\÷E8/Ÿ³úí‘W›ÈD}–þG–›:fºŠÐûÔs¤àès¤àð/שdÍOcõLî@ÿ‚IÂqËi˜&•éÑY§Ls3‘_ȓʊ0¹òö×ä™ÑÃg¼ò–ápå5~]õ|_ûóêbÁ ¼¶üÝ—î÷¤%ð&j9åИ›²x—Àl~³zðŽÌï<ܨýè–ò%Ñk‡Y„ð•Þ½= “ðoÓßü¢ønóc=e z—þ«(¼‰[NäÈum2?ë)K`$yØ–—T"0z p˜Ýõh•§Ñ‚ÆÎ=-Oú•zŒýÊr&ÍK&ó6µj⣮bݳÊðʲKÀǘå‚$Ï)7aQ²ã—ºá21Y8Ïÿ&èé:jçïyË<Ðe8ܺ슄]Qµëõw t3þ$ò¯¼˜¦š§KbyxËRÍ‹pph½­2Ïss Œ-VÑübÎz=ŽÌ ãÙºZ'ËyEÞæ­mz‡eµ‰Ÿƒ¿!Ø¿M|ð£kA“|ºÎ,ŒèZÀ¤ø²VI'œ‡1J/€Á2¿{P¸â–Kp8õ¯ë Œõ:Ûn]ŽÀ¬sÏ0ç^ÝþŸÂÄy?µQ£‹nǘã-#–£Û1s‘Àavõc%À$0\]ã²;÷`¢)Ë.,yOSË<„ ð†Y.¤HßÒ_ÄÏogbï“÷$p¸L»i¬Ó+&ïÕZm2Cóñ$0‘Ûª*ï™å"L{júu@ù|ˆ¾ Þ´Ó܉»_¼Þ‰­ ö˜Ø—’Ñn¦GLã6ñ]±½úøøPý8­ön–Ò/€ƒÛiv:sDg§N¸¥¯«ïC¬¬³‡Ñ-€ÃGù²_:óxìÀaïöcì’=¦ØI`’b\²„½‡Ñ…#€YÕãiœ]tÉÅl®¡wõdLꨆa[ LóV™9¹Öa6—gþ:»>c6—–¯y>·û`;å.éèé—À!ÌÕ×Ó×8›F‘?#0–ÄÀD°ã¯?ƒª1ÖüOg/bg”š×ï9÷ ¿ýÕîôm´éã6f9¿âÚÞ´PÛ‰ÀxSÀÁ[ð- M^0ô.á™ýÓ¯üUXý |æÏ\‚©x tâ16\–Q„ÉÒØêÉê´FÝ¿`zÅb0­Z z¿Ö˜ú1­›^µ Ó,o{µ~HW±ëã=ò~`|u滎cF¹íãv7NÅ;¿xx¯ÎŒ‹-~‹Ý0g§{l§ê®I”Ç÷0ögÀa™yªßT]ô1v$0µ¼vžxÃ,a°\eàŠ[.Á`y›·Ür &·X—®eäaÌL×ÓíáÔÍ̤ŠÐ¸ÂS®&G5 oØÖVñSnNX®Vp•¶‡–·+x›¶‡ÿXÞšw—Ô¹î+ŒñztT¿JhEv« ö÷ñi§ù–X‘*‰À¤è÷/›PÌRU»µå³úº~%'ÕŽÕ÷(Ã`¹Õý­J¼3·\‚ÉuI/U¿_ú+º"1E¸&Ïlž]ú²î˜”Tzê¿1±`ìàP*sl2W¼ o@Û%JÙÿåçä¨`(I2q.Š·Ãû &õgZùî ŒsPƒåtÆÕnsä–K0éÔÜÏépðnÃ:5—ápæÿK­óx sP‡ñüõí«Nˆjvx;–À‘õ9–µ«6ñõ9 ¯Ö ¨7Oà*¶näàía§ù¡Ûx3q£xI/„ùò÷™¥Væ0¯'; »Kà`yRþÄÓ÷&êêÜaØ]“jÏ‹v6ù¹±…ïåh̤fâd'ðÊ{Y‚iá½tËZý('V8¡‡÷¬]&“~‡ÙÒ˜Vš3µbú³c¶´¦…~>Wëy ¡"L²—Ü|󧈟ñ„Š ,MÓ}H._(oÀaÔݬÒÓ¤¿šøcà>(€Éx6º·uê¿eEÊ0Q°Ûñ ü^‘xu‡5Ì"WFMà˜©â½ß±vL³ÿÍex§ŽèG’À$§VþŸí¯nϱ•anyŸ‚÷ËY˜[>¤àCÄr&¹¶íggæÔŠçږᰊέ—Öº{Ä·Cÿ†¦–ÇÉOÆixEà-³\„I}pm[~'ð냗az’üô2 ŸÑÈošE˜ôî•n–†.Ósâ÷{ôBHà¸åj o’–0X^¸ïÞ ‘Ǩ¸å·yŒmÒrËõrG¿½"j–=z!$p8?ßMý9<æ&VÝØ´-€ÃºÑeÊ”{×  ûàwãΟ2WCtÏÖgŒ–ÝõÏ)¼ÚaK0ú¡×˜9Aà=‹ÃaR%Ö˜Ú>Ð×g ,ëi-¨$0úù_ër°ó‡ózý̘VЩ!]×ÃÇ “l97X¦€&–»ŒXz¹ã8Ä€œU—áRëèÁu¹ãä×ïƒÀØ@¨ù®¬ž8ªí±ä·Ÿ!®s)Ë(¸’ÀaÓü†7Ix³¶œ‡É­Õô]Ç;vÚ³N ˜>³²~4C›>oÙ3aR©—¹$ ^¥0XÆ®‚ï¹åL*ÊØþWò,©Òà3«(S†‰Ói¾“ò×íÏÌéT†IJ ëŽÄ`ì[-€‰ånU™(À|ÀÔòÊ]Ga–ÆX†Ãv¼QKæÃðØ#©åKZ q`*p°¼U®y,­=⯯K8XÞåa¼. àpض½¾¦ º†$0©n8=\ÒÏ@×&#?B—ÝÛ]ÃÑŽÀ"ÀT[[gä~xË;Ûá`¹Öý×ËߨL,íëÀ\C8by‰%¬á*n9 'ê0µéÏ®! Wã4·Mòs£kH‡±qíœÒ0º†®j.,LB`,1â\¦(Ý“Yt÷s̬¨`—Àäžò3h>°jCøYUQþêrÐx¾”ÀaáøZ.µ?e’21†-€C¼aÿй_ˆ%ð?²Þݤ×*)}@t&^?±›K¥Ú¾¾Oë×qD¯L&úYþÇêgËpˆ{Ôu—ƒ1Ú&€I¹´ÉÞ´š†Ç›ßxEÀaÛ¬ßé–+Æh›&ñ¥¥èk ‡~ Ô½ÝþÎÍ+ìY Ã@êž¶1CjÔaÏ L¿º»¿ªëGc‡Õ{>bà]¯,ÃÃx³œƒW–Á×Oà}Ìr^YžÌ÷ld ÐG ¼Kà•å~˜íu•OyÄÀ»vÌU/=bà]SË™øÿ‘Þ0'¶¶6½£mÛ\qÙcÏ<™"ªG ¼K`òÌÍÕM©³Ì‘UÀ¤ÆÕÝåe `Z=«ùL®uG ¼K`úmÛ¥àž}A»T)‹W!¾ŠbD‡kºŠ,`FE’^=óøŽ‰Q‘ÀDÁ1éÎÕ‰4å#&ÇK`f9å'>b&½¦±ôŒÏõxäªÀ"Ž=ºµ¬'Àð%0­­VÂŒ·¶í¨'ežs\ó{Ä‹˜U¸»u‰gÆX^[Žf=1V#æy‰ÔÁ%ðnõÓ²¢G§†_$pˆÒ/[±ò7 GÆô,­]Ý> õ…Â06Þ³¿ v)ùÒ+~I`2s)¿G¬˜kënL—&:áV“ǘÕR¿´Ó±£ àðž¯ï}â³û„)e˜”#u;›ÎÅzmïO(2’À¤;Þ%syd­{%p¢]®¶Ç“!$0)×´éögL†Àá¨fs^TÖXGYãTî10&&€I$¶ùJO«3Ž îƒã8ø[ú—zî#ëÆ7z ¼¶2_>G-g`’ÎòðgþTxœu\•À´S îÓs Œ–“'FÖËUËÓ©©³ñE†õr•Àh•NŸV– ðÚrô”Ëz¹J`´lÞ#üA€±´§‡ÀÇÛ¥Cs¬—«¦éYîÑ.š@Ò©ŒÀ<=«ËO÷3%ÍpxM«ôRµ0VÑüÀ:ÊH`(U{דî‘Ï}`e$pÐY¼êyÕNŒÀ0%pˆ ¸LÕêëû"Ã%=×ÖùÀšÄHà°>ÿ*‹¯c¯K8œ¾\“Î;°&18\—¬¾õÃÒ1zV’«k#‰åÉÔóØê¯SônÑrïY¿ÓGˆk#ÑÏ_'êŸy˜Õ¤×U—Z•o@cå'kªöÒu:ùô+ÒèßHu‰ÎAÜ4%pxŒfÎgÜ4%pP_6™Ôæ)I^Ô['ï°Þäk‰ß5;W²šïì!€igâÁÓÌ+$Xg ³üøs##p•°œ„ë[uB‹K à0S.Í%Ãx–À$>h;ªõxØ|°˜f&çg—Î<ö0j«pØçšUfE¿¦%F×Ò)#¨-|b%FŠpØaÛáb–ÅKÙuÁÃ0­$0)ÎzëTDì°a ý˜x!2ù Ö"F“h©Ç›ôcà>(€‰Cò«µ³‰Ç&<Œaɯå7KŽ3·ãÃÍó^„Ø("põOa’˜»4œX.KÍšÕˆ±c V¤þ’[1v,Ùÿ2«ï†àu+žžùѺ¡·ï¾u±Ef‡ŠQLN¹³V©.ÆrJ˜tPÍ·$6ÖvÌìOs¦P3¹ûÒà­‹ ¤UhµCQ WÛMê1VE5J0·\¥à}Är&Ýg{ãÒ5ÃR I‰ë~ Õ` acB’'[ë‰'&0Êü0íØAtŸYǶ"N׋¿MØŒžíQ/e]ü™› “ìÿo¸†œ®"–³p°ìêÉ^’»s° à0D;õN¯¢¬u‰¦Uün’ú‚¬ÿ†umqýrùŽÔJ?T¸0þ n2pÌrƒ«„å$³¼ÁÛ„å$³¼‹Á»„å$&l»Q“~Ѹ#…±¦¦ËÉvXV¡_·aÖÄ*ôK`rŒo2‡À  ·É6ËÌ«&€IBÛ(ÝÆcôV¡_‡sÝw1ìD´ôÀ «K`jùG=7?Ú&ÒÐìÀ «Kà l»æ’¬à·&%F9xÃJŒø3.ï•Æàpúº\”qLN`”& `â…ÁOÍ`Ô¸Jà°Ãvÿj ±‰ÌnV§YG,WQ¸Š[NÃ$¨¥UK9Ì ®à0ûÇlÚVCT€Àð%ðÚò4O1øµœI„WçÆ3ke)€IœÚå`ô# `¸™Æ.ÅÄbŸ›•ªÀkËÎÄàcÜrËó£1ªk\䣠jH‡­méal‡^™çôÁk{x#bxý6^±kéö˜ä»¿ë¡ûݹwå“aÅÿ$0-ú½@Ñ6£¿îÙLéH «ç×ÛNyÞ_LÉÑ<À¸ŠJ`’kÛ©—Ndrx‰>æàí2<ú:áDeåÁ–Ænbqé³…Q“z$æÇÏNÇ¥\fõHÊ0X6oS7ñÈ.é8 þ/÷ó»+JLêatV àðÌŸvTþ›Ìj2õs5Dqa °3}³†1ô´n™Üñ{÷Ô:¨üþܱˆÚK 5¼ý¼žõÍEá ¯á]‚IDl)cÌW®0"V†ÿXþGÿÿýŸÿ¡þÇû¯qfŠæïób ¼‹¼ç,Ì-ûÅ?þQöËY8f9¶œ ËI8fyÑ3²xÊcšxýžßñWwоç Ì-'|æ;ÜŽ%p¸. Ÿ™3«R&ÁòenÕ±Ȫ”Iàµå.WQË-×m?7qx»²\€I £é~Œ–—"0–ŸÀÌò㿵±Zb8Xnì”{ ˜)˜YN?Æim9‡öVû÷:F[Òy唘ã1S2­à°Ç¨¦yõÐ_ÕÔì1˜èÏ¢ípC–» ÓSnnêÐëÁŽÎ,§8½ÇÆe˜ŠN¾'{‰½<2J`´üèŽ=%0õÿ옂¼h æ–O)ø±œ…¹ås >G,gáp»)?˜c£C‰kãý_“0“àía<Ø àìѸw“”,ì±½Ž&%Í{“Y PO)IE¬1÷ÑM,IÃÜÞÎ?åà¬Tà4ú™=>fšÂá0ê®WÛZú­Æ˜Äv¦VxË 0^'$0·¼*½Ó&b9 sË7ÝEßó©ŠXÎÂ!T3èÿ—y™ö?–˜ÈÄ &¹ñ÷g27þÀ*¼unîüws¬¤ùm{9WÝuê^Ÿ‘Èê° ™g£® x0úY$pè¼ì±UØ£SFƒåôúÀ[–ar:¹fôÁV¾A‡gžM›¬têaì„(€‰ˆjÖ®^º‰Å”š”พy«t£Þ]ßÅœ{>üS˜œÕÞ7Ó'?+a'€ÉÂhœ_â)úVÂN‡±ñšKªüìaU´Í)wU«HÚN€Ñ‘dºæÖ1•Ǻ]ÚƒcèŠÀ˜—»ô÷]”@·¡mÖNs –Üݯó~´}ðUK“À¤ÃÈâûú‘²ji˜[6m×Ä^Ýq±œ…ƒåë%·È`¥­N‡Y¥­Áýq˜Da\Ÿ0 N˜ç÷20éˆïþ€œß°ÿï6âeU«f§3g$VˆJ“[úÅ´éˆu_?g«l­›ï"è«xÄMS‡£jŒ³·^ÑEšÀÀkË´"/·Q˘ñ®Õ=™btüš‡rw ÝeèýŠn3ôh{§aê!º°š_˜dÛ^†yiÿ2->ùÍj~I`PZŒfºFë¥Xñ ¼¶ÜݦõªËŠ_H`?¶êöþî0N‘ÇÀ;‚‹ûå¹T¿À1Ë4+~!Ã1é6^•y×÷[t ¡“]‡›©ÿ(¥jŽÌÉ.€Áòª’$Ür Ë<–Â'n¹¯,»Äcœc–sp(2ÚçÄ@GŒyK`j9³1ÛV“6‹ëƉ>}°6‹e˜´{èçËðVÎÆÄǧ «m{±³b×Ío7ÿ¦^×nðûÐU?Úµó÷´ãÕjŠ0³ÌÆ«µåw=ãé:v8?ábþŽ&IžXƒG¦]š?aéLÔ¨³û®ºƒg¢o×e$hg,¿,Ig!“TvÆ ¾Gè¹Í,gôvJàðê:]ÏÛäDaº&–Í“6zä0ÊšpXŸ_ÖùÓÃ&>»Yu Ì-W)x±œ…Á²?ª)xÏ-—`°<&‡ÎÌ«,€ÉRй¡ÑIO_øåÿ6\lkç¯ÿ )kÆN8,ŒzÕÝÞîãdת3vÊÀh¹¦N·'ðye¹‡Ûª«m!‹ð_ðñý¨-׺m—Œ8¾[yx³²\€Ñò8Ž®V– 0Z~¶Ix»²\€Ñò§N»•åÌžyh£]b=¼_?sFËfš†ÉEáÃÊrFË—!ÞöÈÃǕ化Y§•化§nv_ñx^Y.ÀAÓ?:5ô­…ãk€1¨/iÚÐsg7,­3˦¿ùY-_®Ö–óp8ªÙzþ< [¾<¼ÅJe8fyí²ðð.a9 ³·ñ2—øÂˆž Lê†|Sñ­íøa Ì-ÇZÞD,gáà3…=Œ5’0±\õ+==1ÙItä¬Ma-«*ùû•åL ¿.Â\–ø`,r-ÃZ7Õ¹‚* N2¯ÛÿŸ½sïrÛ¸|þÖ§À8gg¤ŒÐn|ÆIÎÒÝ”ÔÇR·ÒlÙÎdrzA H—°ÙíÙ|÷­*€¬{/ªÀRâ“ÝÙIJ‰. …zÞºAŒÃg[ÀЯ&ß3âY¦`|òn+‹àçg·¨óBãÕ— ¬4®yVOý&$¦Œ ¬j# 3sÕ‘˜26°j¬rŸ“s}C"AFãR( õ¦ØÁÁ†±³82Tâð”dÄ> #É¡qÜd[00hYU)Ξa¼áµäXØÉ‚2¹0VAг C¹°jüUiÖrç̵€ÕÔ–‡nGÁ`¬¬¶€ÁÀ¸[¦@óÆKb ÔsUv²Ÿ'fáC™%£Æ†ÁÆ-â•¡Ãâ­´ ¬tŒUÙ3òð4a«/X¦bºŠv¡&Î/‡ñâÄ>Jþ¹bá®4­‘ø;LvuœDFxø¥0ù£Ô˜mâÑ‘ÿ4¬ª.éññæ0®: 8Hû`lvbƒðÙu?í ý¤éáÁüëN—8L‚_DUO1|Ò­‚¾2“QÔÆy2RæN¼I7t‚ø±“'ã ÒÏn™Âÿq˜$¶9 SÉn¥ÿ($뱌$ïzŠ1¢’OÁHrÜ©äS0•l|Á‰Fr/Œ$G!Ÿ†V:]‡­_l`°]zJbÓ ‡ñÈo«e|ÈÁy½+/¶m`ƒd¯Ì’õ°Úþÿnç cëD '¬ÔNÇ6sM´g áãõ† TY$®Z=’Vm`%¹¬ª’eûù1ßu4'>dl«UÁ:O"nÀ8ô˜ VŒ¬gèÏÈŠñ4 >Þ¦bÐ@Æ'au8ΞøÙÔ­||Ü`«é¸.ªc(šÁn2$©,`"9rwÚÆ?ÄK¸#95ÀžNr¬Æ fNœcëz÷+Qm`ÕSja|‰Pã=¬ ID0†~Æ–«°šS¤®ŽàƳ• $'½0ž­,` ÎŠÝ*L0ÉwVn5iñ81®Ÿ‡XQfÃ/Ø3È I’k ’ˆÓIe1ôi ‰“°ªç2TÚHú Á¡ôz '&C¼µ•‚%9 51€ñ'nPu#ÛrŽ—1«Ü‡5ß®hÌFôté4ŒBT½'£nð‹S0Ìê›? q³Á”†¹q0'nb6°r¨ò 0æù™?1XiQYæÁÞ°m#~b60pª¾º›aèÓ°Ú‰û‡¯kV‰vÏ• |ËLvëtcp8ä°ÿ¥°êÞ»Š±Ô¤­ãÁÎV :ý\Õ¹!²À„ø‰`½>‹¸~q¸ÞeÓ†pàððKaXæ6c¤•ÜCÉÍ©U¤/ƘH> £!‰—R¿€O:‘~NÁ`ù•E¹Kb’(˜ºšŸ†A’«$ V̰m#h6°r*Kâ¼§bmˆ Žÿ'nÅ”©†'Ýô,.¿C_æ ¶?³ÁáqÜõB09–> ƒ˜…Q,‘'¨‚=³ð4 Žñ"ÆŠuÉØÏìèÖ `¼rµ€Aü¿ºÌ©÷1€ñÊÕþx¢OØÀ8‰· ³xE,3¤»çð„dñ: ßž¾Ã¶‰-¼-`µ«‰»iŒ!Œ­-`О˸¨c¶×u$ݽ "8ôdjšt÷"vƒ;0öÁчšŸÓœ¯O´™{'$ƒ½ Ò mú¾ ÞÙÀj|^Õ=‹~’‰ÚËÜš•{¢™06a·€•%H$a\¹NðY” ½†v|!¿)õŘ'±Ó0<}‰‰Òà19}9 «¶‘;°&•ÛšŠŽ¢Ø5ÑVZ§õšqnçI¥‘ðÜm%öƒˆ™? >}±AVËÈú‚W60–̲ÐðQ°K† ¬Z]R¯ªÈtx<ÁF60HVÓgê4%.0HöX¸alŒˆ;¥ ¬FQ‘A(ÈòBc%£ Œ„M¦Ã‘þ£L±ò˦’Ç&x¬‘Ü ƒd5«8aA$Ï?Æ ÆÚQ ¢`â ^õéà¦Ó/†•±Ú£0êƒ60X¸>v– &)Ím`µTËòÊ­LÝŠø^ÚÀXrd†½Žä0•lðf™a#XÏ"€µmS0vœ°U™=7*š²ŽÝcCÉ«>Ø'’OÂ`ß]°2„AÊ<&ûîÓ0v#>Ânv7é3¼’±Õܱªvã òR0îÝ60HœXU‘̽¤‚/Aü&›{]Øä54Æ2Ůړ¥Oˆï宊E2K^ q[§êˆ‡d¥±g–Œ=$-`,Ù´’™IX-‰E$*ª£06Ž·€Áqiˆ-i^F«”¶º)ñ´Aˆ·’ÑÈÆÞY0›g«)ñc´•â·æûASR )ñ ´U‡íK?Ë—H¨ÕÙÀp#¶sY(r¨¨¾¥`¬í±;’ÑÚÀä>Xm=¤Â¼fZÜ”ø}ÙÀÀ8Þ v"Gè?Ö#ÙÀÉ•ë%›a°ýÏ]fJå:='ï,`dX”qVë«Î÷©Qà)XHHœÅO0_€±œ¬Ûi¯Ÿ/ˆ³†ÚÀÀ(Ðíê³ìa£@×ù‚Ã>irpc}Ëò4~:è%ã o60È#ÑÀžöu’ûàŽdßk_°îHà‘NrÜ‘<2Àcä>¸#yl€':É}pGòÄOu’ûàŽä©žé$÷Á*1WíÄÿ Ý ŸâÙÀ¶Ó1^åÚÀð¬MfªAnÊ&¹OÃjw\‰)Ð8"á%± %W4y6„}"ù$¬l2ÜÊÍÌkQ¬½´¡ÉB‘ðZœ2šª›“…“0Ì¡d¦@Tž’ª'a(H“8{0 æØ‚° ¾å%Þ§ØÀʼAÎÅ®>´Ç”xüÚÀ4)P¼ÑùL‰ÇoZ'b7â¦ð¥¢s7Iðn«•ÐîpŽ+ã• Tñ#JCE`¬Ëµ€&oŒs@[ÁxIlSÉú¸ S’”Þ§ÿÏaPmÛX ‚-plàŽäýªÐ¾àL'¹FFT›Ü},áYÁþ95¢:w$¯Bm1üNr¬FÑU°Z%ÌÔð2ÞVe®"sÜ)Iïæåî‡iÆï …‡°.—x/ Âd샒¹ë(Õx†µáF åL¤°O=ʶÆyp€Ó”ÙÀjÒ,žkn‹m® ‚3`‡+XÅþKŠAOÛÀs60”ìõÁ#"ù$¬>÷cÙIXa|lCûÇŒÕú {SâYmSÉž h$÷Â0)½ˆK¼Ïˇî9,‡‡$)ýIJŽ3‘þB;ÃzX«fCÉQ˜Æ G³¡äÊè!Éá ‘|†’÷l%ý«5 *km`‰ú‰…?_Ð'™¨Oà #Vˆ¼U™Î&pêÓ ˜VLIJœ¥m`}™»U7=7–ÙÃÉ72Em`µ-y¯ªB¾£QìÉÃ>ÉÃ/…Õ “öi¶IRz¨àV¬Ì ùu§$)½ Î4‹£oi·êHvJî{Aœðž†QvVVºÂ¯@³8ñG쬧`µ*w1oÎ,Û¥:w+˜J®öe¾ë¤€æðD#¹¦’EÀ¸cîÎá©Fr/L%ó½ÿF3[ù$L%ãø ÆƒŒ ¬ìÞ!)·NÏï㣠¬ÊüØã:%>Û60p™[eeˆ>3%>Û6°74,„ñÖ)Ò8ë±3ž¬jã1Lòù±fûQDÝé]!8<"죫~cý† é Ø-u™¦$u¼ ¬ZÝóªÌÝÀE.¦ ÆG$6°ZB„Ò:^ŸCbJ|‰m`dm1†ÉFX¥=Þ†Ó!Ž_oƒ0F|ZsƒG­ ÕtHL¹âÔ5Ž“”æ6°òûÊëǾûöØÀjÛVx}ÕAr@YÀê«ð zµ ôIÆN°: L{RØM‰‡· ¢YT=‡#|~fÝýše¡I‘4Âçg608¤/ÌyN¦$]§ ìVk¦ôÃS»ÕÓ0LšgnºÎ´Šþ1¶.µ‰äÕOTŠxЕÜk${ZØÓK6Ãɾöõ’ͰFòP õ’Í0ò‚ *‘º¨sL’üXÀjDÊžŸÌvLI°êƒ"Œ¾)ätB”¹šð ÆJF X\¹AQb=N'cbquWXöyÇvúQt‚pÚÀêP3©Ë bìNÉF× ¢V÷DÝ›’ÜY60ðGÚ„IfüÜÄÙÆ’aZ¼¤E-ÖnŽÄ¦3’õ4 2/­Ü0ª *ÄÙæ’=<ÐHî…ÕødÏyÆðöQÁxyiw$?¥:£í^^ÚÀ*`aا³˜áå¥ B/›<['ÏÚÏMÜHl`5§ì{bñò¶Õ—»t—ì*Wož5Ã{+X7ijÔ3’bÑÆ–mû4Ðïÿg³®eÛ I®( à•| V*a߆—8NØÀj:®’˜ïò2íÉÜŒ8NØÀJSV'­ÊUÀ~F'l`ÕøŸ³ zÃqœ°Õ»©Ìî”3’ÅHÀÆCÍñX(âp˜\æf$1‘ ¬zJÔã\:#‰‰ê ]åe`ª ï‹axNÉG™$'sÇú01:9 É¥Ùv|F<l`/è„ €0ÉxF’½xH%Ÿ‚‘d¿Qɧ`$yØ©äS°Úþ³²ŠY> Væ®ãÜ ©I?€QCÚ$eš‹w60ÍgªÂØ¥õ’Ræ2‘´ºž*ë ñ!É®ìt+¿VÚ= &)Oݲz®B]€]NãHM0ÌkëEqU$Á³“¼¶'a5_%AUÅ¡iLÂÛtX5ÿω°ø0ÂØþߦ’ݪJ´/8ÓHî…Õ“­ªÔÜ¢ñZÆÑx“š—‚ÿ•qÒiÐx-c%ÿ˜&WExË6Kž Àh8·Õú«p‹(‘FhUM=úgÄlÛVS"Ua“dX­ì‚p—nkÄ Ü¦’×ÚìYö4’{a*¹2Á¾Fr/ ~‹X5¥>ÿ‡ñy¢¬Úsç„Ãh¬³ñ‰Ê&Ðï¼9<:c¸+y7 €fŸÓÄ÷h‡\âèñžŽ¢Ä¹Ç›šRªCÒ„ÕT0Y?[Àj` ¢Ú­}ôìqgaå.[åùÃ=´ñðX ñÀxó˜gQnJÜËáé—ÂJÕ­Â"¨·{­yÉÂf+Ž, Œ’ TCyX'¥ Æ2œ'‰ßÑ0Œ0v\ý\­“|ojC’8­ÌVTcì3gµa8r«(Ô†°ã0NfikakèënÒÇx0·•ä03;Qqãµ€ÁHœ¥”üŸº$9¼l`5² r‹  ·AWÍBrñØÀ¤Ìy¬ý(“‘¦Ìý0ˆ…X‘)Ø#‡q6e X¿~î¾ >h¶ÕN3x¬Œ ìgÄ!ɹKêÂõÌð “êLÊlRîM‰Í¯ b2f»Î)ÎWhËÜî ÂXCeÃXy¹iÏð:Û%âd«ý`íÊ€«ú!—8$ÙÀðˆ„ï– ¹ÿfS¼ ²Aú3Þš¨ûÕq”±Õâdô¬r‰£Œ üE’yiVö¬/‰§Œ€Ý*Ôçˆma,Úm*%é.Öš¼(ŠŽò4ˆ³:Nu¹Õ9ýÕ,`ª`®ÔgeŠ‚ñ‰° ŒRÍø®YßJg£sšBèL%Lð@#¹¦’=ìi$÷ÂàÜ6îQÎð„eƒ…nVƱq†WÛÀjð¯RÞDS·Ê ë~n¢µ€AVMfväå0^œsÉÂqÝ `¬µ«_êæìÑT lFeç‰$™kju3âln\M0"Ac÷ZÈ–»:}œ A{X¶ d—, žM=8XѸ_š¿q±¢‘vÇÛÒê‚}’VsZÊ÷|0õ 5ˆû¼ =ñâÏ.Ë¢";sAûÄï4Md·,|ÐŒ'¬»·¢5宵5ˆ-W­h"[(ø==îÊ>A«>ÿ¹“üÓ¨XѪ 'SV®‘3 ñQ‚doRã HJ|^¹ÑÊ5D°â4öܱ¢Á|ZÐó DãU§#ÓñѦ²å4¥-‰§“pJ£cê<(LåîÆ´?M«UA•V=í„ø¬”Uxš¦ÙOð@ è‘.ýI?­d?Å•»ÓÂÕèi8M<¼lhd<*ã<ïá½»­ô«y—æ¹êmãÂ͂ڭõ#2±×øp³t“|¯7îà4>Õ²¢‘ìX€uè•}’F²ƒÝ“©ÅŽp€Z+ÉîtHûTöIº#Û…©Ì!=ÔÉî¥Aþµc¹Á99J±¢ÕiXmzzñ”d…°¡Õ ¸ŠúK2Ã+ŽæF4^qlYb¶Xà4îóV´Ó¸Ó¨MTpV4H!W±$ƒNa ÀÔAÇÒøŒÜ††«¾çrc3CÑdÕ{¤aªHãã®Mì&¦çf+$Vf=mPüÁ™•-h "GG”ÆÚº¼†Aä(e ÇÔçõ4Ý•ýSú”Ò(›‚ö´²ûè®l˜« Ò¾VvÝ•‚Né¡VvÝ•-âW<’¼É‚ie÷Ñ`=Xõ¬”øò§Nfio}“ÝÚPƒØýHÊMŽ¡Óê³yï: ëA+ZYׯë’1c/&žªV4Å[nõ¥œ&±ölh5~§q®wàãV4’í C“ŒuI9M2}ÛÐÀ÷†eqw4 kM+ZÉ®Sw· »£¢¬h5Ï?ô­f>ŽoEƒÈ›ð¹(YUqU§§ ±BÍÒ‚U5öU4±{´¢Õ[úž/|òªx£ÂÐ*z‚¿¼ “¼—¬ˆ#ëÐ#šåý4­âäeðlÔ‚ˆñ‰­d{¬g=Èiìoñ\ÅÙšO€:sªÁ`†Û ­Æª”5Þ„Ê”Ñò¼KY/ìEzÛŠo½W»:>xòA|Jq^ã¼™˜¤Ïˆ%EÍžê§X„¸ZÑÀ¦CÐ|ñ¶Ð(s<Mц&²·ñf««rMYÑD6¯vÓ[ú]Ù'h"›oŽMô°+û Šòå}ë„1è á9Ȳ¢µ²==6É6ÒÀº#Ü 'ÊÒô–xÀ·¡»²]M°AOµ²ûhõ-£•ÙC¬P°Ÿ¨Èg®8í}1 |ªï!ÚïÊ>AƒüƒuEXHð¶ÛŠVÛÀ]ð²¸U¥- ÉlEö}` ÁYlmEƒŒ~¬è¡ñ¢ÚŠV*”8Ë7¥1ºéfTxÄûØŠ‘bJ¶Í…ûDUuyY¶YÑ]Ùú~é{žVv %;{tHGäPò4­TàU°6/ª=b mE«r»?ÇÅgC_¾^Çj%+îUI¾ M4 fbEÕ½[ÄAe¦'XuoACã $¨è» NO‰qFCï"3­ÌŽòý>ß“hÈ€ÆÁq­h*ïb =ÔÈî§1 ß|Ñ<ÄŠ&þ½ MÖ²”Ví¤(Í!4øo¬h ›Ï“ÆžÆi Ò†² 7­@MDãX64HíÃꨯ$8‰ ÊöÖà””Û‚Vå΋˜MP8çyª×W½%Á‡×64HÁ–vqHãÃkÚÙ†!5jSô'V4‘]ñ-}Ü¡"èYWö šÈ.‚ªª·åŽÎÜþ÷K+šÈŽò}–äA¤¡]Ù'hZß¡Þä‡Óž¦¾ûip UæU§±Q`DÏðñ¿ ”~{Ì}ÄNcoÂ*ÌëúÙ]ëS‡dmEUrÓ… ‰êÞ‚þ2ÙJYP殄*ÌÓm(Ãsœ‹ÌŠM€ö4ôÐ(ÛDƒSÝd·0 É©­–xaÑ£“å4êV´:© Óþ’ !ÙŠ1ŽøF­Ž V¯œÆéílhXß¡ÙRr8ÀžAß¹.§‡_L«M`QõÑ.‰ 6˜âÜÃøy0Ò¤†´Ú`FÌMBéæáv•3ÃŽLaEke{:zb’m¤•ìç(0ouGd ´¢•·ˆ“Ü”`d0"›@+ú(Ûçûhó–qäãsF+šäî­²@—Ÿe0"±@¬h5a²'÷©4¾åo0­hµáé ª4M°Í}”íP=Ý¡‰gFQæ›2HS­C¶ g8ÑnգʟӴ¼œs}| Aãðf½6mc¢v’u'";¢Q;ùißMôi¼ ´»Šåö:Q¬+ÎÆÝóÿÓ´š¹ó$(c>g»“óV¯†?™ëÄÇêD+VÙe¡Ñ^nìHÊ Èfë43)98sÙÐЦbe$ì©îŽßc÷b+Z+ÛÓÑ“l#­•íëè‰I¶‘ÖÊêè©I¶‘–’YÆÂÚpd3öq R+œaöŽc¼eÌØ~<óá>tUüAEgm+ZõËM›g×1ñ!¶¢á)0KÜ2ŒÝT£–çO+ZÙ¤ucͨ !h<ÆÚÐzÙž1qµ¢‘ì’Eq 5›RÙ'iluƘ8ZÑ Ê[Î×xÑN¯|œã7+Ì »,ªã²Þ©0ùŠ`¥’­zñ6¦vÀöpO³¢QûÞ”ñ®r+M«šxx7jEƒx#[—¦ C4®ÓºIeJ6˜} MTÉ”VŠû 'ØÇ`2Áê+Zùí±¾Õãd‚÷€V´’oVŒ¹±^ÅiTßVtW¶öH’Óc­ì>x†¹y›V¦“É{oÅqʲ¡}Oɪ׊ñ‚¢"Z›ZÕ”Xë–AØsD6à½k^ˆÐŸá£¾¾§ìËhEƒ4ô‚Þ­´×•}‚&²« 5Ñ~Wö šÈNX`¢‡]Ù'h";Oc=êÊ>A+ÙÛ*ìûòXÍoE“r³Äø–“n¹OÐ`&aáƒôtËš&?ãßë­h¥Ã{t‹µq]5õðîÈŠÆ-n˜ìDÂ-Ýx2’ìK6´êóQåÆ+cŸãЊƲ‹zÔ‘}оŒ;ÖÓª&clQkCƒUÁ:¯sÓ®n:’U¯‚çðmFj}Hx,+Z•[Xˆ[M˜lE+­…«Q†k-Ú16Ð÷Kš{ËŠV‘%…‰±ˆk¯‹³)hÔb­è£l2ÙlêEóaXÑHö6ˆ F~3{ [Ñê«.78Þ:¦I3f®¬ÂÜøå‡šºò4e=ô #ûd³ªÂ m íQÙ'i™ái×U„*zäcM¥ ­Öƒ'h¬µ¢U/ûVÔ3âƒiE«Ñ‡÷a¾DÝM³Ëè„ìÉ LRzöÅ´Úe=åöh+‡1®ýjÝ£qx¬h ¯JÓ:k­ŽÃ£qx¬h½lªãðh+¬ÙX¶g«ŒéÎ2<YÇŠ»h7ŽbÃÞUX‹{]ÚÐíÓ’D¬Hòg}IÃ/¦™Í®ÌîãÈôåñºÊŠV¦Œi^l“IZWú’àä$V4ˆ„¹ËêÈ\ƒC Ó‚Vu²®Ê( ô½XÐXgjC™leâPçÉ:X >À*m+fÌ« šøMÑ$Õ¦ dï’Š¹q¨ÿ˜$Mœ ,6Er¯´Ò&yñø·Ä>"64@„Æ£Tï|IkdûzÚ×Ëî¡5²‡zz¨—ÝCÛË}‘l|˜fc9ÏxØü­Š»7@»€gÙ¸G¶7ñ¿˜†?=Ï?§?§i(»Õ[h{É™gEeÿ¯vß±gS úx¬²¢²/òˆ}`µÞkÓø0ÚŠsZ$5ßeî…]7Ý”xÄÀêHÂÒjN ’ø!0¸®óU¬V´ZŸì+wU®M5HæK+Z†•kw³7­L=æÛŠjÐü10¥¨.gxícCwe{z •ÝGweûÚÓÊ²‡Ú×Ê²Gz¨•ÝGwe ôH+»VóüàÜ3š¾‡ýYòÔ9ç´Ë­hàòŸ^”™TÑĿʊ&²ƒ$(S==èÊ>AÙ›$_Ýð ‚öº²OÐjôaŸw;“ù›p’ÄÉÐ%íª”ÆaYä&µi.¦þV4ôÌp×Uá–Oº’ ;a©,èŽìÚD{:Ù½4’]í }8AûTöIÉÎ÷æRÙ'i$;4ªÎ†4<¶ dË<¥:¯=A©ì“´RÅÇ «Š-Ó¯}†v̰¢aó:p‡›D»>áôŒ$1?M«9éqpð†ÄGÛŠÆf{÷eëKâãz+Z­”ò,Žò¨2´Ø!yeE«ÕLœ=½!шXÑÀ#‹âúÑÔÆ8茭Ú`T[Ñ´Jm«c+Åa?µn–â4ÚïXÑê[†!:= 4ÖøYѪ¾«ÄôÑS¯uœE=ôÌ󾘮[‰[ïs1Ϻó%uV±¢u²=-=0È6Ó:Ù¾–ö ²Í´NöPKûÙfZ'{¤¥‡ÙfZ'{¬¥GÙfZ'{¢¥ÇÙfZ'{ª¥'ÙfZ'{¦¥§ÙfZÛwÎ;‡Œ#’NŠVæAYWª7N¨Wê®fe”g›„i >Âøqû¿Í5ªÊÑdæ1 ”|5ˆÏ/!M¬ù­hµˆóUGÑi¼Í°¡laÃdAò\ÕÝÏ3#Û ÈæSÏŠ&LNãXþ6´Êȱ ˜q¢§ž^V4È«£I¬èñu¶¡ÕaF–ÝÈt4¦Ñ*mhšÃHc_"+º›¿C» ä´>G­¬ ü*_×",_ßÓ\,‚FmЊÖÉ“XCûÙfZÕÉSλCÑl=ÄKê £Ùth(»“¬ Ñ"û4 eÓ±Ó3"û4 "VìôÖ‰Þ„†k²¡•¥«Òê'ƒÅ7âm­ÚI^°¹”ݲN o2 +DL­\¹Ô¿% cE«ygïò9pë>0MnoBº­h5~?u“)šúXÑ0UvÏÏ”†¶ˆYʲjSéò‹ySØ¿ÙÐÀW®2{¢{³ÁÙÌëžmÇV"V´*Ê*ì-Ê%ÞmÅU•‡Ý DZ}Klr•*YEƒrøÔLÍŠIÿíihÏ(ÛD«®Éç‘(O«3¶A#ÙOŸóÊØÙüÁG€³¢AúøºŒM‹SNc}¯­"¦nšg†ÉÄŒqXÑ :ÑÓ=Çã:×$±â4voÙ)Ÿ b>j’·øƒÉøËi°Cb, ‹{­vØ̆d÷eAwd—&z¦“ÝK˦ äÝgË’¢¹Î÷ˆ¢­ZÕ@„2æKÎp|Þí Ñ›ZÑÀ"íº"(zˆMô­h5&ó`V¯øzP“„Ð÷ˆÃŠ}”}ùañ$£†ë¦zA£^lE#¸Ð˜ù¾*©«’ïMðÿ·¢Õ<¿+Wy–×L—ºÕ§ç£V´ÚeÈ3àD(fu´Oνlh"»di^wUÉ‚žueŸ Õ—ß •iðPm5©u„¹Å„œ×­c)^ת†3¬³¢áÉáN5%™au˜Ý•¦ú’ µ²ûh¥²ª·¬ Ã.c8#~6´O¾€e¥þ<Ú§aÀ¬h`åvŒŒݸª-ú“×{O½+YŽKO€û'ð!‚ªfÙSšsc<Å;$+ؘ‡)?NHº\ Z9gqõ\¹2ʱë+zŒO™­h@1 žž'8`÷‘ž’DVV4Hí—1Ûë[Ö”øYѪoŠ<‰Ãg#çLZ3â4_~6Æ®ñV4 »fõs†×zHÝ6­h`š»Ãð|JB?ØÐPv(Ã0éöj‚öˆìÓ4’½ŽK¶çCQ§U Ú§²OÒJVŠO`Ð8ÇÁºr?ç&;Â!M‰hE-TVa¢÷ãH~^}63F2Sô°¢U}éZOô²{hddÔøŠ¨³Sjt’F²K“¸ gTöIÈfe'd% q+ì4‚pË—²ú/ïp8 +ZÍ;Qêʨ:=ž ±o“ ü0]¾¨yŒaxHcÿ:+Xǵ+ õ%ÁÁ3ØÞ5[Hó½>.á´èð.ŠÛLiÒ6¬p”~H:!mOÑj™ödDRûG+ÉîxCÚ£²OÒJv_PAãð:«ÒØj·ÑËá¬3VôQöB¬|¯YýõÕÇnÈæádD°¢iÓZy—д“Ñùˆø"XÐj}¿ê±û$œƆV¦"ÑÊk›t%™b_2+(ÛD/馣ûŽfc¼“¶¡¡…t¬ò'ýÈ6&gSV´’½Ú™C•'ÔJ߆ Y³Ò˜ëEÐX‡²Z•ù¾2Ìó“>m²¢6§d|N“GÑcœëÅŠg=A‡“)¶ ´¢•ÍsšM.zƒ Œ²Òv‹™tOm†C}ÊæóS®·bÒC}+ÊÞîLñM Õ,h({Sï{hb¨fACÙ¼÷¤6Ù’ëR³ZŸ[VSn¸ª´æ3œ&gU*ùQO/Y+ZµØ¤™GN£’XÑ0L» Ê(à“}· ް¶ÒŠ!ãòÕO¼×¾ ÙlE·²Ͳ(^;_ÿÆù´\Ü_ͯç÷·‹·WË»ÅíâòþãÍíÝÒùÍ×/þË·'3޽Ŀ9}ñ×o^¼à‹]X;r Éjç7›æ ­žÅ¢ðeÌÿòÚá]¶ªp”Îoø*¦Î_½ø¯Ž³Ëªx“±È©¶sv÷‚þ†_èðaž8¿—O—…àøµÃÊ2/ùÏç¼$N{7ÿϬηÕË—Xø+qñ•y%¼l !ßìEó†Õ>®Ã­ó’¿S²–xu¼süß¾8Tˆò/œÍÄ…0-šÚóÚñ_½z¡j¼ƒ¼þÍñK¸X£¬Æ4Ï,K\Dzx¨ž–óÅ›ù§÷wŠ\ñMÊÃ7ð͆oV5;È¡±8°}·¨IÄd–&¿ûí"¶vI­^Ïxã__4ÿl›È¿H·‘5¿óe,›œ;¿ã%þ™åë—¢7‰V½r¾vèo>ÿ oG®3à÷üû¿«·ý/ð6â‡ü{GÝÿ嬒?ÃJ·?Ù±îþ÷ÿvD£ ç¿¿îÈmšø Ú×KVïÊLöÔ»_ý+ð ºï¯/è¿z¾¾¹¿œßÍ¿Q¼\ÜÝ/o.¾[ÜÞ^ß¼ljZ\nÝttNªAëþ‡«kß»ÿáb!F©_ýóÏ÷?¡”¬rgƒÑÙù×âßï“xUåó}œÅu$¼Egþßó ¡a‡âoBþ-þxþ¹÷«?ðÆÃó¡çù¿:ŒÎÞ¯œÿVÙ¾Ìñïÿ&Îþó«üÿÎE^<—ñf[;//^É@eÎêÙ¹ ²˜%βfÙŠ•›ú#ߪÆ2©¡SçήbbqQ<¿vÒœüï ‹œcŽzæÔÛ¸’7ìè%וåá.:]‘É^ŽìAö컲ȫ†â ¡È“·¯ŸÊ*G8åòÒmÊ «YôÚ‘³ˆ/2êmPóðWù#“e’/%oÎòšïÞ (_ÑÄ™$‰@bVÉÉ›Wy½mþM³äx U¹ÂK›Ïq&+ ¿âkõ(QÎ,H™“¯gWgwgB”³b¢Byídòî zd\VÅ¥9¼vŠÝ*‰Ã¸~%¨ÞGùïü+[”ˆ äÂq…·ÕèT ãu¾vöe\óËk/‚/t&olK”¼z²œÏ ÂÈìð•¨á]óÕ.®ƒUœˆBåky³¬¢ã£ÉW=sœ«Z|Æãgû*¨ø7MëPNÖµ‰wŽÓ"‰9Æ…‰/þ|ִûwÎüv±¼õííüöO÷W×WwWó÷Wÿ±¸t|ç+oæ,Y!›2‡—ïœëù‡Å Óçü§ëðu³|¡ãÏM£¬ø+3)aù§ë›Ë«å‹³lýâ×q&»ˆ9¿2϶xñB¬ˆMxù˜ÇÑ«gëXŠº\,/n¯>Þ]Ý\¿¸•Ó-¯‚Œ×TÚ<”O·ÍÐìdŒE•øÄ¢xpL–rnwŸn¯ïçï?-^üçúJÖÈâúæÔÆ®? y¢qÁ7 ñpÇòÓÅÅb¹<’/HÄM9O?¿z?ÿöêýÕÝŸ^܉½Þe¡$÷ü[®ã²ϪË<Ú…²-Þ†7fÙiø„38;oju±pæï—7/ξ½íVßKÿÕëî•0aA¶+øÅ.B~éùŸ$Ñ®8Ûþ¢ScÏü? Çdþ¡þ9ÿÿ#þü:^g|sæ¼[Ì/·÷Íhpw{ùéãý»¿æ—⌮¾xÁwjá0˜Í¦bÑ †ÐAUá–Od5Ÿä¯²ªŽk±à3Ó ·Yžä>Ž;¿áÿûÛVü¾¿c1Áïþ›×üÞ¿y)îý•¿óo_Hð›ÿŽu¬ê/YFðûþæU¿÷o\Dð;­Öb«&ñ¯š¡ÏÄ|äûêÅ öT3¾n”_`X| •bÕ@è²ÔîXÛMþßÞ(ëÆÿ¦~õÿþpèÓñߌÿ9þÿßÿù¢Ò<ü·ÉèßlχŽ+–Üžf÷èðõküc~gÀï Š}cþ©¿rôcþøBT÷Þà€OF{!ë üžÑ^Ž®¦ß±î圂FüÈpÿµl{—M«–ªLg¿å¯²ÚÅ ¯Û ”{¬Êù!Îø¥ùÇ«Ã,±v^6}!zÙ¨@_ ýîñ§V-zÿê•ó¯ÿêüËá÷†´,ÿØyrœöÖ²ÓÏ¿_Ü_Ü\¿¹z+z;ž ›»Ädøk©ô?ÜÔ¾Ån8w/ª¬¡›÷Ó"|Lûœßÿ„œ¯Ûoo!\òFÀë" DF¯«çt•'‡ i†^%i!Âj9­˜Ûq¾+E]oXÆxÅòææâÓð¹>ùr€÷”8¬œtWɾåü›ŠÑDÓ5bx›ä}¹Ìy×à÷¿æÿL6ä깪YêˆÀü±òƒÅbË/k1:k›w+&©r‡7û*^qŒwR^81òûÛ¦%ú¸è©í§mĵ²õRòéÍ #²“9s^À¶Y‰ú£˜¼¼çͧÌ÷Y#¤j«³Ó-¹(·#* <¾âã“Pq4òø %^:Ì+þÐFÌ/ñÁÛN3¿úÑžùr@ÌØž—ªQ’Üß½»åSÕýrþfq¬)^}²{ËAN—ŒIb\øÌ¹OüÃÏMÕ i|~Áåz±¸„xñkqâ#'Oú³Ó>¼s¡éx¸+wãáán‹ë»ÛùõÃWaÍ Èç­½R¯ÈÓ¢ú¹hæv™œm¤‚HM#rï~¶3çS?Éñµy^,§ªC ýýÕs,>¬ô£ªô3­˜_jxp®ÖÎs¾kŠÌßó0jºþ(ªûY4ëÃ(úúГø/,k”ˆ‹ÿ9—s1kúÿ<¥¨#.>ŠC9rÈ ôb\ð™óËwVÖlS‚D(ÛX¹øb":Žˆ•#×J⓵ë‚Nžå<.zO*W(9TMÉ>ïâRœØkú½X04ßOŒFt%5¡÷²-I}hSÔ‹f¬u꘯X*¾&äó½Ì˜Ø¥òé‡ñTMÇr}Âk¸UùéŸUî’V÷ú Tï¡Ñ\çºÖQmÅh¹ã,üÆh°må´cî‰A?ÉÖX9;É$q¶{r^²³Í™ó;Þ¾Eb5ol¯Ú•8;´­ÍJ¹ìš™&c|ŽZ‹lÙ÷÷zËWP÷÷b¶o§¨3縜c‡¥_-–в£‹†Ò._Ëeþñ‹ÈuvyóÃòþÝëã‹#}úßÿ¡)W,ë§¹¶ôî.>^ %EOéºKÆã3Á0߬€ß/æ×÷óëËûü_Ðxo¸Þüα¹üîØHþÐH‡Omߤ ïhÒÚ+à¦ã+6—Ð}ÇF×Þw,Œ\ðvDjö ‰@#G3ß·»aþÕJ-Øç.|&Wz¢yñÛ9¼±Ø‰¼nMo~s¨P"`Ð#ÀÁDû¦"_Y^ƒ:_|MI¼v·ð뾪ÓÜ70U×¼sò¹Næ—U34WÇ]è:ÍæùØ^³îGnåŽû3ymù§åýÝÕ‡Åý;¼y»ÿ°¼¸ÿ~qK~½ÿa~wqóá‚oö”~ËQ[ ÎÃ>]_-ï.°¨£DñØOW7Td»I…?}X^Þ,5…–w[nÛäê»Üðæ*Ö ò{ð-³Hà"õâœOرñ5Ò6¨²K%>®€M Ø1œáõvq÷îfy'Niïïþôqq?¿}ë©v›$lDÚÛÄR÷ã^ZØŠÝ×Ýضüûû7üƒ£aJÌr~¨„çhµ¿¶],o/Þ9>iÚó,*ÅŽ)âóçq‹ÇEðµ¨ÍŠ•|:l'êf÷*Gåš…b…¹zVM_H[ñ¾Àë½ÙÈ•Ÿ}XZðÕ–è*|*ÅDx}ùSNVÎ×üŸák‡/½ø qÄv¶ù.HçÁGìÛ›«K¢ôh=¨=P³œß~œß‹j^.nyÛu±Sý_%ÕrÛTÄÉ/x82®ÀʳÛ›f[/”]P]qæü —’ÿ&·6{±‹‘ç—ÿBòfQoIGzë°Æ weÒ¬ÌäTÈ+å¸kt\—eߊ77¯`¥5ƒMÀË¡*ï0Ž~œ_|7»gW×oé¯wó[i“@~æÁR˜Ÿ¿ýôöv! „é(C¯\_}|K½GPÇ­Ö­ýÌx@™¿¹¿º^Ü_ÉkèÒGu©ýØ9\: ÿô:ÿ—óÿý8’éµ`ʦÑýJU£ðlÖUÍÒ’·êVÇ#—Ò!Gî[ õÍõÅiµä¹Æ½¼C¯¦Òh¹ÿ¿·rÄç?Çaç?1ŸÿxçþxDÎÃÉäŸç?ÿˆ?Çn#[=’ÿ,¸)>ªãùl”Ä%Ëþçc,üÒüŒ5Ý…ø¹^Þ‹±jq·ü¹´ <þOþ°4xŠÓ]êØ|É™Z[ê>>¬\ ‰ò>o4Æ÷Ey*†f¹:éÜwq¼Ñð}b ,›1¦WÄûù·‹÷òÑc^z÷æêÇÅeû6òe„ô_½z®ù Æ÷sëøIÈêÀ‘S‡¬S,þPÆÐ9%ãóŽ•ÏDÄí-18?%Bèþ¼Œˆ”«ë»Á¸-‡XáÃ+óËËÛCñ•±º4ÃK>Þ.ß¼»—ΟÂsY¨7IÀ·õÂŒ£Õ¢‰-®¬ô÷gL¸d—ó€˜y£ñÛ÷{#”â0Žoýädòéò£¼ó…X±‰ÆÈ2þïï3¾nH‚ªjMùÅÞÇÙcÀW½àà#:ó‡˜I!€äÐ9éˆyVjÙXY£öçùZìÄ„NHj ¿ÞeíþE(à­á6àsâïÿ5¼õÃÕs!®¸gm=¤å7¼c¼•xþëe£i*¿÷ŽJ¢\*”N™|W†¬m"zd&tw¿¡ø_ƒGÊ©’¯Š>Ÿ9 $µ+xƒk4¬ª±$¡Ê‚FèmàK±0à 3 êp‹_—wY~Çx4òÇ/þê>é7º-7-Ço][ëú>è|j¹dÈ…Æ(ŠDëÄ|Vu>8çç;¾W*cqÊWûÏ/¾/ð—n¿]'|ETñ>!üÈ=kí÷÷ð/°çÕFŸÊ~õ{WòEÀ?#ïy‰ìvøŽ*50~Ÿ±¬ƒ²9Hj_ìÙù™·R¼¿s¢+Þ*‚£+¹mÃo›jßjSæ»ÂIYºêTŸðu™ioâ““xé]"<ç¨2®Å¯¤Íãûöâ`«-•ñû2q–Öú‹ã»ŠZqàá».Á#ÕÆôŶÂ8XÜ迦í˜ “Ê8܃:å¡âÍ·‰î4½ÖÕa¾“òñÞúIøþ ÆøíîÿY˜dÒMÊBàò¬[V|¨§Ÿßýѧë*j0…/6³tBQûb6‰EðMOÞHÜ2ÃEûñžÿÌ›|"UܺžW‘ç=Ü<®–—×ý÷I/Ho@_Mã+éXˆjð<Ü—ó¦±%(ÚväµÍAVšØ(³æ¾„a¼‹ð <åüòŠôçXt/oˆkc)2Ê^,œ6ƒzW’:|`Íàl¸‹_&]4%Ž?ž ÏÏùHÎTÊçq¦€îÚr¾ó&¨>Þ²|SÅVPœhý_Š=|TûŒ¼`Àÿ!SüÙ ¾ÕÕ)Ÿ…MZÇ{17‹Ç\™|&¼Žï» ¾Ù^Vmõ29ïødøXˆ¸‘Ò³V[Äë¸ÓXâ´)«ï)ë:NËýhbòá%ÍÄLj¯NEíùCT{ó»‡ÚÃe šÖè`¼RÑ9æÇ©á#±;v‹[”h!>m!ßñv¶xâ ŸlÃðÄÅd·òqÓ¸¶Në¸ýVj «^g,nš’§HHÛÃ@W©œ9ÿó ˆÚ ÓŸ¡7Ì3·öOâ¶ÙK¼k!øénÙƒ˜¤ñ òðuf|¢W_²'>ÖŽW‚oÏ ñÖCÚV.¯—ç¿&;BÊêÀ½½Å7…˜Ú†d¶9|CþÂ|ýÏ7n|yyûæB„=%ï-—’>©¸KÞh6Me/…ww)ïžûCòÖÕv-F¶!š€–Ëwò¿á­ƒ•E)Z»¼Ÿ/úðýeÙ SÃñk<;4“òmó¡—‡±ÊPŠŒw@!·ÙEåÈeº/ʪf¼NAOãuî|”¶tò%ô·Öí@9DÍåNj ; ;ÚytnºÃ0$ÇOk9Œ¯Ñ&$,™lJ‰\‘92HÔš&Ááf¯óTÎ6wÂÕY(ˆ•„¼Ý­¹;mí~¡{o€w ô^GÆØÒßþ¥»„úþç뢶ôíÕõ¥«lÙ3aÜÍ7Œ]ëuöb'¡Ýbä…4;n2òûf_¶‡¥³|N³m‡OËïãÃ-ä›6|sLípëø K¾k;¼iFæÃîÃi‰V¨VRß.í¦yc_œN¢¯…Ý'@„Ë# ^×Ïh»Â%ü‡hgíh/‰v(Ç÷¶»F¸k9ÜÛ^Jù Æ ¾­ýtÍgk¾ŽöÕø»•¼¬ÇÐp¦Í[Ÿú<äcG‰_°¼Ë~~»F!Á›ds#æE%­EcWŸHMÎâéð¼XOíÂBíŸT#_TgÚL <Ÿ2ñ£ è ð)A j–ߘ•‡ÙU^‡:„æ@æ`µ+ºÔý§—ó»ü¬Ê=¦å~б@Ð|ðg5Ü9Š¡ÿVü¦Á³#>íàòxMè2ä}´vÄØ÷Œò×Ç!¯Ù©‹÷’ƒ!¹ùçFíqÜ:Ú#3ÛUH¯ùx&Æ1iÝ#ohU!HXÓJùfòP©Âjh ‹!¹Ãà•{·¼z+ ¾2¡p•ßWÂ*ˆšY„ï¿Ð¯ÍlÄ·YèWi%6QM×(ÛžA€±Æö„F÷âæÃÇùTì"­®ø4½G©p[èð„.u¸R*YEÉßÔÑ7T¬¶Ðá·#ôG ôG !ýj ;R¼G\Ýòb,¿SÔQ ªÔ™M%~Ïë±Ñgbý¦ªÓ?~ZÜþ ŒÁj–QŒôf~õ0j°Q¼¹»úðI:êo>-—j‡ÃAãõÍâööæV´šXÄ*Ò>LØ'% ¢ghÀÛt3Vm‘>·BJ#É#ôææöÇ0ÔŽºJÒ—7æW×XR;©Jº¸WÐê‚ëïæ7K|]ªcònÙ±…ׯo®äºÐ–b~ý'*¯oT1ïîçy_Ë×ËÎå¬×?\v®§¼þ¦{} ®_ Î©4ˆYÞÌ©ˆ*‡eüðm÷+xým÷ú^¿í^/aˆxX¤vIˆ¾[R ûXMïn)À÷µxwuýæR/‹ÙERŠüØ}“'pýîÇ;z½~ªpû±# ,`ky³¼ü–´¡1ÈÞˆŠxòFú- E,Å]·5j”óF„P•ŽT[°e]½í´¬¶Œï¢ŸðàwíVx+üíGÐÇ• Ö(ÿCûÿˆ÷7ôI—í~Õ }ÕÅÕ%X {éõÕð  ‚•uû}§²ÊGø&w:oR§h0™Ã~ ô;°Æ»ú+ôbÇQq‹1îhcpý²;âDtĹºþ®Ó.²@Ü|ìTy^ R||ß)E‡ŒËîÀÁv±\¾{ó‘”Aè<`7¹… X©5P?X\tz Qu,A+Ú 8l ~pTC@u¥£ÚöúßÜÒ^Ï÷ͰʺD€ >ï¾'£ÔdÞE`+ì̉u;'ö¬N«Ïf‘z± Ã?ã–õØÿˆÌ+÷Ygá?ÌþgàûÿÃM†ãñp0þßçcÿŸö?ÿˆ?£wغq¯ž– β5¹¾È³Jx'ïÒ×BÃxæ¼üêjyñÕ«®ˆÁl6vù?fXÎÁ»W :ûEüÁ[oáÆÏ¹ñü–¶Ò—ÄÊû›¸~ÿíÜÊ1üðjwïÎòæÍÝ| r®–ÎÇÛ›ï¯.ù†ê«ù’ÿ÷WÎüú’ÿ}á\ò¼Ÿ_}X:s¾–å¸ðŽ»Z,¥üÕöôv~{éÜÝp™\z}ñþÓåÕõ[y#ßѽ¿ââ•çæ Æ±¸åû™ë»6p“|»ëÅr)ü«¯ùÌY|¿¸¾s–ï¤ ^¦oÎû«ù·ïbã%–ùÀ¼ü¸¸¸š¿ÍK|»¸¸{Ýlpå¿ñíÛÅ ŸÐøõZÄŸr.çæoEnå­íÊWz7¿[ÞðÞò[ò]®x7·7œ÷7KQfaóÍŸ1¿›‹»yµñÂ._óû¼JoEçײH"Œ–¸?úîv.Êq½xûþêíâúb!7Üñ]ôÕͧe{Ãk>3\-ÅCo>Ý 9\ÀËÅ\/¡²ÞÅäe‘¥XÜŠè\ ~ƒ¿Ã©˜"Бâzq' cù´õ¢9˜ó~"Fa>KòÖZÜ)§Ž´¾ MЇ6AÂE‹;†ñ•uÑh¯µñ1Ø%Î÷ñSÌgU137-6 &.¢úô2’áú2\¾h§5£¹„e‡Æ$Šbxë&p·t j=šÐ‡ØÆ #¨†ö²i¯¤@ $Œ{% øÓ"ìqòx1s}³üôQèW_}ƒ‹ª•?‰HÊâPàæîv1¿xÇ'V^wm: ¬AØuàë ~shÔ™°·¦WÈÖΫPÄkyuhãÕ‘y9x%Z“Œ´Ò Õñ’÷ªq!å·£±à7Íø$=Ü‹§ ×8+šhVÍF3ü¼ø{´¦Ét„®ÓúÏÈÿÇîìð?‡\^­ÓâÏíˆü•7ÿõê/Çódž ­ Ö/ùm¯…d9®ýùü/Í߃öo¯ýÛÿ âß”®=M†7˜}Eý.ž_Ê儵ů¾9ÕzÆ/OŒºÒpegAù|ùû‘ô¥|iá·ôªmw¿Ì7ÿßXLÑŽ#×X³ÜæÅó½ûºuÖ®cþï2RÃÁÑç+‰È õW|4-7|üÎòÝfÛÈ‘y&BñF.m—ñ‹š}À?ýLNUžbbT¯$~`”‹2xæ?§h¹A}i'GcyîV5}¥f>E=e,ê³Ù\ˆÉq-–ùBÎwŒí‘G椱x£&ô„ô@ÇòÆŸIúüII1¹DÇ×SÄaZ䛑Räžáo1ïYi8ÍI`§s¬ùŸßÿ¡ë:­ßÔÅ7McÑçÿKf{XÉ|¸ÿÆù+/·øÊá®üæØ^Øküù| ÜþrL!ûé¡Y|<ÆîùmóƒÜR¶yùå¼N û¸âÍYDuú?ì}icÛ6Òðû5üXY[Y®Û9ÚÚUvYI¼õõXN›>qªÐmó‰$ª¢äc“ü÷wxè°4míÝF$ ®Á`0˜ãšQÞ¥ê0™Såt vÛ裟hªMȧÍêÕêj& —ú[::nlpx t²ÄäpöY¼ñ2u¨$ Ç«…’b)7—x<³çF´Æbý­øX¸ÊßøoÅ?¡Ze„ñO±^,bÊCƒ\Áaèå5SÀ7N€Œï‰` ™óRä¶JЇäS¶ø-FCX‚p২Z¬7Š^`4Ç/mYS ¬òû·ßÊ ¬"µžP=FÌüj ~FóTUåS=RfhLƒÖH¬M4¹¼CÁÿe·dáVØ-PÀ#ÍiõDÿ8ᨢfKÅ#LßÙ»S„ÃcÔÀ’pd@)*ºƒÃ¥ˆ‡)ªè$±ªþ¥Ô2ºäã¶¥óM4™Ø˜è˷ѰÙhçãë|Ñ̵úö[èWa£ ªÀÞà&Þ¦ÍgÔCµb ¼b›!§k¨eG„ž8÷®¬¾ùاUU}¢rTÖ’÷ßj{†Z¼AÇÂÜ dÿb ¡gOôÄ+tZÅ”åhÑcžu¿­/ßa^^³ß½¥^¡|µ˜YàqTà1/ò+ÜбAÿ‡Í×~‹Æ 㡦„Èã õD+Ãc3I0Hø¿­ ág<ÔéFÄž.™Q1oPeîŸÉNÑ%“?ÿYÜÇ#×'­ü4ÔÌ@ÌtÔÙ²B¸—±Éׯ°WX+´hâŽ~ ȧ$œä£Ò+ŒØR´pM6\ )Ÿ•1%Ù¾_Ñe|¶cU:ßyÀêðÂDdÈO7š{¢Ñ‘ Ÿ*­ˆ¯Iöèþþ'æÿ·#Ån•þ£/tÿ³öèÉ£‡ÿßÚú“Çk˜ï ùÿ]ýîÑýýϱÿvºƒžh¼:Üi7^6?¡Æ™Xnýºûl§$ÞðÍB³'ã7­íæÞÑÛ"•(/úG¥Øm˜'¶§N!»Ž÷4>áÎ|”Ýr\½r8¾î)'òNEÔ“¼¶ŽÑÞа™0ÉéXÌvéù ÏJx¬’‚ †Â¸²œ˜â^Õa Ugä{ë¢Æ$aÂCpBèÙN¬$óÁ{¯«œ‹ŒtNV7å57IE:žl‹Î¥Ê9SÀOi40·5Ú/j9Xd¹YA.N€$$2}Ap³©„^ÙS.䙓N,Bs2ÖÆ'%<ưígí×p »Å2þÙ¡Œáëêþ0]ÝBKgÁ¸R”cÑSÚ¡p=ަsAçýf¾µ¯ð0ª¾¨Ùž“³ðÖð·w>œ\YžöÚ¯÷š{}±“PÜöd•äTÖ/µÝ|}ÔÜÛjnïré¤ –\=BÀ´´j¹<þˆrsé5“ØÒ@AÎT´«o¿n×wvd¿n|¬2Æžô‡=·Cvtt÷4r»DÊ€/‚¶¢›z$½Ì”Ädàã=œl€ÜÝ…Äx'Ü–d1I¾)6Áå@D²ïë,ì¶»«pü%z|V?ÚÞ]~c}¦¡SÕîi•GÙýb;«HoìcÏHíÙÑJ¤ùW“ö¬ù|ÿP<7®HPÐíèNýðEó9, Í.Ä3ÊîÒW‡ÍÈc¼Q"±duƒÅrä¬ÜhšÞ^šÈ†¶D Û¸•·áÿ®…˜ª\ šXŽˆ9VXFrÕ˜í½æ²Ùˆì’H_ßÓø#é£P:`¾GâH¹xñZ‘"i'ÌÒ3Y³`7'"¤ T”à<¼Ýkx˜ À5à¶üÒ>—¥³ fD2á°óâ°¾‹4SÚŸùƒž6UÓœQOsD­tÚRœPsÕoaºÞÄè±r–s‹Úh¾h{`%·}fKGò2`v²½d]ŒáVÐôû×µõ( ‹vÓ<)šaj¥ªAXggå K[ú‡4oøˆ—,£Ðr¼:ŠÑ1º·_íýÏ«ý£æÖrÜM¹´q%‚£6x_®áÆq¿RSÊÔfUÇÊ[Htû¤ê`Å=Ñþ¼ue›(+÷B·“º*÷€ F}¼õª„Ð\1`d¥ÎÆAŠ2Ö£Ýh=6ÿçÕ6Ö쵑TkñÂ9‚üÅÇ#$%Ú ¼hmó7…)zeGù×MŒä†ušôéȆšõ¨0€7L$R ÇÝžR9Ÿ¾²¹ùSd;ªþÄ:å7^¥zµ¨ ìµ¢&UÍPÉ•ó-¯­7c_G[õµde8yÞò0žð»N˜éª³ñ<Ê™ÄòŒƒ±*’z”æ<]’OEñöX¾t›YSØõ•Ìšº¬ÄU0eJæÌM¶9R’XM+ª)–E³R§“"ª¦LgÖ”rŒÓŒ)MYöo£Ú7y܈’щ~9kîîþúÉ™×F×· gš 1$R*E'¥?šyõmupÁ“-L<úpOVðU<ÙÇ9žÎ9?Á“E"x4] <¿þ^/9%sæ_œàé©\à%§s6ÁK™Ò; x@íMŠˆ<ð-hÞ"»R,ò(X"gÐ:í(R¿p™ÆIÙªSÈo ØsAvލdd(ó` ©[YN: óMëÄèë h$<”¢¸²V}’PÖƒs‰e X:ŒâZ)5y½”YâÑêdÚ§ï¢1 ðЉ¶‰ß'°[ {|”QÈ:½‘®ÔÀü?¯ê;ÔÊ,âŸìù²êÔkdï­e#J¤0c£JIP1r)í&[FÖTˆ¢.­w¶÷~JW#¡öÓç£Ã_—ßÄËμ§VkØ(˜PiJ¿ªÎ(kè:-Y?%wMqR¾=&]ÏÃðôiC“18S.~lêlÀ[žBS3GoúøMQ;Ã1«N‡em¢tér·ÃÊAïd„–´ÈÑŸEì’©8C“%:=<´µRúÇ1Pð_ ]- ‚#6é7K‘㎣D1l<­Ü^óhë™UD’“xCg¡újIÄÿÿWÂþTä·Øy½ÍE[\ù5S©ªÀýÕ¬§ e£;î¨ý©ùj¹É€¢C©[TªnàãÇ5Ü´ Òâ€t¬DêÒ¾0ãXØÝ b #ë R™ÜA6(„0¶‹Yao¦’fniò¯[¿ìnÅZ ¿#ˆœÛ*œ(”6±©£IS¬ÔÒˆþ¦©X¹þ*†æµ¶¦þ»wT$ñ®•$~D[ÖÇ«kEÕ4ó«®Î*¾¢©Bpïm7ê;;ý½ŸÅ/­zý`ûÏ@O“k\˜襟ŒSÇVwMÒ›W‹¾$Ôãzif¸ ãíj£Òž|ÉâªØwÆ‘4ú³wœ´rë"t’ÔV7§f2„ÁåçˉîíçÈù8í¹@‰3²ùsc¦ÄvJj0m’²Iô,+-1ÐŒÑ(&RMEcR¦oÎD(cÌŸî`.Y]¼´…Fhyîd¼/úñmQ,Í,ÓfZ¦ÍÔ¹º-tä.¶®#Úá(@Ö”7lé#'¶U Úˆ‹iÒOÀöE˜,i\†áxGÞl­ZþÙøT(d /‚weâ×9fwû£ÀØ*…°z¼‚ÿ?+¼“¨³>Uù:–ÏKF³ðøKAˆjù7koc¹R,éçs‘GÏWibú°Í ’XøTmÌô#?V÷p®êBñˆ%On]ëwXé£ùúø]vmjdiŠÂst&ÖòåØW’‰åÍ<‘Lˆ•Ós)nFôÂJGÄ*Ÿ¦e”"«DLl´È™5iU¢  Ñ÷Ø×Á¿SêˆPú7æR«UÔÙý³«Î¬5¥>gž™ZT2zDtu*†X"'Ä•µ[c¦jîÞ\8º6Gï ¿ ³äóF·ç¿xO“‘Fä;ƒ8‰5œ´»™R]od Ñ‘K»u´XѼ“;¬Ø¡¬¾F)Ù.ÆæEO}eo€R]¶EÖ!ä~úã’À0Úª<ªPø4Œűƒ½«ŽG-yej7€®/¡…˜kùMFà *™¦0÷|tøªq”Äëéƒ)˨°–}[, *ýg }5Ã;ô }CO÷ ­/–F{Ûmô}Ýjì4··îd©  %y­µ@£TÀ¿fÙ6X¥¦‹çÂüH>¯³§¯¥LAþ¸ëRˆŸ*Ð?N;LÈc¤0'NÓaˆÿ“ p©£¥,õ˜Ê\ÂŒàú)rÊ×aáæA² U—ÒGo­øMè–Ä74]vsGô¦špÓÛ»n´’F¾wa´˜mOm¶Þ)¦5Y kä¤"v™¾š”פõ‰æ¨æ†Çƒ\Iœ¹>¬¢÷ ¤õð¡ÑC ¼Ü³&ŵC¨Çz©lì)ìêûR|·D’OEíå+‹=ŠjN”Di‡òšELìm—aÚ:¾,äÁÝ¢,w‹Ø}Î’h^ùcr_Lþ#+h6rûÔNT.69öôí*õ¢Èü 0°œpRËeIÃñÙ2zM!g)dŠ_f•4tŒ¾ú/=á†á¤ïéÒñÙ@1ù†j~ÉApIŸÍˆ2á+7³PÌÚ³ö¿ä&—%µÜ5³²÷-èÝ4[ÙS¾H!ÓöPÊy8Ë<œ–h8Ÿ(9]^i)—§W:UÜ7g{X¦žqcØ#“\Öó*–{{Ølü|GI’.¼Îйt’PýHÒ’L¸ÒÛ¶¾P… –BNäû.C?I÷G*'-¤˜$ýù b W¬÷õØûCÝ'+ùQJªBÕvé°úÏ®ç­Ê›G?OU4¬‹˜Ê¤`泫™Kiª¢Ålý£?úG∯ ,Ó-Y¿Ó#_DÐiÙ&8Þ.¦ö…@Ö÷âB3½0Û¢ÊLM £Q1]!?MÕÄÐRU0è+Twa()„Rû!¡\¡@­¥džÎ4Ý U޵2ø6C‡#^äáBê)&°G hbdÞééñœG c^5Œ¿/=ÑÁÖ?k}ƒz žÿZ“ÒžiZç!­$«lz!¢]y½žJB?¯ÏçGÅôkûl•^™×þF®uGÆ9ò=S´ Œ|¦+sÌXó€†%ÄëSŠ·2M» ]¿ Kà ›(³`L‚1QJQƒsi5'›S7H(|v „9¨•íçwÝj*'rªï6ºFƒ§+ X5MÑH¹Ÿ‹s˨E°À$Ö<õÆ3Î}/¨h°ü‡ókˆ‡7€ÿh%‚G‹ÂÇœ _›Ò˜¢äpÖu,Ö9ÿ=,aøÔ X‹q” =r3j-©W%éaH,£Cò€1ͧÕÜÛºÛãn»ÙwÜÕý¹Íq˜ Øz_½GÇ]+ùÆÇÝ coª±•LjO„^'À솵SšëSOϘõÏrzF,»?=½§g¢·==#…OÏ\hæé³ÝÍé™P1ýôŒŸ¦žžu†ÔÓ3}÷ô¬@-zzVåÒOÏÊHB§›ˆÒÏÖ àœ­°;9[ëѾ?[ßáÙ·¯élm¶g¾³u´Î¬²é…ˆ²åõj+ ý¼n^¯ávöI+Η/x°ÆŠ§m¾~áƒïbð?ø.ÿ6_»š¯\;?™f¨çG%óâúùô9BL© ŸRÍÍ4ôcµgWœVåM•ôí3`ÉìŽm7—zþú ]Wªû²€À*!¿U|ìéü²¢ÕSe?Ö±çf²}<ž&ûA™ÕóÃýÝ»Ww8ý?VåA÷ë¶j(®ú`¥­³ˆ& „èÀd$2=1ê%aNL$DãÙÒ€ˆÀ±Ø Æ~±JƨæÞè†÷NÆ»·ûFƒbÆ3ÔÍáü]qÂ!âeñ™Jغ?“â"è½øèëV¾ "’áGãjîFª\p.u Ìzw*„¤Ùjøy¦j†Î”©žA9QÑP o¢¦¡Ê.¨ª¡ŠÝ™º†¸˜X)^úq¦g‘˜ô,™%~²†'¶£‰Ê¥+±öRËÔCùDcÌ|B²Ee÷Â2½•mÊ(f›¦ ÍâJ)ýHÀÉ é{Þ¢(%a½Ïç¹Ã*ò0âÑâ Ç@<)nf˜&ÂKž*ÊKäž¡.“ìùt`"ÿLQ`r`ÈÄbO¨ÀÍRrÇéù#eB¡¤BO‰ê-©Ú§Î_1ã[–ÔrÖ.Cè>Çp5†ª14´Ç²dS.«ÝéJÈ=SeŸ‰ŸMFº$öüAù<¶$ê€f§ôàñ­zðø–=x|=xr«<¹ežÌÛƒ¯ïÆ+…ž)“=‹ÍN½ýbÞwšâ³ðÇÊüŠßÃëpìõõÕÐŤ7ðF Vô‰ûè“€vk¯ãÞá«0À œi÷jXÑÞ~kûÅ^}çNœûXÓ/aÌ,Fx•¹/JÒ¼äÄaòõóö @©£Û»£q÷×(w}J‘Û”ž{V3çtVTs¦§„¤±³Í3gf^$œÙîù ŽYŠú?¯éûçh{·ùó-â±ß÷.Üž¼ÈXÆv½)—©ð,ïE1ÏB7¨Ÿéºûògº"/Bä€D”…ÓÛFú=mI§-wèú Ñ(Yˆ&S÷Šò s ]Âȯóf¾D ‰·¢ziäÎÆ01#>hVƨøßÀö­ÆÓ'øÁHÏ"6ªN!ŽñŒ3È£}iSŽùI¤M–¦ÒGöê·ý¢]?ÚßÝn´nM•ÒÖvÇAßï´ÇÌ%[ºBx7N….¼‘z…©s{#Ïí^kÏK.rÏèªç¥¸ö4žÉ!ѾQ.Óå§ÑFCqÀròiÔ0Eîlõ{1ˆúJ½‡îT¤jƒ(ÅÒVf/ ÙfcA$ñŠ;fÅi¨µdË–#…™´Fg½yþN j3ÛKâ\L¿{ ÇІŽn‹Ýn][Ë>Ý¿R–Fˆ±® ¸mU›åE)œÜe<Ó•S¶\a ˆ4E”¨ ÇÙúl·3Ž´  DÊy6‹¾lÆ‹Þî„éòmòÍ8Þ$c‚‚;è=_KIâLþÐPÕpà©Ôr1 ”&N½K@nºÓœ…I£[§.L@tSxUÓÕiÊdò˜¦ AªÆÕ#áý>ñ/Ðß8©¤sµ)WŠrP,GªfÙŽæ´ŠI/œåè(!•L¬/–šIòr+Vßt½’LÊq¢ü[øMžªZ‘BîŽ]@ ½RÅrn­²^yXy”‹ÝóÛwûñûüÌÅ›Wë M¿Œkí´p t×B:‰ôÅøîbéã23$oqa-{nGÒ(ELŠÉ[–•©‘@uÑ’Èj­Eõf5]·õgŽE~…-ß|#qƒý&]ô›µ)“[uSØ›çî#âüuèkRt=¶b4ãUŒ1qµµÿ½+¼¼jQÜØ’yÖŠ ÊÅMAö¼âó/Kÿfñ  $K¦$'{áèÁ¸;ɾ˜ËèÞ áºuGg¯;­â„Œo´8ñÛ([Ö½“ÑÝ#®¾“dqÁû{{ÍÆm„ï?ëKº7¦ð`0ð³-Oò² xÓ‘%Ä# ÌÖj–CªÇL-niW‹ªBÂu‘}¨Ëƒ»1›HJ%E3Ð+ï ÈCè_xÀ«žÃVÖ¹§¨½R9¯øÒ‰Šê©ìW#ŒI˜.q RÆ;Uâ‘Lj`PY½žw2ÎaÛñ0À/jûêm(•7Rb75²vžžñä„rFÝÆŽIÛ%Žíé²lyElDµ.´ ¨ݪè!O›,Ïíœ;|€@÷A£ ˜; §m•jñÂ×J˜²'Æ Ò†Çñô)6º…’êl7÷Ÿ;oþýÏ3¶¾ydHc\Î/•Ä:”˯Céµ¢Cyq¥¬ÄþÞóí¯ñò É·;ͽ[Ýæ?G*LÆ"œøc’Ò6ùC Û@º)3&‡ÜñøÿõJ0Ð(ødÄ¢yäÈGœ2ñ—ðÜD6®âdâ÷º:Òº0WM6»*âIõ”°•ó°J$â„è•oºÑà‘zˆ>žº¤#¢±7:Å«·—åW¯åu[ËÀïœ Ä[@ \FÌ5ºJ‘¨àu…®Ž E£Åe®#‡õäQù™?†eÜÅÁAq*2cš(–ê]•åÕpâò-I_M€I2+3iÔZ„Ðíeˆ8lÔh¶ MÒ ‚) Ne,³PZªráW| NÛvÎ ©|² Å Õ¼£ü¼žæ°¤@l–!ÆÕúQ£ ÍÛO éiøšhI†³;4S1dª“‘©üi*®;C8#,·6£ezÆh;owÑ:\8©Þ2p ñÒ@yþ€CÝЃÒ3/½_ÐÇ› µ9>Ä Ýp<²UÛl>جhUyr…2Ť«€$S<‡&Å4]@›B>ÈŸt$L9 ÍB¨¤yׂñ"D I}qnìÖlfXâugKæõ”cIBæ™ ‰J/8ÔâãGÇBÞ`½gX¢ ,I8+Ê.+ƒÔ"ùbköD¹Ðx‘• ~Òëµ™ÇËÊ¿óãÜšâ´ÏÓD°x¼1`·ù†¶V‡-‹tV"Ç*Ï£‚i%7²ä!¤Œ!¦ø^¬Ô˜* #,Ë|,¿µÕÄêÉV¥_fOÈ´M‚ $S*7ÖšH›öûC½¬k¹¬Âö¹²iI5ª‹€EòA…¦ÃåIZ0—šyeÄÌr†‘è¬-yƆœ7k´›¢(èÚ‘I[Mä_ލ)”½‘Ëí’E¬kdÿkbC”×ÞnN½ N±§ÞkN£5º¹D‰,ª“@÷™·£S·Ô†¥n ­Îl’N§»TÒ#輸§ †Zèñ%žzÖû«} h¿Œ ²âëz6,ãš*˜½˜om¾RJ[0Ŭg¬oÿyÊQj&«0lkû§‚ÍB½ÈH ’t=`©ûþ¶1eH4ô:è¡¢«.Ódhy€Œ>ãŸÀµ®c÷j#qÂæT˽J ²Ï%¬í4˜ àì‹÷£„ÅøŠmL¿‰`hÑA4%”Ãϯ+U¿£Ã_]…u©Å4àòëò hh8vO굕ð~Œ?ñÍ4%P+邬çO8¯æHDrÙJ¡ï¼òSlòe¦A ó<Ьä˜S[Ð :t1É7ž ÊUa>øÖ¡ïW ʸ<×’ž0»AkTÄžçK›N^š£¢ÖŸ= ‚X6 IÁMèà½$BFÈÞP0eh ;2¤zˆ2Ф~0ö #À¼• ˜nN^œŽ/%Ôú“œOŠúˆ{#D®£YÊþ`ᣗÛ-ÑÚ~ô °.žáÜýóöVsK<û>6Ecÿà×Ãí/ÄËý4Tõ½-HÝ;:Ü~öêhÞ½«·Öv«P ¯õ½_Eóõlç-±(¶wv¶"Tq Ñv³U|?ŒÐWGboÿHìlïnã…ìÑ~‰[ÖL))öŸ‹Ýæaã%¼ÖŸmïlýJU>ß>ÚÃêžC}uqP?<Ún¼Ú©"¤ƒW‡û­¦Ànm·;õíÝæ’í=¨X4nî‰ÖËúÎUzØ| Ôr«›Ïšl‡8,®º¹µ}Øla¢§Œ´n§$ZÍÆ6>4_7¡+õÃ_K–P ¸Ãæÿ¼‚|ð]lÕwë/ sËÓ‡'§ñê°¹‹ ÞŽpZ¯žµŽ¶^5Å‹ýý-ju«yøóv£ÙÚ;û-±W­f *9ªcõ† >Ãó³W­m8š¿½#8j¿:8ÚÞß+Âtÿ#cP‡Ò[4Èû{Ôg¤ýÃ_.ÍAIüò² é0Ù{²{G‡u8Él7ŽÌœP+Œç‘ÑY±×|±³ £Þhâ×}ôËv«Y$Òv¸ÝÂ<Û\ù/u¨ùvŸ& ÚÆ—hJÅösQßúyÏ™ `D¶%Þ@jëUã¥ýŠÚ™±ÿ „Ë=T#Â’ÒQI‡ÂN'ô»oÞ"Ãûï奢ÞȾ‡Ítù™7zïõ¼ë¢xT]¯þð(·‰å«•Xº«~À ¥)ê¬FÚœ•–3ùÃóœãàM‘ðæðbg­D›)ôºIh,æ…¡{ç" ½. ä\Å{/Gù ßÔÅ]ïŠ9¡KÊîèìø‡/,©+Æ}o”TI+·ƒdHj+oµ/`·íâÎ Eå "(Œ»íx“ŠÒ£Úû!# »X7¨|Sd £V=qQJ‚õ’‚¤}ÂÃ-õhijúÌ·¨'V,ü«`}©¾P_6Œ/M8™¥Ç(ærŠ}1&€9Ìvà"ñ†Vuª4Lº}<^ŒeP‰c”ÆJa›€2%2•OŸ”vñæ­<ŒÊo CÑùàÞ+ø[Ú֨śñ;:*9"=oŒS"¯qß”³/Á÷üÍYžïÀh{fDÁWúÇjNÅÇâܾ¢øm2ì¢&Eˆ2>l‘ @¤ñRhü°ï,e-ˆ³Ok<†XÙʲ BÎò¶ˆ›…ra f­‘KÓ÷[nî?7nV?YõSé7koÅ7߈•o¿•ÀTE²‡$-¹r9gv ÿ¾ý–[·yMú$æýKLaðÞ½þ—jvkY¯hZ<}ß~K¢oµLÔµ-À ý9uÎGˈ¥%IŠTfïÕÎŽ9ð¸ˆôµ‚’é4Æ«;((&æǑԞ²Å%³,û ´º¹À¨TŒïÕ8¦PT`‚æZ,©°wÆÌÉJ#2à ÊmÄ*b³§S"¿§Ë@ñ¡D2æDîŸá†ð{=ï N|r¶ÊeñÏÎñ Wíös¼CiëQŽš¡úAôN¦Ò 8ŠS%Û•\AºN©#i2f¯HôHÊ3»ðp}Òå³Zh·dÚ꘤0Ó * Äfˆ+,¶uŸÔ¦eADu0‰ù±¦{c ƒG1°Ù«™ÚMxRKÁ“ØdÂULg„KœÉ4¢I“Zò¡5ÐëR‹OÁÄ,l´©(ï0ÏÌY?ª-} ÒpRµWufj‹º“þPœ¸÷1r ­ûäÜ^þ×y°1¶Ÿx£ëÊÃÏ.ÿ[}üøÉ“ÿ·öðᓇ߭>¤ôµ‡W×ïå_â¯rœsà?CµöÃß«¨Š»°Õ¹sØ!ÇãPlCè1zHp*޼Îù èg×G9Ðg}錥D2ŠKŸ®Y S‹8Xǘ ja)d¢ÔÁ¢°ÍàZ '£ar.%ÛÂâ§ ç0l 4ülä⣔"׊I}¨0K~PíÖsIˆãöz˜Å÷ÂHmô$  ê½§¦|ЄHÚ‘„N†(@EeR,juÑÐPUòäÝÊv娢 ̤&:•6%(¶™œôüžp (p£¸¡%OR<­KoJ‘à†Ä8¦ø ÊõÝ÷¤—OR5`‘e7Ba)‹eMh¿ÇO*LC¤«ŽÍ* GÈý™ž¶p`~Ȩ¥Úé]a}lmÕöP2 Àpƽ|%vج5Ûÿóªyø«x(rk߉úäL¬¯®­C®ÖK±Wßm: Š'ŽË°úŒgÇ·ç•áKHCˆ^¶9ÛÉõÚ Pë×½ýƒÖvË© N-4lëI‡ÕD=Ëæùêøt§üøô + €\ÝŠÃpvN¼ûž’KëÁÂÁ|Düîl £î< ¹OØ)¤@e®ž7˜]{ß½jOºCº‡ÜE§rêÓl5[Ãm"9(y‡¼Éñ~X„2‘Q‡çM¢I¥S¼šuGÍ:`&Bº#˜#Üh£ég>9 ¾3Z¹d0j™¯I@ÐpX ‚«•tË¡‡ ñcÏ=vDn礄.5Ûeƒ¸À¦ü%ºä .œCý˜ )by7š±Àáv¨„.± X â8VÂf-ŠPˆú(mO:ZȦ Ñns×Ùõ ,bh›wuÇ4œ0»õŸëÛ;òbÀ©w¥éŽ¼Ë†cÐje•7õfSÔwZûù1XX¢m¢ð€/¥è‹±Bb_$za*×þêèåþ¡óµë‹À‡_FÿcõÑÚãïâúÞŸÿþàóß–;ðaíµà,pâÎîy÷‡¼¯ï÷¢y„ºt¾[»îø%8á­ÆOx’¦áá¥õ¦6xϼt}4Mžé`sIë*øAîd¬µáU°z€ÍÌâ)•aoÜæ³¾ðiN³Ť¯’‹›Y‡͘Èz38åÈ÷Ô±y!ÒËIô˜¹KÅ"Æ÷”›'ɤÉ1‘ÀÜ®tÏX•ø*yrǸ݃ »Q“ ×n‚¸Ôb»V9NŽæö1þp‡ê‹¨8­”^H>û©tpã¹"ϵÍ);ÆàW{ÔϬÔýñÏ$ Iÿo°Ð+ð8¤“ª‡éÓ%Þ¡U±äý*"I[~Z=“!ùÑy¢,‰+ì[rDæ×Ô€ÜÐòyp 39’Ðæ©‡Ñ}€wM:Y!®‘k¢°PøàÈÁQ/›…“˜‰4ØWn!òppÖê»!;¥'×n‡×»Zø§Î‰Ìúuû¤éxåÜt, V:hH!` }`=Ö²FðŽw5FŽŽFګȾw½á°„E^“› ½[½÷jdzºb¯Ç¢0¸u„Í0G´u騗²ö^©¦×~جo¡ŽÎ2 aXÜ( z߈åµ˘T,¦þåpû(³°ÀÒT\|+޹ïZS ˆ $lœEfÙM0Ä+kü0:sBLŽñÂÝ0–"éñÀÿïþïkÖÿÖ#îœ5þîñãTþÿáãï?yòPÝÿ©^[‡)>Gg'öž×%_u(ž\ZšéŸF,-a6ñºa89€ juH—Ø€_2Û<М+²·áž£ ·ÐPí¾ûÁ¨VX+LËã0ÏjÁ¡lg¶ý¼ELñN—½ ¼KŒ¯€#Žàèk­ 6ä©УÌV+8¡·]™9ÏóQ¦\T' i. Øýÿ2{qâ»>)J¼¦ÚѸVhœF»¾³Ãöªþ¢I/p@AtÅ4ýLYÍ/˜[Ö‘ZŸ;ôb5AS1Ú$ Ê VиÚÇ{Û{/6 *‡{2CÕ®t½‹<˜xýÝ,¤}¹!Ç\º;$Þ±€à xýÑ—ÞoŒ f¤ ~é‡tˆUÉØw HƒÙ‚³ÌqÇiìåלxZízÕÁòõ§ß¬½+¢B’Yœ$›aXpØ}å•U˜Ž%`u€Å¹’ùX½dÃÑ6¡ÒV#]Àù½qJaKøh} aM¬¨urpâýÖÖt‘7†:ñ ·¡·Q±¦ê&kÔäX¢AÚŒ%»üAÙ2Vv¿îf¬êG/ ѵ ¼ñ ‡ aý¡ë ŽôæVãƒB[ã’‘øÆPjC*+-=rïfÍw ŒŠÝ…»A›ÐëÄdÌ"&ÜoI©U^xò<Üt|’Ì:l}(+{ÐŒ cC"ËÆbø8ŠY×c)t¯o5ªg#ox‡Ãº<ß`b­B—ú#ׯÝÿ»ÝñèÖc›Ë`næÓ߇ßMžtwyÃõe› cñx$Ê]‘#ÃÚÇO¾ûþÉ*å>3›q׃|Ù¹3¿7 —Q¾´ÒõèÇùÔÅÿÑÃnÍ]{Ç&zŒŽ>É·çQƸön0®Ž¬*ñ‹õÌô‡ º50w0êxn.£ŠÎ˜…z’‰j·šõÃúÑþa\çâ™ÝŽ5<e¯?„v S‚ƒ¿$¶üY¡[ÐÉ`µ‹µ9X+Â…=þ³fÚÉ‘éú# æÐ«®ô¬¡ÏÚ6ÁòðÏ&žêjhÆD±xt)ò¨…IÿY”?‡:VM4'*)ç? ÔòñÒ1ÞGƒ л$ôúþÔA ³eó«‰ $Í;(X:mPD4(ÊÅF< p@¿‹ø`j‡Kâ0º=¥¡Äë{ãsÔTÓºc!ÞõŒ¼pÒ‹K´’¦5r‰ÞNÆA%…6ÈøïBš;ᳪKúx©àFëBÞÀbT±Ð§èy±H.ör±ÂV‰Ö8Š.¬„ŒÌ€ôeE|¥^p+Óf‘…§¾#ý“ ÌBb[d~Fâ6´UŠa.ßVLk0°†#9¥gãì)Õ¨‡0Ûñ “ *™6´/¾ù'ƒï°”âDW¢¨3ŠÆe#ëG ¬^v£¨ÕFpšX[86MzQ³¡ö¤£Ô&Q”Çò¾;̊šx!ø?ÀŠ÷À~Ï’¿ñZª®=`3EƒRηû()#‘“Ü&{R;u}¨¾2T‡¤ËÛ§¢]oñ®ÿK}ç'`‡GR?_šjàýØd@âq v@ŠX]¹ á†P¢-í„x!z”÷j|ô£kÜJ‘ïÈD.÷@M”¦p—€Ç—¤²ƒnº‚à½ÒŸ‚MþW१t±Q 0â:ƒ€ì_ÃhÖø(_e<¥íéÍñqõíŠ(Š(|—ÇhL¤Ø8öY)Îüþ`h™œèÈdÀp„AP¹qüX«D®¾Ë#£š_U™TõL?fë½òD›¨ÑÞ{ ½º¾”{³ÇØÀ¼ÀX/ý ¤pó'0‡×8°4ç£Éµçß 7öwwë{[ã¤j(ÏåØ4Z¬ ¦*ÚL€…Õ=AZxea=¸(T‰ˆò)†,¥K¨e~U׊Âô‹ËŸ6ál‡ÝaS#Tr ƒÞDE*AE?ÅöÊÓ®Ì%ñ ±ÜÐ* 5¥õ}WHI`Ù«œUPOv aùaeU¼úe{·ð" ó3Xu†QÝ‚á&¼^YeÎRä>~” Êᢚ Iñ”Ô®E®åúÉ.°Û9íІhÔTX^Æ+X¢HFþÙ±PQ“.ò+땵G…̬*L»~sïgÿíÖ·wè‰á‚6š£«ãü‡<#¦'G yä Ä2Ñ !ó…îS‚ÆüVfÌ»Á2„ƒÖZ­ò}ÐZ¯žÒãZá[—Èbo§% Aƒ^]Ë‹ñFìö[_’7R.ÂEc ;Wqd{ùuJ9¡ cr°u“[ìàƒ¾©˜ÂîÌBÔÑ 4Bo§@Z™ËG‡B.iâYÞ68–Ômz0 Ia³ì]y Ô 6ÒWpi»Dc‡0Ìü‰W@$¡íj%²öE»õ²¹³Ãß fÄ._úeÙ”çã_<µæ®½±r@⊮×!LäYK"$zÎ%Ê.ŒßÀ›ÀÙF«=ÐÖÀ >X2ÔL+ûf¤éîöBd)Š*!¢<²ˆ Fñ¢hºÐi?úµô„*Ì_“KCQ¾ Ðå+!]HšA¥nÅQ«¢‰pí7‰=*ßü1˜ÜžÊJºË;ÔÅÊÕ p1ðï…ܧàÐÖÊWr›Š%ËÔ++Uå5Òô¦€s(,T •‡™,²JQòÛeÇŒ½k$ þÿûñ÷ÝAàwKh¢Šv=JÄ·rfN\O{8Ÿ­ ©*F%}‡Í)Tƒ¶¯nˆÈ¨Kã¾ ”Ãa¤ßPòtÐ&ò²þø±v{N{-6–èa«ex(÷ Oíx¨&£°pr"ByU©¿ñ5±)g1¶ >™»Ý¾Ø†wBR‹v$µ¨å iÄqî8)8þ#Ç8÷؜ߡP‚Z€“;?Î%›8NNßt"ÇS£Â¢ÖrŒOÊý :¶Y&ä:ί7Å'‰oòæ‘3XEV£LˆäH÷“™Ö¢LbCKÂÁ,,Šƒ­C»ÇÚj¬m°“~ú+ÊÅp…ÙyxV’m¬Ë,¬òDv¡éÝ™Ö3_¢f‡§5ÄÌg7å„°“^ëmñ Ö("â,´¢^J ÷Õ"BɈ†±:±Î$RwÉM. •â“$«ÄßPW…Áï&†`ØÐ:ÎHøŽçÀAÐ^«å6­¯yó-¿³½×ÜÛŸ’#gÂrkDz„cÖ±~‡u¬[uïHJ\0Ú0,F[ ôœ:dJbß×­ï§]ƒaB4ñ­X;~wœÓAâ“rœ_^kXZ Ë6±ndÐGº,jÿ`JÎ,'i6^î1‘哌êžçñ'ëßyó¹‘Û®UYzðÜxѼ)¦ñ—è4}œ{}lÈ%P… ¯å{N+㘞XA)ÍÌ,Z´W-Âpb ÔV’&}¤ ò Kí9×^¨(NâÛ p¬‹+:P[Y´æt+¢E™Þ £Â9„HB) œ\ ˜-AÁ|¬€’×Ç’o'-ÑØÐ1m¢FÀÿ@TQú¨b6¿åJ·äç|Êfiúcºâ~ "Å]²‹3Otj(‘F8ž]B´xC_ôxê¨È¢Øv, hdò;LØÙ%)Рì9nVrXÉl\Há<`öÓx$˜Çœmpj`¢VsÍêf:š¬jMHÇNjõh®F;¢­"—Xwø.òŒ½…Ñ’QxbIò‚¼JdÆ#6’%·FŸÒ¬¡W¬ÿmÆžkšwàù –:ê§>²2I)_<è[öÑžL+Í<¶ÙÞýiþþ4ÿ•œæõ9¥±&’§ï{(¦ÒxnWKöQÒ**rç)oSI‰3ìÃzšK€ -!·¥¨PüϾlŒVÉYÛs‚)TÒQCØfW³=Àû8½Jx+Ì;WXq!K‹I鎬às)`ÐUÃðläÊ ñæQåaåÞð¢X`D Õ7„vპ‡<æ«æ³²+mäþ}6˜T‚ÑkYä= yíÆþÎþaûùþa£Y6kŸ1´jŽU[y¬,ÙV{¦nN‹†â¹´Å§)çp9yÎæê®:‰ÌH«a8èÆIg«8f¹evêþOŒù5-t˯m~rH>@ï5££ëñŒ?vÇ“P´ŽêG¯ZN¦A¡4ÂËÿ Gž3—ô>…Œ†p`eû¤&¿æ|ÉÊ£¶d7Òš˜CžyÕ¼Ê%×0"ÛëP¬æ™s$Üòr$Šó®ÆS*Û‡Y¾•ì½ÝüšBb«ñ˜5»ÿÚö0Þd¼1aÛˆEg_[ê&Ö\Ç'Õ <»Pz«nn:7/D™ïd‰ý¯Êf$FæãºFcðTFxƒ;Ÿ¬yAuÍj…5tyŽ·€FÝÔ&jÃqò;¶äÍrµd”“ «…ª>Ü Õ3Ô_K (‚bö&V53WÈËÜÕ, TŽÊ;™N^K`šÁ›0ÊG^GÉ¢ðu%ÞüV}{\¬Véÿ[©®ä âø£88Q Z=.b®é9¦8.ÒÇŠ­/ÿ1âŒ"¥·+ ÕߌæWÃs¾úöª_«òóïøó ÿ¡ÂXˆ_Y™;ûœ€‹³@†UÈQ©nŠß ïäÌ%qÖ¸Ô7"ºÇÏÂa„Ü9Âl '>EÇšØr«›¶S u9ÉQK;ùHƒB•ÃED0Èro¸mÁÂBwçSéë6V?f$cÔZS€„ž!¿C×ñ 3àKRÖÖrZl L1¾[,*ªÛ‹^°€o]†ÝÍd6¹b΋¤©*’*£ÎøQzÞ‰4¯ ×€”ÿx÷½‡ è^¸ð錣ó¤|ªöå9Ir•èÂóR¸}tÒõ_t½ à`\ÎFÁ%:ݼðFN2ù0à.…%bwPW\¶i|=ô;€¿OÜîˆâ¡HÒQ¹rý lª6{Z $u ):âKx”wËûýÚú¦¾ô—7ôÀÏ®­gJ·XÔkÿ2š¨0–Ûú·µc Ùù©`È¡¦€üù5YØ.aÏp„¡ÀUAŸë‡/*•Jêl#\a£¼}Ç k™ðáUz‚!ëù“—Syœ$cÖtAß ½àDî6Pž§ÞžøØaV¸@Ê‘¤{".€J\ÊIîy$øˆÎˆ`Ë^^.©)HÏÍÙJXÏ754PÆ@s'j,gÍbÚìd”QvÿŽÄ+@kÐDcí]b†c"MÌñ r-ÞðµØÙÑ~¾õÖ™í˜Ü}>*äÞ¡(Ž6Æüê;­&DäH°G‘ ÈÇ•¬˜«$‡WKÚ#\‰äêB´€ P8I¾®7è ßÃàä¡Ä“ìêòðyÃâðئg¿¸¤£+V55¤Z$Dqp¨Š)ÇX§ÑX¯Jq©Ì¶fE¨}S<å«8·èçr.ÿ0÷ɸÁ8÷µø{>–?K"çåm˜på-Ð'= ùu<ë«À¶)¥íŒëÿ˜mÕ]4©? s!BEùŽãeÙŽ¤øÆQûkî5c.}e£#`7*(Fš»¯W¥V–Ò†Ì5üÇX”&¥â>µ`Yc°dÕTù‘ªÝÊÉ&Ǭ1\ÍYz2[M=õëov‡hp‡ÕwFÕšG€^V3t Åh|ùkT­¾D5Óô1[jv-‡JKZ¥$ñêñrÄÔc|èj&ƒ¹ºoɵY|%Ì´]ñ|üdu±z&ùÚ"ØÁ‡Év¤†"wèÎPì‰:(£6ÇY k÷¤\ÉÙ¹ÿï{ýA0ü}Ž'—W×ÿ-Ȭ;Í££æa«V¨?kl5Ÿ¿x¹ýŸŸvv÷öþç°uôêç_^ÿú¿:«„š·*É[pdÖ®æ¡þÈ[q{ƒI_ر@p!’c›ÜyEˆÍ‹êô{êdÖu3«qÝ̨úzX]ü*+óV8ú]3箘D¤Á=—l ‚:}.‰g=\ ;ž'š±ÛÙuÏaZ—×~x¸V^ûáûŠ,.÷º…P„ž½"ÄF¹è0Æ–R‹}HÿVßäßrg«xœ-ˆ#Y¯‰ç*î}”p훲Š4Üdùz"7¬Ô=Ã$@\D…¼1å…6µŽ°¢P)¿X=^?^;^7ª4Á”Ð"þ¤šé…ëçYèœ÷ƒ®øöJmòcN]û½}Øg«¸­Œ1·_ y?;Φ¹á°– Îáö)_€|uª0» #O*~R~%e/ˆg=Úõéf%®":f«n€Ý3×H‡BZs4¡7JžîÑ!±^ŸƒÌÇ“!’¿CjYóª{R][f‹èÊÁ%otƒ ÄHä߬bxFWZ(ù R@VIÀÈöC³Ìñ„GÊÍ0cýÌUqpªK2e€qè““4ÒèF !**8ñåÀ’a$ íÎ ë“CaŠWÛêêðeŠ‹‹ØïŠÈ±,)Â$‚Lb8ÉLù’a—'«ž‹QQØ…LE ÏÀÔh7j¤ÒÐÞ“¿GÒìà2๒:jt%Tµ¾‘£pu}Ü)`¼âé¬˜ÂƒÂææƒ%ùJΉ(ÙˆhwóØž«ë"ëU@c L™3HãP®ç}xþý÷¤d§Èþ¤²öN<ѽ—¼ 4«—¢6x fËŽʃ‚ö Ǩ2¤>ÍçåÞ§ªG<ÜG–e]•Œ¢/Åb˜ðCÕ,*™xHb!H”d¹X`{‚eêùS^º=dí D94­º”–Ÿ·¢A¶=*W*ÑÀ9’Áã Äø2gÁ¦+ܙ֊b v[¿÷Oêï¸nª”„}ˆÛ˜¥D^Ä–ÄzQlýçÅÁøÑbZ^÷߇›^A’=”Î^ŽŒ á‹¶­Œä!1J{t» ÌZàã»ÎP”‡‡.”5Rñ9мæ?Œ©CÌÐÁ2õ JøÊ"º7X|"zƒ˜ñ[rdÈžøŸf`q +-äõ§à!b!#jyh3¨– ‹ÙjU‹ðô\- J>ÃÐrµøfðxq,Ô¾ª¤ÈŒmX 9Y-EtF÷"]åð\ºì»C¼“á‚Èf#‹`"…ñ úFíÎpXËûE Èõ?Wl&òŸ6ùÏÍðŸo~k› ÄÛ¶ÿyVÈ-Ú’È·Ñœð<Öšoÿ9N«súužãD¦ã[ÿÙÚ>d©,îˆßýøÍªø1šzJ|g)²U‘;n'çAˆPè—wÂleèvœnBC±Üúùðae½$‚^ý•VwüÁäªhºÅÎ&!‹xËBS_Ø'ÝLó%gÀ8tÚª¦Ú»e])4›s—Řªµßß±ÏÛBŸ\DDIÐôÿÔ¿ª‘¶Æ!êáÇNÏöܯÖè<w|œüŸTæÚÙ~¶ÿì?-Ø,QÂEŠ5t§Œênáä„ïivŸïÔ_@žÝúOMùˆ-"oìcã÷»÷x ìÔ?Õ_4Ûèd–7]7têQý0ýƒ¼f¯Øýkô£¶£ÛMË;lôùÙ+¼TÝ?<Ò9nì6úêp§V(88n“ÿûÄ£¬qœsxñ£œ/‰ç.Ší±.E¨ÙÁ9Ûu“mbjHó/„jÚj¹ãôàë§A¼¬ÿ ]ÿµÕ>úõ Ùj¿$û?•÷:¬b - 7 c¹Ç‹¡h+Y ñ4Y¨u´Õh¿lÖ·ð@i–ˆ¢¿[‰P† ‘ƒOFÍG[€STo:YoJ›i–¹ÅQÈ{«iHpU:•Ùmîîþ«­O~¬ÚDZìú¬&ÄÇšJdôöÞQÊüøƒñÔé9Ú‚rñjºP*£À«½m(c´„2Q šÞ€6צ0÷r-öÁr†]¨3J)úívóu³ùú¨ý¼¾Ój:FÂÑ᫦³s$)ƒ¢Š8 ¡ˆtJÖ[2éàpûg « ‰¾ó‡Ö¯»ÏöwÚ/·¡Ó/œ­}œå”/²%Ùß©a‡õ½­ý] ñ+³îÕ¶aˆ~Ù†¿´,(±O +{« 4CæŒÞùóÁÙtXCÛ è‘óªÕlg|“€¦å`Д¸s›¦aþÝíÝôÂ|ÍĬ\Y ööK¶šÏ·÷š[Ù ¬\Y $!Ü~¾Ÿ ÊÊÅ ^¿†p0ÐÈwX‡ÅIªÆûGûû;Oñ/àÔÁ¾³·ÛÜÚ>r¶`’_mïÀî²·ý¼Ù‚b˜gvܶÆíú¡³³×nA™°õj÷àÙöž£~w¶œç¸ ¶Rq@YüælíìÐ;`)¢ø©‹× Ch¨÷F¢êÆVó`wËþÜH)Ò%fAŸœú.¤=ƒÝ¤µSo½äW Ÿ©$æ—+ÚDàd(i2»#zÂßú.ì™ôÖã8+ín0vZÍ£6îÈNý—ŸuC¼û€h8Û{€|;;DÑ`iî¿8¬ï:ôæHý,àÉhGÇùsꯎö™ÈÒ#Ã…d¿œzcg¿Qßq䌫=Òiüú‚]p7ÂQÇ!j¸¶&g žq@‰mpè0fPÙa‚£26ÔÚš³%óËŸ†îÏVý¨uŽ¢ÞèWÕKä­ÚAÈ¿@ƒ?w†zpЇK³ðƒÌÃ/˜‰žœLh»±½F†àðÕN³KÓí´Re«_4÷^í²Ãçþcgkîah­ôTµìR¿æF4 å韪ï¶M|kÃ2¯¿‚Å¥Ÿí·(¨‘ˆ/?ÀFÄÿÂÍÃ6b±¬<žJÕbXsoÜ&kBU~äÁãgÚX~Á?{RF(þ¼å üÆ9ħzôäãÖâ Cú·{Š?Ý ÎÇýþ"FÉA€#—«†?êG`·‘Ãñtú-<Ö­½^‡ÈLwìªßQŒe“ðà@9áпòGú÷C;ñúšÂþ9ÌÓiCrã&+™äUcÌmœ ŽsËO͇#'nkð÷I0ö ÑnÏÌRЋk-2•ŒñI™bÔF N•ú(³=šôÐL†ÓºÞÉäÌ×÷ÿ«  4dô;ßÊ·ÎdÔ³Š‡×ý“ ×>÷»F[PztÑèwB%¼í³Np¡¡@á´ 9ó¢VqTŠÎ5N“Õ·â/‹´d­„úêáj†ð “‘Þ·%Ýä®ÕšznÓ`ÒšAÏ€[ˆGºJÿõEÛ=ŒÅ¥ud=€HÝ ¯¾ ‚Á æ4ÚL'G]"¸„`?˜„’›3מ±$­¥ŠäÕ&®Ì§)’‹dÙ¦ÕP"m'çM^áù„AaÙùƒÐ'UÓ‘‚-*Cž\ËXÆêHäÛç^oXÓoÒ2ZJPèüÝ Î¨”ÜH =°DŠQu,BS&)À0ÊËÉ{$7M¡`—ýœ±n HÓÐÎŽ +„϶\A»÷ö÷šÎ ‘`kø¨C ×3“¢iiáä4‘fS™ZXº‚ÿ9¼kð‹µÁ¾‹‡yîÖJ͹Ò'Mv…è6r1Î'Ð,2³ªM¤~¦ç†3déiÏ;EõlŽrê‘À‰IHš49Œ¨u¾ÍQ©žž‘QŽª bþ\(HÆE eð5 ÄÈ¢ ¨]ë6Åuƒs7i’Ë9«HW ÐÍŽš:Y¤ýê(²áy C«ôJÂw*¬Pâv:ÞÄÅ}rÄh„‚¶7Œˆ|>)$Â6€î†[cè¤;ꆕ¢Ü'j…ü£ŸPtUP{IâcH_£M'‘A~*˜›fÒŠÔV†_ŒŒŸ Ævg–‚!(Ä6Fós'èì]Ôü SY0÷[üfeþTÅ»Wcw6KËÔ‚½•Kgjú#o÷ñîT!¹šÿÛ"?—ÈéÅKÐW‚ %˜Í°’˜±“Âx ³,iÓTˆ›D;øKAr@‰ÏÌ'tFDéþWcKώܱÙr“îAé¾²ãv W/ùF"-O¥ÔVBK2ÿl@¡‚ ß«(>•ÕY¾LYu[¶ã8Õí?¬¾­ÂͰd?R W%ä}Zí_¨sM‰¶Ã9•”HÞüV{»RãëêÂ;imU+r²¨ˆnÕŒT4»4ÒilêzQ£š%jò Æ¢q û´­IolS‡­ë»gô7<¾ºT±:¥æ#ÞÁr¹¨ÆFO™l~åU/>B¾ø£~Rò·hµ,E]” j+<óÅxŽõSMº)—åòz u[‘™àÌÖ“z¿±öEˆj$¦¨ZcÏÑ£~ÒÍŠ¥´6â2]ý`±¬WëMz‰× Æsô¨ŸÔƒü廯7 »5Cv';!ö¯±ÖYÌã9zÔOêA £Á±$G±Ìèõ¼‘(Ä9*œC“{ U”|ŽíÑR9y¨Ôþ´bB±ÞÌÕ•/Ùƒ|êbéïö«õ¦ç@&ÏÑc²Wªž¨gj_^‰·%‘O0A¥ÙY¬7óÅ#U[Ê8±S ²,¨Þt§ƒŠ0_ÅóUyE•QÔY^\zÿ‡Q˜¹Ö,*’ðe +Û[W‚Ò·“Q“¬]º}ó[ùÛŠ})htb½Q!&þ€ë”N¨² aVënÕXjF†Äp˜*MF;ùn®Vß@SßVÛÕ39 z£Ð‡mÞØ3«““:«M9ØÌ´ýo“É×OΧœƒ¢éÍÇzšsˆ´ƒS¡$ ²Úü‰Õ&Z[¥ˆb|Š=ª'ù[:œY®æïV 0æKô¬Ÿ4¾sæT'ŽŽsÇõ“z¿±r)Ù@æW xæ‹ñ=ê'ÝV.—l+°\•êeE)‹ ê_ííý²üº—¥œ¬Ï±*SP Ž%e>–0vEÇý^N}×;‘N²ÞÌã9z´Ê«ùk¯4³M¼ÜŒVÉUd Vâ-O¤û¨NŒe²_­7ó%)ú¤ŸÔê6[˜œ‡3àˆ1ôË?*^å>zÃõÆÞ&E¸(—Q …™y5²hxaã0Ò2‚a>È_ü9׃ ×È©?1½V4ã9z”O磕`R´uá™Cbô=ʧó0 bxŽjªª¨4A…ŒùkãO$ëT-9?ö£~R“M™3)(à"‰çèQ?©ùk¥„ ›(…+&tëÍ|1ž£G5ÏǺCR²7‘t…Šd½Zoæ‹®Œß£Gý¤ì~q× 1ÏJ¬)ñ„Ø»ýjôŸSÌÏÆsô¨ɨ0mœHx$ËÄŸ£Gý¤âÝæ¢ªÏ,‘Z1ÁZoæ‹ñ=FçÂÉ–³0ŠòÇõ“ÝH™Û(eY+óÅxVM‘™R["%˜ªLê«õf¾è‰å÷èQ?%ú¡*Ð}Q"Ô•Xâ ±wûÕÀ1N1?ÏÆˆ¨jRFE ¹Xê›ùb<Ǻ«‹ÊÞjI㊠:ön¿ZoººhFû•T7*›™Oˆ†R§Ù¯Ö›ùb<§Œ„n€1Z½’lhJZ2ÉœyÏ{·_­7k|uC’cÌ"a*ÔOêAþò=.²,ˆ3¯PÍã9zÔOêAu@–O¶|pÊ\Hô;· &ãòéÐànN‡Æ¡r”¥•AJ}3_Œg=kôªŸðaÀ Š.è n òè«:U(3!önVÉIÖ›ùb+ÉN¥¤%“Œ¥¥Æ³ÅÞíWë-Îø=ê'õ Ö‡Ýüä21ÎZñGý¤ä/ÿØ£i—¬SPòÅxŽõ“zPÈ<ÂÈ»h»ÙÓ“)zdÄØ»ýïµym®{o6B÷kV¢1Ífz2k"%žœu©Ÿ=‚|ÃoÉJJ¤$ ‰±wû5}e}öJ̓•”–¥%¦Œ ¦'³&Râ ñ”uf Ö‡(³õ„,ö)ÞBësæ—iÅ2Ò³‹¤¦feOIKÏšH±³aR,‹ýšŽ¶¢I ?ì¡MbâãÔ‘ŸRxzÑ̂ӊeÊ.’Z +{JæxVLLd‹'ÄWALé'e5Љ=ê'õ c³Î¥ä,³ÂÊÏ|1ž£Gý¤ÛÎåRÚêöYOêAþÆÚÍ Åž£Gý¤¦·çwÌ÷ûÄ÷˜‘´ŸÔƒüå5£¬uEiñGý¤¸ ROËàå }Êšýn¿j¬R)æ‹ñ=ê'³¨üå{ÈÍ–ðÀ›º=+ñÖ&Râ ÆJPivëÍ|1žm úƒzPsm¶+9ã¡¡s‘|Žõ“z¿ö8…–.Fhé_¤½™/Ƴѳð$ʤzfêgØêZ\lFRT“‘Oˆ½Û¯ æ‹ñ=ê'³¨ü ¨Ýz9®¶RÚJJ?ÓÍQ5Ò“Y)ñ„HvëÍ|1žm úƒžd»?)sí«y1b£‡_ä˜ùQ¿¬G]¦¦Ô2Òºø£~Rò7Ö†‘!“Ú¨+<óÅxŽõ“né(C”é1r‰ŒWëÍ|‰æƒÞ£Gý¤äo¬§Q}²·‘^åJ¬Eñ„Ø»ýjb ¥˜ŸçèQ?é1‹jNŽë‚S‰ø£~Rò—ìþ›*år8I¶&ùb˜ðSzq¹¥š3L>Gú‰A+íhc3–šæ*cì9zÔOøð³}¥´Õ7PºÀãnñã÷ùTàÏq›/½¿ÆÛ|+~Þ»|š¨[ßäÇšv¯d¦FÑÛ‚H…eþš[÷H…u÷x ØËWS® Áü•I*¯Ôå+جWëÍ|Ñ»ÛUtcLúI=ØNdÊ"·›¨f¹wd'ÄÞíWcý2o‹¯ø¾X?Gj2¬k’Ëõª¬Mmd¹¬wûÕh §˜/Æsô¨ŸÔC|ࢊÕÈEV@+ñÆ%Râ ÖxqšÅz3_Œçè1̨ ÉÑdGí©0WÔÞßÇï"²Wp0’¤¬Ju”‚tÅ1òè }Ô'›'¦(\ÏJ-¢§Þàý.g‘S½9×î€jšÃ•ZÎî ª7«åÞRàš7ÿ°éêŠ(Π¥V…jˆ¸¢BN¤Ò(‡¹)š*:FcåÐ)rò|ûõnsCFEA;®‘×.ØßŠa"VV+é~jÅ/õýí½ŒDAaÂD&%©ÒSÒL¦òHkíGÑTñv4×n4¥1j0I =zl³Õ¨.ÿ!Åt2}ùIe#ù!ÝÅO&rÒ‘;zgºÝŽ.^+—ÙלÊízíjYîxq´éû!; ”&ChgtUù³µêOìkQcµÓÍŒÕÆ:ôzêŽÝÞ\‹=”|A¢jŠMƒ¦MêBPaŠ Ë"MßÀŽIcd8©ý‡µl)BV红L·x…?0•å”()É’¡ÔbÚ;(k ãŸØŠÆÅ+·¯b¥&¶RXRzjRÿYŠˆY‹…¥ÎP¤ƒ"u L“{²K#ZBî¡·xîºÃ¤i‚¤¦°Gv·ÓÄ KY©FT®c:8-3Æiÿᔯší5¦r`3YÏÐ&uä)_¡ÂENibEiÐD<­ÙoŽ«y"ÛÿÚÀg$Ö‘¥œDS´Ã…@æ‹&ÚV$^BʤxÏ\+02Ð8 L0Èj1¡f¹,kÚPíÎIòB&¿#åïýß{Á°‡Ž@éYùäÇ ÿ“QðÞèàHâ]é\ÀL¤5ï9æÎõÑWêu¢õ­£·£@îl2ÞuaÙ°ÕX>nÜ^Ë'LÜkyËÔ}:X#X_È ÕçXýŒêí0â0£1—i}÷úÄSÎS˳«c£Ú)Ð0î U’ÁN›\ÈfÃûÙt;og4>—¥Ï¼\žo%°72Z©t‘g¸K$#ÔËníüy+×ûÎe—\3ÃcÝ#ÖÞõB´1•w2r¨O®UHDYÉe/9⓹Ò{ð †û{£>zÿÊ9Ú}ºl»kÏ›uçÒk€ï@ú¼PFÂ#¾FyÂMÔž£ Ï¥ï[@£É¨ã‘GPŒüqJÔÌ@/]H~oO}Œ>­·KŒÃMk·æ$å N†šT¡P¥‹^5Ý›6ŽÂé•8¢™SŒ§¨D…«PÁÔE*$a2F‘ú²H˜"»LF¤¢d¦`æŒW¤»òW YdĕۚˆLýÃ$+«æm—…&‘P*Ûk *r´ã+ô%žAldrFW0˜Z¥’KY«rí“ïi^{¡XŽÕ_Ä-S­/l5|î‡gµœ*àÒÉOe)‘kàc¤K2¥‘\ÿ9;h´x–DÅd=±k{8Ò¢=å¹M9çPŸâ; )¿àÊ¥Í9bvº]")jš¢½*o7‰ˆ"ªzøu1ÍkM:æ[‚ï§£ /‹áf¼LðÀ¨¾úÒõ1Ÿlá-8¡“.ûCFÏ=gÜöSŒ‹1 Åd(vËWâ¬{‚ù›}·CîS½‘—DÀ#­T‹ª­šŸSC›ÎÏÅ¿"?§<_[ܵ:òDÞqd`9Å“ÂáµÿÀù?a8>à?è 𙛢é"G«RŒœ‹A' $¡K®Œæ’v)$ôÒìGE܄ϒh›B4û‰ðcIì÷ÑS-²Bâ¸cXK) Tg!vïûž}ç”Î-zQ)#íQFÜOrÔ‚¬ŒØ‹‹v ìË(NÕW¯áø¿Çf›ÇâÇÛõFsÿ¹kQùc(D®Ba¹{E¸n×޹uƒku7¤ØN쯷â8¯°5À×®Š7bó-ºósý°F!ÄðÕq€+”î0`üQ0è[‘ŒÅ²W9«”D£ÿ‘/$(U,Évæ>p4ÔŠ-σ^cø0DÇ®Çû3 &60ˆ¼o|:é™q“-¦’|r4¼±wÅOàH¢w›÷z“urœˆûØ Ë¢’Bë¯ë‡@Z®™o ÏÀÊË‘2Ú"¬X!ÕÙŠŽrá¯$õ6ˆÈ0̪î lªƒ°I_@Z?YCæ§üsɸŒKöB}1$yfÊ¿—”NO)RÓAka"ïC@I¢ýJ3[PXêÎþ(džtÀËŒc=¤o¤¹u÷-Öß(Åý+ðñ•.LIûïßt´P }ô’¥ø®ûÏ©2±¡ºÕ’¤nmªB§6ÛJmÆÏo"ÿ'r÷=~ñÖqR½Bù9Íׯ‡M8_é¦ép¿£Î¹?†· 5Kl²™X7´Cž[oò ŸÖ4ª–ÍgSןZsJ½ÍÙsgÚÏT FÅômU`ÇSºR‰Åª‡%¬vëÉëSI¤~B_Aì„JüLÈõŒ$1Ž«ƒ(óLHy@€ 8LvÄ‚Œb†(&SJ´=, #}æåþn³”ä9ä8!§ðt̽I^MJD´ óú*eBIÐü©(#Õ˜ ¤Ä?¼—2¢ „âœ"/žñ0µ$“zØà˜ Ô “,ˆÔ±L/,‹ÈDúFyŒæRׄ€”Ç9ÇQAÑœÂ#t¬%Ø*>P?è5åЂY«Æ‚× ú²S–‘j—oZ«`Óa(¦¾\Ô7ÊСz*2Žy€E‡ÆM(€Ž½ô §Ì¯dÑ7£ˆ®¡ÌaæÒ†Á„¡!}¨Ë¥¥Z/3sIÛÚBŽ•D܃òY§#Þ˜ŽÅ†é2%ª>š`œšJrNÈeŒjÍo.96¸)3žm÷÷ ¸¶÷´á‘ái7èLtØP«(¹:3P%>¶R|[žR»ôRÆ@¤ÕWl~ÑmJà³’ “RÚ.ÉÃiGïnÌû1eÚlƒ!»ëx#özø¤ÓxÝþ´BR‹9Vµ¨§ Sʈa˜UF²½š >V ’6ÑKm¹–9Klëe«’ÌÊ/½ž2òU&< œ´³h½z'ã¾ÊsB‹YH?̬—K• 2á9-&íä6_î$~öj{gKH_s’kÁ…­ÏΔó¼9›½’Œ;x¹ß:’=#ùj™å«$Ûg÷f²tèÁæ4*ô†`êÉJ»þŠÎZ±k/ó›Ö"aø£ˆ˜ä"Ç…ÊY¬})ë‘'±eø8žÝÆ> @ýˆÁ*ªHÔ0ÛWs„ÞÈl.=Ê\¿à´ÒVdÌ“LüòdÐ 6¤ÕŸkk¹¢5ð6œy ¬æ¬±&AMÔŸ&§J0)óm—ÚâÔÌR²*åÿy¹§ï¢ªJ.¹Q,äö² ‚RÞ_/&ÁØu§ƒ1«Wî¦íž¢‚xY\;¥6«´‹ª*§U•²/6¼‰"¸*(g¬^«t¢«¥eÕÚ¶]5¤Ê‰â@(B»À6k¶ ëš§V¸MŽºËì¨[W,_~1Ëw ™¸€ÝuˆjÀœ@dCØ9xY:W ¡Trîyj”¦<ât2è0þÁ2eÙ#¡™]۔ª3wÝ5ï@þÊÊå¹@I2Ÿ EùˆïÖÈ¿òhlÓå½lÌoÖŸ¤ö#Ös QÊ€N"ˆq³«¾hH2Âþë•‘Þ2•±@j×í|Æ Y&÷ú¬e"²Ò ìMíà§­·ÒÁ¨Tš0Ï&ŠÅ·ž®xqžÃ9Š£ãø²Ü $)à)ö‹Ú§ëd-zhØÅ<òüï… n/È‹eyŸ'‘÷xOˆ[U;Z;û¤7éB&]âe†5Œa¢á«Þ @xäÒɯs2ð;nr±K«E3«´¬š|âG#ÇóBìY8S–ÁHé"sF¤æ*=G+þƒû*c܇RÊU_­%a3˜³Íú°c/X•5Œbò0ƒA©¬;$î2&Õ°EL• †62…àp°‰Î™Û*"üʃ¸Ÿ“pç„1(£n—]ÿªÌ1jðø1¼=úˆY¦-dsaiq-¡¡ûÞ¹Ö>ºêÎYNjfS s§8O†J-EÝ€æ¼5Æäl0)Ãôǘ0„“1ih;…·äµòjPƒÀ豌ÜðOs4¾-íRª¯ŽÌѺÇBR¨ºÌÂû)½Qí ÈÒTÞàZJæDsX%–¢Á©d'éöŽ>k^ŠîÈ'œ§g*¾ê9íM0TùL¹ðÀ…ÑhDí4FLFÛÅ t’ÈpÚs‰’A%XÄ„B}* ¼LåQeÎÉO±Ï¨ãIªUÑH¢šhlì‰CéWßP…Ѐ°Öíg--ØÐ `1 —ÎÍQ éý(qË«èX~yŸÖ ¬Å¢hTß~KGk–±Þlÿ¨Ž,²G±–ëþ©`€Ø»¬þ˜ ¸MÆL˜mÀ¯£Ó:61m¢dD=U)A=ìæ¿ á¥âìÁ¡˜7dµ¦C^CwLWy$j’Õbç ’C+òC ÄpeÓ1ê<ð;µN®…y_ƒiǧ«?ºÓˆæOvúO§Ws”I´PU::xm&oRÁ¥vüxÛ€‘O+JB€Z´–ÿ—%.H¹—Õ2ór–ùË€Å2´JI)(ÁÔõT×p|áFj|ýÍWë‚uúŒ¸,xý­uÑ8©±m ƒá¼? l›ÓÙt€à"®þWSª‘j„hS|Š`YuBÚ¸Ym¢úýS)ÊÎ)Ï ¬à6ÔŰ¯P­™ªtß„ —mC¨ÆLƒ¸«RAúãoÇRÙüø‘Ôn–D]ä*• ³‡þᣅ+µ "ÐRç*Ѽd…²€QoõÍo¤)ú±Z©|<Û„Ù-QŠƒeÁR.W\pHXC:íkZ-ÕHùY( ©‹bf­Ieõ-žn÷ÛYb 0f—¸L‘DÁ =58¾ÞpbͰۥ"Â$´J„d û…PBµ¦¢0N«ÉÈwm¨WÅG@eS]6²¢&! Ôòµ~w”.GB¶ë—M·Gf3­Qü›ÕÓøf•Eð¸p‘QkÊX¦¶dÖèØe§RÕh¤‰AF.»`¬)¬k“& J&ÅÝŒT¥Å'i’Âjúˆi(FÕh½±ð°hî©©µVr_iªÏ ØF†#‡mJÙ„bÛ«ôfU|ÓJ3+Ô\ÿ³ˆA ÇÇÇu,üРw‘á ú©úhM„5W¤ó›2Wtå‰"%'Ü.3D묟ì³éƒÀ5³¿6$ð¦|\nïÑÍËÔ3og,D à7ðDPW&Jë•'? vÍðzDÇæåFQ¬¯®­‹ç#Ï­àt|‰äåy0‡¦$¶ŠCúPQ=¬„ÃvŠåBYŽš™ ÊÁ“`(&ƒžß÷±qCTwÖ!×;ШjÂŒGþ ’d~èÒöšûÈ> V†!S•%@ˆô?±´„Ÿu¿}+¾xE~žV#{uPͨÂ躭nVv¶÷š{ûNvÙrÙ‘*ÎbNià*d`v…‹ oh¥Rñ5Ÿ'ŽçuQ¿:­öå¢óõH1vÛ ¨å?èçr.¿–û}Ct꼯Åßó±7êãRµ‰'ë«1+á~`‡v(µVjLN24ˤ± _s2ÒqŽlúŽßñÏ1c7pi²U ¼)’n~‹>!UÚ„ú{î8w,W¶Ùó<ÏÊ'æUîã\αyõ…x¶§ß<†,SV¿0P½ `䥱A4 …™Ñ kgÀØ¢C‡ÂobåÛ‚•K˜Àפ¥äØÌ²&Û&Dÿšük¬ƒ²—>8ÇùsQšœ¬‡ú%CžU M¨Ã)ùãÉ(—méBýeýEktCª»¼®Áq>‰T’ -Ãá,²‘”èüyT*þ<%j@eñÿõHHZ'ïé Ó“§Q]~q‘ØM¡u‰ÄÜæ|Q¢" ] šruµ(Ãr×,K¬÷LË=ÓòÇ2-€÷lËMÈ‹½’㌠^=̤/i¡ì·fZÊ&):íeRlÜ_ŽÄP§îéËg?EÈeÕ’ËÇl畵iTOù*Cÿf(Iª–Ä–Göw(Ú>¨W·öÅò6* ‰<Êt'#@µúÀí]‡~XÝ7àŠ¦”Ž`±‰ ¶ÞÁ‹íè pY5©íÝïÛºAPÄÑÂG Ø ©Ý,±ÆÒ)^Hѽ`/$•¢ûÆM Þåö»Æí9BòÙžâÇŸxçxuͪ‡=¯êfU í»Ò²ìÄ;E U¶Ï`ƒw£½óÓ ‘ÝÝÖ¯»"³__˜Ñı17R¼mó-pŒá/›õ­æ¡ø¹~(¶÷;¯¶š­Lè þ”4bÔ!¡{W>¦â‚F'Z¹°+… C¼È”iI·ˆ ’õ4°E›ö,…Mw;`„-½ëhJíöçÙ’>ÌKÆ´4^ä×yÁª²íÈÅ2 å(fz‚rj Ý„FhÑûñäðÞ3è† h™†©[ä⊌(jÝõNÃʹ(kûWƒ²KBáTWjáGÙ+è ÇÉ?r–Ô\ý˜_ª$¾Ðº4YhNv>g´SnZQÁ)§š¦Ыm~äÙ[д_·ý ÈÝwä…hÐü}ˆ&‹,7äZ íÉâ=E&?ák„[-rk§ánœ¯CC¹R7æêD´˜BEÔÔ4Y[Õ¼BnÖ&›ýö}1™Õ_›£1&îó1Mj` •j’W)©û þbC]ø¢#½¹8·YŒÒ1C+`ךqÉzkñ™%A3®B‰üªY" GI޵ßôüÕ^Y‰¹˜ŸŸC¥™ËY„WqRÚsÏ Ü–Aq–XkZ„it&è†%¿l æívëh«Ñn;Kšçü‘îºÂSg‰b|rÃÐùÓ ëŸ:K“‚1v†½Iˆÿ9Ð.6Ó\#§²w0ü4e¹¸‰„RilÃäLN ]¨›KlcsaœÞ{¢ï)@º@4±Œªõˆ'rë–Ðü_¦¬n:Ÿ23â¾Wvì(ƒÉعù/Ê®áúM‘ðϾ7ü 7‡Få÷w‡÷w‡_ÍÝ!àeúíáM„ÿ›ûÃh5'éË\âý;ð›ß‹øïEüÁ+Ä{!ÿ½ÿ«=Ñô7SÌß°È{€˜¿„¦¤äÄ_y@‚ó¹P¶¥ÿ$YLÊÿuCigš~¨¦Q˜u †ä³ñÃÓϾ_ÿü8…IÊ·$¶Cš[é:‹1§÷_ÎâçáIè²%Ï”á3³YƒøuÜ’@>û`D¾¹#Éñ¯ì.ùV÷&7šæX;Ò¦<% ´Ÿx8„Þ`|ÃYçÒoú¤«\w=çsM8§O¶<¥ÏµúhOuÚ,ûw;¹²â)skäPSÛ þ…žA0ÑI0+ﯘý_޶)ŒáÆFæF†Ú)Ç*Â`E0Xƒ`CF꘻£Úì(¿¾;ˆ74øÕ ’t:}1­‹ÿ‘’˜IÓ-a¯o~ºE§–G6ˆš·2\ðLÏÕ…¹!©Óñ &çfåV3#‰ùLOrs¶~ˆÛ3“´©ŸŠcµŽ¼ß'>ÅÇ•føÿš«½ Â»]ãCOÚËò8W{gƒ¸ýø†ñæâ8w góÌfƒgó™'r6áX=ï/òO¹—Æ.ݘçŸaÁ§}Óvq[‡3 ÿnÞVŽi&ŠÒæ=‡'èÄã_52/U²ž?Ñ-š¾µ9Nc¾þFÿöâÒly²K†Ñ§:ýzмÅ8qè%xJ³í%(ƒŠlý¥Gù¤úM@šWyÚÿ7¿¶n ïJƒ-y• -]ýÿzüæ×‹EXÑ]ê|7«Ós_¢ÙÔî"¯ä»k{bèzøôîüh}'©VßëŸ9‘t«þâÅ¡Ømî>»ùÝIUäÆÈ?•¼^WÕ#ɆMA „M(I"ÇÔÅvnnò&;úu¸Jþál—˜Iæýqš¹S„ô™_'Ï(gg£M¢ò:Rtî’ÎI*ñÈR"ùÂ}“ôð‹vQ'Þ‘öòÇGBâÈÔsOe„š^pEl"g'§Ò r£…Áµ¤ƒ§¤î¤Ã’Åû"û†ªÔ£É`À®=¥¯”…vò»fH±SÕ ºµøxÃcÅq¶ÇnѸ“gUé䥄vÎ1ë /€çÛƒ ÉQÞzá˜G…‘ˆ`L©ü¿…³1óñScp`M¨ V­WèãÒ:EÉSÕAÏãE^½ ùSAõ ±&Þ-ë—aÆ(lã hGA¤sÔÚïïù½OÕK,óGv#4¼—]fd–ÍW&4Ë„ó•¹0Ë\Ì(ãP¬ŽP•†T:‘:Œ™—Ý&3Õ†€)ÁäòÐúÓ°ðSŽþK6Kuƒ`–ß›ðbŸÒÀ¦ÃD¼ð®ªgÞ8¼)Fˆ†—ø4kØT# T²}êSJÓ§AÅ£I?ù)k³Û„=ïÂ륟ü4ßø1BøèIÊKiŸú”ÑÀ$Âh à9 Ý ¯½ý¼UËÃ?›‚žÐåf»Õ<¨Öö9‚a¨\8ÒW¤M™ J#ƒu.¶öÆHÒ£]´O   ¡2*_[  «»0µÿæqDåãþ£$ÑjàÎHî—S¼D!‹Ê‹ŸFUVŽ +F yè_Ü''$å"Ád¡Z8–…Bõ,÷N’ÂHc¬äÈRâZQê‘È :ÉɃsGAVWÈ) ëºiS ¯Y…e¥o–O Яñh"B¤”† Àù½Ðto|:äDÌ ®Q¯¢Ü""=ˆc0µ+5Â;Ü!$4ðåä³Do铤wþl¾œg‡igŒh§CF­Ó¨hV’xBIô7:‰Š’cm®3zT.Þ£ôèíJ u"×´É)åÑÀ¿” k¹cÞD]ƒšøù@ãÕ)ñ†ß2æJNN(åÐx(ÕüfcOòØHM›ýó!sk›êÜø´ù)­ÄZv‰µMº¢¦Ȥ6šÐ-ºØ½òÇ…nItzž;˜ ¹ûÀ¼NËëdÈ ' TEÿÍúe#zŒ; `C¨7 å—2)÷PÆ¥!Ò†œH5`b?ÄÆô‚མðd)º¢@Ö  ¼•¨ËMw Ü!0E@éÏ=嫃oh•ßâÍ Î22¢/æàt£äŠw‰[c 6 Tå’ÃÈg­-ñ¨²Š®«+•)àhYê§°¢×qÔÀñ7òæIz{BƨŠ_¸ì?8Êï¨ã)R®†[`ÉŸÂ,’ú&ˆ ³£Ö#‚¸]Ò½Æ=—#?¦vÀs˜ÔQ“CDÓHÄ+,9ËѾ&ƒA¿[ü#óÂ5IÜaã¹ «¿/¿qËÿ­—ÿ·ýV>¬–h¿]9.Ö*+}ˆßmªÝQêQ¥Nõ\‰½\P,(±´Ì›¾½Ozë12ŽŒŒ£AÃÆ¹øåfLè§€G§r5R3/7‚´¾ùIQcSœÒÃ6Œ?ðš‚"£€/ßÜŒ>>«·^¶ë‡/~†ÏôÜÚuØh•XƒÀÕ¬"4XÖgEmä{¼iÄN?̹Ä6¾CA]8¾µFËÿÙºÀ»´©Ö%Ž…žu‰v°!g þC¼üRÂ}DJÀÊ6VßµÝÞ`ÒK¨O;$=¦8èÇÅêññZ!®°aDÞuûbmÉU›§šš Kž©C ¡ŠPìsÔ²™”"…T$c½‡“Ø"1лÃqYÔœg.×Ä‚U(EóÁ6X*Æ!B’É!šóhÏeî]ÚʈÑœIÀø˜“í r¼&shãÁ¹ã´+ÚÞ¢g©ÈÑ~Ž|3ñÇֻξú®ï£¹Èž 3,5Lȃô¹xŸ†w:Ì#=˜sÜ“#ob›‚БÏ5ördMÉzÚÉ9eŒmù}JËtèÆ ÿl€ÃôšX5\†'È>0;¸ùsva”tÒó³nƒßÀŒÊLƘ¯T¤Ü|äU´l|Eµ„3–#QúŠî?åó+ÔbÿTÙD œ‚XUç[Ù>ኵ‡bí±Ü¸™QÒYj…¨¯@Í™g&Ðkc˜ŽJ­:Ž9{`+û-[X '3ààØ¢™™¬­&ìzèyÇ»B½¡Š3e `~ºj~+¨cå\#O/[¡j"Ê*…:O @Zº£Lµeœª6J¬`ÂÍל–äÌæ ’L¹ °Ÿ›‡­íý=˜L¹ °ÖÑ!p:,N¸ ¨g¯^6ö h:í&_î à-g Ñv<>)î!]»„^cñá©£GqÇŠI¦Ïlõ/”DUWN½‘ DD)”?ÆæÐçT†Äu'ã·g~†ÅVx9Œ=Z–kµ½ý½¦•´ÎIÖ>ÕØß{¾ý¢ÝÚ>jš‘nØOA$“sJ*U\!Fg„]Ñ1P `‘ö1ž•9œ‰Ñ¶JÕ̬„@UÞYŒ|i¹Šbhl€¨Ã8ä®ò ƒïŽƒîm¬FÎÇaëF7c9×uNoܱòEzé&XŒËÀ!ÀÚó×,¯ öMae9z¹Õ¨ês±„õ °CúŠÅRC Øa$s±¢ÚZpÿdìÂs¢zKzœ´ªd¼†X…ég¦¹ >‘ «¶µ`.¥ÌUI|9vôõ‡ùûD˜8GÇïdŽÂFV?23£îªÜ)XÙ‚®gÉ^˜‹îöÅc¾ÀD£-7"8ÅDÑbŒ¦ }O QRpâ†çâÒœÁFbÃ`2êx2-Sä,`oŠ7Þã ’¹b ï.=5³°ÐÁW„ØúÏ‹ƒáõ'=—dFxmäjäAʈ€U²‘×h~„º§ýºâ2Á·ª™Ž°©¢2‘¾E'£´èF•X76£ƒyêä:š,!H¨6Á„m~Ý!¼–Xh¦—àqxj¤rFˆ¸9i%ÒñƒIh´Ã«´®”(Jàýï½7”·ÛgÝÓÞÄã{ªØd}Ú·5ÆJUF'\ÉÒªãTÐë¢Å*+ÃñÝ\´a¨¨ü'übäx—QÞi(ŸÓÒ€Rb`uîô¬ú”'›[ÊGÍQ(†ÉEgA%I½˜tA•Ò A¨@8Uv¦ ¦Fó‚¦n4Ì Š·«lhÃÏô†’¥”P”t7&y2 ç-»9М+j^*vKż€>â•8E¢‘"†–D×?E£ôA‡E¼—ç°½dM1Ž=Œ…Šz”@ñ)ž×ƒrû²öŽz{%ŒúÞQYU,‹L…,VÐF /§¹]^7öV³wŽjLçîàÌÃ-º›÷ùgpN`8‹Ò§ÐyÀ—} ôIšq6F$¿&‹[F,µsÁŽÞm ²÷–ìøØ˜lçPýswŸ¤`}oÄ´Þm‘Õ§9ŠQChGg2qX_‚È%ºNiÇÌbÑ¢?õ£ÃrPx÷²F—O,©1Y¤œAþñ,? ¤7 ÙµAоººW³*"2Ç5~–Ygê]NäÓîT#é±}ÉË¢Î,ådV(ª.r«òþÑ„TYt;0nçº1P ÜäŠEl´ [ßz ÿ€ãÄâ•+²¹åix < ú>ÇæpŸ3ZvCˆÜüøyÝì¿CÝTŠÈGË^OW!Ãñ»Qßä/ ìHƒ®|1ô±uB63ÃâNJ‰wQõú$èÒ½(º¦è#,ÖG®Q¬ÍÎpX+ä1Js^E¼.8QhüÖå|åÈÑ:Wªw*ŠPd¹ ÍuOT^…OÀÌSoYé ·Ï“šäBíTGþ-IæÔý-«Ò•þ#ü¨×´T k†r†JÃH±¡LC±.¾Ñ¼WÎsdqCí¿+¬ÔBzóx…êÊ:|3ZlªÓ+jŽñ5N¶éÃ- ZÆf\TSkß û¤ì¤TŒPÖ8s;ÊÜÆÌßÿdÑsÖ×§Ìä²6½Ü¦xÕj¶wëÛ{Gð_ó°½»¿ÕT™q7–§Â´\ìˆÁ¹‰^} ¸íÈÈ£ÆQk^¥äcÏTšÜƾ¶_5k)éÏë;­f­°TP½N-ˆß³ÊÊ¡µ|Zq':Ñ&€U¨Ê£ nâSgŸs¶)çÜSoÚ¤–òvŸò™ä»bYù—(Šún{«ù¼þjçoží·¶~­­òæ72¾¯EÛ}fyGÜo#!¯å?ìÖj–ñùÓ-Ö~^Â#íNX“¨®Bá‡5‹4ÇRŸ $n­ë#±ÄRmYªÍ…ÚºÐÍ,¤ˆŸƒQ ,Ì/?«æ—.xX• x\#-5ççÚk»øc8Vü;¿ŒÅŠNåàåþÞ¯B}+»¦»ŠcÂбF=‹H>»s–ã–9²3ÿßÀ2g6ø$72_5ŸR±sv¡¹ˆí?Ãæ ³ƒ¤ÂÄ}LM[ EMs¨l>-OTz&MHVoüÔÚ©·^âu;î¤bQ¨){©ª1&‚!my í)åc»äþÁtíÙ«íg¯¶w¶j9yO’s¦ìŸ v*ݤ,sLʽ™hŒ±;2¹—º©±|úpôÑ1E±xçÆ°k96ì64|dG(±’—¬ôŒÌ‹úrЫ-šXTö'väÜ®i¯ŠûcŒûØšjÉâ)˜ÖØß=ØÞ]^¶w·ÿ·9¾)ÓQNåšëTÍŒ¶MC¿DîL$LþÑDªÊM<[] h K8E³ÀÓ±ý6Ñø›xY´,U¡D‡] öÒŽú}£ž…<§°L 1aô“C25«1Vrc˜Öhc¡ßa«‘ó›·Ù*¯Ñn­ŸN¨fb Ñ©…»tÜþ¯-‹]›&ÞíþŽG~gÑ)@]l“Ì2~IeâÖ|ôKAœN¿T®¹é—*°™Ñ¶¹è—Ê=}UUÍ»¦5)Åì5*w·›k:Ž(:f~5¶Ø;Ý`5:6˜-¼ÙN›„3e›‡‡û‡s",Kÿ¦£+å™Y)ûfj›æCTÊ;M©’…˜½Ì"+S2ß1FÔ |Ôßî'£ž<ô½>¹¸¹”y1dÌ“†‹¯w>l` s8t¶¹1R—ØLmÜT¤´óNGJ]ÏBx9­ÔÊMÙ¸8ä»Åc 8•­ÏwŒÍç>©ý§¢çŸ™Û¡ªtxÝ? z‹‘ØÙàR°»õëî³ýöËí-ØOçÃmV–ÕMDRÖ6g_i–ÚLiæ4,·r.z¾±jþã9imú2lïÔåúÇ5Ksã·[~Wà ôŒÕÁÎ’0H_Р¢bòüûÊSaóõÁ~ ÞëGÛ9Ùs®²Ì5Í`Ò9o[æ{ÚÅ6Óš:m%ÚY§o7vU_ÉÊûCµ2Çè|ÁÅ–™Øm‰ Oæ°©hÔ›­rˆ5mOÁö\Î’­ÙYxÝh³–ÿ«Ãfûà°Yß}¶Ód*·7òÜî5‡Ú]2t”Ñ Ë•©Ÿ1„Œ}Älé8º¼ˆiL+¥µð–õr—VéÅ„Þ@¢¶k»ý'¬DœÚ »àÔ–ÛYi®Ué¼5άÎ6É®ýfn ‡.Æ{õ†îÈ£þ íÌ%^œ}Œ Pœ}L~¶nŽrW‰¬p9e²o6BþÀ£nýB#•^(¶w->fÉÎŇ-5‡¬/ŽzvãÐAßwÎo€{xíÞ¼ÂSàXúü…‡iÔE~:zÝÙ!p°tïêÐS䫌}CŒÎŠƒØßôûh¡…Á™:m„S˯ßÃóÂ,ß›2[ʽ3)éà`Á¨nÝÔ 'ê@qÞÆ6E¶_2ê©å0{NDöq“oZ¤ûÖÀ• Ýj`9Ô²“±åxºçpÏ…þ³p´k¼ä6”“1~è·‡¯¹¸/Uî¾¼¤Az$M)[`;Õ(<~ðd # С¦4lÕ™†º–ªšÇ¼Ù¼›HŒò´réöÂéHwL]1œ6ˆ:-ë½X7t3Ý—‰X º¨í< ±îÀþѦ–äœÈÁl=éõÃô­0…Úµ2Š}rG7¡½)`¾2J\?¼ ®ÎGƒë‡5š£{êûù¨/ñWOz â Î[í·Éfýð64³ž”…Öÿjiu0g:JŽqÊ U³hÑÍHÏWGiT—oCoŒù¨Žäœ.xO>#2ÇûOD‡¢µ˜Ò'ÎK0Ý‚2E¨˜ t¤?|^*wR"«­‰+Ó®ê0Æ÷jÕxé£#ž>MÉÄSa®Hñ£]Älj0‰¯êÌÙ°’z*b™c lѹ]\:Ûá~—W“ ¾2%Å^4)Ø;ÔAŒÇÜáÜå³1“b=¹}÷ª¼úÉ2ø[ϰºÑoÙ¨D~O`CÂ(/q$ÚN¼1†}Õ¤n:r%W¶¢¦[i: _k«+Ëë¿­­Ñ+ΈŒeüÁ®m1ú ¹ë„­h `˹·{½†^ÆõhJª¬ük|&~ cn„9mŠÐNËã‹EW%:Æ&0•¯ð˜~Àvb k&o8fk8ÃÎ`˜˜/b1މà¦ð‘“^s¾pû ãfbª IV9ö™¯l4¢˜_““„›"þ=X’qËÆAt<ë¢'ãc¦9¡XJ”+]M¿·ñ{†j0~'Å`qS´ë¯Û t[ÒØÿ¹yˆn±_ÀS÷Éö/ÛG/Ìj¼g¡ÌÄä=¸•‚7û ™÷tp¨Ü3í¬c>¥îYP,nïA¶)”-ë²ÓÍ k[eß$È,µ©Ãî¦|T>yœzÙ]¥BÁƒ•é³Âžµæ^ýÙ¬zå('ýkÂ]Î ì4gj÷ƒÔé±éEœ(±”³2±uº¨TóšžSjL‹(ŽüÀžŽærhÚM‘ÝÚé£éT¡x‹ª`(È„ m™ØŽk¹µÊ±Vùþûþûþ[[ÅÖr uÊÆ‰Ðn²7öèÿUm;w³ñídmy;Œª;÷ÛÜômŽÇ‰ë«ÙÃvâ»×Nbßڹ厵“¶Wí|¾zÆ"?óçã~ïF†7\ôk;p7÷^íîÜÅ™›!¥»ù[-Êu¿ì§¾Õh)lûzÕ²eùdkéÈpƒÓµÂ”ø;JÿÌ´À±&@+s³åkò!3–°™5e_á$˜\ÌM–11nIP5páöü.}¶>¼£¡勘úY$—= áWYÕjáViS×Z¨ ŒÖÒÉJÊ73K™OBÓ!†dô&­XÞs\#ÙÀGÖ»Ù¥S¢Òä1!5 ˪õ\Ðç~xVËûÌ;‘Gá Еg0ý ŒÅPÃûRؤhÛ ðf ³X\/ z8v{=¯»‘2ø¹4ö<¯Ú“ÊgKÅÊD¿(Hõƒ¹ÜG‰FŨo¿În¹· ¦5Y,½‹}*VxVçì feV‹Â¯nRi ŒÍ‘±M:À6pŠM=Ø4è”­| É’˜‹ÓQЧžÒÌ ÝÎû¬C̃Ø Ç ©åÊû«¢|&ʧ@1pEÙuBxÅêÛ-ìƒ]\ò½3b)ñÏÎrøj§ÙªðÚÒÄ8r²Oî¿ÝÞ<‹rì‚hkû°Ù€ø× q Ë=ïÂë Ø€¼Î]úq ÚTƈ»ð·¼Å€`&—ÇÁC‹€b1­ºýWG¯ŽÚÏ·wšžØ.T_!­!òð#\ñ§Gì…чŠáÈÕð¹+Ù°JÔΙ_6Ã<ËÑ»Œ¯\ÔCNÕMk¯1J[ÖØèÖÙáðPQ¬(`5)2£×½M;S›ˆ €|QïïµHr@úÇ¢LwÕe”JÐØŽº›@:»ß`^Z¹ŽÇ. ]’‰D+€HÒ ã%aŽÎìÊgkìaj$}˜³ ’0påº-F3¼þp|ZÑö‹½}ôÁT?:jî©zÎzÁ Nú]AâÉÁá¡6Š Ç«ùèÜXÅ80,àØØc[–bacÈ…+ `$Q¬"¶¡ÆQ—/íÝn—Ã|ʸig>’ûð\uœª)Ql"æû!ƒÒ+Ÿ¡&R/, ÷Âõ{´Ü€+ŽA¢(NMÿªÅ©Š“IO8óbkÞ™¾ÚéÌ÷Ò\š¹ü2~nf6ÊrsæZ\Ù™fÑëcêÒ0Î4”ÆïŽugßþ}âÃÁkOIosœ•´/¢–š¼*p$é± #Ïež^`è¨÷aGã4/!é-Nöd‘¸J‡þµUL6œ0Ó)§((š>Ò.\å÷²Üƒ¬¨rÇŽ'°zqsæÇØ–ÚuÇ®“Zf#Tù<¨zœ¸bú€B;ËÑ>Ÿqâ˜MB…'ÖÀ.ÓÆ›‹—1ÖZ‘•(Ëeâ\hÏÍ^(XXp¼pÒÇšƒ>»rÏ?¡Å0 /‹w×ߑׇ¢ót0W…ŸêJ.ÏFöâ"Cü]ù߬™6«΃úÞ‹Z2Êå7¥ó|I1½ç²‘Ñ8eµ4*E³Œô~žfüe`(Ï0Âc¹ž—e}Æ%ú£=€ ÿ惎öFµš_vOÂh¨ÎìTøzïªÂ2X—/a= ŒÊ%Xä¡äi Wjbý•”Ô‹¶6`I•4ÌÉ^®pÔ ø‰‰%‰NJ“ Æxµ­ 6ñi4¡fb›˜9lPˆ*B®ù•ÊY§ëæ0>¢‘GSÝóÆ@ô^lñbÁzhÛˆ¥|[»Q³V9[Û­£ÆËfã'ý%Ça„ê²?~[£ “†ŽŽá•²7¤ãÄJ:ãÖqL“v” …£L맪§Q ã$ÙHÍÄÐ0hêäŠd¢*Ôº®æò\*§Ÿª•Šõ‚ï‘LT5‰n&1ƒAÀJމ?U…2£J–ùÛá9ßnÊlQîä"y&ÝO©¸rGWæ®8<Çmév•2 %¿ITlD³µt‚dñl 6ú¢õhID,¡ãF]½8V3}œ‹žaÊc¯”’âƒÄí<ψƒ (&ƒnЙ`ŒY ›x–Ÿ ôå-ž0 ó¡Cɼ’>áË–îȽ$‰¢+N'´Œê“q€ÛÀÌÁ: élU_søZO@h)³tD’Ÿ5É) &# -õC†®é'€»‘7ëþ2Þìâ Pé¶Ûóݰ–7^CÇÆH&=ñÍ7ÉÂï¦Ì£â»9`¦Ï •—#‚C±I¬92Õ5Š~íé1gjÛh^c-z—Ž'S‘#¦ØÁnR"{S;”ŒxÛö7Bí¦@}!{¹2üƒ¤;:ÞyÔ3)]çô(ë~¨môB©ñØšõà §\³ÊºÀ¾²å„çþ阡´;ÃI-¿&_.€.#¼Ø¦,›‚s.‰C¯ïõO¼QɸS×Ô› µ!„LÖYÈ)ò+H÷½+´-âKõ—Ö¹×ë…²ÎÐE^XFC©² ñ^9Æè¶ºÐ;9*!' ` aUTËճ»ÍMã`q‚AÊ]óÑ‹xÖ,rùnwM ‹7vW_m¼°¬³èóì%Õ!—ã 2‚ºoi†Ð3–£ú”X4I·XŒ 8e-šCŽÏó®DÊËË‹FK®Czþ²Ëªœº eŽhª"j Ê÷iKpŽ`û-4³AXŸr:„*ž^±ít»ƒ¿Þ…Ú”O;ÛÏàþ›òQÞ¿åù7­´¼aˡ4 Š|ÒmœV–Ë=äø‹•¬ÖÝ\î Æí©éžöܳ, aÄ›I¶2&^BO™{(ôê&…¶oR(‡ç1¢rá[ã*ø†û›–]á­Ñ:R’Y4&É×éÈ4x´œºVB僜Vi›†'S0%†+ PÞî´»3 QkŸC‰Óu‹"„ØH.”TnŒ†ñÖ@Õ`Ç0.†Ý·î&Š.€ñï¶Ÿ‹@ÍîèöÝtÔtz“®§…"@Â7›ÝÕl:r‹ŽkŠÍí" £®Î(£sÚ*DÒ¸äNѧlj4çØ+F¨ù‘N‚uéd|Çþ2©ÝÐ\ûÁ4³7Uú¶;‚ØhŒ§ï ²v½ ä¶ ß§í ´>N´Ä#˜½?$cúG[¯-Š 6öû)T@í‚·Xp7žMbfàøŒÅ烻èûßš¼N#®·dÃ;7àÂ;7`§–™Föïˆèßžä߆àß ¹×´{RŸÌœIæm"?‰×Ýg’÷{îÿžûÿpÿ÷|É=_ò7àKfIbÕ5Ìô-0;—%*›,땸)i¸aú®ˆçþ•RªE  pèÒ¡ß÷º¾;ö`ÃsOPÙ’T H<Å• ³`PIDœVgQ¦¹!~ñȃ‡#ÚdwùÔ ÇÞ¨ˆ—aÀ^'Iñ¯BÐEÃØÀÐâsopž¡Wä‹Àgõö“QðÞCa(Ô‹tQ}ÔèSLh¡ÑºUoÜQêC%A.Ýà’0Ûd°ßâ/F^ø°}¸ýZÄs×1-–Ô÷Ï\ш*’žø5'A0>é÷!ôX…`8ÄEvB ò‘Pn猓°«À ¿eTü4}¹ˆF{$œ{„ð\vÀ= /CŠÑ÷ÃswÐí‘ãæwåÃðÆd0Cðó¡lÀ¤s/:&990=ÊdÀp6 &C‘ƒ§§9´hU×Q‡ïVc(Ú3qL¨`Ø»&ç¨Ù)„^ßìˆJ¼ÒàQuà“ J‹TàD}q6ðªjbºzû?r«kãdÈ>¬¥¶„úØŸôÆè„ 7*7ö²ý¬µU6ÐQ‚ŸéZ;½XüZ:R3ÛÞkÕw´­oÜ×¶,CE—?ÀüP¸Ãn[)LµàT\Âà£Ï×ñÈeG%aÏ ÏÙ8€ 2¼ž‡„ ¦KÞ³6~_Z^À•*lI•*þ[}Ói¼­âu h¥ãKDô›þd'GKK‘A,‚p~å Çc\ì·ø³œ2ý™š¡–ÜŠ(q+p<ö[Ï×Hý®ÕØû[Gâae• 7a*aЃË©À…2\5#Œ,¼¥õÄ"bÂkÀ 8uȱ¯&OáxrЦôbtJ€¥Õek¨TïÛgjå„0ã€s›þs˜ô'œr+CdÛù1µ´¦Wø7ß`AE7"S0lFPÃaj«a¬3uØÛQ¾’µJ0¸à-¶Âå7ð'R]ÕÞáå°7 oÕ^IþÊ|tõ;"š@Úxéh “þò@ÖV.kuC»Ñ@%èUj®GN’žáJù2ˆ^PÙöv‡ùžZÅŒX?öß#©IBôOgJ¹3¥‰¹wÃË 7§‡^Q®ÐÄ+‘ް¦SÚ6ŒùòêþGSi9n–“8Ýk=©.˲ÊCõéoûÿ+=o¡ ôƒáø:ÃQÅbˆàP]†÷ß”+áû—Z"I¨öE±a†ï2X›ÈgÀf1F=¤`4.iÞ%DçѤF#ñÖ.SKÚ …+!°>R0Y)ñ]¤,u”µZr ˜Ön&Æ : ¥±&V‡†…'׈AA5´™ˆÊòlíÔ%mpŸMõ¹]È$£–5PØp¨$(Òj×ÁC×ÞR|Füe¤³+¶âS½b­Áx›ü'œÃ:¼‰ç?À¦ ]ú„ìÚ6º¦ñïCSSª‡úÞTBxƒn(Ç€UØE89 ÇþxÂt5Á‘;ÂÃú.±±´Z!ÿA&}*8)e[Ãíƒ#«('Í,¹U?ª[å0Á,%Ê}ñäÑ£Gºä;Fkå‘/àÙIô&cO†µrûÚzá]§k`]HÅÈ„–{­C ½Ã!TÚ88ˆn– ¬vNKüÖ@Ú(“Q®hµ2 ãäSQTtå¢5- æK‚RJI˜¤@¤!+)jûl0QËÛNu>ƒ?è³NçN<>œ¯ÌÅT£qÞ¥TÇRF¾Ý»“Êv'Ec”†n_[)haÞj°“9÷‹oˆ±ƒ“þ8ÍqdãA«fÒˆ¯$¨Nß™wå ò ×ÈwO*fùUÆñúªèC´FRÚêÌ@‡›zLN¡æ‡/î-™ýéš¾’qžî%§9JV¨Bøa:IÖ¤ ¢Ä4Þ¥6±GýÍÅñ-ÊóÝËwÏñÝ“ñÙß=Ã÷™>%ÙȤ%S‰ÃÍhÁýÒŸ²ô…º#hèö 6ŠAð÷!‘Tsê"®‰œ¾ú$´w¾ÄŠv:¤¨0Â%Ʀëë :ñ› ݘ¦Âjp\qœ±—ZÄ*|Ñòì›Þ `_mÑÅ”±GÛÔMHLãRhIü£&V-Ö*ïO ׸ŒŽtú”ßPhدî=uÃö2¸Ä†”û×cÙ2’Œà‘vPËeQè“róG•©Ê™Aó.=êG£Â¿ÿCS}*)Amjé59¾ ?U‘ÌWõ2¹lãSúaíÛ‚(|Êÿ;§éæßH`öb.Î2váÙéU`ADÁl§³6PµnÄz¦ƒºßƒîÙÏÄ‚OGº{ôó² ÂîC"äð4JE¦Ó•™ôæ6æ+¤(÷òʯ]^ùõ˜¿ŸÐÒi}ŠHW¸mÞ±hSºÃ1¯ÿå°˜’¥™:ø{Gké²[ØÈêcffjÿÔè𦑒ÞiyÀ“~€zÁYÈKݧJ‡¯¶Võ8H à†P¤O±×Qa|ÂdSÕXqn²-¶âzà¦õš×7upÛ’Ä‘½¾c?Ëʹ9ÆN)ÿ,Ê¿ËwIqºpöG×’þ«zó¨9Ǧ¹åå<ç–æZ+Ç9Ôå\9~Ç?Ç袈2PŸkÇ2»Ôí´¾EŸÑ0¦¹õ=wœ;žn+aä>†¥k õÜ'IQ—©Ž©ý,Šõ§ZWŠ÷ÊpìŽ'a-ÿ/sg5TÖ £AHÈŸÐÚª{ìà?òdPÀq² öc,ØÇlW@ŽHâ¿¶ú{Á*̶¬I¢46³¬É®‘(„}¬Z_c}™aÕhh¸çjKÒ N$Mø$‰¬j™ô•TÖÞ’Œ^Hí§º‚êLFö  GÕqüÁXô]ÀÛe4uš ´Pgä'£Tæ|R^–pÑm›Öi'd"%ÆòH„[!Cü·Òmýº ° ‹L@eþ£Ñµá’ 8ʈyÐfå€yÑš3Œ¼38R†È*]$ø8÷zC ÎÅ=°FÙo(, K¤êŒQ‘P«pùŽ'daXÉè&ªù—çéà!a2H šS„SXÕiÅ,ÖUªFµ¥¾tí½ñ›ég †lEaÄ›ßÄÛ Û$D aï"Õa¹Ph¦6° 9‰<Ô(ˆlªFÓˆÊݺå%2JkQ:[Žr’<2NëÍ9ûËx«sHÕ)CŒ–rhœÓ–´Oàòzeí!`"†g åÑŠyt©;¨•:à¼$-ûÁüáÇ+Õ^úÊî%ÒFÖÙ›Í×GÐÈKb}ä".°MZx®#EéÃÕÀ8F_º!«év¥¥©êês!ž²Òh\îø£+n ‡9’ôMLïh²1œhP*™+Žt¼-ÇÖ„êâãGóà^¥Î¹L߸'o‰Ú@’!ÓÇ¡’Xhì%q2K‚^ƒÓ+ŒY+BÉŽ7Bνk1òÏÎÜ? ƒŒ"•¬ ¡<ΠLµq­¥¯t8K¯Á¦ó€‘t3²g0³ÕÞyWÑ9ê¢ðæ·ÊÛ•ãåãJe师öPqžúŠõYØÈéjážè¹èîQ#†O†Ž€} tO1\Z"ŒA·ˆž*¢O89Å Ðõ3ÿš¨÷® è ÜÑùð&áÏ¥ÇE=öT€h‡ÕÚÂ?Ãy ·ƒÚ½®`é&B#õrhRèuˆìÁ{hÍhr:¾Þ0/9Üî…;£/ýà”êîŒ'n¦ ·EŠ-fONW”‘èÔ¹Á©!‡9Žq³xJšË…4E?Þ"Ús·gí䌽¤jùPŠ uH¡mþ·êGQ-¤*S£wÛ?ø”øÝw"gð4ÒRrzÑB orB¼©°ŽÝñ~É$%TÒè§"EsE’ÑË9 X áDILg’’$•®XM¹,¬¥ãH–§<ÊbêMuýˆNƒ?'äSÎ7zI´˜{W85c°SËÄEÅi¼Ü_’‡ûy·íSq|–xg6 tRÓI ñ]¤ÀTË—n'À]àÌa =8wâ`€ {® WÑ•dsë³KPïz‘p¡ÀUKlýävè`»Yö+^¥$صò|ô"ÙŽ÷ÈÊõ’Ì»>y7êlWúa*:6IYÑ×΋ “Iº;#îÆ¹+mãÖÔý+sªm ˆ3šJ¥RŽ aäÂyAüÅ•u“­ ö [È”NWoì']1B©žÒ£lsw)Ù~bûƒ±oð÷»W-)ÇA?†ã®TΟ¦°(ÀãÊ)˜SXºð!Ù‰Nƹ’È]抑Œë”gwù´ˆ‹ë” ñTwæ‡%E]VÎwœè4§·w /Ý š'dUAKïSdËKÂóñ  ¬ò~(e[d´‰M¶þ6Â+€…¤Ö„Ÿç_¥Lõ-‘‹ßöÐqÉT׺ßw?™äêzh •j*])Èø‹7vá ³9ŸŒûŠγwI} :emÔð¤}â)? q8Jo“% _Ó†‰Ñ›ô™FŸaÊÄ¢á³èß ^lEü®\Æ;T`£n°jµÕ›Z¤'&!6*)ß§í–ç"s»ø"Ç#`àÐWAœû|dÊÒ¥Á¤ù$ZþUïfÿ°“_ÖéÈž‘EÏG›À):©ó/‡Ôóƒ*ÇËò0$ o)é ¿šDpêyʤ4ñÕœ£*ys~’‡š[Äžbgªè#Îýgÿ1ÎNüé¿D›<¿=9y±÷Ê/ÎÏÎgAÈÚlo_Ó~°äŸ ‹h·¡'v[ÛºœÃ9 Xg ù§™ûª6v™®ªc¾Æ8£‹qO#È¡áÖÌOÀH:òl½«»Y8›6ðµ|¬¢[…U³Ae x2“uæ‹7(fŸó¢Ñ0‡ _¥¦%–Öñ¹>ðÝÀéxj±à]7_5èr†ÚBQžçÌk˜ªgÜé´Ïn”ºÙi_ m£7Nž`3Å‘w‹V.y6ˆµƒÒñx-WfÕÚ/ˆ-¸œÌÖx¢ºÓÎοÊ>˜«?1‹ÉÉuXsóàÏ55·¥gty1ÿ<Ý‚¦ê1Ë §Ö÷˜ô̦ŠqvŠÚäѱ½@š5ÄHqTÏ ÖÞ¶=>G˜)Êûë–&·MP"× óBL·ø)Þ¶-5OÇJ_Yl·öEãûfL):‹Øw¾ÿáÆäÞC–Íj.Ù‚ç®…êîè ¥ê)‚öp<šGŽg¸Mµ°š-½^pIü!TÈ‘ÞÃqЃ®’Eëa£%W¾C?Í£IÑc2Õ.ÁžLð¸”é φRˆ/–WF¥øE±lä\) £9ø %‹›¾ù w*V<±<„Ò+<§­ ¥‹u¬ÉßÒ'ݾñß"é³`œŠe~€–œÕ‹¬¯¤–P­¸HÐ8)Äj.\@H¤ ùGc º¥!^?<ŸQáŒ;~A°E™çjù‚ÞdClŽ=:Õ}TY tüú»ètð€”ãÑù$ΊÛCý¦r}¯µm:ÖU~cqN'V½ •8¤«*òÍË Sxè*_½|YçÞ•F¦¯QÑ2@::÷t¬xvl4*ïÒ1o‚êúãÉ€<¼—èþµæE`3Œ{×bÌÞµ‰à†¢p…—µG^ù¾%Q`Kƒ(ôDð“¼Sv»¬~tæÝæk[Aýï]TÂkLF>;ó†.­®þQƒŠ` .Ýk’8t2&M¼‹$ˆ(¹£‘{ Mý¯‡*M=Ï y™FÚrYiùräà –A×j«²-4+èe’¸2¼þrXGx¡Khì/ÄÊ <}„ëë}ÃE­&VſĚØå5ÀSÄ‚íg»p{Bm%çÀaÆ´ódúèœtØ#_˜jdÓ ­óF„03dc1AkÒ&œi† Çû|ùªˆ3Fm¿êužè¶¿Án›Žm6óÒ>°Lë°¸3AUÌ+Zü°×Äü¸¼rZälnqóSôyÝü,‹sLºþˆUcQ½PK‚éÊòJq69¡eñÙw}gÓ‘ àåb3…•R·Šb°3•Ä*Ý%âó›Õ·ETÖçµè3N+&edH'دü{Ïœõ.z5 í°9 .Ì$¯ŒcçA¹ [¹îŠòVûåÁ«×íÖþ«ÃF3‰¯;˜Øn¾>jÂìïµÚík*k;¹Õ°»Ðmæ7æ q“päÌ”¨OÚ’Y éÂ0w…šs¶ ZÆeµ4­’£Ãð’¨7Úzãe³ýs}G wS«"âUq±R‘ºßÀ#-I¯›Ôû³>!'Á‚Dè× k› 0PÞdm±OQmÒ¼4)#p³¶¤ åTVWæP-#QhÌ 0‰0VÑ1 måþÊÎiÿÒ»Üf2èÂŽ›U7ÄNã>}g”eNYÎt ),ßBÉvðg¸C»]íëÆçx/!ëàgBR­´c } £Ìf… >×¼POtr ä´Ýhï—P`Ü ´åº_úH7ù!*)ž¼SÒZÈ2‚ù(²ýæáWÖzef)(Qq4;;ÇZ®ÙäKªK—9‰ù0ÚFûm7Ñ5±®ƒGÐmŸqŒeäèÁré¯ÐÚXëÆf¥­É—,XÄ‚ê.~—Ѷ¬+7`/®|óÒ­ˆ¤ô8²|Ô!NSÛb9ˆÚû?EzÒgTb|* ‡rE!ïÝ¥}Êv¿ɰ¡)ÌÈ E(ñv$w–´q1J2OL 4lì-ñ–l´)á&YM°“.ò|ûõnsÏ\h24 ð€@ãÇ ™ CM±S&>CÁ€7žûhÌùèF¡.*1@¹ˆveJ$?=8¨%é˜9^©n¶ñ«0J´ÌŸcŒ[!·Lê (&Æ%£,.akÈà³3 QÆ“?ˆòxävÉ Ùí•áKµçŸTñQ†\q €4¼íà}š¯NœÑtVAÒny½V†»‹ÃçžÛEŸ¸Ö9æIUˆ6žu:D1ùÖ~‚2qéPyö$N®Ÿ³X9fþLÙXûþÇžß÷ÇÀñ<ÅùÑ Co4Æ7/u[G[v). )º%@EŒ¢Ä_„ÂCk4Œ‘7òR^f]ŠUxáö|ô2D‹~mëÔß°d~ò Ï÷SI2µ9t1LŒ% ±ö€¼­Ñl¿e19dF•=[u½1»“Ä݈ÓMˆäNÛhö"#jŽe8é ™ä‘$}<õøàÜJžŸ„÷Ç&3t7˜bý Y’Ž¡-5Á*”D› M874ÚÛÏ›;­&,Rräå‡,•Šð½?zÝJ¼jŠÌ«öO¥—1Õ cœtwì¨S6¯!—‘£èÕþœrE£ ݈¥(îMŽÓ”Þ=¾'Ð÷úž@ÿÅ ôWeïgŸ:Ä1åãœ\ €¯þøš±ô†J©ñ³°t9yÕÑÂÏ ézÁ%¿aª¡»ÿ,uX„ Ÿ`KeQ}J"¿8Žy`YxýzêD¼~Í3ñúõÂsE3&# íVÓqu•ÒŽ²¯_g8¨nØÁQ #êš4ÒŒ”qh}öí·¢ÿ}t#áÿÐBØ®1ÏŠçöüwÿ]õíþ{ï;Ãöë×wáÛDz¿Þ;§â›Fé«÷ƒ+Ønµ“78½ –ÄO/œöeac3½aÇ~Üf ƒrw4ëïìBûNè’†5͉¶Z}2ç=¥šéF[ØWéG;F¦tª3 3nìJ;…pY_¾¼3m‹„e{ÓÆl1wÚ8µ@¯î]j§ºÔV¸Å¥j«‡/ád÷Œ{7Ó÷n¦ÿ\n¦ïÚöÔX7¶>5`dÚŸÆ¿¨B–à Y‹YŸ Cõ?Ý* ºøUZ Æ†þŽmPcг¬PS²-d‡ †i‡ ¯–ªÕ %ª|ŒÙ¢ê êéVz¯_/jj•˜n¤Cu[“T‘0JµÓ”9],gŠa*6GY¦ªQ¼cÛTcAÞáB³:`§ê^ܱyê]wÃ$ )3š6Õh¢jMÒƒ?ÙýE¬Tç®[[ªâÀMÕßW²lU%¶$¬U5ÁŒ“Ð,‹U¬(Ûd•OH1SS“F«1Z“j¶:jH}ÎøÛÜ5°lν2¿àóÚZ{äý>ñGpHc=!þ6ƒÂ&ßþòwKž@Zò„ȯ­‰Sø÷^kã¿yy…ÙRxˆ«X/y‚ÿ8V2ý!ú¾?¢E+IPžòñMüø¶–ì˜ä^Ì¿mÖ¡XFKÏàÍ‹âÇš¯GÅJoÆâÄ?ƒªQ?„œˆÂß§MÇ„ÿ Ô ú¡¯zvât¹(>|R%Œs¿×b89éù©åµ<3Äpè*ž)¨o?ò¿'AÐ{ú”ƒ´Ñ0ÐkŸŒÜÎ{oÊRdÓÈMézA{Í“T ù)?¶ñ‹ÞE'žòÍ7¢3BÏ£ÛqÃñæ×§Ë¢¬ ÕÒÆi–­¡÷¼¿y»\ü :Y­Šóñx¸Q­ÈÎ{‹Ó^pYÔ«þ>ì@±iuíáwë߯}ÿ¨ª¡ìö|T))»ƒn9<õ®§À5Ð`R<¬¬Éû|–-±f í{þ œîá¬ù¨ò}å!.—<ˆBòƆ6 >‰ô'PˆÀ“êñÐí°Ü¹­ZÓ¦Ö´¹5.œÐæ» .—Àfüã¶ô½þ‰‡#eÙØàD9UóAc,ƒ>-£1;¢Ø¢å¸Òž®ØÅ)Ãrq35Õ!-Ó„¡xº¼*×!;£¼s3Î/RYÇáŒ,wp,¾ϕޞ$ë•ï‰öôJìËUV^”$Û,±MIÃ)W[Wÿ$ŠVšL†ù¥¾ía=uÎIZ ë¥Ö¡}E=®^mFêç´\¸#3UFSÛy‹ñ­0óxÔÏ•û¼Ï´™²-œª÷vÛ© +¾¡’ó8ÿ!¯Æãvgòˆ-Õ|M.Zg)_u£\÷›òý¦|¿)ßoÊŸeS&z§‰¹ǾÜÁœF÷â„’ŒÕ}ëÚq^·Áy ÜcLáÉ(iÈH~¢UÓæJ àÖ¨?¹EÏMÄ{yÜNW^3iczûK+¦Æy¢L;ºë1Æ}.þGˆ¸*ñÊÊŠ¨A=ɤž™u; |¿ ;Ó ƒòÜ˜Š¥A™X'´2g4íeýç&"=0·«‹rN{A¬ÜnÕÔ 'M‘¬{þEÊ?Ùü·;7š¾æà•C¢è»@øiÄŒ8j¼ÅÍ¢A³;ôÛòæ¼VX«¬=)ÜæÂód‚\ƒ7!`€<òËå¼9¸ÆÌ²1[×C<#OÅ/òÐ’Že£m8…Î; ƒúU–¡ò";X€C1Ä„¨³/;ÞÉðÛ=aßTþ@£ÆŒVï´Vp ¬2ðnxÙ}'•Þ玗ŽóÇßP«³¾•Þdâë@6<»m2>š©+/U X™EöqJÕÇâøÁŒê% ò¹! h!µZ sE!ôÆŽìNNÂs¯×“ÑÙh¿Ó NNdðÞÎd4¤\…Љ"&¢eË.AGË;R'žcß”í•G¾¼T C#^÷‘bnJ/o×!ìþ¡€ýÿZàºâÌÕ–\Ø‚~3é÷‰ý‘e±ËÞ™x>ò¼g­-y™&²“.R ] ‰Ì–¢9*’!õ²Ãž ΑyêÉK;éd»s³!ÝX‰öØíK‚ʱ# °="òh¬ÆeYKCu•wPÏsVÕƒ–³ ‰õ§¢Úõ.ªƒI¯'Oˆ‘ Åø9­Bö` g£ëw)t dÅy`Ô7Gu²¹“Ú5¡‹ª×"ÁCo]QQ]ÌîT²²Ø Äa‚D­ÓдN9r`*v/${d»6€oÃ!‚ʾïT˜´’hìï=ß~Ñn½lîìP´!7<'B!EP•±¬-ˆŸf׈MQSµbtO…àX–[ࡼ֤ƒ¦†ŒãÒÿòh¼ÐGîË9"«0KñÎÓ…àÜYÌã1Wvt3& >‡ªG9j5`ìu0™Nn»)Ó¼ŽeÏÕÇêÒŠCÙûׂÉÁL˜¹$þ3‰h‚T#‚uá « ÙKN²tÊŽ5³5ø±èDîLößè í >Õé²Í(ŒYÐ둬éúè+ðd¢>‡ÿp8ÊŸš¿^ÐyoàM¤a3Buê#)æL£EŽˆà tZŦõŒHéˆþЉRÚlIÝ'@mwÈ8ÒWMG~ÝUÂÈÈ‘*jýn éáÙæ¨ )Ú (ÄÐᩦFèågM#²š]Qß°ï¢nþ¤¦S£ U!m¥º¸2¿A²±·¿×ß 0õqr$Ãá²aÕŒ+ñæp0‡¹›sœÿ&Vtj{¤« wp-Ž‘ßÉcüîgú®ŠÉwaéªtUÀ ýà‚<\Á,MBf”Í(Ù[O­V‘È¿­~óMõl3¬nRÁR¾Z-8-6$•Y­IeÏ™TQî£/įrù»Û­ÖöÞ F}Ø™â2x‰ö££T3ëd>Ž‚Žy>•þ„vІû¾¢Lâ8—³Üü¥”K)%Ë#Dj²ˆ|D ¤'‘§âZ‚™ËKТ\öÃr…]À¤À¿†*¿-+h&ƒZT$§¥˜vŽE®Jµ.qAB(H·LHÀÆA€D qFwq†Jòü`P—«9É´•özíðüvóÁ1§¬`ΙÌRÏ ö\§—M/š3¦ +D>ñîÈ—Äp2sŠD-€¥Ü«@ïË); €‚n|rL1TE˜1óËàÒƒ#˜.ÚGLQ;>‚ i)Æ= Â:”êáîhx!`EmcËK¼ÍŸ¢´¨.Ý^aLWÜ΃lgxÌtÇçmqC=—›ÒÎX–j0WÃÓË*pnOV•ç›3ú!úàF„÷A$™Ë¤»X¥MÿŒ0¨¯lfŠlJQ<…—;biYÞ{¸;Ëh}‡7ð“±ß ‹¢€GÔãXžYßQx¥¾?ª¬ÁõAtSmáEmZƒu)&òaýa ­Á‘_¿H6šMøõüvE¥ Ìð¨M6-k€$"ó ß6lB®‚hÅë¸âL º$ê谶熭=slº”é—B^<±—i!¶øî —‡p%ºÔ"d“õ㛫`2êxÑ=NI«É;@<K <¨ä_Z ÝÎ{÷ H\d…É5âH`¹èîN*Ú,I‘[·„Ÿ/•¸]x³_ñÈ~áñ-drŒ"*s’»EônEâû€‘ÎѺã~?ÜË÷¢ÿ ðøïïéÑ£þËOwÀG”TþÒküõž_Îæ—y”¾:Ÿج¼ÝL'{Ö_º„±e+Ó¾ Wª1æãjÆvë?5Ë(Œü„{Dˆnó1©8^qfak #M¹²2#·Š֥źºŸ(„Õo«Ã*Pž°úæ7·üßzùWË?´ßVÛÕ³Â;S1Ù˜m„צª¢ µÞÜì'Ò%&ñ?KuB¾u® dͪá¹{†óàßԅ¿ÿýïþóŸ595~-(MÄ%ò@ð"¯ðÑ?€q#Iô›µ·¢9{äê†Èöå¹ß9—q°M¸3N€N3ÿdM€yGµ¬G÷{J1F¶ð_+²qR¯T §Œ%ž(LþÏJ6*ÈÑ¿æìåô¥êèTTÆ0Æì9Ì™%’5qëÒ7ó.«Ýƒ3^Uuƒq­b\aYڬŚ ÜÙjKBâV»Ø§®7ÄS©6âM5­û™H¹v±d§;ëÜÝ*eË€›±r‡Ë<ðp S®©Ð,RF´ïçJÿ=PQhîmHw¯øcM è‚Æg ê£—åIò‚‚ÉØ©¼ÜßûuCgr“M©å–rôNQjx«ÜÚb:Ò è¦[ôü÷|#3M”¨¢º‘‹ÚŠ, ߎw ²ýÓ ÀÂxRE¯Ã0¨Þ;ÑVH'¬’h=w½Y[-ahÇ"TJ«XÕk QZ­ÓiCŸxá:5Úç 'ƒD¥ÝeÄ@J¡|7âÖ¨lDä(õÙ£é‹Öm¼‹Õ'Ýxì…ãêêÆ¤*iS@C] S}2±JãHADÈUÈÄæ&—[I-•V¨ DMɲ†ÊŠn¤²NÙ’Éhxf-áøºçq,­¡¤¸ÂhoÁÑ[Q“ºrƒÃÙ‡¨îO V/þ‘iK¢aù/—½²Öe zÞ ë :×õD’7g@Sæí.ÐŽ ´Uäéͨlœµ|vÙMëÞ?w5%«­÷ ȆS¦èêN^&â<ÔwaxVoüÔÚ©·^Ö Ç¹¿ ÈU+Ào¢ܬ¾}tøªYÓoÏë;­f­°TPÛ™‘ Sí|Ì9/-ÁŒÌõ'––0·hQPdŒX¬bSùì»=ÿ¿|©O®Æeî`GSñ®ÓÕJÃ@wPo™—©0›×ð¨ÚRÞÎ/ËÐV2D/¢A”+t¼'Á6¸Jç_Cªƒ^ãè°?‚) e²\y»’“3çÈZÁ¬°À‘í(h^HHÙr·‡b×ëHE¸k²Ocz¡R™ÍâSè¯Su´*ÁC>¦š±ºˆäÀÕcFlì´Š_6ë[ÍC ‡_2 ±Á Äú¶÷žïË>¦ªÑécŽ6™ç°JN<4|'0÷—î¨Kf+@’Nü`ê1S0.)çZщÄZå‡Ê)Ì˨âÈoê7?WaòÙE4%\ìÿG4¦ 7ªU VΓJ0:«º£Î9ìcÕóq¿WUU]_][/¯~Wí‡g«ð·VÁÏOoeí‘„Bg 6š}-KY)'€ý cJD©S¸<˜áÏ)v{u‡Œí Æv‡ GõÑAÝ£"Gv'‹ÒΠë•w)¢/Ú5¢eˆJuŽÐ.q¿¾{T?¤š3'æW/,·\¥ö/â»,…ÚrI†½åe] Ï騻,¥Å ñPÒ_Ø76¢Õ20}èÏ‘ª†É€ß2töSÁá!)@-½ ’Ø(iO¼—¡ßŽÛ&Óº8HB΄Œa!e äyhíÖ 0k˜hÏ•è ý€ÂŸØj >Xí@ç§¢ !¯(Äd†àÇs^A¾‡=@ö¢C¡žs2¢§²‘C¼©ÝäøñÌC"ÍS=SN‰Ù…²âì6W+,j8šÂÞR^[RÄéäÌH©ÄJ+¦Ìà‘hÕ“emÖ€NFÜwL@M:ø]úÀg`hM r 9'C‚ p4N‚³I(µÎùRFY!NIg´XÁ€´&™þ0YaDZnP<_9Ô7ƒöò üê5µí¬Ó‘û4.“dS\y7AÚëxuÑ…-àXÊúÖ¨PÞ…„>°¡È ¥—\“ˆ­\Eº0")%HeAK,Xü`ˆŠÜ4ÎÄ ñ¨j‹ns/ihhû2ŠjaÄ‘sø¶Ê¸l2Â@¹mhÏg¼n²a¿xÊ0Ì‘µ[ÔÝËsÄjŸ¢¯ˆ0A°&…†ÎÑ1œ§®õÚ€/*ìP¾&#3/ó¼›$tïP ^  ü·¥•ãå7Zþvå¸XÌWתÂøQTÔ‰ì6’&"‹[ÇCåÎŒ}*K&rZ4 H«»ŒÔÿØ|*Æà Á1«o«ûl˜"JÐ¥V¼›Q”–7ž £Û^:‚ôÑRÂÈ’’; ¨&a°¨)—#w(z¸±›ˆIŒ… ÓYoÒˆïWÅ2Us\,‘ ¹Ô;,ž‰€þlE"—6õ…Eî~¨äí]ô8Æ2."A)¾ƒâ'ËÍæ4ô$©ÄáñÜÇÈ*!–›»¡û×PcœúÍ~_*¬{qœºœ„6Ò#ÁªÀ]O5J±¡Ñ¬§±€“ÑQi~Yß~-†»p£ý1»ª©JGß.ªpäâ¡x$‹'†k–ó-YÆq8.äýBå¶ù§©@ù4‹]ÉYÕ†ã¼Å$7ò ×ø <$uB‰‘ê¦b5¬º"÷ˆ•j!Y‘aQ v yÔ'ÞÒY²õÉêÈA`~Êia¦!„ ‡ƒ^(w D å  Ówey†ËuÝ𼎻(¢”0¼nq"SXöóî2¹kM£ÀöÚN`ÖCV±§êªîÑv( ~Zˆü c%™'¬ÀІ‡*Ûƒ±§4.äiѪ«#~3&2áMEb!ŽÒš5lùûÏþÓ|}T>éL}0 )k®åÀ—œ!¾Œ %cPÔ(@¨®2Å@ =$#4‡¦iòÅ£ê('%Z©3 I&Ri©) %¿$G-îN¼9E-©ŸŽÉö%²îY øŽ ¼öÙ$…LF®i_+sQ)¨ñ® R¯…âü étyÙ{W¸ùúhÚ‡® ÉÑNØžÓåi–wޱN‹ù Å߆îo?¼è|'>òoŽFü죑 †ä/ø!6/FNäƒà8ù×c!îâ.!Ùx#Ü›s7ÔppØPÐsí±u.ÒT9Ý<®ä¹‰Ý+©ý­Í#BOܚ»ïõòm\¹â!ß<禯¶Ž1È “3±8ŽÇqlxE©À “´&&ÌŸìLMcù±R ã Ò^@ÉœÔÔ:‰²Ë›µZŒN‰q˜úé¾éÂl$ñŠ=@·)Vçbô<‚ l˜å‡Œ+éŒPc$=Þ`Ã0žtý¦rƒâzä(hß…ÑuQ¢e@ ì4Œ!’eÒƒ#ú#>€s0#J^ý0œ`øÊ¢f´:M¹Œt™‚Îñ-ÿBBS\´ÈÝG} Õ `¬ú^ºgQ wZ!Š-\Õ:ŒÉ«9¬ —‚d×£…Û$º´&þ DÝû®²J;Êw•5Zð=—–á$ì]o肳nÀÙ)âVT7¸^\‡²-°Q6¡ Ú/…ö1c<0¹gHŠCô328#ÝmjÑ÷•Õé5ó@nõì.Gôu™í¦cmŒEÌøøÑðFÅ,pvöbº±µØØ4ÉÌwÄPdcšã$úQÁz:þ#ãÌiÌw´‘úà70(˜]CR9~¾2$i4¶š»û[Íš&¯swð‚JéWÍuEEä/òŠ1WkÈÀ<´ô3N]\±C(¨.¹ìÔÄeWJ!¾ôJ+ÇWZž†>Âÿ\ò´×¯ïj÷µ{ÚßB 6u±ßKÔî%j÷µ{‰Ú½Dí^¢v/Q»—¨ÝKÔî%j÷µ{‰Ú‚µégŒÏ(R›ãps[™ÚÔ*²„j3 ±Tíõë,±ÚTw%W›ÑÊ)‚5(™&Yƒä©¢5U,)[Ó%Y¸†º÷[p ¢„€…§ô’®8=¦°õÒ™#S…ce:¤¥½ÿÓ¦b*/Ýi\£©¶tüFâ'‚æiëë¸ÛèÙ=É’N´rïøC’(´Ø/'÷ S¢|xÚÇ|µf„'HÚtÍ>9ˆVÞžõú9Cc1‡P8¹ë–b ¨ÇC É–çEêó'“³¥µÕï׿Ç/G²'HQ™F“æ)°A>€( eûïéA‹œ«aÚ²d‚Sý…Q¿ MÛ‘a =½qÿa.àaógó&Bg‰m¼Q\Çš†µ7YÛ cD6llB~àa¤žF§ŠúÐ4š–¤ß¬‹d±ý`þÃq~ÅFXM =tž=¨ÉF^ ‘„uQЂ'²¥ ¡éþ©ýêø«IrIðž¦\ʧEžÉ[ ð}‘Çc>Ã2];cežxçî…̓U½Ì@çd#ÕÑÉ1[Èçý€ÂÒ«µC¸„¼¦ðò@™V×u7X x£Z…)Æ#8†€ae૾wYžÿåwk­?uœ¢s¼r]R€€†GK¡j9*Ì"×^}·YÞÙnÝ¥ «I8ª^ ÏÝ­+šdg†Z~z3g(Ò£‰ÊÚtWTv˜ÿŒíèJÙ†b‘z™9i:Ðñ7^ã“gšÒ _’Y…­zí?˪<é0ËY²ä²!†˜µxÙÄÚØÜttYHSt}W×Ö>züä»ïOsú äp¼ø†hƒÎLzç°2ÅÞ ã¾ôÀØ¿vªˆWÃ×|`½˜wšöŽ$êÉL‰Áô8{¾@eXªäyˆ‘,–ñ¶Èbv€¬Î “@D‹èHÙõOOE,s TLˆbg,„7ª©ߊ5Z=jª°ÏÀYa˜¢Üå³1«hÎûîUyõSLôò ‹¡=Pˆq+F°e¸ì·ï1H@/ g|ÒF-òu6íR–"6¤¦[ê'ð%±¶º²¼þÛÚj‘â ÑU§?@Î9è>sotëŽ4ÐÑòi»çk«‘}{óQ℉y˜aNÊ#…\Éu¤ë¸÷·,—F±= 6й)v´x®ŒÎdD09dɉ'Ý/ÍC²Sx‚(˜§5¡´?ÝB„ëYš¯ÑØwö¦a“õýÆü^g9›¤^|/cÔï¢ó!BC£5êVy =×Ö6£+_ØE:ž°Â0!QÓ(+6jT¬n:i‘ÂgÄ ÿlØD›½Ù·Ñ›}[JP{×m9êä-÷ùÐpÎF@ çâŸ/YZ½3ë%5_¨ÚسîfY¨‹NTå[xYØ…­e¡üa¼†v*Õ; uo€Á}[A_ôðò¨ò^x-Zñíq@ª9*<ö–f˜« aŽUR›«¦ˆ=±ç,^¦)v›õy–‹±æï~³HÿÜý è(¼ýŽÑßE— ¥Ô·Y`.Óœï5›[Vc»fšÿ0òæŸÄ}IhÇJfâMå>ýÕèt×È$±è¶»ùa³¹wtXß;Z|/ŸVôKïäº-í}|äy¨[1ÿq»øÔ&|¶=|J­w¶ƒÛø¼Ðþ=­è\»wÈæÉÍSw|¾½ÖȾÈN«‹Åó®–®6Cù°`TΟ¦®f¥Ù¹¼Šê{”5bB䪄õ|G‹{Ou$—ŽñéŽPÚt‚ÆÓ|ÉÑ–´“òèQÎ$œ_ŠtZƒO?í¾Ûz¹›ótW¦˜ƒh¹ÍNÅ/7Ž™#I~R5ï$xü8Õ¹õ¸ƒ$%xJàºû#hžDª³>åhãýÓ èL‚IØVIš}i·Ž¶í6¹ï”h×óûþ8D¼cü1>¹aèÆü‰PfiB,olgØ›„øŸƒwK€P¹FNB)uÔ¸åâ&Sü” Ç“ÝR”ôÇ>µ£n°ùDßÓ(œ\)¡­úæDtصßO£á f:¾Þ„’³ ú"/Ûæ"ñªÞÏEå#^‡UT\gdÑÉX=‘­[IS£nL£ÆÇz8 ÆH²;ÀÖ|š=•d#’>&·#¾‘7-QI"‘ É#×Ú ªg¤Þ1áK…<“ö™­Ì f–4 hVN)éîÉa ì<Ä—M ù{!äú"ƒQ}wG f& ”_¿8¤zÿ äOvd>â'Gû¯Núæ“ôQù;=øo܌ע|Fê¿TÈ3éŸÙÊ hfI£‚fÅóÂxÅwD °éäÐÊðe)¢QõG!9 :ï½±MÃæUýn¿ÜžfXÝŸƒ”Z3õuRÓ?Ç`fçß Ÿaø²p|rív»ö©<ö宯k² Ï¾µ‰µ8ëò&–-õ'Öˆ®rRqW7:6茋x¦/|¿cWÿ‡‘kX³Ý“;¸Õˆwgžëžø |•$ø ©Cô·"«è<¬ò—ÏEVãÐç'«²Å³ÈªÌ6•¬ÊFÜ€¬¸k²Ê gU•é"«\ý_†¬ªî,BVÕ ü-Èêœ4uˆþ&d•:›NW­OwOX3ÀÏCYíFg“V;_mµÛ±qM¶ã;“¼Ær}qújÕÿ °±þÌGac“ð'±‹ ÑôAú›Y '×èW/NcÍ/wObÓ¡ÏCa­gX+[}µ±yM4â :“¸Ú™¾8m5«ÿ V»;óQV{þâ„u¡š:D_ˆ¬.¤Bop›0îZÌÜvZѩƶ³ìݦ™ÚfÎa¦¡mÔÌÅÍleÙ‰[åâêòÜCWÕ¢\fÏóeŠoE¾´1HE_ ‡ÞrJ>Hõ:Û·¡7þ„Ó¿†7Îô§–—Ø$Ï5Èøwrt?">èf~êÈ8п(ö” !­)‡ó¢¸Y3|Ú- /ËÿPð¨³íFãf^ðÒaÕ”ÍV4¼/ Ñ(&Ðn Èÿ”Ê7*Uº #wmÄ’Ø>Ü~-žTÖÉi†¿ÁÈOfø ³Ë†«ù•Ù¹>zËƭŠòàáºö¸~*c(À »ƒ=4c¿½yôNOÛcr¤=ò¤Ów±¾²òä!Ô‰áEF¯wÍÎð~¡0•è7úÐVfáb§~ø¢ÙÞþ¼}$ïÿ°¾þðáw뫟|ÿøÑwß=þ~õ»[Ä’ r veFÒ ó Ÿx#—<²ÃªkÄBÐA9Õh)FäI«Dö<¥]ËðG}-B·~üQ<\+þö¾ý¡yügüWè÷Œ‰@H®…s{„GÊçxä ¤Í]œšµ½†½Ø»®wà’ôoÿÎCÒj_~AÚÜ´{WI£Ñh4š‡úƒ}"rߣ¯*ÊÆôÃÑd¿]1¡#6Ö7ÿ²ùíÓç߉FCüec½°´$ÉéÏÙe7ÿ‚e×˺èÐö–¨®¿ÛÎô£MÈÜRÊY3»ª\%óÉÎЬ Ѭ5_‹9‹´D°JÛ‹öÈLº唃\ÊѲVO¡Ö"Yÿ¾ÁÃ’Ë !–U,%"ä5÷5ÄÝÝœâZ \lËh¥žï_´^^œsj„Åö‹ù€MÚ,hp°a‡mµáü½Ø†a2vñÈcyì¬ß|¤ìGÊžƒ²Ÿo>eOhFæñÓrLWfD»ÏældžU”6+þ’_P§|ö|ñIe#,s—Õræiœg'‰NhMM­Š›È;·ZH„èÍésCuô^!xH `Æ1ÜOœ˜ÎÔc'öQˆxdµ_=«5Èõ«•Ìe¹þHÎä<9¯ ™ÁlàKˆ üiGý¨T¦`”¹¿|`.Áì6f (W)ýʈfŲ˸oØ¿ØmÒ2nd¤:ŽSÇY#†7ÝK†¹Ú×vµ¹$cÞÍ<3?¼ÜGn;ôý>¥î”i&‡˜´ßçÔ©°[Ãð†2+}o^¦gŽšz¨ÛŸ£á ™KæÄh”6j›µç%ùtä`&Sãqì§â*$U–=¾¥ä ü¨\ãÕÅ »ó>èÛÁµÛÃ|Ó¡ö˜E}ÈÔ¯#G&(…§˜Ï;X_†Añ–ã×±‰ZÙ30¨§Û¢g­`ÜÂF)¨7WÞZ—Åfó]³\o6›ëõ«¶}n^i·ýç•—úpªe(9=gäçðÜjf é°_XÄ Ç¤§Pö}ûs"Ú”L…Òz :öK_ãÜè†1½®©ÙfIz„[ªŽÑ§è§XWî4¢.¨&ùY¥f©„¿dÓô5¿UÙ3f]p»˜É²/®ú~»M7”Ð8ÇPúDÉ|}/(x~ K£\ű­Rû»?ž6JÍßç§ÄÍñwÖ¯)¯¹Ì‰›®ýDÜp„[œ¤ú ެâ±sŲ¸À#è¹£ „¥àpRb•_sÃúpû¡K—<*­ntõ÷ærE‚¨â ¤¨z¢lær¹Ä{Å7ðvs²aQÕÌJ„“T-ë =îúyšŠ˜ÕÚè ½é‰o‚bµ¦§Ód/‹×LŽÛ{¢ZäxÞê·m%Úýû.7þè}€¢–m©"<»+¸3|d›´å(ánàѶN7ÐÅõ‚ñsqÖKC,qÆRn‹¦3ÆÂF ³ ½hÅ f/_A¿8C`µÀ;k…8Œ—(UU¶,4Œâ­”ÐžÇØZ-ϯÍ5“{Wô©’ez¶p@™ÈçQ3‹´³—.)¸jï4~S;ض4¦3½‡#˜1˜;™ÅyŠÂa3¼ïï-¦cˆ~ð*«3r‡a#¨ÛÓêíi?õ‚0R—¹¸]¬‹ ñTlŠgâ¹ø‹‘¤Ìhœ„[þŒ½÷úÑwiÓÝÁEÒ°,ÏME8ýî»_ƒ&<)HS¡¨Ém„1Eµ~²ý9#= 8œ~M©é.ý¢î ~=`:ÀÕäŸÃi˜)û\<÷TNež£–gÌ;'ÇjÖL“Ìaƹ©Éæ‰Æ9ÚOÆ9œÜ/žo.M\é•ö_’iN/–‡Í3ãåÓ²Ì!…¦sÌ5‰áΔHç ·ÉGK (?yœ|ÍšPÌ·éIÂM±ßèÝX_½ 05>Æ”ÓëAý—7õºu©©7CnÛÞÔܶ÷Ïm[²Û«R”àö@=™!¿íA,¿íÁ¤ü¶Ùùmþ7óÛö8¿íÁå·=˜=¿íÁýòÛdæ·=˜+¿íA"õèA<¿íÁw~Ûƒ™òÛJœðlý÷ˆ¿OrÛl ËZ|ÿ%"ÇÁ—Jn{0_rÛÞMnËÓÊ{Ò&·=˜–Üö žÜö Üö@%·Èu`2¨4â¥ñ“ö²@¥ZõÊW…ÙX¢%ZýnŽo– Ï £è6ׇùjY‚ö £PãÎ ´%‡ñØó ßrjô»º?P¢&5*(tÕéˆ*)ȪXµŠ~µPŸ†…OD_ma{\4FQ·}'ŠIëâ”\/œÊÖ¦îôäå[uµ:€š7òîm™FÒwlîv8²Ý>îØ£‘k_9ò¸‚»È6ã!Ìð„PP\Qw¹B–âiŒ(_;-ª]Qj®­?+]ê[Î9`\ɯÔÀ"!FŽf‡­°Û߇ÍCÀBÏÛf³þoØâ*ÕÈA1Åé‡Rýí/õwøoµÞ¬5kõ’æã»¶ç{nÇî»ÿf·„ŒýCy¯ß5˜0 E*ƒU-hQh/ßàmÈ7õo®J—Óñ$YA‹ÀVQ÷æU$ÝÑ[%Ѫ‚!Û´‚o"в¥6 è£õ}ÄŽ£½†cf³,E6‡$\õ€\‚ ¯Ð! ZŒÜ8x ‰†c¼ó°„j±y–Ø2I@Áa ziãÕ¥„8ö ±NW.HòÀ}‘ï2dsMG÷ÿf¶´èÊC­l£N´Â[®(Jö»S–)Š-OÉ‘kȱ:SÃQÁXãÀøèüÖ5»?Ú[øð# N€M›±Û &œ{ô‘Ã<ùècÕ0âôÊÕ,)ºEGݧž.T7×§ü·‘›xÜa6†¨F²VÄ(ØÜÉGqŠ]¼€W@‘=@ò–3ã*uÅȦÝ/õ!£¢!¡„h‡¸˜Ð‰ì˜èâÚ \‡A¨/YXÕµHò$i‰ÞòI·]ì Ô«GDÁ77ØI¼¸¯in> ÅF g¡,Pÿ5º$TÌ3žŠÐ´£DWh/öJ°¾—Ôý§ä²‹È%™‘Â’^§3Õ‚”p%SKQ$ÕÄ$íáùÞ õ±^ø0 #·Ë<ž:Â×rGg¹¬€uc ´àPõk`~î(­U:Ú[˜iÌä cJm“Eâ~w²þm!ÿlÄ9F€yXn”£3Ù9;¿^Z_%§ V¤6ây˹ XÀi “\½Ü§ µdy±!5欯앥É9 Iº´ñå¼'?YuÞZ舑‚™¢ÖÌ4æF.v_-æ‹ó½ª€¿ÇçU4L1)•„´¾à±zÅ”§l—³É¥+d'Ç÷ÜG‘‡œ›É<ªçl'Ç ¨n°Go¨B*†~à†tjÖõã«êë7ê°ØwÁBÐЖ²PUÞëÖ K¸Wž?rºXæb4~¾Y °K؉¾ízÒ&1:±`BeŒ'tä–6V£*8>ÿÇ9*…€¶¡oQ%ñÉ룊8v½—?#øö(Quå †á]a‰ƒDžÒxuIs‘ˆÚv—ìa‘j"E{^¸”(5Ž/‰S.)yHM[õQ­ª#ÕŒtAU,×^Z5‹0ÿ>”£§J@´ h1OÂRr!«¡AôÁ–:° üÈ=ÇO©Î ERšè𮫠#¿á¡Å惡q–ÖÒUÌPƒ²>'#gt”ØaçšvK†¤4ýCAɦè2Žîz®×%…*½“±¤~"ûÀìOˆ¦Qfíu ±óoÆ’—ï¶’ŒöÏÏ…E•s1Hy»fôVí-1ù9^Jó_ÄzìU$§ì¹]<ŒÞlïŽ0•½³UHM¼´; /Ö’[ÃÞëãW/OL;ÿÙ¶'}7i§ÑÃI\PÉÞ‹B‹Uñ«Ý,‹ýÛÍ  ²ºñG]<#%›ÐGÀ ’—ËÎ(d°©Îh„–ùGl!-ó?‹PÛØSl¯QÜXPp)JSDU,÷E)9C Äç:ÒY­4¢R3P5òTÍy¥‰¾.™×“ѵ&ÎFìZÓ¼RÈÂV5Æ/Ó&S»&ö‚ÈÈdÙÄó&Þ•H¦¦zZL÷¾0™8æg‡šrŒÐxþEO¼C•d)u¯Åª²ˆÌ2F¨gY½Ÿ‘­Måa÷aZ_!—ŠaìxU ^&ÇŠÏQ²Æ#÷Êç^˜ûº˜Vbùåu½0 Å,våjRÆ}kìígiyCŒØ!Ó Bt›,Ú·-è©ß²LIŽÏ\‘ÒXÀ–ÞânìÆ¢…ÓÆl• ó»ùñý5 $ÛâóÖ ‰ßÑÕf8r‡}'œêá·ÀíÏ…øPǦUh&~âX,¨[üY—jkÕànÐÆT¯»‹þ{“l¤ß==8з–) , Ó2¯îô][Tu+þ^އ{¬hc‹©uÂGŽäP#f†G 8<1 VꑎÃÔ¼Ø2úG;£žÝq&lDSjæ©ï¼AK—YlWJÃiXxâbõžœËü£Ýa½­mãín†—3³åŠM«©ÇȒ쇽°›!¤¬+YÆK4§2¬ËF8íxÍxZ‹'Ç¢ÙlZ^Úø8£X!³¸•앉.ÞIöÓ1úo%œ{ºf/íS0n»_[MM)Q+Z§qÝgjÒÏ•¸§õžÉ`¾÷P"˜måh’EˆÖX„ʆ§ï‡a¯½ /£tl±´xï{­À0ÿÁç¤X¦Š÷اĘ]|ç­ÈíCv5¹ §^ë=y™u/È’ö­;Dßñ®B2†å9 £èQÂûx€ºÙyå¬à§0ÎYÁäqQ B0ZA·0õ†sÉ*éƒ=q;/v÷ ÚöÇTö 1º~Ðý×Õp¨MJN=±÷/_½ª°K*œúþÉ`%¼m»‹ÑEÆ{þú°èœ¡ï¶;Ô *ΤW·¾pn;ŽCúõµµ5Ѿƒ¹äÜ멃ÄX™'uÇ8rÛŽœÇË5!ö?8žº¦wFx„L`$â,à0$ ¾S¹Q‰òaÄf›"¸–/j{JÌJc}cãÛo·¥MèÆßI;ßF7r¯®Ce?¯¼±Æék ºÇüq<ꚘuY˜9¿ŽÝš£I¯häŽÐ÷|AÉÙtm;Æ”†Qg kâk8}¢ºŽ—è͵¾8Ÿ0ðêú¶1ºÎÝÕë¡rž/ àCǹêtL2úÙõ¾»­ï›ãE* ŒªUBù¸ƒÔðÅoh¿wÔˆ©Ïü)DZaDt-®F èär#„«aÿì§"#ÙP(ƃ[«xûá~p€~@#nh¸ˆ+²ò?¦>ÐIiÄ`õFþ¿Ï"ð˜T¾x"ç*…Ša ß h;º5cçô`ÅŠ„ èåy‹¦sãÙó÷e5ŒC¤0è„êR þ5Fú±né(É€æ9E9¨Ú'ËF…J˜{Ÿ¯¾¤âÞûvGäA°%¾]ÿnC¬øž8¹¨oü½þæUyÒÀÒ&% È:šõc÷ä‚'œ®`Ja¤}™¤‹±0³°²QÔÀN œ?º›§={à^Ù~`6¹ƒNÏåDtß×&ÉUÁe<2ë»0}&©œûxS¢QKýCìÚ1Ü3„ý™§¿mÈõ H×É5ÓÙW ÏôïðKoä8í ‹='”Ÿü¡ãáG5Ê Î5,‚¶ƒî;#R 0}?ýö9ˆÊ¢Zß±Aâ°ìß#u÷Æ#ä# Ó®[Qðn:Þ ûÆZÉ]šåñŒüD¾ð(t)3˜ÐñŠxÞurZÑßÙ`ž?{öôùÒ2ÌdhqÖÁ,q£þ¼ÜévÑyÝî9°«ý[]nåôÄ(a2ñR4ëbóráÊ«âé¥A5Ä«Ý[=ÿ?;ï‘is8¿çë››D¯×ö¨Ûñ»2–±cðYÏí ñH)«È½-)8¼EªÅƒ¢)˺.QE (ªÅÛ”YÇþÓ%|MªÝXí¹n‡€ñ†l6 B¹&ÝZ†vdtwk;°½)Îr@êhrË‡ÑØï™T9QÆxþôÛM†’¿tiä±µÅÊ’D QýųN ;D!V×ùJ?s÷9¦ƒRÍ=­m|x¶:‘ÈÖ66×ÖŒJwÔ@­MÇöá9}‚G›µñ¢¾÷Ì—äM²sö²u¼óFÔ°SÇÖ;½Z·„cωaIßšJ@Ö,üˆŽª†Ò*õÚêÛ%ñ®^/ÍÈžnüåù·)TMDÑåÊ ¦†ŠfübÒ¸2áX:޾­¡[”èʸOV› 931Á{²A·Ëâ¥Cô³qa1µÝ+”àÛNý¯`#ïúx[Ñ»®˜ºadÛk‹õ¿ËøD‘°_Aht Ü8ÒQ?Ä·fÜó¤UŒ>Ó~ç?î5Šéoµøq÷ôäàðe‹¿’ÝUpýù³îöa/vV°e/Š•TuÑËÄ)Áw<„Áî”ðÊÂ*¡KƒJœQÉÄ•–•×v¿§äD»ƒ2k¢8Û›(P7*Ðd©Å¼2>rß\:Þâ$51oÅK ×%Ì…B(eWÂà7IWÅ?ÿYÕ¥¦×ÿÂDîâÕz}C¿0fÜpÑæTºŠ8]ôk¼¼Ï£\ 8íÈ(žŽ";%GŽÃ@Ý“áÎQ›aÉÄða‰-aÕV-v®-¤ú©»±Ãâ{å¹=&,T¢AæØég<Ô'‹î4„7h'08ž=@oF²¥ÙÉE³6»=ÕbbqV ä±Uƒb«c4ç'k_G:TÊóΫ•GòNí^Ó÷ãŸÖàCôýì¸a‘¾¾SN9±r¼sxÔx¾¦Bá×2šo:·nXÎNÇT¾A¿k~ÊaèêŽü&iþö_ìîî¢yàÎùîá¡´§Q¿ùŽÄQj®¯­Ë«¡2®,(Ú6îï0êÐHá­é)v«µ&DCÅ·mßÁÉ‘¢|ŠoµQl=q'Ï_mœ5JÐfsms ~­o”øÍÉÑÆù+ùfý¾ "ø¯Ä&æ*lY%ѳ8èõ5í¥ óøÿ• »õ{؉ËÒÐTjÙï‹ð^PúK¢NÁ§ œTžº4ô[t•‚±¥.¦/Í÷ôe㺖;¹ì¥P®èH ÏfJïÙÝlP<9z~е°ÜÍÓ ]9ò즔²­:%˜†Ð*NlÁ¡Ü¥¬õ×wCXÉk<ÓûÿO©À"êŠý?gÉ[4À©ð`€»»í¼<‡Œ¡ÛwÛ¢xÓǨÌ9NèBZ|qùy&gŒÉ¶ÉIwBh”ìš±UÎõ•Ù.Ÿ¾ø?´{{«e )Ó^Y¾kD¥m”óm”#låÑãWc­¬ºZLw¿0™:æß4é$¶ãù¶GNúN¤t£ÐøQH™ÂîÁp¾NþCÃùFLâ5qÄ'k<òi¾s_³I,©¼žf!˜E]#ò˜Pêí—eEþºí¸¿ƒžNZx>Y>1’ŠèÈ qç' ¦ÏGS½¾õLÀWõäbº¯ªwätü+öu¡ãaæ4íÙ#×™!ÌÄêyÇC( eg] ¯ýî}‰|ò·¯ÜàKÅã—‡»­Ýã½R!U±Ê ù½i”d<‡RaYœ8˜ñÂ'ŽWåtزU{(`*¼šUÆv1÷{A— Œ—;©¢^–𪦄–’æ"DmÇGåTŸ°h Na]•oª#oæT\`‡¨IX ɬˆ à…æf!0ØëX«øV¾ç3¹p/ qòêêò¥gûN l6ŽæÜ?$VPëâíÛ‘såܾ{¯iFwÕißžÐWï|p4Àdž¾× ”al1>çÊŠâf ÚÑ0*µIlzdîyÑe©[%Tv¡1.¦…ÂŒ‚É+²¶‚ï%iL åѲ¶Þ7PH·«œ³g• ú+Ô’¾¤¿Á«X²S‚‰ªe¤‘³ÝÛ·›ÕïÞ‰2)RµÉ=…¶#m#ç¨tÝ·›Ï¦¶dÎÛþÑx»Ý£_«Õ6ˆoÞ¿+Áµ¦Ì¬úÔ½Ij¼r)wiÒZ>´z”Y2Z¢õààÕÑÖ¼ÈØL©Ô(“èK*@øútx]Ûíò2[Nè4KÊ ‰KgŒ›¿Ü~û\`œEÔŒº\ŸèÙÞÑQþH““7t…¸"†ñ‰C¼Ô9Ž‹LDôAI’’j•¸LòK¶¿HˆŸd6v½ MáÉF›.=%¹—”*mì¡m2òÌà–+ÂýÖ ÑGZp4KÞ?«zÇ—q1VXÕ]ù׿6óÌ‚W–Åß9ÜŠKáêÑÉ2ÊÜyf(ˆx´¬Dí|PmžÞX¿/V†Ž»ZuŸ~û|¥¶J# aùƒÙø°üç¡SµGƒê ZýâfõùfyÒ0•„ ª½’ò§¢¥¢•|ËÚ–|2 ÔĹãHma­°Ðeÿk«l¼•&¼,ÿ¿pcÁaDÕ£k{øÝ»9YŸa{Ùd—Ì ­pºV ãÊb”Ý}QÕ!fÕ«lç6ƒŸw†cu­á®i–µ̉ÜCô"ň= ð˜~ ;0úA’7È e…¸ZáFVmGä ãâµ}¶R'«›±º}&c4Çï;Ä—Ç k£©s¸rX‚^|’½ù´G¨:èß•ëîÛ§ÀÿaP+§Šò]‡XÑо¢l“ԨܻK±–3Ûò F{[vP%c/¨­^fúçêÅ=qè•rm»ïÇsRÕõp|»¾VÛXCº¢/ë„)£Î"×~¾³>gA´;Ó¯O@¬ÕèkYÄvi^§Uq¸ó|3‡Ÿ›¯B9í醱 K¤_‡öêƒôø­¨OÊ+(g”XoŽAÔ(ÿo,åÞV ÚªxµS=;<ße9¥Y£?³nho¬µžoÊÑõsÌw–ì–Ù«ræ2™¥—©ÞIrG2”>´B%¯uˆI»ÑS í‘ÿ„b`ò‡\P<­ÝVH¬~rs}'>5k6 ŸZC·ƒ_Maþ𬥶Mì F²ÒA€å¢âÞ.´IÖßøŒ¿áЄ>PÕjY¯„£=ukütãÓª¿…UFDNO7&¤Y‰ÇE¼D™“§²ÀóM|ÿ|3öúùfÂxì¡C\•†cbvv6 ½vè[ÔvÄÎUˆºVaÆ~¿Š»FøÇ/èô£rGËgÊ‹pöV#"þäô{ìAvµE'^ÒùõWÃ,¼y2]ÅÀiÞí97~ðü¡Ž5‘Ös¶3M’±Ï¸œ½~iV½Ð§ˆ¿z·sÒò ƒÚÒ­œ:~9#-\Z_‚Òóvo2˜Leš,ü ÷”|ì‚Þ¦üûlN䎺sŸ²£¤ðsÕ2.pzàùFh‘Ü ÕæDiÝ•Tô×>JAŒAß½¨¥‰š!’ýº“Q ›žäXx™Û;íÝîž³ß;¸zyý£{ø¯ÿ{ÿ÷þÑàØ;ñO‡¯~ý£³à<¼¿þðÓÍÏ·oîþñï ™ð¥ê+¨7Wjµf¹4ëo›ëïÔï«íú••ãBÂ)1cK¬˜µð ™´2aâŒ{žìyýóŸE&L•Ë%ûç /uû}üú ÆKÖ×öèèâôôè!ÂÃ2¤ìð°ü®•z4"˜Vc+¿žø°²«Åt÷ “©cø°Št’ña£çœñR&õ‡z*U'§q {0œ¯“¿ÄÐðp]'ðš8â“5ùÎÔÀ® s_³I,©¼žf!˜…ãºæ0¡ÔÛßÝxI·Öª¦óÑx)?`«IR™ÆKq~’`ú ã%=°ÀU=¹˜îí¨ '0¿ãÚ¡ƒ‘btÜ)Š>‡Ó,Pr£ùÑQеz#€=~_öКÕ°LJÛ’Ìäî±,Ÿ²D;˜}+a+dKlS½®ÓÁ½óßP’6+зÈ{h·aÝ„hI¸±Ï«¿ü@T«Ðê0JŽJûª‹æcnﮊÁ :a<~J>FØ ìî ÇÜÊjÁÎÑrxbÊ Æ²°Ìf¿mwÞgi”9Š,²¥<@%lqx.t«³L3%+} ÍB~3yñ &V %0©ëÓ€ÌaRKÀ/¦"hžÃn"Ý€=zL’’-¥îœ=€hºs–)îœ5èÝ£ä™/y޾ö\(ÐÉb¬Ï…Ü韟o!$8?ú]Sž`“Ó²$É<ÄÙƒ§™üæ8™ÉƒðjÂIW­.÷Èe¦o¾¾Æœ% £¦ÐÄ¢‡Ù ¦c¾øÝS“ÄØOnV,?ãâ”>os·Šªˆ”tŒjoìÑgù±E¾èÎhüÙ¼VYŒŸJË呸ÛÁáѾrë˜Â]³+åDíQËæË×û<#(œ Yg†€SaP»Uñ׿¶vv÷OÄ÷©tõUŠI¯a"M2Px+Fh NO#'<±¶]ø\`˜8€Ü ¦pt§¼M¢ÔÙÆˆh 2Òf˜I2úAÙ—ÂÐf£›3 <¿Æ^·Åß̪8;Êõ#ü—•S£iåL“ÎRÜfÓâX†FjŽè%Æý¤0‚ ´ÃqÐ(þP˜™ 7‹?Àò/êʊ铈Sñ9‘jwMT_™ßÈÚQFÝ},–)J¤"Äžíö1ª;õÛþ@bÙÔ Kñæ”Ä\XúoAæ’GÏÉ£s™^^Ó/åU³ñ!ÉÕ‘a©"è}aæÉBj¡ÞG™ !Gy/À& FžÖFVÁHž“¤ÖÂÌD­`ètŠAe¼JÒ¡¿Èý7ª¥&tAúÊäôó‹³Ã‡p¨'8™:½i¨²y¾l®0•M_˜ÎÝ,&;^˜DóóI. f£Ÿþq·Ü”Ê©ãîMã0 3”¯‘ð£~>/1‘/ýÈW¦ù%Ö¾2f[>Ù}.L'‘EÿÙL&ñîw¿Å–-ÇÏ÷rúÓfï RTcÞ\›#ÆÆ·Öó°€¹ÆÖ—+G¶‡&Õ!W2¨¯lc8Û99:|ñ{ÊÜøUC—yÜò7«BüjvÙÑbªï…‰d1ÿ ˆ&Á±¢ÇœŒ™Eó¡šBÙÃigqóUò&iNà-1”'Ê?ò™i¦ÂÛׯ\â )§Û…(eQ‰3‡é$_þî2§j:.tªi|”:3¥N“Ž4ñ˜rgŒ}Äy{BòTø‡å,+)ÙsYì9¡3`¢Jˆbu€öCGøýn5ï8»Uèv”Æ8:¼jÉo*>rì¤`u⋌†€×Xý¾¬Ô¹ø]ñ|sSUˆ ޽XÑÂä-:÷,ÊŸω™Ù«˜õø·¦lHTCÑ,Ò|q?­”!àB`ó`J2Ha™á™ra! d`%U»ïwÞ·LˆïùÀ½AF†ŽÊz~:Öõ䊠Õvuî(ŠRƒJx·çb.fÊ-µ[+`(ïFñ#þ©ZÅÝ]L”QcrœÌ9 „(’ñ ,£>0Ð>¦ªÞÝÅ%/ϨDɪétŠF´KAèp“TAµÔos^iûFwƒ¶ßgp=[£[0ù…7¨- míÎûɱàå ¶¨qÅnÀ$§¹aMJMŽn–v¿Å#l ÝáB÷Éà 8§u³\bÖ× U¹6::Ò$rFAZô±~_¼“áWf² ªbù—‡ç?«ú×*L‹bè¤H» cì"Sü‹RÈ‹‚2`˜t˜LŒK7ì^V‰ÿg1.Åö΢fÎÒ¨H„£D2Ò¼"³eHb3ÑHüÁÉùÅëw±ä]Ä,o =ɲ ¦“÷^{È!]L—‚Ç<ºqÒ•Vö@ÙÕŸ"ãúUAÑEJÄ_ì•2gýŒ¦=êJä$ÎìÁ´(ÖPÏî8ä1~|ŽçÄ!¬&S÷õ3æâ%->»vhG+Å—±û¢Èri–ú-.Ô°p!üPu0)ë/‡¢¶*š+5X*Åzs½>,YN}Hi½‘kSbÞΆmÏ dTVñv<”½èƺâuN¿uíûïVf»x^y¢Õ‚¸ƒ+w·1_Û¶ìÂkáî1 HõM«¹Þ„ã9™Ç`l¢µÏ•´{g0˜î5 ÞM–®dÔ€ú9=PyƒÄgØ…7A#¿ñô™L!7ìÁ’\{‰šCaSxWbéšø)s;P¦Ï2À˜ý.:«_°QàÁ­ä7¹µˆ'ÖpûA^VfO"T›Ì—ºŽ¦Xí&Ó¿«G“Bí]9¦˜ÇÄ–#v@•.)4tEÐ0ƒÅ:šMĆöSÍõ•2Ñ•Q¶(°ú»šQ7F’s`Ò”}+ò»ÝíÂÙ2˜8TžBY29æhÆlÉ^Cÿ'.ˆYÇž¢ùçæº$êÑ@Ì}yø´ˆhA’ˆ!¦6;fˆÈT6’Ô"ø"ˆšÈ2"\Í…ñ4‰#ýGJR'vÏŽPEòÂe@+øCû¨Q0ò„I‡Eܳd™Krÿ¥ÛæÇµÊzós ¶·p$nE óm–.1g®ê."AãûìÅèŽæ$eb4©˜={ ]•Üquvi©NC9nÔ»E –%¬–Ez3â‘QIUK}µ„dMâTÆ ßÚúXQã­ù¶7³o®³åWn67ü³¸ÁŸGnèèã BÙ҉΅QÔLõÎ<{8¥µÇ\Ü.eçTxö¸`Ý¢w‡r\Ujt´a `O’û±Ž–Ž`õÛÔ^\“vúÏ!ˆ1i1VjµzpVè`ÐrÅ I¼>>ÿ Ѝ†Ù?‘2|óìý ƒ}ÿPKdcOtÐ3éç¿ ¦z²ú„#CØ >6Ë¿ÛB=hÅÓÏÛºtý—ÝÓƒqþã§GâbçÅÑ~ý#Œr…r‹_ÃÄ”aWê;0eøå­ûά|Î@UæèÚê2æ©êµÕ•¡ U@U¹þ‘*š½z×XuA¬ž,kuKÔ?þ®@g×*WiZ[M« ƒpÁ¸„£•À{»ñ®²QNÀ¹¸$äúÇáˆv!ëÖwàVTU·Âý]Aâ,çÀ½5q8+ìòŸ~«ïÓN´ÚüTÿè·6›kOÄ듽ý¡ÞÁ3~G­_>½k–WWÊ©zÝÞ !Sá±,’%z¦µ×´ vä·zs¥Y®Qð;‰ H¶+õæ§OÍQ±LmDp`-x»þî·ú/oÿöÃ;…˜^Ò¯íd_¨81Ù a2ÿF“© „KŸã¨ÕðJŸ4~18‹•ŽÌ—·Jâbymõí’x×\IíÍ2¾À«F;Ef‰EfäÅzQ²:)ðÒAqÊ"ôOhнR˜Å•7nõC¿Þ-I~É*Jåàð±1c5THQâgdø¼EÏѾ4Ë]-°uü÷)ûZ´‘?ºh¡Aû²‹¦ðЗΰ?ð_A fÖ®%>–DÌIiÀš)€ðÁíí ê ²V¶Ï}ññsV[ŸUÊ¥üÑh¦Q²KÛ1Xåm¶Ê_Y+o.¨Qð>²ˆÙ6j»Y÷”e·½ý] ·cûÜ ÆIÀTþÉÍ…w ² =ǧgùC÷Š{²Eš·,ìOb2Õ~/ŠÔNt¡…1\I€´2a6?‰ÉkÁM—ЋW ¬“ &·3Tg™(€í¸ãŽ=÷×±Û»£ü Ÿ´ŠµÈ k`¬ùF£ž\(‡Ê=ÖŸ$$â<Òƒ@ŠÌâuÿŽQ*‘Ž œä$ðì+ @ŽB1wø “$]å`§%sKQß¿OÂ]ʨƒ‹dr%f šd°ô“‰p˜f™u í„7ŽC)PP.® 6+2þmñùµvÍò$ ØÅ–¾ŽÛÐúùðä醸ô)zÒÚýÇKxŠÑ_?%ʵ~ÞÝÇíí\ìHQL U{GG˜´D0¸ŽIdÚäm€@«2@Ȉ™³cs TûÂ9…aÜ,ªÄqûÝR ÓÔPA„? œqׯJi‡‡#;)‡{G PµvOOÎ/€™õÍÂá ×jaï)³ÌÝÒõeòœŽ|ƒ[hvðMã Édj›“÷–¡(&;+·×|uI1 Ö%HY^].¸( Cɦi¬’ø«¹™t«Øõêû4– ÔšA®Œ`à ‡È‘gãÀÐÈ9L $’q'‰yÚòV±2ÞZÑ®&BËó1º…Á˜[¯ÎN_ží· ‹oð¼ŒÉ[®}ðöh>Òݸõ7Yôo±±ø\1NA ­{h¬9Ñ!¹9 ËÐâZì _ø¼]дÍâ‰="‹ÒrÁAi€t,“6ËIf€Txp¶¿/Z?Ÿžý}çìDâ‚<©ñpK€a§°÷WÊ4KÒ;oú lGRÆD$Eô¸ëb¯ÕÞ‚ai8­4–á #×)Æ3¬=Å…½b[£Ãç"þÎz«.ù/– ò9°eiuÿX$¬ùWJzµ<¿…ú Ø79“3VZ\dB¬äÈKøêw–L¡A͆4ÁäD»^L^ÆH®K´s+ij¦Ç@m1{‚ K,HO ¶!dí¤0÷d²—2$¨%íKÇõókƒ¬óÆ3‚ÑÆ€ÀÆ'¦H_ AÒpä !ý ÷Û"¯JØÎÔíõlEu•ÿmì|Á/ ,ŠL#ãP¢VÇ*Ÿxö8“”Êý“!yÊlO.ßÉÆtF*{w4±¦¸¨ÂbÌvh4 ³H§³wœˆFÝäTõzÊŽrÜéûéâ^<£I[¤èé½lºü÷IÀüDÛtáM5fË öÏUŽã‹ÝçA! py]–þV* F÷Œ*WçY†.½ýÛ;t\/¥…ä<¨‘÷æäŸÅlPaªG¾?Íë^–Š™Hhk•¿©ZE‘²*Ë’- ¥4qü‹´d‘'°µ~FÃ_ÃŒ‹goͲۊ4̇¨‚ ôð1€IE¹Y YÙòJ—.Ù%—òËÝÝØ‘Ï€vIy!ª¤JÒ#3æ•âb3SÜÞ¦FêlkdÂsbvÉ’* ¼]„­_Ç~è´HKÅÁ¶%8ÏÿT*• ~~ûÊxë ƒÀäËçÒ-^½ŽFh†üƒ°.Hg,¨Ô.¶'ìvà÷Ç ©cvÊš…&ϸçòzanŒ¹UõüÏ©®g`ú¼Gd bûø­;Í8Û,šk  XiA7÷ö³Ì&ê뉵õ§›ÏžÿåÛïì60ã^ò»|Â-ĶH×ü¨Km@1‰á½½­Fqoïsj§ØÛ‹YG#i‘rƒC›ê‘ïãá„ñ«kmú]¢‚×údÎùí¥iC údçx¿ztxŽj?Ð\…£êv·Uô»Å Å¥µw„§FÌHÛ‰™j«*™Æå& µ0s Lœ¦ÔûvÐ@•LKØX5fÙ ¼ÖÛÈØz:ƒ¡)ËšƒUÐPQ— çFªY4²UÐrg1ã½ç#žR)ÓN=Ï\=žË§˜ì—ÉÍ·bÇ©0‘Ó.’0¡`#ŽÅ"E¤:™eäž, 9Ù±`CÈ;¨Cñ…Òƒ7Cð×Ìjy’ªp u .Ýņ^= lÿ (£7éž`G6×¾{®ºb™¡M¦gRÒ7[³r;!³€lþjÝ'J¼­ÌH(É"Ñ^M¥ÝïŒûHyN Cèâi°&Äù{wHÙº=ÃØzd‡ÎˆÕlœm—íjXA+eÒ‡1[ï`R˜/Ü?V-Ë`ÝÒuC¿×áhTÐ¥Obõm³Y}ïEG/økYeà$Žò|§£‹è¯ÃñÈíÝéçòk¬j³ºû߈WêGÚÙBòK!’coñ)ëK ÏRÉ_¬à›Újý›o¶EðÍ/lÀj÷];¨~ó ˆ¢™‚>†]ª*5òU´«Ï‘÷¹dK–laɱŸK’àŸQi;r‘ñr2 Ñ&™ñœT/ÊÞ­ì=™¿¾íuœ}e‡üE—È2|¤TˆH7W¾ÆMrt„ŒŒ‘dÐ|®ºZÕ&ÂËâU+ÈnðzfçÅ!e tßBÛÝq‡-裋?iã€íwY¼bÃJuëºP•¯cii•ð"ÓÝ.‰L êé%%[õÆS§g(F/£U¼ŠY`)EÓÒ¯^¿ia¾×ÖñéÞ>°ýÂ’^QTŒ¸&‹=ßÔÅä²ËÔ6ÉØ×@œÛóÞDÀ$8 –ÉD¯$‘[‚mºä^GŽõ¿EÉ>ï<¤œ&ó‡nü†wRZZ夫HB¡üñh¯Úï~ÕÓï=ÝhŒ ²DT°´z—SŠzO7¢ÒœŽ5¯ÂóÍ6ÃN³C#ûPÃ1û•3Šûþ|S•JôšÖÏ„ET€á°««œ5öq)ýÞKÉŒû ½EynD^ %øû™è&b¹éÄJÝÄ9îB8>‘‚݃ÄZZ=Ê(ÖO»O7ä"ŠÁ÷LLhà‰¥/ŠXÖš²Vn¿}ÞBÑã}oä8*µò'õ”Ч¡㌆½¢>ÁÑ$xúÝZô@~Ã䟂¡=êün«Oˆ?4lÐPÀÓhtÑG¯·äÔÆ2Qà†ci»pƒÉ¹ÑÞÜÅïv_‰mº™[¾¸•`ܹ6Õaßœ®gJ•²b°‚;n ß5\ö|Ád[1‘à|p;Ž€vy[ɑʂ` ¼æwM†BÇË)<Úð%œÂÄ£¸—»ÜülŽ—ËaÊ\!e¾¨M.9ày-÷)TèAA‹Ëà6AQ‹biÆþ-ÉB})_.e4út£Å @›KÜ ü²‹SÍ¢ÄCŒÞÊÿ|Îkñ.g6Þ;TÊÊ2 ˆLÈUn§×na¹xEdA³5Ü¢²FmÆEÖ6soÒàò3G>€,,Ï2Q0€æ¬Ú³ÔMVÍÝ&É™ªÕY:0y¦¦®ètó`]§ž8ß=%§Ósg„ûijŠ2xÕ6´K欰 õÆý~µç£Á„Ò¤âtÙÙñ|ç§ý¤LÊÐ…Yó\SkýªR¡ S7<ÿ±„›¯œ^9OEÛé´¨T -¦£å ¦Ñ¡1Ãa£TÜ}õJà/BJ©íønWT;B!L—Ê´Ú ª¸)Êz~†IM¨âÑ^L²oÒµ9,hÓ&þTZÒþ¡QÝÉÝ2+¤{Æ’:+¡>þšoÅç †Ýä=6ö Cü—ÓÂ=Ôß±iÈѧÊÈ»vSgñ§FNñ˜‘>YJÃÿh÷h·A:¾êtÄFíÛÚZE8W@¬×ÖPƒé9°1l£äI¬…ZbF1;ƒó‘ €Íš‘~—£÷£t›+ÝFŒy]‘ÒnEÂ0“.l2¯6Ü@…ÝTγ>0VÍ™W?“$™¨”qa¡d‚Y¡E²A&8}Bæ%€a `¼µuô UØ‚Æ6HuÁÇC`Î¯ÙØo@¡Ü>ØpÂÓN•ÊBwä'e­Åp +.Œ‘Êb£Pu©B:‡1‹b=ßÇdt5#…‡ŸÓz¶Š MKÓJ6Ýút¹ŠÍtMнIyóEâ½Â‰õ:¿²¸ŒÇ;'‡ûç­Jnƒ—™1V¢‘¬ñ›1?6cs4úÕDjŒ÷µ˜7ŠÂ,Ä3¿¸“ ©„ “zûÇEа\ÂÄ|Ç»=-Ư¾:ö”ˆ‹;UeMCvíG¶5-¤l‹_¯Ê\m“P˜ž 5;™‡å”ùÝÏ&z?›˜óÇ0´™ah3/Im¦‰h;ÊÜM!j3\"i.Àï‘_ÇÀàyÛÛs{Ø2Ž{Â>0Kõ̽ƒúÊv‹“ãý½Ã‹Ø%PæîÀ¯ºÌãn¿h\åâW³)ÈŽS}/L$‹ù™¿"šŠÿqrh͇j e§qœÅÌWÉOL<˜ì9·ÄPž(ÿÈg¦I o_s‰/¤œnf ”Eeͦ“|ù»Ë™ªé¸”©¦ñQÆÌ”1M:ÒÄcÊ—1öçí_R¶ì»CÿA$Kô•íG‡¯N€ÿ#˜L¾/òý#ŸÏçóO™¤÷Õ°{êd1ÑëÂB˜Ÿ­3¡$øzøÇIiúyʨoÓ8Ê¢ ä+äÑÐLjÌåšceùÈ4y‘qöu1sÑdv¸0•6•3™JüÕï.!rÃqù§íQ:Ì”#Ê‘äbJ†“09ö—” }º¾± }e|þôÌOs O¥ÍÏé£Ñáž~šc#ÍøÕ0øÓ”±áiÚ¼ðô¾…§™&„§¼ùói–Ù³ÄÉé,fÎ 3”¯‘Ã0AñtŠqóįù‘¯Ì&+J¬}eÌ$¶|²û\˜N"‹ Œ§ì”Oÿ0ûäÓ,»äÓG{ä Bã©i‡|š²?>MÛŸFöÆ_Rp|¾ùp¢ãóͯQx|¾ùPâ#à*W€|¾ÙˆJ=2û)B$a+¿.AºZLw¿0™:'‘t²J~þ‹”IêõTªNÎ$X.Æp¾NþCÃÊ—9¼&ŽødG¾3“‰˜ûê˜MbIåõ¼0 ÁÜKÜÌ`B©·ŒÈ‰mg8bg¾Ø©È)¢¡”è©yI‚áOID$Ä"ñ°( ŽÖòÀïŽûޏã&óåüŠy>mö†1u¢š÷qjËÇ^m1)9áÑEëøõÑÅ!’~}´¯–çÒ²xq§BJb°²·ßÇ0–Ä¥㣉øcÚ,?Gí;ḠvÉP¥t¼îÈ÷0¯h”f>ѬéêÁ0¼ÒMŽâÜ Ì`Š¡-)žO£ôˆêºéªþp°t„@Á«(®zóÕŽz%]»ÑuïàÛªJ8GY¹}_¦h–¡±Ö·1sOäy×Q¥u»»'B=Uýt¢Y¨vï@tp;ø­ús¿’@bԀ̉7/ü%!fn"ᘨ£Á`ž•¿ø"𰇨¤“{f4!œy©ï_q%+Ö…59N(%oÅH¤vŒ¼Çã|ÊG‹É1åâ@Þ0̸7É<†ä ;6»Fæ ÊÄsû¦Ü+¡o§8¦72r{F¦dJÐM1TìÌk¹¥è« ¡`¦]¬o†â¯¨d|˜½x‰2­qÇ3(Mgg\£èß¶­¨Ïù ˜Ò4ª‹ÙCÃ8;È<‘«c5ÊxÐŒ®æ¸€æ”äD÷`ÓÎ-¦;ˆrœRžºyØõTyl»ßmeÖ½ï΃1pÎȹ'¤É±¬—ä6c[© ¢B©¨‘š¡ «Èl³bÖ·tp¯¯7a.òR‘ '¡ù‹)\Ò³fÎá½Bûå#g N*~ï…¿:N ϳú²kMXrQ…{®³P´¸ºÍí¨[¨dÈ, @n‹³*cöeE´(骂æZLîãÕŽTÍŒ©Ö1ÚÎQMÅ4ÚÜ9ƒ}lÛl£r¬¡)e3 Ÿíœ¾ˆ×ˆÌ*`™†dd &n×fÄ­)#)èf3Äé¢Y¯ÔêùcxXÐÙW\ÞšQò1ÖK–Ø“S‚sqÒ‰D®P’h²o3/`ÖêâØQ‚ç }4b&Ä,—M¤¦tnV6âÖºçÿ8¾/£F”Ï]ãeT¾ÒY£R¬×Þ®­o¼+ô/Zv¿ïß´Æì¡.¡KÅ›~UÞxÓÿŒYŸ ËAIEUTWg‚<7l¡n3ÚÌS;k«eÌT@ųڭðUÊe$åÑØC¹žŠõµÚ3J\â5ˆÍ(Dwaß¿£ƒ`h0¶Êb aÈÌW§ç”ÀÀõ=’ÙÜí·Ïùðp7“à¢êq°Ë×Äžï•Bq‡Ö>œXAˆÿ!»ôãñÎîéù›ÖÞþ«£ÓïŸ\´.vÎ^î_T¡úÚçJ¢¿WV¿}¾Ze$|»ú‰Éïo¿[Ç1Çç™My’Bò߇„rl‰¨ãm¥6 Ä9gÁ?H?Q>é‰þ–)ëd gªºd‡JÅØ°T0¸Gv+¹²OfS\ a/[D.òÙ…AÒ¸‹B¤We¡Ô‚¥d2¤Ìf~“þuÈügƒ+ðyæØ·8–NäÄ­ø¼LS—ű҈~ûØ5‰šÄ„v[ÙƒRUÌNEDPXæD€ƒ±wåÈä’xÚúiçìpçÅѾ þ²¨NÿRº–ðŌߋTJ˜• d?-Z-8C{DÇ{jÔï À®Ó } µ/ïQß(^4Ÿô½XJ@©¡sqsív®±É ¡ÒbY\Û°wÊnÁ#kïðìíüz·eÁWyt£ üNà;‹5k”íÏÂY‰“ý©q!œ- h&8¨xÉ¥^˜Wï¶¶ÞÂß­wø;è+‚újZ÷8†¶Bÿ`õª¾3[¯’cÓÀU]h¹oËÞÆˆ ™t¤j¿-n¨Íö¶œ z¼º=â€Ûë¦%ÓQBE™†²Ô·ê¢~UºÍbq½i%áÜn­fÂÂb´4 Õ­|HÍ4¨ªƒÐjP«^/ÉoiØF&«lÕVÓrƺ:'ÊÒˆ |^4úÎÉù¡Ø×¿à èö'f Ω‘w_ÊeZAØí,v²|ÕȲëuúã®#þ ÝF[»þ>þ šä3\ñg=`ç!>Z\Ó¢2Éf)[Rè2õ+é—ó«TRØÒWŠÅxØÍ uþè|츸 ²¨BèúßVuN[ œÁj…XûóHWB:©=üª¹1°ÌÑýù.k8LÕâ`ÿâ’Ü>¿,ènçzdeŸ¹`JfŽиGwfs ôð|WlÔÖjBQe¥˜ èwA©Z÷C)v÷C(¥SètðzäpäÞV7kx:‚£J@·,Ä´:áÝ(ÕÆW1ö€qò¶j{[3ï “É–Ù"­Ù­/¤¨)¥ùÌÌJI”ÄŸÅÚíÚÁAY4øic­Œ‚$€¶ŽNÞ?[é”ÅJÉ.‰¿6~qÿÀ·Ò¿KFñ‹Óׯ^ÉâFÕDi§$ž@{ð¥*PD`øUiàYí5 K˜éi%§]·¤‹xWJÿÊ*6J rF1Ë0hŸK›kƼ®ÛÙYV~sz¶k­uWVjåO+½r™Zÿ“|‚ÊÈÿ ÌÿY0â,&¶uYq9å‡+þ*6žÁvè>y¢ãb®@+P"ècþ.øP®(Ôá8)Bc¡?ÆTçørPü^êa”v´ fØtFc/cÙcgY­É fäÔ¢‹.q5ð= šÚnÓŸ e=jñ'nEmǤ7&\÷‹^ ¥Æ“iÔ’* š:…×Àñœ_ìí¶~ÜßÙÛ?;ëðûhy3£œe‡g‡oijÚÓŠî‚:.sNhD_j×”!ëöÝ^î× Ò~JÊZ@tº*”ÆÏ˜g?ªMDoаÁù£;ýËó’2šƒZð >Œ=ô»ÐÛ®ÏâH€öG?R«ËhÄ1ÔuÇ(Á< _×—E$5ªÒ)é‡'C  ÖmÊ—’-©m*X8K´3ÑT5­Ûf1Q³IÖBL˜)_‘~ܘÍ¢50Fù#fHÊl…—b]-5šZ2ï*¤'ªÛïu<£3âDV³¸¦Ç­ë‰x1m§Ò)ñík:J{G»'­³GÍ'F¤°!* Z¯§Ø"kýäa±¶Z‰¢RK/O:Vñ©¥Î:VðÍ/Åõo¾ÙÁ7Mø)n4‹ß|c]Òq-)…LbY¤û_˜MURËx¾ÞsBg4@dɼ9ÚÄ§í  ¨‚ α€e÷’\R£p~\Û˜Ëõvèv°åå5D%.ð„ÐF汕Ýzïù7¸öoH#3vûpø÷ÃkYùNé‚Ö+QÀŒœ_Ç.RŠm7ĉs±4ƒƒ& =ЃÞ8~ðG5PᶃZ¬Û [2Ç¡Q‚,e½¦qÉׄ’×h×:°ïP-䈮`¹®Â´™D6Lë!Ö¨…ksY¬Üz>ï©ùôü’Ò¶É$AR«3‚”ƒJ‚4n^?pñ–4H}VV·ÙÅedñÈ”˜iÉĨøçmŒÈ‰4¸h f{Ž?úw–Á«žñÖ–E±!rŽgED®×e¥—Æé€dPRº_YKA÷UÑ£â*À©‚î¿€ ˜=Õ/ÎL'JÕª,_ep%€28AU0¹þ™º^8dºŽBZ YwDì3O'÷<ó‰åõ„&/¿$ù ¬èêo¿†7O7ðoǹêtðƒÐwÛ½Õ§éDjê™ÕdÛï#¶bß È⃬8pVóHéŽÌZ#yš¨Ðæ´¥ã}JE0}È .ºêD»lD· J¶óaàƒ ''WNªÑ_Žqvm70Œƒ0ýæ,¾èsç­GRî|MäâLA¯wJÃ0FèѪüØ^3U4ƒÓ™<­ìZCœD¹e²Ð`ètÜžëpW"|4Åå(Åàò8\Ô¤ÁÜÉÊw79a>+ñѺåmÐÈ1ÜÝ¡á!€ŠTÈ“BVWc‘´à=Ûí³EbÏÇ[9„%eˆO¢*}äôýosg­7œúé†PÜS1Ì.˜}ë7†:ø¼yw>8^öŒŠ‹kʵ)1“` 5eìI¥E)¢æ$ƒ88@F]šÀš¢IF.£h&‹Ót†c“Õp2Hd)ƒ.ýuíç›ñ|• Š2jPÖh¨¡2p›™"'ÓJ"Çb2óáŒ*N÷yüˆÔ ³r$“!x%/Gs ”ÐsCÃ-Ü®ëw^gdnŠ_\Jc#kö`ĹB¦X^Æ·â<´GxC§»K&¸ò턺ø³,ÎPesUŒÍÓ 8ap*”B<é(fíÜ]¡=Ì4~Ó{~Qû£=ª\ø"þ®vð ®®vð•y¡íœ?€ëÙÎy¦¿Ù³Â»Gϲ|Ï2ÂQ±}5®e;ç1²óBîÔϯhCâHhÖøÑ箚¤å§z5c,Æ ¾:~ †ü`©9¼A£Ö(÷È'¦y "¾¾&æ-Œ®¦PÃ¢Ž¦LÃ|ñ»»—b³qÏRœ&Z<Ž¥YŽ¥Š^ˆHLwRÍ"^œ@úC¦ƒë÷,ø„õµ%ƒ;:z ÐURv*8~׈J=òñ ‰à4¶òèñëI'»ZLw¿0™:ȧH'™.zþf€Ë¢þPO¥êäÔôo‹3œ¯“¿ÄÐðp¹ß&ðš8â“5ùÎÔÄo s_³I,©¼žf!˜…s¾å0¡ÔÛß?ã›j;‘ðMM磰™ŸóÍ$©ˆŽbßbü$Áô¿œŠ$ãÁðaBè1¬¯-„Þ‹ÿÛ{}üê!Bè1¤ìzü®•zÜ&„ÐÓØÊ£Ç¯'„žìj1ÝýÂdêX „ž"d½èùB/‹úC=•ª“SCè-Îp¾NþCÃÅЛÀkâˆOÖxä;SCè)Ì}uÌ&±¤òz^˜…`¡—ÄRoÿzªíD=5h~=“¤":Š…Ñ‹ñ“Ó—S¢Í[¢¥ŽŠgXæ;ç ;à˜zÑ;}b€J¾•‡¾dQ=·PTõD.O3VJð}·ïüwì׿‹LmY(º\µÊ5”9 Æñºr?8^-2#)~Œ™G=Mç3Òü589—ù`÷qCÌm1l?¾ÚÙýûÎËýª4•0C;èŠÊß͉DÜVKN¾õüäKÏOùX& è¨G¾ÿƒâ!¿‡-tLnqå‡5!~¦mAØý¾ŠT6ð=vx–f±þ(¨I`ýY”Û Ì=~%ö‰Š Ð ~øžlO¢A_¢šÀÂ’Æþ›"ÔAtã'#ÜY AÄŒ[’ìRÓ.¥’ÆÓÍð“H‡íš&“•™t¨ø=I‡Í÷rH‡_¦I'ùþ¿˜r4~Šr"€±À¢iÂANöj94£ŒrÈ_±¨rÛˆÑ)¤"+„ò Éjc §¡ $Y‰.¡¬¼¾‚À1Kš}Ÿ"¸’$ übÐ…éD kEL`%=;«®”x›ÈP°dK–œ™­˜•îÇ\LH9,&V$Jûïå7I”=×IQïf-{Ô¹JqrÐFg¿¡ÓivŒ•¸È‚>DßM4Z´Ý۷Ϫ߽[­H3çùOÕõ„¢«xd˜™0e–>9å×dzþ8’N8~//vNÏãÉ0Øjà³–!Ÿ5C©—š‰CGÅ·³™1ø|m~BO¥r!;lFҷ嵇®N^´6`¨©QÄÝXÒ¤$WHô‰ž¦ºn¨#T@Å$.îR1Ù:|Ô¹aR=ˬ"‹Ï°MÀIÂ2ÞËØlŠ,à%GLJ5ΡËâ­¢Uí¾ÚºC²¥ØÓ@´äkDtX@y–ð’¼d%¶†ø>ùøˆ¶Þ¸]8ó¡u~}v×E»e`w¢\j~ }Æðcëù&|«H0èµBÜÁ0V¿W7À Bh½W!fˆÍ0Þ”8pûNMÂÙGÓ~r xyòZ6„{å¡/5œÕöw/0.÷¾hCá9ÐùRu(z¾Y¢`ªG 3xüë\£×9FFFç€ÍÄéhk‚CÅߊrA|ºQ®Å"X=ߤ@UÕ§ŸãQª&°FÆF2FÕä QÐ*ú«Œ–negeCH$g©ñ$ XÐ#‡ý)”%;áÑèt G‡/ðÐŒæhË@_}„³Óò h{ôÇ#å㇆Õ÷D5°¥c*©ÿ<ÿ±õÓþÙùáé óÏhZà«? ÅÉiëåÑé‹Öùëç´²Sår´)Š\.”5–ß.ÆÛ8º@ Pˆ(^HaðU¦éçM]~©ñbv¥A¯TËâø¼ºwzU¡Ø{­ˆ"ø±_bÛ¹Â%ÅÉ» A%¶(EDÈîÛ=â_fÍ‚#½$ÌËîÄ^2 Mwã>º •ÔáYxÝÒ.ÝÓ{CÆÓ„ù”–ê2q tÂÂD¸ „‹Ð q‡\êå.ºZõûÀ 7Ô½¤ÈÞ±*Á9v ãMÞ8Ä«°æîéѲ£“ãýóÌ\ŒRµI >Øž\“¿ŽŽ{=wþ{Ç â‚-Ðô1ÖFruÅ{Àaö8Š`üÁÃTä½—}¿ ‹êh°Uð‘ÄÊGø3SB̈]²=éthY[”jvIos11çŠsÛq€Ÿÿ´[!GoûûP£Û‡?Îmذ¥ßЕ7nõ»Š~HMÉ :·»Û(îîòGO{WFÒfÏŸÀöœ(æ'v ‡ìƒhèïÛÝ%ÎP;“%^ÈøŒ½£Õûx/Œr{\b¯}ݹqt¾?Qß¾ QÐé´PF a¢¨6ä‚ñ´QL–“q ½D‡¡3Â`„|°")ñ€Ó­³ðcX(×~WÍ(,¦ÐèéñÎËÃÝÖî1Ck ¹1ê*ð+BBƒ‰EZûÊ;KYÅèE«3`ÿ⨒Aè Þü%/œ±½i×€Yuò6 6¨;¼h¤8D‚øzÛlÖW߉OBü°…ŸßÚ²šl§]ªí!Ô ‰FN³€rÛ‰«Cºy£›Û†U#Œj•(C_­‚¾T׌ª¢¼Ì92Ç–Œ¾oì÷FDkU¨žM1±1­²¾•  Û‹Ó2>l™--M^KVTYXz×7r®œÛÆ%pö´“Ä[„Ñ\©­6ËÖ%2•5T,¢bÓ$Ö£hf ÄÅJûT hW*–Z1ÙoÌ=¡KG:ŒB¶¤‚€«@ð phw±þýŸ7 …ÕÕUñ3§ƒÙÒj!<ë(ñœ”»NÛwʽB£ªà~Ü£‹½ÌõB•ö-µ=”ºFNÇ¿òÜöŒ0.®)‘[´Y}gÉ)›Ä{Y+â¡€üŒ;9ΜI©×s¤ñå›A§mÃÕ5ò¬ÇF ûõ’yr¼t*“2LÀ;´¼FÄvu„¦nàé ºeº]Îﱯ”] Ë'0è&¾®`¸lƒ£G‡^=‰†ÈƒOïðÐ"]†aòì+àM0‡ur*&íñUUvío°¹×üÑUAù§¥@Q© Ÿi­h£K÷è¤&õn $¾ âüÎŒðh2mÁÄV}´+Þã.ÞØZ2uìÍ62ÏuÿÖ"w|ðÑ(g2O\tãžaŸ~Ü–ÿƒ·åywáÇM÷qÓ}Üt7Ýÿ¾M×PHG(Ø*¨T|š›×ÀÔvµ_©ÌãÁí\¾PPôÌÁX 5 R‰ÁqKÇJn”Š»¯^ üEÊ‹=g•¾ÛÅÌSE•I•JÅAÅSU\ ²žŸf5 JgVJÁÔ¾8וUAÊp2þ”#¿À"è8ÄÔ…¶3%ÌíJ5j&PeBa޲jé€LÉêZg#?ù/ÝJb¨Î%¡‚²î`Ø×i# T@SCÏÕ0˜õc¤›¥#E]dK'´ÀX½Ödø”/ KQŠ-™åte­¼ý¹]bb<*¡ƒQèUáªÐ­Äîn­Àš±ø§Jz´Ï™µ)«¸ÁHXI 4óHªÐ>ªulŸ¥ Ò¿Få°sŒÉéæF5MDQÄâ+G¥ï \ ¨ä†|µ›‘†êJŒ²ƒâå2Eƒa``¦¶C·Ò€Qn“ÈC/v^þ´s¶~û®Ì‰SON_E}jííì¼>ºP}ÃÅ©òŸõ¶e†W‰”Ä<­2ËU×A¢…½”´¶ÑŠ ‘V>°¬Œ0ßFôt.nQ4t3:ºÊìPÿ¥Xïn‹ú/bõI½[ñ´féIÓJã2™òë²P<;6¨Ï;°8QO–½ÏXë=Ë€ª#sLªjwç§ý ±ü Äî-|r¡2êz²caÛ`Žd,¹xçÀW`Ç¥›¡Îµí]9‹éüZóïÁTn[1ð™æ@²dÑ.CÈcÎ+T柳;aÿAÝ ˜…/º»>Æd®ÕâÛ¯šVµû"!ͼžoϧ˃ÐõZ¸âÑÉRåaz ,"«ÍTu“!…÷AF×¢ãÁäJ¢úFs™jvcùZ&¢šNº2o½‹fñPª»…I¶@V ¸‰Qºü‰¯EÐb™wNH¹GãØè±f+ªt‹‰€¥Ø”…%sœÌ´Ò¡×åRµN3iMÀ²B‡ï”¥S9ƒ„Ô‚MEë×±°[@v¸WžJ"»™xµe¼N™Ò|e½ G ´k ©Ë:_eA&ºôG de£ ›Fϧ3r”2’SYzdå5_yZV&spú¨1„蟆 6 Ûô¿]K¨¢mwÞÐ¥k´nކ¤ïû}ˆ +VèÊY\ß Êä·E­ã¼×þ¸ßåSKÇa®¬þìÔE„ïex®øàÚO .°gÛ˜~†æý‡GÍ »#7µ IM)v)AÑV‘ü¹ùq­²Þü,¶þ\LRØR.™•ÄÛ_Ä»U…çfMÞj›•þœªTÌ(µUºÄœo„û‹ù™$[`V«Ö´hy—£Z–ñÖJä-˃w¨ã@&ÍË–gIªífñàµE Dû*QšÌe½+ë¤pÕ@^KòJ©ixž5BãoQfá”l(d,·'bGû®‚tçXØù\•Z·%þðö…tîIåÙ0ÆÊiªâ¦ç‰V|_mç·C #sßãØø¶Qˆé þ”Èͺi7ºnÏÌUz;Œ—ø>©˜1 ØD6ª³§òYœ'¤§{vLl<ÇÞcj¶ÏÌÎÃ8¹²Ÿ©û6AœXd®[Ðgð-•ÅCÙÛ¦ Þôiy£›¦ŸJÿ‚éß–)ÿd7SÂDÂ¥ì×*ÞµôU)òSËŠXèl¶à@» ¢ ¼úÕán-¡ZÅ€¸ÔK>W«TÙ¤æ™@¡Q !‡;Púgá¶¹¥üÞ¾PÝMh”2Zªö oFPµ730}̾³Ì(Fb¹·ÏÔ‡çøÁƒõúC»ì½§òï¦üûÌ l ]LŠâèp/Õd¦ v´ÿ€jVöâýªð¾2ê|áWm.Ú‘uÞSÎOŸÅ02ò5tM¸-†N¿¯Ñ]R`“ª@C"ÖDý£¤(TÛÙyI¬Pz·¤A—Löʉ*nmŽË5cQcÌì+¶hãш+L*Fû1ž9 Í…¨v&"$E3™Kö»ÀEîú޶å¶Ç¡_uÉP¸lèÕ'ÆÞÞÑQkÿͫӳ‹RNTmù‘\žÀ/0Õ®âK“èG柆 Ó‰´'’…/£T£˜€¦Qºì.û(dkûKÖ¬ÿØÚû¦³§Ü‘Sxl1ìÅ’ä`×¶û~ä{:Ì!‡ÎéµéâŠÐÙXâì|Ø\=~¥;j؆Óżçt”• ¾úw”ñWQÔü„ü¤QRžK Ò„lÆOHjᔹã¸k#‹äÓßÞÈý6jy’ûFf§(eÝßgõ3n3ËP÷eCÉÀ‘±pµÄ 6ªã}é?F¦%R’ÚA rkðÅEx=Ò»¬¼]UmÖò%pSþž"èÿþ28äo{ æTÛ‡[èIR‡Aw`C¤œó¥<*üØs©èݾ‚nÉ=–ÅÉÎKôG¶§g<Ÿ@Õœâ¿J©0EŽ#fž·Éõ‹dûõˆ˜((}‡ˆÃëkúÓúìK;W¼Š„$n¤´‰Zº¾¹´Œ5£Øó ¹ÉÂÂÏ“æàD“@©î”g_¦™žØP»Þ´Ç^—îÓw˜"µÒ<Ù¢øñ¦ÿYz˜$wØIgÇ9§h…zXý;|.'ækšx]ªB«­l@§z¿ŠÉƒªWÞ¿`d›Àïƒ@¨gð;¡àÈdTËxx#³OdÁ™*Ò±†{r‡ÀÌJ7T=-þ¥ É“„ÿÎ’ðt•TŠO@ò¯r…lã@°6”Æ›ÂùËÝ]Cîqt}MK¤v‡¼‡¨¨Ï€ãÀH˺.'‹s á‚ëÝc`Göµs§wˆokëšNzß=[°?Z’œÐ¥ Þ¥w¯¥œmkiÚ~µ4i£šE²ˆ:2™-‹»=rayáà]ð~ÜÊK¸pa"wµPùe'.ê×P&^õþòùá»5õá™üÀ˜‹ ¯àY™ôK‡†‹ôÊ*0çUb¯8†tÚÓ& ˆ^—}ßhã•.œìPpC££évHc[Drè"À ÜQ«ûÃk;K<_4:rÛG”·¯ÔßþðÈçðűxs„òmm­®(z}­¶^ëëµu!_½Ú¥ÝóE켄óôB¸üu.åOx*(%6ObÔ—dïö[˜|»Mñì×K²7^={M± »eÐT«’ίð|U}oŠ·ëÕ¿¼«e¼ø¶öv­úô[*/ xi0œ§tZA5ÌÏØ‹®ÛÔÉÅ—xšA“¹ûL‚èRÉÐ4夯Rþ¨þ?y®‡Ý1Ñ™]}»âYí»/ݦ7ƒÖZhËÆ¹Þ=x·ªx_Zb@&sÀY.Š6#k2'»OãüñgbI[O·=ç&ðƒçSô7ÎN3ó¿ÿHýÑÄ«ÄZdÛ§çõõ,¶½ˆ0;ê—p‹P"ï—˜â 2³Üïån/÷ú`ìÉçø‰_ѧ ²›Éc&¢ôlL"xhÎ6§LiŒ¯ÍªT˜{a®1€kãR𷧳ݗX³÷V£–bzÔÒ"—Õf_ˆzÆž{‹YZ KÿimƒŸÃçgè$z G¼×'‡oþXäA?;“íÔ>ä«êuá$æ1 £žÍÏ³Ë õÍXshÛ‘¡+âxNJ©o1H㢮1è µº'•8xAâzWh3ˆv’«æK¶ˆî̤RÙ:qnÖŠ§^0(‚Ö›ëÍK9gá§…G˜\{6³S …ù`¦¦”Y8 gg EY¦g°~’åh𙓛W‹ó>ó  t€  ƒ±4¤Cz£+ »Ž)©Ñ0·òw)÷´]ÖÈ&OêѬÖ˳Àš™ZTüAɉAþ!6Ë“ÿ£Õò£Õò£Õò£ÕòWoµ±ÐßÕ^Y7;ë^•žÝF9ªfàåÉLÖ­ÎN«…q´">fK€9 º¢4x’¬9›3xf¯Ï|YD^æåˆ#p€(fœ*8μC)áóv×ÌØïø}Ó*Ü×ÙÊèi1Ýö|ËLÀfYdµ–ZL¨Rp!OoéPÝPžÕøB=³´»uƬLÉ&åi™)Ö£¦ÐÒá2¹I˜\;ížfÝÒçK2î8‡ŒóÇQœå-‹!ƒÀ;HŠß¬Õëì…_ëûÚ 1½ù­«„A‰½ íYšÞ Dz+Xt3 Á.Èôg AÍù#ʼnywŽúÉ#æVkPsѤ÷ÜUÌ^Í´±$+̾·ÄjßšÀì•UoÄÁÐMµƒ‘(Ð’§r^Õ,(³ñJ(ýp,€IΘ £XX\´¢h¾ê- °ÝØW.àïsúËqYõl]•Þ0ñþxš›|š{<ˆ™¤3ñ0–,ø…dy¤ŒuÿÓÙ¢°Â&ŸÂÒÈM<É:%‹èY²åtÉyNfÈ3wÖÎõÀïŠñ“QCÓ…gésã÷å!^‰Ñ`èzCh9Ð_\þèŽú躷,¨£Ú˜k‡Î€£™Pv/t)ÔEAG‘ëÆ*"%abÀVñ)‡47Ÿ«îâ³xɾkµ Æÿ%£€é™¤YŽ…„Çýûqÿ~Ü¿÷ïÇýûqÿ~Ü¿ÿ#÷ïk{Ô%UªáBŽ §ÿ@×IpÔÚƒr”ýÎZ}¿cª–•U‚ŠOÇ+ øÉ˜ÂÄEuT¢4à×w:þð¢âÅ ;ÿ `™—­¸i “%Š cB„ê˜Æ“Ü÷¢}ØŽ>¶Mq›LUîcÖ¨êdP~†‹7 cÑ¶ç§ÆBŠã¯YË$qe ísScàÎR$ (˜‰ƒ%ÚÔKt7PýW‰ÒbJ/°{ÎÔ´×÷ °ÙBTz÷‡Xzkã¼áXX´Vžn¸€"éXj¤WŠG{åHTNºGOLy¸8ØxæCnß-E¼ø!ÉÖØcSÕ®ŒÀ‡Ï16G‹½îZÒ뎩T¥@ë ºAÃøe¡œ~…ÖÁœ=$ tB†óÕæ\~R)ÒeK²õîgäUƒÌ^©ßÉžq«¥âÉ1ph· ˆ)ïƒã¹xI»üe1’5ZCwè轿Y*õÚª¨×ñ#Zã!‘±Þ¯ ã•$ÿAy¿…A/Qºdýœ7È̇-»øýqè$ÞBÇ¡@|˜É—:¿iìåÀõÆAë(/¸†Jz²aQ(ï.d”¶Fø^r-¼¯zhÉøåPƒ’7Á+ÆýhÆå×Ä„c^%E hq“ÿ’+º@x ‚E·… 7Ž›kÚÒuÍWËì4ÚU] Ô‰œe(,ÆBÚ§*KC¹²SÍ*Súª ®«b"sQ‚D8‹5Æ=66º2‡ü¦xÀŒ¢¬©+QÓ²^Á4ý†z7#{8ä]¸$VJœ¬±\dFç{ŽŒަD®d(OîÇèäžSbŸ]dÚŸÚOµÕnmµÄ)ã hœ”’-¶;”.r¢ß ¯Ð –Dåju)P¥ñÛ9jœïcœÛGû­OêiëàíáÞ»ô§ J“Y‹ãá‚Üâªù»·ĈY8k,þ-V™+v»Œ*ÐíØ#;2\FÄé¬d­‚upê{•“R¶mØúnÇ…ã§aøø=§(À¸ªÈô‡Ìå9>½L”Ǻ„ƽvÇn‡zw‚Ü€(<Œà®èŒ;΃ÂHvW¯ æ(DÑ2Ì1OäÁ…>Ý}÷ß$xס ýEÍ7ÏZ8²'Å×c!ÓG:ò×.ãÊQÜô×1¬‡˜¿ ´i_Ûä›Ùv0@2I»ìëÝ÷ácT¹gágÊu dÎTœ"štÆ#À=NƒãTKÜðÉŠÊúÇ.F¿õ{¡øÉ%³èD<Å^®ý)#ºšÌÚ)sÉIÃ`y-IF2t‹,´þ/\”×þЩënÁ„ÃÿèÕ‡ Š$ß~'V!åB²%uT£6ÐÍÝ~Ñ¿Í GîÕjº‚ì•ÏöŽ<ƒS¼Ý¬¬¢z¥½¥ü}8¶Sb‰½0Îu…ü\€Áb²ÒȤ!\¹ÚUÛ³1}¬òãÕDÓT¢ ØäúíÃy—çÖ¨A¨íÙΈ ‘e®JX™rØ-]†Ç¼+50”¶ºÉ‰v·Äj Œ”At üS޳@ò7tGì×£†îöÝðŽ|53GüáGÿ—tù'¾—Ê µ¿p+¡Mgžª¨ ÖRÛmÔÖ¿«=[…faoÃ;%šÒÈ£8ªÇðJ:\2a„‰ã1™%*WÄ£=Qý@®ˆì(ÄjS4W ‹MñÈ+tûA³ÜT½!Ó¤ …ÞnPd£‰¥dô#U¦ÌyFò¦›²¦K¢M:…IWšüzi»þ4éäˆgr>ìÅ`”§q´W¡%¾» \ªï AÄ HhñâŠN C0ʬ“¸ÀbY'%ñqZ8W—2\ V¥AæGB€…—,ñ Ê(ܽ^ÃP.À„ÄZ4<œ…$™‡¨ë°:ÎÁÀ1Ðf¨æ‰âh¯uöú¤…Y‚dø²<Ù–‚4ô)àS‘ß—Œ¬¤b?Õ©òëª|]ÒY­;.Æi”¸ëº]3¨TµJbdU%uƒv_oDüÕk§?T¾¸EJ–S‚c^¬b)#WŽÜ4rÄÔ"Íz)ÑØÙ¤¤Ë¤šKf¡ž ëMJ[6úÓIfó¬x~l½Ë©®ë+¿”›OÊÍ ùB+KŒ–ïò«åü6p-E«–øÚºôO&¦° >úº¾V£ÕÓ×!iVs¾¿âÛõ ~«}÷´¶VÛhŠéíÀ³ÿR{*jµZÈYŸÊ1lÞ#Ô.|[ÛȦzφ¼øHA3¦™pÖBžà MJBÎ?ØOŒ!• ,9loõW¯v+ÑÎà ØË¡Sw2œ\Vd©?e†–ŠÄ ¬¥™²CE­V¢À¦ã!§&Âo¼ÙUØÀ^VŠLZâ){(í’ä,÷À»ói¼:5ÔˆvÒŠNrð9j%Yç'+k&‹Ü^åQR›.2RÊWœÚk1‚™m‰4ßx¬“[Ù¨m¬áM›Ý¦Jwnpšv{wœ… §¨dcPšj|¦z˜’‡õhŽNr¡Ê ϘFå¥a<Ï øU‹27åø*þþQsc*%Î$Ñis¤ä)ÀZ¬€‚2ùœó6ù±êSÕRf3¦â¢4SXÞDÏŽE‘íôU–q{ý•{t­k‡öoòâI¥'ÇÔÚÔ#ì^ÏYÿèðÅÙÎÙ?Z‡{bªÏ]ÿ§ý³óÃÓQØÿòG‹@8ÛÿéAŒœ.ò°Ù ìœ ø×RÆÃn[ÏéoųŒÉ†~[étÀ(;`OTŸn”ã:A¼¨ÅdŠT ¥23lO§G6‰sE†-#Š’<6mÁ–çô{YÂÃR¦ÖÔÕXÿ~à ¯Å § ºmÃFù×ÚOÿÖÆ[XßÓÁIÉGI܇Ó' ´¤›Q îº 5Ž>8²® 2IÂZE~iíñ]L¯NÏg.ó@ËSÆ47”Þ4£ ù‘[)—N*‚S-)ïÃO·¢Ù*nçÞ D¥à¤`ïèH‹ž‡ gs¡[UCïLÌhɨb¹*üTÀÔl%|´6RÛŽ²f³TªÿòöÅîÞ˳ówoÅ»:ªßáos…L.šåzs]ìí\ìÔ·ƒú/ôªÕò­–.OèST°þË!Bꇷ;‡?k¸s¨õy¬ =æÛÖ»'™ªLãEëík3éá5ª²ßîTÿiWÿ "/ U‚©ÆiZM˜·®ÏCÆsÓ¢÷M²>§}1*:*²4ñœmÑ{¶nÅk‘tù¦uÉtŸ¾]bºËF+›Ìž{){P•øwkQœîÿ-DŠê±çl™Èz ƒþW(†Ê×_ÊKË2‰@DpxÛ†/ÓÀ«®’$О ”âï'Á&CÐÏÒ¬õÞí™!þiƳÁg€MÂâ°üL6©Øý“hDÁŽ-yµæÍÏ* ¿Èù¡àü§gâYí©¡¥IÁưüø¥ÛþÛÎî;-]}¦Péôó4™ÑÒUhô•®c÷™ÕÞö{ {€ŒPÎͯƒ÷Áõ¶°eQ8ÔÒ„lPÿK,Ûø]Z0EöK3F—‹B>Ò’£ß³¡±úo‹Ÿ>}]XL‘âËR,Ž|„3#ðý¤Š<%iq·Äû|TÅâ’ЭÒýU}zM'MÒòlG¬”²8Súeß•‚/c¶&©Nöo±›Òì£>RgÕ‘ºÎÚzs}»>Q!’ÌÂSWK¬n‹ÏÛóÕÿ²s‚O%ž«AgäCz›ß¹´©Zæº2Åɤctu¤-Û$¯l$º@Ne¼è©’›é.7WL }¸'²“I†k9Ëvn£¿¥Ô)…õ|=ºŒ~%¯ÔÄ%ÕÒüËi鋬¤/¸–„¸²“Ke–u²DKÄÜ3.®f¹ŠñœPÉó' åØI¦ŸÐÓjí´ZxæÃ­v_Tõ½ªzõ}Ú0#M‘/Kdƒ6Qz°lõ»fz8•Ê„=%û6ôa£åœVmP‘¹'¸d:@~"Ã:²H܃¿8ØÍÚ·™Æ4sš$¢Ñ¿¶—Ù¨} §~i$oÝIî©, «Ãs‡ÊpK†6IóC‚1« âÏŽ®². }1^ì.õÀ(㸠åwÈýG(°‘ŽǪQøb ÖIv‡$²=$¹PEgˆ™šicnŽ€ ;A…Ñd( S憀Ç´žz\I³ß\ëÙy'ÌÌ©ÙN":GÑ4Coøþ ¾—ç^¢g†9[baG.P+2À^ûn½¶V{ªœïØ`wºðùîé¼R£®uëu‰ŽSR¾ÄŒÓÜ} m Û "Sº^»W×äÉf¿xCM#"Ø aàò}&û9vwAi7³Ü7ÃM•ì] ‹ >„G—Î-ôŒ}"©Rd$/Ä‹1ææ |†0r~»0ܨ“ê. }µîÂkrйqá8k^ aqÖ¤TùPük!™¥/lx’/?D3‹pº%ÅæR’¡”%çH–”!×a2¼Q(†ã‘S Û0&éé«ãÉŸbÇ1q/y3]èN»šMå°yÜ4÷M3ŒË£êÆU1‰ð“×÷´+õ™¾Ò ê{艴>›ážà÷xëà-¯¤ÖS6v8*Ot+Š2zÝËÙ04ˤ$ôyLBâG¯öþVjú/ž­oˆêô»}¼u~¶Ÿé™ÙbdÓ€‘ð¶Ø¹[bNM®Ìû,£b¡\È?:|Aû”ŠOY”“3f¬8ΨÛs9ôCõ¨6ÝF/©Ü@?ö("Û¿En¼|­í€É€‚ÜÕîž?J^³ºÁg8”¹.³½FÇï÷Æl‘I¶—&‹´Ï‘{ûvÓ4j‰9 eúŸ‘SfC¯ÙJ9R¬B2Ð]œJ« ¤qã ~º"kû¹”u}ŒpÁ›?Mú‡.A¿È)XÚäHx´ó‰!}µ¤ù“p>Ïo9^8ºÓÁt"ŽCfÐìÏÎï¸è¼A…E0Õ-éAƒ²ª0§,Ö°vu—\Ðqc`£Ÿö\ÁÀÀò-A1Ë o»7 ?»iCÁï+øä‹¦Ù­ê‹èW!ÊÑd‹}ãØïevË(žJß}ïHOHÖ’%K 4å èˆ ¸Ób`c’wr5¶aýlq¯‘c?JØTI¼wî(t%FU :DË>a]Á8 ¯ È\kø–›1kÀ#8}bia=Xâ3yüÝgüÏô¾¨Ž³9r°ßNW÷_o™úܨ¬ß›¤E`“ [^¨ôP {2äJ삆d0 i½f¤YçuO1>£S¥ÔÉb„G‡ƒd%1 Þ¨[¼'tó$eÇ ÎÒ¬žšKCÀ¦w‡%éO”´/OùԭׄcoÂ"ÖñRP‡Ä‘g2?¦vDu{Æøá­!b©°uw¤ˆ04:RÇS› Ñ@3”ãJ¹W=Æ;ª¼áÓ«U9`vŽçucTÈõL|™¯méwB>®Õ‰EªŒ°=IyÅq)w`ÿÝ}ò¤"~bCñ¬öL+žÑÇÃ**¹^8¡ 'jy#Š à@üžï1i;zIQá  ªf±/–C5R伖hÕJœ›DÀU˜w5©¬{5l€Rs(•žƒú’bÍdç4”€„"u.0ÀA¹…õ> 6Îà´‚+е‹”¦¡S:è@µÒâ &|-*#]Í]9žƒÁ‡Í¨Äf(`º@žQc®¦Ižò’¬—Õ;®©Œ‚q²O¯cߦ“/+×WH.-WHÙv`³âT$5+P$±I}$,^ØŽºã޹ö©A9ÑoJ 82¨\{`r@Qr¯u°DÅ¥ù8JlàxÈ.9¶¬g¡HŒ†´[K™ÝbEħLP„X”mâÒ®ÿ²&?«€¯hI¢¼ˆÕb½¹^W¯‡øá³„ü¹¤ó>™7.»côÏý1#Ql,÷‚ÒzdYLÁº¤°µœØy°-žoVÛ°®ùX$U_2Ê$mIêò fDU·0‰~šW†Fñ60Hø4@ÉøT,eMŒz8iç3Êj<#…ïý[£:|ÛÂ_24+3ôÉk¬UˆØþTж¬´%媭ooò±U˜hEO’õ<ב7ýR1v/¥.´/5Ö<Üj3Ø ZeqÝ·…wÛ9ÅIß»µ (¼ä>˜Š‚­fRÍ+J¦Xh¦Ë/SQ~&®c3ÌÆÞY\ßúñ|dW–in΄ÕÄ©0{m•æš™@üÅæÆ*eYdâXÕŸˆWKKT÷Ú¶–27¬¥Ç­êq«zܪþ·ª¥{oR¬-™EpiɽÂÕ@fÀ¦S"»àÖŽM(¹ç1y]Nš!z¤y'åj YÃŽ¹6¢héò—ð[ªâçpšŒ]ç»(FGÝeiŠ`XDÈ\0Ã1i¤€£ùIå:mê¶bZhSÓÜâ\V¥cÊg81^rÓÄøÆ£æ·âñß÷Ï&”()b»#»×£± `os‡}­· XsTÑés5%z ̨ò·>æòID‹ ÿà2êˤ”س-Ã$À ¾¡®5CWÄ»f³ü w¡Ù\ÿæÊº,%o¨8Âuâ À ™Ò#p.f/EU´CzCŠ—%]ò­ËˆÙk[ k=ýÔ*Q’˜ †=Ì”z¢é™,›êk!Q*æ ›ùQÊŒ.S(JÚÑe{€¥Å{Fl¤t¿ ê6´Ó'é~xEB˜ŽX® `œAíê`Öüß Ýçg‡¯Ìíço+ÉCÅòŸ”GßÊÄše@·^7×£–<äWÉ9Ä,ƒˆ¢,©WO7,<ÃlgzM–3/g·;N¡Uµjžÿ…;–ÚK(Z‚vûу¡xXšùº úãŸÄLŒ#V$c·™©±iMB‰û…þ1 ýcúÉQ胮ûvóYd&{ã¡Ã,@ý~9Ø&gacÛ‘¼å†d7C±k0SB²gb¯ú|qÂîq˜™Í0 HϦ(ͯ?ÿg)iƒñ·ÛRâa,$m^Pb¾™’(¥»æÌR 7Ñ7 á œfxÍ«Œ15Íʯk§Bö.ét}êªåwDT TÔ{8Ú˜ ­ó¾–é>4ƒ .É/#¥›K˜¯Jõðø,Ã-«ˆŽ—­¼(~f¿˜±~Ó}l”þëâ~Säo+©V„'¹´­íŒ+Yx4ª÷·òCÆ &"Š‹„íõ/õ*©ªŒ‘-Æå_ÓáE~{fsfqC,w43™õ· ÈÀÑ.J†ÓÎÓ H6c’aR¶Ð¹Wå ŽÎ‰ZTyÙ´¥ªN½€îᲑÈ"7ÇnE”¥p4Ƴӌ‘e—Ò [O^cüécœÅ– Ÿ|zö)ýˆÒ¶.ýY!*”ìAÚ°'jƲ>àßó>Ž÷È*”Œ×mX+¢zÒ¦´’£ë\ü.œ^6–û]¾ÐÀRdxÇEú¡¤d¹ ëo§¯/^½¾ø[œX–A^²àÅééQ+«4oa1¸¦÷=ù‰;ŸVkûoöËfd¹˜©ÑºÑp0ÂIOv¶˜~–Q1Ö”fÌA©säŸëwNöÏÒ †[5µF;zðÎÊ`œq0¢ªÊ2d5$Qå§hß6uœ­¬âd8íܺ¡XãñüNÆ[)‘³rYì° …²‡LþñP£V{fKXŸNÖÚù€yZÉæ²…w&CÈÕ¢¹’¤ˆz³@(D ¨…­Ü!” R]’cíÉŠ-ÀLe+ñ¶0é„ÄáS?éð¤ FÇö$MÅ~f—@ƒj#Ñtz*ÓuÌ™”ØgÔö§¥6ÚF Ÿ…”z„mT–X\.Íì;}à3Í"¿Wœ¦©Çf*OÍ"Eç¨7•(Ú,b@4º?z\_[ 8ð#;0 [ÀÓq?Öçiý¬¶áMß™©¿ fjðPÛXâ0é(¹7Ó¢{3!»7•0¬B/¨¨é_/ÞáQ4¬ .R˜¡ì¸‡œ‡Ÿà‰#‹xJ"ÞEd@¥YýÕøvR ”—¢z ´8k`”…2M‰ŽÛéÈq^œïa(aöÅP Ƨ`åèA'OFáZÍWJôÝ'O(slË€A‹B9ŒÑ#<ÊG¬\9bRß–Û*áúnCÕŒ„§/<ÉIN›]°§*ÆqÁÛÄ+)ÔVl•¸•„Ñ\8 û*¶ÈX#›³3”Y½Õƒá·ƒ.Œ~Ò´ÍÍF([‡ºÒ,Óx–7 ‡¿Y¯=܃ƞ:ˆqo@RÒó8Ò  ýÙAgK:ö'Põ°˜šc¬ieïütþ”hçŠ\G(6¨—Õìu”*Z"¹îȾÂ,'w³ä1‹âÃçc$ΔþZ¹Žo¿KÅÉòêšz"Y\^›þ“6]ó¨M‰‡rŸ4F¿Qg­Ûìú–tÐuÛt|Àsñ„¦J“ÂN..¶ÀÁÝgdæòø2ãÒ—…“Mªä,åZÊjk)¦/-äjÞ @*9¸ô“×û'ÊíC{E7ÅÌC2.“<ô±ÕTÆ1c&si¬¯e­ å› Ë£’i}5S°0@õu"0Wþ ™‹…dR°$ÓHÉ¡Ø9Ø·™*Æ ó•…’¹ˆni½-e‘ÚÒD_३S¿´‘.ÍGŸKH30‰o}!âKßù/]‡ö*& Ɉng’$ç <éOÉyI¦43y =;¢’ƒ8Î߇{¶ß5˜£{‘yiñ)i¹9`sÇӔ쉋b}½¶å RB(;†(¬AÇîœA¬üøê»ÍgO«këb§†U×kkÊÉ»"Œ×/ðõ›ÚÓgëyVÅßÏk/_QIBÀGm‡þ#Akàl?Â_ôùôüª´ÿ¼Å>æäˆÛ£»´¨g*íöŸL“þÉåkµÛúo‹ÏÃi g®Õ^Ìq –õë[*X†Š•QȠѦ½Ä@ 0÷¯T!÷i!óÂ+Ð #qŠžâ|°ûŸ‘Âxã{Ó ½ÝN†çæµDL¯ŒæÀ2@ÀÈc#XŠeƶÛ2ÔoOp´ñŽÃ«€yËâÄzûŽâ*Èh‚doqÃæàA!Æ[~a‡ã%ËbgH©³á<ÊfßtTæs'F®õý+í©|9´ þ:Œºù`ãR8È]µí㬠Ѡ7RÄ£#E·d¢v±‚y™ÌE¶Eý±úËÆÚ4Ñ¿Qˆ.ºn¯ƒiVÛHõ7¯´²Í0ÃQÛ˜y÷=­×áßÒøMõgÕ$Ô¢IÊäC0ójæÀ([¢˜Ý—ørÖjò¬b´‚ ÙjõTy³sÞûî>õ_Rüc׌ä6÷Ljƒ7ÖOÑæ—÷dÒ99&LdŠœSÐ,Ípâà n~És޳фy“¨³çŽÜ[ z(潇:@hh=çÐ:˜ãvå ÜßyÎMàÏ¿´ùA~ÿz•ÍœãÅ }ŠŠù«­,õ]ÿ$i¶]àMW©“ ˆê¶C…ÔûÝZà§§™ é“âäc ?árÆqi¸è>ô’žK^˜p^^™JÚp|6꩘á§ßß(?ЇÇ֜Ռ`ös~Y¢,dñ“¾Pš1ÓLÊ9“°ÂRzìÀI…™É7Ê= |‡'‡‡'ç;'»ûâbÿìX}™”õz÷[aIÂWŽè¨Ø´T™¦515kÂÎÅŽ8~}tqøêh_œœžœÿ¸s¶¿73éœ4½¸3¸E½©¦©²­[­=ôñÜð ¬zw†–‘Bÿ‰fâÕvF!}XÜ"bz¿] =ãggî1 —&¦z$ˆDñáÖÙ­òìZ°~‹¿‚¢ÝéÖM{´Eü>Ëø†&•ë]kyLªÍD¹¦Eîv5ÊíÑj®×¯o¿qîÈtRåXíÿt’5íþâ°œÐ纩ٳ´3£›@’Õ÷žÎ¦6ÍÓ‡RÆØ“‘¥I¡Ô\-Mþ³gÿ“Õ®1y>Wˆú2XúZt_ËIÙ öM”Ááï³Õ2œjí€@”2Ëîr ¼±¨€# #®â¾>æT›Qÿ¿â›Š'ü+Yd„ݯ[ý†·*.ÞØ]fì³—ä(EÉzÂú&ßͦg¥¯‹¬fÑes­ Ÿ·ô†ŠêRE«zMÀ,£hÊ |"ÒaÒ]ƪ&¬R”šš™'AŠa‹| ‘£z[¢ÄZ/| ÜY‡tno#»"ØŽI›çý»‰+A-ƒøX˜©æsÇ€“Þki +@`õßx·«õ1“"çÐÅ…\šÙÀÓ½åïÅï ›še.¾þø(3n‘à¯è4GÕÁèê,¼Ö›ëÛõØbø¡"Yô·Äê¶ø¼Ÿ½¦ ü8¾FE‚8Söœqä§(üÒª¥”¹xV[³Øà@Îf)C¥AJ½o¨4}yú ?|ò„˜8ÔÍ ;1M1[ØBÊT(Ý û³êã¾üOìÜøŸ¸P&¢,¤PÏÑg¦hÖ¬½áªÏÞQì óAmÕÁ÷3dø§ÌWG0{Ò¶1æîE#Ç¡õ«4R`@Ž›F¢%àH–jB p× :0$ Œ©ƒÎej ”6 Nïã¾Ê¾…¶"”†•'+sl'pÑéúœ‡'6jÏÅÊÀ¾k;ðñYmý‡rú"ÚÜc¦ƒ•L“¡Ó]'LŃ•%¤½’,ehosÁCͰ¼EÆÁåe·Ÿáª.‘ø>Šþë£âé¸îÐ~×ÉA^#eÁ”©lxœvJÖ«ˆ¶Ó±ežÍðz„Ζ &bÚNé X£ Š‚­€8~„ë¹úµkÏp–…Ð(;ÄKµ{ÍÏŠ¦Ü‘ÙAà€05œ*mœÕ2 Ï¢~# )»¿„¯`p|ØÌšÈ³Lûtà¹å¼ÝxÑ7cLb—4ybJ@Œ‚ñÃ?E/®3p<¶f_^Ð:¦Uï"Y!Á`€WG;ÇG‡/d ‰ƒèíË‘Çä³]ËÎc9¸Á¤@Óó­(_#”Rަùfiàƒ¨ Üé‹£ÚóÅò±l ãa ½À¾ Èņ#zßÑÒÈ„Vù¬k'›¯ŒÆž¦­ÒÑ^ëìõI -5K‹aíé÷&ÏéFþ-[”¨=£Ã«Ç¯Ò÷«]¾_õœÎ„ýgsÂU¬9ÆDuÌt?· È¹¢ãŽo(æ#~yv:t¼×'‡oôƒ×ž{û3lÅAŸúwµ·ëkïV9~Öí >¦‚ÿimãÈùPhcóݤÃí—d´¥IgO={Óf7ŸHïgÅ‹»MåÁÎŒIÐ’ð’ažovŠ!ØË/2 —_r,™ÄúÌ$7ùùÙ‡çF¤Ò?t¶0EÀîÎÉÉé™/K}*jo1p¯®CxËŒ$PCÒ90ljàð¦dv̵ÐoF—â4SV, -‡EKåHŸX©Ðí\SLÓ€73ŽMìù:8µ¥¡ý …n•įÇitoœÒÈ1¢³r‘|Ù‹. ·¯®Uód‡ /øHbÆáÒIîHÇ`x6†ê²?ÜU¯ NÔ%x.q[›kÅg*]¹çýyÞ0-/Qeæ;€™ÒêN6çHì5|ë…oCãäõIG÷5ÃÈGЉQÎd}’„c\Î)2yü0(~HAc³¶aÈ!(.* US–%/‡—0…™Ö4'èÞµ€A¼BBÚþÝ|Cæî¦{˜ñöÏFÏT‘Уìaº“?Ë JŠüÜSùuoµ‡ m¸áüåÉÖm1‹mZˆ÷ÛO·˜n›ÒDÉp“°¹®4v—ù{n*™xжŠÁ*Ří€9ý<ù&LE«¥ßJÆî-C"â. ÇßãÃÇÚ‰)±LƒùãvÌjˆŽ£w9ó´ÊM°Ø]ÓÓF+¹ _#Äd 7|©SòY¡!E†ÎÙô1ØÎµM³Ú:ºx@ÝîÊøÚîÃi·{'†¨dðU´ Ã6B@—‚ÍRyhSƒÀüô²èâJñ™MÐ e!šÁ/i:©‡«)hyÏëŠÈ-†ûµ A"öè. îPøöŒ¢a!q}Ãô*+&»×XL Î ‘ýRLl÷ì~,åûÄ^dvœt ÍÂÒCtÑŠ4$hY˜¾Üs Zr?(^ì¿<<ÏÈ9˜—8 OõOMÏÚþ,>r¥žRZ ”vü1Y"¬mË^‡¨T:9Øôñ{?ñSµZ& Ÿ«H/1s[gê¯5K3 6ðù*jýÉ¥9úÌ )£"X?ê$ôÒ¬o6:n‡E9?R £v«U£XÁü‹¿?tóØ [à÷‘óë[~þ:+j¼Â¯cbªgPús‰9ÒÎÏW)&ðØ/óô1´3$nTQ6ËÝ­z×ê´Quœ- YŠ-Am>)f¾¥Y0C…ŸêRÏeŒ[ ¡ç\` ƒç'Gç¯.uX”*éKµREݳcw=àu®®¡AÛ("ß’ÚZƒøàôý!%<{‡²º"r`¿ô)½ûÓÚZ­0ÁÔh/²ðÙɘŸk¦ÑGV.––ás«õòäõ.Æ ó|E?€ýzeùàøðäô Ë5Äw)“á—C óÁ2àÃí•Pµ˜‡K/RQI¶ý黪ôÕfì~ íDq1ò¤½'àZª¯§¸†cŸlX‹OÂxöe¶¥d)D¦k2$˜‘X.ƒ;<Àé‡eX?_GÔF”DæZÛèOC'*G¢Û4$Ý?‚ª|#×­egÐHÂÀ;7X·ÀB1`^•°´ÕÐU«ŽÂöÙ^ÈHŽ4-JŸB£Œ½5±ÓüŠ2EB„?tGN÷Û8C´db—«ܺ²Ú…jf¤bìöá¨âdäÓïWðd[­"v«°¥sW#ø0Ú$Ð %>뛩ý|òÓû¡q ËÜQ÷¦)µa8µŸˆô=Mý0D逨–¬0”2ÖL70Âp_ã­5B”ꛌ‚)aDúc5p=SC| V`Së÷å¾h»áÛªZyºx{¾YæfHKEpðz¨²>¸ÝÌfŒÕ”çŸ6$ÊÑI£ëÀfOÌ^«>J7Žý¾$Þ;w°’»îŒA2ĨÊAëètgïôäèL ôUØ{€lmŒ µ ¾íÐ$;¸ºTÖ=¤.E%;Ä'­Ìõç„2çJ¤¯£ºÎWÌ8ý© ¬Rˆ’?/î@¹ÑÒ¸¸AP¢ú}Œ¼ ÆNDf@ß-¦ïJ?C¿”·¾æ¦À²<æ•ã`·É¢_”à›nœT‡E&%–)çË _dŸ ÖqM¼ùmø¤ j.ÝZ´§+„ÚWŽÔ€_¾žGmâ&è˾7ŽòúÀØÑ ¡Œüd5Û˜¿Sî]‰£K 2öd( ºïÚõq/óÙ°N“€Âê o=¨IÃeƒ‘®Ge" €ñWÄÇ÷xdS€ðˆæØ]\Ñ{›Ld¹þZÇ/>RÛlÛÜ 1çµ›Ýç!3ȨIéS‹8 žŸœì/2Þ Ó€ˆ·WýµŸÊÑ üìà>8#`d€0 Ùh³Äµ”ăV T˜›È^˜Mo¤7»°¹eMð<øÄð±S»`Í{"2ðˆ{UeñØÃ«^½uecÐRDÜ­(Øê‘Ù?u¤æ—­éd*ÐTɼ*‡©-”’ÖiyË£(ðÎQD¼“41Ï&ºØR …¢ E™A– ¨º?–*I‚ü‚hƒññÞï(1µ$ŠëÛ$sÒ© pq—•Ó™© Õ²ÌlK9•Ô—†UÄ‹žÿFè>ŽØ·e 58fÝßtDuÙsTb’] !¯ßâ›òZ‘“[”Š7g(ù›Ž&W ©ìtô˜žªüPúÛì-” |%ÔeâÀã{sn)³wK>¢@[µ`Ú<9+»;”ç á ¨€T­Œì%gA›s æXpÌÚcë 8þ”åf¬¢Ê—àRÈ}§-F–ð½n–¤FGƒ¹V)Rv·¯×hæRã•Æ¥DDîü`á…“(Ÿmh®‘Iývœg¬tºÑÒä‹™£“Ö9euS#É&ñÀ/OZª™h›¸’ºŠÕéEn¬êÄŠŸºÈm¹ÆX»ÀJ9 ”l mdÖS€EueûV#1âü°£,%ÎÉxõÿÆ vo¬­ýEì`õÓs@Êë¸t ÒJKy7EH`+( ±ŸR³FR}…-VAÐÅì¾}øx EáV”=†,ÿP»W+üa)ayðüÛ÷å©}¨¹·&A˜|dYìòȩ́¦KßóÉœ@Xõà.À[ •fÓ¸w)ñ™¯MqtúŠÄR_5Z6-ˆ•Ýc*¿=¯f#·ý7¿ÔVñ*ì—ú»Õf¹-~Ó\ÿ†2Þo“­îb={8P*¸†ˆëW—–/;'dÖ´¶ÅÜupí:·p_ç%WJÝõ#ñ·Iù©(>ûÓn¨2Öœ©*§fƒ®ûvóÙ—¸˜ˆÝAükcþѼP,!’0E9þݪm´$ïw9e”chÚ…Ä„ûTªš¸Q}³¾}A}ÚÈmóƒ¬K×|æ-dV±ÚËñ$4H65¢°û¨Q&]©Î`¬­º|öœ¯¨ï¨Ë´¥úÇ7J•ÙAU〕’©YDõFÕK•t/¬ e‹¼¸$Õvî®Ð2¸ƒ¾nÞ<Ý0®Ý“Ô Å»þMPÈ œ›&׌›5½)‘H*<:Šh#>èÂtnLá*ûÝ;:"‹7X÷Z\a*+×kµ:Ъí’"V![î¾QpþÆ¥îf³ˆ.U ˜nŸ„ßËâùûÐ8†5ÕqÚKcø±YÔ ð«»Íw0M)pÓ ¢%“¹.á—l˜ÛÒ•½¾@k)Ì…ûžÒX Õ3UTËŠi!Q–Ô¢rºø]a?¹Í+`Ø%a÷‹R ÄÏQ¦;ó†ƒ/‰ädÎ+”l *æß,þ°­¯˜J…<Éôûy“‚³0yhJ KÔ—~_‡Â}QMDò&5ûH”(—_ä{´Kˆé&G” DI†Ãé‹KF´Ëæðêjm [ÆôwÐbóÊË~wU/]ÊR’‡–¸Pìmí]½Š¦ÑÞÛ"¼v\Ì{e‡c]+.à&-~4VŽ]ïåÏRLE!áA"hÒAî>Žu’ØcÔ5üjL×ðfêle±²i“6¼¹çœe$’jÕŸ]F›ïZ¸BËÞJ§¯Yò‰âÑñùO»Š5›øf£¤/6S7´±âør:iVVžFÄ‘Y'ù‘¸½ Q<<8—áS£´­xÙÂT[—bäÉG¢È.X¥h€Ó/–Ålâ{§ç:ÓÞ‰Ù¬¯f<¾¼BåÌ·µ§"ïú|O¨mitgy'êH P¶þ4 ä]:¹»¾+,ìö7ªs…¬áñ7šo~ \iv½èB×­kDxNa""€÷aD+ºÜâúÇ9³6m¢´]^^ Ë\NŸšðÃ~ ü]4ádWÿ½Sýç»f³¼õIÔ›ì Áï}§t_?i®õC A *ìg€©~`>iÛ÷±’±Lï|KŽ· X§zÅó¥)ûŸÊ¨—S÷=Ñ÷ý÷Œâ½#ÓST¶z§þêìôåÙÎoë[ümÚ'£ rÞãªüCaⳚ6樣™4G »÷Åú6‰ W“|/ƒHq9•A«ÝXg B¶ª)m¿íTÿ½ 䆾<¹™f—Å!Y¿ Ð~¨nEmñ3‹ß4ë@8’Úô•:Ó"18±éÛOeû@mL™m;¤¼áDÙ5ø Û6ŒLé`"I¹\ðÂNB?pß«‰§vUÖ+iÁLên oÍ-µJ¬r^ƒÇãÅýÿ"ûé¾¥ä#%É( (‰›*|GS¥–Å%¢Hù¨ÅË™$:ÑJ¯®Æ/"ØŽèûˆÚu"mÖÝËÔÙ,’Œ5û™.£…« ÛªÐí¹Áïk(ÄÊ¢5ú½zË“ [\Ýoÿ‹ECnÑÏ—ér—¦Iy¦2DóíÆSŠ6AÃÁ¾ÉÑ ôiÍðlš„Z-êjZÿh–Kt¢Š‰Ë¬ÔbÒéu Ÿ&—Œ!â¨a?䘳Þfö2a6 <±¦¬Œ ’£ØPFô³ìòÔ¤¬ø”LðqÉ@òÙìsDRmm K²1õ°ÝÔ1¹£’©g›µõÚz¢<™ÞoI Ӻͦe°p³ö\`w” 4ÿy0ô7y×¶û~ü‡l¹Ò‰4”ma@_‡tÿw™¤¤1…8&Jmßë×þÀ©óËô”O\Æއ¥„ƒ\J ¹Žo¿Ãu€Ö×ô§u¹ñ½$#veGL¤À°kXÃǽϔޤ‹ws}¤‰1FÙ"Kb¾Ó¾Â;ºƒ>¨Š´Æè£ÏNKYè'¦YŠ!çiKâ «$_rÖ—ÕÓ™çÔµJþp2ÄÏw¼e}¶s•“Ȳ3.²/*ChQ÷ã«×oZè~×:>ÝÛûÐO¸fV·H‰).ýf?µP3ÖPl!¡r™±?Ï7³úó|sÞH—D©!–|=Ú«yÛ¿'Áög X Æýu8¥ ^ÎAç?B©ÿU’ž.†öÆZKF§˜­ÂªÈ=#¦"¾dSÄÓ>Ç|bìzñ„“Œœ_ÇîHƺd§Œ ÿ˜9+g~|U}ýEŽ@¬²3Òªúþ œöÆLÈ)WôP ÉdzgÏ*‚õüi­#ßìC4q•©=ÛEÿ«1f ¿f—…xa‡þ=Iúwè¦À©×-l³åî LÀ¹·oŸþQžÚÿRYRYwÈXOk·Ò‚h]¬¼Ú¯ð}ÎþÑAy&3©iâÜD¹Ë…P¬tüð?x …þP*q2OîF‘ ÿÀ/Œ{•Tv^G1!9¤­Ž\½ô@d#þÅÁá1Ö_lÑÍH^óÏõïBéyÄš1zæãN]Ç®4˜²ècj `x˜ŠÅ‹ŒÐjƒMN…ö¿¾§œQ¡dpã†k¿ÅÑSFõ鯧U ~ ëÓju€§áv0p‡øÔø*,CG‘ì>ØWn§ñt£ÚvCEvU¡{qðN¾ˆ=H7Ï¢FNè@¶_t#Ï7l¸ª‰ç›mcü- *DÀ዆ý|ÓCyò€= ù_`tþ¤Ç,j•âG ôóÜ'Ã|¤(aŠø—˜¤ªOµÂœÓšÆÙ0Ûƒ±aj_R4ƒ8"â÷»eÕäÞñ{½ZøË*½ÃÕÁ_±Lô fÝjްmYÉëŽ|·›Þ1JÞñ{Råb gÕÃÈ­;fxÿe¶Ây¶²¤©ï=w'i+·Ìá7(Ø6é´A0>%e3Ôgw:Î]‡©â9†È9Ä8O›ðY84\÷ €TQÆÒ&ë é5lDCÈ¡«Œ-\M!gÉj¢v£³R7ž…Õ'‘C‡G^ä©é‡WƒX/¦„ïgb'Pc¹Â˜ïu 9é¾_Å;…*l¡øÅ:žÊÆ*ŸÁïGÙíþîUo.#÷É,7¢rhd¢¼Þï’Ô?DÆÏtŽ¡®ö.0IˆjÄYŸ±pëSÁ*3Ù{ɸ  3zÃ(jHT´a°%_Ô) ÝM¿Ñ´²bŒ7Ahl–T`ÆãVA>й+§iYR|á@ДœæZTÅ_ÿÚÚÙÝ?=ß§"Ã×W1Ú¦Q¼{sÎÂdÁ¾;rÂñÈÃ@…Ÿ ¬ž×ê´B sÒ=Z2š±e ʉ•âé‹ÿÛ{}ü m.T_¸+ô¦³îƒ5;r@À3_[•Ø´RvFúÔ!—ë¹øÿh€Îxd’±ˆÙQáGÝKw6eËi’0 D žD}P$î)ˤ8u\ÿi»Ì²8ìÒùŸCÙ’ŒâF(CÑJh³X…b«zñ8ØjYv`€v0ci¢"®ýÊE]C¥XˆãÂëd~ ¨|'@MÝqŒ‰e ¥ãŒÐ½Eë«ë^¡ëÊÛí³ ÌÃAÕJw<Õ7¢úAÑî/õ†hQÙ ÅÓõGvtµ-ǨäÀ盕‚ÌuåÉLU2f”¦M¡Xªxgƒa½(ºâÕÆCèÕõ(í;Lš8"ýuЮL¬à…lÖýq£¨@Ðl*ƒd»+éÔ ;õ¡díÓ~2²—µþ‹,êâ£Ì²p²ûò®`Ûħ¾ Ì5oUD³¸Q.o‹à=œ-è÷@``Ï?ᣲ´!n×t Ì_Mö0n{´\[­×·ë¿¼]ïV¯o:ö?Õ»ÛAýíVeéìÁçÆÛ_ïV‹P”?Ca!_YuøSÿ¥Xï–t8¥¦Wðßå4Ýc"BfÑ@˜%“óHovÊ£†SHG¢&§ÒžàŒuÝ€t‚)]™ïé %w;~/^ä÷êtÓõU!¾:y"ôv.E;L®=òßc ¬×Á¤:çEÀ„ÌÆžÜŸ*‹TmÿeD) š-HI C“s;^Z20 ÏáwÕªDÌÍEvÈŒ0ìÕÈø”bŽâœñhdht,«3>1òÉò ñ_˃£Z4J,õœï¦IÆÌ.ï)(jÏÑâG)¿}Æ£­’à>›ââÔ²Rh4ÊoÓ‚ãlð¾¬/9'Nøâ|Lû½Vr*Òþœ·›ÀgÈî¬Õ‚ÓE«•GP½Ê´uþ¢v&séK€–ƒÅ»ÿrDÔúžî?æŠaú Ë¿ûžä§¨c<ç&ðƒç_YÜùOŽ÷Æ"cDîõ2l%ááÿ˜Õãñ¿~°gì@¨ç¶” aŽÜ«|8ÃyÞ´h)ðߺœ‘?^šféyÕœ&ÃtŽÖë䤋òчY~°¡â9d9>°w:¥9¯oE" Úz ›Kïðô?þæxN¡fòµŸ,EEŽÿÁ°? àyÞŠuh“AÜcqãìº2PÞ­œºïx¼äøbÚ”#À2ì ]Òô)0Ž4hŠ[2E~f̘žÜj+&šT”Þ6ó¥º?FLBwÂ΂¦¢9iRcä‡NI•IÚ$á1C¨$dÆrnu K¾‚%`Òp"sexny†™Ó=tdIÕþÙë“Ȱ1Šþë¢gWPžÑÝgàÃ÷›Z>Û›h¦ån¥ Nî¥ ? M‡«Ç¯ˆmT×ÃämšÆŒQw-¡°Êø)‡9=rŸ£^æÇü™ f–¦ÓL.§ñ¬ï4PÔe¼Ñ¥Ðèhº2¾BJ¯“QK7(s tFî0Ää:}Ì|^àËxä´Èõ5 :„gô¦@Ù‹)¬•ʤG­óœÇ½»cï Ùv‚}/u“d¹!(ª1u¸ J ”ß:ZT¥Û²°Sœ„Š,ì@ÇlÍêÙ»?ÆÐñ´r”&™#Wq0ÆMÈÂÿbfæÒ¹v:dG€1œeÄX «bLËâfàØ8çA»ÀE  ]h&¥wØp»,Äçïa,÷‚ÖŽbQ“™//Ї>¥AWëN™“ Ò_÷ßó½ªs d†+Ä0Ù5í|<αærÈ] QF Üðè.AÙ K14TÍÉl1ÖZa{ ‚ÂyÎÑ΋òC™éo1@‡-vb–)ëŒUr •ÌFzS¶£EòvãÎ «¡_m;Ն߷¼w hübçåO;g+‰1”#dd£l²AÐ:ŠçʾR»ÀÙÅÑ^ëåÑ鋣²ÀË}ìtj.-ÅŠ‚–×X{ïȨ›];VDÕÎ.ºFE¨Ëªç°‰ýŒ‘©ïô}®YñhçŸÿhžµNNÆ[æÆÆ¨‚Ð (â aʆä³]…ŽŽAñH\Œt=pİo‡˜î †{$àÆÃá%‰N8Á7éÑå%îT¹hô{ˆ @bå" ±¾ÈÞM†”,iÂ2:ƒ•-Y2-¿ÞšQ…';õELS®àjmXÕá]ãÚívºQD •Š‹®‚¯1’„ã ²fÝæKÐxôþIžänÐöûŒOÃ".5L¤¦—'¯w[-Ü,VVVô×FC<-ÓCùèøðÆÛßã‹2ºkE…¿ÇG$Põ<„z@€k‡˜äx:­ÖÊJ4¾KÜXå2ÈW ±Ê•ȵ¹AlUKj(¥ Af«Èå€-ª#ÒZÅ\|Ÿ’³DžŽˆTŒ±´m¹ß¯ TÞ|?FÙÝVº}À#¿¬XÔMè½2†Ô\u;+{ÚÇÂ’qE0ÄV2 -âÈÛ…ˆÉP`8Æ 4]ØŽG0Ù+ˆÍ¥Ï²PV·ßéûPŒ‡´o>›âIx®ÔºÔz%S§®„ÿhïç}w~ÚŠ›VÎfÜ$ù岦eatÜo…X! ê²¢Çð]í9?å” ¿Yüq¦+[²Ú?£Ç2öMä¼ð.—˜cÙ Ao¥VW…·ÉYq[”±³¸º]1Ç …½Û¢~YWß&¨¦œ} ¥7¢ aÌZE’ú'ŒÒ›uÿ“H¥C4¶UÐÉó@è`[ ít']#!â³Ê*‹Ùó.R¤Î™%Ø$Åtc6‹ÇVçxS¥ÙÆ¢©bïßGnePü‹ïtï)ÉÎoÙVŽôq•%Ë£¤û(é>Jº’û(é>JºÿÉ’®ÚÑçx'Õœ(÷ªŠ#þFо¼,Ûš. I’“éèo¤\Žéš§æeÝmtgÒœ§•ÛÔ&˜£Ož_Î2\Ψ¢’æ›9ÏÔ´D´¨ Ìߟ„eµÑ-mímü¨`8‚;úÛâg‚1¤èµ:Šì­ÊÖp†ÓÁÉó@äxs~qvøŠ.ø£¨þÄqyTŒ3 ã£x++¤–V4‘Acرø*=ªvöøÊŠˆUέ8öXL°æ¹ŠUkñÎ ’«N>"ÌHiŠRk‹*Ú‚;£eUÌâĶ¡rYÚÐS°Îï$®|¿ ¤…¡Œ³ícFçsOe—þ­:’f£õ|îëŒ8Iˆsƒ÷ü$t~b2´dNš‡o$wEãqÆÁ©o0ɤòJBè@æÀé„cšâ¶#Ðå6\È€ ØM“}`ÒIÀ&,ôYªÇVùX,&ŠS;TV¥­Yœý¡W'Së&a^§GùØM—!°áÔ;‡o*éÚàp+÷•è!Z‚Óö‘+üÐî8á##Ùu©ˆÃ±¿:Ü­eó Û½}*×CLÑ÷m2»nH0 s¶ƒñúâ,n](è̘ñõ·¦¬2«‘ 3ÇI+êPÑjæ!¼ÝT‰ä¢.aUéH(s«Æ{ÆÈˆ³ÂÁ8`‹ýþ+Eü oÉľÊRK­€¯ ”©ÜaÈ÷íí¥¥¥e5hwÑ Ñ…ú] |¡çÈoϨ|mVV§V•xÒq;$7Li5Îõœ­¡üGJêF:(“Wʇó¯ò%–xêíC®ïÄ‚™k}'ê&Ö÷²8¶ßÃÊcð1—ªÆFBNšæL xtÇn˜“–7ŒM [‚,ŽõlÑ?õ–±ÎGV\6:ø¡3²i_h³=g6¾ÛŘŠÅ]©áÖÆ#)E(tª’Õ×ó³¬Ò ´þ<“l>4d­U¿òÆ iêZ(ìî’È·˜ÝB¤Ðˆ¸×î›7ÄçVâ^Èò1{Å ½»zòDïÄ%>¨~0$W’n/EYùFõ4PTú(~¤p?Øófâ¼yÃ3ðæÍÜs€Us&! í^Óp{Ÿˆ…C ÷nz»€ÂáÈŽ|ô¤õGÓà äÕÌ>­ü›gFí†$]ãðûÅî4”cØSNü:ö¡UíÞ%gœap çvÛºT' &S–q%ÅŠê¾%,Žœ9òÚUÖ ËrÀ-ÿ}ƒúZ@8˜õîÆyd„…PK%äQ….:~`u¶ãí‹r¤Ã”ªüW%‚U׈xÊ&FõeÄ€ð§ë„Ó)éN˜Ãá˜Ä_ûîÀ ƒÚõ÷8ú¿ÚŒð›‹Ö›ç{¨au¥±­pj4‚`T%Wø€“¾ :fäÀÄÚœ¶EçÓ¨)¹ )ãÄysQ†Ý¦lºZÃ^(kŒ¼ º%8ðÚ#èçäÀû†a5UæëüÎ í[AêD ; {Ýrt0—JñÃÉ1ÀÊUÛ¸2–àx©/†4fô~¥1¬”ÏKKD8fçÓ­@:hÓ ãÌ0i‚¼ l&[*k°‡ÁR\tœŽC RÞØ1­X³ XÝ´y*OÝß+LA9°=‡°6N`Ùл» Ê€a:˜–9¨L±ÔuBŽ0Ø ˜ÆƒM‰Fs§etÑ=NMlã²/µëecTÏÀ+œ_`/>æ¡A¥B­g […öȱß/2]ŒøÝ’¬Ëï‰K‚UªÆazuvºÛ:<Ø?:߇%Óé;¶ÇKP‚ye0×Ð3[%šv'˜2cÓÈcÃ0ð¤‡#¡ŒJ’âÝ ÉãIðB=L•‹agXHW+7˜¤x=¦=é‘}?²ïGöýȾÿWØwäú43G%ßBÆ×¼$¨7ÝÒVÚ­„ äÞØfàDòíoña%O xwËü¹iÉ5dë†wL¬…sǰÌFk}ÿªDÒú=s€@±¼e¸D?CþŽÛÔõ¡[Î'ƾ2»ºqód«Ì¡…ÿ™“oÁT}¶8&l‚ªTÊ Ú{rkd—|Wàðf-é2#mXt5 Þ†LµtËt–l±þOÕÊs¿áª‰@uªRò±Ýü>š´$ß'£ð% Ê×›°ú£Äkê-52ŽÞšQÌÒqû€Xè0õpàwÇ}Ç@—|B#RM õÐ]ïÁÙ0›þá YlNñe1ù´0r(ΕžÑ¢ñ@½Œª h ‘A7×>ôUµ‘ÀsL¯Ø"m6kû”[ÓNóÔŽG‡Côˆô²_@-p?ŽRJExçQëjž²B9£¦¤¼nöCløòƒÄ}F˜'˜˜Ú (œ&tÖãà~}™Ã’æÙ<…­ª{G;ÿh@Æ[(×bäÎkÒ¢haO^ž¢¤à0ã&Þ²ê@²b¥ï¾wâ*ÜroP:ãѶûþ4;ãܽÃaÿN&ñ¤QÜÍI"T¦†„!ydò_4IQFißaà×P9P¦(ŒžR6F“”Õ k…Tô·,njÆžÛ%Á7Š`Šf˜ÄXKÀŒJiÓJo£já›.¤†Eb€¬–B Y…)mDÁb ÐBŠ —”Û |¨P~,±úö]dî¶²VÆ´ÜZ?$“7 x8F‰÷3²ê³¯®œ®>»ùM€§™VÒcQÊ÷ ÿP¼MÏ»‘8KÈí¹x,!UÜn­ptZãø§ ›ÿ®õ9³6®@¼GÖ’@h÷ @ÒRæ£úˆéÝ¡œÐÐWFjäOH©™ø6ºc¨Þ ¦¹;Bwåå2*¶žz‚zÛÇ×H$Úɹ!:¢P¹t õÇ!å²Êð.D¦BybeHÒœ½íˆyÄ2SáeýÝõ_ÄêLÿû½)4ˆÆÕf ¦q©{Uô²€y™ ã©ù‡§ÍÉãb'ãÅÅ¡µgR5n†s<‘ðòãû"ãòV[êÅѺö^bÝ—T™?¾yc¼524Ì4FÚv,ÛKɯ…ÄÕ‹ô ý ƒñ)÷ZYÓ…4ÔX=ÓªEœ0]YeÈìwøk^'2‡µKØÉo\žŽî>MáU OC#«VçÉ ï õìI»&Cˆ¾òK(ªR§ÓÒy늪PÁxÚ(&˵Xg DJ˜RÕãAyvPé†;®íaŽs8¬9·gH†‘XX»n€€+ŽôOˆ%N•ÍJ²œ€m’[RZtä¥w*„ü›7ñ«ý”¿M !¦Äý“ÏKI¤™`Äl%§v $.æx¨CŠ£Ñ£ÁØÁx“Ú©@ªU\^˜»ÚïÒ~uŸ‰@DÆ”¤Ô@´j,¬,¶V·c6+²Q¡¹ºxæcBÁZ ÿª‹jbt5*(t…ê:J<_ŪU¢> âZ©-‘\ÒîÛ“c Ä '.ü#‹6ùX­®V9ଊñˆ#é;6w;ÙLÜ{bÓ•#å™ Ì¤Û¹†¹‡ 8dmA_Ñê.WèžÆ[ƒëlž¥æÚú³ÒeÌŽmF—1ƒ˜¬ªÌY`éàjêtÇ¡Ù9‚äÛf³þãëþ°ÅU¾— ûa£TûKýþ[­7kÍZ½¤)×ùýÊܳõBV)ReØMc(œŸÑR´Ô|Ó„Ÿoêß\•.•;Þ5 µÉ ‘eiQ÷æUÄoè·ñ²t)Ѫ‚!Û´‚o"в¥Ö× &/?Ú#‹dጙ²Ê²Ù€醬Hªð ©8ÇÎÈDÇ’ÒËÝÝZlž%¶LPð@Ô…^ùàH¨œö@;ÁôÜô´O";¦`ÈæšŽ<ÛL  t´ìÌ´E‹-WdƒSCq¡Øò¼W¨$ÃåQîí‹ÙÄŒ€€4:•åö‚Fñðà|[À¯¥ lï¿Ú9Û¹8=+°aPf|…y¥÷ÛÊ €j€ qzåjD³ü±Q‹öõt¡º±¸>å¿5¼G’›²)9%jEŒ‚¶ˆEró#^!] o90®RWÀ†‰»#žµªU™e¨¢!a^8°Ûòè£?ÈÇÈuŸ+mæ{Õ5]ýêÃù­K‹ ·]ì f‰Šˆ‚¯Ôn°“x V3­ /­¸€h¡‘þªùÐedK¸ )Ë{‰„ù{%XßK1s$sÙá¤ñ À’öiÑ´Â`Z¸ÙŸdj)ª‰…דx´‡™XvÃi :_¦a€ŽÈKDÞÑÙç¥>Ä„Ks Ì»ŠxNÜ𣅘ÆLÆß0¦Ô¼Q€d*#m NÏ{Ĉ9 hì~ °é7✘bºQŽÌd›ïüzy.ÞÆAj1ž·œ»€éªµ’¹z¹OAjÉòbCjÌY_Ù++ëH©Ó—å¼e麇£–3ÇC+Q‚f vâNiµ·ÉJÝž>göL²-ÉÌPÃ<êß±OR€¼–×§1¶(Ge³TL¢6Ú¬¡2B{äÚ¡‚ëâ;,ŠBu-ah9%çaÒ`œÏi(Õ‡ò¦BT¥¥mÕ¡¼‹Y ‹Ày»ÎPÞrd&ŸáƒTÛC ,kѧ:ÖÞoúU¶øÆEù±ê&çfß’\ñéェ¼ª’R‹ÄÑèáL¾³)lʆТtÄrÛ˜t‹Du«\¤*‹ “¸jN4ÛmíUÈcwÎK}xoä rÃðÎðæÍqˆZwLÎCe¥9€ƒ¥âB{÷°Ó«vno™Ÿª\ "OŽo¡{…úRØèmX aXlü­‰•ãã(½%µGcŒÉö:.Ú(È…Ðu»(ÄË[*<ÂãÅMUÙÞ;aMØýZ!òÑg_bë2çw ®þˆ`è?ÍGœ0šð’yÐI¬/<0å_ il¥DgCŒCI—I5[ˆ ˜­E]Lz$*'Ô ñ)0±¿Ã9ØÜݼÀ^r§ôÞJÛ󮹃HßÁP!&Ôyy¦:9ÑsCf@nÈœ”ÒTÒaË€¡¸(º°8v74Qfíi_É ß©Ë &tŒ”£0þÈÂ!^hØÝ º¢RÁïm«»ÃÃ.#bC"ñY^KÉbÄž¡hm ãý"¼,ÁX•¯–äÊk}Ïk¡;úĴћ߇ÃqÈ{æú 4 r±³8z„ùrT” rHö­âîàu¡ãÆÔÕ)W;A8 cÜ~Kv‡¯wq´) K¢k5æ ¬_vUl˜.Ñý–¡ÅÍê‘%Ù±@^òe"WЉçeñêôìâx 1ÑG6iÃ"á´Ž(€yÝùã&O A) u@7{xSgwBXfÀ.;Á=ƒn"mjÒˆ  ‹8/ÞlBí’_—mx)¨ŒS9) ':Æ/ùön)×^ Ü¡3’Xdæ#;¢«Ä›3>¦%¼ÜRžnùŽnÜ¥SOî<߬˜Â>Ì!ÿÌ¢©¾}§X&©æo¤N?MÇìñu†:¾ý4·4êt†÷œ9>$PF!ÖÐ(U_°ÔP2Jx~ öÕÑÉÛdòÛŠõü‚0Ö“j6LÎC—ñ>BR¸ ýÏh`÷c0v߈ ¼ëër5díÕö(¤ì^xV‘;…§¢$D©M Ê¾êæØ¡Ë }°C.§^unΘŽA-å€rÒÄi›’ê]7 ãf¢¡ àÔÛ×úlPûžb*ñ“µiâvƒ@7;VÒw2{BКv+VÛBÿI±±…OÍÓè§4?ßàsûoÝXÕ>Xë³ >É“‘lÖÞn<}÷Iª­âç·Ï˜.)gª~WÎ+[?¾0!G…ÔóUZé ÐÞƒ“­ËH½›ÁØ— Ü’¾QX2Y;áÕ¸œ›Á7Y1ÿ%…ÔŸIçÞÊãcƒ`RQZÌrCàYSë]¢™U-•–±0ãiЏD 3¢ã[Q‡½À,tÒlÐõL û¥Yq¬ÒXÚp³ús¿B“eÉIwùïv,„”Œ “³!µ§mHPÄóé{É<Ìâ…69ìÊ11""Þ­eܑ蒹B{ œ"áT[Hl N@õA O0lJ&X­è÷TÊî€Ï‘KóËgŒ‘Ö¬³vŠ–Å*Ë‹Ó]:„ôúþgàù8X»°VC¿?D+[„ºwqq]=yR¿êt°ž>AòER;'E5Àp`¢ ÷Viþq¬îÍfÛ½âöÕ|× Î0¥´¶Ã0l5¹ñD ×Ì‚™¶¬¥­¨ÉLûQžD(QyBuÒ«D@˜ ͘€ŒŒ,€”Upć]„Ù6*F9€Á2 %It‚ 9äw.¬AÆø¼e$ö6E”sâüIÃ⨤±hãKvªáÅ„mbm}Cíø±fˆ×’U‘²™ìYXÞ%ÎäSıYÛ Q Öžù‰ÊÉÀ„ÁªR\mòÚïÃP7HþVö©¬‰ˆOŸ Reˆcg«„T‘ËÂRâ¾Î¬LÎëK:ÜçÝduÈ&à÷?]·H»hsÑ®±ð‘ƒ}'#L†È¶ðÉç‰ò~?Y4‹@LÛn àP^–3s@éØKf0w™»xR¯­_+¤Ê”‰˜qͱ†Pî~t=%Ð@‡8jÒ ]ÁÀsBÔ9Þ¾™ÏåêøLkv½OMѺV´ªui:·Á2Zq»Í3_µOñ·R!#°î ²„ «h|)‘úeIöe ñt"s;™á¦6ø@È“IW+ØÂ‘ÝuQÿ`÷FüèA г+FŽE'A5‰h"yb8uäõ窲ÃÁbåÒð–3 ÃrÝ8îÌ—ÈAõ[…ˆœ*{²UìŒÆ›©'yÈOnƒÝ¹¢Xñ“¼/{V{FHD†ôìˆ>îTñ¨ÿ mñTœ9}Çæµ¸ ü x10ÚN_Öˆ­÷|4.•·@Î…Qí„[‰ÃX_–ñ7ã"ë•€‘‘ 7£Pûxëül¿—éRS–*™ž·Ä|ÅÖ’)ÂM¿ì@)±dÞq„hÃ0XØQ%¢(Å TÇ¥m;W.{= ½phc À–b¥U&ŒRä†!¯!Õ7Êò6q62ú–`ANƒýŸÛ2”½¹nEħÔ\Êõ"ÇØ.ʆé¸ìFkæE€ËÙ'f¾MšVÌ®ì^®Ä€"aeß :h(˜$·òE2¥/¶Õ¶›ÐßF2U}ii-:õÈ+ÚûF!³?dxçàqa“ë¿/ÅšÙS®*4fu#!÷ŽÑ…/>Øý1ênáÓîd{‰›/“õ¢–ÁCД¶Ù2ã,ÉvÆÌÆu™l<2Œ“2@µp´‹Ýü?DN7„ Qd¼‘‚õf§a“º9‰Øøªß_àtj ëæÖqÎBT½‚ÖþŸþËšüD\¾B/›+oïV›e±Z¬7×ëêõ?¨àÄŸKÚÈ ‰ÜÆew<ŠêYÞŠiïƒ*0t‡ã ƒEe @¦bâùfï6U\0Ò†ÊûJÚH•N·–´NËîkÚ@>w4o`ƒ{Ñs<ÞC º>F›g ÉÌn¼­L^{T»`n@3]Ö·eõ-)An•x–-ÜDS¼Ÿ“×[€;2ÓSöé˾›~©Sˆ”R÷}—1ë®,gWµÉÿ€øn•äçøËÛ€ÓK¶Ùj&¬J¢dЬyÚ,rØLSq&ÔÄh@ "¹î¾Лç#«“ «¼i²šdrb É*Í5m%€ÈMœUʲ:ÉœU"Ò­L9ñ>›¡‚@{bl\zÜ·ÀÇ-ð¿p \z¨ÝoiŽÃˆHŸF* Àý K‚O“ê1y¿Ð¥uÑ,-—’ÊM(Lgþ®c8[È“kŽ›¾˜™dÝņ€ùÆdô:mG–R,‹ý[©sS[iï7“ Ø¡Ÿ¼M¡DÝdÍÖ[£o õBnø­ØË©ØŸ7¹7cHwÜkÝߊÇß;<›P¢ؽp§«üî1@?«/ƒŠ"R­l@-5ê­#³2ô>1Øø¦ßê¹}x…Üÿ2)%ÄKs*ý¤¨sM`ûñ®Ù,Ãh6׿¹².Ké›MÃA!R,¤ÈôIÍ*ÜÛ·Iß¡=QÝeè 1r:†ð 09™¤„FdèêI¼²CD"è.T'¢’V^t»´4YbŽ‚Z'ÞX¥ßPH‹ ž8ÎLA-šêɲ¶¾k¥bδ17ÜßJHc™rÜoÅ »³–Œx“è´Š]Á°$¨A¬Ù3ô;±n UÒ,Óý0XF⚎f® àrhmb5ÿwB¾L«à,ÜÏßV’G¦å? 9+k–ñz-^ZòÀ“_%父 ’”:Ž¥^=ݰð„¶MoÒ ½,¾_tÜî`8…rÕZxþîXæî¥<Œ«ÝþpäPž.RÛ†fj²{­ãŸÄLL%V$g›«ái›[¾zݸؕŸÛŽ ] ž¸Ð›'2x×—”¥-Ý¿…hS[58$õ{YfïK¤§Ä5ã²ø??p†×ĵ6œÜÄ_ÿ5j?ý[%cXðß‹À¾ Tªb‰äIˆ—9|e¥E%Ý×hë:3B‹ªyÀæEÈ`”:›m…Ö×6Î`Kó¹²,)ºLYœ.!DS«x4Œëp¾@7cH¸¦–ŸÍ¡æ0}ÍìCú–?M$»+LqÁžøðaxótÿv˜ ì wöå›7•d—*>õ|ü ;}–ôÇç?íòƒÜó ":UË€ƒ"ö ¨H‡*4ú”÷Žž¯¼¯Y¯rõÞÑBM9ψÒ<„;å2'ÛÌäo%î元DZ¤lîkhçOVòìû>}£®Ã; ã…ǹ|]xfÙ/y¹:Âø_”ÜKÆGÝÀ£DKÉM„D*ž£ì.`®ó¾6a¥Ì K®µ”èB¦¨R=<~utøbË*b*œV ž’‰°ãˆ'ë7ÝÓFÉìWêLMz^ïíàf{©ùøB@©Y*õ_Þ.‰w«õ:~3ßÔi®l×V›åÕb½›|àÛý7h×Þü}?Û9ûG³ ¢8“• ÕúЬø+}HlË—–HÝàѪÃЦ ýæãÊÂu (ÖÚN5*σ m'`&”·4y‘8©Wé€^eÌl1Nÿš’D¾ùmƛ칿ž+’ËÕ dgýmRpÔ‹f!nO£R¾ù”ÇFReÐ)QÅOŒÎS:%4.|©'S/ K5†y1/v^þ´s¶bF@Ä8–ohTÐL°Ü(…£1f Vx§ 9ö|ŽŠ›¯íIþƒ­%3ñrë\ü.§›ƒ2*å;–U®:²`?”ˆ¤˜aÖßN__¼z}ñ·$þ–sYôâôô¨•]^çŒ*Ä7LÚ4a~O«µý7ûå¸QªÜREâ'Þ×8x„•U!ÙíbúYfÕDp7Ž‘ÄýÐg`4@+Þ£JÔqc‹‚Ç;'‡ûç@8€E+ÊDÚK‚© `›íÁ;+“3ʼnª*Í`’#Õ°`ÝÒS´zÕ[YÅ95Ï­Šõäì à›ßÑ×(IÑfIIWOž¤VN®PÀ+'Wô`@†üqÑ#n6»—/ôJ¹ ?ðÂòàLBڵ垻UÙ¸5ç¨ð»{Aæˆ*„WxUvÚ¾rª(ÆŠêÉ´«H¿8ìŽ~ZŒnÉË—r†ÔnG+UÅP%¹ ·^z\QNGv `¸Á6«ÅoÜÞcLl¼’²F­V›¢üü—z’ÂB¾È3U:!Hö7_èHA™ê“ïg)µ¤I:Ú×Oí‘¶%ëLÉú d¿ìk£w6™-XÄèÚ~÷ø3]NMÖ=Á¨='5›üÏÌ:}‡Ã—c臄æÆ-¼•2w‰7—”Ùû@NNÆõFÓjZÛdÏŽMázlZô¾I[1 mQé¼L<¢y‹zT‘•·É‹i;¡ LWoâ€.sâ0J*j旊܇b&ÃT·% “”. -\ýäÙWðaµ, Lë)ÓwšÉijK`üÃXؽäÔ¦ë˜3›çbÃm!sÛb{M3ÛÖ%¥ßäß´¨›zU7S«XÉÙ„«f‘âƒÔ›j)7‹ćÌ„[@rJ ¤q~ lº}¶IÆbç~Oëkµ oúÎL}Îh4WωZÚRðé—O­OxNl¦ŠÍkªc—Ú^k ô·¯ÿð(V?'™ØÁ÷ôð=ut‰Kò?E£»;ý6ÂX~2[s•ÁöôÞ½o8r?Ø!b.tF^`ì­j@p8 à]ÍF´ ¥˜€\2õû­“ÿ N%?6~QáôÒaÈä%RvûÁç8´å{Ív$Kkg3ÎDmUJÜ¢ø‘ÑñºŸÅáÉáÅáÉùÅÎÉØ?;V_¬ ÙW+¯œÞoÙˆ[ØÛ?ß=;|uqxz‚2„,Õ´¬,ñ7ÆÎÅŽ8~}tqøêh_œœžœÿ¸s¶¿7-²O¯à naþ#YÚGÔ­À[‡ž^8£UïÎÔ:’õ?Q—^ýggÒ‡yLs“Çé}wÑBïŠ&/ED‘¶vy¤œ !Ô½U©Ð,¬ßLW<IŸ‘×MSM]Ežñ wéuØ»øì“Ñv¢lÓ¢“4ž˜‹õVs½~X¤jYÏO"Vÿ?œŽMuõ©®fj6`%À|”p>·PánOif]wÄý»WãÛÙ¯`Γ'**Å|±ÙÇæ„ øêºs9rOüèöûjWåøRͱ‘å\3cæÉvÐݨÅ";a3I7S1r”=eæèÙî¯OØê³íÀÒA'¼¦½Cá öf ýïJÕé÷ŒÎLÖQäÀ@]Gwd_ù^¯Y^œï‰§ìÑŽÖ¤ Tðð© mHAT)+'ȱÁ, >âS*žœ!š¢þ]ÛîûqÞèRŠØ{ÛAÌ¢Áèáp|ûÑÃé6ÉOÚ™¡3'»toÍáuº¿@x‹„XˆÖ~¨<áå­Æ#®––––bjHS;0ý6²JõýŽ­"ÉIÿz6|ž•“íî&6qm¥¸‹j2ƒÏŽs6-2A¬ÒlË9WÇžâIÛݽU«¿qÛì0 ¼Ã a¼Ë|À ¶ [o)÷ûd|ȰŒ³g”åµ.è~LEÝ€ã¾ÃæÄ”M鯦Ìn0È¿”A¼Jò’A¬Î¾Ûq18µê LŒ‡#&ɸ³‚cHaдדÄbà3"áÑŒ·„Ö‚2)­¹"ÔÇŒèæ`<Ú Ž‘Ü •Ðï!NšÊ"Òžº²Œ‚à¾òr›¦½!¶éÂñߤqVpIÕÌ«ž^$A–¹.Šñ@ÌÅ[ÛÛbU¿Ä/%pçÎÖ7s)«”¿à«}¦2‹±…Œ»C)ú¿Ž_d\z-Ⱥ§0ïXГYÄ9ܽ××V?ÑßõŒ(šf”µ”ÃÌÜ{ýÒôm>;8Qg8NÚ‰\‡öêóÍÕOè–š2 I˜iDaéæ2`Åià{Rg'uuj(¨‰Wd“6ïŠÇ]œ#Ú×=d§¥é‚ÓÒ,RÓ$BŸK¢úRG3;‚ž&Ž¥8e˜Q³E|£®3Äö`~¥¬Œ’Xè> ‡mœQ–ÿ…ûºx?s7š/ÖÛ(²åýäÈ¥‡ —¦IŽ\@•»§¬¸ô0BâÒƒH‡KYbáÒ—¿vq0_­4A\šCPÈÛ"—Ò{d¹°4E°Ì”«½W‡»¿‹Œ³ž,V9ŸÍœ)÷þ!|4= /4˜ßÙ&‡1Ýȱ+îŒ6ßþŸ'dÄÒͽ]3ܾ}*Ã/ç‚K“¥¿¥YÓÕüö¾µ¡mciøsü+¶Æ§‚Í%„¶É¡ç%@RžàÒ¦'¤Š°èÄ–\ËÐ6Ïogfw¥]iuó ’CÚĶ´;{›™ËRÄ„bͱŸìÖÇg"Ÿw•=iÞðɶ‡vñ2u:î¼s§e£^¸´Ð³ãÜ"œ=žôc)©"Ƴͤ0¶2zc32r£üïl~$þ‡ß"±è0ë;Ä"Y¿à©%+™V”Œ8Œ2JyOºN×ï( »tÜá©Ø·/1;4þ†Uo9 >õ™ýÉwÛtŠÑ ³?À>Ôñ»KgíéûÙ}Ѱ;î%ÆCS:î ®ñ&`åæ©¶µr³ñòå6ÿ9 ³áàE4ùÚ§dRÃ?Ø”áÛ8ÚDø5̼ÂóþÇùµôì†ÈQ G›²‚pE5BŒ —>êôYí¯ã­ƒÃ×Zí3û[_ùaƒ-³5v¶ÈÖ6ÖV××Ùc¶úd}mõ»ïÖ¾_ù ¸Ù¥^"?Rå¦Õ¤Mgº ÚJLp¨†¤QK™O|†Bºá†{Š÷øe£øu—*Òœ¼ÚC VȆ‚EN¸„­= ÓV9±âóCë*´!£ÊSÒb½(ЧRfiØk£Lß¹¾¶tliß’Ò¢šØKLÆ– ÞŽ¡Àa•e¶måì¡çN˜Ñ‚ HUœ/»_]ẫ˜EÙåâëÞñÞ[‘µšÏ‚ôpuCFÝs¶àI"™}ŠK§!j8AøÆI£ä\C«sÎÀê¡FÔ«ÚØÚoÞøõx©1äš³Ž0hî´q)gÆö%N3H W©¶Š†BÅD|Ÿ@F(SÅC}¥s°äŒägêc&ÿ4Vv¾¢WŒ®ûÛX)ãî†0¼Aýq/‘1=þÀ@ß'Ïàßâ$üg•†ÿ…œ|4•š'ˆ_€‹»ˆLTP,åBŠˆžÕÈMD1—R‚ìp¯ ¬6¿°Òøa«ño»ñç_ŸßŸ-,cbt4ÝÁ" {sIû\BäÆêY>«‰öΚÍÅeû2Jì<‘åø'büH$ËKÑ¥çâR!| îžT¾é¿evÒRz.ÅxÅÌY|P·}±ê6± U[Ó뜇!ü”} 9;V=ŒåÁÍî£~®p´¿¸¤?jJÚɲÌ/¸MŸ‘o†3Lg›s™Z-›¥EÒV¯…g³CŸáyŠºŒN$©Ù!CæcNRìû&Üísÿ)7*Ï€ÉD¤¹[ ‰2ì<£^» 4N—0‚læ>û®¹Š% l÷;.e&äñÚm¾,ܤÓùn(‘ùgëÚÔ<]U™"á»fµÀ½IȃN;Ÿô£GÙá—§Ý‘Q²F?z¤ÞAQ: s0O¢s-­?ñÏ Û³\Øg›™ZñGR£•¯³†+÷pÛ|¤j4s¯^­I@ÍxìhI…j2Ž·(Ñe™…Θº>šfxPMœï]‚$ .[½^Âvðc=’ýjßö4*œ$#YD¨gìÝjãéû&eÉ"ðá“¢ôx •[íu`æ6O…’£ ?þ/`Ïæþœ¹T6ñšzÓ åo4"- l>T¡K¬ÆÑ.pFЉä{‘öz3 ï)Ÿ° YÂop—§Å¦s`œ3à6ö×NŽ>TCá×|ž™¼ iFøq‰Ÿ©ÓÀâ‘é¨5U->†FŽ·ö÷^hÁhRäÀ;š«üÓFÛš±£'¥ Imun3…'yüs8'ÂÃJLy%F:óô+ÏÅ…ÙPXX¼£»vìiÑ5so¦ÏIÅ1»~M`1¸IZQ.࿜%§1½Ð#ÄÂHcu’·ü­Å õ¡öE¯¾f„Òw+ÜDV…ñYêúCOZlîïXÇo,´æ,–·Q s‰äÏ*Úº¯@[btŽ\\7A‰+Ãä›0¼>j¤ço.vÚè£{6Ïð+üSCÍöêòý²µ{[ ûþ6pÚšªê†bï.ð/ç—7ˆ˜í½xÍÞîs}‚ÇŽŽ¶—øÍ ÷:,'¼NîTI!©t?W}˜¤ hLÑÂ+°lØC¡¥K&ÐL¥µ<Üê_ì²ãŸÛgY~õ<É3š=¿EÂGDEÀ¾çË™ÞòFà¼sxeÜyÆŸ³ÏÏËØÐ*àS1» ´e`¸ßV{[7Å îQdVÐKй{ú‡¢^8zgl;R#Ì1xBÚ‰§Íäô41?1T=‡«}•åjŠf£ÙÇÿ {TŠxTèÖ½q¬•òLgœ{ä;Ÿ mü©p¡ÿ=[.ô‘¦0ê“Z1Ó®…ßähŒN1dñ¼eT˜÷”M‹lÛ@Þ£Âã]xEp®ý!œ‰çŽH‹æmI=ŵù¨+Ý÷2(¼ºI1¡’Û<Í‚j6T©VT™WN7v?ãºÉäÙ¡EU”Ö"·ÞèÑ Û'­#ÀÝï¿ÿ8ØT§Bú§ù41lBU¦å"±8ž3@Í’ÎcËÚÝiYÈ·!*ì²FȱÊW?šÒk$1 ð¾ ŠAOØX$GúTŽ˜ë´¸Y$’ñ±Ñ3æø(Ïëòḇ_ýþG»ï1Í}0p¼wŽU±à~›8Žu_T™8¾-S†¹RdáÚÐYÕ”IsnÎ’UWcH£ýw¬î¿c›§Š¤q­5×›«SóˆW¸ÃŒSŒZ²3¼…Åqèa²ŠÎ'$û׳ÅzA«³È=a ü¸Fõãû¿<Ët^7p*´4†u¹‹Ò袻Ö}qJJLF‚›ÁsÈEYõƒAçø4 =èÂà‚Uÿ°gg^• ]-L/Ȫg5—+¡YJÜDj¤ÞPjâ®D©b*|w+†hêzxž 4Å.²ô…!M'»€Æ)Á€G¢?Åw]â‚ìQ[㇠³‡ 3~aþ€ÒðûÙ$nÐîéZÒ#4”™8£Cä4§°+}½¿„¹TNŽq®†‹ž;9y&tö8}2òHd)ïïÛPĽbE$:Ϫ±°?RȽÛ#½`Ôû‡a™ƒ!lÉõˆ+ õæÍÔ„ÐÏ…Ì¡ï[nû« Î-ŽËÌ=^Á=ó"¬-±§ÍÚqÛÆ€­âY]jl Õµ"ô§*t[oîêKH)%%€¢v‹[†ÈšiV)ÒWÖ¤ 1­ÉEÓ˜¦ÿÓ%bv€Ç)Z»´kÍ/Ê6K ùZóÝJãé{2ºV4bqñ¬¾á‰Ôdz_xxŽ8Í# ùý¶PØÂ‡ß£Cv‰` Jœì>ÅwX½ñ'Sîàê͈wÁ $ÒÆ°ÀEý ï [kn°ù®} âÍZóisõ_عLK hŽœ¾ÝhJx#Â!‰·™Sc-äH(Fc€‰ù…Žjp¡T²MôŒÅBÌÄ0ùÊh^§ÈàÚd‡ëFœL¯¸\)3[µýÁ<‰÷eãÏÌ…ùÂnÑÕŠÜI|ë*ü¥G8Y²Ú_×ÏšfÏ%wɺ+¬_ý÷µ³æw©‰sï4¶ËU–Å}?çÒ=t”yJœwiÞֱ71égbòO! èŽd cè#Êú âwBH³Øwþº0¼zãUžÂáUŒFШ T ¿ðûÝfî¦{õ°ËÌ»ìÕöšþ¶z5­Eé ë{ŽMºž$»ý¨ §ýˆ˜ì6¿âlMáhõÓWçl“ê­Ršà6ø´¾8¼^#i~<=ì9Þ›ƒ½·áƒ7ž{ó+,êw0¶Õ÷Íw«+ïñÝ_ãc*ØòŸ4×>=m®@¡µõ÷¡œÂPЈ–põJÑäTEbý«YuÅ#«.õ™R¿õS)¤3ÜéyžuhŠ•;Á~Á Û³D ù1ÚEìÈ–<Ѧ66¥) 0àŠâQXEQñýé'ŒúˆlÏgìW`õ·ð8E7`.B˜€áÚa]÷òj8v—Âp¾×Ž:ƒ@šq>¼Ñi-Å$ŠËmÌyÛ»•®ÅœˆÒµšªG vçÚ¾ HÀoWdÄÞ®c{û ö9RŒ.)dÔ 9Ô•–ßG“ÈÎ-ˆ{i§”䨦esähq'R¼Ý+xy%ÅëGôë¯Ü„ÕÃøØïòËÉ€]9ö§ÛÆ Û¡ŽÀ#1…p é™fE1 õÔcá|ãÁJÆ}¼dÈ‹kTñןA‘ô@ù&Žb+” ¢õ¨°†x*4ëî¨V¦Æá4A Îq®^­™ÀT…÷®ƒ¶ó‹r) Ä TM·°Ó£¼wL{8áEm Ó-®p?Pí¾w2ð{7oñ9½òÕ\E|º¹öû§Û4½ôdB±šX¨¾ugµ¿àoD<¿QÛß;Ø=8üü ö[¬ë3@-6aß>­( o7@V£–԰ʱRß~‹¡÷­ó¡K/é±ÓTíÕö67õö-=K¿÷wx9¨¶~ÙÝ:e»¯NŸÉ§Ü Ç °QàÄí €§\³^(J/|<¼ðXíÚ­¾Ò“FׂñÒ‘°°(PzÒsmºÿ£·Ûµ £‹!HÐè† §‘¡²WÀný!ûèù×̹±ñ@—àHt×6Ù ¡u“g~šc;Š¥  uì–#òÊò€'d~ʃwØ-Ò¶ŸUtɕ檓UÅC*¨—¿BbkdñLWV3¸RA1þGEг[d×ýÏZû§ÖîáËJ«cÃè_ú~å¯JoxÞq[¸*ð›Ícò@;aq£×w?ÙÀÅU(u³ŸW>?¯H@•ŠÕÐŽ} l •\ÒÜg…SUu+¬¢|n¾²xÆŸ щjÕPR½ô†·UÜTä¼^?£0½ŠóÕàúÚF¯3¼t½Œª‰²†ïB÷fã/`ÿ쎰U<«žñ­xVMÙŒgUœs±JgÕ*Ì#mDÆæ Žòvåo|Ð,{lÖþ? nû³Ú¿`¡jaåªh‡vsôX,f˜CqŽÙý€k×Cí†Ðf  ˜Þ‡—T/Œ©dÓð"×:½(µì;¡ìN'TétœCÀ1¤¥tGÅh…°¡1`e_n¤Š4|—H¬*Mp'Âæ°ð¹t{%üCû-A˜Ðn¬Gf¬4áÕZІ¤J&­•èE»¿ÖäÔ«±"Mã˜þíDTF‡L»œ»@JŒfá¨6þÚ_:þ\"‹Ãp6#ÇŽ$L2£F, âMcŸèqŒ•SU¼</CÍ?v~³ÖƒoxCæzÃ0ý#jjÂvwoz²G Áõ}˜}XÇ/ eÇ#ç/Ÿ–™’P'ºˆþT4i‰b>5F¦s(‘!$2*VË»`õÆ~Õëb44ŒÆ>|٬ŠócNã1`qR`'`…ÙIƒÙIÀì„©r,QÇä,m¦4½©¶¼Yë “I‹—Û¶Úr,Bê>Š*Úü6pwgìx`Û>úq„tDÒÄö€W\LÇí"F_(âçYúä¢Y+bÐ ~é ;Eœw ·÷»}«×—µ±1W—«En>1ÒîVdØ!&€ëM5Î:Põ[¼Ì£WP*ªÜ6dÖ©ÖþÊzÿY’$.ûÕ#I@üµÚèTùq}ˆGŠ š.Á”ÄYªÊÙò5ãFÆçÄ.1Ô3tøöGÃg€‹Ó¥b˜NöD/m‰f'œí=Ì„ú[y´a¢o´ý*1Ö|± LCd üü9¢è¥‡ó¬*Û?=”G˜(.‹V”ÄÔ˜Â)†]äð„-6‹ŸBܰû:`Ã^TÛG¥²à^cGk‚xe‡m×Ék=åœãVNt¾üNÓôKª-l’‹­l²€ &‹/ov¥öÅÀ=Ñ,Þ›äS–Žm!‚éHE’.]¥¢ZœWÎmwÛÁµçñßí&ªí¦sãTD†fq{枣ãz³»þŒ9ý¾ß†dë¼b G$²wNÒÌÀ«Ë¾Ý­VpÉñ2 @#)hT‘¼x “^©xx|ŠÂ+0"ý>Pb¯‘c»'<a-ã¢ZR8ÛW77±Ìráá@Üž2‘~{StœÛO‚6kvlq†lÎÜÖ&‚s¬WÈ7¢I³áÜ0¡Î .4·ƒ>þ[½|ü¸ŠçôøT0Š ÉÊŒ•9ª°Hb ÓI2•Å*9üW/2ô§!(ãal–h3Ä{´ëÎ>B†+¢pÈeyÀT¯ßà8ä¿aß\ÖÅÏßÙ7ßÔ?¦eÿ!åÆÀBÜ´Âö®;|l‰hZa~ÃT…8Ë÷ÑãÇ u¼î…Û¢c‰# €d¡ÒK캳ĜA —='ƒ|Zë_;Kus¥Oõÿ!n¾;T‡nãaŽmÞní½e¨óÆ=t´·-OÙU ½N}•1ÙC7GUŸ2ÔTÈHdlo Š ¶ÆïWe÷÷…ìpŒ¬¥®I2›ÖcšG»ë^ÚŠ1wZöñžíô{­xèïÀ¡3ÓŠ›–-xx²Îš°ãM™ç vPÑ v7¾ÿoXhè¤#^׃¸3`߯¬­ðEAÿ/Tp%²E.áuL žÝnK©Þè”:ɾù á>p˜<çã­ºD‘–b;îG k}¥Þ,:¼mÖ€#ˆ·7x²Æ]~×…Ï@tsöºa– jåsVVdþSRÂÏÚí÷xÒ©Ì s”•ÓÕr«ÓF…߀*‡'螦ub^#œÖíåµëqˆtcÞ»~BŸ-ç’lç5þŒN7PÝåàû°Ìqg-8uáˆé„jqvåwE÷ÈN“Œì€u³Y*ΣŒ,¤®Õïç°†scã1¶ÐTö8¿áã¬s‘2—8…€ç Fj…À\0Á‘ 0¿Ó’rÛqB`óFÛ 0bOÃü†ÛÅ,Dh™¿wvö÷­Ý·xÂ×+)ÖÒl õ™$„üˆy”‚FøÑ¶ûbûWv/ðÛ·ÙÈ!ìªBcªŠj†CŸsÊ@‚Ê`îùú'kç7 áNŒCjæùA¬ëý]lÿçRÉR0ÇvþçÕÑ¿žõ(tZ¯}"‰,õ'¯e½±+Ûý8Ìß,?a±¦‚ð(æ‰l6œÌ87hn´$nŠKÖLëŒzœjýI°lQ²‘x—0¸qÃYæ¹®…}:»t<§º"öѦAäÞ½v”¹Æ)ì=ÊC«÷‹[μ> ûòEmñÈsZòtLúÆÏÈJá“øÁ'‰Zîzl¬7Î~mñ-|Ú9ðå“5|…šŒRã)-*€Ÿ9å‚ÒºV¢“r —<Ý?a]˜âޏc¸ ëS×ë|3çY´]ÁýŒaÿÊZKœã%ßñbçç*}s:tàhò²IܨÀ›%ò–z]oŠÆ¶È!Zî°äó\(Ìg ^£y;î¥ +»§}E¶öWD3pYDÛ‰DáY²ØÄѲLŒÑIP$„ljȎqŽ.cšÃxCxoC„¡Bø_ž?H‹24y9ô÷’þ‰)¾_ð-ôtœžp26–F:V¤vº˜+E½GÆ„Gî 9zÛ¸}¾šPCQbâ ¾A9Ç^â]º¸”OÚËûº»jì]æ\ï­èÑ2\»Dɾ ¡啬ÖÒ^ñ.T%(nžQØK¢uå´È—¥±Zdž%åÐÃÛÐ|',UËÔn6›,ô¯ÀHÁˆZŸÌƒzüì3»°;Ãu4ì™bŽ Ï·lh»½À!J«¡ €›©ó‡F#8•¤7•t1É.K’ºðYµ+•¹ =¸züí,·[ƒ!Úè¹ ;§ u4›š´–#ëòÈ„ËbCØ‘t¦že ×HðŠ#Ÿ<Ú…`…C“ݲüáUÙ›š+аM C?“%³‹êh Û)âÕIÕàÇRá„Cs˜Ë'ä×ãÜP4&î´,àÚ‘‚Y }hÁr= µý—¨Tä=&út‘ -ßæŽKÊøùÕÅÓ§ƒÆ$‹Ü£ä0[xoü}Ÿ™_[„p±Új«Èø³Š5Øü“&n€»nVd/‡SeÅuó@€ ]U ¨ 9óºt%œ3ÎKL…ãR ®Æ†:` u’À粫Û O?A­ãêˆ+\[Åï¹^K‹I¡ï\8}Œ¨ÐfŸ\àÉyÀ½j£[­$÷‘a·©¯c˜9"_h“v†EÉíY“Oò糿V–VÏ>³gßÖâ¸Àž:×ÕJìÝïìý¢œç³¦ hj¥o•j†RÏê°À¼Éè™ Zµ³*mó…¨VUy[Ù?\}§ß_ÛFõ¢Ôj!áàÃt%ÛNóBš2ïܸªSÐ:öqÊð‰ûUsåˆE±Ã[)²|öÏ#ìr#CX‰ „Ž€,þ¥çþé´+¡Ï ì[´Hæ)RúÜçAV\ &‹Oá€jsÍvZ„U'‹ÖpiÎ}ü ¨k!ÎÔ—¯-·ëL™àa¥­¼Ζg‹± >ÇʯµŠfð ΖúóÿµÝ‹ ¦¶¤—HdêŠDúRz+m[¸áÿ­}%üÅÊdOô°éÂçºVƒNŸJÜú2¿ª2/œ?M%çò½ŠK]%»[ÉcdïTŽ2d5@ÜdxÑŸcÓS˜G¦[šÎfp0")K sÝ1ðt\J⾉ðrÐíIq‡Å3é‰CgÕʘ¬ŽÚãZ²ýr|N!`ŘQm |N²`uȦ^Ü”Q+ä -ÝMehBÃЪF^ˆ<s!"ëÒ¥”¢“ÄŽ•Ƈi;©¾ ’„^D!&™×é©NMû:œc[=t·¦[#ò‰ Réê^6;~hü”<*WÅá?9DÕÌsƒ%ŽQìˆGDA< ωÈÄ-¤c¥aÄÏšF_9n¬®©x?Ás(Þ³BG‘©RñÓ(Q[Y…gG‚jY)h|©° )´PÚ}5(I9=G¢SaŠš ¥)…Ò“¥   œ1ìân|ÝýØv£·Ä ·µŸ¼€?Gœ4Ë“0avY–^SçÿA4Ì ¤:u2%»xÁ)Iwi¨ŒuïDÔUš‹MX¶H—œÜØ“h/Šwñ–“%ˈy’ÝÖU×o³áãkÖ”áAbBŸãW{ñ`ÕxsÌgËÐ ·ÔO×µÈQbu×¼¶ TÎ4“ÚŠ /Ñhk)§tA¶ˆOû]AƒÃç²»øL/"H8¦#þÓ”lÅlb$”²œx8ÒŽô‡#ýáH8ÒŽô‡#ý+9Ò+–A\ì`z,fJ&,¹¡,9Zð€>ãªgMXQ`xë¾+š}:-ªEB:¿ ƒ!z}ͽ‡0?p°¤ÚËQÇfTÔ˜ 0\LÇ÷82w”Ôœvôõ\epµuÀÈuþ°u¥TÍõíSÜÌq£¶]3# DÔ_‰i‹!˜RF¡/…»ñëÖñÁÞÁ«g ãÑÖ“>ËubëtÈ×é¶¡ñŸ:ë§8Ø}á$ºÍÛ›èµç<ºh„è›x^pS$ÁS*ïÄmɨ·ô”ÃýSSâ‘‘J{¾¶¿³qÐqgäŒ1XmÛ ©X(|ðZ‰ ¬f(€“'뵬žÛsÂcô¬^–›‹ly¿R¶X2Ñûs{è Ö© d!‚‹æ­Wû‡/¶ö­Ã—/OvÑ-óÅþ®õ·|j½|··óÞj.b}ƒ™âü*Lòe\ô(&º×]â’wG¿ôx¢I­6¶«‚ýaVÛ",{ÛéÚhhF‘5´¯o Z½g½®ó«‹1d+Ù ñÞDàø‹Ñ ^Ÿ ðÈ ”kÇþ( ¹£ í±ƒßXó剗9Æl …÷öHÿc ¢Ñ¬úk5ìë²ùS¬³Î-ÉèVFlZ˜ýy—»t¾tQðQM*¡¹(´× ɬ+%’ÉÖÙ qˆa÷yŽê+û“¨ËSáð–± â³VmU ¦:Û(qG. µ‚€ÊrL£K#ú Çð‡xº²G>4í*v ‹ùFUÐ?úšÂêÇl®¢@œÑÍßÉAË=ÿFrl4‘‡×‚Ô“«`† ¹³K³¿tßGJ,jŠÔ¿ÙøÄ;¦”–0çì8¥KjZDχ~µÝþfSt<9¸/kÊ8µYKËCEÑEÒrTQD‚q%NëÖÎ~<ÁäLJ&gJHõf}I&:Åîz@ëÜ(]´ x3H2Câ“Óñ{—;ðì°Žþ…eí¢òØgOš+Íœ˜ë¨E„Êf¬~oª‘\ÿâ\\}¾[Ö«ƒ7Û–RÝËχ67á ˆîâÁ뽃Ãc,·É~øn;Ðs0dØ­>˜ƒùp/êÈ¿ýÍÓŒï²F¨ÆÒImô£g5…I_`Ž êpæØºëPÔî”äVð¬ëtÏ}—DG8°W¸GªÏç]µ¨l« VDO.¸ü° ›ü!Ä­“Ȥ±Ó¼³ ¯Rz…W¦_’ah Í\úèÈ„äØ¼¬•h¢‰OÝ«A€‰õ]uCÀÃ6v<"«h¦¢„ÑF`èì£qĺÍxÐKÑ„¡]H%Ò–×,o0&0ð 6f XJÀ@…ì[Ì~ÖsúÁ†­-Ï€¶Üu”²Œß_¹òðTãõÒ„‘W“muI&ÆìE„?&À|ž½ˆÇætZÃv9à¶:¡µˆ­×8ïäÊ®‹G±ñ¤gÏ­ÜéÐ5W£³Ûˆ.~6ƒOýu-§äÔçŒ<µŸŽ~áy¨¨Ã8u {s~°õz†Óü…Pß ±ÿ‚®ª"K8‘}ö ”²g–¸'1?×øÑM”ì¢^4‘3.ŽŸäSÇ‘Aß‚KVUœ›ˆswpí¶«æŸ¬1 ú¼À›±Ãàß<¾OAÍí5P:.&N¹JXåº0T„'Œ¶‡=ûðŠR¿ŒæN¤ÈMVyiíníìÿÆÑ˜¾%~±Gž…ä’µéÊ<•†Î6(»$–l`´[®‘Ç@â4å'’¸fŠßÂ, °¥Š ¼Ï#×’U-OKוÊUP¬ñ£†^jæ RÛ~[¿—jøúe‰½Ò•a™Ç(q˜¦f1›õk óòPׯÍcpëK–I²e’ÂùâÞ†År7ÙQß?‡o)“­EgºdA¨}L6!‚hqÝ(B8'jr1ìà¶¿â=nSæAðÒÿ¾­Ô¤äB2„¯.ºÔqB†žè9íCy˜çzÐýB\å‡( guž=& · ¥ \ ´ÿÄùøE¶0À û!zo“ÖA’ë÷ uJÊ*£"ÜγÁ‡ZÛÛžÛ²yˆí„ÅESt\Á¡ç>C¶—Áóã«€ýE›± 8ñö<Ÿþæ/ Ñ üêà98} d0a€²Ña‰{)]pÕ§tÖ&„Cé:q‘øAzÎ.Ït›Xà2ó‰ñ³5©‹Ç++©™à¬ZZÄy¼@]Zxt™g°*gçn^–šNþ©#M¡:"žäb-•ŒžD)‹n1 /PEÜ«*{HÛ[ˆ¢@;ûòfi$"_Oy‡+7<2EKˆ%HraªÆŸ¥¥8BNqÚ`|üìw$‡ZIõmâ9ž¢4ÌS&Š)„êJÈ5¶‰IT™ü±‰Éåí=ÿ?=&†¨¢G­û5 ^ô5ìP íö—Í 8›8Vòí€RЙ%ÿ/Êy7 B¢ÓÑczŠ*#|þ*ÞB]™¯˜º¬ŽD„BÈ×´µe5¿CZ|„ÙrÑnÜeL›'†R5w‡’B!ª•~—&W¡Íƒ¹ƒ ÇI»¶ß€âçl7e-MƒJMúæmFÎá{m§F¢A©]Š˜Ýî„{Ô¸ÕøNã¥X„îüÁÈ'P:Ù©†ûmfÌ·ÚÑÖ$;„Úþ…IÇY83ŠþBÖV5N[æNjKRnreWÇv|î&·Åaï}H3‚1kh£»‘Šš}ΔéFË:7ÇNÈrà†Àv¯­¬|åšóËk¹$…JK!‚«,$ZdRb#™{“ü¤B®~‰› `îxØðøºàUî³(B]µ¢v¯Y¹3Ž”f9ʉ—Õ‡¦{£"„JGæØ6—Îj‰7Ÿ­°4ЈçÄÂô1x«!fQ½w©s™ïœ³ƒLŒ­ ®,*-+&ú”›=¼hŽY=â>;¯j6Jÿø½¹¸Œ¦cËh:v­ýãlõdùœ Â..›‡¥0±/«Âþ ËFÛ·F”ÃX³úœ•®ƒ{—<½Vù–‹Pqä§ì| y"úêçÝPöœª*§fƒ¶ûnýé4.&´;ˆ;ØåOFõB±Ž“´Y=«áç³åàÍx:m–Fb¶áâ)q!!¯ —„T5¼&ä_Þ®®F?PŸÖçY˜r¥èƒlÌ/#ðÆ[HSZí9M©IhÓÄ!2»ƒš®Î ’sŸjË.oÐãyùu™¶PÿøJ©nܪ€aÀ•’¡YDõFÕKƒ§ì$Ý)[D6ä@`­ÁÒ6™MRÃf(Þö¯Z/容M:ð$ºnÖÂC‰ìðf¼h©ºG@ò©1´‘ßý}òàl×½Öæ9–-,7›Ëç.©íâ,VÅÌwaßȳoóCØÍ³>øð’‹íóû¡vòÓ.4N6ýQÚ&çÆðëY-…?ÝçüæL0Dt#ˆh=²\àÑ0o+,(½ñºänáž|&‹†¼b’I%CÖ.Ì`†ž˜öã›´J¼Xì~M0”dû:àªï`ðG,pÙ i…â rkZAüÏjÿ ÓR¹õJç:´EÁUÈ^ZRš%êK§óah+8åBÄoRÍ"Qú] Ø~‘áç6φ HL79¬%êŒïM_Œ FÉ…{˽!òeøòíör¹þA”4\Ëi½ü®ù~¹±|YÿÚ––6–}öµë½ú5‰ªÝ£Î‹QeI_ãôRë¤âˆ@×tðS™ãÞuî›èOÞL÷®Çœh3÷×…þêz08q€ã9"4r_ Ý!æØ=À{×'¿lKzªÎwdr?•uÈ¥Þ4ÓÊ6á7ÊÑ>áH¶E×73QÚJ²¨s/‚ÍÚÞËñ¾mÖŸ‡™½‘ÃXRùQfCn~?$MX¥¦€SòìÃÉ»sŵÀ‹,›+™¹ã ¿qBÊ÷Í'Œ’ókie+¡ãƒD`ñ«wÀ𯖗·Y»ý{<®?È÷ÿ?Zü_àV?„`Ó™¥ZÚ+¶N„çT2'S+ám1µ¯O~;áãlæ-Ôý ­DUÝNŸÁŸ¿—ÿJȳ3^ìÆŸ[¿?;[xö7[>;[Þÿ‡Eýƒ¾’¤6ê9fi@„Ž—”[.PŸ`ì­¤’[^mãUVãKM ìzvË ¾YÐRW† XÇ÷?F3In’HžÛ}ت˭å£ãÃWÇ[ÿ·úŒ?l6ó§ B7⃫"r‡¸Q¢6Ž&kTtä¾e¡€¤3U@Q °Nv¶Ž·N—ÙòeõCŠ‹Vj'”]ކÿP¸f>×jü¹ èöl¹ž‚r³â`Ò8å‘ÓæW™6û•óÌ´ê6¦G>ý©™¿S m…?Ç9 Ñ^j9¡6rV!4ø Ýb@ l+t$p‡ÂTüñ0A·ˆí‚·l! ž‰¼Éææe“U¸ôÂuÔU¼ê®Ê]R]0œ—2Á„d‚/‚ÏÎàŽàW‚?’¼‘ð/CÞˆ]÷QKÛÏåZFçˆ"aÈ^âèBPÙ]}ôs¤»ߺ¬I× ¤Ãàè Y¾E™Õ¶ûB-п²{ß¾¥ÙJU“µo;íj\SÀ·®-¤Ù"“i:Ké¬âPtõSvéÓµó›AE¥¨Dêh'6k EaÒ7Yó–Ç"ÜA=:Š´ôæÏ=ÿ@,p†ª®«˜f/ ¤EÒéÙGŠÉ<#Î`J²k:Hè÷K8ÔCOòù´ýá Éèd™[!’mdÇ!Ka¼çÚ9Å”© +o{nÐÅë‘ÿ ÎE6còÆ _\8œ–ýóÿpæAá8Âg›’å>¨ÜF݃滵'ht¬@ÃÁD,•ò£ê¼q4DPµ°Z¨îSËÅ:ÑÀ<’ wk4ÚýorDQ|b[FaNä°'9fÓ[c/c·ôb)óv†‡Ä(Ö¤Íz‘󙚟Å;î3ñ°@<+0Õ'#ÑֺēϢ¢hˆßxú^+™x¶Þ\m®ÆŠÀ“ü~ TÈë6·äÂôKëÍ †ñvðTéÏĦG¹8»²ÝÃ;9:Rù a—ju|»íô«_è)çr#“8÷ýÁò•ßu–ùçè)—•”Ü÷_2©˜@kßÞü€û¿¬®„ßVÅÁ÷ŠlÆ¥Ù.¡B¢[[1>×½¤Æ£WaÄ ÊüK†»ÜŸÙ—x%6¡¡DE:5ü£ü¡ÅqÉdï€nY!IQ8´Ðp7c—¤ó¼áÝp>ñÌÝ«än)ÖØcÏw¼O¹tn¤åJŸŒ;9G9% b °ýtôæ­…ÞnÖëÃ]-kVÖ­®àl—’ÎýšŸVcP {(6Lª`6ÖMýÙX/Ûá¨FMºêõìÅ4„팉° Èø“9v¸ušÃN~‚Rÿ­(]/zöÚŠ%£Õ Ô‡ÕJV¤jàa‹Ì1²—XOχå|ðü… ݾˆñÃ} b€¾˜5ÕÕ*?azbqÀ¹ïÏ" :þ5H{CŽÈ Ït袅ÅÓ§O—×Ð'õ…ü"ŠPïëÔúÙn‡b.÷ÝË+îA#'žÙ¿‹Ž[ôÿ’àäk ÛÜ€âôv1Õ¸{óîÉ]9F\Y\ͶÇg=iÞƒU6´»Äobv÷_.²JÊcç2ù.:@ Áñ å÷€ø=¡Ä1JîJ¶À_(7"2²:ñ^ò<~ôhBh#‚–èàp€¯DÛtÑ«üZÏ!“%ÒÕ°ŒáÊë N]Ç®lrÌ¢¯‰#€ÃÛßÁ{àÐæ«Ù]çQÐÑÜÖ÷¤ï'” ®ÝAëŠØo¶¿Ã1£ñdíïÅ*ü˪/6º( ¯]·‡O•Ÿ¬ªè(âÃg]ûÒmm>Ykœ»‰v C÷tðN¼Ð$›€gQ#¤ÀíÀ°‘u®lbcý\ÿ•"àð#„½±®Ža!{Àž8ÓèÚ0±Æ …9j•Ú_!ÐÏ¥%Ãt¤&`2ý‡Æ©ÊǹFY0«y” ³s(f躉 ûDCüN#Ê¡º‘ü¯[þÅE³Âƒ;Ò;Üü'–‰~aAÓ}Ͷ-*yí¾ï¶“"¥Á{þžT¹ÔNö0ò¢Öìܧs–9Êâ–µcžNÂ4mŽG» À‚¤ÓÆè”à9ÔÈžÝj9=î©[á‰.ºèÏL1ˆòœswÎ*žò @ª(â’Ý„pÒU‚¤à•á—KÈsÎj‡"¢oP›5útÏ,/Âp|Œçã].!Q:¯ô£ßs¼Àï‚ñ¦üÛXFå ¯”]y6Ù0gï´‰óï!ñ縎ѥvN­ã7¨W2þ8¹¥ (™SÓíò7|Š6ÅTUB[ܪx±|áûÏ1š¢)?2§xÌãYåQ˜éã †|3wÐYµZQsѶ‹ yÅìŸÿ´¶¶w_* be4ÌåELþ¤oÂ9½LòO¥‹)žæ*á‚áÜwþÇVžW>W8D ö .<«usc ßIYQÞªÊ"@I6_;|ñ?;o^¡åD2%ð‚f£{·ï³!0 ¹(fµš°"øùKˆïÂÅÿû]ôƒk!ÁÔ""aòtO†Îs"§ä§¼¡†‚'<7wöv©åŽëK;qæØ^›tÌ¥E1 Ù i Ï€Ç"[ Ï7gšæ›…ûvqÎb‰]ù×ÈJò®¡‚l€ã«eù°|+@­Ýñðs" IËéSr3"Ëa¯Ðkä“ív¸ÿˆ?LÕê•<`·¬ñIâîïËuŒŽl³;`/¶ß·£kn1FÉn¬/4ŒÊÂ04Òå•×Ó¦(( ¼¿ÁˆZ‰ ÍUñ¨:Gôrˆ:•ó[Ä#qDŠï :Ê u›§ \"äƒ0xA´ÒîÍSu­å¢pƤÖt®ôíÍÇùw˜-³¿D¼äù€lx/æÉ± €=':õ@ÝóÕ%vV[[Xx΂ gl¢[ÚgŠÿ|´†Ð_ Ë`ÐÑ:ûg¼‡ºÑ\sq¸¿{ÄÞ/^]·ì~[n?–ß=[zôÍîàûæ»ß7ß/Ö–—Åw(ÌÄ«ê2|ˆÄa³AŸÕϼ:ƒÿ>äé!õˆ‹d,'¬Êoü+‘#MÑRà¤#R“¾SjRpÅÚn@úÁ„ÞÌç9Ÿ„êààöú£ ¼ÈåÔi'ëËØ=™.D® øv"Ø<Çí¼ïtDNŽVöUß7àˆÌM6yœµ:÷o_l¡Ú‚ภÃmBŽo-“…âÖðàr†˜‚Yó Ã^õ.È6¿Û½æ£±¹5–ƒ-óùˆÅ%û-œÿ¦'ŽjÑRHöÔsüžšxM3“9&Ã:mÖþ|Ügs%'÷YesË æQ)§¼M2ÅàMW¡_‰gðâd‡ ù:V|)’Œ~É›N 3d=fY eX–)„Ÿ|e´XžªÍI f½«2멳8o7ý!0]!RG¹æ¿”ë†"øAãJõ9ªϹü`ãžEŸ-/AŽ=K8‹0A(›/þáì&áá™ääÈ_§ ³§œ@¨ïv•ÀaöÝËt Xàö~PM’ëRƒí×)RÒQéèd6‡¬ÉP &wÁ ;†#ûsx²¼eßE»/f“ÿ†ÈÐŒLF¶ü>Š¢PH=(¡¥?D‘j`8ÐæÛoÀÚ ®Ëÿ´Y›ç®1áúE‹F u£Íš^Ú‹JGÞ ­!´zεùùïåjÍ}ú¼°À+7™%ªŠj^íÓ‡ØÖÎf±0U’ŒïdºÜ¤yŒ\ttx±ûjï Š“q­õ`D{†\jFu¨áókp>)èOSØ›¦¬}ŽwýD|ëGõ¬ç~õ#zûdÌxгOÜÓ‡Sž‹'xRÀçºø|š,P¿ÜòfÏ¢BJ=$ê†NœuƒOPˆ‡‹¯C®¤ÍëzNKÁñ‰¡gáØmÍlÑM‹“P,aJ~§ŒL»‚–ÿ¤¹~ú‰,ü0îÁ5´€ßA&~s°÷vQîôÅáõš‚¶ü;>ß¾ˆ“­ -ÎØ1~r¬Maª˜Ü:¡Ž x@=+QLˆ? cÅuáÒÚ#ƒëf¾³qtºzÂèôè%KG7)Ý¿t뿞# }n†ØA¨_>9¢-‘ 1ù:‘g9^$-Ѳ &P ¥¶uá÷­>¥åج’gNM›VS8”j%Nþ^moGd/ t-ý%f¶²vßîn[GÇ»/÷Þ²íÃ×G{û»ÇÜSH]€*ˆÈN EvBA¥§ÇPîsÔËôÈ=Ù`Š4$r)›Þ釔ɖ¸CLÎ=;ÚÛV™‘žÛ¢p0!Â9¡ZKãÅ8cu•YJr+J)ÏWBæàBL ²º¹YÿhèMñ./€:ô0²W´V²0:ýºu|°wðê3purC†.Z×zñF¶öüóh»¡,DŸÐ¼ŒºwKž²uSË–ëAÆP“¢Æó•d’ó¥#~ö|%Ë–:'5q }gÑqõ;¡6 |E-àX¸J—ß꼇Ǘ§è0C²Ç•·¦rBŒƒrI¶OCOl8äøHÿ™ZHÙAÉ 3ïY.2o‰ |Æ'Ž ñ¶Kc‚ @LˆV8"ŒIžñr0A-4Lˆ ¡ :&T82lѽÑG l ³ƒäãê°CúN‡.i\z•=ÌK|ãöÖñî ^¯ð¨…oNv­_vOö¬½ƒ—‡Öéñ›ÝÍå^níŸìnÖçÂé.Ë…Í.dŒT—KŠŒôàÐzs°³ûVv'k¤Z¹"#MN©vîHuºÈH_ï½>zs¼kî¾=Í©V®ÈH“€SGj€Í¯÷w†tï(q5À¶Ü]»u‹Jp]w@*}‘þ‘0—Ts2‰;R¦ÀéÙxMÎB¥·ßWüj2JÏŒ±BZJG0(úÅlãÅ$!è-ÀˆS8 „&âP½E*s‚rÉ6ìIxOσj¢K Ñcp Ʀø ;Ãéc“‹ øô¦QQðM€dSŠè³ßo;}nd TöêP™“Ê>º¡öœ’ ³záð`Õ@gh.}¯Âó¹Ö;ÀPÕy‹¼LÈc÷ýOx%ÕvÛìÒå1x®/€ÈÛ×ÈÔ‡»K1®|?pŠ0s¡¼xáûô=mšv—ñLâ”^ñJrKh](f‹ßnÒê£Pkйő½]þêíÞÒºÈ#–ßœ¨§-ˆ3amM3 6ÐûÄNÅm!zgñsrºuº·[FîÒ¬2‰š ïÎ|˜ÑΤ©NNf˜é‚‘ È|ÅõèÔbŸ\ŠÔBX8ô†ÀŸÈÅñ”³ ÃÈpÄ¡é÷˜Óí nU@2ÒìÄ—+e𛕑–1 l˜Ø£º¼pelµƒò.ÍmoV…]UŸ{Ãîfu¥*Š£–,°Úç—˜Ê\«½Ž¥¼ñ/. oüÞ ¾1CÃ7qhQÿzdóŠWô{³êù¼@eC"÷"œ $.;»ÛËÛðÛþcù§#–%"fWÔ˜Òxß?¡s'»;ªHü* ÃÓ€3h²mn_6l®™4îÀB<0‹ßC‘Nk½°³%/íÜV©Tf³È\w{–sÓÛ¤¸c“ˆ:V™sñ³,˜éíÊö›ã}øöÒ:=üy÷@>èFP8‚ŒÊâqÏSÑß<&[ߥ'n°«±0dgbiÅܲX·Ò ãâcè¡æ¢^á{ÿ/./×s«¾«RQøX^¾¬'“Cj /F‡ÖRì m²*Ÿ==S€¶€|U•èh¦Àh®)ì™±JC­a¿ƒ÷þhfÁúZ¼/"`”S)¥˜ Ã/ß+¯dk“›pÒ›¥(óF¤7›qŒÍˆ3xŸ6$ö§à¦¤¢é“^Ç7§rUKK“s‹‰H…fvqš@YE_i5 5©k\Ä#:ÛyH…͂ƭm±F:?Õ¸dËø» ×àï“x1b‡à]ü91CPW}2VCÖ8°‡öÀ>¿ëñ¢ôájü9}H Ã•-=I^Â~Áó•)ôwlîŒ'(Á•‰ ÜØÔ‚ŸŽ¬V+y ðÇGÀˆGMß}¡ÿԙğ—3S~þ®$Ùç³pDZ~ó6ƒŒ)”ÛL¸ƒ4ºýèöc Ûn?ºý8…nÃ{#Ý~ü…Ðí½¯ËPm*þ@³§F³a~·-+I´Åóª="Õæów_È6ïMº- š ·xY’r‹™¸ Ò MË©x Þþ>5¯i¿Yãχïn×ýÓ)V^–Þ\)Y~µdùµ’埔,¿^²üÓyÆ|.¦MlBuŒ˜4ƒtG¨7p:¥Q^ááÞ1zpº»oI}Ãqª¿8VG=Vµy¼7ǫ֫"Ǭ^!å¸Õ •=võ™šõñK·‰µ¬UHÐDIF·2qòâùɉäÜÃW±iÍ$E¼L’’bÂ뙈Hœã¦-ŽÕ$ãÂz'_j wºÆ»ß$ ë\bšÞ[KInÚ¯{;‡¿ž¤Žnùß{lùß.[þ>ÿ„ÏïÀß6|‡Ï?áóßßÁ'ü=¼Å¿05í7>^–)û =#KU躞۵;¥ê ‘‹[²Îfð)S!pº¶‡&1ÁÀéõ€¾–ª ;(ŸÓNA8Z+ã:V(“i(âàò!¼]¿«ðw þ>¿°Ø‡—ø·ÿ`+n#+—S± T#Oª/@6iulX Â’ K¦ÆÐüš¸ùâ-Qx_øÑ ‚,iæäÛ’Ò†œ»Ðòmïo¼9-±Ÿœþæ RÒv{Â)áƒòþÊÝä Jj²¼ÌÑfMXªUµpÇÏ.¼ö!)ø|˜‡™ëËW.«.VÙêÊ {,Ÿuü…$–ÖQšŽ½Æåeû¼XÁ``Ÿ%Š>.V³D+yS¼hûÚî_4ÖŠþÔ-w)WÔš"ȱ¨îÒ¢b"Ç7¦ô+¡X¤âÇ÷ÔŽo˜_ãíœxþpxxxóù»/g7ïM£[4ŸÜâeɃ[ÌDšA]tÎRi„?Ëãz(¥íËV+ãpÇ·ÑÑÎËv|릂Y‡:oF=Ò9¼‡ýË;ÐUQÑëD<̹ r¿î„®Ø„XʼñÍDغôò8[÷Ø(E2lÜÚÔ.OO†ÞQIU½¨ñÀ§MíX8ys@2Jòlß<#rïË)!ûS਋šÏ‹ðuÉC#œ‘»¸[ Ÿrà§Æ ý]ÅÖðŸ'øÏ:þ“éâ&…²dýÔõnËu^þ¤O¤Ÿîüf”½å‹‚>"Ax_è¹èNr.Kš©¹|[’˜ËÙ¸ ZŽmgPòó¯ÌZfl"ý«=€ŸeÈ´¬ñ@¨§F¨Ý:Ý>4Gë‹^=ë‰u8…÷…\‡*@°£²f’½/I´£Y™Ù~ “$„Å@+ÄóB1"¡àów_¨ïM! šéƒxY:.˜‹ü¸@œŽäBméêc]eš?…33ÈØšÎtò‘ÄàòB¥Œ§Ü`RzŸÒõYÅŽá9™TÉSÑ#©ꆴmõÇo×*‹‹‹øØÈ¾ó;½Âè0a» Õw{Ööžô qažÉ~—rô1ûi.¦~C0!gzë)]%È[âù,ÝO”ÿ ·ÑtÁÓ?†nŸ2êQ¥Lc~Ÿà´Ý€~^:žÓç ùŒbQëKL„ïz"_`Ÿ]óÍhhWöÀAOS8 0«X@ëÁ,cš=× sŠ$¬CÌʼn©ë8ý¡Ú» ]»ÁöùÊéôh8­€ 0Ñ&ߣ$wÐ69ìõüþkõÃÉ!P§e{0T€ÚÂìf.œ*æTÚ êtü^úNpº6OqØq@™«Á ÷ly¹åûæ•}sÓ œe,ѵ½e,—9¤eb‚”_‚?†Žó§3¿Àþ‚GVðÇŸGE!<á©CO]¯7lžÕj«XfŠžüpVÁ|Ö¢BÏs’¤^­“.­ÍZ5A ù/–¨E›°í{ŽBmº®Tç}g0ì{l¥ò9¼ÎÎØWß˜ï¾æâd;¶¹?uh•VŒGUpcœYÐ" å±yT…2a¶™¾¿h]]Z´#`fùÖ‰»Ëï·Wiµ’á2# è¬BIñ˜±ÆžÈHÜZD`ù‡rØÓªcÊvü"ÖPóy¨éƒ ÀÚS˜@…mù½±·Ì.OÌÉ€sù0*$–i[N°^Y¼Q”а¸Ì‰ì¡K7ñ¥3›»x¢\´|’³k9.\€ŒW_¼¨„iWâÛ¨ªòL{ÂÛ ¬‘e™çä‘\,$§ÿQÛ«E?X㇞¦pÞ\ñÄRÐ$D’¨ÊÚ”Õnj;Á ½Z-^Üóm/p¯sí D5d-àˆøe*uƒKëÂÀ¹3ðý `\KðNä[üž9#DÝG˜‘L "¯ÊHýguddxü+[_[ûni}íéÓÌþQò€ÜÞé»0L–ÜøcpÕwl%îdþŸlxYRp¥ˆ+Ø'{ÐJüÖ"[/k+l^zÃï(>þBƒ¸vØêúÊÒêúwK«O—Ö66&4Á×m¶öÝK?|¿ À7~(0K¡¼7鱿=Ú®ð2¡F&K“î¯f½>qàâ~Òpù•Ф¡jzŽ)ŸÞ…\ÿ)ùu—$_Du±ã›H‡µ-¹š¿“¯$ƒ¡q[ãÝ^Ù­–ÓÃlÜ~×açvඤX^ð2+€v·eäÂ4Šéc4±Ü ?Å «däá|yÄxK† Xçz2퉨–+®7@AßcóŸ|·½Pù+ Qƒ¬óªD*!ɺϡ<“‚ís”lSμóYJçøøˆßçéèSËHÁ„£_>ŽÆN›8õåV«qa»gl¹®ëjeI­ªª×í;)Ê]œIÿü?0™&-o\üлl’@¦¼z†õea~L[¾b ˜½„†ET–[ÏYÈ1—òLØð7|¾”5²U¸Ð7µVß16ŒaNꛃys1”PT1qÀ›xÏN?ÒÓ•¡t~öÓ»nןŵ¿BzáµçŸ+ñ;³¿%ë=Þo`.ûv—]_ᦧ1°p •Ç \ýÛìø—uRtq™ÚÎ9ЮÓ ­ÜdîÐä¶V¯§;t·Î¢ýBÚöO`s;îyóêÇð¥¸V+°ÙV¢ÍæÜ¸ƒyw¡ø^ÃyœõVã e±Í´uÄÀVÄËO ìÁ0`8Íükµà\lŠØwšáj-²Ë®ï5Q½~N†-ˆ{3“üž;ÐÉpUH|³Ø‚áÊMÃt©$ùyù`·Aê|¦²1F$e;hãùçðâqô9ɹa* õ׭ヽƒW†õ¼ivÆŠD1Τgq§žÆ1V+fežâ 7úýA¾¶/[[AódR fhpÜ£e}²û@Oún¯ç´9´¤>y[W&«µp#·#'ë®Q]íªVÑEGS'ÔÑ›âk,º¢±)E-–Ç €NÔ“>RüÄðk±'Lt0q×›ñX5,oèÊ͹X©‡YOÌz„Îyó.%<ãÞµí ,žÈx?1‰™_kÓ8Mj61HÎi¨i6U•¢¥ÎB|±&9 üÞÜYH@)1 Qe׈Æ$¦fìHSyÖ”¶Ú •:+—Þ)ð2@šÃ2j8ôúýƃ~ãA¿ñ ßxÐoÜ¥~c:ÚÉè6ŒœYAu†R× Á˜†þbòÚ‹œñ'®£(¢Ÿ(¤øÕøòÊ÷ü¾%l€SAÓ 'Œ"žD»Ñ‚a×±“B[ÍÜÒ e Ùü¶4^f]÷òj Í” JG¡é.„•P ïÚƒÖ•¦OÈÕÿ˜Ô ”~uƒÚ“Tu}T J‡¨vªV9¯pÔa¸«’WÒ|ÅS3"¯A'èkj)…ÚGK)m’Ó ‘C-Æ´Ò1;X1óÅ©Môˆ‡R€‹/)ÊŠB“0;5ïÐüAÍû0ëc«y³w¤a§OFÅÃcêzÓfU§p`‹­döÄ$iÔ¤çe\õo¤R3*3SB\N œ¡ÖÁ¹ªà¢Ê`ex&o*á•ðƒJøA%ü ~P ?˜¼Ý#µð—cØ6Õðc¾vÿÝYc²ŽŒ‘ÆÉg8€Ä ÜVµHá_)µö¯@úv± =è¸ÓoØ}$y_¯áÓi ¬ë]Å@WvÛ¿.VÖõpÀfÇi7 §Nß+ØP× 0äG£í´:6ÝQ²&¹Øn{NÁz°U;>ÔÊոèøö áü1´;…›è]q[Wv'Ó½ôˆvvß)`èÁé^¸-]¥áù°0õE{Iì@£cŸñÄ^~´¥§SY¸†}h‡«ƒîÛÅÀ¶4ìÌQás/ûÆ:îö c´ß8^cc½1ðOÖÔZæë=ó†Ý*k\Y]YMnøì%¥¥´¢ñU¾–qt/M‘ : ‹à:Œó¤Z°—©Îç¥{™A ˜è]ÆçDKùde¥ÔRš¨·25iýÏ#ðc#äz9„,|JL`òG˜þü½d<¦bKQ`]2gumå»r³Zà0¼ó™wsOzA~xZnAÒŽûñ;²Q®#)\ÄøˆQŠqãÏÍw¥)“‰·C©{b"S8Ùž>)7ue¸¸ñ;WòŒ)ÈŽÛ¯õ’'¸œ%ŠÒ¤kóÉd{³V®7fxün”Ä$D—FÇíºD$¿Ó†Åºí8ê©P”p…GÔë:¸î±µÛÜ6ÎýömQP­Ž~îô鸇òá[i¨{áÆxÿL(¾÷ ŠcðG.ApRª<üÔ±';ûOó(NVÄÖ_÷@DÉäã3©©äQ”µü™¬*~kGgð¨ L¬xí!`±;À¨x޾"8äÅÐkÅy3µÉ¥j@Õ|àwȦ4Ä\Wˈñ’ej÷]¿ít0¸tË k“sHeoïÔv?9­#½R˜ÞI$½1€1¹ìÙÈÑ7 ­ìŰÓA@e{˜’o6,ɦ\ûlumå‡ÂÃÌ:8~*Ú±ô¨…ÓèžÓÕ’U ¨{³4F"R½Jͳg$7ââ´&&ywZ¨£Ñ Eo¤ÃOfQ5‚£ÈCǓ֓֓֓֓֓֓և(ŽQïkÇô„KªÂ7:QRÌe³u;1X†· x†J«OWœ ó‡ ÝFûÖ³»Ü¸‰F9W™H²bÌi`n2þ„ça£«¨´!&*L™ƒÃ±å${1)Þ{òû9ÁÈ)UÒôu)S«çCUδ‰g•—×/Ù­l$óœKž0@•5³û}û¶4¦LYqÛs…"s¡s»m ÞaÃþÅ<>Y`››LüÜ^`ÿbUö ÿyÿ<Ý k»ÝÛç_Ž›å¿Íåe /¹X× (¼GYdÏ5 ”ŸK "¶¿o{mDuæ-<7?–º0E 9啕ëª?~ì=O³IEŸó47ïÖÞ«Ýù° ¼KïVÞG½˜ÿÏB\=ðŸ¯bf!Ê—¶ Ç݈B°+·ÍÓ²ž÷íþ-£‹HÏî°à¶{îwŠžÃ+æ%…gYÛ²ìÁ ïžŽe±ùyËúäî¹Ûq·øà¬ tÂ8«.,,T+IE}ã"ª± }o;áUÚD(¡/„F?æí0Šé$”¯mo³Fƒò7Ÿœþ¹Ó²öã·«ìovÙwzLí*û‘EùÓæUãÍQ‰y*8WÉÀCáü™ ar§Ñ ÃL~ÓÝ S¤¦ì‰š¨’,©s}<õ²T`üO¯E.æ«n«¥ÎÃØØ‡ê¤”Ï“DÈR(™ƒ”ÓTAç«r·Dü2[ ¶†Ç”ýÇ¿ý–#?!JÝtÚAËï9›jɦë«sÙñÏU‹{mÎCpñ /@ô1ŠËÏh‡›!˜4ðÙû²ø5Ÿ!Wò%0ÆäËå°E’œæù÷óáÅÅBÄI¦ˆ”p…*ÎëïTæßDPF³¢œ^ês&Éà"ä»Õ÷ñÞöaqx¿=WVêbßÀ;“°¹ØŸëZïÂüñÚ6mÚ-õˆ¤Äo²ÂÝc0RøœHάj0ÁÊf§’T@»(ȯœu/×j5‚~K¿”¸›R:µ;<#Ì¢4+£‡i\ ˜ùÞ$E12Á ¨V”-9iÁK†å„ *YçC·Ón»ýͽëö•»G7Êx¡+ÄìnÂB™÷ 75î#lq´¸_Åž‰ëU–Ypôð·áÍ€ÓÀË@µÍÜ‹…üêÑ‚iÊnÚÄ lô.01jÁ)L }b’ÕG›˜Z²0s† °EOC)¤ü>Çé<{s²kmïžÔ ¢T¾@MRÌÈÈí!n¡DFD‚lóQÆÁ‚ tk¼s=©€}Y¤ýHsqûÍñþÎî‹7¯êüž,ŠãdÖÅm¼¥¡a†RNRíZ‡ÆÇÐuº>ð[ƒ¾Íß¶ló^p–4/‘FQ0 ÷ ,äHˆöý¦I Uå³)˜‹a¹HØëìí3N ȈsƒV˜*}‚ Pö2"ìÕ1.&æ”ÆP¥ƒ’®¿x³·¿=´ö÷^ -a«Ð#E#ò#¶ÆNHqX,d¢Á‘!­‡©ûGmˆ¡þk©¶r›hè&4—†Âá¬Óã7»›Ú“—[û'»›õ¹º46ŽÆ7ÉòÜZmDƒ5J‡àzmÿ:hfÙ?hå´MŒ:û¿ìs X–(g]=~ö™]Ø0ÅX\…>ß²¡ö‚еE:ÁÉÜ‘ ÈxxªÊœ{A?)Ì„µ¿»u`mìX¯áKE"¤ñ··ž ïŸÂY0ß@A;Lȧó–µýÛ+jY HŔǻ¯¶·áix ü´õËnèõŠÀŽ`Åeµ&tEÕrcÛ¤•Þ\[„š¿ì?—˜ÚÙ¼¬&cï´’”üflÃPžÊ›»”¤–©ÅBÛº¸O+'îðaJ*D\•„…ˆâXl¥WåÒ©kÀO@üÖiT«©ë+° Ï…k6°û—ΛyÜŠìW>xæ{NÅ(& ð’r¶G&'ZÖã"šS¯$z ¸{E[qj¶·:)y '寰üqZ"žoïŠ7t…;¾}²mmXÀ{Óè)a’m¬/,¨×Y‰Y}£>ŒuJ¬¥ºØÍ‰“£´EI’£¬å›È•ž¹cP%½_)4)YHòŸŠîÝ\4Ætì"›u°uº§É_&X‘tœ+É€Â"£oiƒ#2ú¶ÁÉèh„Kð(ßúX„—áåòy,÷õó2ÚC>5Ó`pN·.Íàüz²µÝqloØ›_˜>“Ã×»“#KÞ#&‡w)—ɉŠe39²ÜˆLŽXíÉó(Ê^+º×׊nöµÿÂݾ6‘ížÎ™ ÁÚ¢ÎÞÑÑñá页{r4R°Vœ¬ÝCb°V¬%kcÒƒµé„`mÐê¹½|‚Ì#¢à+APž†S6K2q²vº}´w4™°Ž~>Ý;xy8m*¢H>•PŠÞ*ö)‡Jh岨„Rp$*­y•ˆ97G!óv¸h‹ÿœn®Ü¬`@ÈJX{q¡’ÇÈå÷Üu­ z6ªñÛåÞƒ¾{ ùµ CøC·Ÿw%“_?v3ZÝ@K–‘#šKÒ l\õ†7¤¨½=<Ú=°Nßoïr†öˆý¸É`qQ£=G—ïE¡’ÅâÁÎîNQ–4ÏgAS0 ühá†Ì“^jíï½@ÄÆÖè`©‰(.ÊS cG´"µ÷<«È™!µÐNñz«^:ƒ+?œ£¾¿ùîÂR–þª’P| iÊ:¨‰°¼Ú=ýéðäôÅo[¯w7««’RÌnh­¢)V£ãÖÃ\) Á)…×úGaE8Å¢ÉG˜dƒL(FVáØF]Xø«Z™ ã"#Ü´za€+<=«nWå&"+{}bPÎOR ±=“Eã'{)IÍ“½ ˜¤NaZ1ÏŸž« _(óŽÃG’¤–•(«oË”âEwff,M4â–«p c,.I67løcØL¤lbä€F—Þü¼^Öþç%fFxsÿÝTÀ4åfB`,ù¥ÒÓ`2ÈAZñtŠ`®1"QÐɀ؜àß2t`T€“ûð¢6챓`àA)º )Ƴwo- ‚ÛËrrøîi±¥§-HÎü„|l§áî”ÉN)h_¦ØºMÑO·ì^(x[ž-2íÁÒ˜ô5Ä5+íbc±Ñ…­qýd­å,ª÷ÑL"·ø©R%øpfMü¡'Ä k†áŠî<©ÚPÓØ-®Y²Á`·X© CJÛã TêF»|‚üÖ¹’<ŽZ×àx’ †n[3%=©Ö’Ph§©O‰ª˜jð ¼eí#;ÎNl«×××MÒîc\v'ã`Z±(óéðô¢>jû4"³&Óªamy’=‰mŽO^»ž{Þ”ÚâJ½i½‚‡ ¸¢ ‘½,€ qË<Çi³zÎ`ùÒñ–á³á°Ø•ÓGÊ €R#h«É"…™—éí§¯Ÿ¹O\ˤ¶€³í¥ñ+M%â[2êÍ2? s …ô(:)/[!åÍPåý·«¢¼bz(ï«QBy%4P^9õ“7%Ý“§)ž mõPÀKÆvÚ^}| 'c ¸Nܪó zàHÈÜPm}töû<'¨ÝëulFdÜ£+ä&nâC[´²S=«§Ôƶûoi5¯ª©–*§[ǰ,ÖትwôÓáÁ.Æ ^ÝOË@†ížÞyI¢=}WQI œœ£-¬4€YÀŒácôè œþ'·å$wbbµó¤*c÷[WV¬ôÈÇ Ý ˜ñƒeƇHlHÙLj©pÊA‚ó ½„)Ç#»^Ǻ~çÓsÖöGÒ+ñbªJ ž@q´ìü/ëÕM¢D£#j+& á3FTÛ8×j\«ç è g“:Îx·Ê£Þyß±?b'Ú0m£`¯~j§ 6<¶Ó]ã”sìš»’r]-0'³pES©ö‘zÁ©èùÊdÇ^“{–ЬhA(a^F2‰&?ãm aa (_÷Iºëf{±Sù wøÑ±Lû ³ µ®T›ªä¹Ä<p_„£Ia޵N0è£â¾Õíé¦:Êó;µfŒóÓ'‚ÌE¾/Ô7«gˆò9&ûëø5Žñ’Ùùôk^\¥¬«^™OqN‰0¯^÷ʉ _-&½vé+䨹(Ácüê7Ñ^½Ž2„|yùòòå!äË$Ý©"'Wò¨"¶ÄîÅü ^ÅH€+K ÿ_Ð³Õ r±:9»â<ëR…Ý-ÝêiaD„9¹Å1’Y ¶‰-þ¶!pn¡2¢³ÜKwN¢8EJ)¢˜8',L’5¢ü¤ÚfÖ/®47‰·‘UÈ&\4³8r+ikcð[7–Rúb@‰°hÉP©óLŒsOX×õÜî°+-¥Ùê Cã {àôóÌu²kÏÜÀÕdÓóc9›d«,ñ_ý²{|²wx€ –u¼û¿oöŽwwØ?a”øG5¹PÆþEÙÿpÞÃõku%É€ÝÇ çYì®Ý2âwsu­è)â~ïb'^omã^xî†Õku ΂é4€®®Ñ.Ò‘Rl_¥µí3>¥ú~› †AÛ F÷eï¸o¢-‡´S¿â$…oKš‡D e¢bcÜØÊ Ò·ëÀö!gèÛ`YüD r”>wäÝH»@DêâÀr´Xs´KÝ …(à n{NL?M}*Ÿ p~>ô‡ÀºÀ|ë¯lÂbµé[0&ùcG’´êËò·²&׋1•Ø“l5€,¡Ý¤&‹ÀvˆB2¬ÔN÷^£wú“uòÛ‰…¿’FjdBA" ·ÿäà‘kWp@EjþQiû|þtgü‰*m~ˆº õµÂ…ýMs7è[ÁÕ‡˜U˜(Ýõ½Ë¾ÓQíÃT4ãa›âe(òŠ Ød.æ|²;|êΪ7gµXÅ3ºzV¼¬ Úª(ƒ$!Ú8¸V¯÷AQ¬à$“48:«áƒ„å{n‹µ:¨¾ÄT’¹öÓ)µ¦ÃPD÷Ò„m¿ížhNÉ:M O|½bìO©‡ '±Ú@‹B縻t¢…D­†¤fP-è9-6¤R„—Ôfz~{µî¯Oö¶—Ø·ƒ`á à>ÈÀBÊ´™ì¶'£È¥Fô>iMšB0Ì£U—RЦVL„>àýã™ë>Õ£ÑÛËVçcR9*a`Ã7Ö †‡‰”¤ý}ôüÀ½YWt¥êt&À§kJcN¢¹d¶61„İ"ªX QAö?«f˜*í –£‚y´pj1OñkÄ𹦬ö J¨~åvÊFa±m¥ ذ…ÂP6 ð¸*àtf"¦ÖÔ"^”OEGXÈQáÕî)¡cˆìÚMÜBæf¤ šV1ûèI„ô‰´Õ#ƒÌnKÝ Òs–5»¤¶9çvbJ0#'‘4"GˆšC‘ŠÒæò—aÅÈXbŒ ƒ<Í%“‘ÞÔZ}?;'»’¨>žÒ¾G2b è¹€aXç ;tfUC0&…5ˆO"½’ìõWñÁ¶ï²&gpÂz×íú³4‘Z÷Ê]Vèñ~÷úþeßî¢[fºÄ1°p •Ç "-mÇ¿¬ ±«tf`»ÝU §erêš»qºX¬³ ƒ6Œ,FãkfO²™ÔL­à…NîD¿¬vnÜÁüŠv#w¢Ìj ¶ñm†a²f뿆+HgïbìæbSp}Œ•#vù"»¢ÚÄìÏççôa`7‘Í”qÏ»kŽ£œ¥ §™u΄ìf)“¢´iŽÛ™OL‘[—z<†RßgCP½ËV«ˆÞ^-¯^sl ‡% žì¸Á˲k;`—î'Çk*hñ2/ó8pŸñ˜ƒOå˜ãe>ÙÍšVüy¸2a ±´ æ@!8ÌÊtcé‰,Ó"‘Aƒ ¢“¿ÛâFÓÛlœì±m&ÔâÀä)l 5r.}àœn݇KŸˆ]PŸÙýËø³>¦öÖž]t|{9l²×<8]©×<ôr×<)×.^»v¢ÅN†Þá [oÞ095¬í;-m§Õ±¡]§»¸DL(¢ Ä“æä×P®2ËótÂ)~¯—ku­F³¿åv_ï±*t·u…Æ ËmçÓ²7„“ʬ¦DžHŸ{ÞÒ¢~C\`J÷N¶ÙZs¥¹Æ$V&§ô¢ï83™R¹-Æ›RìîÝMèò¹ë-ùs¯ïÞ4ÖarŸbü'œS¯AD«…œ?ÚO€”Æ.ø®5l/p›•Râܳ©)êc‚F…t ï›ë¬Î¾e+7+/_.ÉÖÍÊÚÊœè‚[Ù;Ù?üu÷x¾µÀæëvýs“áwLð«þg])~zøæèHWªþ‹Õ·êì1´? -°gaA 4†öÎ*¡^4¥]·ah 1_ÿ©X?Q,HE‘aÐþ†YZ_QFÀ,Éà½=<ž‡½vuççjå›ù‹ò1˜ÿF<Á Hÿ+œþ#íçæÄîsax=ï𬒓œëȼ/n<²GÙÛF-%$”ˆÿQI]µ[Tä~½µBw‡gn¸¨°A_4.J- Ü›1MÅÈìâƒÇO¢SÍd5:‚zæ`ww' W’úa6"=vº~ÿ6Ÿ‹byô˜ŠÝ#z,ºýuÑc1Éùô8,xoè±èQ=VJåÐã°äˆôx÷õáñoôxlz¬cZ.=Žaðlèqˆ+#Òc3®¤ÐãLëÜ3YS1ÓÕžNÇi Oy¢ÀØS×o :ñ‡=»owã‡è7=²ƒÀékàD:틹5\ÏôtÐêÅ/»êX@OkÒ0Òé“ð}mHñ9ê¸]w U²û={#‹Â˜ÒžnÛƒÄkÌT-¤{*ÇBz&÷¾É:[ÇG[†(?Ù=Öêé“ûc¤mˆ5ˆê»§‰&åª=Ø=…99µö´z*æE Vî­øˆ·¶'®Ø5¿IϾyqÕÓ+¦±h-‹^ßÙ½E–;šZ1ð¦tá†uÝ^ÀZ-8·þô0€»‘þ€ùøÃ»ä°BÀ^àa? £Wv?pïÖÞ?ç*› |ÆZ`Ç_äÓÎ>?çÉë€Õæj¼1 ž¢rH‹â£×êµZÏå»ÅÅ^¯%àìn³“_Ž×In‚„*,z>öú/üçf‰Ý>§~{à¶ô"¼å?¾ƒXYZ‘#ØÚ{ËÞî³m¶Ú\A-üŠÞ§v{ƒH%ß©¸õ‡,žú64€ÁŠ9ø·‹¼5¼ ëû]À4Ÿ.Tå© ˜gÃi €ò/ÎM˜=rƒ¼¾òáø…g=Œ×çò¦l×ö„É¥RžOm¸>lñù8~$Tqh4ÇðìÛKTÜ^²±ËÆ%{Æ8ËÿéèÍ[öŒW›a SMüñãp™`}ª\¡¡ÅÅ=mÌÖx‰Uý‹ðdû=i®}Z/†’37Ï£‹öH4…x¹‚Ú]^n~<Óû´ÀÝ Ñpðø1éeCMl° ðvŒXfÞe¿ëPjèØGšÄvXö^–ªÝ¹ ü€ês >4 S¹ZøæÝ{D¼µ§Klõ»ÏÏ¥©-ån„^øˆ—ßÞ¼[yÏß=~ ôþ@ã'Û€¥LoW›ÍFƒ„<ØaûÜÿ$×3ÚèJ»noÐSßX/šX~­ùì}¢/ã ì[´¬Bõc³U]bHÏÙZsí»glõéÊFceí)›?Y`‡=§î„Ýa@*6ëúpf¹5¼'Ö0ƒØÔt ðŸçêhìÞ»'ïv³s%aéÅsœ^xÌÎ?þ¾?Õ÷fÿôxïmãÉûå P²ùcçûa}Š#«DΰI¾n« :}’%~Ó `…éJIQó&=”ШÇâ¬J^Ëwë(z‘"Å*oMŠxñšEáîM:x^fyqq٤׹LºT£³»:Ö ŒÌޝ­ðYª÷îÅ«U2j/ 7ñúlèî¥ç´Ù4ÖéÁøÁøÁxÎÀå‚5ƒwðl½ƒSg²Ì <¯NM D¥,Qêž…`üz33eú£jt²TÚ:þjfýƒ 9ÀA-ñìÑó!¾Øœ`ð—0ñ’¶WÒïQâåîüEïPZz¦D!S\Êx©Q‚Ržœ¿Ù>%Üúek?30e6ÇÚC‚á?:ÓŠO,ñ¸ ߪԋ³®És–ç29ÌoH䕇½¸&:êN9=—¥=" ‚ÞÇ<ü‰%dç&ºì³Yr5sÖa³Ö82»lÂS¬þƒ^Qb9Ž@1³’k…'áJäÖµF9ñ¸ ‹ìŒÔNEsãyˆE³ÏCA‰‡ŽàYÒ ¦xñ©Œt2d&f×R`sî.ج{h×,«ÖâtrÊ2ëø<”œ2!Áæ&οˆì‚)0Ù÷l­.×Kf'¤ …^‹•׸‚X‚°B²Wæ`Ýé ’už“ðR34®P#9‘ú‘4èöBò·YM;«Zçê1(gµ X$³T)._¤²€y­ È‹YSë…¡ñ¦Â=ÕÔ^èÝ“§OáJœK&äh@gÔî¿ã86¯×¤àºñê´½~.ÊT3áŸÌ½¸!§ÓLe”%7»·”ŽŠ¬'R•àÆÿÿdžæ¹ôšª$omdhƒ°´E¥G¾µ‰"4Ä ÆòÌ(‚{UÓ@UU…•ö&M+eno©‡ý5íì"Ú9À7B dcóÕÕæZóIs½:Ñ6»hMKÙ,6q­Ûh×e©3%‡¡\(:ˆ%Q4>ùqâŒä¶ÂH eŠˆKßëØ-b+Õ<‘±\Ï¢Rà~."Åi#ÈŒ#cX³<Þz•æX1^ÀÂélw” ׂ.{²^5vËŸ£â®¨ y¢bм¨óÉÞ«ƒ­}íò\uÌËs‘¾´ìßu[IGiíŽz¢IíÄÄäÛf뀋ÚhC“ÖÖéáë½íTKí˜u‚¡1Õ:!º‚9‘ £|Ø>,ê­4V Î>ù{àvœlç•€ ™Š&Ÿ‘§Èò椰¡ -²ÓúIëUΟ-ñ˜Ná ¦ôÝ’#2x›Z‹ì~Œ9®,_5—PÁgô)„°À–¶~9Üß:ÝÛß5:ž©|jT~× \#2è_ˆc€]Ù^»ƒªÍô]š]1ͨPÒ o4OäÅC÷¶aS‹q/΋ÓÅýÂ|’|urᔹ"ß'-üú»v—”¾¤XÐÅJp‡·üãüx÷ör‚†¦g­JÁ8Q Æj0º…Vßi}ÊÑsa‘©d4ÐîLGˆÊã|pA…aQÉÉð7Óà*¤0=žE~t½½Q,¡Ëp,z¢tµm“]EùýÍí#èï2 pI*wP`÷®ó¦ÜwXÄBPyëoz ÝüDæœd†YÎÌuMÁ–¦¡±Â¬Î7œ^K¯ÇmFy@¨ÀÃ=Ç+èUžp3SÙ†hSÞŒÕc&¤ P:°u¥ßyõL¸¦Ïg¶FÿA³_–ö‡ìÒö/¡ëÑÖ |¿›sÁÐùŽÿSÜZ´§´ºæJtºÔµÄÂïkÊ÷'Ê÷õB¶»á-A´iƒÍ„ o¢Ô;^(÷| ”[gû2·eš-8w`KÑ„Kز$^â&n3¿ÚˆSKeQ”5Q–$äR4Š š2ÇLSh?•¸<‰“À”»“d1<îØÛÚnlomÿ´Û€¿Û?WÆ£³Yw)½¾‰¹ø™,nTäYÀ8ØøMŠâƒF÷úÎ'kïåÉf þyÎð[}©.J`´e®òú3ö¿¡l­å³Eüÿ²þA€ ÐZKö•{éh ‰˜Û¿9´¶Ž_­²Z)Go­ò«­\ù «=¹ò:«­Vì_XíiìÎj®°§BJø¨)éˆv:ÜŽ!®Äqð %ËEŒ#î 04çÖ`Rÿ"õc°ð’?{þ¿2éUÑ|Qzìû¬u¼Í»Óð½:;@m(¤€n‹M\?MÕP‰2z r]¬[R_ «MLg –ÓÄk?5yʪ‚!R8ôd#üd ¼…Ðr|‘š>ÕþÒaʘ5¡4 !ÆÓ‚|}ß´!jŸ²5"q­HDEpÒ„'pM£+KLû½¶”B×6„t"b½<ˆ§1¥t3 p™:šDé]Mr¼Ù:›Dù\ÝMr:®6¨B‰nIEQvùH“Dˆ“Ô&-Q»K²õé)—òŽÛNÇP:†®1la¢>±KúœMA-eTMÕS)ïƒK9ÇòTYZÑtuÖ;pì~ç–ul8:»®78èè]r^’Ô€˜í UE+ Ø•ÓwJ©+tÆT1……Â÷—îtѧñ¹€ÂkôëÖñÁÞÁ«g¬¨§ï2-ofLˆkÏ?›´‚4äq5ƒÊ¼åkµÂxïýÑÍÚZüÝC»xºY{šVyc³¶QV‰X9–R0Š6Q0ŠF1ÀµŠß%´Šü“Ö#¸²üÞ Ø¬5bo¹w§ZFuG_¼Ð¼°?kí9âQãÂTPqÇÖZTN}«jó$lh-éµ1¨©H„;»ÓšŒûw‘ìi9Díô1z’݉´æ+E&-¬KY´c⃠÷R4Û4KÆÓTO ÃØH…±‘c´Mº¦4NÂH{æßlí#ħqŒ Õg?5ôq<ˆˆ)=:ý’•ˆÓ3ÒX{'Ö/‡{;‰+ˆ¹ÊèÃÓ‰ôáéX}ؘH6òû0qòú8Ÿ¼ŽÉ•åñeúeRyf)ëº)©–4ðFEHV¨|÷~ó‡}Š5àtyòÍs‡}v<§/[ ü.1`]Òîœ0Ò[b’ÖÀ÷0SjÞ&ÔäÕܗq%€Œ’—X Š<\Å}EWq¸ _–!.öx–—o¼½»¹xã;r6—n9»¿€œË6,2Ñ‹¶ ñ’Þ½`“ Ê^®Ézæ‹5y>ç?³®Ý$À‰\¹I`1Ó gûÁLw*—S'»;÷ébJíO13ÝhÇiuÍ•èì©…ûn‰…ß×”ïO”ï%Ít£-e,í·lóÛh+å™ßF³À/Mh  ã;[ã[…B*S­Ì´2ÑÑ—¢1ü7ß*„-ëÆB+VÚø¶õÅøÁæßRãã¨Ø•Þg«×µ–2TëTŽ´Y‘¦0Ô­Ò ‰Y5®U.«×*—U‰G•ÓŒlïµ:ܰn9ªð¨-r\ N¯ÚbC3£©¿c­§7lj²2¶"‹V[*r×Ôq•U kH'!%Ì÷_­‡ÉRé)Þè¶á\œ1Ú†?(¡îiŽû×'¯¬ƒCS%G¥M )Ñ .-Ï=¦ÄCvû/^½Åó^!¿½©bÌÄÓ먖žêJ/uçY®Ôçˆ1å¶ÒËŒ’ÖJ]šr‰­fÔʘÐjɬ¾€DV÷>‰UÄì`ìuä«ÕñGb†¢¤èì}àg– 9Ë,aw:þuj‰Ñ®_`‚€0qÞ¸áxœvv@´ÔjÓ¸¦IÉË$‘”׋҉´Lz¤ e~EÉtT>ÃѬï&Roú—) Ïö¶Â؉É\[ÄÜ í`JAQ|_hÕa'±3ÆÚÏ•åk¯—˜ùê[ƒ13Ì?TÛ}u¼{cV§üÇå¶óiÙv:Xp5ΫL'ê^ ]M2AÓ=˜Òx|ðy\¬¨é"tN™óC…ÖRU› WR“îé8<yÏ'ðSIb7=d7°³CvCã$R7F¢Á©lŒa`_:ŒX«2”]«–ØJT]Ž´m7HpoUÄÌêMl@ÓÄ*»•ý´0ÈÐäB$ÞT:ïM¥ h5Æ.)ˆREåëíýÓ].Ȧ;¸˜ð±¼ea\Lk™£bh2˜*ÚY-»ëtò¼”r‰ÕM)—XWC¹‘÷Ê6‚=)-ò¥V›È§ä5Í—ë”þ~ rÄ€;’îdó÷@Æã]™? âu I/µÚ %=u?Œ%Î)ƒ¹Oâ\ÎÏP¨KÃûD»éâmQ/µÚl¼B¤<Ÿ˜é2Üì1<µ 3–禸JHu©ÕF“êä î\¶Óðê®$<³&$ç©ëUBÎK­VN΋ál!i¯@¼½QHò›À~šžügmo½ÞÝ/$Æ0wæ² Ž´ŠYB*ô=Ïi¥^ö¥¼kòV¬ªáí蚬Ôåž©Êý¹Ø‹8‡qoþø8¥#Ò—*#Jl™©d(½3yw`rZaóeîúLUîÑ=_Ñ}2ÞE \‡»–ÓvÁÔeÅ´PXBœ&¾ô3U¹o~qtïN0•ô™åì±?ÖðL¤Ç)í”2·€¦*edE9„;’5<™­\¨bʤnýÄj”¹ñ3U)"Æp/Cö+PÒŒÏrÞ0ÒÒÝáÁÁîvÖÍ^ ×f$ÉéhFò[옸hyƒÎT­wßìœîÄ* =7´Sj¼Ü>8ÝU ~Žgí+ÛdÖ=¶ú¥Þw£_] É(ÿ›ßñ}o~ÇwzòÝÈÔ‘@•‘û ¦uE,oÎõ<¿5ô‡Ä®°,ØAÛ–;"Ü·ëÅi$zeÓ×|4¸ïK f«×ø·"\Ç«ÛUYƒb%ð>Í/<Ç:azgË ÃsÞAö÷ßñç–è:LéG‡u ÁLFÍÜ{õ‚@ÈY*D“w¥Z æ'Æd ,/®V0T˜¡Rcòx:1w¬HAÜiëR·¨6`JÈWT`¨0[=€À¿"<•üZø™#«Öì,„÷i v ÁÝP¡„Ø.:7B»Š3Ùì˜ÀÎW¡„¸n¨P@X×q-]TÏ/gÂÝt1}|Ÿ°Nbeºˆ®QHºQmÁŠøÞyÇo}ÌXÒŠÍI¯ÝÚ•5ü0 D0ôü`}/Û½y‚ŸçŽhá°frj-…[Bõד øx'Lƒ­ƒÃƒû‡Û?—?gÓêÞ»#Wx³cT)%þTâ$~i잾ܡ¦`Q£~tùf}Vk=˜Ù±­´:½ÝSú0O«[ö\×Fw‡G¼™´Íö´Oà×D~eÅJóiu3ÙÎ9É'…öÓ8Ô-e>²ÏwZÍFŸ†Q¨Ui²nŸêmÀÁîé΋Xju<ݾqUúÔÃûÇ#¡Öï;fs½ ?M»ŸUD¬"‚ȤÌ*KiþSëÍÐì/X´znoTs&Žmél¬:Æùûr< gª‚×Z¾3M¼Ò‹É1ž*®—Ñ˧֛¥Íßd6Éxê}mUîZËŸ¹E¦®ìÏÜ&…uþ³@óš‰Ôz36Ô1}$ƒÀ¼#aŒCáîw„ø¦Ög¢ˆ˜ú&)£€H­WFù èŽI,š­Ò!G“R8¨+TFÙZ¯È½ƒ G3®ŠÏØ*ŒIm˜I«/Žww·vvŽ÷^f¨.Lˆ9#•'Mšƒ`Ðî¸ÓUœœîìïÅu¼Ý1À ÷9 (uñ>«”¹œ2>À¶y•Àl7³Æ‰±J0.ñvYí^cöñKPF™TR—Î G#•U‚Y%®ý~N+üLÉ*1ì 'µÄȹ°ŒF+µÚףВׯÊPÕœz_¦7«†?³Ôxi ß•ÂKéÄÄdu'”Pw¥Vû/ÓviKrÇÊ®ÌÍ1m]Wæ)ªêš‚Ut¥Vûõ\…ÏŠ/Ò8çŽö…¡ñIkÂtýQß1Û”ê:ÔI-@Bg0íý8N—òÂ!Y|¿iÕÒUfÉo"j(lù_Ň@É›ž¡sögºwÝ®?KKIžZs‹Ç“Aµx¾¼þÐãýRwÙ·»ìú w…c¨œ8ÅEw/›ÿ²NRVQ¥ Sävô”z8)BïqÇtˆËãé¯IÀš*ƒ6†­ Ñè ÊÏS_/ÚnÌ`@Ó²=`vÁü·‹È!æ¾õ/æéÁÂBT›4m×’¦[{ÖÁ›×»Ç{Û?žœš Ú]·s‹%_ZoNŽv· …pV(›ñ&£´G ±ïn½Ž r<ÓIwuuí»æ ü·Z¥.ËÞk» š}&¯ü÷ßìxSQ3§ºƒùÕ…ç ðäpq#|)âe®FpÜÁQ`agw7‹Mq"ôf¸cÙe×÷šþpÀÎÏéà C p‘yvœ;@pT€[ZeÞ«˜NÃq’ ?}`“ÝøîûxGñÙêJôuµ¹¢|_]³çgÜn/&wìåæ ÆíÐb)ÆŽ~Çî»ÁÚx] óëçZ¢¶–Â=ìõäVç“Ý:&1;·Ê„Ðzb«iZ%мutx²÷ÖÚ¶Nßoï.ñeñ‡ìGX¨••ïW~Ø7èÓ9QA¾=<Ú=ЪÜw++© 4%MÙš.ç€ÑA0t¬ïò±@+<Áõ×I›¶û‰¢ a‰ŽJf,GТ•1É*â•ÉL$èW6Ï ˆ˜ø(Ÿƒ;å iÁSKtôé¬BËG:­ÓŸŽw·vN¶^î&²sôLº”Âòa¤1Å}ƒºŽ÷)ÝÇô2Ô#˜^†jƒøËqô/«¤ÁL¢Æ4£¿‰ö¢ðoüÁ„ã¿Åæ€ÝJ‰'ÞšBÀ‰–ŠÇ€SZú¬r5glCmÞ¡-´?Iá{) œDY&ã÷}c[ÏÐ$Þ½áŒg`3cÄáæ2ÓÁÁF2‰3N&а˜q tvþk0g™1¶êíÎÂk:˜]îþ0Q£ÜÕ!õÿÎn # ™õ…aˆ#“»+Ä•(wM˜¨Qì†PŹÌËÁ¼‚F,μÝ'¿·{ðKæÕžŠb3»ÕS°KI¾•Àð¢ëüE¸t9,£L¸|e•K)3ÂG KÊhiïMz®^ ÑXæ¿x§Gf,%©Mß¡°uc’§º‚ïåD§´Š÷'Aׄ¼Ôy¿{1+kÌ@ÚÊÚ %„®Yàr ,­â=KÑUÊ !“ø©bÛÝ`¿±ù qSß)åDº´Šå$;uPw&à%piÖr^›&'î)«TNêK«XLø3àj¦ X°|Ö^È”'´w&/¢;Ëßð".S>4`èÌÄÄ$ræK‹žÝuò¤Ec™Ø ËÄV5Qfüý‚ G’“¿\iÇ2ÿÅˉ;îDNäMß¹œˆÝ˜<Ç@˜>Šœ˜¬ø•ʉ|ÞhÞ3“Í{¡´œ8]\.-'&+~ùrb‚ìÙâ¬ñÞØüL%Ä)î‘Q$ÄdÅQ$D>¨;–\º 1¦IKˆ´J£HˆÉŠe$D W Hˆ¹å³öB qì½3- ñ`ëõn QÃÐKˆ*rš‚8ò É÷ ôÙïqØ=ÞÅ//„ÀŸ|A¾¾ _[0q]Áˆš‚{¬'xTXQÀùÅ/þFùÎô÷BK0 žqD Á}ÖȽ1 Á}RÜ©r`"ªi"pIµÀ½W äRøB4þKV Ü©R`æ*Éí ä‘U,·û—lµíÍRglœš‰‚ƒPÊ[XÈ‚Jk÷ƹvâòú—«È´×ɵh±ÎêC/p/Ño(|‚X_ž³¶_ }9eí5ª [B­Êb”2k Ö‹O·±§&Ÿ}5ãîD=£ ‚Lr`,Ôë;@f[†Fzð)VP8w!-yùæ`{kûðàpÔä-1ùu ƒœezd¦BStÆÎAÄp0s°U<çIhÒ¾Œæš‚š/ÔÔ’)ž¨)å¿1DªÈ—-…¢Õ$ù[[ǯÖ2F iBtEØL(aì¸/¯„Zô(EïX%:-…èˆêÐq”¡åT¡å¡åÔ ÷T ZHzw ЄúÓ¨ê œþ§óÛžßX•Í,®hf)hiv¿ÆÙI*Ð’J²ôªSö”×Ö\æÕ7“÷7C/âD¯õ8Ý›^+–âV¯u¢”}¢_‚ÞOGúëþôÆïPÿ§vd’Ì‘¾“JéÓ«ÎP8!c }zï^ß—ô3Ðùe#~ ½_âêÕŒG]ºŒ>¬Ø€­£¶#h–Ãz­jë§Y­HÐ4E9ݽ¶Zåô÷éU‹é𸛩Ç/\#{dêó'¶£&¯Ó?Ù=þåÅoG‡Ç§–êüZì²P­Œw…',sÒ® qZ çÒ›¼¾Œ†šÖƒo^žìý{W&4éѨã ,4sX¨jƒªDÛ®øõ•6LpÄY§_J·úÌ®DL»Üdn÷{6ürÓÍæõ0åÛî©¡" ŸRó`÷fâÔÚ;ˆÕ„.c·—]/¥æÖñÑ–EuõŠ8âe¬:fNx¥çLí S¸ÇöêáÂy&ëØk;¬ÞÀ÷Rnñ²ËpŠž]†ç¬Ê.Ãé|z™‘ÏR d™»»ŒŠÓ¼¹Ó›îí´ç¾µK{g§÷5åÆN/dº¯Ó›/~[—lþÞßÕÅ|–7u±¦ïêžNëÆÄD£Ø®)~G—Qq†7tÑ2Þ-]lrïøŽ.Ù§}C—ƒðEïçf„°EÕ2gk¯àlû{­Û_Qù;Ãqcó÷-•ü,öN‰tòÊ߇„ò9ùâ#’““Q>‹"éînïÓ†ýnuãñêûçéEÖíwëZ Ì1wÈ@ЧUDï çû•gÏÖVן­_\\<»pVΟ}·Ñú¾šYu «>{5œgß]¬¬<[Í.ÿËw±Ÿ=[ÞXÏ.½®•†¾}·þý“õÒk­Ëá¬þ°Ö\Ýø¾¹º‚iã3˯ÅÊ/?YË®ð$Ñ€¹o€D 5Õ|v­3˜§UYb«KRUEôTöOÖ’gÏÖKÒe,19Pþ `­/Mwï4Åxޭܬ¬¼ÇVWnZ+ ïh÷pQ¡UQÈþ>£Ðš(´±žQè‰(´²šQh])4ê('=ók_Í̯ܣ™o¬æÏü“ Ì|Ô§xŸ6â}Z]û>µSÔ—p'´±bCCˆ ǸBB|¿’Qè{¹Œk…~…V×3 Ù¢ÐúEF¡sÙñ¬B­"£kËŽŸgrD¡ï62 ]ÈÝõ}z¡Õ•  »¾†r+f­Î“eÖ ”yZ ÌF2ßEe&³¿V2ö—2õ|æGØ{k“ß{v>/‚ÂÏ¿»(€)Çà´°s¥6¬(ó…cy>Ý,@6WбTlb».ûTÛX/°±žŒ²±Ì(–‰þÇÖ !Ðj‘[-²d«NºÌBçE µŠj)ä)45ZRþd»oûù»Ùî± n6Úcë“8¼¨ìÊBqÝ#ªZî@ïh¼MÞÑØ¼Aï¸ØêÇ¾Ó C‹ì²ë{M8`ççôa¸LÂ[¦LEå¹cw“jK¼íÎ1Ì3«# ÚKà ¹ºSOÖ=íe ¾ŒŠ%,ø ƒš½ýž {gj½gÀß Ùîé«TÂr/£b»½lÔ.z«•n³W¼¼Í2ÊOz¯MؾìžðïÑéáAº×¾£gc¤fDf%µ…Ùêgà÷2-~LïU\0½W×Òô^Åøû1w€+oÝ“¨4}Ël2nÕϦbÑ£Á-h̓ýË´äÁéV<ØdY Ùäb½Cˆ;{Ëjön­v  ¾Ä¥ÝPÖZ'Q鋵ԡ ½V:F¤ž…ޱËYçL 1ËYå$*Ý‹èòWg3c\N4}?­p¦³GJ[ß$*=XÞü·XÞ„7PñÐùU/ÈN&ퟵ§O›Êßê‚jƒ#s"p¬¯eÕ³a¿[ÛÈ1ûyo¬jzƒ>^µ^­'^%®Dé¶®~¶R×nòÐf€_ãµVâ/Vù ûûø‹5þbc=þâ‰áF[3%_˜úÉš½$Ç¢Ù#Àï˜÷ª„’\6Žç”€Y¼²lf²D­®Ómu{óábÆOKlõÉ©¾G¾7˜oXø²w½|õ.œø !߯Ä_|/Ö{-þâþbu=J4²~‘x#Z¹H¾YKí˜ÄÄóÄŠßm$Þ<áûø›µ§…Ðw#}7Âë±$Ú|›ñw£4þnDø»Q7ÆÀ_>¤t[Ä%¶¶>*‰w%3æ MQw$*³˜s?BE'z7‚,bé{‘D¥Òw"á@îê>$ÂÐ;¸ qt¢÷ ¸*¥ï@• ߘжˆÎ ïÞ#¯l ÞwŒ»w¦r×qzx”wÏ¡bê,ï8$Í»ßÈóhÎófÎódÎóbž°óHÞËwà¹lòZž–Çò(ÞʹžÊÙ^Ê£x(aÞÉwä™|¼’'ï¤6’7ò×ã‰|¼ïÐyÞÇÓCÌR÷_ Ç±êmüU\nÜ¡›ñ=v1žÒ){¹ñàVüàV¥]zÑKã…5Sâ²+læþ_tq„œé%oòÎ.¸°ùÉ©H9–—¸ØJV˜á¥–$Äc^iñ)¼ëë,3êNý*ËŒ¾…¯±¦ƒ~…¯¯’f{ub`‘‹+ììWsi5ktÕšôe•Q•1Ô.£—HV(£“à¿#}„‚³ÕEDØ1)=­BD²Býƒ†kº‡Ür&ÜÍÐ9Œã“Ö! ¼š¡?P©N$á(ƒ¶.\ß;wý,‰ÅXF'ñ6'L^î¼Ø;,Ô+ÞÃ#^]tìË@w™Jœ„b8Kì[*ýUŠvÝÉá5?³CR69¥MRúÐ4V,{xFƒºÃC4†K³?Lulšè¡*W©ôáj¬˜yÈfájÎá8ÜžÆ!iÉiÈ>,4#…» y„i¿éÔàãÒ½°Ûí~æÉVn¦§÷ ,À«½—[;;ÇåOðÔÊwsЇžjÚÀe÷µ“Y'¼H é^ô?ðߌC^1ôPöë8æ5T¼›£^ëÂìŽ{¥Ù)î¬ÒÇ~jåÒG¿6À»<þ“8v,@Ë&ʨ«VšH­\˜0árK0)üŸ [ NIk`®Y²Äâ&F3ìDÂíÐpkÊ/ª³îNSJ(ˆ–RBA+C‰ñ¶XúNÕTm7«f¾äÚõ°k̇Æ`ðÞ´êåùŠ;¾¶”ë?óËKÙð^aòNL–˜\ö:ÓTm†—šÑÿVSÎê}¸ÛLÃï™Üp¦áx©{Îéâh)1ÒTm¶dB]”T¹BàìqÚÐøÌ¿)âYaÏT­¬˜'‡s‡ž†?³íT š¤P'V§¬8gªVôò4†›9W¨J§ã}Žx8]2 ÁÛ爄:=3ªjy‘"׬%³ÕµS¤3£^¼fU¿çnû×è8þoaãÈw‡'ôÜÈê Ou'xrOäŽ6>Ì;?Éïü¾Ö„qS8ÙG½»Íª^Te›‚Û…Nå{{›+<|ŠÝé¦àÚ µ¦f4›¹òVç_óU¸VËî:|EnJ¹$šË%Ñ.Ynäm¸‡`OJ«vS«MÓiFm4rQžNØÆ9×FíeŠ3ZÄäR£6\ܱ&Þ𗤧–(}GÚjÙü=ÐYó®LŒÇÒöLqÍujµ/ÎGÉ}R\§!ü Õ×iH?‚{ºH[T´N­vx”.…šìÙ#yjf-+OoC”S«(‹Aݽ\¬âÕIÅ fMH&V׫„,œZ­œ¶;†³…tÞêäíb’öøûiŠrööÖëÝýbR¶F³4âT°„^<½|íøéÕ:òÜê÷ï@ïøÐõyïüì¿;}¹ÖüT÷Öˆ<Á$µæ±ÁÞá¾hÐ ˜8ža=znõ’zt3Η8ãï»NÎúršu3&Î^¿nDÂ;Ò²ëܳ’¥E×¶ÎËÃñ›¢fÏ(À‘3£ÇÀ”#oÈ^…zZ­;0•Na‚ná/WIçÛRG£Q²¹Õ*ŠÌRC­¶{Wªé¨ã`\/¡’N«u¶Ôù[d,µ:çw¬²ÎBýi몳п¨’zêè[T¦M«uGæ^©²n2_ŠÐ‘íÝ }²íYˆ¬ÓÝ"%DÓ´Z%$Ru,w#‚&0g¦2gw&$d*+SB¶L«U@-mÀÉt}tÁ©؞.NhkLX=Ù=Eaôð(Ãþ:IÀâÊæ¨|Ë¡°?s…¤Ô©jæéÒ—“Cëdñ}˜ãT_ÓÑ|r¸/â~/©þÚNk;ïîäÖû1ÛS\m{Ú;n´Ó=ÂH'½>Þ»>õ xG@'Ï ¨+9g ¡€â9狜ëÛ,S;ã-u† œ÷Fœ~7÷f©iNòÁ‰À3rdÆâÈ Ã1ÉåƒoÜ“¸¹¬LJšæ¯!`Ç]Äê¸ë0öÊ,œã¾Äås‡Œ§h¾vÑwËcÜ0SÃáÂRìý‰ÛQ@jM-RB¨ýªL¥ï*ÞÇ,C}Lg”‘;dz¾Û°wÑc Á<ÊÇñ1„Gáè…wŽÙqÿÂuäEꈡ،ä³"®¶Á ß²§Õí¥ÉféIJ¥Ëe.0:ЇðJÉj)µ¦éL«´ùÒF'ìJkœëI«t1Å‘V)aò£UZ-îFkõþ ÏT€TÚ½3!2ìÃä e_”&SjÍÖ]:3®@¨Lè] …x=uÁ0· ‡ÓÆÍÂBbJ­™;ÑzòÂÏRÞ r²í™H{SEú2R_J­2’Ÿ2–;’þâ˜3[ 0†;“’£•)# ¦Ô*" &q2C",V8Û3$ÃÉlIK‡§ÇÛ['»Û¯2$Ä$ÎHJL``†¤ ’!&šÞF‹hz­ZüíX¨ÀÊŠ†‰*Ó– ±A](„'S5¨…ÄAìY†,ˆ¯ÓAl¬œ(û"D@BÒYËÔè] Љ2„ùåľD•/Qæ£y¼Ÿ‹g!í1¹Œ¨7%L,#ä%ªÜk :ùÕˆw3FÛXóì¦â%EºD•’ò áOf.É…˜2A1W£¤ —¨RP€Sq/[zË+iÆçl¹m\ÌŸ‚Ðöúh/[bSqmvâš‚fé²Z{˜q£gz®™ée¸Lñ—ãà6À*)¦%jLYJÃö4! L^FÓ€Ѱ[é¾Mа¥Rò™léKÏ5g,Q›w(œAû“dßK‰f‰_ dF“x÷‚™g —q¸„X6,!”%jÜg™ :;ÿ5Èc3ÆV½ÝIcSÀìr²X¢F9QŒúg’X„!³ÄB™œ†+QN KÔ(&…©8—)„å4bq¦6.ºO^Ûy“}e¦¢ØÌä/»ÒÅ/7Ó¢ÒÍ4§t3m)ÝIRºå­(ÝY›Pº ûIw*Æ“niËI7ÛlÒͰ™tKLº_’µ¤{¦’î]ÛIº¶ÉqË[Hº_ƒy¤{Ol#Ý»2ŒtÇµŠœ&–ÊÜ/ÊÒýŠ,!Ý»2ƒtgi9/'ž¹cš>ºwk÷èÞÑ£;‹G·¼¹£;¢­£[ØÐÑ-låè6qtïŸ}ã^žq£{'–n!³F/×ÎËuór}à¼I;Áy£yÁywáçý༩9Ây#yÂyù®p^Ž/œ7’3œ÷¥yÃywåçÝ8o þÞhqÞ×âçÝ#Ÿ8ï.â¼IxÅMCKÈÞç穞q_‡HèÝ¥wœ7k÷¸©b9Ñ›€‡œw÷.rÞÝúÈySr’óFó’óÆp“óJùÉy¥å¼RžrÞýt•;(â+çÝ™³œWØ[ÎËv—ó²ýå¼l‡9o¢sÞ.sÞÌ}漤Ӝ7¯9¯¼Ûœ—ã7çe9Îyå=ç¼/Êuλß9ïÎç¼I;tx#¸Ïy_…ÿœw_è¼;ó óÆv¡›>–’¿(/:ïkr£óîÌΛ©#Ý”½¬ð7¦/wÇÎtÞzÓyÓp§óFð§óFu¨óŠ{ÔyÅ]ê¼â>uÞ=tª;ÈõªóîÆ­Î+æWçe[vzÙ¦^¶m§7QãNoëNoææ^Ò¾Ó›Ž§WÞÂÓË1ñô²l<½òFžÞeåé݉™§wçvžÞ¤m¼,=½¯ÂÔÓ»/¶žÞ{zc[{NËHu_–Á§÷5Y|zwfòéÍÔæsJˆ^Rª×ìÓ»c»Oï ?½iX~z#˜~z£Ú~zÅ?½âÖŸ^qóOïÚä€zwcê%L@ ¹s†®¿Y=ÃG> ±û-ˆU áUÙß´ƒ¾\}¨Èƒ6‹,8á8—'к…mâoóWªxt—Hh}V½9«Å*Ÿ!^ß(ˆMcÊÇCe 4ãÆ[úAÁQƶïÁYiõ¯ûîÀù”"è§¼ä»9å%ß¿†—#S>«Œ€oª1Mñ^´ ÷üÁ„Eû8Ð\Á^t+E¬oMB½h©¸H¯´tïz‰š³çe›w%Ìóö'ÆQJ|/.È›jÌRŒ¤y<9^ÎâKñi ‰‹JðSC¢һ©ÆŒew‰‡„wÞÛ¯Å8wöH«·; É}:^Bj7Õ(!³ËþßÄ®aÈLåuG&$­‹•(!«›jÔc8—.§(hÄât}è>a ý×ã½ÓÝ_ÒåóŠÍF:×±‹dóÊHh…òÑK žŸndà’Zl*B—F\{ªÉÿ¿îìþJZ÷‚ Á“'kÖþîÖµu°c½†/áŠßI¥‚”…®]¯í_s9Io sQ®QSJYʬJN\¶JÓm”Òlðä—‰j<ý¤Ö&–™`䊄§ø/[Ç{[/öwÝ:ÙÙ} ïvd…î1vð?»§á x,6Ùl:?ËÑØ÷‚íɬž¢sÚ‹ †0"YJˆ¶Üš!F¡Ó# !uÿoÛÿ[ûÿžíÿ­‡ý?÷ÿÖìÿ‘ @0è[Ø}–Ýn÷sè@¬ôÈÁ—A ÔÂ'k§ÛG{Gzá`mÐê¹½ä6žC4\ÓªyÎF?Xv=IUÄ–Uü¶\Ú^-Ç (« ÎÁ&6þ…kÎwýøµF xƒ÷Š<œœ¿ÙÆeÛ°¶vvŽ¿ .Aàâ?â ÆF1B¡Öx _±P—ö`L` Ž!Á@Ê ºà¶?9–º›ÐÌ ¨‰~çÝuºçN_½ë6j€‡LÐò{Žå¶«ò~×Ó¯ ÆŠWxØôSÜôdj µ¹e—f“¡’7º(Šà f['ôÏöáÑ®µ·£ŽeP;èz>¢—k]tìË ÓdIK)÷€`Ó@°Q…_½½ñ¦Úç&Q9 ?*úrúŒ¼wðò0f(ÿr3$TÝ¢Ò¹;@º…¿t·ëømû–¸°¯Úp.ùžÝu*ºmÒ'Û`˜D Ÿi”Dˆ™"ñJÒ–È25Âד´3Šõ8fe^éa±Í¨·#ñ°mÇé¥À¥¨ñfS™×xÑih¼Òy+j’Ì^î«Ý שÈG įa ‚ЧÍê·Ëöy J]^¹ÿùØéz~ï~0~º¾¹ýsyëÅöÎîËW?íýÏÏû¯þ÷øäôÍ/¿¾ýíßËu Xþ}«ñï•ÆÖ²µ|Y7"Ósr>fàv:®(þŽóGS³ÇAÈÂò.{o[h0pºxUØ<¸µ€ÔTµe3I’ÍŒÂ Š©ÌŒF"-$ù§»¯­£c8ØO³^íž²Õª†+òŒç7¦y¶›ò `☢g×÷.ûN§¸'ü 4`l6 Ñ½5áõJp)Îiej”’Ó4›TšQl'•§6 4Bε¢T{™bJ©1ÙSª 7ªŒ7|OO˜Ö°ßÁͪtwÆ•Æfgk_iè7žÛúGájŠíZs…é·e¯)OŠ+š–åQ!¼’Ñiã³ÁœmêHmRŠßéu§ƒêª…)ܤ"(Hs„µ¬úÿújÈÐ$¨¡1óaáû—î㠂d(¿²F‡`8µ¿äHH2SJZ#xüì3»°aBmy¾eCãíSÈL¸šç•”Ð.=_®¢€V©ûÙbÕÉ@ƒ™Þঃ/ÏYÛ÷rƒ„dzP!pÿtè l\½šVq}ƒ×TK뀆^à^"7Í_íüzx¼¨üŽ òÒZåD%¾g“0ON¨fýùrΛ 6ÿQæ-^þ=8]X@áE{ÄþÉVnVž®¬.È®©oÃæ´*¼Âý8ÞDÿ^ìmoíïoüÂ~=ÙÚ:ÚûN¾dçå+fø#¤W<'Õ᪇cM€%&¿®-¥ü!yx1ª½¾1Ëê²Úwx¢gð¦:k,°¢lÂéŸU ÈÑ• Š• œþ§%¿cta‘V g6P˜C&Ft‰¾‹F—8Ð… zi+•}¶Dˆᑲ¨áÈ'âr£‘yW{@:±”ŸÊ®:ƒº¥™¨¼cAg«òK#WÀæØÖvc{kû§ÝüÝþ¹2‘“¨ðØ~Ý:>Ø;xõŒmÛžç`Ná(âŠbÁß |ô>‰s6Ì8dÞÒø@מy DP_ížl½Þ¥;½kÎÚ’8ér;^ˆì¨b¥‹èÞë;Ÿ¬½—'›5øç9Ãoõ¥º4Áq¬=ìvoå}JÞ"‡W$g‹øÿeýƒ€D-¨íÉ®Ü ¹Yæ”ný1´;.m×ÍÚjX¦Àå2t2Z[ǯÖXm-º§ ÐÎÚ“q|Çj뚟O4pš›àÊò{ƒ`³Öˆ½ÅÀö¬¦–’Å‹EÕÓòyD´µç¸¢ SA'°[¦9ÑÔ×£ª¶LÌ·ÖHXÖŽÞÇÞF+ËËІrÝÆÙûåå›Òǧ7Úª¡½JöŒ”\íÿ}³µ«½ª Z{¼¨×fLš®<ÎÇ•¢ *Š÷[¹LêT×F¼·+/;__9pâôÙùíÀa~¿íôÉy1`çî%r¦¶—!;çWNÊÎ|<-+,2м,§E³)ŽP…8¹`:õ>Òz»CýuWÌfCÏýäôNãN¿9)ý¢”ä,këèh×ÚÆ+®GIðäÑZ·{è¯öBÿAaH~çÍó¸ÁGsl׌Žêž?p¼ í7ì~ëŠsÐû½®ö1êáÐë8A€õq8Úáï€u¨ÎàÚWAðÙ…ž_@Ièí'»3«ò:‰¥6én<ø&n—¯iP¶¯moÃß—û[¯NàóèH|Ûß¡/$å? ù©†Çox”d˜…;;‚*fÐý×÷@1o¾ß°6ÖáK¯×âÿn¬/„KÂþ“ÃÆWQvŽ Sù£Mþ›Û~Ääå«.a+/@W1Éøú¼ïØÃJ°™Et呤*853 uKêöï†EY ŸÃƒˆå&6zü¼ìJ-1Pè‘Ø™oîP«{vßîÂŽã41ÀrìÅo§»ÖáñÎî1…­¾ß¬LL)“¢ »O{)zö£I:EµË7l^^ +þöÛðÂøÅÞ+k÷`goë€áJãåõþÞé) Q^èPRjkµB$>÷/‡} gæ,Ð)Ê,ÂçL´}49%…sÐ wŽ ¥ç°Õª!˜æÚ=*·nÊ4³©t'™÷RÌ$‚žØô%ÉЧiž?öæœÄæôbô=Yv„[ÜÒ1pÄRPfÞi^6—؉߱ûn°0•½Y›äïíXoUƒ¨×÷s#ZÓ߉y3É9¢‡M6¥M¶-æÂæ5{}ÿ‰_%qxˆ™nyÕvAöog.q&þ–]ö^9gÎ̱‹¾ßeÐH UBgBØ\ùýq¹vÐr]«Û}÷žmÒ™÷[¹Y_[ÿa ?¿ÛxŠŸ»ëëôùÃÆ*ÿýô ~~÷}²ÏÀ7=ŠÃt] æÆëÛXçéúSë鯶€ÍÛøA´±Kmp˜m€„‰Ù<þtØ_T m8÷={5í¾ÇúŸµ~9ç­¶ÛŠwìûvh0»Ovéóû§?ÐçO·©cßÿ°½Î¿j¬›ÁíµmšÁíï¾*€­s`~ï®áçÖ÷ô©–ƒ47jŽÆ )°r‘qáûÏ3 䔩…’ lsSkŸ=Ÿ‰€¢ˆÚxð;Þl®“ÛãVüèvš¥Ñ˜G*÷.ÛØwOO;Î.5“ÓÓÑ=íµæª jðè‘‘´=Òä9Òââ†>÷AXãqÇ”û@Òs?:ÚþWv¯‡÷hSp}å3l&ø—±)t?Ò%ø—& z=Òb²6]6ñ1-èð5 :¨×Pª1öiàOvÿÜ |ïۓ㤆8ì|9!…‚\ÇGÍ4Úy>£Ë³Ö;¼)÷/ؼ,²ð^ù̆òë°Ù%_•?åviªÃ$­¾Ç³ZØ ´?ô ¥€R©')n}Ù›bõûN3\®EvÙõ½¦Øu~N“´5ÉÄ“sÇîOâJ„€å/‡ -~É`*Á­mBDìà,››ÇnÁ-˜Lô·ŽwOT>-n—ÿü¹àùR > õfÈÛBõæ`ï—Ýã“­}ëÅ›½ý¤é¿Uj;ËßÜ´üa§íÕ‘9¸ÂÚãúòyžb ŽÃ`ØE$võMî]Îè`évõ³¤DA‹ ¡ “ür£š«FßöÚ°³¯í€]”zÍÈ£ö–°x‰Ç3øŒô>•­‚%€KÚ¬)EŸ3v¼u°søÚz¹·¿»Y­‰BUÍê'ýO&ï†&\ ÃîÏðÎ=ƒ£<µªtØ yÿª1ç‹ÑœÎ4˜gÕO„xñ¸Š˜|4ÎjÕ¢±Œ¦"Îd{y <€4Î$ô5ût”_u¶Be)ÎsnÜ`àx-±à G€L¹¥< q¦ÑgÕØ\‡‹%CüDk¥z×'ß /{øŸÞÁc W›g5¥Lx¦ŒDòúN`¢s}Ų1Ýy›Oqѱ_›RÇ.^G$:ñuSÛ‚UÃUŒ-Ûóˆfx¾çä ‰4݉Ë;üWÓl+s†‘ù›·±çßl²·ž/ùÅ"MJõX#º·ìh&˜’–÷èxt©#nœw|þ¦¤ ôx£ ÀR!81ñãSëàðàÅþáöϰd›ÕÐó‹¤äÍçà>„n&ý¼ ¥L9xA:’už'ºW Ë‹½ î”cå åèìç®mo ¶; ¯#ÅäÕ ¯Ê‹e«ˆkÏòÔ':±M¸“gìø”Iº°Â~[³–V3 mÈWþ5b,Þ ÛŒÛ"'îëÈÛõÛYѬ‹ÉŠÿ«\_´¼AÇòÃáòË¡D`uΨ ; ñOFí57àú-hà¶â¹ë€NåÙË=¾wX4Ÿ„² ˆ©+ÝLËî:eF³‡uOJ4+‹Mù=ŒáQfU¢Šì$¾6BmX~ãE $¶œþ*‰eZɯ‰¶í œ~, ñŲòf›EëÂÀäÁŠ.:Üg]KÒsaZ|3ô(?]† áR`‚ò«ó)=l™9–°‹W®ËÛê1¤Lç%ƒa¯ç÷AJieËûžÓƒ¬iu,n†Q(”„އ Ú}{º{|Àb0ùÓѾ°ëÕÔbs.vÍ0ÓZ (½sˆ[Ý0ÝÖéñ›ÝÍÌ/·öOv7ësu)æÃ’ùð$w‘5Ã0âxUx‹i£fy¡£ã½_¶Nw­ý½'›(4¿@4/9‚¢oàÆ“ý|+vË5IéØÁ·êD›*7~åeE4‹à¡ãüéð-pýfFáƒÝ—Ñazý†Î* ãáDò¦eÛmŒÓÈv ¶”;2Ý(¶NXËCÿ(]Q F¦aKé}^‰ =Š›...²—Ò„÷?†.u²Á¹4Ýüóz@¨é¸MS¡õÐØø)µ‰ âþP8ßöôѨVïÚÆö[ì7½*:ÿ•J0<‡“1J|£Š<ŠT…'¼p/É69Ø”)%Ã'ìµýÑ!\ ƒ”Ú¼ÙkÉ«i,H†¿ìŸÿ<“·’ì÷5Uqq±‚+§ÓaA«ïöÐ'ô&Á*ÜÇœOEä­ûu\¬øÐ&Ó {Ÿ>V»Eãd݃+èQ¾ ®ÇÓ@ðŠn>GÁùj†ÏêÐz‰ìpþ°AlVæÔˆ s1ì`w|¢¼?µáý=¡æÀv½ Ñ­?Ä£¥>0x}Фæ£ãô–è Ê}§‹d#44€¡0ïC3؃aÀ…”ž}  81EH8w|æùD_T¤G§BÁ"`8pþ ãƒz}'5;oñ7p¼OÖ…ïלA.Òž€Í£-tfÍ,pS˜vèv¿ï¶ÛHìÉæXÇ·ùV•k¿$æi‘ª.Ê6¾c"$”>f@|›aœ B*G)pâOïÎ[•³Ñu%¼6öÝs®;äè ‚¸pÈ£Ê!‡*„àù ø„v³©qìDds»=î{œˆ%Â"çâÂm¹°ˆ'þÁÁ¡Dó%°€ìEóXøMgÐwo[ɶr—Sì®`ÐFo,BQ]+ÎqGp¾ ¦…éÜb¿± Z¡ÑX¯ÜË+L¢ƒC‹a‚]ã³+‘ú]™¯„i%àVÿ0O+‹)jEP£†GqÎæßÙ?·ÿ¶Þ‹/˜UäýâÙÂfsqùlu¹Wÿ ¾Ò*O5´Š'ð‘Æ†?èDn8l‘è¡×ùr”JÁ¾RŠ"Þ,.ŒdÎÖâ#§Õ ‡[Õ–‹TÀ–­$àdŒÑˆRGhÁÌï½<iN"' øóbëä' ®ô ¼¦ï'‡oŽ·wøœ p›Zš,íõs¾ƒåïxMªøTQC]Lìä‡yÌس[ÎfÕŸ³°èÓ*‡eÏ";  ;P©N.ôDbÿúòTXÄÞn·ùóà"ûE?Cp¦w0än؇Å8ƒ?Ün÷ìlIlœvøN¼i†QäãÏ*ªÁr}¹Ž•ëõåKróÃmûÀÂ!·ú–Ýñ†Ý÷„ñgg°- h¿,Ÿ­n µúr¯wKŽŸ/7 äuÚè~tx²÷–&£íóFáœÄQ]þ½H_7Õn…ë.–8’WY áŒ\þ=:"–ÏÑ·Kˆ.¬ÕqÄNgϔü¾IôçåÝ_ŸßÃì,Ô–%«|¶ª2ÈÑáÛe 5l !ÀôbõͳµÏ¢Æ3¨PfR´W‘?Â@Hè}„¿‰™©²ˆaIIÏý\Ú°…!×:ES™L¥ ²8 ¡h’;ìµm:ÚxoµRô¢™5"!XöútÕgG[j\ÇüHz‹ÔÊT ~Dœ\D…4¢‡þº¨\ø×³E ÛÑý$óœsðôZ 2ÃRñwú0TRHû-:ÅxRµ°è¦ò&Ä-ÊÅzxÚócEW²€ÐºIKÏ÷@E¢g¯,ü 9ˆ좤ÈQ¸,á£bñGÀkì£a6°ý̹éãsã´ÄÛfSy¨VžoÖkñoŸë• ÷m6v¸xxðrï•õ Xøçÿ 6éû üõfS¦ tq¸yÚá‹ÿ!u»jÝïRûϰñWE8äo´ÚdÇœÅF# x¨ñåGBí î»Ówì6-»ÝA³k‘s—„‡MŒZ{sÖ\n.?‡¯M¿¶,¾œÿ¾ÖyaWuôâ¬O§K°ª¨OkMvÔwzè$ÏG³³w 2įH|è‚È|\€7W›«+QIÞ@‚Fº)ø;©ì»E޼ïˆ:'"NH@qãPP4C§K²Än³hX½>ÃÖ>ÓX`ï睊ö «~µ:~çÚÝ"¼µ*•ýSíñ |QÑ‚Âýõzkïàþî[¯wvÉöös¤÷0"ÛÛÏN8œú^›®<Ð絫}V%=ç€À#Cú4+onËNÂN×±=Εó»,OB›ë}ò?:$|Ê:·M]_›Vâ6vyûð—Ýã­WìhëÅþîŽy æ¢å†k„1ƒAaE³KÇsú6ŠF\7H Œ7êñ®lE¬ÍJ6QNÜÍKص‚ôVÏmk§üûÉm;0'}b{Øçè*ßwhííH¶íÚv‘#WÀ+2•ð *­Mj¼iå3éJ¬ ÒÖëÝ#3ŽñWåpŠêÌ|ãÀ4Z6 Ô½ímó`ô"å¥Õ½ÓÁ½}›?:(3úðÞ¾Áøô­´ûvw÷í©ÒYè:k(ÞñâÜ#QCwôæ4”¼öO­“Ÿà²ÐK ctìX<²±‘ðæT*I‚³¡ÍþJöçàÐzsìTÚ)<%Z¥±§D…v¦äõÞë£7ÇÀ‚H¤+2%Z¥±§D…6ó)ÁCéñtºuº·3NGV…rS‘iö˜ñæxg÷Å›W)8¾.¹Ú²ÞÌÄ}Ø`>•ôHƱK–¦ Ä Flršo_ʸS½üJÞg3ðŒ $„ãîys²Ù\Ö.ž>WQ§« à ÜÎæ Ýv e~1hö'‡6åa¬Œ¸NŒ°šÖhµ„ ‚:)DbRt(ÅQc¥´¡Ñm¦^”ü,O0ÌÝߤ—WʯVæ¾aµ“Ÿv÷÷+sìU(Lœß2Þ>Þù½è6Œ_½Q§¸6¢5ìSˆv)jP8¬¶-MAfè )–h{ØâÀC¹dI^G¢‚¤íœ//a¬áÝ!•péâK¬iÇ¿DŽ ä Š¤„WkTm“b:Ѫ–¸-ÔžÐo UhÈ›gêàÏçïËŸ>wÂ{51³gS;dž?ln_½^®ØÚ(Ú÷O>kâUZ-˜–°Q0 Þ Ø÷x´¨zÞq*;o¶ö·¡/›«Ï™è¿|Äæhz_ÿ|‚+=@Ð_ÿ>ùIriB‰ DbÞé;¸ÀÁÕBš~5Ša)øqðfûõÎ&þzÔwëÍ5†áäÐ6o(ÿ nÓ-e›= ®F÷«ýµú¸ZûÕÏKû¨uE\~Iö_€s0^@ûÃ#îðÈ)éþÈTÇòѸdõb}³ŽŸuº`Ô à¿^í¾°NÞ¼89"C¿@d A^£K Åž¸7‹ Âe–—eô0TÔ†oQKzX21¡«£Íz¥.1‹Tpš\fÁæAyMØóv€v"f5ûŽ-ƒþò¹ë-÷°ÆE³"èÄ&]óÌàO=lQ’¨¼ÏÒŠ„>˜Ï—}Ä›f2» •¬ÞØcØ` >#2T1ⓘ¶ð’Ü\¡ÞΖ÷‘'æ<‡iF£€?ƒ«¦~–Òý¤Ø5eTEâRÜ$\qûöuƒ´Á.•cø@ö+oåϪ†Sê¹ÊQQž[^ôÆ£WFoø‚ý#«Yp晚Å7¡hÞ½ý0OØ8l/ÓQ„þ—m껇÷Gy­ê—d{ç~ûv³N×¼ ÈÕÚ*¿¦­Öµ:ÐÇxÙºzÉa€ {¯“³ZeÀ5¼•—œqÀJ™6§¹Y[}®_~÷/õ»ýªè&ÞÒÈ– Þ–(ó¼òa~ˆ—k.òa×>h—Ûá÷4𨭵™ì ÕàŒH2ÎøœÂ~h´”xˆTH¨Ëø1PPˆV1 :GaÍàß_Q]éày`·à¨Øçt§á9×dO¹„s܃ãÜ (ž0ª<)7œÿ;ôòD¿U€†vÙ;.é²ýÃWÖË÷³¤`‰ll;ìÓà¶ç¯ÈþÚmTµ$<¹EnÍv?aßÈ;<Ábæy”nNþQ}#N–͵çáq#Î8gV×LR×Ç œº6ÿóh£ùWdÙ\[}¼yVÃ=ù9ºtÌ®€fЫ¢ðL_áÙ€c€1o¿j6›ÆÕF”sú°'»ŒÊvœ+leÈÏsŸsP"Ö®ÔuEÞ‚Ç@—`Ü:âÌìð¥×ž=n°ù07—ý‰¸£T7Ä•@ñ¡; Èd]šÉ3›;ÇÔæç¸É<È\êjñØåðÈÿcø Å6YÁ¥¡‰R&šbÕ€9_0­NJ!BÖþ_dó¤Ï“Õ‰C܉jÙ ;ÖÏæí³…ºáį„q#ßòFVàÏ*VQsÖª‘xÿvE°nRµ…7ñeôŒ«^ŵÅ|xÀ7lÙÈrÈÖµ’Ü2›«–µ YlS~QÚßé}’Èø'làƒÒt(µÀ(—S4¡¼aS|*MË7QËtJrK;uhU”|þþ›_à„ÃøðÍø2Ú/¿Ç¿‹g Ë‹µ:;ûm½1¦!/ôöl~yùl!å .2§¤B4¡(«ßÜ.0&:S`RkÄ [àí€lõý÷$jÁzlí½eÍÕìG¦ƒáµyó¾P·Å@ë ¯.%yÅ ¸VMçÆ‘_Q¤¸mùö^¸IUøbY­*¶k¼ <ê~DEGôH3lãbû<üGžYí E;kj§åLå9§\ßfêÕE:j´å;碌H£ŒÙ“/ý,WðLIóÐc¯O~þ“òs}àmS£0Ž:jø0z‚÷VMQmíüÏ«£#öO”Í×Ù^äú ã ϼ:¿Ÿ$_Öë>²}²›Ò1*íy¼ˆy›]ÙŸH]',¶ñë‡V5zÇu^)m¦âkRëo”¥CÌ>éÑ$ øU½ã•_ˆŽÓ1Ç!c^•ôë/5³v#ǰRCî~7#&ŒÐÕêÅù/õù•m¤‰³qÍB⒳Ĵgãn€ë9ÌîßJÑ@4À…ƒŠâH%ô¤ope"iù–ÅK5µƒÜ¦QgPAòI0t² xò:ä÷K?xv”gñH5ñ.Nþ¬Î;òòº Ê›åÆí¡¿”ô™BÅ;›«+nhŠ:š˜Wœìfµ^¥ë²[a‚ ÉqÔ"΀ŸýÑD( @ô˜ŸâÍE<‡áü_^ å/ W@†Ke—ÈÏ7(}Wy¥»È D.ÆCkäñJñ‚€Ë±,Šm¡á¬¢co$UÞA„ÜU~˜¨8ñ9rUŠm‡´tR|GªYˆ@¤dv0o³ÑÓ—PSCó›õ°hØ‘º–ÿ ºØ\†×0pNŽð—#âr݉<`Oc’ LeF+@ÂC¹…ÐëÞSÎ/‡»/’Åà ï.êÑ•hú­iK¢ª ‹Y7›uQœßy+e6 ÕHÅåC‡ ϲ®ÝÃxü6ßG7Mo€e݆#w=õ~@R6«„´onÿ±¨ó“ÿ8Ò9Ê<þñîwÝòÖ?.ëÕ²= }€ÕîW±Þ<þG¯—Õf'ƒm€8”f¹’bþ‚wXt3²z̪†«Z³¬a 0…™N¨ZLq@z#åjëªë·Ùã›xs¸ÙZºéN†µÏ¶´ö‰UÉ·…ƒÚ(‰K‰%,ïáH¥á#gŒfo° ÃWt |®h¢[UJ0ª«E®d˜#ÑÜ'Ì´š15”‹º*Qܾ@!ˆÇJ…àjЖ}Û¬V¢À¨²&‡²¶°Ìj`d aýÅV›«O›+Â,ËV.U±WoØÖpà#[lâÆDÂûäóœZ”a G‡j5ªŒ1öÕaÀŸÍp5èQTâ§Ý­Àwµ„x•Ùß;ø9…E%Ä%Þ‰RB>BÕ5®JíÿU*>†¸òƒȰºC~2{ ú¹GÛbõ•jÑ!ÊÔ©ì^¬VªÀ9 Æô&Qà9 ®Ü‹Ás[R[ …ž8ä+Xm Y°EtñF…Ÿ†åYHþÒ /õðˆH]hUlÍJv(–j%Ö©jraEz!ùP[‡²[–’UÙfõ¬röc};Qz—áX…:hŠ¢:ânÅMV!;ƒƒv$ µZ~ŸÇñ3Ì${ã\ DÔ‹ b“+"ß¹(ÛñXŽ.êŸvºEªQLCÓwÔnÒvÂT³Ryƒcz†Øýîðètïðà= ï :~Á}ظZÊzåtzB ç†FdR‡O—¸î’î ô/XZóE¥å8ξ †ÏŽ0ƒthMD¨QÚÖªÆÚÿÛÿcè¢F£Ám9M)OÅ 3H&a8»‚c@ÐFɨ¬áJD\@ŸLùbȾÊð3˜#ý™I Ï1øì8Y£pv€ä#´]Ž!ØM¤tïžî¾>Úß:Ý}o‡²´}´i%ÊM¬”„Ë7Íø9»²h4xV©©9^Fìݨ”x/'·oTP>©TŽù1Hæ°yþ)N¤®MQªà0 ÏØÕ`Ð{¶ Ò²ßi^Ù77ÍÀYÆcK¸Þ…¿ÌkþØŒˆDi‚ÇIïãf5æÚ([vÿ2Ò$†œaË ;ËïÎΪճgµ÷Ë(Y~»|YÿP0ÅÞÂsVCÔ *?{+a#Ü*ãì#xIäèÃYM<ÀõèÝöÝË«›ß†Cneu½ì;;ñ/×H\^¢Q‹ØŠ{^«Éy½‹âNy ¬ˆºÜ# \c;ñ$ñ]GÑìj!ÃÚ‚Ž-¡m°¬çh®‚T7Œgëp-a,½ëöf½Æ¿Ô+A¿…Bu½Æ¿Ô+{°´ûûðD|«W^ÿ¼³wlÁ#ñ­^Ùúõgø ÿÖ+¡Aôþ&ù ßÚ×Ç8^x¨'©áB¬ ðøÅá0@¿4FíÅK!ß´,4·‘a ‚Íg®ýàLîèXá¶WœUXåúÝFcqó_": ú»"DÖ†«R¸—ÑH„ŒË‹j†‰¢(AK¢ÂÄblr…#éC°Ý1ZM…› ]~«UévR©LÿVôŒ¢%n‘#F³5Ç~ ²¼Ð;‘!åÿ[9¢ïÑ×ð›ü">ùG8Å9ᙜ4yŠþ~¾†ßäñÉ?ðß_ØBˆC%0ÕçÜL@4&NÝ¿å×ð›ü">ùGl%šª‹oò‹øäøo[åná,Йö7ÿ">ùGر¸z0.Ž2:µÐøEˆ¬÷œ?ÍRûÉ8BõúBBCD íDZ§òö¸‹8»N×Ä*«G½¨W%Nè{œç&çs"Nã¿å×ð›ür's“9R)¶0V>¨qg€ CÇm ˆ‚[Åã@Όҋh™ìî9œ—þPC|Æ€±_­WN«ƒo+P<È™™…~—säÕ°;ПeBÇ«´­@⃾þÀ Ĭý›ü">ùYÂ7ÎØÒ³ø×ð›ü">ù‡J`„§í,¢otr ]NS3RÑk37ô—½ôÈf¤ÉM†°£Ð*‚ÍClÀØU†š8–Ž’À5ŽÜ<š›Æx97ƒ¾Mì×&]é×Ô)•œBG¥^B¦A‰1vÑ›pIx*ÀQJè£äÆÄAö…ù·ÂvÏJ%™LQÙÜ?Ïoõ0}øC: dì,ÂßþÐ#ƒxÕnS´~V[$ÃH‘Â_×ùûzä ¾–3 \Ôÿ+2K¼ÁyÊàq¯?Òë’{¸b¸z,7—Ë—ðù;HµËss cÁ×Ú2››[~Þ{~ƒëÜòÅá[T'‹a ÿF¡:Ä—ñÍ ¢²Ý2G^n Jºw°wÚµNs•(J `[ô£Ê^oýŒþÂÏFMú\­Èˆ¡?5Þ¼%w($€IOصIÁ¯ìqs)wÜPÖ¢Y ·Þ¥;~gPÞèfÝ¢h}…*D~[‚‘‘0°a¬Tò!t:ö­%UÐQQÃãz…\ƒC©þ¡†°FÚs<¹j'»;˜Œ” p;µÙê «ï|rÀ䋂жN['kíìïŸî+UÅ“‚õ1(Õ›×GJ}ñ¤`}¬›‡V hÏKÂBƒÆ–=/«ç¶,ÌI¯€‘ÊõÀX"Z²OêÛ‚pù”m]aN殃ú. %6|z¡‚­¤ßëb¥*~¬©»÷(0ô¡¡Ý"G\Rô°”Xý2íû‰Æý¢-óäñ(OËÀ‰C(Õ?Ù£€*íî¬÷6Ðþ,XóÕñ®JðgQÌUÝ-Q÷e¬îËu÷Õ)Ú/:C¯•Z¯‹¶u`©'þ,|^ÝX­nÛÎS;¬Â§á„q(Q,Ä‚ÔõÆÑðkwÂ] ª/‡pr´v°¯C GÅ!ì¯éèQq­OÖÀ·ˆ¬ *B‡g(PúÀ÷;™Ðµ¡÷ noaF¤ò´h8HÂÁ§á´f¤±H ‚órpå«c5½.™&¦k_÷ ÏŸþ¢<4ô;0ƒÃ7áQzÏG=M ^ìM)îæÊÂ[HtÜúˆ?ô‘§*Ê몼ÁÖqáZ¥jÒêZ"Õ]1ÊÅù)Ì^*Æs%_=!O÷T2@¿ Ö=Þ:Øß{¡Tæ Ööá ïùxEEh|™^—„<ôr`ëJ@—¼­®úª(µóa_«uI›Awß*ÉK/U°ímÜövÑZq¼Ý.ƒµ2¥R?ÊòSŒ£Òºýªp¿ùÜw’‚¯Ýs8,znÏIœ$æbc¶ÇS«í´:Z“EÇoÑÅ›ûA±&yÙ ŒÒB3!Ën·ÑÌ àpµ:“c–—ïŽR½Tϼ.Ô§AY4bíª/ B…*t´šH~â]ñžÂ ô}?†$âa9­?ôZ6Z¨]\SÑ_ÞË×ö-yÅâ)É¥WšÞ—;E¥$“x[.úSK ¨ÃÔÞ^¡4x±7EoÛû­FlÀêã¢ü``¥>/£k7‰ý#ÉüaC  Ùï[|| äôB¥ä*“â%ö¦ ¼¤¹‹ú¸èøyikp«éþÔÇEï|†ž)O Kf’8 %Œêˆ4ΰ„¢GFȉRÅå-R’Å0R}\z‘Î-0À‹½,:¾©{ÊÓ†_ ÈyŠãß— )·#ÞvdÞtŒ|Ëáå‚«88åi98èK„ƒOËžö˜ì׊¦É—E1æ–«z¥‹vG}RŠ–¥‰*JÊV»£ÀÑÇôb£µÄ5º–ÜLÙí —æÂâ÷U±7å4íŽßÓ,=´ç£À²(Æp @‹Ç%jªÕ_²L 9¿7Œ‰åòqQ OB) !Ôi(»€â»Ô±"Å90`ƒ…¶$ƃ)/JÐÃpú›R½Kv«d  ÆXÄ~6)lfm¿}«Ùáƒòö410±7åíjÌðä›oìc@M¯Ë®ŒQ}\ü–;D<™Ð½U x‘âcÜ_åµ&ŠŒ~•×/1Þ}V^Q©ñîµ’í¤•ãÞ ÖHZ‘‰ÝÄÚ+VaÌ{„x›ÅÆ»Oˆ5”Qjœ{…4¢/3îýB9L”›Ä=C^{ñ²£`}¶—‡¨èîSÇJ”¿ˆÁ½ù v´Þ*7qü×ߌq/ŸÞ”"£ÞOÄÀß{Ok#³Ü¸÷9miåF¼gHi!z;æýENj±ï1ÒZP^uŸ‘?Qhä{´´£ÜoÄ'ÞxÏgh ¯Ç¹ïH‰”2£ß{˜‰x‰Ñî?°oG»I¬å¨pÕ‹Ðø«QîEâ ãïFº‰M¾M›•ºñ·cêPÒXLÚg2}*Ö·.€8ŸÛ­Üç_„Žå™:ÐÑÿŸÿ´öO)=ºþŸÕV+Êïzå3ö“:T“R”Õ€g)ŶNØ™tø†oÂQ¾‰@ ä¸ º³-¾‡‰<#·J,$>_ŠÏ}|wð¿XØ‚ôƒã_É¡ ¾*j(øeò§‚ǺK”þÍÅáIÌ- ž¤{ÁË­cú‡{ùÀפ“Žnà“ûÎÀ—ímüGÖ‘ëΔê©ñZºdá®9`4ù2e•»ß°šjæìaAÕŽœ?ÌT]™ŠôÜ–éñuÇô”+&Âæšìlh, ?4ƒ_Ära¹K¨‰F¸ˆž{GˆÝ‡ý¹+!Pho ¿ÒTˆ{f%ƒ‚"šbkDb"ŸA–‘øÉg©2‹á](cPï5žžÄ¸¹©Ô5N·:ÀP®–ùÏØÍ0Π¯1ÞÍR»á#üR/RDô5í†Wúé‰ôs/,¢¼ R@R"Ó3¡w×)”x¢ê `}Z1¡i5cÚ›H³™¾ ÄÛ,%[:ÖÆÇWiéØ+ž¤iLX,žgJßYØŽ.ÁE'±Z~ OŽ_ó>… ¯×èæ‚þŒ¸¢‡º `Š4ر ”Ý=¹Q 7l¨AÝ®b4kñªyU]ˆÅݬÆ:0½¼D†"‡"‹‡@€[à9â9!"a–ˆ°pXÈ%†Z)T[– +¿¶?:/ªM`£ª<.lXLmµ…ÃiöZ9uÕ’ñè›QdO×ã9_ä’SXÏøòÕ«ä‰Ùž«ìi8™ïP d¨†­hÿŸ½_kãÊÖÆÑõß~ZWQÁî€I ÀØÆM:°C7>ÀIzÅi¹$• Ú’JQI`’xßʾ‹}ûÆöxÇóT*qpÒéµ¾_ò¬ÕU5ÏsŽ9Žïj52¹Oülª :¨PÖxAûoÀ=àù³«®&J†—ÂA™Xµ9ˆ3;gÃ>*ʸk¢Ô0RÌ~›Øæû€y‘Z[yâánÇyžžѵ¨HæyN Œ¬'tú“þ5ÕÔNŠÇãÄ$.<N£õF³±Ö0¨¢F©=ûšŸûgM„Zyò¼Çfäî68Gâwü_˜où¤-véÔ0‚ÊÇÈŸ±†fX¬´g÷è5=.¶„ÌfR¶Zùx{*¶òsB»£ÐÓŠ.*®hÖúéH’…p…œç" î4eŒ«Ìû1Âv0ùPv ¹4(+¿‚FEÁŸ/ˆYZ:Lt–³D¼“ q9Ì5¼r@Á­cxcoIî×ïˆuŒéŸÅ·+ÍÇ‹ï¨ñ£aÔ¹>§S‹Úq~ÁÇ“&-zËÝH‰Û|÷.Ȇ0N~œ2»ÑîïŒ1€tLˆ÷{?7×Ã% ß^ÉØÑè*›é¡sGë1¹ŽbIgCUŒ2º]jȽE¡ 1w)Í’ Óܰ>ðÉéŸ?8,iP 61·‹oߎßrnOÁtޝÞó„ D´øbïÕþ!61C,ÄoÇí…èãbôj×m_×òC¿6Nvó)îŒ?¶½¤×~“è‰Kî¿‘Q0i—\ÀÚ­ÅèKsΗ!4Téò,‹i1—±ç'&Å-¾Å§øxAÎCNf‡Ÿ¥ñhùóÏ~Ž÷$‘¤ƒåE¿˜Ö¼e¯Ú2œÇuæòJã&¹ÐmæØqs-$Z~7¯çㄨK'Zü'í[SdkñÏŸµ>{-þ¸䨉œnA)Ÿ÷¿&?i#2'ϯ‘¬¯jë¦'3l'÷íÃåï–‰¤VÌ ô»w’‘XóåÙú(ÍŸ2/ ®IvÉÙszÓ&ÊýÔaù‰uÍ,ؾ|fE-÷ð³hA’î2ê§×Õéþ„gR@ræŽIW¯p¶Ý)Ñù_¬\Tòå.Ÿ~¿À¹>£ý¾ðÃÖreT9Ç‹ïÿùÙ>[^®lÒ ô+=éŸ|yÑqañ!½ŸDüGesØç*ß.5ÞþÜ\úöãÛj™à›øØûMzû= ÙÈ.ôùò9Zýç²´þ éšVÚÒØæ­…´:låQW6¥W7÷hõÆÊQu[z±ú)½ùœÙÕLb*˜ä……–Aµ¿üvH?R‘™P²ð3Ûéî½}dܼ‹ÜŠøJ^zŸ0M9­F§­4o·þ==ú#2ݼDúÂ…ÿ×B…†‚±q>E:§Ì‚Ñmô»9xüQ?,áe-⇵há«hh˜ÖÑmq $“ØÂÿžO.–øÃï›?TMWRz·úýÁ< ª¤¿E-„ÜèÁxL%‘$ª¤"§ü\길·cH³†j«Ñ‚–¡Áhú Ó‡/¢5£‘â?mŸ¸l•ÞÃþâ‹ôó½›#I.ôÑ‘#[YÓ¶„Ô½ Är³£'ðеÿä¬4aš|EîìåeÚ-‘c¾ŒBŒ~/u„WŠh¿$©#à%–Ï @Ý#ž€ê/c¾ ŸÊCNRòË 4žÖ™XZM1$¢Ù î\Ð쌯Cbo8ŒÑ7œ“`_«´6³®S¸Sˆr|sä†{ÓD}yFŸ<\’„_UH‡–?>²xø•üñUDrÿ85"¢´…Yæ·ê 56gŒh‘㮊—ÐOŒ5á\'ës.F¤i…Τ $–•­|²m©R©dÝ ²'ó TÏ’äs%)˜zOM@²*‡Ê%'pSIˆù½Ôª$›b^ 8Qé1³¢ Ÿ¼Ñúl-éûSôÃ#îÿÚâÿ%R‚MDôuÿðó‡ò{ó­ÂMzr.ÌDÚGf2̓n>â7á¾úÀ7‚´Ç™µq¼ª(ñå›oËôßdvùNmÖó’Û%*£%ü2•Vñ)R•QñÍ‘ª´fÃÚóÜØ(öÝܲ z{#©Œ¼wšÎÆñ0g=Ú§’y㪵 ›w¥¦ì{çUºX‹ª Ûå£T †^ïfVèá^ ÆRµÓËt2$’½t4ÎFÉØd F“¬wa²‘eŸgÝi'q+¾†€¯÷jMWÍíØüxɇ4·½‘‘qvå$Ρjºð4Û¬ ìóøîÏÌÖ³?qìõ²\”¯–>ø|´¤}G¹…ßlöÉoÌ8#¯¯ªMÝ©E»š4*cÎÓÍ9RÌÓE()(¡¸î§ï“«”fðÓ3^OKÀ¹`L8w1t¯×(:64BwNSrAU “+&9Ôtš ÈÆÝÖ8ÙúÞä ?äè?|&%ä˜quü<`±‰‚ïM71âøß\Içþ_9ø)ô3¾³Wé‚&½û!‹ª¢·KÒšvyañmõíÒÒ÷ÿ\ªþð¨ú¶*T’).SÙ&‰ oWÞVvÍ_ÑÛµ…åѼÊü ¼"«(B}üwöJŒx,UŒ*œ®wrß^–UA½æ‡·¬”©cú–ÿ סs³Øag¦s³Àäõ­-}SYC騑3 Bä•·•…åó»‰÷)B!a·íÞ$$|„ôvÂ[šÿY’Mý { UùÙÞz-áÉÒ¿¼}X]Ž<ñâ­È¾TÏI¦ˆX¦sO“èmQà sOpKTÞ¯ wO„ ©OÖðDØëÙ"ÊÛK͵hµZ,Íõ}´ÛÞ¯RÏ–¨PBÈÎ?§z˜Qg'ÌYé"¥†?蟦Õ¨5Í íds¥V†yà(˜°‚´`Ô'°ò)ÑqªHî°“Ó¨¸<×Ú•Y–…šööXˆvõ&&Åéz8–È´1Ï[s#›ðo˜tùz|]ã”|ˆ£~RÓJÔ`ö\"î-N*Ö:=zs²³WSÛUÂXìaÆ<04´)=ÒJ2±·DùuΆ>ÑÇZ×gé&è{é–ÚÌ×J‰nl! !ýZp²¢jO—ÑTéÜ™ïuîhé-ç1Ù$!2k µ|ÝUöQÃÜ<é§œ“5—{¥Ra%³ä\ˆ¢Í—Qhô6¿.²ðæNT´I/T$óŸò<“ø¼`À§'b¶ßüþå×;?p†PÆýÑ·Ï™¦Ãiâ,Â^y|:[Ï6Uùû̓GD77wð`®Y…Å M¿JÌШó‡zUG°U߬»Çìc-¿©ÿÏé÷*_¾Zû/O·ÒÿÐ#üÜÔÄ‹Ìlèó‡Þ÷^þDzÊ>œXgC§á€û•gÓqŸ»ÛTì8™GÓI.¹u‘zB3Ý϶òžñ¯ˆ"™‹Þ–Ò'DmÔ}€]DÆÖ‰SÎIk{é8/1ÔÖD°5©ë¹ËbÁýU³¤övK…7á‰U&6‰ý[>RûX;‰vNëùä4U;°ŒÆ˜Ñ„WŒÞm’pô'==a¤Mó =,Ξ|O5<­"“EöO2pWˆ­ËZÑ矛9 žkAìÓ–¿M›ÖÜGD &iZ.žLãBÑ+Ù¯A–ÜBß]Þ^1oï¦ì»ÏŸûUÓ«z{ɤÞíiÖ]áð…Zß¼˜“x•rÞHâÈ1$ŽŸygIö¢!ýÎ_#§MÐH5Ôµ8Ѻd!‘D³Jt9ÉFPÚ ]Dts®Iþénj)úoù‘£è•ŸÍ>4éå£eq̳žŒ<Ä­EWˆõ:‹ï°nÞd>rv§_þùý?7‰“ÿå—çù/›ú»ýr¾XùÓ»E×(ÕÞX4(ì˜óÙVô¡îÉk³}²S·^š«éç Ã(¦nóáÏ1|2‡É0«ë.ú¸é\\†t¦tù‡Ï? =IuÒ“édL”ö§D\sèré\Äp®e‘ ž7¼x 0mìÎË,«¬»¯ÛÍ…¢Äƒ%Í3ý9Hþ£·¿È?oEFÇÊ1é²Û‘N›гýbÊ© ‘ý,?ÿåæÕ‰_Ä©0ÍVKj/Vé;†¹²íýE5mÖ7¹ë›DfCUŒYV„â¿•¡êàÆ£3©´ƒ4õ-Ò±L ý`Çz=ò¶#*ž·£qô÷|3Züb×÷ÿ\þD¯eþÿ´üèábôöêúŸJJ,/“ÌFŸÝòÉU¼­òÛ†oÒ¶eÿ»¬Ëÿôºüvù­×iúýpùg¦É$¢±b‘ÿˆ>â¸0 Iÿîüù+®ÞV%¶$Cþ¸øND¬È‡éxá¹îv+iduùêÅg Hƒ´íçØƒªî€V>íO”œld‹Áv½ÕžèQl$vÊ kX.Ü4š[ÄPÈ· \¦?üò ñ• Æ‚È ÄÁ†n-ƒªª)+vo¶A-ൻüý?Ñì£_–_Ή3Cö>¥Éôð–üë¦þä®lVd«Ø¾v=œ™çe’çõCgÀ¬,â>MæåœVKæ²´'·ÍNXöæIZö:éï ï«°`¡+ó䊗8Ýø˜z2!?³%öIš=8Ê'‡ EuêG[ök3›þ»²Ñß;éêõßw÷OZÇ[õ‡íþ}Co¤åeiÛÖSÖ¶©ËµýéîðÖ¡þ{ý˜ƒœÔÖÀÎfqÝx#?-M IïÙ1•Ý_î÷zoÓ˜‚:ïI4ì¯Ø»p+K®¢ë$&6K<@W+b”põ¶PzëyTxš'Ép«¢Ly±µXYö>®•¡øû ¯`ª[á¬c§Ã^fÿèg„q™?áúË¿…ÀHÌ‚êÒߊƒß‰· –­Q¡cƒay=“ÅœÏu’㊲}ôË#ÓOü4ÝÄo×Kü¥äËíÎ|ô·Û'‡û‡¯6‹Ý¥Èx¥ŸဋmP¯{½…RŒõ<Æû·©yõùÇ[´Q7*£JvD˜üs;½Ÿ?Ô_ŸŸë ™kzÎ?Ìc3ïŸ?Ô_æ…[„ÏÚßæ¥®Éçå‡>FÔÏÏ^Ç>J'ô¯ÏÏ-ItvKOB3:C9¼SºmEï‹8t§ìõÙzè‰ntUÒó ÖñkLטwJ»ê= –x’k±Dƒ8ÝüD騒Ô9Nþzÿ¥ÐãÁÍ ëÇfùÊCÓ‘OW9nNè€~×Ú®ÿwëóc¥þì‡G_-Ö®ä¿|Uq¾úåጠôËso…VÌ¿è¿ú¼ìêÿ|æS¥½…Ïõ©ý\}ø#ùm_¹kO^»¿ƒÆüOÜßA-ÅÏÂgöÓp„毠¦ðÿÉLƒ³ŸúOíçz-ÊWú‡}©÷–¼Ô?äåÃ’S\Y0à®O~y7½]p‚ !¾^K€Q›Íºí|iãJûd±µR ÌÜÅn?,!øêü36v6uöôÅå‘ ÛÇuž¾\x÷ÜS‘Ki G(¯O̸^•ü÷æ£-Ôl$öò~*máSïgýމàô’1,Ù 7¸ Lfôö×U nBçf/â!l`?Œå}x9ˆ/@>'ª´Óî|GýGz†;ŽæS¼+ šŸÇå2¨j—`­ ¾-TÁË¥<«÷Jv-"9. U¸×N¾»Õ§íÆó |èæ×3<¹Xeôé]ŠÆØåVqùѬ–˜d§}B\ƒÍœ}ßchq–\¨£Sk¹ÐË_­Ù2ÔnÚ Ö£¤­/ç83ÞKSêvNNû²sÏ爹©çòYÜQúØßTn(Þ@ßVþôë&µ¶¶#¿Ç~¸×ª×‹=¦þÒ¶Ï#ýn"s1­³Ê(ŒWlTZñ Ï·¼éÅ£|FĶL‡øûQðTJ•Ôc]µ„†ßÊäi;¸õç¦ÓF³_–d·‹yÇZÖ‡…ÇÑQó]T’•…âØC|É Ó0m³Y…®}WPèÚçwVèJ”)tK>¹±Š»(tÝþ¯Tè.ó:Ö/Š«_ÑPëÍê=hUò!éLk&˜G±n)Ât˳ïÓPwäGãçæRÚ~½»wÜ:;y³'÷Ò‡‚þÌ÷ÙQçi{:Épö" ÍË]qA߬*&âSã¨V àL”óVO$(}н •!VÉQ?¾Žò¸—°› ‡} zºD‰Så\‘ At“ À¾ð]â ]¼=;Ú=Ú³‚ö9LE;æœEIƒð?OC“±Ï.ñ.ÄñL¸ qpÁ”ÛQ¯6ž¬=J¢qÃNrà“a `bÞs§uãøPôWŽŒáÊ~«NA3YÉÙy$<ˆÞ¨™•QÌÄE‡1íÚÄÁåˆÐq¤4É“S@q0h;[+êXF às $c³;üë—êr#ñt$NF˜p&_YϺ¨ºµ„j<1êþzÞf.à¬ãgf H„áJ‰Çé6#üKyn ½ÆƒÚZ§­$ךh_S7‰½®4è=F<†N˜JާD€r)ÔÐR¯h¦—–8ósbï  ¨îç¸ú6£íýï$~î‚#F9êC*bÇeÌÉêÊúS9ˆ§ÓÆ6Á«ðýï<†a½‹øT0Ï“h}ee¥aé'„™¼öÏxP¯›ÓJÓVû®&’™TîÈwE&Ê¿ÊߎYÕˆ6y™]Q+-XåéÝmŠþ÷¥Åâ7¿“5Q»ý«-‘W À-[›ÏÍë¶ìÏ$¢1–ÜTo[±_µ Ëå+Ò ©:q·•X¾Çä.âôþ…·¶ÜÔ›Q§+“«'&`± 1[¦;ލ’”ú ¿OÆË]=£fÕ\ÑLèëí¿ï3¯Gþñ–ËŸ¾Xú®¢aÐ nZ&9bÎܼ%©@b„åc×y‰°/ªP¥@¢àˆ«d&Ù;Æ+"xI´â‹Â÷ਠ§lâîg¬ÑUwqs./5ïch(ŠrÏ)@D.p7\ÁæjŒ’ðF˜©7ŽÏ™ r^|¡Þ»˜"s1Ágn|M×SÝ`Yùî²rÉrM‹´Ri¨^r¿-*Ü®~{•´á‹×g+(¹ñÞë¼Ï“h)î·Z'ÄåÓ3 ·öºÚ¨ˆë­:Š5úõ¥Î ~Œø‹™šñ!€XHöÓü‚lîlÒ&MY\Ð$Æ´S© mE«¬Ñ°9ôv‚žõ„Vy&2œ)L«8yÆvRÇÈäC'±tõæž×pT©ªÂ›·M10¢[Œ7†ØÇóq<`1R¶¡Å®g<ã ·€:à¬k\ÁÇ .?Oº–Aˆå¦Q²%þºÜ¤„l6*ñ% a>©d¾µÈÓE¡WÊbt 2ž(m ¼l;˜ üÞÏDçOÿqÚ:Øq²}òìó[wJ¥Ë)>”ùît0ò+Ô¼üµþ–ñ‰jƒ&TÚpe‘¤OPBâÞ›º_ò<‡Éo¬NûgªË¤J¯*þPª<Öõˆgݹ› À§KùUÞ>(ë^ØK½˜£KÌ8– {­Wá¾ê^YNå_s¡Ã×þÙ$…A-À¼¡< þÑí÷Ôm$‹á"øa©@*ƒøC:˜!G˜•^@‚?/»E/AbíId®DœW£¥a6ð‚,d $9‚À|˜°K§üD¹=¶m°¸:§,Š&.*ÿ¢œÓ'z"R5Gø( E äoàŸ<`þ…“éx(aºRa pœ‘@‡¿6Ùtló‘‘â4ÿH³c ðÁ¼ z4¡‹SÎ M.u*û–CÕÆ´Ç'Y‹›ciN·4 nñù¼Š¹N\ ø±yÕò=RRmðÕ¾–D@TO'PÇÀÄÝ+, +íÕ;£QšVˆÛ+{!¬oª€Ä–æ&ÚŠ\."ZÑ0S·>bìZ¿a A´Þˆè."Øú:WŸÔRüÛÂ3FÍ(kEØx/]ÒÝ›-$Zâf Ï 3çyÖAŒžY<ç,270?[·0ÿµ¹L'âœä¾Ùæ;æeŸ˜LÞ9Šá24_6lþ'ý\þð(ÿè´/Í0™bI›Öf3Gqu³õráçÄ*:ËŸq¶)¹MðË›DMfª‰šÐ(ˆq’¸U7ÉSÅUÈÏÒü¾ìÅœÌÁ÷á+Ÿ¨ëQ‰#ä^b®€ÊX†Ie0Ã…Z~.÷rëá /ew"“Q¥!iÚн¼ÄŸö-Ûó†ËÞÆßÙ%>ƒéŽUc|•3lë€w¦AŠíšÓ»q|¥K'fº!—Êl¾/Cmç& AfúHiU´L‚~<|ݘMǵÏ<5݃_¦¢l€a¡k+¹¯k8Mò-Ô`îw‘*Jq0Ç"ÁsÉC÷»pßX.=ŽÚéÂNöóÕy3ä?æXU.¸Ùmë¢êPµU*6áÄyp•ü‹*N-âj½P¼ ‡íäõ³¾†¯_ºx_o¿Úßií¼&‰Ãþdæhš3ú´Ð]‰ÈD= rÈôã¯^nbYS°Î?w눸ò¶±\;(òW¯“|2oiýæf^*ìà ž¨æ—«æ«A–¥äÁ”+Å{ s.<•9—Â8F$˜é†ëRõB¿è¬ ØØ@Ä'‘5#rÂÌʆ.  Ö7ÅäÛ£Þ?Ü~½W’žÓôµðØdL¦ ê·5ã:Ð =ĶóÚì¥ýB‘rœŒiΛ—?ͬ;RÕÍ2':£†.M#Ê픾)ç5ÑI¡¥YJT*9ÍHMóê·¢Ò--”H[å’ÖŒ4(Yø˜mºf6hÐ0ó²–ƒiø¹ûTg`ÿS8ûh¡¦æFôž“e|VãR¢7švQ lŒ6v‘] ~vW¿9v– u‚ÖÆ%‰?b¡j-oØü x¡&„Ùg:oëL³DEìS‡‚6æf34géK&ÏìðËÞœÃû6ض\s7¥Oý䨟vˆc(±±óGwÊz\ƒõ ÿ¹Õn7•u ä3»}’Z‡ LÖüרÈÖ>±y\RšŠêDò95ßT¨†Ÿ•×%ö$fd˜:vïP»¡ÊñìS;³£ðÜnaý4ÆVƒbT‚7ö©¡½JÅÍ1UªW÷v=]•ª·$W&+¬3§ó¦2^c.ìýí'ØôßÍ¥;Ò¡rT15§»ÿPm ÄÚOáð%¹ØÒާÙQ½Žy LÀDXLÑï›·yðWÍKÜ¡u{% ¡_Ä¢!4åY¯i~æ¨G‚Ÿ8¯T Y›xxcjgˆæÿbU {0ãÇc¨™UJ4'syC#Ùcºº£8Wwî÷v4ê¬åÏI£rÕ/¯îª_:ÄÄ\‚„kŽhn€êœ}TsMÏï¤; »0‘Ùáçé`ÚŸÄÃ$›æýkëÂTï°¼UÏŒÁë¯?mµ'Ϥ´.7íÆ]ª­ß 'ú6õ0Ö´I‚T¯ú´¼¸8²Óœ«[…là ó6=ð”44#¶o,oñöÔ9ÕrE zé7¥+'ý!´Ÿ|W)$*oÌÍú­"TùËÒ&,à|hNq¡"À©ôܘ—P\,åﲸ;²œ2‹½/ÖŠ™4ÊÓ”¤#xヹ—¯y"éÜÄÂ3Ô-x@Ç;]Ñl³ÌÙÀ ¾-‰»å¼âÙ‹Ë;R””çQò™¶f(x@½K"yÏolÕ^U"—æPÃi¦“^öenÞû»$³ÿI¡ƒ@TñöÃC½bÐÐ;f8mõÅ0åýmÌMž—m>C¤RžîkÚÛÒôÄû‘£Àe/Âf“!Ãû+̶—\Iµ3O]™ãÇßBg$¨^l,P媲˜öêP'Ò«%³ñ{ñ§£µµåÃ| Ž“—×Ê1÷m™G•QêcvïbÆs§•Ä%™mÌ4n[J·oM2šˆ…k„GÐøÄ¨º»²L_Cê~kÜx’“Â4ÙYE2 *"sªbÿ´Ïf'™_¯‹Bö<1Gü~}1f¼†­ñÜñ9Ÿá‚ÁÛ]¨¥ v¥ÌˆŒ«ß¿juÉ“†¢·¡ÒGÓ›pÆisk€êÎLIË4637öÍüIbô£Œ›÷ʼ¹ÁÌÀ}øë4H‡Ó¼uàuFŸÌïÄé×$º±‡Ô7Û'[èÌoЂZ­üyYŸ,Œ‹nl¡“üÜNÙÏ¡^‡?Ú´-ù2O z™X›\Å3zM¸›úçÓ¶ì Ä>óqpe•‰CÌ}%»­–Ø¡àF“…šM(©¡n"“’P$2qð§O‚Œ†éßæÎ¡Ú S<ºÞañØT湡ðQ? èèÃ'ekUP­ jðq•\Å×¹aüôâ}Ë—iñYS_lÃr™ú·¯£ŸyÎ6·§å¹°€ mq­ÎÛ#‘=æدÜ03ÚLðl¦ ^#ë¦>!_ÔƒÊ Ï–Ŧ'PÅF«AX2+k—±ªNÖŠ×9O¬žvÏ{pCc¢(ói€iVô†…Jý'÷°òªQhÙ5ëªjy ÐëšÅÉjÿ«‡GáÙtFCɶ_«âWßq+°Ðå²lzáÉž’ŽjÎC‘ ðR”wz$SqX“äjb`2ÆJ]Ö¸«ÒNÌâ0[kÒ'%Ýâ#Bì.ðñŠÎ|>ÓZüâ¶\P wФ[ˆ0áì04N䥼ã|¶ûÆ)öô…å/—ýÞáiùq[‹úl±¹øê¿|s¸s¶txJ·çöÉÞ.‡uh­oNöð1Ô;-D $¢XejF7ìþö‹ƒ=öd¦ê·ÿ+£)•æÖ,bñ¨¼³Õb×Ë–ÇlªS ‡¿¸=. ?÷­ëa8a¬ ªóRœˆC.'»”­/Ž”Hܾ@·ï÷›ô??l.TŠŠco‰ä±¥K²`†·`–f!ÿ3-÷Ÿÿü<ÊÿüO/ž£þç?/¼Óu1w­´Ü»$d25D&3N?¬é~‘ äíœÈ_HA6(Ö¬2J qUD¹CyÅn¤ý>ÑêU/RùQ”]EâQ³}m¢¬wŽövÎZ·O£dx™Ž³!›HÍEQ3y(¹Eªè2f®ø|N{%š²÷‰K‰Ú?ÛBœuP!Ò:x‡\=Âó†Ï‘ÕÔLd!¥CEB“ô{ú|ѲVfÔ&†p‡y[«©Ä„›¬9´7.à­´û·WÇÇÑy2É9.PxŽžG÷„Aúžîœ,¼ä“vð²ÎˆJê@G3îJ–S¼ðZ#-Õ‡ »Ôâ)®²ýk|K ÿ\¹I6Æ}Ó©—žä C”t¡ÌFwçê⚥’1ø1«G jÍþªÙŒþD ™¥…p§h‹_~‰– LŸygbØ%Žp¾¥Ÿ™Í *lùÌÂFvF¥<üIóg¢sAs}ñÁ~X™"Ÿ•°Y†];Û~¥r3Úùî»{+[Zè×,¹¦Œ–¦¥ßÞpij¾—ñÒº§Óſ׈iõï2dVþ70fΛßÄ ijÿw5M;¿‡as~[ÿYãæÜ•üm œs›ùŒœÅ©ÿ= v¼¿›±³ØâÜàyÛ-p?£'×vÃç­­ÿûŒŸÜô  ÅÝù+ ¦ºÿ€!t¶é߯Öû?× Z²’¿¯QÔtàŠaô÷íÏÿbãèÍõ;HoîÈÎH:¯_ÿë ¥…üžÆÒ"yú= ¦óÖí74š¶ç¼¾³åÊö½Ip#O‹iÞ%pòåÅåÅ·úßââòù»hÖÂp+r¯•S„h!ZÔÚÿõ ¤õ"P©ƒ“[ e 95¡Ó¸äd@¬ÕC(°SB¤]%RœªÌ®ÄCù7H^hgèWÏŽK¨]BìI:Ï4›;&úÃ&»˜‹EìÊmQ£O3€±Ç(Æî¥‡‘\&&»àÅs1ðô©ÃC~ðt¨]h5rÖ:3ê?ß„H1"¤oÙvÒÏd¶Ã §M¿µµe›y<ÒBÑO‡©£ºPHWxkÖFªßæ‰Âƒ¢¯6*J0ù ¦³Ï•b ÞC?>2Ý5ùx·Ébn à`6ªºb-AàÙŠJRo5¢’ Ç[8—LÖ §[&RœWò_þù¶Áþa¿ü¹fàÕ°Ðh,H¢4\íöÊÍ©V­;x¦{³ j¯Ýåïÿ‰fý²Ühürþœh,©*V+tka¡zÏ)a¿¶Ò·e­,;êf“˜•dSÞÒÄ,•BRfó<wEÄi:W€¹5@¹i?\oV ÝØ*Ë_­›EO„ÌmqÈ lu´L¬^iXz)üƒýÛ%¢.óY˜³Ú L¦‡· îï¿nêOîʶš&l_»ÎÌó²NÉ¿óúá³J´²rr9§Õ’¹,íÉm³–½y’–½Nú;Èû*,X芺fuÝ­™è°™Î§ «}-Ñ}eP©_¥9’‰L¢ëóá:†ë¾'ÃR·hòU¥³î+*:#~÷ÎÖ¼bšŸö¶>¡ö;ÖÜH‡aåjzuP`:3…9™Ó ãYì†MÀ{ÿÜÃ,dßèÈŠ?ÿÎ=B{kÆìûUµªéƒK†$ãQG#w£"€36JEÕ žâÌ¿6º‘ž,Æ4õzŒ{E’ª7s¼Ì¢˜¢ÀqÚÉ–Ç/£C¦Kö󭇳¢g9éøSIÙ2PVŸxÐÞsK˜tMFTœÎ9ü^()?œéµÝ™·•~ç.lØ-(›ŒÕ&P3å&Aª—­Žfˆ~å­vA Å~½]˜××·œa/è±_í4Õ`»m>à¿ÞrªYÚõìlAEFT™3*›ƒW’9; ð¶/)‘^ÏØtHG";";T‹d‚œý|UTRÿ:ZFT`eÙ0³çñþdÊoÔ-—tç:uϺ@¨0K•w‰ÌŠ<À‡ÑéD³qlkQ׳}M?¼[œ×û¯¯JP‹ÅJ7«ØÕùLî ûͲÉýꨠNÇ–°q¢’Ï•,f€ÛŸ»È|·‘ ‘¦ƒu½Nw½L&`Íg³ß9œrQòÚ&Lb&Í!P¡è¯~¾õ޳I,þÓ|Ôx´´»w¼»R],ŸŸ\óêê '-:­]ªË Ù6¾ÿªÕ¯èßÉXD;ÔŠ 9ü˜Äí…wŽÂ»!‘`4àYuŸ¬ÍùdMO Âf¸‹y“ÍöŽÎ*Ëÿ´÷6ñærmùŸßÿóO?àÿé/„æH3l÷o«Õ’ɇè‡cA–+©"Áµ$׃ú¸w^—W]—ËŠ<äªéÿç¼Þ-©s QD2 ¥Ý@•rùaÃtm ¢íŒÔB³ˆVÛ5æÀK 6¸Ššë¶¹0ç^’ÍSö ×\(Ô³Z^|;¿žÕb=kóëY½¡žµw×Ìa%ä3ËO˜@±y–O s ·µÒ bÇæNàmÕ¬Þ¡šÕÛ«Y»C5˜¾ žÑBT(5*¶4;Ê™1ÍŽ`¦¿³½C_0ËJ°ng2 Óº7ìþ,+3¬•ÿú-ÿëÔãq’×›æãÆÊ2~·Z¬ç#Ýèü&m¬Ðëëø·ùäñŠÿ/þ[_]]ù¯æZsuc¿×þk¬ýWô_ÿ›þÓÁØÿ—üWY~äen>{öÔx¯½Žóœdæ)\Óóh˜OÒ ´¾´ÏˆfýìÊ›Gô>з c×8aiM“ñŠ‹F!--Ê™¤¾üžÝ³«D·Å¶­á5ÂÜGÀûƒÒ½$1Z+êô92·BVI²å®KÛpé˜q¢, iG $bfá€L_/l.ÛÎ8Nœ””åÏbÕ~¦Z „ç• †Ws M¼4$¯û³†ñûUßBŽ»zNÙnLÃiŠ;éäíU‰òs™wÑ=˜j›l]%‰û—!Éôhœ¢^;¬®éŽho†©ÅŒ§é_in§Õê¥Ä²¹ (TV²Áš† «‰Œ´ìÁf×k!†ÃÑJÚ ½Fœ’xñ…½èÝ2Qa#Ï.0õ¢íJ¬ÄÅBñ>f°ø–¼ y¸Dú#ÔBçÃdÊŽ‡ÖÉÓâò XË,)0Rö|•¸W‰½ãÕ‹TDç" [dwQD8q@GԞ¤\‹~JÆ™ñ ziJeûhæ?  ˜®"IÇÍ^(5¦‰ÃWHÕŒgÜzHÙ#¸¦£¾`„{€ì‹@Ýà­IÿæéO¼{Fä£GxëPT\çQâ‘¡½ú¯)[.b>çtÆM+fU:KÛ•³Ôq lS®×©ïßÐ§ÛÆeµˆ¬ÐðcŰR““‘´NŽŠe¯Ðбôrÿ`/zÔÕ3Žák8ü”´&v8ý!ÐÐS(„õ£¬×ƒCØV´â=ì'Cv¶¥•Zâ‘mmñÄ›åg£žæ7Ò§ÏäRsõiÕh›Qø3|ãðQÆ Ç„oŸì¶ö^ï½~îÕÅS¿QòôcE–ž?[ÆT´¯'’%îj'>´¦?M²<]²•ÕuxÕç¿S=>ÈÀ¾Ð/j~}µ¨7ªÎôzI§ê3š«jôW’o7£¥+Z—ð==’ñ¢lêG/ÍiR©£ZÉÀ¢'a/‚¹ãWÕïQ¬5À,¾.º~ý\qÂèÌDzžæ?ÁL±Œ~Û.>/¸iz µü%òf±Yõ€`Ä·ÁÎ(‘˜m=E’œUf ìXù@¶œÙ(zæ–d§Ú6E«áÆ‘RåƒåŠp:dÔþ@uOb³úço<7ZÔ`_>ÚŠVͶ ë;}³³³wzúœäÅÿúã¿ßõ¿þŸ(5z#æÿ6þ¿¹¶¶¶ò˜øÿµæÊúúêÚ=o®>^Ýøƒÿÿ_Âÿ{å—vªÑ*ItõUZaT´Ó¤wÙNà ý‡´ð‡´ð?TZèu“^ôõö7{œ_çÍþQ ‘Ö¦ö—ü:_ž¦YãâËÊ(ozA™Ã½³}úÿÖþa¡Ø0¯:YN‡·”<Û9žStÒÍ/»ûb¶T·=çûí“ãí·–‰Ç£xmÝTŽÅöNÊŠrV±d,¥á5ã}±`_.ÜZõÎÑëãí³Zh‰W×ÍpåÎNö_WŽÁ$ó9cÃjï휔¬wšu&ýÙr4ßç2ó9IxÁqÛí/DMéÜñ;û¬×jíöQ?aóÛå×îð“¥ÚŠ`ó°0_·8Îj 7>œˆ#Ô/8¤Hâúh¶ºñ$^âê^0$Ú®ÿÇßÅqŠi`7¯Un°ýÈñË:ï“ ‰K¦L-’#Ká òˆ†Sè Ënwì {KWžh‰;wdÚµˆ]yè×÷å×t‡~<ìÈ2Åí¶~œ&ÓdN§°Ôì¿M»’î‰[úä÷L\Ú$-ø ½Pî‘“ˆIž7)·ÇTÔgï“!œo†:6§ÊÊŽwo9æWÉxΦÃ<=G$¤hbc7uu$ÎN½ÂÎèÆâ·÷š:ÖÞKÓ¿vÑoo.Ÿb›¡ž›—˜váø:zÄÿÌo±ÐµBcCdŸýí»qtè ç€ãsÄçðæ6¥_ËIBn±ÿ¶:Šß¦:èèp¸s9 p™÷ã¬À×?bÓݰµJ‹Ç¶8ölIóš±|Étš†GÔáØŽ„‡)O㸰¢JŸÆ×÷XOiCfç è¶a@ÜQÍ5ÀŠTZ|°•ɇ˜AàØ³Ž·¸H`RŒCÕ!^u‰²-•ì¢Òn¿ãD£ØÏØ»¡“G[ÈÂ|UÿrrIû¼Õ¥æïªê—øÛ/£ÑêèHšÏ¡Bº†ê“;‡àpQ™)”XáCÚ—?«°FJTÌQŽ6TGÆifYå €h®kf®Ä¡W¿Ò( nÞ¨ýÌȦšñƒ/¡ „î‹8D®Ð¸9Ñ=Óˆa/¤ý~jº¢ŽÄ¼NЉÒã,»Æ¯=ð7¾¤ÊKWwˆ©>—¥ñWã‹-÷v¹IÒýs~±d?ù3>©>’e‚iÀMÑTU)÷Åþê«:.œ5[/?ÊlAôaTC¸ƒÉ¥e •âèÄ€Üïþœa_æp(·•wláÞOæ½°>8[æä]Ò_Kr ©¥^+ާü\|T`m!74Ën…E|&ïN¥f¸ [jæ“þ¦ø±S`Y_HðQ% "C&§à*´B6VÑU VíKè§ "÷âÉbMG¬S ªF‡»v²1 )}•–…­ôt‚wåpg]×Ûƒ%Ó(ºà£¿“xúb{7XÌ»ÿI“B¼Ï‰šÃßÓX«]'úLÇ íVîéZǶÆn"mÙ8wÆ„;Éaó— voÇËŸ¶/ ÖåD¯&s(=§%¿z%ëÒÃ6´hjÅ ãOx½V°86â©aM±@7 æÓ×Çõ7ß™ô6ûé½³·ýj{ÿªA%{ß½9Ø}q@SÛàåfmÓ Ò…už¨bòb2m.Ãsœ;ͱlîm\Œl°|zö÷ÓåÎyZo§Ãe*»z1ôÿŠ’ø ®­åi>^fˆ|Ãß5þ{"YcÕ'Ës…ošü4oŸK¯ïðHrÏy€•2¥ ‡IÊpkþçCz¡ó ¥¬†híU ¼%Ó¬X‰TÇáÕâp'¼‡›•À0Ô|îéH¢°‡è´þúlkNÅüzn«Ñ ï3Æ@,ÕÌòr¹ ·|^SXož4»¤ûöQDÿ+Œ8G>°ªi%õ/Q¾…Ë68«’÷õ/‘F¡{¹D-q¥,Î~Øê´ù^’ NëÓxE«wûý†Î4íQ„ÖkžûÃ6FÅ`òèÿõ~6è!§’“‹–UÑPñ 1îzfÔ»Íèç6º(Ãffg$gÉüÑíËRPd1YVÏÜ•²Yž[Š”}¢”Ä)»Ù†2ðœñEx$¨nŒd´ùŒ³`½v‚!F`É2;Lðݲ±[ óÔs Ð:·¢ÏÝÞ—Þ|Ÿþ¸Èãú—?^À×ã—_"óÀé8JæÈ¤¥ð[«™–õZ ÇùyŽX¢—»­ýÓÓ½³¥Ù>xŸç<â×úÀÒÖ^2.ºqWsSe}·„00û¸Èž`r粉1aµÄدd$¡Áxoγ‚>ϯ9p·ê1Ú$î3@šùÆh¹¢«Ä¯¦ËqWñp"r0UÙ0˜N˜·eû`r¥}‘WWpÄrU€Ùºvü”ʢÙMsÉ’~ö=âØ£ °º~>#ª„Ø£qå×ù$(æûósvŽó¸NZ÷ƒ“[VÝ÷‰ÙÁ)—±XŸ¦µ4ÖdûN2¾ÇŸW%:ô<ØÿÏ#C"ÿ þEšå–}øÅ¥n:L½°Ø¼ú´ä0÷ûtŒå„ÓœgÃÀ/töÂÒJ4,ë-ùd±8òàA©uè%üðTÿ¡}âìià5C–Xthú­¦¨Ø+é÷‹_rUW‹Ï””vÀ~íñÁÚø>zɆÐéK¶!sàëÃÀ#Ê9K]ZåŒ[mÉªØæÍ bÇî3™=99<ªVgná@•ï´÷ÐÕ]U‹ÓP$drfv®‡„è¸CÔ¾^å sð§¹N ûgŽuÉïÌDuÖ/ÌÃQ˜ÙÁ;1hY¬ç¼G¥£Nµ§ÜD¡có¶°?yÙn¸y3û´lÄ™-ÿ±´wyùP}%‘ôa>HÎSäFp¤]· •š,¿™·=nYéÿ”á3ä†ofw˸åRÎÍëópô71¦K¶UÖþëΚ»õ­¬ô¹ê•iªcÎÜ'õr²ò…ëÀ¿¯‚“Ó‚Cp|ž¸î¨iù‡¦ª™ïªa#AoÔ¹Ú;q8\Œ¸º×ÚÙ>8x±½ó÷›<‰+ÞÆµ LÍXüa}~Pš&. ¯+ 8jr …%ìgÙÈ?I+ñÇŠû߀Ÿ f»BÏ‹_°ÏrÉnMíÝÿÑXnP Œ“Î%Îá|¡´¨FÀ3_‡€¿µN^[c‚Äáãç£ÉO¿­;I~ú5ýz“‘]Ê$Á¿(8gÝáÂ݇U®ny™­`¯” \öŒÜrIwÞ-Ùˆ¢Ý„‘8ü üï‘ùR3gna5±ðEݘ)[´z‚j·Jfäû•¢¿ü%z:³¿”}Üüáù Íh?CÍßl?f–2ÐÜ»Šª3s|Ï-b¯P,NÒ XtÁJ×Lj¢cG»G›&1GšßhR¯#Ë õ–‘qd?<½Ÿ['ºtÞ¹†N±I6Ä_y Ÿ”ÝJ‚ îå¥;ÌÌò…UÊŠŒ²òõ)34åNô«|Ãe2sv?ý” Å·7»óíòV|3ëȦ÷Rqê?¶ñ«…ª¢Ÿ3î ×Ûßíîžžþ7QÜGsTÍ ÄoÕñM‡ ßªX,hfø™Zk ïZIJһõy/7èåû¬rcV]ñÿ`Á°„wÁ¿³dèþÍ$Co,ÿYÉðË{©dXºä¾•û v§„ÓWODQÙ FöЛÏjµŒù¨â®I!¬jIêÄ~wºY°kîxª%lÚŠ§Ž/ìÆ°fP¢F/¤4¡¨ú%GÀ†Ü‚Bpbǃѵàj øÍ›ŠmÅJKÖ{Î\ýþÒ,‰¶z[`™¹^¥} y°êôsí‰þ Í–[æ˜É›ÙÃÊM¬Oÿ|¶ôFržö<¬ú³ îÈž¿ÌA?º PD\Äd‡IÉ9ŒµÑ¦d:¥Wä* µ0Šj=bé›d vAÏn I'HfkÒSŽ’1 ú‘Läau£,Í3ħBtf òˆÚ‰<Ø’=8›äÈ'ÇWót¯8ÃÆº(Ëö¥5€x.„_é€]m¬‡%6 ‡A—‰*p¦>0^‘’¡ß(:”¹&žGLL¼Ø(zRdÜìjárÆ(v«}mêý~ýY.–³ý×{GoÎZgÛ/öZ§ûÿ½÷C5p³K —dS¿šºÝúƒ¿q{%*ךÊvÛr¥f]ŸfZ“Ϥ5ÆŠ—<&\êþVÔ%6\h@5@+ùš2pÑ06"í…F~û<üºz³­3-×ü¥‘^×{:­EÉï‹/ÂòO./¼×ÒùœegÔ@›í¦…›HÉÛ×|/§ê)÷A¬×ñ\âõ?=.\¼ö¹0qkPÂÕ KöS <Ò)g铹ߞ8zÌ;ð`2šauX4“nžý}0ha‰É&Fq0å<µÆ “‡$lñX Ö¾~¹ÿÝÞîéW‹" µüj·½#³¿[ƒª`Èêãv:©yq^Ìtç~$óeÚÃþÙ=SBPƒ´Cgú#Iž¢GQ/’î²PaÉû.u¥]G“‰?…¤koMOÝ•cȰQbÝ~kü˜v¿§êôÊ 5Ÿ¹.>ùª¨ÜNøKÃkÌ霰××4Ž”Õ(i· ²_@ À{æñƒiÊsüÍ·Ø·b"~Ôú™9—†Q]ÇÛïNÿû¹%WŒ`íÑyQ?fV¤¡ÐmV[ø=ú’OÓiMŽì8›d¬_1r24y­ÀÝÓ¤:&YÖ5gzÊ@é¿MdKSGÇ×n;âî–»%yxºnc0ìÍ}.[æåÁö« aÌdzã·¥’î0 m6k¨”ƒöëݪÇPÙG/N^“T<;Ý;ùæåöþY½@V¸a››¸3 ËÕ*ýú¨t4[ÃQýs«0¬ç•¶ÀÔ»5¯NýîÇ;}Eµ©-Žz\¬UÚä¨âË/£§´Ã£•½Å2¬¡YVWPRÔ#Ö§{g­mÚcoÏ–‚£/¢ÕÐ_°Ðd¬3xY §«¬–¥Ž™FgüÒ­ÇëøúVÞÉCw\?Vü³wž!o޹#»¬kWo%¶½Ž%MbÆùWõK€ÓU<õXÜé$£‰wÊM«Ñ¦îŽ ê g,q„ºˆ»TÖV“pÚ¾(Ë‚³¶D.rÍóòÛãÄdî3š'þ÷¦¹ÿêðl§Z@õôªþ%çe†»Õ „Ðû p»¿bQ>Vf—Æ,ʰÀd 4U†Zê|Q;˜kÉ"i\bámL"Á%Ô“ü•L'Ö­dÍÂi-̧™N›\è‡c#ý}£}Ź洦ëþü‚ÅaQÖj±4äFÕsgXM)‡Ÿì½|ƒ“–‡¿q±v¾ÞÛù;ý}\²ä3Ô3 ©%”WûS¾3|D¤â¢‡ÐF¥Âš1lW>UN Ϻ»œ‘ÈgîÞôÑx¦ÀHL;¬n7z³BTB!Ö††2å$_sŨßØËŠBéóO4 Ý׿Üó¯ÄlóóݤåÑÓ«xd–a™Á]eÌæÅYÏéë¿YšÚÀ”¶â¹3=§@Û›^’Š[P{^[´–4çæäé’´P}î¾oßþ}»Z&cFYŸª¢r¤Ò¹ß´í7m‹Åî:jLcÚú0´,ƒî7ÿÑ7.hu@!ïkÓ‘ülàpÖ¿“KzkZu¯ñB8ûàõGׯö]ûÏëW¬ýòn—ô+ö_Ïö+~^ˆø}àåî[~›’â~:Š;ãTÔ¯nl0˜ÓŽÂÚªÀʦa«;2kÈ6JµëäE£Õœ%DUAY­¾6î¿÷5ÚOú“UìÙ¹*†ïb™%ÕëÔM°à°d“Oˆ J1Ù¢‡Ô‘D-Õ° { ë½>c9‹ì#¿íš*°¯Ôe†GÿR’o!âwâ©§®ä&´:NQCJV..œZ‚>IA”'*ç™ZXsd¬°q:*¸O2ÓIóhX…Òãô¹ý)”ÆÑH÷¦}¾4·‘ê-z€F‰àó•±¹ nQÿfjbÁ¢½™ñ°AF÷äjîÆ£|”=¿Ó‚KOU-ź¡q‚ÎßI¿'J9ÄUð–cúš7p¬>Ø-¥%h=¬£×tÔhxÛ@†^våx›!ÀXù=à.™ø©½R#uUÎ1SF½&^jàST’“Œuiýg‰ÆM?LÇ@ÖVÁwmÈÕ~DÛb1硉°–H9'p+!A!jÃa¹æhs•b¥ºJÄvÄ}`éÍ•qʺŠ:@¨Ž…iˆ®;W|N"ß…ñ. %•†âIü¤è5í©NÚÍFÉs[/ n¤jµ>¨}úÓÎûk£ì¥¦Ùˆ"ƒÄÓÑRr^s³fè˜ÅCĶƒtå¸T©Z\˜dæšÉÍ‹CxdìfÕ9z"Ãp’ÄÕ,¡æP¶è=¸…ÞFt¢çÌmý;¦š-û­ÓÅb]iíŸîD®¤j˜‚YîÛ_‚\ë£Ýéw¸IOëÛÍf‹#2"hP¥_±ÇSÃoô"Be¬¾5ƒ„ã/²+ ÖtH‰Ñ=˜âÖ6kOžÔ7ȺÓ~L}Lçr``[5}æ«ÜÅÍâÝ †÷/¾Xr=jIð4 &K·®zg1Åwíy­œƒo½îy¾…{¡(¡~A[6ús‰ðt»÷[PÑ~Ǿ-à(‘ql޵‹@¤£ùÒÜ?—ÎCý‘’/“2ajódà?˜£{}iõ-^zUf†ú•iÚ‰p5DR“xÜOésü]’!/у.k.–ÖªÞ.ª=HÌ&b·*ù›h½ñXGb».A@€•(£Ï?÷Ïíg%$œö€„ /ͨ·Â¢Âf(­¾n-F(• [[78—©Î±GÜ_ùY¢qÛïÙT{>}|Õ‚ø›Û©n7>Ç_gW ßJð’«xNœ´\Õr5KÏÀƒºÔ͵Rz¥,Ž“`³ÈÍb®ÞZâòX¨ÁlN:Õ×Q7´Ë!úV^Õ!oP†8Ej¾{Žâ„‡0ÙœËdtÇÙÈ;hÞàq6êÇ¢nS®ÔX¶1ÄØw’ƒ€¨“Ä€ÖÌ_Õ÷B© ŸÓß¿ú¼]d½?„ц ÒQšß&ŽÉg ?,è­çº5{ñÏ:åÑXüšTFÑp+Ëþ™³è÷t-?Ð(^„]/ŠÊâ¢x³ÊMòJ0Õ_ç…2KOÊC”FGþ€>ù{'Ä~úÌ`_”ÌÙ-j\IÒæŽÛ”ÃQDÜm¸Áƒw驸 k ûV2E{1¨èŸKM™Ô¾V i%ÕE¶¨µ‹ýBrÁHW×jõ-€§ I "ÃÍ]1¾¯DøHË$Œ_ÎL‹Š×È'`sÍaäÂ!……™•Dâ©ìjÈIžŒç¡9øžµl4e¯ðt8SCx2{’J?+Äß„è Ca)@ÈVhtœù††DôÉÚùn-øFÕ„~G0`¥TË!Tla4ÞÂ÷).Í`—ÏA¬y^rFC¬—‡¿Šã©Ü™Õqš;'?ß7TäÚêå ø¿¶ò´Üˆèå;Ô{–õšï‡03ô"ÆÞþw¯÷6³ â31ê­!ÎM€/b”}ÒÄýFæ>:ÍIxY -HT> :°‰bSÄW11—† }~ šxQ¨“eMH;똨†^?»B®¶ž'¯ªw8q’sÚë—I­bC»¡ €™;¯§¹ðÒÜmÎ5•žsWK6𠳯tSçÙ°P¾[¶û¼È} û]ö'3r§=ü5ŠŽ{sLZ.•]oösE¥O†—GÓ!–è<é–±µKÒ«¿h˜²áÝðÉ/¿Þ>i½Ø? sür8£]»/¿Œn(… o´PeB´2ëÁeëù õ?-‚‡U|ÿ#=m[,£<·§ÉO ®Þ5[µÒÚŽO’X¢Î{ß@ä{–ÚÂýÔâE~ƒ„åâgÚ¿¬Éà MKp¯ˆô,}nÄ™Y÷}ÃoKùô”³“uS5ï«›âÊÝçÿ|GG„¹&ÈîN³lUÞÅIÖ7f®Uõ«æ¸`Κ3Å7»ÁÔ{‹ñÌæ±!¹õ0¶I@zÏ{8‘& 2‹4É¥¹M©PÝüº°‘xÖ&Y4õ.Fí,#:0´‰‚4Ó"X€~¤çýkI{?ž°K1oC¡»K5úèoYlb½Æú¹/éüTÎ4dgAd«“7{æËíƒÓ=*mòCh’…¥7§{-N§°øJyÁÓj¥RÈö$Ðö™vxq6Ô¤ïÕÃx/wÏZG­Ã£C®³ªÚdÜô—Óaú!Â=ƶo±nd?¶‡²ÖVÄù-—Ìd¼l½Ú;{ieQ0o2¢Ï¶ì€ƒ\ Åâ§R\jÿ%òúøÜgšïRš¨óÿÛ+_ûéÁÎÑ7­½ïvZû‡{ófHr…¾Ü§ÂûGfz²~O7LLäFý•¨þ¦ho9Ѩë­TŽØMeˆÁ9QÞßuG£)¿Ý>;[[•Șñ =08ƒÐÁß]i¿­³,Ëßeåß †7^„¢?•3>}H;Û¯÷fæy{žÇÒùã~x“»þœÎéÏMÝ¡=ƒÎŸÑ¹š9/’£S¯+íÛº¡4#¹^œè‰ÅoÛÍRÛª^ÚUí¤ÕÕd/Ã, {Ò e]Bï!Øb© —©É…Y€HìIf ϧã$HJè§áËQÓš7¤ >õç¿6˜=}ã%ÓÍØãjJšG>fÐáÐ`ÇubŒcè¯ <ȬÙuNÒ‰$ç€ëj‘°ÓD€þ*ʧÝS´÷ÝÞNÕOɳôút÷ˆýýíX¦X˜QÕ¹v¡Ìb~Ö/ùt¼¨&%Z†^íÖ"¿!ONÕž×›ó(—ƒÙ€«`2ñú›¿É=ŠNXA^°år¯?áÔ%Q©+| >8bk$ò·øÌî>=Ü}ñæe ¯`BÝ?¿­µ’²zHn+Y3{•yÕ‰ùÔ±žì|sϱ–4x÷á–ž?b½!¨—/öwÏŽv÷¾ÙßÙ+ž>v­nrÙBêíïW~0މ¢Œºaì~­¥œáœ6j3£ ßW«U_Œ?b÷ pËÄÎuÅ™LL¾Ó|Ê^, ½x÷Ñét¡þldÎÆï™µ¶¬ÕÇF8‹ÜìahH „[CuN›BÿÓѺ븪Ø?çW˜ðµìö¡Ó­ÛGœqÓ¬iµü+¼ÐÔ«[ÑÅ$öËúä«pÛt÷s:%SSYŸB„{oK¹Yòf¦hß#š‡Î`4Û­ êß6tð]gmråû„ S?Ûré³Ó½Q6ݳӽ‰Ü˜™ïç®ÞÎèÚ«W¾GkQÉ *wíÿýeãN‹rcâ4s㳂øÆÅª¬ùt'×È‹_&ìîÆda²*wH”¦í÷îìõ/=¹óצ·w/qÇDm®ç:7v^žÏr^Pþß<×¥ò¤@Ùêx:ƒ–/{>4™`~á»[¼½»eÉt8K¶wI¨0¯«¥_*û¯_*;°ËÒ;/ÅõúõÉÀy¦ +jlÿt…>ŸÅeËãÛQÙîÁBçxä;#xéºÅé@3A–@&…îleUb¸él[±ÉíÎ&—ûÇôL>P’ìž ÃØžc¡ÐqiKÜx –à>aá Å aSÃêð^ ôˆwšdÓ|N%žesêöJi¢¤B&øn ë“M 5ð?߬ϻK>­z ÑÛþºnܶ°·.ìÆ½ö¶ ÷ÞK«þÆk{C­Ÿ¶¸ãP²ºw_ݹ«Kì~<íO6KØ„9â£ïȵÝùq ¡AATÆjŸi˜1¾zD¤fÌù'{Û¯} `>׈Êh8Ì(2ò9=0j Ç0ÙVw1!Î,›{£q“:Ã\Qêlç¸uHÏÁö?¸¯â+¼›r$KÞ‡ñ9üéúç; £u¡Ãð2ŽzŽ« "/Á…¡VÙF<˜?Cìºâ|8¬d2¹ö TLžlA¯ì¥lÖËz=,/Ò\;g…ýFW1ç;U¤vÔ€o¡Ú@MãÜ,Z]²‡ŽËÅíàé¦3ëó˜Ø¿*j?«”ÙûÇÇ'GgG-v¬ô&}–›³4‹JZ®™~‡Rñ¯Þ¡PIV‹8Bà±äyö Õáç"Q»Óò‰œª­ÏÏ+ýDóÔðólûmSáfƒj+õ;#;d„ÞÌCT Ï®Ï »vpO˜»¢lÁÜ$ZˆÂWïjzÿ6Ì+"/§ÐÒ™§.õo4õfé ”ì ¢Ê“äî{Â|þ[í SßjOÜìÔå%áº-ºÌÏTXê[½¬èÃ/¾®ê¹ÎXe2³žT„©ð¼fŒ‚6Ñø°l13³ô.ú?f»|iæáÇþ<ð*—XH*,£+³LÐ ìg]ëÿófïôlÿè°uöã=ô¡êúj6zñÓƒíÓÓ·<®ÿc—Ì­Åii ؈Çâ‚Ĩ·"1o‚xvXŒðÉFøm„Øm„™PIrƘi±+4ÌåfWÄe»âÆQåsãz–¯i1«[, 7˜Tq“é<Ç3}¿wçÜñ§÷~îÎŒ½Ý&ŸÞ¼;g¿/ß¡ºAvõ&AL{•lºq ²Á‘Â5«RÁè˜c¶¥Ã*ÌáÆ°åè® 1gž àÀ3“<¿¼ ÌŸ»Øû¿¤·éŸ]ߎMh–² &¡H‰NÄêp¸ò4Žå®aϘßs®Ú›7‰×Š[Î &¦eÚ£v)¾/N{¹ÖÅXÉ›G"ã?Ÿù`•‘®—JôGªy\¥Îª~!,ê9ëp3b(_µJu×d!€¥° MöB—+ø™­2GQ>Ô{ uÃëÆ¯ìÆo7رÜ}uƒXnžþÝüõéÛ0 î‰ §EÀæ1Êwà‡Ó€Þó ‡¶0€;ÞöóÀQ¨³T¡Dm+ì7p'àÛiS› &è#çAÉ% MуÒI!áÈï†üy$„e!8@«üÜF Gþ^vµ +‹áÖPD‡†D|Nè÷lšGM›—.%ª³Éd¹‰ùˆJ²Ù €Q‹„á³mØH’fþF¿ölvo>’‘›°CN— 듬ÞNêçØT ? ¨ $óiÇíþuYe\Á ‰‡ŒùãPÂ,\†ŸÇ¡æ¾vùßJÔ·Ë#V¬ãvB5p’Cvf½±® ›ZmR9@«$ f.&&ˆÌ„¸¾O’Qùè|Hßh<rnª|e“ ªKb>9Û‹éÄp®Wä²êAòb1àc±Ý;Ïl™î¥L|§L'e•q‰œÍB ›I[ m÷óL²¨C;5^Vg¿àõBÞc“ŠBÈI1´€EEw»ñð¼Y0”¥tâ2ÈÂàW`Sjª‚XbBòšC§£/ê”ÔxGs\:žÁ›±kN’Jf"ÌæaJ„9©\ÄlÖè€Ðµ|¦`¶?—ݪû.­«v´Ýܧ2$ŒÒzKJ~¼1+5Ç(+JOСÜB ïJä<Ø0—Úri¤$`ü6Øvz~.e9ÒÙÝäðÔDñ‹ë‡ › ‚$W:Ž¡kJ­¬Ab©R@6@d?‹é:®â¹ ð†ÃoË9]²°U9àaÆï‹$†nl1kDßÜ•Ä@ÏÎPòù¸áU f7Ù@ÃFf39ó¡5€u×(ŸMzÇóU„e+ä0‹þ·inpèHÔ£–ÒQ÷|‘(o­F£qÛAž“”¹üRÌÅìoõPK¿?¼Ì Š…6”]úœú—æ¡ ŽÇç5ÃÐó€¼ÑCžSÜ"áO¬i'€w;Áí§ëMœÄaæ§<jcœ9ÑsÇâÑ“ ¢:Œ[’D€M‡}„ºžžmÿãèxïP®î‘?À”ôÂ~J¡c]Ô—–v¶ZÀh¼êZšƒ]ÆúÙ=4oÆK¸{ äy’˜Ô†álhŠõ/ òtç JsªYj‡ï °ð=úL»UoGÜàÛo+¬f%úos4™Éx³8D F 'ù"éè´@ÔkOÏóÒóâTwr¼‡¬ä[8Ö”štKf´Äzg”³±Ø¤XºzvÒECâ@¹Ñúï<£²fáó|+ÏÂnŒ©VÊ}ô9ˆ€ÛÈk7»ð{AÞ¹–àNÿ×ÿ}ê:–°Þl47V–e9i-mà]cí×·±Bÿm¬¯ãßæ“Ç+þ¿øomåñú5ך«ë+ë««kÿµÒ\{ü¤ù_Ñÿª‰ÔÁØÿ—ü×x»P¡ÿvˆ‹3êêJs$/ˆuxEÄ!G9çÛ_‘ì×MúD:N6ø²bŠ'ch»·Æ|a PiOÑ·»DlÇ)Éî‚ìËó¬7¹Â¥³%hL†åg=ö8’¤3ø¦vM:6.ÞƒÎH@™¨ËçÄOMÀº«x©Á±ø‹ÄmÜm3J.L\^Ú¡W£  XHA(ßg*¬™ãÉœÂC"¹˜©7ŸŽpmEƒ!Ö\SŒÈK:ã×ýÆYƒXÛœÞÚ\:¹bŸŒ¦mâ“ÒÉ5z0¾ˆq¬Ìd£G"5†n²Ú壤“öÒ ¦ãt2I4“¢b; ÔåQ2y&$#çfa¾Ót·Ó>:•õ¸°j^´éª.l¢"Š,ÛB 5†l-ÓÏäÈsrSY0Š)nÄxŒ¿nÈ><ûZå´½³ÖÁÑÎöAkwï›h-ZX[!¶{˜ðÖ¦ïN¿Ž·_ïUf©]ô¶½`ìî ~N:3†·Œè‹Ô¤¿` VgÖàzOÿqxt|ºZi ià/¢é°ÓŸv“è/h¬qA'æø/Ü5t ¼fßööõçÛÞqM]  _}„Wap4}Q­4z)wcwïtçdÿ†¨ R ¼í½˜m‹J8ÔF– ÖšZÇUY¥Í <ÍL'î ¾i1O'“´VÈ“‚ÊÎ3½Ž£ŽlX‰èÅĤA<·ìzÎB­šúE}Û F¸²€q;‚Ý#š%9j¢Ø9H‡ÓŠü8qÚØ—i?9·r{´u+¢^LL]ÔI,· Ø†g²IzípÙŠ*0^ÏbœösO”÷ÐÃÝÉÊ«¢¬¹ŸHbNÝBoÇùÚ€GÆ»jo/Ú>8=¢sRÜ4éh`ãå¯6ä6üÑÙÞi%D:VHÜíJ ˆ0Q³ñ¤±Î%¶ßœ}}tRq×ÀlÖÿCø?kTnt~3Öè&þ¯I¿ üßêÊ“?ø¿ßã?Éêg™¿æ³gOMzÜ×${­%¢5!¾lŸîžtÞ(Ø1€Ã¬ŸpŽáÛ>‰dMÍ'óTú“Ù?*ûÉÜŸWöžÌ§6ýTÞ#ü?™õó§ú>œ•ûdÆÏ&»7ßç%]¾‘íˆ6Ãc-˜ûo:j\,ÌÝÛy}\a“uøý’c¼¢G±Ï‡EÚE0>[ßëãýªAµ FéGZÁ2¬±³“}*–IÙÁ–aå\ZÆ’^Ô).ÉÛ*|ú¡L4ˆ+À€ÛÄþé›ã㽓¥êÂ说]úÙ’ñß›QlÍØ\dÕ+Ò.ik‘¶+ÅOö’Îj;¢Yךּ¯>ëX°Tëø18Ð2bY\°Ã²ÞeÉjf ‡óïpvõ†vùjÑpî Î.áЮ¡-xû2ÿo[½?8­ÿEú¿a÷·PûÝ•ÿÛ ¦¯Àÿ5Ÿ¬þ¡ÿûéÿ>üC ø‡ð ðpÊ¿ÕÇÑߦýkÞ׳Ê?šõ·uÚÙéF¶(f/ 6‡ÝOŸ×jp'¬×[z$j<5þU5tömo?Ÿ³*×3ý)–s<¡:þ¤ýœ?,¸U¢Šö´ç×óº(ÿf5‹ÃîгMü¨M :Ó«¥k욨QóÛÂHçª$QµídÅoëBäþJï¡É÷‹se†D;e8¡›t+mZ³ýû¦ÁªO8Y öÜjìs0K!øM#ª˜4?®5£„ÔÄ&${°µ“„©ÑyÌè]§“‘ù¢¢`¨Äà¾Ñ~fŸ– o£Œûþª’õL²þ­Ÿ¶9Á-'(MÙCe&¼QÙ‘:øD¹¨kÇ0q¹C":%ƒ¤‹)E¸k&qúª;Õ”°èŒEm9Éœ&ÑÎC‡˜ÝónBD%»Æóïº3ß]ÄàªcŠéw…G=ÂA5!dáÚ{ߣþs]·Òúä¼Çß…F‰:/öÔqCgxó¤ËþT4±ì=2©q‚Ïtb³Ì©©X¿D!¾^Ö'ö³"é>6‰žé@—}0î¢4h–ºÚðÛ½Û»ÿçÍÞÉ?¼¯Õ-ñŠ}•³±ø¶B­½„G ôû§¹@p‡vUnÁT.“¢“,SøkÅ ò]J«³Ñl•ÃÌ"xI‹¯iW Ô¡Ódo ÒŸf%£Ú9:<<Ù{ùætow¦ÂŽIÖÕ¸S:+œ—¬òZü0šäÃE<ÍK¿ÝÙ>ÜÙ;8 –Ü¢H'v’~¿¬š³“7;ÖöQF5°—ÌOÚŸí+®Û:é>÷¶ŸC½ý•¾i×^¡Ë‘.ü¼˜]6Öºÿ°žD6|H:Áu-ùlÚ=´¼ïŸuÛ«Zè¶œC=õ„fÓÛô'f7rj”áùäBÎ œÆa#ÝT2Í›Æj¶Vž šx²DJYQƒ}±"}~#®X|Èúñ¹]/v³:<Úùzoçïô÷qË xïxâh<ß ýô'a1oµˆè2 û+ÆëI 2‘å.æ.7(âŸIv¯À_Ñ$pÔc­Â99‘·2÷kƒÙKÓ¢•3{CÄñtïä›—ÛûQÿ<<¢cwŒJ0+ô@ Í-MFú^hg+½sè]L¿8Ùh8làóHÒ!8a¼ ©0™éÐOÍKŽwá &ÎðT1|9¶†Ý@êýʃ ‰Ÿmvœôúh–¦c÷g½Øch÷†joû|žuË¿xsº ™1Ûr:îØå*(BT‘ÛK9’ ÒC·XfIJVËðG÷Yª2Ö‰I†Ì›]Ÿ»Lï)Œ{ô[¥Y©¦ë ƒ¯®€0ßD—4ÜZåv‚®±mëâ¨>QøÝt,æã„1':I—ߌ`.áz¸‰Ò®å2Œž@™(áy " )Ü"T ½Ql³½°ýbÿ`ÿì•íçÕæZceŽRJ¤–ÉG\D-$¼µ€`Õ '¹f7Kð‡î­ æó‡f_±ûÑ·Ä› »•ÿ¹ò?Å‘ð”O‚w:l©r SƒÌ¥þ¼h‹&¾eŒwK¨¡6jwæçÖÃú*ŵ®ÐøÄà¾}q èÏ3XÚ‹T>ÛDÚ*´ä¦9f[(+jtSPC"N‡Ÿ»ÑÒÉI•տԊά9”‚ƒžœ¤’Ôyi?é°Uíä}¦e?iÀìMá†;@¾jhÖm(Å''8”*AŠPŸ&ý®Có+6Ž¥^ŸûPN·mžÄDo=ý:t?œÜ‚)[\¬} ¦ìPK6V)’£AÕÑ{@IÂɉ"ÇRÝ ê á¾Q¸ØÂGߣŸì†˜©°ƒ.™­ä?1^gÜx·¢bÂ;k§i+:kŸTPZ/úÆns À›óA–i?ó.fJ™LܱtÈ]é×mmÖÓÜ‹ßj×ì.âf<Þ²å» /66媶ïýj,'Éû¾Z™³ d´|}fEˆ9¢Cù¢Eà:þîö߯·_íþL£sí¿ë«76Øþ»±öde}}åñ­4Wž4×þ°ÿþÿÑݹˆ‡çI?; šºSŒÆ<Ñ+õBT Úót²ÚáBycÔ¯T¾IÆlû”M-­®EG’|Z­T^Œãnôuì³ðM=êCq=H‡°ka"‡)TØzý=°Ç³lܽ˜¦Œ>…‘šŠÒþ`‰O8ÊÊÒ½³—Gowy,Œó&‹¿ëÑsv¥IÆÑÉË'O7ÑÒƒÕÕ§ Vôÿgš1¤½ŒðvSã¿Cð!'IžõÅ®º}¼/vâŽÐÕx©ÑhT£×oNÏ¢$åpuûÓ*l\AƽÞI·Ú׬wî_jØÀ—:8ôï'Ù¸>FV”Ÿ.iB€UT ¢|ÊësøÝîÑëíýÆëþvÔOÎãεqFìc:ƒ²Î!¢u0šH/ÑxÄIµÑœY/aŽvÕ”=¶g¸ÐL9‡•Úµ¥IÃÓç¦%µVc_œaß¡]ÖÂ;ÜEÚkD¯cXºiÈVÎ=ô‰J‡ éÿšä¹©º¨ŸÓ*ôIÚ²9l$ÎwÀžlyºD OJÎNg9–kCs2 VçpA­C]²á½¥Óýbz¾=h>Û ß/ÓÑ‹ëÍ(ÜÈ_µ‡æ7¶ùhœŒŒyÜ92á0Œêožà£íýï¨fÈXT§4„G:—’ïFͬì´P4óLdŧb‚gÌ-;§Žá!ÑFšKÄ0n¢Ö›Ó½ÖþÉ)¢Äxmoq¦*—…`2VW×ýÉðÂWtxºká}Wç/:ã8¿` ¶-OGKÕ¨;e•í0¹’S~t|Ö¢¾Ù9:|)-yŸ‹›õŒÓ½i#4š´{/~op©’Aœ¿'q‰–\ð Ç)mª¸/ÏS6Q"Óƒú¾•÷…QûWñ5‡1ÎûœRq«T%œF½óƒä/";ânzN’3dú‡®ãk6s忏[h Ú{’ÁâÁêÊJaCƲôÕ˜dUGTWVx̽þ5u¢;t.ñ8¬y£>\ÃùúÛ‹tB Ñšjƒ™ æšŽöJ$Ü…¯òBÿ¾*6̽ù[v1ŒN;ÄÀ´iç.À°;ÎÒ.ízñŽã¥U6-—L­šë =kVmË Äò)OØ“Fô\ÇA:|̗քذÆy2Ùåš@b€7ŒXrN_Á4Bj—¶Ôë¸ÛÍ…å2¾ÓÒ4Š˜ã¥âc¾† {˜ãe°g#u ’|cRbívœRMu“~:H'³G ™·-íB”xz’¸oYî¡suÀÕH"žÂØœFåÃüm:<<£!Ÿãè^cyWVuyÿ–©æy?kÓ¥+餭ç¿ã Ýò伢ůÿ~ðúí©ú¾=FæÚ o_§q÷÷Ôl7»Ê£Ã³·Ô½æHßJNàªg±fê`âÿvg:FþÄŒÎoÖ?Mð-³¢ùÛ³Î(½=¶%ŽûÚj7¾ß/Ón´;¾Î»àÂæÍ9ÈË”¨qSFóvQ¼úøñÊÓfoµ³Ö‰–L#GÚº\©~\”$aeÿuæ Ú›æ“p|üît„¥¹áªúP°|¹aÔµéÆ{Ïw2®I`·ˆ‰wr(iÃÀž3%ê0lÊK:4š4þýh $ÍxüãN’a·mÛ^®}ËI7¥3G§ð^ÝGpÑv¾uùÛóuöVŒbäEʨéùLö…ÆÑñ *5t3φ#‘hv©{ÚuG‚RP‰tìu{ýq¸²œ7‰îG=b¶Ldª–*qA˜IC~ŒCi0× Ö€ÅQ¦>Õ~‰Ô6ºÜÐ4Z-ÛѤ y`@.Zc"¨:ìË­š—ºüŒ‘戗C£õ ]Áp ç„`VVÄðTP×°¥†œ:ðY ãþ&$àFʦðÃõ$Aü¢°ÁL\$”8ƒ­0œ˜…JÆ5 :YÌEÅ‘#-b”"ÎöŽ@!Eýz/•2)Ù…¯ÚX-ü¤/ŽOîJrhoWî|¬Ð°’>š½gÛ×ÑëÓov$A‰åú·ë|l “¥ ¢½erÓö¹*­ Ii邽õnα)¶z¡î–!¥vÑ×q¿g Ó4[´3Û“X³žÂð^ ¼HÛÐq„[WïB;:m8®Hs§ œÉiÂ]r_r[ ÙP5”C:Á`S‰Æâ<̓<çÈV;-.ÊÅVosMK¤ó ˆÙtýÛ™G»’7EôÃȧ™Óx¡šOn>é!Q/C/É×i"¢¶x‰Ì¹âE4`ô±xgŠ,!—¨jšpb?w³ ¿k¡N̺+:\ñDH•œ3$ñãýl@w›ÌafW̦˜„ÄPôì‚ðKFf¥»95;àý[ «7ônýšöM<˜{HŽ5‰/?¬:É+î'–hÛ$M:arvJËÆÄ¢ÆF…ëMâ˜_$²]3cд‰]Õ+, Hœ_¸bá+ÕWÝt@»©}]©8‰¥æãð&>ËÚ)ÀÃ4ùÿý’áDìA‘ûêÖ7í#ªã}ú¬páo|Â}ÿu<î&  +ãú“5)lAìЩ^hù‰Îô£û—çR^îÊ1¥»‰.+ÔØRq¿3í+4Š"ÙY…'s²Ú ByÒ6·4ªW£©S,ñÄØvð °¹šðå¨Ï¶y›ÝДþË_"›¹q|Ý’‘åÙÌ l÷*Z²¿EKÏ¢/¢% ;¢q=©V«TGseöq$£ÉU&z{œ•%/Óq®Ä„Ư†+×ìÚb§qTú$% SY3Cj „ f|´£ÉÃiϨ¤O(›ÑóýólLMj¼O·kP1¼h‹K6MÑêÊʳ*ë[§ãјc!|X]½ò¿Â B~ïN;‰jºörèçé3(Ì»|ë'0FÑ‚¢åAÕ?XàdçÅîªÉ„Z†ýŽV‚A(¸ŽO#Œ*ˆÅv¶j&ÚŽè˜|O\È >'&dÚ~L”ýP¾1-È}Uã™J>ÄØ½5ïYýC^[¡•î0ȈY&a”hÒø^=Âj ù‰~ËÉâ=F´x#›i”ø¢8‘¦J:OWVV¢A^+N¨=œJ—Åä è8«O›«Ñ@4m¶¬æÍ Î)[ìØÞå}ØãÀˆÅ¬Á´`‚ªÎËGÓqÊ=Q—º>²æ¦ýžIÜn6z>Î]*[ºèSA½8Å>ŠØ¿™AzIOÇœŸ ݽֶ”=ù0I”uñ×;Ê×™ðmïE {¨LçŒ8enm¿Èm9|Ii‘kªq¹n'¬¿œLˆò2À‘d2¸f´ ºº†DCð…Œ’[G4ûŽtÓïD®`CÒC›g\°ª8ž„w=æå|È~a¨o†çËbÖù²ÚF¬%q¸`Å™Í_Àfòi?]¥¹àWæ´›öÐFIkõ;0èvys¼»}¶·©=7àÄbx5’BgŸD`r•od!46X,d ©gwÞkaÛbã*‚?€am"|;XG;&NSN¹9N®£¿_ÐP²ËüýuQW*lqã"þð¡‘'ËPŠé³:L(tÒëê+ëËp~kä“AŸ­ÇRøØV'¿$&ÕaôqŸ‘Ï8á8ÐgV›f þ ‰½ßñ„#jøDä¹øûÌkgl¦iM.(‹Rp|¦Ù%÷éá2®pû¯€ÞØ‹›§31v¹®íJY‡jQ÷(EÇ“zPÿÖ˜þ‘ŠñýÌü¾­Œ.öp#š ce½;}1L&üôËè© k½„† ä¯PÁ?èÞA>‹ši©qô*_áóƒt8ý0óóÚ¸®/×ÙeÌç`é_fH’áe:Ά¼ªV h8ÌðÈTצÒ¸1ŽSë £Îþ±ÕÚIPµx‰Óå5¤­;IÆéÍÆÒy3sZZíë–8õ·Ø©S»Rô‘ 7þWç—ñ0Qss õ“³Žñ2×;¹ŸeD€°Q† ¶+›{jÖ?Ó‰ò&ÅZØMÔ *q¢€úÐùsàÃ>¬öxÂ+5ð‹œ`6±Š¶P­°£¸1‹¢àPŸK±È{/³ö£ÅʹiO£%L„f&³k+| ͙峆ÄeP–`°Â¤Õ’8–„+M®[42OâWRb£9XÛ>y½±ÖƒùWW~=hg¬ˆê§íŽ˜;H:eÉ%ûs)Ò ±*|`^%ny—M sëâk@Ç)ˆÖ¢Þ)mÞÈ›¬º¼”˜³ÀmUàÔÙ&óá?'È’Ò,9têØŠÔSLt„:%XŒ4€¿È®³$âYt˜]:~'—‹oÇœ–ÐøÈø1ƒPMãàAOƒu~,l“Ä'Å“ª xÄ )îVà»8ª'E'BHd"Ô½ƒÉ;ßâ4 Ó±€åBñk NÙ÷Ô¨Û€aKëÆ"7¶Dÿš£Þ`ŒƒA{™–ð’ÈD}(2.ç›èÇqĉGíg“\Žh.=:Ä”ÍÆ¶ó @û“æ(º(%>˜ß¿Lútxÿß %“ oÔèð 6Ë´A«Ï¢Ódd×û£ÒAû ÒXP1Ó›Ü 2·õb<í ‰‡âù XDP#B¨ëÁÁ©X83&dJnqÄMµD—2í •Ñ¬òû[üžøÞ¯ÇÙOÉûOÓ)6ë+Ë++ÍU£‡8“§ÁìÜ‘3Á28Õ/lÚ Þc]à Á:24Ô<`A’•T¬ŸbÒèó&íÍÈů`aן:V)­ˆ¤ïjYE6 ¢%3i]ðC¨¾au‚ÄʳCÛ²c–é@dËú¾Nì\Ýxc«âb!ò""æHö­gÛZ´Jô|íÒKD«YrD2cOü(v,ó¯n6SI+"a¦ z(`"uÇR›/ªíDƒü²µ8û±˜œÛà=MxÁ'Õ Ü/Œ4u‡ñù|î÷e€aG›¶O÷ƒ]üm:„,ëön…U?èÆ9`+5e²+©÷ Óg1-æÑ›Ãý£Ý½ëfº77‡…ᵄ_dŒêîgDý٢縱¸?*N@ê™×/vNY΋–˜ 7Ë,®"‡æz\;~£±íéýlj³×ǹ7mñl>Î- ±w²kXCýƒV†ib3bô€»`ƒvš!?àñ syÜt¸¶jÀXQà:‡pîÂb™èá+þ¯7™¥ÃÍ›áMý€â  ñË¢ÞõXЇœ¨Û*÷Ðê¨ô ÖE31°3ƒu—^oÆ~Np®3n6Ø%±YI[=²ù²ñõsñ¹@|_5Þâxܧ“3žR`R%?31ZÈÒÓb?€V§ 1T:Û,DC­¯”±Ã£íé¹[àíá0޾N؆—ßà,mYfh6E3ÎGìËJþŽgòä·ä”äKÕwÞ-¼aÓ»f¬éË )m\Ò¯$o•×°áÆßù&%¿?æÊ2þs~ŽD¸Ád¦W|*å¡&¤¤§5 Ý×n ¦¤Ã~ÀºúŒ±†œ¥£çO£u5é•z÷‰$ü+çŒ™ßæzà9C$ùi‰òêi¸¦wMòˆ9mù&Í(x:™vSVÀ?)H Ñߦ}ÛÐñX§œ·±ÇäecN»í"'ØS÷GÔ?€ß1|ì9º¡ÚB LˆVà‡‹I8‰g,Ej±@Pïkób'R†‚Þ·'^`,„qFÓ)É<ÉÝ{"‡Lõxp!HFwÂD#0l±ÉŽ®þD0ÊCϼ¼QºàÏ裗&dÛD!›‘³9½Â!Šº’e|¦cë>ôlýÉÓg+Oãõg+ñF»·²ò¬?~Ú}Úì&O;ÍîÊF÷ñJÜl>ñýÆã V…Ò“eÈ%ÔÇü®¼t´—$w»1´»„›¹úÔª…cåPŽO¿0Œ!VN1z¸-XéÚ…çÂÀš?åö|gQߟ¼3N?ÖI8LŽ0æ˜\ ë)Gçw_÷³¸«‘̈¢H3A½G÷°)¶ÿa;‰Æ¹GvJ@âh ß3‡À©¤â‰°Ì^4$WºŽT.–@"t“u7’½/gNA C|\p—êÐ;Ñx*‡û½a6€×er ‡‰T]ؘå„xnQ¾šúöYÝczXÛ#ñ‹p£²ê.gNãP1¾41ìWiNGáÖ Ó4W7Jn®µà¤”y]…LœY«p6ût´¹1{WƒdT‚2e†ï‘³I–Ÿ´xøžev Ø Æ•Š¡²âëMÏ›jnX—Äk,·Ÿ¬4ãÞÓxu½Ó{Öm>Yk7»íäq/Nº$^[ßX_Mž­vãò½º1ÔWWŸ®­<]\B¶‡ŽÈì\Œ!ÃBx¡b·…¿½`-7ß‹þJi‘æ€4 Xˆ<žN×ÛƒÅf96†çì?ÂzÛöó0ndzaéL}˜TØ´¹«yKl,nœN~êû›Ö l•ÞO蘎GÓܲЩg¾Ë/R„oˆ­Ã ‰`µ¹Q9‚eáAÕw¤oøŸwFë¨Qu§ÒxbAKY74K» D¹„O WÛ4Ú‰eô5:Þ}é“thýnUý¨ ÍF£á…gˆõ‡µµåpeø“’kžÅ²€U5Þm%û¢Ñ"ÉV£(}Fã%_€Uø2 n?ÚÔÍZ´¦÷Ó0Ö‘[Ÿ°5îU]uÄ;ß»`dÛ½Ldô´+‰Ù’[Ú¾„»N}0šª‚¯ôÃØ@¥ÍL {çPâ.þý0KºÍËDtå쯬o!hûÿ~'2­!qa¯úñOó%´S×°qÝP§!.OÔÆ”Œ(Ùð0ùtÚQ÷^Lˆã0 ¾–´u°m4.¾´äªa* #³Lrsf*!ºKFÚQ ½¾¤M‡ž96LŠO““ô3œôL‹õoå£zŸMM}ëœb4¡)WÉŠcò‘´iÀ=ËH1.4µðç…èødº¶*”lçÙ3Og¡ž†~;!&ª“l•…{ëN–Tuu܈{¥÷€õcôZà44·ÒŠ1-c¨Ê•u^^°¡õ¬×c+LÐò_Îÿ…¿çX]pY .¿ro¾qÅ'Ëw5ìdSAR ¦…4 ræêŠØ¦dÁÁ¯Y@,W±Â2)£3)X£äqÙe“.>f×ÑØzÜ(;¦¦²W€ÔsZ+òÀÄüJ 3ÍåB° Þ,6–ÞCnË2ÆÌ…XäD#Šýý°QP+œŠ%Ž^O¼X4…®rØ]þw ýˆŽÒ Öž•!sÈ_©¨´b•v]pWg9bŒ¿ wM¹6GcÒe›]dZÿÿÿþ¿t#'3½a¯Ù0ŽMãŽ&`+윉þZ GØ©™„ºˆÕ†n-èS,/g˦ÄSy±~Àl[ÂïÝŒ#—Û«cE*`éœi©+Ð) ‡J´} ÈUwLÉX†p”|BSèõ]µt´\@ wÞ±û§Gõ§O?«7Ñ¿7g/ëpa|ö,ÔÌ={rwÇ#„œ“¯uÐ1ÓÄû);^×aFâÈ,öö-1þÚ¨èX<›Ë„¡’)¹E§5'Ø0D{ÜQÁÄoVC12Íèfá8Ç!íÄuy¤Ðs0_»8^n vºÈpösľh`ŽZG±FÇ7â-‘’ Ðç%»·L8Gt2«\Úž»C7! puÓqÈD²õ*†~žî¤—ÌÅÔÅÅHŠzï0°uÄ¢¶±©’ܳú8›°>SüúíQàÃ,žI´ø¶ë½,÷*Qp-Žœ-Hð<ÿØïéOÞ;ˆyÌXW16wž4ÛI³C‚*„§…’&TóÜOêà2² vœ%¾fkl7â!CL +ç€ZeuÌès?Œ•èûš¡-áñ~3w1|Óî6@¨ï‘«³4›@Ô×  oè”$b¥[¿‡.­µÂm¶ô´XD?oxÈìNu§s‰×K‡å¬>Z°r!æ…öIf¼¥Þ‘Áä¼&Þ1¦‹è(OnuîhMEÓC,+!BÒÊ¢ºÖî½@>ïd¾$Ø~éÁSÓ‘#£7>fûÊKÐqßus~Ü›Bä§ O_Köwë2 œ=ªE»ߣ~G¯’É ÚË'q«ºrªø³ûHw_¨g^MóÁ³fjŠX¨¤17”¢°˜a>´žz!r·bs»KÒ /Û—Lñá(,xo?¹LM<„ Wc8ïoqå…Í&¨,A4—ŽèÆÙ¾¦Ò¸™¼N‡¯¾­_m¬ûÖv‘‘óÆï¥ã' >AŽÓ¡†¿M‰Äø·I£° pr9Wð@ñmh'ýìJ™CìŽtÓ_ÚŠÜô»!Ón_‹@E»4„m¦µhõˆ÷ïFÔ\ß\ÝØ$®£¾²¶²¢=:¸+/ë„~0¾$AÛŠ`°|‘>ʸ ¡I·Ù¤\ÄÓ¼ BRÈ]Op<^¾Üp’’‰ÊdnûÜ:±$ð©;yªàГž=Ë=©+?öè_t§Ù\“ìœQ?E 8:­9]—ªäØÃNÕ!»†7ÀTèc™©oÐv`ꚊôÓQe([„Ì,-æ3ŽŽmà› Õ¨êHQ6ˆr×ÛKý85³ƒç[@ø“ní…ç߇ð²¾~TvAp@P›drÉÿ×­£òYá+ãxl¿[ð<»bå]2òQ–õ‹§S5œåÜÁ éðuƒ1QÍ6`! OU|ÅZjêÅ¿Døi_pàÌ_š¬8~×5]󭦲=¹G²Û¼¿^`¡3vüè”rÛOïwN‹A¤€¾ÿ­ø²Á}7P5^ÇÔîÄÕÑ ~¸VáQòµ)ïZÇá*­›-o‡³ë1LQD™­5øªÓ\1ßf.ýÓ$ûi­HôtÀçQÄ $L+'‹¨v4_̈ÄuEöͲn´€ë|ÁïϯS’ÈDA9 ÷Q†üĈ}7 ±„&rÌÄWH­!ïÅÑPøBe×u%y ‘ö‚éggòèrÕ¹oÏêZVM§È6ˆÊNÓèøºM›ýýü^Aýè1.·«éCÀpXe+­»(kÿñ«¢vÀ¿ÓQïOé››|NŒJìÉ'Ö9f²Õç’,†«˜—ÂÁGœI$ùQꜲ9U?XèXÞL\¥Á_(Ú¿Lmf1&´_¸ì DÔÀV9ew‘ wÎÁ1%5N›÷›cÓ‘iјSN'ƒø± j;K2{fVf…\kšhSµ ܹ;e&I1º™x#0ž—CÌù˜„pv4f 1ÎÍèÊeÉþP#üdõ~3Wwö@^4É#’kào®ú”†Ú?òÂŽ-É2 óæŸN²ü’™²9¼ÉU éÐWˆÞ\ôgü(ؾûG nDòvE¹€ëcÁˆ RgÆ Ø}Û40‚NzÚ»–¬ŸæRÈÅfhÇÁŒ±iÏ.UéÐØb#¢X¾ÜŽdÕ‚–GŸ»&¶c-’>ž¥ÙMyJÄ,¬wÓÌl^üb1êRà[ÞásñP©‡®L ÞtfJšU¸.8SØ0c¬?ÐívÊ(ÄÂm&âGå z©—b¢æé¸4¹Ÿ ™siaN}lAŸƒR +)-”DMØ]fq_ «ÈÃCg°iwÕù<ŽœÏ3 èâ àL$j‚{QcCØ2ëD=/9VÃÌ´Æ9ÞF|$Ä¢›Òùž2ä•JžºewÐÚJ@oäd¦çÃLŒg9å¿È:öYÀ™õ\!aùO³q?™oÞØ–«~š«Ë[KtY-ôʃlqüÚŒX?àÚÖlDF£ÆgòlûäÕÞÙi ((­Ý½Ó³Ê=zõm ̼ŠCÑÙûÀv q:ò_ÀFóêð;„|ï¦ã\BBÀ-$»2¬y‰¢5$úª ³ Zñ@ý-±]á%pàÖᎦ,a$:ªOÖŠ1¯ãñû]¸~NÔQFKž®Uïn¿zø‰3RÁƒ'OLŽ^zΫ±Ì6­–dM!þJ‰ O®QØGàsh#Öv)܆Œ'’ÎTd9ð°Öx>*¡@ˆ0gáyx¥ƒÜ…£®]@^E‘zO2Wqh³Aɨk€© ŔȨˆçdÖ~7ÅA·Î„iW«ŸDØA«éÁÉäPÀH¤>¯Y…)ø®š5cM”̦ q°L›mf?ñÍçl¼Ná„È Š("ïj>Íýv&ZKñTP¹ˆgÌeEðâ}äUK»Üò¼çjZ¬¥hiú ”#™}Òi0ofÜ|ÐÙã7/öwjðRùV1êÝþáÙÞÉËí=Up;¿3ñ³\·Gcß„Aq² n˜\©!ï%TøTÑ”£øÕß„fJGoeýniA=±‰ «e2ÆVØp&Ñö8Ü?íÙüé’!zÊêÝ`ØÅc/Ó·È.’³*ží¬nÐYo>YÝh‹ÔÖî4דäIؘW‘òç²_ý¨&]|ñ àtãÍA|cI_¶ó'ÍÐ=ŒÍ¾Îlêl‚¾Ýq©:Ÿ¨eùüu‡TIÁéÑ›“½SƒÝïõuš²ýäˆ÷ý$a9Û­âS@ Œ,"F#I²‹#*4@ˆÆ×…ÊþE¶ò—-팃Vñ±ãA€ˆ÷¸\:cì› ¬~°@â/#c3°wU„ã°zKú½:~B^’ŠÖäqQÞ& ëåˆÛ´Ÿ½™ƒ® ÙTO‚®‹•ºÄw¾põ±Iš½áSÙ5°4Z÷ì šþŸôzSäÁÆÚx&¹Áhó£iÒ¾Å1Z&œ¾="BùâtwžjC ±3(ÐÛ†ÙU'ËЧ_«ëš)I2-â|b<^¶-ü[é±ú6l›¡õ=œl—Öéøäèo{;g­Ãí×{Æ¿‹ãÙÁRIAO' V{ÅçD؃ââÐ%Ÿ»»­ƒý'Û'ÿ+× '5à8 õæf=°…Ü`槆Sê~5WpŸ*к Ýí1±‰¾Û|Ò¾žTmnC®Cªð’n¥G§Í/Þõ`~NfŸlz16)5lO9bøøzçάãÏ*0ær¹KV¶7Wâµõ§½ÎÊJûi§×ÝxºÞ}Ö|úŒ^t{Íõ§OW’øYp”njË$›HÊâF×x¹Côs’ãÑŵ ?[FshÌ­YD¡U­ÝýÿjÛAÆÖΛ““½ÃàM9ÿ•xQòâqª"EÐ× H ~Yf?ß—Û”s9 Çš+”6Ë MÞ.p+ TZe›há$ï\|E BÊê\4†ÉÄî2à Î(HEêN¹•–úå‘0¥a´‘²ÞÌ*¸¶\ö­n㑹•– h~¾›ÏÌ…§œN–Õ™ïÁ”ÞÞK£¢ÍDÜe6V¯^VÖ&Ý´ˆê€U¤4S¤^çɳæ5ŸÕźfݪÓè;ͺ-ÕcòëžKCÀ—¤ý—.2EôEèÓáÑY´»÷rÿpo7ðú_e¯¿¿7áÄl”{ý¯Š×ÿ}BxY¿U§{¾ã£áÌ.T’wbvÑ3‘3Ýl2ÇGëv*sa©|¤8‰DÅm‹Ô¾ÙßâõVn°Ž»—-|¾òlõY£W&œM# ‘!Ûèmôà¦>cNï€ ¬¨Y?;¿¶ÒÀgÊ 4á5x9Ž®2‡‚ìÛÛ×~î!5qœ¤›GÄ&‚÷ÍÞÉéþÑakÿð告éŠ=;ú?+ž»Ms•~BÑQ DVpæ“Ö@pv&Ù<@ ®ZîË˧~ hp{.UEÇAWæ%Ý™‘³–g%Ö%5ä±¥¤XŠÇ},W`ÔsŠ(6–Ó»$2Ô1$ðÁÂUK‹!ø˜=©?38-Ñ×ÛßÐeup´ó÷Ö«½³³ý×{­×Gtö÷w îœû^·70PÖÄ!f%ëcÂr嵟Ŋ͒Ï{O0ÖΚÄHà ü1øäô xpM’{иh(,´ íÌêÎ4ß}"[„˜f¾§j³Î,ÈÑ]NÌ¡ÒMâÄvIdÍœàSàT$ƒ”f_38+ Û$ “Š€”KYï&#¶¦*—*Îf"(±Lg»Ê&{k:”<Wׯ¿GZHB ÈFúÀAt>Õh¥YMQE«o´j†œÜj6ÈpV@´ù¹ô`‰Xœ4—¥¸›žÓ³ Γs±ñu5âDeª49Û¼è=“/1Ö¬bÎW^óºPÙf2l§mF•]#jàWPe%ÏE yR¸ñ¶w_K­b=KŽl¾ÊýR±mòß.³ Sð1„ðg%—ïBŠ^k.ƒÁ<Îà ã "c¶¹oF û‘!’ƒ^LÙœzº£™è9Háì jØ”?Ý#Žuÿì›âi†x9íÛÝhá‚Ç },ÅÍæ ›ÈøtãøÉêÚãv3~\z£“_ñ©5Ì™SisæX @¶WÀ0 Ž›eZ¡Y&Ž(;¨NÉV€Þ!ø—[ÑFãƒ6K­Ižô9‘Êð¤ÿ j#)JED˜uô'V€‘NÅwß ³ B° —ª@|”Ç3š>æ®4ɺP ÈÙIF2 3ø$Ô4¯³‘ÕÄiŽD±6Ýqù¼,JñMâ#íx5È‘…[Íf3CûÜ []5¼‚¡Â.eÚ ãp>íØLöUΕðLÆ_P‹¨"Ì^£ÏLžÆ¶¤hb%ô2ÉŽJÐÒ;g׃ÊqÁ¨`÷¹d8&çUa$lŽ–òŒ¡HL¦DÖàõ™÷&w¶áådÒYà+G9"ÊÙºè“EYÒE5¢º -عðRk™ ©Î¤¤L-*ˈî£T}‡ˆ«MÙtjGîl»¢ý¤”òœ“ ü¯8/¦r“5“ ·`ŠÃÁyœ™ñ¡…§E*öedï5æ e]>¼‡·,Mw.Ѭ̔y £ (mcnÔ©~:–vl¡àHÔ &LgO€T%M!‹7piÈ-}¶4ÿ€H"",tÉ7fˆU/×\B,ƒ›;ïë´ŸÎSâAêo\\7É•NfM†PÓ1ˆæŸÙ‘bI‹›´î%6·3âjz—.IWp¥ª¼¬á²1¼Šå¡LŽ~ØaØ0 ©á1ç%MgffCÍP'¥ŒRz1f+€y1_)H™SÒ3c]˜yõSß`­o´ÛOWWÚÉZüÔÄa…õ¯Ý<¬s“ßQÓ!¿°[Üæï4›o0ð±ó¡îO$¹Õ?iÌ çh(,'+ ~}êÂfqÓª+ˆ"~;DMöë˜kÒ8oøž×ñÐKy½ §* C6»šª¡3ñõ—Jù<ôé¹Üà°iR…ÕîTýŠÙ+ÑÞ¬Saît:Z2'ÎÊÁÆï=È/`×P¯q´èªt]Î8í"ósÉJaúJà×Mz7óÊ t€ˆNÍi‚6Ä¡ÿfØÆ{ÖÂY>ú»¹ 2³é+Ü{†µFƒnc“`ƒè"‹ØT³… àòÀ¶'Ñê+>Œ‡>Ž‹¢ß³"X^N¿ l[ê‹èAå{‰‰/L6=“ÊÉ™ièçãt¨Ù9 ÄzøÍ¦ÍqϳêóÎõäIˆ3Iy Wð¼àȇUð]q~ù=ýOç‡{$Z 3v¦×\¯ñD"é9“¥c‹k*õÁõL]Á{Óöa‹Å¦Ï#AO'¹áÚœX1šA/kB‘2E•cþT2zlj ^’ Χm P†‡pJ=G[Y/9@ JÇ·gcoûœóx9–Kÿ¢ºrñ#¨Ãv»“ 鱆ÝÒÿýmª¤¯÷ÏìkIÉzÅkôµ-‘ÀAkbP ©ø0kÅa%¢Jt9.XÎ@ê=×4|QXF·°³¿/GÆç!_QØ+ylΊ¶¥nÜêBº`}-ÕRâ"ô$X·Cw8•â±ÆÄ^çöLÀ!ŠÏˆŠå´kr¢<šýí}:0‰Feœ$§5ï;"ê‡LKcNL=ÖÆÍ1¥ù׿lYph ®éšj”¾¦¹ó¾f» GF› ivèÝák`ç‹/B¨€DœKüíåÁ"[r€ '^N ¡40LRþòÀÞGß¼®K–Œcì9Àò¼ñÎZ‚Ë& ‡½~³Õ{pí¼ƒÔŒ«.G6¼ Û !ÈF²ˆ’—#VÇAë~>ŽúßXž4á}îË Äs~XÊÓAÚ— é6´œ³[ÁÕ!b˜%jж^UE…9õ€ŠF©jåºm®|¨òÕ £rÃY• ¸Õ„rV[ñá|ù³Õ¢ùnËŒš$Ÿ±…]­s"‡¹Z“”¿ªf’vê*‡H‡€‘¢­áwv¸…Ε¤rQè,»93XêSR=Âò{,™ ~åKÖ¸Ó¸¨jD†·†®vá%¼x/o±ljwq û®#¼(Ø‹¹[Ho^>aZ*>¾«H8`¶è–/Þôìâé `˜Èò×Ò½TâèŒ6Uu¯Ð$é¡e’(Êæ¾–e†â%Â×Ë‚óZ‚ÝfŸt†êй‰ö/wæ6#°u|júŽÙ´ >á„­5éŒ8/…SyN!÷§D2%‹s æz7z¼ñô)à!‰Ó†‡÷äZbXí­îðs)ÚKX¨ˆYÊVêê³:@’?Órq[&rå*–æ*i‹ý-ÚúRôqdÉŠ+ܸŸg™ßÈãgrÓîMŸ‘²~Lð7§Ôìcóz­rg÷³’ ¥%C;füVæ"”ð °ƒˆ±Ÿª’{û€ŽsÚ+7›ˆlTÀHN‚Á@Ž‹H\-ØøÏRÜ]¯=]@‰ö·‘òÉí5$Þ Kd ¨7ÊAJ6)&ÐôÒP -»Êªm Å¢¼¿K·û¬À`ê}OÙ‹$*•ü’xÜ$zOÒ\޼‡€¢õGó+Öªh­iм©:ÑûßÂ5Z¾ÁË©xúI"jFÄc3–ÛÛf®ÑËs«±ºSÍÕâ ™U¶w)sÏ ‰¨!¥@ÈI&¹¹­ÓœÓ%²OëƒF3U?!ÓÖ@ÌZXu«‘©4Ë,4U]:Õä^6σ* K®zd·eˆDõ.›Éÿåvo%ÕMñ3ÃWß>É$>Ì<¡¡àèË*“.êÐAìa _¥ L”°b€SiÎÑhVßùÓªmß8‚[Ù ø{Ë#p¶z/ bIL¯&Ep¢ÆW“SǰÕ$7xì­\ÿ fJÎDx)¤Ú}È);¡V¦="&^äÇ:·Õб®^ȱÖ¢ Xvö´J£önÔYîF²®p¢"ð¸2Uý/ñTEåKš²j:I;Nõoü³ÔB N+¿c[æùµ»Û7æô~àæ‡ö|øÚ9 ÆÉVb©™àtèd1é^Ì#­V& ÔdšaœŸ¼Ü] ø~܉ Û÷T ý·Ay¶D-aXŒ®“J  {Åâפr,ßž\•1ø \@žõE¿âP¸Ó‰,_]gS“Ö3ª×U fžXüo:Éê²ñÑçk±õ©ïãT[­‡qÄI=øêt@“^ã¶^B ñ_«Æíˆ]Œ\îMÚGͦá8%ÑAÌð¾âd!Rt!I »G»ç[;¦ÃäéiL+cípiU{ýø£µ)ßj†3ûÕ‚—˜Lb¬p ËåŠáädyi.1²Ö›i‹–êÍsRcÜÐÂ@o£Ø'Žž Ø4Á >ÅXt]qÙ`uÁíïP#ã5Î }¦ýA”H²0õ9æú‹s©•j‚@%&*öèRªaTŠ ÊU³ðp»¢.ˆMV# f.´™mgÆBQÓU ̃ŽnÕµ%Yx†¿Ißsþ¿'ó3‰9ê¼¶*¤ÓÇ*Þ99:==>Ù{¹/@Ú¿I¥ìiÈ[Òy,Þs¡µÊ‹îÏ»µ/¶_µö¾;;Ù>…ƈ­\S•p:àJ!»sô¢ß¢ºŒ®É¨˜Š§Ã hZ¢Žæ_Ë}Ž_Ü<ªâ:Y¶À&°1RfGã%¡¤kn’ÖɃÉÝ0¯3·Ùètî nÝz!qj®÷¸&–'†#¥íV¢.{f0Ix‡xœ6ü0»"úL5ˆgàÖ·¾~g+P³A¤oÅyL×Ù±zS¥7/€J¸“RpTöûÖaœ÷zŒÈ.‡<çRiiÚ¿cü…?Ÿ*A­¿ÈX!¥rƒ‡Oå<ã©¡²\‚·Ž˜ê "GÈ›²]fœŒ‘.ÅÃw’ŒÌÎÌFuÎÿ.¯°†ËŽÐÁ³Öâü<[ñ4ov#e2œ|ƒÃÚÑ„rHn}M·•_Ï×#¾=,4 ²a#3 CÅ}ï¹íëƒ Œ¹Üßt²yr/£  ž»ˆê°•Q¿wVƒ=`"e~P“n¥š^¨ñĦà§àC¼83¯2 V*ÒÛŽÙmnî%×`¯c{m°™½µˆ¾.:nûëØ¦fâm‡³½?XÕž Y¹6d;`§weßÄJÄyÀÔiõ2opjº‰IÊj˜5á…í ××3æõWO:´kœÍüÚæ4R>Þ´Ð7Ëö÷+í‰G‡srX¾kåw»u$àÍKjoËCÀ õÕÞ¼™€7ƒEô‚¢g2Ù•â77zj¯=}üøéj»Û\oo<äœCä."âñvᘶvÿí†öm9Ö‰}­Ôˆ}ÅÝÄÄõKt-šÔí2›êI)4ˆ?nÈà »G£É†×¡b°‹‡yN£ë\°Ë¤Â 't°ñ¬wÉ"#•iÙ¤äŒÒÁu•Ž2‹/p´ë-£·ç k<6ƒGAY4]Ÿ\_!ýŒ/uñ¸ÿµµ²”;ïhÓ„lÅKžo:Öðfì¤ÆCÓeaQÐI$¡T"(€=ì¦OÛrÙev€”`ð•øFòÜÐÇè/ÑŠÄ KÚU‘±Çµ°ïèèeˬpk2ÝÛ¯¾Ý®÷`>‰ßž½™p;>Ð*vØ‹ÏBU ÑØù­Â,74º†j3ˆ-“1CHñC,BÃßÎ%iª+%:ª—I˜Ãîtr™Øx¡w½l” ßÿ$%æ3Ži²Ôwo\{¼º’c0¿î\9"$—,{ÑëPˆ…'‹Võר±§¥æ@:d\Ó ¶4û¸Pƒþ¬mÓ¸¿cZ ZqפùqK®´.ØÄ u’1ÂÊ¡¥4þA|Œ„ý1¼C o²ÞG⌥ ‡»I c„°hYt”õN„µo<Îd˜ÆüX8uqÎ 5e®‰ÉkÂ8 Æ5VÙ3¦bPvã‡vÞ`N=ëÓÖƒ@×&Å‹sBäÔ“«hûš¶çR(ží©Ç^6Ÿ¤C'Óº$³×‚nÞp:”âÆºm\k5iq39òn ^*‰ðÒ,~Ö÷#ñsa r:Û4¿Hºž¿*º{±R}šO²´ñà–áQ"æ•(wž•È,óæÈ:G»K¡`'ó2°M>L$ÿZ‹dp’V=?ª»S}ªdÓŹbƒúߙЅðK|ƒ·‚žjg]Ñ;1½´XyðŽ=’~×Ñš _,þE1Ýž}w¦f›¸€Ýß.ÏÁÅ©?=¡Ç–7gûEì×`æF(ý@V €ß¼avd7Š£•å¬h¦ßÓ Ižž††VZ~”š…¨QæAÆ¿âXI¾ªT]¸gžL‡A$‘¹ÎíS|²H0~œ¦œ‡Æóvd?›.»X‹ËË©ñÙ4·¬¬Ï‡xR³á¬XÏãk`kbt~êl힎ÄÈ¢!¸ê¤CMŽ…5²w1òVSŒ‚ÓD}9Za²ýS3ÀÁƒÁgèÊXüiÑ€ÃÐC_}¶…‡ÑçŸã[ù£Êºë!£ù·9“Mõ%ÎdOžÕŠép­g™]Å`ob‹"¨ì8D^L·:{¢—7ø%Æ9ö "¼Ê™s·%@ 1øªçf*÷2j§û¯Ž÷÷Œòūᵸ÷lNá“ý’,$&}3ñ'q:H@Ò\·Óä a˜gÿk}ÿ‚ìX@ ëÌ£M€²²º 'C£œöØSONÚ©­¬ºKŽdùa£Ñr/¡m*ªugÆUgiç â²6›nH§ìí%¶j R‘OÛuG"Nn]2@>Q¢ÄcÁ.Ï<¥‡­›¦ºÊê«ÿ:â}$̽9¦³0ÊÈ+3ëaÕgGFP”© :aò§á³b†Àxsvê+ÿÔ·[}±äD§œ'ÓnV·íñ˜½q;°ÌLƒ˜^Äï¸úW+-õ `yµX#ž¢sËÝ g?-á{¿åš`2>Wv’Œ‡­øU‰{³‡'È £¸ãY¸^Þ?¢ò÷AÁžÑCóP(4õŠC„4çö)ëPåb¢ã¦ Á8Z‰ržã8üS52J+±JŒ}¿FbBxš++^Øæcü*î?ÃDÈî“(õ¬=5¤u×^|¼À@°ûV}ö`ÿ,Íå]^ÊY¾³‘haÈ·%˜™çâ€× ²â²º‚Å ‘ÿsc½Ë§>r4Խã×{¯…˜sæ3õ®²eÑr’XÓ.õ>´Ò¾Ov‡øiÙ{;G‡‡'{/ßœî킱¾&ýK-½âÈ ‘v‹QXå(bŽFôk * ã„3L&Ý6GÞGuãl2Z›´ýNl¯ËÒ%ó½Žéñ"BÀñ±,*Øåöì8æ83[4CßžnŸ‚7D<_´Œ?wÄ'þC¾Z͈OiVÏvŽ[‡G»{Û [—±{ÙøÒþ3ì@s%¢ëÐ^pt5~잪œø£t$Él“áeifCF€äÝÐWA‘{š ¦5`Ø ëιÄ,Œ¿èÀ •/ÂØ@˜ 6¤&Wp”È ­îtìÐj“Éxõ15åÙ2žªÞ´¹-¯ )‡ ÐûSmÓc ãQ4Ë cÎ5­gÂÓ÷5›  Ç Kã7Í“˜ Õâc/3¯—¤ÍB!ðP]ÃlOöH:µÔë²Çþùr×<C²B ;ÔðLHiÛÏFÅIoÒÇ·.{0òÄ0è4*™'žÜ>b©Ï%5Bˆ»¡JZÁ¢Q®ÁŸ_>w]0q’ºTÇÜ;§çC^‰¡ ‘î¶Lì«×kH¼È’âýBTòú/«;©qhuŽ˜ÔB=¾¢x$ÙDTjN)º¬walš2>5ã•]{ ZãêJÿliÀò.”$~F¾v·–ÝÓ‚àì¶œî8¬6ì¼]%ì©úºQ8º”>¨‰÷=§‹†`1´ÁÏæË½ÝÃÓú—ìŽösïÖð5л€róÝGÎÅ,|Ê(ÔþÌYÛÉ®|N\ìrÿZ¦4ð„Jž¡}ì›ÏÂËLæî±PÞ9ù€dH*VG% œïßìMW.u?ÙÅï¨ÞƺHÜú±ÒE7\qYœÆù+ 32̲÷šÝbL=ÌšÑÄxvc½k=>;Á\æ}#Ãûú€íûâîb—Ó€á„=ÙÞ߷ǧӗ|fù|ÖŸ×~0z‰Kå"C–a‹Êmœ÷8uù ëEY6¼¥<(M¦-ü8ñ ²öfÞÐõº7ñö‰øÿ'êYü D±QtY¿¯sÚÚ’Ù´äïuƒÀ§Ð{ƒ$…$:´š,Y`ÏÄrf1ƒo[è^sÚÛ#جZŸCÒó¿>cÄ<==ÍžŸ>‹]èŸ[æ<Íá½iØjÚ JŽÿÇî#zêsó Àë3¨FÝK§c` ˆ¹á¾%1É S(´®›Öïž¡±*þ2R+†XÕf ’"SMûno|57qªÁ(ãîÌõek÷ý÷½âj¤ñá–BøQËz”eÚ‘™á{ÛÁ^3ÞŨŒý0Ä™FœÝNÿñúÅÑAëëýÝýÃW’ýæ¹ç‹mÜ|_`U:·-I¬_¤&™e24>”yb½C¦-PÚãG‹âû¸@xŒ@˜^ÈßË.4FX%p½´Ç×tº•I`®L§É¯É~IJŠL(4”Ìe ”àtøGÕÿñjx>Žå®çP(ãµîáF0:´ËŸ§ßÂŽMßÌÙz¡…Duý,îè]Þ»VËóŠ]1üôôàË­•Fs ÊCî®Ý÷à‡êB8Vhðì+~.Û¢0!±S¾)QXþ ÆNqc°d¢ëù¸fß9e Q©qlUîbÜÐ)e;¨à¼‚3|Œ÷ТìKöe?g›BÈF­ âÉ8DâVÿ Ér`s]°+TLxaØ_;F™†¨}Ѭõûy#Í|FŒ9\•\ÍNW2S~ôuÁ­Ó†ßé7®Z7mÅ“>m ‘µ¼Pp3:ÓI \u—'Ö„4AË^r Ÿ*Õú™œÅö1‹EôÝMáS~!9]Q°9%J5s €ymSA¦ãöw: …Ϧ” ©™Ž¬r׺bb%x—Z—üØ‹~Ió.Û`=㜺taLÏ6|Ð’àFÜ‘ÃʰàÃ?nUc§Û5.›ƒu/ê°ê#ë29 ·¶åsô24X¡™Ñàbq®ç÷¾E‰Ë -°ÁÖ{Õ/$kp¢6cGèe ]To¹ x{ÅL‡,F[ÖÑ->0në$*ÊÞ Ý:ƒì€›"Ò²õè€DðG ÕFÙ^fô6D¤œÑq2êRÇÞ©œAɧ:6Vþìbœ{˜Pt™Ð‹jÍaPu]2¯ý)r‡Óbr>—Üàµ*£µù¶K¹&QÇÓF§c'ìN±ÊLë C÷ý.à Ž´•°3Iy‰ý ”ÌœÅ"!³‘08…½ä}ɨŠ¿:î+.X\ì,uBðL  žÑjM|ZMLŸö#PClëI®K£8S<µž4æÍžb®Nãaö HæÖ(²ym‡ Sœ]žÝ# ^5Vš€P…fCª9óæ)ÂfoÕ‡“¼ÞÄzñ¬K6Z›ñT¶ÁûDr¯šØ’õbxíË ©NXoŠ«×L’Ì“‰Ms_ž —¥5ö aZ/TÉ…\Xý°vN @ï$ c Zµ´o‹CÑì:eTÛ§,Í‘Î)a%ƒ$0 ùô{¶îGbé–œSJÌL–®FÉr²f5áõY¶Úå+x2ø8­]pä6¹–ÔeP6©ÏõbÛCau®æp§“)æü@ÁJŒ%;/´BÝ jœ•drÿ~4 |<åo³VEpè\ï²Fû-CD.Φ‰>cQÞâ ØÚéI`iîc«e^Y"Ëܺ^úË‹bçdmi‘Br‰7µ1F0ÈL$ -@3  Ê—­ÃíN2 T2 kÑjŽ=ãÔrÄ+BƒSÂc%½$³pþ²²~£^°˜ÙmPèÄP¾a-E–ƶÂñO€"HŽå<)šÚ‹k¦ÁÄØåÄžŽ9@{¬¹•ÄNór·{0~m•‹Dë®ÏlLÚ’¦:öP| w• +¼ê'½ð¼ÕÅ.îh Àê_g€ú½YÌ­…ؤv_ ”7‚Y¿Ö]Ø2EæN€ðJËŸpÓ3ÉäºöA-”k3ƒÈ’¸%ñ‚k&è4»pKˆãÛ »žõlë]³¸|MpŸY‰qÏC:ÌÓå4€Qu§sà¤BÏ íAëYªSL%Æ~Q!¹±à¹Èrk„å–clýibU£¬§Ò•žÕe”Í¡Ÿ‹¯ž[á]ó_ÅBC?'…áÛµ3o'÷¼Ÿµé0ZµyÍE­¨• ¹Ásí–äx0ø9ÆÐ"Áï(À Rp6avÜæñØÑXßCw¶gúY±wzØ<÷h91“qWœÔr“á×õZJà0©à*"ø†îz±i5kÕª†,™=寢s‹åv˜A±ÉU2´ãí˜ÙÑñqoÍìÛG[(OB þc“LÃíÄ]eV¥c„’q¢X\Ö“$ÉrÇRI]üxr¯vËI QâÀÑ¡äc Zñü)Ó%iêcyá4HîÈ©8XšOÁË vs†š2gÕ†¼×óè/¢‰ý2LøàÀ‚wL‰õÒf7Eƒó\=·úù+\G|ž8VÌ2Éý²”[ÒȩêÄRYcº8§C(Ö™VA™›ûÐЃ=™¨£ ‰9´ˆÊ`ö9ê£Fb¬V0®Ã°›‚½“@umòõHyê‰Á\a¿¦º:6A·©Ä-CÝ´ š&9•ÆçIwó¾˜Ô«õæŠi]µ§¹Å )ÀüšÛdK°÷cÈ­˜‚â ÖšëtëB8Û©Ä‘˜ôu7xþ38XÈ!Nœ'”÷eYšMÅ)À¬ú_.­¬p4X,îWìÇkâù~žˆbTÄâ*Un6áÙtòr§¹²ö8Zo4ëQqÒn8Y»UQêÁÕùcXZiÖ¢æŠx hβ®Z‚Yw;Í“Ò\WkÑß⡃ü3´â,¢b_@§µÕ»cgy¨Y8kAzbµ¯v°ð›Q¾¼¿,CñÐîTûÉÊâ¡c jBK¨ÊfÕFSañaæa$¬B¦¹Ö½íÌzšÖcPÂXÛô)ó#Þ£ocªêRçÜâ!'^qè+9<«”±Wä-#±OôÉ¿ŽM¿áÕ!cÓgUî1Vá ž±£Ž#_‘L-q­'«ÝÏ}K²ȼ4WÐLˆ}£š!¥«Žµ5lxÚ .­O;Óæåõz.¸ZèsíIóé|‚Ò¼'þiÁ9pørÐWÙ_1Ÿkξô§$HSÙY?}’$ñãµ§/ßGªó`¶?ÏÕ$4\Ñ,bÉeÁˆ1Šž9¾!a5“†6„WA+Pj‹o®H§½^gc­Ó¦>>îzÖ{døÖ‘ N6 x=a"È’jnÂÚýçÑ~dó ÃÛ—9ˆÑ4¹TÀ_ØóÌó¸R'‚¦IîòV#¨Q„+æyÛàzìóê¿ÆP…™«©£{V¬U r—²'¾Ù¢Sá.æ…¹PëI<ʹ¤Y¯‹ø}áæñÁ ½äÞÒY욤ø¨øåÞ6(MwZþFÕÆ¬bt”Éþ°•_@¿#ๅH hUztJ“99:e¤KúW`ÁY;cBpª.6ŒÜ Y V]MNÆ@|V%KcήAvl rwíÎfô)ú{:¥ÈÐýåú½ùýÕ5’w|¨S[ƒÆxúeÙB†ólÒ!zHãP0ÎÌ›“ƒ’uZ×é I£Ó‹ô¦ë–U8}M_b²à·êé§äPâÂïÕï1øÜ`ww§ƒÁ5¿õLbÆ«—³=²-L7ѱ€¶J°œqÁÚ4£´±éå bgö -3ܰkFÚËÍ<‚ZÅøxL¢ôÀ(ÍŒ¤(üÍÌGêT!úE Ê›”ÜIq$ÑR?›¨·ƒb2ÏÛÅv% /0ÜcfÄÅÑZ#­2’¹R˜(îhâ[Ûò ßölž’ÙÑý:ñpEÔúhš_,_æà+Á™›°¢R9ê'çÑ11í×´g—ŠœRwEßÄÃd~››*/Ý<Ì.ù%×oÀʆÝ÷ÿ> TT™Cá^ Ï%Ø Y˜ûB,  æC8·­46ˆ)^aXl>ç¬uÝÙ{ËiëðÍëh‹¾[™7»«Š'I|q;#Þ)ë ¯)ö4÷PýBX`ÙÈíl¬•$ [}ým:´Óq§Jþ¿Ÿ¶£¯ÇÙOÉûhiÃÌçzµLôa-$Ÿr‰g¸ƒÙµµb¤½ÙÜÚ¢ESr e~ ÅÖæ—Iºr«fðI³þã»Tc¡Ä*d•³ê°Û`àküîJ?mõš¸MÕ†¬‰{àaô¬Ïv>¸v”…”VT˜ZLà»æýÛ1¹Ñ™)¢¼#,™Ça–¥KŒ UµZ݈hÕøÙV0Œ×ê$İhª…”g|=b´Î™a¦â¸GçÂ1 ¬‹©ž³d jÍ)ïºÙ´ÝWH›JéW5û»S—d”“dìÇ6…œ¾ð°;/bŒèÛ¯áNørûàt/šÕrO2M}nÉŸ“cVS±Q¹Nߣè<ãÜ\ˆ6‰âsC£< ¡ê%܉ðì0ù¡æ=Ô›x_’Úa%:MF¶Â»1@ÇÊuN#œ>A …㸄ðX™Á 9"{hÃ:*“n=ëõêíëÍ/þËù¿ðïW’ ä‡úòî¢ñ ÛoÇ·‹Y¼ñü ]\ýzø’møÇzm=pCJgˆ=¹(é©öñÙÊïÑGä½ N ;¡=vé©?IûŠQtÚurøþÄIC*;H‚*!È“%lì,½™ÍÅhG(ˆRµÅª¤Üf΂7ô«½³Ó£¿·^o‡‹NrwA«*V©¡ôÒï‡ÙøÝf?pª°æ5Éü9É]‰«\2ü΄ñ’JÔÅ<’ØöÚÉEª^Å"ZY|¬Î(bù½!"’ŸT̸¹Š>tçÚµ,€v"zª{eK˜ðéi·qÛ~~òôwØ+‡à)d$Š+&ym5òÖ÷kvsÈ5¬>5én×ïÌæí¨%ÜDž¤£ËÆEIÙÇAÝ;G‡g'û/Þœí¾ÒÌ£©DYm¨j–#cƒ•|cÉLJú$šz.&¬–ñü¨†þ»òt6lb2&1aׯŒ R¾û ó³Œíyàè/¡HÛ µîîEŒoËši— ݵ§W‚ÜŽ5¹®ãa‰o©ªÕº3ä©/¾ÅÇÓ–7Ĉ ½ºs>½ÜÙÚ>-[´¶’­ÖÒ˜‘ùD%fÌ䌦#¡opºfdföçî¹Þˆ d †˜ãj/2ÚË1Ÿ¤“ê0¥E• Tï ke¼;öZRÄÀçI&£`Å™õå¦ÓÖék@Œñ«ÑèãèAÔåûæžÒ|€Yí°É‡™v%lÕ=6[Ї*}í<}ætx:Ïh£,¹c;>'Š †ŽeÑœ-'ÉêêêúÆã•'gä™ö¶¾ñøé“æÆ}&K5s</—Rµ#€¤8·¦F _ô»a4©I‰3•‹Ÿ“FàBTŒÃä¼/J€‰ƒªbó’í »j_Rߪ&Z³ëh‡~bñŠêÛéТ›g±±èîJ¬ÛÐÇc¶ñDY™µÖYÒcëë­`c\ œàb*éæ…ù‹†+{´ÚN&b•à ¬÷;º~Š ù¶ZrH7£ý¡*&P[pdV…}›¬_Ìhªôá[Ö­¤6Tå¾ï§T¥cM…À› 3g\„`àôª””+\/B˜‚ø]+CE h`{K‡Yk dÉKUÈnÒ:^M…áøû0žö¢¥µf´MgZ>µ‚ÔtÍ‹ì«j¨ÿØÄ†,ÎQø}†ŒÊc’Â’[5ÈáPÏîÏ ‘¼@¨P3Ökmš4ñ®;•ôšÏÖž>évŸ¬®‹õž6 m“Ïù_ú)HjùKf×ó,6 —É ©ƒÐz4Vγ¹`ÌÒÅñ‡‹ÛÌ#t ÂC·/‰Ú<ŒNÞõTÜ´ådÂ5abÛ )vp{½<á¤T]ëÒŽ¯Gãô’Ή—°å>7î…CÁûFP`G< ¤æ¢S t“E5‰Vßei­Ø½÷«g·UAÀÀÕoÛÐ0i RùèÜY®Fh‘xxÏ| tPO{H·;Xßt®çc&€Íuæ¥9Ã=°(iëY›]¾9ƒ›>aT‘xyg_:M’è» *‡»­ÝýÓ³ƒ½íÃÐ˽›L Œ*&l ˆO˜ —H n=(I¹ö7gG¯·ÿ¾ÇžAÅQ™€Zï; ½‘sà "ž]Ü 6m<CAÓz<u{|I±hçëíÃW{§ LżLœœ…nŽÑ¬4šA·Îáæ·}k× yÙp%ðQÊû~1µþ;»¢u3M(¸ÐóB'ÝÀ'ÔâhZOˆ.7¦Abeó:ƒÂkŽaX‡\€ÌÇ@¹­Æ>/ 4²8 ® Ã`•x— ÇtØÔu‘Fž_Ëóärâ’Gú,“ðKâèSÆI A€>Õ½í½ðHUõ¶wlò· Øëd¶ûɇ˜!ÇÿÞ§,o¿˜žoÞÏ·m­¾²¶¼²B[€}ÛxÕPqtMßÓ9ŠççÖXxË›qÜy~Ùi6+Å$N‹VWsYã4_ëJ˜GÖ˜¥Ç³âzn­ô¥µá:Șý@¬1{r Ÿ<ÖÁ_©aëÆŒ‚½öÊ“µ'½µx%nvÖžðdÇD±Nã¸}_Þø¸O»Sïé¾ø’Òg3-æa×ìd¯*cùîõºOzÍøio}µ—lƒÿäYÜ^MÖžuŸ­&I¼ò¸ó4ÞÐn#××ûè¢I§sƒ¾Ü/ÙúöÛü=²Q9Û¢l"†et ê§ NäUvŒµ$>UÖ)9WïL†1aX4•f‹Û|î@¬Ggr ð*•³ô—@Ä%y.w{X„ñúá_)hæÌ¼éX˜yÞDâï…U°ç«©ñ5±œÛÆ¢Vû¡˜&ßhá鯚‘6g:šÒ¹Lf—Ëæ¨5ÞÂóÆÈ+éz–â“«æE%pò:Œ‘>"/Zñ¦FóˆáU²!PœÅNÌ®VÆØ3Ù9;-È.—‘Ov:ãËH€›‡°[7v^M„@ªE$Ѭˆ¼-Ä{ÓéTo59¬‡—Î0óCb7ˆÍUîRc)çoöͲ¨ñ·”©jÜóˆ3~X'ë›;tÓ‚!A.a•“¦;¯T#µéR‡aNÊ•›´émštæt;Hº‚ä® u\Aæ *ˆ,MYFcËyìpª¶@A`…WÉ”'Þ}ê^)jõ]•6ζÏöwö_°_rΟ6Š´Â$ »ma=XeÀ«lÝ[YYD[-`6‚yðq™ðô4ÑÝtc–#T‡Æ´Ÿä³äøž\-1`Wܧ¤×ƒ1–:¬ÉfÁëhñì1t.8R:óÁVS§¨j å¯"ÆÜR7¹¶í £zŸú§õ“C¾¸aé MYÎýjà¾$W”2Ì´;è{±zT%yyÒ¿ÂX8(Ú)v^ÔjÑF|`v½ð¥µÜÅ@ƒ±b@`+zS:¯jÜ6ÖUqÃzh i㬦t­¡^U¬ç㪠ïrÍplÄU÷D±J²å^X]Eü’Ò2¤µÞDP8OWWöÒ–s-PoV1¨\rcÁy*Ñû$Ò€fÄhu‰}²c1S­\»êêuŒ/Z“ OQá©Ó¡Ìì«æ\UåÑFuCŒèmYÑgÐYŒ13ó܇¼>£2é’ían—¤íœ»úIînžrï‚$Ì€2„;ah,Úâ݃Öþ³#>Ž cë9-Ô£P åÅ1#/Äx0„ß™dÕ"†­5^ÝŠù˜Qo©îŠx¡Ó££}Áv£UÃÅÐoÖkßNžj¸zã| —©M\™±¢IiíøX†êéa‡µýW{õ&Þqãiß5ž{ÍŽ.O¿eð†Të êÌ[ŽMX14wSKóú·(O”‡CºáR`K¾ +B®Ô¶mâ;Ô ÃjZ‹/ éÀ= IAx‚ÊH1}K«ræ^UN»jx«ÑŠ”P´dàÇUÛ.¡¾f W. 8¹ íĬ3-„ì§YhªÓSµx[o[/λ_+u/¿"âðz-†¨lAŽ•õβñì¾®·jûGÍz«i p.›žæÐk¥’ôå~mòY«t©m. ÛÁ:hî5WÞÄãqÅD~mÝ@_„/—tØ|j¥-ÄÕQS/‰©ÔòöþÆÔÞ‡Ã;#À$´m,Šëö1ÎÛøN2*x)tÄö5…Ác`¥!¬sÎÄ”6¿hŒÅÖàðQÒ©R BÉ, PC@­.žÃðµàÂHœÙ{“ª~8!I¶ÍÙDlŒôÓ¢»§Õ…UDv½{hgB8Å/¾½é!22&o¬îÕ™|dî´Ò›xØb”5µ¿˜2¾g‹aÁœ1[ø*©Lªð—£²Íž¦m©MFt|ŠSÜS¸ôA”ƒzÒAþxÝ´'\Õu÷ÜF^¤3Èa[e6¨ƒ¨…]o5úÜïÖÆª áª~ýusµB×ÎàÈo¶Ý´KOW18 Äb¯Æ~Žˆ4ï²¥›â—É`,â’® PÞɾÓ_ÕµtªÊbmeuãáÃ*k,œb>‚bÞ3…¾¸ó¦ë§¼¼}ÚmÍ`Ltž_„p«:Tº:’®ñ‰h®Wà韧–½k&c‹SÓxÞ°6*]F1Ã`õºªo½»·¿«‡™^1m¸}B§BïÈA¹·AÏ DÌÛ_“NE'Ÿ/%Øþ¾f-תƒõ ÖÀ €s W:^b»ï íʾÆ`× "ްTø„_c ›þCuVd6{ÓP%WÁõ¦âñ 01[µ£Ãç¯Nê­ã“úîÁ³ýúìoÔ:Øý÷£“»Ê4½2/ëµZÇ»§/[ÍúñîÉî)W‰v9ÕÈŽ ¡ûù°àr;²[Åf5&W~¶‡dîÔÀÑë“Ößÿ¾¹êÆì,&×’' ™• ˜EŒ|÷ìhï'Y ]Kó^1pÊ쫤iN|Lfàþ—-ÌeªúýÀ…xVI„Ñ‚÷„«…êMsÏÑx4aM ,s@¼ÆÅÌÚQ*w—"^žõu“¾XÚþ?Öt‡ð×8¸Jàn0üª-)ѤpyÝÆ>Ä)2‚Z¿÷ÉyzNUg6ÿ•ÍüþÏ=–«[3å(á\VãDU Ñn­uRÿW5°G&¥P{Æ •„e:Ir;Tø2 Ë`9¯ ¡üfˆ“”¦¡SÝb¿)Á©©ä‚Œ”%¡SûË$$œ0Ži´xoIûªß%fÂkŠÆÐb\³2.¯=D´qMS­ú#¶11´/oË׫4š·ïMlu ;ï&Þzç“Ëü­lNº€X]Å“ž·qóN{ý#²ñ&ÆÁ’·¢ÙSR⹤,@¤A©2‰ýìEn´™%x•Le/—¯áš¼Sp@7ß5¼z¼Í1sqG‰P.k„]¬¾Q©°ÔĆŽòåèirª8¢‡01ù׿ê°Á½Â²q¯¢KÉ{ÐÇ +Œ*>ˆßSò8hôõêíÄ^¡?ñ7•Õ„hN2ìѱ[“IÂá2îdÚXW°åJ#¯1=†+{Žɟ±¬ñ@¯E§‰¼g<`l+¦cÚÕ@pÜÁdä%ÏÍ´CÌ=©N+‘Ó{ßd~ ìH3Î>Òç g!Œ.‚FO«ÐwnDEfzoë´“.¨5—£Les§{S]žND5Ç Ê÷MÚȨ…„*Kú“:À¸kjƒJsˬW·žL¹Þ'wQ¸;ê ¤©ÃŒWãj‹€4¯LFEMm†TÓ«c³*1 *ü0i€´Ì±»ˆì„wçEãœ÷Î%º÷U0ûÕ¸½máW¡ÊâÕzYßÝ«Ÿh,M-|ÚTw `Å”Àt/¦+18ë#‡NvÛOSz°Õ]Ó»µ“£Ö^ãÄWsx¼„1¹ë›1QÕ —é®zXä ”Ëš?!ØSšGJ=­MêçÍõ: ßHžßN:>;È4À/Š¥¤ã±@¹”£ÅNr™î¤ÕY[!³Ü~ïÂMð¡½%&ÝN:ÑXl)l6*¬— ØmÏÙÒø:½Æ“»˜o²˜äéu±Ì³O®Ü„Ð:¬—Ç•W?:ûEéœNH©•.àPâ¾ÐºN’’·|©ë’‰8o'盫«OÆš£þŽh]Å=±¡9ÈkxÚ-1‡`Ngswçh+|×-çÕe£{MR1ŠÙ~'[#O‰ ½fØ&ÐG^CÑõø¨ÙøQ3Y:QƒqGE¢óitÕ¢­×·†ºV7 +¨ii¶Ò.ˆaКºzÝ““³ØâÆZµVóèÕI­}¿¬ÝÇ«Oö—ăe±õãÑqýÐûþðÚ¼D™’›ÝÀ¼™þ±ótjSÍ­yAÀ9£‰¤lXh ÅÙõ¢:LÆts—_ÕY{ó»ôVTèɘ=¯yJá’j:Bo‡§Û[`Ý*b5IIŒƒÐV:`‡ câf¨ŽLC£61ºiNÚq?M Írs3pi áÅ‘HL‡Ã'žá4å\™ä:êw˜Uõ5pâ3Åmu®ÚFiÀ½7¨ãÆèYåd[})¡Yj&ìRu-y,|Ë»`Xj §4㔬lÍ2vÔ®[އ`OHœ³TââeQútÅárâùÆ7h»á,Ï©ÊÿzŒ&Þ‘å x½Ô¼‚0DŽ €9Ï2@¢çP9æ‚N}/ÈØ%ÕÛ„Ù:êÌ)æ‰8e3~ßø9nìbõù$M/WÎv%1= º¤ÛûnÒ§ÓÔÁŽÂÃMæ%÷àùTeím@é2#ø@ðñšE7^JA×,›y¬&Ps&]eJ¥6~nV½soŠÓ“Wu‘àfx·ƒ'¨è;!dmCFyÏ5Ê@DnÍ«Ž>®ºû–c&cXèÀºÚ-£;Ë– /Òí¨qÒø1Øô6ß·Š›#MFîŽì=m-[ã 碣Öé‘€håh¬`›õ{êyþ¼s‚ð®^¬?ì<Ž7Ï×;k[›í‡Éjr±µ¾º¾ñxëñãóGñÆÚÃö£8E:§5e"û^,¨‚¨ÜÄÂaA—Þ± æ}1é9Ìë{–âN÷røÃbG29œm‡é @5èQ‡g¯„ ~ƒDvúb’"DýääðȰUèLK¹ T2jöؼý_¥6O§`ëªÁ‹c?cf51—å5ׄ]±¬Ñú潓°ò"Ý?kýÞöfFÇÖ‰&Þ¥µç4ÊÅÁz-îèi2ÖKŽKµè’öøU2”xÆ‚ç»R3>'Uö£ä0VJÑÎŽ*à ž¶žíP2Áp\[Û$OÔœ/Üýö‡ÓkÃZ ¡apï ]NE!`…a(ðŠ;ÛÞú“`>…©7·BªŠ8¾ô*oD³[á@b";âjÊ‘©Y¿]d™ôß÷9¡¼‹;gßCW"oÚ+C™N·Z%ÎT2 } ºþÈ«"g#? ZÈ.Žîb2JµY¦\!¿8R<±žîf°FcMä"…˜›eÇŽ6­fç½þ0èBã°yº»¿¿mЗ¬“u^ïÃW_4N+ÃçGŽõ´ÿû4¨|ƒ¥‰Iç®èx8”¤™²Â÷Yïê÷Ûg´mt.®&ÝÙ!´ÎÝjc]E>ªþȦ¬Ë2Ë·UA3〵“ (€jÑbÖ–_csCìaJŸ &ßML+M*ç–“m })Õœb@â]²V}T}8Åi¯¯“ðJá<\d.âqÃã°¼aifþ¹Ú fF íóJôÔ5K_$F')Ö²ýZ ZðN}‚ëaó… ŒYäDd Yµ’jðƒDú4zrF>åSiöøäè¸D4Ÿ7~ô£/‰PÐÔ3^ZEàÉúùr¿M@9¤ _ÄVJâòãƒ{Û=¾^þ *ªnÿ{ðfYOÜ‚ N1ìq'm0à¬É,q˜Ãʦ%— ²£‰ƒs5xØPo½¶\Œ¦æTöÞ4ú ›är i‚‹âÕ혆z5àlbßñ³ªÿìoé «’æ÷.ÜO €¤4’˜ËxtŽÈJ/2iˆîE'¹;?'?š:ö!%_{4—æÄ¸ÉÌt*í™-ô•aÒ‰‰Äµ+×iEÙbùÌv—臆q8¿žÂÜ”õUææ=õ¡.¥ì0czá«yÈm=«_ؽ1%2@–dàéÅ—yŠÕ1N>£C±âÐÁnЦ…½Š(WV¹é)VùÄ”s†Çn&á. GÖZÊ"ñ¿à˜'5IB,1Ú‹©Ì³9YàÓ™ÔæÊàwO¯ë­7ý£7MÏÙݨC­éÖ¢«ä­ºjÝo³e€¹ B<Öü2“!V2X:?<;Úo½lì5_ÜÙ/ÝDS%PV[ÀzßÿÌӋ뺋í0Yo‰Urzd¢+¥7ç·ž%ÀÚ¦†çòìÙù7Ûܿ¬†Ø KÚöª±¦˜r²{òo”l(pîD —-Î~Wå`ž˜•5N9¡Å›-‡å,9 !É0Y­ß±ÿoL|îYëM4ðwýƒS™FyÊЦ(Š‹u¯Z?d(øá™˜;\ÔcÖaÝ–ÕA龌SPÒŽR@ ·f_ãÐöv‡W½a<ì¶è‚m©aÔ»Ö§ûÖÇ #Ôyty†”ˆØJŽ4lásõêúV”ž¢´ßVÕr`ÛTGÖ²k6ËI«µ{¸wrÔØkµ²ÄP¿ðnÿ¯yM¸Ëdîÿ7ñ­zkCEÍz3ÓM™ò©;-Æ0vÆ’YoÎ’ \ŒÐMô–“pu7“½ù4œÍ­6«UÚÊâX4&…ÊÓõøÕx(<év()r^á,XÒüÖ»þœsšM0ÀÇûèø´EBvëøèä—Ÿ}H·<Œ%·X‡ûÚES f¶í„ño‡ aÝK%‡Å¸AÈ¢bû^´¥˜i3‚ÒŽqŠoSÄÄc‘¬Ö¿µQ DA÷\_>ù kà*â˜0_ŽÄ`Ò#ÁxpMŒÙþàúj@|–À’{˜ ›£€Þ褒Ch¡ú¤–~@24˜wºÇ=T[G6SÉ´ÔöU*l"1ªé=(æ(•¬O3+¤gQ£ªUÁkJ+T`½¡™A€¯ÔÈ!=­”ùÕ–|irBHÓœ»õ×¼Ö´z×HÐø”9_Þg]ëu×ûƒ] ºídV~Gš‰,¾¼šôèLÇ#ßÊãsýj?³GY>éÊ«œN겎{2õÕ’$Ï ~λcÆÈQ÷ N%ÛŒ·ö†½S—gu¥*ÉõÌ“Ï.ÎØ bÌØÏ´­U´4ÛÍ„ˆ¾øŒ@|bÍMkmëYã”'•?n¬ã£ !ÉxÆhJ³)ÔeëôÅ$·IÅõÊO?®(3SÛlçL>¢Å¥|«…¢°:z¨––ÑciauF;‡ovNç·òc‚è]“¼R8kE—Üv2\C,.:“†ùBý´Šø?›$ÅX~Ù¯«ö­:ì•ÊL¦> Þ‹p(ˆ4ï“ñå¯.Ø¡+Ä&ážˆÂÆÞ¦Œ–ogƾn„’CpAÞ¿£!+áÊc‡¤¹ÊÌBw<¥­ôfÛŠe`cÜa fÛ| þ2ô] 73³É_¹“Óœx¥¢Wâ=I Šƒ‰ á$×Ù¬ÖÅ£ bô³I?ÖÍ1–þE^ªMСWgh3H2.Y‡uo áwüîçõ%¹V„-u|#ûqð¹ãíc˜Ìâ·ª·Xl½i®Ó•ßZ*ªQ@_2>cH &°,ð'>ùrÇj›Œ‡±ÎµTkîîí´`ê)E‹¼—Øl‹ìêE%u?AÑz³i â~E¹* d9÷#ÍÆ¨ê¼Šm˜kúî&]§†=,èû{ÈÙS/ÕhÜe&6¥ÃÓ½½'ûk–Tm"Ë(î*ÍZý¸úpum›Cx{ð0/#ÏEóôèd÷E=JÆíªñ"—ùJXiFO #Wªt^5ë­7»§§ë%%¯•Ž~6Åe÷êGÍ%c\(Ñö+±n:ŒR‡>¤%í©’Þ°Ã{:f2vo®^VCî»¶]ªî"Ƹqüz«¤À9ªu1¯F/ùŽ Úþ}Ã)€JÂÁÁÔ'ðϦá2{i‹ƒô­{ÍÈ,ÔµEÝ•ªkO–´MÉ05tÃV©¾’À ƒ: Ñè¾3êMïL#yM±óÔ»¢e¬Òv8m)¾Mëô¨ÕhþÔ<­†P›“Bßb~ºvtpÜØ¯ŸÆÈêÏõ~«3 ˜aT4ÒæJr&³ê)jP~Ôö‰ª¹‹D/P?:nIf#Y–ÑÏQ?mÒ Ò” “ô]ŸV!ùnc]°x^Û£9€WÐý^É!×!ù|{J+û’Ži’Þ ž7ã\ËŽµYÏ´ž­}:Ü6,À(<`ãwÁóöÃ;–¯‡MÄ¢ºh÷Ç=•/ÄCoqižñÅz¼q¾šl>¾Xßê¬o¶Ï×è^IâÕN»}þd½³¹ö¨Ó>¿x4…\þe=PL'bÊû)]Ï'&‘ÐÊ8ûuKÌ´ÄÉÚ²Ûlž´–Mäít….®>4Ž:ò†P„4[ó€â@Ts®PõZó½¶ÿ «tÎrœ?|¼¾ÑÙzøhu+¾Øzü¨½š<\[[/_¬¶/:íÎêÖã'Ou¦Ó\›'„ÑΪRµrȦk¬ð:ž= Âi :V,ä[‡P¯ü9^_o¯®%O¶.¯ÇÉ“'ëÉÚy?\=¿H6Ú«õõõ'â°Óì(vBM¾Ogbd(aXr`qçYäP|AÀc[­¸÷,fO ‘²õf$LR £M9DÑãáx$'ùë^×ËÖVÿuï÷S÷¶du çÉs÷õ}®¦‹{ ¥Bo;;2½‹iG{¯-™äÜ·Á±žK¾ÙÏ®\t+,¾Úß_2Ö¹XÚCŸŽ?ÚɈJÖ­ù¡@³ cúË$îIÒ9¸hî«¥Âï¨ÆÞí6ôÖ¸x:1®©~´Ÿ3k›Á`舑0¿m× ¥ª•v‚Ôw‚? 5‹?a {mCÅC[— ð².»B€µ­ÒÂdTé¶Û<}=½`¶HÖªoâw¬®nÛx(ùA¹b“3¦wS û Ê*„Âð¶“PžçèàŒ!i¾ŒýU[ëˆ;Ò¡Iâ9“enŸzƒs}‹¢ÔÍœ‘Àòõ‰ÜMU¡oG3ÌÞ& Û¨ÚM•D.kéCj¨¬#uþ. ÈÒ0a‚GŒ%ðT›0ë e©EΗà[!’Ì©9ž@„ŸEÈSô+h„¹Euf²Ð‰˜ È)R+kªVÓd[2Èñ™,C«mëÈS{ÝÖMhPÃ%Ã˃1åÈ"ÑNèèù-+ATõ~mR‚½«D]²`‰ŠÊ›DŽ>lé²ù³a—IȈÕÄz…ÄÊØVŒ.T# 9ã¤n½°å$"ä†moªPR>o:èž­§ Z fáC×xêè…‘‹g@›r ÉÆ@"kûGµÝýÖîAõªœ®××Q1ñ0=†â­Ån2 ±¸ñ$ê!“¾Ç],ǽ<¯m®nl2V8gG×Ðö E¯Ir§±´Áµ Wåã*ÿù"wŠ’1œÔ8{Œ‹\¼£A§{vûŒ7¥Ù tL..\ú}à˜gW³LÚµµÚ å ¿HƪF«6B_ĽC[1é`o3›6Ö}•E§f²w¢ÚþsPX§‚ƒ¦R)¡8GIn >a‡ÉøM<2nºšOãÍÔ[4`FX’ÿøx«µµéLO%¶ˆ V9W[bœ*Ãv»"꽊Z ÙÕÓ›jªùáhþXï½Æá^½’±÷]èûÄKõÕÎÎ,rÙ_³3ÌbÛÕîÆ6·`ÿ Òט%ÄNÛ½Ž£ÓnÚŸ#íÈl?>î1¤ý"+È–,øYÒK5yÏšgPpصz©–5•W‘®¼¢fHci *yº´8w¨ ×t¾lÏi«”Mú eTŧ/t9%—{[ó0'Yüøñ#8¡u,v‡-ÈŬ÷˜:ެÍ@œ…sÆdÈλ¹À³_ù’Þ`(ÌÀˆÙ±úì Æü¨u±úBÈìÑpŒ{ÄO€%ù¯Å€#~L^JýÉu‹ÝJÞPfiÞÃâhÛ*Ù¿ÛVêF:63ÈîºàfÙËE3fKö&„b+xzž-æ‹®¦¦}+¡Çt¢ÚWɇ»]ÔWÁBdâ^‘›ÚL Y»’UþŽ×¸›¾'ñœYÛ Žäçp<(âã{ŸÙĆç·‹K™#Moã<}YêjþÚÙTÓ³ÿóÿ»êÝ•½ÅÃpÞf‰–&zZnÒB±žª„GƒÁ8“óÓ?8Þ!dc±É:.ÆxϾB;Ž1‘\˜yÔ_=c6pÀgŒª¾ÛlÂÒò2cx׃«§¢øLpæq/¯É9Ä×_š»ÇûuÁij2ã-O þ[È[äp2÷e‰Œr–MöàùÙZã_¾&iŽ÷*“nLu‡ú[ƒ™'±b·ž±ž÷‹ÃU0"‰)F»l¹zm¸°<ÖÚ„ í%‹ž‚I\ÞU¦”íÚ<>iž>WËÖ´/ Jj$®B¦Œ9í©Ç^¶sØï„~²û=)IjOÑÑP'> ^v·jþ $xÐDñÙ4ÞfFÛ`n¡ÅF£±ä\v>°4AïÈXk‰.È™æ‡ÕlQîo¦$žIADµ¤ˆ€Ä»°~ÚâOŠÿ/p_€}ê¦ä÷Žj)ôCŽFíTBÊàSÊÄåЋª.0ܶnÒ3ž½! ›c"w\ùi ý¯ÉÔêB]æÛ—‹]c÷°Ùˆjt#Þö$¦}Ô°¾Î{_í!\·‡Ç›; \&ðÏã_d1u*c§Z¹ÌΡ€¥îŽºAZh7UruŒß¸Ÿ÷¢ ‚Z˜S…] I¦·š¢;IPØ­1â‰AV`ÆÑT s®?ahñ+jeßUÙâ9¼Åt/Ž™6¹‹,ß9Ý2•'Õ‡ÕQ{5—xÁ·vBZÒDã¶ñåŽâK’nÙ(4ãµùõšdoêm:Ôˆ¬T£ä?=BÏ-q}Ôè6e£h/Z@­EQy@‰Vd+Y9xÓ3{Þ»6ÊÐ?M_F ÃuœJè»z]{`vºjW´™…Fð´¼q_¡D´[VA`’ÅÌÝйøÕeãs²/ ïG ƒ®-J0‡7’jᄎA÷Ýý6aûsìf^âMŸU—¾ ì`¢T¿PìƒÀÅO=ü ¾àLjŭåm-†:PV³8¬úAB“<.Ø ã6J¿Z§Ù`a2;:¡uhˆbg¸±úù w5¨î«¾9DÐéßþ„ÑMïéPË•%…CšÇS¥È£ÁÊ")ŒúËï$é¯2÷ƒ7››áIzIILÓ„öþ­&+/™'ø wO\‡Y>GŒÀi;‰#HB»“D±(b-ƨkÖ›zX‚Å ï;ØO·§È³tÌAxÕÓ3ÀvIc¦ÕËÁàRLòd¿ÿ3]¡¡Þ E8Ù®è¯xm}ëqûI?LžÄ'çàLÜï¼Rǃ®‹¬§Ã?CAÿÝiÖ™œzñÝðBÏ 1È$ø›[aÜíe Êàv¸ ÿê*ïîxŒzøäÉ“G«d£s±¾–:o?JâGO®>9oÓÅrAçúÉÚõäñÚ#:ãÕÕÎÆÆ“u.Œ?⇫I¼qñøá£$Þ<?é<^?òxc£Ÿo­¶ÏW“'\øÉºª6u6ÖÛOˆ2Y‹“dýÉæÚã'km§}NFÃ<{5è%ž;§‰i' ‡fã¾à’€/˾:½$‹æÉíY³ñTe7 ¼þ­Æ¥ì®32‚Š\Ö„­z¿($¦Ç/qÇTq-‹KÆ4DµqÒðåmË­X‡/&vÓTLRs ~ë´Y8²ã˜FúvˆÜmŒC&AÍ÷Õ@(¤MÚ¢ÈPE–~‹8]·œ‚îÆ™ÃÆÃ{³yëFƒŠÙ8~µÉîÜ&ñ™Ò´cÜÆ¨R°2&—Ÿž•wòJQè?ºa®Ár–E'¥xî£Û^F¯4“â¢=¼õ-Tö ŘG`'lŒœ§Ø&­íF.|h±§Ö—Qw¬¡x»¬53™®ZÃ%Ö‡*éuÇcÖÀ#„^$scêé ØšG×ÅÕ% ¶ÿ¤ ›Ã54Úê*žþ‚˜UÁøbœÀõ•R›Ï£"ºiÜ”èˆØ³µºÕ5~ÄÔhlú  `—y€ü¢5êJ2AŽ·“¡‰—GÀhiä ÷6è¡™E)ÌÒ·0$ tA‚œÅD¢"ìЫ-GÀ¦MÓù¬ œÜ F‚#¬YñãT~פºWˆOútŒ™X ZK·"<Á9g|7UVˆ‰˜(çó?öË›³ï®ãöß®Ûø[á½ |½%I<"¹lÓD‚¬*‚µ‘ v6f¥2PTr—Aä%&Å&5&…{pˆ*ö \ûî‚f{ ª÷·µ­ éÃT‡½>}wÉ¿ÏÿÖF>>p¸í+í¹'­ýö®ÿ™'›ÄÁdöéãìØ”=¡Ö)Ìâçòé`‚¬P]6Vø®nOU§ÏzðíèïN1蹃8D1ä°úPª²nAl aÔ Q3kœ=\K°šÜ'{Ü®cI½È¡÷.èï”p£€¹­€µ­À¤M/lW#ÕØÇ=“k¤ÍâK5M[Ê%ý8·ÊêÝÆåÈ (—]HûX 4ÒÒFr+ÑfEjègÒ¬õ—šC‹¥¶ŠQbÁ*#!¯ä«{íR“5¬’Ib}Gƒø›A¨pµ?ø>‡pNoÈìÇbß1pSD3±”™…Û°Àí\+q<$øü-RŠ Ùq>¸gþBXÅsqt¾GƒÎ¤-šÞköùqF"fMÇ„êîÏ ÷Zΰ|›ÐXZ$nÓ’l ®?ƒ…{É2¶ÄoÿСǀÇÇåe¯k÷èWuzú^ ×!ß÷»´ÑÜk¼hœ:ºÑ\^\bç"cç[Ã9Ù‘¸%—ì~ÒMñ‚Ëx× Î'éÁB¨4‡± Þ˜îøBƒ´ôþ«1 –ˆ`Š®qÐܧ›8•´àôpÓŽÉ÷€lUc*tñwm£Ô¢K™ùäë¤m¬·Æ{T¶ã… v]2wx‘Üü¾vÙ÷MÌÈVÀNë3|Rü:­6‰Ï¿²eÖœWØÒD€cŒF6Y;—5ÄÏ:Ï5úŽaÍð‚¸ÅEß§w4é÷ÍêÌ£ºïãhUn•7|]ûasØ¢©¸VeÑA @ïe˜OQ‰¿“N¡O WWüüÄ¢Ó«Ø:Ý/ú=ƒE”µ8÷°URp5XüI-G¢gÕ­ŸÉÜñ{æ9 Õû$8±6ÀÝœ ™|ß‚y9àï *Èù>K’ŸÑ êøµã³øv7´Ašê¼ÊxI>K›¼{¥qìÅxo°ÿ©qƒµsk+26’–*—‘UU9çðϡѦ#Ìf± ú˜e-±ã6?LÜŒ9/®höݤ£läï;CÖzÿ;±àS»¡æ¢V´‡ofNx&R^4ih ÜÐÄ/ý™¶ÀàkãÒD¤û¸Ê®ÙgI‚“y1Þ6»)ã|"#¡ÈÕœŠÑ0&öFâ"ÙI*™+dâ†}ÐH*Ü ­Ò6éŪÂ)8¦æ×t¥ù…âT4`ß~qèO®}}Sàåfø×Mô OÇŸG«VzüïÿçÿýŸÿûú–æ®7Gó×IrÏ‚0`ø;R”sÈ‘Œ 0f Îû=¤™/ªí©zR[wÑt˜ð.ÕàёˊyI3üïqÚ¿5¹ŠÉZµ/ð8fÁ»á ‰þ ެ×tÜú]Eç°¾ÞIôâøs}’pKŽÒx0 æiôŸƒÉ¨ŸÜzƒh{sàšuf©ýÇ——Æ0*-8´¯ã½çixÆÖtRãmrÏXðµà;­ID'mç"3uÇè^>ʪk„2c¾ÛÑòÕ¶!ÀÖ|Ñ<u¸÷S¤›F Æ¿BƒZ¹”85H}äwÅa¤çÞ { ®pƒµKÿVÇô>ªž·v–‹Ã#ù¬r!vÕQEÙ pʱèj£JPAòqÑö+zA3FôQóåK!Wœ"šðî, 0CÐL^BÆ{™á$ µŸ(×kÏ‘ç\J·8^¤TFi‡²§ ì‰æõx”>ea„Ô±WkÑŒ§p'ŒìÇ}©¹òfü™Ï¬¨:Ð(¨1¯Åßç±TÎYº,¸¾·¬aÝ ËD…ig¸2 $ÞØ‹eʼ{4L¿­{ì‘6ñvTˆçÝ©çíl ›òº¢nACCœf—æ¸%©·n~ËËÌpÔ¶×úB^«¡ÒÃÃÖØçU \ÚU©ê Û»F“~…­&êå!øJ,à JŸW^üµ?VpLžOKÙBí—I÷CÌÉGVNNké„íu7E¦´æxÒé0O Êt.¿½nÝÚTã?4ÎÙÕ_¦mn+öb”uÈþ%؉“ M(îÃn;Qg›ˆ!Àò ¡ÍýY¨XH“õtd7ÚÚþQ³.@jðóÂ<¸ç _.ñÑí{î)½[ Ú/É´9Ãl'eÙ¹ÃZÈÌH.÷Vá×v Gz"ëj?åÐ9?ðV+™ëýx4/Ûç»L³\瀺 l‡bHIÂ[<ï&t,' LÃù€`7O^ÓÖIoØ[?}ß2J» eV@ rEdRN‰’AEÀn‰²+Ьñ“TžW"X‘wB ìU ™gÚÔÿ ]D“Ö8pòÏTè¦j ‰¹@$˜²@ä5Éà¸ÆãžQT¶ðA°Ôš)½B‚jriøÃàÕÓ‚Ÿ”CL¤¤Ò‰òó|±„|ÎÁlUȘê©cÔ=Œ3UÓFÑî³Fèâh2n»C€EFô‘úѧLj¾’Ñy_»xò4±Ób¹ÉAOP^4Ž5áœUŒ¹θ2eQíøÖƒS궘Þ[ÕµjÎJ ¥a»ª%¯´µÇ\}©ï¶(êÊÛ~›Ócµ±]µ (Ë.袘0ü¢ÊÐT˜m˜˜:ÕC±ÃPÁà§ï™—ÐÁQâý*osÈYQˆK/ì^°GÕXÁò5öÈ’'¾–ØeDQ…€ˆŽÙf[£©é^ B‚±0ø©1| G¿ím;T@A!ê4ã!Q„_ã÷~(f/‘mÑiŒ«ï«q5:Ø­EGÍèÇhmµ*ÞNÊe_žØï‡×²}q&÷Fñ%­<-ï³æÔ…Háâ+mÙB F'hKpëf$íT†ŒaHtüêÂÛ({ËYYþÒüNjֻ ¾ª¼‚KÞ9ðŽŒêuÁ ‡ëä›z<"æe`…9|ö:ösVsÅÑ¿v£+Ó[W«õÛTÇųÐD?@Ìö²¾–xoFw¥÷‚d2‰óý›ì»fDwT©P|ë̱ͮ‚x`Óïò¹DÄ8t!&ˆÖ(t㉗€o´Dô/¾X® â‘SóÜΘÐÒŠ¦QÊrB¬üDKÙA >sƒa"ܽäb½>§â’ŽnF£˜¥JÅð²™ïRI‘[Ÿ< ¾ËŽfu`7fg,7CWàP5ðA½i}ÇÊ:D›Í¯æwö’+Ëófíè¸ÞªÿxZ?9”{=ÿ¨«¦]N»¶VUC9,GìÜ ¹È€ãKb‘Kói`Ü{©MÿÉxF!=Ï.¬é'K–¤›²± œY{,áo±ì9 ʨe35Um’<«¡äÌ·³‡ë{µQ=­ÒÞo'ýT"§±½©¢µ'O›¯Ý5/†cÉás4TÛ‚zA™!sL.-Ž\ªd˜™QëáuiØ:6ôƒ3мnF D~_š îQ¡€,jv[œbr_Öå4ú,L;¬Až®²I¹º¢ÖÄ@›{ÌØIØò3Co£¤Ðz|yÂ@ÂB:‡¦^gýJZ ßð¼ S S¬$—®°Ó D yÏaºl¯¶@“ø` £Oý¶æ›_“Ñ@ê§Nn­õÍDC:ñ¬zªÌw ë9•p®x{Î9“æ¨ÕKúåHÿ°:uv1•pn C±{ÚÎhäÒ, ŒøÙÌDJÐ æ^´±™>vÃ^fuC¸ù ·i“¯BmôÚËx¤\La^ÕjõfÓ & ì´ƒ44y§¿Nb%ÉlRVØÈí¹·¿Ÿa†%¶S@k‚AÏÈúþÔ%>’¯¼)>R.Ä @&”Á\ö¸–S æÿ«ØËi±'Ÿ)¶UÏãTn *g15éu‚Ðé²hr[ ð˯š§ý˜HÐ’Û(Þå4Û#¦ œ‰Z}O8 }o?Ýþ–9Å+h=ÔM5‘ð{fRŽÇžW–r pW 1nÜ)-÷”?£O1 §?žÚðæ‚ Šÿ“Õ…—$nJÂÊÐH{³z¡eæGÅÎ…3Hd´ìÕaç¢pïÒœ¤Ïo÷°:ÄBè=Cˆ‡ªþõ¯Y­ù8Z?GÖÔ› lVš´í'ùU´WÊ !˜Õ9ÈÐü:µsÉËo‰q¿8|Uã=Õj]öçJ¬šœ$Ýâo– d_í¿ßjAó ˜hPÇ¥8‚ÎN[Ô½.‰XDÌìÕÖÐ(·|–Õ2¢ÄeÒM_1Ìž\ŽÍ|íy1Xþ]í¼ËŸ#Kàë¡rÓGšÙZ€f>íóÇÛxQÞòWpÏ0n( †«T‰*uôZ˜c6á’Ô™ˆU ‘DL×vkõýýúžÒÂPzb6¦8ÂÅÜêl}‡DoXfÑfÆÛÀX"P!ÊH¢×•MˆLJ&gÖ²¦þ;Þ=}ÙjÖwOvONZ'õÿxÕ8¡þ2ä:ÃÄó•‘_\tô¬âè^5Úxø íd:âTFÈÃ;" ßÚmf»q|‚?ëì02b3¢p£×›Hž=é—:´?%±„}¤Ø>¾É&Š(–dI€ªÑ+4Ü|IëÓjî6N¯[ta±’À©–j´|³»ÿCuô‰X›"³5‰@ŒlÀÉc€Çe"n®cAí £L펅DLÎࢢš{Ö¾ 혇ÓòG=w)I±mbJéZé‹OïFŠ„æS°A%±x7Þ4þ«xÒ3× âml"®%ž#UvÙÅ}g\wð%»Q¢R`)µÁa,ÉËEf.³%ÚH<|~™H>–ßH r¾Lñ´ 5¶ù,š°š}}‡²Å›S'vߥʌûΊ¦Î ‡[›A0Àn¸ŸÛ¨Ù½wèëç‘o£{<­6QúáéÉnà'+K ÇÊ‚9‡€ˆA î= ð Dzµ â¢C¥2ömΗ¢AÎìªâ±ó“mdG*zÌñµÇ!¾Ì(Cø ÄÏñbYŸx±#*Ž~è‡"¹˜žÉµaØÖªãº£Qfø_\ßf¾sFÙ$^PÐJÐpD,+ñœÊÃR໺ ä´;?#äß.¼˜ø1Žƒ—ÚFjꬨ9@å„a˜o[Ô ™ EwS #E¯mI^8+z1jƒPE' ;Æʵ«ËÏ.®ôHaˆ t7†`m8­ó+cq-›C‹«Fo©„Û™6ã­ ºgÓ3…Ô;øÞ^`¤ðÚ³¾¹Ò(zQò‡÷gÑ!eëð-XvË>½´€ô°aÊ$’·žJ¾;b.o‹,ÁU-=y U-P{C¡àcýcÓ©ƒ«QróôÂërÒïâ¾Af³Ýã0­¢x’œ9ÉØÑéo³ W57} ?Mw ¾¯ 3©ØÏF J»ýx½¬F/ĦèìõGŠýà3ûP ª ÍLãøÃ¦7žŽ(‡ð±¸Töü|¨iÍèJŠ=—¼r+»6‚^¨€AÒè¥ýAÜÙ“ÛâR5Zì%cöze­5ËÏeZ²Ôü–u&#¥DžÏpÐüîõ :¥¦ö Š•“CŒ˜…4;M#àþïY?‡Á;×Ç6"ÿªWwiYÍ“YÖã¸ä«ÓÆAýèÕ©Ü‘1ÂJ8s|¦Qªæn6Ê–RÅ2ü;XîôjG?ÐyTÿ@± gˆÈsWÌÛ~àª"»ˆaEá à²×6ÇFÒ àñQ‰Ü‚BÊ®“X¼/,Œp,Öyछ-!‚XA2¦wÇZ£@±º¢bT@5âBRÞµ-ô–ucÏ":`–ˆ¢W«+0[°—Òâ¶Œ]ÚWE£À )ËÚg-æ16ûÀ÷a3q»§.«ˆQ–*1ýÒ_Ñ™„jLrÕ%ÂÔF÷˜H`sO‰tÀÍN5Ñ@^ßv…“©áîÃ[«³Ê»i²5‡±8¬<ó ë:H»M±fHoÊS@ÁOÌ®4q"rÚµ4ÅøØAã¼y;â.Çk“¯§R(rªv.W¥µïrg¥Ù.{£Ä‘ä¹8h~×5[­ÔhÜ#fÕ¤µ€Êð -e÷VΦô޵½nX"žéÅGÔzˆVÏ!Îcîýƒ£À‘î(JioÓ=6¦£ _6ê2Œ“CÛañ¼üëžÎ-|ÓD‰ð‰R/L9î¹N¦ºÄ7‰ûu³Ò8|~$¤]¤0I¹‚ÍhºPÖkì¤%#"e82¶ŒêØpßuDØG]DP{&¤"Óo¶l©Ž-·iGœàÇÁTAÚänI½x°_¬Úp©be¯ õgÓØÑÖi1Z_d¥™x9¼~ÃfÄiÇ$ˆC·$¾^#Ç®[{`÷4Ÿ+ä+¢²7 늸ªM¯ OY¦qj Œº—]ÍuÃakV?4ò½aÓ+Žmñxf)ú•‡¯Ô‰Måq¹ ¼ Æ‘aºå‚XX†øB´]Ä­åÖþÞîÞ^p|úƒŠÅ:Uï©”‰„}Åဪ‡#‹lÒ34Øà&w²çŒ(jö*u»wÍ’Nï™§/æÀÖ ±ÀÜPC††ï^'bëþѽLÆÃ°ùÖGÇõCŶf‡‘Ã=’mÜÀ;“D¢3¼[S &r¡t ¶;3Ú–ü£â@”¯'õu–*=„¡ä±Iz»Ûø1—¬Í\Ýâþ{pƒž›zÒå‹âôÈyÏ¡ñlgö"æ "77Jà$¤r6Q&&\¢ì–¨l½„°™c’kÍÝRð9ñ&~SP%L¿Ëï$–X'†· u!® ´n›g)læS£‘®«³ÀWÜ,_3ôqÒáÜ\é—j¨¯"L¾Afk¥2.fpF$Ÿ·M×€hÓªWãk‰½³î)é0ìãÂâѳGžú¥£w¢‰¯¬Àé9iöM&JX ü!¯†ÛoOb ÊÁ–ÐÌŸ‹.Ï×EÏ”[#o2¯:Xš¡¼×»‘È«œ¸”tsëj@´|¡ÁEÆ/\­_Æx²i4:" Ì8À0}Õˆ-“ ÐÀ$x—¾xt>ÄÃîÆzµÓë‰ZÖù°BåÂpi¢Ô¬à q–Ñ𷱬ˆxì‰VÅDtôuÈ ™uÙ/kô œ!ǽIÿ„6ÝàºÌGŸ½ {cÌ“±QRyYĘ{s¦¦šoºý]äBUæû®˜Ž–=sÅb€4^ô†§qø§mî7žìžüÄéÌ=ÏÍéµýúîá«cq D‰‰šQi8«Ø  ®ç²vÀ(Y5ÌÚrŒvLîfã ä0 «£íÙÓµôÇÔ !É)ã¼Ls~`ƒ0?ׂgŸšiÜœìO’#Âdo¯Ì㨹¹ºjõ$¬‰å–w´ÜÆî¡ËÀxÙó°}*W ¡ÊË:zHÃ>â®ÊcµÍ§zhã0ðtR© mX6W'«ð;fBÿ>ÒeÜÅò˜ˆ+ ¥ iFIÉè3:ìØêö‰¾\o²]ú—É`ìeëP&ˆ¤  )í6[§'­Úñqiú\AêR»)М§´¿r_ï*Ì3ì»aHYÍÎ',BÑéX®Xß ê5£eðWÆç£vtpÜØ¯ŸÐ‰Ý?m"ÕëÑ ×1Ud÷äd÷'I÷vX±{Úx]ŸnÂCN0Æl=Ë÷Úxºaû„Œì'Þv¿³†ƒ×’…oãÑê½—B\¦i5À46¿û W¡Ëº+ZK.£ýñãÊ’ ô%´Ëò€þeeT¥žVâ÷½ýÊDSÉÅh¹ÁŽƒ!ê%ý‡È>hº ¢ƒv$¸Î-õ£xzü¼bðm=½ŒC»€C’HÓU]Ô”/^¯¦©ApæÒU°®¨ÆÁkoNøçgùö°’?¨ÛÎ!"´¾Î$›có*f¬ çQ! š†~Aª°— 'Ö©^…Ë,bÖÝÓÀJ„ËxÔ±BƒÖbDÍúÑ~æÏ{¶jqªLTX–ðÝ‚aß…‰£ƒ&¾+JÑLòf¦²/¨Ì¤€Øïž×8jg&) +&Bœ„T—H¸zUDä4•±Wz`< r"A•Öë{­ƒÝýý£Zë%·,OêGÄè¾äÌœ;Ø»õ S³& ƒAkÝ¢á/RÙcÖy¿qÐ8%6:ôZ{¼¢¼æT€«èŒ¯0§åd«ûlÜ a‚¶5éšµ ·¶I7¡ÄUOeëѽٳúI…òÕpl©Éãëî'†ãhà‘!ääô%cæ2‡ Fâ…ñM_P^KÎX™Øë"E+ö<*”Ÿîèãý¼Ÿê‚ŸF[›•súJ\}±pcÝ=ØI ŒÐŠ¥–ü‰ïÞfxé…nÊŽ ŒW}+"X Ý ç«Ö›ÙYÇ´ÚѳÔh$Ù.n(6¥ì“e|M@Ÿ6øa´”_WÉ Í± øP›ê*„Gެ}Bäfù–´˜‚~´Kÿ$߬@\@ŸÑiÄR¼«̠𾽉o«3ò„Ä}OˆÈsô‘ðµv;ŽÁb?o½:l×k%±Z¨»Jð‘1xYšÐÚxÿ`Túw9ØXé ©Y)omÊjäõ˜ ½¼9Qä¼H% œ³g±WŽØxJ.h€ÖˆsáùÍìV§i‚?ö º¾ûVñhR`Qó%öÌ,‰r~¡²; 47žžŽ˜ùãhñE2(x¯/.-U£S8s$*w˜²zqÿ½‰Ž¤;]"™÷p@;ݾz§û^ÓŒßfÎ V¯<àgÖW`~øÌ6OO^ÕNi¶Z»{{'Jm„ï\wÃdtÅ ‹¯a©sþ (DòAzmHœÑA;ŽE±3{·9 r¥!I·|F=kŸ ƒË’9nky[¶E¯vZ|tÃ~cøn5glÃ4™t•k43.Fîà0fg àM_«“‘PP9jd4‚!Œmð¦.fd-zŽH<úÄQKUE‹Ç&!-œÆMpËÅdñë7qíÂJcF‹ ÿêL.zÂø ¯5§½ÖèÇ$N»–X¹¼°ôûØJÊ).¨6z‘aݸÒÔ¤èežGÓTç |5öÄ‘‚ÐD©Sa|öñ’Í´ {›¤LljÞÝMþÁÑÌ=£»rÆ=“AÝ K”ï­l±¼e}tÃà†A·öêdßÁ³³ÓâÀ¤‰Ø"Ž@ ÃìŽæ JpÔyW‹p âèÄ ] K=—DAÀŽqxcvec]=§©Áb”©¡öø‰‹yŠÙ¥ê€øƒ¥h·öÃ’h‰LTŸd»Œè^ñ2B’ƹP¨Ï½.ÌʬºH‰šôÇr³sÖ`ħ§ÃóD< ioˆØ:mèö{*l]èS&ƒ—Ô[ „ú•ˆI£^–Êü•(ñ¾À"þ%Ÿ[Ъh(‹ÚIGa–G"Ø\#K.³'ÇS µKzò(*¡6Ý@´u¶¼ÆiÆdpSVz'öävíÒ¾ûÊð²Â”¿®U0Máåò½:S^xz–/w÷[/Ëöck÷ôè Qk‚á8©ŸÒ#'Îîøäñ½­—ùNÍþJ·T†åÓ›bb`i t\’¨J„$›l:†Ñ¸96Øt&`ϘRøkbu;“¡PTg³œ:/áØžŒ@WØŠú¥NùÔýa`a hâP¼|§e¿æýÄfgÁ&šJ ð„³²b ìq›Œ}]{↱±dТ4=ÝØqì7VvŸ5øë+I/,ØoƒK¼ «›¶'©'¼]÷¦æf=à)üüгþ§.ÒMcœˆð"=Í}¿hÝöÎK¦*¬ +íþ@Á ›¯š¹ù`‚Žˆµ´‹ˆ‘±IŠPcñC.tuáWoNeuTÐâËþ~õ·¬Yah$a†<†f¤tl¨}*ñ©œ“ë‚Ú¦¬¡O õãiYõEýY]ë\šžëðÍ?~²—T•Ä7'è“J Â+¨¶>ƒ<À@ "Š1ðÙdzM tˆæô(  8ô)E®sÉ@, âÖ^ÇÁp¸›†pZ;níÕ÷w²©wÝ7Ï´²þ8˜G“ZJΪh;9g`MŒæÉº{¥Ⱥ3„_Ù ð’€¢œ§-Ý—Gµç,bp-Ðn¹i5TÊ/ÄÑqzÌ{;H˜ vyÄ•Ua«ØôŽ ʧÉ$~ªoc}%Ô@½§y8Hqn;ýÛ÷OtÜ•µêÚÃêꊟš¾Úþ£ÚX¥[››ø½öèáªÿ›þ­o­n>ü·µµÕÍÍõ-z¾¶þEÿö¿éŸ fÕþþ_ò¯°²LÐx©0x’ЬÈݾšàL¥DOÒqw LÚ¯§Iûª?è .ì¿¿X[âOüíÚ*Êœ*Ž“{œ³y'¤¬©î1궬y¨R! (ËDÏ/œ¤ÄçΠÍâŒò &T[¹”Æãí‹„U܈©g—£iaÊ>˪b½>x¾;x×¸ï ‡ˆÀýÀ 9CãÃ*¾Íƒ±²»¹ïöÕevèF?U­z2 [‡Wv YQžÖB¡®TŠÑ09¼wÀAu%ø{¤\¢j©ý±q¢È ôýƒ7Õ&ðÞØË,’E€Ýhx/hw$×Bl–ê’[ØZfÝ&ݱÃÂÅ»<;¶áÌjÂzÁª»^EpxiošNª7 ÆËšlp ñ+Í;u¥P(<0¼ч,â dÔƒçx—Õ£­—…Q~ÚÜÂ@¯]dkD]™6m}ê1§Ü5iws¾Wåw®ô'£6J%@î ‰Ž$Á5ýôÔ?_CȽûˆÀ}çPÏŽbn˜¼¾H²B;L§Û ŽzÀƒ ÈsgÑSÈì¬úe~x驾̣´5,Ùý­à¯§?Y4òƒúÁSï{³t>{UÛ5šQ³ùšæ*ùˆ… V*¬/é¥ÉìZtÏÌyßß/^1· Ï» ‚,›Å§'»ò½Z@vÜzër¿íþ\åìÛRâiv>Â×wŒyÄM‘¢¶ýÙ+ú^o–£?ÏlLKd$$ÕÁÅâTUKv ó:«é­;›ÞºoÓ[¦éÏæ˜éû6<Žá±³‡…ÎßM™ ®ôÓ›ÅP Ÿp§ ©2;åy§( ?-|Î'–Œ’ðE$sád´…{QO¯ä½Hh¶ü]t4[þ_ÄTˆéñÑÉé¿(êEõ^t†¼Géåþxp•..†‚ðÒÌ*Í›K9µŽÛ_[«ysé_ÔÿÿÔ?ýCYåûrʆÈö'ׄá.¯NSÞ){Ų[\ÊŸõ9AXOù\ï׎^·ê?Öö[û´w·£þJ $qá›nÈ,} Ýç’b÷é¸Å‰ÝÆ#JÜRküÒŒŽ?µ™Ú[€Ùní­ÌùMoÜmƒ™ÃZ›û…g62Oé—ÐÒpGÚ)ÿË_2ûÙ-Æ÷Ñêý.*›O˜3FXÒ˜=ráä5´lO›ì)/^ o¦lù‡)3±Áõô9Û»¾ëžíÒÓÌ%ŽÐèfÛÀ]ýå(Mèæ/ÏZ˜ìî¸Cl á•2÷Mï’Y½× Þý¼`ÈÙÜ{À'ÈwÑýèÏRÝŒk C§o©›àþo…oݳñ-¿ñÏn·4,yÊìŽî¥#uÐíñô·µåSgñÿE<ü¿ˆû¿ˆû¿ˆûq¿ë"ËëKSâÂ}/€y•NI ÿº$þç]Ü®1iqØÛì£üvKøóÛ²÷áçjµŠ^à]Áõl˜@|ئ(ýecÄùˆQÓèíEòxu{{íO½ÁêÏÛ7P‘&`µ‹wWµÓ_~S±ÿ JŽ–#ÔPæj'pCÀ^”KJ⺘)I=áIž Ç#÷ýzØ\Ví¶u>䨊îqkÞS=h²þ7Ý‘ ZãQ/é/b1xGâí.ν^5¹{ýaÏrñÀÖÉ’æe±ü{¥ý%Z·•‹– ³.™ioÞA·èï·ÝÊÚϘÀR¹´ý†~0Ì—VÏáó[AB—œ]¬}£ÌÙäz~ޏ’§îÉ_Ö~6{æ³ôÃl*¨‡ÒOÍýN[OŸDËØ†Ø‹ùË’Þèé2¡¶KKþe-0bíAOsègtÍÎŒn+°}õ^Ñd#IµIËùSxw±·×`HfØ‘·aGØËÎ üwúâ2$AÐ2s3ЇC‰àþ¹¾˜Û×é×ü™Cþ­Íï^Ù랞[1ïÚoä Ë…ÐŒfãHÓßžn3óMJ@ä}?Eü3ŽÒ}¨iJóZ–×FÏÙÐm;;TöЮ4·Oµš&‰A£àš¤öè¤Su/òh3èq&¶Hóõ½7ñKïBMÆpº¶CQfVYâÕýT6h9*ý¼]2éº[Õ­y?¸]ÜÝâºkºL«<äEþ™ùÏƪ›³2¢‚FgeÇMWŒC;é÷Q»µùEÝÚÖnáÊØ‰Ö¾¸SLÔͽƋÆ)j]Š>}Šüê—ÂÕ.–kc狨ӽ„¿‡úHÞ$ÚÖv^ì´àŸç4-g™žÙi“q!cËbä†ËèjϯPÎ]xÄr-Ž;’×*ÿ»à£+ÈOM|»ìUL?XоCÓKSX&¬;®FÇð[”h{f”Xfw ;`f÷j7bfaÛ2L©´²cpNñ8⎮OooŸ‡SJÄÙÝ¡Ye¬U¶»CI¹ÎÈùÖXb;<ú¼¥¤o‘ÞX"J3ô‡e&Såhm5`¤¹³©•_¯Y16°Ô(ZŽæÔÒIclÔr4J{ ÷iCæÏoáNŘƶæ‘å ºÆ5dQŒ²·#ˆu'š š£þ– ½—nðÚŽ±ÐÞæ4´5ÕÒ–7M9mEÿˆ8¤æé‰?­—Z©Ádœ·ß±áÇ3ü0¡Ž8Á«aÊëmVW±d9]Êö,Ù±)‹Þ¼~¥žåËLËÓi›ŒÈD2GåŒN ¸B]?}C_¸^:›ÿÓ'bþÍ!CŽ!R}2äkŽÇƒèÎ{pž‘'JÅ"y[:1­‡5­é¯¨øh#m;d©¼¢\™yS‡wiÔS…Ì,É_þ »Ó%+±¨@5ú0[ÃüR{Vf)Ý&3uÛ9éþùî~~ sÞ_§Jø½];=y¥=û·ýûê¿Ðÿ¿qØ<ÝÝ߯^wþh×øÙþÿ«k›kÿ¶¶±¾ñhkíáÚ£[][ÛØXý—ÿÿÅ¿åe“7D`âN<4U“À$~¸… Ìù¸G‰ñgÌtÞDßFË˅»wïæ¥V«eÿŠø-yF?f¿¶B_ârô×»èSTjµè¯èŒ¿˜ùɘTó§^^¤ÿäôÊÊUu6»½3~Eÿ*·>á?C]+…»ˆnô’$ÍÓgÛ¦iå)) €BoŸI¼â1IS€`-ìÌüW(ìÆ ½9LâCæÔÞ î˜˜Gß{ßÃwUœM?P08뚉ñ<1Á¤]é•ÃÓd=º$¬Ò&†ÒÍj!¨ÒÖ”šª4P©l [úlíØSM àûj¡ðÌÀ'ó~{Ñræ qÝ&|‹ì¹ š?¸@DÝ ÒîØÌ£˜!ÆW1 µT¦ÛîÆ½‚ Tà\0,ðöE㔡ä^4-YÌwÆ«`Ö8}"5P`Û¡A[ëj¨©Ì}ßL]2X‚ðlÂî28"¬Lr£Û0.–h ‹9šô£wÕÜ÷.Z|Õï~\"9±ð.À*£oLl»Äè ˆ¢É› ( 1± ¿<*„MÆ l¢Ke!„w'ã€ÿRÄ]\}™;r(wÁFá2x2"`°&1«mdö£Ìì#ÊÕŸ¢úˆw@ajÍfFåHßšLâ‚äK±ÉíÞp”\t?î¬ [ÀÊx P+@ôŽÎÌAK"Y=½X0Þ±GlÊü;ƒèo$ñ;—•㬱ªÑ.Ž%9+àųyK5ÉwSe’Š„ÜWÀ<²­ÏçÂË£ƒzÎö¶Û§÷:¼£¡f;:58ÚHÞÀ"µÐkýrJ´Û”¬{!ô¤-)Ü/ñ›N•Æ“•™TºÚ°u¤ËµÚÍÄ‘"9'ý9E\c“,Þ ZÚ‹­ãåÇÈ€ý·iË0´mè©-3{[›äÐR›Ù*¥§&“]ݸ#áb0a4²5®9æÒœÁ»çpò‚À1šCfq<ß…¨øï´DU¬‰C@D²ˆ„B¡‰íàCÇOjà­eÜŒÃF.¿«s’ªÊ^ëÅá+ÅÝY{WȳúF¨ªn½£Ú¡Q¢cÓ úÌûÙ‰æ+À×Å?"5¸ÈŒÌÀÁ ÒàVDƘ9ݦ† ÇñLÁ2ÊÒfÞÀ¸AßqvuúÀ¼Î;0YÄŒ¡ âà[iB.xF‹¢Ó«Ä˹®ÉW ïô Ñô»ï£N7žD›«_Gǃ›dt\‹š¹MXVpÃå{õ`Ð'¯é.Œ¹ž—Dß@ßy'WYPJ¯ ¾x{ÑŸ Š•{g?·WhnV®äÅ¢ï»ã•á°½B}Á[æ {ðŠ•Æ¼WrŠ/A 5-š*è\P©•¢µ·›îajîïهĸéC=)æ‹Qܧce»W³_í2OìÓþu¡Fééγ=lWt<•S= ²î*Ã[d§ûðñV… ñ—•ËþÄ0w÷ýæM¸eûrò1iÛì÷"ñwC{FÁ0œ†F/öh6-_ØÚ8Š…·ƒ.¬LäÓO7;’[øèL ík ¢l$¯ªÙ¯`òƒÀ +ù€˜sAJQˆoø“còÎ̉w° ÆÜ®ˆr†°° qno~>¼t‰½³½}ÇT¼—À>Nr%Î kÊ–©áÃ,F–¿‰!‹NâžQŒÆÈxvzñѬž#NŸiŒàâa‚÷™ ¸”´ÐëŽÇœÇ;Ÿ¹Ä6Ú=©½¬ ý¡ÐíÛK"NÂ"¢ÇG(E]ì¥x“¬HQN&ýüdOŠG¤s'<<ßœé•+ü®ê¡Y^xŽûm"Ù.èø¿cÒñ2 Øö4J2MãO1Š@Ÿ…tQf_ü‡?~éõ$ äÏh>®âkÌPŠZ876ï*ͳ¨Šü—ùÆ»M$§$¿*`Ä´Q˜W`/WÉÂ¥¶šÚ¦úÆf}¾×jíïõw‚_Tf¡ó[“O‡gc½inOÑ[ ÇÈ,/zpµrwý<¹–±ÃVK>¶ùôRãå}I•²¼Ò7)¡$oïJ³ñ¢Yñšn//í0NS”óN3§V«Kï ‚®'·Ç»‹´þ:£ËÁ ù©2b»~:èiòŸÍ` «qh#/ƒp˜™J·[™óKinRø•wQG¸(»cÊFŠÐ³òÀÛLÊã”*{nÚw¶6£ÊeT9Z/é^:i4kŽÒ©ËâÉrÌy†AèèðéVH;ïƒôŒ†“uÓö Ž+J?Å#sá”Ü“JZ ε§ßÓ#®+¦<ÑH!¸$E)ÍæÇ­„S¢÷ÎõF©–mþg™„05”AG%Z¾ 0cIVÜ/‚—æ=U: r#ÍÙJ•~HîVèÅïª:»»Äô"µp .3…>úxÈ„-úÌxrèËÑáÞÑèѹh-* %›Èq1êRá¿# LÖz0+’8òTv# MóeKÊ[_°gÚŇnÛéN«+<1+˜ßŠ«²b›¯‚%Rÿ­ö•HXœÚš/†YœfÈ|À4M'׊Á :œŒ•¡€Z¾ÃÝÿNV†;íÓOq€¡ ˆA ¹OœóµÝ>ûÆÜö›0±LaŸw+›ÕÍê÷6óx;SWRîûÑ[IT›U¥üìŒòF&—ÎU Hûj3gÂú/Ü*6ã‹Æ)k<éB6h—›=.€Ö|Wl*YÎYž31‹µ_ÂkpRÉ<)ÿýq¯ÛÉpïïrç ´í¬üRÛ;ÿ[Í.Ü\öáP\ðŒ¡ªÃDémÃzÛɯ¦“ó(Úqj]flÞt(u9ž9–Ü¥&O–~çÚ“º˜šèÃË qIï̾—šçŠB$ÿ‡Û++—Ýq5?;_U‰³­F—xx“œ¯üu¸cê쎟Æ;¬Â»¾òk¤I…™É|V ²ý•Žð±ëB.YéÅãLuHv\ð¾N¾» ŠõnQ¥Ûœ-2ðBA4Êš¶9ÔkF"Úè²×ù¥†QÅ·Ù^8ù& YAI Ñ­ÂXx ÆzN¯eUÈqû¨YFK–:›ƒI¿©0¦ ´‰Ïã´Ûf {9“›Sú'‡ Hê†zˆøG¶SbòV„Y*\¿§ã)U¡þÁÓ[Ù«ìþPoq†aNJ±s¢vó•Úq[Ç'õç=Éd…o“ˆÎS‰tÒ„ª;–\ŒÖ®"ÿìì–šI!i8›av™ã(UÙüÅÊÞÂoGǧ£ÃÏ; ¿½ÞÝUÿ\¬2[À ÒÈff…\Q‚Hs‹¾€“Kk9‘Žúåèè⢎&Ħ<'Á *eÍÕAC>mÔˆÞ=“Ž¢Wô5y‹09Îpɽú’~í…¯† ¾EfÞ›:ÓôêK,n·ÈeÜ$ï(Жðí‘^>†A Ð:ž?ˆïRÖUš ô œNíe¡pØíÿg\ÐeäÌ8²öçã¸âå ŽÏuk²A-v™ÁØ€âqØõp ƒ”ØãÀM ¨.NǶˆŒ›õºÛ‹GVó$æ.þß}*/¢"OLÇ¢ÏóÅç¢/³å “â ùºó.ïx"‰9*ÓÿÄ"NÝ>ÃØÎÆƒ3îùÙ?clµí3oL¼P==•Ññ©ïOŸx;°nÿÅ›Ê ±ôþè¢ݘÆüSsö03ƒþo3ú˜2xzÀc4¬Xs®æåõ~bws²À˜[[¶™Ì½ý}A¬¹\ž‹µ“Ó%‹OÎÌCÊ¢s¬'­!9UÙO,Lõ(*”€ªðjˆ®ènéÝ€MóK;š“£ÏîË -J¯¤6›®áx8ä”R†±2¹`—ÃÖ‡Õ#…Vþ„Dr‰iᜎ$(—l0ºàÂãè‡þà†Ø#êÐ3Î £72›þðìÉæúæc~ý‡gk›«o²ÚUœò ÆŸ™1kì¨FõTÌ4²î5§øìK¬ ,ŒH×0b¡A•‚ŸÁÎïr Ð†"L²Ê%î°Ò벋Ä!¬"¢±•}«üyQ¹)c¸6C«Ò¨WÞŸ¯p±•¤_™¤KLíÙÅã•°jPúTNi…Mµ2Ö»ë•raÅÔw—(R.W1œ¸fìFÒäãÚè“ÕGOžØF¯ÓN?Ó"·³¢¯Qõ‡›[«høØ¦œâ|)itL÷»îèèü?©ý4Úe±‹wä30œØÃØ­FfW]wÓóä*þ ZVßAõÓ¿$þm™ñy5SFNÆ%ÈBˆêS0ÜÉP.P ˆS |1±—lÂeâåÄ·Îð´ŽVÎr¢w‡Ã˜ûÓv”“±ØŸ3°ýaT/ŒÔª‰¿¡ðw@ÌÐüHŃShPþ`N´óò ‘„‚Sß1Ê4uc½”£R—†HÖ!X§9Ë|™ê^ Éby²½}†×›õ3ªäéŸððO…ÂXMÔQI¨ç…Ë–qM-fXlOq}!þåÉÔvùøÂÖ¯du,ú¸•£ÁÖ&VZ_]Ý`¸~„ãæÞÛÝ|777™½GÛQÍT+–ï¼_¡ÿÖ{eHVpÀ‘ÀÚï«äöö8LÑ`²ðCûC,ùÓÛØ«{ý ^kX’¬w’u Ã¥„¤tAúZH¸cÅH‚ÑV³jÓ!…•èIU]?ÝÄC¼#Àc“÷ÏØÉÇÙ(3‰ó<ÂÜtuŸ²_þHÌ,}!Ÿ³9Ár¯hÆ4HtØùŽš+ëǽÙ[ïþV@ÐÇÔ5:ºžÃ 6éyXÖÑýAÚVm[rý1Z­>éð‡‡¯ŒÆF>H¦N|zŸ^Ù§çÝ”ÓæÊ'Þ°“±æŒ¶ÓDê4¨ýÑzumƒ·*yÍ”àoãR‡0Kί%мïZœcëðïóHXJ+hn¹QÂ#n7QÖ"Ò M.¯Ù5ÃW/èÚµhÝZ§-NÍÕj½+µ—…¶ê{@\ –{t5¹Ô]ÁúWo(~ùÚðzÎJò®rùŽ#fO@ ’´yN =uj°wžŽ5Zñ>ÒïìH¶ùŠÕÌí¬Ž#Ñ»£&Äw&=ƒ!L|nJ¬,=å Yß(¼;ÜûáÙn³þnÊ â\K¹S:v*üT¼áv;¤[hêÒÖWï¼s5OCKêŸB|9:9mT9U{PìNG·oì®”D½yßg/¯xÔ±ê˜h± ±GàË…õYdÍ5´;«‘r ï9¡Qè+Z’Åžmoxj–MV4é¢3Œº.l[±J)×õ­Ú*ÑnoxCÉCb臇ÕÕèauÍ~wr` kÕ‡e8üØ0ÇͨqÒø1Úª®—éÇCó »n°o£ºŽW7Q`³ºð‹>=Äß«ëæîÆã-Ý7kÕ 4´ŠëÜ$~lâÇVPÜ,¸Òÿ+#ç<¡ÖŸ<.GõrtxZæì–åèÇcþËåãã­M7OKþJTI¯Nöé” “Lÿ6Ÿ¢”Ž‘º_Å?VÓ„Ï8³§ÛQÀGÉêbý^D[†¿Ç“ªì@ZýKÞ£\Þ%£ *D ?–šÿbó¿(þG?©ŽžU2ÕnÿŸÿ³º¶¾¾ùokkë«®¯?|ôo«kÖÿÿó_òïoÇ»µv_@­Ö8ý[®-¤œd›Ý¢ì“»µ×8‰ŠöP§e¨ÈߊKfd'ÅâÂoR®öêä¤~xÚÚoH¥>›Í¦ye·áUê‚i˜˜ü“Ý“Ÿ yÛfÆ µ_,þÍ×Üÿm©ð ñ™Nh1(ßRU~ãð´~ò|·V¸>ë{ôÆ+=h‰°†:ÿýã“£ãúÉi£ÞtUjèí&¾(o¥3ékþ ´‘¥b½á±¬sÇðDxúúáÉû_5zú¿±µñhuƒŸ¯­?|¸þ/úÿ_ñïA÷â}Ôjñá=>i¼Þ=­#í&9›ú¢ðOIµ‰”Q«ÿJõ¯”QÿãRF­ðÜ“ãð¦q¸±î9XjjEt3»Ç yí0Ts¶Øâ÷÷Ê>’g­ÖÃ;}kžKI{þø£—kÊ%©:¬ŸrŠªÆ!Ž«ÍQå'ý>ûâ›ÝÓSTgKÛC.fp¢ÜA{ÜãÇÚ M™œ–?”ÛKªÆOZ©>³%¹goN§õ×Ñšk]¿Ý«?ß}µ/ù’^Z͇D1ªÛëuÓùD-oê=æBܿ͂¡_CÍ£tX·oyÏ¢Õú/;%µÔ<>jÖ•Oi‚ĉ¦«©\ðiô «¯ ’H¸£×_ewNëôdz}êC´ÎøVµß~¿¢p3„ûƒ—p©àïÖa³õäG?½Ød½ÌÙ™ºQÕð™ê5“ñÙY3Ášž½þ¸wvvÐ<­³Õ«þCý§/«î´=ìÏÎŽm8NXëÞa³¶ß !ÀÕª'—Þ€Ô k-¡šµQ¼H'³?Îôò4Så]õõËáinÈäÛ¬Ÿ¼®ŸøyHci2JŠ+¹÷²vÙâvâÝëÉu´È¾…K²$.¾Dà"Ð^’™QQ®ïI}kkà 刵橰(,¿ß$²8j ¯ •ß—|Þìšv¨Å œ ŒŒ‰ø™ÿ4P≂¤ ,_XÔKð’Mfí{ÿüÔΚ€àGÊ~3üfË}³e§y,`9³ úü[h/ð$ðÖ €êYøYÙD@T‹–Qì©dï%}À[Yæ8Jn‘w€fO`ÖNn›%ˆï÷rp ɨ¥]¶jšy©‡”Ê>,¶Áq€$iáPeÛq9oiN ÓíCXñͬÐ"Г$è`0oË·÷ÙŸV—#ÊK¨b·ŠÐŽÉkɦ‘Óßa‡˜ï¤›´J 1Œ;Ö½!é_’LM{§“7lTFEèå·ë??õö <¤­˜fžRm¦ÝgÓMÆí1¼sˆƒö33Ó¨HzëW-O¤A]cª„DÒád|çÄÿ"ùÏf} GSëÞ|D±ãQ?v"{—AúJ8Ø'¼›þ5zÃñ[% +ãh[xï¥×]»;R‰hd[8;ÙA· «ßÕ±Áë– !µ0°6c÷LDrƒØ˜ ƒªkЪö§,Vòt&Û“ ÆZ ˆ{³å<ÚÍÔº#`ê &ç½ÛŠÖIsASn]I5Û ²ôXuª9S#RjáÖx 0ЦÅ}8ož3ÃG’ã+¹‘«ÊÃr4/7Ò éóÑà}Òç…!Žý½7Iì¼(_+Œ³™"Ùju—½ÔÑ´7J|º×XˆÉ˜ã¯ìTvÓ–Ô'g÷ä±§”?2ÝèÔ1áùá|,Ñ/]«£äÄ_Ë:m2ô}Ž¿4¨ ÓËÍÎm†ÃÇ.a@Üy™ Ú”¶âœ=“*LÐt7½"B„]høX°X/EwÑX•‘ )Þf%$TYeö\…¾K"Ä@j;¼­nXâ£Åµ%·H3·àùm ³¤ÜÃU 8}ÐrÔUÜ×/† ¢w×gç÷~;?§”—>ÊlnÙ´!Ä·Y‰5¡Ée—¡d§€*Éµç ºJ5y4Õ»€wG—¬MM˜<Ñ\µ#‹Ø•âµcH×¶4çºÿÅkínËœd)wó¾agúåxtŽ]3k:ò5ºm1£ŽjJ‹ =¢7ðlîjð¹2ŧòH ®€ÿŽö݇Cƒ±+áñ :ÍuèJw10ù]øÃS…^OF¥I^Ö,ÉNCëÖ¢ù3“Ãþ„-“’SÇ)Û)Upu˜xŒ‘¦ñKl/³C‹Ž³‹\J Æð¾éûîÐìWá6¯ MÓW:tä'Lòx)cÈýõ>× WÉ[I( ö°wÅvºÒí¿¿z£Úö¾EÞÑHFT×5¼@M¾ûõ¸VŒþL_§ï¥Ï,•'O¸~Z?9lì6ˆV?®M}QkìÐëNDÐ&y–X&(D°TðGÖ:u9hê…î8•F13Os„à%¸ßɇ¿ àj«£öfë}r[ømŠÚð–{»þpëç§Sß}œ~D­~6µ= å1½ï™]Ô ³=;F’Ñ‹/³§è©lµ)}¹!)Lq5Sag0¶FŒBÞ¦³Ça”~‚"›T…o7¶ ¹Snåº/ëîSZy}æb•/†Lõ4üΤÝI¶„çå«ýqÛÏÙ­¾œRÏpOÙ©BÇK] ت ÀÓ_  Ë®2RÅÏTfkW8¿ˆK+V¢ý„4Ë\sr‰•_“Ñ@PÚ¦>wÓsG¸êUÝ‚éîíÆz¸÷Ð7)ÒnNoAóÕÖÛ5lZÌ`8æ#‚‘€Kø Zw"†¯·2³yÏiê*wÁ¸¤ivM§¼­L‹w?äÉ…ËŠ»Ì¾ù¬ðžÁ´ö–ÈOe|Ý‘^¥ÓfÞe–ØÃ=ÚY×=™ô@¨drѰzCyý01³L×eGr>¨Éty¢<Ïi“±r5üÝ<ÆØž6+oÏà_–Ór]¨Áqé·à…ÍüeÒm¿ï1Œ2‡]`Ÿ@º¡­=þPºí_®¬ÎþÆ^‹Ív-€ßDë«›ïfÌßæ¼úóœê …¤k£Ó3ÒöÅtçÔ®êwpmu}ó~œþÛUüì2¼bÛË!nµÏ£à“cyƒÇ-Ñ‘”‹ãšƒ‡ÙŠìóÜšøÞÌÖ¤§j2Ï]MÂæû—³^5ÎÒ»,•âAš©Ï‚êÀ¤"ÁÀ^©U†ÃuÊÙºiDTsƒýÐQýeyÅ[o°ÂøÞ@Ã¥äjãÜXô«X€Á*Â…Aÿ®ÿÊ0žˆ¸}€|B`sL ç/mIe‹.SD´ŒÛfIÚ<ˆÌë¸_&öæMÍJè!.T™”Åe/3ÍÒ¢jEñ‹*Ë+IK+Eå)lÑì·ô%äôðÞÐ~jJ Fédœí¨>’1#ܰ7«]‘ξ"º5^Ì(–©¢ü¼¨™rÜú"1Ô\)³3L=ó“w≗ø5+£GN¿¨5¯1¾…tû¦óÛË»Œ©27p…i–{ñyc¿-_ ËGmkÒBÄ}qš2¿Ȩ-\E^ Ê©±>H×t­½Á`uæræˆÊf˜Óm@oÑUO,Á¢^òÌÐ;™)Ô…ÿ@3É»)è}òq/h„æ–¹sIô;³±¸Œ,™ bžn¾—ôïWÌ%]¨½œO¨ôj89¹uó6FøR~ïïÁW…=wØ^äî™^ÄGfOÕx­<¥ÍCþSc ôÏÐcÞÝA'Ê¡•G/¸ ›ov[Ï~:­/Æåó%Fƒû-+ÒÝÄÃgÈÁ¶C)^"¿øÓ¹|:Ç'Sì)rYŒ£Úì-ToÕv÷÷ŸíÖ~XlÓ¨ÊѰ›¥;—ýé ¨K¿ûß™MªºØ^ª|ܾK_QSMדS5ßze$ð¢#ü¸YZzêÕô9zó’N~‹39o«W'û{õg¯^V4óý¿7¸©ôøÇÑi•«Xà  —Äï¡ ”‡ ,h2àŠ ö.òI¶’ (Pç‰`´â;jrrIׇÀõéI*‰”©”]ü$™r³Zl:€›…Zd”EÖî˜nð!†!DŒ¬ÓŠû·7±˜5šô»ˆ¢­úlÜËúî^ýÑûX|uÜ::¬Õ}¿bµÊ4;Ü0ÛÝ œÇ¬Û.Ú¸Ûÿ»7¾ä½?Ü5z–ÿ÷Úúêê£GkÎÿ{k ùnüËÿû¿ÆÿÛáO?xíE‡G§Q}¯qU¼Ä@æfÕ€oÍOR‰'Í–éöñ~ø1 ÁT4‚õÃúêÚfeu­²ºQ]…/ âs£E„¯ë‡%„UV·èÛcKVd€ù™3\±öêÿÌ\ T0UzñúS^ F’çâñ¯ÝË÷Iw}wIþ¤¼¸[½îŽ«Igò}Žì[èR蚎§pMÈ€p‘q0”d«êdÝè·Ñ¨¡f`^¬OòS É«s ‡x«˜« é.ÐË#ö6?<¢ÊŒòSvÓN>h¦¥ƒúIíåî! gýÆéOàfŸ7NëÍfôüè$ÚŽwONµWû»'Ññ«ø´ÝŸÑöu®§»hòLŒσ^²¸@™%.öTKw¬°ñ=õ3@ý&]Ë1»Ssm=ØÞÄŽäé˶T ˆÌ˜Í§&Æ^cÜ£uÓ„Ö‡P{ªc1Öd@"?-±ß·0öú&- •cd%…b ß¡Ñ×í2†+Ι¨9±C ‰-ˆ+d ½b í»CSÆ[‡dm»«ÜN2ÕÀæ»Àã^&>€d1ú©Q’*€ ²ðJ¯d2À©cE`4T›ñØâz |[ôq¬§/á¶½{øSôf÷ä„6âOO'ýµãgýèá«ÿà«¶n5õôPÿ fm± Þ¤£Ä ŸÈº¡öQõq‡±r‹Ìì=@uÄÌË*“Dðœ2Ê9LÉ$õ¶ œ=©#]ùÇ'G/Nvv”Ä4†Ò~~]?i6ŽwŠLú¢½ä¼÷+ü¡²U,hþCàx>èï…K$уøð ø+Uýྡ‘/§ÄœïI©#ɰÙí–Šû@– ‚ƒ§ê·=óŸíl}=­y€¤&h7Ò°·sëÂyæ|LÖ±A—/cÛÂÖÓ¾…šPí1™}ø5L…Îӂ󬙠”\ŪN*¢ŒF59…‡ÂB?É: Æ@µrrA†€&˜é¸FÓ똚Žõ@a*TMEG.(‘Oaw·8pð5ˆ?bÓv˜K,¶£…ßv_Áx§h@^ŠŸí´•/8–öó]‹¤3ß”›It-qOiX7¹ÇÒèª ‡]iF3o&.æ€Ìtªé«ä.Tn´+ìÀHq^D3ŽËÁA!ÑË Ã÷—Äv˜ÕƒH°@Ì]¡hÖ†,{¸ZßZj·yemµ²ºY]_Ñþ<­<â";D÷ÿù€3К%œ8™]‘å7@ý_W£×ñä’¶#:lNó&äí9_qêÅÿeŒÅÆ×3¿‡¯˜æ*¸ã_ÂWÌã*¨²{ð÷â*¨ªù|EÎú!_A5€èýsøŠ9lÅWrÿl¦â‹x Cˆí´cÎ'—ň8\CCõ 휿i%Õ/âêÀ_Žη¸SMd@Ž”Zr[°Õq¢8m>È\¡  .}”Ps0mQTÞ%í«AT\X-FŸèfkÖ÷*tŽJé§·ÿXùyyáÓ§Ò;OEí@‡‚ KU(>‘Á³28×ÔE€ž——Ô <‚@¥eÑܰ{£P&2–IbЦٷ¬¹_ùBÌãnªIbf߬:õœï¢Ô¦ê”46̯ÉEJäâÙ9L˜¢ªÏ•† RPÄýñLú.‰"iïQ>e#“T[àŠ4µ[è':ûm¡°÷jwq';kOM®ó(RqðC“z\€k F¥O‹øÛß›/[ÊÞþ…&ösÑŒ‹ÉõD•Š/Eßs<|"¢õïÿ¼öTœ æJчÃWûûµƒ½|Ý@R¡ <@Õÿ{zÅÃðýæp±¢«-ü¶ö—âÂߊŸ•¯àÄz,duÀ¼ËDB´g3ýa‘“xL3ß Z?š˜ÊeT²5–vJø]*0Z']t϶^ì=k5_=kž2ž,{8©ïÁ%Vtý»1¬.Z¤÷Çå¥H 0Â÷Çè)Mt· ]lˆÃýfÔŸPψL·áœÌ»A¯cÒ©2n‹YϘ³(ˆ§ѵ^´Àn¶Ø=$ÙÁç4¾Hìg,$=û Ñåû»‡/øÇ+W¢ýZ `çô«°4þãh÷”ÿ< vJ5 8k³Z¿höƵÏ~[Úy3œeµ=‹ÕÒ2;g ú—WÀ|W+|c“n˜Rô$3¾³¢­ëìl+?Ó'O#þË+}VÔüq5Ôô ï[¼qÑ-ô„¹¼=DÌU ‹“>†,§¶8Ž€_€yh{Ï›*ɰñÑä2J‡;¥¨Tè÷vJ…R îÒá7 ý^Q®cðzìiŒŸ,ÿŒè!^Þ,gTzZЏ1OM‘pïßÚcLg˜£Àz²{zt¢ÇøÛ¬ª]¿° ŸÒEÆ®-AÁø?JO£ç.»ÝS$´ª´£íÜégA¯†í/ªá“I žé¶ >Ró¥#¥Ðû´Ìc'²ZÐÍ;e#&ãà¡à%àòvµ† ¢…Yob‰µ ĶS¶ø©¿FÉ%\môú™n`q© Ó'dø‚–pÉ®|þÈŸ Ÿ]÷ ˆÃˆ8h*šŒÒÕ^Ök?´ž¿:¬Eo1?î”Ò³C‘ˆd ƒSìLË.òŰ*‚a¥bxsÉ.á0¬xèô‰"1VEFÛ]u ¼Hðòzk…è²Ê#‹äŠs@ŠêXÄûž[Lbc9OZ/ÿqf2ݬˆnÉkL¹A°qúU_Išè@­°Æ &U ‹H,›îXúê])"ŧ@fR}Ej±™ò¨¨„‰ÆÈoáÖœ± Œ‘tZ"Ôî¤+ñÝÿVÎïúÿ>%=]¬ãZ´mD›ÑÃh+zdÉIØôB𑸼ðAÁni•˜ƒo‹¾”A’4&åÉ“_¢ï±a0𪄫…M‚Âg&Þ¤ ÄDp„ÄnÍÞ ƤwÁpÔí/¢Õµõ͇[?ñšUÊD;6ñ¶žÌ‚¡m’ÀY »Æ×C-ý!òŸFÙF¨Æa~…ýž”‰¬ÿ}ΗSTö"ò§/úÎ{Åë Î^0ûŸ„@ŠÔ½ðêAá š)^6xÙÎô;`W Æçè/ÑšIºçxwó-uýrœîî¬}”}ìC]À¡›ÅÌî˜Uuï“dÈœFÑnÍ-ŽÞNo ¼[¦ww27aûl.ìnÁômmuyqýk«KÌìpl·3&jX]ÇÖœ¤lµ>W°¶Uzጘk#¼F×Á*û{&Øaý^°„,V¦î»¨ˆmrI?йçJ}#+ÕÇáå&§õžêƒT"Q;3î&½FîEN_œÔïAO/GÉÐT|øRŠŠv,IÍ+üBš2ƒíü_Gj01÷%7‰_(ñŸ•EMûÍáK•Ò¿èÏ¿èÏ]ô‡Ú%~óa> ¶›Onþ[ìÿÈþ5&Œrduö m™º E&f9º}µ‡²ÆY!LŠUéaÆ,o¹l¤8ätlÆÖ!>&‡Í5ö|¬•ÞÕL$MIcXd›&Ð0¦’gQ&²¿v¼S$S1ÿzíåÑNQ‰ßŸÒ³¾yÎ 'ä7ªÔõéóàés}ºØjî{ý¨’êq!P÷~ðÃ^ㄞ gŸyôš>p=99Ø)ò¦ÕÏÍ—õýý >o¼hñ犺~žç–à6 2`%Ó~—V{œÞi0 K]Ä4ï”ÒO+ÖRÄßšÁ|õêò ž³zŠZ˜œ N­MK \@`K Î_÷Ëd€»SEj”öâô ¡²)UsŒc§|qðâõ¡¡lêƒÌÑqI¢qöX Yäg-îúy¶ø–„ü³³ŸÏ–>­}º”>sú¾T gÅiÉ*ÒIïLØ4=Z½´œie…Z)¾ãFVÐÈÊ圉²ÕÒâgÁ±î1´‘ÉG¹‘œ÷›Ñ¤X¯;†´w+ÝÀÞj鳿‹Á¾ý¹úö4Øå³•Ÿi´þ4¯ì<=‚¼Ýl¬«Y2–àж:J9IåB}º‰aª±¯ºŽ;&(ó’¶ãaÒYr«ÌTcW`nú1–†èÄ¢ìʰø›–·5ny éß2ýütù”ö¤ùƒ~á ãIR)•8‹*£fF|’y_Y,82å.¢!D7´©¢Š˜ÞåZR˜ûÅgHÝ Óñ¸iñ2êD1ÕSZ(ïç·ªI]Pø&fö8iaªÅŽ>|Ý>Ü‹b†!B­h“IáM4¾à#‡±Hz.¶ÓJÿ¨ꡤ‘¹€FeÄe5±£zhi.·NŒ^Q³hÅt’Í^çéNéì¬$®ãoûiS>Ù'j!ÑÃ…’vìòîⲊÞ^ùóÙYaå’ýCž­/Øj´ÔŸ9b•NÙâ[-óóÙÙÒti:…ÞÃóÔûJZ8믬\gPQ¥“/zƒó¸ç_|3è§1ô‹FÇ8|\f^Çz2tïVSøÐ½HkPý¯¨duU´%ÿÁ4š»§µ—;[þíDôgWýH©VÀ;°Ñè读)ߘø’1Žþ MýÐ8Þyôè[Ó£G¹5ŬRâi"Æñ³ªŒ2‘WåiW)¡¦éäZÖOý¼\Ž\ IR„8ª(5ë J gÔj_wJ‘Bɧcã¤F;–×ÛN¼[©KÖëÅ£¤e¿±¥xê9¨Kqþ‰lS;%v PÅæo0µqùíêÏŸ£…eV§—¤n4_‘]VÁŽ,¸:~³WŠÛÄyBõÎßlcŽžÝzƒ.#‰gWë3L~Ð7ÖÛ/p‚mÄ_¤7›ìꛌ#¯ †Þô+Œö¡¾FÕoÖ’k1‰˜o °ÜŒà"¦YÅDdì¢Ö-%9'‚}\ðp¬ÞV’‹7&}Ëž+^vü Ͷ>|#¶Wà‚cNɸ Ø>穆#&V{XŽì‡Í¿”á Ã5ïiþÎ'že@œi9áí‡"èbhÄ®Šö 0pì¾"[?¿ÈጠE÷ÂFÑZ´HŒÜ’ÜDꑉÝ;H»â|ìqV «eÇÇá^, ¢K’ ,¬)SEŠÖKð–; «êiáõœø¸ ‹ï ¢Ñæ5¯£O03Ð_$)¾ ½? œ'¦ž§¾­L Š,`7ÄvÅ`Û‚ýÞž½üéínåïqåן·‰]“Ú²|µ$z ¼ÃèU©ªø.óV»£¯;ëð¦ã•‘ÉÒïWÌ´Héöƒ. c.8ãî Ë0OÖÊ–ÛŒaØÚöœQØs{˜êNF ã™ §êq>mvП>¹éø²Ñ³Qs.×&%Ž¢"DÜÅÁúŒ˜y‰¸ƒ $¤n3uWš¯ WÇ*ˆ+cËI‹‡p,¥38N˜’ JrÐwÉíqÐ*"CV(¡A¨ÙÐðê`«3ºmÑËê%€'Ä &cï3]_çÄiè8^Pû—âºQ¢c[âž–ˆÀ&%µ>NÆiV º ÑWa ßNÕGš¹-ô4‰çƒó‡ÇŠÈäÁ¹=dnƒne—ÝR:4ý¶Õ¶ÛÑ«E}¶ÊŒ.Ó#~Q‹¦°F?ª„qšZG––8î Ô¼dž£#¥ˆ‹o—œ®×¸[+ëê¹Ãñ˜DkIê+.¸ÀPqFÚñ¤æ¡±ÿ¿&¨wnXìb§ARÿ@§x)$5 5옮˜€ÉPÒ­ÄÌ}‡?=øNÂØÙv$'±Kþ¼¸Yšç nÁBbYÅ´S-LMözr—B*G⸇ï©À¸ê%ct^¾cMgoN!³,&'}ñÉÅ=FŒV—‘•R†{±+¤ ϸ âïÇ·a†[´7æ6hfù%v'3ÇCN:4—îxóöúÞll¥Å¹"ç‘ëãŒh`w‡(TM]¬®­˜•¦#6h£f˜’‘ø–K®‡h±ääßU¹è`ا§@J¥!s,ûyI&ï6ŠÔëžs²êt”·ÏÊXÊ¢B&¿ °ÇƒóäÖò²y7*²¾v‘a‹…•4ˬ²IœE<öÆ#ÞÚøà»hËeè¯'!`\v[ˆÉ ãÖ0ÍÊ÷°>ßnü‹èÎÀœŽ[£:ºÄéM¬tw\-ä4"=¯õY_8¿2'$ÚGn“Þx¯šõÖîa³ÑâÇÍ|=GÂÙ \D\™¦´ÃG†1te¨†Os·ùËß~ô0Gîê!•<Ú¿LXU*z[™¦¤S ÜÊØÝÀ9³CçÉNqÍ8Ë9cØ sÅ…LÉiû—½øQ*}¤ë -8Æ‚PvJÿŸ·«×%ÿ9¶¯]—žÊ¸&!O……G —Ýp…/‰Ãìó³õL½Døù&—¥'íÛXJnÙ’‰ñø“ѹ€Æ#Õi„W°TªÄ 3Puí™9ÇúÏôr´¸ÍîXÁ„¸Þù_‡õñ1™ªÏLž+ó.lÁNä‚ÝBzM¢a^ ¶WnNGiDñ¼…rjÂÚ¥î¬g=·Yñ Ü5mæÏ¶HPìΊæVÄ;+(æ*úfõ å´í™–J½¾Ÿ!Pìîæ²óîtQÊ%’fH¼w¯DÝ¡ª1Hû¬]  ób_0Nl«`!ÅßHy Añ2Ù±_3óE×ĆŽú)düù˜·½@£†>íqúsÌÑ€LÁy\,;ŒhýltãzªÎ7<öùõî ý·ÿj¦ç:î"S”ŠQíj|H>v%A¦K]ªQ]µÀa8ˆcIc,8DèÆ•¼÷À_V¡¾¾Î¦P÷¬%ËúƒhÒ™ä/·<^ Ì6އ:HÌáy’j?(h‚M¯l5ç : }FºžífšrBœ<šŽË¤HN ³{Ò ‘öèx§x›ÀàšýþGºŽŽ›þ×"×ýeG¥7$aŸƒñhЙ´E)΃بŠG©(üN:Oà·kë?W—£OTxU~Å€xôÚæwêxŸn¬ÿÈô:rNºêž‹€ twê5~Z;³©eÂo"•œšˆ‡ø=n “OCG&ψ-í|2ÄD䢨Ôa¾3HD3e2®‘À<ìSQ±®8 jÆÒÇøiôñ/;Åè«Ç¾+1ýÍkþ±X B¶ÜÛÓ“Dý.ØÐúÀLw  Ä…wÓ Ñúûq|<) Ð,2}l(dìÕª ·*ù'Öó®Ê2g›µ°ö—³…õ"šŠâi˯ŠQ&¹ ¾•Y7ávâ‚©„öÖÝõDEѳû^D&1‹…|fµ¨Uj©Eæ2ÔZǦÕ4tl\ý9cí ¨K¾ÈÂPÓV)¶¤‘Eþ,Ìy¿ÀÛMTü-V"ì”TݼPZX+½+ÏN^u)ÄŽ£;¨t¶X=[*½+x›)¹­×~ã®»eªÇ>.†W]@À\g^hÑ…ñUt6o»ªÌ•6\ºMõí-/|¦ù·”á¦/).»N”gaq‘$‚¿ÐKKw]M–é˜{3ÙFs ÏÁ]dÃûz¸°LÝË!F_^›Ùc#DHWŒevX¥¿@¦´·Fc)ñðñÆbÂö¬c ãP Hí+ìÜëëìKA¹97£ M À41#jä$DV“üƒ6Ìõ€&_“`AÁÑû. ð\8cvG{Ùí$ÑÀj'ér®í¶¯ïá©‹«oÕQzK<ÅGa(Zç;¥¼)ÛYømíÁƒå•Ï8º­ÎNIæšp¶¼bN˜¼wÿ´²üyaÝñZŽ¢¥72¼¦ÏRáþÌJ*Jœ™ƒ±¶¯µYÖ93̼úoϳ™9èrêa.óGª$£ ÊŸ“<=‹OÍrÞrw8õŸï|Û#4“”—h[ŸKZt{ð´ 9?»ÇÇõýèðèp¯qÒ:©ïïÖêõÃÓ/‹fœ¤ë¡`íq¤®1²¢»ÖW9"îtLí®ŒÛÜÜiŸîaÕŸ ÓâÜ™èäÏ[GrôGMKvŽŽ“‘€ë Œ3‹dM0êÕ5o3G£·£/˜õBó9s rW óòŒõ ‰g€ õâ}î!â×ÌdlÛA+ gfõaíJê™'$RÝn/í?ö/F,Fr©¶“ à Üt%#bŸ„·"EggºxFw LçìÈÙ‘áæºó ÎÚªìO³{ò"Ÿ™# ˜}n‹øKºhn®“”ñQ ®¦™ý KP‹ï,,{×:Þ ­ýüA`4>’3˜hT¶Ö’ ý*Ó/|7Ù ZY1'ü7¬ás8E-Ü$3§I§ªÁ.-Ú¬¸ÂÝ{{&3Ð+GzsÆU»yÓ>/§ºÐíÓ´·Ö¢ÆáóÆó;3ËìT§Fy€0EeëüW¿NÇ8Ïô8Á0ö8¸p¥rþ€LGgn†…<“’Ù&üöÎÂÀ<ºc÷¸C¼={`p ^€Ý¸“]e.³gm>˜UˆaSsOÖ¨âB©'}fÏ9¬‚õ’¢Ðßã¶P co(Êß0èŸFÁ_4¥Ì¬g7å‰ìèŸÐuÃà4gqâ3ÆzFC çŽÑbŸ" ™vµ/¾óëÐ9öëG®žôÓ‚mìÓ§KûþçðD¹Êü…)¾sqÉ™ŠKé§ê§èÓeéqNÅèìÓWÇfjª¹êžwÇ­>§ë5Cš%%º÷þX’âUš!-vš7ÆÛ .ÐßmW7s)‘ß°OØ•c6¸Ùf#€1-ª—‡WûWÞi @kéïÿ…ßd÷æ&‚#œþ }¯•»ˆÝWX¼à ©C÷Ûœ9Þ$1v® ¾/°?Žª«ÿx|Ro²lœWï¢Þûǧ½:\BÈ[Éð¥ì ê-[ÇP ÑÑ™ÛëÊ¡`,º°¾%õé‡h`Ô<=i¾˜/\S¹ŒîC¼R_åýªþf€JºT8J®ÄšXáêvHP¾^ÄÈÓyºû•ó•öSŸt>dH†•v[Œ6>~^øíãŸXö¤ßò B,~á÷~c›™«E™ù=>“x—ÒÃM IÊÖ>O+O¾°£8Yƒ>­X].f£‚™@/\ÇQÞœV°pè_k›^¯üTaȲ¹{9ðhe;üt,4RXWà’¤›×´:Ã4@N·-q·\ó¾|£BÁ—¾Í}¾ç±¶iV\ð\ÍJZ·‘c t²R·zÊ»¸k`=K•RÁÃê™nÓW–T–—rS]Éy+Pƒ¸N½áðv¶C‘£.ž4ÇÎ(v+^ééX”;.(žþmTéäNMsÄÚFŒŒÅ5!$ƒ!{ß#ÉŽO$/¾‚KóZ}§t/|óÀ¼Æ³’í/КԩwcHñY»²ÓÝ^ð¾/x½n\8Åi8\„ƒÄÕÃ!]ô6.[·A†³õƒÊg/¥è»ž>…^Ypˆ rc8w¸÷ÕhpÅEßXZŠŽ·§ØOv0fFîïŸiËîgå±*É m”7,J3UòCŸaÛäU3(ÿ˜f`½¶C¨-ÆËÔËëÇþxõxsÆO%ꇨƒ¹$Jϱqy7—äbç~30™3=/©Æ«@òŗõ`àhÛ©5¡w üOøzu¤ÀºíšèSÚßÚ/8@ÚËØíé9ϵ=ÍÏ0T\æ4¨õážÆöÌè—xF$$H‡» ú­ufì’O6ãS4Í‚Ÿg뇽F¸º>û÷Â˰PoŸí6™!™‹hî†Ø Ks[Ÿ§ø†}1Û|, Ç®qs^Þ»àÂÚ±†<8¬È c"- .”Y@7é~HúåÈtØDX‹BÆcN3£w3¡ ðVé?=8¦ RY_?¯,ü¶V±ÒçðvÚŽf\>fcœHŽÃ8sù˜pž2Yª.Ófª¦BÕ°‡;îcî=ÓOÓËÊÂBÁª” Ù”ÁJz¬²Â‘ņسºqcE:žªþ¾j6ŸmêGý”wYWIw!I}Ó^’Ï5ò b÷`ÆŸáÓÎ8 Õ'»‡{GÖt‚XuDTzD5w2~“÷*«Ÿi^ÂbW¿5AåwüË Õü1BJ«\¡ƒÉ_ȫڹ¸ù r“”Fì0–]_Úƒës&ƒ¾ üÊ£Ú…»N¿âÌè~Ê;¨%W›# …Œ°lì‘ ÁÁnÅç)ßžwð’ ª„`w*“¡ÄŽtؘþbµhxê-ÜÓS(«9?50“…¨B~*V§‹Z$PqE%6G( g+ð"±è-¥™Ì$rðMÆñmö°º¥ÉTíæ– XõÚMO?ýà €¹8[ªÒÕ|¶ö©”êh).óÉ}ÉöŤ3#¶ Ý)m#E|¯ðÍ7é§•³êʧ•O€nIñ/Ðã’Ceêõâ!‘]™{Ü8ûm­|ö/ÛbìzÎñò(±,uX}ä>ÖöŒ&´¼VðáK“kß6n7i8éFÌ™ùýØ ò Ľ±õôßñü fVæ8÷bqÉ£GuŽÀ@ …Fà¼Ü‚«¸Ð¾éTÃÃÆæc¾iJ¥¨´RŠŠ@V Kåv!¬Á`ò˜7ÅRR˜2jÐ""ˆýL’À5Æ„§Cx–à¦e–œ;±«½[[¸,ë$"«o•bqí³!¤ãyÕàO%!·úÞkv›¸ó!&vÿ’Y2Ì;°p·T$6ú<¹Š?t“‘™¼•••eÒ_õ';؆hdÿ •Õ8sűÕSÓ‘© Lû ˜‰xÔåÜÇhèqæèø¨Ùøv,$FMí,”VVJ^=z+ß¡¨v{yÓí Lšñ%9N¡š§$±Ï´"n;ª[¸Ò§ì2I|üäâ‚·¹@Ši@$^Þ šó«ŽöA€åŒ¾›äŸ<Ù¼Æ ,¹ŽR±§÷mFW‰¤ßä±h3Ž"dYm}wL„¹Mg±"Ú™çiϲß­/Úç î¾p4[ÅEÅÎó4¬a¶»Ã×# ’ñ_3,Ü ³³³{=ÅÑ1{Åi›æ:±^š|7eákÛó¨‚Ñ8LÆí+«ðùuFÔ¦;•|`ÕuGÅâÁE.ž}œ;fËiüÞUÀ óÿ´­£<„mˆxnɹ&À±ÄU äXtÇÂkþøÚ/ÿå;ʰ=‰½P—VŽº—}ê Áwoy¾DÕjXÝ1gAsñT\¶D dXŒŽ«[Y^ìjvK—ˆ¹»é~û(Ïw!,ËáPvôajFÔë§;Ýiß(·/Qq厕*æõÌr[GÈŽ±0áÅT±¨"{ÐgæãöNÆná®lÎz„BǘCËï´éßì$£áš§r˜Ô|Íáàak³/6Ø‚˜ó§°ieÌ]¶‹¼N6Èã*_h‚OÒõT›Æ*ä-´HƒïÂéeÁãÀ†(Ja.$Å8ÛXýñ@«¸ñ0BÀÝŠVkÛŸâ‘^ø¢mžÔ õî5Oé×=œ|3RPÓ”3­ÇVȑզ`UàÖª…œþÌ·îåµ8S¨ì3Þ÷ºç¬Q˜³/g×»>»Þs€Å̯×l¾A%Ð’ÓñÓÏ–ôoæÍÎØ ªyd9°±0æžL“ûÜû¤~aö|…”NÛDΡ³0%n™jDÂ'‚¾ãôoç mÓ—åÜÎ8€C™‰lœ@WœSwâ^qÎ|ï=Î;¤À<&(o›Oó@óÎDpÇtï7ÕÁ|·éœ‰ºc‚S6ó.½kÌ¢äLÁƒè%'×’ÈqÆQQB‘ß oúí}g®º2{îªcjÙs÷NPKvA‚ÕúýÝœÁ Œ0}/Ó¶doñ™%~Ê9},3 t¤ Ó3P›…9*’9»øZ>ç°dÛZ™Ó˜[‡â´a9·‰poM±e¹WáÊ¦ê ´¬˜å £`Ãf\ﲳ˪ ŠJՒɘäÝŸÕƒ¸›Nd'­ŠY»Ç }íu}P‰ùý´ Õ 6͹n.q†S| "ШɫdÜms²3KÅË‘ð¼žHÊ~XœÊôK‰Á¥½IÇñ}“7v(>ÝØ`S¸(øçÑÑâá’æ¹þaâ¢9hœfB´iÙ×–LŒ–ôu>ããwÒÂî{wºÿ½Xõöììì’ùýì÷;_ÓWßž-ŸýõçàVÈëM(½ú_e¼=TÚâ» RÝü«ÁCïf Mô^;ƒ^'IæŒÙÐkr"¨3Úòïè¿b ³^â¡€}hžîžÖÖ–¢ã“úëÅ…õ¥Èbš-.lø³æ\¼¡ŠEúaÞìt&××·¢É¡þLÏ‘ù¦È½ª ¬¾ô[ФXh¦ú© ½²Áͺ¯eNñËá"çÀ`§6\œŠ?+²•U+1‚áÙ™a¦|&OOèRNbÄÌÎtþlÏo‚kZºW·ïèl&ÕUà~âû »´[ÜuœÚ˜‰ó½‡‡ù zHošÌî¨ÉåÕèv‹´(2e+‚@JIJw)šJlâ5äô²CÚ—, wî1÷/ugT;éK™ú9å&‡Ç} ’»y[£íløŽO‰ÝD߇$ÏêìÎÌ‚þ÷žk—dXxàIyÞí`EYÉ›jÚŠG—;3IÀ4¿0¿Ë†søfÆáŸõ^Td!¿SÅ{žÝUí¬Z­ÝºzùÅ|÷ Úóv#Ç|øi*%Î2›²D/¾õ* 3—]öòÞO™ípÕ ¾„šsª^½}\j†AƒöêŠ*G²Š,ÑçÔÓ÷É#ÁÊßó»ŠXpÅNKΈY.na0‘.½[×0ßõÿ×Ùƒ³œý™îüų¥³ßÎ>Ÿ}:{zöÝÙ÷g=+Egßü¼üi™þ õÀ4õÞV<›Z²³â=dͰ’lÈô›ëOyçþþÂmìæß¹—ý-œ»õò±‘4|'äÓ|ì¤N.Û{/ŠŸCðŸr¢—œè÷JO‘ßµ™trŠã0 )¸Êohj°ÞAd¯±r|c ùi ŠS_Z‚^|—kéÔÖ¨7S–HKEâñŽ,á—<Ú1—4ü~Âðd᫉‚N´Ð‚LÍ|î~ò³@áü{§ÂI²Ä¤#<®ùê9~Ý'hCO‰—ôu¬ƒVÁJW ÒàÕa‰Ê÷Œ¯"™ºŸ΋+ɗͧ˜I3pþ9œ}žJ*?ãËßrŸ?Iúüåïý öœ{M¥Ð¢uG†ª¡aªyK87OòôOÿXXûÓŸŠú©RÖÏèÉ;_Öø]•f*Tq( GAªðѵƒ½è-¯Zõ¾Gp•¦Gt¶7xýŽ&‰"mh¦ªVÒ„õËl¹‡\xDu¡qÁ”—Î%Ñ74ÌÀ€¼HPúÈö79þ¦·‚â£NÈܸ­Ì§¹Îó4æ46ðMÜÑZ¯”¶KŸçÐCu¹îøèN¡ýra!-z¦LõX†îÍfH´(¿ É5«i²þ"$¨ôUX–"–Á’š%æÎ~½ô”?˜³˜Ÿs¶L«7 .&ùÂó¿oIŽd~úîL†Í>K¶öì63“ó»w[hÜþmJꜽƒ](ñù;Ѓÿ¼{"ŸRÁ»7§{9/}¹ø_·sÇ£§Övá)”šÌþr> M³–Õ‡„°v ÅUv¦l*œHÇ)û¸)§¯Þ 4!ºm5gç¨üº[ùûjåI‹$£„³©“\©UªFÏ'#8@  ™¢þž'—Ù%ntî%­bäGö”!7  €]¿î- ¼¥ý ˆËå·ßº.:móÔPóä¤ZMWþq¶Èµ-­´ÎÖVJúøí?¼zWZ+—%£tÖ[k9šÝ˜žh–JNóÌÕÅÝÏK…–ÊTÏæØtFÍóùÞ)¦ÔŸÿìù§pô´e*7À=á*æÅd'¸+€}ºõ?&˜Ý†¯kGî`7Ý­ížÖ_üt¿9ø½S½‘"œvƒ Ù„¦Ý ÊÏ7aºW¶ºž†–sžqÂh[™”²ƒRðAM¬ !“.0ÿ9Y- Á4͉—°±äsž˜f¦³>p?¾u„ -ä*ú˜€ ¹`€DN“Qß…ÀtûD½»n ´Â[ „›:q™hsÎEtoj^²½óªá~.ø©8œƒØ, ’F|v£×õ“5üXŸ £PBù¨òºdö2éK¶N?"›Ýãu«t’]ÎÿÍ’-–Åä4cèÚQ7ôyJ³‘™Ü¶ñ˜ýßP”FkÕ‡ÑwøY]Õl€æùfu3æ¯6+ÃX5H šÇ(Ñ –×Nä–ÐHÁs«t`©¸%Ó+6ªŽS‘•;:;Èíb¼L««ì\7Œé‡U¤ÐÀxŹÃËßPDs†9±˜éº±àÕ.𴤎®7[Ú–L‹›`V¤pµfžMð[B†_üWò Œ×î§HV‘îíÊûh­¼ÖÇïõò:ÿÞ(oðïÍò&ÿ~X~È¿·Ê[üûQùÿ~\~Ì¿Ÿ”Ÿô±£ øƒtÖ˨öêädþ·(‚¹Å•ϯ`qñs 6É1 íš'çNÙ]죈q em» @ïeG*<«ßY€Ð$ðgQð iÕ‘ÏÆ= w#:],ø5ÌÏkQüˆ5؉>¾ WÑ-rk¿¼ÓùÖÑ%µ€Ý ÷ò¶0jš¿Ž³#V(†yôíÇläv´w:•+dI- \Q̽>Aþ¥ ] ×Ã%xØO•ÜŽŠk«+ÒŠnÌ?mßVþ´º~*ýxù15§µbXÿùë Dý¶Þïо4©³IÛS§L©„ÑâðrËÕB؃õÕµ‡•µÕÊê£êÚš6ÎÉ -~9ö&——ü-¸ˆ¶ ¹FÕ¾ê§öͨ — À\½€"çu5zO.¯b’¨-ÎÜV oGÝË«q´X[â§t#z_Éæàb|ƒú^±älôÛÖ”‰»’*µàSd~¦Xró [mjBq‰5YäA 9<’ÌG#",·O%™‰qüæAý¤ör÷ðt÷Yc¿qúˆÖóÆéa½ÙŒžмïžœ6j¯öwO¢ãW'ÇGÍzÕ¦%0,D¶Û67!À.Væ|"AÂt8W¨ ÚˆD:%Ø‘†­éDÁ"¥&XþÅá«è…\ Ñ1¼¶ÚÑ>Qá~Ê„xˆ'´ š—/̞ΤË>Æf§l˜&´>d5B"fI©8ÒU_àXÌ›¹wã³ÌÉR´šû‡!˜ÏMÒ`,o§/^F»‡?EovONh~zjãÚxuP“J6‹'ɨ¾fÍà+уs¦ö‚‡‘«ÇÐð¢ÅÔK‡=t‘§ )?æw÷Š!(–=ˆX ²*Ôã¸ÌÛú»«ñx¸½²rssS½ìOªƒÑåJOêHW¾çÎ÷8Šd7Ü@D)ù¢UŠ '3VÛyIçñoZIÕÏÉas¾Z0Ⱦá§Üà09ÀĘD’P¯,·M>+øºl˃eømži*X·âé®É:—I–ɵdõä°.I¦‹ù $ÕsÍ—,ñeH¡mâ½k¦2ìXéËÀˆ?øÖPM|ªZ—¼ø©­Œ+¸Sh”ÕÙ%t¼!…\*$¬kÕUYnfÇ<0ª Hòì!dLZÖÙ8……å~T«Hx…ñ{)RYÂa0D½ÎM éR¥¢½)Ê­™~Ë.ýO=–Œ—¸þD‹q«lÛX"tú\/|q¿Ó|vÀåðÓo<)‡Ä\ ’.P3šï).¹E-U®4·`¥B›iXÊé<Ç JÜ÷ °$23ªÀóæªJ9â“Áö32 ªËÍ`¡B²=ÆûL‚ŒâTP¡9}›ƒO6 Œy›R4†9¸Aßæ¯vÉg‘Ž7sã™îK¯-Ÿ$9$5•;Ÿ2቗ÊfBUµP²I`µ„õ‚v‹³›ySˆÛÅåù³#¬ºØ~?öëé +è\d¦v9âß&¬ör¹™ÓÄ`¶Æad‚&è#Yĵî/l3+-•j~–>›¸<̽éyò½Ó§Km’I«~ä¸!*WÂÎ×´D¢x‹:ƒ¾$³ »Ù ùy”{7Ž&”N4¯^NÜOœOÏ)x{Á©ò²â’‹žIPª©·S͵‡ÉºÐqñ v®• ¬šÔ§Öp VgÌŽèJR»ßlújsÌe[ÈAW-¾ÙSU>vAr}Œô@±*ù™Ø8Ï›ËúçØÃ‰Ä¨øÃ*æR—€Sl±YjHÕ¨Ÿ1/£ó¨x.šš½ÇÁv8e)R/rþ"ÓÌœMÆlódpnEvܨxâvJ.‡ðÛ£ãÓÆÑáÏDÙKÌØ_Z`n|å"]CÄ£súÏ,±„þ¸£K†Ð瑦kçÓÍÝö^§—üMÁ’·MüiÎY°ÕÚíÉ´d$ùµhcZ•ÎY'Ë>K†vÈô*qÃ+•7ezŤ Ý1ʨŒç¦ó1fbê©§RơǸhš¬*ë-=û™«ÿ€êMëA-z·¦6GjÜ ¿Y­€e¡‘K·¥ñƒ½›ºBS¼r柼˜ò’ÒÆe60XZû~‘1Ì)%Å5INc)˜ïÒô¦Ð½P@#-üíÖ¦ð&Tªu™‚0¬ÌÒ¤²Î¡ùãý¼²¶œd—µ˜â|]\x;™òL ì .+ï(5”˜ ¼t¸)ÏÅKšx!ïp°Î%:Õ‚h0;ÅSèÏ,TdˆŽåô½µ¬R³33Óú”ü%TöÚ¼_ŽÚ»“Ú9 ssÝÁE‘ø/kD®JˆTîf¦uð'áüÈDøK=FD‰YÃírû"M½6T6øjr2‰Í¦*¢ŸJ}Ì/ Z>ÉÏ_ÖZó]u蛽¤Ý‹M†YûŠ^´ÄCл¬!®qÇët¸-ï%FÕàÙ^Ì÷êUŸ>SºuÁiƒà}ëçš™néåÑÑ-|¼§Ò ü¼Òqv”œÐÖevmwl<²‘ðȆÖ/k8Èó |ž$rä ìDE3Š¢$ÇâÊq⃠1d5ß„G“‘™œûèì%ôòÎIH®Ù|v+Wsôö,ù‹DrÒç–l‡5½}?Έ¿k\+·*–E4gÃÏZŒ 3L·mÒ†9»îÌÏÄä†es0Ï8 “<µ PÒOQia½ôé’Ÿø#ŸôuZܸßîž¼øù>Àô:f:hØ-áªÀ‰ ö¤‘\,Þ‘å™Å~$ôJ:–q´S”©È/E©aš*aW¸¨he:Ë828hþKGLh ¬,b€ôœ@9šÞnÕ°ÖfÌ¢|nu"‚E„‡mš™ÙyÎ#¯àkÃÿ™çLj‰v†ùüôg êJ¢mÎ'Ý|ê›À4ÆH®5¯xÑ Ý Ý®¦h :‹Ò\ŒxRÚ´ †3äÕä@ìá|ÿ¼W ÷‰!±J4Ó%'í:/ö`tjƧþ¦>g㣦ô*á»E?ÏAÞÂn‡î .¬v!SÒZæíßÃÕk’Ïp ÜA(HÎà”S°ZÈæÄ዆ö¦Ÿe}¸;"?³ W‰±pÌÒç9eZTa®68ÚZW|+ H²’cÊè~·vé­Â.ÖWTÜC·ÒTCq¬æµ:[Oú@´ã îû­'–i¿Bð½Nh©¬$:¾ VâO£/R ŸMîT/<•(èñÍWµ4ÅcÀª™ BÛ%%ú£è}Ÿ_£¿6ÖFš?zMÏï2õIÌsw€\ÏnÁq¯û«ê<1«šîO˜â^r»Àx0i_¹Ü‰¼<:Ã#MŸ!f–Jzd@¶`„fQ»ìg xQt}kõCÅ®ç翹”=Y|àž>ˆêÇô¦…•€ÍZcK‡râB(Ƙb•²SŠäAc_W:+•Æ*Dyœzܳêy¿ä÷ípOª¾ÈÍ¥…¿•¢E™Ž†õÂ?^¦•v æuɳù5õVcÚј6Ÿs´]‚¤y^Ò#°í¿œŠª„ êr¸ a|öܽHŒ´òQë ™À@ÉÌ‹œi ËjwƒL¿~ÿí€˜Š–LyG/Êႌ ’ítF'Ö+A¼öi‹xˆhbë%mãºF ÄnÃZƒâõÐPM“›NN…­GÏM“ɬµv—~} Ž"K„WFSPî Dº/ÇÑ*ߨ^¦+ˆ—dçA6|w0ä@í 5–ÙþŸ*é{±ÊÇíL­ ˜?õó ñ Ühj¬R¹„§ªªeÈTXIáp ° $¦Åï`×ÈíKçôdÊ’©„é(œ-fWÁ@f•ü·Ÿ•wΦû‘]™?jj½I’ ?1CÎnÓãvŸ¹c/d‘™ÍÞÆ0ËW‰›JèÎKðó뺈üQ÷êê=WOûëf[·ûS‹ÊïWÄ ìƒ xÚ£Ù¾(ÿù 7L|=&d_FP»~¯‚.ÝEf™’Yë_¶¡ÕޱÃ[üeÄvÁQp¤¹¾£NF"§Þ†º”¦¬B–æÒ½žôŽ®GN•v?$Õ¢ßú½îV0S#æZLJeo DϾt-;QÈ/dÕÕ$JŒâPQ-7 xB6rÜ#kŒÀC+rÇ…15•yþA´ºÃÐñÅ2ׯÉS¼Óáßkeus¥"+lzu_1ÆO~Á\]¾­Eî·EÖö”üFJÚ£ÝÓƒ=’i~žT›S¾´^Üz3br¾]{¢&Sopð²b“‹˜Ù¥íç|NQ_obúy×"@ß®:ë)ÍO·ŸÂvÔ‡óadþªçP ÝÀ"Ù-áÚx“c•ú’„úK¿ê`ïÒIh1_#ÁÚì[ñXíáPù½*MÍp.äxF5À½[0 ”ìúg•Ft§õ¥ƒ>Ú)-”$´dá7}ùóvgžø®ï£|ÙÝLÀLÉxhQÙÍ þC¹‰â9Æœ ´æpu†•^ò!éi-¡Û‡SR6·wߦ–f¥"K†çÔˆ‚Z› Y%—ñ¨Ã¡Mxi!–u,Y¬¨ðÛÙGÎÓEèü2áîó/Ð9Uι7³çÓõ4çDʆ¼mÔ³É9¶-æ—N`í@Öù$—xzŽÔ@‚f¢­¦ÂP©‚¯Çh0¹¼òuž…­â¼‡U™M§ÚTaµ™´WR±†±d¯EÃÈgÏSCÍÔùƒ%Wñc•}Í4>ûCNy«;0KkK:a¬µF#²è<CuE7µZ¿¥yDLÄÉéõžx ª0u›Iå@{ w'MùñïäÐDnðÞ™t/ÿ6Ë©vÛá§_D]òNÖ´œŸ{;æŸ,™hïx…$þ~¼‡ºq°å0ÃïÈÑÉYè BNÓómrAY‹Ÿã­bPÀ[Ær&Øž ÷ÇTòA2f‚±ÙÏÉ-Ø@v} -X'¥2™yPÖ0qà — ë¢#Ä#¨_8‚б%‚šÛù”@{•æíÄpúò·â,×Á쎙¡é'u;'ÏÍ3Ö8•ƒñLÚ¸G_vn…¨v0Ú‘QÒI¯ÌœÃÝ_ 0ÝAbƒýÒÅéù#°xª,‰Bÿ’O•´íNÛ)1ÚòÇÒ Ï/ªŽ]RúǘX!< 8ã]o?ÏÔxýë¬?Ë'ÿ“û°T¸K¼v.1œ ~ê¦ÎWg|óM^¼ÎØž¼™ÕfKKºC jdÊë.kØ\E%ÇÕÿ7oÿMÿ˨†ˆo3¾˜„†ÐîìÎY#]!š£!qI`=4~_©'f$pªˆ}2çTåÙ»[“~÷—(/.ÍƒÍØb3CͼL_ž93ö•Mcs~YÛýf/ûÏ¿›³_æ÷ŠM¬ÿÌ) z™µí~e§—îÚ@¾ùø¬0_=:é«E9™©Üö’ ~a73‰Óè>ôQÙ»O•K»·í·k]ð–ìøž_ê쯟*WKþ,‰*¨ ª°  ëÆÐ©o׋œ]…25I¶Iõ#rjFãú”ì%à$Dð´HÛÝnå\ I5ç¼;ƒ!¾€å~@:S+eÎ2ÑαPø%ªUVéô:3ß9÷LrÏŠE„ÝV3cñ¬˜WfÁÕkJˆ69ñî øT°-<Š…*ü 2s2âσ†He;˜Ž6¶Ó YðTHÑõ~5H7îÉý´Àw@t~å V'ÝÆ‚lÃÑTrÂLp¯ó‡¬Îµò‚så-ÔSue­QÖzðïÍÓ“Æá‹ùãµy´²,¼DæñéSAm …B 1+-›¨¶ÒN‰Ý«—`' û©Ü1‹üùq'^9_i?õõtczFÛŒúÛƒŸ~ûø§?­,óoùõ`y…áw±´ä'wmdZß¹%iùNdÒ‚ÞÜ!îGô¥…zéi|XY"Qy£ x~2¶UšáÔ_7™sz›Dù˵CçøOÚYþ<³ÐH =XÞùìÏiñã,nG‘Kßm´iSõ8£ñ ±ô¬™H´ÌÉÇáÈÄ#âïqË…î|ÒíÑ&ªòDÒ¯ššwhOC¬õG$ÂÞA"ìÒ»¹³õµÓd@c¦*Ìv„»±s¶X¥¾,pg€^=˜z;{ÀlÕ|ytrzt|zð´ÌQÅ«ìqD(ß9óþ‰×~è8öë}/¯sõÀñr³vÿmÌŸŸ¿þõó¼b˜L>Œs¤øÏÿüóòûÆÊƒÈîÖ mÔü3NÒÔ{Õ¹;ܾì69_üY K¾™Óéðâ»Y Q©}%¯ ¤R63ú´ðÛñî‹úI!CŸ%"“#&󸑰‘¼ûEãô‡g]Ì~çHmËËŒlI#O?ýã4KÛVþáp&V~óôŸŸº<‡Ÿ ß\¾ ÿRо|-ŽÏ4˜åYƒA¡{!îe* ySgÔ¬÷ßæ{Áª•t ’“0R)†Sçæl±¶´òíytéR!ms¨™-pV]ùÖŸÌC?ÑÓ§³>-AôÉO ï;ÅֶׯÊ?P•òŠ_²ý4.³>Y^È<;[¤±œ-½V+OÊ•Ÿ—ßFô“îӵʓŸMõléÓÙZt¶î¿8Ìéj¶{wô'¿ o ÿ/ÛâÑŒ¿?os½h£æ¿Î©8öP_³ §}PUׯœöÊ­@EM¹EdªÑô*܉Ã:xTF6=ˆ š0½#œÐèŒ^j,hèóÊN×&H!Œ0”YQïÎd$P'o;ç44Ý$z{p´W¯¨Šö °N¦ FŽ2Æ•J¥Íà:›„X´}àGºfÀ•Ü´¤pµÎè¶,ïŸJÒô0©EµÐ?ñºed¯mº¢ó8í¶3c˜@"•áìì`ª]e€H }é òyû²_Gá#› 3 £ÌçØâŽ2@¢dPž œÿ'ÕbªØvW…4›¼^Pv&Juõ5‰ö´`ÝŸ8ª#è |-XÕhX˜ÎL4-èü¼ô³-ˆM!è#m¸÷ÏcöxȬ¾õÞ4/Núa“º®=Ah$þ:Ì]ÑÄá½UÂà“r}áûj½1ñæŠ"Äáur7• %–Ø{<çç#ÁÔæ7Jò%'q€gÖÄ+¡S 7íj¡„¦ÄØ Iá!ˆbH!î]¼½-^ö'%†‡®ÆýÙêu¬7„RI[~–¤í%çݸ_a6¼²UÙûļÿnqa÷ÕéÑÁîuß¡ÈWi²ÈÑ^¸>2uÔŽŸß]Gáăf¥5ûŽþ¨è™4x¬ßW ž(AK ëò`Ó-Xƒ0Ë{OT[¨ÊAçÕp™ŒQžÞŸ¥Vé ÖÑѳ¯×N+ó,<0;’´˜²áÜ+¯G9*U{ƒ’@Æ4àTÄÅŒ¹¼‚B"T(¥¤ã€öwÒ•³3zÿla¥º€Ç+…ÁzO¿ÐGø¶7X)|U4¦§Í›NlHu/¹)qÂÖþDß|6ð€]迼Öòý;L†­R¡`!>òäì7žÑ|VŽN*Í£W'µ:?OÍj^»Ù×Ý‚ ˜¶•ªíR´ F£%]âÜR™ÅÓÍVÉ,Q0Òeo"ÝÓ`Ê–?S•_¨©M’E¹ë55Ï9ÉdÀ6¬Š¢(-ø]›ßᜪJé§³êÛT^^øDùdµ¯YëwÈlÞ/Ëh›Gž#rs äá –=ã“©Kal3E{ŒŽwk?쾨³ÞžX»Á `=÷úsFî ; ™U¥ç°à^]Ó5®^æ$ö^q[=$|¯Z7âQÒâ,Ií‹Ò?ü zVÑ8Äy:=:Ú/™RÄ{xeê‡{®DÁ˜0öoЭªÓg×Ê+ ®½×IãÅJç)?åúͳòÙB§˜§ŠC8Û²óSSZ(hŒ¿jÕ4ô‰wÔ4ô7‚Æ<ѵƒÎA ’ÎlóK¨€(oÙëëŒ"ÃbŽŽÚ…f†ÊDÙ’*ûfLf¹­ˆìÜš „K°Ä¶œ]d‰ù¿³-lO±àÇ9˜ „%–’?üN‹Ë’:…CóY^¶˜ ¶”Ò$ÄÏ)®a ùHgævg®}ÿNä7¾O9+#Í´TZ¾ññu2BZjÔò°µ±#”"IEV‘EëúÆ5Ž Kn*¡€ÓODu ,ûÍÀχd¶·gf€êcô n8vo<ˆ^„¹”D§¤ûqIY:QÌ£3NC1$Åiò1÷EäPa€ƒö˜Þö¨W††8¼V—3ÓýªÇä8*`[iíVþW~…%bågÏ#y«Î$gÂä¡×Ù9i‘zŠÞ݆8UcRŒj¨­¬P?ŒºÕ—Rñ¯;@,18žäÛ%¹ù:½aæÈ¢¨V³Ø{Þ¨àûâ¤~LGÌÍdÑ'V‘ÇÒ¯ÿç5“W7vÖNÑì1oüøžÕ䃜"Ì´wŸ%@[VЦ™7¦Våu • t üK›ýàëgžô=4C†³Ö×Ù¨À³ íÒMJiN‘ȽDÜVðD*0A Ä«.‡¯åH†é6 êvL°ß™»Ãæð¶›5s ¼ãW%·£Wƒ‡šõMèÁŘ]‚‡ÍÑç½7½ë¼Ø°)ºØ«×¦‡b‡ê;<Øú ×34à›^oÒþkšÔp ŒmuJÈÊΑÖ"Î;¥ŒáB¦;ä(’¹ húh¥ ƒ.‚£Ñ·¸¸îap=¸—_×Oš£ÃàcdÍÄí™—Ø«lnI¹1òðEß}×Ú?mÕž¬€¾ @ìÆÝT¥)ó¬;ŠåM÷Êšn,ñ«q¦Om5§Ð6xz#º"“‘™æª_…‡ ?JŒÂªÍéD«´ˆl®‘•”ʦ:æW¦ÀËV/Å—1¼EÌ ›øâT¹º‚ÕýïŸ1{vƒ©ûÃ'Μ•hêH•ýªu~ï9©®Òð@þ®YÝS¿VêÕÔ(ï9ç.îÛóS>h4vOk/ ?(´ÓpÂ_Þ¡ñ# 2ÒÙÀ³T ón©bnSY«ô¬wGÈÅ›Áèôä¿ã>KÖâL)Œ±j×~2¯Vg2lÁà•)͆,?@ƒna·«Œ¾Œ`ºõ 7ÎâLl®$=ÉÈ(š/ƒ²¤]†,N=X9ã윧ÜbsÈ'üÄúoɹDž³Pì'3¡ôªUíï'ù-¿ø'~ПÚw¶¢†•ùí¨-å“ü–_ü?è¿OÉ]íkÌüvÄÒò‰ñOü ÿ>]ÜU¿ÚhæW¯†ŽOò[~ñOü ÿ>uïjÆXTæ·û'úAÿ}ºsÙ¾3¿>kÉùdþ2èoùÅ?ñƒþû4¹«]gšß¸åàó‹q7%¸¸Ìk™`¤ã°ØæJª_ó–Gɾ2ê-Óc¢ÊwA»æ5ò¯Šñèùà¼` ì S%Ë«nßÍY~›w„»Ñ˜óâ)• šˆ=ã¢Â8%@‚—˜¼<Ùá MÙïY©àƒ(‰áy&H^+ÑàÀp£-Ê££_*=·`µUÏ”#~8` sR»»CÙf£³ÇŠ6øvÆ× Š^2,¶ª;¦ðAÔôâQ7]w¹dáe¤®iô:¼ã¬{Zû²»BIJJŸþJŸvÖ¶6®»íœˆõwÛTrÙnÛ ¨ø¯Ý^/^Ë‹>q%ÝÎÎÃ'?6öÎöíåM·¿}Š–¯iånø¯áÍÆ:ÿÑN¨Fþ+Õ¾ó‡ý^ò(–˜Ø8—YŸ]ÛÕÉÝ$2Z “6fgxèíhîð¡HPÆ/¾e|'[—ìÕ7N:*¸¦èˆ×‰ûÕ±+ͶÕ.ÉËÿ›[È`ûóÝö‰EžmÍú†O÷3¼+°ø¼âÖ"'‚>Ï“©Èá;úHöøwã$¿ïÒŠˆ-nËE€ºhgD鄯Xð!WÇVz5J>ŽwΊ òŽHzæ½|Ôçl ¢]]*áÕ^ªu­ÅI¶š1ÖYH)T´³ajå1âYÖ&ç‹(ëW—V¤¤m{pÆÓñL¢µïÿ¼^ð%• zÉ4`lM²+¨ßU-æ)¨8uPßBàòíJHÀ·­_x™Zg¹WÛÑÏÌÜ*a…7^îm6uÌj¯´cÉ—æ«´’x„äžnËdøÖ9å±~Ê…œ¹B“ Ø~Äù  ùHÃá-ÎðT\šÆžÑ¿˜žx-ä”)\Ç—ÝöNéOúÓÁî‹FÍ:ßЃ’|Ù¢½ï¨ÿX ¦wèXY׺ªÚWÝ wψvãÞÎ*çÕS»žub(%öv`¢•Ä^ØÐ…"œ ³®‹a{Kó‘ô;ÆiÁbáÉR1^’jè3IÃ9× Áõ²>#i³º€·À®——¬tŠçdÒŒsÖ2¤*¿@3˜º¶žŸ½ŽD*>½0¸²±tA ®kï#g%Ug wÍœßrÎ^áêÆÅh&5~EÛ““ØÚâŸF\Ve~쨀Ç@D”]Y%ÚÍgºžÂ …'û In‰†NÒ+†«î€¥‹ù:®qñ&#ƒÅ–×Í–µ)ªÐ?hùý«.³j1ú> ]¼)èÑA=§ÊäýycŸÞ\@P©Ú‹K~œŒ¸X«k5Þ¯ ¯ìl|á\P5sfÃôØòœrï\ˆ·óŸÿø‚&Ñæ/òEá͙שəô‘!çŸ7G«$µþ62AäX£/%'¢ÛÐ5ET!±4$¾×Hæp:š@G¸,©š%)Õ=-Yڽ耘–Z¤Ð Oâäm6ŠQ÷²‹&8RÌD 8gÁ ÑÂ^'1¼Êì·EÕòâß𱎣~rI܇Ädt¼aW‚sgGj¢V7ñ-¼#£÷ŒýWB{^^YNÏì»8v;èlíô°á6ˆ~ÙÏ QÑÃïþ¼}‡GÆQŽMBRY Ù;¢µh=Úˆ6 ßt 8yW„v«<1Âqâ›oΜ¹3zF‡ô,²‡t9Z²='ÆQqC‰³ýƲ¶ß°äü ÷võ»??D—+¾ïmàx«•ýí<¾Aµdýîµ¥õ•È‚!üœðé~ÞuØIøè]°ç´TßýŽCo[wQ€_4S^ðàílý !ÂB- „ÙÉs­X®R ÏãtÞû(š‰²÷Ñ‚e}à•º¶0»š)OÕ9[–Ùi]Š]Îëjô*[Aòæ‚JN@å¸|AÍ\ _4D ›B(¹&i®ÜÀHh²™–g;2c«òÛáÔáÅÓ‘Ü­º4À»³Hÿ¯zŒ€êò×¥Ý4„’áZÍ‹AÊ©™=ùyÓy¸‚°/z´²ð[ب~ÿ™jL¯´ÎÜ•ørª›ð¿ýtÌ>–ÊH¼Ô§¹t€ÕÚ~\ȵ,J; Ä-I²Ã¨®‚ï˜dw?u|íèà`÷p¯Yj«v°‡Y`œÛ²0´Ì&O†. åmaIjw*H’†,“oEzçÛÂt¿gz2@›×ê^¤ œò”±JJÿWɆã5Š¢µ,PJ:4à*Ê—C8+.Я³bPPPÄ ùRkVâ~[¯lÎN±ïû¨—.ª°ò {´ xšÍ.[T!°.ˆCÁ$Òq“muÇ"”Œ](OE·Âú7/cL=KZm>œPùù`|%O°(øƒÉ'³4Û. ¾"ÕTð%Uqž\FS}ÅÏõ„\htûâÆR™;&>‰Iq}éÛ(Úí¥ƒ²÷‹dVâæúh!— ¬ŠÔ̹žÛì”-âé嘒Ԡ%fžá,k™¾ÜQi"Í›þܦ´gÕBn?tö•‹¶£Û6[í¯ËÛEïy1vƒ"2ÏkÁlæõh‡Öä®YÔæh¢°{²?°»ðÎÔ°‘· ÝþÝ6°Æ#œÚFŸÓ|Å——œíÝWs„1._Vñ ¨#þ@×ÓxY ú "7q %ûŠ$=ºº±Ä-±¡¹h¯–QL&,U£ìz89RQÄ-@‚Â.-1!Oju 3hUœÚÕ ]J¥‚ª–Dÿ#r-øÉè:*]¶Ûã*e&f&1 ôÏv.ðNêÉ| 1A7ê¹VµgÇ ¼28bpš…Z¯·oü¼GRÚ½‡VG—æj븬@T"ù8Œ8³óÎÁ|±«h­ö.Ûþ¼ÂZä]àŒ÷7ßTõ¬÷ß§fuÌr€I`Í=k±xg†ºÉ")`ª¶*­fjµ(éèŽ}V;[–BRQ;cõ“$fåEt<*âj(º¿x4f¤îÛÌ£3¿¼+kæÝU˜™Á([ÖÿfÉ™£ì´©Ú“ópr\¶·1J óÙŽqìøH€¶Ñ6+x Èoµ©‰þF£¯%*°×«:û+~åÝnVÙi~|ßÝ!š¿.dBÔ|…Ÿ û»#°O5 ÌvùÑp¥•;{PZøµ„€ê;BB¥ØÀŒ¶¯ï4›w¿™uþ¬‰k0¡éªHä!r5crT®`œ]'ãØB§USÃ}Îñ7ösŸSüÍ—b§**Ò!æünßüþóÍ?íÀ¸ù?½ã&ðÑÿ$uo².QP5¶êj«ºÒ"àë”Î|Çî&îí›6àùWóD\\:AO©ÆÚ3U­1óccpÓ1N|—o²41ùké®Ïë^é» º#•šFy‚ÌÂDÎõ‹w½ØB‚M>ä› ¤1s{}¤‚œôMnøîLÖ¡hß b¢ÅÈ Ù×,óu%îe©Xxð ‡´=øÆe.c€¹¢’Ú ›ÑæwÚ‡HC³,øäˆ„b«S…¹àó ù°Û–?úƒ¾ù›^®y^n™(…I¬é .“T̹Åj/.òWKå‚\qJ¯¥–îX¨x ˜WÁ²ê°Ç÷ÙìnZ¦Ä~K_FïK‘´ÔpVZX?+eq¼6ù 1h ú‚ÔCßiS³šÒ"S-xnü¾£‡<.üæOÆçÓè»ï`‹{-øÏ£JþÊ2Ƭ…ã“£'»ÃÖù’‹×|ó²D(ïE‡G§Äq*ª\W4„ß‚¡AÞ ñôÑoÌj¸©bWb¯)Ozܨiïªì=ù{gÁ-Eö ¸>¹· ô±5ý¢Ll¡à"^CÙNôþã Xª_úϨ%rb—njöèŠ6±—/ëûÇõ“èù«ÃÀN›Ñƒ¯iÅþ!rXÆQÒÂ:´nˆÒµÆƒÖÍÆ:Ð… SÉ‚l†>Ã|æ¥&uH¯ÌxÊDz.÷»qªÙWI|¸Òˆ•3eUs0Rd €2aÐ¥­F'I¡û¬ü¥.CKÔ»õ½pÐû€¶ì[Ù‰Ê(Ä€±ûðó1ÜÕGõž¾¬òž¥ 0W›ŽÄ ?fècñ¿AÅQ¤ÊʳSOøC;wO¼ £ùÆ–5Mä=VmÉ¥ˆ-ždí%½T¸ÇºÓt ¤Ý»[B:‰nͧ]¢Wp—OàµÖ»-»ùö …c£ ÂYü5 tTíA'a(ä“â3Õ×–9Þ]ùã1Ûeì @·Q•DcabxÁÉ·¬²±Öe•®©êå&(Âb³¤,EÀ;ƒQ&»cîX[Ä«Á~ZٲŕQ¯¤eAÐ’®41aœ¼ÁZF7PªYëâÀyÇtÈBKE&“ñz=›ukÐá{œdʼnç±|_wÞÙõ¨ÜLÙáÞe€!þZ$!ãñowë}¿– íþûË£ݳl߸FH?î~HZðDI{1‰n‹ï²—èý»ål¹Ì>¨³}÷ ùÔ+ðÔ–ìÞ„VµL¿ŸÐ:2Ë$÷÷ZŸÌ¢wLh­¡dìŠS Zm2$t“›+J%ÎÇÇ=RÍ¥²¤YP$”€3}fjÝío¬¡Î®™Õ”‚æiIv“þÖÚ1–øÊ`Íú Š–¾g5ÏS6l <“—,ÙóªTùÆÓß*Æ,‹já,—ì?ˆ&s¨5sßR)Omª€öLsoŽó´3÷Þ ~k*À¶µeÝ£‘‹|c—Ô{ïãžKw¦Û*æyÖÞ›˜ÌÅŹ÷|NcæÜ)îß×Y 3¾ãþ½ÛŠO¿`–¦Ñ[ôÐÊhWx>aÎvÉ#Ì·’AлñFíáñˆ5F Ë|‡6D ZûýÓVí§BÏ :Œõœ„'ÎîâÚR†N3KQ#G!¥ W¨0ž¢°OA ב«ÄUrÐü©²Ô5Gâ7üöä‹jÔè‹Z ½a<ª³¬N»Â]h‡« ÿNŒ¸Û¦Ë,éb·?dCÎp#æP%ÊT…ã’ ¾«ÝÁ$F^(6êr4»¤“E•òxåå%o(™p¦3À¾Ïî×}(5t~L7N´e°ƒÊ¹@MƒÌÕÔ Œ ^VºáݘĦŒYÇN» ·’í[Mý NhªŽˆÝfÎÓAn ŸŸ´@šõãèôÈþiŸ›‡™½ä¾§ eÈÿ—ï%­üK·.èûm§X[ì¶#J2ìIgž'½ÁMvÃyt÷†ÛÌl¸/Ùp‹†M§"ù}öÛÆ?k¿yh„1”êÝsVË#닛ĢÓY3 ®WvtÄM©ühð!éá«•$2ÁoÕð^ål¡ßr.ÝõPé­g ˋɰI=Ý)¦ŸÖ>-¬²^Ánx¥ÏùšYMÌÐíäµ°°‘§Ì™uâfœFº,ûc¾ L?pÄOétDÏvk?à÷Iýx?::iàê=ùtf·XÍ3²Égø]šr¼nlµ¶դ˥8³´v#ï¨äô>÷܈˦¸±,¬™ ù³º0뻌SU¶ÚuS­/NæÍ6Å”ƒÖ¬Å›âךd”Jzè™h<ËÌï4ÉÀñað^å¿ÒB@Á¹Ð5[bFŸÄFÖ}ÅÊ/;€)+… 1ÌÑ€åéª;þ·!™fÄË`Niâ‚>)i¸»–ÇÌíÇtrwñôlª£¸·wü"ÁøØlÆýÿÙ{÷†6Ž,oxÿ•>EG(#D$aœÌÌ.2!˜$ìàËx’YË‘©…¤¨%cÆö~ö÷\ëÖÕ’°Ìî¾ãÝ Ð]U]×Sçú;Çûÿõ7Ö…ÞmØ Ð)#8vJ™i÷“:ЄãH=[ÛpÌ^†9“Ô 6o™jK³A“z¾Ènýyú hQR;‘v°åä U¿ß2~Å­ZÝë0º„· †@Ù€,‚D½XhÍ…ª)o®l‹¸_)Ò ·©}ŒÈº±§·´Âê8[¾%‹M¸^Ë%¬a9Wˆ-”ôoÏìÊM24YƃQèßVÈ{`}ÝÍ.ÏŧK‰åÌ¥ùPò‚õ%$ÃйÝÚK˜¾Ø”­”—³ØåZæå‚¨ï…m~a³ª¼E‰HÄñE¥{¶¶d'¬!Q’zjí-!Ú¬¸¤ÿá è÷â“.!*¿ØÓÓj7Õ²uóI J×\=é« g,Ú,rµ »šIåÓ'˜÷¥;᥶޾¦¾üWÝ›Í2B5|³ö¢“Z°¸ä¿,†ˆPYT>+»IBg!f+Q§¸QîFm§åc±ó|ÀY/·‘üZKoghÅ ÁB+×^i¿§Æv—ß9 ±3“ø1ktðŸFÎÍy]DlE2¾ÞöðÔ¾¿åçi\NÖÝ JJ÷‚§T3ÁEhÂ]:+»¿ÖVÚteY{Z¾[^þoÞr+´t|G”iéüwW8üÇt®½ ;üf‡.÷“ÿtµÄ úó_¦ŽôÖ/ª‚ŠxþFšÈXßþoîç;2ŽÒÉæ»+F#'!T9-Ûó»¿ýŽß½Q¦uuÅ[þÎ WR·2eÿ4*×»³)wU¹þF̾4@,?®Òr^¿áõ¥…"ÇßúÄëÈõ´úL—Eýÿç`Õ‚:õÙEoJN^q͇ãÁä&OÃ¾Ò ý— º‚ nÇ}Ö­bRd(Ø{xø]ï)¾R¿Ê믪ÁË–)üŠÿÃS˾ê??¯$/¶ÐYÝ>Ýþ¹»ù ³ÕmnÕ· ¿xwóð§§ONÎN»ï޾=Ù?ù[·ÙÝÄF¤tÑ€L¥_äWµuÓ‘†BeQì¥Éù TS:»Ä «â‹Rø0Ä›˜;g¬ZÕ`n¢Âm%ùhºQ‘Ïúøz¯Îyl°å$ݤ@=^áÊ¥Nüµ(kfI-ÞŒùbŠÊðœÒpÞfyðßü1'g9#•iŽDë(l e’²y˜õ0a‡dkx% uóÅ´Q‹+†8LIQj$H§¦>×èÉ{ ÐVÂÖ4ÈXîÄT+tìaÛÕJØëŠÍ£…¥`à[ ¢¯¡ßwëò;îç~¿ŸMç¤=—5l;;ˆeÆJ¸Kí ÁÙ;D6Љ[0•Š9·“¦£À QôœF{Òà„˜ë:™Œûáí˜ðñ‘'«´a‰’wIûB>=:l–DCêj"Ž“ÂUÌá:ƒûÚ‚éG7mø 6ÑE6ƒo¹á–„'M $Ÿ¡ý³ü˜[Q¶&U÷6ïx¯ô“¢G5½É¡}ç…T²7§v9¡°fVÞ'5wcÕhgRþç3‚Å0U‚…kN²!Å¥Ÿ£á ÃP÷?ãþù 7ìRæ·»àÖ_.o7µ@ö\¼¸ìàì·¶ìt:J||#j{TJ¢^rcW’DÍnŽ·E_qÐÒ°9‹—æƒäVJàÏäN§ú¬P?P"£‘&jn—K…EàŒ˜¨šüb!Ýè„Ûуã«%Þ' ›Œ§ß٤Α|óY¯(™†:{ç<ƒ¯gy´1®é^êÑÂéµ@ôŒ1ÈÐY”ö˜¡EN–lAŸ,ÛÌEû@­®28ןÉhxs·ã¶k¥¸wþ”ÚÕèdÃ\Õò+þöÜq d’l„blì§5ä æ;ì2­¼KÃz|Ù¤Q+q¶×ýØm2y;êÉIýEÆ:çRx+h  »¹ÃÍÝCn—Fß—%yGyE²^`Ì$\i`³™Æl&ŒšŸIê­ õÛ&œ9ëÙžð†ž¨ÝP2šz7š8‹*ˆ\& ÀóþÁw§Ã‹ë|òÂ`qnuÒAŠ(Ïðó\~æü3¿vJõ¿ø‚žöûôc8ä¿F˜ÊŠ~›Nùç›7N­çß½x~ï?^ü™ÞáÖÀŸO_ó'/'ô;‰?ó7ÜÄB~L½ò†pdÍšÙ|ve¨HĉÛ]ŽøÔŒ&šarb?ò ±ã) w_q+ aCÀt[ú[’%ü†|/Üݶ×h®‡cêñtaÐÍö ÂZPX ©«°ì˜]R ýh^;¬$³K„K1™ì*>h11~O˜š¦Vp»A•‚v“Ž7dy"h aÚˆYYÞrM¦N¡¯è¡Í}KÖæïV„ûÉPŒ†ûiI†6«Òú$G¶ö;“m<ñß?o½}ÿàO_ÿ¹ÖÀÿ«$¿Ûl¾{Yþ¢á6Áx‡œY:©Éà;_7 ‰üUÁ¸""„˜ÿA§¶2õ²¶Y1¬åüï âYJEß@KÑ,ûÐYÄ2&á…4Y­údÝg)‰ã/œSÊE»q"âbM)ùC† D)S£Qf4ÿ@ç;Ã6ÎH…LïMœ_þ//Pý­ ƒ½šK+ÙL«OÆÆ4‰:®'ÕfY:ª*" !¹"ãCM dB²æ·SamvÕÞ$WÚb™š<¦šÆtÂiK9™©ÒNsÔQZÅCcÐÑ ßûŽƒcùç?w¶¶?ÿüA’Þí<ÿ¹ób«þùç—܈ °é-;é¿bn×¶ÚÁ‡áŽt>ªB|–Á¦‡¢¹æïrš fîxB8}K1 “d’¹Ð¤Ð^¦áÈ?“ÄU$1æºN_eÂŽ_Ç”¾ž 1£ "Ã2,¹½á ;²¶ãþ¼.à2 RGc®#ÑÃqPç9`ùÇtH}ÁÛÛTwQ>Ý@|*ùM÷C(z8ùÒg$êK;íåL3]SÈaÙÝêÖÖVrxròä¤åô†ðE8c°Ü ùnõ%bÂÚ2žJ•ÃËÇÊ,"u:f丩¤ E­ÒìVÞñ"rª¼ªMÑäàDzz]eû& ÒžâÒp®Q>U ë3ÿdygªÑî‹æÕ;ó ˆW¬ ¸H j#ªSI”àÜ´ð†Ì ƒfƒ†_Ã8î r^'W)jÐa²J;ŽRšFÙˆIižlÒÖlÿ½i"‡€Ÿ#ëJ–(î¤Ú‚É®WP%Üsõ“GIÝÞ˜H®<=nQådk¢èmO®2¡¢ñµ»w–‡=[þi¿Íù,C²¼Å‘TÀ Jç·óûj5öéŽdyŒœ§õ- ]Âóyºß_ü–â©x«N²få¢-ذ$"@ß^z‰‡FO‚¹¬:„M $TrCÒF„+tx)–BO‘›’ñ‡†%{é<ô®†ƒl²È{ùf6ß‹&Þ•õ™ww+ý6kÏçÜ’ºÎ]BU3ѽIWN Ü O™^å«Û«²F³aá0•”Ìa2ká(ˆÃtN‹áª1‰Ž]7N¹ÎÍx¹FŒ¢†·;qn%]2‰³¨§´‰•'­tUrÃIÕm»FrÃ'bì:ÁÔŒa–Pktª×»cÖ¼XÎKLPH¤ÒnÕèåþuóü¼y ©ùO”'ÈtOŒ°¡mÌÒIÀÔå$aÇd=µ®í ššÞßï*d»yGŽÜÓ¤¥k0N»[‰%ªZƒõ ÒëìÕÿü Yój¢ È4ìS`…‡{¤Ià43ÏÅp–ÏÝõï#WúîgÌØBËb#LÇÙðÙW8t. é$â·Û—Am¥wq9i×»„â¯[6~9|(‘¯«IÍ¿3î~׿)WLöZBæ£T~#9•Õ²DCDD¹õG˜ ò6 •)ˆl‹èGëÁ>¨­y±$öbù 6ì_·É¿n“úmòQ7Å]/ŠOzO¬“¥&š!®tA€?,S˜Tåç‹J‡Š£™4§Ïâ²ÁD„’¤ú{îš³NŸžž¢oÍine2¨Jñ/XÀè‹îBõ·;_ ,åZ±¯©IãJDz%…ü sØÖ· ¡,­æ+Ê<¬,—ëBõóÖÐR«Y—É3ìskéúfN õ½ûÈGºS7LfgátªžG ¶mžX#G”¥cÛ¦ Ýjí~o—ó·‘¢òù“§-ý¢Óé$í6):©nËöüäQÛyMIh;jU\2±7¹ _Ù§Ë=Ò¸hW'ª°ØJA'šë‡Û©tÒRæ Ò„Ò «Ýæüv*ÖòÆöùp¼=»n4Ñ}U{ÉðÉâ$”l½»BFû¢Ñ5c+Wá“GÐãXòkÑñ·”ÌLfÚg ç£‘Qôº}­R_Q§h<“X>þÖ<ÏFøI)'ÍСZl%y37«²’ržTuzКh±"SÃ{8sçHÉâìŸGfÀòè~»€%ȯ>p»qåäùñÑ·NxŸHðuY怭ãìͪ¡«‡x=s ‚1löIP*E+ŸÙ,ǹ¦×Ô-#óÁðÆ2ÕHç³yJMgÃ×@#.¡$yÂáh´ÛÀ?·á44çd£äï ’MÇ„h€Ñ7žç§N~t’e>p–¥vrôøôlÿøØ¹ƒa3Ë;Íy2ó¦(¨¦ •·42…ö™µê$&‡"ñžgUq›¥™’ø½FÚðȆ°" Qµ°;| 2b×ÄodtËT¿@׿ðM6EòôÈñOmÜ(¸`î߸Ïñ¶º$ªÍÑõ厑{5C`bs™K¿°#_ÃŽ¸Ç†mD¾°6énþöôa9“.’òŽ)%|G¾A3º-ðZýÀ=UáÐ<þ‹·Žñ©sWú{Áü[Þqªœ°ü*¾«J2TJPgˆ¡]]÷³þUnñu,Es‡'ˆÏŠpìüª¹lX P‡Gw +ö“×›%› ~óy a¤àÒäÁ-LµeuPz‚Tµm…À°ñJK}.·?‹é$ÏqK`ÝsÔÍ’oÓ¦MŒßy«ׯ½Mb¼nóyv3P5‰ü³ËªÙ‚9ó°$\Ñ༹ f†~×ÄWog¼$açÓ=)"‰òê¨÷6UÁ“ašâ–¤š6Fûr(Ò}7@Uº>ŸŒè0æ=¨5š¤p·õä96–½A%U[WÃfPó­5iƒ¸Œ¿º=ä“Ñk•õ#(¾ùeÓiOëŸþí‘ÅŠs æŒIv–ª ~Œã²Í·gp“¼IN¿?üéC>AxꌲÎ-´åN4ÿò,Ù«w‰á,¯a¶61"qçŸ;}3unËŠàO¬ÍÅYŒ2§•´,“G ºMDÒºH€+eDÕg§ÆÓì¾!¯v®a IS¦,5`©’Ô‚}—ÄXä¤AÖ¥3w:i´¡$‡ñZ L*°ì&,È–B ݧFQgëŠmÔýJÎ ÜR¼”öÒ+<›#«ZéƒÛ^~0ÑEÀËI™JÉowF²rdœ<9ݾŸlŽad¤wKþÅ'§YÞ!´¡múþÊMËɱY;ç V±ý GšÒ/ŸîŸº´®ÿ uTZ³=`L2^ÊXh¡³ÙY·ÈD\ƒv¨mAòËyæÇ/sulîäyòÂ;9Hä0ÒBÀ˜Ã’È”«®Ý ‚ôMç.€ðºˆñ¶ÜÀ m‘§Ï¾N…€ c¦`I*à.ЉøQͳq.“TÞ—ß^ÐW‰wšlË;ü™—ì_ж.÷b;9xvrrøøìùîÉá_cñùîþ÷‡/^D¿§ÛF'ÃbÑCKÏI™gD=ñ¨¤kå6×¾ÉRdŒ¾5”Ï£`Ç!"˜‰ÖÉŸV ð"ígŽª5ñj‰(?HësÍÚBú+´ Øâȶȕ£LY¿E.DøÍ˜F‚&‚¾$}àÇæÁA³ZEôD&Fñi™_Âr3ÅÔ4šÌ-SÀúå7héV0a=dæâ#L¬¹ºµ‚„ñÑÉ)G·Ñ¥ l³êÔXº{[ò5Q¡ÎœƒdøÝÛjÀCJŒKÇ R{ B~Q]9Ì•µªtüîd“´9ü¡¦æL5WCK nDæÐZUoíq M£ÔŽâ‹!)‡Ù¸ïf¤‡Ä;Ÿ²Ö¢vfFŠÃ¨2›ÞHgb œ¥c® ÍÀAÓØs)†¯–}ÇNß`Ûfòè º PŒ2õ×0VX†›îÿtì‹Ðÿ—Ìe6Š$f£¨~ ÅVÓ7J¹AÃñët4„³=Í$‚ˆÔ; c=kx-ú‘Pè7]uÜSÏà(4ìžh·ñ ÖòOfs’¤çèéÈ´†Mw„8°‘<&¤STÿd×HVN‘U.5ÒŸì0¤ˆ-äÔnƇgt@  ¥ñrQké®±Oâë,¨±CºI"={/}ož‰W‹£1„›­ªc=¢Û³'„ŒzŽGºÛÏÏü½† ´<ìÀÈî·êùöÏ|·ší&ÛÓÆoÚcÚ«ûm³36vÔ|½ýó¤ÏPpƒ-¼ÝÚþù„þØ~[­üP­ ‚Îú­¹t3m›ÐÆ`:^w­GOš·fæ:[B´º›ÏN^lu›PtûaÆ ¢`íîPã»Û àfËøŸ«è#àaeèô°2ôŬ «%ôn|«Œ%Â'–îë‚aqWˆT{×p+Ñô˜«àcxÚD§AJþdx} †©ƒ 3™©IRœ$¨¸óhÃØå»[­ø1ŒÜ£½nÔ„]t+ g{^ ¥|S‰ðMÙ…¢¶èå·ùl‚ˆu‰vœ¿ƒ26z~#9 ìÑD[½7Æen}ªŽJàö:òáÐÒóÞbœ§9/›ñ†Q›:bd쀙רS'Y:PK…{¡À§$ÀîQh4>êQf÷=õ—a3šÎ¶uúj8å1¦D%­{¾Öü)ãZBþèRf½SÂÓNúÃv±€b"u+`‹Ø%âÄÊ&ûʬFQ€‡±â.šu¨ÁÿÃ5S) mtF‹»U=vèga讣*"kÛÆM½ÂþöÂùÌi°ÐÐ’˜e »ÀCJ•ñ„Ø3…nÿx`è8|'œ–©qÍÉEk©¥_@iEjø°¬xlG%XUµÄ 9 ŽÂlA!þYä€ZyäotÀ$ÏF¡À’Ê_`¿_ö¼´ý¦7ƒ—™Â]Ê%é=”ÿ¶ŸB¥8—H1® û„Ob´ã(ÌÑ(zŽºµn½îíÖÌ~ÐÀ÷õÖ€uk¾í²²»‘oøî]6^zƒ³Ñˆû(W­Dóål¥#²8÷*mɬ”ŒÝº©†ÆAGܳÔMNîÂÞuz9ìïÕé‡ Ü$<ôÌÉVp&ìw¯£Xùžw+Å@˜ü›£½E#ÆA€ÐLÌÛj²Ó3¢_d¹1OÅãËÞ öJ0¶¤%|+Ì¥«=bjKA{8”fdtç¶” ¨pR…=⺉È÷‘;`¥ÀÒN„½uϤ§eU ÜGŽBÈYêmþ?Âd±›bšÕ<+ |Ÿ“o.jÁcFé•$Ä÷3ˆÙz(>‰¾Åkwb~¯Þ¹ Î|WÄkø%8Ñ‘“\á U1yí†Þò>L!!*Rôì ‚ˆ×èüFrÈ ­«Oed«zifó¾… ;b" ¢(¹#½ŒæØ©¨÷Oÿy¶ÿýar|ÐÛ?>Æg{J<9>Þ?£_Á0¡Ô©Q´—:V\€·„ÊTç/|ï}·B#üâ­¿ý'Ea­ÜšÔ&%óu¯ä»‚O[Ì ï/†5W‚ò.Ì1LJW J}QÙã¹vE„ŽãñDé)ºfíÕ©„m­J$Kð¸ Xý(i!M£Ê„d¨D-pn‡\Jæ…Ü ÏҦˑnU†Èâûh§-v>X'¼‡þ<ÁLIVhÒêÙ6ºÎàüzJü«ÈbL üýry+nîugŠáöóã˜æ=žÙÄNiw¨u…n2úP×k¢KŒXÃ"òwRB¿L7³3¹ õ5Ø©6lñY t¬a&9»%¿>tB+Õœ4hPóËb·,g„ù¤ûOhû“ü«ymõ n~àþ2ÿ{·¶Æ–ÒIŒ=¯U‹Ä@ÕíúeŽ,CÓý ¾ËF¬µøQ²ƒÇ%ºwÎcN,þ((-${}‰¶%¶ýVb”…⤈6¹¦Èç·¥E:/ ÉÁ$£˜Æé5Ô)§á7F HƒÅŒ‘Ä U.ô—B¯†2•¦+›™öuøoúÊ‚††_©eKkN#‰v—IÂp2. _¥>Áa¼kœ*wèLßòÞ€¸4@ŸûïC ¿íኚ¾ñ‹=q aæ™Ð»Kjw)ÚÐìò¶]÷:–iˆå=YíËÊ%La*5KgB5ÙÍéØ0Ÿ3=>¨”[Ïæ]§ÁÒï^$ÛÙ¼¿=tòI÷"ë´âËþ26‚ö…oÓi÷N&¨ uÛê`AåCƒIŸ˜>×RÐêSó´ ”8ñ™óÉŠä÷;ÏÿðÇÿïÌß;ÏïµÿãA½rB+^+Qs(êÁæN³•ôg£ ~a‡àæ¿£å~ ’JÍ65ÅPûNMáZ·îö•Xã‰ßdAcðéoY«x|$má–ÈVR¢L´Rs[A¶ÒË I0‘â3€ÙS 'ɯh P/‹îÖeraR+ÐGz¨I63ãõëz2<>kúPµúé‡ÇÇ5Ž3q ˜ zI&v™û®šø€ ‚¸Š4ýûÇÏ ¿xÑ4rc ¤\ÙÐ 7Ùרj&»$ðã"F~5ÛÁÓáİ~‡>°oXH:ï!ÐDíÕ–À fŠ0ŒwÔy5¼˜T/n›n-ÇÞgù.vÀGJì›M|AÁeÂó°0ZËÕ3ŸlìòÞþY6-\U‹3íâ×Ý6lt/ˆ%~ãŽ%ðy·ÛM¶_ô§]\z-ÖŸîíºŠ]÷m\°|œ ê½òêÇñíéCk%ç0(vË犩7ÊD³Ë&¿!Œôž7h„r”'d¦ >1þB|_ËËñ„ñwË3 Àƒû{±›ûUˆ°/J-á ·aç3Û˜]B‰:d;hJç™n_4I²©Ûùæ.ÀÙLT-BÓÁô¾íKÒGðcJ"à³E_§¨ÆmEm¼a½þÑ…é-AIŒZà"ik"ÚMñø’ÖwD4}÷ô› è½/¢è\¨Çª³b1^Ž èFà}"Æ?ÝXFßä¬d`#-3£•ŸGñÎËÉÀ2B¬¤!Ë“áoÜØ‡ï×–AìEˆË:=±*3kwGsW' #*É­¹­›í´´Uf›±œ ¤3ή­E$èøÆ#p2ÙP¡pɹ¯Dü>Á‰/˜5vF™Âèb¿)Seþ#JÝy³ñ¥R,¨9À»i­L [êQã4S+z:EÚEŒ½Éœ•Rà‘L(„ÓJ4iU£òDC‡g¯Ÿ² ®‰Õwsñ¾DŒvœ}:ÐáÎ’oŒeô··X” éø‹óŒýV¾gŽ5S¼‚¶Ë°ªOÅá®ëÊÜp ±—û±YšQà;9d¢êcûu—(D³Î`q}}ËçüÃæ)y}výå<ÙO˜ˆ‡vÞ1˜Þy"_Æ2z!´ýÛÏ÷Ûÿ•¶ÿñb—Ÿ4‹˜ù® —tµR¾¹¼ÂØüV\+é-9¨hàÒ#uȰ® |ã¤ê(j»"ÜØ]ŒÍP\¤™µ”J8¾ÃÚ¯.óÅL•òLr˜øKfÚš“Eëì2ç¥no¨/ÌÞÌÕQAB_YBeN¯ã“`;ºÙ¼ï9ýoô§ <KêBW9AÄÃg{™„Ú¨žâÓ•{ÒišQëbì­¿ê,»@È  ,¢›3Œ¢¶ì ‹<õ°mzàõVMµÆIOw…$Š®PW?#åé ¾‘ˆaæŽCMhŸË£ŽÓ5ÿÜ©g…ªÑŽ-ñêã´K|Ò žzOÖçäýu÷Í.&{ˆˆ ‘l2Ã\áìL§£!ËŠ¨”©ÒyÂÝãj=²â©±Ô,ý;k¨Ë?—9èÖ?ÿ¼ö²ª– L] m9Ê<“ ü²˜çþ†‘ЃìÍ”<ç¹6b Ò­~¾Ýˆ¸ýåäeˆ´Ð‚K:qíp^¹ŽãW3‚¨¢]OfC²;íÏÙ ‡¥&Œ1¡ã¢Ô}Žž¼íQg0BÅNÙWDæb»ÓAíQ²)[ytÛÒ a³W4ˆL²R1˜ 4›O0Û€ •p†Àq’Ýb<§õKeŽÕYÖ\™uY–¥Ž~ìªã¬röJ†¡É¹ô ˆ Í2vWf4<ºÛW,Dvq(qA¹d=³ÉÜÈüceÎQá‘5³ƒmolöùçßßøæópDØ]ܯ•ÄHöŸæ«Ò(Љ‚Û¡p*žwÇMÍ`?'kÚ(]T®4º i~1àC¨em=òϳ‹‰Ý¸´Âs±ê’ÃufÕo¹êß ~ÒÃè]OÊ8Vâ‰x+ ]¥ÌàîP>4*.™Ñø¹–ð½±Ã9­nj¼Õ*ïÏ„þ(J±ó¤ŽçÀu‰»Çv㸻1Ù]™åÛ†‘Ý6Ý6Ë…¨ŽtÑ ¡¨â§.¿˜+ÉM…RYš ES T,¥Ÿ•ÊÈ ê¤Mí„ù®>à«J/+ûÓ¬¬hº÷MëßÞ®ÐÚ¾‰ž¢“IÁëÜ]-]oÞå Z•¿È1÷|Z%9z>ö†î Û”àLü\ÞÑJE6'íœóÎrÀg V6ŽÆ }‚ż¼šË½­hÎ&DÜ^IÎöY’œ²i‹Íð ƒ[€(3ŠëLÚ-m‡sï¤#ø©j`„š˜]ãìR¥×lÚ¿Ò#–˜‘æ’Ñ× lêï슚„œÕØì¬D‡Iñ’úñãÞ)ùÚ˜MdZ%N†55P©CU"å$ïáÿ›5íì8s–µÔùe:AþÕ³Áð À¦Ù+nš2ß§u±›KH¦Kl¦y¶LÚ&‚ŸÐ‡lô×t1ƒi…iENY"üW°#üžúþ–HÞ°6ëkýøÖ ˆUxNpÒ[ §PÎ…™L:’ù‘q­$bM…Q™Ã?œâÑÀÈÍa'ëÀªMo›ŽÀeð"¡äw˜FŽ (<-ûkÙ0fD ÛQ|T æ† Ô±ÐhfMK>’ÅEtkÇ—²´}N*;ëa6Xô‹æ0wÈ0©í|~ëÇV›¼ÆÚ¢Õ‰XçyNY¨%¨×¼hŽBÎÉ^hÌßàÝ kØî;£ó­æ1XØQ\ëÂR“óiµá+aƒT…ÕE=s–ShrÅ_é ›àm٭ϧ‡ÑÝm5ÿи]À{Ã~Öû|äí´åÀö"ºE¼l‘ý¥ –1šƒrõ€»uSÝüκLŸòU"¾AHÕÿoΩXçø¤åpÕçèóØÒ|ñ¬ƒM“\.”¦Êl±¹Æm(ßÀ*˜kôx _e^ÀŽ$+Ë^ÝéÅ…[eãV8¥{Õ(\èˆpqAØ_fS¢ÁÇú wÕx¼$}µ1kǰaI†–Y4‡û#™‡¡-ËMo1;mÇ}§€#3«‚ŽðŸ”Ø[s$ì²@ןmÿñ wçUÇmë ¥v¦}y˜gÈ6¿¾L£ó¢LÆE7ÇÀs]Ÿ³­w·1ÆþóAc˜ë[`“¯²¦ŽÜGd·CEïÂ8_xç ºzwÔà#…O„QØ v÷ÒS׳ GfDA[ÐMª$v߉ìÖE\} E"á*ôö9wx¡d2^¢ÖSï û½iÃþ(y’(MÖ‚sgþõ·¶©÷§N©M¤‰E¼æf%ê!ìOiàÃõmÏåÛvÌCÓë½ú}}Hýß«¿ý²Müñ{óœŒönõê»ÌÙóŸÓö?öÛÿ…‘2Ÿ÷ˆ%“&¸Ÿ{‘8ѤÔíüØ Mäµ³ÑÅ’¨ìÇZq9šœƒ,ÆS›Zbo{SëMÌ¿èÔ(LëǤn¨3­2*²ØdÎcZ#À×tÌ(ßý楗ÁËñáïôÙëi˜÷ÑÙ”5|Šíæ“ ®iÌyÐlÎ8ºA¼9錯«"‹¦n¼þ–~¾?5¿±7ÐÓt–;zF*,yšœÔMj¦€ŸOÐyÆ “Fº%³ËÔG;ók/^P “2no¹ÙÖ“EîZ›˜ØŒD "Œøžd× qDK¶¶±ÁïUC€ êOOž|²ÿ(ÙÄPúÓýƒ¿ìØLê=šÕàSí6)XFƒF„¢ÁíqT[‡#LŽÏzOÿö¨wðäñéLàÈ[ÐI~ÑëaïÉ—ÓÄ/жôÄ’.@Ôs»G•ÉŒ^.+¿ ¤¬ä-·b·›:=;9ü›ùN+Éï7“MØ ýë)lº#7áYwݽ&m…CÛ^`°¥£x\0%û`åN¨|‚MP‰¯¿èŽM”.¼QâÍdä2ºš¬”¦wÓ/Ó„ã›êF5ékz»DOfYõcƒA5…q´nH76ÒyrްÉ`äê»ÕŠ _”k£n‚¬˜v¡‘†ïÅHR…qº•½QJ*Ô®šÂzu[»ho0l£ó´çÙ |Õ4o \2 ^‡ ¼ÜyF JS²E^Ý”„½«}ž²Š(klpŒj‘ån3n©¯/}-ì#U(PðK·•@à7éü’ͦ•üâÑi]a& ­!¢ŠuÚù|¶èÏ)Ù+(p<Ù¢ xFœâV:áÈTߣR˜¾Ý} Zð@Gé–©Âdµa“ÔûÞñÙOůÏ_<`%£3Õ¹of×›‰S þ“"Áìæ›ø7[Þ–ô9Ù’¹ÛKÖê=N ^›dŽÛ_sÊ_ð߬Ux«z8¶½mw¶¶Í™ß$ n²éÖo ÿ]·ÖlšVe _›¼0ͤû»ß=Øv·ÓÑ;íYdšÿ¾fzÖ¬ø vD²W}›¼íÆËn­eï}ë“nš¿÷ÍÑ㣳o¼ïüÎî ü¢=¢‚Ü’' “W=OØæ ¢×cŒ^TŸº®±„~—8½üÀï©âaý½ç-Xõýƒª1 pès:£T·”ï„ÏkJz;Ë2„&XM¶8!½úîäð^ô~|rò—ý“'Ï?Ô£Îä‹¿äç‘Îæ‹éf“hÜ ~‚µæ±~ïÚõB  ¾DÂUy¼Àg.óÛó Š~‡Ð&Y*Õ÷Äf¶°¨w¡€lÕLFW…pÊ•ɆØh”ÕpØÏ‰¬PÚ o²%XÝLóùâR35ƒ°›Û´·”ŽÑ|(e{„i% Ÿs‰÷"{¶îÓ£ ËJ’oäÿGh*§¨ð ¶WWd}ähê° jŸqfDÚÙب¹ºvü~ç~çt» 1†þ ûëÛ/;;Äzmµ·Úðì<Üïl½sþü²sÏû;]à#9TñD§í~ûaqC*ò6{5]¼Y»µZx¨ëêâA©~VV_î§ÇUz}BùÛcU!ãß%õã³L{ª*B¯‚É¡‡¢Ø]èϧG‡%xÞg0Î1Õ¼N‰¨Àé 4mù9HaÙÉ®·ÃŸQd©Gt8Tôìà î¼ÝGT0 ­þœ¦¨DÏ“£Ù¹0U ºõ™èM[‰³Kˆ¢Ò\Ãcž:¿ŸÕ|Þ;`³Ï8Ç\ô»&{ï a4 ”Á÷íô¤à@#‘{kDÉ„úX?ÝÄ2—Td»×q@ú¬=6xá¡*7éC¿ù|å·’º€ÏU©~øÅ†o>ÝW­|ò‘#þ5ÆSh“<çÆùÄ}þô=¶Ä̓Æ,†ö,ƯÆè)/.A3ÞB|(µ˜ã°ã¬HHªÀr9Á{ŠÜ,Ñ¥#‡)Ò†tY¡ì~§u}fÄag&_7;£_¤Ãž©¢*Æ´$1n˜VP3Ewü·Åh¤¸õ ›Ë,gbgÿs“ëäÃÖ1Ò;{ŠÃ&$3½Ëñ¥d6nìŸ|_à4˜Â†£dÂÃåÌ-ü#›M(¸u‘'›g'ÏàZ~mkr€å÷Ÿ¡›þb>å0ëkê;É 7µ¨ÉñdìµúÝþñ)4kòQ‹Gg´ÃâÖé;uÆ4{;«=ºË¾2¿žÂ”?~””+øpâ£ùU⪰V¬‘lö®²tÐŒ½{íÿè½ø¢÷<¼m½‹=ì ‘Þ5ëä(êzC—öµYäëüS®ñ8ytú«,­ÛÍ_meíG>ÉÂòºö?;>î=B[uïááéÁÉÑÓ³''ËVÍ뇻hl3…œ ©º¡R”“ #A}úžÐ$4 X£ºé°3J}=šcÊåd‚Å'æÝ:‡yßb·?âàÍÚázýæ’Ÿ<•txØö'“Ù€=êY:ox¿Õ eÐAo! f$eÔy%Ñ]è)Ñ–iŸO‡sëÛbì”â’ÓöùÃWÉ9p†Ý4Dî¯0?Ñ]â`œl¹ŽÌ+ìØ ýÒhöÚÇI}ÇUÐã¢1wæg¿â­tÖUhÀ®ÌaW—xsq$bÆcyMķЩڛÿƒ6$Ùš®F÷3Ôj_Ùµˆò¡°ð&P•âtš%Ùå ~›¦sRªó© ˆÃ¨+xbxïà‡Ãƒ¿ôí„©îÎ~xòÐÀóÓ¾¯?ùö?>{D¾#0Ku®±sï—†oÖ0‰„ØÑì2ðJ²9͆[íá—ÿþ‡ÍÎk ôb–í&ø°ùçwӬήÛ7F†Àô´ÿðˆö¯ïñ5PHåUZÇïG§ˆ5…SkÚ˜ê!òŽ•õå÷ –ªV”£æµ_ã’%60î» FÊðJw¥`·Ñ—¼.@¶`I¦“ø«öþ ëÓ;›Ø‹½¿˜§ÝiíÜ»÷¶Z©l'G ¦P§§ù;ÙyXïäÑT~þ?Å&õ£•c‰3Ü“C=¶ËÂÂv^ï4¸ðûòoy=> µb¯$¨€O@²·ï݃h1 èžS¶¤Š!‹î€5[ªF=N5œ Œ@ÃN»š£›<=ì&G°‘GewEç|È[ó·ü¥bØHŒ9ŒF$žófgþÊ<¥s<¼m M¶‚ÛGʺ@)è)æù¤?$¹Ý(å}¶?‰÷ÁÑøõä‡ ào¨¦MÔ]Š.÷ð¨RjPô§Evå50ú¤vˆµõšïŽe3½|–6ìLÏÙ“'ÇI»=DìL ÚJ༄:Óu—ß]|¼ÔW-¸øÒÓõÔtYˆu†èÇ_ÿÞxòû[äóRÝPHí5G‰O½¨Z)žŒ!yþø“‡ý«I^€û)”/H§ºþREw\“ý+Íwi…¼õ²bÚ‹£󌗊ª×ê÷k‘›šíbÛ?L€î °+ ]ë5ju¯;µÆîö[#ù>%ƒët†Ât:÷rb,Q˜04¯Ò²¢£5nþ=Ú?ù þÜ–S…ö[˜IWC)äÆòcFj¢¡¢Ñd|©‰Ä¿ú2±œ[H¬¥$Òéè&½ÍÑa!q.”íÝç•äŖ˯L³çÃÝ·­îûö6wfû磱ÝóŸw_líÊØDcò¶)!Ñ ?¢½‘N«^ŠQ ¨ä‘Ñ&¡Á±8i¨Ó}ûÕ—Ý÷۟釿Cw¬Y†D’³-ƒqK\>'÷)¶“Û†¶înî aVù?'@0u‘Ñ`d:Š!A£d DÀŒXâÖ8Í$–’f‚±'¢-/ÐhYÿñ¹üÜuž½1§;ÞÞ¾ ó´Î¯tòM9ÿÃÛ…š=a0™³…­mÚxÞí$Ýù‹­ºSÿ)®¬Ž®ƒþñïd-Ð)vr#þ6Ð"VÐ9„¶Á‰iD×9:ƒò•È ô“H"Öt:›ÀNB ]O&ž0ÊUާKKšMΛ“è°†¹ì¥¹Öî$?d‹ÙƒÙv1ñ5yMm“˜äR_†Á{% º7°[I¥>­4:dS¶Ð&…xUg‚ðlï—1l!:!tËàµáNS½|íhœ¹hd0Ùó"MÜ{óå½ûd¸5«íÃVHü½¡a]R/i‚H™4kHÔ††=Ð n'HÓâN„dÆ’GO.܉åÓÚb! e3NKÙ©ú¾†?w;ÛƒxZñç/õYQóüæLœª–ʸ‹!‡¼ad!+ „Â<ëC5‚fˆ/²IœÂæ!¿h×&zý‡BjAþt¤ßDU¬Á*0y_΂®Ï¦4”×jG*YÏ— Ó^7¯ó¶5áý]ýƒÛÕ\i‹U­údUÕäzÎäŒôÒqOÉ+š@1£ZV¤nàJsAÂõ¯ï¸y^œ—Š*²ãEÁk,èhãÆ8Jùžv1×<% ¤™°í¾«ª‹"^è¡3éhìAOðgÙ;ö¾«”A¶E€ªý˜É?Ϲ©"ºEfL;*¡²ê~$5t ,Ðݺ?yd†Þ?IÞ$ÝZ·8¾n­ÉhɈŽš½úŸ 3ã§éP4–h|Üd‡óWø–;BtBÃÞS~”°ïÈò“G©üh/ú¡GjÓýôn4+’g’ÔR"òÓ0öÉ¿C¯ÔÝ$˜ÞíH·3Rá|èÍ ç}>™ÊILÒB¹eˆÜFp:ÐL".…Ø[¼§¿ÁÃcþHÏ7„îgФ,yeØ8E¬„4§òÜ ‘'¤j¥<‹’vÄg˯yþrz3xYÛÖ×µhVÚ0zú$i#¶{±ñ0à‚,ûŽÝ!÷K¼p‘½,8Ÿ{ßôœjÂÞh‚¯‚k0A°» s¿,4±!¨G¦‡à<¯aF†ÀW'©7¢àã6Ù€ó)]Pð“~Àß‹1Ü!íz};Ö“¶ÛŠ Y‘UÁíè}&i Üå–¨Åw°Áu¹Œ‰«1Iޝƒ÷Ѻwjn@þG׿\€»È_8/æ}äÌWé-© n² ïç025B#._^­är2Ÿ£x>ÏHĹFw»Ý¦·)‘a!ô£—˜ï)ÑQÀÊ¢åùNêîVg’´Y’mOìÑyêä©"õ¥ N4¼Íˇ÷ Oò½Ân¶!×~Ýí쵎D28­™> óå`8{[É̆v›¨y æÑÅÓŽŠÓ)l’öìÂôKØœ]¥Tºø¸ ’°„CDbûÙÜHò+_)­TØZkÏ’é…Ñ­ÿ±SãðoµºýÎ-˜¹ÌîÊU/XÄ2Æ”ªèôÂãu¯‡óžÂT?ÇìêãÉ 6"À =€²Æ¬°óÁÓ4/çùÂŒ Ìœ²‡b.¡ wjqåV„\žSñ–v¾õ3ÈÊ üê69¢ŽôÃZ';Iò„'ÿFhO MQ½ÜŠ–ÿ’ÖÅg“ ÁF¥ÉxA~ /6í#™$=ŽY$nC¬J-œì±?žì?}zxÒcw™Þ·‡ÇOÚ;zÜCcÆÑ T6!ò¤Å›§¯pGI¤³†$Ú&X‚`¡™!ÿ#TæùâÚMWk²«ÝpJv[™ª×0¯r. A¼urÙ&¬Ô"7wŠZ­ŠšÃ«ôõp2SyÇÝ+$ëT ÏÃq…™öxò£9™‡èV7>Kû·žxÂ&íA«'¤l 6‰ÚED ¨|'ð5c,ÔO*Ò“@Ÿgvß ¬ç@tAêF0ÜGmŒKTÀã ñúàë¤< T¢§ä,bNÒaJ1dôPt¿Øu8ftzÄs{EÑ܈;fqžÏ‡sA·#Íw6šæ˜!q0If“s<.h Ž{¦!í¿¢œË¨ ÅMsÍSkbáFp„Ð.nB`â_gzF ÀvnBö@l OâÕȨÙÔŸ½F=xÒÀþ~›%ßN³1ã…¥ó!ª%~!oÿëô‡ž,èpßw %b“qù0[³$º5Ilø]Ú=¤TÍÉåWÉ—7d)ù ~ øÁ8¦#8d„^ xŽ]ù¦[{ßB¹²EmÞxÎlœ÷r‘§—x¤sNÓKÊc¸_¡E); ßm_& ¯ÕÆ^C~E Œî©äñ“Þ÷ÇO¾í>ûöô¬*Úºº/7‘,µ'M—ëï¾Döa‹|h@xäìRóà_PÃê·@ŽNØ{3½üê˜~#ƒw6[üá«êÃgûÇû§‡{;¦”>’rþrŠ+G쇧íg?%¯`VqFŸ>9=úIüJ¬]`ô!›;T ÐER%`–ƒ‡O÷Ï~ †y6c?-,2n·@µ`ËwCön­ªç2¿Î&ãkµd INs††£#†§¯ŽŽÙ—¸PÑÉ]L‰‡ü‡Ù…& 5D@3|}°±w™¹pps.KAé:íÏ&ú7n—0gF#Ì ÑÐͳ‘üˆ &{ÁãL,ñ$Ô:ØRðf\È.Óp67K&\+VºÓ¡ØÈ:ŸEçCÛ±â½n­æð/D€¿Âo²¦âüuÏEáw”?æ~Á[Ù±‰û&ÜñâºiæŒ'²%ª'!$>xp!לÑ“îWtzzéOêŸáW{‡O¾«vë;Uço4ga·¨Ë0nê{·Æ*xèâ_3Øò / ûbôA#qNd˜ø){`m¦M“D™&×$÷J+Ù¹zݼµ;i q£Pªb7„oð“5§"î:b3bšOkÜ&±»ª%Çß ïå΢L2çZ·À‰ü4A |7.×5Yg†²%ëbFdRŠ|ަ>‡K`¨ë&»øáPÞtëR]ø“7¦*&¨–;Ò1âú$¼–ò _©ÿé ÂÌ}cuµv§ª"ÓËQž´GƒHÿÐÕ-rí¯“íí)÷-à. á:Æ$.I„ÖwW..HœŸÙRÔ"Ú‰FM,þx.ÚÌþU:¾ÌÜ¡¸²ã›®f2Rqñíe…½³¥Í~Žd¶è¥ ~ fm½ÊînwKÈïÛѲnü#Ç.<Ÿ,®¢ýàêõ´\ݳœSµ6Æ“F ¨]?cµ¼«Ìe6 ýj’ò)¦œåȾ0f¸«´Ö"}½`U3r:n1³„çSGR.lvZb ­ï4‚]±N°;ìùÞ ÌTW5ꓺQâp"ÔRÜ‹ì4 IöªÏ›q2aë9iq¸æóŸeòÑÑd´=ï <ï0ŠpÉFˆ$=§Ä%.acÌŽ_qßúƒ _þ"ÓâÒ®à“)÷y4kƒ—áÒɦfïl!ï{p«4F¤Qâ@!\"HºÊ…8ò¨œÓÏD|êAò^¦Æ×vuëm§”ŸÆ:ðxÇÀïÑ_à ùB'9´¼úƒç®J'$[†Ñ™éé ›˜ÕaÆY?Ësuj ØÐP©&iòß Ê Š3¨E «“*gZRcº ”Î!‹¶ ‹€_¥tÜOB21!:g¬Véþñýk’/2çv˜¥»Û‡H˜Ð’åÄÅ4º‘³ç¼•'®&àïîÖpÀyJ»‰KÆ©Ÿ.†oàh€¤ÚŸÑÉ›±Ðê(ÊÜß§üÒ² :†¿&aÓ™ ƒ6Pø¿ŠŽ5mrÌþÃÒg‹ÊHCH6WU6a z„/{K|… ñ£‘ífœèiJ —aˆLfç°‘åëã/{þ§@f£×5“Ÿô 1h0£ï½Ng2w¬BŰ‹ݶÅ1WØl8@ç€Å˜=¡½Dj^ÃÁ;4Øöf«§A3ëh,Í Þo¼*ñÎ#T›Ûtëþ[¥™ –ábqþ¤\eBNŸ4¤MÆm6æ­8ò]VèjV`s8†ç¢ 鶈}ßfON““¯ Æ Úo—%{m9ƒíÝ]`¤·· #-¦µ ƒ…²Cw5¸P Ø‚…WŽ2¶pš1\0G Ò]ö¬œíŠZ†¨:‘ ‚¹G¥1}C{¯S- ó’縡/ >CÕ]ñÞ4ræˆsð›xŠªÎ—ϴ׉6pš±ÿ‰j&ƒd_äPÍÉ•9Œu܆ÌýÓp1D$ÇлFm˜Æ^>C¿ |ÌvN€@ùÔx«Ý[¬« Ô\áèRâæ‚¦Õ•Ž.¾—Ki÷Åñƒ-ah£{ZHóëpFTæÛÓy7ç¬ñiœ;8µýÚÞüaÇ»ÃÝÝ=<’d}­í*ÎzEíúS þ®xÑG§è*a³¿õNÎz§‡ÏN{Ÿô>=9<Ø?;„M+ФÃ1Aš'BqwÒ¹úÚ„‘5ô,ü‚)Äc¡Bö!,²ÁSi_2Ô™Çp1ׂ²Ø±6+詚C×ÂFO8¬kXµI¿0. vþ³4ϳÙ<,‡¦LÿYFýG@ÇÆÁÌ]ôÇóQÐØm¾Q9øôÃ2ïy™ö`?á–Û|zdœy!·"&‡üþÇ/ïÓœé4ÂGÎzXž£}¨‡I1Ư“MÄ»ùÀ™U?‘¡³ñF¹TbÑÝïµÛ²íã·Í§Ý‡@ ýi%þ_PÎé"ÌßK (è'“d§C¹<ô–x §b(âR9©U`åPAKc Ø)ü‹0ŠS]8|0røèÉ/ÎØx†{ø‹}Ü¿‚bø˜~±ÏAúïßÀ‹ÿb_ÈÔéòÙ§½£Ÿžž$=øåð§ÃƒÂºÛâŸ×Ýò]%5~Øÿë!Я³Ãǵ¿{òôðqïÇo“ÚÍy­dÝ­¯B¸Úîš!{Ý{´ÿ“—.Â3ç¥×<<Á7LJ£µÜ×…LœZhçÞý¯Üñáš=vß[DxܳDÍ–üþä©_Ø’´§½MëîpoS‹N`šŸîŸìŸ=qv°÷8il7ì+šçÝn#žÄ6’ÜõÑéÃ'§An×ÞÃÿüþéS~ˆì®}ñäô~aG`ýo÷¥î!"dïôo§g‡Ê6’¨â {÷ñ‰³w8ÒnÃÒ>­ïÙk |•44Â+)>ÙÔŒ´rtÚóÞI„;þ —€÷ªÉ»+ÁL¸AçÝܰÑ»ÕÊfI«”<8úªwóÓHJ>jÆ™'Ûÿ¥?Bÿ3ÄÂôc\¿Q†3ŠX»fº‹¢ûªžÉÞ“Þ·G÷Oþæ0_úÈ9—zïÿôhÿøøÉÁ&2-dÈl“ž Uâ 3.ð„Þn%ùðÙä‚Þ7q-´%DßDæ4k¢‡ï[:?Ž+ÏÞ&N®>HègLŃä=”}/f¢Md2Ü£‹9¿}ö½(ö'og4“7É^²ó@è\üõ½fèîå­6@ sØKj‰·…£ÑVGrßW4XL ó‚¨V•QúÍ áÌôæ4‹„óÐ:Áì–qRpõc3Ì`bZøžÃå{%¥Ï¦0üZ¤lhÜóÊ"MF{‡p9„}TÖ.–•rý« ]—4c„ùþG:U† øŒ‡ÒšÙ„Š] ýVQÙØâå$”ïÝõ¼…÷ªÓg¯ßÂ5ê—/3mÅËÁ 0“ªÕ_ÁÒ²œªPØ$p‰ð“ŒÑé>!ß<3•P ÔÀÒÃúU)@I<ùÜçé`À#žOzPÑéÀb:a×°WäˆË{T'XŠ;Tç¿¶¦œå·—OÓ›±nŒ-ôqw:xˆ6eïUXAxMb¾#qâßH&LŠù?%_ù9ç1A=ê ƒôôJ~ß´Ä1“,â£ÛÞëa>¤¬‘àÙ†Lâ3N‘¢½^:‡Ã|Žº¯Þæf±ÈMNsD€"͸S–0h(pˤ0eœWX®šO.ßÛ^AiêNÚo¥ˆõ“+v&zpñ†ñêØÄ¶º¢eC<~våöHaÓ¤B ?°: 7£«ŸXÙºÛˆäÆ)d’Œ(áWÚW¨¯8,~amñïp8å~… Šõb,ÄÜ%“r¶òý!È.¬ŽëiFó¶£¾ãûj2Í.€h³uNOâª¬Š£_÷cwý¿¨&3<Óñ™z+e“ƒÑ&S‰ò·š¹MúìÌ×å‘LåÇ‘àô¹BcˆÁ¢•£+PYÂnú°ù.ïñé-©¨ÇèУ:f1Ñn©ßÔ…'Ðq OCs䣮ùâ"ÃüÌ ·µmFÖß»grÏ ‰—O†pMÓŠ&Ã/¾¼sÕBš9š¥!|Ì߯ •TÞºêHÚt7ŒdˆZ• â…ÅÖApjµÅ³Œˆ »oå’ÉîpÑUmî´Œ´Õ|d¾ä:/ƒJR`zøëMª)õ0A•÷Ë&@ÝvÌ‘œÔå“ñ|8^d+Ú-¡2M;à~Œâ ÚZDð5Ü)k¤‘8®–ÿ"5n­8*AÅd‘@½ |f â%é9.º¾zí0â¢D! þœ,U-,˜bñ¨Wݸ’Väfê-†ä‰&\h‰‡mž\/¯¹•±¹FC˜¿¨u+¡l{NÜÕMRlj B WÊeF ]Ððñ¹Lz3`ªùÆh´%©çé”Qì”`®†—‹YÖ¦ïp¯ý–ÈŒhÊuÒ~ÈÜædï¸Å·¶ýý*"\•j½pÙè3¿ \:I'LåóÜÆ¨|ž7j­€Óv£¹•ÈVoÚáçv³É¨¡Ú[(¢|Ï¿øBØ 8^†Œû-¾¯–”Ç8` Ö! ÿ¤Oãj¢ÅQeÈ7„¹d‘Ñê d|ÀE”å^†ud2¶cet̸Ö|7ø­ù¡M¼Ø›‰q÷ÿ<‡6[ú7MÔ]Úq/RÓ˜û/A—€ù.(OÜÏ#íóËó5«+7eR£x©®Æçù݇Ù²:Ø òAÆrS3M%Ý-­O:rOGêp¿î@Ûmº¸Ä•G¢LÔ‚“ó…Hw0†Š”B3ä6_¸ˆVX7§•;Ìi¤V0•N nÏëíZ·Î ÂͯgF ²L¤Kßøl{]ŠiÄì]s3ãKOfh‘m”KEò…f+‘R5ñ‘©5Qº€ÿ•U§N‘¢ ÔùaÓv§U~Ʊ0&³q Û—–Ø®EfA/&Ø´9f"Ú’¼SÌrì"Ë@´)߈‡çüfØ—û3XN³7í÷ €ÚŸœ‰@uåírþv>qIp•R·”î<|Rú9¼É†â¬–›o»{Wù#¸F‡3úVâ•%D¹0mÌâ¸+¤’Xo’;ÂËbÍØ2²x[w+™2G%v¢Í)|§îjæOZM›MôA´786TÙÂ톲zïK›s§çŽ ¾·œ’Ê~%’_)¥)¡åá•X¾ECC1U€¸ÕjN n ƒ¯bvƒ)¯è*Xc‹kùG§Iò+®ž‘% â@ÝIB­à¦¯þl3ËSvnªmf vãJA”@þ¡*l7MrS[+ñ¿ÞRfn]±Q¦t]±YL(uÆ63U° „zÒV0~e¦ ¶“P…ß †Ø\÷±ˆ³o½›ÃX±ÜL©Úå«]T—VԼܥ'z ?¼ð:BІ–í–Š® Ð](F¥@õ‘Åmœ~5ç;@ŠIKstyÎú„Ói”'±º¶ÀX%/¨“¢âCMe3áptzO{?zx&2Ñ•n™ 2Ò·¹—´wüIÇÓ—G,™Ã^ƒ…NV]—ÏðøsÓ(G +ÓÑ­ÁjÕ kæÉ,òa$ƒn’óa³iähQ\‘Ti£<áŠ@éèÇ"«ÉKPco!œq¦öàs¬-JÑœˆ!­„!cáîÒ…:«’¾²‚F¿W#5få'•4¿Ç›`“ú&EÙ€×÷³éZ²äuvÑtÙ›+ d°;kLd pBx+U—ùPϤ’áüÙðdVólÆ$LÔ&6×¾’$úhWnó÷¾Eu™ß«ì'‡¾{ÇG*Úü§¯†Óm”H¿bqkˆéR¡ù—‘LH4Nö0OGÓ«†ºçÃKüv IU‘yC3&ý¾ó]c·Á«CM±—Ü·þ"B!±ë°Æ,Ôlñü¯Iülèæ”lò<(Ëà´Sìì`ž˜÷lYÃÍ‚f–fÑŸ³[d>¿Ãe~ iŽ{Qž·> VjƱ†¦»MîŸq§x˜Vc­%©ƒ›,Oÿ.’ù5¹sûˆ¡×+xòú„¿Ôiôñ'|§>ˆMÿ4ƒ&êÃ~ø½š“V¹µÐ4:F›{>fZƒïýº³ºdRõêA±¬u¦ÚÌja¦aö›%Tû=ùtžf gKGƒT’xW#Šy ìNLîbÖ›ŽÈ¦4éSx…­ÅGú‚µF-"5VùŠUj©T™„Þѯp1è‹8Úrf&›ìæš„\­åBe¶|«Gh3º7¼TxÐÃÜ]Tø$Ûèù­^4OâLDŠ*€´ôÜñÆŠð‚ö_0(KQ¶ÆFøL›X ×Þ”Á€×Û”:M{ˆU×¥ŠQÚ¢[ÎÓF÷^Ã߬¢á¦éØ×ˆq\î?‡NëK/¥]: 4]ÿ Èú[“<ÞL¡+Õ[×9k ‹a­ŒV6¤·*\]ä3·¼=M†\½ÕÆ~³x8Ã#Ã^e1TÖ€³RÞ *%#¨¼_Íp¬ÁŠ’tòždê^È@‘,íˆ×îéR_¡4®¬M|•)Uà›ÇÀ03TÔ„%ÉÏðÍá}ß¹T9˜üm¼A%Œ€ÃŒŒ\ xXøQ™ã·Æ×ÄùÜ/†ï•ã.‡]±ó±Ý_°¥X6ùçªR‘M8½oný‚ë Ue†¤jùRu€ÛÉ´é dƒ{Ø‚aàfïq&¨8ãçæèš©T8­1Ê[D2ȯ)é/fháw`!`®+²!…þ¡Ö¨åD!4­­……²4ÃòË.™[¢?®•K+j3á©RFžÈ;ï¸I•ªV÷¤z u"1ëJvM ¸Ó&Õ6M¿ù\Þ¼PM“ðäa;ð§­Ä!šZZŸdéÖØÇ k*Õ#CZw@«†³•«”¸RBÍi¸­[’¹Ø³@êÀmû@!Ð93…R”÷|×dèñùšï:`©¼ê|PD镆`½òIŽÇ á½ì0„7χ‚õŽÀòpÇí_]oŸ”]†¥·¹ÇãX¡|-¯{à/ªÓãDZ š ÝQ¬o(è66¥Ã5¾(H,q'8—UðTö/k8^í½0½¢!w¶ƒÕú#Óõ™[éÎ*C«™¢52qޝ‚.Cm¾ ˜*Ø ”2ŒXBòm¿Ë5•ïoòyâ%€ªhDºþ{áõLÍŽ!#î­ûž”HÈÿ3à Î7él &lŸÅà 2!¦Á[®/’øt·å»ÖjñuRXÍÏ"šˆiS™¾i»m¸ÄMâ»îÚ‚™æ²œÀ+}šŒ²‹¹ ®8Gðƒm'Àp8h|?½Ÿ¸Õ~@L½Ò>jC øçÄ*0Í.ñ÷Àrvཡ䥞–íŒîù%YvHÁPf”m7᜗º¦Ü+œ²¥“Å*r)òïcÜ•ä±Rèeq ÁLoißz1?¬ºb¦68}™X_ôR àwZÃi?pžCQç9ÊÀÞE?©8·è¼àX£ªáãñáŸö°¶?‘øÝ/è92ÊÒ¯‚w$ ›„Ó€c49˜8xõ@5ÈÕŽqbesÚÃGè_”ëæÐ–ý¡2º™\è÷òùv90Ÿç»øÿÀ^S­„û}0”>ÈFt—Ê¡Èõܼ“O¼.|ƒúŒåÝfÝÙțhIt†è8 0N›P´÷"f{ª´¥,¶ “˜2Ѩ/3SžÞe³?–ÍX‹’ÐØŠb>˜2'UüN‡½ìdIq;z=‚yqß5½íõ1¡oþæ"nÀYù©Ú2Ý…:üéè¬÷ÝþÑñ³“CFjßíŸí׊ã7ÛaÊCˆTKï<Ë5@X­mbÉfmY[ÑÀ<·±Íœxx ­Ö6©|³­ÛûŸï»ÄòHïõÜLë„K `з­uø³\'FUdR‹Žû@3ÿV!T\H¹ÉÓÑMz›³ûoJî2-ºp8°/²qÿ–aš>s*«ìc(¾ËijüŸ¸ÈÓtñ Ýqx[÷Np(·q+r8"nU-(þ§©D hÝ9>×{tíqoÜ~Ò!X x¡à…C[üôÙÁÁáé©UPé¼ £ ·§ý:'ûð„r:a0ãì†kèM`ÛÀ­ì4Ür<Ñöu ï9õøU 3AYxb ™þ×A+~~UåBye,¼Àñ)Ó™Št5Z²ðaêRÄéÛÁ±\ùq¿…øWeà%=}S 'Óº–›/:l†³ êôA¾w'SÁgšx /n Å:¿u?ŽxÉ&'q··þb7|d¯'¥èëvé¥fKÓ¢Ü3‹„¢\€ò×pAþR´2¸ 4Û «eŽÓ5í‘ùJtøúkèŽ(¢ë5ŸCÁö΋’P[¬ÝVí‰áQÝ ï\d¼+Š=ú¾xÙnw ÿàí¦Ÿù¿·Ý>r9"Aoë8N¡M÷)û;Q´–I-ôšÔøê™‡`8¯äñ´Ù¤(žÇ“¹d‚”§1c8ϳÑUdÀoÛ…¥Îf°Rð_•™˜ÚÁ“G§OjÆáرÈKÅèÝ|›<9•H•£Çß=I^?H^w7ðS“/&§pñð1t‰WÞ¥àßgs©tøfów¯ÝWØäS11 P‡6zO÷Ͼ{ròˆá…zÏÌýOLdÿz@žåÈ¢ÊÈ;ð³Æ3wÇ!Kè®Kqš·¢yÌŽpÙ2ÉN”°‘4ħ&–Lë”<÷){†ÁÒ$Éû0r23¯5øÞ¸Ÿ¡ä—÷ÚU–§xuòÄÉ¿ˆ9²øËî¼Án±ðßZ#ÙD+\ñÆŸÔ­Æ×&*»Ó*q^ ¬Ì%-Z;9¥d”,=XCÝôÍÃ$X×Cü*…µq´~`NÅ2<Ѷ rÑ|1#ìTž-Î ÉB<µ÷äÙ8ËûéÃSÝBÔ¶«; |!uh8ã„_ÙÅLq*}éÜOH)íµ’¼0d Mëq=%ÏN¹tÒÍycu8‘±™i’)×ú°:÷·Æ_ìØ›äºa[I½vÐvr-lÐxÝJ›cUõ`bzö׉ÉDÕíòƒ®ûDŸáCô P 1LÒÚÓ~´Ü;øaÿä4©ukÝnÒ½woþwþ÷%üï+øßïá€ÿý±{oçüÞïÀûx¿ïwàý¼ß÷÷áý}xÞ߇÷÷áý}xÞ߇÷_Âû/áý—ðþKxÿ%¼ÿÞ ï¿üc­Ð¿ýƒCíÝ?¹g_]±â*Þühyº°°Œã~2TÏ8Hs«ÕâóJè&Ùª)þœ|ˆ)ôƒ…€Ó³¾ZûGˆ¸á ^8NýŠ…¾"ÞŸ.„Ø J‡é&èð.ùJè]âþ\t³„*ìù êÈ0ü’"pÄ-¦ZÑ‘@Y—¡ÇM]³n4&MLÏg¯´­VìD4Cg”99¥ Gï-iÈlݦ£Q­¸Üê%‚#ÀãqC +-1x Þ(vRø û7ÐBôø«Îóé2pól`B¿‡Äè3œw4bzàš_|ñÀ¸_äÌV¸ÁVŽ£!N7ÉÉgÂ÷ÀÀ>à>•¾+2­T ª"]ûbÏëÕ޽Çë‚ßFŠ@NM§˜˜ßcƒ£ÈÒ1G»„¼¹Žê@¨616×çk°5ýâ‹„&ìW[öQð¶ÞßÙW€¾ö÷¤8ÉßQn‚í¶º’hGaY<ÏyÞÿÍVÐŒ½0"Çß'T8 0Þ@t%ж5üÓ§=áÊûÆ7¿¬ñ×ÒND{Ï!ô{Ö×ÏQJðò>êiïÊb®$Rж•\à f¡u ÙàZèNŒ&/Âô™Õ|ûçîf§ûöÿÑ}ßm¯­ns»»Ó­vïoW¯à}wó9ð /ði·»³} êðëx›ßýÜ¿€*­mÔÝ/à^ʽSkAŸlO«—Õ‡Òñøß3 çîLvl¿A¶¼7Dìò9KºÉþÉ÷˜úu¶ ÛþT .„QK-d›‡ öö p9jâ‘¿‚Hµ¬mIìSÆ "XÖ¦$ât)A[œ¿OX¾sï——&{k $µÐŸàEç¦zo†ŸÃà+ù|ÐKχðô³ÏlþˆZröÃÑiWrúìqrpìwvx’ÔÑW{¨â%‚ ù·äð§§û>üì3JKÿ:›a†'.=K.Fé%¦‘!Ó¹ÿí‘É= ’Éo’åa–Kè˜&”è$û´_9A2i!¥ä‚°7X¬I~úé»ãýïOÎÞ݊ɯGfÓBãÌ=Ü»Lj[ﶺIZÝ>ëù½ö¼ ÿtx¥¿{P ÿæÍWTÞ{<ÂEÂçªMâ~.òÌôuo<ñs¼.+ g1’Ö.²M€è™ûtù¼8A9»§Bø¼³¹>õéÍ—÷·–%þ¤,r¼ä°UsFäð(ê¥QÁåWä5È´ ™ Œ)fÈ}‚˜`þd:Ñ”BN s5‡ÿaË$aX„ã· …tŒš—žüàv $á®?Ms:þÙ›ù,5Màn¦¢a?i0ùpüzÂ9;¦(ÏôP@&_^\ZóŸî‚d MÍcID=7™®§³ ÌÐun3H2Žg8Ÿá)0m)˜ O#­«£²Ô‰˜3bƱ Fу kÚ ÿTýé5• &äÁÜéÀÃCOnZNÚ=‘¦‘öxÒ¶_Œ½,æ´Òðt#iéû0¹˜Ü"›á¢ÙáàP•%Ýf]ô+¿fƒ–#IÃnë „ó_8.fo®,i’j.4±ïÕÇ“±àyQlQOèÈ^MÞ$õoXŒW>™ŽP_z5)wϯà<ÓbG2(<|˜û?˜Œ½ÂÃA6ÅàüÊS­Æ)zzƒÛqz=ìOeCîEžõfÙeö†ß\jf3ÜÉùßu‚æv/`³È7ÆEjÔ'¶T˜GTUË” ´p P.U)Ãê'‹¼Gƒs;„†9ãSÒ£È'àÍh’öˆUÐ'¯M­×°Í÷Äks”Á—?ìZ¾q~.ëÚÝ“6r\þ¾Bt°^ž^˜A¿Æd;{ö×k@ôõM–¾êÙ C÷3äxÞê7£¶÷¤j8Vh Æ;J]wÏ¥&”úÑ’0‚4kóÌ´Üä‹3BT‘l38£ýhRïÆ“îÖýl»90öJ'•ó3Ä·¤´0=%%8¾â´S˜õŸœLz íÅù‰jšê†rÊÍ£¶•æÕªnuÂ-Ó s,Gµbrš¶awÉ`á†.üÖVdnl ‰©œ!UœÊMÂ<°Ñب Ží? eõ“Mˆç×C$eÆY‡k„¦–Í3KÙÇä³êóἉ"°¿‹¡ÛC”]úõÁh2ÍÆ=¢uç©`›Œ%¼,*ŒC›úT?ê#ûþj}¢[;èU¸ºÿä.:ÓF·k¥¸xûÛšª…ûÚ\Ïš4—ÒÆe$Çqþ<:+xåP"hN÷Äù¶hé›NÕ¤ÿ¤Ñãgå]-=¼Œ€Mæ­éš|û{T‡Î&‹Ë«ÐÂdp$ùµòI7©0.N"çZ}ˆË9ê' ¡Aš\ß)$á–#Äjø@dÊ_µüBU#Å€õ…£» ¢ô<xŒŠL±VÙr¹œ7šn¼™Ÿ‰¯gE¹56 Øu¬Š×.6`6S%|Dd‰I4íg·¿E‘î›'ÏΞ>;û¦ °°¬Ù¢…o3“Aß~§[6<\£ ª /òβ!T½.71|ŠË&™d#áÛÞ*Û•(J·aóVÂU‹ÌÂéß¡¦ç›Z±tl"‚âÊ0ì⟤ó/ `ª;£Å¿Îh‚yæå¾e|ZìvžQLõ LwGT›ý¬éCX't©0w`W+ËÛæ/7zCŸw£$ÈYUBÛ :a‰:ãmC¯+æ[”=Hê ]5|€C1W6kÁ´Ño†¾tÜî¶Ñ¢µ„‰M¡Ç~a3¥^ù5»ÉW…œÉ7S8|~]¡¦µe2ÈLV‚gÌa³8:¡&‡Œ ,f¥¬-=×Òf»#]~|%}¸˜Ÿ‰0:M{¸Ñw*¨ t×ÅÔ-Ô©‘PެWŽÉ‘éLÑ¥„´ÿôrňÍÎb•Ö‘÷˜! ä¿•³u=½¾¦ªÉÁ(Exa]3„¨:>þë#Õ2µ•µâ 2æýt6@E"7ÑhSƒ /¿"“¾b0‘ ›ù<›v–v©5ºzû¼–nF÷<åék4e\š'íCJ9°Eak"ËûõÞµºÖ©½^lR݈œ7m‡îìáÈ$E`V`8Ò¿á¶Ñ;¾C™M(å(¢SµÅ0~Œ´?™¸$ÑÞÀàšÑ-§ÕU•V¶æêÙ(E ÀbŒ‚`oLGÅʵ/ëKº ð#zø :ôàRÀCž²Þ—“’ ÓáÜ>‡ËíPByÚ¾ö­ÿ¥ º¶3)tJüîw±A;f\I„æˆHGˆ¶äù6¹Ð[œÉœS†Ê =G¯•$_œÛèoã:£ìTGçÊP³BþjÛð?lî .·ˆ2~Μш> í gƒœÙpâöˆ@Ã…[ÉMTn‡ª9«YÇ~8­W5Š}ù Mu±LúÔ2zß2j‰ß^长 Þ•C_ñQÞå˜/Ø?¬Ð„íÏÝ@•æ\4¢ª•.«ãÐ^òïÌŠ¤ÿ`øÃáÁ_T,'hcABuR B\Ñ)í$IûIž§×i0Óålް¢O…=¥• @¤¼eö€W–_óÅ9´3h{¿Ÿ<=:ðÚ TˆÅš#Zæl#{^OÆm¿Ñâî.?°¸ÃšÅ»Üh‡ èx€—ÐØëjaøÊ§!踷¤‚WNɼµ¦É z+ëT©˜½md;Ûe‡Š7/ZèØó²#åi@ÊÍ,JÌo?Ã&Žø†¹ëÌ({iŽçFò} 5ÍN’b¾æÓd0»mÏcÙ1u`zð“7yûc}z,}.£ÈI²”&KíÑäþDo·(-ÕTÛ¦´¶Qº/£%סžC·½ä o>ào–ÃèLã+–_Í÷ˆ%äêýÖ”‚žÌ˜X\q¼´‰7ý>à í¸v9"k%J¹X1óÉåê«x»Å•-Xƒô¢ù?³{Ÿv‚oFw„[gÕ8ܲáPøà‹š>Ž.MPº[[¡LQ}>žÔ>øš`U0«…’vþ3œg¸Z×(Ä©¢£¨½Œ\@H{É‘»Ì1Èæ˜±¶³Æô>ºÎÞüýîV ~9:=ÛÝ¢h£öñã'»[¦Lì“„îj™Ú<˜ £»07‹ZM8@‰ £Ô>Öa#;õ‚þ³µ»eÌñèÖ»ì÷·­Zx<ÙF­ðp6|ƒl˜ýc «X}]B¯å¬Á6:ùÇøQVÆÍgÃ) ;íãZÒhÉÅRý²&ªÙAZص…nÞÞže¿,†¡%á`çÙü&ËÆI£},qsõFm•¨@ì/qi¤‰Ãº¬6âýëA—'£×ˆG–Ï&“y阪+âuŒðµ”õæ €b4®úr¶›×ZÀo¾ìPý5äÌÂänUquŸ\Œ^vË&Dt•ƒŒ£°3Û;+ùª³ßâ9f5>µ잘Íýei„5ò!µ¬´È%Ãшƒ¯h«²+Žv„Ìx ŒÅÝçEH£“g³×™–d û1zs¢7òh1À˜DÔ‘ Ù˜æÏ?NSÙÀ“½r‹Çô—㉨¢O š»ŽtØ4ֈ̳¥ãÈ+{FLÝ/ë‡?<Ñ}%Žé|kºUßÚ†R[—fÚvƒìÌj-®íbý]+,íî6§A, ’d dtŠ%ÜRÍŸ®Uß¶ãYÞ[n½žØòµˆá²œ|޶šî;êÛKÕÜùðø:v׌…wXëól’»‹-¯Òá«…Êït?æ¤ó;™Üœ49ÀcxÓ ^Ä›ižä‹þUs‰õY¶Û¿Tò…Øäi+ý0,!(óÅ,Ëœ?³ôr2¾Ýš©a¿´]}8¡»\‰ô©Ÿ 瞢FŸâÁÊßù N΀àå“雀w:ÏïíÜaúr"¥`nð¦s–a(ËÂæŸ²¼ÃJ4ø†qYÏ"¼|%óþäËÎý׿׾Âß¿ý;c("ä{¯×ŸßN³šØ'¯¿êÜ_ܘýŒOÌ÷1ñÌ ^ÿ~|öøè'§G¬Lb6›ç¼Š2WýÉ ¯¿v‚ÁøÑ“•ò3ÛÉ»CŸ™X_¬Õ›EÎtx¤?v»Fw+|™/: A@á­=åÓÊÛÕ ‚Ç`˜ ø-WBåÔlO|9ýQV{¡¤øü–ŠU’i —5¡Ý…u³Q‚±s/(ÿœa\ȈŸÞb¬ ð*_|aÚè1gÀ*8=ãË‘¡Hþmt_#_&xn#=ÒaäïbëmB%%ùÚû²¸“Gá&œ$m;ÔlôŽj¾k…;y×nËoMž‹Šžîµ˜ýõX}Z£,+[ èⵇwíWüÛ»ö_ô—ið jóom4ÿ»É ½k›÷¸Á¯§ïÚúÿ÷Æ<Äÿü’_O÷¶~û)žµ<"a•8ñÙ†¥ Y6q ¿p RðgŽIÑCÞ-PÒÆxÒ¾HAd–ðœVøÓF(­g«|6Óø5…L' æ”Uà*í¿Â¸+Œd’ˆTŽ_%ï$‘ýNn:®«(‡Ô„xiV´kkÄØ˜œˆC9ªZ•žqOo8c'cÕðr<Áïb›4 µb%3'À¤pÆj+åZáä«ã†ˆ KÊ­ác¡Š­¯ç9.°Oʪ¸Ö/®bž”Ui²HH¢óF_mÒ¿u•öme%M[;Õ‘?Ë ‹Õ‹‹â%O´Ð›¥¥"êFû¤áª?¬ T|BùÏQþ8]Ù“ž¨œH}A8,¾eʺåÊÐnÆ+ÿžíl‹ÅWC0KmfF*^²ùMä Ó†Êñ¾o›`€ÌdYA%ë¥>šLз¯¤]±½ÑVà¿ÊŠ®ˆ®‰ôLƒVôŒ6 ©Û5¯.HÂò‚䆸6aÕÁp`Òò¦ä¾«AÈiÉ3:âÝg:‰Õoäúž©}ŽPKŒN7³ pD ùJŒÑÀ.¤ˆs’æôñ‡ÃË!âç>ÃTH”÷~*›j‡MÀ*'x¬\¹.„6Æ’é"Q`ÙŠòvÔð"ÒÊ¿ÉfUõm n(<%ZúÇ~+J"à¹G$8À´ä8RX^…†Pìè»Ó üg¯-O8ä·N¬Ñ5N¾¯kH!65L?³<öc¥Arievâð{Z˜«$œ¨Òyrç}T2ï£ÿ=ó~3ú¸©¿[ýý'-ÜO޹~-‘ä'c@çâügYჃ ¸z8”É™íëü²ÇÉš'ùEÒïVŸë‹‡aUJ°ŠßH¾£™ù›Q0˜ 2Ì% Ò)úŽ’ò„CïÚ~þá«tj8Í ¤B<¯Æ”–å_¡Z€°Ô |úý‘Ù2¶‘™…¹Ø2¼ö¯r'³m¼A™vMfo8ýíÞÖÒŽ,ÆÅF¾x¸ |ñðá–³¤‘žF:òËV¢ÔÀ”“¼V?úöQ¤þ5Žaþü«ß¿ _Þä}˜ñ-Oœoó䈗7øýÁmã»mbc¼ôÕ…6Q¶ÕÌå­!¼HY:²MM¡S¸¹Ûí>¦n%è÷ö¬ 2Îí-¼‹ðW¶ˆwæ¾Ö÷dNvŽ-ÂW†G‰yTRõòŸ þAÁòédŒO²ž›OÍA`Ë?Ìæ#ä¦8BIlwCÆÀ¾¶­¨6ÄmëÂ1ûˆOµ­ðWêÿs1šOèçÍÕd:£ß€…jóaoOG‹K Ü8|Ò&—4ø]ÿ‘ú}À΃Á`=z;Ÿ€ÝóK Nÿ ['+â>°¸‹“އóá?2§6Ÿlã×$…1Î^:Ì0Sµ–× à%ï¼³üNOå;{(ßá!{‡g쨺õÎègdÛ¿3»þ]{ ÿùÎn¾wÎÞ{×þnëÝ7X|ŠŸ°Ëæ´ø^\ÂÿhaÞ麼‹,Ë»âF}gfÖiQVæ;u–3ûºìµ±B—+[ªRZÒp¨È²K®%}à\gÿåŒW•Ë Š£fùeöf*ʉd7it¶º›ð¦Ûl¼Tu³Ý¡É“Óíû¢Gý¯7oÞ8h/ôÊ’9 ’b/.¤VR_â±ö1 ¡?jû¿ÄoD¯ÿ¢Ótb ö¡èXZ˜[u€1°3ì²Á@½§ˆZNˆ4>àUƒÄÌ0JöÆa­±ó†>sPöa£OFÍÀŸhû;_Þê “9ËÀ^ü‚ ±p—M=Çù3n+£‰4°4èìÃÂÍÖ 4ó¼ç«E÷ø*/{$ÖLµ*A°ÙÒà ñV_nf‹”Æ›EДĝ,õâXq&q9wŠqXâ°<ÂaÙ¸Ýø»äÐÁ_sv‡°çOu¶V¼™ÆIùVD'Šå#ÃË ÞŽ~P…l‚»Æ–Ý-†~etÙª(òH‰FîŒ!ˆ0‹`\DC]LX”…¤Y#Af.ŠÁŠ(³ÙÕëÅ™éÈKÍÂYX7’ç£BÍœ ä0ÖÌî?ëŸw§p3®p‡x³ØdztçÂ18ìÃzÑf4­±p3Ôhñ*j¼ŠÇB΢´´<æ¬t“Æ‹®{ï¾Ë=׌8³>Ÿ/å /4V¡Î ŸC²°zË&W¥œe2Ї¥>©¾ëí’{íÃÜøVá n¾C‚ªøÖbœ[l‰“«úáÂ¥,»&ØV²¼KâÂé•{W¬Ý±<+4d—iy+e®ìq®ÝžZYhZågc„¦{ ûÉùý‘CQ(ˆQxÕc3¬=La†¯²ù°OL³À÷k¨†Éç¿‚{t>^iQAÐo#tð¼±Î|@Êòùp¾Ò§X˜# oA†r9úOçèa˜ ,åpǦéŒòà¢1®à… Ÿ® ¡Åôæ* ‚#jÔ%rI}ÊÕqÁÅ’0§åôM´6ÿ%ÉÝ=<)¾ˆOK‰KØ-¯aˆ¬¯òX{j‘#HQ î¸ivú Ü}œJB¤ J¢t— <„Ã`n? úˆHrÕ±SŒçP\¯œ+aËuÓCÛÅ^]þòçŸæ×À¨ö`ùüIÝ0БŽ×x‚NlÆõëº+A/é‘8H*rmTZØæVé}¬i·®»A7$ƒ”+˜3àNÉ+xJº¯ugê]/Ht¸% •u ¿Å+G¬ µZ³ŒœÝN¨ÚAŒ)³ ©µpÙ0L¤eG‹Í[b4!ô8Õ29Ïÿî”J7n}ç1&F:dÍnQb½äÔ/Œ!N÷¢&îTý¤ ’ÚÉà+‘0´ê;r8§ãIâå <ìeÞƒŠ,n¼°«.ÊõŒá¤2ÆiÒ¼~–lfËNÒ¥ð¿süÙ4ȳü ")ò5R¥‡©„¹ô‹)ò—¹‡žˆ¯nÌ4D®7.÷§!1kÅ(Ý8d¤['èTºŠßÝ“P\\6ŸªÒœÓ½ŠƒH¸ßV±FÀÔ§Lö<ÍJôíFîÂúÁ;sOÔ9˜{œYù iÄ4,~õ³W³§œ(æ„v²ÜRW˜a˜öe‰ uŒiF‚þÐ}SªQ.Ëfdž3÷ð3´^{Á‚š{fðgÚ[`Ü"nKîpì0Ô9A¶ƒ÷iãÄŠ;ÃkjõþðZ»~Ñ«©ÁæŠL²2ù8»ÑÙ¿íyÏ£w"2Ë@lqî'”' #ý&kÌ,Î&z†º&Z‹lïmXbŠ4Õñª·×­F½‚:ìAG;E‰VqU3ýÖä ¡ƒy·ïÕè=1¯&,C†U®«(W·Ò“·eêRR?—`}ðEaOð5D„lp0_a,»üø;šµGê¾Ç–šMP1ì§}³¦0Ú9fá1Èðü‡E†÷ç*Ç>s‹ófožÄ­dߨk…Î&¦• 3I…ÚÍB®¶®å>ÒRÎ0F1§5Q²Ow4§ K0u„Ì[§}Œ<;­RnQ:¦ô†tÁùd½@å`?Ã!¾Œ…9o4Ç¥Ð-꺻6 ¸]ŠøK‘27”Í‚!ó9ûg0µÖÏ 5 ÿÈ1›Ã-.†o°{œÖyšÍF·Æ˜5¿žº«]~+Vü²ošÔ§Æ}IK¹/- ºÃÔ°5‡ŠámÑþY2…üUýbÅ#fýÓOc»3Ÿ˜·‚ ¨A"íË™fbE<0/–ßcËt”½iË“Ï>>úôóš±ÙÔ~bp 8`fFQçýRN¥¾¸²\‹~D&Úºe®ú‘d"WüTwkÏÍ•6|â™óþ1›§@ï6’#òî'ŹëÃKþÓá=£×\QG+ž;ûZ7¨9w¹D‹×Åj…OÄé3žŠˆªÆ¶S|Yó‘¯ìmzJÿ±Y öÐMQPt0‘",ÆÇåYv­ÖÓ8¸3wswþæîN*dÉÒ|ú•qÉlñ¦'E|Nè–‹$ò?O\5ƒÿg˜Ãã­¦+œZõaEµ‡ëLͩ̌xTÄ@ùÀrŠÇEN±Tö.d+¸³5|FTC)êHw_øs$ùYy:ýyÓ³¥m­Ò´íR‰ß‚*‡Òÿù«è©°)çx])Çêg€âéQ*:$‡ÇpòNB±Lè_aUKa>vîVÃòù³ ç QêJ@¾X'rf¢ãá/ Ï¢³-Ûú_Š–íàá…hÙË7|™˜éJgË™QâÑVL7i×9ÿ«Nhñ]A›7’c“Î$ò•$³9»Sy9CуÂ4YqÔâÅžj^ve©…ºPtB¹ãkíHûåt¡T¬¹rÀì¥Hû•Ýv¡e–z} é]gó«É€/ÐëtÎÇ„#JŽEIÝæÉ`q}}¯ø@(bQ¯º`îsÐT-Z·–웤»ÙÙê61 ¯;;Ê©ÛÉàþ×Ûƒìõöx1)^âν_r“Ó’%õÃïOŸB«‘¾Ô’¯SÝãúÝ ÛµŒ0Ýþ¸ízŒÐS)–Œ'ïB‘Ø)i¾•õ¯PØØÇ­­­äG¦Ž»fç‘»—˜Öø’¤—H%È¢Só[ ’Ž;‚2ʺºË>ÃZ«¯LM–ôõŒ²§›äóä>j» D][&a[ãVŽ8ƒüÓiz> ç·&;YÖtéb>¹NÕéRROP21¿It¡¡·äïhuó$ùæíˆ ¦D\R+1„‡ß˜L¾ ±â?'-¶$û;V0’Ø”À°5¿-ÇA” Ã@ܲqN9Ñ”Øñ†d4NDž\#îîh˜…mÒ 18øßÑm( 2°r#õÑÑDn¨þèÔB]NR¸ ☄¾Œ&ü³ÿeÌS”`Àfka®#ºì|ŸªOqAYÏírkd! È7œ˜@‘BBL •r"IÊ¢­ÂH"AœK¤j«‘™Ôwéà͇´eÛˆFJÝ›<‚Õà·ö }‹wl™h¬» m=&v˲4Û®½–«Õ kS-@½*yY:šzÓ JtÈUÒÀŠ \µÅ˜È,iÈ'µ»Æ‰Q…(ѽ•^•ŒHã5 Ä(Ñ.Q ¢qžLj¿ßsÌõ{dýúô‹§[õ«qõÀ^µbb©Üp ëWD÷!Þ8@~: ‰¼Œ¯…õ~ß 7ŽõÅUÓ0â=í´Õ"Dn¢äP»Á)?é%#*yo “ŽRA̳ë錴hu(ÜT¢p#Zc¶Áã G½fó€¬6©áÖ¨Á/Œ­çÝŸ2‡Æ _Hɼ4ì’F,@ö¶Ó³îæóŸ“ú à·»;n×¶/;›IʾJÊñò>Y ޲ækW2‹^þÑš§Rݺ‹bª´ÑZÜ0T*TéDIìîL¬;«Ÿ'îÜï|N“¼¾CO²†K–|[jI5VÖ¢öAòÞÙlf_2 Š%áVR"¬&D#RÓ»·L¹*'N\ÅH4# C´C]Óqxpyˆá…2M‹2ô¾hµñn½•!î´®Jï8Я¿Ú@ô:ïª(ì–ò§ŠéÀHÑýD“¯ÛʘÁGì<.é©XßÞµ>ž.ã„´¾ãÎ:ŠÈ•nåªæÖ>¸9¨?ȹ¼âJ¤N¶?§ç[>‹cSz<êŽá2…ðþì‘ZŒÅ¢LVì›·G•øjû^¢†Üx's3K¶i‘;ì—Çî?ÞÍånʼnxëÛ…ñĵ3°Lt‚|3[Âk‹·êæîö •öÉ7ašʵ͸l•¶Fþ-P *´4ÅÑݨ‘½»¾®rKŠÄMS«(-ŽuW>ßU».Õò&„Æp=—ˆU>H™pEÃpœ" Â~µµ†œ¥ 8âVLÊJÐ"} Þh†v±ÓJ¬UHæ¨Ë9Í£F®4Oªf35éçäú<¡8±Á6¾‚Ó+ cZîߘJ# fª¸ƒ™/)ZJxB«kÓŰjöDæàâ^Ž yÅi‚èw/Q·×Lñ%.awËD­5j±†p6ð—!®64FœÄ3ûØ‚ ƒa¡—WXèzxy‡>5‰îÃq»öh=WyFé’˜Qʨ§â*JI¯SØa\ùë(9ÁêáP²ìÒÔ0åÕg"=[xf&%Û†Úèß wi¶#$2œÚ@ÈFj‡©×(dæÌ¤’²Q‚}^|ìØÏ|i.î·}Í‹äMÕU:ôá~îÍ*?I¬Ô„3é³P4‹kΠʬ6Õ"›"葜·bH6ˆ¢¥Í9‹Í¨;’~ø¯?q  –Õì%4÷¡™’¶W÷­ÝTÕÊ2§Î5¯b ø°DÉXëKç_*~è1 ±¿=5˜'ÉRV ò -ä«MЂ ïÚA"Ž,X‹e¶ÏõX-|b}ßÕBÕµ½X=íÌmr† P¥6ö=.ŸV…(2LŽB­Ä¶¾ÚGÏ2˜ešcU8ù]ÔE«ÐóÃRUR¶‘UA­¯q—5èÉ®œêic×ÕÅÂø4§òšŽ“Éz&ŸÂ…²qÇØHgöZ0,&"§“ðg£ö¯û³úá¾öã*:† %¡,Øâ“Ùv*™/,7x¿iéó_©PwÃrB­z,çªõx,ÄZºuÁB³Û9¦Â2Š{D%UÀ§kPLïÆ ªÁA~«:îRµsª5w¹Z<Ðs»-”¤ÞûÁcN8—Ùx®ZŸó‡­³J ÒºyJŽ‚Û‹ï™{'Ç\%:ØxoææGæM&É»w—š}måÄV(Ûl:M?”ÍÁp=}5œzpj¹G¸1NŒÙ²R A”z £ÛŒ(mÕ“j T˜Ÿ½‘ÆQâ¥*'SïìЭ¹´…ÂÔ…-˜dìqç̈ÇۆĜÓò!^">¦H…1š0ŒñzƒòéHKBC;˜¤0µ…K˜Öˆó+ÃpG]xÃývho¼åÊÑ") ã§ô@v$áF/–Ðí›Î 12\žŠ~€"’øP%‡à‰YSKµLžKàö"DÏhFhÁª‘Ícºëð[èÒãðÊ ºOÌ _÷x·Rú[L‚¾L9¿9iÇ›4™N†„?š0$Ê‚¨l3þ°6¹!9à†‡=:ˆzáùPP®ñ§; AqÚ²ùþˆoÞêž‹Ib˜ã•=¶I`GУ1´ê¤MÎÐ-ôWnÌ}&J97ð2¢øfnAó»orj#TË=¤Tïç#L±Ám³XK0mÊÀæžÏˆ¡w’îÖ0Ú(7ò3š½8¬‹T‘XáPõ|/¬¥…(òÜY'ÖܵÙÚ¦ŠGËó‹ D«¨·.;¼¯‡ÄÝ\åÇŸ½Éú r½ùð“Ù”^ÊŠì÷Ç ”|D÷«óÕ.Ä¢´B© ȬQ°7¡Î·(ûý‹ùSÎÀT R ^YâÜC­|/{3Ío¯#¹„;ëbx‰ÌüDr²æΤÌ@"&¢É»Få-‡3á¯èúÌV¶Â;¨I¯^J°’V’7‚Ø[{©=‹OL 0ª›,¹œ` GþT}šÍ.XMz9™ Ð%äÏ'ªyä±íÉK¥"¾`41]*H>pƯ€÷1¹¾­@ã™Õ<>`% WêlHH0‹Ù ýMÚ°µ/3 4ûûD·©ŒEuÀÀ›ÅÅÅðÍ^»NÅJ£¬F™ßõÆØÐR%]Ô‚0E`ŠZ ¶ i&C1y›r `š ef«»{,ôˆà25­°Ä1"¨*àf:בÖL,8º{Áÿ†×Óv\GÕI«A¥µ\¼c˜“@’Ýô,µcÎÂÀÎø ÌÒ§6aÙ- °€>Gc\ͱ»ñ÷‘é&Û["ÈðÖ–5¯¾Z3^ Ä`/®Q-ido†ó¤þçF1N`„VŽË™‘=X2*ÅÙFŸßúÉþrë g9¡‹ŒK†uí)1ô»6®€¬ÌÈ›KøyMÂ~÷P9ÈÂàXh'¤Ìués5ªX•N˜·fý3*ø ŒW:@ %ÑôìÙgÓ!í2Í^òˬ q3¾0}ÆQW¯éëël0ÄÝñÎÍÕ Íq"Q˜f˜G±¨ØÏl£.¾–¬¢œÒÞjçýÉ—û¯ß¹×y~ïþWäl&Ãi×ÕÕL ßæ¯¿ÚZÜÜ_Yê÷Oà"~öøè'¢Îúó†/™ý¾µó¢ó|ç¹»i-–[@‘,²ô,pETvßÐy61ÄYe¦Úð5•{¸™Êž°3œ·HÆA꣈†©Ng£!ú`0Cœ[¨ŸíE>Û>Ž·)Ô²} —Í`Üw‚~“wPº’Ô9Fx7yþó.Œþ|Qµäëxpp æ¸2Çg!'0Km‡¿Ne2Zâíóñh¨¬tÞÇÎIŒ®üÆÝgŸºYâ ‚E FS-lçLMµ¤ózÅnÉ3g&ý”há ºzˆ©b † lI|\e Y£§E0òøQÙÙve‘÷ŽHç ÒñXŒ'¹lyK^ì¶çOUü!½=ªÛ»YO¢é/¸Qÿ›e Ól;Tm<)éeJÚ,K½’.+Ä…6¼ dOQ—R»p* Ÿ-¬Š3µ,Q~¾3¸ÂF“ ½ÃYî¸÷)Ÿ…xJ³Ïu¦›O: ž„§åd0î²çÚ¿]LYõ¦þ‹ó¯Ý|nJyî-ˆ6Ðß evLE!œ²‡hë.Ý7…ÉúM7å€pJúÒY5OlÅZ£<À¨?“`ÆëVsîWkça¨ê9Èúµ€oóó¹#añíÉÜóí2»~»kÉè¦xØ…Ýå¦ÁuuJþÕ¦èü »¯4Úk¨¼‘²\7Þ§H_V÷!øv$JÊßTQU)+¤%,µÎI’=côÁ¦©à~áSm6J¥Lçán­S“eâÉïÆ þ˜œð©Óš%ŒÄJ“†^Î ÂŒ²]Fš0'ÔxFÝåF¹Ó}"É-ñR öCõÆÊ[Å4¥W‹ë@Ïßðhåi°Grʶ¥9ÁZ®<+ÝHEmÈ]bÝÿãÉy£—¥g»»((„VøÌÁŠÒÁEU¾ôöÜøŽ*?ªHaø]g¿¶’ËE–#.{˜Ù “÷¾ÒÍñ‘ÌÇ“p¤>ÿásÈ{, -l™ÂMûa·UÄáÎ\%0±»"ÞÌZH¿Õe¡@ÖCsÙH~ÈØ›?Íóŵàl ˜;¹Hªˆ1€!Uã6ÄBãpO3À¦FÓ@ø]ØéœÓ†ˆÑÅMá%\vy²Ï–i8üé âgKBZ—8rªx|G'NSm…g᫲ñÑl¬ýÙ°^ô»þŽXâánÇ]€Ç¨3Æg¥Þ¡ë’¦9£u±‚%4wBÝ$bhU;צê QEªEÿsA­þ©jf(ÆÏŒ«‹D|nß­/É'ÚŠúkN9Âí²®YÓ÷¶ï„Ü(j…mñXä¦Pаx™ —i»Ÿ¼ÌoõãñËüö>¬S‹3w¢ôò/ûQìišS³s^hÚîF×e¿¯Ð¤XÊçø_±6ÔŠÍš©3šd7#øèh‚Û-w"†hÿM9áÌA¤ašfÚW†U5vœ@Z`â§k­R2/£u¹SXHOw9šœƒ”Ëå{ÓáÔш®Îvà‡É æ£jñŠÞЀh‘iTà ;O022áÏ'jŒ’.ùÈph4‘h0“–±%ñ)ñ5Á@a” &)KÄ8• ÓŸ÷›3Áÿù¶‹Mô˜$§é´¬,•‰~p‘g#à´Ð?ú<õìûÇÏ’s¸Ì`Ù9` Œ ìNl5 8@Ìwê ”jLNå~qpÜ‹dv;jÞik0Œg¤rQSbŸ¯öÀFõC“›@P"|v·}úö窲SÆ]ø¦âÛ'ôí+ŠÏÖK£à²ë_afÎKË9ã,z÷Ê&nŸðžºª¬…—¡LñX ‡¼¥ÀMócD .6|³“o‰zÁð¹¥ T*ކ‡Î[Q$(ÛˆJ^ŠÒëT¨iadá—{ûk$]D$ŹáCçûºÛŠ£’XÕ þ*N ‘½«ýTYîùu÷H)^¾KN¥¡I§Ó!’Bé­‹{êƒâI>,H!ŒBI¼ë…£$ÅwŠK1 äõŸ~´¬9 ªØMó‰‚-–D¿P:”èxK#2ÖHñv·0Uøæœzw0)ŸÞí ìø¢Q6=?†'ôc^}ÊÑó•@Éž#¿sˆ‰by/Ýe…0)~°îy$Õ‹î8“íeIž—¥.š·Mµ&K\è#Æ 'šyÎÐ->pK¹%0}n‹ ¶xèlÂ1vN×ôˆ§M×?[ÈñÄF1Åð­c¦N±Ýóø¡.VçLBäSÅ­9Ș/ ØŠv†ð‹?ûo¾»¾ÝÝÙž6´/ÁìÍš{îþî<2N£“4š¤ÈöÉŒ<4ùŠ/žS W"UÔ?¦Å’ò¶ Í[O&¿Ç€õ'gOž“¿”‡Ý—Þ¼Jo¡3›O’½½ä~3yËòq}çºï¼ßx#ñ¡Hù¤Ÿß;öoI?ÿð•×ÓìªcÚ_žðfÔÜ"ç@¾ðgl`»f¢­X˜^ƒëµ&„ÒM€ä39TÊØ -LpM ':3‚â9)øxÉ) }/ÅÎÐÞ•ð¹¦qC·Œ6ú›¨Ã|5鹸Ž´:qf¨˜2ÊU7›¤æâöy+6ŒŠ•¨8kŸ‰?^ÆÒ)ʽ‹qÐBã€|ÿ‰9-aH¦IZÈ£‹XGï[Ôy.yª"#úÏeMD´’*®ú‡s¯VO«Å‡-ÿ‡BÅš\°æ—‚Rdª écK1Šƒh YÍâÍi9†+X|7ѬrZËâ¦i.Ïv[ ç¥zz÷.yËÂŒ H ®µÂRƒJVæá¹(È…`Çõ¢ w‡”3)1š{FÏn±?Ðå÷w{~Î(}¼w‚’%Ç*¡—”10M𔦠ß&%¬73ö,J]êI¦yNÇ^Õ; ÝZ·ŽEÙOOY™\ªUìâ˜\ñO³A:6`s1ÿPô2aøQÞKNˆÙr”ìªØ 5*æÉ§ùüÖ“C&`ÃHןöûCDŠä(H¯óÙäU6'ï 3O8vEbÌI/¯S¿Çæ†áÀ@˜µÛä"»!}â_YT¯)9‹÷³ÝU@Ëúbö©‚Š0ä?©ŒM˜æ“ñ.iîטÕû¤3Gè,s1°HSßGûJ+ÙTAçvz‰óO­2|â›q¯¹‚˜ 2IÆo8MŸßú8UJ¿[’èC«†&šïêÄ©áÔEÊšô92£OqUPû&Q™³ŒÁ “äÚOgŒ{çäx@­ùáp±p‹RΛÃQ!ÍùÐSUËn4øšö)¤È»lgÇÑÀ:û©%Ш™lN½ío,ªMÏÜ„6«„ÜŒ 8˜„“Y‰ºçÏ.ááG‰¬7×£”höôÖ±¸6ºIos>y¬Yçµ€^8µ³1ÁlÒÙ»1˜O¨3ŸI`›d[¸Î ;ˆÞ:JoÀ7TÄ/Æ™grpÌgÃþ«Ü@„8`ë² ýã¨Õq4ӽ̕Ù?0[ŸèÒ‚ *oŽtÔ ™¼‚’¦lc­CÊ'³â‚ï/ÆV—¬•M+¿^$šÞPËÔ‡Úþ84á”­ƒLR®÷-‚Œ¬ˆ¯»CáІ×F[iÅ®p?²Eà­åƒª†¦Â=yº'‰ÉŠ ÷ºbžíV ÂÁO?Ñ ?O/’ä”·Fü´ÚŒÞ$w5«°óo<"}Y‡o¶ÿšÜÿúw;À²"VÓïyé«d· kÝäffƒ{ùÅÉï;ÿQ-h"søO¿×ÇDßé¹^Á6Eœ—Å|-ÛÝÅ0sÓHÚš†ä9ÍãF5ÀÝ?= .- ÷Îü•OF@gso¨+}/líà Îh=,¦ \oNP“¿4ÿ/ÎdäÍ{»áSÂ=ʦ»rªá8av4fõ2pœ„¢—ÏSBÌRªsh‰tÎܰ\?\ž”ÜJ}q6)Ðs”Ã’ìùxϾK[ >™KZ†5Gôs„¥¢ J*UÁœ ÕÖòLS˜‚*`i’¯:‹¼†—m™UÛW4„=Ê´êÒ¾b¾I|: (çdE”qÀ¼^‚EŸg£ 3éa’U7K3­Ö ä9PÐÔìAÞêÂy¡è±®\]áÇF â,ÉxE1ù±/ÚãÂá¡§Û9E~^.M¡µ7K›;¹KSÀÛ^LÊZïš6–Ù6×çÙì.‘ Q¥ãç×wi‘ƒiÅ %þÔT˜ñ¯qÙ¶”]ýQtZ»¡€zd:m )ù£«å@9RrGjÆý,ø\£P«Eú>9ÿ»ÆÉ‰Þ¿äœæêRnMH¢t]TSq“BH ¸~¼ÿè1·;î9‘. ÄpUyss8Ê`»m½ÐÝk'7^öfN¡íW3øÂh‘ßR…³F¾ûˆÕŠ9oØ+×â®q‹„¬êgÑ@Ÿ!&YÀBÛs¿ ¨!²Qv‰>l(ù54q\x]>Þ)ì‘ìy8ª!´F|& ½brìZ¦Ð\'ÎŒ–Lg’,PE X6¥V‹_6©&˺}Ҷʺ…ª¦(eôC$a§UÍwñ-M•ÂWåKN\ ÆðjIÔ„ÎÅ$š#¾Ë=´ó£N˜Ÿ»Æùv-hR»B_/¬ñµ‘L2í®«ˆ®#Tä’Å“¢) wl‚E 4ÒŸÏ¡C,ܺ£ô1Š8]Ø[­6ôy=¦æó&ÚèNô–dº›†Kj: Ö1Í8±S n5b€ôáïèÒü­ÞK‚u¸ð)j#•-ÍÙ¹Õè9©"œµx“FWôš%@Õâ&j|vIGe+§ÒKõù…y½&õ 9cR¯tf ˆrºMߺ”¤­¹ÜœÚ¾"¹[•pÝÝøèôÔ¼Ï|HñƒeœHIÛŽW%Úež¦3ÁÝV·dìøìšƒh4')Ì9™^†pû}wú ÿ (°svh^’{ø˜ý’y°T]kzÃúc0 ÷¶ƒÕI®Ó1"N¡¡jNZ¸IâÏ­dGíKVLãÏ¡Ãà훘`/q974*kpcÃ`Åeœ¶³¦âGØ9úß͹¦ñ(Ç1 TÐÀh¥É9¦èA…%67Ë®p'éj&#šœ÷‰ä8ØY$Âñ£žï츆c|tßy4Ë^qp{õ/é„(˜ªÅ¬žŽ «Go&É+Lo·X.g?x®¢Xë ¤ «³6uG§R#áh3Àµ³³(L*½Ã&é÷\Ê'4m„}æÄÆäÚΆo¸85z¥ÚyhÈm:À^¦GÜаǪeV¹íÞüvš‰–nCíYó„+v9^lóƒ…«#q8^ÂÐ/R4БF¼Þ]̲ì<´áyGßMò‹wÅôn¿¬é:¬1–’»ÉöoœQ=òdGá•ÈÓ蘒b5»èÁ.p¡ µË)Ãw¿Œß¼#Ô„fða·%;ÆþÜs?‚«…ÃÏç“éâÍ?uœw£y;ÖŽû³ ‰U ädy¸;òߤ2ÛMcÍ2=BMh‡5¼ §PA>¶$þ5žÐ'ÍXéTÛ!Љ¦~é©oœdÏx²´¥ÂÙ 'ˆ½J„º™LizñÜ{÷|§ý/ø¿Ïïù¿Fÿ.Hÿi:9Õ‰ùÕƒg''‡Ï`^äóFA¼®Éxœ] ¿¦Ô2 ÝÎjq¶·ÁÔÑxÎð#×Q-˜.º¡]¿éØOÿztzôä1 ^;ðO=’Üßtàûߘ᳿ñp Ø~»–´/ñWÙw¡TUì*|í’b™flRt/?ìð .LN•³Ÿ?Á $çA:ê/0±‘ÇkÍ dfªÐÿ>Ç;kÏ0á•GשW*‚5«îþÀ§ãíÅvOM¥ÃÖ>¨!sƒš¯ 9D…”!ÊC©ËRñ£X†*˜0;±×‰};^Æì`­Nݽå6’‡4´„ wáøî) útLqÆsDÐ.éÐ Qbº;zËo¢7£¾ûºIz|bO'=&½öÈ¥R~//e‡WÓ)O•}ÇÿHñ ¥Í[ë&·Ö‰d³¾ê ƤƒƒbxÄ8½„ÙŽ„xøUçªøåH4ÅòþýŠ\n¢bRÄÀaÓšîÉvýó`û§Ák xÔæ¯é“Èe%ïŸ bÿ ÌX1Û`i'ó±rz†9d¤®t©ˆ8C°;Cô¢{ækš/ì#-_ÐnµzXZ§×̬վ€róéu”‡”TKܶ£ŒH9;N&Ó=o¡n®ÐíšVäÚä.…jÖÂ[Ã:Áäb1 *‚—rèn}òHk'‚Â˽)©¶Æ´Ðwwík/´g#ù–]DIx'°ÌVÂ5™ê“F§Ñq·½xŠ[½°ËIàk:rä$Èßà‚,úéN¼Cb _s–¬¤Ð§Ù¿Òã»m]gÄÿ„»Ë›µs/Ø£dвðòꢊšùÉb²^Pn¯Ú®™ó{5³ô ØßáÖ0Õòþ䃪ÂßR¢3–ôYŽ:ñFr÷•2âpT[I>D%¥Úo(ãôX2)Xµ0üÿÃ'§É¿w¾$íœæXè¬{V…¶¥ÔyGö)AÉ»£®À—ôG„í(^‚\Pó³AKônèybÒ§‰è|;Aú@«š.êí=¬‚Æ’+Ò‘$Ĺ“S_)‹xîÚ=ؘtìX˜ ’ BCøe¹:.­‡0 Ô‡ƒUÉif˜P'fWÜ)*pìÛ{{1ÝKÀ‹ÅSç±!®„å²Ξ–/˜<5&É´·Xl‰äxyƒ§Wì(cv+4š:š–ôÞi[eݵ«åwÛ+•1Yy„¹x2EýU zÁe1†Ý5Pï<’»hùä¦gJF° \8¢H ŠFñ&=n¡* D8>ÆÆQ豸öÂÙ›Ã(=Ë士ƒÑÙä£K% (â¡™¶¡VÚÈ—1ô¡6àøMÚ¶ëC'Ñw¥*rÇYbhlÑ•J’ØLïÕÇ“àïŠÐ–J£Q' ÌGq{'ƨ^sÝ­ÆBýŒ½j"†?k®‘š÷,*)˜Sôû^hH_Š(nN^œläËY“1 )ÿ=68‹¹†ï¤–XŸ KpÇŸg8Àñ,øâÎxzt Fk˜]nÐ÷ÐXu=uhøU`qÜÂLä Ç!^%å]˜ÐNm NíÝÈ@¾ƒß/û¢1ö<‚C˦ãáò.)3{n•¿Ó› ãdƒð\0yïp²È)tS’lH.F9Ë L)ÌìbžÛYYU¸›ü| ¥ÐÄ÷Út`JÆûÕÙxvJÉm²V˜-ãÍ—ûF»· ÖìŽ@ªozœ+¤þöäÑûYÒu Gœ¦?Ô³j4·¶k·ýl…-ßó½bC7ùR,µ‰³áôl–ŽsrªêŒ&r~àêèÈïp A:¶ììbãíÙÆXç÷kÐam»«©o ›}BÅß?}ú22›‡£áõpŒzQ’2LÍ@"nÜœf‡SD@E×~IfBä¤P% Ws»8Ôj·óÏ%ÞõóäóËÚKÓ”†š&l…Sµ}\VÙó¡uñ€ÖÖhŒEŒÈ™}㻘<"ºârŒã[ÉIQ¢b†¸ëÓ:ÅÓaræúðs¥e+1äÀP8(=ƒ Ó>©Çª»`ËSEÓÝ1Å‘K!Ê=Ð¥5Y—"";üz“&âíäzEŠÛq<²TŽ,‰ØœZÎ ®µ.D=ãtíz\[_lÇe]ãfœZ¾Ãº“ý\[sÓݸ˜`QlẠfq|ôÝ îÏ€ù^ù$xCµþßó·ç^:f?™žlF/çûZƒusįï|·¼³&Ì-&ˆloµ‘ð—ÍLo¾¼¯¿c’(ùõ<›äü»Í!¯Òá«ÅVÓbB¢ÍEÓ2K–öç r@aüÃÄà¤%›iNQrÍÏ<Áš]¥Ó|2¸Õϰ乃YPî¿0_;‘RÉi½GØŽwÊØ‘&¨½&dÉ6—uÃákaÆÙü<Ø‘2G.)7àCKý£FXÝ•v0—ÙhÐÙvˆÍo²A'l$6*ƒå½ó,½œŒ/F·îGIÆ~v´düM®¹†wâÓmüOoVø¢&¯1Ifú“ß¿þƒýÀÆõæ_¯×G%@¡-ÌmÓ¹ÉmÜ”5ú‡æ¥Ñ¿M~û1±3¡§c6›ç<Y>Õ³Ò ö<àÕ9™—]O_`b¼û]Jë+èºlÜÒ½ gfœõA ³€¤ËO{J÷—¤"µû© åÊSŠ\nY-­H–TF•'DÇ}\U˜,;ì™ÞCGº=…6nÐôLþB†x|y,96eyaþ³³<ýpkÚDƒa¶ðï9 Pªü––uñFw{Dn*¯°¾¾E2ÙÉbª+Þ%›Cüqy=ý}S”BLBH÷7Ÿ`È ×ûfØÏð:MüÑ?›áVsU™0b…ĆfX¼Y‘œï‚ú>ÚD=Õ•»éŠåVýåÁAB×1Bž#ûqËæ'Ïì5…ý“ŸÄh8Ÿ0´øôc&/eØü®zã$BVš—½!(Qø>,Ž Ð*À€ZÊ'ùÅ—ÉïðÇW¤;Ô¥ß@\QÄãCd`A­Fšê¨óÄN ÞÏ EYCבàL˜È8“Zw0 qÛã™ê‰M¹éLyJæ°òœÚ)Ð@|)÷C˜«…Ÿƒá%áÄçâJˆ"ˆçÀÜÂ,f q&ÚœÒ4Â<ÔÅWÕ ì¡ Óu`×C‡ãÄonMVA ñ{fb•¬‹‹`³Rãò ná8ÊŸ|i øR =Ç`vÛ›-ÆÈWÖO!csS×éó->O¾vž%úÓá“ïHõ{ä±ÙLÞ¢ûêb6Nî=HÞWåý²¶5§øñÙÁý÷»ãýïO“öÄ”p?Y7+–Âz,WßMñ—o耄E`?‡.ì݈"ȃ  µˆa‰ËƒqJ4–.ÓÔÉ×DÛæ™R Eƒ0 L¨mY`*ìAÐHJ¾[ö\€?µPI|fåniK æMï:ÃÎÌãµ,L›_×qÙö›y yTƒ££ú}™½™ÎPâ3;¢–ì&µÎ–×^í%ñîAù–ÍŸï‚.8›üð,ñR0q9x‚If±Ò~?›Î e nvjN»ŸKü“ƒ‰šøz¨dº¸âØb±=MŸ&.OÃÁæ NŽâÀëìœð Ç´HŠ­æ«,Ї©I¤8ÚŸ\fsEöìo×[AáL3KGÊ÷Õ2p2«ëßHIÁ/è+eW8¿ˆÌ,×q†‰L=OG¯ÅÊ(bQ’A Bá®2¾ˆ–žáÕ6·úH0ÉÅ×ÇÊÿ­éèòK£r‡;cè’³òË¢Rd¿?€v¯E½‹ô{- îÐpCÅ 7È„å´üÎÔüãèùš=NÓ? U_kVÊ^FÛ=êþ‰éû¯FáÿérFÄZü8:O½Òk™Øé±÷é<ÎÁ´ÞG5»'¶sÌ®)î˜Ï€\›Í@îÚ¼C«Ë.ÙHð¡I䬵ªŸzõšóSé6€¶ÿïçaU+‰éÄâ(.N®³°5“zgÇ@‘‘ãÜquÓbô0+ÃmØž?¼qÒŠÉüiqÚ–¶ÄÜÆª8'°$•ÍçÙŒ&ý߬¬Á¨ úq9ì³þ¦@°|Ü­$±5Ù¨¸§d*\«¾“0ªkí¥B¥=¯;†å”L¨‘µ“–\¯ZÇX#W„»ÇTOw¾ûVÞ{xç™ÑèÕW¾ŒÎ й@þÚ auËr~pN.mÃôòN7 ×–³â˜¶%"$áã½—è'€î¿1¦µÉoë¥KHÜÆ¬þŒÏ€·B¨›é'8ïÔ!J‰`þÜ{™_ •´§ÎCüeäB»c=¿Í{ŇWQÜÏ»vÈ»‹¥7¹Óy3ÌQɓНËËì¡1cÁçö‹­ä¾5Û+ƒQsîònU©;Út©žžP¿Ic|#ùnB®1ùä‚é0jÚì–„¯·GÇoÛ¬¹ßö3'í¯“h~ñŠë"jSÄ-)|Hm·:¢Ìk”ܺ’ ½`9Û–S1ÃŒæyÎPž;ÜÂ!Ó™†«½Û sãŒkÃê 9+µM²NsêE™Ru§2}K4ËýÑ$'¼ñoPÛN³Il9uð:Dµ,\M¶(Ý“9å°Sk^9¾»í+žýpæe+ü ¿H›¥NTüÌBow¶pi¶·šX¡òmE¦sKR 8=•*DÉ*ö•1ÆkOÍ·ß=ÿÚ¨¿{×xYsà|/#ðö´ûˆÏ!:ýëA‚˜²ÜL7º…VíÜûEŸ°_G Õ¡&’G ²i¯¸”½BêÓä~¸»e@6Í(~‘1¶,ÆÆ cI”ÏððÄ£ššÝ{Å6˼›~/È_õÉ8ùOÊÃJî½È·?Þ—@áÌ›K“•ðFØKzžÎPµ_s/ÚØïÜÎJݰ—?>yñüçäÅÖö6e_ùø‹Í7n7׈´!±\¸«Âe9Twz}(¦‰¦Ýn˜4ìÑá:O_æwõá»wµ—1 3 N5uX|þY·Ò…yi†‰£mh×8KÖJ³íªG ¤ØÔ¶ÉB *jõCa—' kÒLš½Ihÿaßà-ÅÙl®øÀ‘Ì6½OÛ³?JÙ(¹´yÎð ׂ6Y¸%â¸Eü»‡ì»©cUݺŒY¬ºëyfÜÓöꮟš¬ÚÕ0 Þz.¡„da|BÅ™œˆØ£/¼“˜{¨sн¬J%7ÙŽ8Ž&Û|t#5zŠy„Ð-Iàm7~dƒy¹¡yÏQÈ/n…ŽÅ6J­ÝÛ9˜ñƒsF›`‘„qåÐx¤çHªBvóÏ^lÊf_•<ÌŠ¾*ß·kg ð§Éü¶ú)Ò‡m~tð°ÁO®äj½$àQ é²@¥%‘šš8Ü-PÌîRê%ážaÚp;-gŠg'¸Z¨!†rÜ9M‘ØëŠ{ÛãˆâùaÜyv%‹ÛÞòÄ…&ñÞÏíÁ‡M©'d8ïÔªÑõ)ð-?§^éX% Ð…˜ÕVd·)«‘ ‹«^²V0‘‹‘"”’É,ÒÌ]U5™Óè–@ª3ÊD³æEà¶¢gÓ¡ktÔ™¸Ybæ4™wKy¿öF¯,Ù㕲ím 1Kö¶“]yèD´WÈ¥YØsâøæû¬j‚Þœû0L¡·‘œaÎ rXNÇ—»‡qºµ‹ÉÄ ®€i"9O90½æ¤„¢µj˜=Æ06î]në;å<ä oñ<Š{¿f²E›³p™ÈpÇ&£å”ÔœV/ѵ¸ÒÙ“E_°T|›ÍM+&­±ŸVÃ/‡cŠÓ÷ålý^ÒŽM¨g£¯Êã9ËÒKmÕ4HRSÀ:aXÕJyfÓxÅjÌ1U¿”¯•1Í…*Å$áAò7•¦Ÿ*pIÚ© æÌ©dŒr{»f¥ø \ÊÀÙ`l&)ÿ‘ÅoKèi߉ÞôaÎ !ëi³cS68¬À>ÍdBùH”°8CjL>þ”tÎÄþ툴£Qà".Œˆ¥wŽÁ3Àõ› ÊÓG¸t >ÿ,-i!…¦¯Ød ›¢“dà\=PÙÝúñÃ.®úÍh¯é¨ zDâX]øäµwbéøã{S™—ŠU°ú½™ÉYÊ¿aºUMm,Ȱz—J-MJÖMÕ ìxæg?õ4¡A‰“R<`d–VŸÜ‰“9~UpsE1ú—„1‡*¿p6]å_a¦åS®oƒ‚uÐÅqqm!D%VêulDCù0 =)/j –4Ç–L«ñ»/ÚhEØ©dõ'k¥![DV‚Gé.Ù1ÝZàæf6:RE± Y)ØÝ^ îbŒÅ{pŒƒí'ñÃÓlv²«wr!˜=’ Ы³û®wÜÁÏ:]œçóá|!{Fç` ÛÆBºRójeí#“üîwòýÒҾا'',$SJKc–¯XÍêKW‡Á²sèuŠ|k4JQ@=œFDálÉžŸ¬Ù6ê*X=Ü^5̱¼[óU¡:f·Ó{ ¦zݺû´ñ áP‰7@;N¢2@¾—»7óS¶Kx*™bnž „J9wê*I7êN#Þ™çÎBÈL˜W2æo˜ï3#Þs‹·ü½.&Z¶R‚.‚[0ª»¤vr˜“¯|/'†WÀdÅÀ>±&tGŸ…s41VÞp–øuqM„$êú–÷¼‰¹'¸BúÃueÉT®¶QœOáÒ/½Îˆ%å˜v_iZv\%DD ¤½ÉÄÈe·:ì+ŒYφ}Fsa¥ÖÀ¥)Ñp›µŸlØÜ?%\ÈŠ‘ᯟ»- 5´;iŠðZÎ4‡Á6ýi¤­Ò”6 (É)±¼{Ëʇ«¡ÂÅ>,«>Æ´|ÁUÓK~׊–0 ŒÑ,PåÒÙúGáe€:%^“TùjÖš2¸Í•ĬgÂ!9rÜ„ŒAvÑ‹Í.Ìú[k CÂ0Äh®ÇOÎLÈsšt 6™/;É#Ê>‚¨ˆDæ$^f+²’Ë!ºÒ+:nÜA:OíÂI/Ý|äÙu"˜ÖÙ´_°ì Ì ’¡Ž“¯Ú{‹Ñ9åCχ—5Gy¢9Ðz:ÃÛK…ζíW¬®®†ëf[%µS7ØÙÉh‚®ì”jÃÞId‹ì¢`- ÷î5qž ÌÝaF÷õÞ00°šOy¼K‡PÃ`‹”j¢]²ð@‘½ÙδC_g³sL¥S(>Â(¤*Üi$¨ sG©æYóäËÁ‡„G—7X¸@´ëøu$ùSã¿–!‚’;Äa—ò@YjM¢Ä©½¸%Çpš³r|M8r=œ ºÞ体¬^’ ¥¨h’˜ @'k‘9ÞÇOˆ^/|à¿ë $“¨OÏÑo—½Áþ›³*s’)~9FêwIìÕ5:\AK7_Þ‡ÿ-âÎgÇa—ðB‡ámŽSØ­Yw³”M(?„¿Eê„߬¤™hzõ’O'¦P1ùx¸Á Õkì2…©¾5û|½&‰ð®Ó78U=zd}«ô<Ú£,iï<à“Krƒ#r»0|8䤑½w÷gØd•üÕí*rðö.R×ï‹b…• D{'‡¶9¢–žOÑ(• 2hcp+_ <ƒ>—@WÍŠªííÅá3ñµöÇÝv^ŸÌÇ #ª*Ú~–]õ¶]ŸüôÓ¥þøìxLôH=ÁízÕ0.úüïtÆÝÉ0Î}ÑÑ 6¨ã0TÚ󚸿%_{s=«·‹N¿³8Ý_¹¹HÀ á\‹ AfUÌRGæl2#ä7ù,â00Ãx§0Ù̼€,5Id=v°K9œEœüN‡|î‚ÎíRg¾%'BDÊÒÙè¶ÅxG7C䥽ò¤=çp;Ihxý˜&#ʆC‘Wx=Ç^““b¨ò°Rk„¤/áöœ¼ÆTdW’Ç{A-Ù%n¸H£ñÖ‹|þÃ÷gµFé'ý5Z¡Ør#bMû4ÒúC­f™œ´E‹¿i'R6&è|óq »j媯qz‹ßÁÉñ¦#¾Úþ„Ä†áªªÏ Í…rÃ÷ÒÁÁœìIÂ.FÌô|" ÍÖˆ@æ Ê»¥ ™·ÒËäáþÙ¾~¸Æ…~ó%­'h4*+táh‚ðMÜN#o(QÉÕ+U€­á¸8Rú*ů¹e ³ž…G£¶æND/ÆN²?ÊÉûC§"Éû)Á"/¦Ù É’ ëF#Ù®´;ì4㤤Jþ>Ž7wš6`x<ìgäÝÀ^* Lt5_ z+#¸ƒ„@lYš`9ù"LFqà#‰{jl?OZ/p–·?<È[}ÐÝ|žt[/ð×VþîçîNý]w§{ÿ]«‘ü)d`á¨/_Šõeà ÝEø ²|Ø«6 2r,p¤áæä´Ž[&kc(´¿–g`$ª“sS·%É*}Ç&È*ªLXo5›ÃñË"[PH›ˆ!ã!Š^Èk‘ß)œŽ ÏLBˆ žŒû©ó74.©_à §PrOè¯W{;Õ•tçe•‚ü6 .Íu9^ôF¾ïõJÝáhüŠcÌœ`ôyrʹ¤«É3þÏ£ÇOŸ%› +?Y}~LÕ§z O…ÕøyðmåJ?Ô"x_v<#¨‡pχEV*8K{æÐI.פË´ØШ¨^w±—.³¥%š[¬¼.1*ßÄV×€$Œz©û¿h*ˆËSO›@X³/¼ox[î·ÜaŸx#ÉH»ár—öyËá”o¶ˆn´¸âZåœÕÈb’]±ÙÚõWš•Êè¿ lÇãºÊX&} /îE,WæårL÷ªÖ¸wŒ¶Ékƒ}ÎF\GÀ6ù6x)Íâ=Uq»)¦ /%(¼ù"‰˜Ø,ÏççŽô­ÈryàýÊ–°åì ãê%qâVœ.:n .7h'ù¶ttÁʶvÛù§:˜àØÜ‹ŸWZ zh]u]Ô tKGm·0}ˆuOq%ròÏ%:‹žyEmÕø†ábÕÆ±MwPÙÎq*ƒ­û€lwŸx›D«®±ë¼dÛÅ)²w›ØFý«d=ÙÆ!pê‹´‰)›Ó°âªòÖç¢Údª|O¾ñË3w÷ž¹ƒÿLbÔ¿A„KåñÆÀ9Ž3ħ"~Óvý[k厉xù¬½s*¿eÞW]•{Œ·^Áë¤NšÀø©ß ·Ÿ0Š÷á¬Eîè•wˆl±çKv¼5] ØÊÎÅJG(Ú^¿,†À޳_¢ÒVL  âødÖc…¸9X§¡š?ÊÖðÕÖ‰õº‰ªeÅ‹B:1š÷P¹ºWÿs•|N`¥&³¬T?Ì36tY¢eªaèÈfÒ„Ž®š˜“©l¢š£ó=óß²µÞj„k”â“ÿª%M¾ap·’ŽXÆLE™GÃ]\JˆÖÿbwV¶Eþ^ +³ž³è'õ~(=çá]kÞ-wu°,÷Ǻ;‰çG¹<òî'q{à¶>‘ëƒr÷ïþÀ-}q”.sƒˆ2¿­+Ä2¦íîîwà«Ä%¢| >¡[„¥iÌnD¸3ÿ^3– .Щ:R”ëHXÐ{ºuæ­£[ÿµî<É!³n´¯Æ*Fˆ¢§‘ëÀÑS\×y´s¸¯6&mHC«í°¥HëXb?¡-v¹…ÕZ¢Ô"ţ3£®°ÆzZ>—{)ê¹÷œíâ 'DwØn“.¼n"SÔYW$+ èwºÖó€€ýÆ·F²'à¡)óòÙ n {oRì:ý_×±d-·’N%Nváʇ{”¬uŒ9N³DþðdGè`¦vZªÅH¦"™¤ ˜»¢T ±q¬w‘HÞ—:ˆx’ÉÕ®0"Ù€×–GÜ#¹Ü[ÿ-“J S\*˜¬J<ư š¼Wÿ¸P¹Ë€uל³¥®9ö­ëÌcŠúŽ;K¯Ò(Á_×bˆÞž—{QšõîŸ'œÁ™2'S«ß£\Î-I;Ž~ÃÊÀáwJ˜̪X¶…©kV#º.IPï^,¦ãã /Ô®ÜÑ…é0-Ñ Ã2&µ†€®5(5ùåx‚Xlb˜Â[®f{äÂ^¹ØOñ¼Ùê"‚:F™Á/„~kÔ Sßh7x:"ŒcB… ä…~… —åc)4öfik'whéõ„ª²†$¼¯eîЦ “––_¯lÃÅ×É®Vg4ij˜ú˜myQ‹ÌÊê%B¾H~÷2J6YI%_&R‚.ºÌ†|J Ç0nE¬³=“È&+Ú°%frb¼™áÎ¥æ±Ä˜‚{L’ÂÚ\ °ØC˜2Q`OF&x_qœ¢Šs´ÐJl;O\0Êù)9É+75Ñm”éŽ(­û£‚+ިǴ0^\€(?&ó‹5O¶qžá§â€f  HêÆ5X04©m„UøÄâA7tÔ,b+<Õ"«]$ޱG€Ç<~ˆ#”W½Å¹ò†”§Ú?Žhžª6=î݆¤á ˆ‘æ¯Æ6ÎU÷±àmOü½ƒð†ÉL§i?ëx{ÝíœÙð‚Fõ¼›të/BD*;låí~GÿuöG¸žöŠEÉ„¼Tfv>4bÒ^ÒÁ“()à& j½KÞ _aÅ뎑¯›”µfÝ=K¥—ó¿:±%ð…/tºæöz¥ã^³f+‘7gC ®‰®ÑNð*Φ9ÑãÎZQ=È[áÚK€Øpílx¬­dÄöâÀØ€>µóù­±gÔ8(x4ؤ5€E¶»ŠáYßlDU¡’^£üdô|§z‚Ý2ƒæý!I1jÒnпã³ÞÑ㣳Íç\ãÈ¿’ËxÐIö‘¥ÄrpÜ2[>× x~]YaÖHS°N’‚a^’¢@áÔŠ@ÁÁ›;¤*0ðnÅFÃWwh5*”Í™Eu&üéYü0eúchQÖbÄ È“ƒ/¾P£ 8‹þ|‚”h˜órÁZŽP)ý&CÀþdç^ç+Ô_0ÂÁæmzûYÓQOüôÇ⥗օ»ýöÑþÁ“ÓŸzŸ?ùÛ£ÃÇg½³ý“ïÏÚÐð½÷ÀþµþòE3fVÓuR5z ñbÛçÃñ —Î{xj±jf%VÖskÑûSrÐî»\õ‡mÅ;}"Ø—ÿÄ.,Þÿ`ì Kÿ˲ÃsãeW×¢áñª®G g&Ê1Úò•Ä5²+¨žjwÉ<Ç€¡$¥’æuLnåâkN¤uÕxKœÜr’Èå¾¶œ\JÚ[ÚHn°J…ªH®ƒ>PWÃýsU‡-¢"#ÀòExl»·)ñP®“`|•º”9f^ –ºMØA¥æî5Шˑ¨×9`˨-IãaQBñ/ƒŠLo¾¼¯¿OrùÕÅ!Û3œy¯ôeÇi*ßÚF•ËÖ6”ÝbMõcD„_¹Øï]3Ú]ie׎vw·™x¥ußG'Ã+™˜öjþe²ªvxË;bË­×[¾¶îü8áwB×g—î5`ÂË!ÂéÌ(2x²ôÔv? ïI² êÿ"ãÿ"ãÿt2n6áÒóxý2Âþÿ/‚áð€bøá1a8¸¯Â.¤vx–ŽsJs–ú s,ø9ÙáHôŽÉ…ë·Wbðb-ðóP†°­…oÖi.d©i£©}ª7T´j;Åå›§'O¾?ÙôM!)-;ŽN†Dˆ¦qˆ M¢m.â;OÆôÇ^Á% ä›Z¸~Y gÙ`ow™F‹¹d\ˆ³ùò~?ÛjéFòp˜Sh’6ËBX‰,´¦R‚íæ-±Ü$ýÙ$Ïåâ"Îøö&½í˜†‹½ä9Ô÷Ö¨ï°_Â{Ùî­ctYÿK¶Ý 5ûz<ý¾'ÐgËó,YøªN˜“›DÐõB}1'¡_UÊŠSgï–ìU)[ôïxøXWõÍ“ggOŸ}óyÃ(ú¬™â(M…MøR#™«~h˜Ð˜óŸ›‘RbAø KŠ©ñä¦Ã¶"R”/ò½{Õ"Š®Û)9!ZœŒŒ>ƒy¥‹'o%`‚Wmï¥ñí!5 [õ˜ü²éÔ·gOž÷œ"¥ Í—%~?9ųN/ÖÏH Î ]s8¸.ȧz½ÌxI^}k5âÛY…[j ,æk)f1ý ÷˜©¥»^{a—®£ñÒ­ÞÆ^§—t±p¥Eú¸^ W`ÑoOúŒÍ†Lƒól%;ç©X‚¢uÒÙäD«R-ML¤áîàüÜDÝZ,9LY-H13Žs¨Ÿd\‘vï8@o©î4Â2s³^¢ãIOȳÃòý(ŽÆëÅd˜•{É`«•\ Ѓ—Än2ïŽZÅ%þëÜaEÿ?ûQøLÜýO 7’cô™`¿9¤¿Ä#Yöuî¦ä_—Òúî5ÜÎŽŠ­úÆèˆu}û˜Yk±n#ù.%ž—Š™”ìN‚ælÀv¸wõ{¶²{@ Ô8Ì8ifÍXüÉi³˜Nz4|åO°CšµßÕŠMYÿ[Éæ-}…jƒÅ ‹¸óRóÒðOÜÂÐ,NŽ7¾pvŠ 5ƒé)ðž+ç8z¢»uôÏ@¶¢KU´-ÏM¦°ÖxÒüg®m¡;@A1 ö“Ï©ÿ¥˜·óšôU¡@>ŽÈx=$23‰(õ¾¶]Zá‚ÍË?¾ÍÛÎ[OÄ_‹DǤö(.§Ò±é¨V>)Ù.›ñ¥äw¢ãq“¤2 KÑQ,ò‰¶öÿ0O4ñæUË1òUùÕp:¥èÝÓꇩyŠ!Â3K¹uR<“‚ž¦Ó) @9A‚Nfl6† ÄË™Š=ŒvP¬ Ò ™2t¨ùÆÐÒ·Xï àßw=µwp¦koKkÑiÍ{‹1òžø‚4ôÛžÍ, =HÞÓÿ‡3a"©wP°GAÒ{À8R-«©7ï–ö5öåø7ó,•ÉÇÐ~mÉwꑺ²×肉«Øf’F§½œÞ ^*5kä êSkÛ D)žò=VeA¾¦T&Ã6ÍÙ7’d€ø?@ÛÐiµŒè‘šçf8þò>_áØ³ž|˜ÚéûUÃJNI3ïtOûß² øü#^Vðë¾üÝþÑñ³“ÃZ²“ÜOv~ïeM¸Î{Z úÐËg}ô7÷Û5¡×gÎuäopŠP“;Œq<_¼ z´´ݬù…‡á¢ìkG÷±1è˜Dšð¶Ö5qtm1GŸš§3 p²ýi%×hÕ<ÏlúºŠÉ;Ôvn"€Þ ‘ù¥›lüz8›Œ1f'žEÑàÑÕÏè¿ßïš´'vâ S¨uNÏNŽž†+úÞÌ0Üý­òËŸÎ=Ÿ0^p˜Ë]g9Gs)ßãòÌÒùߢ}SZÚÛòÎF[Uaé†[>Hѳ]·“qµ¦¢Ì¬Qá;cö¯€ìwBÔºÚ¶(ŽÂZe ;f—¦Ý†s:X\OÛòµ¯×Jj6:žÜ¥‹†g²3*çiK‚eàÇw:Ý~Ývi“/Þ¸O7‘÷kCøâÒFrše)¢:/Žn…c†¡X)0LTkÒÝ ßÑ@=CùWöõôE“‘«¼pâÛh6¡?…xͤ.Yƒj3 Øc3ˆ+~Œ2jò4q|»÷ï+^Ãh ^«ñ@ê FáD¨%aðÄDY´4G8ÃU4 •Päaþº”ÍMdQqÙ“!¤¶9†ëa´¬ê¸"ÐQ¾ë7å rydc‘UX#ž¶o™œ8ô9›\÷Ð/XóЬ4Ä+ ü”¶UuèÓÿ}µWRMwOŸœý” 2dZh|ûñ†³÷ æ×0rœ ¯ÄsO’ôõd8°Ħ³(`ÂÂe0%X+_“V#ÈTb× (ϳÙM:C¼¬sÙiq²%û¬ÏñMf«aæÏÉ(Å%Äd 3nÂdk’õñ|8Ëæ·\SãµI^S"Ñd³¿˜aDÚmøš^ "—ºQ³éB¯Ë¢Dqü]N½ Ã?`Îk¨DåRùÑ^“º=È^oÀ'Üÿúw;Íh  ¤¬õ'Ó[ò#ÉFp²nÖÖt&ö–snðó?Ùž×2ׯРijÃm&½IœÉÔglŸ[ŒaÏìí¨eÌýw*yF±èìÃoø|™d¤ö¸©çHYM{ía'Ôinëy7Ù~A:§ê[&@êæ {»’5XRå‹Yfâk¸Ï^!§"ââ*&ÔoR-¥£œëav€Q:E«{èâUŒæu™š¶~9ø—ׂž®óÅ'»¢#ãO÷: Qºùß·¼ªÛRR¨'Gµ=€mÇÕÜTÜ.z¨];Ão•Р§ÑWÑÐ2‡d–”6+Ø,«H „Óþ‹:hX¢Ä%F®–,M—^­P.»,1‹ 3çÝ…c]­ÙÓ‘+ŠçN·xL™²«x13_àÑ)/gÑd0±TÑFO‹©¤ZÑ…2•_ïð—¦PY#/·ßr`Qø £]ng-©TóXÛ$2AË{V>ïyfSb}@þ4x2Mgó¼la,öeɪ->Ù||ôí^âcy²&› Q­ul$GW5£$ŽÙIÛMJüúÿ‹†³®ÁؤTùóº×!¹ós¨p\)Šùa"'²²,ALir›æ.ל—ÝÅÒ¿å ^’¤¯fn%:ÕuÂo¢ÿ‚GiN€q~‚&ö>èÓ3ô6"ÏøÁ6(öš|†¸A—°”3ÜÎmªà¡™°ö¡ëþ”s3œ`'›hM/€[0r)´¤7YóžîŸýÐâv0¯Œqšs2ö1ˆ3ô*Kó!:CfólvêLúv7Âd Y#´aN­‘dÕ…QÍv„HŸžœéäL\C™Xð2À¨c|¤¦u=AϨ–ˆÕY:¶Á2ƒ<áYòô›Qc”@ U$¸A¶//ò!9•7Έ| Àœ ‹Ýóm†6é¤ê K Ónä 4×DüÓ‚ú¡+PK¶[ËÊ-IRЪ›}'&ñAlmÒ!r´Æ“ÖVgß3^‰ñw^|״ʾ#´Á¶y(@W/4fJ¯° 9´o0`¨€YÖ‰&éT°Õä ‡ÞlÀ¦K\ IÙjxGèœkÊ ´íL§ã÷0ö‹áx¨QêU¶˜ s?;Nó.^Ø”U.úh5lš0f‡¤Ö­n$nœBÛ1cë Ã-ž7–×óÛ¤.HÉ&æ‘«?Ý?øËþ÷‡Í¤þ×Óӣ'«Pã)A˜&Ÿ$ŸœaF4®rҽϠĹ ³~–çô)I÷aÔ욤ÊN’Öh)ì /ºùe³S• iÔejXé1ù d |È4'¿h¾G7´ý»á}Mà}oNÕU±5êÎ_TCñ²ƒ¼ˆ×ÿå„|¬}.¼SŽaŇ0·= „š fzƒ îâ/å;&ñŠ7 ­.üÕ#wÅ›ÖëuÉ=œÈ62³#¾M˜-ä¼2V˜œŠrÞ%ñÁ+›q‚Î-ikC:KúFІ¾V@ÅïóŒÑì9ŸÀ¥õjˆŠq +n6ÛïA2›54÷m$ý«É°Ÿ1~ðå„•Dj0qÔÍÄBx ¤Ae­*¥ÒígÖΈ*.ì…†8iPlfz:P@‡ê†Í"“æ¯$}t23¨Äû»Ðlø5‰.ä®5Û/‚¸¥3Âb”ÎÐâš:L¹z“ý£ŸZ¦Q“šqC›B#'2Ä4j!ß =4Qææx_lPâEFŠ€çÚ]µŸjÎD^Dj°=!ßIX“áåb&P`bå“yj˧çé%ŽìW±%©…Ñt¦¹¸tݨI\Z¯Ñ„²žq-ÙP6ÿ:µˆË°ý"‹ÔÆÆFòíá÷G“ã£oÌ ÷lrðäñwGßï}¬ÆÃÒ}çí=¸{¤ÝÃÇ×iuý^ÐPÂï½\üa“C=Ç“eÿ@çÓtu¼\·¯üm´WMú@þªšÜÝêQ˜ÝèÏH`#pÃ]µ‡dçÚ½ǃÝê¿ñ¿~Æž·w:;¿ïÜÛÆß‘[ͧ#¦®þíÓü»ÿþðÕWøsç¿¿çþÄ_îüáÿ¶óå—¿ÿãWøÃW;Pnçþÿðå¿%ÿö¿éŸ Æüü_òocx»ã"ùápÿááIï`ÿäð´wzvrúôn—ª|W”¾¯no%“é-#yo4“û÷vþšÿ9¹'§ý+Vîþéïðç7ã´´ë& :Àñ}]M¶àÿ“§è,’ÊÉ·Z D·pCÃÜ"Ò'č󅨽±^>¹˜ßà…Fztm›ôÉSÁšD1Òbº˜aF*%âÖ¾È(Úo6è.ˆ6cBp1†YcAÓ¨'%ÖÅÔw}rÉË8 ƒ.SUR]"î’³/R—Šá%bG_hV® ¼E¡¦7¼–ýÐÜ1°?êuÎ: LCY¨SÝ^ãZ‡ˆYüçp?£q¾?ý ZZušEb€¶½©VySq%᎘ çs¸ò§³!¶kFÓÁzÒëô¡œb–Q Q1äb+¦«m14öâÉÖe´ýp°špհǃY¯JD˜‘nËt2{ƒ_Ëq¼p;£Û Z¨q¥1YÁÖ6ÐQà+F `ÌjLû²ùbÚ¹ªÑ¾>E*H!©NÆÄcÃUöŠ£4’ìz Åg0 4‘ÑnÆ!èr=J[ôÔ¾„v†×¹€YîÔöç˜6ä€"\Ê%‡ÀëSmïß!iµ¢ÊÒÙ¡Wf±P3Å| Ãp:Êl•Üô;‘¥ô?Þ¹ì$µÈJ„ƒ¤£xlˆÎ|šö ñS‡Ž;§9ù!}YÕÔ9ƈžÂcæ4%j”R´¾8`0ñÌwî0;7[ñ¸‡ N&SçÃãÅu/]''ú­ñCtSS¯xÎé‚?,s,ˆq¸“nuÕg»Ã‘ÅhÒ'ï*A~ 摬O°i¶«¸ÉÖ–woRJÙ„_ Ç­ÄýVê8j`ÖÍœˆ ²ódKÛ|@ù»Y&ªé9wY`dÍüo6;Ø2±y/zÐʦt“¿-_s>VÝA¤øhÉA§îßþõïÈ¿ÿwýê—E6»í|ùo¿ ÿ÷û/¿ú#òøò÷¾¤ç;÷ï«ñ¿Å¿N·V…ÿ9<ÜÎüÇ¿·€‹»w]Ó²äQšƒ„r¼Äx¬£±æÕºvbÌx2š\Ô¦>ˆ›ÃŠÁÎaõæç°ò3tnå;rtXõÃY:¬ý<7áwaê°âsuXùÙ:¬º_Gûð쇄.žGùÏOþ–|™ÔîßKO^ãÎþ(púCòxÿÑaÕ%yI· ášwªœ.Aâ†79MÜÃǧ ;_\\d3jãôoŸ<==:­vÆ0ºoÃOþ î\}]í<}Š/ðžv¿åÝíÝ‹#\ìîÅS¾ÐáïÁ8ïàà¹Ïæ·S*íUã|xIJ¼+Ô'ÁÛáÀ-;ã¿L1¹¸á ô^Á²òh”ái³Ú¹ÒÀžœ==C䇸¼Ì¾ ž“5=èUiL•Ûã}Ù„†ÈQ0KŸU«g¸Û¾õ_Õf(Ö¦¹U;¿dÓHt:Ø’åÛª#:!ÕK9ÃÍÆµéØóüøÙq›¨ï†“¿À=œ Ú’Ñ/TGéy6‚5ewÝðõ Q"á ä'Ô‰å°HWƒ §2M¨!…wM²¼ŸN³¶‚5°éÁä8]ò*´ãrÓè%_1€çʵò-¨-E³çFËtâÛÜŒÓt› ²lÊ$2—ÃÌdšìü¡}ìüÕF˜l{&ªRù\Øy¬=T-Èx2þG6› öÍBœ•±W9f7k%úHš4ÆÛB“XPhƒÝ¹ì4Ÿ»®ÆdHHY&"DjVs]2ãa\"¹<#}ÞBO°­¤Uez›!bÇ%,Lª×\r—æ½¥S=2:ì>úÉ¢Õ6þûPÈà5¢™xïóx«zœðu÷ªœ&r ²‡?êüì½ùcGÒ?üþjþŠ"]V9J‚%dkƒŽRì,RÐFk`–´¶÷oëès@¶“Ýý>Éó¬ÅÌtWßÕÕÕUŸB¸Tßï¢ÝXæ,ônhF(ŠÇÈ¥ˆ=¯Vp‰OX×Q¯CØ‚1öLtô€*ÎXÚ4—ϯŸ#€Ì´;jã1ßSœ¤ ³5BrR?=;9¿ÔgõfŒàÁ“!Œ)-åì;œÌ<‘·€“#d,d烄´îÝAî9žv¬-Íb á´Ó‘É_?<:Ý;:;ÜÍœ: Cs“±-OᾫC¼éhÂB)˜óìíˆo6¿ÝŒð¼¶KK }vùR¸ÁÕ‘ú¦Œ’ð{tµ£ÆÔ\?e9g™ßiiÕ÷k¿è` ý¾¹ž1 ‡¤.:¨düZÌã5± ”'Ô¸çÕë¢Öhk¡A…ý±Î‰óÂ$)™/ÖTÆ/”¿vvúòè$óbì߈—Ónˆ‚ÏÁþ)H–Æ¡Éo™ÊÕ8ódÓ¿z‹Ÿÿ +Û"2†Õ¾ýôsàœó߯öàü· ¿ÖÖ7ñü·±ö×ùï?uþ[[Y¥ÕõvX¢xlùþ†þ^ýL»‹Þw°²Xÿ×™ï¯3ßÝ™¯Y?…ÿ ûd{§ù žýÖWÄߦCŸ&wôðáw%{‹ƒGßð€ˆJjeM‰‡L$]ÈØ’ÿãN†‘ŠXþ‚ {8Ècò'ëÌéq?Él|‚K!©[ñÑ„ކ(å€(˜T qn'}ÖuDJ Q€ÌØÆªN÷â ÁáeÙÜ>ˆH¿må]*3ðI¦ÑV&ƒ¾Õ­-,ô¢U².ÐU+³ ¯¼“ʇ´«ß­UV7¿­À–¸²R²ŸVKë•ÊÓÊ&Üœ–kÉšª gð`̸odþ!iríñâf'ô dyIIêÒ o^7º%fÐ5þ 4…ØEËÀÙ.ÒéÎ16ÓXÛÇdŒ™‹gH(}¦”Ê ù‘ÍŒ®#ÂÝ}‚ø¯]ŠÕh;f(ÒQ½ƒ®Ðè€Î¬½IBìuÓäÝSvtÄùumkkë ÿ¯?ÝXùKþÿ3þsíwÔùzuõ‘çë¿ìxþ²ãùï´ãYê]“}[í—zû°»*öѲ Í9¤D>ôahüIµ7D¹œm¢9wŸÇ3u¯RÒ×NŽkm*ËÍCzx,ÊÊ©;Ö:ÒÌÐÆÿ&0ñïÃq7>ÀP¾…Ó:u„>Øü½°·ß¨‹åëß]{ƒ^Ö)«V…L$–—ñ£ð=AÕoãK£$–!÷òï%´^é÷¼ð™N5¹ŸÀN<.Ñ/Â7âw*É–êø$­I0Gm± |WCÊás*®µ“Rz냮³úÁµ$3z§^ J- a!RPJ ñIàû_P*Có"îüÀlìÜŠ¿+Šwrº¶Gƒ½{³é¾:;l×w”Ï5Û`ß ¶ÙÞÒøº$k…ò^í`¿ñ+&%ÜÑ î;h+:Ž!R…_Àñü É?ØÅ¢ØÞv¤hFÅ~§|ï Ý§ãÞ€ÃH˜« 7ÿA9øI9¼ÈJ,Ðÿ|±-òKùbQÇ}ýµÆfÀÜùó•ü³hi“±G‘ÞÄ's1«Ðß!ÛH”Åj¤ÔÂïâ®N‹ßo6k;õÂòïVñ¿—˺ø¯¿þ=¡Í7½‘èC¯¥–?³ÑºÔQr£1øÐðQƒ"÷ù È¡®Ù‚Ð*"-ç¼]ÏcsÛC>¦£îþñÛ ä‡ðw“ÖòG<¨YÔäúÃ>´ÉÕºo=ô¦aà…”¬NC¿ø -£Ó2ðmŠQpM¯ç¶û=ônZUç–j#âÈᢧmÕ «©úçÑ…ÛI™;G¿´ë¯wí°‹­¤Õ =BɋM͘ºÅî\Ü/}.$å[t"Ì®ÑuoŒs Ùxd~â+Í£M/ÛüΊ8È ákÃì:þžÊ («G]Êïn«B¿›´Ò§dR%ÎG xBP‰ÆÌTnjVNµÏAþ»3Tµ’»‹³wÕh¯ŒÜ6¾Ë¸6­ pÂJHÌýØÌª½Ñ/»~‡#3i6jójî‚ñýEY+Œ}²AUíÙVWK)Ãîi|U‘þ¶Ù­ÏøÏ/)zl‹ýÃÚîîIûðè°nXA‘ÙV‚@ýÝ×L¾˜<¨‰¥‘ˆ¿ ’³£:!ÛN-gÏdÐ<Þ¥\s SD÷ÎSKé@lø³„DÜñ(”×v•‹éÓ`Vßnrç&ö. '_ÈB‹)M=§m² ŠtIh!ö+SS(ñ±ò§÷åæ#:ss¡ÎÔ=3cGSž¬‘u·À"KÜÕ—ÔÝé–c}hS&<3ÊöS—©¾ì;(©Ù[bM )Õ­ª©:ðI~«ªæ´ÀV*dtT½ê-ŠEGPou›¥Xo곯•ϰ øý.3($SÖ:Š‘"ãu*ÿpÛ6ƒ½QÚ  )*™}ÞÑŒs„Gq8äC-·,‹ JÛÚô¿;¤èØl•eFó©øÈHi¥Õ{ÖPqÁCÁËbj]4‰X…ÒKk­^,б­•‹HµÔÚ™[ÈšRͳã†Î3¤3z(¤vøÒF)‰«ê ú Dð‘d7KIü¥ä¸D“8…í>,h™dºâ#Æ™s¥t«ââ"bÿ0Fg¹À™¿ÖÒI¹\ŒLå$©URüDYm¶‘¡~giþaK^u·Ä‚ng„pIŸ€=àRwB†[¤%gC]„†l9}énRñ.%&ù%÷”&¢¤,f]޳ %³$ïñ»sd±!.÷Î};ìM`ç²Ws1H£=•iú/‰9‰©#:mñÌ6¢¶ðª,ë ¤±sIï6½ÕÙ— æ„"O‚2Õ³­“TIÒ¤^lßòd+±k¼†8dT¯LZ]1…Ò]%«¤t{Òø™ ™Ž¬ŽA±ý8*é¥î\nu ŠnŽ1™{WJ qó/ÌàP’½OÐ%°º’YÊBÙ ¥dõìܹŸ4Ò*"3}Þº£²Ž ïP0 S©<¹…ä)òÉ]ÇrîzØ0Ž¥Ðõ(Úߣ©}㊼íSÄ#Bf„HBì¨#©}!ž•‹ÐLU·•0³¹Õ¬Ü)ßÉÖKxè÷âfìD¶šÂq!ô¯ŽB1ra4D ç£]™0âFçÖï¼Áº’j6ã@‚EQ‚åéÁª†Ã>3Œq~g¯¹ƒž ü•ßBœ3Üø¨l$CŒùŒÆ§ä2Ÿ¬?GÕäsNãh#hþWkñjã§jzå­Ï)MûN…>ûcp7œó…¢|Éô€è8azåÀ¼©(`<’ä$„zð×e†÷"Ç#Žù`“x@©Þð­¢@ W˜]‘w;ó…b^µ{‘tØQîú#¨L™aWE™–¹øAèõY™ F•\.cŽ$xƒ!®»äã@ûs®k#ô©½ša²õ×ÀêYËãXn ²N|Ÿ\qΛð ò~ö Q†Ó±fÔE"È lXa 'Ãd(Ë=¿â!Ú[„¼Ò r_`ýïßg„õMª<{“JìÓ`£Ú!Á@çV—ŽӎǦ‡_ÕÔ™ª‹ƒ8/Ù„-ð$ô¥Ý†/²†Ú%ú «6¡¡†>‘bè i6ƒ3ã‰T¬ý¹Ðç Ìc`P "eˆ†˜Ä Ëï¼á¤ÝŸ´Þ?ƒñöªyî áyC?ûéÜn¯ég‰Ì¹½ZÙ¨¬1X·ŒFãÀSÐ|„o"ò7²|Ö"âmEã˜`ì<Ø ¤(Œ–]qœÿäjfÓÊóA×Ðfƒ#Ü¥ o>¬d2æãö¥Þí꬙èÒž}÷ ¾-“™µ™H0÷Nžíÿ£¾U6I>\âx:Aw“hÆ$„H“hÎTÌŒÃþk0%J»—0}.2ôï|+xptºáØBêíK«r¢\V¬z‹¬°<«—˜ëwÊEuÊI"ïÑÖ«ì‹lX-´~+^,«Õ›¬|ó[ë·•òwËøŠ¨)dhüîÒh•ÅEÒ+ ç…FÜ£PŒÕìe¤k5Áÿ–®M&*ùgäkjÕö™»a류[Íèe˜[Ëè%˜[ÏÄN9¬YªAZ³W^7›1Ž•Z”oðÙYÿ‰$n‚ F1‘jèzcë¯7¥ŽÖ;•Dr½%þb4RêM#±p½9u¤Þé$ë­hô£!«A:ói‹)mþÊHÔb¡õ£–5•ÿhVõywÆ‘?îëmð¸~ÒpX:¾Ø*cšFƒ_ft‘ÕÌåmÁ -³ä}£óhëóùMW¬ªÅ)Ž4g7DSñ@+ ‡2zP… ?ù7Æ21?ýÓ¼TïàIÇ÷±Äù×AEh¤±Ø‹Ê•÷F½DÉŽj]¹µ_qõ“ßYeL'Á`câW:hÊ$_"P‡©˜Ìt3E¹óªÜD^LÜg©øußM¯œØÁçÒ0r„%Ë'èSK+£ŽyCsÍy2½c^ ü®^NÐѾÞêgö ­|“pzãír…Ù¯þ\…¢n›—d3=T]mŒÊ·«îãš8Üæô…>Ÿ0Šög>nN¿BÅ«U!Á†ÁLáLlõ©`– •ɽ³d2mÐþÐ\A­G¹¬Ã… ê'k1)©5÷~m²Å+TN°2Dàjåiåµ(¼†óØÚf‘£ãŽì!…ãœ"Íw8¡š²}ÂU†øœ€rFó„ òv£w‘‡)„²µ¬L>vãÞÍh¤9Q} ×Qç c“é(²VÙ\C†Kqª*™LÒÞNghxoïžðå©á€É›£Em_k›öY76‚Øx«se艹“ý–• ¤ÍA»ßÕvG;5`زÍ8Ìt¶‡eHsU·ä8oՔ✿;£äDxº4O™ÈÍt\×'àì ú4oÕÌ)!AdOv„÷§à483Ld<`‡ª¿,ZJ@˜(÷ˆ­À§cÆ yŽƒ5nÚ’iŽ)ð )ñSçmê×›g!‘@ˆñŸgÐrÜ<Ë[ôâÝ®´Îl’£ÒÃ=wnß&LA2×£Ó‡^|K Ò·H!½kcÝ y~¹¾†£Pù<¼(V™Dnµz“µ(­5„ŽŸÆåälG—°öq½ää‡ö^£ö¢©yœâ 1÷Qavr¨ŠêÜÓç÷ƒÉ:«À·ððé©©g§G ѹU6_>˜¶éw 4Ï.ߨ½œÉã[—8±ÐÇ‘ÆF‘>¨ý\ßÒÛ²*¯Û-«íWîOvy´KÅ·¢?LO„+’}dmM†™Id±`èh…zéŠJi#”ºôÿ*9R½“Ïžô³cׯµhÓá¤×7Ô1Јé½ðýw—D3PA ‘š7™ _‚ôáÃ;ÎN›ë[D4ꣵ¸ÑÉAÉ7¤NvT•ª]ß™ŒÂÈ’g—{¥ÄÜíK—bšVEE‚ÒUPÁåòr¹ë1hºº˜¦@½–â.ò–ôO#o¥o3òšFx;ûà‡Y7H-{;šÞŽB7+T£±†Å '“->ÌÑ„°°ë‹]|\#â´1•¥gÐê/N+¡Z)’EÛckJœÑùˆöØ“ÅhÍhODe±`{ Š3¯ßG“²-«ZZÖK,*"ÍÍѮثAéB#S¦âöx%Rá4ÁPñåÙ:“Õ¶C±˜ÚG÷ð ÄÞr‘*§émŒˆ¦ƪLÖ‡Då´Ï»ŸíÉ=±#CF묣Ÿ³Ž˜ÅƞČW§ËiàHT1ßMü¢•¿°Úþsö?rò•ÃÛ?Ïþg}} ñÖ6Ÿ®"NÄ&Ùÿ|óþÛŸmÿ³¤X(ë_ž úX’:£2*¶áðÍüR±]Ä(Ãÿ¯­TV¾y&–ÄÙ鎾Ԕ! aíóñëÕÕ“§¢0èMªS.«R'¥¦`%¼-–«‡Ò.iY0¼¢ï1‘Ø…ûŽ ™E@[M M†Ò òê³ãC’^—"‘lV¿ûnC¼F¿³±¦Jc\$ NM¬ èqã—GtHØ !rù+…ÐàQ5ÐFè:‚@Ç€0 :=ÒCG 0HK]@ù>Û”9²E,M®|8EJé¿Åy€U>÷:Œ8Á( Ý?SÔiBýEݦàx |jaO„·% Ó£„çÙ§tE_ ƨ¨ó ®†ÄzR5”ù#NLdW… í+Mtkz8®§c¹-!ÎE]G¥ÚáníÑ–Ž5!K†Ã‹,€äÞz ,ñŒcÉF Á øéâ$¡¯aiÑù-ÒZžg§/ë¢y´wúªvRûMq|rôËþn}WdkMxΖīýÓ—Gg§RœÔOG{¢vø«øyÿp·$ê¯Oêͦ8:Á(nÇý:¼Ý?Üiœíî¾Ï!çáÑ©hììŸÙÓ#*RÛ¯7‘ÜAýdç%;9>jÖ¡ »@øpÿpïÊ©ÔOÀã^Šú/ð$š/k–ä^cø²æP9;ÏëPÚóF©C[vµýƒ’Ø­Ô^`•NÄä;¡d\%ñêe^í¹Ú¡¨í êÖ(ŸžÀc wrª3¿ÚoÖK¢v²ßÄ~Ø;9‚°!Ç’Á|‡õnˆö³; ŸÏšuS£Ýz­ôšHÀNÌ£Y¿ïø#Š×cpwi2XÌŸ’í‚¿m¶"g$bì%Šô "ð]/$;à˃@F«½>”€Gu•ŠXA™XúM¨ëã Œô¢p_¼)¼+P1mv¤jZ¦¸ƒÓµçJs°Ìn8ž4•@WW´NeuâÙX²Xh*ƒ•#Ó#¦/ŒØÁ@0ÁŒŠøà­ˆ+Èg¨áþ[`‡@)ªŒ<Âtzh‡ÔW› V3›¥*u”f„·5JÓ›d¤‘$bhm}ã&™…UÉT:@÷JmÆ&>oîjºj$+Q˜²g‘eQÄΕLfØßÎgò´YÈŠlöInاk´jØ=Ú?~ðKb6v.Åf6•Á´»”úb«,ÃcnTÖ±:dUëû=Š œ7äð“ÀäÉ<µ’é½Évî*ªüÁ½œÅÏFbÇ'ŠÛ¼ÿ(µŒyKÉùð!ާš¹x/†OÔû„ˆç9Œ­Ê5¹•ÁŸ(NÖÞê eæ3ÜÇÔ&ø¶7†d6üÖC”êLçöfŒ–Q7Pó—/NŽ©êôö|„½I<8Ú•á-~ î†úãÑ«CùÞÂÇ&z I ~+_»Á›no,_ü¼»B_è-||«¾ü¯ß~ÈŒòÝɽ>dÆ_7OOö™<½ýÉŒ‚°wß¾éWÛùóƒ[ض¿([½lμåÃñtgôN  8£Ê×E[Wæ-ªÑùõiËœ3?À¼•µ¤†oÓ\d`q\[ÊH^Kø~Ïr;ƒî6þÊéÁã‘¢¯ƒ·ô‰{:Ÿ²9îPhQ–û‘’fÂqg;Ó 'ðOoÜÁ‹žøG·ùv0l3¯Ú¦°`™aО €6ik)$"Žþvöœõ·DnE´ŽçBE«|z!š';„™´Û<Å¿Ø1Á8–T¦jâo˜'õؤ~MI[ž˜$vÆ´ä]|ŸÓeö™Û®†Á`Iù­j üCV¶¢R®¡Œ ÿ[webd_ªlÊ¡j¤ólL€s4§™ÌÑHÊW4mÊe €L—÷½pÔ÷˜sÑ[eð_Qi•þC§U/zÃëÀJéË[ÃR`HÕ.*UË;n6æÆjÖ€1Ó/fÙXÅC%6t’XÛ³L£‰h×&*n›dË'Ö|'·x”бyåñâäèìX*„4÷Š,Ú<)!eP´i¡3É…‘” Rž…•“G2»¤<˜ò„޶Jó¤hJkÏOÝ»$Úš%îÔ¦9ö NÖ ØË·íZÍB›P­;ÛºËìå,îþc´"¦ç2¨±¼À¡É¦7¡9¾Ðì]Hn.˜ ͯógÈÏLYh&œ=˜ÍÕ‰¹æ–Dyè‹i¬Á— «ê2¡Ü)¢®Ãa1Âf0¡þÜ- Řœ÷7M±Ã¬5CrkÙÌ“ð¶w=ÑIiQ•1*Ø¡9â÷:Õ H,MŸp}‰#÷(Üýr^ä—Å{øûDþÍä—á=þZ–o~”[ùå"‡»—%®liŠ2̔٠ã‰ÑGBMžÐåC¤ú¶T²ö¬5EZ…fífbêÏèKÉÛ±• rŒAîL¤”iaò ( 6Úfåq(ÙÈ™%cÔÀžŠS[v‘$'{©ŒÐÚ>/œ¿¸0eUª*]ZO‹"iWq\±;=+°ölJ˜–‹\Pæ »1«÷ËÅ'ñ±aC&U94zXø*ª¨œ¡­["¦ÎvGJ Ts_[®°\È“Xõ„¥A°LXÛ|W‰p…Y êŧ, Vh¯ ®Ð" ƒÏ*šO¶åN)ÿwd§I&OrjÅšpvùŒÑé8a†Ýø€éÛê¤%±?ɇâègš]8óÖ³ÜÍë°š<ƒè¸‡·à·ˆÜ:äÓ¡>KjM’×·gpE§®¸†2‰­êmL»/ð2û“¢Zòð›û±7YxØ^]ûî gÉRó¬ë+öÇ5÷ãÆª“s=òuÝùú4C­ÇÀÓ¾a€Ê œÍzu 4 PnhAP&CY´Åm äî{ÜÁÙ|\ybÛysõEºäFؽp,ö…G7J|ºÒ½Åª-‹ç2 —eEˆãa„¹ÙæÆì+£6Õzd]ݸÃIÃú°¶¦ù_k¥üöJw†Jí9j¬žLÛ£þ4lï¶môëuþKŒD”w=Ê„)öQkE¾ß|ó(ˆ})ðšCä‹y‘Ó´.UÅ?SÕJÓ¯Çw©£Š˜ÂÍ^€ó—<‰Æ 1¿Oc%<œ@LËL. Ác°øcª‰òÛ8_ÀƒfRxEDÏÆ#¿d­Tê®9÷cFv™œc¯¼ÞÄ@ZõT,®M'ä~Ú<@p‘ò¶ ˜ FY%’JZl”Ѹ"ûäÅÔÕ7*bžOLÂ^yŠt•T`Å4,6YfÑì- ¹Uœ]ê v–„|Æìô î|—ä –Êé¾ÜÃî{áÄâ®ÑÛæ¸ÑHâ¶è0p{Oâàñm9Ò’´«ýë˜8`Î%‚Ü–1ýÌ–“÷t6jžÐ0Òôo7˜¢6Oq”^Úòhév¬šTnÉš ÿé5kõµlÑ–Øw*ïHlÑÅç¦sÐ4öò –©—y”/\jÞ¯D5<¸¼Q׊uà°s¨¹¼¦«¯ó†â¹ó­ƒ¾ÓašR’]Xq+w™yRPß¹«½ú˜>!žøš¿Š-‘}^¨,·~«^œ«Uúÿ[®.çòâü½8çÃE$Gµz^Äds’Ì$q^¤¯•x q Tâ÷œòùêoVeÏ«çVuáw®ú.óä íVÏW«üûwüóÿ¡Ì˜‰k^Y^8ù‚„‹óH†UHQ©>¿«-ëRá%3ÍD¶é:úK÷Ö¶Q`—ú5‹ç*¨¤\±Vï–>Ñœù|Ïw;,¦ìÀïö¤&”Öø´©Â~ ëq Ã¦í®‚DH²C×Ô€#²êÉ•P˜Ç¼Á5Þ÷~S^])¯} yäN.ÕQQíÄ• J|dLRðÐÝZ[ßüæ‚ÿ…Ó9woÃô“BT–WZ+kø?Ø"+ÑßnF–gžq†æ¨‚EYɯÅÚš^(‡ðkDàßH¡ß­­¤$Å”NBNuÉõ_NjZé&(ßéã2Ã+Ë]­G¤[1ÿNXîÞê^&Ó¸lBá0ÓHZ§¼±Û%fYECšYòÃÕO¤&)H‚ ’üä|Ë<Á9þÄÖtóÔ–SÁžË­Õµõ§8Ì8ö ‡=jî¿f¢<ÂcÌܯïîÅžŒýoÜíSlƒkž¯R6PùÉË;zñŸÁtT)p¥¾ë++EZi&£‰Ÿ@‚ ½äÝéÁñîþI¹ /> ÝDî¤v¸{tPÎådB<2äñÈûñ™° Ùg¯v³úwÖ½^0Ç81%¼ŠàÊÙƒ p&¼D’¯Yº2£€=V.Ûe£¨'²¦rpら¾!–,…°OPÚãÑ1,¥Wîåò ¢r¼<.Ÿ½««•µu’v÷O Ûf婨Û8Ê"«¬$—ñÌCá¤0°2ÆŸöH#íàP„_Ž¢ Rˆ.[ öfe5^œºq!‘ ù¡¥W¥üý°Ýï¶å_öCQîwÍÀ]r"žÒvRšÙÜ¡Ýá¿òãòrÑèÒy‘|³²‚SËIWNJ÷ô©IŸi%©7Èx& *ÚÌX.™Èl ùö¢jW¾½šÚR}qf§'g¬œK!Ëé?ÈýSn”8H6KØR_€Y¾ 5X0à‘‹ÖwIÁ{ˆ‰tþP@ÃÐïS2©ðÄáö-$^%{PìI¬X2½@Ì;B¦ø#0ü[bwu¤D²„"uç‹› ¢Ú¤õlj¹Uae ñCï~;_Í㘴Êò°l}©ð'TåªWùgáUü~ëõ¡—¯³*Q °ä3>VÝ1Çô‚ï‘cºKY}[g™’ùëk«„«ªÀ­ðÃmõû¬«DÐ ó„V,Jä¸N_ãìS°Ò¸Asäøo®kíÿ¸úùµµý›Òô®çlkz?³v“‚Ò˜D&97ñ±3ÐÈIÿ®vw6âÀ IÛÖ]À÷kÃŽ¾VÞOÐ`‰ê„ö×O\¡]¶·8yx|bs)bS")°>ÏÃú]öߥÈR´èÌ“ «0Ïåù<‚ް,!ùïn÷«o|?â ®"X69™-O¹þÏ%UÕ`¨¹€#Ù)rzl?º7Ó$¹‚έq>·Z× HÇ„s”=$I‡%¼rOúÖéjžì%æ¨Ë5*‘ê+ô;­¶ø€­Šçä H7'¿KÍ™Í%´FhÑÜæ­žá¥Ì¬å‚ÙüÃ-˜ßI]©)Þô£«¹Cs-²¥ÂÆH¶uþ`äXIC´q0b=‡Žäùvf­Eiãl©ärm‰ÿå|è‹,÷wNTŽK Zé¾).}Œ¡CTfR ¢Y ýîàÊÎ\¡“U«j—2s¥òË=c¸tãHÏb‡IIõ¥Ôê [Reôœ?á ¬l×÷ß‚F†ïÔØí(0ÎZ¯Kg®Â’QÓ™¸®!ë‹J„xEQf¡òw·AŸboІô¿"œ 3˳" iÙg-‰N¡>äÑHðiòÆ‚³)A+³ ˜Un†B×nÐãÖRùèå6#³¾°2«w ”¼Øz³H˜±,åÞ+úqîÀÂ5JTwòÌ" BõdÕÔœk¡ê',rû²±Ó®5Û;¥ön¿!WþYÌÊ3ôïÒò`ícÙT¾™‘E?.øXñÅkPS¸¼°ú[¹µ­ÜÆVîéVn3žõ뜒0.*Ù•V ·ßåc rê*íe—Yl%zPÖçdVQ&ë†OX£¬ä9cô2°ïÑ•ÀÇSŠìö¢üjQ´:’ýØ×ZeŠÝéo½:?óEÊà-^Ëæ'*B5ãpkŒkúýk:$!? }¦"x=¨³:8h:2Z'´B5 ë3d :èØ&á7p"Hóç‰sA¡pËIyõÊ'ÄB¾cñN¡´Ý…áà&N‡ýÞðlª·°±˜Yáûyò~Ã.…Jæ«§+DK 9ê ­UÌ ƒ†NÈg¥18J…%9¸x£M;ldL„d¨+ÑfÒàËwROÀ)‡¢š+»gÇ;ðÉ;- }¡'BVŠHr–=§õ1ª„GÖ•8¡¬ÝÒΣdòw Ä“?[ÏøPÿA—fîg`p#‘ã€ç7žt\¼6xâüUu}OB7ÐdÆ©gË‚Kè‰ÓØèÒÉØ å×=KÊ8Çx%‚hª„¶§Û‚WÈ·(âHù6Þˆ<]Å—±nôds4,PQ‘ þÕS™b¹mÁ‘Àñùʺ‰ðÜíaª/·Ê_®¬ ðŸnþyII?ÿU…Äg§;‘¯þ° ï¥Y–R»[y†þÑþŸƒêä™îÿÉî’«ëë›ë߬ll¬@ºÕ•µo6ÿ?ñô/ÿÏ?üöWÙÞVtü÷•õoÖ6"þ¿ëðî/ÿß?Åÿwùóý—ù¬Ä~ o 2ÉÞHåñz°"~öý pÊP7x6¦àšò¤£æ·™LwØ;àãè—úÉÉþn½­ ‰èÛãq0×qßëH?^”€”ÜÀëŒQëäân{×Ã0îþˆ9ék;íýÃýSq‡’a)³q×#kÌô¶Çñ´ôN”!Ã~± (×,Ƙç¢P#AçÞš„[ªd2Pên}ïì°ÐJé“‹’haªçõ½£“z¡•[¹(µà äÛ¢ùE¾~±‹ |¤ò”ù¾*=b›µÃDì¤v€^ÖŸ0êR¿+{Tº*¨Ê±‚ù£Äy…d‚W§ï•ùŠÜäæ> 0œSžÃèääºÈei{FeÑK‰a |û)Ås}' w+ÒÐ¥L+·JQÚ±DQxôºr=·–Ï2*Íʳ̇Ezx½p?O÷zd Dí€Yg•µVÙ\1.ö˜Å‡å×Eïh>œÅmo¢fî´O·”Òóð‰ª[‰ çØïN;Æ=…†ã',F”©ïÑ4€Ö­PWOh%÷;vìôèPà(@ŽÞ5üZÃÕ€Ã!if©w ”D»ÝAÛIü_Æ¿‡µ=Y”R×ë:Cq£rk¢P|vQDrèô«†V膄þ¹}zòë_ã˜:ŽN?¥ (Žçc÷aЙÓ° ã¬Ç³yº»Ón“Ã4ù÷‹ï !¬ÜþÊ:ë“Âî2áO4âKÓ!’± Ο «80ƒàÊu!W8™^A½·Î}ÙÆê· _²'ת™\Ÿ$ÿÙ`¸ŸQ4J—ÿÖ7Ö6×”ü¿þÍæ*ÈkO×6ÿ’ÿþùO¼ôûx5¢}°âˆæ€¸…Úgý|ü¿òrÙ,Sx yÁPY[YÙ(Ã?OKøóüùþ$˜˜Õ§åPPþ=„Öò§dØ©ÐËW£àêA¼@8Å_*âozõ#ºÆ[_E<" ªB·fnYV9SEPå«m ˆÒt3–‰u’g‰Ù&‚(°C ¢2ZΤa ¯ýû Š¡ !qè¥[ÉX«ƒF­ÑsØ&]h%è(EãáË©,ô;"5bmÕ ³bÉ}Sv&n¶Aôk¢W1îq¼á­2RÛÓöpÑF½ÍÉ µ“£òaí ^üŠP|ĆdñðXȼé-?¶/ ñÕÈ›r!·

·–Çñj]`éÖ¸íïÍ6`{eh(”?Nñáâqó/9øÒ½ßÁõÌäqü¸Tº.ð'T®,΀°Ä†@×_Ž@¬Wã€ÖéaÙÂg‡z³)34“ú£±ß<µëõ ½àv€j'°B4J%?zfGx(²J§`j&AÔ¡»bã¶Föäö½Î-§`èøBSoR€CT%ã%]'k‰Õîó»ÖPÄ<ÒVÅZp¤m~#ö¹šˆšªùÊl‘D»h6¸LÂ$6ë0uØ3TÔîrâetürè<TAñÒA oHhI5\C qnp›2âûv¼¶’3ý–XK§Â£2BâC~¼RмÿþaÝeatF žøÌ+"d@axƒ$ënÉ$S08¶´åñn§Í/¶‡h8AîsÜõ†ëkån¿oÑ w@©o‘1-…é2Ä£™ãv|‚7x]:àẂŽ<4`…©ŒðFQ«FR Rî¯@éÎ×ñ(Tw‘ñšsì„çµ Šƒc˜¾–°‡~.5™X>¼Åù™‡ÊE¥¬^b%GxZë’é 7”¥©vׂSJbÞf?Fb)SVmÁ`Â-›ÄHT?Dijvóeí¤¾»ÈÈ0|¿¡FQj§µÓýE¨z2Á  ƒòÈÐAгöñb$®½pRV½ªZöË ÉdíîÕšH*Úh,Rˆ×»/‡Þ•nÃOa=’ç°õ¾o8%R[jû¯ÛÍ#äl¤E›)Má‹bŒ/#¯^€‹¥%LwÀ:Y¾i~ Yk5µ+2ÝBô\¹šå§Ï!V§HÕT@T¨¦—Ñ&Át‡dw(f“lÒú-YÊŽîéÛÎÑný#D»=ÑÂRåÛ¸8JÒ•Þ£ãõ¦Æ0ëÔuÌÄ·ã}€ã#vNíLU•P¬,oï6ŽŽë4Ñ]'N¹Hµýڋã&­¬,I9¼²¥œè )elm¢î!ÜBدä!˜fFÒš#ÏEåÕÞK@>²&ùPÆ–DábàcXZD¬°”'ÏòjeƒT‰Pƒ®ÅC×™‡-Jh› Ý ZréMÈž &FBÔ¡óÆ»ñµ5n šwSf¼>†¨œ9fÖ^—‰ïu8r¶V¡¯¿ópƒa ž0<ÌzÝ­¯©ßÿ¦Ó!§}hèÎËúÎÏmlk¡ÖÄÃx‰_ãŸw ü[Âú£Ì–šðèùßvÏŽK"¸úgw:Y Ÿ=˰±¿±ð«5É„´ÖÜö NƒÝúN£ÐÂN¨ü$aZ5ØW¸ÝJ€ß : ZÄd‰¢ü½-«¡-¿âÏUù,A3(†Z2yÙ2"/oËFFÈ˯šü½bÊhõq‘›Y•¼_íÂÐC¥ªø¤þ÷³}¼èž¯!¶)ÆyyyÔê§o3ôýc·©\˜·ÍP²Ôm†ûrmÆ©êçÜf¨iÛ Œo3Ñïÿï2º>×.ÃÓ7e— x§qv­ßš³ÃDfYÂC5˜·Ã¤«Ó»ÃÌ¢´ø£—÷Gï0\Y;ÌeD›5c‡‘ÔD¬3w;—ûòóí0ºŒ™;Œ*ºÃØjËÅ÷™y»£AMÙsì4ù »aæ“´­òþã(rSw!;ÕGîEòìÉNÝ—(g ð˜(<»ê¬”HÛ¢’Úñ7*¬H[V$e»r’¤Ÿ"ÉþßÝ»¢]ö™v0‡ì¼|ÂìdvNk‹¾¦ÝL$lg³g¦Qc¥ÔiÎþ殢Ô+™Gîu SMÞ÷Îâû^”­|ìîçÔìS‰Ñt’‰óéÇéáœ~PÛÑâ‘<F›“·¡?I™8afoñ iÕ>»,üä= #Êæ~2e¿t/8Õ¹èÌÇÞâug|ËW~fÉÚò1[¾$.™p—KÊ<{ó§L±Í?ÒM $Eò¦å«Í[¬ŸúJ/Jy€umyß  ú¸VÛÖýL)稦p—wþ/c€X«õ´üÝÅÅr ·]¾M9h¾à!v—|b‡c :ú¨¢ [o{]ÿB’By^°î«Óe•ÈÌÀq}ñ›~¡vÍVz ÞOd¹ƒ³E]iS/t‡1(Åå™”á!Y¦b„îW¬¨%±8õ,FBY«gÙ±õ““£cå§E¨c¬.Šñm9#%ÎÛ6¦nCê¶ì®\ä…îh¼¦mÿRƒ'1¯éÜdÒ³ºˆ+«Lr9Ö;©7!7lTIi”´ƒ¶ ¤)šÈFõY"‹dP9ÀY:@w ˜"dÆ¢]ÊåÔ‘KFð’‘D®(H¦Œ0Õ›Üõº“[Raì) ûþ^«Œ+àg{sžJ %¾ç$ÁgDàÄ:Òû%m¹³? Æ·§@–Dý­‚ÓÇ(ÈÊW*T/GÏÿVß9mSèDÀèÈ"_@mÿ#¦*)©žA}uçíÊÑQ&” Ýlrh›UP†FëkEÔysƒ05ÞY9Êëk\Œç¬‰{#Š1;ƒƒóDË–UtÎÁOûš×½M/AIŸ4ÿ›I3D(°h1-§L:?bn㊨‘U4G[“¶R©9i‹ói/LøQTÃéHý¸2摵R*3v7áé¯Ç v“RMÁ+­TEÌNº@s:Á$š’Ï£l'EÊaöü¡ø/÷rRî]{ÿsyÏöÿ]û曕o"ø/kOáÏ_þ¿†ÿoùóýGN¸îüá߯#¸ƒÁ«ëb׃Ý͉?„Éø¾K/~ºõîï+¡ÿå;vœp§ˆW‡ž¸%v±}`™ÙòÇåÙÊ¿—âø €Îh:!JÄWW\û䣉¾šWâfì IB–Ú•.û3iÌP ÔÑ ‘^¼¼ £/¯©ªú4ùÞ˜‚aà 9)(¹)ÛÑæ÷›âøäè—ýÝú®ÈÖšðœµÃ]JT;;}yt"v÷›;ÚþAS ¦ä:©žî×›@Š¢×ŸÔ_ÔN Çdr†ôáNãlDsÊ·pÜØ‡BL~q´‡G‡úÉÎKxQ{¾ßØ?ý• ßÛ?=¬7› wx$ê¿ÔOEó%’±êõ¼.û¨q{G'@©vø«h×wök’Œ [ êäØ9:lÖÿ~Ô Ø­€ßĘU>b«^ÖN›GPê‰`µ ¶aïäè@4ŽšXm c EÔNk˜ú*Ü,A¾:Tïk];Ä í(é¡àÓ“Öâ°þ¢±ÿ¢~¸SǬG”$nHxÖ”J¢v²ßÄ2ÎN¹“Žˆ(P9¬3Mêxì ¨ Õ¡~pP#º{î@ШÎef¼ÅW3, µ_[âÖI½v£ò)àFãÞ[Ľ'_¾ ¾b%µÙÓÍBó íÖ6öûä–Hƒ˜KÚÒZéLÃI€×_è¨jÿ¯+ÿÖ{ÛCó~=úœlŠ‚ :™’¾ uX¸¬¸\$©PˆÆ,æ…"Ä`%à"†¨jĪJ ¤HË~7J}ú¥SšÒå ,ª”±?Ñk‚\ËUµPï ,¸3¦2ä1Qß„%–(³¤ ŒÔ)Õ ¨§2™Üx*!!ÐÑuoØÊdî;m8#"`sÛµ>%íCÒg6âÏÔ%g0a’=è_9—i"ŒtLýì½{ÅñÓ—[?‰œLïáÌOÔô:Ž‚¥ôkQªTðâTeÓ¢Tõ‘ü>—V<¤çtž1}g$—U’ɵ†ÒUÅcôR¼j–9s^…=Ô+{C?˜†tEÜùÄ©jf oŠjöô†]ãí1ê–5äWd Å+“´t%ÝÎ aˆ£¡Ä¾PõRðårÄ/&üÊ׬#wšëç)xx§‡h–/<‚¤r{Äbz=†æ‚«ÍpzÒ ¡”ã;Á ¤g¯w¯ÕXó§¦ÔãèxŸ8Þ„¢¯ù4IOÁµ!R§Ðw``«‰GOPâét‚©X. ž"RƒLNV€üö°Ès’eXƃïäøÊqµŠ¸ÁŒ5L^t'¢asW{êÐeÜNJ²™œ'‘­É´æºYmlNUz^§p9›ÒÍÀQîB‰ìÓÄJCú¦¿ˆšboŠ”ÅÙÒX›)ÕâjB^­¦¤%æn³Àt†‚b„Z½¼«iï>/z ÁÈÁµî?y…ÔÕI0Š[MbþuÐïwH Qœ¡Ÿ(ÐÈ‚€"!¹ÅIûõ·›íÍöúšPŒS± R  xJëêpaY¾wOzD LTòÑ=ãd 4…8”ˆŠy3¡£¼LÞ@gÐ]À eÆyš6Iü¦3šFÎ=õ 2–A—þö¼Í¢´(™S‘Ž»7œÞ#WBü¥«°«9Óüãh™­ûáÇs,w¤1&tþ]˜5ÙŒ É«k‚%3¢0®{&ÃóZôº½ |vÆ^Ø‹1.‹]éÞHÃŒÄ'18$¥–ÒŠ'žíþúù…ÿSo [%â|‡&PB)¸ûpP¶(w.EBª\ åµ7¤lx©B+âŒëøëFŸ&úch±?UJ—ÊeÑD`óX fûõãW£Uú\¤|,8¢0fÒì5æV™‰À«fxpÓJWõ®cÔíGÔ¿%L%T[86j6±24åùÙ~c«vÇb8ŸÿQÇÊ;6•TÍ™!¸òÄXF.ÀÙÀ†'îbÆð¡º¤×*fÓ« ãé ö X‚®²hÃA°ZË<]¶@•'ƒ y°-’µë„·~ßßÇ Š²;„A>H™#2»ÓFDÏt`F¿@ ¯)*‹ê›Hy„6Ì+Þt'¶Œv°*Èݘ{D^°Û³íæ7‚ƒÜ ÜãÊtèß8Ⱥª¨kàEH:[Â%*M‰cFˣ瞹-þæ¶\Š®ÌøÑ-çúF[®<3ì–/¸3è™Ó| ³¦}Ö¬+ì?`T{GØ’f$v+3£|xÔ>;ä›ÉÝ?|úƒ²B‘ëþÉÓh»îBÓßî˜Ï9ýí>ø¤éoJ˜þvƒyÂZ³ßÃÝÙ|ëÒfS£ë÷Ó ¶±­Lu:”Æ\~÷Qäg./ƒJó¥Ð…>fÚÙ?uìŸÔÛ§õ×§ø*ô#8<”'þýäO^…²è6½Ð*´;æs®B»>iÚ„V¡Ý`^…é“: ú@fmѱ̅Õõbg'AWš4§Ýòôœ–Æm‹Nm›ÊÇMm–̵ÚÉQéNÍ>'Ѳ#ùÀD™b^³L|&Ó‡¦?ðÀäèEq“bÎʶrUKlaµ±‘N¶V@¬;±7ís„2p´|ˆ½švxJR‹ÍhßÕì'Q¶71ëÀ—P›Å«¼¼U‰»i'¥\í¯j'‡‰§-5Hú ¥ÍR‹I\ãÑ<’ñ5“yNbKMêYeų‹•åöU2{›yvä%ƒv }Jú£9œåqQÅú‡ë #ª ÿ¾ÓŸ†ä–¢­}(ôRýœ¼ jÓù}ÃÜ}äfïh2@fé™kRºËP Ž˜ÃÒ.YoÇ 3—6çè½g¬£tq1;Ö‘ZÂ&GšÔDòºÀÊ’mHëÍ™z!Õ›Ü/í͸ ǬÞ4½4»7M¯§ö¦™x3zÓN´Hošô‹ó m†sÔƒäw+¢é“åCN SU,†s¥[ ‚&ÇLä[5ÓÄHÖ>E»H-þ™ê÷Eôy‹(=9’Í’mÚæMÓ Ÿ2=¦W}Xlé÷UtMZ7yrïØB_+Q¶…n©ØšJ]ƒq>9½®r­TÓñŽâðåvƒÓO^1³™] b`Uñ³Ao)¾ŸiÁãÛKãy%FѹâUGÒ¡@ûkð2´Ü ¡ÍØøj"qOÁ8vwåãFH7áÐGªÈÄMÕÿà ûC²Z0%‰­³HIbŸý>ËÑã“DãGcVˆâtYX?©ÿ½ÐZ«<]á%?8AÕ­d1éc,¢cJ¢8¬]žÏÕÌÀudÓdç¡ìF’PÕvvLY‰®±Kï´}ǺªMA‘XÉ-¿(ƈ9˜HÇíæ( suͪ‡ÏôB:7ý|þÞ}›W{: Ûá2úTW¹ñ×WÑÿcse}ãé7kð~õéêÆÊ_þNü·X7ŒyõëáÑqs¿)CºÕ^ËÕ}vÚl£#tó¸¶SgË®zsçdŸ<½dbkãÕ; áƱˤyŒ†wn ÕêBϸ¿Õúa`â®’’Ê$!ÛÞ[¯Gžg%Ê(4h&6Ú Ç!QÂöCY3³éãþ5d-qô´~?”ŽŒè·ö²öKÝmwÑ £›Ü7ÒÚCh´ JcN nS9t’º/ ^€Ëð­»)öŒnyÖ|Yhí(Š“3ýöêfÝÄÆlìÀ³ Ù~qx&_g–t8ˆ©KÑ,Í«Þ H0‘w“n/ˆ¾cp@çÝug8‰äœ{9’õ!¬â%d}çõ(¸&ÅÂ…¸R,\±Ü-Šwx ‚á3¯¦××þ¸µº²¶qŠ$˜½Rë(– Í`[d•ŒƒG©,&B‚ã| }ŒŽ<Á„FB€¦€´DÅâ3Æì(@Ú/¶ÅJQß]Å7V^®EI`5(—LXrÁH'²LëYæC†#€†“5ªÿ²lÖ.ÚÖQ¯ÛÆf„`P¢óå4Ä7Ó°ïû£Â*1â3!ªË-ÎnÇÁaÆ®¥ËUÙ(¨ÿ´×-šFå@÷túp2*P×cYkâk¡+Z;£C8LÔ_Á$~ßܱó²±[¢–qLåû(qêx[h§)‰¯¸!vnHö}¬bøá‹W0Á_ïŸÖw œ«¡Ï¿_aDyÿßS˜¤×ÓáðÁá”òPņ}N>¬•´ÝßèEÑc}WˆÀS^të]ù0é2Í»Æã† •êÁ’Öâ:ÂßHµœU/T<¥ER/„.k^y½B…¹Ó«.ò:“`ü eȼ*´âŠ‚Èàé0Ó“±ÊÇÁ€è°Ê DG åS#&¤|ÕuÃÆÓæŠ)a9rï©Ôä’Ô÷†7STÁª{Ž®ý jÁ›î¾½„&:bëjåiå57¥ÀŠ= †Cö}t~Úùúë¢N€CËù$v„l§¤UŠlë³cÚ€©Ç~wÚQhÇ‘ÂVÂQ__Y?_U2ÉZ3’v^ƒÐqt¸·ÿb¶î,šñ[,%Ö,²­-ƒ5± {ß|³x¬Äsª`“W…;[¼ Vâ9U°ÉrÔ]ÉÑ/'íüãéʧ\–ô½»´)à(ëš–‡ž¯C¢”‹¯í¾D‹ím/ì¡o."[Ó² ]+œ—PR‹”°Vq™ºlï-É+°Q‡«Nà>Ÿ«×þ$íèÿMüoðgâÿ¬‚È¿“ÿ××þ’ÿÿWñ¬ùóþÏ_òÿ_òÿŸ‚ÿ£rtPû¹þŸòÿU§A¹×ïý‹‘@Ø XúÇxÅ+”`ufeÒ¬UÊ=ôï|[ ‰Â›ÄÁ‡”—0rŠªóõ‘@Ù]À:Ìó £,]õó¦P‰1alØDjÆ"u´~¡útˆºõd]‰ 0!e“8äû§îžÌª—ë÷ÀÎÈiÝîÑví@]‰·ApÂÙ£¤ TæÀÉ÷†’$÷-7¨l2D8BÇ ñ%Æí–œ™6ßÏz®ßuÊÌYÄ{¶_v¤ß°ªx…×꺅–;-ØU;–lŽOöíÏÖÂÅ}¸­qúl«t0®ŠØVŦ§ƒÒCù-bkgÆrUì„YIÉÕ\DÆD E¹…Y_”KWˆqŸc‡< ÝõBcˆmÔ€=ÚÔ':[]ÙØÎ`Ÿi£9N²1â©))þ1µƒúá.Æg9ÝiÔk‡TQh5àEùh¯Ü<{BBSÆtùÃw-¶D£¥g6°TÀ WaÆ (svú¾ÇŠB ^#N<œøeú €·Ýøšà8ÑHßÄüU£ Oõ›ÂÆl8Æ$¡™šV Ái¼ m˜<ƒu}(¿&pë„ÎÓŽñkÝ|{v z##øf¬ô}§ÍÅN@àðL706_ˆò5›@s¢êìIžÁïÜœdÞ´ýñX$$gU.ºë¦uE¨ôÞÕx’?|µ†”î{§`FìùضYçCftD†HÑ@Ѫ‹P ýÞ‹P¼jÓãöåÍØ‰üo*Qe¹°[?†9_Ì'·O¬ýPíúo«Ãi¿‰´:ˆÓh™&ë²â½¸ëˆòüŒE¹+©âÍ!þ˜xWÙË á*@!Ó¶²nki LŠ,ž9ZZVø¿Oa¢õñ05!¤&fb·2NM}¬òfw\Å pÎn™(ßLÄŠYe~xtº6,z¢%ô²?'Ã{= «#Fåítø†Ge´m÷8¾À•É`”¥ï㬞­×”¾>‡Ùò^äšp˜Ê‡_Ê1ýòIy<€ùúeÞ;$ ôdy"Ùj‰‹ úgùK—l$½šLÕʲþ˜tüïÅtØûjfjbµ–¾éõ‰•— 4ç¶…âè%øŽçÙ‡Ÿî‰Žëöùe?Ô¹OÓ¾]µóËgâü<+¬ÿ~UˆÑVóæ„ÿ¥|ÞM ¹4e$VIòÎ…“§«),‰ÚhÔ< ­oÓÅ.˜Ž`˜‰è½r5›²©ðDJú†ƒ¸šÐYK¦ÃiÓé¬E鬧ÓY›Ag=k6Š9€“ia`ðvvÂän¡-^)Ð`à/Äág¤™Kfm2kóɬ/@»Ï¡3‚ àæEKŠ·2Ö¦x bõ×낽,™×|1r|þDóq‡æˆý™) ž§­3J¢ÚŒÅ¨Ÿ¦A|g[-6ž•Ìäiå@ŸVäùDž‘I-w~y^éqt¹Ä8Gx¾™øe;¥SƒKwYbVá“,u—Q bT¨ ”ŠQò³Î,ršÇS¼rX’'ysÎv§†©Ý&ãÞÍ ÆÄ›S>™ªŒñ>Šé-¤>ÃëÒ²€®Aà4\æ–hèR¦ã˜B<…>ó-0ÚŒP¸–Ó@ßðj…£ô•}dúôп3HiˆúKñ’ZÆ¢ÃB™îË[š.),kî!8ØÁª‡UÅnà°Rzxƒ#°Gà\ôQƒ5|¸Ég—ˆžÉLÙ¿3VŽ‚v˜¹jÏx^TêÒ Í=¥Ú 2¤Õ*Œ©\ö5W“d+KwÚGg§Çg§íƒÚþa»qtt¬µAòNŒb1''n*ƒ‚AòkoâõŒœM t ìèw%ο.\Œh“(Øó’[eš6=Œ…u7†QÃ)E2Dõ¡d*¡ã[¥¢ÅóÓ5.™Ï.?êÑFFè «c $ö[\Éœ¦w¡j3º¢éÛÑìþßø…þøó8€Í±ÿ]Û\]‹ú­¯üåÿõßèÿÕ¬Ÿü`÷®Å\³œ*¥ùf9‰æ9gE½ÌR½³œòG¹g%8T}^­…]± ¹Qÿ¤Ç¹)ï(×I»ç¯Þé¢Ã-(É‚þrÕùÏ»êqá][I ÊuÕq?Ù¾:±/‹;ë8Yç{ëD¹ˆí®“Ä4æøë¸Ìô¿ÄþOZz.Û¿yûÿ*lüëëÿßêúúæú7+ëßl®¢ýßêÆ_öÒþo\”ÅŽ>Ö(@ÔÝ kPA1A‰ (1ð¾o™ùíÅêwßm–×`€Kþ]‡Ÿ«OÅÞØ÷ESYèíám]º—Äþ°ÃÛý«1ªâÎñ"wáduàMþÕ»yã÷&%¢ÊFt¶ƚІ´~SK¢S:„O‡ýÞ ‡š€‘cfˆ6~xĬұVÛbáûAŒVCçŽ&‚:˜Î”ø—ný¥) ÚÂ"óÇoc ¼S8eÿºø‚b&S˜2·¡ß6æ÷›r1ˆôDè³}‚:ÖCå±}Ò‰UaE6y©wx„!Ƽ1ÚB><#ŠŽhµ„WÒP EM×NN÷wεq|vr|Ô¬WP˜©F»:Ä«øLÉ5ì;½­†€oÜ1à  î"1:[Èn.>ÑAz­_k@·Q'=oÂ[+ Èì~VÍK¸Waøæ¥˜+ëÿCŒÔÌÖSh°z3öƇâå°–#T˜eRIdD‰:}e”Àgˆ›~fï«Tyê|*i`¨Å$Æ>[0ÐGY-îˆÈ$0ê*5â-HEZ;£ Ø€øõ´âÌDš»¢M&š‹J;Ö_Ÿé{gŸÕ'0{£>:©y 5J0t]dú 2½š²)Óìš&*Ì%m„Mþ:G¢ñÒúØïøÀ|0Þ1™¹ÓãŸ?!ÆÃvƲOéX«³DKüûÛÉd´U­ÞÝÝUn†ÓJ0¾}œh„Õ*¾!—6£O¿UA¿3ø~KÍÄí*&Æ5$¾ýêõX-Iæ=ég â¯Ðº‹FS’­H¾7´ —‰ÊÖ×À¿ ȉâŠý§—Ék;?×^˜Äb‰ÌEàOyµ¤¢µœ(ôëXÚQH5"Í­â4¸f˦h¤«²šÿ6×QSeŠÊ­±kI†ÃÒ³DG0h»û's{PbR{ç6kMµû{ñ‡FÅoëq2МÄÔ ­¾Œ—ŽJH´—£»î%*o…X>ˆ ¾|þÄ FÁ訪[T|HœŸ¾¸Ã+šz¤×'¹+‘QV¤ÊnÐQo8î7Þ“$vƒ9ž[asýäæ)ÈÄ+ZÿXUB•B%[³½g%TÉQ›cÐR¤±k×Î^·¡#°œÚY#K`ñxFHÿÊ:ËÔï*œ¹RæÉÉ“8$”†”¹ZÕ‚=Ì£V/w  °È­|­@’z Ky ‡mà7WpZkýÖþ·jå´/¾Î銨dä> © X¡úÑÞ{ø³ÛxÑ8z^kðïFí¿¶àrô _ ­=’?kÔ‹9­ì^‡µ6ªÊ#4)éOdÈWKðNo¼1ýÆ}h¢¶ÁÁ†tg$ŽpçëØ‘°ç«© œ,·œñlœÊ™dV}TIÛ8mž½¨ÌJ €g$9zÞÚoñ:]óѾOHC°%`Ç:ÞÎvF¢|ýÁçƒ_¶³dM%ŸO¶³dГ5“<¡Tñn`uJ¤"ô]Š}D5IH¶J~žE0?Ú?;½††;š*5Í t‹6UÔˆ¼Ÿ”­ š7Èð„'•™åáP5<ŸVEKÙÆ9ã¹8}ÊÇvZßãir6^n¼Ê ùRKfª±¢ga»º‚ËùI£ª¾̦Û8lËqf›´Çwd’†?¶³ý¡(‡ÙHÕ)ŸS¥Òaå*RVÑ9Šª&WÙÛÁnû öºÝ¨F{ÍlîiؼNÛ9EJO¡“uM-æ2ôs K½ò(–’’Æ Da%€ƒÐ´#†‰„¡çNê£Új/öáäZ?}y´;»‚°þwÔý†AF;üÒK>jì¶k';/÷©§'â“S»ùëÁó£FJ3½ùkóäèè4]ðÕNë§‘‡%Áó‰¯âÑIýç¢Ç†}C°ç_á-ÛBáÆKÁ-ø8&Íñì‡Â>¹­Ë]fr;¦7·Zcf™¦ƒ|ÔñF°ÁcÉcy;ÙóÜ»4_ªÓÑ×PÞct‹ÅCÉâðˆú‡ºìrˆ|ŒÑ£çCÍJ¬;OkÀMŽŽaþªcv4ÖTÆëݯ“ÞNBû¯ æÍ#CúX3ƒPiÙ|ñbã‹÷û°$×,ÛB™@V¢¢eˆúw5;GF}ç”oõ„?|ÛC´2ÒÀçl’©Ê$Ro½a/¼%Ku¯Iã‚7~%cÂaa _lc7:eD;Ò­Á6½Qý>œ/Ë„P/úÁ•ç ´ÈG¶¥D½:t½>ø!Ÿ-ûòèÁAÕBsÂùŠ—‡yÛ¹EÔy'*úLØ ¬Í_vPXeKHdº!ä…’óÅJþ`X/O†É¾NÛý.žnñ ‡G¾Êd¨ÜÎÎvng‡î5j/àÌÉ®z1ô†¾Òª°8‹M¦¡iºµy`2Ø:€j§cï)§òþ oT úîÖÂJ·Ë)v·¡îæµÞè«~Úäj°Î­œ:í±º€ßÒÏ‘ýR)4E¢èõùRÁ¼ m×€+÷&V-˜Ñ¯¢Zè§m¤#X×ÁЄÒ\LRƒÕ†IÚï¦×¡5g.Ý͇vgÀqLL9v€7½}Ðׄ¹zåïhAK…*S6™|Ñ'¯Ü Æænžœ‚l¼£ÐBQ„z–!¨$#6oä~h¿—¼ØÎAíp·©Eb©‰¨\)43Ë^í©ØÈ×þ{óL¯ÂIo"ï^·ßúýœ$à +€`ôÂß§êVR 9ï%ñÜë¼ û^x‹'i<Ïh—å‚VO¼‡ñ8j®>Þ%(wŠv®X(ÖLŠà •mÓ»6Uy;VÏ ­Vö2w~~qq^¬žŸŸ¯Voò´ñìÅa¶ßút½ƒ­AÕ3QÐKf'&ÉŒËM.#¡ˆXß¡mß“ê)ÒÿãõÙPî|ÝHˆ bȺµv©yÝj¨Rl«¾ÀSX‹Å¯7)À:ÔËtx…|ç=Ä×°Q;«Û2…F'Otß<^Z¬ ®„·ÖI"Qâ4ÝÎçÌC†—‰l[o«š®¥ú2ƒŸy,\F­Ó™¤~gi#AÒšX1X+…ËÀ¹èY¦D”˜,Ýd8[„¼'qÌ-¼›°DCojÉ›éN„¸b©Î0Ô!zC³Ù{t§X•%/w<ÊòÔðÔ*' ŸžBB<Ëð)¯ñK¢ï]ùýŠÑ*&%þ[VE§\Ç¥îC'þ BÑŒ…CEêúp†û)md3ˆJÜÌ%VC=Ÿß’qþª¹^•·¶¨Àv9¿ô8ˆäOô•Rv,ÀîÙWð~¬NI4‹)} ‚Ââ=i÷ßçîºOé5Ý„ÏÜsV×Dz¯‰†“ê³Õ‡À©T䣦ç¬Ë“¤r±Ë’F”®ÙR—^ñ;z_øâ×O¹-ðc~ÍñÔ튾ïIÿ4‚í€e?~*S Pk3:óžç¡¿O¯>DKÄ­Ê!•U®»Û@j‘‘ HÚˆ0+]ßÈäl8QìbCè6'>«D s\¼ m÷…–ûÄI~ËøgIØÆj2µò ú]àw¾‚Ha€×Ý*{ë‹+9å¨S®d£ŠY ^òÿ½ý×õ-QG+¾!òbmñP4g{ A(«Òxìå%›$‚?gð§e¹7Мm–áÐð¢¾ûãÇOظYˆ®ŽŠN£üÁx¤YDH<Ó ýŸj¼Ì_Àë‹"“QpJI8EœZJ–`ÀVJ‚LbÖXò¡[=2Òb±\ ¤\,oyMù YÕ† –Y–\ÊÂ¥ŸŒ88áPß»–¬8(»@ÊNelº"¦ûñ5ü·$”˦éu&mذQ8}ã?˜|øÁä‘]GVßhå›ôò_6ïAâ‹Ó¦ÓãºÌkß Ò'fÅ“¤—®2ËßýQzÁ©ª<ÅçîI4—'Ê£ƒþØ¥ñ)‹!:dñX;³Jõ°p÷rÈf(C,Õ Ðj=[ -çÎF6bµR©|Tíº&G;úpÝëÃv^°G{=÷“¶‹¤mž=ÿ¹þ«éã”Êóq:Ü­€ÜPÁÃ~˜èÿ¹÷¢„5D í}¹% 5ï|‰²@zøßªÊËSÎlÕq±YmM‚‹’ˆrIjý±¤h>¥›C‡FÒ0“æÐ4Lžˆn‘‰SQ³¨UgêVýÁµN¬v÷1õ^K¬·ÊÛæ¥öçÔ;R¨\:(ÞQ>ZB‡©5yÜέ 9+5´àX©²TB7¨b)ºgÐìÄ?rAqO’ôˆÎŽú½ ÃW ¿›Â%ƒmÑ‚¤¶}{vãTÅÔñàŠ˜­åÔÆ!Z/ÆØ2œkÿL¶lGsêc ”¹d5™'üÎíÝ÷ðݦŒ:ÕIf)ü§yCR'G«ïÿô†µ”>µéÄ÷äÉ“äÝŽšQ‘ZXüÉ>#‘;m°5¼¿–£°ð@²¿“Xè¥)-T>º€‰¦v¨ï!6ªfS‘{ôÆÁ–x Á—œQHn$3:¡$+Õd æk”ƒ tÊš£GªÃ)›ç¨MQÃ*ý}ŒfôP·»`ü&íÔívŽRnu;¯MÄ.àÑØ‡åÒt³ÙËüœþ¯±Aèš…Wº1VÔrì sÅw™vûCЉ¶¢xÍæ³§(ví@hx™Šrû¼óeϳažà'÷#ÌY ÀÀ™Õ4Ý¥Žü1È÷Bì[%'–5Yžá ÓQWÏž*n»’üD§’%ÉbmKúœ‰ï!ÿÖxÐób’¢8ˆŠd~YááÙ×/ÃËÌe öŠ.<ŒEÔ ’\ñ¢è¸(erë„i×}Ó Îôñ;JAˆ¢²Òø¬£]­"¾sÛm—£%QUÇ©Š˜ªœV˜¹7n±ŸJäMP{Ã"Ë ·ój+ÊG¸“1bæþѤ^”9Aªú=B¥L$R‡¹ã^þ|ñ«NÍ6 +š}Pºtuq’²-3Þ–¨žŽ_…þuÔzV¢Êy`3ÞZ[Ü‘7L턜à‚1»;ª*m6?Äó/ƨ…ºÐ›(SŠôMÊx9Ó’¤WŸ”.IB0n%ì&cŸ8õÎ…îÓð–‘N"‡gÝç9}ÛeÐãq´X$T;6Rœn·rZ=ʇ÷;övËJ²6?‰ûõ1õ¼0uÄ»6ªZ¨£„nvOöÜdö¥2†ÑÊÌ^k·¥Ñ’åŠNÛQðrkÚ“æe¢˜kݳËZIe¬ˆÎD^dF¯.ð¿8]¤(h×ÓxdÛ‘¾—c²¨ÁFç‰p5ê¡J ׳:1•Í»}Öña ’¦ñÍ ÊææoTËò¦Y<0e(ØÍœÆ¢ î+‘f@éP¸ËË6ôC@&¢Óâƒüj[ýp½ób·pÉ+¥‰÷mæz¯‹€a¸ÃóÏ9{7¹L{C£¾Ç}7d?S3Éà‰å#ŠTC†¶&oÐzÌC¯Pºó&ˆ¼l ´TR×–X“¨Ve¯hºdŒKÜ%sáH²€AÔ²Óe©,=°ý Ù"·¢‡q=Ú3Käýl.K™ªÕHI·Nµ-áÎwFå˜PIÏì+6úÅØ9\ÇxíÁƆþ:û׎ÆÜ B•Ä‹x2³'6Ò“«‘nœJÀê&¾Ç@”S8Zwø>ºGF–ÅLx7äÕ9Œ‰ÒL:ýÎ>Ó8©ÐªÓ*–oI^ïM˜[Äu4´cA‚tû(aM‚1Å*‚CÓ–¾iÅ/ j÷\Ô´rdÍkWàý{Qk¶±¥°ZÄõ¤?mçM²¼¾óY £ÑçÛG4A‰é&EEI[·Îüqý$0^…Îà&/ØÜÙW¢3?ËËav]Kâ)waªïÁÙÛÏ/Ëg¯Å›ð–šz|ÔD{UZª„$…oÂm4îÂhs0é2$EïZìì’GNRɦC´å·Ea¡‚¯ýðÕ*š÷Ù 2q;®\äM>Ñ+—`(•b•KzÏÌ9“©ežL/ómW™×ö–ùŒ²†„—ê§2ß#¨¹|C:…Èx'™¢¶—}Mà þ_\KϹkX÷èHØ&˜oé;‡æRÀ"ê÷ßCCÈ£¤~´—9ϵ.V3Ö›|æCFkN¤‘•¶¡“æ¨È‡’Õf-qž¹° WwZÔžzd¢y~Iµbë3: ã¯l–_œç ýΞ_*W>r±£ÿ.ñ=$»¸.ã²Y(š²nsº,§Õd5mOEÒY\~‰Ì%“Ÿj&–ðÄÅ€´e„4ñ½í]õ&í!0•;”U’î}󫨪Ä帹ɬT!«ïZÖÊÔñ“‡©û¿3Ne_}Œ/hLi¾Ç‡ÒΜ°ÄÿÛ;ÅȲe|Q?¬ÿ©ï’!†à/Ú4ÿ0òå eˆèI`:iq†Yñ€E$…¦8À“ ƒŽÒ‡Ðq/@Ñ¡Qô ~¼UNœŒ#üF!™{¯Ý…LD6‡véˆTt‘ÂGãYKÈù‰ä—¾È  ÒñÉ€W‚ºFª?ñïñÓM€†j’B¥TÒ–lÁ‘Kw6`S)ê ø« Û¯‚®„ua<Ó™Œf¤t(3PÇâ÷_þ8(Ò^uF‡Z¾-ÁÜ%ŸúOC(rnTâÓ-âAaâ_0±‚WR‰Õ3£vGrüŽ9€}Á „Ѥõ"f$ç;´¸àxC‚@¹‹ºþÕôFf@HƂס£g2'>ñHLççïáGYöÁO*ë‡JV‘¬(1v8±o±„ŸRP‘W⢨W†¥åæVð2xóžðº˜Ñ#È|”tÚ76k²*Wóôdÿð ] .pu\ £Ê¨ k³÷Gá(fG1†¢h(–lä:’@8x^o‚ý}wKËœ™ñÛÐØ% þ¦FZ«JÔ5óé=þF«ò/BË€jÉ¿ì3Æ'[Q2Ÿœ¿˜ÿ–òß&çÇT ™y²aî.åîêÜôe{Ë$剌I§¤ef4ü“Þü®3;œˆh0‘墂窟œZÓ!0Ãà•»ÒÍw‹º(s 3=O«–›˜7Xt½!JKŠ)j곉+û¬!¯!VÈò@ŠØ 5åìvšÈ}ñMZ+&ÐõWrëd^.?ÎS¬Ì&¢6„Ô,Ñåf“Qz²•¢*LËvqrÃVü– 2zžÙeØάLÂcë¡bùŽ2Ç|å®F,'`ZiBtß=j0©IÂZCTE¾ñG¨2B8jä.º‚ C¿$ >&0#ØÅ‚ô•„}í“c È-)Í&êvMH©Äye c¿ˆ%âlCu»%æë:@ã+j£žvðü³½Å’ÛôÊn<›PhËðB¢|xS8Üæí¼S‹3›¶Ý›é'5¢Î|I È‚©UÇ…¥‰œ“ÏÕ·*l,)8ºw)·?¨{¼Æ[keNª«2^Íy0JªÃYT¬ä³'Ùá$¹Òjad:t.þQ‚§º#„§Û%Õ,_a¸Zn²(7³Ö2G—]oÀ»¶CIÇDÛ.¡ìÄK‚$`¡4|‹tW• ÝùE.žø–Ì/²£nœˆ ²“Ô÷Œ4 øT4&ó(D‡ eZ‹! ޳z¼‰t®o ÷Žxäþ:{# ~r γ9™ä\m§«Y±*ÖÄêSJЉtš¬$ªt§¨%vm'H>lrУI¯C–úè) 9)%EN¶ýNNë[bç–q¬ß|™3‡òT^û_?Þ žvq$,ãcŽƒ#¥²>í™s·Làƒ‘Í`põmOƱXÖ:c¡Agb@ªÅC¿ |Ñf Ýîƒ` y+Óá ¹(o 8€£wú¯M$yR;ù•¼ëIjŽßÆ#26I Dd²¤¬^ZZÏë/ö£·ðiöIÏ’Nýp7J%#Ýžyù.™ Nm4¦Œ`ÀB:nV^ðg‡Àbh¿yšIEj3õ\ˆ¾¬x uD;¢už2»? ,Ég%™ Iò8@’I" ‹{Ô‘ZQËP"îTŒüO"ò~CßÎb_ù?]yPþöâøXPÀ6œì¬¹&"Ð 6èÝÃÛ“jcXpc¯LñÅ8–³Íª8É×iDœGïë+AÜóIUªE( N"“) —!â‡ê&{›k‚˜)l9×Ç“ë½ßeQðîöNÃxAŒ:¡~W¥‘jð# ÛP­|î÷}Øj^£´RÄfw¬™V'È­ª(v˜n|Û´žj?TÐ$´e¿8bÜâOøOËíÖ•‰6Ú §W«»Ò$µÓŸrü4Ä‚ù†WИë…“uƒíø• Ѝ¸Ê:7 •Ùƒ}¹ï“›³ÒA‚œ¡É¡Å”ú+©2Ëû‚ðà+U*sB½/}Z‡™¹eC¦å„¦{(ˆÍÚ me…Ö‹#<¨ÒBxiyÔ¼HHOV78Âvúë>0yy¶6ÉÛ]J]PdÔ` à’¸étn 11Èàƒ‘$ó«×i“…4ZÛ‡WM[Τ[¹wnúTØEú—"CŽÁÿ§×'¡ ʬÿ2¨ÈHˆKjPäo^(ˈâŒ- ž7Å6Rc¯¾~­ÙH„¯[¬ÁI-8‡ý®èf'sÛ…î!Ó· 5L?¡PJ)ßÝìs ݉”¹3£Èx‰;v;²<Ø-qz€Ï´j- [Ýò‰ŒÖï½Q@WhwŒ=ÑÀ ¬C›"ä:h剸Rˆ0£UXŠÓ,³Ã&årj'wºXÎä¼êèer&çuv]·šO’úš>E:ß]â ð@ùc2ùH{Üܪçí"…¸ wŠp>  &üÅü‰JÚîÛ£ô‰J›j¤ïŽìbÒËS=‰,Œ“„…a§´óÄ^'; @"™¡³ƺñ'Ò2‡=˜h Z‡DÜÆ°–¯¿.r°‡xRæf}já2=ÇNB†ÔÔ<À:9 ¶©iOÊQ9µøI("]Cë’™Ivæ¥íž•äd'íÂáMòUt·,²7Žï„[˜×høKúöÔ];Â@ ºÙÊ,˜²è_«W½¡7î-JGi!ú› Äõ&³Š«+• ¾\¡éQƒ “¤ÐBe‰K1ºSÉÂä K…ñí½í ¶IjU.-ÉöPÅër‘J™ñdI<×µŸ"šr TkW¡Ø¦h؃ºýq¯ë#«?WÂ!ļ4^B¤"˜ ôýÁhò ¼IÄ”•" ^±‡)P- š=UvÀE ´tSÉ<Áë§1Ù•f‰ÝxZÎK]#ŒmgÖ”kDªÐèy«*YBe>çÖùŒµ¬“KIV’‹â¤˜0ÜÎSï%‹[9–ÀQÓ†QfrÀ;°ÓË2QrÁO®±©Åü;ÇäÚ‹Ñø>±í[lñªÔ5Y͇Û'†¡&t„T[aÕ%*M4·’¥²Ø•2“Àºˆ‘ú6©ßS: ‹#'*]lh+c)‚¸¾?€ÑtÌš^”]krä†îX•kЦ°(m$l˜Taظ°×äí~§$r«E–F­”£gmv–š“H;p:Þü’†·0@hÏg˜Ø²ËÌXÉSÁ*ƒbx´U Q*oã½ ’¿”`Io šŠ ‹‡=„\8ÏžS\v.ÍbÎÉžÿí9Mˡ׶RoÃÇÈ+Z–X$3?£øèÏ88:ÊvȳD<û9"¨Ê[scO(ZòÒj ¾d «6«þt‡'†¢iÑ5åc¨à„Ñ«fáÞͫ؂VRã#š‹Œo˜25"œœHsÒ\ ³×ºo;þ¸_`þÀLZ~?ônàHŠFÝ4ñ6õ^œ"‡.öæ•ñ<ö¤”ÜDƒ« ”÷°â¶©í`{irû³ç9¨†­Ž:Ï%õÊëç9þÿˆ†â\E•„_zÄùƲŒæs8.Ôoç¹1.Çêy. ä i Gäâ{[Îæ£Ùh#x¿‹µa^½ËWð¥ï/TÿÙP½È;]²ïßÿö¾ý>/¾²fw#üðÊÝÖÎSöµÿ÷Ž‹»i/4VÉ=Uö?kg}þ 0·¥Ž;›êµ"âבòX©cQ~ãû£öhÜ{ Ç ¼ªôÇCÙ!ˆå]j§lpyàaL³J`Zü‘³Ê¦ô¦VBGþ§Ö×ÿ3½9wª¢i+ê8ÍÖko£]šBKã¨àRTEwD¾þaŸ¼ÚþëÂ#Pa¥°Úè! «'½aoàõµ! ‰¬,ÈÒ-”F»’¨¦d9ð6Ð_JØÓ;¨‚Hö<Ÿâæ–ÈêA±BQ†cÔ%má?ÊaK«ïk‘9”ÑB •¼]‚Žòƒ6ÖÓaO¾ÄªcvE # ]äƒ ›ôÜù÷=Ø~•¬Hٌljl·5ƒq—ýô¥&ÀëÝ‹>‚ƒ §^i7'.&dSåüÝí]S,Þ‰Õ0ìJ‚ñ—WÑÆAP€ºd@YrÿF“Yœ‹ÊoYr±Þ}[Ê×QÄY2ßrÃöQ$ÅX17Eë‹ ,n½ÊÈÙ­ë¿Ô6q¡ËÒÖ(ÄÊ.wÖ]F ¬€E!Dõ@K²²êþ€„öÐQ¹É0„ÕÚ‰ˆw¨_¨þ¶"ÑÍ<‚Œx^hý&.–Ï‹b9W=_­ªÏ#üñARþp‘wîŒÆl_v§ƒ‘(¿ÔÊ9¶lñÑ r-nȇØi¯Š´,{IŽÆìÇ›e¼OgÁ^º°v{ÝØ$¯d"·Ú‹Õ=åôµHk_on|ž_÷¿üsà0(uÔ¡ò ¿5éÉÆ»µ ‚Ùæ«v’æ0uŸ3™ì]=hÛè`[hl4_–ù£Q-,“qâOÚêóÚÎÏÍF­ùr&>þή[ÄUfœík Ç;ä‹ éþÂfü„Ç‚žx£a4ör¥Â¨c"òâ¤×™öQK@—ÆÚYh­²¹¢5¶„Ñí’ã¶áÖq@“…wƒþ Ý(#£¥/ ,oª%v-PbèZQ°# ã6!¨ÝFcO»=‰Ãƒo¶óçÎù G¨¥IÿÌùÌiÆi—ö_Z·¼E1̘Äu%©ã—%¿¾înG™™+@dVrç=„dAØ#ɘÉB¼Ëh ×Üä8l2ïY\½8Í<ò'Š‘kë­¼ñM¥ÂKómËšû@C­"ŒOI2¿ú#OÂá¹4$À³*ÆÐr!œY—C¯H‰Ã=fàµNêͳÆi¡ÅïD=¥$‚ñSÉâ) ‡ø##X¾¢5Ä´9E4…æÙ‹õ¦„MzO¨63``rïž×¢È0„@íÿ“×½.2}]ÏObÒäI•-˜ö¬‡g “‚@Óé £Ù$/ gÑ(pì£Ô5ìæÎ9®í!mcÚàIŒ\"Љ¢‡³— eèï¡„&3d°ã§ ™»:ÑÚ„‡ ^ê}‹t§j;MÚ:Õ¶ŠÐ'¸ñŸ&ùxO‘hjéãá2` \3‚ zÕ°§(æ*´ÔkÌÖlC×K´ÃB«\Ƶ[–)~ú~ë§íÝý“Ÿ¶~ø‰í&àD ç`ªCPO†E¦ YDAÕY&ªêdXÝ‚û¼v(V;–<:dZ6Ê!OÏÁ—Ò~’Ù  ù>²_ ú«0 °§ …¨ žB@[!È2Ÿg!ýãIÑTù’ ÙuBBK°bü°˜I¸¹{±³ãèˆ,j—¤}(ÓVìì}ÿôìRå q›†4±«„øâR=—†“d¬È ƒ÷ù|ÑzÁä#¼Ð¡}a§˜†§|º§êSDÀ+’è<ôAC8J:i^Èr$GòÎ4j«< >Ä–›ù®½z°`žd8‰~ŸfF2Ör¼ä«wÎLÇÖ„•îåW¾Ê˜>Ì@xQÖkÏh‡±ós*œ+ÍYiåŠÄ%Çou´Œr?輑‡ÖØÚëöBT¡”ci!µ‡†´¨Ù >U"éÕØ÷Þ LŒ5ï“ÐÔ ™Ú÷¦ < ã^!ÚvÞÓELFÆWc½^IG$DàñnH^–ò´¾¶4·™87A€Ê˜þF%clKpSïyp(].ߎ¦÷4åYAs«=ß'ü›lG 2Þ9Ô a‚ˆ†BvÓêô÷•vTyÜ;zÏò¶M–ò¡• £vzòk»Ž*SJÑZÏÔ„K:ú]õ†U‰oó_Ñ‘@ب7öÊëkh©ðòøìu{¿¶¹Ç»úöúZæ‰6? d› É67t2yñD<"bȃ¥jz´7îÝo~z—ò€ÎïÔÖÒ"1‰|®±X?<Ê‹¬>Ne?¥¯“o}qÇmß §í~Dÿ˜¡y²¼¾† ¶iìnƒ¸ÖØ-÷»Dyà÷¯××®ÂAo”ůhj²|È#˜’’××LjÖ¶¤eØÜ¸bÚqÛË4ás5Ç®WJ+¬ûæ†J©5ÍÇ“2Í an——a¢|ŽÕþŸšþ`Ú߆¡üXž`†‹(A'ãß4†%˜¡pRÑ8¸á£*qÐ|£}5 #ss¹‘¬Iö)Õ“Ò¡?´{B,%‘ôÙ9sïþÛÍ6n4oû*ì.—y¼WoyB¾wþxÔÑ3ô=œ=ÂõïVÌ ù4]ÃoØs;Úlâ0˜(¨  UVxa"JAÀÐQi„½ÉTFŸd¡Ç "7i] |Å ÈéHw<Ç—D7ÀÊóLµãH2mã\@¿ëX-ò´E¿"¢ƒ(déñ "…X0” ` Ã`FÕ¸|‰AºÈõEEÅÄžøÓ6÷ yýº2 °ÇÄùVäÛèÒî­C†kH˜å4È„ 5Åž,X?y ± ù¥4ñ$¡Ðõµ6e>áeèŸÄäTG;)­H«¶rùln€øêV9±ðþhÔ¡TÙD"‹H¤€kô~~î6¦s3â‚^¬à6¥µrs_$1íOžœ~ÁÉ‘N ©—(Nèæ¤Ü‹äfMe§³ˆ¤ Õò"˜=RóEi’¥ÃN°^Y{ûTrù£¡hî‰#8d6ý1rݧA”NIå+ôcˆfÜÁ¨,­9»Ú¹CCJ?£åa´£¦”_ ËfâGÀ0É ”ÀgÍ ŒƒXR.ŽŒ¢r§#íùð­"2@e;ÒÞ~®·Uë⢄ÿµO“C›M ¿ ƒ «"ztìÜÒEŒnœì¶„oLÝή&Ö*ßVVJ¿é„bµB—@Cfé3ÜTh\ÈEëJIkªç­aPó€ÏOaЇ± ÿ<)õOÛ¸ o²ýbÇ*³ÏÁÐèĶkˆIü¶X(²×´dU¶ûQý7‹I™Tš™šå¾(5³ìÉiQ’'BÂ@{×*k«xë¨Æ³ …­‘ŒÏrˆ`|7ƒ‘{¯ ˜aÅö©5ùE¼7c$é$û9­Py)ƒþd¹ü˜í8žSØæiÃsÖZÅqÇKñNJ<Û¡kütçÆö›É2Y×Ç&äAçM¸¤|Òúp[½æ\/×"0GI§5nd`!š…ÚII´(Ú¶ÄÄ[µ“moüAþlóê"úFz½ªôŒÒ¦mÓK*:õéÉßA‚™%NXÌ_TÑ?Qè=©“JO4·½I›â£®0úVz‰RX^‰I7}álÉ‹èØ9Ìæ9ýpbBç@a“ñÃv½,sªÉ7³Ÿì¬I®kyãÌ«XK×®cj#XeÿwFpá „B}N¥é”î=ŽÂ2ÁYâ*¸™Ê@ä@T‰y\[mvZ‘y’Z»'Vņ~RÅÌ"Ž ÑOñe¬DÁ#5Ú'ª„ãc ²Ì¬d¿—Ùáo«»å„O1B 'ÞÌôx.ßÑzÉWü×>Ý¡PÏc22gâ® ç¬f!Rì¶»ðjçåþ/õ™Ö,-ÊÍC—±6i)ÕëÇ%²A•Ä–ÔŒ“a}"wúµ½½6Ä·0™‚!R#¹ÿãÝŸZå¦Pv.‰±7$ÛE§XþHåòÏXÁüÚ†Jií¨$í,/,Ùýn9œ<ô}›í,‰]‚AƾÏDó(“'t¯£ab*øÔ¶™£<   Uømjó”aàг,gb4úÍ •Á$œ¤fŠÓµ¹ì=­RA†÷nÐCáAŠYIbM²¹¤×ÿ>WÎÜå‰8ÏÑæÄõÌÿ¯O!›FSn¢±^fzö«TZhŠ‘Ð+²n´m›"0¾±GV%ÆÕe´ÀuÔ¾îNÒ¤ÖãûµØ†™<ìvZ ç§’ÛÝÀ ÓÖ]z¥­‚È…bz3å #—ñJ°ØD€H²%Fˆ™…•Ùð·(?‹!ïqìÇ‚Ü&Kâ—ÚÉ> Ae4ï- Za¥ÌÒ“'-•/£€À11c¹y¶³y­7{µýÆÙI}á@É‹¸' ûŒÉhùæ¦N2l±Jˆ´ò1¢f[Ge(vßÈñ¬€¿RRΈ2…Û×L„¹ 7EnƒÅ‘…`“ÎiÂüëSXÑëY‘…fËèÛíÞ°í…aïf¨¼ÁÑž cB[‘ªöSaµhâD‹¾Ls™Ù²‰6CjW RX+ª¥ŽY9N¼9¹gu²UX/ ©_ö‡Ý S0zg C桞C›kJª¶Ñ 9,5S’v“Ý §8ÒçŠÛ‡ðù"ų£ÒqäÅ0‹%B‡–B‘]ÈjOmo{ÐÓ(X°|ùÖœ#Ó}Ï-3C¥í)lÄGinLÖGäò´UáNþpþn¥´zþAl}•‹·Ø‚+og-4¿XV=}^Ù±l_ŲåRmåÉŒ£@æ|\ãóì9ÇãÚ’w[N6Œÿž  •¬•:Aé dZØ•‹bU¨uëvžûÄWK‚N˲@` LÚ¢ö/‡>´¾8k_ûnsså[«A¸fÍ>ß^Köz¶qÔ¬Î]ákMxw\/a?õ7o|l†8Fý&l–ÌÆBúd0ãÑtðûÀg‡½ŽÜÔ&ÙZR0±ã©Â䥇 #mé#Ó†ÕæmÒ¬býOÇÓÍŠØW»±ÚsÑøï½hC¶‹QãØÇÐÕ¬&dè`‹¶7ÅYöÐK™¬y<Üž•3eŒÍõo7˜JúÒ¥–'y1¸)DùwÏ:)piÛã,¯.Swÿ4ã}y9åX»¥6lemceÅÊôBôAëOßnÒ/xµQY›Þ©Ù÷†YÀö%ÙÅ gì¢êO:Ulaµs]éVñŠÈ9ű)%¡ì"üˆÎù*‡ô‘ˇÕÊr«õD\\T«ùYÒúÚ7›ßÆ:kf']n qˆL ‹.êbVËédµ»vš5x¦–Ñ\4ÛBݳüDFhõí’8@9Âþ0DÁdËéªwƒ2¼¼­ øHÂ̰§«( ‰ÕŸ%ª€åÂç¬OzP9(|-žjVÅšX nŠoÄ·ÏØ²Üô­6Ú‘æû}cÜ(ÅWW©»4©È±“®hzÒàÖë_+IÑë ÔINbº&ŘyØ 2ªÇînñ¢ç×÷õ¥?|«”f‰]“u-Ìÿ‘ovr¦gâCÔ: f»ÊKE¯~Ó¼—ŃZuM<·FÜ¢ä®ÇÅã©ÉÙ_‹ÕËOb”LÑÁ‚ŽœŒ BÓNI’ÓI(!˜hï¨,°dœþÈŠ-‘­,s°*US«žº5pz7C ‰ç!¬ ×ú.ë#çÎ×_[R,¼CÕ-¤ë^6¾…¹1ñv?˜*–ƒˆ>|ªÅˆnÒ2ÚÌ@…ƒQ¤X—¢êþD%¡#¨p¼(¶‰”äHâ©|OZ»LÅè]€—ÚÑ…-_ääÔE —ÊJ<„¹AŠ5»ÚÉ"æ=enÀ‹7Yä)ÝÀÒÌ ¢›¯É#4!H¹HC&¢:³Ï¡ÈK(źøxY¯íÖOÚ»½Ãù,íÔŽ‘'€æuû×aå–c¶óÿ ÑþáNãl·®oÜ@êNthÍ“_áÍÑqý°Ý¬7öDAÞ§ìï•OOÎê%á>—_•Ïš;G'õÄë6uTé÷j¦C`çä¨Ù,ó Ñþá‹Ïb° ýé¶&é*Æé[ÎMyÙbüØPÞY2›ÆU#¶èÒeãB- Ä+ìO‡xžn¯<ãçaО‚8ö·WÕ´–ïÖ8›ºU¶)db±2äÅ ãÖfMk‰ñòJÙöäÌ,I?~ =Vn³0ÆÐ¶—hæOÍm¿4é¾—3è‡Ìl³½ëŒõ)œt{~Âü@Kœœ6vÛ/GÏk v¿p!î6øí“'Nê¡%ï0÷nÃÊ›œÛI¢r'']¡$TeUóê2,nýoé°cglÔþñkûè¤}xôJ¹Í9ÚF‚‚ã{ éèг ¸È²’–Ò6UÄrûÑX!¦áÔ'ø%Þ+½ì;•δ^÷ž!1ƒˆ“Îqê"k7›R4¥M˪”C+Z4¥K-=ߊ•…;ö Æg®×òõÛ^(ùööm¯ÛõÉ^íæœa¤r0:©!ŒºÇ ëlyŽ‚!;¬XÈž ÞÊî™°ýótê\Òn¿8<Ûi·ñìR(ôãö¶X§KRõê`ÿÚÛ?à‡"A!éÄ?à+Žt4DÛ¥Bèz‹@zõÛíBÁ´¯•çñl±X|¦»Âɬcìl¬à©£ï(ü)R,“aÓ¶èöQs' +%{ñ½ŽRñëxs4´o±y«€®E©òYñ±x/tû >–²TM¨½òzq j¶úÌŽ£&SjŠÁÛ†d”šaÉÏ, v¤)à¤"!BWÀÞ|¢N00³º} 7é<¡\Úðð $Ð_„;Ÿ«ò,óáŠswqBÁÒµú‰ß§;‡ë¼[¨TUâgPî™(&ÙÙÕAÞ1xbUÌ}N¿7Z–ûȸEÎR­ÜÇú¾¯Å¾Ëiòþ~>¯Gœlh4¶Ô—í|íhÏ×ÿ¹uöÆÿ'‚¤X´‘@]®¢¸f¿NEÜKÖHŽÇË_XX4¼ÀŒ@î¼Þ62ó¾“næÇ6³ë4FTé\'£û ú&¡z²¥¹¯/)*Ó¡ Ǧ¶Ç–œ¢#AŠnw •¤ý^'ì¼/¼?‚á†ì…3Šìt»MÅa<>Ï©XB¥Ê}ÌÙJhÊC¿ûq}/¸¥ì,Ùú<?`“ð~ ¯¾uèkÆc>=Þcˆ1Òä÷ðJ¯7ÈÜCøk¦£ã–OÀ$S—MK¤’$$6*5·yV>fÔ╹‘Ñpϰ¨w ­ð¶¯">Ñ^f²Hë›¶=s‡³‹ãé’H#’2¬”«©”™!N”D§'d…?ç“ÕwI†o¹•Ñä %’åܺ‰ýh³“´ãÔùsjyõ‹ÿâ¿Ú½ÎLw¹»X¾×ŽSY”+Gù2M)½Ï»ßxm¡gŠëV,û‡Tè7׆L vŽ•¼üe°!Õq ³ß¶o1Hô¸M§¶ö-iÅuæ¬Î-Ê»öq/›ÉÌŽdz×§S(¹>k#Ý»>£¦ªhh­ %d¿ "¦#Þœ;eí?Ç‚à_F­ÁG·i%É&‡Uv˜žF˜D]žêM²Àç¹[ùÒ†è‰HÚÿ z? ŠIÒ]B…Ø›. .T´ìŒy5P}–N ½>ñÓª–ãZ«r¯o‡”R?1žhj†ÆôÇñn³ê#§ß&Ó ®ÕŒ¢/Û˜\Œõ1µ´Ô+_j»£G•ùoç˜"’/ŸCã)ÅÒvk'€öÑÂAW´>¡š’^N†”;$0–² {hïæ ý`’=ÚH›Šé›Ää&c£‹ß¨óÈ8ƒñm_2-¦‘õÎÖ; Vo·i~ˆu€¾Ò%%; ö…®·l{(ƒP£Kãá—qƒÜY@'z§€ÄBçQ‰¥p±ñŽ*oº=ó•j]ç‘|û‘Ž‡Éž‡Ð@¶j AL¯dÿò0œíaø—s`Ü9ОL3£ ÿCN‚i“Ÿ¢Aü'<?Ö)0Ò¡³=ãy“ä!M¢½£%ÇS¦ùÍ,ÊEg7búõ¨ QDâð»n‡Üÿ/öÛ6–—háÛÐëÞIXE}çžøVn¡:޶ŽRî:)2N7`‰¥OaèP͈H tÉË‘.¡Ò¤S«$¡ÅÆl”Ü—ò(†SkK ›D„ ŽT-¢kYpu8á¯Iwn`µÌyQZ‰#¡¯Íݸ7ñ-ãâ€{‡ó ˜ý¶×e9QA0æ-Æ­Ét?õ6í«fèøh5“×ptAö‡Â‰Ò?¯œ¨^Ð>§¿P ­…4ƒÔWO‘YEi|lÙÑ滃V(GÑ|µ•’Æ«Ú œò¹¼bÔË“°š'q$?@‹Èò?ót}ƒ2D³.yF·pÔpaýšÔ¿Yß ö1è&óY wÄ/ÑLhù]5ÃüZWL‰kÞ,$³ôI›yôüo»û'ózìÔʨ'Š‹Æ!@ ;SÏ™#fUHmf‹Ù,BÇßkk°.ÔcdÞ¦O&þÒA³¼{Ô4#F¡A©«SŒåT’9´IF¦QÒíñ\bÝ weÊœ/ š£»bÅŽáMÐtPTZxš­j'%åv´€‚Sª( 4äšÍÁ§rmºà“C£N]Àð@*kŸþýìˆb™$%­Ã“1[³txÚe[jmzU6•“8Ñ* †Á …ÒAA!Õž}ö ‹8Ñ¿¬ìîíÖñ<ŽQ…»ë8;ô½ #[ebFÀ)'Æß‘дO‡)¯Ð&:rPhvvÜTŽ6c ± ä7&¥ÆÛ¹Þ8£|&’u<R·K/šXG4OªØt Xå‰ÙäÊÊHÿÜ7t«‡Á° b:ì‚Éž©×â§_¤ÅYôv˜± ©Q$GY}' oØ ïÅLÔ(ݪP‹ÔÒ;_QQÆRcÙx‰1=îz!ÙŸs€ºzá¥>ѹú …<Æ0óiËuzsRžå+¿lhh㥥ùýiƒÓs3£ïeØn8£¥üJ¹š2–’Ê¡|4-Bõj®D£d&NZîWûÆHOݯhnf†Kß‹F'Í!¬)T!\¬ôÞ`àwAŒ÷]SÕ@é¨ßÃíöyèàN¦*ÁR—;™çÕ¶u¥¦Ã!*jÌÉn#p¯¦/N“kÞ‚î a¾÷&m T™KbÏ#”_š®ž[²Ä:ùJ ð5¤mË´(GBU¬™À*jqØ– HUSˆ„˜E!4Ìï.T¯¡ßñ×eb½@"B¯4%+9˜s‘þsì³_FX9úm`­ÜèÏÄÒ½¡ ÛÚÇRv“Ð&áÃ’”•:U[qRG˜mB«„šnú¢yŠíXêNÌÀ[š8Y¹--¢–öD“"ú1yr¼9¬‚È¢Ã<Í&) .¦]?"èT8«È—éU¹ë_Mo²'sjÆéOŒÙ¸Èÿ@Ñú¤‰æÞþ냺(ã\CE):Ǿ×gS’ÐfB!ÚŒàÄ#‚®qK™‡Ñ˜Ð‘Ž"%Þ†{u£™Ü7MëÂ3Þ°ˆá`$ÆiOpqKKšrÁ¥PUõdÇ"¥fŽÅÐÝÌ.Ä¢^+5º~\;©·Î_È ÉýæéÜrH#`a J:˜oü6ñ)IJ-qæ+«VKK…£N,—fk)‘°F|¢¨˜‹‰«JçB–'ÏîÎÒ¼·)äj[蘫„Ì ©3ÎÆ%£ºQÝ´VÉøÒ-+WB_08“£$Å>R$9±÷ƒ{“-x• ½µ…‡ƒ­¬6]–¾Rô £B^duˆßјãô‘ñ˜jÒÙÒ„¢ã’É@ªc"s|±µÕ‚¿µ­ ü7‘è1Q=žW=ÆõWÀÿaöe¯-V«hÛ4q•Jî{2¨€ÕâLâ<ÒÁsÙTõ§æûŸÖ”•ê}1Š¿¼e^‘šÓ¯nŸg/Y1ÍÙ• :¬nUEõ&)Îñ¥=ÏFiÞo-§5¹Älúq¢Ë[ P=O$K×$Õ P¨Vóò)^ÎÜÖËŒ[•å8™™ý±üQ]§C\õCæÂ g3“1¼MG„Ç»í_á仿# : Ï?Ã÷㣓SØåöXASƢ߭„€SÂÛ‚„Bo'Œ°¼x™ /Í’U>åâ˜è ¢àìàxl¹èWÖ4p¼û½zíô öºä”iÜ^éM\©JŠi¨7·WaŒr+éq³ËÌŒ(› S©‚€ûïÞ 0Àv¾ú›Þ\·ª¥jã&²ž¤é)óLubqQ° ²œ÷å~ßöß·ï·Ï ­V­ü¯ü¯‹‹­óâûóÕ÷7‘ ÄòTßWu"YJ†˜ËÌõºžãèÊ0ºô5M!TšD²iÖjΆN+«Y|™‹TâÒ6ŠË­_>f[Eã–Iò¿V¼eŸeÙa‘Ò͆Ÿ®X5/7e¾yÂÈ0Zí N”mû ê݉¾Î& ½Š_2[„¾¤á¥¸´.+á&ìB:Ä}ºO„Hnp*K˜M˜…õªZo¼å/Fbï]0î«(º˜ ¾A§K}V¨®ì%†ª‡´sÂøÉ{ЄY‹9>c昄¸ðq4aähÅ6q ×NN°„ìe }I½)‰![f³¢HtÉ’ª`‡&I+,)A8ñGtLþÏd¿DRÂÓJLAì6¾¸’ÖJEê'ƒQ;©mü•òÃ*D­Øv•Ö€1|UQ£´M¤\”©„–*6‚¯±$ |œP%öòãé<`D.áõaø»„FÀ¾ÙQÙnŒžéÍòHu޳‚ÂØ“1Þ>$¬YfOxœØ¨¬ý¨£7z­ER»ñÏ’—g–h¶úLd‘9e«óK½\ŽQK{_…zº9}›-xuÁѪÛRXC 7a]Nð|•£Uˆ¡x¤M¢’òQÌ,! ü4Œw·[‹ÄŠK”’'Ÿ£ŠYs•8 ó–{ Õ¬Üò™çõû‡âÝI·S`^b~Uߟ³Ï>Sä¿Hõ”}&/t^¬<“#Œ·µ=xq¸G®Í=ñƒ`·ç^¹\”ž}h—’£¨Žeµˆ~¬d‹Ž ÙÆ/ö'Sú×_+±¬—|gÇ›*˜JB-íüvs`£ãrø•qø‹‘4å–ËV²ŒýÿýÑÅcÔPt¯Äg”Z-þpqÕw;±Ò«˜X‚ª¤ÿg®T{õ³¶Åö®Œ¸0Ê`AÐB‘6Ì­j7«´Qvé« -Dá%¬­ÍR˜Å(WÁŸJ«µ² ¹óTY¶‚ú½“ñMÂÂuXs@XCA)Ž ñÝ7Å<9>1RˆØ/ç!8b°/¢N/lÔŦ¶÷T(Á-Bá ÚÚ ¦ÍsL¹ÍZÁú¢Aè—ÄbíóÀï‘%•êÀPpå#J-ƒSª‹3ºóàå£&–4,*_yˆLh±%t“qïUx6œ°+âÕ­™¡3›ÈžgìU0¹U¦ ]½}»—ÜžnþKŒ5*ñ–PªzëK< ©´RÕ¡àð*FœÄÛí‘6H2‘º[ £ ¡z–²OàtÉn]2L ÚP©‘j³"^¯ +ßúv+®úXQXB”ÜÁÚ6*Fþ˜n2`y« hÌnè!„[c4R­ÆQʃ ]µ~*@®hIB¶*‹-'s0!sS,û´á¸+_'jd¤þ| àx©Nù0íîü~Ÿ,ÊeìÝ2,Æ2ïPÛáÛñ‘V]r(›6HŸ>ýô®h9ø3‡Ôµ¹BK+hNåšú:â)Q-Y—Q Â$kHe­™‡n[#MG©ºI+7ICè@–ªá P\Nw –ÒPî†ÄUor×ë¬*¬¯a¿mn¹Rt@»#œgl6£"oÔ;CŠ“BÊÌC£ëÆO _ëUòw¾÷&/ÞøèNcúÎj$S4YöÚ£ÚîÑaãWž I–Ø®‰®¤É&ʔٛÈàÕ!ÂýÈK?‰ã§¶zâ 3àÊGKA VNÊ@Úí ê: ’7äHÐ dM¥€¦ ÜÌ ’ Ül%’»·ë %Ê?8Ó+cíFØä6Ìï6ÏïRC½Úrmk^` -‰~ŒQë¡g €)H_à :€Ä„¤h¦8U€>Ì:®ˆc…Ý)õ¨÷‹—föu%†Pù #¼SÀâ&×SºŸ¹žb4y'h{ ¶¸"òÿ±gå$K…d鞇òØ!Ó¡¬]Czèç¼ RʱÒôP½Zà­Õt¸lÐ]b\¤i4¾ÇþøÏŠPaïq=˜ïñûÈrƒQ_£a³[Xè+|M¤cô¥r]EÚ]}Œš _ΗS£¨ pГØ¬/2ÞÀïµ <•_ZÅ 3 ¯è jÀÌ Ó¼ÐÚ0q=EûBëœ2ŒAÊE”7(m¤¨"(°ÕwtÓ§P/÷üE’ù£ÏFV_â~UZƾ¼F}½}%÷bVõ"õ^áBQWÑ=y ªTèÝìGΗ¹3†Kºa ¹ÞõÂ6HM°-&Ò2—Sà¡c3‰g©;L"u{¦> G%œ)m»ëóôT)irþÝídYÀWbªbÔ.à‘ rÀU`ÈÃnß@õÆã[zlh=–‰†B=lgs¸ƒÑû“M]þ;ÏfEÕDvÞçyYsÔIB¼!ȹùÛ­¦‚m%|2Hå#˜äÜ”ÿ6Flü;’•N²mƒ×úiñòVEtryd(C¾´°Ç–â6·å+¼»@'VTÉÏè¶¡lJ6¹:YR0 ©”@*\ÆöGÉB™hÌ`á1«wÖìs–]d%•þ(®õ9ò¼EÉ’ÿ°›$ÁÑ‘áQ«gx·¯×jâ’ãÇ©„™öüâ£P ¡tö¡¹Gâ*ð\ÞQètÍåÛ Æa»‰®Lº%ÉS= г–lb·Í\Q]Åòôb·VwdåÏ]ìž\뱆OäS+Éú[©‰!ª4ÈÒOuFSùG(æ:Ê<£Iuþ6q|meå`d þ:=ÍI*4åÑÜ-—HU#!3x€–öK$Ý—A.ÃÂïÃÏFg³pËDM$—NÔüU2ÿ1I•zy°ùí›âÜ:Tz÷ö„°ùÈ’ØáS[îüò¡­Sßs[ŠF-Á+Ù‹ö%OžÏ‚W˜ìÎÊ9v[ª.[%Ûæ 4eyÛ—4¡Pó‡Nk´Î®ŒµÈy>~ù[e™îÞ~«^\,ŸÏ ÙÜ—ç«_b" ‰Îªº’ÕäAª}¸²°‚uZ³€sÄ;sfŸ‰GçÁÕKp«¼èò1œþ‹ræ¿;Ú7˜yì¦íì9mQÌž,ô¬ŒÙ#gwÂÕTìÂbÆ.e\â¾^]5¨k÷®øEÒ=¯!Ÿxí™T€“{ÉQxÒÄ©Pd¯ZeK« ìý”[Uùd“^Ô3Cc²j(°R9Ž ª ¦!+,3RëHÞ£Ò§¬pŒBßu¨”ó6!¸aeՙͼÜ…4^Öåv—ôãñéšpó¦7¦;;¥\§ÓFݪT1ìXI[Bæsd(Û°àÝFÃ`…Fç <ËŠÕJCΠJ/*fe’e/¬Tl_êjžçðÅå¿•DÛ'Aø2G–±ìØSî·­°D†?Ïsš>öžñý̹:ˆíŠäù¬Ä®KøGÌeé„ÊÐ? ™°Hvö.Ô;•TË‹qAQ¦Ôâ ²E #Þ×÷i ,ƒ(¬~N •øÛàÌØß`ð!@˜LÀDщ¢bÿ繟éë§|&Múý~Ú à(ÌRê%ªK¿ÿoÌvF5Ñ›ÖäãQú]¡ƒAL½ÀIL·<")ò‚׎£KF‹“ÄÓ‹ è%׆ èŶùhÛ[‚Õü¥L%y¸kÐßjU..ªe´*5»‡³%XöØW¤¥ê‘Ê siŸ4K­×ñF½¬d•‚obÌUÂ!è _¼2e+©od§Í:à}Z'8Õ$¦i*‡Ö ŽîæŽaƒ›7”£»OÉäCFTûª7„öÀ¦‚}ÞFL.uúšUziV4ÙQ,Ûîs¶ŽúÇbîA½m­E7>´šjÅy“ÙXš´gï:ÜÎíï5åkøµ–·‚ª!îª2xEw¼X$.Ì’³ÈéK¢Û;¢mh6Zšò•ªp¾­¬‹pòÐçÛEm‡£+Ë{TG¥²Aj짨VwD«ý%ƒ+A&0~¢ñùòßa/kb…}̂ץÇ㈥tpůcHr>hþÚävVæ ”6LK‘µ—Ôûsø]+øYœã)É+ÿ«VþÇÅÅùyq뽨ž³‡§ø ö¤ü¥»†âÝÔ¶¨{r,±ó¡ Bû b÷9)5v@ÀKo¼‰Àl<Ø…a íë¿(2vŸ„Ô$0æÚ›Ð GöƸ tǰ\«*âYžÔþ½ºÅ/ÙÐ~vÇBBšÒå²üC…eqzëÙñˆÜØšY£ vù1u›5 ,ÿ—tׇ¸÷Zj%¬uŽPœ LÛã䟵:åíÀ„C# '"2-É®ƒƒ9«ûTã£p.}NÉ7µ2µ.´P,~l»œD¬|ž2挃¶:’è[–ÉðB¶ŠÛŽGÒS#İ>rÁà5Ÿ&„áž‚aEüÊMEd¥Q5)ƳxßžUë$[LØ5ÿ:||¦ÃÇÿ„@?CF‚§˜”¤$¤{º¡„$îÆ¨Ï•\>E.2 J-h.$ÙY^z}MÂ÷Hè »-E¶lý/¯†˜rÇÒœ™Pñã[oÝê¯TF4ÉF•LdqCß…”h¤ÍJêÎG©Ç¢T\MWÚür»k÷×m˜¥}É_ÒZ¬äàÀ>…Nß•Fà¤Ùƒj{<=Óoè¿ÞÕeâîãÏoZFÇ·š´¼›^8þÊ ¼{3½ÿØÿOèVç©I±¯Ç¾vqUuÇÞM0¼îó²Â8ôø¼â‚xŽÆ‚Át‚1{@̨²‘%™~ö}2†FûV0Z–ZV oyþ‰¾‹(¡Ú¸eÆÃ<Wÿd±Ä’eô»íËxºKÛH=Q}"›Ùj­­“UµE›c9R›:Z‚ñLìE§š¤[ÎélZgi§‹T£ ¤µlø2¸ú¸‹ìøJ0Èš‘Ec >ªÙŸ³ÍI_k1;PcsÖFÂ,’­XSFù‹ìýT¤Ì¸.úq­ÉW0ôÛʼn¦:ŸÄË[#™Xúõ¹IN>å§ä‚`R'¼Ý¨¬VV#‰àÍüúËi1¯úl²6b£²)~ eÍ>[7Yw·^ïÍô?²‘¤J/Ò—~ùäYü¿¸çD%‘9“c¦—’Œ8ÐM³KÔVÊ3VIºd­¯»ç3Ò¹k•|KJP|= üá[ CðXdÖS(ÿ‘]òcöH%ÐÀa ­ó^Ÿ½n£{_ûàh·¤K¿¦Vw8’+ '¿ÍF¨&¬¡Ù(„Ý‚õÙÜHªÏæÆc+ ]m€¼ÛÑÈ[N›°ýOœ°ý&,LF¨TáL|6¹óEó%¤ú¿:¥˜#om¥­&F§Ú/³™9³"õ̃ªIž1ìÏaÃù5áªHä*RÖ±{\tbüÏŒ©«¼yy\>{"G(–ÙÑiY„ýàÎ~SžÈ1 ô| ÉÈÓ§OK‚ïâzI¶ €$Tû<†Îr^¯O±RÆ MæÄªã…7 Ñl‹â39õ¹enA¹{ðÇè ¾þóÿŸË¢ê¼}î7±^¹—6H«¢p\/ñ­O½±W\ÈÐjž@7SòêAž¢¼…?6ñǤ I0’JÄ“¼•DD+øƒuûò$9V&…iÐîk0ä'O>Ó´yžÐ.9l`æÉuÏYv N¯ÇõŸ2!ã)Ò&kÂ0ê‘wœªŽUÙæ™E?c›Ókìâ­³6c« 6󭈃¡ru…”á]oÒ¹e|ÖÆ.ÏŒòúÚûå,ü+²ï—Ë<¯]…ƒÞßZ"ki,¢Ãwï¦×Ù^_+_õ&jÚ•‡L}è’ròƒó"^¼3…ÒU,t!›H ¶\UÄæÆ•Õ~Ї †8`,Û0èÃd Õ;ø÷/YîÓmæËÃG™ÍÏfÁfÖC!Ó Jðý.F¸ð¼G´®ÝÓöÉÙ¡$ªSýRkd ª©0s*mrz8zú­ߖ½ÑVÄYù¡J8ywýíóh(¹hÀtšîç /žgž$ÇM_xÑœg³*Â=·÷÷ê&£<7j‡/Úl@r€Èý­‹¢XÕª5!i¡% 9‰ÍŒ*$‡°õa¦s=XLc$9$•eÙvüŽ.=¿Ï)ò4¼Mg®úÜ€ŒŽ•>‹|nn þ×xö’ØïÒyš1mI«Dj…²±ÞeH¶¬¹5…“ëJãÀ²ˆ‚`.ìôÅ{3θCaŒ«Fa°]xY« ’*0ÑBáÕ·Ñ_íA„Ï/ðUQÚîbº ~}ȋt-~–jÿYõ·Öq±|{×ñFø«Ú}V[[¥'h&¿·[¿m_,ç )ÿ†ÄB~ÊVá œû^LÆ">Ì ø¿Ëyú¼PfÎê´,ߢ«ØQOEÛô†J£Öí…¤g‹éŸ`$TK0'úíà°‡N4÷X~øÃw<‡gÂÅ–‡9ה’€»o|ª°3†µ¥Ã¿†<™ÙÄ’ëSf¡ä*¸G©K Wv RVAœrÆžãå%\ì†QéÊeÙenBI†C++U’`’]ë+cË)4¬ÊýÎ'k+ìÿJ‚dirÑP(ÁnèOø¾—¤´dñìE-íÏ™{'% xXT2Ð[àš›VŠ]V:ëk\ôZŒÞ«‹ŽÄ¡?yÞÜ%³»þu;:qù‘7†ÀiÈÖ«Ýù¼ÝNÂýSŸ£Sÿ¡vs¶˜›Ú‹¯G颙ÔúîëFm¿Èü  µO=ÏQp ý»07ÿË€köúä^ÂÎX†"Ôû߇ Öˆðòÿ˜]áçcý.ôžµ¡¦@Z+‚”9îݤsÀn¡Ó†EK‚ÿÙËùã¥}µWÍiLÓh½þœôcùèçYA¸¦P’œü>³Ç8ÅiV×LÀQ´Ÿù[Èø±èà ¾}k‚…„ÇŠ*õ¥±æ@u$櫯4š†ó5âo·sveÑãgjŒ¦].rê¡Im¼8;S(õJ”s…·0årï–Þ~(9sE´eV™m˜{{YÚ³E¬6º:J¨¤+BêGcðïN a@e>4ÿ£í>Âæc`¸œEôYØû屎÷sÜî?‹ÓýǺܳÃýGzçÌèñ眨gsžëuÜ)àï†üû4¾_ÀÛÿù»ØG 5³/Ò,iÈc\ï;ƒQÂû´-ªP&“ø„Å£7îJxž´{.ucð×5Á ¦Í9,Á¾Ð%ýGŸÀj¤‘kd|»f˜}}¯-ƒhPQzÛH—êþ3bNqÒùH0¢¹Ý5R!`f×<%ÕË‚„Ç¡’:ó!|‹áèoå¿.ÌÈÁ°LSÞú {Ž••Q8쀴œï#SªòOα Aêí¡ïTX\ÐfÀ÷››>Ù[g¡¥nùNîù?=—ŽiZÑÚ(ï#¹é9þÙ¦ç°n•Ù<¢òqZœÅ"­hlFì22 ;ÁzeMÿ~ú–ìä©àJÀßGp&>;ܽ¬Vúòôn-ƒv‚ÿðþö?±³-È‹g,ˆ<„©7ϧ…VÎM{QÌ RÄÈÈGÒ%…IÊ(ä¦Pºíë`ÜSŽí,¹¦äœº‹œ%ZdgG¹žE:—þcYµë¯ë;¥{oÿµØ9:8ÞoÔOØUÆî9 ˜Ñ•@# ¬Ä;iÏ‘ÂU¾†tL-ÓArf“Y¤è8wJ)<é¤:U` ¯b míN¦7è Oqlr)ËeËA8œagÜM0ŠM?Dw >iLÇ~›ü@æôœP› Å &¨ÞD¢ý'/ƒéð×3V‚u‘ÄyG†`‚1©ÏEP¤žôÒÛ)^V+ÅÑžèÊß 5jRÍÞzý)úÌ»1Ü(K¤Wd¤[Åz¸oHf2*h}¢Â§Ozüºª¬Ð~QÉÄlB>W,TîaÐÊ5U£(ÑZähª‹}8Àä Æl×¢Ã÷§p«ÙŒðÕŠªËn`HÎ^³Ä Ä!dDðÇd¢’ËKŠ5O{®:¦EqBöN¡ 5âaÉè{4³Å­T^Ñjº¡ÍTP1Z#jˆb”6(iE)-J!ÁþÐêòýÐìÆ2IÛ‚ù8·›ñ3Þƒö%ˆœh¢µÇ\Ù‡hÊWN‘]Ö™±0IKï¢t Tí0ƒç†&ôT0ôKò)œÚ†‚%±‡"dì{‘lh?®±ãT µžg^îcà‚‹xŸÑ–Ë ŸÞ2§é +D™êŠ äÝÞ5ȃÄ/Ñ‚M×ÓÇ JôsŠ<öǃ^H3ž<Ø´ëÙ5)(»7¡hz×1áXyQ;[SEí°é!õa@¦k -‹\K,ÂU£Ï/D§_¼K–D?ÔæZœÐ¦™ë©‰ë \Ñ3pOi¥áƒ;!j¡ÈZUÉ–„fœØ`/h Æ[åõØ£mVî,H —çt"Å0j\p7ŒO‘¸`ì,ûW·>m‡ÅJÇ-³ùKÈ8Ùé3#M`‰v.‘ñŽËæƒ6qy²SDú&ŒÌœ ìú!;xñ£j‘PV¦ì”X¿õ{^òÞœcìV³1=!Ð~½; p²!èb³d2¡ˆ©6YËpBµ+£Ee¿Aë°Bùšû¯+‚xܵò®Õ%@4ÀèÓ¸…M'£)í’”XCå†%¢„œmªè³ ÜéãL/Þ`]ÈÜ8DÁ óuò n¶3W ÙÎ*è4˜ú¢$¨Õ°à±H†°0Ô˜¶7&È_•홂üMD¹5±j8+(ùçvŽ÷½Ö‰ª¹Uz"y6ÈÄYHnÏÒål›Ûø’îȵÿ,OÅ®WÄa¥Î›öøh@A“ŸdMf‘EÏ\!,rcÿƿ߾„S„Ÿ8‘¬Ø6óBeù¼˜½DBV ’Ú…IÐÐo²í6 ˆñyb£ÄšéX¼§É"G«Öíªw6).2æØÂ?ì̺‰øþ{dõ£=±úÃWk™Ìòò²xå)´«ŠrC{¹ÚY%t —KǤ‘Qˆ´ ciÁaלéÄÉI‹S3µ Ñ8ed$èY0¶/zì³³B"+„ª„LvnuàlòÈé­Ã¬…b•JqÄ•8ê¢7!*&>w¬½t¬U¡)Xü”ñ^)¦²:&"ÛÖªAN0`°•Óe% šQzÀaU>ÄEÕÄÏ%ñL‰ ¶žCkW B‹åløRŽÕ¦ ƒçÝ`³a·J1À‰ÆÕô¦,«öÓÍpZ Æ7|"…™ÀKùéíDk!×^A—½1@);5¸«ÀåÉFw{Á¼åâ¬yýÚðWûeR3Rƒí&ET¸ƒÎ¤¯'¢u&¥KÿÞ`xwküñ:²r¯ü¼y¦¡'Æå UIÑÍŃ£>2¶2µ³v­±_k’ÏU|ßÉûy‘¶¯Cêýòjeƒ`¸ï`F±3Ìí«l<[”ÐH)…AGj¡^‰I*‹K'^T>ý§ë_O‡–|Be d’(+åÞÁ€ÓTj >pj¹ٷ鱘±í%§”™;ÎÜr‹²7¨Äº-RëÅLó-¾«€ÿw&÷6€zÓØu:_u¼‡¦ó©tBŒý Ëø“ÏÁ–pÂÞt:¢LŽXeÌZ&ƒO¨ê œ¡CK"NåÙ߯‹PÞ9qÇ耯é–ËËe;¢Å2}ßcò“±Çñò:Hä°¹À‚ŸLÇCåè8Á‘)ä˜CY6ñ²@ÆÊñš£èWOµ jþ|eõiþÒÁØXÆ¥s×Ï “Y­°á>½_…A:ñ•Ì·}< %V䃺©„ã$j`"ä«„N†¢«žWÎ+U[sǃeˆAÈÅŠbFW¦ÓMRøòòEVż ¿ÄÀ_V¿4ˆõÐÃÀq£´í7¿•ut„@²j$1þI¤TEC–™ ¿4$ d \oź0¬µ±KÂ~ƒ%u$c\d³júì_£âŸ0–d´à°ŸÄPŇÿ•¦|ÅoÙ[öTPôÿªO¡[$U© ¸–øù ýÝ'u¸‰'`¯Âé#”#8!~¡K÷ÄåÅ\ã"*z¸‰4“Æ„° ¤¬x¤v6³†µu-v’êðûr¢3³ñ}úWãžzþk˜ƒ_dZ)Hný¾`¬g-ôÏÉy?ßUñŠPY.ËÛ€’•ÄpöMÐ1±I?þ¹°L%û§S:{m‹òÛŠÎþ¥`þÚ£Ùˆ¾ÊÁÑŒ/ Ew¾ &¬òcºtd\Kå·l~ü½ b '–"9õäIÄ|¾·›Çc«Úƒ¾ˆÎS4–Õ••#P鉽P}˜)ìËÉÄÆc•8×=X ÷ЈÈÿtÁ¿1Gâ1.™ª~rrtRhA'÷|»ë`JnÚ‚Í.¥–QJQm\¸Í³çÍS¯vQv–€ æXÑØÕ·*§ævB©­éÊÝQc¢öÔà+鸇 ç³s–]¶TŽž&ΜV ªÌ‰ƒZ½kûš‡ÆÜ,| ½ÅSK©ì@À¿”È ˜bc¼tqn§¬Öäu*â53¶/)ßmèM{ãŠãƹG ÙÙjàÐk¡qTÛM=ÌÁVŠŽIˆ "•ët€X‚¥_.‹ã£“Óƒ:ÃUð—ôò¾Ö\ˆYd*‘‘5•HXR3C¯#ÒÇnƒHWÿDm EŸ&Iš›Þï¶9A™àûVÒ‡í|yœ‡Î³_å’òÀæ¬78˜Y”­²¨ äq6¬“<«­qäK6܆69DËȱL½Æ ÒùL‚¹ÜBN] Á/bç\M…®=uµqne(“8Á¹ô § ‘㿌:SB(˜|î®_§68‚õûQæ6ƒ:?Æ‚-:š#¤.̰ǼæÄõÉF´4zæRÒÑòX+Íá~»‘•gt(¨DÑ·ÛMâ„»©‹ÅΉQIí™0¿9£~ˆ•Õµõ§›ß|ûwÕ¢Ïâ…ÙSéeP+líŸ:Õ$ÛdÒ´»»µÛÝýQ%Üší½zíôìD×WVH´°ª$ÒòáEW6+®BÄìÀ–;ÙžjeÕ#c¬%8þw#Q«Y0¨‹°NmÇ*á<¶iÿßÞb±d<@y6¡„µHiÖ¥ y› ŸžœîÔNë ÷jNtÌõùd<vpŽzˆqE½½‘ŸÀXÙ¤+>5‘¬+<9.·¼t)V4¹™QªÏmøüϪxÛ5[œ±ûS&LBmâ5ÁŠl¬|·©ªB–‡ Ï–LTQi—–M­„ÄÕÙø=ëÜ}CZw°’‡P7؆É3ÍšÌÎäÕ3ç‘Ô«ÔO_í¦ÞkÃ9ÝèͺÁ÷+þ°ƒ×6K¶Äq7%½¡FDZ`c8«ö–î…“^'Œ.XýæÝ'k&%¼Yú2:oÕ–‰%Ø—äÄNºH„úðG÷>6A­0Îgb)ôÕàö ÒÛy©àÈ#¨oñøØìw|º2Ö!Zùé‹Qß›`ì yë&Ñ‚€a['Y>æÈ3Cga«…zDéT0iˆJ1S ¥Þ :Ód©£3ããÙ3?˜•¨Œ¼0lÃ"ƒµvJůên(g×’:Njz)/ÏÆ«gÉõ…å°.y[-º`½¸psb˜Re¸J¢ƒ4ÀÔ–9hlŠ­‘‘:B¥´ÞþÊÓ0*r‡Â¿GÚÁ`™X•ýk¼Úã WT­<ªüq²¢¥Ñýœ»?\ÚðœûrÆ>P¹“ÖDVÒ}ä2<-“\A×&>'ß7âí$ T%—V=„<ßÐç3æ¤*UÚ¶_ùÒ­öYÂn {:¿,{ìê=¡ƒ¾Cµ-ýYF€axwи¸h>yWÅ2à{‹Ñôxò"Õ±¿è*¬ÜHLi+{"£ J§*Ça+ð.HhÞ|‡± Ñ^©×e¯”ðÖ‡Âot:×J;ßÉÀë +áíâ=ñÛý·›Ú³7À¥ùžÞí6é-VLùиgnÄsœï¸Ê±Î»Žƒ·Jû#篒u$è¡DÏ‹u‚Û~Âç'ËBà*hÑ"N]Òça»ÓÁ(Ï8hÒøÎgñŠK.ÑjÅ«]Ä7S`m¬–n>Ì% y¯À÷UQ´À§¤jÝäûcð˜QЧ¨%ñ³ï¤7fMFáðc6P´=‚—QB•ÇÔžúAFê-ŒüÞr¹·þíf¡²L-BÃ`5[_|?òËÞxP¾Cø:|€f–77гšiðD¯ó¶¢9÷.ÑÀÍžÑô}y€®d>ª…²þ•e4áêû±fÂÇâé 'Ò–‘Cg©Q &’Ô’b6Ùe˜š&2ø¡ÜMô^"ŠÐG„Âàš|@ õk¤÷` ”Q¡7üI>Tªµ«¦'›ZZÝ÷5€h§ï_žŽ*ÎeÁÜ1,ìA/A-ÞËÚ¼×!ÛŠÕž ÐÍ*ÎNýÅ»>1£‘wEh|È;eGÆØÙÒš]€1œ4ˆ…Ü *Ë— á™mP¸…¦‡^+&†ÜâóŠCŽUÖ¢QÇjõœp_‹ŽZèîÒòÏ{˜´e÷UQ8;6¯Ù²ÀàV)¼ÅÚˆÝÈSÖŽœù©µxå±jæ¬vK”­7ÅŠÅ ¢Õ8¹£ø£Û ÞeŠ?¶JmY×Ê'ûÍAyÏ+ô'±pódÈ#Ù¾~ì2õEÖN>žW¢#ã,žEê«§å¶ŸZgIïï·r ‰ˆ ìߊ&S"Ñ;F[âýyÅ#Qä}{Ôëàr¨9Û…•h« «È÷þ_ÎaÊ Éb.ÿ¨2+$ãÆý(&†ïpƒwã¡7ìÀÅÄèËÅô8²wgŸKñR%º(öf òõ“w¼z=ß¿6¿ÔÄâ)±ïž7¿‚š»ý» Üü¼ ³Øé'º,¸À‡ýÐ~bX•‹ÏŠdðÅOKüÌó!>†ŸaRÌŸyz¢¤¢Ž-ÞÑújñ,6Ö#r}”‘ÇÅ#JAàq!nþ•ƒ8ˆä¿È;kùbîžš,eJ!“¸ÿ°3.>B²”¹Bÿ÷©?œgß4SÈžîAivw‰¢EPc%}j岩œU›ì\qÇU©zÛ¨K’Qç#2Y’•ÂAYxéhÕE3PahbõÇM?¸ÚΠj±= pÝÑ‹a  ~²9²ÉÒ-4.Iæ®ËãŠ(©µ o8aʨ¦¤™j!¢õR1]­;ëh[xÅyµ«çî®_¿Þ»yqû²·ÿÏ¿½ù¹ß ƒ£ÑñÍÉéôìí/w¯î_?üú¯X±²aõ¼P©œ«áyµÕ:_¹Zÿ½yV½‘6™öõ=õ.‚>Dæz.id‡+—>”ÖU²'ÔW_‰DšÊ¼2âk‘”Öñ¸=`7-}U¤´ W+¤®sØB˜àØk7ß))â©L~‰.cÛ¶³WvV8œ2¤±éGÂlô¼¾¼'øè#³Ó)p/©$¶¯µfÿ#ŠÖW€ñÛ>Û[áð`!oOY¶“°}æ¾l=eBÌ!îD‹É³G°»U‰P`¿’­´Xß\sü«Ü(↫™Ë:ÓH/x”åïVÑ\8Ûvdz*Ü©(©ìàdoø¶HyJБ“ná¥pÈpŠÑ9Ã@_Ç£‡ß„£_{×ð+ò–?ÄÙOÓ>´«ÇC'RÜJµ{IÂ’—ߤÁ™Õ–aðm³ÔbVfðN2ñ;œOŠ-/‰Ý^­ Ø$oø@MHÞ0JtÛOLï—€aU¢</{žïÊ‚ÅVFßwÌÙ7´h‰[íµènØ,H‚(:q‘¶4|#Êø˜…ÝkË D|©ÊåðapôCQ¾õ½.šìΞ‰ä!°s´·§=ž$¥íl:ͬ{g˺•x§AÃn¬çeâ [³Åcév&ÑÀq”¯µ#¥Ù`Äq?Àù1° ôA~ˆÊP(RHƒÐÚ|IÁ¸:Rñ~[ž€ ÙRæÚëøÆ 6Uë­±W¶ßogqâñöLg‰,F[C{ô¶6ÒÁxkèÜ¥ù'oQˆ1S HΈ ½Dº­\cÿ°~x´E¾^Òòå< $¾ª5AŒk6k/êíR{»EM$k%ÎÂlÑ¥Á´e5‰eÏï’¨-P£Ãq~~žuÚ‚lø~‚¯¨%HÌžÖÚî2ŒºôÙÁ†É3êêƒæ…ÉÅÀÄg¥d¾~J?¯_Yv†>¡2C›íNªƒ¦âUZîs —#®'À繞ðⱤó$ד„DŸèzÂS]OôgÇ>±ù²vRßmì?oï><ÌDà‰Ú,"ÜŘPô‚—À`wŠvtz(í¹©w-cÝ©”•?ÀÐ1¹¡Ÿjò˜øy·ÑÀÍ)Ý"RwƒFÑcݶa$w"‚G!¢A“âb‡dZó’XfŽqô…œ(–Ää.°¼X\s£0ÑÞêåëÂÈv})¥“(ÄšmˆÒñFMiŠ K\v\Æl×üæ”:¢ùR]–{¨îè]?”1ÚIgâÜÚÎè²î¦c›1¬áIR€Ú«”+à#Ö†ƒK—p’ZQY´É$[*¤¤-ö›B—šY ä±ìªg¥žGÏ’Ò‘,1·N18Ç´ôiÊ'³X$^|­Dõ0)\-àq¸¿Wož’ 9Ë4ò„™Ô©w]CÀ5‰ˆQ垢ÅÕ‚ó¹$’OMg;ß©7ÛƒI&ÁëÏÍÆV‘NM¤EÒ=®RüÖæoFÞŠ•ÑhI(n±ùòùlÊþt¶²¸bDƒÕäS¨ø#‚„V[ÁÞâÒ@Ì©,ŒÌÝQÜJÂØq潜AŒCæ¸SXÍn`š¸÷· ­½ýFý"O/CúTÓ\ LÉ3çv£(lù Lð¼2½9óØâfd²;þ¬/GÏ{6=x~Ôh¦‹˜q—U7炼ùÀeô­öêçøG[!‘öí1Kà ê: ÷/Ëó÷fì]1²¸w'XéÊj‡ë ßîÁkG}!òá ‡ïµH޼1²‹Ã…ÂI¹Ìãû(ÒoËD›À{c¯ßæ2Ûä £–Q›]Å{C_…RP.|ˆs‰®…bÔ]\ûw"èwåöGŽyˆ‚"¶«uÖ±ç¾"Ä+‚Tñ  ÞP¦øñ‹/ijâ÷£ÔˆNTP ”Í®Pj‚6såU‡¡É0” Oøk;ßj=ßÙ…ƒyv‘Gb'èt7Ân£k¡ôÞå*ƒ~ägÈ â âPÕwˆ.lRÛyÚµò?¼ò¿ÐnHþdó¡ó"´KºÙe­*Ò!*‰ÎvĆÝÚŸ²M0Ö…tVæä~±ß<}¥)Ü*{eµý ¿¾kFó~7ø”CJw£±BDkè¸1tJïK £ëÄ4·ÙV†vÂÝ+pÊJdõKTkÊ€0=Ñ"öˆ±¾-bï°yz¦“ð–H¾žw>znJ`´Ã3Xßç L=X^úì!º´3©¥^ æ|ù£NJÃ¥‰Íƒž¦2Æ+®\&K¿lÙI¼@À¾ŒþÐõ&žYCty3Æqö2 Úœh;‹K KxJ#ʾ¨,K¸å\õ|Î"Y*¯Öý'Z¥#ϼòEFVüdì CéÖŒW—÷Ó‘¬P·V×£Þ´oƒàÍv6±\ŸTô¢Ý¦ð8°h p@drERÕŠóÕg²jHÂcÌ"(Ä»óìùêy¶$ oƒ^ÍöW>”b$P‘Äd¤À¥ßæ‹g²r@þ”X¥!ÝBaBÜ‚$¯_l$cïäÆÊˆF§j Ñx†€Ø½žþxŠäºšbÔ› _ÛÊ4¸Í‚‘ÜvDÒÜš»YßF•È]_ÏX­î?”2KÊý”<Ô8$P¤Æ×¹­dfô5]MhÁœÓç=7N&Þž¯Š4¯¬´9¹„Õß儼Δ|DOÚ’öŠ|öºÝ1l}3›ÊC(SFÛlFÜjÈ–¬5Ôæ‚X´íI$ο:_•“ú#»Ø'ê¯e¬#Œ¨´é˜Êâ=cÇúKì$µþŽšÉ2L_=ªÇãlÄíô—ÐcÀBvN{¨L#E0ü­;U0‚¶•Æ6$2¨´2D1Íߟ¿[)­žÈ3ˆì½Æ]R6R²F#(…‘»Óžb\ST¡zjP§C4nèc…-J£Þ>'ÍÛPÂ_ß#ÑlVdÛY²[cÕŽžT²‹J‚åÁ’ZB2'q*K¾÷J õÞœï¯Ç`öç«t/3ŸŸ¯ ø_– |5îIÝ=C*;B^õ ¶Ê£öp¤½ç½ñ ½Õ¼p+¼qʶ~ÃB4id‚žÓÊI_ØÕ‰ä~¬-̾þÛ‹+ ®·JS£¯¿¦Líö5œ#:ˆú¡4 ÞÍ_ ‰*XZÎM¼±„™ü Õj?ÚŽîɇ8ÃñQ´xÚãï0èT;ô©aÛòï3¡^œçÄú‡g:uõ74¢|°§µçzõ4³ÐÃÙr #S„m‰´²øðÿ³÷ímÜÈãß_ñ_±çpg ¶y„$-9zuŒI|åõ±I›Pg±×°¿êµ´iÿöï<¤]iW»Þ5&I{¡ Ø»ÒHF£Ñ<ÎÜ µr“ÂYip.¯=ˆcm¯¼¶2r᜸Z]ÿ*ª½ºØÝÔº`­5žµ¶c­ÿF9HV ³EoP<ÏïœçWaî®7½ô&ão€)q¶VCpNïF)yý7 þdçOa{nQVu‹ÜߤÎÕ8¸¹ êiA`—ÿöǺ4‹°ÖÎ?¬ÿ†?Õf¬¯¬×G¨`—ïà?€SØÏ.ÎW×VV#õ~s»+„L‰ÇU+\¢»{žß;Ï@ìÈëç+ç«eê¾9Å7AaÉvqýüÇóñ:b™Ûˆ`Ošw¶yñÇúÏgßýëB"¦[ćôëy¸/Tœ¸‡hˆŠN`2¿£É”&KŸuÔúðе{»û³ÂZ.òQµ¸u¢ æå5¾'8_‰ìç«üJÜn(Í-3k\f†¾¼¾,Xž|é9c±&½–6nëÀ4(Pæd¸Þ)¾©Ùñú)ä¨*-<™u¶w‡LŸ·è9¥GÜš‰ë¼¨eVd%÷Èíbd´œ {Sÿå„€–¯æ­ßrœˆš9’ÖÐ oÙ€>ÏÑN*Ÿ ‹¥½u5öÅo¿›Úú]6€T‚×x+«¿)ÍììÂs ÖêsŽí¾²±úüw?Aï'•jë´ñS«†J¢ÀXlUÛ=ŽÐ„E}…–`Ù̇x@TmùH8š‹l½Ðy&‘¾µ–©¸›Û ›šÚ8ÿ`%SZÞ:—íà¡;ÒŽoº_ò÷Gs8bIăMü¸ÏMî/S·{'íÆYmWLر°Œ¿Àhå“Si²ÞÏ6íâ±ÿIy¦”@LÎ~¡À@×ïß!Ê÷C{û ceàV¬Ì­Lå©tUÜ_«T½\ú‰Ñ·d¨ƒ$™\)œÔÈ`&¹¾¦DÉáÈâ²÷Ò™Ü8ŽŸ:µÜß. sòáScùš¥8„‰i,×Öq¡ùB­ëG·Ð“ÀÒªþôž¢ò‡P¹ÖÕvh¯rZeöÈ €Áµm¼ ¼t8ëXÑW$,«r"~jÛfs%TÄÂéEPdÐ%âo½NÁ󣫉¤Gkä9Óΰ$D Žè¤upúÝ?&ßµö@’iUš§À>zê`A,ï¶Z8Š àßfЏoí!rR4¥"ùKí¢+2¨‘Hª]ÏI*ÁÐ${KËgÕ”G̬d‚_…š…eÚ°3‹˜u¾Ï¬ª«’ɸôž8®õm”& 9åH—:£òI°ÊéÔSNéb> ȱ`Úž,1 ´á¬!¼–£=EDŒ§Ôç°wÀ¸éR¥Q9lA7ßà©cá:ïììâÂÚÍ!Ü߬üw¢ðwÚÉÔú½¨¢]¤˜ÿ$ŸÏˆìÕçI¸†7´uî÷ç9ŸÒY<°Ç!ÞösoA‹"æŒPÎìiq¿Q«Á‹ÖÇï+cLsâÄÄSÀ-Ñ]žUØ{G+«4O¼[³çày°Ë'ŠÒÇ}{-w4‰$ßA¢}ÞBL;#=ó&}å™ðÁå½bgŽƒú‹æ.š4Mo9xôî2ÿÅT>¶(Å3_¹æE ¾ƒ£_U÷i9ÜÀ LM§§„hKEiÓüž/›Æ¯ô}ٌܒÌÏÇöh"7Õm\넚%?_ˇñ,`š«Žâÿ¬…½Èš! ÅÁ&È>\aˆ‡³H#”8SkŠ<7¶·K³¨“ø·ÿx¢šº©]’ï ö8R¡Œ-g&E4A—/65労ÑC•ðdâ¼tg+î/ù>]3šÅ YM“¬…Fzj¸³7½˜¬Iâ&0\İ”È%Ñdh8Î-¥ïû ÙùP&ÞTs\(u¡ï…À —Ûw¯lÔ+>ê+ˆ¸Ãg,£ ÉŸG¤Oä–}‰gxÜܶÊÞЯV𣳾Ó0œ>ž~ý.܉ýú›ÃÚŽT5æeO¿ÞØÚà‰óslÓ6‡àÙJ€†RŸ |CÉ—Õj­`²’înr-Nâè‚ØsßIXÛ…ò<øà~€Èêxt£÷xË*õ9P;>› ÇNÉÞ6`Lñ±—“.íדbTr€8sÀ8Üt9×°ý „Ž›ŽWÖ=¾}´À* £GÅ$3bÓx€mc²SÏ<@ú˜átÜ""…! Õ’Ä!/hNIòçŠî¹ƒ6œ~QéEX*®¦äš, [Ê£íß&¡ÁWË OÀKâ+vÏäÑPfT½¦É€äzèÊI4I:F6ìu€ÝùÁY+¥R‡miJöt2,IÛ¡ }¹ |•ñ¾¬þ['/¥$ =ô `ŸŽÂ…a¹ в8ªWz΄ ž$oZŠ¡<Šî`wKO˜ÿ‹b˜‹DAúGà9Ã?MxR³…5,ÌÅá«ÖÞOpÌæ½<#“ Ñï B :ÿ½”þîýûåÉI ã¼.ÂaÉpk){¡7„oN\w¯°XYY;Ž•“’gîåÜ‚H$ÕûArË):¦IZß ‘xEfÖ î.§)îÂèÖiaC /P±Šp½È©Ë ôìN‘3·Dr…î;Äm8äá‰ß'ÿ„Ûá0C§-·éT“Rú@„ø(¼Ë©’­‰3Å!y­“Š íƒBêxÉ!¢P]§Xt• À_\¶iÆsÁ6=ÑKž4­> [˜št»/ f³G’py†0„ÄÖ3ŠfÚÚ“øÅ€EUŒ àóÿŽÞ)¹ÑÀƒ1'òÙˆ+’ 'ó‹Ö7†× ¸.jm;£aê ÊÙE)ÙR!&ðÉ|R™)Þ{ —ÖR­,ňªK³¥TÚÒfË©Y¤l_Rõµ˜éë^`«/]Öw(8&¬c´ïñʰ3H›Nûz8ž¢ìºdôZjß¶¯Ÿ~ÍñY/ÇxEò fݣÊôá·iû—/•ÃîÔpRE»ë‰Ëwh¥©Õ"Xþ2¢ÿ$cØJp¢¬´öê ÷óx|Y¶­åÃkþãjÿT#ÏÉ—Á½¥p¡·e¯lçµ0JZÒ ZK‹±–%^-ʼn83ܯ⅜'+âÌ1„‚ºæ¯¾’³R¶õ=³± ²ÕÕuûVÂH&·ÔmŒh Ec{f=&ÌŽ¼‰RY§R7­oü4z‡X|U«i°:©/e:ª£P kà·›Þï"?Ž€ q´¿Å°´ôHþê?._ÚHTÛŸrˆÑwIÝx?ˆlKr;ûê?êö.Ÿó@ªÉŒ‘„ŒÚ–‚…L¨°´¯øú¾6­\oj÷he¬ †Š`çñ^6¸Ã *7”…7w²åÞñ/µ¥Ä Ÿ’va´¤x *„`fó‰oå”øÍš_!߈xd}_©gdS‚Jè”í—O‰ª¨,¨„lÚk–ß-tijS î·_?m=ÝöãaÒÛÏ+Ȉ-/~vÍ|?»ÚQ©«Ôe1H 3¥¡#ã™—U9>¨4µ¹AgP´ ’Ùɉ¸Ð”ºÒíÃ"£» dŒ®€QB¹jÓ![ ðfµ‡òÃËñp:"hÏA Ù‡l¼ó½Á¸Ú·ŠH€kËþ…·ß¨!CG:N8.b¨Â©¯Né{,kÿQ«‡è…Ëâí >cûæ©^gè…m¢þÍé Ù)õ†RÜо%5Ô}X&º O;°•ôî Q‹)­2ŽÐDü—#áJC+À? åÆÊˆëd€â]ðX3’–øObŠòiŒ j£ˆÊ‘ȶ2¶-òãiÇöOÕÖÞØ}¶Ê[¹,:Ì7ÂM³FæqJ3Ý…?åØóJˆÝt­Äž…-†Él"AHQ)Fb:Vé”Jɹ ßc_¤žÛ²ár:3ùŒ§¦O€a«¤ÅØ$Ŭ‚?¥¼»Ú`½ÙWÐ-M±}TyiíÃÄŒíAp-—fh4ÿŠ…¬jlí67$ŸVþ*dž¿„üžd¦4'Š•U‰“$E!ºr«__ʯ¾ÀšR†ô x"I’½Ž w åÑàÆè.Ê +f:‚Í^zêrŠú:Vµú¯ŒG£iSH¶M´Þ¹×”®ÐHû¸±²ÉÊ2Ô›}Y-qfòXÕÞ%µ­‹tÁoÏ"˜°2:›7»ª3ÂbAÖ…£ÊlëŸxS™·‰‚³p¸€¶É!¢»@DØå\nž_—7å8zÝožý“ØFôWÝ “;ÈlÄGÁf5¾Ëô–ð-·ƒsÞ²³£ŽŸƒÁ€á8pn¼¡÷4£ò{E™0÷.ó—P'^¼ÎqÃÍò¸¹¿¾iÚ,qw‚ET3É|lJ8 )OÈxBÂó¦ñ?ñ+ú”á¡ráÔª}¶“¤o6·Añ¼ZÁ{/dº|GÚ™Á]`ª @Œà«¨óÏàî9|PŸSd®àÕÅê…¸;ôó„SkSij  ”@üxƒ–,âŠɱ){š©ðnªÁ‹Xo3Q¹œ²Õ\îQN þß7óÛí G a>åîq9<;Á©ßn*ÈÜ)s’RÓ¸9i0APé¡éNÍ¢Ê 4ÕÀ¤è“Ç`Îy+¿¶êŸ¶àcº%•òRÝŒ+#MÂ×P¤žy¸˜!£+NOl*Wx¤o­t:®pi«™\ùúÏ·  °¥ ¦@ּ雺é-½ÂxÐÂhÀVÍ4«YCƯ(™ȼ¨nzÉL@ì…{ÞNú#±ÙÒvÏ“—¢²/ç õ£ïc³ +]]Ž6¦¬ºKNT VÖ1@$fib™ñ»kÀ y6qrTƹå÷ ‰€……±Õ¹ƒ @7e†%îGÀÈl¾ÂèÖéjc">Ç!qÔW¬æ>!‡-ÄʡؙZëáÂáD¾I €ÃA7éåa娾_kªÌå0TðëÓúAóW^œ6çK œœTØ,9eráH6`iz€hÈ^LÀÊòÁÞj0 aììÆDUH—Íd,úV»ßñäÍðÑ!¬÷¸’‡m€Þ\gÐÆ=ËÆÄ=” p^(xëå5k}?âAe7?×ɲÞb!ÜvoÚqZP ˆ®œ$:÷÷›5,üâ Öú Ÿ¶öÏê{­òZá"g4xÐ"0‰;Ë„t­7Ž0aİ„ú|©š²–ÌrVª’ŠY‹û6Š¡dû/À ÎH¼%@j´—ô%˜E";n¥'[)bê3ÿ~?_z¼àúÖdìØO¦Nsìw~–ibB>¤–’™ÜB%ðÂÚ0 ÷v4.@³MËö¬üy¿¯×hC^Ø`ÁzçÜÇì 4Άídê„jlí²ŠÒï"ç«ÅD¡zß/$¬ÌUÉ¢V¥`uaˆSÌèç ȵý^šÍÇœÚNAŒµ|é$O0UlËxâþ­…ÈWã.eFˆ‡„†äµRz1ºŠ]0öÍ;Z¿a'VV0ߨ–µ»kåOó«˜f&x°~ð"üàÇü*%=X9ã„aøêqq³».†Ù)ã{nH­D"7( ’NaÞúlìôw¿ãêâ-MÍ WK. Qo1B 3´ðòñ&øæ$#Öñspÿü‚n/¯Ÿœoyk•Nª£«Þǰþà‡ðƒÿ˜æ`Ó8™Á*s±™0O›YæI¨oH€&۸ȉ7vÎ@ êôzô €aÈX®ÚØÅjHÛ=“NÁÈõ ­£×­ú!Ú³ÁŽÛ¬6ê'§ÇÑGÈúgG÷[øV'HvýgJuþ²ÑÄ|yÖÅÅ:îô‰HÙ"R^?ߤ´QëÏEæ=xÜÂ@ê-¥=ß‚ ë?×nç9¶U©c¾ï ¥ ;m¼ŸÎZ_7\åEëlŸ÷\zxíØÖY¥ô»ôëFéxÒšùyÒr‰±_uCâ»ÙZ+°ÌRån¥€Œ9ÂTšê)F³ó9<¢s4n!’§ƒ‘=¹¦¬~ºHDFÄ-ÌoK›w'R]ýZzk FÔ¢lé§ Þüžé"¶X²vw¯ÅÇWs‹š÷F ·hyn+1=£§;% 0uç3ea¨¼M£ ”ýà<¢_®ãŽcñ*Ô²/½ao:qf”†1C…d´… {ÎÓ Ç‰…íO½ÖÁŒö½k*éšËN¾e¤^É€0êNZc,o†k^ïÓÁ»Áðf í;Ó^<…‹×3|Øë´äZÀ,@è7é ®[ar=F¶éÙ]'y†n®‡ÐWv¤è#¶=¹´9¿tÔä*#–Kbv•cˆ­1ûXSÁùÒ¼Ÿ^Ý›„ç̰ˆÐÖBÆôØÊÚî 8çöå}õrê:Ô»ctÑU°V d0UX].ÐÑ#öÑ£ / `¥µ¯¡Ê•; l!Ã1÷*@K¨¤lÁñ„,ïwà¸ñá²ý¡¼Ö ‚вclÑâe»P$p¶Çym,\‚èÒBd*Zrä^ìéVq-6Vó˜m½·{®œa‘ü¥hõáHlÙå!ÙÅ?RîZVìËUôä“*¶9 ºðØt¥ÂÁ#7@¼P$Û`·KpÁx:·°2Ûî„2÷tát \¶oºÈn)œ“™'"# c*H×%=b:Uð(_ÔÃ|0:Dœ÷ÎXÒ)wœ%³ëùS‚Í‘£ù#˜u.®)Jî ª;qa¿R(£uhÂÿä¾í zÖÑpŒÙÍíΑÞÂDŽNÊy~9|OÏ@ëcØµÊ vsf%…A¤6%\ð£ Þ9:¡NÇ'utíÁË×F3Ðᣈģt‡2œ6 —§Cz{:†ù©³=oÚ²ÆÚRO"êºíñÐv'JxPÿˆí‡íø›!n‡EÇsÎìì{qª‡“ *©ÔlX„êëáÈY÷»ÅÁJÑî—%¥.ýúkeW „+«-Ý9Êá ÿE˜°Kw2v¯Ö¢T!r¡©t™T+ux£¥±¯D¯Ç@C¯=†…oQAÓ#u‹bï ˆøÊ¢<ï[?ò ¥iDm—p.v»bî•~®&¾N®Ëœ–V»@Kõ‰ÇŽÒ¢`PõÄ8*K슢càÒbœ×È]i[‚¹c¶Á’Cw{î䎬#žójxƒl¢ˆ\ßߨc‘@оr+»7l¿³O"À^kLx‘ ¿#f₉²B»…LuˆDë{ñ"ƒÃ׉›*nL]ƒ‹>”Q¬pW<™N&bö$vÃ#ŸPÁ²xûÉxì¢3>Â8èY ½a¦«žöZ×Gt!æM3Nä F·Ÿ–¹P!æøs #%.Se Gƒ¶‹7V··£F (•HÊ-‰©µÀ°Ý ô¶¸@dHUw;êS)rêe¢’B¨CÚ©±à—‰4Ÿ %Æû¡¼ÑiÙhÿ(ЉÜG4ž¡è¢¼õ•³ŸW/οZ=÷ο‚CkÀPÄ"%p'•µÕøVp5ëÙÄÆ¦´Ógæ²l#x°¹Q&“Ü&éÛç¡ÿÄ·›(üVþæqy£¼unÍîÆ—|õ¬üØ*—Ëa [d3-”CÆxÉýuyËLöž/Kð‘?Ÿ½¥ÂWÁ¿0ä{K—ìº(Bl•ë''Õb°‹ñ} ÈЭ;GÄäÂoŽÂ/Š`„6=Íùæ·ÿØÊåÖÖÖ¬y7Ý õ¢„×šŽøž¿ñFZÄ>ŽqüG(ÌÞ¦¤¥]’ôÅþa£C™*Ÿ"·Ä]ºˆ&C>‚p¬$Ó}tÀ¼q¹N ŠÜБA#óîãPΕwâ>phQF<˜ŠÍ”Àl•·6ðÖŽ„º¿ë;˜Ãj£çñé+ßÓÜFÚ’>s]LMÎÃú š£³(ÝFJÛsŒáes<:ƒ¹WSÎÚ*#-”s~Žð›ÍOË-ªt,‘@w Ÿ¢spßÝb›rA§›AÚ ÄÇÒªf5QõR›1€Æ¡µÌéVQý 溽åÞ Y¡Ü±'ö˵ê«c+ÿHø ½õ{ŸG-b¶úõJã§V}ÏÚ„ê™ëÿPk4ëÇGÖrßþïp<„Fí‡:ƒ;ï]ä‚é TükQÚt€?ç,7*Gü±Òî„€áM›Ï*=ÞZðYbNé@“m’ hJÎ;?lGŠØyŠw¬è²£øˆ‹#ÞlªN¯kb–R] ¨ÚU8’ü{è9£kë…ƒ¡œ/mØšÿùßñåãï.1Ù:,¯oéÐðàÓtT“5h|áÌo X'Ï耴;~.ÈFÞxYHX¬¢Ð»³úCæj ZþÑ€1‘ -†7¦T¿„rP%)ã¤b¯\ôAÙ2îf_ê ž,Âq+Ú;8ð n8™I|>º]Š¿Ý߯ò× ik}`lÛ²‡ï±7Ó‘…F_–‚¶á«< gy—ãw+[«l‰UÎ.³IÇÔÒК*¦¢iñ-H ¿5*G{LJ¥ååß­¿[Ûß<µÖ­-ë|ÍÚzºµ¹½m}em>ÞÞÚ|ölëë· ²_ün‡vByïÃÏZòQ™>F*g0,pìcM²ä ¬DG­ÄÆe’Q¡éì¾]ÉdÔžR²3ôHì¸Î$àCr¯$x%|‡¹ÇƒxÍCÏß!ã² a%ºKó¡{}þ|éQ(_‰³Û¥ð9´Vþ†¯ñ¾wUØ„N+æC-“Ô:‡~þã<ÒÁF';+Ãmóñ©Ýé·i! œ¿a‚â—A¤Å^ІkÎou ~¢9OµŒ§i¯}Yߦ]!¿EÅj¤ÐNEUMçÏa;CFzµƒ`‡ïÏóˆÚžƒÒèhzT¥ÈÀyné¾8Ñòçù·¼¢·ÜKL‡f4³HʇKFlBUføßl±ÿ·k•Ã>°±Ûß%)<1†Sõ¿¬.ù)ŠŸsŒI /£ÀK®7Ю ”b´†Á†Ãˆ¦Žj~Ö zïvÕ0°Dfð°aXŠ•É(¯5 Íȶ4!y„CN†Vµb~(àêþqÃzR~¬èµ"°1´ª~Iͺ›ƒ×ÒãJÊ ’+Çî1ƒ¾íuA¢ÉcÕ8¦_úï¼ë1l|z£npʆ¥„” ÿ 1«‹°Š lâRÆÇd;13RÃØyn¥CséWË>|ÞXŽòË‚M3À©.4©"OÙl!¼ÀÒF"ÏÄÂÉî¯Rõ9EØ,2Îò(QÚ§’ÉI'ŸÿM8…ï$©” ­?´[r³ ©»ä€ ¿ÎZ“õóÍç뉊¢`îž{;ÖÚsë÷çÙê?ìáS÷’×»£ ½ï\Ô,-^cÄï‰L®š^PûÖ•‚÷ËWBãîÄ"îÊ@­bÛPËÝCª ÂfWžåN<Æ3±§$ãÉÙl`>CÕ¥™gi<‚Äß𽌼ò‘^¤KÙ—çÒGY™¸6ï¿:-ë^È/½4ën‰–œº1.(ç¹r‹Ï1ïsoBW«U;Øoµð¤‹¢@Í*ù7ÝòÕ·‰F>1ü‚°Hö’3é#ƒ-ß㮬xJØãÒÝW/¶qbQ -—׎½ E•Š÷!K†û{ÖÖyùëY†\ó˜Û¢³Œo«µUþº¼&KƒRÁÍ¥5-AH°¨mò¸d?2ò ›ÖŒ´æµ?:Öt|ååìdhMGWc»C=$0ÒpV·þw£1  ä¾S°=¶ˆëâRi¶©% ]-ɹ┢›Æª¹4÷ G@Ð §Hª2¶F¶SZÀãÃXò}YyÆ•7¿E„—Ö‹VV‰KkvÆò#ǧq…À'OðÉê½zC1È -ïÑØÅxIClñiù›ÍòFù±t§e“öÙVôÍêñ'^ïA×?»U¿D‡J!5cdZÏiOÇm n¯(²Á]»W×äë̆ñÊä M#"ØÔ‘aàõ› Ú@öìh†2¼³Ü7Åì¢s ~Ë’.œœ[è{9S¥À±Ä²^L1†.50d"þœtRÞ¢§¤HQ>¹qÛŽv=7‚%\²ï¢¸àB¼Ó–>²ÙSzY~ÍÎÃ?—$óœ)ß y¾°ðqÒ)&fO¬Ñtì”&ÎíD“W}C„d¹UnšÐ:ëßhî•ê?íúËVÿÙoõº³<‘‹kÁXXºÂ,r)?Êj¾1·;h4Wp]Ã8ǨÃ'bÜó†]ÞyK/ø¹ƒWðÀNˆ«‰®†Æ\ ‹7ò7›eÆS).Ä,Rúø²¶!¿Ó'›[Véý¾<Üi6jFß$c‹ý ÙáPÓ’bDKâMC’“`²ê/hßf+˜q%†ÝµâHn×åp7¥ƒrv‹×°Š £pø—ç¥_ÙÕÞqXÉë|ä¸$ˆqÏäèP> Ça×Sø"]AÙXAf´ïõÆ–n¯ndãQ²Šz1†£¹¦ËS¦RÌÒ©„0Æ”•ÈȘÇ `]Ø0ÉÈ£Å`RJ4ĸ?,.Ñt¡¯úôŒC5öZ B¤À–¸}xÁD ¼z0l9ƒÉøŽßh<ñ^Qj—¢véþñi—îœv))2íÒýÃÒ.Ý;&íÒi—2F£]úŠ6>Äé’y¿¡ýLƒÐ.áQ#ž?R âà]p x"F‡tvŽ0i<<Ç}»‡UqQy“»žÿºŒ¬³t9žô8Ã{ß¹a7K؉÷h—ÇõïstÑ!8Û pÉâŒíþa›XϾ1\À#¬³î$«vÈ—‹Fœ^t¤ª's†µ8«ÄÉ]ùçÉ.ñÉ|©hFmF¿ƒ•òð¾8æ)öeÙ^ÁßÞ°üê%ó]®vâ¨_„‰—×>0õDSKŒ£Ëùd6"V šzýÏ IZ·¼¸€]Ü.‹òd="^¢eS´Àªªû‰a~©K úwÁ5šš¨·¯„Lqà /†å˜Õ 6Ï¢lí»‘,èYiÊr"O”\‘Ũ@íÝ%$EHd~¤^¢Ã^XxDÓ¹ˆèŒãË–0í(KrEpDœÛr: йÛÍËY´üyÉîG#BêeŒ oCú®\”ù .ØCÕˆ¦› 8¥HsCLS‡LXfìuPƒíƒ!l`ÜÇžƒáCqJd¼:! ¬CmB?<Žç"1eK¾éÃÂÌbpØÛ}TõR”/@gÞáÍéq•Âkuᤛ·ì°Ù>«\ØZJ“afćS}ó†ð¸^etâb¹úê«uô¥€.0o“Ξ·Ò²’kÿÄ"âõáD»·TCŒ²ÈÓ]ºWܶœÄr.•®°m™1ÈprsðàÂΞ¢JQT!µ0ìlXÜ-êÉ8Sr-ö`Q†}šŒm™§ £ÈYì‚NÙÒ”87^òà^±*ôùj9ÅP=>ðIÁ¦¨AW)NÁ¸ad‰þRâ&htG€è±±¹ìô¥Ì1A!Ïóc ¡ù ò#ŽÇdm—·øúCñ»é¥H €–¨TR×Ðù›Ž°Ãñ; µLcôø+dK² ±f¶¦$©³„+¹DOe‘·ê¾PêZhÍTFÅñC¼ÈkyòÖ0ì½'Rn‘v)0Ï B±u¼zì`¿£IxøzGÕÀe‡=½X=›n¡Ùâ ­‹¢ât ÂPiWr$"ö•× €îN˜Q$çàT,Tã¥×ငaýC@Q<èïSÝ5 ©6¥Žji^Ïï¥LË£;Ü’p* {„ÊLñA…“_V¾YybO/ŵh½ËP~µÈ®.ïWŸ¼½ì(VôŽ/Š Ã’Q&02C”>‘ ”uäë*±ÐB!WuŸ·$ÔO(£BΪâK}…¬Ñg‰ÁëZ,-Òp€í$eÇ®€ A9¸`0ëIù‰¯Dyr@ë•*õ^8Ûz,ïÌïßñM7m©/)b'TA6gÝ8JwŒËn'<¯šE¹’3“H˜¤ õv.R€µÑŠíZdB¥¢¡P_X4ËæjŠÂT ðä9ŽLÍ*ß³ g˜aú ¾ ;Rž…˜¼‡)Ñ­•Ö*iÑø"]D&¼r†¨Wc׫âÉä`Î;9â<;×éá‘4ÑÀ$Ô£A0eÖiúë|hÓŸ¯#VHö^-’röÒÍãüÑÉ@‚"©Tègaq˼®¾ã® ª–2"X ‘Y{`ºO‘Ô¯ýÀ·r`«|ñÞîMQ“<–c‰ UW‘ðËšQeó§fëðxïõAsóÁ‚¥4t«¹9"¶9ŠîíˆÍ`§ÀkP<Îç2™À“8‘åVé¦WXÖA…Ƚè[-ݬiB…ü%òxESœÔm;Ïa¿å>¨'´ó°–Í*¨{‘Æ…g3ÝÌSÒ°ä\Pnrø¼³.MR‘f¾ô+pxîåc¬·#3—?Ç©SG™/dšÉ@|ks™/˜.¹s"ë'ÎCÞß6îµÖ–Œ«liÆúZZøÊb96 ˳¢<¯ÈÕÀí4ù32;‹·®1lHÈóÒR¢_OTJ×>ÐÛбσ¬ŸÁÌA q±]Æ„¹.GÌt²º}iñNVÐñH\‚)wq"7ËhJg 8c ê¢S©ûÊÚg¥‡Šh£Ç ׯV¯wZHàéC«4ŽpŒîËÑFþX>ü~¯ÞH(QÄŠšK»Û¥±÷aÁº£^ö–ÏHЬ j_Âó/žˆƒXí žO³*{iuݼp:‘»¨|˜å•«©¼÷wêÚ9^N1Øàùêß¹ç盿ʿ-„5¤ñ9$á„HøT¤Óðܾ۳I»†ó:ÊØÊQhœòü’?!ŠujË8Í>'®T¾@á´ý G`döÁ&oá¾ÚÒ*,ÇLsĈшq/[˜½R–…½«!N´ßÊúP$ÕÙ“ø°xGBšx® ÷þ%Z•(?Òt4Oõ\(óöó•°löèoÒ i%±&š–ùëîzÜBV|•Yð‘õt[Ê}‘W·ò( >7zz­œÅRŽÛífв\UsÏÿÜ‹ì^”z í¢:½ÑØÁ )|fœ¨»`Uþ`¥b+¾=µ95²¶ˆ­ S;šÓÿ.8Úy "§ZJ)´ÁWôâOª(:µËôÌÁRJûöKa’(_@wÈô/}šàÂdÄynÉÀ¿ÇÑG˜E6ðgH(RÂa?†Î{ÀŸRæ>€9Ú#‹,2µÄ4C³6¡W\“«co_÷‡8‰mÃÚèu">UX‹ŒX”*½‰ Jd¶»ùïŽ_Ÿž¼>ýN'ÆIK!_Qðôøø e*Í›ŸWõF&5X&·µríMmUO¦y³)­+ ë€N´x¸³ËÑg†ŠZ?P2R%ÏÈ;¬Ó8¬Õ÷kMÀ,`AñP鲇ŠÒN$‰.¼Ë³Æ*ɲ $Üc’Uâ§h÷1·Sq2jtn݉µ©ã…þøNjŒ³Ê“ùȪ°ô…R‹Hm=þÒË_TÜÐ=J÷raýªØ}|½*ï–V©×^^—Fþ¼qB—ÿ˜±˜÷£Æ­#ûÆ sšö„²ÛX8‹ÝICièßÊ´0!ðžÁæðbÿJë¼{l\I磎=g™ñµ=ò†;휴WiüX?jÔ¾¯Áa±V9}ݨ5WtÎÕô6‹òK«tŽê”ÖyÑé*Ò8%ÃÜçEsã.–É"OÆ”žzœ‹ƒ´¿új<Ù(¥6 ó‚cðl !ô+À‚ˆ ûStc RuJ{>¤ùbÎøiÝýf<ÿµ}Ÿ8vœ@÷i¼V¸®ðèܹbË †lÙ6“IOº¸RÂt½Ê§À. Ó0ú,ÓœÝéÜ’—ØërˆóL{#Å´/Öký‘õz€QT§{âàŒÁÚ¶àÏ+àØ§ iíÅ–æ8Û›-„ê‡Åôbp3;×Ëœëì1ÑîùŒ‘Çr¢y©¡dÓWsW@äj±}…îïæI΄üǨ¾Ïý9hõz4½ý&â´k2Oάp,=.hüMï«KÒKiŸ‡~ŸÜPçó·æúyáùçQ” ûïQ¨Mhª%6[ÂðqI^Z8ØûŒT]®3NÿV"›µŠ˜ÅÙ„k¶ ÞÉ@êQ]§`9;èû/³ j¡ÅD[œ ÝížnøƒÉ0D¸!±ý<îó2º,‰CÔ¥¸¹aZ‹Ò© –cÑhø2WL˜ºëP¼ø™‰å¥Z1bY¢_Ì É°}©Ù Ôè#3P–È—²Ð÷RÒ^Êäô³”™Ô–æX4KÙÖËR†¥Íš‡Ä¿9ñG/K—®G#{ cä§A«.Žð’È@ù©Cógl6yM’=&¢žcmeïÓ‚ûs_vóxùѧðò笿Ýr»pÀ.Zgð-áŽ#g \„››å -‡®½l5_7ªþcõMµÅϪ(œaÀlr3-b| ±3™ŽÖÆsë÷ ß’¨Vý꫌5d>ŠgϨ¢tºŸ^ŽRÑØ ÀHémÐ1ÖMWqUnyT5~¾©¤+8^h­þìªsÛ\˜·ÄÜ3­Ë_†/XEb¸[´®\Â×DfN}0;9|(YEZÄéXSQÅW*~ýQ‰?õØt*H™«!•cQa0ÏõŽ9õ”î¶wÒâÁñš¾Y¡S¤°Ã™EWg›QŠÔC¬}ûrì¶ë…ÓëA÷-÷Ü‚gºƒ;«ê'K ÔÖ=Ä-Gâòg”™%íŒ"À–a dUf $¦oGøþìßCÿ ®ŒÎ7ôž~ÂþôãùØ\#[tóÁdHŒ~œA¾D7±t.]àÕW‘#Q©ë_£7òz¯Sö†I§ðT:ç˜#o¶ó«ßÅ_­üÛ” ü­ÙíýAXÖ½ä·Ô ÅE`/F #~)BëÃc{žÁùŒqþ4CÏh¬²£¡Ù×Yb¶GlôR±Yö>HpefûwéÊ·êGõÓúQó´rT­Y§µÆ¡ü’”ÕºüGnIÀ—fËèdtž—eÎó‰©çt•ÓŠuøúà´~rP³ŽŽš¯*Ú^jl:ßœ]ÜéßÂ2èSØ®çÉÇ >p'§Î¸Ÿ_ï¤hWÀЬ²ôŸöxBæ7R˜Ýo·? ÖW|áB¦ ý_$T|4†ÅxËë,´‘ÿ#ظ$”]Ø¿ˆn6 ŸvÔýJ‡¥|CÓùÍNþ9ò°H›¡rçyoýgι¼Þ:ß\¿¼ýÁY©¢I$µÚ!Víb÷ ¸ ðÜßàß[èvbgl7‹mxké>ά¯ž÷¦E«é@D@$¥ãùZ!ÃiÎ,çϬÿŽ;%àҀȃÅÏEõgÕÄ(‹kÏ@ð÷ÉÚêÒ#¼§¢¤º°;¯ªJ}à–jë³_ÕÂ4¾ÏøŠjAó'Yä4.u3^ǹxüÖ W¼Å òœJ¢kåÿîY÷ÎÏùè=cþ|Ùe‘ 㪣_*Eƒ®Ô¥ŠùÒ5…]Ê+E#N«‰“Dâ`ì’HÊ$Õ‡WFdªROŠ;;Dö¶@©4^ ÐÛdÈÞ¾½ Luü0d¼X§Ò»Ë´’ä2Ò×ÐC0ýÜ:œŒ9Mx¸Ò¯htàëû’6gDÆQ˜Û暣»ZÊ„ˆßç¶›;¼\1‚½Z,š^ÖŒKþž¼Âf âP_bs£&Dü?ŽþCÍwi-//3<ëIy#Ï–5b¶ )TT¤d63y4ÏiõƒŸ|r-+qèÁ4̆Ð4jFOÚBL¥@¼×ìÌ«¿ýæ'ið™ç'q¡%X\-úB)évØÌÒß8A÷“‹ Š ?*¯).ó|zJ~‰Òªu Ó,Ü|áá%Z“à~:v†c4Š&Alåùöëª)j¸žBä…²eÁƒßÛ06 ¤è‡A%êöPš—±Óöd¶4”¢sÔ8™@5ý@üž‹aš<@k«üÔZéÛw—˜bûIyó_ãuŸË~T0rL,€¾šíI$©(!ŒûD)ó @rs)¦ÞÆuðq¹Œç¸>¥=öû9¿L1ê™>úÓŽ•À௑aŠe¶Ni!ê­K§m‹lb“ë1úðºJN&ü^Ë”'ŠüçÙdŽ}ìÝËÁE˰ž]LEÎòZÎ¥ó’)wØìì/ã½´)ÿ3‡R™×½fÑ(ŸÌÅÔ»óÞo‚î1‘lâ ÜÕ´È„8œX‘ƒ°°æÅHÿú׿h…-y®Ówl”ÿ葽Á$¸$k$X âprP9<¨¿%€ÿ;õ‚·/ÇCÏ;v¦Ð:åpçãØÁxÔ‘¡:D.‹2µÒ†[‰v²Ô¸ï'ŸºÁÐzt(:È`Ø6Ͼóȳ‰clß+óð1r­;àSŽ™oªé± {­Æë#Š5^XÄ2(?þ”A’º™þf;HâkàÚáIÔ†¢Ã6§ÁªhNjÉ`n¡Î´2ѹ%¿¢Z"lÌa°‹¹gÄLo(b!~yr˜v!Ü” ÿH‚õ¹»‘ÑD÷åGðˇ«q‰TÀe\ê”bJIýhŽá×Åj®Rm6_¶µæëƒÓ•³åX$@YÕã8¶]æµíA‹Bû ;Êc¯*·eî·êÁÌ%÷jÕƒò·çP‹øi÷ü\Ó–7íb¦àNw‡ñ¼‡žv½ Ř¿n⯦žI> «ì ÍЄfMÆšõÁn]p„›3¡.í“®“2óQ2“pôCœÈ³…RiÊsr«7óL—yë{€’4€ÒÆ¿ QXþv9Íž˜G"¼ýp‹{s¸“‹¨› é(®£v‡7ûÔùˆrzÀeë(.kv]êÚà•‘ÄXäŠY+üQPD=ùE:8±ËáNö$¶Qv¢’˜¡il;¾¨"–±Tì)v_uuõõÞŠï-bÞó¥C¡f²ÆÒ‡Ëwâ`(âRä]ÛD m’³œ.æy„ºeáðµÝ;vçΡžÐÃWÌ2!,΢N™°¡M¦ØEã´Ë×h»ËzH =ÆMÆL¦‚ç&W€R~ }›Ý-½çΛŸxäÛ:P—4ۆݲPtЀlô¦5ÉÍZcëÔ‰àDæ%u¦íÖù·çÿØ´Î¥{ÉyžÈþœ.d¢ÔªšEšFtxv‘V¼×òàdª,"$DóÐÄ¢a9 åÁM^kª¤km~û'|Z6«Y3ËY†gZÄæXˆ`xoã-èŒ"= H¸±™Z2ox? F3Ëû8ɦ(·9ÂÅ£i86$Œ]ëãTv×§ÑX¶:ÛVxF'1Á46©tLä ²QÃL€ÃfiÀ,‘ AƒÛ–†dIø¡vÇN·çÜ¢(Óé¡§™gj æ*0¾Ÿ*8”¯P6é‰ MÍúŒ 'Ük1­ÑM»dÆ!¶FÜÊpÚAf 7oj06æ³&[U)ü(FÞ…ò%or×s|y0NŒšÝT¬('›±„£¤mW^jb´ØÄ9zïì^¨ËJ4J3Ér#)”²Ÿw!5<åÜÈ` eûtÇdo\óxD¼\÷‚ŽÛí:˜5‡/—9§Ò õ·œÐ‰4ýUF™z|VC(Ta¼à30q ü>-'Ôû‰ÐÒaÆ ùÔ|Ü—ÜcÃíXL«F0nS<˜h#&À±çfCC?N‘´Yä§¶uéÒ;Ó±ŒEYʤø2}TXrx8í"-HJÒs8ؤ顯 ‹›W:ùØ(d_ÝåÙÊ2ÏœŽ°ï‘ÛÕ°%¶Ì\HÛšíyò8Ö¥îÕè׋9É­^|,²f©‘-Ž!PˆQš¢[¾#ï§èŸÐs«/ä$f(pо“yªò²§ù¢å–< ã#“ÀƒÎµ=¸r0!¡È ‹É©} ¯•Û ku2ãu:‰¨)PDñ™pÐD0q¨A´°Jg®©ÓF–¢WÍWõ”Ÿ$¸]ìÝuÌZŸØ)ŸmÚ:ƒ» åqHè•_ˆbRM/¥UPÀ,ñe²[Dâ ûÊÆíÓrKW b *` 2Uv0)ÃaŠÐ()XéÁ@ó1¥,©dLkäÒ¥^™E’T`ËÌþ?˜+XYR±21oS†Œj‰ê„3Yãæ8†ùÓIbÕtG‰*-R[…[1Ö3iL¾)7KJÎ J™à|Î÷ŽÄ5b;”ä–D¾‡Ù-ÑÔ·rr&˜Ø°Ìgd–“lÏR>uäò3îY+rÎý ^.S OblãP´U1r‚d2¨AOêà0¸áP é}p÷…5¯# O®QÉè®á ƒ5’Ï2\ÝÂêòD¹X}¤F@%ÖÚÌårâ)…kkUöë/WΠ;På‘UŠùWµ‡ù?ˆTøh3èºWÓ1b”ò<ލgUƒ£§.ò¶;€#¤µ2ÊLŽç(5¹ äÀWeê^ì0÷Ç}ÏÉ= Ÿ¯ÔÞ@©‚à8…r®¿ ¬©;¬œEFø=ƒ×‚pœ—V µ3¬å–ªjuw¹ZÍÉXw'¯›¯Vª¨Œ¶š”Š3ø€ Vì"¢*.B¨€Wαvo·µŽiªLµÄ¨:‘ꬨÛª·üLèA„& WQ~eq›Ðˆ†£Dˆ:Ûuå“»yŒÈ‡ÊÛ–œ$k×ÚxžO†OÜ= œ–m¹€11ÔÊêoåoecõùï_õósxR?¨5½œ}$ÿ)g½(TÌî3ØÀföÞ#u.Y_•†¸ÿ ¹ +†€ä¤lÁ `3}v±Êù¥ŽŽOÊ9ÿØ¿WÛ¯¼>8%R¨HÖ=FNà­_± 10ÜYBhqØ9&dXëÅ1þ99¨œÖrÊBUçвòC­rjÕ1ß>9•¹¯àô»¤=Á‡éY¨ØºC<™áHû6&f-ʰË,€"’š¦bbl£´Gèºq=<Ñ2ÚQ2„Sœ´01«u7œZïà Z›œÁÔ r|î ñXT.ç|;6tl“ n94l·§§u‘±I{uR¯šW[ǦÇûð»up\ý¾©¼Õ˜ ò¼ùS³µ÷êUQ&ZéU¥±W=Þ ,›Š²öÁñIí¨Õä@Yԓýe–G{VºGj8äDGH’áäŽB˜L¦¿•GãÝYà $ÝXÔ^Räj)C §<Ϥ8ôkúw—á[G¼?3À÷ïv¤nÃ\½ì ¦;NMùHœ|`UêoŠQ5ÝAù™3ÅC?–´R25LïDK• !¡¬H¸b% žÃ Þ¶{+MG5Ë ýæMí:uGÞnk$Ìé¦õ+lU[µ›_V¿þq.TŸS¾?MºžCó³y¬ 9ÅÞ€oãaggÛ¥o|›EÙ) "ÍyeiÓõº6R‘¤@¶ø¶¨¸ŒŸåR;,%%ÿB/-¡ ^\¢ÌÒÒÒ#]}ŠOèç#RùYÃ0… ®÷~¼]\›YUj ûNÿY‘ê‡ç†ÁóCp¶¬Ûü0Eú]¿¸ÃëFC[êE¢å ¾H>D· ŸDÜb 8²]mpÈÛïøN6‰f1Ѥ†¶‚ŠˆTÕû “D?df€ _ª9>É¡ = © N!Aò͛Ԣä<Â$¥¦ûœÅIü&w¤×§õƒ¦š,XÎ<ÃïI1¢¥.år‚®7[ñy51ñ˜¨~ÅZ¡wW€Våõ”Þ[êE$yÁ®©qM¿žtu5H} DtÒ8&tTONr"át /çìéÕõ„ðäŒÇC6 ² IÓ_}µšK{½™îz6]ö¸8C³œAPÔîLÐ’M“r)\GRG7Œ)k¶Ë¥7ÄÌÍtvŠiÙ`i¦†”3Uñ5k&À†°·zåþ&Úõè½J´ŒÙ¼t:@w›™!u9ü8õ,RnÍ•'¹$¤eåIn¶5q.­ÇdnŽS(Ó%y;˜½£QÚcoD†ƒïÑÐò(Æ,öO7(-Nh{`g&N³+m‹:ÎÄ÷é 7$±¯RŒœÈâ¯vðhcÁðûêVd¼†AÜqjOÇcÞ~8µÝÚ£QïNÜwûxh*E>tx€„ô‹$d:%\:dâ>Mx“×tBÃ@ͬoc–Š’è¨:8Š¡(A¼ÛÄ•é1½þ€­m²k’ÛPtj±Z½eád;¶ÖÎÎ..‚ä¨V°~/p{"5Š–œ§­Üò&öÕ´¯íú&‚èû‚ÅΤÿZ ‚ŸM:·ªç~íü©)È,‘Œ$Øk }E:i&ùîOÜ÷‘ R`)Dêþ«¼8ØÃlʃ—X÷%UæoÞ(o•[hÝf5(B›‚™•øk.tÀúMÉ»Ä Ú··_ÎW6‘B>T­^NØ?Q ÛN €¢•¥ñ±#ÜMX q0«J؉oÜ<5ìÇ"^þMi ¥{ž††Xÿ >–òí¯¾ÊÿŽOäì½y#çO®w1ÏF½±KÿuµÚzQiÖðªu¢Ÿf¨ot„ýå=À˜ÏƒaɹŜ'¤B×CfÄR|Ç¡ +§$``£Ã¼;àØòâZ#^ wjÝ$«Ãl?°öU¼à3·?_sÀ“‡ÊtÝ}„ùì­éÈWh¢E†È¿0 és"% ¿~õÚi¿Ã†dMbg°C$K¢X½;yû¨K%ÞY—‚‚Ø+ø åÒAö¢&âp]OèN‘Y—cl_921·-í?º0eñ ¡À!KqâÀŽklŠ–30ðáƒÑp±Á>¨Ø^¬îŸØ`½t¦@—€¤Ë!Ì »ð~†wüžƒ®eò"d º-J2‡×¡IïÉ;DBͺ£KµyØTHbO¸.ˆî´¤CÈ[³*r¹½WA±+ ÿ®Î¸ðJòQ”~Á1a¿”Ë!Í{ V&%GÎXŒGúÃQWLK"Î=Ò Â†Enr"·9ñ—9ÜÁãU¯<Ý. ã2B—¶i Û|&ÄË;ÉÖHྒºÍw¢Óþ„,eïºêvDÝ6Ü©#´Ð\åö±‰„:¡Ì<Ãì‰ã;.·)Ä·¥õœüÑ„/Æ$çŠä“\©3:0j0*õ7[¬KS^d¿¥Ëñ¤GGýaßÜ| Óô4âD1¸Eps¬Æ"~nŠ_Yƒ²/ôM Hë葺“PC ¶š£Ñ²”èÈ}À´±!›Ö Ðy-¾4OH0´£ÕÎãá`˜g»Õ²½Â÷zåVEëE »3­02¢pÈ`OÞ ú?*ŠP”Gùá+Aß²‰=Loýr8¹æaÈþ¯x×ãòp5Üzbcsžš§ÑÏh>Ûàcû£·ÎWµr ÖzÔ‡942‚íòÙÙÖã‹‹ÊçòÚâ¢O%ï6²1q+¡ªÌ‰ŠaŸeNN†’Ï×h½K@ H8ÅñÏ%, wÁW ê¥Ü0ÓgŒ8ÍŸ|wxÄ®š›zö-¼tQ(\H»çÞŠƒá.ÁDNÁKZÚÓÜ…|M]ØK“a[?K}âºFqq]}õÕ:zTC7þYLJ’©]O‰D‘y8)Ò…{+Ì•i¬EîÍæ¥{ÅíËù.çRž6 ‰: sÌÆŒ‰ÎS(Mb#ÖdŠY£Ö­%J·gn–Ù”‡ž°ÅA­+ù¦ŒùˆãáM3ÿ±ÉÏ#a %Iƒ‰­ó»}—Òî€HÞ¨¾TeóÁV¸Ä S¦ÕR˜‚Îf*g“6£Í­`7¢/åµU ?²ùëÃY²&î7$ 8k»¼EB!¬CÔÐJBU®ƒ°ä"<¾#z¯ãÝ"I_^DŠX±ÛåÇ_±C=—¡]Á¬8’EÞ §u™§•ûAe2Y›5:ßx‘ò˜)Âvábh‘n2°Ñ]׃mbì`ßé®!rÝ[=(?ì…‹Î"ÕÀ@«ÝÚ.»v]²dxºÏ¢4V^K¤erÂx),45a O'Aç,áÂ8–Ë4~x‘¸²Kó‡ZÊÆÑD€ÐÉåÞÉß *}Éu–B¾Qa-+_8ÉÍËB“à‘u$ã¾°!YDèð,qfêøê¹ÉØæT£1œuäÃë,¡ó|VÐçm°OB2<äà:îÔ—Èý·1gçGJ¼;Ø­•73u 4\[ɦúÕWEë‘päIù !Ø“úX¯”P ñ™ØÖc«áô›×î#àgÃw$kòÿ²L[D`ŽÞÃÀè(r¼¾Ð€a¬/Uñ,` sPTr@F*\C¡ËÃf£VÐåÌÈ”EJFç-4_ÚZRÅÊl×)(ÅQÔ[Œ6Žr$ c²„êwLÄéG1t®\6AÚUàp8ú6ÆÐYi­’æHª„'¶tõýŽlvwCÛß½ã‘s[fµq¼ ž–šWèæ9*i»1ÛbàrqóïWrtÇÐ&Ý «xW蜱ZÔ€Ra;fc? &Â$[„K¦!5϶ܾCšà@nÊ—^æ}Ý<K…7}Ä¥=FxŠ &‰=…I¾+hMîI;'Í™Fì_lG/ÞÛ½)jžpW ]΄îÜH¼÷Ï>áΡWÄáñÞëƒß[ÛX9[Þ¼X!Ô%ÜC^ŠNîˆml§ÀË_<ÎçÌ gD Ì’bò¦WXÖNŠ…È5Å[Í^Âd“*HÔò,®8r)kç9ðŠ·Üõ<»sNÕlÔ}3n›H³dó)cìÈ´ß;ëœø+u0Ó|éW‹#™æ£µâ¦2N7ñʰó…LS[0Úäæ ¦ËxsžQ?qbòÆ í>+RB …©-Æ¥Ùëpé!–àR–kEynQ¸?›]J›Ü‹÷RÉ*Óª_Ó¯– f)|Dd7'’„:Ž¡ÜëHÇo³µ€¯BË”„%áâž^Gïì#BÒ#«öžv£)¤(æAH¦…SÊÞs¥Ÿ!a,K³´{BãÓ<„&´à̼,~1)âK"ÆK$»Û%,PÌEiÖJù]è ˆ1™Ø}1 u®§^í£ùè˜Áê©Õu{ðÊéìÞ†7”ïÊk¹£þN;?_9;+Zçç«çnœŸoþý*ÿ¶ÕZ³ÉpH‹6ÅÀÁ‹3·ïöl’¯‡7tlPÎ^è爾RÅz`z `øG«2ñP‹¨D4µ¨–âžnh—Ò ùå¥ò…?( ærHò7î/$‹¾~Ù*,ÇL(óÛZ8†±qûùc¹Yi´XW“Uýð„fÈ;íwh¥)"y2xXì#1ÎF?W€Ù¡øJyø‘&…üq¹ÍÛÏ?VÂRâ£¿ÉøÑ+‰5WaBüµ{=n /¾JŒTúÈzº-%ÐÈ«Ç[yJŸ[¦Du«Ö·óŽÛífP´\[sÏÿÜ3î‰Ò§°ÔéÆ+ä#2»5 Œ<ÈÚ8üÁJÅ„´"³wÑù;4kûŒWƒ(J{ñùÒbžVÔPøôÀÜÑW>v¬@—:Áû¸‰·S^ƒù隌ÓF2 ©YÿzÎèÚzá´Aȼ´Û×Ö?ÿ;¾|üÝ%g³ø–3&Q¢Áf)¬*àXÍè r~{e0®ãxÎof©v`{ %!c¤”,ÑÞΆFÒåéN0‚6eÝ‹Z6ÉäyÒÑüz8žzÊU_ ´Û-tL¢\U3Ã×íÌ­fö'zã%ªöÝÕ;À›-8r]Ýà‡ÑÍc /ßv`º°WÜñ—oÞý_*¶{Xt0ÄbGl_yØü¡ÊbRKDzÀü&·Ïƒ!°¹>Eô`tÀ‰æ[<ìx希^1§6«0/ÑgPØÍ¾ºü®À£:uð@ÇXÒZ³Œ¢d_ÉæÞ ŸÐ7Ù}þàO€á,0Sr3?8@GôÖ ÆÐc§­Ft¨´nF{@WhÀãˆË@\ùç!"ºa\J%àÙq0¡íÌF‹¼¬Ä§p^(xë?¯—HyPª½AëÕu|lý3"«|kÅ·©7Ùu ¹saâcG•bòóß% G=/yät,VX÷,Ž¢¤f¡“§ÑЮëdzÆ–òt©ÌÀb|¢µPÅ‚1)d˜\ÓºßÉÛ¶=²W"3O{ ˜C¨á+¢ùöuØ©vÛB7m©œTêjñåD¥ÞDàÙÊnþ»ã×§'¯O¿ £xÒR¦EÅ -sya¦ÂÖwHÚ%œkåÚ›Úªnå¤ehÑz¡t@°LÂÝ^Ž>3V õ·\}ˆtf˜  0¯÷(„yfÙáS¦ç‚ÂSæ úÀú°—vá]Þȼt@VI–f0á‘ú°`iÓS4q@ôSqÁrëN¬Íðì 4ßÑc å/„æV‘Å•¼ÝÇŠ G‘1%^è6óùƒAo¥Û +,#ÎÉw„=CìIyg‰ ¤bŽŸÔw&F4¡y ,”Äì+§„"¯Uz#¶‡.ƒ¥x¹ ž.;ä¿$ð‘³Éád€’©p“§ÇEio{†ë=Ï1®)Ú²[¼w71”\z5î=¤œHÒ°Xg¦4B"è¼d*ߦ`”R¢„ íó§¹@ÿ2ëDÈZä«l•íoY{,‚ãk{ä ;wÊfJÄSiüX?’ök•Ó×Ç TN½Co+”†, ÏLgè•#F=3XO­úêØÊƒlÙ¨4~²–ã¹ú»9ýw«~T?­5O+GÕšuZkÊ/yqûÒ¨Óýƒ\S¹…½Z³Ú¨ŸœÖ¬ó¼,užÏ›è;Få´b¾>8­ŸÔ¬£ã£æ«J£¶—„¿&gWpú·°ƒ .QÖóÄ\êwrêŒûùõNªÖq!þ«¥ÿ´ÇúÅ!|„˜ÝwXAA¦Áøâ©“,~¡“˜ À1»î­Œ $’ÿCµ€”vÑ¡ hó—0‡«]¢èð”ox¼ÝìäŸ3s3´*{ž‡ƒðùJyí|uy½u¾¹~XüC&b ï2,­þ_‡¦Õcé¾áXªÀ üMÀü½…'k;}“™NµÁŽÒ¹šÞ¦×¢:í¯¾’ŽKÙt©³÷ÎÐïêº}4õrì8ë•Ûë±³¯ MþQºòQF£AîÂÀ/½ÎVYsÆ&#‘mÇŽ¼š  M]Û£^…MU8K!ÚJz@mò’áÂÙ¼Šõn•œ^7$ȤOm€‡Rgl_ ÝÞî& ^4÷¬ÇìÌ€& $ÔˈøT&ÜF‡5 ý]mLÍ;(ØVŠ¡«þ2A_¯m÷Ýtö¨M©‘ï{U2—§ÒóÑôösÏSd}u9+.Ë Ëþ9k‹ó¼ ‹»œ©^:V%Ú®sK𣓑!˜u$,çL¥(mŽS $dQüÌfpÙj5¤i›#J@ê5ávv¤ùÞ8ŒÙ€Éš¢DT#hGªHEŽª„­ûÞgÂ?HÊߚȣltK1²Q£Öj¾1¢šûGYd,´AD¹P-î/½ìÑÈaK* ôwcSÔH˜ä›ÒzPæÑ&,”Ó–Â;P”}<ž–J½¾Fä©‚æÛ£ ,zC?€óp#FÑpFuÒ|UÕpJòtŒÄFJ¡Ü00i»oW$-ψ—²ŠBmM ‰òö9Mû®õœôž¿’·¸„‹îâ‚Ћ0ÈU®‹G æå_óÏŸ[kþKüb(’Äsr±ûÆRùBüâ­üT®‹÷g5¤ sö—ãÍÝœì=ƒ×üéÒˆ()ln¬} ¿›†Ð1jPˆÕñ½äŠ¥l"…Ù‡¶=š†o·®G#{íéöÚtBˆ\e….—‚è s‹*¸²•9IêxR·3y5›‹âe' ; -™Ó~A²ÜÒlAn)—´2Ixãèj-E‰lI§0% IŠ# ‹u׆cÊpÁèD,€{vËÎ:G›|à~/¦Ï±›àƒõ<,s?ywi‚îÒ, — Èr÷”i—#Ì.-DŠ]2‰¯K!·~îbk¼j.AP]Ê ¸ÄmÇKÑýx5·”A6J¹¥îI½ú‘بΒLìt~“UVÿ$¼6:¸0°ÇÃà s`W¯ûd“)ÒH†ÐW1Gw€á7oÏÎËxi)ÄÔ¥ô²éÒ<¥‹Æ[ðtýÒ#ë•Ý~·C‘0ypÖãò-Ç@³”áP$¨Àõ|é´mÔLƒÜè;Šb +„Sçø»¦´tcöNÅàiè”g‘eÙ°V6à,Æ?ÖåÂKj•¶K?Q·Hä}Gü6.@ï͵۾fkCüPâ¾ÓŽ ô¦}ÚPqßÛW˜ÂAd­Å´¶è60´ì÷C·Cû$ Ö&SCa¿ˆp¶ž<µ¾w_”ìž{…A”Î_:“¼»Ù¸}"Ç€mmÜ>Ý߯òWNÏŒpðž š<R|øéˆ·NeøvÏʘÛò.ÇïV¶V-JØWžiy *ãƒåJ-4¤Ú”v$Å·@Gckù·Fåhïø°´¼ü»õwk{ã›§Öºµe¯Y[O·6··­¯¬ÍÇÛ[›Ïžm}½ñVñHuŽ’PÞûðó‡Ö‡|Ô\'Þ¤Šü±ÀaâÀ_8¶|äÂB|‚7FøáiúKLõðÕ|YG¾˜Ù`Å’9Ù^Áò_„“D²øû6ˆëk–Ãb‘MjH4*y €6G) ›Ž:ÀZcç ¤'Xö¡iò†-yÆUãö ÄTdG%í4n šàKù»/?¸+ùÝKyÄ—=ÎEÌ>øŽ!\I´­7êo´{Ò=Éõ AZ퉚‡ö[`QÔžŸº›Ø§”Ÿ}?£u/ö™ù´xžá´Pú±Q,MYÏØ6l½NëGDçaf!DZÚ¤Ú*y•Bñ}„H¡L:] ‡¶øÀWxðR&3øVÆß 'Jq‘¬cžKaCÖ=ó6Œsz‹{À»54(ÁBÂ/èë { ZyòüN¿E|¯îßOQÜ™¥âyÃ6r@g}Ð.[+ßW꫺=Š_ ˆ<](ð†•ÖZMê(Ò¥T= ²…,òeo˜·VàŸzy:Ž¿:)½~ñ²ÆÜ}ƒÂ`2¤xBú§R+QÐH݉|¡ÈÓl‚ÈqÑEî-Y+†xJ¼v‡Â`?¯¬n”¾©”þc—~ýí÷‹‹óÕõsüÙ\¿ÂBoŸ3w/%<\†jàˆõóeÑây¹¼¶˜XGÍg¹ÿžÞta %Çåsq±ã?P×^*‰íWq‚Š!95§_”ŒZ%#ÑX‚‚±„1½/åcu%h^-y€bÇ}¤s…ÏQ+9Wp«°Vb®+º¿`óQ£üûž.¾g®ädÑ͙ۣ6îíýõ÷cÔÁô‚S›šTÆpÉMÎúºÌ ûrøž”2•C†bÄP(éÎ Å?ôœð£Ó‰0Qf›E ? ~l=+ob ‘ÛãžK‰SØõµÓáµ*`áBöœÞ{ÑsLåDJl%@^ÆI}VÎg¼]òå߇Nm·´”>,âCwjžvKKê ŪU( Ó»87Òþ&ýQË…µ¸›x°$õîAù‚UråB/`›Kª~7äòË(F¼wXŽÌ¸˜Üo²Ü¥5FþL¸÷ÒÇŠ°§©-FWpÒÁ¨$WíÑ(buz‚ÐȲz<œŽ4ŽeS‡ZC¨çÖÙÙfé Æ«ÇÀþÔ€òÌd_3âÀäš =ê†wO…¢§ _þ;†£¼0î‚@e#¯©w% [2ŽR)Ð$Á¢Æû ÁZf² ÇRgéH ò½ÈÔ·ëGÓO¬·Ë[Â§ØøÖùZy˜ñ0PH@G[Í“·ù‚/1{iÜÌBÎ\Øá­šÏÇ¡Ä ‡Ô¢mÞT5=n 4*GõZp…gØO„·Ù»›¶„C[]L¢Zý™Í¤Føýe€ ñ‘¿ÌÊÏÊ\ûª~ù¼¶ªˆAO±ï;oû]Šðs³oã^4Ͷûãõq“ĆˆóH5}îç ټţ>.B:í+«ñ<ž§C?é×QÁ~ž§÷ç¤]'ŸË ô.¼ =*ŠÒæ~´ü¹¸´HH8ÌDûVñ_Dý°ýˇµÀ†&õZºñt ÍEvöZ×G‡<{ò±æÌ`³“û¢Ñü h43§HúËJXa(ßøÑ±Qk¿òsy­×Aùó ?¯eÔþo®^V˜o–ý¾¿ñœŽ¦ª»¥@•@ üáòê¶0¿ú‹CëÍëMÖÉIµÈ7[ì¯;ÿüÁwª8ÖüKÿw=D.@Ëb2Ù§[öÄU¡ÉŒfJų9âoÖUoxi÷v’¢b@CQyÖ·Œ¸u¢`@­Ï×c]sçðz¿·c­=·~žÆ‚fŸ L—8Ó¸ÁAíIhÉ¥À$¢Ç¸{ò‹¢.iNçV5P‰<²à i[ž”¿1Lvlv‰Ò¯˜Ê¤Aú~iÎ0Rº~@cäô¢ÆGì]&ic)³µD©¡3ªû ÄaÉ–w‡Ù"réWEBþðáãJÈÑqû3€2€'fFÇËݺÈú dJè‚Á«9w<Úot`[ ßï22€s3œÂ^|鈀ßàÒǺ‰LæÀ™ Ù–æ^L2A«U;ØoµPÖDÒ©Y%_Ê–¯¾oß@…Mó-xÊv}¯íƒƒ*[ÛMšÜÍÒ´1Ëï9ìN»”Å—‚æ?²~ŽßÙãáó‰bØá•£.m–ŸXc¶} Œ  Çr·¹ND‘·ªÁÒN©wÕn[¥þƒO;;ù‚JkƒÉîŽ~ÜšƒÖÂõ¨Ááà'b ]ºpº¼édT_™5S™­Ã Ì&{°ßo&2:?/}2å©*ÖÞûZÔG÷¯Vþmüʾ;#ùæm~FÛ¬¤MaׯKKéa”E \&FSHºþ-øeŒbUâVº&ÆÌ—œcèu㲃¿Ûâï“/Æ·Ÿ¹ñm^D4ù¼ÍoÂ\#µ:÷þ–u ÆsµbêE+iu†uZ@‚´“àhbz°zêêm؜ƻUÞ.o~”¨Šœœ€U³‰ÕŒœÀÐqÞ0Lï='H?_+Ìa¯eVn,ø^å¾.(÷÷([Z˜s‰n’—yú s÷™M\©“Ÿ‹+àR¦üÖ¸3º¨!xkп%Ôº3éZù¿{Öß½óóAÞx@!´òçË.«€¡ ”‡OQ­¯Ô—Ä͘RÅTøÓÍ’²;@ C2vÑŠŸTNz±“iD eý™o•F®I—²Ù |¹6ýrm*®Mý/P¾ï,âõ3½F ³Y2:…{0åŒ÷^ äb””¢²Òœ±T>†¬ó™y(/éQ[æE¢ÑUù!ÑÙ—Qþ xUvšE̳g-d×Zо•bçJ`æs±päÚ?W¡ˆ{5ŊȰvò¡bòðþù„*yóÞ$Í6ß›ÂÞž3T‰¸äÛ.ß~”CtÓÓrKÓ¶ÛùË'[!²ÌtLæ‰Ú*ZOÊ·´Z«FŽ‚eæhŠØd¾£’¹!³Ègi2·å’<âÅd“Q4—a³$Y3Îä(æð˜„ ÜCµcÝC ìý –ݘµ1[ñ{g¥91=E2ke«|v¶.]ä§ ?*¯­†Â .q&XcìŒÝ÷2%,<¼ÄåÁ!͆ãŽÐŽÃŸáˆd€"Àؽ8cJñáY…Ò¯–r[(b®E™¯Ýsñf¤É]´¶ÊO­•¾}'´­ò“òæ¿VuÇd“hvÁ±Ýžh7/ðFÄfo㪦 Ø2ãðe´:Y˜ø¼'Ÿ:~S²­‰žh(}ž¡nµm´UÔÚ$øóI! ]Ü|Í‹Ååƒ=!ÿ‰Yƒa=òÓóø]¤;0¹ yÙ.àì»"µ–»éý®™FbnUò“'E’-ü¼u^~›Võ³ 4uäÜôgÚcãÝæœEöÚ8<Ô–»°CÞÂŽy©zŸè¨gŒÏFi¦aÃ}&t¤„űóËÔ…áJ/ ÖÑñ)|áÐ[Õ¥*Ü/ºÃq¿œi1¾ü²úf¯¾—_–ÛÃ/·—µÒºî¼j°†Iû—2Hü”V~)£‘»Ø§c$k}'×%ì¨F0“"È»óÞo¯Mo¶è0_žœÁë£úÿÁë{û#Lø3é& ôìlsãâßOáÕ ¾¢ÂíáãòÖû'å ,¸µM°S‹+4Æ"¬›'£bÖ/ª¿dAq˜,H…H¢úCêÙ—ÀÀ18¯Ô2R#€âzQWÚÃ1šíöîàØ[ÇaØ/0® ý<¤Ž-®h o~=œ^]ËFñ¾Ýëà#[eÛ~ô1Rr¸|›ìY׎ýþ®t Ãv¨#ðH Pxž†­¤Kï.ªPî¯U=KéáÂø7ŠÉ‰ìÍ÷3…½xB\ÜlV»b©ô&º”Z½ÿà<ôóࢩõ7§á.RÝ–^ ùåY ó‘–1c‚ÝIѨ(8»á0ļézÿãìŸÑÞ¡8ý„7ÔÝ:ýô7-Gê ËÑpМ G¥×oð¹ÏÆ_þnêýíÍpüîã^W~œÆôìy•jë°ù²Õ¨5_œ®œ-ÇB¹àΩ±ôcË’BÛ´.§.½A²ÇnäB}Y­ /‹—oÞ„_ì‰w{\ñP+?Ô*§Víðäô¸±#Ÿ²A˜ëaÇàôb¼i³ ¢#ÛÝ!î¿(0ôíöx=ÑAÛ°Õ_9…=†4ø|+2„ÿÑ öÆ…%ÓÇøKhÿe ¯éβžu7œZïÃ˹µQT‘àè(Œ/m2YC߃rÙió§fëU}o¯vÔ:¨¿Ø«4W`ÄþëêñáIý ÖhÔ«æÕÖ±ùÅ>ünW¿×!Ô¾‡·ÍWМþ»²÷ÓQå°^¥L_U{Õã½vw]*£´~´_)êu]4À÷ X$¿Êcñjuw¹LÏ^Y­â:¤+é;¼8Ø«¾yC$€Ÿƒôॠç%RÃÓú¯”‡Pž¶ß·Hˆе'á˜HñðJ€mßÞú`‚§¦’æ^È £Õ…Um`'-èdˇˆЦGG™>žÓä±dc±Uèsî_«!&ˆ}à[S4µíêÄ9€Ü?(½iÖWý˜Ç0hwÅš—¶‘°?(u•Wtygõ·-”£eoîðzFN'ü¾-Q $ltDz¾ñ(:‘Z8£œëoƒ€ ]X93ÏúEñ¬3è!é4jÿ÷ºÞ¨qÁ½Zõ Õ¬ík¿:i¿l¡itëExÈA¥ù J(de5÷[Nˆß5?|·Årj¦B¥á8í¡Ñ*[\cáÇŠEé߯'›ÿûsËû;:N´óå¿ÿ=ÿ–v-Œ |ap´þn™ÈÞ_W†õ#—–sŸÁ¾…åQq«L_pû4Á¨Á +Kï4ƒ`>[ '. ©”JXÔš&¨Ja)Úcï%ÃUqu Ž÷¯‘¡–d[I›6üùHî Ó^-ÅܔׂBasz}Z?€§¶_Á£y±j"P%S¹GÖžŠ4÷îÙm ÑÅ$e(‘Üý‚ ßð±CW œW )Ž"‡ö>sG°^º.PÑ&¥ïtz¾ Ð;ÇYøJ…2~¦/-Ær—ÊIÿdIPêåh™HX0x~Þ"zAqF6>"@ç½N17¡yòÌJtZÆš|p+à%B©A¿{F‡jr‰;Oì±”ùÓO3š/ývPlüž—Ž…»X9ÑpäY¦ µô´|·¥Ò%Œ0B–¢û/â¥o„ß]Á'ÜÝÜÁTòº‘õÛ­ÝŽd¼;o<ìÃì88~1ñ( àk 2¤iFã¸q¤‹Lƒ–÷‰KS¢4Õ sÕt”*” V¡ FCÃ(À‡Ýe£P«iÂ`rb`6"0iaöâ`ö"0{)aªº4˜ŽX,íÆ4½«¶Ìež¼™m«-‡2>Æ®£€¨‚uÁ·@“¸"XýÈpÆèVïóÉ Ú=)µq¹H¹s( q¡êrRð 6Þt,)Zvo çÕ;½¾¬HÕ×sY¦÷ØÃ0PxI×D‘B˜”Sl¡pZéS·úK-³ ®BÕ+¤ÔõóË¿¥-û»da¬õf¤ûg#Í|©—ç9åË]%zÅ !|. ª|6 @#ì·yIj? o{Ì.Зà"zUŠŽÃ·vPñ{V°éã2¶¬Ž9톩`AŸhyçBŠèµ2;æó縮ˆ·— ”œË-R—EöKZǦ}<ž wX+¼Ë±ø«çƳ¦£ ö P„Ö6´uG˜3í°Ìö=ÚŽ³²—GÂ>’“Ä’@ôG†ãh<% Ïj× “C:êMÕwÓQy'õÞPЧfŸ€u¢%>’F.§l8o,ÄU{‡§#¤-N†g—Q'c—ሜ£žû¡sYñVîoïX¤ÝA¶ çÚ¾ TdË›ŒHTúŽí~>‡…6wÉT¡ÒœýcΨm:9nœâMÈQã1l$"/¦ðY÷„Ó€‹v "àœ~–¦#oî,bh†g´±{{vö¸ô0Ÿ;ž{k=.?a4ÐÇÂáß5‹Û[Ç*÷laʇ²hõ«¯8HS ¬$X×( £›ª¸0q'EÔ!„ÈdŒ¿óW_}•Ç]lï´qŠOä!I$¤Øþ+yTÁã·¬X†M§¯ÜZž"çåõ`>IÖ~#³6A@¥ŠÈ_ƒxc’~CôÓÔ-‰TV–FÔ°WÞß@Hú›õ·«‚øú³õ·¿Þ"© €¨\^a NLOð&-ʳÓ(ÎåX®Çp m'¹Z˜Ô0£‘è¤5›YèiŠD´u"×óÌØX¹7±Nx/h4¶@ÜlFÐî_(S’iù<ë ¹<Í‚š¡r*”ÈÐ¥=ªöµètqµÿ왼9Dú õ9¼¬ È·É—+ä] _ùJU#s%ÛÚŽáÀ7°ž= º=Å‹¬©‹úO?% 枣€Àóº7½ôœ_¦pÔ—ÊJÀFpÝ™£ès7cwR6èÝ‚2±}ÂZóOû×|¯›¯V‚!¬æ´mêPdiUJÁgþA÷•Žëá`°yp;Jka–Ê|M/…f-ݪÅ.ÎT&—Ú2,7+l¨ÞbrИ²f¹\z“8cÑ>œ^ë ±e{:ö1¾œ©”!c»^ ?ìL{N ZÅËDÔ›M÷¦4räfÚ•-‡ç¢æ[-+OrI–cËÊ“Ül[Ì\Z‹xè´\D¼Gº¥ç@­ñŽ }' ç*ɦcØ2è<3 +ad=]à8´0=*â•s¬1Þíb½cå¤× ¤cÀRã®6ÓüLbÅÊmCxt’ö,(…MˆÃ!XOfÛú‡Èvã>eåEÖšcõä¾Ê7ÙF-£ÐÅb aÀ-hÞÁhTü!3G&ÚžŽÇÌAùXH* {„©€ñC¯§(…’ï|„Wณß2úÏÇãéH\”{ÎDêòú~xz¼ŒJ¢£JèG5õ‡oe¡0ȼ¢?®ÒýüпµDòý›„ÇXd#¸›¹ÝüyôÖdw ’ÏÍh™ì¡£Íê·mA›ââ7¨´Ñ›ôÑXBÞÀy䔄ä7±¯®œŽ¾{‘Ò)ð*Æ¢.ÊhET÷m>žb¬{Œ„ç­_ÿä}ŒŠq1š ìq.d½ôâÿœTNk9ÍþH}AÍTpW² ?2þ—2Ù4’»=¾‚L¼²À[í.“Áb>´»üR{º—a³¥ß€JJyXšùß»¥}YD’š€n®ÅJõ_W«­•f o¸á¬&K‘¹÷éÙ³œ¢ËÓl©…´0䫾ªU¿¯(åv;‘àF—Ñ@äF}a#À°éÞÅjÎ܆¼à@äcù¸Tù$ œŒ5žá[ —X•ú›b.ñ~5x(oÊ=œ{$ºs Y2ìÀ„í*NêÕrÎèƒ%.-ÝÛÇŠe¦–9Hë¶6êšjy©M 'RÜ'Xꆹ›_V¿þq.Ó¯žSä`5«0tYœÒ¹fÁÏÔJ^’VDShÎm<úo‹£¿®“f3”é´ãIºð`-¶\..ãg˜¹gJóŽh^çP QWƒq&Ä õ Þê—eà:¾¢PÖóÞ·‹k³ªIú¾Ó¿Dí¡ê†g …a¹‚eû ÈctK§·(>}¥pxEiØÊ°œB.–Ó#ëÐçÅŽKU´ðÂQ"rë;Ç+çfQ0œ%tÜà!i@Têb5ɲ—ø×ÿšeï_Öt×`s›Öš7ÆÈU¿ì[ƒóqH}PM¯=˜[yðykª30ϺڠÕTc”Õ/:ƒ/:ƒ/:ƒ¥3h›UË¿Á‡n»åÁÓÛI©û{ZBû3Ð TÿgÕ/úƒ/úƒYúƒj)ßý扮>¨Æè*š7¾ÇÕï_é\ ¦¹{j¾è¾è¾è¾èþ”:3Güâ?ü¿â?ü€Jˆj¢¢jTA¼¬þûá,ð=†¸ù·ýÞö¤úr‚Ž?/…D€¡‘ð½ú¤k):÷H—?ªÒ„…™|4¢ñGÿ…7)ÏC NDi%úDy^qTú=Ÿ U‘Öceõ‚æÿä;“ü&=ž³&Ç'”ØWš”âììâ%Û÷«ÐçÖïìÉ¢dú¨DŸUž•æãdù¬’|HŽÙ#Â=~Àí‹$y âRþªý_åe=x$œ¸T9>QNÙ±’…÷GÀÿmu`Nqrn1Ž´²Ɉ µá-¶¥cžÈsÄ1ºÜA9µ>ïóPÜ䢻÷¢vîîÚ±;öŒ³–FïGÇ­Æéi]ìƒ1yÌ6ž¼‰Çmá)vèÐþŒ aÉ»A€ƒù€EÙ–C›rÌ–¬m±ÁÞÚc~‹}9üÌ÷ÕãYÛêqÖ]†lÜS¯†)wÔ€½ŸJ¯[ܺ8ûïs蜽˜ 6©/ûæûæq÷ÍöÕPÝ9?ÖÆ9ü²o~Ù7ÿzûæ±qÛl<Üí8¾ÿÑtÐ}#¼ÒóYïŸêŒý³Qͺ6ªæýsÜN¹F|äý³àÙTã°Ðoô§~Z;´òÿ€AòEksc£h‘>±¶'ö»ûm¨Ë Ýù²›¦ÝMy+mÀN ºë/ØK3›¥z³„±óU®íÖPI›4ƒQï˜Ya„ó…y㜰¡)é“Îû°©½Úþë#]+ÅáªÜ.ðŽäÁ Kÿ RK^œêeõình%µNVàEѺjÿ·(o‚˜8Ò¢ÿ&u _Á“ßI.ŸìæKWVéxK^ØØæëÍÓY`õþ;»@VÆBÏ1ºÁîä*¯[•ƒz¥I£OÓÎQ8»M‰-J›åmëä`X:öŃÕwéöÜÉÝÔ‹]PgâX›Ó< ­"븊È¡±¸š AlTgAÆØ€bí3ñÔ¨ªhÂÝbXb bH~\¾fˆìÖð€" ‹×ÈÎ8ð–3À`çVe:"ƒ¤|T×ḽ¼Dʺ;#Ü—ßÛn‚q©%0Fa×S:b?TEÁ³P– o¦A鿌u“¯÷ƒ×U>£ûNü°K•±G#7HÞ‹°”h8…J,©㸠ÙC“.·t5ÈÀª5j"ä8Rx?Ô"L¤3¶{'ÖUªáÜ %@ªƒ‘'KNŒ¶œ ™ªÅœ OD™@m’ÄAfÉù«˜êS¹ñãÿÞ{}¸`¢Àä¿ÓþéBô2ºÞÄ‹¢l²huížç¬*$ ŠˆÏ»²ƒúÔø­3)îXÙ~ÐÂ:47Ze¹Øý.ï` ²q ‹2¾àꋈ²QˆpêõPL5 @!ˆÏ»¢t~+ð]øEƒŒ)Ö…6~Y!2þfm/4vò®ö;aÛözw%WÈa¢‰¢8-À1°És”1¡ Ô„pÅ'2” NÆN¤wT¹‘øØ…fàthÄ%Æ'e<çÀ®È‚o„(ø» roà×n^z©ozë?¿Y_χðFý5­Œ„By"ð”+G$BD¸6†óçáåv߆p°Æ{#4%5†÷0v»Maeɵx ˆµÄPÐ)esU&à´È®4P|©ýéâàMJƒÃôü?h÷w|ZÛá.tîÇð»À+œò¯¾;™ˆ’”@’4î‹eaešTŸß@E¥s0ó?¢ß8©ðÙ 2QÙ†ƒdÏ!<%¸®.B9–qŬÌE#ÿíWÏœ‰?î‡0…hµ‰ šÕm1x1y’*( ÙF*¶0¼Ž `|†Ã{W¸29ïSä3\#ض†®àC™à LedLÝEG§S U ìž!øõEß`*àl+‚“Ô÷A‡_Ï-ú„[ôì¤Ò¨€Ìž£Qzh13Kos€Ž +0r–b“Î5h5óÇݲrÇC5®Q:h:<?¨5‡‡n‡ã1B™BÁZ8ÂiË?|{~=ÎJi{j±‘ß‘õå Ùe|ؾŠKy¨ùTïÑX³Àå43ªÇΤ?ô+‚2Ó·ow7Äç6°Î |ƒ³g§c­O½ñúíèj{ýÒ¬Óä{bÁMîFÇXq[´r™A‘e“ÌDçS¿¦Î×ýLÁœˆ³xÌ‘>œÓdÿ Ãà(hâ\A &Œ²é'Uãm’ñœ>d–‡Â?·Ž¬üÆæÖãí'OŸ}ý ?ªæ­oõúê¶&·2û¶ƒöY$ F—Ø’ˆL´þYL)Ü?•î~`¡´ M MÁ(‹y7Lo/aÿ~—ôpsM*œñÔQ"8NTŒhŸƒ¡NúM«ÿ^Æ’Cè€#3<ÌÉø ñûí·áÇA¯9ü˺½¼¾^T(•þ`4%8¾ÊÁA«Ð“R`­@ÔªZáG¨‚ÚØ q‚x”;À žžƒaúá 㓬X£mnX¥ÞÄŸ:¢"¶²JMoÛÑØR [_Y›osz°1 Vé*x+Rg ÁBU+/ˆ€&?à°ÈBJ%E®óC¸kÖtüUt‚¯¾àâ¼+$ õë"N¼¬r¾a¹ùªvpÐÚ¯UN_Ã0TÕ<YG?§P:p`Ââ}1œŽáà«üM³î÷«GÑô‡c’h( Gøƒí$\Yí ˆú‘ æ¦Îáþd±b­Vê»O7ž[Óªnðë*Ù<Þº“UëÛ€9 ·ðI&“ÊïÒoeÌJÇM)9å{ü¼¿¢ƒWsµç©pžÚ9aöV{QÝ«W •fµ^çøWê͇ Ì*œonlÞ’¹reä± ðàxcbažøi±‚FcgB Z‘¯ µø2ùô×¼-LÛ—ë“1µy²ut°[€6Ï7¶7à׿Vßl5OÄ›Í'ø‚Šà¿‡ï oäXB=ÓAó€~F¡óøÿ”˜`Æ ˆ@»ÿ™Ž èvÁm=~á°-ô ˆêµ'@øŸ²a€ B üÆ…!W ^Õã£jfýøˆâåŸÂ‡æ¬A_øêðÅ]QŽš²€òþ&|~ˆÓ …Ì2¶Èœ›ê¯Õ•‹Ó"€V ¹×ª „W?xk |ïߊ8cJá·^I^b„þ¸_à3Zbéé&¼\c±bPVU+GÇGõjå õê¸yjTXE^¼®ìùetÑþzxCÚBˆ}lkíc•dj2|Çqöí_Å&^ßjûØ}`­´V¢a¯Y«Š‹·ç;¨¥ÐE¡=™’äׇE¢Ê®†6wiÂÄ@ø)ÖÂr7·¢ÖþØTûîêÆÈe‚ÍUã¡Sÿýå¢ðþ²ÖîmöÆ RLK¾•=牌é#b™^8¢pdüHø5 „bjx:`mCJN<â V~€K¤——«œ°î­ææ®ë1RmÙ ."K™‹i¡ÈKfú¦jÅÀφwñ \ƒvò¹¸jA„v³8T9Ð#AÃqÇ` @âÎSzµi¢;Mœ¸úìmVGØ›J³ é—Í-ÅS‘V,LEúK•ŠBoRPQÌÄ«F¼ ñÿþ~Ú%B<8Çl>)o¬÷·×oÛ% ™àÁ¦Üß^Hxz}º½7Ÿ=ÙPÿâÇÇ[Ÿý¿Í­§Oð˜ûôéãÿâî³ÇÿÏúS!’³áÿý“ü<*-î‡ÈéôCªÃÑݘÒn¯´W­­ÍMkϸNÏjNœÁ¥3¾²þÙ¡ß]Û··eÏù–ê €îy´iŠ»s@­þ°ãvï83wÇÅÛÈËéDhýawrƒ‚5§yBA}4ð:´{ðÿâɹëÐ-^@‚œ~½ž`ü{%a°£ˆÓ”xLŽ|nÛY?ÐÓ>èª|596i€Ù7äâÁšR콪YÍãýÓ+šUoZ'ãê{˜±­Ò„ïy«r´G…*¯O_7¬½z³zP©6­ÊÁµ•£Ó:é~¬Ÿ¾²µ—•Ô8†J.}T=x½û#Õ«žÔ¡‘ ¾uŒékê+xPyQ?¨ŸþDï×OjÍf@XGÇVí‡ÚÑ©Õ|…`”~½¨YõÊ‹ƒšµÜ@õëÑOVó¤V­WŠÐéF­zZòÔ6Û„“@ƒ2Ö^å°ò»Ñ ªâ+ŽêUå´y ­6,Þ;p ûãCëฉݶ^7kÐDå´‚•ÐáfêÕ { ìuå;DŒËCç öâ¨öò þ²vT­aÕc*zÜ€‚¯›¢BѪ4êMlóøõ)#阀”£Ã$Ä#. 'Ô‡ZpX!¸ûúDЬ/r™‘öDÿ˜ 4]©®“²õ=æáq1¡¦ˆG1hŠ>»xâ9c×îY[9NTô¦ §ëÖ)vZ;vÊj®ì}ÃZMRÄðµ-^´,–LÁƊîUš+°VMX†E4w\9†Âîumt¼­]ªŽª&6~‰A—A¤j£j´Ð*UÊÂP¥k¡.r0Qa‘Ôàh àND·íwŽÈúCõÍW è ´Ž£ù´g°HsDYâBcÇÛ?‘Ñd‚6åœb²£LØE¤òåMŒ?Žº‡‚·~vö³]úµRúÏFé›ÖÅÅzkýªð–´‰¡mÕÞ¨“ Beÿ¹¸Ïì६J5˜ÍN! ñg‰ê0Ú\Â-ø3ãï oœ1‰¹…Q¡Œ!§¨Žsˆ™gk_¡t·vÁüþì« Ò›¼·{nG…çÅaÀÚJT2‚ºÅ©õÐ~M)EyVù±çPñb}¨ž9êTn/vqõ·?Ï•¥ã^Ž?²'´®Vàùÿ¸ÍZ{üòúø´†¦Å\ÌÕt¿0o­ ­ôÙùJë|¥¼v¾Ú:_Å÷ç[fô?äJð§øs] V‚,¥®„ø¹Ë6‘‘yÅÅ”ºôè" òL"‰%“(ˬžœüåwAÎëÐP\O¥ƒ™ŽFL®f1²u♟¸öݺ}Ùî8Ý«k÷¿ïzýÁpôËØ›LßßÜÞýº^yQ`/_ÕÿýýÁáÑñÉÿ5𧝸ñÍOÿY/¨@ˆõÏÜ€¡¿#ÉÞ—ñøólN¿3fîÁP,vÖOñ oÄcZ£ûÉÙÄ繟ÏÇ#L»ŽX‹ñ ÌŽšpôœc#9‹Ÿò”›ËY;^%Ë/VõôŒŒìÆx\6,É_’†%{¦ KVŒÖÿûòó‘ï~ýu{£tÛ. ß?ÎýÏöã'›Ã÷?O6¹ÿùSÞÿèôc¾ÿyüåþçËýÏ—ûŸ{ÜÿˆKœM±ñcËît0¸cFØ‘‰*ÉÆ%ëJåÙs # P ’‰ˆàN„7O€TG×ö¥3~œü‘Œz\ |:quQ´ýw|´ôW ¬záŠDÍÓ"êÓ¢¹r&¼:lïÉë:̘^ʨwe‘Aƒ ˆÚ reì¬R( —m!)Ú0Âa=6Ø·ï‚\Á”ˆ>èžì…É8¤,°÷ƒ¸Gã(/÷‘N8ä Ã)KÏ(wàÄNù¯µÖI£V9„…ÓoVþ}ܸ(bSÔC¤«S?¢: ŠZoaùý—XÒ/}ŸÁŒÝ÷è“E£Ñ„9SC(Ôa›Y ­Grßý}ç;üÇç»è/ðfsÇbÿýˆ+Ï,…¨ÂP²i{—»%ó(²¸uZpʰûè]jõíÿÇ»…]*$Ap3 `w1ÈF]õRßoZÒ4ºhMìK6ÿe»iä,ؽÝ-XÔ2”Ù-,ÑGQl·+'U~Y^æ‚ËA¡|ЦÈ{Ë Ãý•µP—εýÞ…UïG®¡Ö1âÄn¡ZÈT[°?ðGxöx9}át$>ó?SQõ –í£W‚ðGÐ[‚®ö½«/Ù-øèÝÁ í˜õNA–°/ÇhÚp¬&áZUößkÐp"óBÎ?F©ôý¢Ò¬£ ó÷­êá^ ½ª·¤pédÕw)޼C‚BGðL ·Ki™ñ[µ¡ôäècäu¬¦ú• S ­`\z_«»v£cÃU67®vb;8_?`/ïL}L҉7i·[YR ¹©ø ÞæÃn$oWÑ‘I­îMÛmÇó "ù­VØ>ñ›••œeÝŠ¢l^¹£XäÊ@à§ã;f_‚ŠØ–4»0–ràFô:ûÏYË UÂ8þÁ&–è»wȲrùÖš§ŸˆüÐuæAÉÇ6‹ü k&D­·óbÐçÑ¢Ðô¡=¡ýPi´Øgù“6]ðY¿¤4ϙܓÆä°²ÑQ¥™ÆôŽÆu2y!¬OMX¡ñ ea|…2°Ú›“ƧÚ?oGã‡Ý?alé‰Ë'ǘTíí¼ LyÈÞ½:Û± 嵚OvoSÖ³ $¥âxÕëÓ:‡ù44…Q#, t÷•$űDQ^TÉÄ%[¤/ƒt1 ä/Sw,ެò¼NçaßP›Ûcw4±.‡C˜°±=QF˜‰çôºeLaÖµí;ò|Ť“çõ@åé$îØctY¤¡þŽè‚ma„ÀqŠu çcaë@ÅpZì¦\Q!SY fc3?rðß0v_Ýɼn²3dmìþâ±ü/xQ¼µO³Ž0hÄ¢Ãü˜+‰[\èR’!æ²–4,ß1­¤[BDÖúÄ2ŽŽ‚‡_S§ŸJÚ™Œï¿žÒ‘èéâ„¥Óó’g~ù7ÖlýþÍ×Þ³éÓö“ö¶óØÛò67òÙÙÿdl•:ZXžxæ¯ââáéôÇê'¢Ó›öÇ¢Ó«ééT¶™L•>ß—‹Z1çUnÚVéF{îÓoXë›™|·3®Š‡'ÜjåS)ÄÚöäc‘. 2#íþX¡]µ×‹•§12×?ÿÙªŸÆgoâÌÉÜÙá¿ØNÊ}œr5Ü<ér(›P°ÀD¼Jf:!âu8H¢Ÿrí‰)õëp,JË.9ô ¿@œÂ‚­óEàEŠ'%“`c(@‡z'£d§?Œ¾·{S'$¥ë=¡ }ȉ#ØR¤¼ûâ÷,¤C©ŽÛu0¶‹£GxÁíñm¯#õXÎà½;І•êI½VÐ#¿g4ÿŽ8ÆÚ)Èèžé'ªÝù‰È#Cá5‰xT¶ ž¬¿ ôNQ¯ý—·á¾PŽÜ[sUµ£ú¤£™‚PdÄc o˜9ñ€!ø`…G‚ ˜¡ÍeU澈š7O^ï}Ó ÑP6£‚¬w¿Yïñ²j)²nÏ)%t %š¡¼9ŸDŠãkÆCÊâx$I,o”xV…ìc Å;ÀnáÎñk£­Ô‚ŒôBâ(Û:a úæÚ…ÅJkƒ¦²<é ‘ˆí‘ŸÓ~‡zfTív–,®ì‚"ÆR„IºãHŽ|àÀs%G‚ôµÓÒa±”¤V„)–{”ŸJTE[g6{ƈ;°W¶*=OŒT´#O #gŒa²¼ï m­Á¡Á™ „é±xo9Q:E¬p¥¤#ö[C*r“õªÀÌ¥ÃnŵZ¸¡áišã|“Ú]͵ sv0eIü„‘ÊB†Ä¶¯öúSØ °5y;€EÐ^6í€8Œ„&¨2T(oÈx@)äWª¢“@ÏÎØßí®©þv éû‚·á>Ü9^L63‘e\5SkZ»ÔU,»„„qt|Z¯‚ÐÌÊ8ÍêbÕT ߈Ø2T˜S ziÅõqÚhÏ£E+•Rcx­– *ˆ$ºW€ý½ýƒÊË2ÏÜ’aª;Ýž}7Û\+Å„ïÅL¢€n˜G¨ôzžJõy*ÅÓc:)ˆŽ+§¤;ÆëŽaA} ¼¾wµ›o} _“‰pðc£agЏå9÷Œ™M˜ÛÐìF†´¬÷ZhV”oeë5€®žœpï»8ÙÎ… ØŸ¯m¤lÒ›Žd<áùÚ¬giÓ´{ÓŽãë¢h0O£ñ¤9³ >ÃᆉA¥hÔÏ)È9ž?É¡|%›Šr¨öh”À¢d½ýÁçØ¯›µFëÞ[ƒÑ¬ãDú>›†gÐ\x"àjÅq%‹lj/I U‚ñ‚¨Éd€B`S•kû½Ã.ä)áÛ.¦“§²®'´ˆ|wn_¢¶’xŽgù&B³Èé}6Ê ÛmÅ-B¤L»¶{P#g]÷¨ ž%¯ùM¶l† î`ľi¼Û¦ÇÚÝäõ¾¹U­Êrœe /ì8FÓ¥ƒ&z}º‡AÎoÐpY1+î$b™ŒYš ëæÏÄý%¾”v¼O'|‡n¸"­}÷VRGŸã¼#yôûN­^Ð#õ׬¨¦°ÑÕ’–¯ë{®Õe4°â€ó3Wš Ü!V[ª•Fu0§–hJ΃1™i¥‘U Z·¤_mÊ´$/·/Ëhæ2Âxá°ŠxÖPòs0÷Ý Í½ˆþBùzoze/,÷OŠûßííÿ·ùøñÓÇÏ6?{º‰÷¿›Û_î?Îý¯L8p{߬¾]âñ£gß9ãrlθÒZ©"ŒRácø¶·Š·½Û%øõ¤ˆŸáǯñãæ&|Ü|bíÇjŠ;[Ll1w(ã@˜gÖÿ8v} ¬Ë;ë%е?”­ìéÕµ= ˜|Ç|ªæ;é"PyL,@oGi…‚Px`:è¹}ÙýH»vÆ;_Ü~ÖɘԿkvÑìR¿O t1í¶ 2l16°Š!Zº{Ì7ÄÕ0ÞâsÆïQ( nóž*s‘“cr)ãÚµÓYv»7lÛhõI×Îä¦JŽÔ’ [‘=( Q<—V*ee;98m¾~ û‡Z£Y?>„ìÇWÎ6Ê›"‘ÒCë¿Cw°Ò¬àMèËM(¶Êedy3rhà­ýxØ™Â(±*YêPUþ36$S³ ?ˤpθvÜ1°=oØvÉpS «òÈ:bÿhŽÈqãàhÑéÏÞ8^ì4烩ŽO·ŠïÛœ!e\×Á6|¯ëÒAZèÀ¾Žy* ´à¸Z~„ˆÛôsTrnD~JÉëôL‘~5‘Õ’ÿá×ÖÅêò†È{…¼k·;Yñ?,·ºÊÙ•Þ´LÝaÈ[¡Å4»‰K×® †¶=^9¨7OWÅ×Nð54ó‡ Ò¦$ÙûèÁbA‹áÖ-\›qõ ÔéâRV™äzüŽð¤C™ŽÐãZÄ;"²Î7ÒÞ™²*>?½»ðÌA×Ũ/t<ò8“ºÁ ¢kOìWvÄPÔ¾Dbëõ„s?Šˆ>劄¤ lFæ¡C=ÕQžYèÑt@åÄò¦}22î¬VªãÒQå°V´š§úÑKhEµƒ{de±Ó±7l€‰Í {òæGAÝ!C9ÌezSÏ*ö“îC–åp"üŽK^ìªâXt—&žË±ä;zÄッî#l_éM¬o¥çØï¥E|à°…ÇrŒQ*Pž«÷ÃwNg•»¥ôÞÁ¬`â@FUêÜØÄŠß»Ã©‡!f„_LÇZñ© ;[%ß §"O€Õr°ñ°¶Ëõc8y”‘-Xœ3$K‚}Í÷Q·(q§Œ !HžŒá0ñ3fû&‹°èsK@—ãçÝä2α‹ù7ñ·Ì[,Vþ°‰@hc€ÃÇ~ýM 9ùÀg Ì×ûðéŸ?¥Û2Òî'6ަAnÓÈ_È)¦‡Æ£á™{È»/¾rzo/Ã. ºÌ[·è/Ìï˜Üúøû¤š üEÔ–® Ø@¹¶ÙWˆÙ§ñËÚ³w*HËdeD˜—˜üvÞ‡zd}k=¾XåíHå8£©w-¼Â&èS̰ðú’OýiÜ’eÔ:#V8;€ ® ¥ëÞÊ$­DEÜšVÊ›v©TniéBã}a.³õ¬®žA]ÙEA~?•Ž™j/DÛ«ò?I¹nW¬à±î/3…,P¸)|y}Tÿ?ü{t|Z¢Ï÷#ã0M×»òÃBÝ9¬O°(üžá VðIòVü%€@&V¸\—¶Là'UæSÄ3,@‘"sYr¹#ã*@Ðk]Ö•á§øƒ#O]€3±Ç C¬àîpbé‹P`h¡»n”“Øó>Lѽ$ŽåÍj™Q¡À;Æa6^Ô"cAIÍ›¸“©°»NÇè¶6ÜÊžÓ–BŸ] /D¤9@@€ bðm›¥ìo|iWõªv„§Ž=Š¥ÜÊ)Ý"IÀ¢8jCŒiM;´#"•‹[R‰»YÂn–ünGl‚BÝ%@B›å±%î´pòÄš² ”S4E³™¸S_,KN%)¡ ÖKFýCÄ[SˆD…ܰ’"t Κl½Â¦n€BéŠ Â–Ë¾ñ-)ŽM`CŒs”´ÞsH;çÖîzÎŽx¨Š0òYtíˆrúËv?(û ¾ïúw- ²D´v­r¹l-¯WÔ*¾ŒVã6W­ª5yŽ®)#¬G3‰gs+Oæ’úôç­ñ&‡§™oé0*?)´q r Û³òÆáæ­Ûó¦}yÝv<ÁÂÛDŠ?äcZ$0ÓåjÙjÀ1½¥“MRto™ÅÅù`ÈÀb<(](xl?éMÝ ÃZ!° ò-_"1ë±Cdì AYÛíù!ëül  o×'Ã)ëˆ[¬ÑذJåu£NË„C fLC²qa—èðAÏÇ|ÇiÓIöå{‰õÝ+w@'ÖžÛvm‡×>ÆÖÁË“ƒ÷[åͯ¸ƒzµvÔ”4QMmY'×0 ‘õ#ÌÂŒ+öXØÁpäüW z=va%C±gì ”˜Ú³‡½¡õb8vz=7®Ð€ùÑx×îÈ\ä‰õ†ÖÇã×ÕJƒôC>¥KHÔ8¸·¸ŸÖ¬Û¤É«ÚPI`çlâ %·`¢/^[އ® /)èžo~€ó‰=k„O¼k:ë°$³¼ç–°%‘á-aek&%TX±¹c¸ ¦½Ê ʆ$j—cPŒØß“¯aJyå¸A˜@اºÓ^ .jP7„j+¡Oû鹯V${b„…y‹PÙcCÝâ›!X•ŒChÜP“fU¬“Jã´^}}PiX'¯'ÇÍZÙj:N×+ß]š:@)/PObà'˜m±‘“q<0‡Ö—͆Ži'”€Ùd»%òQ#ñä²UH–ˆÿ4Hƒ=â­‹æB—õD=œ†·8Íå–È#€ŒÛqxf™[RãÛi¡s¹¥G"ôó$ÐÅðF†•”׫W/[8Å+gøN\IWš­Wµƒ“Û¬œ•J8ð–8ÛÅMýo’0IZ”xŸïR°1Á2WðÑ.VÀàl+<Ò–â^cv—±™–Ò‘™5¨,Ž6o „ZT(ÂW €D‹[+gž¹3Q¤˜æDtüÇ u.×r‘Ê›ÄÇÝÁvˆû½:Šé•ƒ•3£xˆÓA»Û­YݵnïOŒS$ÑŠd!ê*1êŒÅ¨ÇÍV}åLÄÎ3ËCòУ¼E.KK„'‡”&á‘ÑsåŒÈŽ/=Ï–gÑ…,¸ƒÝ–âþ¼YÆ¢Ô7;yYPw;¢eâªYŠ:C+ÀõI=Ã+‹ÖíÂ0Ú#ˆUôD¢æeµJ }D,é=aç'tªu%û¸RWIò©+;®u•;‰"ćveXAã•¡>h‰-´ÛÍo–ŸZ›ågðïkø÷ üÛÜÀ_›ùœ:Kˆû•³š%ë¬GkXü]–{Y;zuzx€E®œƒÕÔß®hÖ,U+rtEu0PÛï[ê€DÝ¥è›]w'%·C¯µo©a«ô>”ÑwجUr¬‚·þsyÍZ_/¼¥Ê²#-¢g †|ž#¸%÷g¬´äGšÔ m,G¡É(“TÕ4S%keøn5Ïuº.ý%ÏÓ%¢ø%°C5Éÿû4†w±‹ôˆòÂh¥Œ•]a0ˆ[©ÚU ÃpÔ2.Þ1 #%ÿeÙ…ŽÉS|9:jtùü1™g«Á|Òˆ~šÝ_Õ2+š:j­P¶äЫÕ2c7iKKHM»yÊt¹ñœ*<¿É8Lô/U¬”8Q%ù†28£§„XAò®Èaüìö; §zÁz–ëðüÒ9ʘΗ»ùÒñ†Uº²J]€ð|‚Ê-¾bƒCe¤º8ÙBýr)É;Œ{‘• ¾H*g8…îè&^‰„Ç#¾ÜA‰®R´ðÕíqã§ët8*õ@²í)'J–nŒË@œÔWöXkd±2ŽZ$u€ÕUSs RŸ¼>mí×j;Ö>à‘.3éê £ºÊãbÙtÅå¢â››»¼ã¹t¬ô„K.¯œTªßc£hc¹Z ¾ ç˜UÞ¨¹¤þ*XÚÓp£ ×ðŽ=`T u’PuîÓOcqiµŽIŸÙ$yèî€ìŒW¢ ?ÄídHÆ, œW@ÌÙ±j·“±-Î[4„‘íùú5šâjpBŠÎʃõ@ŒÐØÁuRöApnÜï‹Ò v"05TytŒ¶+§§µÆ‘lçª7¼´D`bäÄt…­¹WƒáØÎjV¡£‘§Ø‰;A _÷bCÄ%t¦Qƒb4`wƒä$ƒpÜÁ½Ã»–§fŠèQ'öB’ØJWj[&]äü˜=ÜuÈ£6§ð£@ ž‹áIÖ¿vÃ\%ËO¸p¶5ŸK^íAæRÐ=‚T—f~™ÎŒ ¢Ì&YîNªÅ_h&}$. “K"i|ŸÓ?-؉…­ž·–W~€-ÃôÆÚ5>Þ°“ô© ƒgž¾wè ÞÓ ax ùŽÿÓ1.ÎreЮîä–`¦ñÎ{ú ‡Qü(TÍ¥w¢ÞR\ T©m&»7gþÚR;öÄÎëì˜A•®‡Cj'nÕŒPèg)ØÇÃ3î“8Pá_Æ”hã͇ë(kmµ<éòPÄÚÃó³ V K£aÚÇ–áŒgOJÒ0%‰.W7Þ±ÓG?ÿ̯ßõµ|žNì«YPBbé»1Œ¾kÍê@né rôr· ÅòK<»Ì$\t2ÀS\OƒZ4ËÈïÓÌ0KŸU_ÝQò ZJ%ÌSªÊŠŒ!Ä{€¾ãTìˆíõõåûÒ öˆõ™ƒZ'÷º‡Îãº|ë‰/„ü\×Z¥›×ŸoC[Ûå(¿\w€ö{YÒø0gxÆ,ˆ)^'mmC„ãDz'ÔLj³f¢ ¢ãVÙk~­|ÕîØ0ÏCõ œs,˜êž3¦÷²~ʋۡm#ôä«Ý¹º­ô*·Wož²š%È]—†Ð\ü˯v ±žAÅœ+Ÿ¼:>qß°7˜i"Sg¼¯”¤ÃžéЪ&Ê;ä ”‹ì±Ð±!ü0Àúðuøò“*þËÃKoˆëó#åÿxüìÙv(þËã'[_ì¿>VüuÂ1ŒŒ3‚6&^÷ŽÒÓ‹zIs+9 ýþ&)ŒeŠc©q`šíádbý6Ïj8ý=˜p,˜ò_&Ì“ÐÄäüHÎ-ê[Ñ Ÿ|Ê'hoò±œ5²ø¹'Ð={4Rl»9õÈë@ä ˜÷k … Ú¼{Ö{׶䬵ƒ«¼æ/«x¾çûRóm;²\Ûƒ+¾ ò ²yÌñ#ÔŒì±t«8έ¸y©œÔéRpPQœ *ÂÙ@¤ë#pÝŒtBõ1§—4ëEhën]ºhuâ¶ßÍÖ'Œ4"®Ó1à…"@CáúÔ¯{×d¬È0Ö4¡6ŽNÿã4N„] áÜ¥Ð;h OÊ6 gkpqG.ò}’0„ÇÏéØâN"ß Úp±‡ä·ÔëùT߬h ½Æe¼å]»èâ܈Çh:è#%J¾ oDŒ;µ2. —•Ù ²9Ĩ‚õ¢?åˆSÏEƒ›®TÓzCì·'`> ¬Ù‹„ì\ëyNYXcøN >ù T‘ÿÏ Å6º5î‘ c𠂃ãY&BÁH‡Œµ¨1ô‘wÚ6뢆J‘üS‘.«ÉP»¬†èšbP‘,,䯡oÆÓª{éö0¬!û>ð`s}Ê4ZNa|ØöEëŒíô9  0‹• ªÙȆÿ‘õ“ã…W H‹ž°e× *B1Cx@2–@à´v(..`¶U°¦#Sïý[qØÙ,ë¶'‚FC—¬5o¿‰wŽ3â8ÈŒé±g.~ãˆØ>p¥!•&ÀÕñ‹æñAí´fˆq%"\Ñ·t:‘¾ õ£ïk q†¼(.)¦(q¥Dݵ×(-eq)Cyª(R*sê«ãÖ 887*ÍWzGÊ™!6_Õ؃CïNô} €Ÿš8vJºW©¿1v'\ƉÝ:àüQ?2tD}kîÆiå商y â]t.N÷„‡Ÿ¿32¯†21Nµã“ÚQt^µ·ñh¬žÀ‰µ‹C¿€ÆÁqõ{3è¡×J†îヽV¥Q}Uÿ¡KÛár1SÑø©µw€cm5kûÆÑ„ËÄ÷MÄnU[DZýRË$òU¥±GK”PBRcG.ùøÅ¿É{l)¦â} ÙÄÖV^ÎÀÌ ö–Îíb¡Å-¶B2æà3™p$RGPÊÀùpùV^֫μ‹a™Ðã—G¯cx¦x_µQ;8®ptÜHÿMe¢öj'h€.¬qk§¯Ž÷" Œ…fѶXÔ­£ãVãô´žC ,üu5‘¢Â'%Rz/æEJXj ÏÚCOVaË÷#6’}Ðu¿œ)=ž¡˜fýãy| ýÁÛC]/žP_›*ó€$mêgê[x>¸júMÉ’J!uôÔϯÜãœp7×hØÑâM2e’“ dJ9rtc{øßOóæoëzž¹„s"Ò^³N)JF»íˆ ‚Òp\&3å~£ÛMÏ™xJ@Ÿj•›99)Š`ïÑ–cpE•Â3u;³‘-ˆ8·#ÊV×»óM0.9£Å¸G&<|“jÎ/¡ü4©g, cp·(Å‹iTŽ:g¦|3úg‡›3¶gˆr7Ú‚Š]xŸE(:ƒýŸ š±° p3Λ[χó¿=Ùü’ÿí£ÙÿŽÖÒux0Eëoii©´V ì…’¬übúæ7èûóÛó}ç‡vj¹ƒÑtò"¿oo>ûF›€ð`¥¥da °œèU:º›å+o—ŸêQ•‚ÚõpI͈F@ æÎhóð}é T­ã§¸ýjQÑ´W«¬-­gØúQ„”í9è´Ž.åeF|°ÿ‚.E ÈvÌsõãÿmúŽ4;M¼…lÉüÿñöã­ÍpüÏíÍ/ñÿ?ÿ_[Ü9ýç×V‰u~ÀæÃj?­N ë³)5rúΰM‰ùl›¢I –K©ýã¼oŠþÏ ý3¨ø„J*^É•”ͧ81iØŠUX1hû'ƒ¾–ëåÓ²%RÊèšvøïÄ%ƒäá˜ô¡xã´Ž¹¦È!| —ŽNÄG±D›Ç ÜÉ\lࣱ‹Ç4(eKv…]mhJ»¢è¿'¬ÙÎÃÚÂôT†®«qå’·å*¶êyʘÇîÈl·Ø–‡»w8éâIò˜²–¢w © »[v¬œ‚²õ=ÚÅbD=LùweY²*+j<©Ç«V5iaÄV¦­êëÆÁ^íÅë—÷8ÿÍ`¿®ZÕ<)’& ‡ÜïES2–×tÜë8—S¤Õ'N>fb„ƒ.‡ñ¿vz÷>™m·{íÇG0@7öDJž„àxª½Ô*AÙàìMFòÞYܽ¾ÓG/ÊÉØn¿ƒ¹¢ßЋ,gbßÍ‹h°ynA‰’`M–Î×Rô! (2iŸ%‚*ÆŒG$ƒÙÁS4¡ü²¡` ¡ÛÆaãLKL*‘ Jâ _\R'…]Œð%Þ<NRUÈJ(`†‡¼M° ô€×ôÎFé:èkY)yÊŽ»>OŘ†É¯#aT"˜ žÄ8~,¿dLʲo.+W ”kLÞÀÁ‚íÙc”_ ×DÞ6ü¢»ñtÂ5t˜b ypäQû‚üÔsû€c{àpÊSöñr1ôÌ9ñàæÂ¦÷¬¨€yìÄQ—ÝnÌ•B.M{*Xö_aÄQ„ €ã.0 »=!+ÿ®‘œ(93²+Š®¨@¾Cq·’ùLPa0,”c(Ãî©$C¡§|æ!‚û-ëÕØi6–qZ¦m`Ø:³f„Q%ió3ê´LZÿ±Ò8~ÖŒS©%n1u"ÍôÛ›ãbŠ˜>>ÿOÇûgñýÏ77ÏìÃŒÞX¿hèq,wÏÂÙ¹úƒpôlÜ.AÚ|ÇÒ½2aÊ ‡/¸¥‘SªP²-z)–¾RºÕ„¿µÓ +:Yò{ÙöûÓTÇù+Ui a¥ª¸‰_¯J©`Õ&w"~õêÀäN„V4Œ)v-+…f®efÌ+F)²èu­/ɸåµËY–º:5É ÿÖÿSûd«“?üêèK]>}óëϳ¿ËÑ.Èc¥ÅïÓþM±Ë88¦IOÙÓàã,~ýË"+»oU9¬…z T+¢­ÝÒ1f.Nà°zj3ÂTNl‘¡ÅŸÙÂEgòƒ€ª”ƒú<“ ñ5UOhÜlí8¡ž:‰Az =Êp¦±ê]lUT‚&ÐI} æÆñï¾…‡¶R]DZê8ph¡¤i7®'zŠç$¡»Ò)CþåUæbƒáÅjz¶Wð¬05ˆA݉KY*nœðYHÇ1`6À-šPÂ67ð[ˆŸähôøÇ¢åÊ–‹T†^‰r"¿‡:­Ô é Ïëp§ ÓžeŽœoæJAÃ~nnÙØžÆï|¤‚!¤"´}NRçUÅ)æÕu† œRŠx*IŸQx`‘Ê„{ç‡I¯(W X8X™Ø-[µb<ÙÒrÁÙ¤r Ú’!é€Ð´&0ê’P¨s§Bà…eÛé`âl€ýh·(s͈-[D˜;”ýàõ" ·LðZkÌiKΰè”5£äÍÖå¯FŒ1£eûOÝÔ Úèºi¤’E0Ngðçä› ŠCæ´ aá+I®N©¯ê{Ÿò(åÝõ/‡½Ò5'ÒÔ$,íU17KñÄÅ[ÉZ³„+ i4Ýr—×+¦—£ä0»AFœÆÆÀOÔýàP¥5‘ S…°+Xiå¹*U⥪0T)Z¥[4Ž4VÄҊͯBt§lš_$ÔŽ8âtábĨÏÀ„†¢jDyPeK„š8Á¬ ðâ'6êȨ>°Öû¸E*02†×ÁëÍ8ÜiÜA£ûEŠVFêò•Ró•.M‘Jټƅb ‘^9i0ø]Üvq?B˜$8º3²œH2ž•;ˆ·Þsïàï‚P0“å×Þ`^+XÆ•ÓzµùÉx>“xÉÃ{é¶§3}ýÝl®Ïå[V*¶¯£!àûñÜ›Q–!µ†ÙßÛ"%:^-9$!ú \o%ƒ‡‡ËÂõ‚§ç¤ê¦îcLHÑÅm ‘E²Hs2ñÈ䱘¹ä=df’s"2+oŠœct€¦ /äúQ­õúˆ<‡÷VxEë¤R´6‹¢¹³=q$CJ9|ñWn¬©H·L½‡I;•—iŸŒ‘ÞØc´# ±Pùt¶fÒ¯ŸM'é_"Þ_'i‚N…@‰‰†VíIp~“£ª2嘶äxvíÃ÷uBâù±Frâx8ÅØ¡ÌV]Ê¢3Ùn@væKù~—E™”ÂhBñ<¥L”««ßÌQÕ&ibú!f¹ôPæùJ[¡ðé˜ eä±z–‚¡pÝŒì„|úã÷<*«ã”#†eOIZôŒ†„%O ·ÆæÖ¼„¹ª0*Æ $Å’§‚³¼ ‰˜µ@o}c 5fÁ¦êb¦ÅÊss9½T¿Ç‚ ì^s¢\4°óµßÁX†ú¥5J.ñËÊpߟj£V­ ^tj h³ÚÚ¯¤*Y?®f)1RHU¾U­ÖÒµÒ¬b·,þþM¼I« dØÙÍO¤ÚÍGEVåâ:F^ÕyRºí;Ž˜ýön—í6&—DµÕm&½ÖÐožÚ¾hÿÕ1PëØŸW¦|§gnÀ¶¡.¬žKw˜:•·öp^ÔS€æ¡gm@ ,s3m²Œ¦Žu›Cc(ü¦åeš• ¢Õ Ï¸ ³£ z˜D”WÔ´$[­uÅ»•³¶=@–Ûq0™<†‰× c€!–EkÔ+ú•¥]ÃÁí5œ×BœÉppSo: ód·´a™ J(ØÃœŸ~fQw!{ÎȰ¦pýŽ#gÚ!Yèò÷ÿ¶=’n¨žlO¦tMK×Fè-M@dÕàš—]z8|{© jl KHõݗɧ•$"ö:÷“U¥XóÐ~ç eÙîs¢Ärà’Ï!ù½k?K¬ô•¡¸è—»&4¯@e]úæØjW2¼Æ„ì¼Ïçø®3Æ+TTµŠÛ]ªjÚÍ“=Kû7û"C\íú3¾D¢8ºlqó¡ë\ïNÁ¬¾— í6/xÎðòÞiݸƒÎðÆË[“|ÆúÇ?h5¨[”2Hq®—ji/¦´²’ýô%©„A.kuDÀ”|²ZG€hVOj­ÚLæV´B€Äcm¸RcOù*l¶Ä=ŒsË“DW2@¥: +®üûn³FØaå©j¯ŽÒSå`eïùšE1™ËL¾qWÕx,±(]Õx°Z& Z¨I 4:, TrKOýâÒ»ÿß1p¹ zÌ-Âx†ÿï³§áøŸ<ý’ÿéOèÿk-×;ËInÀß|qþâüÅ Øèü”GC ìMEòOŽœ MÃR«azƒ8<:m­ÉGÞ5R#ê¨_U~¨µö[¯`v¥\ßq9ÏvïN&j‚%`cT+—E®1™-i,èH’jДéG¯Ëêƒà/s) eºož_i¯V6©³ôÕ£ãû*´\貞ÿ>FÂ3Ž+ËÈäØQjS”?&8òXi¿· Ãz¤™‚ɵíìFjS(äÞõA3~ähµñÒŸ‡›Ö´ùPéøš‡(2àd?êÄq'Ž<åØƒÑ«#ŠÅž¶½–/ æµòø2x§©³%†“®­CKãåáiý°Öj|šu.¯Ý­«>ægkÝ„<¡¥\ârÁ*§$CÆ%Nê_z}ÚøiåL¶Y¥ò…q¡/cת,³\)« FÊSºPTצwç­OîF°)¥±¨Ï‹´Åô ¦`‚+©ÝƒÄ´”âOZ5)ú%ïpŸ>"mW+Ÿy“8rO WF3‘+=ˆÐ¹òÎHêÚûXjWJÍ&xµ;÷£y­sYÈ>Ü……S¾¡g‘ø›§ º×ýä´gÚïAúÁXæ ü ýᯌt¯¾Ž%û ÐlªWº’†èñ48¸2“½Ú·,TêÂD¯÷*JöÑž}\ª?=þþs ùÉðÝý(žÆ1½SÛ&j§q´.^&Q:IEçÜ…P¹èUFš ×zõé»~T;mW>9‰R'­Ádh߃ʕÑÌAèJ"´®¼3’»ö>–â•R³‰^íN*º‡Ç|I­?0jÝèÏíñÈ^Ç7楢(Ëj ÷{žsß¡Dטa8óTŒIF›§/~ªìí}z ê m,¼ÉåÝéÜGŒ jž£²Þ“è‰Yo>8‡ËÄŸŸõ’)ŽÑ¡î¥Y†@g˘ãt¸§™NÕ†¾Ì±´´îN׿.~Š¥‚¹R?Ÿ¥‚W2‹X*<ªû,îIüRá÷ÉKE–™½T¸d†¥"º·¨¥"{:×RQúò€KEïâÇ]*'ãÓãÏg­ ±X´qÍ·Z´¾˜–‹V n½„ %-­hª£wñþK&ÔÙŒk&Ú›Y4ÆN~ÜUÓ¬5~xñÓÉqãôsX4˜bâò-î·fÔQÍ·dÔž˜VŒú>nÁèe’Ö‹Z2ÕrѺwÿÕ¢÷4ãb‰ôåAÖŠ©‹q© … bóS-ÏyïŒíž #ð¨. ¤#-hÙ*˜’‘…ltýÆÒ.*eübAéD¬c›h^!á4¥Q3ø{BV¯©\¹xجl]8dU͵pàáÃýÃ5 ļ‡h@$¢mÓM¯€ÿ©yZ;üèÜÓ¢ÉÝ@·°"wùŽ&k={_úÇ€xô‚÷¯å2ž9ZCOzWzCد\Ï÷_œ± „ÝMÅCΑñ`¨³§¯µÊ^«YÙ¯=ìd) }¤éRZLž°(’¦ÌvoÏÎ6·_\”׬øu»|v¶±¹…T?Txcm—·È6tØë8ãð¤M®ÇŽÝiyv×1ø´Bu \¥þÀ=&pçf¸4D“Ô¾‘l|ÔbèÖÑñ-tÕ®Ÿ¾RĦù©Gq rTÆ™4¯"vBÒ Jv“%>MœÿSä×(]8‰mˆs`°@¥utwÒº : î@ Á¸MÜ)¶¨dž¥¯~îž´ FSM´ôœÉtT¾æÎF„ÎŰ¢ÓDî{¬è=~ŠïÝ&®ikÄú«Xbˆ§ ÿö[D<éÙúç?[5LäívhY§JÛ–eÁÙhŽê¤§Ee9ÿ9¨1ÂIal¤£Hw.†ß¦š0]*¯ã(SÅà¢hSEœBÚã4ô¹0ÖØuǘ6@” BÏQ»2ú»€¸ê]´€w½Aa‚™rÆ <ôîrœ&‡ý¼lòNve{hy>rƸc2™!'Ÿá:.Bó”]Û¤¬5c.Kþwâ¸'mßµ°©~kkêQ±¬F 3îè°ÐÁ@8¦Âà0 .gŽFO*„ ½ è0ÿ5 ï†Åu"¨3¯° Ù4aÈÃ!¡)¿;sÔ`itÏ•ˆàú2.ËÄ5¡3æØÔÏLn©:kŽâåb5›{ÄZ¡«Ð)¬Ÿuë÷Øa(¤øBmË=-­Á#꫸ g3á(*®G‘3SBMÃ*ÅÌH`¦SÑÇÙ秃šÓœ5Û—C /°HàªÚ)K‘ ±Ä¡P\ܼ Ò­™áàÆwʰݨrÅ_kà Ë\Ù·œdÜÜÓQ‰ä£n;ʱøžÏ H‰[ObÝ´›OxŽÒm?P W:ùIXxh|³™øl¬&±ñÃÍt2]+ÿ6á¯ÿ!8 =tü‡Ç[›ÛÏ¢ñ¶¿ÄøKåßúøáKà‡/Œ¶Ÿj§£úQõàõ|¨4N*t }£QÖØt¤ÄÆE•pfQÍñ„†Y(+ùÀÂÆ&‘]:0”GÔ©`îfQÄ îG@²>m--QÏk!T2°ßÍŸçÖ×$@CŠŽ'ÖÚºÉ)€„­ÓŸNè+T‹Æɰà®'‚rF+*ÞÑšÐm2¨…j†ü ¢5ýa‡*j¢ž:pxñ~Y0~‚[­Ñ\á[Û`¬–Ú}Kí‘:[Fë ±ÿ–ãf YÖŸBЬú‰é¢‡f¥= k ;‚ö 4÷ú¨Þ<Ý Uš`ИÔÙP1ê{SŠlX¢qQP©‚²Þ{ñ‰ B˜Àe#급 Úƒ5å"lÆwÏépfÌ*•J˜Õ{Ç^Ä´úü,Ó¼*q¥Cƒfx»½·–ð¶27“€fL.KšÝÓ½ƒú§^´À„znæUË]7Î.Á{ØÙ¥ÆÃ•Ä8î?»Ь٥b‰³Û¸_¨àÅÌ.z+¯x«Ù'¸!cßF>¦ø®:ÁØxd‚¥ãul¦±Š·¢àÆ-äLò—«>>9m~zúŽ&ÞÔ!„ø™IróŸ7°&å0T¤xòñ‰(ŠR$ã{qò£väPzÌílRÅrI´úÓç"ЍcÍF±?%Š$wG,ÉD…‹8ƒÎšú»4bŠíg0ùrŒ™çž7õuá3?çü¥˜2*9cÆ^×?ƒùšºÃyf :7WñÁ×(4o¨EcYÈê$H)æÊ%Ì2x’ým(Ós×MSÌð>éá¾ûòŒéåb ³ûcý·Š­O<¿7î7ˆ•­Ì'9Ó, ¨[©æíÿ(g™íqáÙã­ÖA­rÔªíµá¾õ scÞ bPæ]äË ‰Gèj«Ô}nV¯A}UèzžKD*˺ÑÚ¢²Ò#ñ!‰øª¯ùIÔĽÃ>$½ÛЧ¾æÖiõ¤~ò©©ÏÛš´Gî(3í‰îiOÀü О^IŒ9 :¥žÇEv[æ—’¬BtwÒ¨4Ž«µf³U­T~X4å…B„S*( 2WäC’^¾/Ûîõð¶=`2!¼?œ¡ß É ¶BD¼IAv‚¬ÐV´aµPý„0…á›±”2«J{r^N€E zpܬÝû¸§¤íaVe‘×Î ·Ó­þdˆg‡®Î…¹äW¹p`›O¼Èç›o´;ÖdNØ­…M¨™ŽÌ&˜n!™JÇOŸ©´ÿ±“Ž!^xÃ7'"%—Ó»á”rQ²£‚>)NÊ\‚J~XÓ Ï°õŽ¯Ï“†#,p"ä…wUìEóÏ)Üqà¢t@DD<ÆÓÜ‚žÈ7=SÜSî&fÉqÜåÙÒ\L¹ÈŠŠ)ƒªTòJ‹–ï‚ûŠX!Niþ„8‰‹ûˆrF6Žk¥ÝÄBKs†X§”ŽëÂøŸ[v áðœŽÉŒrܽú0Ò\Åq[™?„À6÷dÅBšKx›²æád“‹ä"xœ_œ #r¶P§â#³PB}*Ñ.EYSœJÌ›Is {¼w§ùô=ºÃÁ¢ÒI!²˜SÔ)"Y<>:ªU¤ÜNûÏ"ûqg#J=ÆGF9+-V™çÕüñ@ãäĘ·b9ƼÕP˜NÓ'hãckùÂ;hV5 w{e£háÿ ”!%î²K޲fy‘˦Vu x–âKίôË2/%Ëf3Ë“:~SI‘s£ùSiÃèŸOQ»8'yÎ=™¡ú¤Ìù&3£\)¹4ÁMV2Œœê@1Ú”Rc• ²bŠ’æéI gNdiwøÔj?¦$¡/4{™D=}â¼ûzâ¹ý9„;êjX´#LdìÅDñ‹‹¥/áÊh”½Ìï˜ÌÍï”Ñ¥’ºxÊ2Ê\¡ôÒÛ0“x#º˜Y¸õRˆ6T2-“öIw†XÃcjèõ<2‰ŽŽ¬‰†”4òÈ|¸yY$ÀYœA%Rˆ˜ûZíôÄØÏ&<ˆî!:„1’Qp¡d¶ØÀ£L'4èè‹f—3MG¼¸0kÚÒ ´¤5 ‚Bx®Ì›Të¸ut|ô‭<³ÚdÎ%Ô†'UYž7±'SÏêöì++hX‡'¤Ž„Á±V<Çé“]èÍpü…®e<‚+>ã ² !/<Šîç­ak0¹aÒÖWìQl®€é`èm‹˜óñï¥3ô´ñ >;C‡å,D”…á|92о'j™˜ŽÖ³p y f‹aBËÆ5*øøÔ`BÄèAŸ7žÇï[û­fítV<þ tûÁ¶3óḺ³i€2nrJݹçuŽ­Okö¾» ‘ólˆFL¦ÝŒÌÚ&gLÀŒ.ÝœeÜìî—fß³‰õ Eudð³6BÓteÞí 3•¼ñ5j5ÌT?Ú?^̦7vLÄêºÃøµ•?ý‰Ú¯²ðµÒãÈÁZAOÆ­S©™âöDzr,øö„ÃΘïʰãNñIEÄZM*Åoº£½JB ¿U>"ójï)–MäREíòÊÆêœ7':¦²k´êi J…Ô»\h}ÏR;(Å®T7)µ&ŒgVbðžJ—±ô?Ð-‹>sݲs>‹e~™ñ~Sh’AV¼ïf”µæî#š‘–U64b-…\¨b ¥êÄ„è JÚâ Ó˜ m¦›õ ’¦",¤Ö®¨HL’-MSI®4Ìr¢Lù²vºP‘òʙ̖(QP zŠ4iVžDäK¶Œ–·6©åK¡NAíN¢|©t?,^*˜ŠH—V¥£¤¼‰­‡)wýü A.ÊŸeO&N$Rg•¸˜•o: #õÃþ¤ç1|ÇxïÅÀgO4á¦Ehw DO~̈Ãd©X©½X¡˜µ¥)H¿RÌÖʾÁG•Ózàój–É•I‰É“J0/K*K ¹•ÉFJL(@\‰8–¯’ÛŸC¤—º0¥çò&g¡æR&3ËüZí"¿R>­¼b¿3~¥ôg(ï›UÜ7 <´ÌÿeýÔ«ha:äûM±†yŠqg(a¯5ž&nßá¤Kn›Ãÿs¬` Úã¡ç•xò0œ¾.àãË–ÿRê¥øVïIHš<RãõуÅMx=fÔ< ìi{bÒŽ;˜xÏc_¯ÙnèRd0áÔJÏsþ³>àЙ¬üƒ`-{î¯Î°»BVWƒÚô lÃC\·TꭣׇµF½Š ÒMí¾ t%÷á˜Ð<©U …È„¡…àÁ÷•à uØÒ×]~sëYyþÛÌS—eïÿa»«ÚWþðÁú¼QV¨sëNV6WŸ[ëkV„pŒçá¿ ŽŽ~Ñ{œí ’Jæµl€‘þdoZe†%iƒWðì4Uê’̦ˆ46§ÀŒÜŒ*#vgkÔѧS$ÍGºÍ6þøŸ¶´ÿ ¥³FzUr‚Êv¥¢ö´$÷ÓÔë‰ïU¸[wàÜ̆«-(€;öøÆð`žD{ϯ¡¡ j¨o·-Àíµ »DùÍ=ÅÀÍ->5´¸%Z¼ÇpQYuéu´ÉÏpùi¨Gâ= aûžbá?¹ïð®GSA˜Ož>ûú1@| èó?n–7”Ï›¡þàs‹^Üs¸(öæ}‡ œÈ(ÙòKëñ½I”™¡oߟ×¢À+¨}¤Ä¦ð®àÍÕkoسǮ·-s¼7æÿîdžŽ {§ðN©M\Xjü=ÐÒY÷ÎCï–hN™9«oÑtÊ3»£gnôp°«¶ªÕ•³ëˆ¹°ƒ±r!çM­3Ïí9ƒ‰/+}nOÇ=DN ¦ßl‰.˜QÂHEZÀ&Çúdi·¡h@8yIú‚ÄÃ^*¼ÌÄŒv&ÞÁ½…¡o=WK}x­ž>¢‚à\¡ BØÀ~¤—oõÞÛ½©£!1C­Ÿ~›sâÓOù+Õö+­“ãfýM«Új¿nTk«°”¬ðCëÛ]Êh¸ñÍAk²AÉUoŽOjG:@õ‚{¶± J;Í¥È5œn6¼K Ï›:­g©æA+o˜!h+@¦ VØ’e,žê´•¾³Å§`é‘5œÌŸÅBB¸™%†O“ ŒÓtŠœuQ®€”ÓHô<‚–¦ˆ.“—ýyMq`0XSŸ3‚3jâ5fí^ZµLgðþÏá`Æ}5ÜT2²™Àq¡´Ë»È˜ƒñdã.ÃL/ýC½é¥:È´7W8w÷ó4c s\ Q/ç¹¢Šé.„ h†ã´ äÙ×@8àøK>8ûŽŠ”9noÔ¤¼¸™ C8IU¤ÇÞµ@Vêve>ìëÕ3éa³c?³B•š¸Ÿ.UGKv5ª†—TTij婊ÄD½é¬‚ÆiIÔ–&Ï_&Õ'ì'ií£‚’Uê¤eÔr*ó5KŒÀ‹ž?¡Ì´(i–—w(àü9lìµ.d‹C™EŒ êBƒ%XÎkƒ‰MÊøk(¡Œqiå…:>rP¢™¦4A×VÂ’FÅÕOA»¶ò""ci~‘ëg±FæO.Ü´""–ÿ„"¢†Õ¹ED·™DÄ{¡øó#‹añÂáœh„2‡p8ÿÎ)rƒ‹C˜›W8ÔQ—A8$,d5t§g–OšÎÂáŒéŸC8ÄÝ>³pH¨L#js>—p¨NwápÑ¢a²`ø™]KÊLj…s …  EÞçØ‚¦|šIälñq¶ð8[tÌ*8~ ±‘óIÏ’y£|ÝâýÄÆ¬BãÛa6ñ^â¢:sÉ‹‹ç”ïÙO$'*Øž!(š¨Ñ’â"äÄ9¥ÄÔS×޵¹³ÇWÖ–Õ±'¶… CY¤J©¾jAÑ-’ ³Ìñˆ«Ð¾¶ÇÖZÁ*Lž{…Î÷þ“÷C·ž[aÎ7 “µ·¨¶;˜¨Uù+úµ&j½0&Œ=7{e¤8Óð3©¦ ØP!CÊèPAçvâ¹¢ïšZ%ñe9EK~ÜZ}®Á ¦^-qö¦º•cØrq=ù½Ì«õ`¾ng8`QÒÿ`²õ3¶b´÷‹¡š¿Å‘A¬VD¥ÖéO'µV¥ñrK ÞÞh ˆb6y-‚àÈË1´H¥´­|Á BŒ|®óâ¢N‹ 9+ÎyRÌ~NÌvJÌvFÌvB\ôùpŽÓaʳá}O†YÎ…ÍZã‡?7N[ ³/ñœñûË»ÑpY½¢áTíT\È”ô.Q ÈQ4ïÀn±ŸÝ¨B-‰mFü|ŒÞ6õO>שÿ|gÿÉ_göŸ~ƳÿùÀÓ@)÷ш~.æô8k£I@ZŠ[ªì"$‡ÌY½Ñûfcˆ%ûÖL©µ6Rl¨O<ܦ®‘<½‰‡Ü”‘é «ž\2v5´†¼f‘ÚꇚB?dä~?š#§ív]Ç£–Óþ¥3ú¡ißL(V™élrK(9¿X ž˜\‘n¿x½ß¬ÿ§æÇóÑÁ$ô¥…ÚãUEµ¥wëˆ3¯u9íva Ð÷‘í%ŒA_+³zµ½ñÍÓ…6/x«®0.ëŒZ ÓŠNÔdÀ¸OñàÜ:9=>ZˆÈ{‚Ûnk4aOã?[ä`ma††¯lú ­jVÿÜ„‚•ÆI…€gÄ«ëH´qÇhH’Ë0N.Ãñ¹’Ëæ!•fD'½ûéE4XYµ"¡®gÖ‰„ê§Ðˆh5ÒJ5‘¥:C¢ã$VbG6uh}ˆuYµ!F¦Ñ…,s[­ã5î>ZëÌG}½ïd¡|n‘_@ýuFp×0µÌÿª“~»îŽÞ?µÏ6Ÿ~µyñ<¾È¶}¶­•h€J¾ŸGЗMD_×ùzcggks{g»ÛíîtËgOÛ_ç«naÕ¨áì<ënlìl&—ŒåŸu· àÎÎúÓíäÒÛZièÛ³í¯?Ýþ&¾Ö¶Îæ7[åͧ_—770Ækbù­PùõÇ[ÉG0÷m}Í*©qaE¤\š<~HÁš¬êqgoEÙFeŸ$Š¢%ÊŸÖöjÚØ´á>ASwàlãvcã[ݸmo¬Z>hꕠЦ(dPhKzºPè±(´±™Ph[)4ï(ù­¿ æ7>#Ì—6gcþñ0ôéi¸OOÃ}ÚÜú:¶SO©/Oý•HОޛ žjÑuŒ3ôT#ˆ¯7 }-§q+¡Ð7¢ÐævB![Úî&º”O*ÔN3ºŽìøeB!Gzö4¡PW®®¯ã mn,€Üõ9”K1iv§(³¢Ì“ež¦(ó,(³˜õµ‘°¾Ô3æçX{[‹_{v¾LC’ΟuSPgÌ6øPÔ¹‘‚6S”ù“Sùl¾™‚mn¤ac)¸ØÂV]ò®öt;ÅÂz<ÏÂ2“X"ùKÛJE@›ifl3Í”m¦Øé ]¦)ÔNS¨“¦“¦Ðƒñ’ì;Ûç¶žŸ}Ü5– Íkl{›×bŒÜWmd„’Þ¥Á¬Ð‰M3*ž.ш®ÿÉv]lhpÎËâ8Dg¼*ŽÁôì‹b 鮉“g'­Æ6þŠ8}yãlÌL=’–\Ò_'kGéÒÔOÞ?µÚöˆî·d.}6Ì©Íd“å*ÒH1)."OOx 9Žþ¼Ðyóå#àhž‹G¨öÙ^:ÂX/MïÕÕlz¯®FÓû®3\0"Y-âràÌw±HÝóR‘ꦾP„ÒÙn<Ä’Ku‘ˆãÈKDMó] *ÈJy8/Î>ý¥!tä£\Î71ŸçEá\Óÿ§» ôï¡Â™8šä»t÷këÉ“²ò/¿ª^Ê;Äœ•WHº|„s×ÖÓ·“O Òåßh2Ö3Op‘W-—è1) çMáˆW¬mlo„_lò ûëð‹-~ñt;üâ±AqÉ—®Ñ¦~ò`‚…®]wØE9íÚ¾‡Žš 2œåeãÈfÌô•e{€É µàðÜîVü!…îhA†~¼J'ô¹Õ›‚ò ŸU%ͳ×uÂ/…|½~ñµ˜ï­ð‹oøÅæv”hd»y#ZéFßlÅvLRâeä ÅgO#ožˆ…ðuøÍÖ“Täû4†|ŸúZ 1%¾Íôû43ý> è÷ivú}zúå!Å›L­­íû‘ò"U:ómìYU9ê–;CCE³¨ppwžG}ã7t/ՎйÔ6FÓªlpÔYÔ5¦H#ÏRÓÌ*ÁxJõL2dUÍÀÑúÞjÄøL•ŒJÙÕ1 %ÌVÅ,ÖüOm k>§ øçlÿ=Ëö{–Ý÷,›ïYöÞÙl½eç=·÷}컳Ùvg6>ÍbÓýÐöÜ÷·åžËŽ{nœ}rUŒj»ý`z˜ûmÆÛóÍýCmáÛóÙio‹šq&Ñ÷1ÙÜÔ‡¦¾€f…c!6²3 dg[ÇÎ6m‘¼X£Ø¨F ‹¶DñS{!–oÖ,“¶MY$ÞâôkY$ÞÞôY$ÞÚÔ·Q‰·5ÝÜœi¦·¹5ÓHoóñL+ÓÍí™6¦›OfZ˜n>]¬ß–ç¸Ï,±=³Ä“™%žÎ,ñL)ñ(Dîoß2—mK»–Ì6-óÚ³,Æ–ev,sÙ°dµ_Éb»’Ån%‹ÍJ{•ÅÚª,ÂN%•ÊýìSÒÛ¦WO£ ¶'½?GèwêjDí˜È¨òÀ*iÔã“ÓfŒjû§–0¾kÆøN_:UÃÿgïoÓ6²€ax¿.áþ¢:Ù\À;Nk'Ù%'lmðNšMsQV•„§ÍÇçw<ŸŸßqÿ±ç¼ÌH#!„´ÝËncƒ4sfæÌ™3gΜš´[ªFfw1»zë¥Q-`ÉÔÇ$I¼«T 4Ö%I¨{æ¹k)BɬHPÑ’J‰°v¾Têk‰ªìÂU¬‰ÿPí ÂLvüg”L¸ÛH%Œd•HÂ(I!Ð(SJ"!ô-‘BV–‹›Ž%ÒÇŠiË MàÞ‘6|£f™È™«ø­ªÜl·^4ÛËŠtáÏËæ1å–Î(x¨¾Zèð;swÂÝz ¾häWS¼;1]Ž,H&)¤'õâ…œzEr '»!« iâÁâ^ßÁÔ_˜ö²=?¶L˜E',’ˆýcöËÓF}ì†-—¶ÑÉ¢öˆJ±Ý"ÀömvJÆÝCV\oרM‚o»«Ä`nÝeuiw‰…U»Í2t¯Ø%RLOÆÝ¢ïvšó§ä xÕ²03™w€è¤¤Ø Ô=ç ì xeGPv>2r`>sä¿âkÁ»‰Ñß$ï€zfùI×ø ÛEtÌkl ˆ%Û† Ææˆ³/Ù:’ÊÝåö¡ÎÄWÚB`âöÔ2¼msT¾|»½„ `ä,Ùa”qÀ.e¿Üš–[í3!HY÷¥òúS¾ÎžjøÖûN<6×Ú{bÑ™vÿQ±’eŠ›†UûPº©Ëº…–@öýHEÀÊ=)nÖ²ïK1¶zo ÞÝíJ˜èÊðþBjRîp¬²”q³ÆÎųgȌќr÷–éOJ(«*¡ÄÒkTÅ,Ñ\–qé*•Æcte·ÌXÂÄzŠ[Y;­ú–ËgÚp‚–F•Ë¥Sf¬\G£Á×ZzÝ0ÖRkwo…¼¯’”r‰ª7‘ˆïV¼Z{zb`d©ÖŸž5Ä(ÙØm¨|­#:E–Rh£Ï  Ž x…š8Eéäé[!„­œìŒâï ™ÔÇ}«„­…^¶…+ åÌòX˜ ÒJbw¯5xù#uÇ1C[W¨Z­Gæñ¦Ñ&/)¹\)°>kûâúåå;P s°1}-5stn¿W­­rW¿Í¯½‡Ý:¯ëïik+¤#ØÉ H˜’TûÑÝ«¨ÃLh Å@év«Û+­ã§/õ¦T¯6îÆŠª‰½éþ5•ý>5&¬MßáOëïmTý.ì­Ôþ®Ö$”[\„ñåð”J› ’Ãí¬´H·8øË®ßæø/adSp­´[Nd­P¨¸ùb¶]±¼…> ŒÆŒZ[aó³S:ò•TkÏW"¤õD®µçk}AK4yGbV·²"ˆ\-b©øÈ¬>ˆ >•!EUSœN€[Eë‰o´Ï¦U.„·(èüv´’[”,Vïÿ·×9„ (›w§úu¤XÔ=D­Òé–ÅX"™ÉÁÝRBK­ƒ yÈ ‰H.ŸF±>ýC­Þ&6œþ´Z‰È”ÜÕ6y[ EÈm¦ü–Ûçk+’ð}ÛítÍE¾²k.â§*Ãö÷Å´!f–M—‘°)fTkÄOö­v½L*Žn£‡¨€Ãôlw®áaW€Óý5TA£æb²m•A½ìÆËoáÛTÄê<‚$(;–໤@W©ô )|Q#‰˜­öþÑ‚H´¢:§„Œ½SS [™U)jå:” xÚ}0¼NWèN‚Â)­(VOI6åJ .³jU1šFr[Ä~• ®•ØNRµ¤Xw&PÞj A¤o5…ÙDCµ©[È‚±¨Ê(üÅájµ´§Œ<%¹ÉÊ“”…§-Y^L5ÇéÄ` O« Q·Dî‹Ø%løýH“'ð5£P¸8ÿ)¥ÀP›w,ÞA_ÉcÉ×”îT8±Z`àÀ‹ûˆäøºR¶J,œ¨ÿ¸‡S§â/¶auÛ'}i$¥ ãkìaáIºõ~·ÎÞ¦B¸%¬»ç…»p'û_š×Þ ãñœi_T1•N²b’Òìj)gw®Z9Yô HIµÿÅNìzû[Üœ.ßëîÎÝã¯äéï䱎Ǻ®™´Ë /Sƒ,óYê&²ÔC$ƒsÈ×ð I±.X¡ùB%kû’dp#ÉfŠšÚy$“ßÈ-g$£:äv'Ù}MÖÅðŸEš\ŠüDaó‹Û ÜÒ3%»SÊZó˜Q¼½ÊmP²ûždr;Iíq’ÚÙ$µŸÉº˜dó.YíX™´L²\z/‘n¯S¯uõӻɳézÞÙ ¦³¿ˆ ç÷wAŽó“Q–ó륲¹M̾ô,IöJ. ArèàÓÉaÁÜÞΪ6”YøQzœ]R*§‚üâ©Ù{ˆøW C–YÏÊ8ïYšEDejЕJ°¹%Ö¾˜©PRÀ|_8ñ»‘ÿbÒÉm&eD)å6“’QZQšºÄ‡ª¬RK ®RH.ÁÈSJ/‹È]"Á¤+œ8mK$™4sœAšñ·±ÔM€¸eRÍâÄf’læt¥t¼ãÎD˜•¿Ž\­Ç 5€ì Tº½8Z"ËĽ ÖAÜÛÐPS‹08‡·—_Ê: ut-É…j¦[ lF/¨:…À‚£þBÒŠŠ™uD?iå”õÐô‡J(ÐôOÖ›…Hýl‚ɳ]$¡Fn)„q³†0BN:IG›^ QQ¹\YU2~z–KË'2›èË)‹ÜhZ!t¨³—UâP&n•¸qt~gŠ”áü¯£D¾ÆÈ€ŒÌ¢Ô¹µ¤½I4â^úä÷RdZ)çîÖBYCÆ ^®#bPÅtÍÀ³!¯–/pÀ_F¼P‘²†t¡ &¥p±†þHѺÿRbÅzØWÏ$TdÇ~f‘‚š¸DFKv"„—TòŽ4µ8¡"q©4±ª`ì´,•%–Ï_&Qö“ ’"h¹ ¡NZF9B™¯UbDó/dÌ¿ÒmŒÓ\ç¦y—0æÒséõ‹¹ôîÅÌpñbÞÉ­‹¹Þ•‹¹ö}‹™á²Å̦ž6S_³˜_îŽÅ¼å‹™ýveM4ý‘¢…ù…/UÌ[Þ¨˜Ù¯SÖ™…Ì"†y·(æm¯PÌì÷'f¦Ë3õ͉™úÚÄL}gbÞá…I3Ûm‰¹úªÄ¼Å=‰™á’¤uÇ6 Ö_ÍÄJ¶i­kÒº+;k¥!ˆµÒÄZi be´±îÌÄZßĺ•9ˆ•ÑÄÊ~‹ne²±¾¬Iˆu6!ÖzF!·DÝ)¾Xª]È—“b¬;° ±Ö3¹Íäd–j¬;²±îÂ@ÄZÏBÄÊl"be²±2‰X™¬D¬;6ie·±ÒŠX·´±2šŠ´îÒVÄúK‹X Ö"­µÌEZwb/b-7±–[ŒXËMF¬,6#ÖÝXkZXë›XYìF¬ŒwñVzËë šŽX·µ±Ö0YW¬$ó…íG¬ÛXkX¬7kÈ-w`DbÝÚŠÄZÃŒÄÊfGb¥7$±Ò[’XéMI¬»´%ie4&±RX“X·1'±²Ø“´îò&ÈúK]Y wA­µ.ƒZwrd-¿²–ßYË/„¬,7BÖÝ\ YkÞ Yë_ YYn…¬Œšv+ý½õ/†¬ÛÞ Yk\ ­«?T&ùÒ·CÖm¯‡¬5î‡Ö›Šì2É]\Y·¾#²Ö¸$²²ÝY鯉¬ô÷DVú‹"ë.oŠZ¯Š¬wEÖm.‹¬Ô·Eo:Í^ãõH$׎éW y„û•FÙd®“ByÛíŸ7Ûñ¢w'AIxÉTŸðRe*DLÞí’Uü½Ì,|ÈŠ)D.š–ƒ”¼BìN:nÜþܴב:"XÉ*s„q“FâXE_HÚP0—$np¾ä=ÎÚ“®ž^ÖXk²É²‰[H hÉ(cDñ²ZÂ#M'_D˜,]¤(;-É’ÅÊùK/WðÆ’VªZ"SD&-‹Dž/–'þvÿóçü”p½—*åÊãòÎöto›ÖIH[Ž[žîݺøÙßÛÿ•'wÔ¿ði¯²ûxïo•êþã –ÛßýÛ›ÙއZ”ÈÀŠA3Ø?KŸx:-7˽²8òОG^ÅÅ£¶ fó‹‰90½lÝÓM ßÖ}ôboøp X¢ÍsdŠù¼GG+ ¥¬É®LõžÁ@À‚ó—+ûï"JçÔyãÎMO¿0'Ø#jVÚÈè¦ 6Hó¤mÀ!Ï„-êßEã#¶åÂ`5s:›˜xÌÓœà›2Û]<4{ lR»’â6õÁÄè“Mœ‚²öƒaÌ€:5]Ã)€²Ö| Ô_Æ‘ÃaXŸhOÇ·…Lܹ“³6Ne]ž  œr&W£Ã^â©UöC‰É-áôÍaè°è?‡>ÛØ‘çGJªÕ^ŒQè UÞ€”‘ðÆbÞ` Úxhø&¾‰B ú43‚®f3ú.¥,‡@œ[’^¾:;ÿ1ùmóÅé’—­^ã$ùuODI/_¶Î“kžÔ_u_6û§Í³.´ú+ -)qÞZ ¡×l½M~û¦ÖƒÏô>|ÜQÈ$e9}¾´<>øôi¿Ñ>Ö*ÏUs¸0áŸöFw·h½K:xZ#s<žâsæK5X?DR±iÁÚò¾p'ã/” ‘'Íq!§M øIظÀ8áœcü:7XYðÔ°H™\áà‘ ¿Ž ËptÉe‡ÆÅ|L­5 Psj~ïfÌ*£\ó@Ür04àý0Œ;„K<¹~ýø¤ö²ëë¦h­#s"îêÌ­T“צ{‰}¾4&3 †Èh1¾º€¶°IÞ—°–ã#‡@!T ·ÇÔïTF€ª†û|ÐÆ†2±g¸¿œ©»p¨ ìHÚ¥çͶ·¶=)_ê?–]cKLukK Àm†´M£BJX¢ÈŒ¬¥»à¯ œu0Ñ­ñJÎÊýT‚/ÇmÔ>Üy_|—¼Î•ÈÎ ç_¿?²tH«ŸwN(èNþ]¿Oïú}lÿ¹PÇò"åÁÜ™àÑWIhŒú~µLçÖЦA#æÃ<ÁJ~öóÃz]+ çÓ™ØLVÞ_šÏ~6—¶öP–×~×°HKC­¬•FµðÄ^^¸ús¸G¸]ýœG±AÖ¸4µ­ Î#Ú·òÙÄiöù6Ðê¶5ŸLFdo+µÒxþUà_þínÄ{úÅÆÃ‹t]”Ü E¿MWvûbº’ÓÛ•ªé _M†E»xi}L[8`Y}î‹¥¶VjôaÚ0mþí¿½hq†Þv£Ï|{'…Òc%ƒaá 2h@«¯f0Ô€Á,ePv»ßõ_·_iõÆ¥ê1\#¾`ÿ5‹YX Ö[P -/ŽÍ¬Ï’Gë-jA©ÕÛ‘ê22­|I2e±ñ ’)4†Ly[Kº‹—““óÄn²)÷LêpEûzö-“k%Rô*7- ™VƃÁ’mß›*—ÝRñU°¡Æ\¶r3êfÊðî·Ò¿ÞVŠüÉMàOÕeü)f½i¶v«1k趬L¼¿ /{uV:ÿ1 7㮤ÜuÔ–óê¬?då8TiýýªcÿwÄl4æ&‘Ø·@b߉} $ö-Ø· [à· $öíÝl¬’ù‚d ¤!êGJš! ïÖØ¤¸Öú4C½¿ K>ä'ø÷8¶øÃÐw­ô«e u‹‘®¼,ýl'cùJÆòÕŒåw3–ßËXþq6žŸ€Øýjº‹åÕ+WèK¿äÚµ n·áíü«À¿*üÛ…0Ùí1þ+Á/lÅ,%Påv"UÅë¶L料 ð«™÷I=­à…%ãY0¼É.uQ¥õ….¨ž rÝZÄŠÝøcwý»ØÉ• Æ/H Њ†­¤Ùσ¥ÕJ…nRÓnëA—²ªœ‹ºcóª)ËN¡k…&¾¸+Àü8NdÒxŒt×[GéqW«oԿ‚˜9v–5ÁžAÒUSÆuA=»õÒð;òºÑé6Û­4u°Ï)ê­±¼ò‰âÚ ÖÛᅦL‰«'V-¬½iªÿ¯]‡Ò¨åK.Á¹u–rõ‰Þ¤”T$à„Å£BËBÒ²ÞúB‹á «Ké_Uñ×.þÚÃ_ j ät´$  ¾ %õLë& qORRM !„´†Ð+ª­OA<‚Dú¹ø‹ ¿¾õÛ$Ž7ºoÒ‡ìMJ‘€H„¡­A$~ÅLd²ØRû¬¡]âz)´K_+ÔK¸IV¾ ï”Éf TÃåB[åÝë—ÄàV)˜Æ“m0 ½Oèú­4íHH=éqÛïµûÍîÛn¯qz‹%X¿Ô­±áj®§[CÝAcGrPÔfºwé.ÚgR%´¬Ÿ±Á¦iy6,©×3¦áÚe6c5]ª4´Ùµ Ýš$J™ÚÈU(ÍKaáK»QÍf¯åKCŽËåØw-ÕÉδ¨é´Ÿ_¢q¦n L´ÆÄZZ¸¢šÍNц–Õ Þû9Ó‰§êî+ÜòŸóFã¿´6²\²é0›GH!:¡'*‹Ý›Î€+øÞ¦#"¾\Žû4uÏ6ò¤ ªD»]ÛVp¶†JÂìÉ…¦27RÁ (éû¤–š[ªƒêB|_Jþ9”ž«†«è#H„ÃE€Äóµð˜Øìc#Ü@ <ê6Ž6´Mwûÿ”šÛZI’ìöxóçu!iIêÁáÊâ­ûëÜ0>rIù,!Ëĉåw?uw>u³+'O” 9ø.°l)ž´;?t…·¸–W«÷à [j—èr•àQ«Ý _•Æ5Œ©‹Œè๠‘ß…”¦ù䨅ŒrS ÃÀ¦&·ôÇ}3uáîZ‚ºcIdƒHä‚(:£‹T°­«ŠIÔÆ WA/bi‚cÁ Ó¶…qXlôD¡E ¢Y»ì‘P1plWº"s0)5N¾ìû/•¥tê™êœ·RLÔ?¬´~¿Û;‚ŠÿXó¥¶§®7œ˜åËçþKÚ£¥S½LµñÑôòfáëÏ4?‚©³Lxœ9öØÑ§Ô+8Å\oîju¼Åé)àÂóR›ÏÐÙx>ñ2¯1s„¢þa¥X<(¾{X§J~X-‹ïü£ÁÃjÂY Ûè¬õE­Û¬÷Ûg½î-ö‹®á¹Ê&!œf¥O×6»Š]_š€X@ë,Ô3 ”¿}gµM—=Ä|ç0Cu£ZhÌv‘0®”—YÉbw¼x¾Äkï›ø» Ñ#øRq=½À®­>ã)Râ«qñè¯H,a±0('ïãÛ ªò,ô„Û¢chŠù@ÇUXxÌëçHxú'1”ZçéztgLÎâp¨³)ε í‘9†à`}áð(úS"ŽìÃ`õÑpî°Gð~|_„Œ¤R›Ž²¥1ÿ™C²Ž(çTI8$Ê 'ÅÒ¸ß%¿Í@>><\?yj$¡¥kLÐ[‘2àxZ­ÕmªÒÚÔ«»|»²‚ÚÃ=×üEèHÐúÄÔɵޙO w5lËÖ-×ìSµp/ùÜ™Qr©ð2RKb*Ec‰ÊGšb5…æÚS¥5Ò<ŒtOŸh°•ÛN øSwÜçžm 5v‹ðqª[7øyé4ÒâN𯳉>0.íÉÐpVuci#ŠyÙ"Â@<(‡0ÙCƒh§hXŠ—0ÒÐAA›Ù€# J>mÄ®RBµcLuØÃBìU«O´™>bƒ@·s [Ú]-íâ8.€\Æ–650p@´úãÇJuÚFKÁàÓ`½£‚êf倾}£a‹ØÎRL“íož–‹Ž×tò£êíÌŠ$}r­ßàyÉ1ôaÉÕGF„y„“¾Ò¬ô+W Œ©ÂØÇå¢]èÈÇcð—m¨EvíÆ³œë… Çö+é®;Ÿ ÷lV})´¬õ‚¶dù0¿µç“! ;Ü<ýM®ôÉÜp%zðý „dâ¾8wƒá†iG׆°ø4û´ÓbŠP ÿ9¶Ì4ézöLÓGèóMÎÚÊárv©cŒr#GÑ?ê–èÔx„‘2|1(ŒÒÈ 'í.õ‰÷ÌXNйgQ¶- ÍGÙMÝ7àÛE§§MW¨K©Û@®žG˜!Þkx'øî{mhųɜ]ÈÈÄÏeá,Í®óllÍ¿û>-¯Žpib•½dƲ`e7­`èj  !ˆ¸¨g¶%ð•„ d$›2„&¨ÆfÂþcnvÔÍV÷÷‚÷Ü>ÞTaЖéMnÒÑÌ »ƒ(B7Š5+®>ùþEnϱ'x@„¨€7¨Ð“ùƒï¿«ûZ·†Ì¾ \ǺÇawæ–úá«í £|»²·mn ‡Î`b_\àEÚØ²aü)=Ô ×EèDA¥X þýÍ—ÞsOê_q¿µ–v%°9úÒƒÙÊ|ñÆ„õÄ—n‡ïØ¿t+¡ËÓ¯ÔØWZ ¾JŸ¿Je·º”_Ãção@ºÔB ÃÉxñ•<³ÆÅ錿ÁGÑbæ¹Ì At ~0Î ”µp»qw6ʱY‹Á\ì%@ìÅŽ¶ì* ¨Ó–Ä%õ_¶Ú½f*…RE‡ I¨ ÑèØ–2õß½©uZ1Í9ŠHéZdâDé¶ ØfLôrðoüB˦+ פ)’%D«Ššd…êì¨ñâüå×T‘¾Œ•`1:3Qg•b,èõ Åi¶[\>ëô—V¢­VN-WnP¢ãtXK^p<Ä×µ¥T9Ë¿ ÀÀ¢ ;ÄH³Ø*r$TŠj¯ALë³ORìi*>ÈÄCÁ»äQå…!$= ™»l¨ &±W–½v§8†X–^1ÌXŒÅzgÆ#/I}¨´ËþU²Q¬Œà-Ó”V쳤Ù>–lY¶Žð ¥ žiŸˆ@Š!Ͷ°|SP–ÝŠ½™åió¿?ÅvܤÚB}O·)È*÷ûÂÒ}áÒ†3n_N‡€©ÜZrs8ƒÍQ8"ÆÄÁ ’'÷€óºPhþ©»èƒ2=*M%Až7¯0¢0|UB¥H¼xéùÐÿ ¼è{åV@¡¸‹#Ó¢bFèlO]ɶÿéÔbÞhxîP€Kó?Šhëú€Ø¶ÄJÕ©© AŒ=¢™c‹ÝF}/~Ü j=Xü븕¥³m¿A‡åÂWãø‡†S8Ô½ò¹xœ¨! LU=ƒ›ñt -(·j*²7<Œ­é—&,¶\ü.žjžcjiZ¨tÄŽMlÃéÉhô9 pñ!A”É€„Tò©œÉÂÒJ‰°8K‹øˆÁs*i0X+‰bj¼H(Lª7rÌ.ëäâleìc²ÔšÜI_níd©5›ÜºDr É®+¥×´ò«2¼?±$:o_Dó±HfeŽ hÿnåÛd±VÚð«b­4™ÆJ)ܪýN'ÛŠÝ?¯lûç7Ù‰ðW9sI,kɇ´«ÙHSø Årzc|ô=]qõRÒ¼ó+½¡d>%Îæé¦á^êCû:]YÓš`’¢Ò °c KxeêX)Æ1%åê2cÍÀš&]=Ë.Ml¨‡¿ÒÕMlÝ+Áá%ˆF³²‰é||©;ˆL8: ¬îéÌ­¡1JÝG½/Y6L >m/É’µ4Ñ/`OÄ^’5Cft*W"CƒÚ‘xyœ,K¯Df-©Ì> %á •–¢mÇ3¬Òþ^ɳK»UµÖå3›À!Œí*å žï&0$G)Ãë¬ùtC+ÅTv*‹Ì`ùtã©Hí‘"‹+³XÒeæVŠé®]ÂqÍðTµ F÷ǃ*ž¾G:Ð6?ª¦A=š˜‰4 Tiw#åØÍË2-:ÁGd°+“;øüXX¶„MÖÙrBGƒ-|™èß-m·¼S$Ÿ+Û*欢0¡†á¬n4á]#(·GQKÍ⃃{¬5m@ƒ»;;™h0nKRfg… ôà]¿”¯ 8ÜOL˜_m«vr²Eèò=E¾‰ƒ ûÝÊõ‰ TÊ{k¬Î½l«3õvêk½b¨È§›€µ¨` :XÍb…€M,%’ªå'™'©ºó$Û$¥BþG¦g•Ät©iÍùýþqö þþq¶ NÛR÷q>îgëc‚ x¢¢0ÏgÁ JÉÿ úÃ3Ýð1OÙÀ@¦<6¼0U;#mãçþY»‹&;ýnû¼Sol" \"öå°£-kˆtD§…#ÉÙ±¥;†ñ¢{¤í•¿O-EäÝÔ³ºkùþIfÊ[*a§ë+°’Ì]Mà’C² ¦D¶¹ÒÕ£;|=áLè0%SÙ‰ÝrU³Á¡•äþwû¥ÓšÔ0ŸG tÁ©ž‰‰é8DÏl×D/ØÃ€j³`YÔÜ^y§ü#‚2Õ~]À¶°_xSƒ£žè&êªÛR¿[˜©`ª“G'€Á‰j¢[)ƒÌ&Ò ºeíÄð6™~a@ùrš ^g&wטÉÝlD—åp–¶Û{kt;£¬”ò4˜®Ç{k,™½Œr¯Ä¬4ô¶»N?«kô³š­ŸñÇä´Ü]£ƒ)ɲ41§¦‡ BLý ð&…$Ònоõ¦R¹Àª˜Î¼›Ò…=¼I JXf“<+npK¸?ãý²ã¦†b[2=(+ x›V^Môuæåñóò8iO ¸×¦B;ð[ݽß_c"%Q:äôÊ-R á¸/¶Ëì‚¥ò8btÎçu ‹yĹŽv>_J‰„ÛÉ­¿Ë®¥ ].qÏߤÑ((:‘a2%ì:k<&š¦Œ·Õ.ÈsKÌœ¯s.Dɧó•èõ ˆêUgÐõ’A'N§«¥ö[ÃYObËufK¼%×Ò6iÉ¡JÆwX_=¾o¯+iu|K}ïÊc`•+YfÌ$“<ÛO–Ú»—öµpú*úåTàQ¯¦•îC¬'»®.Ï8üŒFWFa—pb—ƒKcðAuj\ÝUYl Óó"b¥ 6ENcYs•xTù,OMÔ;ÄDärÒº7wŒ, µÛlX‹þøÒ{;Æi{uc«ÖxR£û{¥ 8ï ÎTF±¡½/KÛ³ý½t‘Q°/z#”);Aö2YšT5¥‹×‘ˆ¨IßcPÄÂÔ\g!W&Ù0™4¯ 342•Qk—&9[ëšê™¡é¸mÉo•nô eS`¸0FŠ„ùIq\ÝâÜRê%4 lIœ0}$›þ¡8[ƒÐABY};¥:j²vãÅÌðØt‘¢L+쩽Ú1p»¤ ç‰Ò%A] ’×|lH‡5›Žœ Ãí¾Foòo8Á¾I HË{LÞ)Zœ•0´Å)r`ºÆFnA´7Q¦Ú‰;¯Óâ6$yWÆÀ³aç¥Ã)ÉÅË0%zÁ€”8køNêÍÿOáÕº–\ô /H¡Rø†VÚОÓb­»âGR}!õУrÿs?óü…9Ö`ÊЉÈ8õ)T§ø}q?†…ÕÕ]èÜÌéÌÁxu}±e(„.t-·G 7™txpŒ²ŸQÂ]´Z¾ŠaoùV[åÕä‘–"–{û®5SRâåL¶Ôœó‡Ä.8y%ŒƒÃRQé¶„Y†°í¬ƒJtøýÓŽ+…÷½t†¯îdsÀ_óÃô ÀÔ^âLý'ÁíUÚ±$;l¯5’†«ÄDpt¼ˆ©cæ‹oBÑ)Yièè¡FwY[©I¼K÷e±±Ï-aC‚ÍËzÝ—ü¥[†vq£õêõ”ÖU>¬´³²ÒÁýë® SõÿÞg>ÎgžÃøÈüÞoþÞo>)yÈúöãG|bìkî¥^gòä&È _vä°ùÚWÇŒ¦‡À@@ƒw°f°r5Œh|@ògP¶ãF+ò µß`À}÷×O}Žè)òc\¾é©iÍæÞ³ŸÞ=|ÿWrn›Þxöâ˜ÛAA?à¶\Ñ´hðá5j÷auÁ÷8¦ ÓjqÈR>âÓ0°ßÏ~R+åüÀ¼;¹Ï ™>Î;'9àv¾Q:âr ÀÛvj$¯%D(ë )"$®U“ô6ŠGžKègiºHeªzNGaŠÿ€…»äHɹ£…Nº@¹¡âÜ JH2˜µ®]Bá¥8ðæt‹?À¸`;F¢š`›M)‡¤û`'‚.æ&ÌÉЄs-zwbÐ fýuÚ7Œ"èŠÖä8Šó…£CïlG¼ºÔùºÃà3 B_vЛpÉ»¹ ×7 ßòP# ´izÓ {BÉlq#r8hd¹ƒ£“è$HØÛä|+’&bü0~ÄÈÑ/zíöIVwŠ⮈ƒ9vžý<»b4v1·ïH(êwDñ Å !Ê…O]ŸQ'ìØ”4gÚÒ‚Iþ¡ÌðEç´PMɳË>k—tŒFbºAä’¦¿jÁlý¥š·ëïÃÅÂÜ•¨K^P#‚çHžFu„ý‰Jû° û–Ý÷ +nâx7#²ç²Þ/`$´ 0Þ·ÁÊÄÄu`iÁçĵ"ÄQo—ËÛâ¶v;B¿ˆâË—å¡éz ‹B’`îâÚsŒxH¶ÜÓ …—þRVdˆåƒ7&éúŠ!T´”Mky7¹#4,d*a—wgnÝ¢ka]”¼j6Ù .¯”4iÆl;_z\Ûl°@í­è›À‚ØFý:¸‰ë˜;휀/‚§§Fš¨°V¯bœiÓ2M;ÆLÛü?„&ï¼ÛèãF´™óÚóí¡qµ!þbξÿÜÐJt#Fß7GêF+âJ¹A HEÊjÎu2¿ †|åæ–¿Åo¦ €/_6¼É<-QÎÕDìÙ:Y¾D‰„E!'Š>/™‘kŽúqCòýߣÑ /d‰Kn-Y0€Þ+CÉà &#ŒÀˆ|°Â)zIû¨}Ieóâ¼yr„îÀ l"­²’Þ”W®‡LèLà aY¶Ùj䣕‹ZYºÁ$"çXÉB6§›<_ ú”a¿ü#wéÈ_,ZÄ7FÑ‘„…D ¨ Q#Ôût--ÏÝøªvÒë·[ýF§ÓîÜ6Éž;ÄÜ(Ê&qrÂÈÇn’9ÍùCa™ýÕŠÄ|#B1‹:"s‘ï›±5!‰F…ɶ ̼*adi²FòHìp(hnãIˆFJ knL¢$Ý“xNƒQO¾üŠï{y|©Mƒ_Ë ªÖéÔÞö»ªÕxYë5_7þúd5¤«HD/äj‘ò•@º/ éŽ£ßˆøõƘ­w†æ”£i¯&ǦLz¡ä4™Ê}Rö{Šaø‡<†µ¨Y#œ ³݆\èþ÷Ú£<>)hÏžiâ»iyíŸZ©¢à¯÷‡ ëªkÃùtzsøAì¨ïft{óz¯Ú8}ßšÿý"Ë/1áׄîŠ.uk8*/Ö ‰œ ºÌªÀiŠ~’ÒÅ‘®Kª^…Š5ƒB=¥¬&iKg Å. 4=4üæh5(›0µ^)Ò„/ .-ùÇ­œ4‹ „Æ™´¤Ôx<ãžë è}ß¶ŒÛç ÓüöoćßB™µà˜\3Ñšš‚Ѻ[h{!_>LhazƒÓ÷ós…–ìØ¶aÑU䢕eËSsaíÂâ ¯ÝXPÕEP³…((• ˆ.1#ð3Ê èü´›¦oéœEö--,ÅX5SŸë Âyä0›ھĥõƒM6)é\}y×öÿ }O'¯o²‘AЧ®o2Pw(B\ ;m)óÅä’®¬¤ÃpNñe丠M®ã·“!ùŠ„Ô‰û+¦Üs—±Órº„òÝ·§/Ú'ýWM< ÝmVyy–†°R¿K–x£äß’å·¸]Q/ƒƒ9î X” ‡öÌÙ̱gPØã+žk¬­óÅ’âj¡Êò o¹Â/?ö ¥¾ùFŠmTÅaö¬y/Çm,öphØÏHwÜ|yÞiD`§ÚbS¢è#½rMÅ¡ïiãðÆo¢‘±ð»ú~I„¬PT,vôñ=@Âáp9òZ 4º2]“Mן)á­eký¾îÁQâbîý¾–Ï÷ûAy|ðÓ†ˆ3óÓF¡PØÈ-Z¢„Z€± ßn- qJÐDa²Š0³Ê[6«§,”X¯Ãš…U3ƒ?€­ ¼¸¬>TÑ~g5£:í¹æëµX‡´Ûa/Sb1Nã*0çr2dþ~ÑŽy)‚¿_4b¾{'š‹˜ø&“KQ˜:8x™—VJ%AZÓÆ´êÛpîYþ^ky£üâW陆ŠJÄìFá0CU«&=wGq™h.%Õ)ÑvÓó,!Ó¨å¨ ©QÇ@­²“¿¥>N†îÀžÏÔ’ #t<±/Ô@!4ùà¢8JŸð…-^Œú;!N,Z¾"Ò[¹Å³% ïKÄw 9€mLI,Íóç‹ùhTˆˆð‹ü÷ô¸É‡ßi¾-зßâeÕD\|e¹p©Ï±ù¡YVWÙí¥Èçž>ºx·ó^tÍQû%š£sÁ–“œW:™øÖX£ÐY,ö2,X´ÑƒÛªÛ.ã×ØÛ®å²Mü¢]=ºtÉÏÓœXSŸYc“÷"KøiE™hÞ/..ÆXéPYZ«O>+O.°x{íÞÛ³Fÿ´Ù¥ˆëÿ[ÊoÇ`õ7޾¡~>p¡`ê|U} WŸXq÷ôÞ‹¹‰Ñ,ºŸUûý`AxSN ½ ®ó-" Ó,ŸÕEç¢L¡Ã¿ýÖ:L ¿ Šø>/h<°-ó]õ½Ú‰_`ÍqGTN Íÿ4/ ÿò%tñKfbM¼Ÿõ@ËÃÇVí´QÔ^×NÎ…;Z”µ€h„œ(²5Ʀ¨uxFiEáĸPýT–Rq’ßà\0º«9»†ñÈ,ÍeX×¶3tÉmMÇФºë‰2½Â" Ùtq9º˜@Ù´ü–q¡Š¥Ñ+jëÍ!ÅØÁ®ÔDì+f)û¨KveŸ@£úi(÷(¼+Ãﲕ~÷°òÞ·’–¯ªøêÝÃjð&tQŽ•i  Á„bZ^…E4ýI"±Þ£´S¤² ?ïjuŒ:^j—|lZížx|¤T*3öÓÂë4¤MI›EÚu}«o]ž†1Äš&@FE¡ë`#kL`^Õ^7p!À00DˆÖe7(L”Ý!üž4ëV·!©ßžÝ8”­/?(hÕï´†õ‹>ŠÿÁv-óƒöôâƒýé_€bVÀóØŠ•ªö_ô|c˜Ö…ጵ§Ÿàëõ¿fºe~\RmWëØ7Z׳ÇŒñ©cß¸ÞØrþe *ƒÈýQwËÆpžP{¯ˆ¿k/mƒ®4­AùãRÐí ¨M@z‡&ìöľҞºüá_cª#ºæƒ—I%Ñ)‰€›.O B[„Ž’œP1’1Å©.\6ƒ‰Ýp¦¦ç±ªž¦ÆÐœOýZ0R}âÝàŒ_™¸˜ÁÈZ¶( HL“× ž‘@Mb®"°H3‰=ɶG#:ÇênÉKƒö Ô5Ú£YZ¤=€úèSý}.7Ý볆+ÿ®ŸÄ_û(Db,V”žQ|ö ŒåìÚST[XúÔÐz¬ö¶t(Ë©Š¶+ïë.4íåU£—§¾åJ¯PD™Ô£9†eÏÇ—ò"ëóaN…ÿÕ| úÊtP9¨Q>Žº4Î)¶:¢BýÒ„5| Íæs°´>ò}­ü@¹°%Œí)ÿ¾°íÉóçM[_Çà?ý t0õ¦ÏýPT‹‚F¶­ùfc"®·@ÍøÃ}Æ=Ï´ ÈÁ?S•Sšm•Ëe¢Õ¬õ¸Ñ§½ç[áêTÑ/Æ>U/ÂðôÀž*žçw Ñ ­Ï9Tu*§è$΀ OÊÀGÌk:€¢èŸT<%ñ,î…ܯàH÷ôIþi]Á„öóÃÊ&ÊP‰½*Èó»ìUUö*"ÂÂg`oRxôa„ºGõ|c]¾º²>©—c!"2ª+‘‘Sô÷çÝWùw )*w>@™õ™e‹ €ZýUƒ/òRÊ|Ы&¢üÐ<72[v‡xµ8J|õ.æzAöŒ3S¤Ú† Eïšz†:òEP_RÈ}|˜PV=zW+šg7Èrdæ¢k@!j¹F”–|ܲØ(ó¡…UfW¾ì|T´GXþ•î<«uû½Nç7a$ý‡ YMaœy²‰ @Å\¬Zø¡ì’BÉ8dº‡ 42{˜·²-¥ÔÝR‘è … ñ{®PüûPðµßÑn¨É… ÁO}`‹– ¤(¬yCÿ«™ÈÚ#Äzg¤:upO¦÷dz;2U¶­ö™Øµ8vânŠÝÅ 9&ÊR²Ž^ánmmiµ@ÿC„%û¸˜ð|ÅQ°.Ð-”Õ0Sþ•MÊÞçýg;¹Øè^-;Ò½°’ãZZÑ åú\] ` —áàe±²¸„ÞÉ¡c A^è.µDWn,Oÿ`A^lwÏ_t{JCÁÖ½¶?þæ]Â"ÞBãŸEÿ¿[ݲÑÿW÷«÷úÿ¿žþ?0BÎz IîîÕþ Zÿ³Þ«N£v”Wl ŽÛç­£wE-lm@Oß'êûI]Fš]£m¸¤ÐÅp‚¢0ZµrcGŸºâèO™ó42Zžx¬ÆTðÈ÷Dß0¬B¡Í #.b>‹Ê¾ˆˆ-ûÁpÙ…®/€(¬lc`¢J‘T˰K×}ÎÀ1ÜC³ cˆŠÂ<*Öç.°g ϧL[ºÞÚîÄÁ˜0tmqÁêÖ¨ /!¯Ú°®LǶè ê;ú” ræ°B”?¤zr÷¹Ó¨ê¤>cÿ eM,1 ÑJGÎN^9]‰evG²G´âÛuhì¦Ëwnp=ƒ—%5œXŽ“M¦¢OƒAßQŒQ™ä ¨¬q ½µç„^Ýuá>D ¨·$=¼¨ˆW"Žì­¼(@œñl° TÏ"’0Ö¶,6•^Te®nðzEÜCPQÿZå¡‚Yé«ð0B@OŽøC¹\^½>Äßbd"8‹þɨ ’z%æù¶gJ>ÿ@—uÖÇÐaA¦’ÆÖŠÂZ–é½^?Íkô„ÈÅnˆQ§ŒÈ@ýbuJ½¾!Çgù‹RhñKÁï^£ÿïv³U{qÒC.ù®ATk„tInâ?‹?RDE¤7ªÍ4Ž¥ ßËEŠkôð´s$H´PV×ÉJ²ÊY§Ùî7[¯fbÒ‹m0<Á¤ý É^Rl}6VÁp–ìP6«Põºˆ /ºfÎìf?¡{Ii:ˆI` lZ;y,"ÜQ®Tê5SI “C_€K·t¦ç¯zÛ“×r@æ1¥HwÁu&Ò†$ZÃÐ Øb¯:ghˆÉÏùöÎKÛq5ôdfŠ ¶Ò…Û|;„j_¼-ò…&Â%†9ÛØr™Ž»î|<x¢qž²º­¡¨Wiï`™ÏÜhÝ—ÿ¦æÄv®¹ÇĘÈx€9>î½ÑòŠ0‚ÍŸÄ€‚–úúÉŒw4º:-kÇŽ9¶ ª³'ñ$Íáœ]^ø_©kduÇ›ˆ fã(}>¶þÔç†seKfîw”Ç…ù&\•°eí _ƒ!ã$Hc´!Í'þÍ<ö–¾ÃFr“@!ðiM³qtå„φœ^jÖd‹Õòþwˆ²#Ý2‰Ö¡”½CíeÊ;Ô.^€[P\û·}i¹€ô§.=úå_°AMËSÓ[r«YYlê˜[þev8oýPnw^>Wå¹Åà’q ´cgÑí€h·{8€ÊMÊèh߯„Gxwy#W ÆwdôyZÚÌ!_¶Îµ—dG?ÑÎøòìÄ–KŽ¿tK›DÉ\0+°Ö½€ÙÅàÅÌu…é€L¦¸+‰þóÀ qÓ P¬9/Ð"à|Ç¢n9Á@‡ÒpãÒžB¶ðxs([ "îÀçM³÷ª}ÞÓj­·ÚŒ«Ñê½=ô¯PiBæÆ@#y—Š©5°úi£Suj/š'ÍÞ[Çq³×jt»Úq»£Õ´³ZŽêç'µŽvvÞ‘²QÖº†E1s‘0š)7FÂr 9ô·L@ŒÂÉÆDÃH®’ÓL ÆÅŒäŽ—e‘>Ý íiÌ aÂ@Üíç>ÿ§¾B†2>bÌušuìˆÚð‚BÏøëìW6ÅI”kÀ¾¶„*R[”f¥>¼QçžM5ŠÊ\Ãä̺MEuÁê|¡‹©3 ÉþRDG™úXF\(MÅf2™à©!Ãr n6™´Å΀ª—²«EIqxNÉÁ¤ó57øÑŸ™øˆCê³™¡;‚è§e²¤YÒ›ü˳“;%Œñ–—78L8À›ÕJfÓl.@$IÈôælYÎк\ ÉÜ¡mìïD8Ù¨Þå*HetŽA[«ä3A«5>––9ÿ& ¦Œ°¯¢“kÉ€"íq[xËJ¼.ÄX„qUÌx<š›á ½ ­I‘>°¿¨Vr¹Úy¿vÒ¬uñpëŸtÉŽ>øV_Å*…rª%3©É[íV³^;é¿jw{\Q½÷ƒ'Á¾oÀ;?ÓîMkË·‰óùl’FÌRØÂô™e …®3˜öÀbŽÎ¤,ìzÎÜØ'§û.T\8W£™Ëí‹-Ypp:ò¦ökŠ©ô@;&39Œ¸4>νR=sQH‡³§H€´pTǘá 0ç°ŒeÑ“@JùÔ B$ù+WÛAÎWå†Ï/Ñ †iùÒ¼Ô}å™'F¡øÐ$ß,9WEb’¾cÊü÷±MŠôOpÂ`XÙÌ]Œô,œ¢×yËòheŸ§‚·â MÆf²ð†Ê*å”)ÙˆQ©?êpؼ?þ½Mc!‹À°?1Óò E8-ºéÜõ”§+b¹LWr†[!SJ”\Èæw4 "}–sƒÂ ¦•´<ßv†ò:‰púP™WäQ£^` âX¿Vš¨R¼ÿÍ%OIÒ Áæ„ßÇðÿå„ÈÃÁ¸DJ³-Ô:TGìÖx¡©ŠB=¬Œñ'j¶^™“7Jª®á'j‚“êâÖ.±Fx) NM¸Ý€n¨"1àÂæ¡×èóy£Ú̉þ¡È€ Û¸(±|¡sÙ7”¤Pö”C‘“{†a:§sá­*: XR–*<“MáÉ^úA ­ôA|˜È³ÈW+M}|'ÔgœÆÞkÑ‘ÀPz* m™î––GzÁxn! &˜ª.’HA†ËIpzŸWæ-éx6XB:@Ȳg¤pË+DO»‰È–é“ZéF}@Þu7X:§­À ´‡Rö½`o]?é¦*˜1_ÅÍdÙ€ôÐa™>ššÖ\Ý´üDM|rÃÒò²G¢7¼7úMÌ`‡ÄQÉÙ; 3Ò‹î‘ö$/câ0ÏfÒoÅþÜÂV3€#ÕéY w&„4‘€N Û{r¾ñ¶¦DBÏ“r1&ug‚²ápòáÁñÜV'¬Eâw ˜Û®=VàbY|1õ_œ¯w«ø¢¨ÜXƒ"PkniopC…c¬ñ<Ê]¤~¤MÞ¶»>vޕİß3¾ÅÉ•. ×Úô´Ë9 Àbm,¾IJö•tþrñlûPÂ!|É¥#Øt­ ²êPqá’Ǹª}PHW4ë¯Î¶õz= }á¢/ràðÕEy ýPkâ]iPG¬ÍÅÃÏ|^“ÇÆPÊGÆ"ØI!—£Eóð·KÛõú¶ûY†v"1gi«Ø>ÐÚ–œ=:~“[m‘Í;p©Kùˆ‰=ð÷u½ùÅ…’kö3i³©O ²½+ÇÆs2i¡ÿ.‘ÞJ…»¹Ë'v4¾· {îaÐE9Þihù7|Á3î«Å’܆yÚVàù ¦\ÐøBûÏ\ÅOþ,¸ðp`ÍgýÙܽ$µ„£# Q DGM&òh"5q4¬k<Š"“R·x%iÔõ¥M:ÂÀ§~Ýl¸±ƒÂ'Á¶É˜Z¥ì=88Ž®]T!Xëd°Ûæƒ!´¡³PÁâÔô7 |Ÿ+=ŒÖ%Š ’yéεimR4´$E¸AQ€LŠåš—Ü )9ÆÀ[ÚÖÏs&¢=£.Í+®Å5ϵ¥7ôŽTŠÐ*ji-&yΨN •„^xàÃ$÷wî°Z‰Î”Vð <‰[„ú—õzQˆÄ,d":Ù.™Ø&m°ÈDæhÁB“ÉkC ÇŸ TÒh|d3¼ÜÂÑ"¾åQ¤KbO,1"0;6î—(ÒmIš¤nä–>ùñ#Ð0~dÛy´P.¾/¾Ã/…ˆµ“âg¾!¾d°ã,Àb"86ãEö\ºãå<Ç]]ƒ£ÄLÆpAD bÒ¢ðB÷P*äz‹dþJÅÃé¢û~”ºDåOiëVMòhbÚŠ¢¨ÜFª.…7¾Øîqp$¬¼:û\O—aø„¬æ´pÃåçH!(«“-¥FãP= &ùçÈ^* hj~ÞXq&]¬8rM-æ•y1³iæZž[fÑSii²j®¹ó¢\lüh.ÄÖWë1–+JRh9VèR’à†**.£¨( %)¸ ‘È#½ ŠãKÿê&Íb)m3~]Ò7^·C„”o³îKœ8`1$õÊvb"þé6 ÒÒ®$’…‹=¥¬¤ƒÅÎ.(ûXÙ#õ"¹¸¥H Àö›æ!é­üu§}Ó?1V»õ>NW@ 9MúQûŽþ ÅCaÈè!"ð”Úq²[d(òBײ†#˜;‰I ¶w¼”ÕÂr.ËÅ(­•ÃF¥B5x,tòÆq`ÎÐf&—Jraã|àG\ò©ëy.)@‹HçBn@Bâ¦WÛÒ Úo0ŽgÚΡÆnyý-RÎôcÀˆ0I:@z_L‚å+ýP‰|¦تàÏab7Â(Ì?ò@(ß)j¡Á“ÂjHßyªž¢°O£ùGø1E •öò™:æ×´gù‚¶½¥j[Û±RNŒº4¦Ð{列UA¹¶òuãcŒt´h3²ÿ>TUª¹UŠÙE…,YŒ³JõµàÉBßCIÛå|ÊÎÝJ“~Km¾Â=Ž …}T™Ml×ÕÇÆæ›–I”ƒÎŸáPy¹b×™úš^ M™Q¢}T£>Ò0Kè¿o‘Ã'™:%Ú4)!·àwÉ\†HŸœn±‡Ï`OGÆâs(|¸|iùÃ5‰DÖ—Ä•wb—Œ„·\‚·t7”€Î˜Õã[énÿsÞî5Žòïj£¤«ôb)êhdGlá„F¾µ¤4VL¾=Ü X¨¼Ær¥µnƒtMÊ×jn;• ÄÉB}X…ã»}(R†zðÁ’ì⨞¿b•dDÿæÇ-íw2©¹p‡øQ*2ÒFé¨/ðÝ­76Ã,ÞvGXçr6ÿ¨ÖðŠÑò^.î,²ñðe½$4äÑ»ØH¨L4¢­à3œiî G\à©‘Õ+üóϤ–P”ØZäH•÷“VKäT¡°n:GÐjìe^ì3ùº4Bdª{ñÈ8 ÉÈÒîkñ%µwq§«åœ.žÕ­^°‹+˜8 ©=‹ÆáûÝÉÒ!%ˆ«j-±Õ›Ý.à"ÿNÙ› åSFçèÎJï cq2ÈËñŠîq%ʤø¹½´ô@;EÞÚ²¥98c¶ú|nT9§Bâ´È¿I”˜˜c †§4Bžsªïy#Ám|Ü~-ÄëÍ>nm¾ûþwþÓ¯T¿£ß/þøOü[|ý8ˆ?ý«}ñ)xŸàq|{8. ð`}(ÈÌt@·=¹a[Ó³Zï•°h•—¨ÙžÏbzÁHJcÝÞJ|'ˆþ4~lÔÏ{¸ƒöÏ€3ýV¯î;¸t‚-ÍùùFâšb§w_GÕUöé:†…pá|/§ôDeÉF†¼Œ#|[ZÈò“ª†úŠÖð9ßíî*Ȳ­Pä…oÊó m‰ÈÇÂÐÌE'3j]½c¼}°\›ºHý"ä%y+“= ãlùn‰¾ uÈ…G1Z ;eV`Ì„‡óPQ¦à Ú6Œ§|_â*Nƒâ®š£ Š÷Rî®ýÿèi£<Þ¹k\²ÿßÎþãýý¿Uv«»øaçÉßv*•êÎî½ÿß×óÿÌ _¹Ü»oÞ½ Ÿµ.¥¤~O&üîÁö¶çèW¦[˜d©ËµÄŸ²{5þ'·}6ÕAôv ©ê°µ7¦5ÄkÊøV¡š>›]7¶Cñ‚ô™¹ <¯¬ÜmΚ½½³k>©<®Ò´ªÒt÷åØêmà¡=ÁðÒ4 íÂX™,‚¢Ê—L‡9æš+®W¥€ˆ­µºÚ¯sƒ¸¼¼ »˜Ø””îóE…œ¬@^†3GÔš¦…‰°Q»2)sl™cNñ8l|Ô§¨·%צùà2Ü'<ŽRˆ6GöuæYœ±$è·7˜˜H÷"éa—£"ðq•áK­”:l¤ãô""ñò-”¬h“r¥›ÒíÛÙw›ŒëMiB­ G^uΙ3\ê?–]c–¸5±õáv¡˜#X4;€¹Uœp¤Ï0O9-Ì0›Ñ¤{Cî]³ÕíÕNN`£zŸ>8nß$vbr J“ oDØÊ‡˜ÕhhÚA…œë®á+mì~H2œRz"½¢°×RÍ’2‡T$Ó êŸ–ÇvoÈà}jè–+L(Í1Š3ñlôp¨–ˆKíói^ænÎ1AÖTgÿ84pô13°í‰R,1Õ­m,ãXÊå“3«Á\ºFȇ%ðÊqQirÚì•\ïf‚ö¾"9Ôs@ß[{Ž– „>£hG¸±YÆ5^9ÆANu!ˆ\.×"k?œ,é£Ü9n.1Jxn‹Œ:˜Ÿ±fŸf»|ùs·¢WÊÎÇsáÂ&U5¹Ž€c ÿ:ù‘›l)mø®—¢œ¡#"_…PT¼hB¥Ëçgê"u!†HŠõ WLº ÓuÆú(ž/¶]Ññ— Z0¶Àc|ðÊQ`ãoÙµŸ©ÛXqëgÄ0ÆÏgQ<µÀ)Q·†21–•È>èò\ËúÒu mÉĤ©™š¡w¾IìÏþ8d—Š Ï…NNø\âv{í˜7·j*9H§eøåîÜô°'9¨éô÷ y©Íô{ÁК:HÎã×rT@.4U4„©˜ÖÏA¨L¬§N4<%XWý˜€¢ñtố%}ÉNbÝ­­Óónok+§Eût1LöB ºÁ¯(ô“¸0è¬å»€ˆ©5½²ÖöSa¨˜’nt6… /5é{Ì £„*h&üóá´,¶ö­-Ôom‘Úr‰\vdžKñQeÀGB¡Ö²inEœ^!Ù w[ŒénoRqŒœœë¯0¢pœÞ¡1CVE‰EFd~Gîg¸)x©¸þàcÝ`6 ̘bLþ¼¸8Qˆ>è.õ ¯·u Aqx€iÅ£(Y¾’}?Ç× Œšýh|HÆ9ÍO‡ ½¡z)ßM0Uku›¡ "F‘­„™¿¦ºRŠÃåeiXß|qƒ½Ýô-À288V†ÖÅ"ưÉ3ªŽ·0À–q=! [f\ÆP€tôQìmˆ {¢˜-8 ¾¸ú^?u¹ÃSmÀ62XKRâšÎö@µ8tE½4ÒÝKœ¾­mÚ¢°†1Ó8ð·a½KÄ:ö}·mOæS zügÿC”+šn©Ë—_þü¿»»[…󥺿·³W­îÂù÷ñÞ}üŸ¯ÿÇY-øU£vÔèô9sÉIóE§ÖyÛo¶š½þ«ÜŸ`I™\n{Kq=¯|ÿýwÒ±òxŽ>¸œcœWkJ_Oä=cpiÙ{ ìSSëçëäú¾W"ÿõÀs¾ «ãCi¬pò᣿7;ò²çn1ê´É\Ëwhg<-mdhÊì˜ÃÉßh³¹3ä°XJù°öÈ © ]èÙݶ1ƒz[ì$ú…}¥DáÆº2è¶ïZK¢´=“ºCŽ,oËð±u¥©âÁ¼6ˆÚŽ5CÃ+†ÃÒóÕéH;-7˽²ÜohãÆû€-MÂÞà™dÌŽ÷ äõ‹ÛéŒýfÇ„87B¨–gf)*}. ‚%ÂõGC´ ºƒfg豄'EÞ|ä˜.éC¢ïð(%lIÿ Ñpd6}€?_:—6°¦ïžÿ[£3`ÔA{üÞ¿XÛ ¦ Ä=Ÿ•/ÑíÉá‚:ï6úoàlÚ®ÿ ~jÎ.'3}f¢…Uð”@¨¯r2Š÷Ñ›vçHˤÚYSÛÍ^^ËðÐ@öLǃ}ß+hùãæ#XŠÇí­"WÙ*ú0^´Û'ZK˼X}‹pº$Q {³Ý}„Xâü¤Ýz©@ ï‘^Ô†ú̃}´6"ª î -Ê?^ó¬_;ªõ€{ÔŽŽ€}t]ÙÌ–¦4Ôjôší>è{çÝH{¨èêÀÜUnŠöOΛGÂÏÍãfë¨ñc‘ 4D<¶Xiô°LÂcÑÑ³Óæ‹~óì¸ÝySëõ;í7Õb´0v¸Ü±í- K|]œ’³J ™ci‹ê©g{+À¹|iM‚Àòëõ,h×0§ãëK;µ%Ò z“;À®bˆ‚[^|sTŠ¡YkáÕa¨­˜©WÚ[x®¬Î£R+x|ë¤as„Ò–²ŒxÙùo–ìFTò>¶ãšòߨðpOÀ“Hy÷ËßÿTvv/ÈÕý{ùï«ü”ÚÈÁ?Eô±ë1I\öÖàƒvjŒ'¦]ÎÉ¢k ]XñRV_[ìÂÊkË]j匂V]_òÂÚ·½BÏ"{aŵ…/¬¼¦ô…US‰_D‡½W1þ—fkDÑGÛÕ6*pÚ¸AþÊt_iø.åjÚO%MlN%Ï.Yö“cxЀ+éM‘DŽì%Ó ô3SÝ€BÛ*Z¶`à/´°8‡R\ùì _Há†ÌÛó[ÔÙ—>ZÚbD±‚°~ÿiÔÔñO£³"%z¯|ωOØßÅCô<LÑc‘ žâPÂOÄ}#<,ÈîP;QœäéT³ÐU*Š D'‘ëĵtÀƒ×E¿´¿³ /'†ÕçŽëðQ YVÒƒxP»â³7‚ÆÈ$ü«ÁX{Hñ/F•ój•„dÌ7·:Ó„JôHBÉ™¬ÄŸ^˜–/÷QϸY´£º¸A0ùÝô•–;¼Ç(407ÈøU0i?s²]VŒÊÞˆg7†4æ6E—Š7"`s1Ýš˜½œ‰“ŠÃ\¹Ù‘o´®-½L÷P§ì±?(]—â+ÒØs0X¹®yÚfº±DI}έ75WÇ+=ü³Ã([¡îÓ½‡O3þå1±B¬D4‘ãà\¤k“±’K†p„ÜXÈkÊ[êâ%Åk øåÞ™VùéXD«ÙoµÿsÔʵñZˆp%—¼„%=x°YGÛnA+|swËq°ÏOfƒ#v(, 9ÐHÕ+àbejO…Íþß8Ð`cÖiüç(W“ŽÇ*3Ò‚Ðó^"F§PaµºK:ßmt^'v^ÒÔ:}ïÕÏr=†D_É¡ÙÞHÎ|]?”÷×f¼ó£lð üRxÝz/@¬°âQ=ã±ÂRˆrŽêí³Fò$ 0&aóh­Y:i·8?# ®”ÄF‘†‡n±PÍOšïdHGÍz „F¿ ìIoä½'ñ³ù )ê9êVÃÉ(ª¡»+b ¦uXìe …I`h;b /Kc9¿5ò’þõæ“êÿEÛC ‘¼Îæ»2›ASÉûŵ³ö¢¿% aŽ}#6€(_ ðx?;áçÕߥÛ;òGøÌ™™Êµ`ìf§Të`=­œ –…ŠÜbîÏ3"*_Z9G¥W¤k0¼^¢!q.Lj’‘e…3$ëA¤Qmw-wÏëõF·K]¤ÝLP‰œû¡&òW QÊÍÍ50SÅ)#.D€Y i‡±<0t×¥N‚º ráj¤OMØbÛ ëRn…ëÒ¤ÀÇÆ ¢ÇÔ=mœæN©dªcÖ÷K}»~õZ«Þ89ipCŒ~¬Ât2‰«ÒO¯s^—ÒOüö]õ%¹øQÃCe®i‰}߀ÅF_Ô8î7Ë[róöå Œ 0€hŒ1 "Nÿ "—Òlí0ÑNÛ©‰#ì袛ømH¦ bAâ„X}P˜°$“á–Ñ„À§&9Beã'ðÌ^b;ˆC.e¹%F&ÎE²/>óÌÓE+>N`´8½~xèB$&{þ"÷¡%Ê“™¦Ù·õ›NæÏ‘ÆÑ4* …¡ÉI}&¬®CbŒŠÏ3/n-øœ‡@h³u4òž:×ÑZç''¸ìð4Õhhµ“n›ž«LU6Y¤"µóÞ«v'QLäÊN.…úâ^×—RÿÜC|ûïÊîÙ«ú¿êþ}þ÷?ðþ·yöêä¬vÖLºûUÞ™k_­¤%\üjurý{ýûG_ÿޤB)¯ÜQè ­(¼3¤ÛNÓN-%EžkZµ*nµÂu÷“*«/´ýÇ~eX‰¥•?Øyìû7²óý7ÝêQã¸_P¼Á=Ò~" Þ T¿Þ¥›Pö’:êCù%¥z²\!}¯ü;`¡gì#>ª0ê=æ>9“W²ÚdÖJ%ôdk¶zš)œÝÕaî³QÔ¶ÎÂO[# …26éÅ *ƒj¢ÕÈ»ÈúžQ‹vÉðz"ó6=:G}ìŸÒvNùz˜n>i:ý+Ño49›‘ÉÔÄ¥³ør 󹢜?£2ÔÓvêþ¥(¸@•ŠÁÀÑQ OSè4™ŠœxyÊõ²`xÐ'p'Í—M *¡í|DdYytDï¢Ý›ÊWcP;u·Ln¦ÓxÙìr{ü {~|ÜüQm,®­Wõ³¥míÅ·Uo4_7úíÖÉÛØZßÅÕjµû§ç'½f½ÖíÅÕªìÄÕjž½Þï·{¯pD½Z¯q|~Ò¯·[ÇÍ—\«º ñe­ÖÇse¿û@8o…šŠ .\¶Öz»P¶šP62ˆšÂeq*ñ°ÔèÄ!Ç/ÛlÕOÎý³NCÎY%a¸Ç ¤£“·¤Ô !™aͧÄuš³3êl“e?YLc\¥â«Sc />cL&?`Œ•ÅWG—ƒÙâS²½pjb³7èàû'”ÇÖow`É´cûÚ’úª¾Rûª>ôU}ôU}zbZNôì.©dKt@Ʊ§<^PKp¤ÑÃÏhŠŒè~÷å‹KWFøñÑœ]´¢QXÁÇÃðó36™;v„>pmÄvjÔ‘ˆýÏgÐ#Ê—ª>=’SžõÐyÉGŸs¼EÎdšèã–í±°}sb_aÇQ÷Ûgb‰ŸwãÆÑEÅô‰qeLšÒÛ WÉ3±®‹¡"8±>oEªá"Ýù…g€P‘Ýp‘ÚŽþ({(èø)ò8\¤íŒáèñ‰¢Èwá"/Ùt+¥bªêû'ד Ca’‚Õ…dœ¹… þF’§‘í]mbŽ)›ûí X¿ ?+¶Ï“r?cËÁcŠJ>kôá³6Ç?)z³Õ2>z1rŽXu$ÑDøƒ¦²Q ´þ4u•Šþ:ÐäBÁ<&ºé;1Gj;x쯤ÅW'è’<þ¬%e®ä·Ë§Nì<’©‹öfåԅЩAKäír´ø›ìŸ1‹ýɆš…úä,¼_Žž@®ø‚øéä)eÃÑ"€’ ,Ç’§þXÊHÁ–d~ Ξ  "Há‡+˜Œ4–þ¸hŽšÖÐø˜–Áø=ñrVUëhÂÚ·¥3^ÂO9¿Ò9º¬»ž‚¾%¼†«Ô¬›%UW8U:Eoø%Õb¨žêYn—üìÕzoh¨øŠv/õ™Á¾w03ÊÓcÇ„CùäFbåÅ[ØÜÎ.o\Shð»ÓÚ ‡Í“FëeïÕ{¬Ã³©Ld„ ùë©7¾4G¾Þ!$¥i<§ž]í+Áÿk[ 1þûÊþû( Å !´1õG÷I4ÑE>O§åˆ*9’ÎÜét3ò”æÊKý¯Û³!ª†ûä!»ûïvïìEí¿÷öwßßÿü1ößkÜáÜ[†ß[†ÿ-ÃÑÐâÅ[RµíjÕÇÚ¿ç“"ðëðÏC#ñ¶HÒ… ©q(ŠM—-B)‚@6sp %ßh +ìÀÖ*ùFÒÒÀ𠙍´á°´mÞÚÂO©Œ§#} l¨E`#Wš ƒ­ Χéc´Rñ’Dñq0RÀš…{ŠY-Õê@-pr/ó"ßXY±02ýpCÎØ4Š÷$-!…‰³™tÍÐÙ„0$bœeíÊÔƒ€8S[5Ý©¼BtÚmŠ1»¹¼+b¡Ý³x&M—G¦AÁ‡|s?tüë‹·lôWˆXR“± |T ¡}Ìuëü¤„iÑðcS ÀŒšf^©>4\ ]Œ§ Êi*ì±¥Ù)|A ØÍ%̹úvZ"¼5Ù÷hk› æ3Aí+˜ E|`ÑÎl#;ˆ¸,0M†GB£˜d8+9Ê:O‰¢yLÑÞt¸;0i-R¾x¡æâ†lø°Éó‰9Rº€Vo¹%Vo> „ýZÔ|­öºÖ<¹ÚspXc÷_áµ[)?.ï%X¹…®°u“ïÔnG^©,_©r/}¨ug†5@ƲŽ[C¸»·‘û¿ÌþOK꺽ðŠó_uoçqôüWݽ·ÿ»?ÿÝŸÿîÏkŸÿÈA¢ý¶ß¦CN—½ƒÿ=q¿º³ó$zŒ0=<ýñ#ß#·\SŸP.PÎ%N¯¶_Év üp#ç…\Eïdëx䟗yÁ‚Èó"&û ùg9ñ:ìsÉí†FµŸ”f‹$,“'E9%á >Úd쀲™l^E‹ïç+©%³ 9¯àÄgÜ‹8w»ÿáÔ5ú–>óœ>,ïÉMyðEíÿ«"þÇÞ“ý=xÌúßʽþ÷«ü|ûýïÆ¿õó í•c2>hO¹¤ÿrŒ!lrÝùù½ÿ½ÿŸ;†¥Ád_¬…î0šŸˆõ©e`*FoÛ´(˜[áGj½X¬4¼H(_ëœÕ(ÔX¤ŽîÌômljY=eºN\U¤×p¸6¦QJlø/7V‚Æܵޒú¨<ÑÕnFPL­„‘>´bŸêžó¨ì $ š#`\˜ Wˆ¤ŽtͶääGу¾Ÿõ:¹¿Kk\ñ@Û}Œ7¼Ðm’eæ@0­¡ýò/œs9x‹ßµâˆ'¨ç..Ƀy*Ô­-þ$\ȱه€0ì9&ïÕ-ñÁÄkùøž˜¢¶u5ã<¨Xݾ‹šãôQ1Làôô ú‹)Þ³øÌ|]ô3ÒyP‡Sÿ‰ŠÑÈâxø &ÅI_ºä¥/=˜;¥£†9íž`™iéˆ`øz_¹eœhM-.›dX/1˜ ÞŒ4œÕpÂ^Ƕ§ V$üРpg^{ª½¢¸ŒÝÿrî¡Q÷=©áï™léØð—RërwŒ³o¹×äV=·¼ $x¨9AÐs4…6 ÿ9ª·Ï[=èt›2Å r «µ¢Å°óâ7ϴʲž‹¡JÀÏ´˜Ò­öQ­W“Ãl|œñ¾%¶,HrÔ¼¯¹Ì™6ÓÅ]’|'Œsà ùÖG1S 7¾C:1¨­¾p‰¦¥ÀK“–¥öHÒ4|„þè¼zý™+lg$°Cßâ‚ßÿýÑžËbs\]Údùº]-/;ágóMBµF•¹©g‘¶ì"?34Ä6I:χ²8ÆÀv†Z¾Ó)ÐM&´"Š4œ79m³ T+f¾|ûm¸ãÐÆ‘Aép^:\âb6_| ¨2Õsú ,E™‘Ën霨ý‹Éÿ+óP+˜S!‹¹ët–L[´T1“´´‚éŠ5Øéô{oÏ܇`þ? ÕOjÝîb)$¿ z†KÈñú#‹µ€òe† ç·‡v¯ ‘U•ÂJá½ í¾^oÒ®,hÔ§ìk€gZ¤#ôSóùLnèñ݆Æi×& 5çc2"!0Thš®ÅUvSÜxÚ8Òàýç3­ª}Ä­´²Û…ÏDÏ~—•nóð$œ{ï·Üb6ôå˜Ánâç5¡…ˆ6¥¬â‹^‘yà‚P8›!âÝô‚d0ÀЂmU.Þ)iyH.˳z Ø:Ò/ã¿ßiœ¼ å$G,|Ê„ºÐL…„p{ð°¼¹ \é¹e|ÄmQ•$’šXHwWˆ:i †¤ˆ0#®Ä†7 §³J—žI“Ó²ƒ~eÿE³—¿šE²Ë_ ŽàšŸ {”÷eEd_¯yFŽx•xKðqÜDÝØžàFöµ;p&²C¤Ý%bièJÝî¦"ÒÉŸ¼—Ž1†òX'‘k®îâl¢Èñîú©îLG6JóT ]¶°ñ"ž`z†ˆîíóFErÒŠº%‡DA+§¨@bí–;ºÓÉí:8„‰žâ(}!1·Lz»NlÁ ³,)bš ¥7[†ô.ËPú[.Êj‘ÕèŒHTËDä[×7?ã„N˜‚†³Ò l€vTžP¹†/d.Ù‚fh|ª-º˜û|oÇBÿßiœ4jݦÕmtïT5¾,ÿË~¥ò·Êîîþî“]z^©<~R½×ÿ½ùÇìO¤ƒf:Èåê—º5Fk<ÍFO§Åë¸|!Ha%´oW3nûadËX„-ÛÞUÞ¬ —ñ‘5{”ŠôÒ#Ì8qá|24ѲÙü¡Ó¨sCÇÖú©þ€í20kèØæð@ë²¢œz0´)÷“k`’<Í%íÝUèPt¹ˆùÕ*Ûä[%*“:í.g UuŽëOö¿Û/àÙÜ‹ùFôQâ¦ù£È5‰ÍÈíÜeºT]ÒM@TCJv›Àüì…ïªÔW‘÷@kNQÉÍYDy8øy”™Z" ”nõëcTàßhïŒcèÓªZÚËzµß¨èwµwûŒ¿ÙLÄÃmž]í‹ô¢Úì¹èH€f~{ˆïX—Þ0ü‚%ÑMÊ»'~£~KƯèù´ûºÎ)çt Qz³§½ûŽªœ9Àû-²m¶ÆøÎf(ÒNŒ]/† ôt>Ƽûž@¼ÒAf¥oÚtQ/ ðD|A2 ¢w•ªy¤dºC*×™ªp&*L´òr /zÔ¸W@ÿxÉ$´‰ äÎ'5vÖ+?#':½€ãnxtvxWáùÅUEw%’ѸÑëLȪ[° Žm!9`J<áW„iÏ&~Š<Óьш'ŠÜr>$Sí_úÐâ¬Së.-ãÚ5@øzHkÙ ‹\ÎM˜×àV]|f„¨Æ>Ò¯L|é]êÓ¢ö¯Ñ }8÷—SݪîµÛ—B7¦º3w' e¼À)öyÎãG¹1CÍ¢Ö³/LXf-Óøÿ¿Ð‘|¥tÞv0½oG?8€îœ‚ú#„ ætß„9?5@'™#·¹@æMÊ(»Íå·«Õ.»LUörȆ²TÙÁVö²Uy’õœ¦Êl>™@…jWw† •.ÜÔ*ßïæpÙf¨€]ú>Kì,Îô5¾C4UBsÉ7‹Ùrų’ÈžŠ©Å¾+íìmãv]v/½é$G«s(»(™(£òýþ–®&,ÿy†ë•†ŒË¹cÑèÉãÇIö•½¿UªûŸT*ÕÊþŒÿ¸ód÷^þû*ñ¿Ñ¶a/Øv/s4eúµ’HŠÏðvN_üÂO‚Ì„äø ÖÁniçI©²[®VµÚy¯ž˜QãJ—ÌžvŒÓ®¼ß?F/ aÙдåܨJ©ÝEs¼ì§³¬4 8äÜÆ:úU¬CL7†mŒÞMæ#Æô”œ×èCã»$¼lk/EFï32‰ÐN‚$Ød$Až†ò$túPfirt•âäæ9C­# ì 8†¸(?T5±ÐI\b€wN?ìùÙra£Í'E€€¾Poš½WíóžVk½ÕÞÔ:Z«÷ö0°‡¸aÖ£Öhqñ@;mtꯠ†pbÀþ7{-rŒow´švVëôšõó“ZG;;» %%ûƒeÈÑt8†LÎc~ ó''¾P5PØPÉ“½|’AnbOA!{wúi= Ô¯¯¯Ëck^¶ñ¶Èvîn?/#™Ö(¼2šµ@3p41hƤÎ&¹äðs "6J|îA:ÒáÌXþ ³ Öê†ÓGÒù’ø\›cÔ@k$òsë7þùBÒ· Qrb ò0Íûù’ÕÜÊÀû=F4¼”ÈËI‚”ùÅñP„}ebÄž IOQ›á݈!$2¢Á1‰iOáCIÅþ%0þ)ÊÅÕpÎ!KB§²\I<öËS?è¼7·`ä2<¶FDWX(áÈ9­KOJ-r+2]€riLf8ÁÛãÌ>tÞ sÚÍÌ.9Æ„Ñ ý/ç0“yižËÍ]}lôY=–gS cpikw´‡[ÚóGUʉ ÈéSañÄøSRÍ}ÎåÔwÄýôi£u”;ÇÇ(ž‡Øn‰¾áè9®–J{\™xvVë½ÂŽ|\@¼+•=ÆÀ+‰£É³ßn ÷wËþüß ì‰íP nð"„…ˆ,]b–C¿­Òkt{%6CÖÞ)_JµÎËóÓF«×}O¶É›Êè6‹øUŽm“ÄùÍ`p›¾Q2rZ8` 1ÙóM9‡˜Ì"Òi>íÆ©Z˜a^Ë9€Lî«Ï4(ð†í0K½.ÒÓC„“ ä1Íߨ  ËjN‡‘"R­ëÌ‘3æûó–#|÷ßð•ñÚG¼ö^o0x:p ÎÃZiìáMüÐ&båõ°BF|0óHÆ•à™Öþóð ˆ=¥ U%¬‡¡íz#ZÓŸ—‚ ö!läî¥9òD!9[ÍÇn´ˆœ?#Ñ-¢!*‘ E †)¹ Eð»P|j¡Ê"Æ£Õ â›¸( ‡[M]ý¦ˆ È4y m>¬lnPQ Š W ! Ì¡kq.'Îø¨7sŸÙj7ú8Þ€sÂG¼Ó•Ûx¨~U§gÃ!§`CKBN^AÎPZrn7r˜tHQËlàµÁGÊ+BaØÙ×_ÐáeΰÂ@s#3ç·ˆ ÄøH\#R¡"S7Dê*Ä#†¥çCy ý€iÛißFíá5`©bsb^lëppC#†²>=x˜×§ý¾çÝô š[Ø,ÓÃðÙæÿónçp·2Ýht½Õ´±c‰ÇUzüäG4Õ&czQ‘/NHBËד¹x½G¯_P M›Ž%¼ÇôüÆ;s™ŒŸ¨ðh-›×°%¾µÆ.R‡¨qj‚àQMÂÓÐî#Sx¶éLµÒHó)Ló)åPË3Ûp½‚ä ®·‰™ËfÚ†ë=«T¿?Ô @ZEy³»£¾©*oö*¡:»ê«ÝЫÇ$šÌšÂÌ-2ã.ç6þ 6å ÛÕç*9ƒ¯šž=ü§B‹l¯‘l\¢€¸CZûþ{ŸL¼kXéÔ@+¹Ñᕹx¤ÈÁÃ0;c¿sTI\ñÙCôÞùìÙghÒ1’ nÚåcüDLgç` ƒwS˜_ªCUü:02QDz©Ê“'T‡ª!PŒOWE6óý÷A ªÓètÚ%]ÛR†3u~<®5O–´³¥ G¢€ª$¶C\7÷@ª÷ýMöø=ec{¢U1©â@tâÂùÀfáã@ÀiÀPÞ 5Λé.J"6à1êEsÅ’ ‹o–ò&B",úÇ/¾ûEp˜¸VB§j°›ó)c`;0ؙ͊íÍ2¬: Ž’BLF!õA¥ò]e¯K›åQTq[ŠX£‚Ì|Z.ÀÚ‡‚/‰&Ï&3bÓü À¿Á,|~øÀ‡ßÀ'>(íl0 ¼rPÅ!ØÓ&‚xm\é˜~B‡Âç½zä-œÌà¹ÐÜà»<¸¿5ÿ¿êþïÇ€0¿€jt‰þw·ú$¸ÿߌ÷ÿÕ'÷þ__ÿûÆAóP‡ŽÒ‚øþup çQºÞ$M]¾Âi} •ìÍ8M0Þˆ”vž”wv5Á•ï¿ÿž.OVj‚¡[ìc[mÏžj=v«í©Gÿ5¸[s—< ïÕÆ÷jã»V»÷zã¿žÞØš<ÛÌmbÞ¡Ûéh’ëé$˜ZƵ6!óBVL× [< 8ä]¥ýgn“Š˜4ÈžÔ ݱ0U"ã %œhÙ¥X&H«Ø$ë'ʹæq÷Ù†¶±ñ÷‡ÖgÄP¦åêv£2ôýGlPÄG؉þé†X§…þ»@ ¥µÑ„zó¢jQt:rœòp¹˜¤ä~HÒ+ÔéÂò&˜(|r#Š]i¹#[ËhXCƒ£ÌdF"˜ Žý-LWfÚøy>²L§@ÿ²ƒçí¤öß·h¤ÔæäæO/dÑ[ÎEF,tã¬.¬øŠO¦#‹´ÍÛÚïÚö»o¶ßÃéðœSpÅð‹¦ÔFüœ·ê’Ñ·T¥CIéœfüö6ÄþïÁ˜úÕ¶L;¿`rvs§>ý<§#VÉý;öwM;m¶^¾Ù*àGO+:–^óC8¡ÂßúÛ—oš­Å‚°}]3$Yr± 0‚BÉÈEć_Tc»ø°Z¤nƒ§E†Œ0¨{Ûü°þó`:Ô¶·ëòŠƒP¿8ÇCo µîöÆOùòÖOxºõpû§ÊöæÏ! îfL¶€¥©°~Woøµqt¡ºø€+_¯ª,ü2ŒjØÏþÊLúCݽ<Áÿah:òZi0á¼À”ä²£öI³õÃQ³“ ×–D&݇•\„ÐX°á+Ž4M>{öP§ïLâ¿ *ò(sb†±ß†#µ²Ê7­tÒ|×@¢Â '2/2RW6Ð6B)'“2üU±*ûƒ×(ü:­’S\rÊÂñg-ÔNÆ6²À‡²TGOÙ€_>¾ºbˆâR¡FX-™ôòªº[´ô …HçZœ`‰èθ\F1¼6ü…]ãè`À¬ß¢˜Œh¢Rެ-h¥$wŽŠ8àS3T¡°â$§Ð>ÝšàÜ?;ˆ¼ '̃îW †hè^›ðàY.⯥ܤý½d³ ¤'¼yÀs 0ôAûå¹åD±MÐxäþпò?çö*ø©j’Ÿo•mà [åwvûý»‹ïßýòï÷‚¹Çð‘ê†|…7Ð5Rg—ŽmÁòü—t¹ôwŸÝqK™Á«ÁLºÔ,„†ÓŒæïyjCM¥¿ †(x~Òo•¥æçÌà&1ô¹˜DƒЏm¥[J}ìÕäsZ 'É9ñ;Ã%›;Í|С׏%Z'#©[¾3»;¬“gTž|¦âÈÌîÀ`¥›.nR«¨ÎžècbÔP“®ÿ.ÙóÆCYWPIò>ô¡P)bI@ý‘«…ñ³°‚*`û•EÜo•a‘⪫×éÏàãGþúã¼õ÷èØþ÷ø­Ü¦›†À´X Žš‘ ­Âv8šlM Ÿïö/ûP‹[bsœŸícaã³ýwܼˆ“Ì{í¬Ó~Ù©jïj—Ý÷¹Üš3Ì{…ö06â+Û›|’D¨EÚ|dCBG‡å)1sòrÛåsîðD¢µPh¼[ÄKè\“ô t¿ø¦ð)R‡žÚfZ|@%¾þæ¸Õ¨amÐ*ð®x ït7 H†2ä36›­n¯vr‚šAqÅ´ü€_Î!úýézøÏ\0[W4[Wb¶˜,ä ELZâ!€«íÝöO?½§ƒIhSy&¾b*cS)ÌŸÍHqù»•wˆÞÅýû‘ˆÃÞˆ(A‰.ñm¥MGÜ€ÿ䤄CòÍ2éFÈ6¾dZ>øCÂ͉6´®QP'4#j…>n²câ8¨As;ài@nPCpô° $Å (%Ä[Å{Uîk+ò‹" ø§à¿ûœ ø0ÔH Âߨ¡¨T(¬,$¸%ñ3Õ¤'tÖ³ýóiðŒº±¡—V(ÍÚ(J»k°fÕBó4‘FóŸ›Ö•ýÍÚ/èe}¹œ9L×5ÇŽ7w™ñͲeÍ£N†p²-•ü5Í ,ä’1ÿ¬4ôƒÈMl²‘lŒ”ä—Àa&†Ô‹ˆM  ^è c œ Ž}"þ mh‰to½ „ý¡¬nd$ñ@k‰ v Û<,èje€ÙxF97`úYl1¤¬Øtÿ?å­w?ý´ýþ÷ß5øöN/}ª•þûþ€¾oÿT<Ü.Û¨¿@õ|Àc+´J¦†hDãÁŽ€ŠÏM\þåÒûMMj ËÅõEøóça.¢6•<ðK zØ÷MªQaaP~%M«nŠhro(ýXï.y9@âuÆâX9n õû¸ñè˜fÉÄ1j)ÇÄdbL˜ç£aä• òl{¤êù]ö÷þïãÍŸËCi¢èÌ a™k`Š`PP`€Úóí¡qµmÍ'2½Q¸–<¶òRš ©U…Óí¸ùãiã@sPYê›ù2’¡Ê ðÁœL\XÞ5R·KGOà»ea-äLñé¦ìͦ0OYª¢U…åPgn C ")¶Ê‡YÑa]`%°üáã´DÖ³ÐÊŸ^)¯ä‹œ1 Aü |¾øeªò*²úÚ‡Žk†ÇÌ@Žw?Ð[-\@³F åyñä²Zع7[øÂñ'¨ã/_ÞíÕø²øÿ»{ÑøÿÕêÎÞýýÿW¹ÿ‘2û}òŠ?9iv)§ˆ—yœ»ƒpÁ÷1ïcþþ1‘‚[Â(Üôéf`:ƒùDwŠ€tÀÔ ©6 º Ž&Bâ×¾…õ â’·ðzø0ö%ÒæbØÿ- es˜û|˜Ëi8ÀUÁ`6ù(Œ-M„Ò‰¯ƒEbêàï¢l+ûùçú¦Ë5éÌ»IÛdü¡šqÍ×ô)9ðí"r¶4{2¤O‘ÖÒ“ôñ ”Øž¨äm ó¬ÿ­t­_ÚþÜÝÁÝoKöÿ=øú7´øÛÛ­ìí=/¨ ´Šÿ¯>Û‘îùa»Ë;ôëv·iÑÚoº»Uñ’ÂãËã^ÿèäD<íž¿ €Û“\îEãe;þâªot)å±91šÖÈF½,àþÿýÎÞÅëïƒ×ÐNí伡mÔ12–uƒêÁ"¿Ù@obÛI´“‚¶ü„ƒ,SšÆŽ¬ÈÀ+h~C4{d`0¢.Û«œp~ƒÕ-®'D×CÔíu´…ZMÌA`éeÄ¢Õ…¢màR&ņ,.¾A›øM_hèŠÄêQýiÇ GP«Ré̱‡ ® …¶D5u<)sbŒõ‰¿cR­ÿŸ¶ÁUëí³·æËW½¸Šlø+{H½L Yac\ÆhBú½óï`u½Öø¥%šìçtYÍÍî|„•VÔ*ˆŠ á¿{ø^þëÿº50&·Oû™:þgeoAÿwŸÿëëüÜçÿ¼Ïÿù¿™ÿ³^kÕ'˜ös·„ŒÑ`açÛ‹&þdn‡ù>ëüIÁkÅlž‹©<eÊógþó§QS|L•³S€ˆ¤êä§.Ñ%[j»ÛŽAYqÐÅfè_ãäú‘S‘öü(¤á„žj§ëq­çØü€Óƒb6õ }€¹í”]F&‘ Ìñ²}µH¾òä #œÐs8ÿ/:"ð.OÌIãH+ãè]nÀÕÆ¦ˆ°´§Ìû¦Ë˜åH3NUØY–9²œ 'éÿf:~0vrqç˜Çoƒì,Ìfôá›´ŒëœÀ¯ôãòGF+T¾$o:À&,Oœ° CLÕÄÏoŸ°óÚ ¬Â8Œ'¥GEý.ç>•ODêV?!*ëα㕤4ÍвÐW1´³ÿm¿¼Ã¡tÖ‘C³æO™š²^ó´Ñ>ïU¸&·HœO%Aë‘é|€ug¹Œ{!ó¯$ÿ…ÒHÜ…¸Jþ{‚ñ?Còßîþî½üw/ÿÝË÷òßÚò_ãdzZ눒—¢XÝÑZöÝnDEÀÃCIP¤)Ô1•Í&Þ°0éÝPãÙ²¼û·­áì<± ;A–Ma®u¬Í¾K e1q%eÇ6ð;t—¾GŠbYWBü;¹¾‹¦¸B¢`Šåûž $Sv’u“0E0N‰½kÉ'½ž; †¾t–+7eíJ‚,z^cÓ²dv4† 5 —MÆE8ˆ˜&XÀÏг\ Z²ó<… 2B£w(;B_5ËàçÆ·ÎBÄGÜ:È>lŠybÙÆRZ=SrHÄ9h:’“ûóÓDð¢‹nCÑ£"ÚnŠ|´€G–uDH¼õ£žŠ¢äŽwqïh.Ë×rjbˆë-%@é%'fII]X C"IÝOÛ¹H è)ÄãPÈ ¡)ÚSÁâc§Ñ;ï´X…ÙM @ŽßAi~ƒˆ¡á¯ô %(÷ÎÐô€¨Ù€r 5‚lL_áŒ00Œ!ºOD `‚¾n¯CxTB‘{ªOаg“ò0ȤG­IÉîr§œ€êšœ7.õ¹KÞñgJ±$š•§)uÛ@O&œkNñÄ´skÈ}´® –w(-‘ÿöwïFõûðú^þû£îÿ¿‹¹ú× Lh} €!oá†|™œ·JÆãûçx1/£ˆ‡ ë~ÅÛÿˆp‡°2ÈwKd;ºjOï´ô²„Ä»¯{÷¿!3òÌg‹IâW¤W¯‚ß4[»ÕFøF>:íµ»…œ4÷¬P˜£yW–}G•;¶ooa¼Ê-í¥áõ€çÖ1QU¾@®.Wº9¡mæ¥äÖ÷ã­ó;æÍ÷µùŒÁxè0x­õ·¬uh{ƒ-ÅD{l=#`g˜è3—bOâVKiCÝØ)¦@½¶Wd0ðÎA=¨kaÙ°PÂ]ZM€>Aí½ïËO4l‹ŽhtÌ¡ {@ÇÐxñèM»sîÓ³Èð±”.{W0Cx*½­U€;*eæ\(*õ*Uê¥ÅnOÝÀHä\!'íUíu£_Ç;ÑþËF•UýÓv«Ýk·šõ¬s9@gŠþ¼Pœ'S0’„ ½Ãz)µ-ã¿c€†3X ËZÏœ ÿI\Å$gá{Úy¡"_3=Ñ’!.„SÏ5U-aîm]€ðMcf.)x˜kO N¢ˆÿ>IÐrH÷"/¦˜Üžeá2˜H$Ãb0¢ýKôûÂÊ€XË)FyŠÃÓGì@|*„íó8@ʯȜZú ´¢û+)%†NDDCûøŽFÆü NÐî6I§Ü)ðÍdÇtÇõ|%Ò;m‡ãZžà¥°ØiI]›.I9ׯ&ˆŠc”}á³é`ä¸1ÌêOu º2¢9$oj]lÜ£ÅB"‡6*æ˜q©ny,ânFNVËGñh\£f òÔž 1¢Æo¶òTPàºDïÅ—ÂrÁo™ø¥æ¡bø­°ÍÜÒ_¦÷—8ÿ—ÜÿÌtÇ5úÞG¯ ¸on´êü¿¿`ÿîýÿîïîïîïÖ¾ÿ9«uº~ïÇ^¿Ó8;yKw@O´öÀ³qû»Š0>¼ :ÃGdD©’ñ:ó0 ³—‡E…6ּдw+´¥-¹éñ¯ˆ’ì¨`Lt„_™xõs¸ªO}qï´_±ƒF⺖x-Õ‘špg7´ -¿ÿÛ€W…àþŠJ¸2 ñ̶8B޾8¿œ¤CÏ©N¡yLbL ’(1ü;¿(±V¾@ßì`›˜YÝŒÁ÷¯0nÇÃÒ¦¸Ò‹/©þ“#‰Þ=)÷<þUSnÊ·|Û©Ü6QþQ\Ø@-¹i“¦•sM_¶æ«¡MWöÇ 2¿S@vÏï1ÄŠ8« øNÇryjÖP8†ÞYt3#©l/¦Ó¿+¢ë¼_"ÚF$ ¡ÉÈùµÃwH#Ó˜ ñÉåÊ€´o÷,ZØñëJñ޼ <ýõƒ«E\Ë…žóu­‡¥? êGvDh û¶#ÀÅ×|¾^ï£OáŒe;x{§;±céerÔuÚëšqÝÊET(Ní(þìšÂ€MNÇ•ËpyƒÝá:F¤ !д澞Na¾M{îŠêeZKêê—›i|ÿÈ4ôª:¥„w9Á‰ê3ÜÊlü:‡ƒ,Ž ÷µS}ÔçQ=wEÅ?@ôkZ–¨ÅPmh¯H)Ô‰+Åv8ïkI-MñþSwVƒ²üÈ‘bÄúÆJbB\Æ…ÚLŠºLÇ͉“P$™ŽŠ…ñÄPf·|´jÔ¦È3J3Ö?*3œÒ,•y;È_èÑO1™PõÉ8‰»c¾ÕvrËË螺ûPH-¼}vÝÑ„Ôjü=4ü=[¬-® 1Tì]óQ­W ך|I-¸ÆsÓ-÷š7 í†Ùï­k¯kÍ‘"Æ<•U2ÀLÈ +d©*ÇWÊOÊ;I—à¼G‡,c}ƽW2ˆü[ÿ0¿Ð^9ö'ãƒöô—Kúð/Øé@ö¦$"E¤ž ãðˆsÙž½Ò=JF¢)y„ƒDU5†l÷{l T›Öpî9<á×™ü5®…3ýæLŸ ÈŒ3ýf†·ðÐÂpþŸ~¼«ãÿJÿÿjeáü¿S½¿ÿ¿?ÿߟÿïÏÿ·<ÿŸþÿ÷´Ú|Œ!ì“ÿ’ë¥>ûŸþx«£¿lïnOت€'[Ø"pð-Åé:®‡™Oͧ?Æš%PåµS/ãò–‡^ò•μþ\ÞâÀèOßýƾòÏŒš8bŽ!þîS¸{‰¡‰É†…É– ²¼—¾¿¤ô]½ké¶èévÇǧô™ Pþ55&æG ~Åø§ðÿ'˜ò%,ůaÿ»[}ü¤"óîUï£ýý{ùÿküloiÑI‡-ô¥ŸAP$¸VQe}€«#øcl@J“‡–™åˆc*™#Ž3¬wn™ÈK`­çMFÔ ÀÛ¦úÀ± dO4§ø£µz¿vvvÒ蟷š€¥vÒ§=[ÄkâPæ#ê0îØÇb¤vaŽI ìSX©)°‘a¾h¾¦yÔ¬µ$m³~OÙ  äu?éâļ̉…ºÓl½ìŸ4_ÔÏ;'ʨ‡Ô Ω@2æpÝnó¿~€œSrHrÂwüÎqR>aG1àÒ`vàcûä5ABjѶ o° Øó8'F'òFCD£Wï7[žJÍb &yÖæ„Uš‚±á¡Lƒç47/°áu{xª ÁÁÐ^V“¢­= º"A#XÌh`1¢Xÿ?ç°<teE_S”}­¤|Z€Õå]m¤ðý¬p÷öWôôIVˆO`WXà²d˜jùîeØ@Å 7xœï;aÀÝFçõ‹·gíN¯ßA¸Ý¸¸¤¤*ÜÏ0³(úßgÿâüWM‘Z–ïjÇDÕûêøÉ¤R¾XZ{GØ™Nëαó}‘¶ ²sV# *:Tœlµÿz:ø8s€…~½}zVËÜR¦&ÒÀv1îJ¨]—¦¯?_˜ž5˜bj#±U,ÀzÑìµê§gq .làÞœ‘%0,ÆU±¤ Ì»·²;!ÛìàAT¾4¾sZH0ÇOÓ$ìœÐ,°ëDð.0ùúÕc¨#À.LØ > ì~ádu—mË¢´‰ Û­V£ÞSeqé'7ñÓò^è.à´þí·• {úÇh?þX©¬¦Ìád4°VæÑÉq½•†Î DZìUÐN«tÌ›$£ ºÔ[õ§eU—ÖŠ.éÚµí| u¬Ýoµ[boyûAÉÕc†Ó±>:¸-Ûi4jGG š®Ï°:WÃ…u¸ ,v0ëµÐo×ÕGÆ2¨ýÞ«ô¼[;n¬D´dXWK;Ûh½Ne°‹ìöRh(“½x‹]M”Tð«’9%ÐT Ó”rÍR€RÊI0$s,ªŠ «74ÕWas)ÜÀIe%PsÔÇ”5a4,ÛD!çÎ'í•xÕµæÙÕ¾Ÿ¡V./”{úøoæáMTbC(õà¿3hjýv<{¶ª^ûlmø)ư²ÿÄ{á`‹r…»Šý6[=°»)6Ó,ÛšízŠM€¬’TJ顉3H ìÒCÀÅÚ9nÂþÒlí¡}U“}Q+eÓ*ÎÚ[ÖØͤl`-Ð]¨ú²yŒl~x¥èjf#4›¾&"_šˆg…ø¾úa5:1§¦·r 4O›=¹€†#7žœ,TÂ_›#öäpÒn½Ä+‡7¥û¶òåÒÁÖN@zJÁøÊn´Æi»ó6´ÓîKܺ͗­Ú %@^¥”X=“À[‡«&¸ëÑ‹4²6@Cn Gî ‰i7[YàzƒYZÀ½úYJÈÛæ(PÜ—Ã;KÒWœ¥ÕW8Æ`‰pÙiÔ_§Ašï¥`Ž;íÓ• \ˉ`ºÐ{%Ù³=ó–ê!WnŸõRòLh7Í'h ßÍpìyŠÊ`}å1Z¢Úäu!Õ½q·é¤´rzßvÅ9éU:¨d´—êY­S;M Õ5&˜T>Ønã¤Q牢›n_C¸é÷6„ëéé öj©aRH0é’%-Ì4ŠšRsCPç¦æy3ÍÁÓ4ãN;æ¹eÂÆ¾ Úy« { x×ÇkÅQTäÎJ)²º ’c5=ÄtÓÀsLÏXr¤zÓiö«U×nNžælU¿ºU8u6#çNS³eO›”áx7x1‰YÞ] íÒGjë5Nûg°U5:½·¨aޱ@Ÿ]ŽëJv””vd@oRÉãraØ{Âú³ È4B žôúíÿ>j&n;h¾›¨Ñ Š@EÖNòq„>ÎŽÐÇ«ib?}×÷³t}?{×÷—tÝ·OžÔdºžw½×©×XLFCÉ¥ ª©i<DzÚN±—»ñ¢XÕ¥X€Ì€Çd\v‚Ñóó?‘l¢/ßÏH›…0ð^·ù¡§6 e¬£Æ]„:vŸ¿VSÍ},ˆls¿Dº¹_ "ÝÜ/‘iî“!Ŭ¨Eá¿Öê6µº*—†Dh8z| ²ìÕI°ÐÓ Í&7šô®$·ÜÐAÅyzT Ãâ›fï•\Ž434] ,Û*] Ù#]’ª ÔS´1§«Ô²‚€{,òÈ*FËR¦*ŠMëœDnîÙSò ÑIé&8Ì`(nuÿ¤Qkõ1ÅÉi£‰1šÉáýÂ׊ŒÍÇ›kÛrlÓÅH´´VÑ!X·@¿ñdÍüÄü`h§6Ôµ':¡»{VëÔ1é½Âd¿±ƒ(®Éþ4¥T_qÓè÷á4—Œ©ï8,%8E(ŒšpA1Ox!ëstËEšƒìSµær0§g1˜÷óN½= 6,"© ¬G ýi¥I9†àÖNõ¶ñ£VÙ)?.k¡FŽj˜drhØßC“ß~³Õ>ÂB’JP’o¿-Ÿ/ЫžÒŽÐ™Ð\ã@h™&O7ìaãâå É*á“èÛow=l/´N‘Cð0ii`À\Éõn&7‚uì§A£ËݘμDÿÏ佩ĥ¶-ô­ÄBÌMTˆT˜@õcqø0e\A ˜©Žûûþ/!ºð:×ÌйͯéåÏj4¤MìnXµæƒåéRA²/LîOéÿwÒ¬7ZÝFy:¼k׸%ñ?*»O0þGuwÿñþþþΓ¿íTà[õÞÿïkü<²¤SÎñ\NÉ2 l O´ü©|W\H B›Æ”"ËÛÇ™°Xü®aßßnŽt|*Ô5â‹äî&ßÈ%á4!·Ï4¢Y/HR‘\Ö#IDrÙŒ, ²nàø !¹UACÒ ¹÷ÿŽñÿ总_‹ÿWvvwò¿Wvïã?ßǺÿtÿiíøOÿ9ot8êóžöoÌß‚„úÄaL~*m›ž‰9ÅeäÉåøF´ùAŸ²Ez–‰¤èÔò["á7§n)PÖ NâéŒÕøNœ}[Dxú»xH4sÏKî™#ª {䨧a,IQ_¹F}ÐHˆ~æP~h¹ƒ 0µI,} “€‹ÏrH‘¯Î=ʨ<ÒÄD¹ËfJf¤§u„ŽM°srÄ@[–Gi–d$'ù¦A…q“‚’”¡ó›“ÛT&ƒDí hXr „‡Q§&ú…1Êa_)º‚ˆVJb´.*Š¿Ì|s. ûÒ¹FsºF€ü»QÃè3c(¡ø5D$¬p@-9w2¨ΛTkB)à‘ Mb0æ öGTòu6È^t½¬Ë¹72«C€¥Ž7‡l`G:œ†E‘Á•N!ìbAñsMëÊþ`ð IŠ*ÃI‚`Cs„õ•ƒçRâ%s:5†H/˜ÌÇÆÀ#79ñj8§©B|z”Ät‚1mƒxF2F3²àùÐ@39 ~äGÙ :¨æ³…Ï9õÌ”¡T¼ÊV*tHs[NÈÜRÑh \_œÊ»Ÿ»籈š Ø=ŠÚ¥}QÅáÄjs~ˆáÕq³¾›Å Ê9†Bg•£ÕàWÑŠ°?i~H2ØT8–»ã¸Ý9mt:‰@ØZÞÁ°!@ËæÔ ¶T.~­»¹˜]JèÝx\kždiÃ)ô>âÒÅHË€üœ LÀužÂoa²XÒaÛ,}Jé%nÌüÆOjèuRÕ¨ÿ@ñÅÐ5…£’ÉÌpOÚgdÄ '2Íî‡Aú¢"ÎÇeNs‘æ4Ø9(¾ÈêæÓ4y) ¡OŒ+cR.ÄÌ^ï¸}Þ:ZŠ‘ᮄ;»’™F€2ÌÈž[Ã8Êè5OÏÒ ÜW«áÞÏ÷ÉFa†ÑŠ0žcÐfÀAô´ÿ9è4ŽÏ»£4ˆrŒI‹É(Èý%Qð¢vDÂ[/´ûu8ã²ÈÏLµBŽEM„¿0:i‰}îC ÷“áØ%‘4›·Z;©¬|?âTbÀl,m% Gx±,Œ¼œÏ{¹–H'x!ÀŠ\$Æ‚Ÿ a` IQ€~æHêï –Ù- "m«Öª7NNBô‡U˜öã«€HG6ÊB¤ ‰c’|pîäG?4“Øb †Þ2˜[ŸðWìÀRrÎI›-ÜIcI )ý ¥øm¨!ª…T@YÁ?ƒÐÉ %¼%Ã-7U¹#XŽy2ºãuåˆÀ’~bÎkÇ–RŸéaÎ9C'¶EÿÅ~ÌVÃql‡V®[(úFÅ Œ–J†.dQPEˆ!ŒjFTÍ’|ÆØ¥jÿƒX”<Ž¢•pxÇD}šU¾H Ó®JQJLÈ—Ž1Ö^͇.ž}O›=8€ñ¦ŒèîÒÝ ¬ÎíÇ÷ú½µã¿»¶.À¾¬þogwwo!ÿÛ^å^ÿ÷õ󿯱ĴÅüñ•*Tv>ØÚ¦#y:Å/œa ¦|Ïo‘Fžr¯¯.„Úkk ¡îÚÊB¥îWÌ$•o¡)TQEQˆ9X×Õj[h.ùPæä{ýÍ7; {èKƒ‹HMòõT¢ qåÕÈyj5ô^b½ \ÝBÕ@ãÊø%6ü—+AûÁö’Z"ø)zUS+a¤­Ø§º§Ç<*» ‰æ$œ\ÜVE_ÛB†•(±sÿûB|‚¶µ…Ÿ†8n<À™ç`4sŽ—aXø™ßüJ«ñ‰IEmËqúʃÃ\b£ðQ)„]ýuò»…Ò¡EäsÖæ(º–')î©öê¸ùcã¨ûßÅX¦{¡PåTx=aLƒ)sÑ2M˜ãQÆfÑ"ôã¨Õ¶xýÿÕáÔßË#)A³èN¸œ Â¥°kÞ7Ï´Šöûï~Mü¾¬ŸÐà@hÚ·þØä¬È4Áò”7–>ðGÂ{XG_<óµ¨11!h~åãà#øæw[€ƒ^ªú.îðØÆ@þ¤BÃLXžßÙoŸ1pÝæLû•T¨´_Y©J]¥£òÚĨ´çrœØ§…fÔþA„¤®ÛbAÀùBx舉"~ TÐ'Ï›Ð_gˆEN§“;~ÙºL÷ OAbé1¶h½qÒ*G\'O#E-%ÙµvÛ5Îâãä¨Çàä Ú•óô¡x‡%L{ÏݳÜ;™<èQé9úû D»½©îz’EܶŸ¼»ï+ºŒÉ´sX,ÔcöRõö3SŸ×ß­¾hö$œ„SðK:ÆF}[´-êߊ+X ´šŽ[r7\rŠaØâû¹'J"²dr†<ñ;fãþ3±ú¹¨Üü$|¢G*“óÏa¹…l7Ê”¨-òRÕäïÔš¸¾bÙËH¡ ó~Gåùù>aýšç¡3»ý¹?åùÿqõÉNÔþçñî}þ‡¿Êùÿþ$’ÿ³Ÿäý йŽ}1ýU=ƒ¢.\¤Ì©t¨ðSðZö5Mn~4Ç\8ƒx Õ¦ædbºœ,YL©Aè0É‘rR^ˆ«2Ì@,jч•Oª¢3yzTzî]&Z {"¿¶*À™´os~¢8¥ô<\¿¶±–òwË×ÿpÀ.!o.ó¸ àûÈð—òVk0wº»‡Bì*&du:V˜nŸzJž@ùGyÖÒs˜¡¾h£P©Á²'Ǧ%¢aKœÎ§~_8Ú@Ð<.Xè‘)ú+Wp¼+ø–'é20¼-U¨-Ýð(¡›X›Íû¸‡²~=8¹a¢¼`bðšDúY¨‹Ÿ¹nø4Ê*„¶D²6.d<Á&ž=Óv >}Šl膬ç[aOˆ= ƒ+¨-‰ZOUÈ>¤µ¤Š[D.j‹üÚÁËLh2$ª‡ëæH»6ØÜ†Gè€eMÜ™lK2 ?Ö…o‛.‰˜¸´<¦²n EIsè(¦µ¥™œ#¥; ”–ašÆ÷ Ž/ÿ÷WÊÿ'Npͳ’ˆt´í窠”kD¸'àáÃpünczH®ù×è%¥?àîÉ®ÄÍ3M/_”å!ɇœyWVÆoÄEÂé6òC¨pQÖËŸ>•¹eܘGËÃ$ù!óƸ_”Ú¯§´‡“pR9 Ù å4ìøa¼ÏÚ›W„å¸vÒmøsKu׺éõ‘’bUR…ÃPai=,¼ug\TŒKø³´œöµYH¨5Ù «wP>ì Òì£çT€[U^ößzû±Á)T I]x›©B«]Ànª x."}³†íJ'•¥¤=äïPÝAýÞú‹“NG¼˜-úä» ÇÐ?†]mä"lëÛo—Õ¸ôkð÷úß¡7:œš€¼dh¯ð±ô™Í Æ­ôŒüX-6ÁT 5Fð„•¹Pî©´õŠÀ[ õ£€]Ý–n7÷¨B”ác…µâk‡=‚]šP°Cáƒ!4Ȥï&N+û°óí·Q³¡–åOr…‹ùè]eg罯€c&I¶hWá¢×ˆ j›ÔÊ&¥°!†Zâ“;‘Š7ßUXd-r,7ÿý¶¢åȹó"It‘Ë›¸«bÃÕò-žêóþµˆ€áÃôw WÕšJê¾J‰ \Æà³gª Tmž¿åâvÚüÆ1¨àáebÛæ3I-Ì‘#µ¢JqUCéÓ Í­€OÖOR‰^þäÕøa…ÐPžÃéx¯°¢B´Feø¿V}ü8kÅïRÖS«qC,å7N‹x$LÂÖ ¨Ä+,¿Üh4™»—¸NÕ«‚eC(\ «rêXRQ}µ•òÜ$C·`/+dÚT»µzP/Øè+‘w¦¤ÑÍàæIðV¬±•¼dL-Ê‘¨@<æð0–«(Wˆ³¢†êrÿ!žS)Ðu4tùnàÇCå*¢ïâÁñQÿ¿N;ÿHVò§Íãñ_!ÉÖác0‚¦cªá’檡˨Ð.#’å ¬m®yWÑŽp‚ÐYÀ/vç鲫±Ð…qª~H£'.ÏC}¤z¡›ékCICêkg9”¡g8ä‚P=t6U¢¨à nºEÆG’¤K¤]äÌÞ"åÝÁ¹@±šg36€W„ï­>Œ#YÞ7¤Çý¯*¶?êLA6ë[¾ƒÍámTa Ë÷…>L¤Ö#yßOÖ1_6ŠIú‡Ëð\xôsýúûk=RŸÀŠÈ1d¤M;JAåÓ!½7³¶@·úŠÏÀL˜çY›QŽÞ¿¡üfXW.â Õí\ÙŽ‚.>å°þIK>²1f·òa©'<ÎÂašu±/Pë³(8³€ëEÈöŸTU£ )Âm±¢- R#b¡ã d<5¦xçNô Ê9EMPµ^OTÌnD¥I-Ôúœ“V.®¡;ƒK> ûr“ª‘óËW‡$˜Fn&䵄/W •‘ؤ0‰Ñå»Ý÷LšµªH-ºQª+|/Ä%U ÁØB¿áIкoV‹ô0¢‹ç™K0C ã9÷¿¸¢“ ”ezÇEøŽŠ”°Pé¹ßáÈ­ÿˆmBJÏÃÅÝ?›Ž4íÂòÁæ6Ÿ–Jò ¾‘G¿ÏŠ1nkêÊ¢«œÝäÀï²cÎŒ2i„]g°$úBžæe[P¸Å`C¿:Ð'T’íá‰l c£6Ãi¢=ØF²ÔçbP»º÷ÖþˆµÿßÿÏ÷µ¦‹6RU×4ª>¡ÆaÕ[¦¾±Ô+\»RÅóý'®=F—€Lµ÷±m—jO¡2FéêS;H¨vuk©¶5´'SÛUBºÍµÇödUåPíý}jÛµçædUýð¸©ö¯\Û*ÚYZ?Üs𱱍 2Œ§ºs1Æ ÕÞ­ÒñŸj;cŒòe-ïz¨öã Öžrm8ÏgšïÇ»»XûškÏ/V¢<Òs¢–9Նú£OÌ =ß#œ{~íl”ºKãf:ÿd8ºùËÒiií‚èü…~©Oä3´M üâRÔv`gÏRû1Žûbȵ­ñD¶u™ºç‘Z..¸6 {h»éé¼BÜáâ†jÝ™g÷cœï CÔ›ói–ÚßÎ?‰Ú°™gYßÕªý ×¶Vb<Ò6q‡‹)×v¦Ië2©6µM”úâr¾|'ˆ©MÔB|í…=1¯²Ñùê¹Îµ]XÞÀZ^Î'cŒÏb@…kÓ|_smϽ֭,\ñ ûŠkϯ@ ^±‘…kµ_{áèŸÌI&¬}‡µMÆFM÷Rk²5E{`ÀïœuLL·Wû{jÛâÚsË0µ#$vWŸèÓ•¹²C8'~þb>ë+Y“Zû»Ç„µׯ´åºv¬»vºÝ¿²CÔbŠÚp:33PK…öïÄ™êúôÂféy…öïÁTÔ6Û¶²ÔÆqt®méÃLûw…vÁÁמhþ346Rצqßpí›)ÐSª›Fn©ÐN4 «Ãþ û˜V±ðÓ1ØvdcImœ1øyýR®dLáÚÄÏ® ÂøF¶Ú8î%j[ÙöïÊ>µý‘k;&¹¹.]âáÚÔö€jÛÛ]…òpmâk›kOìéE&J%Îô)ÕžÚŽe«<ÁŒ¹6ˆšÙ°öõ|¸nmZ%¸¶ýa%Ò"µ©ç׆3‰ÖÉ §îrÛ&×ö m¸Ù„ã½c¤›±ïQâºä¶NWYö±Ê÷Dk$+ÖÓš‘ÚDk¼¾of«Å–ˆì€Rî€$ú'cp™°ª“j#·4cG†…a2Œ»JklHrËÑ/&€™éé¼Ê§9¢ó#=z–Ú8ßC[­m-{¸6ŽÛ õÝÌAÐt2Œû;®Mk¬1¾™y™VIµŠãvi7hLà:¹ZÑ~¸6R˘Ns_ç:H èÿrŽî^+wÿ*íDÑyD ÇÈBçU:Q$#7\ÏÎv«Ò©Æ I³á]šö, W¬î"ÎGD©Çú䃢zp7RÔFjÙ\Û±Lü¼º‡X›¿˜ÙÖwugldrmk¹²d±6¨F4cÇvÌÄö¾ÇÚƒÚEíÔð{Âz¬¬n±6qmÃæt¶LÌׯ›©µÏìÉe¸Ióæ-8nO­Ýþri8xlêü…kÓ*!yí¥~ag;QUiÿO¹öêÝ;Ú6Ž{L«ä¥a;ãl«„NCQÛÁÀ˜YjÓ:&ù奞QfªÒ>6&J}‰—±OwRëK-ŸïÒ¹d<µ§Ù¸Ã.KÆž¨íS}’^Ï´K璱ŵ·€$½"×¾j—^˜pŽœo¤k›p~õoR[¨6íD—4îWºé™™(u—øù%­ÐW†î µGÚé@;Â(þñÛB¸6ÎØq‡×¨IÉ¡nz7éäÔ]:Q]Î_ÙÖpîè´T»¤»ü jµð+ý|Óyì’híÕÜ‚Ó{î°Kç1“4ƒÍ‘q'Ú¥ó˜Iã&mE¶#~nEm{É6[±foi:«uTÑÚˆ5óWQû׌µIÏd\;3ÖˆŸ›Äך®£™4E»t3i•4=}r“ ç´üB«äßúT_)`‡kÓnðËŒkÏôl{èí¿ÄõoÛfÓ+î~=ÿ@§šôOú‡ËwT‘¶éM3öƒaÝdÝIßB»à¦c^èYN5{´} ¬ý`ƒ|­å-Ûñ. ©xêÝÕ|p”Ú.J=ikÓ¸‰Ÿÿ0G£¥,8ß«<ÁÚtªùáÆß|Ê„s:Mˆ§žè+UÑÚ´—L®¸¶w•MâÚ£Õ„î NŒ ݲ³ÜYìщjârm×ö.í,µwqÆ&4c'æEÆ;É=ÚÇ&7¢vFJÝ£3ÑÄäÚpö÷ ËõŒ%÷¡Ú´M<®í]ÎWÞÆ†kÎi':™4¦púwÆ©©…ÎDSâ§ú@Ϧgún)uúAÔ6†v¦žÓ‰j:æÚC}¬»ƒåbn¸6ÎØôškOôk3¥Ò™hz#k߸YÎÀ{¤o™^‰ÚCÌ”¥6á|"jg<ÅîÑ™hê‰Ú^6J}LÚ¹é%×vÜKô²L}zß#èôWQÛ3-ó×yjù|4¢S‡kÏ<÷š©õŠ{´OçAms…‚.¬} õnÖnlÏ3²pÆÞOæÀÞÈ„sÔÖŒh÷?5Îj‘+Ô6íÀS’×NíÉоÊÄ×Hv˜¸¶¥gëùíÀSKÔÛ“,«ä1ISWÔö\Ãqto#um¹ε{0Ȳ<¦Ýú‰kBÝAJ­pÛž§ßÇÓn`\{l8ÙpN»5ökg£Ú ¬9מÙö’ÇÄÏ-ÒíµlgdO>¬¸|ó5Zß3Q›U‚§xméñ{J¸m¹-j_ë7™x*iŠlZ¡íiÖsècº÷Ÿ‘Ür¦Xew·P÷’Ù5מèóŒ:MªíŠÚ˜žÑ2ãL âÛ¦û±™Îµ-8KfÂí%³1מÍu ×Ê2}UHKEü|võiܤÇÚ>ñÔ­’3#[‹Ô¦ž“ÜrviNÌÙ :–3íµÌˆ3™Þ@7 ó½Oü|F\ñÌN¡vˆèök×v¼ùxSÕ&ž:£Ýàln8ž—±vÚqÓ©æW¢–ÿèžž3íÓ©Æ¡ësËÌtšÛ§s‰Cë»cO3Z˜îï¡Ìä_ëÌ]7Û9tŸN5­ÐÎ5LX¶Úñ®æQKWGKæLŒóúVË•GsaQ: ‚Ú'óÁÒî‡j?¿Rj¿6­ay©vÁï¾Ã¶¯]®½Ä 6¡m¤wʵ™•[öFêÚH-®Çµm­‡©ºigc`Æ*ñCµ©ç®ÎµçCS«9úRÁ)\çÛå3,cå cxꀱf8Ð*¹ ¡Èа{)GÞÿgÌå3n—F¼¬“T›pN¼¥k¢€¬p@H7î';„µ1×¶ÆúÌvŒÔr˲XpiìNà\ñ!‹tÿd÷1×”µW‡mçk¤)ê¢eŽ½Ê˜*Ü6ͷ͵§+-‚#µI·÷‰i •zÂ+Ϋ»ÈÆnP{ÕÝb¨m’Ï ®=Ó3Z˜VèÎbÂ3æ˜Ú‰n}H/§î“ŒìÒÚõÊÚ+cbX©Ï¡û$§Î¦²öR+®ðS̨Ã~Bg×áÚÀQô©‘R k.Y t¯ôÉ_Sý›XÜCxáÚÄ×èdѽF Ó,÷¡Oè¦Ç5¸¶142iߟ°åÏØµé}â#Uʽä Ýô¸$¯uoP,'¦ºÄ6',·`Ûq¦ž9µÒ ƱHÙv…NTíÀ=ݼÎvëð„öPï®ý‹¹ZBñs’z¼O\Ûú¤gâLOè†Ë#œ÷.õÕÓ©Mã&ŽÜ³S˜í…kÓ —÷k0VŸ-µiÆl® »A¶5F§9öï,1s¨ã*éÙzÂ0µiÜ´÷@Tt³qdÒRy×v>™Î‚O¾ÇÈ›ÊÚ蟲œ^µ kY强n.15 צq_qmL ž¥çßщjNÔr>Î*§~G'ª9ícçÐA$‹Nó é4uâLç–‰oˆ;4¦¦ƒùÓ—s‡ïØúíB©ý C{šFsðñó¹«ÔîzñÆž¿Q^›OjÃVdÙŽÖž{“Œ¶àÏ_ØrglN\ñÜ™¯>ĆkOo9ÿtadãLi/¹š³½ƒ5×½y¦¶q•\ÑŒ½Éôl»ziçûŠVèkÓÀ(¦Y£P'95PœÉQPòììb¦+É˰†ì L1¾€tXÃ:ÌŒgk>-jÚ†"»8˜#_^ŒSát ã9ÅìËÊ¿E?ˆâ#€ø >b "VRž]Ÿ=Óö0h‰@°›¾C‘Lü¯•ð×jøë®Aô’ßýv¯vb¦áT¤2އAù§¸Þ‚G²3P¼‘ý@ý¡è”0}¸)L…Õ¢¬5Ê㲈æ{%"ÚV”À¾–.oµ¼¿Ï`”ŸN6À.ôkÔÕØ™ðÌ~üä;-•)1„Ò‹êÁ-Â/íÍb˲‡H݇ ñ n7O ßç÷.ûq:doªïvßá5‡ßÝÚ^/ˆ\7õŸ€ô?ÁšÄõÅŸ*óC QŽ sÆA>0Ô‹åÙ—5ø‘û§xÕkŸ´ß4:^âÝÎ{~SYxSá7Ô7&O %:ðãWPgýì›9{‡¡°™gÚæ§M\Ùÿò$” }»Wô£Yr…Õ—ü‚óˆš+DÐSDUDóÑ#û‘Œê\BEÔàÒ‘‘66Ë›¡06Xæ›gšèh|Ü.õãÜ2>ÎŒÊLÓÿpe(ìG€7ùC‰Øhp…ňþ‹±ü9B…?´jxh¡™%¤Èù£·•…·Õ÷¡¡BýoÔ)ã/k¹z§CŽ H“Ôö?㚎iv! MÉÈuºóž‚ñíÂËDA¤_¸’Tx7¦p oþ´³y¸8ìpó\(ç3ÌQ1qgçã1üªqu8ªNhøùîfQÆùÇ0^‡×î?ýµm㩵­?'dr\ )G„ ÙRDøAû#j‘œ¹GRQ ´í¸ÇÈ ‚<¢âM8àN‹6=Û_òÇHa¹)›IYä0Ž´"¥z|-{Vz®Dc©A&ÌTAûý÷hP¸¸Š•pÅJêŠÕpE Àpà>‰ªÂq §¦;Õ½Áå!.”+w!¼RðÓ`Ño«]¤Ac¸ÿá +/6á÷£»TfŠÛ -â?>ILþÇzîLî0ÈŠü{ÕýÇÑü»÷ù?þˆüùz“2ìaö†#Ý)Tëz†<Ö ÌŸ~‹Ì iR,˼°*íþϼ1í‚Z¬ûÓ.Dr. ¬ i–ä\ Ii´ôI(³C(ïštAI}຀Ld5™#¥º¸_¾ ñ—hÍã2ᶈ¤ëòŒN‰R.0 M™Å) i6Ææ`[„†,#†6Ôkµ{ÚÌPCç_8r.óâȸ¥D¥¤mFóÔ®&G M™80H9×Gº¿}nAR“‘³¦õcqS÷ZŸd Æp|6#ܶ&˜¤y„ ©z}i.µkƒrJÕâ œ*‡ÔØ-[ÄPž[Z2H¬ŒÆ‰1,“¥‡6 Aà52d KùE”,taà„û8éXÍÁS˜ã©k ½”O—2 ™ 2 ð*œGŸÄ¥Ü–‹)“ òkìÎ"MÄÂæ¦WVð‹E²FúµX 9ybЇHÅhO´LI—$[äh….Úª¡mé æTûÁ}o‚°…"5¢SU|§€“œ+½^kÕ''£"ê9íN802gL§ª @‘$?ËõPÎh¢QqLðOj/ûÝ^ímû¬Ñ"Ãz ÛðËEµW$;N’IêLÍÔžj~iK‡Ç2z0´ÁÖoóØž<7ÚÖ;ó}hÔ÷Éÿ¾¬üÏ¿¯&ÿWw«Õ=ÿw÷wŸììÒsÿ«÷ùßïó¿ß§b»OÅvç©Ø‚\]ñÉØ2ÂW$¼ÿÿÆéCj"'Œ%ºZá®,&$%ü "§Æh¶¶·˜N‡,ÐêDºœ_§dèe”‡–;˜@¤TîÝÌ ?9‚[[~ { ›åw?2v_wAr8Œö„â¤ËàÕ|cç]‚î–L7èÊOý¡)†C¢Ÿ@ —AtyRš¢ŽÔ„NÈ„Þ<(ßCŸh9EzáGߎCjµ^Ãü®~-Ò7 qþ ¨iÛ$%¢8Äd•¡ê,õµÚ”QI§».\6×úÍ?âçHÒ*AV™‚ò/Í1ï_³1}é”^ƒîª'†É¿Ë¡ï²ÜGå[ü.Ô“ÜíšÅ'@Ä‚HòÑÅȵòoÞñœ’n¯Yï÷ðáÅIƒ{431$ȸåVÔb €*§mj êê‹A\ŒÅ„¥X bè,7 Ëp£if‡¡E\Ô¬¡-’(lÓ®­uŽëhзyÍ1„¶7A$ú²ÍbUâÐ\¾ÅnýxÔ>­5[å ‹€¼ Jëœ |%IZ9 µÚ½ãöy+þ,´pÍÅùxÇD]€¸0ÇôLa\q‘Q6¡mmz”Sƒ»cÂbØÁã9:aÈ Ã/˜.iÈœ‡ÄË $u÷SW…é˧¦€Gn¦V÷ ÓÜ©/}Æõ,$E¸¶ƒP1µ#·W² žG6Sß<ŠŽ(sKHÉþ.œLLIp!ân,i%Ȉ„)à…Ú,šˆ çckF–eÅL€à †Ãm‚ÐëiCw=U}+Þz—0‰Döù¹;œÜhÎÚ²ås"m|‘ŸeJÉ"q]L¯M®Õöß#JT¤›kB¬àÁ馯ÔV•ž‹,L°¹ÃÄÊ«Ô[àç •Ö(1¯’Ë”t@á×Éã„I+ÂÛLH¾‹ã£ß>ÓBù±ðêijg¢UÊÉgMð}WTÐ{8Ç[¥ðØ à!."ªÈãÊ£GÑ En£óú¸Ö<Œ)!e:&lõH!NrF±â<¿ê»2šhúzmð}zâ,‡ÓYÆ-ã`™%ìp~’]ÙxI³9Jy¢Cqz`;¬Þ9ľPßiBp°OÌa£pæ|à…WH hHKª.1]r³AñVm²@¢ ßp€šŒ¸ÄŠXº7Ð;¤>_ëZ¯_[è–W–¢ËÈZ¥L}-¯Û†´¹BUø¡¬¢sg`ˆ»–CÐé"DåØÌ£ž(†¸8Y‹RBÅŸ*uÊUÆþ4´+[Žg¶êö‚J‰…m#‰÷«Ìn9OÑwˆ˜.‡÷Œ޾IÚ7V,³(pýEt¤Ù £å”A¨Ùˆ—nfQµ’I—à3Í®—¼ó©»_x QR˜=‰ž—O ›í.LK”ŒVÈQ‰øRIm=Ô­F[Á —¡%¼Èi?ˆ_²…Öbè5Äãb¨6˜³õÆÑ~LoS _M Æ¢DôÊØUïŒå"Žîþ »ç ,Fö"o 8_Yx”·(áõµ-øï¦w¢Ÿã©½ïi ‹Xl´‚³±x; ½e@l²»åF´è[­ÿ†âcpÊÞ,^xž(gf,"²#n¹òlbIôÁ³Â;üF¦ÊåÍPihB6ZÔä ‡ U•N½—¼Rí‡`ÜûG†‡w.–Á›.,§XÍMÞšŒ4“͈Pì÷/žÍ×-(ái®Y¸ðI4¡Y¶'!åX/†ëƒïW¾€ZU¥…xRP+£ü‚Á\ƒ”ÇMèÄÖhÅ”ƒ]úo¨ÚN…¨° ~\е­_e-…ƒÓ¾ÏÈ1ë/.—<NCˆà!⌤.Â:a$¸€ŸÙ]ÝâGjíðñ=ˆx®±Ÿ!â>)ihƒÏÚ‰ðQ>X Q“BôHÚ?C4§D—‚â9°Ô”¤Õ®4kÝF7ð^¹tòËÉ¢ªAâÏ·ãõM§²*S ƒ™Õ°®ò¯Ú@rÜâFèô¬߈G¨õÙ3 )¥,FËÙX©F³åÙâE^O_<Æ+”á© ÑäÈ2Ä$³ˆ!»ÿól™à×z ø9–ôâ¶ïÈyPÜY4¹—?ß4»Ý3ô¦ÀzHTïzŸá^XÇ“5¬3òì‹+!ð$Ûš%´2[ E\|•ßFö+tj†¬ö0¡€èÓÖ¯D°~×~Mš„ß½ðŠÛϯ°N<“x“ddœéĶFd·…ë&©D6泺{Ÿs™:šÜÁä#Tœö¢}¼8qbhÁþßË•‡*¾6¦5:V{á$umzƒË<•IÃ"1h€ÒF«wð²Û©¿:ˆA÷ð±‹ó04Fú|âÅÕ8j¼8y Øe×B?)Ý ²Û‚в–Fp€LÉ~:1x!×TNÀÎ8(Ä’ZRO„[ìî´#èÎAêöÕ­%¶QbRÔH &TWÐòç_Á\ÄÞ2nî6j0˜4|A«;ÌÎÂFÜ’½Ô†£•}È‹wÊÎ|çRF "ñ½Uæjÿ Ó\Þ½kÓÈ%þ_Õý꓈ÿWåñþî½ýç×ø)ÿ´‘ƒ1>`%øõ}Œ#XNVYËæ+ÞÂ諯mõ‰•×6ûT+g´ûĪë~bí[X~†žÅô+®mû‰•×4þĪ©¬?‰{¯xû8:?Óvµê>†»Cúý^v_ièTŸ“lMû©¤ÍŽ0[^\ŽÜG©F÷m«}Ömvse ÆñBS¼ËÈ"ôy®|v†/Hy' ‡• [?šèÁõÓ謾ãƒ|Y¯ ¹òȤ&Ýz§yÖk¶[9<4ÿ4záÞ-@ÑÀai(»ä ø1]ò?ØÓé³Rò¼ÈñøvèJô)­k¤‰w`˜¦ù sFóÉîbûè×”C ÝQaøë 8YÍl×’¬Ä`ÐdìªA†AÇð&Η#6r¡NùÎq¤1àK,©½2­+ûb¤ò‹ã^±‹]N4t-•1Ù&Ñ,ÞÊ<Ë0€ÊÊ<ņV;é¶a;Zn1xëÊ ?™`ž:çF¾!`µ×µæIíEó¤Ù{›óû`N—®dÀx·Õ*åýòW>ï½jwrQ›û£öÿ¡9¾CÇTûÿã½Ý…ýçÉãÊýþÿ5~îÄýãÞäÞäÏîÒjôšð¯ßlEœ@,ôà4¼mÓRü@ÔšµÎY­OuÃug¦ocÕ„zPãèÅbcËeí ¼Òmtâš"ãkÃáÚ¨`RJlø/7V‚®·OÏj½%-ôAš˜é^Ø-æKøÒ ­¸§cóg^Ì Ë†‰·äÌZj‡@ü ¡CQY Ri¡þZ¨1fžSé5ð:Úôz­Û¨ŸÆ· ´ò ­Hmý¬RœUƒ¶Â[l­Ó¤^´‚VÞD'öM­×Û­æÌ©oš­Ý*iŽ:ƒ'éå&ø ¹â£‘†PŒô¾×ïv^+}¢ï¤)ÚÝ%.rè¹ob°4À@´jg½N=A I™¥OÉÚkìÁ!ÞGR¨ 쨂tÔeÅÕuçú1æm¦‹wóŽ–ï×÷vv÷ ±ÀºÝWÇgááá„·GÃîãã‚ÄIjI†ˆ1$c!v:ÝæËDz‚÷ý´ªÃÆdØMLë—÷´ÄF!< ?!¢iS׬tÔêþÐxÆ!=Pß[]팶!z4é&g]i¿E®_É2[ܾb\aø¢xA…âBmÒ…¾ÃÛ „ó×5(‹„òèIÏ»×uŽ5úf1§˜¿¶Wô¬Ó<­uÞú…Ë^"ÜæËV/€kÙâ‘‚Ÿ/mµ;úy§Ûð‹ÃÈnP3­_ôÕW€ ]t|I‡èE0ñ@´&:ºt4hK-@+ZAÊ~µ‚þâÂñŸŸ)ÏO‚çÇêóã%¸áò«^Ÿ£ûÉWݶß60‘vÐöé Ö‹àùKõùËàyG}Þ Æp~r"ÞÀà‹ÿæÍÝ iøâ¿¼@†ëÏ_³uÜ–ã /Aóê«Óð«Õžýè?ïýØ š/þ‹Î™R¡sÉq÷è…lƒ¾ø¯~¬>`ÁÿE³{Ôò‡_‚Vzj+=eÒkgÂàKèMŸ‘ÃoBÈn­Ìd3˜à‘Á d˜>žUÄœˆyy&<Ç/àÇC&·òÍI»4_‚nu^+Ý‚M؇õãq'€_‚ «5O|<ӗЫšúJY,5ŸnäF-_©ëè(mš² ï þìt||Ê­0˜†F]™ F0VÞè¿;Åð˜Þ2C¼!à0ôUá/Ì:b¸ ocö ã ¼eã?çÎ[J£íB;ªsÄÈFO  ”®Ýk¿¥»ÉüÜúB®E/R}ÁZçgGµ^£FÑÚéã‘òQy|ª|¬qÕÿ¶[f«Ù£èÛð¹Ó8ÞXÜyNdŒ­v£ÓiãÜo·;§ð…†)œhhÂETóôŒrU5Žak>ZwÄ Ã_D« [TëeccÁéú|GRú;3n#…áä>›è7}r3Á4[J‡ÓJŠËìˆqO ìZ68Çá8w0‚ä¾'v‡Ëಥ@œyén_ŽÄ‡  4¥Ž¸ÄÏ]}l]D^å1…y¦ÐJÒX˜Ž_ô”JmáÑ)RÕDÖpuUª»c Uñ72.lòÅÅxà›d—+¶ÊLŠHAÆ¿€î¢Gó©î¢¿'‰¢í³‰£ÝÀ# ^¡hÈŽi°¹_[ðBa47Š˜ª„“£Æ>)•Ä_å5Úf`”‡-ñ|<‡¨îÑÈ`¢"ËÀJE\¯pºz¸šA¯®¢M*¸r+§8òT\“qõápÜm×oÚ#íú5Gïphc¹Ö~hà˼R¾¨|&Š7ݹ ]»ú‘ˆ?ºèÃ8ŸåÀµG¢$Ô–'+Åeñ~‚æç¤ù¢¾_;9É䎾`V³Ð€´ªñµ l²ÃÀ Q#‘Šb"æ¶,O(ꡦþªQÿ¾Ÿ*£ó¼±‚Wdò&Í5%¬MÊ3½#¡ÃP†£÷`pàôÎ6 dAYŠDÌf#,-?ˆ31%£ªÍáæAD¢XP]ÌÇ< Át-˜]Eà6ÂÞ$µ!0:öF\G¢×ø¬‰²g,&lIQÄç?ó}™-II@1 Za'ö9bHô#\=<Ù¿?Óü†Å‰‰Ù³Ü!V<êÜ(êÎ.JB¿m ƒKP$û ÓÐ iæ†ÆõnÔ9à76Ü@˜iLŠ¿ÁÊËçaauµç”¹„ýi¿eµ`}³ËˆX|Ñ’á7_ »Î#«H_‘¸5¼þÌ¡¤vLúpI4誵JÏ)OþÚ+-{¨}.2Ò§æ=cŒèô/in?¹½ýÔíígò}“[¥+Ž”b±ÄÙ—~#ꤳí^ä²Cs| (cœG"¿'4œ>’i$ÎÚV2B1®ÒóKj‚¤©Tc¤*Ð+Á¬&³èŠ+j‘.–䂎’m‚Ms‚™lxlûY·Ÿitûw1ºýÌ£[b¼@º ýY hãù>¸²Ì„ÃÈYIáYi<=•o-¾Âåk_LÆ…÷ Ò"DJ¨ùBp*6“íQTsa¹ýù§¸¿¤g<17:]ò¿rMŒƒ£[p¼tZðÒW……W¬ áèdîBWxwa÷L}b~âK jDze÷Êa`oÐ\FŸ`®0(~e„÷HŒ’¤]P$ØD¡yŽO} ›èx”é h€*±çÒ[ë&0\âa`p4™ã¹C£(k=#:_! —àq Z C’£¡™¤ØÌÞŽto›©×ÅÅ©À+kËà«)\óP|aÓ"æì’B\b.4÷RçvèBqz1t+ž– ÖÐ&;%ŽÕ`;"B‰<{ýþl¡Ï«E¤ATDê s.vZ££Û*1SèÙ3š2I’PÐß±¸)oB%•s¨Òì ›ÞrLâθ ‘¤PÌŽFÖCÞ1YÙ*§D‚ºkäõ’׫Ÿi¸/ˆO ’hÕì5_6{ù-1ðª.ȳ‡7˜õ ö3-ïë‘(OK°ëÙ“¼”,ãB$Ä-;èmÿ¬Ýé­ðyҀϾ܀çû0ô6iÀ‹ù®ð´­•žQw¬!{ž¯0NMð„}(P¯? ÅFˆY> b…‹G¾Z*È›¶¾ŽCm+Ás(³ÆÃåc#§‡G©n™A¸‡ˆ„³ZJ)$ì.»&V£"^ûŽ«F›ºgø,ÔD_]txŸ¡LaO§ 4•ÈûTQuÙ~Ù£­×tÙÉš¼å}7yvq*’ñ<§+P°ýuÚ¡D^µž.œ£8$$×ÂH‘×”åAÄ1d‰fnº—( Ìm"Š&‚™Ã$±…2![ä ˜j >†Áå’꨸ [¬ÆJŽæ(r“hØñ•hG:dP‡´:ôgm•ÕÈá˜yotÓc«?nddQ˜´0›žÜ'¹7‡áµq|Ôÿo£ÓÎ?’Ú]Ÿªü7¾¶×…še¹œà£’V ÐÇT£zT5´•†œw5“Å P¹è#ï*ˆØH Ÿ c§ÀzOñÁ ¢XÄ\«Šùšj!*Ü_ËEP¥)RÂÀ±I%Õ,÷x.U®ú÷€NìÂ%4Ü:§î㽎Edä××ÌF…§ïÅ\dóq1`+É·¯êƒgÍ!†íÅpkÈ}¹"zIˆs¦Ùñƒ,)n.8y4,¯¸8¸oDXaÔ©ò€”‘ι1æê#ûQc%ct§Ú«ãæ£îÕP5~tfÝqySƒfËK /šŽZÝþ«Fí¨Ñéÿ§y”§¾bç~u"/;Á;¦ÇðûöY½}ÔÊèzø}­¼óáw½zðΉtª£ôɉÀì(0Å.uÂ=ë"2¬£zû¼ÕSúmÅ”ªµ"¥ÄŠ —ju£°œ8XP©ÅU7U’èÌáHXªÑrð†®DPÈ’ÿ……-˜Îjð{ó™ªo`¢à ü^xÓoà÷˜$x¿ß4GB u‘ÉÆ¿ó“&/ü÷}¨¨*)ìFY.–¹|l ãë?òù¼Aþ†{0`_ûÖ_<~°_å„-èE9bû1–Æ‚¥™$Dciù T‰¯—sƒEbˆ‹i0¨hׯîºã|‰N·º2c¤ßÁ‹Ä®‹•õGuŽD&Î¥>IBm¡@ò,8_q(Ÿsÿ#VAÑHM;¢‚ø)3•B E7=9X5¾wø¸l|œÁÉív¢SR©ˆÂ/çc•ˆ äIi`@Óöí3µo§útqbu¯clºšaÙóñ¥FqHõªÀ}7.yð™³3ÝñÄ)s]äðGjÿŒM{.Y#76T|Ÿ=ob#sJ>'ã—”}x/¡ª€…·¾ÿœ7ºèšÜï½=kP©EÍ*U?©u»A1‰ÇÿøÌ:yà(uˆº©Žçk‡îÄ]sjN€¢(›À5EýEodyè&(Ž’1@®öŸ¼”*ÝòO^ ¥2žý¾öJaIê¡Å½bæ[„…ö9,G[\`gF·¢áP‹ ó#æ†eõ”+ÿ«ÙÑå~K:[Ì’³çM8büºüÕUïöößó‰éŽ)9ÒŠ¦»ý9~Œ\ÙoåËÏ×®;[qŒ²hâKr¼>Šg¢óaîÁ¤Ž,DrN'–ot:ë29ê, $àlA·Ø¡U^aîSÓ…ÃäaŒ0žå"“ét–³xa,@vJÝÞ‰R•ƒJŠW'Ö"7ò1uÆàÃ0~)ä©LOLµà3Â8¸:Zdb¤¹ “(àà ð´,M{ìqâËšvDgdφ¥Ms W§°- ŒIÑts"œfÔ'§/Â_Â_Ã__†¿vB_[ÝÐ׳^ç ˆ˜uÌë)ïÀŠêppõRä,]M‹¤¦–¸ž“V¿@já©,GHf1ÉÏRBVo´žÈè äSA †1Œ½ËÉÏ‚±ëäpÒG8@iTi#Ùwiåò^#Q0ã “S÷¹¦,Ô¥Xˆ1ÖYÂÌ¿Ì$Ünfþ^r¢ôdzºšLÕœfKH2y5ÏþJK9JFÿ#Ê›ú—ÏûÅ FO›WdŒ„¶E#ÉP^±¡MÑfÉ­fö±,†¬Ó­¦;îçèŒQ@I¥_ÙÑ챤R8Lµ“À¯þÅçªÛ®¥_¤"X y„öj#{î”p2ƒ™bK r9劃c"mBpm°åÍÈâLþi׿Ùò?Å‚ÿ¾ÀåÞXÝɰ-Æõ-¯ýcú¿5† 5¼[Å5<+C_¿Ý+,)üíwÑâ•êÒòÅ7fIõ~ì%/)´ÀK9¡Ibš’žh¥¼&Ümf¨0C¯z\2/ 3u—BL–; ]I#Ф§å8z.åc&~ 'Õf©51XŠ…·©l}]ŽÙÄ`ô{Yd·ÀaÃòì™ïBDzVéø¹°”zѽ}Ù8*ûbgWû+FëäÖCØ_g o~è¨Á—= \e Ñ¬³à ú·%v^/Ù/) ßµÍXû‘KìzÁ¦€^¦wƒÙ$1xëÐ4/¦'ûsÜ$‹7ëˆ-²°–XyrÆò䜑V.Úÿ‹ËEIá ò‘\H‚UØu€XÚZ—LÖVDaeæËÇ)øÓUéáûQþß1Ê?TؽsžqVhRd•Ð ¨Ñ6ê¡>å`¡ãï`"mýLw\N(ª_éæÿ߈íUÄyLuΑ8`_;DóYt¤A°1€¤ÄãW¦Ëúðš¯Òc@Й謕Îj²è°KÞë‡!EÇBŽÁ8Ä[%IR·“BR¬êû¢‡ŽÚû¨? ö?CÄg'í(¢±2¨Ç &æTà@Cï@í]iD^Uïá“+ìÝñó€»ð^ÛPDâw%žF,1#Iæ=ß™•ËeiÌa|4½|¥°Ð­l‘:¨çtÂÉó÷°å~lÅ¡áéƒKŠu$=ãgñˆ3dÊ”ÆFV*Ƨ!üZABÔ„ÆÑ”bçàA͹6Êo-¢ˆRÇ>cd†Œy|Ã@ª¥ƒW‡ ¿EKÍFÒƒo óëû"kÆÿ¦Ð¹}Àòå׊ÿ½»¿³·‰ÿ]­îìßÇÿþ?2Ôg¿ßmôÎÏúíV½‘}E¸ÏÈc‘+4š*D+ÁŸÊnL² õ “[„_ˆ¾C{YˆðUñÁ9Bu|ˆðŒñÁs中ûãƒG‚ƒ#¬ ñÁ—§`ÜIñÁµôÑÁ)y(@øW‰${?ØæÒ pWo,/³Ê3ñs;(©~Jݶ(À Ì›¬S¾4Ì Ú Ø¬0~* LÑ(ñƒ1óˆ¢o¬AY;¥UÍA Ðì‰”Ï …ÞØs -6æ^¾ËÝÁ“ ö¨‰·]±FÐ>©XІŸ Ò­iStõà2ú Ïu åt'òl@æ@ð(~|¿Eûå@¢¶ìÄhío»dYÕ UqoÜm:£ÄTk5GýÓÚÉI»ªÃ±+4NÛ·á ÌhYÇ0(æB¿Pò]:šæicq0æÔ`ìQa*ó¦Ù{å×PÊûeE´k¦¯´²ÐÂBpðt —®”ŽÒÀh`y“ȈD<ía^D|?zÑnŸô_QjÝÐ+zÞ+„Iå¶'I(:o5\¨ûs þ0¦B¿9›¤ ó#íÙnÿGŒBÝï¶Ï;°ë7~ì5ZG£&ô‹üÐè´'¬Š• Xíìl·Úßß{ÑìõÛÇÇý¿õc‡·OŽË,©ÆÁè“ÞËAÉXø¢0Ï›ÿ!‰Ñ·2†"íÁÃûÒø[Ò}…1ø[Zm]Äx„­š¾˜ â(Š"n׳‰î¡¹¶±2®p G™žÏé Îë=Z`¯k'¹H€F88’ݰwÕwÁáÿŸ½okãH†ñûß—ëz¾Ã„¼·-a!Æ$›½e¶ž€ÄJÂN6É¥w˜µÐ(3#›õï³ÿêÐç™Ñ°ãìwckfúP]]]]]]ý4¡ÇO;.|34§þ(gM‡Òc6Þ6k‡cLØööšd%¬¦ÒïÅ@‚SNÝ0L•k „˜A©¬F¡av£$åLroN­ýÖ³K0¥æ•[Ó2yB¯w h¿)£´}„¿(Ù;¢VÈŠè½r…é¯0hS''dÉ Ð9·tS¹­ü«,©%œ ½L_JíúÞ{ÚŒõré¦\ñ~ÇŽÜ®¹Q.ÝÞ­æ‹ré_åò"Çe†X®,&¯¿Šµ;½¡f¢ Ï_š·%v´3™¾Je6ÿ Yq…ˆ‹üÐ ä,Ž.¥”j‡½¾êíG$o “ï>]º ¬„~ ò!yj(¾ª ,úµúšÊP¨I²½ûXO&NÃÃ$ å½ ›@VÌ{W4L¿jõ‚¼l4:6Ý ¯O1¤„ºq–8Uµ)¦b?oÐ!Áž`§È&¡Z¿j×»ïYpô‡I„ÕOÙ£…F\0s£Q-Ù,ÉIã-œG ÚuÁl‚>^Í >/p8MæF$‚é"Òª0IÏ?©jDZE6*öó çy“ÕÌZ6nÄ23Ó»•à p—âõœ_bcf‰3KlN/à—Ùšœn29¡óž8Gç=ÍzÑYAosèà¯ý+Õ͇§²HX‹_ ‹¼SÍÍri­\¶ä[Ä^܈ ±-æDö¥ß£ž]É3½,º¯áú¶¯Ñ"Ο5þT²—×ÓæÙU™7§ê”½ Ë•íõ眳2lQXbê uœUbsz‰‡[¡8áE+tÊdŸÿjæúnUa•šÂ`Ñ‚¥MÄ\°„–ÅV¬]%ÉÊ~xÉ®e©¸¦Ú­#)›íMâ&sxK ‰$da/hÏ…e<Œ•˜²$as|lpöîc•Ú˜«Ô‹¹JmÎUêå\¥¶f—zØ Q>mwÃ磻rZ9VÎ*gü}ŽÊä΄WJ€°ç¤ììfdO™·R.>Xs/ºÓáÜënFs›ØÜÚƒA÷{ö`ÍmQsÃiû9–Ïìéu̽¯;4U´·ËÕÁ8 v¯Ñé½o5öäqª}NeYP&Ûp,äWž¡¸=‡‚ÕagqŠT'‚þ®‹ ±ÿyŽnnï°Õ©³b¨læ[¤Ú°åxÜ7R‚å¼ßh¥·W;ªŸl[{ø«3G[½Î4hz‰ªma×-'KYZ•“ñ8 £uWœŠ"Á#u­Ùiñ†µ‹x\âÐã^_ î#êö±Slƒa Gx ‡xû>8R›K` jSyèôÑźêâ•>3ïSLxy©O±ÖY¹:D´©Ê Gž°~3¯‰2µHénŽ¾í»·ïÖÆöñÙþûÚá=Ú·ksûh1£:øÐ:9ÜsH»Knmì@¿3‡qÜn½m×;» îÍÃït/µÃv½¶ÿó‘åÖÆ^Ä;ݬÿŽíÂ]¸µ± ñNw±_ïtkûûívýïwè­]ït7G·Æ?êw‰[»ït0C݉wé­]¨wæŒÐËÖq÷n3b׿‘4[¨³jµ»wŠQ[ E½Óe‘ºNYû†ªuŒÔoï„`·6ö¤ÞÀÐÈy8Ȧæ\pùåtSËí(¹Ñ<éܪÜÚÔ|gw˜¨½¯5ïÖ‰Y[v"ßÔ[ïî·>4ïÊOœÚD½üÎê⤠llïÝ»°j‹.Ä;«`ÆõîbÕ½Ð;ÝÇ^«Ù¬½b¨ïß¡·6öa¼³»1¡Y¼³¶ìÆK³õæä ãÝy#±k3ÛÂwÆžÛÁnï,:8µiÏ¥wÖfhZx3´j‹Í»PÜð݉EâÄ Å;] ˜õQ­ùs».p‚¥Œwb4ÞoÜ‘JÝÚÔxç’ϰ“ý;“®­É‡Þénaƒº»äéÖÆnðRÔ1f*àð°Õ|+ÛGIBW ˜G3Œ&É<³ì4C³¬ß)•¡,ÿ®ÕÉL¸|§oL¶´ØàÝÚ²ÅÔZÝúÑq÷gÇwÂÓŒ tz—AÈ{‡#kfÄ;]H¡Ýq¦Þ‚àßOZ]§½3W·vXwŠÐ;ã´W?@í"üÎ=Ïy5™iõðf¬w¤ãëIˆfÒ€œ­ÍÕÓ0õÞu„2†VºLÞe¦ï¯KZljïÍF·Q;ì·à¸To÷Pßð‚mkSŸSe¯6œùšLGÖ ÓಗÒá=YTiBÃP]›ÍÁ'¼¿ëÓ=¬ƒ¶UŽƒ9¸ð}ÄM˜x˜È¬Géé¾4‡ý·Y=8;bR,ÊÕ…¾’ªŽ#ÔSˆ|Ã$Z¾½òcG-®;]CeHa»ûb•GùÿMþÿdF‹¼zQíãEÒç÷ÿ‡ß[ëŽÿÿ‹›þÿ_Öÿâ‘BÝ `¿Wø5é[=…‡ÝÃz³×õþgÊÇÿ™Ö²ü‚úüé(Áq -ÜU#pä—fª…[á¨=ðŸra¾:d'Ÿ*+±;¯‡Œóo›—tË=0 Þ vw—Émì^9ÌSƒ°Cî­Ö`9‘@AKÉvÖ7wJí–XPèC£ rÖ´f>t6º{Çãé`Gsõ#÷È¢ÑxÞ\¾Æ…uêz`ÀoT¿fýóÆŒÊ~ÌÊÉFÚ‡ã™=KôÛ¢kkÔêòsÚêa]yŒðZtJ±^L«Þ{?·VoΆžÃÿQ(®ö˜5òÿÍÍÀÿ_¼ünskks}㿬½xŒÿòEþØ]Öøá{ŒâBδ eúý TÓ4ñ£$ SŒÊyÝ 1ІÑ9ÅØÈ„ùnµ Ì=ÁPô'Ìü`ˆ'OSë. &¿îŒC5V8˜EbÁX¨Î„ƒ)ŽCG¯y£Á8¡`Ø´ìóGƒQŽýË2ãú˜ûr6Àq­];ÊDû±Yy¡YïbÌ`8ÈZõFAŠq…Ÿ‡£)÷߸u§EÅkíãE'¶ªøñØŽM­†*œ®í­Šê’8Ä\]Ø')l©Ë†±X~Ó{­£ãZwJ=6n-ŠˆQkî·[ '^BO¼%‹,[4 é«ÇfŠi(Ä {šaåÄp²Fè1¹põöÞI¢O4‰ûåhˆ1rÛ­cüª4~ò €ÝÁhN–;ªýÔ“eëín£NÊïsÇÅ[1Þv6ÞÀÏÖá{s,g4¼²‘b‚Po‹ÃUÃã–_ö»Ì±M;zöó(BÕBΩ'Éû‡W~˜K†¤Ž¬Hã&,)8Õ°›Ï:ï÷”­Ld°CŠk °öNo{ј{,‰ôážÌ>¾43ËÅP4å­ˆS«# PîÒO>–wò FWa/ç—_‹g·‡‡Žj‰ªIQ¥ñs`4ÁÇ›žXr°È ‘üÔâ2’EZô•‘|œî¹Äj­„’ª‰94º¦ ŒÕûù³g:åFœÚS'¿¸º÷5–4T2_íê¿ÛP!g"ÂAïcp[Šû›øïŠUð#üÛÃ0=Žœƒ}Lai춇Ñ÷ïâ“B<†dŸM×EH­õ(FÓt—i~8¨SxP »IÅ:‹x")$5ލ¼·Bôw¬§#?Äþ°‡«®Tеå:ZlS¥µÎßd6ÛÀWï(Ö‡\6Z—_D¡ù³$ª£èãd<qO™#³ä)œ5ûvm˜Š×óµJþ…±šÔ:b¸KjŽ%#Æ›ôûš¨’°¹×j4ÞööÞÕ÷ȧt³ºËXH÷ðDéíz«ëz ÿPyfT‹Tá)[°JªËà ‘6h&@¸¸‰òÒ¥Y•gl›VÄŒåOqxeˆkY\1E]°BÚ´)§HÇVëù¤0:JYH7Qr…à© È2yõÙmj;nÙL>3‡IªƒS€½±wãœ.1e€ 5D!‡µ·½ãvã¨ÖþïA³ŒÈ+9§±'ÙJt¶ÎNv=1yç–uâ†Ì">±LoŒlÉ=·*óàªt ŸÈ¢‰ZLÆpF‡¿‡!/¦;•'jö q“†Cºü–R^ KWG‹Þ­øQÚ¡«{\Á´X[““Äýl:(Ù#ü›ì䥊ÂÓ¦È%$5@#8­]mJ¶,¥kJSTñâ¾|2#a“gŠõ5â\uïˆhèe¤ÜÃ`ºæJ&÷}a mœ|ï,!®Ú9ý)}Äò¢D<ãJ°:Xø2JR!`^2Æ}É­&—ï "ÿ1Ä¢Y2:ž‘¢LV¦zeKóÁ˜RK-‚ùHȆÆì_sÐ4†P >PKUÈt Õ€r?0 ‡hç€Ë­€¤ {Áõ¦hH&¬Á-‰Ä¹×¤Œ£m«.IºÈ›&'”¬à %" rælÍéVÌÝO;ŵä7§}Ê©ªÎàÙå§)µr:´>e«òY]'”1ªÒ§üª«l Ý/øQ|[R-¸gkªë¼4“uóѸ :ËÎG>wí qÏ„ÎàVá-u ·_kï`2äOr§A¢CI#Æ1‡ç°G”‚õžã«Í Ìø ˜šÈª¬o\™Ý#2!·–‚< «(ƒ ‘»VÏüËøŠJœM$ ìæ×RúA¨·6W ¥7¤e#‰{öL''7²vÊLåŸÄ¾œSS6¬™Ñy 7V,!Y§-‰asP§àHmóA&k7±¥fªlƒ“g`Û¥ ”ÎÚŠ‹¥ô¥!þ´T _ jïk:(ã½Ð&‹˜•†¢øê;µ“˜„Åxóo1ïzµ´bÝ- ÉàŸJJ RÙš\ÂÿâÈ&ªÛiñ UÒihõ\„e}yôMöÚRÊx¹—&ûµnmGÉ®þ€ÜÊÈ©Jì]8(ïÚç ð7‘Ó”À%¬3"LN—ÄTó3 ³Åª×nukÝ:g‚`"Q°aèycÄl£Heh iиŽð‹2ãõHvÌBo&kˆ=SÎjYiˆ­ã.ÉЫÇn»Q7›û­nçß™©UßOö{èn4°ç¾AhÊ Uïí½™ÒV§Þ~_oï·Žj¦ñâ°Õúñäx<èù°Ñ1áaµåQGlC ÿ~mÊÄ5ÌßtKbN¶õ›f‹ßizš~¢²ûÒ “ñ¡$-´´õ?¹Q"iºõʧ╬ýA‰Êg¸åÁfÇ`Áó€Å6 §dŸé§OE,ïӠœ¯É™‚QšiÚÅJ€ þ(@•¥@šE²»¾$sïÍv¬b¤·†H¯¬B|f¢WV!ãÚl”FÌÈnzI˜F“¤”¹]cÙDÃÑŸ«¶,æÔ¶¯‹<Tëcq5)N¹b²¨%¹g1¯`ÄÀ3Å}Μ‚åvåÊ3™‚E2«Xqåš×†\óä‰)¥ÖÔ“H²Íœµôä½6.×={{‘rÍ'µƒ[Ÿõæ­§GíKæí·½g­8Û0Š*[  oÜ&3©¹»okZþ9ßÔx†Xw¿é¹ëÝeŠ”ÜÿÄÅÑ/ÿ|öì·ÑâIaø×ûÍœ*î^~E=gŸ 1ÌdCš ,"Ë’ÏR˜³î¤nPL”jW__›t–ÕL®³HÙF¿q+/Ó׌U/ZÈYõ&C– ‡;îGñ °«Dî4F•«7Åû¿üeb˜¹R²Ó¤ËÊœ*iQ*©BugJÛ äŽËÖ¼ÚC2¬ãŠ´¹Sì`$ÈÊœ!­G0c‹QöùÄEf.“¦šù$檱‹ffÊÆ-X¬+Ó6SOF)¯w²Ë’÷m§ymd§€à›|¾ Y:C s1š5È¥…|í¹Èmü:(Ò8¥ööúÐ'§£®d]SÇ/ÏSO<ûpbkö…9–¾ŸÉjÙ’óΔæõÙÀêBI­9h‰ÖrÉü¢lOïí!ú‚µº¾¶¶6ulxsúbË´¼ž„Íš-‘Okž†Î [¸å4/mßlY~Zóâ¤eµ/Mår:PVtëSanݵ٩˜–g`»YSFÊ4lS.R\Ÿ™LyêÜîåõhJWÙîõ¨N3Óz´Îðv·Ž•+µl‘¡Ð¢.ÿ´3µš<"M9@íXJÊâñ4÷ßœH†ëŽ)×`2³ÅÆ•„9Ef"¼½÷~:€¹†šÅ0æÛuº`æ”RÜÉ/Rx Ï;oÛmäŽÑ:–ÏÃY>-Q´>‹‹¢ÑÛC—çÞ Ä{æº3bJþ ß=ÅÛj‹bë¬bÅÔ3}¾TÀ×ìHäºUÐB’GUgb?¼µržL–«pêÎRd¶žŒ•ÛJÎìžãª¼\m€-ÄXJIo§“%›Ê usÓ¾æqH/÷¼Ÿ™•é †BåAþd¸<³Ô3ÈV5-GþÚ²ïZ@C1ÓñžÔ¦§ {0¨x+†jÂöK$@Œ²†_àak¯vÈ»’v 4‹Î»Q)K`Ã9^Ý– Zó2݆¼Ø€ÒTÂè±zk´š=óú»àŒ¿ƒYíîçzšý•½Þê“¥Ÿr:˜ªÙ’1)Ð?\DÛD«’vým¯óŠUНÞâ²ô|ïéÅÁíSi$‰# Nøçç–¬½ÑÀÊ‚XsÅ›þeðTÆÖ¤°5‘«êX‡ÚÀ\XðïT¼³Œ…xÉŠáw8ܹ æœÐ© á ”¶MR4)¥Ÿ£àÄceæ,mî`YP»‹h8àˆ¦žO&K“áp5ÅH=#*Î}V6ÚÂxtúÆ²è ’¨'c ‘+ƒõ¤‘†bÈÝæÖ©9ÊÀ"[¢è¥\™£—nmaŸ,%ôhlð:ÊPÀøÀAÕ¼f×{Q}É×pjp cÖßýXÿÙÙ¶=×ù”ûNæ$”KÅG_e©J«‹MSÅ  ‡626Å ö0‰¼»Î$Š’4ŠÙêC›b’:­œÿhãö="²~S+1¸ˆkÒÝ›ÿ~‚hU ¶Ë®Þn·ÚrE w²ÞµÚõÚªPpo¨ÓœEÔÔÄ\x|´ÇqÀ¸B1=8²ñp’y6mq|£,I™ÎMŒ¬ñÙm–Ç/#5!•y’"Ñ쀡Qê:?[×~Âj–ò + x1ñÆìïŠëB͵È$}Ô\óBØ/IÌzÙ1&cy9Hæ®.­Ù#×IÓD«š=@ãµ+èŠl=ÎTs˜®=5·ãua—n³ÏÞ?)*S,ÓÊ 14&®bä 9ì6wÿð²âýð=­à£ú”勽Þk£žSÛÉUü®ë'ÆÇÅýe·Føã §µ†‰b§JIÇ>æB½‹¬„MÊ–•ÆÔ3~Á–„’Ú’{J(I“¨3‚yÂd£PND¨'ðU«Ô§Iñ“$ꇆ¼!¤ï )B©pPBå^“# pªLö(¥*S<)«˜³/Í Df1}zE4"øeãåÖošñ_ÞÀâéˆëëccp#÷“àÄ\Ñz·8Òae® è±´³£¹@xÔbʼnñQ9þÞVçO’±IÔi°Ÿ=«˜"ïI“îç öK*”m:[„Åša({Ã( àk)ÕrŸ–fïjüƒJ¶gœ_î2k©* ÌÌ­£ä ÿ¨dAÌ&gÕ©ÕÜ{³ß;ê¤ý±ZÙ¥2e¥äQÏ;rŒFUL喝÷®Ñ¬Wð„ß°~øIÑfü+º†±!3µäcÍQ>í &ìvaÅp Ô÷õ¶EC.Y Hѽ øv?ŠivïC1íà,ÙöŽÂ~a8^ïÇQt= ç÷ïsüšê~|³¾±¶µ¹A´óã›ë›k/_Tç$»¹6 wPS)¯;ó™ßÌ`5ús¹÷Ž1‚o®©Ÿ•>›]ô꟟F] %UŠð°²Û0:…YüᆟR`•iÉøcbdLgo¬úc‰#Ys;‰™<¬kéEÌR~ëûïöŽWe8–`Àíäõ _ò´³® 8÷bT%ñv 'Ï ¯pEæ0n#˜IgL÷„ [»\]”*§L¡}rváp–õÂYFJͧOg›öþMoêÍ“£z­}:'oÔ;SÉ[÷4“°YP*^Ø™è3âpë"fJ2ÅS§ã{R.L‹’ÔTà )ÊŠµáNA®tcÏQÞæ•ã>æv£Ãˆ£! ÒÂÑY$ØäÁq¾ç×¢«[æ¬FÑñyŒŽ¦åQrëËKx ÆâtJ—¥pÌEÈÇZp`ð²äÞ罸\ªŸEéfÌc"–Ñ?: ¡°Gë¼"M«ÑZüTa•³î ñéäŒrðwx¡lñ€ý¬st&©ƒq1ÁmÐ{‘WÂúJ H´H€þ¼gè˜ ü /ù(N)>–áýFÙÛöXƒÇÈ)DݪøVh`¢9­éãÂ&Êä'êȲ]Q-³" £ÉA¯ ÈÈ{]„aŠÂ˾ý¤Xê-!™ãx+ŽD3D¤ãî% ´ÖˆžM5™°:œÉôVTDcâu×r,TÎaŠÍ ½ŽâÄs“bÎÈy ß©S^ç<“¹ˆËÊPrÃŽÕ†Þ»`¼Ë+³âŸe¯vÜxd°ŸE6ó\þ½}8Z¢Àmi°íÕFýU¢Çý(#@Ñ€•¬”Ãàø¤~|¤…lÝ&•Þ~Ðø©¾ßk4ZB”[9 +´"ϼ(@#¾Šw”6Îø³’Þ¤X ?6Ž{˜]»×é¶”fv%×Ä7V©Y6c‰ÖÓ9v“Jw¼ã,,O¹ÆyÄáÙ­OF«è!áùW~8ÔihòÖŽ2ÞaÕýØ-‚œJ%ÔÌÙΜ+ÍÞ¼]EÝÒJA—e¯„s0í"âÍÉÁA½Ýk8xpØúÀv`¹²vžÐJ“ëòqì2ÃÂ%øv}ª¬(ä.£)>ï:=‘I‘ ôñä,\ÝÝ%2s=ö°ã šòT!þ±ºÛ nR}Òt‰È ú8J•·÷_Ö~îHIþ0à 0yÊ´„Q¥¡Å #¢•ìXÊ~ªÂÑ)r eú–’°t®H@!r!IÛ_¾KÊzV;åªÞdñp^{&­²Zóg7üË|›­fÝðÁµõªŸT$Á)ƒÚ*ÕVѨÐðúr\r‹C¢- 9æn‹]xÝ®ÊìOz´B?‚÷3V\iÜFÃ@fä$Œ:=ñ (n[4‰“`x¥¢È´!Qû‚ÿVO;+rÖŠÀ*‰®Éfi„S~!м{G¨˜™$^K v¨«€BûËýÀèØ1~RìÌ­¬%f"Î]òè¨GÂP «w¨è¢J ®xr¹ÄÉ`I‚Fa¸9`ÂÖGxMÆЧ_®YRƨ®ýT¤r÷㺹Í祯îT’ÉéˆO•j±>ìRÆjSD +ýîƒÌ-q‰é›æFÛÙ£}–nÖ)ƒL,nÖ“pPA¢P³ÈžârP| R„Gú>ÅbL{¾(õ4QpàLAÕï‘Ø # ¶¥pDY„`XÉ$e!/Ðäz„Q]ð~-â]2±@ƒCU†˜š»/hâ*ñvÉOô +›ê-‘K™˜7Â’Jfœ±ÅŸd¹Ùy¥>‰š(Ns†³Å&«ºL5û~ò‘'‰èß, ©qE†\4Ћ¼ÃZˆ C&F[€  åWG1Ñ©Xv?ÞZò æçAú€j#xâKƒÞáIc_KVDrèÐëãR9 Äûí’ö~%Ãa8:õã¹]µL!OçlÁuˆ´,!´vEê{EEæ¶W¯yM»â”rÔxÓk´Újíý^»õaª\£ècCžÐ&YQßhÕ“Bâ†R†ä},‰#“Ái»¤…!ÇÁýÀ³Ç ÈÓ…¦IÂZbœ¼êÔÂSg§{mê¼PmƒIR¹X«3:˜îÁ­·&q‡™ÕôL‚bÀ…#جÖfâ «øˬ֞@™y$zµ1Z«]ËôF•„"¿?ACteÕlõHç¹äé”=ãŠ[žŒ//{¥Õõ2žrÓ(ò†¨ä'¶4!6ðP5Øe$a)¹TTäGØ,“Tɨ¹_ ]&®RL¾%)Tâßÿ&$ŠÍçõk¯D+¾¼ºž÷}×+©ïeo5ÄÎï¹¼_ÉL*7$⌣š5Í?ŒFL™JÞ{Ѧz]a[èQÏYr:Ð\\¤éxûùóËd0ª^J«¸*ì¹ÏƒÑê$y.’->¿f9ö9÷Ç4?÷ýï×77Ø,]½¾Jªß¿,Wýd|#‚%@É~ž Ñ€±Žp×]†3ѲÖ4ÈÀÏ»Ï\|æÜ ë“DŸígßæÔy¼Cü Þ!þtìXʼ¼ãZ­'R}âeQ¯óoý%… ÛØ´Ka’{ æ½È»@ÌÒJÎ%"]õÕŽ»õ6Õa;%ºýCW¦•pìÃëšy/È…E‰:—ñùÞQüÂê£4¾ÝQÚËvðû›ÉE Ê .7W!ç@„ŠS~bÐ[†Ø¨‘Ÿ¥å¨Ø"ú>¸ZT”…9¸áLó&·6¡ïTe¤[‚hg4¹—·yŒ+ç7SlÖ%.ÒšsK4¤ïB±D¾×Z'õãTœ…Xu£7kß; ® ŽQ°n¯ƒ§x´†I¡»¦‰ FýhBŽH¨gÔ;„E?/a^·‰áÜùa¥œ“¢W|+c7fC2Yob‹¥wïÉ:ÆÐ(% IH—&Ùƒ”;‰ÚÑõ%a±ØûíÕÚW¶d˜±ºM½"sôŠ#ÓÃÖ¼ÎP@ÙÃÛÊ“f績WÑk¿2[ ¶ãYoz"Ñg¹Ù¤"nòõÔ&WW™_ˆ ³¿WŠ]Ú·¯‚ú×ÿ<2k`êÒSTÑ7«–m.þ‘WÖWÕ¹'Ñ€•ƒã‹ÍYþ¬i;„׳œž>ÝÍhAl_d’c÷ô†æ¹é·k²KÒøÖ‰¦£âo4ÎôóÉ8ïÊ[®ÜÆÖÑT0EÈ€´í†2ÇV[wlKâ„alHºÙ3àT}@¢¦ Žû¤Çç¦l~èõ¢QÏëa!øGÚžž23¸Œ( (ÚÃÖPFö)›’Ê16Nð„2€§À)äíÙ?Q‰ëkÁIª.i‡DUÙfÛª°ò¹Ojí¨7B+YÇž[JS¦lWÔ} I£†Œ”yɉM)Ʋ–ƉV.ÃqGìÍ‚:Dî]qu7ñ{Ù€ðùåz›PQĺŸÛ:ÅókÁ1SɺŒ'½ßõN5ŠðÆK“(@? 0Ï-ê*lÛ’| ÇÖ9ÞÜ…œõÚÙ5í°Ž¦/p;±AÛö3oÓ „æ^ŠBµ£àÒ éìè’[Òfvwý;!K²}{sÏ7–qÃÚb·´“÷U \€°cÄ/4g‰ÌW´m#NÓá$¤µñÕ¦8þZó!ä»" ˜r~¸M™ÉXÉÈ8qÉM*å팢 ³ÆJTäGþxøt71Ži‰¤œZñ|j²'„Cäôú'Àb×ÿ,[û3ú½áö¬Éj ªEŠT\&UZy[³ñ—éòŒî4Ã^j—ajËBÜiñSˆù¾ÍkVñŸØoX¶ ¸F·”>™‡ o)<VÎe‡n]ãûìÐriZÝk£oSçv“Ê«Œ*ҵȗYk]íä—f±›߻њT=°n#ºd  ãÉ$dþ +é"$Rë oØ2E©ÃGÈuÑžF\.ʯ„Y;ÎL2í"Ž,ÃîsÔ¸ˆ3nݸ¹…/Þ*îeÞ†7ß<¡N$¡ä\ ‰¸|C èºàkÖÚq£àڣʺg¤ «°%+²Ü„ù²c‰¨ïÁY#'Ù6jæâ[iýªÔvº¶ܺøBP ĺY7ÃY ËqÅCBÓÞœníÂS»<€Y\=õû™HD:\Šè¥¥"Šjxån­ôÎäì,¼AŸ³Ì‚osdt1Ç%½›²aef ºü‰CiˆHK½.aÙhYÁjòy5)Z•#Fó5ïrœÞV¤Qàòq^¢ÇÆ>¬†gKa§)†|TÍÝwñ‘™‡ñg­?Öªzkk/ôBÌ[‡9Ó8-êPÅŠ Çî®sÏ}, :÷Ñ 8ÇͫϜÛPuV²ã$ æß ‹à^E®Wͨ6Y:ԫꎖt ŠsÄ1_ʹ×'¼‰:¡r*^§^kï½ÃÄܨ‡M.v«gçÒOÆe'H~Fh+!AoôúÝØŠ/ó)7>JÙŠì6'šºÈ@öõf÷n˜Ê»‹­/<~ §ª·Fu¤™¡IQ(²GdT¶Í[çW=Å~4.HzŸ¡ÇíÆQ­ý34Ý998hüôg¡Õ;­z* À&"È]d3Ø¿èù÷—¬·üë¯Ë^£Ù­·j€œ»/cÝRãècQtËVdK¹Ù²"¸"Ƴü(£2>q5åy¡+ÏEA"ÃO ˜Âx•F`ʹ:tOà0ßcip¯dd±«—ôÜ—í F¹1, ‚•Ôh õæÓ¯KÁúhXI.[þòP¼Û;þ¢L :kÙ‹­ZîõßÈ0©;ç%Eá¤,=Œ#V˜å[ÀÏ7lÐ7(ÕšûíVcŸSÍÈ—½žxÝëÙ>ÔºÝôîW‚_}Ù£Ô'zï°ñ†SØ”•ô2DÛA9툭2®x˜ Îy:CÙ>)Ørò×y+º¸Ä½“cŠèEBV²2‚%·÷v1c ­E¶ÛVÑ \jæ& qN$R~|‚ø0Lp8ü[–Hé‰Jaød¤~RõG=¡^~Z*JΉhpò [°Yyj4Ó!‘­ä¥Q=p¾ ÖŒÉ%íQöüT8îPö8: ([‹S˜ ² ÿ1¡¬0^‰u¨T‰à’ä¿*×*jF‘'\àɘn ¸yòCO¼Éh<œœŸ£¾˜^ȃÆaI)€C§M&ýDð²´Naøv£³çµ:Ž8n:!ar :…QG·ðêÒ»òã i ÿo›5M½sÌ«Š@™bÉÔ>v-ß*Ï”¾§KL8/×XÖt’GQÉ F"€d…@1#]¨j3³ÇCд*Ï$4ˆ4ÕÑ(_S ®‹¸Dý=õžÚ©…°ŒÞEWdì. :Z(}‘%+ð Œgž¸"ù$ó\]ÓÖDîl9ë]c[,5›§¶hS¾[Ü)JTÇÌžÕ ì  ÕÊž&i%4ndó8R=*†(ƒÕEdi†©LžÃE©Ç Ô´¥Dpv–Òü´c"މšbȤ íù#˜wn^Ϊˆ}ÅI“‡¥l3‚ÐæËt:;­é¬¦ŸòY€C5Jø÷¿½áJ¡“/.†âÅ¡ÊÌ=¹àd-Ä—^t2ã˜2t[Xò< Ù‰ýÒ&Ô…ðÞˆdB,o†[¤ïÀÞ¤/JU¦}â!@è%§¬YŠÄÕüÃ5ó,5·ìNFî`ü þ4Úìü¦¦`%äì$€ú튳"U+Û‰‚Q`167ã˜n™°û Ù‘Ça§Û>¬73’wSˆ,"+3Û*¡BZQ‚˜¢„9 ˆfÀûð?QÂNž5£·Í³lû&.†–NÓ<üõVZÐ5ÒæŸ9æž‹ö¹U5¬>g÷:ËøÉÔŠjìοˆu;¤ÈÏjÈ]Ç@ngîÔΰŒù”Còö6­Zý£4ƒD‹ðÚ‘K~z…d lµ½÷®,òû¡ ûô/¢ˆ‘J]¼yöL™ÆÍHW/{)LRŸŸ¢¾˜'[¹¹3ž—¶]€à&¶·j¦bfÉΓ­ÞÀ“§~¾,õÓÆ:%¤V&h!©PˆTé÷N¶¾ •Üú’ް>œ‚ãÛœúqD[D~ò£—eóí:ò /Œ7V’üª€òG y“¯­ ú¤ã~ÄÑ­Þ|>áîGÊ?S#5fPïæ­œ‰'ýc$)»cZYqÅúq2Ƹ¼=ãi§w™kO¸}€ÊXÙÜQ<”c¨°Œ8b¡Ó—hS¹7ÞööÞÕ÷~”ø+ç§K75Ç"<†í¢ÈPGrõpÀÌÛ§tðL¥ÉŒí"c zÎðÑŠ·ˆ=énEJ?7›½Jf/T™—Il¡JÓ­P*Ì]¯o6]}Q©P³ØJ¶úq­û®ÇbaÞȃì/jÎ0MeÉ© bl¼lœ5Œ’-+À–ˆïR†M‰(ru¹H·ç¸Å!H˜I‚77³Ì3RõÓ§ebþö<–§ì[\DåÌ›*µ÷ô;Œ¢“±Ù¯fümj×\Äèš< Gƒey»Œä³¼@Lõ ""ï@»´˜at¼”“m2W²‚Ÿ™‡E0#î¶æ‘”³à“mt⿃M° Zá$‰rų´T´+Vi.¦Y§µÌYQH}¼ƒÅ5Ÿ b.+í)]â7[ê¼w¦@bôM³ º¦¡Þìn[¯PŽÛ^ø@ ç@Îbºâ~ýÍÉÛ€–æI:pe_+Ó=˜ ¶‡ m{ÿ=ðþ;ùØIÛ#é™~‰™ò{Q§u öLA—¡çmÑU†›Íå^¨Ù"”bÅîU i4ðPšåLz`;BÕ «¯Ô‰†~Â;„3ÇMÅ{ÓÙ Â,jYF O$oïÚÒ^oËσ´ÿÜ*·lîÙ=ã>»†;Iù´ü‡#¬D¼…I¶q!þº6G÷<?…¡ha/‹¨eÁÔ“å\#wm:°ä®°¢5–»Êò×YæÔ–YPŸeI͵ªî²®ŠûË£Rë nùjq”9 ä¥{¨@¨mNúQK>s@`ý!©$ ŒBö`K˜Öª÷Ü{Û<9ÿ´ïmToHþ:Ý[ü<–½‘Ôg­aU毲~)‡Ï"Ë×™ÚÄ68syÛòñÇ¥ýU,mM¼íeÝ'[›¸õ&+¹êÏZ·²È_jÛ}ý'®[2Áx\·_dÝzλ:ŰELRZ¢hô‹÷ˆ#R»ü.ÉüwY¨l¸5ÕNOš”ï`‡J2œ~³˜IÓ”såïök^l«jÒNsZ=QFUš3SM/-椗;8y„ay'UÎxŠ/šƒ4ŠþpõšÚJ°R)Ð(S§i ©Ï„K޾0mè*æ€ÆAô¯T®òS®}± Ø¤Ð¸Xjl‘ÿÚµq.Ý;ö3ç÷o û·õî»V§‹ȆõOºcЧ¥„>ãpœZ«á~:g(®sÔÖûõƒÚÉa·×mÕ['Ýl+®>>£W-¨x Sï2·ë™:Y~VƒŸ¯¶Ë©g’¡¡ZRÒY£{Ç­v·œxJs†ÕYQsn{œ&Ç 0§9õÍ«ï7;ǵ½ë]ŒÈº4×Í2¯µQtYjq¥k#ÇJ6U$¡sç,÷EŒÝ+%ÉR´ÖºŸDQÛ‹O¹Ð`0‰)¶‚…Åó-E´´ÃVëø ¸<£‘¬åaaQ×1ŸIÊpÝß&hìð¡ÑĈ(e{8"´®+Ý”½Òœi«8r ‰(”¹¹Sã…Wvì(êH‹ÝV‹B˜Ìlµd·jUFëÈ_gG“tZh4ß×Ëeq¿µà¨Dí">˜ÏŒWX¥Gñ•¨Áå]í*~÷GŒÞ=ô$ë®È ‡”Ü‚Â8 y¢ß°ÌÖ¦¸|˜Ð X0ŸM†:È!Lꨀ¹ç_¯‘ ±ºE£@ØÄe°ÑL¯ûóq½Wk¿ÝÀ\ÍWPkÓ¾9J¿T™îj[šÉ 8K´´¾‘…î²Ø]3xŽxzŽq¸Ñ’šoÙËX’„Df>®9‹¼@¥4€“•×Þ†õæÊy5v£½Z=[&¥oÆö]|Ñ€ómL 燨Qw4b;ŽÈ!ºã¥hŠ‘¢(ý”Â!&”öÅëÇaŠ~ä•®cÉHÌ&½ÑG$u³ú ˆÖ)e4ErSî1=òÔ”w€»&gDíþ Qÿ´úÔØ` uªö©¦ÀäÀ£ ¬v wµþ(žçì,*6 ÇNÇðLä/¶ÎXûíÁ 1Ö¿tÚÐ>j9ÎTÆEš¶QÈáÚ0#~¯Y¾QY­€Ûªxïàiùìt9WÚp” y¸¡ÎùÐÌ‘¼c•xü´ÏÈ-ú,–)³S|R2]3}HäÖ—7ÉÅ…vŠZ ¹màœ»J¦BîLWn²L¦=§Sû(4›ÈéË-›é3k+a;¡ ’TüÆ €¤Þ›y‡cN1bù”’o弎£‹9 æÃZyKM ˆ¼CjE숉 ÝÁ¿«èüä"C…™&72Psæx}åw‚±ÑÁ#JÅ}÷ïh‹{ÂïÆf u9 ‰Œ!ó­åUˆù‡½½ÖÑqã°ÞfáÔ}‹üè‡õ5¿º~ëΰÔ*õ‡É(¼/·á‹ï·ØÓó-GñG?¦Ý$ì÷½ªëœÌvŒ˜s÷‘l&ª{WÐ OY±w aR†w³EòܘmífÁô¦[hpº4#ÿ—Dåhÿ®íSñz¾6På׿0¨F¬â_^üVñV†:{-7°1ÖAZdŸ*&'¯2ýÚã&=RÌêË£ë Ê98ä¸âg&„2 ô… A0Æ:§=Þ>q0 ®üFÃyDC5NEx˧ˤgD(øgùlYg ¤LGè‡ÆBu \ÝNÜ)™tÄÄ8»LÆ9¹ê1²Ík9=x°/4Bô;$Ø¡÷JvÒÂFÙ1ªšÙjæëÙ3\—§O«ùáì©+2¨qØË}Ìk^ƒ÷´òÔ°v3ÈT.™•<0UΩ¬ .2C60·™+»oýÍRÄyÛ¶” … "Âoˆ¥{0jfäøKphüi°k|ÌaÒtˆ’§AnÓ¿‡B¶*Åh8VA/Ññ[D¼âlž^Iúmc^V·Iåø¼ô“e­è©z:› ŠòZ’Î3”<%Ì{s P´br¢¨Zë[Þ)¼KxÕ°cPŠ]à’ZÃõ³¾ñ½W: Ó$›>›m"ÇW[=¼'Æ"Òh+Jbð‡óËúÖoóå¨ÈTG°æ«š×8&{~èžY›ýÛÆo@bÀ¸?ídJ„’U…‰ºJ¤èÒa»ˆªüTŸ„ý”xN.¬B:·!YhtÞÚÍÁAEÍÁsïû²É!ãwhdJ8!*½¶,þßP\°Ñ ¬d ¨\Z»9;ó^½òJß{«žÕHY6`Sõ×h¤þj}ËrœâtbZÃß`MP¯áo«$n}p|æ ãHªŒvñ¿¬†¡P¯Ü*RçéФRpj1a²ÚÒ([š‡80J§ ÕhTf˜Úå‘ÍjÒ?–ŠèÏ fw¹ôÍY¡T¿AJ5×YÐ_ÛÞ~¾¾FÇßA0Ž wzëýÒ>Ø{ñýw?ü†ë¾ŒÓ€rgm¬­mV1+Éec9©ìê„i°zHJᤕª„Ò|‡7œð3 Øã—²z_!3½ˆ•æìtB(÷>Ž¢ë‘ØsyB±]3#Þ '±gT`ŠF@ž©ø¶3€¨’ãäVíˆtÚytœF#SE ãä¡9ßJ’³Œá™@Ÿòï7 çƒü.¶òûØâ>–²É›;’!bJ¡F†ɦmF*˜ÊsyP® µR¶`Š­\2ȤG!º ´‡’Ÿ3óãØ7ó~æ^úhÎZRl•”óá`fþƒ)7ä:Q ~Í÷†³bF‰Ô™È!$Âègñ‹Õ½&70¹3£Nöš»¸löž›gM\&9oúãÛÒ“¢vyeØë$³© L›K©œKsõ¶e¯˜Ù½m•Ëæüœ°§¢ŸOÌl¶ KÛEéÝ“¾hÒ2®`Ší’,½«#P»”3S&,àŠön2z8-Í<8 ²]ø×U*½2Š®±—@ÜUP ŽBÿâF²óÔQ˜¨x¼54ûx@;œ‘Ïn~y±ñ›Mô3,RBCCõœªlsw#u6ü0<j<ì<ÍWtÊnƒÔà÷UÓ3Ÿa¦w¿9Ûš„Aå—½« 2ÀÊ·Èu¦iZÿýÙºy7ÈiãrÆæŽÐ;D5LœÜ‘ŠÈ<Ùëpkõª¦ÖrF×݉8nQp÷½Æ¾MÉ8E-1çF9’66 ±¤É’Ç|Èî«&SOÞ6ÿœ3ÃêX&E fêv¢ëa]35˜IX,½ì Ü­·›=ÄÇŽSsU1h­J.`–ÍU&ËnÁj3“Ë»'îÕ”8𲛃K߯­d \%çÌ»Vž¶aæeóÊä~3ç2ë9:›45TŒ)Ý\$Í®;¯›_üþ5§ÕP¸à¶xpœ ýØâúÐQW2jâRÖ\º ø\߃„l†ù‡C3w‹ÏóKÝq!ä4ýøq³Ì&5z„£Ö$ö‡=,Y¢É³»03à9.ȳ*Ï¢§>ªu~üër’\Ò¸÷ûiÉÜwäÕF’ÆF+ð¤ïËæ³j7náçºkR+:û£TÜêæØa~ãØaîµÞ÷ê?íbÇvw›"c{)~±çDiË}FÈa@Æ÷ OGÔ«@ &%^ïâܳç_ ‹&äÍ`2†i¾L%kåçYÅäÙPqrÀOî [ÇÂŽ2Ó qwI–h-/Óÿ×ÔÏåo)¿7ŒT¦™pÌ´ d"¼¨•ʵ–]˘[pÍ5ÒhMF;X€ØÌ—¨düþ»ò‡Dy³¯Ø7-)gX«8«:Žm u zÿCc {¶í‡eM®œ`G9ˆ…›^2L£$ÄIO£!¶$=ØÖ×ôI¶Xh8¹¡Šr½>¤ÛYeƒ9å8<0ä2˜¼ÈPyž%ëfú’Bž<η_˜½FLB7âпu´¶¡‚ÅŸÙöð?JøÑ´†(q¡réwoÕƒÐùšÊã€#Ìž½A-¶wFc‰'ã_àçopØÑ‰¾«71á€*H9Âð-é÷]4×;ŽAK#È=¿!üŠ- #£5WãOž*¹Ý’œ½ïä!± ›ará=ýö)uè÷)Ç ¦Ž¼öotàµÆX$ LÚ‹e)Æcˆ}b 0&7í½W¡S`´0ð[G{WVÂA€)ˆI/nØ‹(È`^òe46â·¼Ó”Ù‹qðíSóFËÊU!Ö„’Šª;å)KÈÀüÂ!¥WÔ·5ÊFq ”½nì @ê@å –5U\]¥nž=ûÝéˆtâC=òúQ±†‘ac”кö¶Ù—„C<²F)³’Ís‰jæ.TÈ^­Ùõnœ *H9m¹‹ADÎt\¸Ä&ñÎCtµÉ;@`ïÙk^9¸Ñ늽ƒb 9ÖêúoDTÛ‚&ׯùõ7™I{ne< ÒëÀ¢„ ÑZ ]Å·KF(ÇÌÀ‘‹T /«Èƒ CfÐÌ…P—ïF~s Xô,^õc¶¢,swÓ9G‹-¹&^˜5¯HU´ëQ–däó"Áe4‰½Xlšs6<*Œƒ8Ä ²·a0ÄD²)g˜]©9²éþËp¾Z–\«œD»[ÝU®…¤0Ò'tåEj{í çÃf (fNä-ƒ\Þxù²jü·l.K£{ÇäB`bs[§õÌ-¢M=¾Dßâ/™7Ntw´Š¶i«d Ø Y  J$ï´ö²ý·•%e„7D”@]ÄS9…²Q] Q¶ºk9j*372à€ÿ£¤ ÓE‹0 uïuꋎ‡ã cšàðüB¤:àéq€as0ý¯ç¦ÑìíÖ:ZÉL® KkV²>¤¢*¦*(ËýÍjõÍÝ[}cµºHÍ=QÓ9‰9Ê•{_Í$,ý¯¾„ó½ø™½sU½—¸kqãê\ªÊ6|(¢År&!µøð ·‡ŠµqUej„ ØDÏe>\D úC¼VöÑdÍR(Ϭ µï{ýøvœFç±?¾©ZA0C¿;8°Á«,q:¦ó`$ U87€¯s\ŸMFœJ²„»IpãcVWØ1F/6ž&^;¾ FmnÓ ‚¤‡§dCƒÏi:Þ~þüt'ÕËd0ª‚D÷ü¶ ?ö.¢k?_[¾¾ùüÅË/¾û¡ê'ãl†¢L]‡"Á™2ÉH¸ôc÷ªL» "ìi"_N9èËTar‰­ñ0KÚà‰øãÙ: Ç¶J]!Û$Hø·‡Wß=”TˆÌȱUV¨(t:ÁëõÚŽøÌóÞ´Z‡õZS:Ä*sгq‡BæÔ¯½Ø²u ì•ZZ),í•>ЉLóŠþšú¾ßÛð¿Cþ¡wOv%FðÛ°]¶Žz0pIV±‚Œ¯xúr ®Ÿ)5#D¯'ÿ¢ãõ*×îuôŠw&ÏÙ2nŽ TLþ+ߪ¨þ V¹ õଠ;ˆWf?ò¥Nº_/{íš(cÓ¥²÷ßÞÆË­r‘$ˆPæÄñD^°pñßi„åØÁÍúNþûÌû66!#:¼}‘¸Ï6°¢zæ´Ælî¼4]V3´Eè6+dsTerB™Å)Q‚ӪȘ„ºÌ4 r >ý²ö›HžUÒ´´¶£ëΈz”³‰y±0+°<™™ÒF"ÒƒqÂ;6¦Æ ‡În<9e– ô(ZÈ1X—?A[`¦O›•hø+ÜÑ7•ošžn5Á)·ž6äÓB(渲wÖdü½þŸ3òg3.¹}µ,–t¯µãÞ›Ÿ»õһɊ'^pÕßTŠ69ð ¤â mÊÿårxw¡ob,’Ü™¢#öÏb=ˆÎ”¤Ž7 TÅV.YX9¦I?Ñùeño¹ƒËç-\™“á#Òá…JÌyJgÛ|¸¶òáZZÀíÄ‚—J™lU<ã§öVwJ•ËöèÁU?©!Ž,sKÖøä ªÞi€æ¸d÷Jáè°e¡ŠSÉì(ÀªùòNvÒåÇ_fÔE Ño¼œs*0 üÓÉ—Dˆq%Iiû‰!P­yýÓYu š\<a[íbìêÓâï´ü þ“³Òä(Iw ’ÚýÆ›;r6F[`äsã@´\ˆù}>Ha;¹ÛÐ-o5|³]8ÃàïdfSÓ‡Mm È‡ÿîä~γrâ! ÓÀ9®â ¨ºŽãüCÙÄÄS2›‰Žwܨ¹bÊ~­[SâǼÑÙ%˜;Ssî’–E>2™S"/8ƳCР3üe$‚,êä¼Â<” ˆ§Dž›’$zÇJ„êºeâRå%!d' 3¯BemÉo8¬S¿ w‡Ñœº½7µ}·,š/RV&¶ŒF=qrÆòkïÙ3+ [n±¼ö`¯?œõ8}íZ^ ø|Y±*q:9§™ê¿_`~•üš¿§˜ÒÙþfÐ)q°ºÌ¥5&ÞžöÒHPMÙmSRŽJ4â“Þi}¤;‡5y ý´ô_ÿ+þôW¿«ëÕõ—Õµç2‡$*?OoQd¨öïßÇüÙÚÜÄ׿{¹fþ ^|·¾¶ñ_ë/^l½øðýú‹ï^lü—÷—B$fMýûù³Dþ>ãÛµÆÞú?|_ñ6ÖÖ×éï蘈 °#ޱý‹ ì¤iâ5`¯ Ó 0ÛèÌëý‹Q4ŒÎo¥'à±N£™Fx¯[!åyÅ»ŒáÙ-û×н-<'(òwŒÎÒktžå¨‰7ˆúäUÀ y8:“Ž'10&.…WIÑ$ÅÚgÝJ¡ã}§aø)ÉãUÈ™>EÀ‘B^Ž뎢4D¿·ñ8 íkEcÊó;uO£ô‚åÖ¥bèf¥GŸi6á,KáèkZëèŽ(ôeý<óŽªj·JWgpœ¡;rÔs®xþ]´BR,bÆ“ÓaØÇÌǘdSxÆöšvõP-(/Åûï:A°á=<¶«Fƒ³+Á¹ô?o ¶ra‹æ³¼¸ˆ´¥¤Ñ ‡Rt†u ;ªcg6ñú$^j<_Ë>^~,cM dp3&7 ¨^އè8yŽM£ô–]I—¾ Gýád@m!øMÆÕ‹å%+æl³ÞE3Í^£Ù{GélEW£ Å{¬çá¨z±«´}vÍý7ÙJƒÓ‚òµöqLB:~<öŸcWÓê‰HªyU…)׿h;ªÄ²ú¸<³iŒ&TëN顇*ßÓj¬Óm7šo;Ø€ªŽô6:Oì*æ¬`ö9Šø™H~|®пÌ+J"¸¾„-2z~#+¹¦E¬Ùq¾ý¥”ÚxVu´ÎI>B-\­âê±vÜ0ƒ=ÈŒz"GÏ„½K;ówœ›Úà&•qŸ²x^¹ +ÆQª‡·0 Ý™Xè*)™Õ*ÓN¢ŽŠÚ§;i:D²ªÏì¤Ç Î|a¿Fm2;º/là ˜mO|·LXÄE(OëÒTÝD>iU4a9݆Ã@e˜ÖkfΨ}<ÿõ|ž§”7ê9¼ñ ÏÞ}NÏéxë>=ß©k|u¨÷H…\²Z² 7f….¸;[Ó`Ìwk~HÅ8ØÛŒq¶æÁ‰ÛTdת´¹h“ ûZàS"wŒä®‘Åãrð&c€qÔ7PœZ%ù XRKÂ3 ¢ïIާ~Â×âÂÀ†sjȔ̬š¡Ô‹dÛyÞ2_œ4;Çõ=Ξ¡âÌZ95 ­&°C©hê6ŽŽéæ‹Ñíº(eÙþœx¯}°ç}·õýV¾ÿ3œ‰ƒ6mËÕóu/ËàÒÂÐ íºš?í·Žj¦aF$ðI*ÉP¬Ë¶säÃ|Ð:iî»P›pÁU-fÉ4$Ù”& $‡²5v±«ãU#¹3cÂW4{EÅcza šÄ2T“ÏÔxñšÚ Ó ®7ÏøêG³/Á(PvÈf,k8N„÷Ôe ±5®Êw^~7¤öˆ`»:Žˆ>rÕÛ ÕÓÿÙ½TAAF;K aÀ$Zcô’¼¶D'ù¥áŸ›/3¢‹™‘Öfdy)I¨[k²Ãh$pVBy!›òûý(ˆ³˜Ûª  S’‚|¯Õl¶ë'ú¾§­pÌð:+ÏËY¸» VYç“¥|ñÄÖp“¡®jFk[ÑR¸Ç;Ø<ši:*WÁÍ )N¶¡§§OͤAñ¾Ù‘±2­xÓ&xŒ·¹®^)w h÷_ŒtãìBSª0‹Îøì±{x¶ðËFEƳC.qÑüq£ä¯À<ßdyÅŽnk¨Xì âíAýŠ×ía—Å›¬µ¿Ê&Êùî‚™¬R3¡¿?ð¹±!˜DwæÝ;'5—ôÔÊ0…hò¡8ÊFïž:™‰&Ùsð4‚@2Žƒ«0š$€Iz-Îiß8§4B¹VWä”Gyr)BH¬UDðm#Ç3*ñBœox}ŽpÉ_…”$(’™•4`ÓTÓ¬D¶ŠÞSon¥`‰Zפ2`=m0JãÏ:FìfqH¨jï^Á™¥ù¢Z0n"ÿr>C]&L Ó(IäåP¶pOØÝR§´dq NO„„'¢:´Þ圖ü–óÜ@¥C2ÊsÇ DY(Kkë–¯‡Ú¯y¯ú–¦{ù̺mÖ^‘´L¥bþƒ¸ÄKQf ”“Ž’I,ô^‚öôTöN1êEê¨K¬’Òn˜9œŒÝ®6)’(êÈ Âk3¾ìc¬%Ap™xÜE$eJ8. u¾ä{*ÕoH+fP]Ks’ÆÕ~6ÿß c;‰üÅ5@…ZRÚÊÌÈŒn‡÷çàÆï§ueEX•d=¢½Éƒ5õöí›!A ®®ÒÊçjrxòÎ'>ò¡1 ;rÚu^©È1ÌÍ%aØî‘÷µr ºN©F,Ô\W~É)ÿœ«ÖZq}…iǵî»fÞíürTû©‡$Y^ÃF¥\ŸåQÃ[‹OdqÁâ‘QÈw%½Éêb¯”^³kk‹½ôrlCâyï~¬ÿì]| nQ!ŸHW>hªœ·ÆÁèÇà¶~S+a±Þak¯vØ;ªí½ƒ=²Ât |$&‰…ÚõÚ~3z¢ú!á¥Þn·ÚùÄ»ÿ¡ÕÞ÷ׇr»•PË% Ðý·Ž÷MTMWà¢ìMFi8”*”‘èF¤\µó'…!çþ)\ÿ $åu×–Ez·ã$äVªxùÇ:& :ÍÚ‘R›Nˆè²µªC ¹ c@@(ÆDÏÇÕÕüE¬€ÝÈvc6°à€7ŠV!¾±ö«×4ìòtÝš7R4ìÁÔã,?-ÍßÞúŒö>‰C²JfÁ!™I=-i‹ˆãá©ôx;L$y$Ì 2ÂLN¬ˆ¸äâíô41^òfÐ >TìxËŽÀYg[⻢/̽'TZßäÜÛëœGùUYbÇ[/ÞºìuÚW[ÊÄsïT_¿¶ÊÛaÜæÙö #ª“ÄÇ2‚ð€Ed@ŠQLŠzž1W™RFÛ9À5ÓaîV÷Åìì3 üÔÍÅã–÷WÚòl•sÎÆ·õõí|0ÛûßÖ׸B~¯m0·Õ?i3üÒÎ.3ƒS}î]qkú¶èì EÇVeæ¦`P » ü×ãŸÿäø/>wü‡µ­ï¶þkýÅúÖ‹Í—/^¾|ñ¶¶^<Æøª¿./ÁN ˆã>ÈFîù+Þ#ôV¿sì¬|çàfå£?`Õ»‡ÀÚ÷ˆÿ`!|‘XñÎ °òC@`Õ¹b@vß±Þîm½‹ZÜ7?£½­÷£‹{ÿwÛ'8”ë¼óðËR–çy¿®­£³U*# £2 .,@•;?7[ÇFg©:‚ѽñ¾5"(ÿ z|Œð@Š—ktNat-{°²0òÿõ¬áÇ翞óYY¯ˆo ¡ÿG¼”fyTÐ=gÁwñ>—%sùáBUñ“Z6¯>à–€x–G¨tŽ•¶'~SgÜYH˜Ü¯wöÚc4±\ê"¾ÉuI…†ÅÔ$¹sƒWÃj aˆ'\„b\K@V %QÊõÓÛ¥j£­ ªØ3&‡j åÁ7žiLh(c΂ðmôª,éíy÷‚Ö1VfÔÕAbROÀJ”çÅ3m>"s0ÌaI|àTÞÁ’°jL(hì0H)Ë…Ÿˆ[>"Úà¼wcÌÙk¶j¹Š>Î\T—ö¸â ±¼J—f/Üf¯Ç°´Ð¿eK åõ§¥Á$æÞC#Áb'Èwh–)à%/½( È×€Œ4Žnù5´¸$?ô1#ûßW‰z»ä6$HJæF Ãï%Bǧó,Ž.™»åQ±5Å|ç6Ì‹n ŽdÔ„±0iî/½€'ý~ ‚é®ð%­›x˜Š!~¶Ä¨º ˆÓ üžEÃath£S|² LëØÂn^9ˆD ÂÉLNý€H’³ Ú˜¸Õ…£7U·( i31ÚÏðŒ¦ÙF QB”8od;xSÛ'ÞÙ5Ö~¥F %§OCÎ?pfyŠLœ½ d |¶­\²·Z+£ŒË}Þ ñæAŠÙ›v' ©|8Ðèç&Å<”(“ŒPnrHWB4@œàÜ0Ô‹&£A^Å£úÑÒQpáôÑzæÂŸ`følÙ½Zs¯~xXç^˜°° ¯a^Ã]–arªâw2ö‹XpÁ`Ç bbB¶P¤5cÕÉÍg P]"qãäŒÜ6> È¡Upì6¸ ú–(Âébâê$)÷ÜÄ-ÁÒU<è?ô¿¾ƒ>XlbÂa8ä¯ç§DÀî_ñ5<߃€xÅ4’AzÅ=ÞžÔ¹ pj‰¡üy±“¿y„VF‰ÌæÏäI›ÇIÜy;WxU¤âªƒQ/¥»—òNÁÉY^iÊÌc«&£nyÉç_ T¢%_L›Èsty‰öòKþa¨ 8˜)€éL¦NÆ@Ê:o“À+‚ò>Hù}íð5BaÌKA§å%÷ )Ð@w•$­_ÏÞøgxB”HY¸h™†YRg <ã¶Ê¼šâTEÐBR’÷&B”ƒáV,7.¨"ÊõE4¤>ä¿vµiz°QŸgº6t*º ƒ2רZš«ÆÖŽu‘|‰6û§”òM’(¦ëXâ«Z >Iøž þ5ˆWr–LrGz‰%­w0&Mÿ®KBùPuŠThO‹È©šÐ$àg&)<qÓÇmB{C¨ ‚ßRG„c‚Ñ$-môƒcÏa½é•Ö·ÊF®B"œ’ŠG´ŠnZE—DÑ­r‘Kî–€«Ťlû¾Ö8¬½i6º?ÃÉV<°0`œÃ[Á—á‡^:0q,]˜è‚¯äš‰k­ºfŠÌîf»ôåå?´~?ªWûøîaE£)ò~ÿ"ßËÍë›ëk(ÿ­omn=Ê_nþ—^ÓŸ%ÞDÆpºôÏIÒ:õQr%:*©®{%)8€fóÊÕŒ¸8®0àÓîò/vÃhoî{I€êÖ”ù½€ŒÓgF¥ÂíP·þD‚¶è½zÍv4Š @‡7eÇ$`tW°¥ iÉaTtfB›š´šÜ`rЉŸ2žŠþÅ ®}>¨SX܈Â}”Ý—ú“x¨/ÁÙ\@'nÔƒ‚ Í® `7Dq £Ç¬Y!³BüïÌ a4›BW:l5ºnabÉb©$£LdòB¨`™ˆx9I-݈Šsd ·=È+–y*žý·ÒtÈæ©ðcjlGNV.K: |ñãïÊzŠ\„~ØéuÅ‹ã^÷ÒþÐÇKð‹‚þá§tˆ®|2È%˜¦Ð#ÆoéöŽj?íˆ0¥×íâ"¤«_±P¸;{@%ŸQ00<(æÕî¶.†Çi¬]ëåusÅ[õ/¼ê­HÏ{n¹Øð7) J)£-饯Јb !#ÐA‚43ám¡¡îø.]²Ë=ata†x°Ãk¹Î†ØîtFÐÝu b 4HF´ê· ºc-¨€Ä«Â‘™BE— ¢‡‰ÖPÓ¤£ À,y¯¼wŸêûäø6‹ u²§ƒÃ9‹«É„vÜÏüQr¶"H’ÊpÃîNP.€½ß®P¯ícúûþ^ë¤Ù¥È”Il”SªÖtJ!è²½o^{ë³áfŸy½å*å0x_N>†cL“Zßd8‘Ä1üLálgɻ٠¨³GL‰âžŒYò)Mu& §Ud&žæ±êx¨Š™Dàžáªƒ¿ÿ.`óv%´Ö´D7b¶ ʹáG"¥¥8÷ôÚé*q_ÙŸHd9ÁlFå€lAö¡k2â`Ç(~å®?ÌøENx~ÙêÊœî(dIíä»LÁMqJrÛóÂdÀ©¥ÔÓ+Fb` ÙãÀÇ-Ü Bý™G¹ôŸÌ¨ .Ú­DŽjv€–‘,LñÄFºØš^>)/€óˆäs4‰û±ê•Úí2Åpp«¦“v³  Wr+Ìz[`$«€;ãrn·‘G  Ùa´K#ÜÌ=Ö±Ú¹Ô2vbaS ÛvŠ×‹ËlC¬îv{ÊÂ.&›EŽÇ¼µÊ§:8 ñBpèv»×ýù¸Njþ!]fï°Öéd )A§(rXof °L"ûéÚ$®Vr0&zù3Ðe½SyM1MQÒPx|-BõmñgBÏë©Í®cmP䍨ƒ¹ÁuMu¸a^€v­Ó`*B¶h”Våá^ë}¯þÓÞ!-jíî6ô tØ{>¼;gOÓ¼“Uà„ÇQ][ÇY@”“!…ˆc~÷[ÅcÆ0·{a6Þ±àœ¯l)uú¼ä7„Äë£,õD ÒÇ©=µéên8Þb;žØEfÆ 0cVV<ó<+vÐP{¤b׸+á幋Sdñ~+öHe?âý½šMïM aà¹ÝÿÆ—ÉÍL"KóO»l ‘ãd‰±vvÚÏù6j<ôÅÕ2ð§óU˜V ’zÜi»§ãé ÑÜ€^¦€0¯KÓ3„@5zš×EaWQYL^ñÀ6›P>‘ 41hõÁ® tlS½à.„ܨ yálù¼;föû¢mþÎŒiñm ‹‘¡9j%f}AqVIÇh@xÿ ∲³D¤}õ(¢%O€¤Ç„{ãÈÁçæk™ ªžŒBÔÁ©8ñ‚”ÎAàG)ž+!N íðÉÚ!b=bÄ…I,äûª“ØVl¸lIëkFò9o[ôþ&?lÛÌ Êxfç„¢(F,Q:¤ÔXFêp2uAïß\ ð½šÝN¤pEÛ/3¡…¢E9» :…_ëÂÅ;ˆ¥åGãÊpí<Žmﲉ'œCö…-<’ð$f?¦Ó“ÆK¨çfeØÃà¶¹ÙXðÃÔù…¬îI\PÎôƒxNÏV£ÙÙû#gGpâËñ!ì-çŸ<ÙÈ“`ê’¿ïL/¨xZy¹8?Y¦†ŠA=OøióOfm²&7»@§M,¬#”µ'Dòð·9†Éõ…LœЊÝ#8fÎYiÅ‹vÐÐN{^^n«Ñ/oýgÅ =39Ö 5P†oü±T4uRÃgMžÁlÂßÊ™€ª C˘ƒÈy'±ïÑþ#ÿ¡‡>eAœôÈÇë¾~ 3ìÿÖÖ2þ›/í?¾ÿG‚¢ãèEfê«/-­þ×­ÿ«þóÏ´4¾{ù²xýÃrYñbëÅwk›À`ý¯½Øzù_ÞËÇõÿåçÿª¿å_'ÕArý¥ì¿7^nÿߨz¹Žå¶ÈÿoãÅwüÿKü9 ûq„öWÞ~p Ñ›Á뤓Ay¢øc2FíÆ7¯xì õ^80lU×ÖþÏÒ·Þ‡Z»Ùh¾Ýöö[^³Õõêû®×j{ûõÃzιïïC«ýc縶W§\ ßüŸ%¨ø°°Éc6ÇÞö–ÉaùõrõWúõ+5ý²/{«Þ±°En]‚øõ«Í]ªÎ/_¿z üñÇÿYúôé“õaÓùðYÇàÓ=e|KÃ8ùû¡ƒBô›àΛ¢s …q0£þ-ï{ð¾×Äã$!“¿Õá\šWï‹ hž3zà¡þ}D‹Æ þ"Äàÿ­˜y;ŒNýáö|£|ñù×øW½ÿãzþgËëèÿÿ(ÿýYóo°ÒÏ.ÿ­¿ÜzñÒ‘ÿ^l¼|ŒÿðEþ|ëM‘%›¦¤8«rò×¼éæï"S{@9 –ö†´þS…Ê•Kœ\Y!Vìukí·hAä-G/6¼ÒÍ÷[eo/%@XsBÊ—µvƒÇH¬¶wðö5 0s­ ùGЖä6Þ¨§“óÿ³ôÍQ½Ó©½­«ààFP*º^Ãü1U¯«¯-Ø3PÄm6j?Ö+FSè5ˆZüú jÒ¼#Ñ yÚ³)ìÀ‹'#£†ñ“ZóžŸyËr=ËÕüÂ?Gòw—¾ñ”wñ,<ŸÄ"±Æ‚®F N£òé-§J’ñ.}˜F'£éIx‡áP“†iá0¾Ðö" c‹L@Óçb9¿Ñã(IÈI²…}áWmÚ)€¨¸ÛýÃCÑ­WRþ®3 ¬ì¿î«ÁMð–Ú½×qŸ4Ï[þK@{åe¼ˆž‡rê s±y'IÐ;:Ø3@S¯©Bïbv!ôëv‘Ö$O@coy0®Dûf n'B,:%ŸG§ÿtJwñ>Y´¨?e!œÜ ¸æ©q>Šâ Ç {2 È@ZÛßç1ÀtyÏÉ…0òží¼ç^xÏßþä=ÿGè=oÁsÃ[®V­V—½çûÞr2|ñoJR(^ﵚÖažö¡þ?¼ç}ÙÏ肆Ôæ=Â~³¹öƒ÷| ’…Š¿¿éì½Øx}šôqsar5Ú¥¯rê‹ýò°Ñüš®ü1SŸ¿1eªC˜˜ëd£÷bƒ~úƒ+ЇYq(Ê’ÉiBqÚ¶ûb™?Gý˜s…·GP„ÈÁ{»Åì ÛßoyÏ£Iºm 1€ ð7œâU1¶ Oǰx·q XI£©6Žð&@rDÿ!ƒnT?ìÔãH’ ߃'­MçI±êa6We˜/­ò¥ l €õ ¼IóÖ†Ë3šsñŒ"–ô€-çs¢æ NÔüòœèaÖ.,¾mJ R´\%9 6JòšÎrþ P/Ì[LqûsH;úœÒŽ*ùE¤¸æék‘vàií}ºµnc¦òˈ@óõûW‹`‚ÿiBSÖüÒ„&ÙB>õ0ž;q°Ï+! óJGFÙ/"å¶X_tTÈN>È4»»¿‚%WúJLÚ™*”˜´8“EýG^ÔÜVdê°xUðVIÍ¥Jš«pÛXÉ3Š›‚Û\…Ͷy$oãh2ö–;ìBªøÄä ûœÜ½0šÝ²QÓ¨‚:­“ö^ý5-Cº†¯ÒZÂK^«ä\Õ… b4NïÛÊ(ºöãÑ}[Ñ.²÷hÉŽ=sßv0,{QøŠ&63Ïï(¶ÆÃͳ1Q2Q6Q4Q0QóL>HÆò­iñE ²÷¿ÂºèùŸyÿ¿±ñâñþÿOºÿ—óïXš}¾ûÿ­µ5÷þÿåúæãýÿ×zÿ/íÿr6𿸀\“Q[|a0×¼|›€i]?„]À¬öïo0ò>_ûÿ©6óQÆ£À£À£Àƒ\­Ëá?ÆVàT¨Ÿw_y´x´x´XðöÝ^¸%»»B~'>óh?ðh?ðh?ðgÞ·/$aüEl`Lwæf¶¶¶_âJ~– òUÛÜøym æU=Í]!Ƕ`^Ánî _ÌÆ@bÿÑÎàÑÎàÑÎà¯bgðøç¯rÿ‘Bž?øÕø‚ñ^®½x´ÿøçß óùã?l}çÆønmãÑþã+µÿ èB9ã £û×¶ü ù5ûP° ›ÙÓñy > û}k©ßßÔcœ}¦ÆÿS<æ †G G G 1ˆ =à?Ƽ㾣)¼¥˜ky4ìx4ìx4ìXÐ<ÂX²%«Ž;½8{y´çx´çx´çø3mæ)þ"Æ÷ÐݘأǣǣǗ°„˜*™|Õ6w‚|^޹ÔJó•Î1ݘK€›¯ô3Ú t?ZlÞÿ?æÿºþ¯¿Næ¯Ç,E¾Fþÿ¹í¿6¶Ö×_fùÿÖ#ÿÿ:í¿˜·~Uö_û·#ÿ2쯆£ëÈn…ØFq­Nê§aß)¿) Æø,Î#1^µM#1 ;‰LÁg1 ³ûšm –Kråé-β¢Z´ÍÙf_‰Ïhk|SZû‚^y†\E³÷h¼õŒ·L »‡¿Ô¤·oN‡û¦vž^À)£tÚ®µþŒ·›wà¨{øú2d‘4LfŸ×H©²è¬R¦ã_çFu1m>ÐåÝ ±Ä%'¼„…°×„§9Ÿá­{ Yp#ñ×»èv´xçy´ûŒVcóñÅ;\WNå@x-:«Ÿ¹¹\s..×¼#—ûº®^ïÀ.æ¶üGð ‹°¿3lÁ{.¾ºléþlîÏ‚{>>÷h¾¶¸ùÚ×)Ù}Qc¶ƒê«ÒÞÜË[*pXØ]Áóµì£ËÅ2Ö”@7Ø[‚ã%[#(máLß"tÏ—–$¿«½¯KB^ G©Çw\‚é•0ŠDê]EáÀ["uêǸâaùQygéÛ`˜juØ-ÜTn+ÿ*{ö#Ô…/‰=X=îšB(¿ þŸû}qÿo(·¾öÝ‹—þßÒüÓ üµJZÙÕ$ò«ýþçÛÿ¿[ß`ÿïÍõµ—ß½DÿÿÍï¾[Üÿ¿Ìþ?ê'Œ#§½z±¼¤_FÉ*°ß4Â×úý«µ®þå®ñê Q¼»´DÇ#ò'?ŒØ¼XêÖ;ÝÞAIøuámÅ;FrëD~¯Z?–¡œçí7;èh¤Þøcº/àŸ*œžz¿‡ƒÒÚÍúÆ‹Í2=COc`ÙA‰}¿T†ÒžWõÔÀ'¸•FÁ56ùwù¼,üÓªýèr¹â’^Š—$e£®?J®ƒXÖDøÚnµõµµ U(ü³ ®WíZËgq0°ßMod„¬Š÷¢âmV¼—å2b#IÛÛŒøW§·i°ë¡FÐ{MhŸ%(FåâI_ìxê·|,;š ‡ã4Æöê?×÷º½úßKl8u²·Wït*^ÞR‰”ÜI…ú­&á¿|xB8ÄkN½Ýí5ë%ÑK;-Û}åa‡FÆ÷ý%ø¼º;JŒÊnÕ,³UñjýÒOàHìV_'pVwá4úCçã†øÐIrá|}¡¾¦ñ­ómS|á$ŒçãKñÄä4å>µ…¡“1ôiŽeRÇ‹äq©Üy©ì̽8 àóç^3ò$†ªÅò9éUûCêKÔ]Î:Ì,¯ú›Ú>ü{|õ…íßmÚvH2FÁx¿Ñ©½9¬ïóeMï›×OèÔqΠVÀœXj¶ökÝÚ=‘tWè‹Ñ'{ÂZ÷ZFrφ¿(ñ<<^!âN› ú³Ã“ I®~ÊïÑæ!G7ù,„ÿZ¾¼±9ÅÇÞü#ùª¸¡âe³çå ó±¯iÝx2êS‹±Ï¦¿EHBmF GÚK½a0‚ïë;ô㕉zõìoá÷Â,´cbôÓ\zç÷üpø(C<”¸½€@A$‚ª¥0dò€_½ö^âM{¸qŽnÞó:Aª&®†âmvß<ªÝqMz¯^ ŠŽ>íÛç¸ÌKìèñè/|ÿCú}â¿—Ög^ýÏææw|ÿ³ùÝÖæw˜øq /ƒ^>꾬þÇVôÀºnˆ/¤Ã Ñçlä=ŠK„l ˜³GåûÑÐ)²§%[$-3–÷Ù7lƒd+˜ÒA°ìÚ¯†á)¾ËSDeÕNK†"À{ÜìO.Ç¥|άÖ(Ï­zIâîäĩטSÛû¸Å³û~ìNÎ΂ø— ï™·þóèd ­§g%þ»Ò¯mÜ,3 þ% ¬¾›n£vØøG=oU_ݺ‡­Ú~ãøÝáqí¸áÖ4¿¹õjûûí·õn³ÞŶǵví(o^™ Öš{õÃà ”¨Æ€Í·t¡“æÍÖžÂO.Sl÷£A`ñÄߨ,ÑxEð {Jo‘Á¼î§Ù†Õ2¦ŸŠ¡¡(ÔÅ2œŠ%A|uÛ¿.—eiÜíÍ ºôÑÑïOû­£Z£éŒR¼Ë7áC.æ¶ghü ‹eÖ2»Ítûs~··71’R³\»Ý©w3ÃpŠ5ó‹E©?I/¬AÔNºï²Åþ«Ø?ZͺSìÔ$á¹.…ëµñ6[ècpkú±þs¶z:X¥­Ý…ÛÝÛ±C‚1†ªrhÐx'áH{¾±,ÓÞ(1ÐÑq>^~´ï~<3>8û(!êï{6W’ʃŒ[.`—§FóoÜÆô½u?Ëè¨íŽw24‰ýäðÐ)pýÑÀȇ]”ŒS£õã®Ûüz‚êÀ]Z.xv‘£¼"7Æ÷ŸœéA3ÝŸºÎçxl,Òc磖 ¼Ö:û.jo6^ê?m¼t>‡ÉÀXÝÎ~Óí߀®ÝÍP›?6é­vœSÀÆ1êem­Pwy¦=kmº fÑ@ð±‹àóqdÀÛã–Kèfi þ8†Q_?lí¹ƒ¼±8š‹¤ 4–]½á®»Qxiµßle»Hâ+=í÷îÒKsÝ£ [ðíI¨egà£Ã]ö“öêJð·Œþ·œ›{ìçqpôÑ$€æNhlÐ:Îôoîyµc— Øwç?I.Î 2îtÞ¸t Û–I °ieHt”æ,vê{,$ï7;YJN­"Ýœ Ý,áÍ™1ÓŸ܉ö­µlØñ‡&·qäMNß.â’œ?2Rkºãø—Å?ò 0¹fí§;l²{C?±¾¿÷ñ•½Çšïd÷ýž)ô8âN¿Çv“§ì½«9L¥ß»0¾¿«w­}§ÀÈ]¹¥ŸÀÅP ÐÂS¡@[f®xW|ÁÑ:Z?{¯½éšjDë÷s@á™W¢+œ×Þfž†gseÓ{潘ªç™Tåÿ‹‡ÒdËa ¨É2óËÚo³Ë¬ÏQfcŽ2/ •N»šƒ_ß’£·o.¤>l}‹Õ`¯7d9Æ|ÜõÖÊ¢‡§ÛOwÄG ‰ú eBY–7Š0ü­èóu9ÂìYµ&Fú‡†åo–ñ©»b:#ãójåø:Í!ÞŒÒ퉸MÌR°¼`¢ÏÆ“ yýI¨!ç âW^³Ó{wÐø©¾ßùGÙu)"/¹ˆâ”Fë¨|,/3Ê2cfTp¥Ò>6çâz»÷÷6ëõx`þÿ†g´¿C£Ûð£s -î<̨×:Þkí×¹®ÍÔ"v§ß–ÿ½ý³·¼ãÂ8?îXåB»`£¸$ë UI vÒ)(‹gÓ3Ý*žLŠÚŒa*{r¼_ëÖ­²ŠÊ"ÌK„ö|ðTXÍ|³kÔ¨Õ$öDӵ𷼓-×ÝsÊu÷r˵÷ríýürn¿íü~ÿáûGn)“~ÖeY[ñaöm ݯ’Õ¾²pµb6½¿×:iv¹¸\Q#aa­5s‹ÂéÞ)Øìä ÜÛV9gɇÒBÿn¬TlWâêk÷m>3Ö·¯“½¿o•ÉËy…Pæ'ïÉøwø‹õñLb1n¬ãß§ô/p™ß{{o·súc§ã¢p š?é¾{ˆ`ê :Øß_¤ýYÛDffl3lŒ™â-„d¤-$íbx¨Å¸¢vŒ¿/°c¬Ìµe, `…<›,Cä!Z£>´#×Q܇"nÈ´’¸w²öÇŠ½'ÂT`Qø‡,˱A‹ß¼¶.‰Ü±‘žÔ;‹£ËLÏ36ClŸ»ÑgEáÝiº‚cŒÐµ‰P ð'jbÁÓðü<ˆÑ l}] 7.b6ªiº“`­¢Q»ÂœÆ|%@|Jí`ôÈÚÆV"dÜ™\†ÁYºÍȆìcòÖ¿ŸÔ;xáÑÛ;¬u:LlȲ̋ÝÃVZZ51K¬háÆÏŽEçµâ'êmÖŠ7øÆ]×úçXåívþ¼=®òÇUNí»³87Ýåë !NµÛæ’U.мVJ7’£ÚO'ûǯ• ͘<Ã`LCÞhd .“ ºaµÝíæœ5³¼Ìè~ AÿÓà‘ˆÅ7|¢åëMUÎa†jŽnh½7ÈB6î’D»í!Uð5(@°Ä R±‘™sßdß8¹/Pgn)–¹Wå$Ø…Ô&¨Xæ.Dj?,‘P»"NðÏõZS•Æ€ ’À®îCkPÌÃþÊøÙ³ý0 ÕŸ ÅÄëÍX‚p–ÆÀDEõ³˜‰ ‰ñmæPMð ]Ú«‰’ìLÌrÙ¬¥~‘¬[2¿øýä`™/󜗣Ä}C7Jõàû‹œ„â=fÁ}ƵF…œ—]«zÅ{&/o¶Í‘ÈÕ·ëm¸$8w@DwÄß<\‡Mb³ˆY]o}ëM£k1ÿB,ÏÂsf%8œŽö? è§iŒ„îËþÈŸ›-;S™Œç)¥(±YŒá x¼ø¸\Tö:  viœê”À2S~Ó(Ok}kgÂÿ¥Šðª K N¿ ÌüÙÄå®}²w˜k¯zøiúKðͱ-3“púˆSôØX›Cò°™{[K6ñbc:î×Nq‡«¸UÒø6[áû 쨭±^Ìé0ÊÑåä2§Î–QÇÚlĸõ 94ó B®Ÿ`ú…èöó±aeQ°ï|wç}'Š1ëœÏ03}Û!’ÜtÍLÚ¡ÃËt9ڋφþy’/[“IåvrDXõjVOh8öƒé}=•”ƒE3ûÅzƒs ªy:å’óôùŸ²‡{³¼Ì;–ÊËè9Ž£Ÿ¤&HÚeaóÀ®ßÍ£¼¤XXÇ“ä¢1J_ldG $¦CŸˆ8¾\ÝC½Þ)L}©Dß¼'ÞÚÍÙ{K•½]8ml*ã‚âkk\Š .;µ8W âßç–¶ cñìP×·j¨s"Èz*ÕI‹˜U3=>!²5¿Á.²*aMÉ&£ú§ÁpGx=·ö[Û㎣ÃyAÒ÷Ç:: ªx¤˜v¨”$®]ñžVŸ*A€¼¥ô˜©DÈï<½(•S™pü.eÕ`4 çf*|Š¡Lõ#}SJ,§ùµ²AÈ<ú\¤þÉÛÛÌ¤ÄÆ6"­/À„rÔš(|×S³ž78QQO¾ÐÔÄøD,~Rrõò?²5Xo~ ´Ûs·eeÀi:\† k`r¯…¡Ñš™(½âžcN#q¯íi2è•<÷ó9Fº7é=Q¡‡µ¦.êsêô¶ñïž\«X vÒ:Èð^`C­µB”Ì߃³\NŠ‘‹bñÁæs!Êü‰$†¡ YæJµ½/BøêKa*å\•ª¶îª0*`’¬¡)øHù¾¿ŠÅ]Ã-t´Tì݇{qjXü¸(Ý`ÜŽÏC7ë™ý5Ñ;la­ ·V¬+exÿº@Ÿ¦½ ýæåÊæ}6…õ Á¬ÈQy#Sy#+#èý—õ ½üB÷Pø5o ¾±N¢à£ÐO,°ï·ÆŸo—ãæANyâEcÜàï$³É¡å1| #jï.[Ýôn2-`_HŠ=±ÕåÈSLº¸"ýêÛcU@_Šïc<¿O ßÝåHƒéZzz â;¡q޲΢—YÀ&"çß=HÔ›kÖ’ŒìÔU-JªIÏ;Ð-;CžÚ¶*«ZWo Û·‘7µyYTµ._ÌÍËî½q²eýBg¶ìA)ðR¸ŒSä pW†$"ȬäSïßøí{úF¥R4¦EÌÇö3º9|¡ŒP|_×ZÛ”oÓ¾ñvCõ30Þ®çLÌ)Ãè‚绀áÛé—›ê¥oô°¡Þö·ëÆÈbk\ðˆ•Ú&#¼ñ3âN‘=¨4}’õT̹Åj¡åï¢uƒùªäc&#ô&@k‚WÆáw÷‰6ð|eå’!Äß»”eWw5Ç,^1TK¯—ßõ7Û~¹àv@cR¢»Ä80Æñ|ÐqƒÄ÷&ö«…IèKç2Ç »–ÿëü2ê„7ßË?)þÿÆæwß=Æÿÿ“â¿™óO¿Ÿñùñòqþ¿¢ù§¿ïžjZü¿õ­—ë/aþ7^l½ÜÚÚZûæÿ%üÿ1þß—ø‰Îå´ë´â½¢óa€áÿª°6zô9ñ0«O| ð=~jV&!ÌU4Aá‘'òÓá›ÓpäÇ·¸Ã^&¾<‚ÍVæh‚V(TØ— â€ó ¥b7“¨é,£k¼ž‚ízŠ Cq@-Ái@€†V D- C×»œÀ~cèÂQn(Üe)[S…óaOlÃì™ò3™`Aý¡^bTåB@ C/í`‚ÁU%,Ø€ç^°`Kb”v-¨ôæƒÔÔÞ¥Ÿ’ÆÈȸD† ¢ s ÆàšAHµÍUÜúÍA˜&<²7Å t}«’Y¥ ð6 ,VqtÁጱƒÀF BºîÇvìRnò*‘³Je°2rW1©tß5:^§uÐýPk×=ø}Ün½oì×÷½7?ÃǺ·×:þ¹Ýxû®ë½kî×Û¯Ö܇·Ín»ñæ¤Ûjw°™åZ*/Ó·Zóg ÆÛ®w:^«ía誴´kÍn£Þ©xæÞáÉ~£ù¶âA^³ÕÅFG.”ì¶*Ôu¶¦×:ðŽêí½wðX{Ó8lt¦.Ý&vwÐjÓªõŽkíncïä°ÖöŽOÚÇ­Ní(0ÖÿÞa­qT߯ ЯW_ov½Î»Úá¡=\l§õ¡YoãÌázoê)¦ Àîh´ûv}¯‹ÃÒ¿ö‰äaê×÷ððR‡AÕÚ?WD³úßO |ôökGµ·0ÆÒlìÀ$í´ëG; ¤sò¦ÓmtOºuïm«µOhÇ(d½zgÇ;luq':Ãé ´ˆƒðûÍI§A(l4»õvûä=ÂÊ0çCi C‹®[M3ÓN½Õþ›F|ÐlT¼ïêð¾è%¬ÕÀÞ^×,]2i`z¼^³þö°ñ¶ÞÜ«c6ô¡Ñ©—aò,РÎ" Û;NÀFÓu`“s…f×kxµý÷ „_”zè4ùúöÞ ìËeQƒƒ†ˆ»öGÿsN«cf{¥\ø£[4ÑúàÊ(V¬õ#¼Uχu ý:Š?Ò± …1yöÌC9£«é QËW/ü9º=yœª›ÍúÈb´™ 1ÉÅ|­ê”noZ{?ö{õ?ñßïz*IÛÔB ê£Î‘&2q8ir óFï.èe ¦„#êE§˜ÿ´zÆ¥jµZ.KîXýìˆ^y3Þ ‡onE®Vú¸#¾ÆL…Õ)#R"R*ûCâívµ2ï"`pã÷Óá-¶AIe "&øÝíÂö‘¸/£Nd艿¬Xck¼o+lëÃ[·½v† ]´Fκ´3•0Z„JÀ8ô$hËÏb‡:.{}„{I,º«Ò$?Š9bΣ˜ó(æ<Š9bΟ%æ¸2F]"#¾¼ŒFÃ[f °#—›KÆ©Q|çÎ|²ŽQX5ÝûÐh¾Øè}Ø«/}멈úA8ò¾Ì\«>ùÃózqi‡åÇ{ÜÝÇ]öq—}ÜewÙÇ]öq—ýówYÞÅ LfáXÂÙdHm©}än± ì¹êAKÁ-íÉ„ÌÈGúí¹f ’…&‘-¡ÿÜ~KR Qs„†ßH›ûõ›:‘J³vè>žt‡37ù™•§§Ö‰DÎ Ø:„ú;¼FñµŸx@\õv ×Ñé-I2°lKn>ž\Ž«ã[o”΃Qãy|U&ZÅyIªU,HK‰ðçÕ÷]ä—À–ö¿ùæ›GÁâQ°x,‹GÁâQ°øó äÀŠ/ @€V„ ÝÇÔyçÐâ%6ÂâÆ­lÃ0)l¦@î`¡c!é@m¼÷“¦5“Ùv¿Üv·ÝÇm÷qÛ}Üv·]Úv¯üAxyjí¼ïñ•÷Vî¼\ü0º^WÁÐCŸufFúLŽ›"º[:û!®ô+Öç„îµ´OÀá·K¿G ò¬Gœ¨G '·—§Ñ0´€×ÌâD[ËtzæúÛƒ ®Ö'iŒÏ‚òè¤C4¨üLä‡?CÅ#’6¨A4zJÛ€¬àÅ ÍSƒ+b£OÇNN‡ÀŸjÇ ”¸Ò&xzË Éh11âˆlA‘AV1¯´l/JÖ«ß…‘JÖKšÞ¥ýkj`a©(|²H"l ~Ÿ„±(, aŠ{Â4Hàm[W±Åê…¤â&î0íhv‚û|'Ûø MN¤0˜Œ‡Jþ@—/ØËüÒ%´çŸ²´§‡MÐÀdš0Iø9¶€† Ø$Ö Áˆ¶Ã‘ÙÐS {4Œa!S¶þœ*x§O@@[+5+úeûÓX5Gï}˜L`”{ÏžUà¸à1ç"ƒaÀ´#y5ŒàÃÎþ¾ƒª·¢G%òâi…+¹òÝ™\a¥ÞQg¯«ì=yâÉÌÒ÷b}mé[ƒ&.ëžhÜcé»ê:Y!ÏêtYY ¡T ˜x ËÁ¨¯‚jÒµ*[{‹ã Ƚ×x‘8b‘ŽØIJ²=м“å5‹åÜž}þâ–:Æäô¼Ä=ÊSߣéí}û-¾£åâ}#±”ÃbÊz$|< =éè nw9üÉ nð´é½íÖ;Ýãz~ÍÀWÐ’Éȼ_ɇ8Ûàö6R&@µ½-϶ÛÛŒeÞn,n8¥3,`¦é ®Î8yIªf3YÈ,Ôa€£n9¿§éÌ9ÛÕH€¬>‚ièÎtjòáD=/ÇvXµÖ—Ôx,-©ëW¨Ó!i¿»»DW@ )ð6Ì £«*íËD0µ‘×8‡ó@0xO¡/Ù-AÊÈ©Ã~˜o9¬G â¾óIæ¡p™UÓ}„Ž À|­Ûä)ÜK;HÐiÂ/ ˪€Ô‚á%Á—¶EÐKl[õg9fE05¾Øfé™]D6ç³0@o!, êÊ»7ÞkcHq(ʎ̦ºÕ\êÆ»KL P;æjÈ-ñÊd+ÔÓ«]o—âH`û(ºe Àwü¶Chȧ¶>oWPrVg¢QtF¿O?lÌDK/HÅS‹Be>¼X Ä Ö¸+˜ÆÃ‹{Ál>l.>€ ÖzAÈäsêÕæÃË|xy·AV°æÃ ÔbfÔ/?Ó¨¹#ýbëîh¨`í/‚ ãû֗‹ùõ»û!©‚-|yDßý)X3¾¿? +ØÊŸŒFãáû?§æÃƒà ¶ô5!Ùxøá+øù°¾öpøgx°É¯v"2Í0°zrð8#çGàå`2¢³Ð«ƒÝŠŸøê=ïÏÄgj¤¢ìÞøžÅTï l$Z£Ë§­m'[-Õ’Ύšamq…T˜æ¶[ÄrqUÜ\M/ÔYGÞ”*Qº¥Zw¤©ß¶ÔÒ>žNB>ÖBèc>öÑ60Å4ððæÀiÌ$§í鉢¬–¥*8ïO~§GþGqv}…ƒíL ÜœÒ6 A@N Ô¯NëVžŠŒÙÈïß<ÑmOkqà:ŒøBhc‡0‡á¨U/©;Ÿ1µ3å^µKe{u·ïL[ñ»6‘™eUg²ŠËÃlm™M‘–ܦ-( XzŒüI£,.ذ8gjjëå]b1ÛSV[WYŸŠ4XéñçÏ õîó"ª?äܸõËÙ“…‚ðô ã)µ'í¥BÝË&•8_ÇÄѸï7y¢‰Ï:•\ÑÔÙÄcÍìåy·guKáukÁYeÔ×3³„ƒûÏ®hæËÍp¾ökætã)v¾)gâ°§ý;…ôïî0í¬eûº¦žðñ0Ó/šú“H _•7= Vc~š` ²éâ{5#ßß‘.XuøõÑáæáèC4÷5ÐH¾jrn‚A5ØbDÃdfÎjº~¸á°Jôë$ÂÓÃTíQÃ_)¹z×…ˆ«‚U§0¦KG ±¦Õk÷¤3…|Ô§~½$ÇØû\t'[Gâs“OH³žìëE­Ž¦z$çY"ší±õ šéxáM‚ΠfÇ4sñ¨Öj êt¤'Å0ºâÜN±G£x€¦‹u4-¹ôo(é;©1c¡æeux|éýR[ý‡¿ú¯ß~Á¿Vþýëà™0ÛD¯'ìÁGŸž€š„Ñ$4¸ñÑb©âFé…·|Eoüx}ãÅ2™¡7ÁYõNý¸Ç/ãÀ¶*ÂÏ|öðsuÉ0#ð ,40Áj7ú€£–9ý ?^õD`ìöM½ƒ uöŠņݩ‘÷…™†3H§·ž¯›ˆ¥É¬0í."€ýKt|ãz1ºwø^ì_Ël!Åv;ʉ…ÍÞ\cè0Ѷ=…‡oDïd„ÍXÝåêŽå@%ÿR( ö‚ž ÄÒ»_ØüB†«G¾…)n^„±h£ äðÆö¶Õ˜ºÉ‘viäÕâÃe``‘R-°Õs‡ùª»œTÔå>½O;fP ¥¤mÿZÀY—…j>Éô> ‚xx‹s7ÆiÁ?¹ó™ÖT+ct †gf!, Á­C"YOƒÙbS]!z-„#Ìh-’‹MŸ£1\G<=ñÆœ7H\cŒ«çAʉÕåŒF°N‡‘¾VÒànÑY­38 lñìB¦^#L "˜já í¼‘-òÅ;BƒƒæDv€IJ–|èä¤É *;¤ÚÇi|$I÷x"ƒìz£q@•Êe¹&¸ºûWÝÝ'Þð"‘”ùgþâ‹Ä̧&æ©ñ^a9M˜ŠIÜ£vn/OC€é© }[ˆ»ãä52Õ^¥"]*¦7‚âìÍÇl߉ï$qÝ]©­`sO¹³‰–i q\taŸÏ>}d}M0wîuº‡Ç½f«÷aï]­ÝëJ—ž£Îû=Þ”©Ÿ(ø¸ º oakBS.¦‚­Q÷8Åð8%á9Þï<°¸hÙZ^ ¨Û{þþ¶èmUlŒÂ7/Àí°‘ª¨m½f­Ûx_—` Sê}áÛÍ=xÐÙ ¢Ä›a«Óëü|ô¦Qk¢„òp0S.{ÿþ·°Å.å:P(Ûêà8ŽºÄ&›§Š™hÂÄ·že.ë7:²EoÝô¤HUóƒNµ#÷%Þ}·ºÒí}7’Jú1ùæ Š‚O— Ñ©®´h-œrGQ*¼˜É ¦yû­æÓ®ð¿.%ÅtÒp8¬X´âÞ'àŽ@±t‚+˜™ðL{sP°v.d¢'гc)E§Wèí$[ëäRšpK:"¤LÆ.ÑàeYynFÞy¿_ákdÙÞë×. ¿yíõµñ˜R…Æí½mžìõzz"žç"¤Ø)¬AÕàw5 ½Æ[  5×ö 7€ŠÑ™7°„œœâAÀrùc8,#vá_ôŒ&éFðìTP?òÑ É¹ÀîÎÑŒp)¸A(D#À\ÎÞì0ÈWÙ—l;(´ÆÈ¼Xœ½”®:Ø%†üÕR†Aq€æ —äì!‚ô ‡K>Ù( aÁ 2ñÏ6ê×"¬?"ŸcÅ-;{8ÖÊâÜ´ç'iu)(Þ…:?zˆ|C˜øØ`<À¯1`Úûà¹E} VŽõPðá–ÅX!Ý"Ú SÌÁw¥ 7BÝ@‘øµèLJP]fÏ$ `Ue˜ƒ˜&ÇGáh$ÚÍ]‚ò{~Š>ÅWO‹|~l4÷{%¶ÙÁ‚ì`bاÛ`Ó€PìsAÇn?‘H×>a[0:€d=ºÈkמ(h$¯Xps•UËs¾–q«2K™BîÔæ®Ét7'ðóF£ó;>­"m™ESn³‚ ZàÌ­V!hdksæØO²Å2Ô—Ãã ú¤’.“(èyMNñ >WaÄ´WXcéÛ‰á®kÕ¤ÑÔqÂj¥P"Y&à.}ªØ:àUÏë=A®ÙïÁA!}•/K¶¹[R—_Îd‚K–s€Œ‘yžÙPÙÓž sCm¥nÙ+™ðvwK«ë(~¯qG‡Q’ áÔP£Èó”:°Û¾öêãA]" Æ»?v# ´Ø) ¾jaÅŠr—Š ›p«u#å&OÑW„ܓ듌’ ‰éÀÚIÝC}¢†žÐ¹y¥° ²˜ð Û{/â¢àn&$°ùúÜŒµå[vN²eÛÃaºŠál˜¤H0gÃ#Ge ¶+°ènŠÝh‡žåŽI˜µ6ëUxG8 Ê8V•¯·GîÕÑSôè JíçÆ¬jû>N‘ó¬·åH9gÑ·-ýÏ|ÏYÑò‡Ø”eY!<Ñ™ÿň+¢ájžÛ×ÔÊ2б…òƒT~ ˜RH® &:tF´V_¤wB•´¯°{Cï?'ðŽDxç!˜â¶M·ù¶©@»‹­,xZ!¥ØÔ;7ÄBîF¹•¡ß Ü#«”ß)HôO²7 •œŠÌ DD%³@!"î¸d³X)&Eòz& ?J_‰=Æò™R_c…¼ŠI=De&ˆçû!˜_ÐÑ Y´j…ö2?!™JÄ1Àó 2b·m}F–’XU´S*aãÑY ƒ[žxìFeÔ9HWé›Ì¦Éþýïœíêâ—âŸéu 3épx„ôHàpæÉ€sÐÒù:Üh¡B>´»ºµ$]|AçrOŠÖe †½Qû0Ä0@¾ÆpªÂiè”—BþÖöù {›šÕgÐò9¸•îÃñ¬èiŸ9†;ÏGþ€ŠÙÍ=GļØùbpb’²ÎÎ\NLj=ÁØÐix./ž vüàØAUK>‚f‘­Í•mög2”Ý<,Nì•#K›“•÷•¢i‘ÿ?BÞÿ¬âú}Éɦ޹(Ï9õñHús¾!Eä‡A´ž¡õÀÇÞr]`è Œ³Zf@¼jȇ8¡%¾ÎᨣÕ3?õ‡¨@¥eZä€K·©¥ n¨Ž²aFÌët§“ü„¦QtÑ%žCˆüØŒFTW"þ‹Wp ñ`îâÃ;ýÿŠà*a@Ž%‰?&8DÄQ¿?‰ñÎOè&ÏCT÷ >CÑñ‡‡ï¬=’I ·(ú.™€+÷Be‰€-UpfðÎ1È»æËÜø±±ÃïhÇ?§(9kÊñ±m\OËñÄbø2¤®EË0£(BÝ©:KREñp…×ZAÈŽvpy‰+ ŒeÙGiKF×dœr S Þ¦XMÐ>C1^w!#À+ƒÃÖÛÒA­[;,#콫ïýX¢ )'´ì%5âkR¶ìx£tôQܾs JWÉŒKûõEÈ®P½¦Bʽà;øÉXjðÅ÷?²ù‹9‰EKDŒ"Ò#ëá-LÎä'ç|ÇŽ—ߨVËbmäÍ×ên.aff{{›—Ó b4Ý z‚œWÈ÷CET3j˜-ógœ%$vàÖËdf€ñ>ˆqg)¦L™¤‰.Tç‘‹&<ÑZ]j´FU¿ý¿ÔÔ*¦ù ³»0x4¢ZÑìòg?~;1¥޶N ¬kqSv«tYÖEÈ)qÜ?ø1…m{í­KÆùž.7IpІ(««L:…£?…y«*%<ô–€@3⣕NÏ}Í­'eŽë“µl•  Í{jüå7dÛY&›'Š|-)nC ÂiFÔã–šYØFã":-P¬Äeg;Q¢%ñN›ƒ{‰Ä4ÉM Ê/žßïG±Œ.TûùètcßÁÔ5’÷ÜLÉœGÙ4ÛÃ%rÞ’t€ö#ñSYí©·ûš¹?Œe‘›b!€ž×8cþÞ£D:I/zÉÇp ía+kŠÒÎNônÀ[§/¦é8Qö·Üæøû¡ ÊÆ/}t "1L0¦É­JLMÙ]®‰³?*j(? |l›Hf†rkëûÃ!îÇ@Ì쌴B†2i!Û øóT„çaPt²B±&˜ÌYî¼å³œ\¡&¿(2¼á ‚è¶ö[%;;RyÛ;#ئ1Ö[ú¡ëÏɼ€4Ëg±¢y_ ôÔþ5ÇÍâ_AyuÙØDì,<ƒê[t³éBÅüÜ-¼ê>Ù-Ðè.Éó_/øÄÓäUwŽŃYç#Ûq ¥3+’iíJðŒ.ï6> æ ~˜2À8¸„#œ3[T‚¿cM…qáø„[ÁMVØŒ s{˜i:ºPk4¹-Ú‡¸ý ïßÖâØ¿Õ#döìãAÞó¨N~iþÆñkqe¬ÐœŽE:³†/‹ÑO™¹$þ«m0¿8¤If¡b.N†òNXª^¤—zÍœ_uah¶ „¸¸bY S°ïƒ–à±0Üî9;i¾¥rá d Ÿ6-› ¤ÄêJA¶(ÖÜ:Ѷüæ0¼ùå·²´!r,•ûhçÊ(±Íb åܱÎ*QE˜ìd稤ʾ6"ûH$}8Ë&$_ñ¾@‡2yb ,©$VÉúicˆI²–S¦bÂJpé[4­;¿ôe¥ñ$¹(g_ºíÍïÖ¿+Ûö`dN†7àe¶µâ bn\a %—*ÚfÒ^ŦX~ªàéX.ÁÅ` XœÇh¨däéÅ“‘ž™¼ £.fª_¢¨Å°„Ö¢¼ß§¤c¢fD¤+@v‡Ž7€XÜœK˜”AnÊ}ŸË´Ðýä"HÊEvÆBòîJ$–¬³ñYž—+Þ*ðçå†t!Ánˆ[MYõCvÀ!7Ã#_&_™ÞK¸Š`íÜ5ÙäŽpד¢ #ÃTFUÅR§H^Pí_ÔœJ·¡À‹Çì¡OvJòäÌípøWJd1:—°+ÉÃ@¼4‰‹Î ³É7[äù–$J¶ÁgC¡¸$þ8ŠPyžô®@äkT'x â²×ö¯÷"‘t‡XÁÓDI¼N÷p5Iou¶Eá B76ó%ÆUa' ¯“UkïÃàú•Ùü.iVS×™„ãèA«V=#®,m#xFó‘uÝ Óºú"Œ(õ*ï²PϨ¿úÁ˜Ò(ØxØ‘p¾Œµ$SŠhƒˆÆ?¹Mïa‰¶¬U‚™ì)È´‡hÉiÞ@€ì#ƒÏjQGˇ&Mxªžñm!S0Ž»°‚·åù»VÚ_Rw€üdø[^Œ¸žE£Â%ÅôE!-]„&‡bú´Èq)Ÿfmµ°ŠAe­ÚâܽŸž¸4C*_6ªÊ“CÜŠÙÑϘ V° ½ÝfÕ‘yK¡â+ceNÖ!H˜ã¡¢þ»µDõɆMíúQë}½‡)aº½’Y²¼ËΊ«õ5‰£F š– Q׬ñe[Ò®žVE4b¸!hÑsš£Ž!ØÅ+QRÊxYÉC™¨DüEü6 G[÷5 Z–­tÙ]Ej(—E@&Ãû2LP’ó(uÇ+Xø© ‹áonFÓ_ VR@ñÜÑSÐ °.Åé2 &òžjzz*vM# ž•BÒž ©#çêOçX9OuJ6¢tÞÎ/XîÔ†³zʼ»(±!ÓñFdH‰ YhÌ[¾÷^½bÞ¼Òy¨¥håÊ¢wZ´Šl ZÁI¶ÃŽ·ì¯·šÑÇÐw§Dæ r‘Üu¤ ÕC¾!iÑɶXIB:È“Ò#Jx~’ô&]Û¶US¯ã=ý%ÇÄÕ¤p:ǬìþV5^–d[øç!ö'óÔ³òËæoa[Óz;`ɸu袬üÔlŽRÍàD¥üòt>(­—”\€\©x¶yùB@–Œ‰€:¹  Ž•ç ¼§5ye" h´ ع´é„¬¾ ϼ§åE È°N5;Й Oî²û7zædzÑ䜵»M©S Œ ~³×ËÀ³ÊT²-#•%¿SÙ.‚á¤!–ù/§ 'wÀu]5·>ìg»iIú»‚ ü²öðÑfVmèN¶ÁÍÈ„}ÕÜ~„¼Ý¬Ì¬­ý³ aÊ]À 9Ë‚HÈ€M]ße¼FÅéC}‚•yb¿eU¶ï•”=ÊeŽ@;MÐP¾øêC* ÙPn;TÝ[@$T¨ú×ëV; ÛuÞý…˜Ýp— § é‰X½¶£1‘Ùy¾ZÛej:ÅÇuý8}©M]N_2µ(,Â7]ó ¬´k -6Ï~§š4…*kÎ{…Òî>ÙFâHû£„¢wpzNü `,«Åq a X•¹š}øò)ö~ süGq:Gý­ma…G‚pOÙ÷$IÔyy«GB˜¼ÏÐ¥•„H¤ÅŸ„—áv(Ô®A#°›“jÁ˜êyߦ1“CEpk)P»¶æôF’ŠNM˜”µóPC™ª±ÇÿXñÞïæô£Á{ÞOîUn“Nàu]†¿ZC8òÇce{·§ »³“ëö;•l›¤ÛÛd“øê#EÅÙ•W¨23}ÃbQ8pYs¤tO+ÞËá½áÞ÷De¾) ¡ó@trâæÛ(9%w÷{ÝŸë½n»ÖèvzÔò¾0„C™•¯šR ÙÒ4»=¾ ÜUšÂÜta줭c¤f¹ü Š*ÂoZÄ_¯â±„袨&,Žpq9Š5þ¤-ë”1_EN¢çmTÉŠ —·†ýÙ¿Ðí0)šD'"!{¨ äL‡ ”­B‚!^GBå9€Sí937v‹—nÝÂvN…ƒ¯ žàp"d<ð3ÊM×*£„›v1:FÂÑèF=ðñÀ]#߸éâüÒùç­‰=κŠݧ”Ï:¤0GÀ«€hATeÓŽjQž¶<+Oóvó`CJÜimàϼ ß 9jc´ÏÏ´.Þ)4Ž——xa ûû[ ´¡~”ZšË¯šyߺ"á›7µQÒ_5,î Ô)û-à8/1ù¶>vš’ÙGÑÏž„…¬8„±TµàªŽù@^MÍŠFALNìè]¡T]8ióî:•ßOÅ;ã'·Nra]—ôzÃz¯‡¿1—aÏ:L,‹>äJ&Ÿ â!ÒVH­73Ùò­Á3³,š7†ú€OSúÚ…o“è†Eß ðÍ“™®4TzÎm§´¦£PFTMÉ%…t»l“+pY]/+×~åmJ݉k:¥Œnž2qI# #®›Â®éï$ / i©ù3ÍÑoH˜ÉuÙx+£“Åj+ã7lIã¤m0½gÏÖÙÆð\Áƒé| /´º„ÇÞ7É]D8óG·öõ:âq§ìÕemÕj¢I©"“Ù[6:DdEkÑV§&¥Ì™Tóô2}‡4nÿš6ìÀÄÝèÑ2£9+ÕÂ#>Q¿ÖŸ”\d “žÌôi!V[Þ°¼]´˜EkÅ A-f˜‘¹û”ë@ôMÇgãüçcÈ=1£X¥;XçÈŸ;Zóà?fyÚ=þ$huÁúeò…ìŠäÈ¥'–ò“.-aô°0½ ‰ºëÛóQ:ID ²äŽy ÍlZSY©{ÓR€,*5¨F©‚{J³®ÅÙ¾›#l*mŽzÅ6²ùùŽÂ:‚`îð ›Lá΃$Cft÷_`þ©v{µ½n£Õì´Ú½v½{Òn2©Š1Î!!Ÿ‹±%#ÆPØ3Cb.¼ÙeiÙ;ØcÞ&Jhæš[V<;¸‰ÍÜß¶ÞÀñ¨Óm7šok\n£hJ’§|€æN 5À±®E«:ñsžþºötÑ&îÝ€US,œÉG[ÛR"-µJ„ÜIFzVh.u}§ƒJ%šÅú:èVÅÈaìW'L~ð%ZŽç<‚Î_3!qÄ!,l“å§¹°˜—3…ɨ}ÕùâôÌ…màÚ‰³\ÄIþnô#$¹Þ…’dSØ’wçÆìÛ/„ëNÀpí;/+¾ \;9¼?ZDS‡÷C‹ ¥´ðîZOD[Z¸žŒ£´–:iž¦E­–á|<¾ä[ƒ‹Ûº4†õŒúÑ+á‰ÄÐÉiý†yÂ)+[t3#"¢€«,0æÙ¥¦ ßô¨s2éDE3÷Ý4yG´®C*-@MŸ?Õyë%ÈhºˆÇª _(òNXZóåˆtB`Áb}+zÐPoå.+ÒúRòg _®ÒhÔÅÆ¯h§MBÆð–0T1ln'LÊ"(´z†¡Ê9rÈ-퓱 yY–€äH•æÈ›Æ‘^ÄÀ=‹"aË–‘p¡‰|.ïLG‹Ž£óA±#•‰„HZ—Žoõ]á§ï.Øi@bUbJ#g½ëÝÈÓj6Ó@ÞFÄ=ÖͨGï5ìˆ×ÞAx#Ë‹/¥›²:†‘o’²[Ìêc ›¸Úø¶Aú!fG_5“˜=2X3.ílI-A÷éxÁ°je…¦HÚÀpƒÃð2>ÿ‚ŒËZ§ë•Vl™ ÌçBs¢PÉ),Ǽ R¹’VÙ’‰Ü“Q2‹XÜYÞ~\š:Ó]füàl¤óBCÇ…FÒ±ºëo^«óTnÏJk û2ˆðÞ"àX5‹•Ð)åž û¿ÿmh3gž›óP9ã„9†íC˜éi®oê' F ¶Á6a$nIè·¥Ò20­ÇŒÍHéꮃáP‡Å™®q1è‰'ÕûÛ’áÉ6uÜà¶neuW, Îq^ãØVGXkí04šÉqì5FÁÌï]OuÅÁd`qQ•á~Ú;kÒJ(ƒvå}[\$—ÄóèìctO,1òJ«+‹,iÛÛýF§vxØúÐÛkÿÜ«5÷{µF_ꕲà•3XÈaWwÀCÓ+b§Š|¶å«^I³Ú9°¤j•§`ª ÷y1—3 wbÁXŸWLN<‡Ž,+wi6É6Ÿ˜¡.³×à“ÝÅe”'¹ÒÅ/̳ "Ò ÐÇ w›'7 noO¦ïoFÓ»‘=™¹“©®ÿƒ6²'÷ØÉž<àV&šŠ–÷²Mdc­˜{Ô“¼MJ“Ê¢{Ôc“Z‘ÍäìLZo¬ M1‹Ûê I\õÆHê*Ó Kš³Œ©ê½Þ´¾æ”’›LËTÈbœÛÕ ²À|¾£~g¶‡Af¾g…Õ;€õ¤®îŠ—ì W!7Neå’Ú!¦ÒHêúµù ö¬A–¬(³½ijQN*“MH¬Ê©v°‹öÞ˜ ,'Áý¬ŠVR37#ú[ÚÐI9JIY¹ßÅù^Eñ%¯UÆŽtI=á³@[2©xðIƒŒ‡È¾JÈBÇÝŽœ^pvFÆ0x>–g“¡›ƒËç&΃t`X7éªÈð³Š6Aô¶ Ñ}…Ö¥q-‚AHgv/dcnŒ™Ä Z2Cc‰i#¦›RÑB£¦ÈiñYB‡ƒé²â05iîÊ6–²¥qttÒ­½9¬SþôTD729$×R1± ”qrbP5ŸçSÿ#&jy!(„š %jDÜùx¡ƒ²ÀtsS?€»ð?12)Ù&Ø9‰úìqCr&Â1¢Žˆb…1Æù»ü1ioöI7Ž.0$[q+ßÐÏÑ„(Š|}e'¦àĆÝ~¹¾0¡@—ÏO×;%6 #pÐDK‘e™Uÿ¾1IÆI:¸€Câ&a:¯øÊX„t¢Bu Y»O`ùÔäzoj·rL0¥1«,ÚB±Ò-·ZÚÕ¹ í¾85½òdƒÃ˜Ý*›?¶;NÝ@¯Jw|¶8Ô„v=“.pd4ˆVņ²,Y×’q¢€eId…Z×ó“ðøÖt3iûѧnGÀ@F{"µ—ápÇ’Å„÷GÖ+ƒIÝU¤>"`nFQfÅŒ€|€Wdb¶©”Cf\M‘ /¢4ŸO™+‹Ÿ¦¢{J ŠÑBŸUëòZ¯„>gL¼ñövŠÏ§z?R™ži!ø›En1eæ†S!2‹½vÏù[_3J©v±6AnšT왤’ §˜‘ØÉ«Œ²¦²´• ~~´ö‡ìØ=S»ä)>†©Œ=Höw«§Ñd¤'E³uØ^…6o¥Fr™"´yމjFôп HãÄÞÐðè£t‹ÀôˆÃ¬Œj-Ýà© iYG,UÛÙ‰½¢ŠÚƒù÷`3[œæ}ÂdR¾±È`ºå2n,ì1€Óe’O8"ÉÅ'©C])D‘ýî²nc?ª ‡%Šûø!L/tÞ`ˆD‘6Kšfý‹Qˆ~©F3Lhj|ŒÑ„Ù3ðx--ío6<Ô°œSPDØ„¾õ}Ý9qnHÇÙƒu£)k5;ŸÜÕym \ß½ƒ&eýΪ”õ9¤sºcp¹pÄ=£ ’Eâ“­¸+›\L çææ“ž7 ñ¹˜ñYãÖLï]0cê&952¼™…ÐQSLjT”WúØCnÞ¨5$õ›´«š‘AÉ´ˆƒvp^=´+R‘ýHð&¶z;ÍQ]ùíÝAsb<·ãjr­O¦MÀؿŌñ%QIÈKBõÞ•¥r¶­É>…@vSVÂ=Øg ^u®;­yY'ýÝo*ðúÜ”LLÅ2ar2<6˜¢Âc›I|+3Ƙ•Ö=1dœ•ê40TAø•òæÈ$"¡ *¹û2ð†Œ¤7$Ñ.8 áH…¼dˆª4fÂF µL'œS9€Ì²Ž&ªGõî»Öþz鈎5¯[:)3?Ò¹8E÷FkB©ï'ï¦ôDq~Ï«ÿt\ßëöö€øKx«xÜ^ ¤Âê‡p8laT5{\í“ÌTÃûš—…7¥u̾ñ.¢á ±cWA÷bö‡/‚ä&° øÔ~Ž÷ñdBÝrúö3¥cÿ‰Uôäoœ SÍV”=<Å¶‡ÁY*c< Ò‡#ZŠª²šê²÷óÇ 1¢óbûF ž~4 mfž®âQV¨B¸9o˜ß¢KŠÞب§³÷(’6ú¿ÀÕˆ’+j°ˆ1K"*y*âe ¯-'¨õAÈ K$¾Á–Î#8“D8±ú)­™¼³®ÜÕ,6çZmX x«¤é¯Óñ}¯p¶òÂ(UôrR‹•ª¿Lôô6M yä*E0©¡%óY¾«C›b¸\vÜt[4á.µ3–Rx–j°FW'®éβ: M¹f†¹­T±Ôš?ðÄ›§‰ ±vçÓ¢Ê,c¸BŸ( %´ú>‹²Z_} Rf(®Ÿ1èüÙ­Šý€ÑtÂ; ´*æéhÑ„ Ïyˆ>‘õI«D º%Uù…N-*Ö/ƒ(, ’¨àxL¯´wú KË6äh(ˆ³k0ÁÙGô%·—§ÑÚ•jà”ƒ§plo2B«z « ï ›ø( ‡Ð²wÞHÛÆÓÉ9ºÖ'©8t„ÍÃG`ËÖØ*]3æÈnæ¡D~@¤Ba—õŒ‘žÃŠesî¥ê½™ˆdaZS’¨]Oº UóOÙ³Žå,CíµŽŽQ# "T½­#3yÞ7V}qÀ^¿Zg ãêñ*hg=±Ð{Ñ™x‰ù˜ê{¾nÍVÚÚúRr´+°xuæ+:²r‹+«o2ëO0ÂKÆ®"_;Ø3OZyò“…õ$ jG„JY^‘±lC±¹Q‰-8Â÷Œº9ô¥õ•m žo¬*­¢yÒ- 0µ@@~{+d—õvmÙks ¹¨D?‡!P†öÛºU6Æ>+‚»È€J*z¤„5¢OSi«€®ÞGá`ºÊ¥)¼hÍ#¨{N,™ƒÏëö˜štLñ¤Žù¬^qÌ)[ØaDgj+á2UaÉIL§(,•­¿d™"æ<.4 Êùu1º°«Ž± uT2ŽbD5‚Þ6PU#ðO¯D¿ÿødåC¾³*D`!mˆƒðQŽ,, ¸yz‹âÕ9¹ìÄ¢R¡psmSÁš Ü-$‰Ã˜8¶ªÓ×…ycPÚU™‡5‰`,/,5Lu^ÖwYŸò³G|<÷›\³Nøð©o¡Ã½µ´ïz¾ÿkém!s®•{G±QL6\(Ÿqÿ‹I]f©"–bPåE˜}댢M°ü%ƒýù,Ÿa]ˆñ[U¦±ÿ%¡%±˜í Šè>)v+~°]AOÓãÞ0coШúr;DŽKã‚êß܇r·íáÚßvð¿q›XxYßoË0£ämSWSÏêݹÏçg›k ÉóÝþ±òK«^Œšýä0?s[º+_Ë®$òuÚ)<7ÕØ2_[㣬/²„ËS¿XþBq‰ê½Š„ù¥Yõ˜‡PóK©»¾â‘~¢»a¶¤q¯•+Ù¸w=¬Î<¥zÏWȶÉ[ynï+Ž÷Ú {‡=ḖÜÑä¼1=›ØdŒ*oTR™æ~ëC§wÔz²óLËÄ‹&YÈàýƒÈÄÌ!ÐÛ¾8*z‰2¹b´±õÙ•™ôâXJXÛXB~d’‚§Ÿ‘f½åÐû·5rYþ0S°€cn[„2±v¦È\Tñ jPA‘åâ S ­…§˜*HœÕ"lO²K†c%`×(Ra*å‰EÞóÒðDøˆÚ~×Qü‘Cq£áÊ"Jà=a`D`/89Сà˜ßý!ÃÐÁûÕ]×Pg¾NB. cc+<°M¥™ RîAëÙ- 1ºŠ>غIÏÊf(ŽÓô–ͦò¼B”våÌQÐˤßVz¹e§·QL#9йá>i[Ò¶½†·À™Ø}؃Z: °Áép¡<3´HìËÊ‹Ïg÷¼3}HËODobB2Š Ø…g 8T’Ê\3ŸãŽ)¡‚ gÅ«œdR œ›‘µ8Ÿ‡‡9¥ÍÅär>Šâ€\’Á@²T¡q¥À¨8Õ76[P ™:úÿê)îéûhñühñ<Õây>—dW§ï§–] #ã@]A 0W]LÜ›­Ü+ãNÜuÏmCC=¯Ðšéyås©œÎ£ÃfOļ(ϼP¯TE%D5㹘«ÙF) ¥”Vž‡€ÖIéqà‰Ði"ZŽ l$‘b(3Uª»…£§.ϛنR¹Š9±üBÝ2»wÐÛ׬ºE53[ˆ”ÎSÉ¥QhW9›!朋[Î'Ǫ¨ì±BìʱˆuÔPAQ ÿl– p*–rùa§0ÚI÷ ´u2¢8<<EÞ(DŸ"ý&¹‚Á›d_a`ëVm•ìëD•“2ÕÎk§·«:ÖsWöùC1B®<{V«Uç,ß»öE*ßeÕà’¶VN–©Íx]Û`»U>) Бk{ 倆bAàÝ鬻qC³®Å ©‚³´Š¼Æ½·]M(†=}± ,öJOÔ˼;oéš>­>ÎL O&¡S‚N÷Iö gEÂD!VÍ[…®^'2¥,Ñ0ÆEöóæÖ4ÃÂ6t®xû:½hn˜Ùb½n$˜mÎÐɲCå AžKú–Þk,‡<âdâ%™?¤¦± ŒšJ%¡ôÒa?BÉä:dŠqŸ`xE”ªpÍ%"€•x‘£²a ,3ioT<“Ús`úd^\ñu{µ¡-O$6¿ÿóuÑ´'š/6ô™G”ûÝ:zä2òÕÆ½ÕðqÜÐnoTV¾•† ¨eu™‡ì{ÛXÌ!ü¬÷ôç¼åç“ù»?»ºÞúÑØÃ¿,A×”·¸–.¢‚©8ñýž¸$» ÑÞ'ÔŽì&O Óa¹EÇsÊjEPíd‹ìª^‚.@M;Œ`ªdd²!MMYUgåø¼åÆÊTéz9¢-,~q‡/ù ücÉ /A>~¡®Tp_^Ihc##f8 Ž|ï͘¾Zqã*“‘s£Ã"¼(qöwJð%…½¿aÓöá-¿a ñë¶,ƒ"X ½ÁÌ¢¡‚2 ‚›âê,hI'u›(´Âév¾nÄB2*bž¹aÔÁáõ&¿ÇiéfåÆ{æÝ®ÜÊ!|šÙmÇ1cD‹u¦¢ÂÕªÛA%`6JËþi¹âa¼ÊrYG¨ÓQ&X´,⨬ƒV¸íÃ$•^Þ±mB„ž< ´Ä¡V(À’™¼ëÇŽÀï1Mêè#”½öÔ…H¼ŽªSç¡Ä…¾0îgbe^DÏÕÜsŒtìÆÁR ÉHQ0waà=™(ÂúЦÙ!ºÑÜQ„E ah_ÆæŸN á©A„)ºåÓ#—h7÷Š´¤Á—ñA KXJ„]âË@z Å¢‚ТÐZ…›§M¡Öáæç˜ÌJËoJD›ße"r¬3ŠÂpбCµÀûósº€RîÒ¬-¥„ĸÕcÿ–côKgæ¸Z°DãôfAo=‹ îa+¬Tò#7.™hFW-Ž“æöªÝüvm‡>Òü¨jÅ-•æVéð¦- ç^û’íj¯±…×­ÌxÆ•ÉW6ÅDB£r{WNš\ð,ÜÎK0T@9f”³ð®C÷µB:’lL¨[è+rNNñZÆb5bSB*Í)ÅÁ 9¤"|aL™³¾„µ8ø?‘¹‹æ´d í(`jSa}ëÓ… S컾¤±þ¿2[Ù˜lÕ%§½$šËJpíSx öiÑÝØ¥Yg9—xA¬‘Èo”ÎfQŽçú®tªn"Í­á2¨›™ËfI^Pm€m ãÕ,¸6Φ•r.ÜN…Ò,(‹Í—DÚ*4[ÂúÚBpº¥ÛTc¬îîR–ÃY±¹ -´hC†¶ºSÜIj޵%"Xv½Ý%nM4¤-îoâ˜ÓAZ(E8d.\*ñáòíÞ^ï}½Ýóž<ñœ7¯¼Í5øCù½”ahçç£7Z³¬$; ɽö¥XgœV¬ß§Û ß³eZ•ÐÄ£X:VI¥Õfuc<ß^žÂRCv-@ˆ`ÿƒ$ôI˜\,IÏvò‚’t1Pmc»Áe˜j™„E’<º;Ý4¥Ò§¯T<ŠçPDTÆ?4yäP :ø,cYâg Wû\#vÁƒ–¹ê…ÕY„D‹4)I(h¿~Ü®ïÕºõý¯’§˜­}]Œe¯÷óG„SÉ#ÓDUÓ=âÖìRdX~íz,„³¼–KÔ¶d°ÖiFôÓðîfXmÞÆã8‰8É0©é¤hÍwž^OYÙ¥«ŒË𲘫%×E°¸Û’l^4.Ð7§+Â{áŒ"y=›gàÊÕiH©<ˆ-»¼§lAˆ3!òÙ¦›Óp_`Ë÷Êj¦! þCË;LÆ\p8–š³ÖµD¡”*G2G42Þ±:‡Ũiƒ8Évp¯D£º­\tÏe”xgÄÏ [Ɉ³ `1 ˜5'ciÕâz†QKzÓõµ‹&&ìµN¶-\s0]Gñ€ e¥ÄLá-²u»¬#(Ïx}tÒéÂ1º«@ÉþI>(®ª¯Èä0s$ÉZ„¼ªíÚÆŒÚpHBSpZÉm«¤keóèÓ»ŒÍfž§FÞáªÈ–Ž‘‡UHÅŠÒ>Ã4v$cíìÖŠ%`éœ[ŠŒæIà=Å‚WÁ€4w:¿ Ì¸Ï_+âž_f…œPûc(÷„!F¯}Þ“EFæ8{=‘gja;ƒF|o(†åÆ_ÊwJuOÁîHÝ®³òH¯tû¼ü]-G;‘5±àš¦³U9™VJCå{þ){¡&|3¬=ê-])5š{‡'ûõ?ñßµ½n£ÕìôÞõ–D^¾8<¿H½µµï*ÞÛ(:¢Ñv¿*Œ4<úLÖfA|Å ¬³À#NžNÔ:f“ˆ†R”†#ŒÝI‹¾Â,Gä{7Ô±ô}‘)¦ÐmpüÁ#‘HÀ40"(™Ø0…JÔRê¹ô¼@š­s²ËäûÂSÙø ÚQöƒ Þ†a’ …³ê™x— ôÄ^¢†¸èÐÀ‹DXÉjX8CœžûÀ²¤ÍUQbåIyŽqˆÁ^ƒ,7L4âi„ ˃1¸¦0PÃÆiaXÜúÍ`ðz‘š‹âº¾UÖ˜Ç`4€·tK  \bò@Æj§5©œÙ,9:K¯‘xd8Sfaa_œßq¥§èŽ´E†F*#Ø»FÇë´ºjíº¿Û­÷ýú¾÷ægøX§Ô_íÆÛw]ï]ëp¿Þîxµæ>¼mvÛ7'ÝV»ƒÍ,×:Py™¾áõtý'8§u:^«í5ŽŽÐtЮ5»z§âñºl4ß#<¡ý9l5àdçu[ê:[ÓkxGõöÞ;x¬ÈÙèþL]4ºMìî ÕfÄãZ»ÛØ;9¬µ½ã“öq«S÷p|ûÎÞa­qÇG€úõêïëÍ®×yW;<´‡‹í´>4ëmƒ9\ïM ¥´ºÐv¿‡Ò.KÿÚ$‡Ä•;Çõ½üÆû=T­ýsE4Û©ÿýÊÁGo¿vT{ c,ÍÆLÒÞI»~„°J:'o:ÝF÷¤[÷Þ¶Zû„öN½ý¾±Wïìx‡­!î¤S'`ökÝu­â ü~sÒi )×Ûí“cd’e˜ó€!€´µ÷ ×­&Ž™i§ÞjÿŒM#>h6*Þ‡wuxßFôÖjˆŽ`o¯kƒ.™40=^¯Y{Øx[oîÕ±@ úÐèÔË0yhPç@Ðí ' `£é:°É¹B³ë5¼ÚþûÂ/Ê=t‚|}{ïö岨M`ÅÛ¸ëþÏ9­æ*HD^é zÝ¢úþƒ?*“"ÖúªlWÑ] ½ŸÑ’D\xÈ‹PCFZ]ÚŠuž RÓ¡’+ÔæRd¡Ý]’曘Bßhá ­h”q1Ó·ÞË;VNñ§tµ°Æµ³£½OU¾5Ò‰ê_†¨T¥ó󯕋wÖ½Zf±h…¥Šûë·"ÙàU ʨ ¢Æ0„}0©^ìï„¡â®e癑DV¢®•pÑÀÕ­ÇÆ*H7¸^Å"21¡qš²¬Ù”ÁÃtVäÕçm`óðؽɪ¯ÄX³WË4VõÇÒ™ àŠ&¦m.W‡ÁU0„Ñ ƒsÞæE á­QXÁNtDQàÃûHH‘°A õi)~'Ü ´‹æƒ [`ÃVaê-Ü×®1sóE8æ<#ÿWw¶ûÁŠþU xIdjB2 › ø”~éß„—“KM˜’¹ecÈ-hþ³Û{òÄÈs—Iž¶—È%sm!H¨ÒèX“Ó“Öo‚\‰Âæñe633À·l¢FÕÔØ §M|àmOtZtaûOΰvlÇÜ0(ÅÜÐM»®U¾}WB6ð “Þ§ÞH’RÁžRK± uÊs7Onã³[?Šoöt½"ft0ºmRÑÒÜÍŸéu€÷@!«+aÎèä × a@-ºvÆjswÜ50 ]u.7¾ wZ¡6[ÅK ywݾuaÕz­sæ kþÑuóm½Yo£eÉ®Ð1^í·è¾¦¾ßè¢Nî]­¹ÿÍ7ß,=*¯•×ÊëGåõ£òúQyý•+¯ÉˆxëÙ—hçP&«íм°­Pέ–¯".ÌfÏF!œxI1-!k]€½MFPå# ×ÍÕ”Ü~9Vá·°7X1ð"i¤¢8²h„PƒºÎЏ¶?`5‘–•¬x ¥PrMÃ7sé±´Ì`aE²±ÇcØìƒ1¶‰Åàä™s~»û*©^ µF-³³ó|ö7ouíêV „Ǟɘc$Õ%++++3+/þ È xpó›ã -ë;g üé—qF1{+¿;nÜX,3dßÃè2î3z6FŸ)  “\Dìxq–&ƒ>…¢­æœƒA—sàÚ£Œýï¢uåLùñd½qàôcz½÷ƒçYòfïàu·A>­è°ý§ËQüÍî&ìþ‚¹¶ØÑ~À" ä??ö(­È åá8e´¢O@*ŸKÊÿOÝ¡ô–Z4Ú „ò{DÃõØ!äŠ{)–ml¨d|&Ÿ;̧?Ò?©¥IÛ‡8Ä‘=¸FˆªÝ$Wp]žÙN@’æâHÙxH‡“ïEÿ%DSY™[”+s»=jEONÑý0' î€MšÊ'éFÈæNL—œ|ÅäxÊé7ôYDLåQÃïߤ}ÁzÒT¤ƒ–B.–³1P¶lX0LðÈ@fl[HÃÚ’]¢!­h5^…Ží§MwtVð=—±mÚá¢ìmN^­ä–ê/NSÀöKÜvSZ¥5Å3uLÇí? ÉÆ£ÿB§eUéŒ<|up‡ø¹^[•g–tm òJ$öПŽ< ¯ŸXŸúè—;¿Ï;­ãÂèßÇò¯<âÑß?ÉwOåߟåßgòïsù÷5Ö#S:Xí¨' Hn) €k)¥æ«•Í­lð¤Þ8?Íçi½q~ž5γzã<Ÿ5Î/õÆÙxÄKyÝ ü¦P¹ãD9nä–ì¯åÃìÂí¾t)r¬OîÍûéIáz¥¯Ý;ø“+]}r¯ÝOÏÂc¸ð§_Ü5}Œj9Îd¿E±gNæìÿ¶gŸ¯¿bã®1ë_{Xµý·Á¬b9·Àð§EaxûæOÞ"öA]#·Ü¼‡îz?jÞ(ßÃ\ä.*a`» Å·°›3åƒïü~¼‹Ý·EÁQÊ”ß:%Ô”ÿžÕ]Ó‘R)HO¨Ÿü èi¦æñ/!Á-úS*í‚éuä¿;ÖÔ€ÿίM½Ê sTŒVž{*žmǹ·«üeT¯ÌwDýhß¼§þ…X1ïI™ññ¯>;Ê„‡gßîÏÐݿܲš~ëÌý8µò-0f9×[¥k`.*êî‡ÉxGB&n+*Nä×Ö¾6*C€ð.»J>cÖt"L®ò£}×:ÿü@ÙœÐÑe–;¥LŽ9=¿.Ë„ži˜ж“ô\ÿl/qæa‘ècuA>­r% Mþc?ñ¿>pt«“™ûEÝ®|œÙÖ½[•ǥ˞±/g4®Èê®°Ëú¶†íBWF¥ “Eœ–ƒŽ†%yßÏûùŽÇ ¹µÝçÑömºóè†(Ýy¤ê8‘þ=PêåDº~Ñ9÷Æ8¦Î•xv½±¿_,{‰ˆnò@œùÐNÌz×Aú;E¼—Ûg!» ÃžÜz?(qÍ÷ÄuZÿwÄ˳˜í©ÊQs³-¢Ì-¼MÎÆÔŠ!©Š-øþ6IMå¤}YܾU¥d¹ùÞQj’;Ý?7øç{Ú=/Éme Æí¶“üŠ[êÆù|7ê¥Ý¸ÃÝ ¤Â¸ýLî< Þ“õwÙÙ×ZQ{^4×÷±Ç^b‡;Þð@¢…lº“7`çù_½ñNß÷°í^&€¯@¨üÑ-ºóË·I %¡~Ñ eG#£Õ¯ñ8ͦ9Udq?'ƒ•DG7¹ ²#¿8ªÈ´ÃOv=pSAÑ«¶NÙÊÅÞkù‚æ\ËÈš¹ÕÙ±¿®ÛžN¸ô!UÓàˆ?hÔGøä£ê«(»2šû¸øÂU´ž3,Û¡=S«÷³$Çh8*!>ž •2F"5pÂÜNFqEK9™¯ ¤CÀ&N˰§^ÏCOx2Þ®íþ…óÞ‡(ê÷ª‡œ`a÷7ìúîEèÕÛÿBVÑ¢Ž;Z ^s5âɰ¸Uµ(œáWF̹:壱ÐU¶È]ÿŽWJ“ÜpµÊ#eá«n‘cùWX9MtËÕ+œ;ÁB‹\›¿&h²aC¼“ܼ‹ÆL‹\f¿"v”@@Ž*‹Ä“òâº{|µÈÑòkâLÓA‘'ÏáM±ß9þZäh÷µq¨×Eäuçxÿ£¯Ð%^ûvüµ˜eôÚÕú\…[-Ç0C¬dø<ù}ŠÏÒè”Òã}Ü» R:½¸ÔûŒ¡u4Húæq߯³W¬—ת;êö¯³Á !ßpòY‚¿ê¼@ŸäfÃ^øæIíÕTþ.5j̨zÍêï'QüÄY?wÂÆò4)’ôÖëôSuÑ·?-tõ•mž´ôœÑ<øÑÝ¢ø§¸ja³»ÃW¡ÝÓ¯ŠÁÊß²i²ÜßÏêï§Qü´&Î[Øôkâ½ðÍÏßÜNT¶yÚÒpG‹Ú+=dÿ<Ǿµ°ù_»w…ož}w»YùûÏöÙ|¦w|Á{îLÅÏæ¤vùÖè 8Öó¿%uT¶yÖÒk¾ýè)£øù h©…ݾz*´ûå_’Â*n“Ç/~E:TÿÅ¿Ü&[Øõ{¥ËÂ7¨¦Þ“jT+ÛüÒ2Œ¾j6ðÀ„nAÛ-êÏî¿ Ê£ë’ÊKéE…dgâ®^ ô0cä½ kåf&L$êMóIv©íIœÃh_'ñSuž§làx°Hz0æÀ8 ÇâFWé` †6v]Õ÷<ýœ ¹Ž:Ù>’/Io:ItöU3¤€@Õ™°žÓk~¨ÔÍxBµÜX?e ú¹» RQ‘(ûÃ<í'ÞH­è:›"ò8ÔâŒ#(°Í¿»ù`õ eðmô”*¯B£_å$°z¬ã>0¬VA ºøiÕ )`{Ø„;ãó ¤-It lt¹ö1°Âè%}±¥~•õ?xÐXß›òƒÚ&Ê6šÓŠ0¬bèyÛíöo€Ô£a/q''nõOFŒ“g.²Ð^5N¬ôº¦´Y¾BQ¾J¿ÐŸŒ e·gA†39\ ^UCއç6‚mYÁa6D$p²UŒ ÁYóQÒKÏ®u¤PøÜ è1Q/Q>J̧$3Œ£^Ö§€8Å@±8ìzŸÑ~cƒUøò<ÁÈ*«#:éY´†[[xG€<Àî*¢²q{; ) &ÊI©· mÒ§‡pV¶šÛhmI¢i"OD8»L&)ðûU<¤8žQŒÒ{§ÿ“¸§Ž¨\c©Î,G‡‡õÿòé¿ûøM‹îVñžŠS£ìôû­¾:Úq|þ(z =æEGÃ9›Á£ã5žšQEO£qöY1;òLãŠ,»)"¹Ó ¡:ÓYH†½ÄKð­;;%ŒÕ³,[Õ|Œ§/CŒ¦¥"¼N³>^#å#+>Í>'…Õášxg_åžøV‡ú¤ý–0›PXP“àu,>ƒ÷t„C©oá:ÅÃÈäND:LÒu³p¹´ÚÖþZ§ãÆÇe= w¦YÀç4¹*Ƨƛ,Û(FŸJàOÃ.áØ^ÈNØÕ„‡H¡#æÊ2–ùú}½Íý`B>|závPí°IC~²A“/ î‘"&io:À,ÙjÁé)`™‡*ÖEÄ'ÑÇ H\]$Czaø„ápE³…j/0•x+„ÜÛ _Î`k¾]â†î_À±žÒ‹…‚aœ |2té>í(&Kþ;°…Ø-ž‚P‚îh8Э¾oò<=—|Úì§› ÀÑËŽY2ãÍÚJôVA`œb£ER¾äÌ$›@BHj‹TgÓc’åˆ" «Q{ÙO–·“J.Pi²ÎÌëÃ` Jloºõócõ;lŒO¿]ºá²žŽûÏ1Ž€‘ÁU|MÑ¥ˆG^!Iq(qâÞF†Ë3é Ï«Ä'¶CNHJ/ÌžÃfÄß0¾ÿC6¸¾ÌÆ£‹´'¡þMXÚŠºƒùáËá‡8Œ‚Zy Eƒ Îx©¸<Ê{ð7ÊïSI07ºÊÆŸT|ó5‰£48ý˘Œ³"Õš7¿ÊØ® 1û¨JÀÉ9O†pE¢A‚>|¼ŠÓd‚LÌ»îM\.ûç!k>S¬_4žY8¾æS‡!²tg)b³ˆ2"™5²Á’u5àHg#ä“}É/ÿß½¬ÚOtê{—8unüÝ_÷v:ŠV…€0“C,±ÜU:ˆH÷cP70ŒZÄvX°ííwâ­L!~}GpJ|+>‰'ÆçÒ‰áuJ˜ŽÖш˜áÑ”†ýxÜç;ÿ,ýB±ÊT”àˆïÚ Üãަr¹‘p0¦f³ø”šð‰Ñ¡ï‚¢÷GÇXRãÍÑñûl¯P×É,@ !"äøz—I™Ï$ð2h•£“f<¢BN¹Ê¯ÒÑF“ÉhóáC4ÛçYvÒ¬ùáè!@~x•~JîfÙ§Wð_[Qê¶d(‹Öël{Å@„í¿íbDöIwçðu÷pç=üõñðãÉÞë.Wá·x-í³/°äGØétŽ÷_}ìì©.-))‚rZW]Yj´ÞЭ7j´~¬[?®Ñú‰ný¤FëŸtëŸj´~ª[?­ÑúgÝúç­ŸéÖÏj´~®[?¯ÑúÝú—²ÖKA+ ă©@çAÑÒŠá=šK+bÀMŠŠeË@“U~Ó©­5é¦òUV÷&žX–ÔNOt‡ngïý‡ƒÎ4C-¸Ÿ [Vé D,@¡’Œ¸ŒäË$æâ%mOlÏj× YÌÜ|7¢djœØÿ{·sÒ½Ôí»vŽwÞŸ4@z냄|W CøU÷’¿ë^6K†Ã£;ìþºsðQeÄ©î°Y¦}ÒŽhyÓ$å¸,n0 \z»UÃÐ.Ø©”êa’\ÎXÚ‡h£@2lN …§¢Öã&‚|C'‰E±Ò[¼±ÄÏñº&~cî`…±€UCâ¯ö{Ï×Náÿt˜ñù‹O­¨³Ý€`4PR$¸Ò%ïÔ'´B…lOz$Û?ŸNd‡©4ášS:mkìívº»; DW‹4à_].¤þg4{gG€ô§CT:à„c¢íÆÊÐhýpwsd“ KOU¡òNAË7&˜ƒýb¢ؤ{¹Ýø¬>}†ã¦L&u × rº¢0úÙ´"ZôUƶêÂâ^š©Š¹U‰¨„a1O(ömi޶Ù,4¶caUŠiÜ杻ë Ë™‰,ØõiÚýT…º©9°ý$OÉ6'¶”Ïݴ툱š¼-¾ýP³oÅö•¸­åeÀˆÌ>ÝŒóÚ¥ë0'DF²áˆ¾;§¢ÑÙOâ!•}bVp–¡¨,ú&öP¬4(<ÒðÊk ZÖä¿hŠÞA%)4ŽðŸA²® ,_»«8Ì*[ƒrÑ'lsÕæ îØ“«¬|`—èµ’„É„òOlsí4Í¿)kˆ›˜ °žhbb‘Uå#ê®uƒ¨’ ­‹÷£œ[„ÖIùYÏ$Çð2Fí¶ö#‡«Ñ)ÆBDº7KæÆóS”t8~1Wÿй‰oä“Ð'MJp÷Y?smµ]Ú Y¢bùd±K´0x˜y½·{ÐýñGoá˼›¨ ÷bÊñåOO‡7b£p·8w Ž×ãµ³ò7´Ùƒ[°ž¤ÈÇkCdÉøo)N€IÀƆÂv–‰ö…t8M,ØéR.€¯† $2DM’ÞÅ0ý}JÆ Ž·““†Š³VjièçSÒuÒ7,Í88K:!»¯#ôúÉg´¥Ãìÿ¿Ç 9_fS–wèÅ…{0Àq€9œ¦C9øÊ2$k·¯“ÞÎgî^˜—õTÙ:Dƒòä#–£5Iº|ÄfŽõ¸r,Ñ7”jE²»3¾4à_fNö¤Þd¢"ðœøÝcþîqùÔüá17› ÇO·„ƒ[<áOOjBeô„{ÎôéBåO?ñ§ŸªÀ¶FrrÆáaf®áç;\zÊŸžz+2C…·£lE2(9syϾÚòøÓÏöaü¹6í•/Ö€ôÔ™‡'˜¹þç_ý˜=Ö3þîÙͰaÆ €ƒ þðŒg›‰š_¾!Ôp‹çüéùÍYV눲‡yÎ̾ãÍ}1µx®ZÈãO¿ð§_î‚éØÃ„j¡RÀahHÂ8ÀDs‹û'ZâE¥`¡G¹‰`!?U z‚Û öt­jÑAϺhÑ!C«Z8РܭpP˜½i?Í„òk^ÿ.ÌJ¹t«¼Ú5èõÕ^µöBZÕWµ^Ï·uUϹºVõ¥«ù-_ºõ—ì\E2VåÅi¸÷÷sqÑaƪ¤=¤¹ö\ÅZùJÞm*E|,&ƒÚ#÷A Y¯—÷Œ0‚ÛÒö¸zôãô2Yo°Çþ`è†þ§ë߯‡µ§Ú˜kª'¡©à¿ÇóNg÷x.~*þ{²0Š#<™ À§UÂ?Ý-vëŸæüçY€ÃO¿>ðöwOçZг: RÀŒ~ŸÁ¯·¨â?ϵÜçó->=ûv—l·~6~™ ðßóï öwÏçBÏÆ£›áþûeù«yh]#„§ÖÕ8òGxhý‹Âû"§˜´$ý‘j û‡û <À ”˺cQ$®Ï’]……MÀ~Cœ9vXB(¿eöQ}·áωmúÇ™” sA¡¶”Hó±÷ëãjq¶†n:âj9cN¨‹°:+yâýúdž•¸#5ô3W8[P¹ãU¶ÌiWßý4kåöþÛ8°WŽã6ô€3ñPOîù páôxêýút4âb ×ÙÐÃÏÄ[Mñ «¿wEŒ9£üìýúó]ã1ÑГÍÄîóºØ%9î»ÀpËÜÍê»g‹?ïUXwÆ{ÖÐ@ÌÜ_êï†N,T~·ûâôxîýúüëž•–³W.d Òl ëÑÍ6‘$ßïx#‹ÛçŒò‹÷ë/ßâæâ44€E3ÞYš $Çx>ÉÆªÞF½7‡sÚó¤CÀ”gˆdôhkæ%æ;gEšÒF³®0ÖÍÜ"àÑãÙSÍ0ÊÍ9u>FOfO>CŽ•é~òÁ¨ €u4G?ͧ†8) =]Hz<ýÝÓÙ`Îm»3P-F6úy6àÏççâ_ x‹ÿŽžÍ^ÊM¥Š/G{Qµ—c]$£ç³w«ëö[X¡K_£_¶<¿‰Ú÷ =»Ís¿èÁûef¯ÒKÿÙ»òæPÏeæ¥`ž9Zgõì›þeæØ5_>FÚo§øëÌ9nÀoËÎË̹nÈ"«4Ì™sÞ‚—UÍ‹mfŸ‘[²šY`»ê“ÏïÈÕÇî7c·WðÍxæS±;FéS±eÌ÷ijzW> —ÞšýúëÎSóõך14Wkö›®;íoºõ§nÍ~ u¡˜óöF´f?²º@Ýà‘õ¶€™Ñæ‚ô†ï£7„Ö“[ö[ÕÌMð[¼hÞ%ð­ÙO»åÓãWZLË{t ó¹ Íí!Tâ0³ ƒB+ „Ï·¦=!4vË‘ÙgÎ4‡9aöl-GC˜9÷¬ ­Úó·Ýd&476&Ü¢V@É å­l ‹„´åhw3á¾µ)áî`o9šéÌ•,Ä’0ÏjŠzv«öjZŽž=›.Ìð×,°0$èd¸ùô s8I(<\4yn¢1œl+S—NçQ†»Ý£‡óÙLÀõóav¯’KçÃãÙ]+î•OfwŸqY|øiö5ÄûOgSS>ÿðóì¡ê¿­GžÍîFŒîÃóÙߘï|ø¥%ÞêàØx¤O™éæ–gLâÿwvNNº’|ÀÉ5Àp:©Ý£ÃÝ€þ}ïÿø£*É\ö?ºy –n“õà?z͵²˜×7ZD™#¡ æ6öb´ÖÄQôM4šžÒÞ&OªÓ+Í…ç˜ôàëBýñ§øÓž¾Ù–o´~cÄ,ø JðÙu£½Ô/ÞlËR¼Å°×!ì]ô&r;où¿k8¬YLù7Ò&ÚÜ”×VRèÛŒ¶#¹j:˜çÚÞwåN®·ÆÂÎH¢Ïéx26èºNw0µ^S£Õ¤.‰7ä]2%ãÖð- VX¬K×jjÌœØâùôZ5ÌRÑ ý,R¶Ïýî±£|z¥Îu:>·ÏOïžÎçç@ŸgïžÏ‡Sám«Ÿí*5oYËËwèÎåf7lyù [^†Â–—ƒ°0–•q°åålyY[^^ÀÂXVÀ&'NÓÄzÛr‰\þqúhEÓ³ÿ×û';G¿u‡í¿…ÀФ"¸?·*“Î^dAp„­9*ŃbÛ‹Æ´<ü5d·ñî" ±\põPã"¦-59>CÀûj÷šÔ9© â‹Ê„–@Uj5óà!9ÆÙÉðâCw­"Žy2çRê/¦Q¹'! äíÿª»_*/,övXÄͰˆ[¡äF˜[Fq {b››ÜêÜæ¦Ãó|¡ \tÅif' ®ì‹î\|ÆHʶ2‡íßÓß °·` R,TÞ‹¥÷béw)–~ûÂfQÀôÄÇZb¡ÍmÙOD2‡ƒ’däË:. ‰÷·ú nu­…KõN/QSSéQ³d¿´½;|×~¨´=9-k„^ÞßË‹6,̓ôûüþÿ> KŽ{ów|­ùv¡âÊæ¾ë?„ =%,> |xaš°d`CU%%Ø=qq•2ƒ ǽP±0¡ÂÞ…¯-`<Ö†N’Pµõ¡äe’ÇãYz>L~Ól VØœ¬w/ž,Êlpû})Ù™{æ^†ùûÈ0n¤Öw-ØûŸ)Ü<¿¼ó¸®ÀSzÛ„„ Ç/BÓÈlº½˜J1©dl…¶zbSéjîE©Å‰R%;õµÅª'ŽX¥3?ÍK¡ÜkeâÖ“™âÖ“¯žvê^ ûº™'€-fïîE¶{‘ío.²¹1öß½G÷ÍMd¹æïžÜF¼+½ñB"ß“3bäjKnpD¥,8{R{n.–bâ^\\œ¸X¶™Ákô«K‘?¤HsÔÀ± *“2š)eþ´)³uƒ4¡u’çÝK¤_["­Î ·Èt°Qx§ïå×{ùõ_Q~uSEý-„Zºþ$ØÐ3¿¬ûÓ¢eÝ™wrHþéÅÌ\šŠÆUñÂ!ªª”k@e i¸Ù¬LF«KÐ3ñ{/]/Nºžƒ.]ÚüÚ‚öÓ  ­“Âß5á… B” àOg àOïLwzÌË~þDº÷Âú·/¬×«jPæЪçü^œ¿çïÅy_œwS¿þmd|ºyïNÎ`m~Ñÿé×ýK%„:ðôÅ<©ã ”4·fÊ$äâ¸RO¸¸6À!êùzjCéÞÜ«‹S%nJ$6™|m­âçR­B—Xú+h3TޝLÛøy¦¶ñójßZ¨{}äûÔG¼> £›Pνör¯½Ük/UÚ‹[¿âo¥ÒеÿUÕš2ç×t~þ«5R‰%¤ýü|;íÇJ{º'’VERÕJµèçÛªEöJʈñ¯Õ’J÷õ^sZœæ4É{<ù«+QÏ*•(]oõ[!ßÐ?ÏP²žÍT²ž}CJVëÅdo_ÖÔ®iª)Þ+dß«BV]ës‘‹oZ©ó^e»WÙîU¶›«lnåÁ¿糫¿\¯ à{~UïÙ·¨êÍ”©Bjà³…©–ÀSC# ¨VmÐêoíf¥žølz¢½Ôª* ßžÚ8“FîUÊÅ©”ϪRÚD÷µµËç3µKª‹÷½PºÝþÙ ­óùL­óù7®u:=žy¿>»ëÇ@W[pai î5Ô µU‹ oï éóÑrš Râ½>{¯ÏÞ볋Ñg:x%—„¡oPÑ lÃüºïóïM÷-•öBúðó»Ð‡­n«»•(+åçw£(Û8¨qŒä}_t)¥ÝkÕ‹ÓªŸß•VíµxöW)Û¿ÔR¶©`æ÷|0ìïžÏP™©„ÿòÍ+áE¥Çå¹÷ëó¯­˜ÛJ YÀt¯¦ÿK«é^Ÿ…Ñì"ÌI‘GÁAº½Wêï•ú{¥þ•z§Æý¿†¦O’Ø÷¡ívg~À/@©ô2 ürÇF«Ïó»‹.õíåö<Ý¢åVƒ_îÜjвãœN[ô jIß¿¡”Zï ‹3,ürw†…ÀIwOû×¶1l<ªmd€ÿ~ùÛBcü2ññh¦Ðúw3C´ bÔw¿Ü½{ŸWÅC8À{CÅ¿¸¡"DÉÎ8sSõ_e¼(¡ì{Sƽ)ãÞ”ñµMßýò¯cß !ð»µq6m~³ÇÆ£¿«Ýc¦0²‰l<ºs£H@×_k±i,]Du¹µä†È»1ú Ú£GnYЙªßßÓz2“æï-+‹³¬ÌIî75­6×åwmeÁEç#P#AVôÇÒÒÒÇQçB™^ÖàÞ¾Œ{ã,&ãôü<GWñxˆmwÚxô(jL‡ãä,'Ã^Ò®x€CŒâ1Œ˜o;ŽÞŸüº]¥“‹hý·ŸÚQôq-'Ó!Ðåà:š\$×Q/³ItšDgé*â0ðÏ‘E(ÅýY.§’ˆÔdˆâô¼ºH†¦#Ž’æQòeûð+ü¿ŒH_å0 šÐ2‰ÚGãøü28°ºlœà(WI”OG£q’Óô—þØ^ú1=CͶûþd·ûëÞñÒwWà5FÓü¢YüºŸæñé ÙD4ÂÏɰŸžöÇi6Í£ìs2dq?G´FûÃÏÙ§D)Å/A¢jCkµ]ÅŸc°W¶Ûmø£û©ÅDÞ€YlÊ(<\Ÿ\àGë§qžô›x hˆà1í]D—Óœv%Ž>­ÇcܧÁánEÙch‡Pf„o´vÇD}˜Ùmʇ(ÚhÓB¬~°«£8¨¢Óëès<˜&ø ;†“ »³]gÓh˜@‹IÆ£`Øc= öÐ  ãQ”NyÚO¢W×ÇÉ 2ŠÞdc ùÃÁJZ®ÈÇíÆv®Îìâ2hƒl´^ë,ËšMÝ—ÀÏ£§Du^½¨ý*M¡?üÀ½5Üm=àã6®Ñ®ö!šÄ¸™eKŽN§µL8< ûðÚBT\¥ÔÉ{Iú9¡‘MßIÛÞËF×j¯^P8Iâ¾ú)ö›å6ŒQLs& ÁE\‹Ž4©U‰ÒÀ¨[iQC&ãòýy´ÝðPm6äRk…7d6FÚöw(;ýï¤7±·'övFãµJQbfàƒ€^{'‰ß«bag’8¿¦³ãn±½ØÅã!à®\ð³qviÍI’Ó*.bØcyÄWHÒçaP>·í A]šp#Ø_âl]½q»Ú’xœ#›wÁÙéVs³Íƒ6–p‘ FQü9Kiò¸×ƒƒ|w@xȱ-VQB®°™ã½ŽÀ´—`Ÿ¦°/0A'†KëÏ-¤0{´˜» «P€…¶ëÆ—ö,nK|gœ}Nñº@Oé~vW6Ωû‘â3sõ€af—ëjW½ñR:t) Šr‡‡Øá4î—åu·/`ò¸OâŽ-éÍöÒqqù ÆO M¼ Þ/iÙXÁÖÒŸ3µþÞÙ˜9C «÷&‚/æžÊþð¸î¼ðÏc¸e ÓãÕsKìOæ„þyÅO‚`µð‡‚ÖZr$ãŸn+üóSÿT r ¼K°í_ŸÞj ð\½O+—ÒÂ_m9ö‡Ÿ±6øçç(þyæ[Øè¯Y¦ýáÙ×Ì ì<‹âgµ–ß堧 ìÏïðÍó(~^--lü­¡Æä—;ÅüóKÿ2ÊZØá›G›3ù£¯DâŒñhnl¶¨¢ôÏ(!©Tø üÎâÔÒ’X@:{ï?ìtöîj[Î# þïÝÎIwC7ï~Ø9ÞyÒHQþÔ,6G{Ê£î¯;uÛ&¯sš£]ÄØ›<77 xß2Ø)üf?dn7ŒŠÁy bËvžL^|ÚnÐ'!÷kàhÃÅÑèÑ÷„%ô4új˜zìc Žß¶毅±'!Œq}ôïk\Qü+aî§2ÌqÎï{\Qò+aði¹ÄÑ÷‹E.²ó•0ùó,Lrfõû+aôYŒR®·¿V9gÝWÂìóº˜ådìrNƒ¯„á_æÁ01ý}°Ì_K24/ªÙŸêï…nöA”—¾¹p‡ÉÕ‹Ž÷ÜêüRúÒÊ‹Ã÷¦QF‹âµarÅù$VoHè…Óiñs>n$ý(㳋$ñ“ªþŸ„Ô3)=¢8 ûôÊJpâ£Lç9´†å] “q~‘ŽÔ£ C“ñ«]úô:ëž25´¢Î\º³r;J®¢N#|î–2Õ¦L¼xª4A¦r}ëàš¥o`+×jî¾:ZM ŒåºÃÀYWw¨€µ\B¿xç‘ÐgÀ\.ßÜóÊÁ5`/—6ïþ›H›5×P.ÓÝÁ:n*Óͱ–rÉé.î‹ÛHNs.ÊÈ'³=̲‘ñ ó ã" ‰‹Do0í£ÿȵø)ˆ¨2J¿ÏŽV( 2X@ bl@î¿%ì–Ê0:#N Q<¡ž 9èÃåÓ1y›ôâ!út(LJ~ÒÄ㘧e_ç,$â“!Ÿ`}yôvïpï6é5ÂÖË./A¾ÙTž?£éå¨=ºæXuíh\(ÚØ[¿>Š:ÑÞëýNôêŸ@‡¯øáÂí‘ËΓû‡»_ïuÕ§ÎÞñáÎAw÷ãIçè½|«W˓X½å0²‰´ƒwžì0¯w:;4=Œˆƒð÷«'û„BbùÇ? wnžÿHwЕŸp}tˆkfÚÙ;:þ'ø ÝhE¿½Ûƒï½„µDÇ `o·c7ƒ)™´0³ÞèpïíÁ>pÿÝ=lp„ý¶²×„ÍÛ?Áû49PLû‘ÖŽ›°Ñv½qɹE»í¿‰v^ÿºðK{ ‡“}!Bßî;Á¾:;S8GãM¸†ÿçœNsñÿ]€(“sù-6鑳þ½‰Ñÿó 㮲ñ'²èàÁ£à…Øá˜¢ê“ÜØvÔ½—¢ã2;¢k§d¹Ék|ƒQŒbÿJI¿lß|æÉÄù"C_:_QÄœýÍçß'· xITÖÖ½ìî>Yú1²º÷“/½d4Ù&;ÕáÑ0l;ö^ ½hïÚ{ö^ ½h¿6Ï.zɆƒkf :ÈYI9 Y½—´ê+ºîO áÖOm$ÕéÑah﹟ÉåØÙfϨ3 w9‹† HD9ðéZ’ÂûÎî»ÚB‚ÝÚ‘&í ûºç ñ‘ Ò g³¿¤pmæö7™ˆÎÕ?Ÿ°ÜÅÆ üá '×°Ò}<ÊûÿßÞq÷`~°eÊ.Rèÿ$ã.^`6\ÑúºI„Ò\tŽÏªí -«s© efsQøæMÞd òûâ ÙÔ™0bI÷ í`ÊO’4\ÝJË­•ôBr©N!Ç F,][ùpäÞ…bôW“Áp I‚@µ±žÍlÍö›\eëƒäs2€U ’s¾ÊûIžžMnƒQ÷¥¯ÈP˜Î®$ÉÝ™Ì$Zþ¼lçTXÞû½ñ¹¹¬Dp¤¤wIÐiN²–HÒÀ”šháŠÓ‰˜ 'Püòð¼îÃþ ò ³.$$g¹ËxŸËæzZF Ÿë!,à”ijŽö ýDû2 ôÆùÚKúPsê¡ 1|,E@Q8ò†]á'xòèÅ “UÙ2•”(†œ&”͆f»ºÀ8[ ÿœ£ ÒÏ’|¸* JïÖÑ룆ËC››è ú!ïöi– ""+ ì¤¿?üíâºA_Ži!*_¢l] ¢‡±°MZôX‹MõP‘ÀËÉz&¼o<(6\å?WÛK|BÈûcI%¶]¢óº«IXO)¬„Åè4P¢_Ž×xR…±6ÌÃèΈ7Ê—ÔÀI=¸1+zú×~bR‚¤CDZÛk7"QŸÚKíZÚƒóX[csô£ÍM™q ¦Æœ¯ü©ÛÀOü¹dòªþ¿ÐÍèeôh‹àysÖÀ,ãS‘&58¡‘óè‹ÊLRÄÑ–^ò¹ŸÙ8‘eçÑáǃƒv8÷Xg{) -vEú‹’Z´³}aÏ™'jÈ£^ÒMñÐYSßÃaù²eç°[õâ7ÊÅ7¼6„ØG9ÿ XüC *³mO‘͜͠w¶Ê €£(s¢€Ð?ãŽ:Þ«Bú;ÃþŸr4÷Ð Uö 5MGY¸˜«gœiEeÇñ€Ró ³(&Šnô~ιZbXÂ1Ã\ 7|ÀdôôP£6ˆQ¤2W«sûB^bK”ö)™Êp t‘‚¾’ó1Ð`s³ä`ü!¾ß;CÇ;Žòé)r’”~öžGÀã)OÞÍÏyž ÎðFˆ-9ÏaVÉøµ´6÷²Ë²ÜÃjß cÎ[£~•cl± ‡™›=s€Ö ØW®‡d|.Æ1Yã‰^Ÿ Ðfá0N¼‹„‰'Íy5· ™…”9qÊ W匲æJs“FЇ9MpX¬ïg¶jÉ̽ŒüvÒxÖt¡¡UæÑ2LtN7^?€›gËm Ùt$¬CŒ–‰™g÷ ßçêWï&£þzUÂ4å£à iq <ȳ喙Š=H6»â¥À ñÏlJ†,l1N~Ÿ¦c¶j`èÃ8U^}ÄlµdIîWÈlQ~±”®ë‹ôü¢¸ÿ9E%Ϙ´®³éX-ŒAž¥ÌI yô#˜¶ýµ™s””JvêPp^¹c|_¬e$<-ã"Ë|+XÍ·œvÍe¾'$•’±^¼ÞçØœñðÍæœ|sàu¢þš<¡ìRQԡĺ/["±ò¥[r "’ìíªºVÅîÔ$zú2¡œçãxtÑÄTfæ^"3 ­˜ בûSà-Ÿ1|½CÑ.ÉïeNØn·—[<|“Á/ôM”LzMŸá| œz‹ØB—žœÿ$¼' »éñ#@9#ú—.Êç‘€J]v"Ÿî½ïÝEˆ„ý¡Ì\ófÖ` Px$óAz¶¦ó_*Ã&Ž–ò{‚º‘­+°·Êç;ñ÷A‰AÛ7è& À"‰ª§ŸÑ7¥©’ÑÄ×Ñøëø¢í±FİX ìÈo–ðn‘T>íõ’„a1J“Ä©úI/í#7W‚¿‡us`¾FÔÔb6¥Ðc‡N„݆4lLS¤t%Á£XY>·°FÒ>o{¿2G%µ‰?ò‡Ù¤ÑlÚ[îÐa-_àå>‰ N¢GQ"Š÷²ýÉT É{ ™˜ôB=DNÙJ8ÇýA’ëìv6…Èɉsa¬øÙtà v¾…¾×[*TŒ åÀí» ^À¬&×ËÖ%™Æ§@|DÝFƒtÀ—Oÿ‡®oí¸5y‹A]ÅG˜>ÈÕñ˜N_ë§wGf–/PbFY‹ÖÁmïÞ]‚q÷ºÆ@Ãr¦X CŠ´3<Û:Ù+ã/ÁÑNOÉŒ¤“926,Ûa!:ŸƒDŽ£6¬Íæ¬|$Hù‘TŽ˜|p›ãmB²æÄÉÙv¯¾w'Z_ïáUŸâ¹%ÉŒ7Ɣ̔°n®ÔI<øä1{õÞö>‘¬Pç–{–Žó‰Hﲫ0ŠŒ´Ô> 2ÆrÕŸ^^^k­(êì ÔVøepÝr5æõm­3ɳ‰ÒÕNš„ÏI;Ñ—VHz_ÓD²ý! 2e;XžHLAé]+7ì¥ÁªÞu$”-%dì¸×‚V‰®r`ªÂ:Dý„ì JÑ8¡O!Ûˆ+wTNJÇh Å!ôýJžw-ÅÄÖ¬mxã^oz9¬ ’ÊYLçÐøòRpEu2ï¶é£kï(Õh½Yhg¨éïj¸ååf™fÊÐðŽaûZ:i)îD3 &UÕ)L‡×{¿“Ì(w¬Ì]¯¶•®ì$¦ØIvV¢X"‡£W+Ñi‘qôòetºÅâ­™ø0¹û‰M|0¹û‰_æ}ûæÝ­÷+ úEÑo¿ÂÄÛfâ™L-=†¸šâd¯ñ’¹#+¢”‘%‘ù˜Åfù²išõ˜;\áW ÿ¥ û4=@8>¨*§w2¹JH€JÙ³"ü¬°¤„¥Ä± [؃íK¬ f¹Þµ»t°Ð…¨’8wFìÛsíKéìÖÆ æõã;œók¿T|ʑή”êŒm´¿Hò•2¶¡[šäò:,o[ÖxØ™|?ðQÔJöT†ZòýéO›r6j˜^¡mí«™´5øæ2ܶ™qß]ßöGƒ±f÷¢*{»e9Ó s¡Lr„ξ”ݰë¼$`[¡Vdµ¬³J0©%pþ¡ãÙ®‚SÖ6Jú ÌaWóÀ±zŠIM¶§ ß÷¾¨miž"[6YjȤ·µ90‘×,Ë™ÙÀb,¼¹¡]­&9m¶=•”ò–ù¡qK¼ö¬l+Ó3êÐzÞq'cÍš!ꥊÏZô6™è¯åg±}žL£q6¡·õÍ¥Èf8ö»Ä®zãÌ­Giá’¹§âŸ=e<|ÛaF0·Ù ïÿņϺ>û^€BÝïŽ& ß£÷ÈÃóÉà¡ù²}Á.êƒtøIšQÍÐßÓA<6d[®ÞZøní_wNÑzpM> =y‰î]L‡Ÿpû/“Ël|-›™EÙ ïUÜ Æ€ ³ÀùÉ„?Ž{Ÿp«Š/K\2Á,é¸:ÐX`g'Lep´Ÿ!a¯4r¢8‘² -  Äê€Ím¾ár£¼÷Ò8ÍÚ`a­źŒ£ z|e BSÚùÐà#ç¨Ü.±a?¦k#ÌÐ °Z8&Ÿ3Ûv +š6a@-*ïæ%4ЧgŒØÕI‡ŸŠ%¦Ì¢^”’3èDÁ,’”ç1&)ÒrÄIUá*û‚Tºÿþýǹ:6Øš¼Brô´ÁãF>íÂ'Ø¿pE¦ c¢œNA¥8µ8C TÊ ®aúoô‹ŠííÒæ Sa/¶êè¸2HåhCÉéa¢+˜öu†—Cʦ-mÉ8?Ô‡ŒÜj6Æb wÁmÄf`Ã)mêJŠ¢C²W»G«Œ%!j ttÄÇU¤Ø©hGÑåºÙË2J£Åð:Áõ*ï3|ýg6Õv=)ÖƒFAà é€÷,•”]æôò¾óåÁOö>—%Žh{Û-†yÏÁ¸K¶ÃáåòòB3ؾ3*îŸâGI6bß1r‘ÊY9˲Vô*70;‘åBl³÷;6kš×sÑÐAhnnÙx³^ ?ûä*+ÈöìÙ¦Ý<µc,Je€S€ýŽþ-|ù,dËÞô]“9¥²Z^¶œ­2¨“ÁŠÓ·ý®>½¼k¾)ne{‰÷ªò•õuÏ•MvKsNÙèõÈ©¬·Od;LJÁÍ íŒ¦Ž; ÊÍ0a>Ùámkõ%ðD¹KS3€ª  XqÖÜ[kþLH½µ(ć¹i:-†& ÃÖ#†B·{*°¨À÷>Þ?|Ûý°¿·»×ýkùÛÔ?¤I/Y“³†›‡¿9ÝÉÚœçájNÇ{Rž5ÓȼÎò¨ŸŽa5ƒk{d«ÁY¥5F-³Û/†²ìë‘”Ýãž–¾-Ù)ÙJخ⻲Á5¨À£‹´§” &>MŽn™H絞üQGfÍ@i;iÛqJ+äÇ ©‰– ^"õ:&×)&ß@îùa69]‰œh$¢À”¨ ÐR¥,µSª8< Iæ§ÀK^%FÞ7APÊq²_6%Ô‰‡¾‚æ2¡èjíÛ C÷;…[S/4hçfòù‘µâ”D þ¯ŽA\—Ÿˆ;ž)vŒ›¡Ñ,Å@{îô$Q®Jö]ÈèCd*n ¤ðÓM±¡¬G[lv™I(œþ¢àØžNÈJáÔ’õÜîŸPßÊ 9O.ãÑ„¶7>R †ÚY 6ïÔ†£,êAGòûIØkýŽLï³a&ûB•ÀE_î6-­6q–M.w¨‚gªc¦"˜ ØW‘;LÃÇO3h¤½‰ÇÍ*%<Ù¥C¼UCÏñ°áOQ|Ù(Lµ70Ïò>ëLaí¸MžÊ°H_{¥:†ÂÝ<&"êâPÒ¿È&Ì㪉¾šeG9”èã<å+ãXl“®egtRß綃œ¸°S%p.®Ètp-â*òLçÂÔ7ÇËL3z ŽR\kxS4Ûç\ýhkÚ ÀíÂ'ÎŽGá%Ø3̲˜Ùù‚-nò~ýéá:tÓÏÄ;aÊF½Á{q‡_Ð…RÜJ¼܈›ïBà*lH ÿèìM–÷že_J—XA‘ÃY;T6˜»_;Ãk šãÚóˆU%ù®Z/ûå¸s@9(ÀüSt÷øxBy0×þï⿘±àõfÒ ûœ‰h)0îÆù„N¼'W’ÀnUÍv‚@ŒE»7šì1¤7KåðJDƉtѲ=¸vœxý¥o e˜ñC‚/çåíf{IÇùs´À–röWg—q²I8pÙeÍÓ|–¸M*ˆDO‰¸M¡ÂC˜hÂöúØB,GÔHÐ)êu2٢ЎéMFéf”™' ûñ’g´|ÁeìÃ.$–Ø{ïýDS†#'æ¸I=›£2„•­Øè ºÙ¸ËÊm‡«TÐ|ËÑÈÿ_Å{èÓr…ù§Ù›œƒYN›ä‚>Ú'-Wá»1E H У±JBN³ªà3ãÃ-ÊÈ)LJóޏ÷Ïjî¿+ÊË" òºŒ³³¶ãíÓ¨F ÓŒ"¢Ó¤Ç9Á&«0:.áò4=ŸbòQÐ%;¬%±ü€üV eój~A‹tD§ù”NɦžŠGýaðm)§éca]ÑÓe×Àêü?4!=éÂÎN .`ǰ¨ÍàAækøüœdw‰jDÍr]¥×°D–Ãuex¨’/ UåQƒ ãЋ‡§¨øHÚ¡¶-”«CÑÐ…ª`7å^”˜ÄCzdR~áÔ0†õä5¸ÞeÆ€Y ^¼oÙØÞܤÁAm‰þáj èï•¶Zê,äɶJW)ßEª!sy–í%—g„@ìáˆ#j8ó˜ T¢iã‚£†rÉÇ<“Šy Õ^‘|®ÍYC!AIaÐÅ/„_j§ž:¸ª·¿ÁÿùøE_5½œÂC¬JˆQt@¼„ÑÄ* ­œ‘ +YŒÃÑ4ýóíyRÐX|Np“€UfæÁÊÁD]ת³:\ä©¢9cÃ=±‡™B\+À®Z椟JLN_1Í,\—Mè‚Ì\I£è}ƒAMèàp••±}ôcÝ$Å=$`n¼e¸QÇåUôãE›¢_ú»X’Ë|bˆ$c·¸Æ|µÔ¢u´„  ÐYÚ–Ø…1!3TŸÅB}%Nc{ÑÈZ.›ê:žÐÛ‹ö#º¤©MÅGGÙŸæK¬X„îÌ÷ÂK˜ãëL•.d2—‡–r†ªl‘þ{¡³í †Ò—ÆúÇÛaò’ÀV¸v1ñüFjtóã—I?ÅEˆ "ƒ]°§iGÕ6‚Àp˜}JãU2œ\ƒ„ֱò”£ t!C;¬1EÀc˜ÔxßT ÑœŸ?ÊÏŽNïJxªŠ6Ò×q#Ï*^”òêÓå᫨|«ã¯ê“R7RS@cä õ–‡Ô\Ožd/õ×j?Nd@–BÀ‘(Iãô~Ûó"¡Ío˜‹ð*´ýöÃ( ¡Àq*Sçj±å¤Rmˆ…$ò"î©Ð{$_ÓÎâ @fée¡ŒME&£ñ%ÇXk´ˆæ&ûÚ~J’‘x+ßè TaL¡mÍÐÒóêð{ÍG¸è¯ ùØ2Ò-=s§“ÀS™º­°›0y±ï±Ü?ÄÙ>²Vb^ÞpüŽXµ(p]œA…Ž»©³l^¸Jëà·\¥üSÉÇ ŒT6h+ ›c àu—÷ÇÚÄm‰|ž`ŠÊækèI‚¥™ô±m‰»Gï?ìì¡4°wÜé6³ Ä»Ä<ЬRN;]T¿»§ü”Êu-õ³;ɺE¨ñ×p•èÄAªgY ¬0ú‘UÓ•EÚÞ&ºDùR—ж‘4ïê`d™ÑÿþoôCI# ƒ ¾ÔR»³j?éQ…i\¹Á`¸™"I!î!$4Ä”ö4A"!!¢%6²˜ÀÕ)¶4Dß ËókÆö¥Ì­„ã½÷G¿îÁ?oöŽ1Ï.E7bbÀL§ÇW­9»}¤n·,¡”ô‚Oýüˆ‚^J"Ø߇^Goº œ¦‰A㽟¨iqUƒ|¬dÆîè`›Í,ÿû¿º…u&˜LeGo‰}6p5-ÂAà„˜½éfg]³§T‘<ׇe 34·j§–µ@¤”û›Hi¾ìTu:R[@ˆ ÓRvgš—)öD0²«ã¤"*Ñðë‹” 5Öjv0ì›yþÚ?+fÔàI©fZ*œ¹ṳl©“°ÕþÙa6ÙÃn¥^lÖ<ÕÃ2Š;‹i/m`x-/G++Ð@§Áô2žµ¢eü×ê%临T žµò¡ÒŽÒò›<¹”¡5‰3Í^L/ã¡)ϪMʇH·Š(" *ƒ¡RXtAUºà4¡§Â³é@cVLÔ趃﹇NÃyt§»&¯[^_2¢)| 3ËË@¸LJN”_d Y¨©£’"jZvÄ|ÒŒõkèùÛƒdxN5[^¼Œ?²9Sd lŸ¥Ã~—ŒŠÀ_Ë/ËÄy9››Ã™þ4É+EbŸc éÄÚ&ýP&”jµê4TùïåŠV6™¶ÖêäÅîV!2Øã!ÑÉ|àwrSZ—y:;•=sõ·ôË %N×JêЬB£üÀ”td,¿òÛ…ÍhŒ‹Ž¤eŒr¼ó¢RËCÕ±œa#Sçó“ùÈMj‰‚ûŬ°ˆ6#Þ’âÊ/~;”`m·e‰tˆýäÖ…¤¬€*æÝS‰ÊSѰ]ßÖ’sÉ3m¼tG·p-H^qi’ëã0Åû5Щ¦ÅdQÐÚF8îtö5…ÓâF2Q<âůò,¶%{`#†q°9v-° ùgÔP×ñQ3£J)ߣÂ-à.ŸS•,uÉݱ-;­\XâIaRTô3.,CöŽuôi12aî7à]ÓÑ aËÈYš ú޽Ó®u'Ñ¡²6t°ñ8 é—¢•Áüöâp[éá¹’mº4Q‹Ï0‚^*¢†Iº ~M9˜Ète£e «-`:X3µ(_[B©'Ùí:d™à :ÜÁeô¥¥Ü9ù!A-W\hËx…å,Ýì8½Ñz´QÅzf¸úÏ“‰tu{4õ©·Z؃¸¦oŸíŒ o8ßbÞÉÔ ¹€ƒ rI¹k2xJ~F ƒµ2Wl¿˜7ìë­ØVòæGÂ=Ç ³M5äS©Èéò4‘tÒ’Ò6_‘RXè© ™|Æñ ê©Û½Lrät–ˆÓVÉNÙHZÑ|ƒ¬2‡B¶ô#V‡32ÚYJT:ÏåA½ViJ£ÍÔ\=»ñhý”î~S?M#pFa¦Ý"ªîJrM³åìMŒ\©3/5J‹gHivJ¯®žÅ"™ãWõª‰dÄBÙËÈ?Œj¢ò»Ø¾…EĘuóê;·©_¯¬òÍM]åDP-™TªX”^2Æò8q/PYH%qjÄ•aö:ïŽ^¯5ÄIØh«lü¢†Dxd(R…ºèGºL™ÐðçÍH’2‡÷"ø°gÿÏ¡uvè­Àu‚qr‰ÓÜô©è9¿*ÿ¢ÑÔŒ„%&I‘YXÈVÞ´Žf#ÆGͧŒR j9§1` ºe& è2Ëu‚t¼Êuí ×¢*ó¿2gsÆÒ\'ŠÑžmH«%Žô la!ÍB¼/êøBNp–ÕÓ¨—XO6AŠá´9Ï#ïYñ®oû‡kžx²ö°þ­Ëºz7? GúþÊW’YX^±¦ÚKœcÿzzˆ7#ÇÐŽ>¯œI"&¦Ã±+l¥Ã|)cNöKªEÈHéКƒŸj%ÑŠ<,rrúÔ]åùÐÞsÊd^™M=O%Ó ž…ãÆìéE_ëGè Î[ƒ*ˆ¬ÞH’­!Åê2ùtœØÆA 'E„“ -⚇”öR™)˜/^Ô]^x—º\­/KIÐêêÜÔ3\÷Ôb`ü˜ØÅtõŽvø-Å =q½€h_ ü»d—ìª$z¥¾®–¶ÍS®ˆÔáyI½Žiùy¦è|3z,cNôó­e曋Ëe’rɾ…h®\ ^r(Ȇy ;ãx˜c*óWæ¤xdÐ ‡Õ}FhúŽ i_.}m*¸Œ‘’1§[/Š’i¹qÂ|R0»ßÿaƒ¾·Ùo¦Ãžõñh:Ù@ô^ún¤¢HÚV- ýŒwžû¾@Â1TPªþ˜\cuÙdZÌêdµEÆÅ¡CiE îyk¬®eÓɃ ™Ÿ5&ÍÕv1Ãß½¤ë§ŽUh¿ŠCõb©»íÔ)àTKr1 .¢ãé°hŠÎ”íQˆ´1Õ†õD„}*›˜}²{!˜×H0þß ÆÂ1jNG­H AŸŽ“˘Räã ,WÑ@ÀÓëôÀQquŵ¹ÞtÚ­Gáß_è„°QZ¾¬ÀUËëÇJ…+‘H·JñTžåÑö,Ä€˜s†B’ønBßU I¿8Š t‚5.@ÝBëäç ïâÕ³†(§ÍU´Ò™P'”†¡=¡a܉AÔÖ}j—ží²ƒ±Äù,©õ­˜†BFˆmÔ?Bê .å=ê(1jöÍM<¨6y<Ùøm´Ú{kgxméœåJ\,þôÓ’è á|! >H<4o$W{é¤vDÞ¨øÕZ™£4Óü~»\1ÚîµÖC"êÂ*6®3 ÌWÉÊÔÁ§‘ÏxÉq9íQ¢’€`5—ˆJŒ1™(Å%‹½Vxx˜m<…EÞe˜| G!sUiÉݬŸ /¦ã‰Š5'#ÌÙv‹MÑtbÓv JYÕmÕza‡J5°‚¥K²jä®’ެwLì»äúŸØ±r˜@ׇü ‹‹¥ã”Fé& øà¯)žˆ!˜PâFù½òyÛ bÎÏ[‚šÔ˜" ùm”qGu>9$sœ¬çÓÑh€5YùGŽeAW_a/_¶¢ø§ji ­˜7"z/W«“‰±ü'Ñi9™«íÈñ©Š«@WÁ'Ê mïgÃó|Úô˾Ҿ¡RË.´HKô®ô3؃„«l1ø Õ¢«øU¢bë=ê’†ØýÄf)VN05˜•°„Bê’Üdž?¾ÈaQ"ÏãhùP¸ÌP°óã#›¢Ua÷«päáSge5Ì_[÷ Ìaß.#Åšwi«Ò<s¤ë ·‘((0âJ4¾ ’«ðO·ASÁÕ,yÄñû²$&€ŠYáæ8[ÝÜ2o­@l[/”¥bíõ.­‹¸)ó\Z®t4ÙÆ Œ‰è6$«_onb7õæ«mÇž%'¶¬›.(²ÄqÈu ,sãDœàAÃF[uKÜ.%ÜÓ!¹>¤xŒ¤È„¸÷{!¯;Ê Ýâvkñù¥b8Û%‡T÷ðiTg9«?…Ð3¡P47;%˜ì†¾“¨„Úï¸å“LÄŸ@/w+íÎxI8ýÿÜšÀÃdu ou‡I“9X1Åü,à`NΉÀƒÉ,êÞê&eÔ=ê"°bŠPà‹›’Þ‹z({;eoKÖó¶eoçEYÅ7@ÙöMQ¶]“ÊfÓƒ’3tPzLæ=¦SÜ„Ê^Þ˜Ì^Ö¤³™H{[²¢·¥H{;/Ò*¦¸ ÝiÛiž®C¯ñ–j°ŸK @­óIbKwÇWøÆ”_Æã §¤á×k®½•‹ï¦ÈŠ4^]ý+펷—*3"J«•hTjŸK4;‡o»»ÿøÇƆ`ž´˜¬4£_Þ$|“[3Üçm29ޝÒÆˆœq©X}19§3—¹™éÇWf“[Ö³fªáKì >å˜ì‘· ]ØT (<è÷N??Üž~~¸sú1;¾  ÐÏqrÖ 0ÃS|ìµ)à )ÄNBMrW=W•¥ÊJØm“"gî3ùfŶ”OñuHÅ ØqÖÈ–ý€U„§iÉ25ÇÀY‘„`Ç\Vc)¸’³¤T6”­F‘Ʀ–#^B¹äÒEI.êð¡ip-†%œôKÓ2Òx±q*¬`ÉŠÆ ”?·,,ô6;ư‰$›æÊOÔl׳]6u=¬š=ÜrSÂwÛÑåFô’`bjbmƒå$+2Z»Ðo:>¶;ê~›îVe!7;VUlø¢Ã9×é<™BÌLŸ u†V%Ê7ŬÓÜ”³FË_6ž¨°g®ŒíÄvä-ñcÇ®,Wá{hÕ ^Ñ%½w¹cfs2‹W'j ³ qB¤~šÀî6uD¨M‡˜91•Ò<|zù,Œ)·Ž,!¡)^Ñ¿3“@\²D;7¶X×VȲ®¬©p\MS€@4l(›zª¸íØÉò‚O£Ë)cAp}A'ÚíâÉ)Ô§  á0hm£_V|ƒŒ÷êšâSLò.Gòè´’íKgwà¸>°¥†¹â¬Û–ÿ ï'ç8w¸X‡Ó(QRB*ËÕ2)ç°§pØy[†^ÚH̺)¯ÅcEKj'#r\¶eÕ¦JÞ…† ³®½Rï]-‹¥ìç,£%7›MKâÁäûSªc"Ã4›°ŽÜŠÂ‘ßš& Çd1>fº.\éJÚsXPÕªæLÖ£ãZè²×¹]?ú?äˆk§êáî(U¬m7V¾øí+_PD^¼.(’E¬2vÈÆ÷u™ ÔñÍM¶‰ XŽYt±FÚe|þ#ù×:5 …55Hö^#½®AÝ™Ün% 6É›­4¶:ÿ«\•4ŒAθ¢«ö C>¥ªƒÉ¡aGr½?Ì“ažb¼Î.û»ï¡/w 0…ßþ‚õo+®Yb%+GTïü†?' W8qw°Ôsl5{¥;ׄû7@]ì(%0b{Úfa£þ²°Ÿ›¤²ôþˆÎP},W2>Ɉ\Ü›Ðö„ø1 ‚ArâHê@–é²å5ÐèöX;”îˆÜtÒ‰yÿMVVî\¾ÑîuÅý<¬þnz.U”ØÒŽ{:ù”Ž8œìÉ4­IñÀ‹8%u9°x:Aø‘‰ªk€£}Ð`JQdÀôW[KfŘIƒGAiDqAd¾|ƒ´ðÇ 8îK Æ”8|ñ?uOÛPŸÄéÀB¸ÉrZºý°¾|zŠh†qDŒxõÕcúÊ'aÃ<+MœN®9ÎÇg%p»}¢MØû½…ÿ X‡ {d$“ÞLRÖ…Í÷dš ¡¢ø{ˆÄ'ã3 »Éï%4OÐI°«ñgì¼À.UËi™¡º ýg³åuî6¼Á¬ò<≠“3 k2FÚ\‹BÙ¬Uå|p¸˜úÖúÀõ.üȘ.1è¨kQ>—ü‚DŸ+›\ÓþÁàÍ~-)Òmv±‘7KЉ¿7–/E·Îž”Yä`§‰2.9 AäQ­ê¡ F×$ûBº$†QÈÛÕƒ0A*̳T™Ðù@I]˾VÊÔê8ÇÄ>•¸B{ ÿÅØâÊ.‚†’…¬xóäw`ÞYˆþ ›Ì ÝhSƒUɳ·T7u‹¡$4ù}ë6:®"¯›²§¡9ÐFÒ+<‡$Z˜à‡’,9Ò[„tô¸XTÓbhV›€æÃeàgb—\¬*aY½Ò*©˜îqo+›»‘ž¹°.6mFËöéö¼ d7]Üú”¥öÜKdà²ëÂ*ɹxi ºÂ ÿ.ÎOø¦ä  ó òK\ïMBäêå{ãŨű—^§¼Š]ó†ÔPUW†ò›…®I½*s婯ºöšÿþw˜J—«ž0hÿþnúžï&µ£"ͦç_·÷Єm]±;¤õ8¢*­ßàÒQŒ“6BA£Ø¦Ï05´‹¹ì¹‡ÙM§·³p˜·îRň}¦T‹ ŸL€½ä¿ÁS|Ø€U͈ íœxD¡lh 忺 õͶxÏ}ï¹ï÷Æ}uʵ헊¸Íw++c–xÔ*4$—ùòÆR¿b‚9HÞÃ0ÿ“™Ë{UH M?ïìU¬Wã¥JöxP-Æ»7ì{lWUÍt½VAá÷LX.ÿ…/s/íÞóÛ¿¿ÊžÁoíNë…>œú’¿¼5ëMàXV±>™çno2ìÏ;wµÄ{6‹íz\(ÈtƒÅä`'çÉ—Æÿ_×>Øå¨Îo-]¯+&—¬07Ö¬Ø. ÂSùm òæÝ[‹81ÄŸMNblŒ ô{W¯Á4é6¬æ÷ü˜Æö3ß’+ûÃ-„7²)߇¶©óÛbÏÅ|ÒE&mÑyôopP67ß(·\²}¯ñ¹hZærlôk¥ÛÝ–+7\€–U04ZŒ%Ýr¾lÒYRðL.ÌV†täªìè DûV0øëÛ£x‚-¬œd eûË¥k´WøõX¸[Ì8ƒtø)éwGU¾úxo[¸¥g·–Uuøtð2*‹Ö¦Çç«ÌJôG×)EG9Ï¡mEáÙÊ3öëDhWhsÚ¥M1ÚÛ-ý%£/Ñ•–ÄmoSrŽ’Øí9·)Ñ“»=#zÚÄKˆS¶§Ã¥Cn»v:îÇAŸÌB~ŸØ GóFWŒ"‡àÆ2eã¯Ì嬡*ª¶ºœhã (dÈÿž|ÔPB›Ø•p`Hµn©…¨µ¥8×iý¤Ö2§,6‰FM ¹ê‚Üd GJù%øQeAHü1m¤RÏ\Èãvš#Õ•ICàŒPQT«öºV®W$w¡Un•‡YiuÛ/! ù¦WIš²åãÏq™TÊ ª –Ç)S[¢ ¸{Yú€çå²<üT—u®-Õ×<–érKnEI »¿©àWNrÊ 1[1€/WKç¬a¨,©¤e:’Ǹ4a‘í›æÐª¨ˆ]8ì ¯Z˜U¿¬Û Fó„pU“:J)cg08:k\‚||ù¸.;%u­]ÍN_e“‹£³rŽÊŒKÖå¨îˆÈT鵉ùªaªN³9øj¡ß¬µÐ·œ©nT”Bz\บþÑ×[5Ó_>öñM-ù ±†èiƒéÿUk²^G^ŸÇ3ú,/Œ¥Î:TÜ´]{e×âróqy* @ЫA85|:"3­/T­ŠÂ¨1ÚÖÊÄ(õÇ€Ã_[&œKJ9-¥Ef×½Ø(¾ØÞǺìņU÷‰Ó ¸PÚ¦ƒCtÔØlà{\ ÜãYÀ=®  ˜Š`^¥y¢Ó=zH_Ã2¥kïú>)³)cÄÉË0šÊ:<¶:hÐó>…œ,/—¬9üýQ¶…p› … ð1W=4ú1޲l¯”ñ?Ë*0Ô|6,ûhñ×Ç•W_%Ë ÌH¡ŸYÆHmZö™r|_& ¾ Óü’£ïò »HÇ&ôÐ$Ó·J pzEÄd1¦Z;84¾S0÷ìo“â½½ìò”2&›ë—4ʇŠcáHme#ÕwAÊN:NzÓ±d%fëí$œ$’Bâ1m“s ¬EŸ(MsÊ¿+³¯…’¶jþCØ¥µ.‚Õ7fŠíéž`@0ˆ ‰éž«¦c•5ÚàÑÄÜܘZ€¶ìŠ•ùˆõãq¶í%É!mïíVÞsëûŸTºêõ…1¶íßñ»-'e:ÝQ¨Ä¾pg÷{mnªßŽÔ_*íÕ4ô˜N2´Ì]õ¥ž±Jyšby¹!×à&­Y•¤Nßckø¦ý`È«zÒâ¥Ì9ZÑÙ ‹'Û››zâÆÓV´|–ep„·5%ÙÖ%]ÄÆ­Ü!ÙªU>BMB¹3m[™ÙÕâͪEJBü™r*; nw£ä¼ :5RC÷)àÜÌ1áÝtk¯íâéK,žBÇ1ñ“ïâ1T©mé8Ûç¼q sH^ŠÓkkU˜úxWik8«b+ùÄÔý4ÏÕG¡R ¦€@H6EþB-±®a¯ž^1Ôž8ÂUf­4§¼0ÃÑtR¦ù´Bß>„S­=ñº­U.Ç.Þn£^(@m¨)CѬԥx±¢öKÕª¼MlªéÁmºÑ«ô(¤U\]c)P¹$o³íJ+pVÕ%Ùo3Ôµ˜èŠa^(ÜÜÎé›y·TUq";zâ†/·¬.º¥Ã$mNjëð´YG] `©CK³—Õd–¢ä’Ç F÷ÒT>ÍüM©½ªm˜l•ûè½É&E,L‘ª¾¯ÜçN¡V±-tï] 5²Ø"sÚ^~h³;T%Û´å›…ŠÀÖ7Å-a,]Evg|žó Ö®†,%;ëJ8š²øèqŒÞ²ùØî5³÷ÞS¢¥þçê­¬hƾÙôÞáívSóX,÷¼mà‘Hĉ-Ö32s¹B T1C_¢Fq\¡‹;1¾´Ýˆ±ëmæÖ H‘˜Œ ;ƒõ4vø5ThoÛhk©˜ñ ³f£Ž*ÇÛÁÒ4цˆYU Sª(øe Š”YªS)÷ð~TÜB3¥XÌÆBF0 ù£mÔúKCjšÂ̈Èi`Ôù/Ê€A°ÂÞ§IÚ2ñ©±noÙ›ÿ@‹jaƒ¼¸ke4ehT>õÂîÔV²áV˜Ë7ºÍ9rÆÌº —Xß ÛLÖ‰ÂN×·J”Ûäùz¼‰M¾Ú(O/Ò&ï Xj’ß#ËæMŒòžs˜å½ÿî†ùJÛö7n—¯~TøV óê.b“<9U‹YX áX‡³a⇓›˜åïÔ*¯Ì´73Êß©M¾Ú Lòøro‘dçºc“|€Ï0Ê;×K}ݳD¿¬! ÛóEáÀ% €o. O¢A£‘Òxn¥bz›¸`ì¡¡òÎý6…cÈïM<ËSulB()ÿE¢¯´~ç¢3ž®1xº¯ãḠfŒ‚)Jzª c!HÒT{S Æ®öP²›4ô4µäuàoº ¢G—Éä"ë›}ê³Ödù#9©†ybqä·(’õææº5Â)7ÈXÅ?W¥h[bTc ¡€…Ã\§×vm ×C\Ƙ–}IìÂ%ÇNRŽ.î÷1xFñ=½‚ÂÃR¥Ô-X½n´….ž@eÙ”;¦gëh%’‚“}òë.…¨MR¬w1bc ¤C÷LF3ØŒ—ÐÀæH–?=ô¨Ù–fzR]Þ’ë`®*WÆ,:ùÒÜZUž¤Ú›§ëÔÖÉ0r:ÈñGò`ÂU€â˳íÔTмˆ?sØæ,?4X”œ±›erU0mç“3À•œŸ¥òÔÁiŒåÅ'c é®+'³Øš{®5U,Ìf ³ø—WX¾ÀÄt}†!Wp°ØZø^Þv¢xÇ;¹>ÌŠ ïoäaiÕVF¦WàcÜßpÉñ¯Ù%G¢jG¡ö϶V->÷¥ŒyYùôO¥h+Ù0¸–,†¢š,ORlÂfhXñ]1´FÒ>oó¨sÛàz M<.3¹œÁRCå÷Ç|è>B' í(ÑÅWŒËtÂÑÚ–i‡ÂÑoz™Ÿ°ü3lJ¡å*ÎÍ£oÒ—"š¹ñ&NsS¹×ÚPgŸáìjFUH-0DPš±¬5ôØñnm«ùA8] íTTC Ex±[eL¨q#Ç:+Û[ÈáÔœN¢y»UÔÔºË!èè©Iõwæw=Ùi²â<Þf›,Ü·"ƒl×¶$gÚ¤’A +Ç\ÙùR^þÉ¡£Ÿ8wº˜[:ÜŠŸ“(O'S¶ôµ²¨7_±!A²–Ûr‘° ·}ã3Zè´wÜévÞítlCÚûLJ½]õ Q•£k—}AhpÏN)¶S‰ö%©ªLÍ›5¼å%… ¿g—Õ’fe䨝6¦‡KØ#8¯¥\QÐ~ª'ãQŒÞÃ?±#p¯Ÿ©nQ>M'䇤ÅÚ3¦pªÅt€Û®æj?>ï½î¾9:~¿ÓÙ RX½qVÅUw€ç‘þŽÅáÈg°Z$¹Á“/í:TÂxU¾}Öhc L"ZfWkUŒ·z›Ã4¸.bKcB#¢«ÄE9é’dê0ÆHÈ-—ÿv5¶^´y’všc Kþ÷ §W_گݡ>++Õ}´|`Á²¥ýSÿ….CºM¡ÅIÙD^ É±*¶—¼!­XA3ù.ÎßÇ_vNó=Üh ÖU@VDÉ/RÉ]覹HzŸ¢<“’¿Ã3æü [˜? ®¨ˆëöpXÇŠÎêiæçÚWñU*h‡eµuCÑ !”éЄV8ËTò,Õž0<Ê™ ßOÎbì­¡Ÿ0táºeDz‘°\Š^•ù—!Zy¦‡i;;Ï`ÕMƒ¡}6–ÈGñtìÑÅ ô²j¶œYϾ6mbþàùæÇÑÔi\ßÞÏ÷µiÚ§Ø’Z’Ĉ jJoGJô]ô?«iÕu:Ñäpí .³|"¥|4ëóJn™Ô -_ßM¨—â³}ü|Éûäç”K/ç FgJ3%k_%fŠ£ãPùO¯è®(\Áå”Óó¤k„â,=ŸŽIB0cÄgh•å ¤Ð‰$Ó4Tc”bý½£lÐïj €ŒÜµX›)]‡ÓK,ܤ—ŽÅj77ûÙ$ßx=ˆ7mŸ2îlqáR>i±;¸¬zäñá²E2>Q˜¶Ãä³)œ±\¤²BWk#‘aG½ÎâšfH¸D–®Dz(¢t-AVù×Ý0g;]Ò ¨<`bÁVtžL 5ê9ÿè ­sµI.5Éoç#8œåÎinûF$G…™C•@]ºtÊ×’äè¯%œÈσy[êjjr÷¯IqVâÒ‚DEÆ[[y°u8Rßø²µ”82¯# íàä.°sä-Ä_>)uËÙÌóîýn®¼H?Œ‡'ªNY±™ï×£”އn)#€k¦WàWrñwºà·§Ó ž”ý‰]Œ&ß.Ð`Î-«y´ûà¾ì‘Cêäzh/^’²R«çt¹,h~ÅÞ@òdp‰/„ôjˆ0Þ› ±²5Ò„‰Ó¤NæTyzŸ0‹öKzqÕŸ†m7Cnp»™™ùÓhÉ*hˆY9– ßZa…†—¤&ÕC®Ü¢â ·ì– ݘ‚ý¼„C”ó‡Ûr‡¼¡„3Œ:¥A8tó%‰•6M^Ñáo6ã«ÄõWYNËüE¢=rMæ4¶>©òÂ,ÚÔ8&õ*¿ŒÇ“Ú)ÖºOËN#y5µG[™Ë¨Ì·Öws´0GÜÇ(¸:r@ÓðÚ)ÀÈÔ˜¤¯Ò|Iû„ÄìüF¦`òñÃÕØÆwÊ'‰½>8ÈK.c<&œ«i‰çöÕW¾3H^D‚ZEä,ƒãä Η­8û§Äªã®ßdN©9-/ŸbP8$_pYä0›ž_„ýÄ-µª©¼L…ñ2/%ÁEÐçXý6G’eÝŤ« ðeÖφ™z<ñ<õÙ¸›?åÅà6›(f¯ª–‘Pµ/š U(¯7trtö‚ùÈñÞû£_÷º»G‡ð¡ò]uÚï½Ù;Þ;ÜÝë6dÒf¤m‹.`ôYµ‚ÓÂ'Ô2Fê“Z|D–ÑÍSr³h[¼yÖeÚ”œß-­-çV$»\ e{}Òùa#óB  Ú]+š\´ý•·Éä8¾’‰2QS—á.1á,•‰ÌV-{!TAG5µ6-/ÙjP×¹:h tÕëÊêÅ#PïqÞ¹êJ/õß@Šx} G<íá¡édä–Øtë$˜(sEàXÆ÷ÔiFWPW@rJŸ§èö8¼"bÛÇ Mú:—1Ⱥ3j ìð*÷Ùù¬pÏñýYÔÉ”—&ƒ‰ùäÞ‡Q@”ð¯Uì¬R<Ñë=Q—?œ Ð* ªÌtD\öà2駤l‡#{3%Á¶Bö®Xö@óȪ.~`o6Wã99"œVVŽè½Þ0•IoÌûæž7œÔx4Î&ìˆSŒå˼s+)m$Ðèd‡°‘˜ÌÛ Û{·sÒ=îtömÑ۠؇Eÿ›ÉTcâãBÝ–É™”Õ„ƒ\–·ŠquV¿p-Bp ¶BHvà g˜Ø¨Ðëç‡RÄP™ªˆÖð)àÇ—è¨«Ž ó ÷|·#€¥ðëi熧͈KUpYÌw&kÇYsúç4ä”2Î.K#ðGz™7ê»sôú¨‘Ÿ&Ãÿ‰››ÑN¿bì8G(ŒZ8c³¼¥ø|Ä;$ÓÕ¬òßh,ØB —&ß@¨\çµà½<ɘã®o—ÜË:UÓ zPÄ4£0­™xÎì}ÈŒ›]%Žˆ€o(^òÅÞˆ¨`pý×¥¬•[“ÖÊ hke!ĵr#ê2ªè¬ú)1¤Ó¸Ï¨çx„jI'ðñyâ׉ 1jc]öó_ãAÚo¨p¤Š0Ë×VÈ82˜ Ú~Î>%z°³VÔAìYhϰ*us+`>u̶à6f×;ãóiú„5– N_ÈϵfCú6ÝŠÒ ¥º»…S3R5vuß3Ó# x†ùE]ÏdeøM-V‚&Êǧè­Ñl/W†w·ÎÞ·˜f m&DMh'+ÌÅ 2e¶ ºRÌõ2ç¨ÕÎÖ^e›•¦ª¦ jª…Cå‰lsÓ¢k›"–"††êœŸÿh8¨êRÁT¯nCýVÁ¨C9¼Åé1g«*7͆©Ò_ê© Ðͪº 5Po1ÝÊgew·˜íF»:Ͼ.ÌMŒDF#ÎØfrñ©Ù¿ÿ±ÅÊM^/ u²ù¼ÅJ"g­D#mÌô ªeóêc<šÅØ”2a êå§RŸ8¾.¼³mÖñx«TAJüÝŒ†Bá½DH«tR$æÖúÅE )D˜Ïåü²!_FTv¦kº ´¶£W˜ý¤2G3$Å`Ð0v~¤U|>]e'žPËùûhTÉcVшüòô4¥cÜ“¡g ùϦM5¹+>6t Kô»\DçÓx£ÓV~³+À&¦I¦ «üt-¨üSÚ²>“Àå”SˆU1;'Ö(Àñæ÷2d_rÍå}&5(Á»­ƒ¶÷ØõD¤0pÆ$Gþ‘ rÒ9Xçh´\’–+ZzaøÕ~^5à´[¡5Ô Òõï™MçënÃidr„ä&µˆ `~ÃAÝêä@Õ¬”B@j]ߦG¹O¹1}žLºÃ¯irõÂp»ïñÃ×ʪ{‚²àŒ²ö`wÚ°nFD©k¸¡J³{¡ÏÞòžÛîèjwêNGBßk(%Äbå‡:óßT2ÐÛgÎø¢ÝÎÕ1kyi1üÂøö”'¡£%»™èœ¨/m"tqã¯5§b¾+Îhzv-îX«76gÞJò†Á¿r¯Gÿ_«(õ3Ç9Ô—õø$ìŸf“½ËÑäºá@ÁyãŒd°¾ÍTÑhú"ÏZÓQ^Ÿ 1[õÝä !xÖi-Z2¤Ãè缎N“sعf» ÑO£ŸbÒ¬^á†Zâê³—Ôkéé]T¯pü½a_ý<ëÒ*m/ÜÌ›fECÜ-¨Áþ/ÝF¡m¹ÇàÝ^fÐ¾Õ mñ÷1åtÂí²ÑöEñÍ1xí¦»ª3¥=8½„m§jE%Õ7cmZ S“}KÚ·w¡·¥>¢*sa2$ó)ÖwYè¯rŸ.ÂoòÆu#%N:¯»¯öÞîÒØƒÿd"Î ÉÞÀ¸ö­â÷€õ­M<†¿ävêsƒ‘¨×„¼•æsÓ~ç«;¨áé²G-‹ÍÓVÙïxÕR„ÞÊ’„µ!E ðwTµÙ¢0GQ¾°¤Š:„È ˜¸]L ‡ ¾#YÄá@E¤ÞF&ñødxð²B™e÷yXNS ªèò€¶,7‰t§š•’”âå˶”ð1žƒôS‚¹÷›œ‰ßÅäÝ«Ì ¥¦T;¦rD&Z„žE8µ¯Žyfw4¶èœâ8å B/Áy2Ño‹jÒKLêŽF3N¡™˜ÇLdME#ì"`$† û¹Ê#²$.Œ”Ô®:W5DyЍ?Å[ LPb¬õìl=÷Ù±^OŸz+É£†2!Áó/ç|›pöcX]ÎHíÅC+ëõ¦cb „‹úœˆá³_CGËRIy‹¥Kîö^•<ìZh©4Õôl§…´—/©8šfhú°‡_{Œl¥ª†Ë%ÙpkˆO–ô¥$¡‚däšÈî_Ñ–o,±v·cõ­Ê“ó[Â."hO]S>AIéA`b6E:{ž2Í]f}JàºdåP›x'©Gµ·Éú§«"ÞDÌÒ?˜´Ž¡„©¼È]€ÖdáišX›÷d“&J[±`;g>GG9%qµ³šA•Õ­ÒÉ ¢¨âOSû»Ð»&§#Gκ÷»ÙÜÖͤäFóÖÕ˜ˆGj·¬ÃSyĺzì,0Ú±p1•™ˆ“p"æúS‡5šƒ‹ÜQj*Üí¦+Ñà"o-ÝÞj¢#P]GEχ}z#qƒ«‰*=o?BG2cþ§J#SäV6¤âÃ[µáMѲv]=,£=Ks[㾮кäWa8ðÉç9Q˜ ¾»ùdÐ5×ÚK3ùðè¶ hk…ªzÚy>CeËìbš"叿VeV#2™é Á~dºƒ ÎÉ;vV;ÿ´ÙB.PBUJwò“RïZD”#¤lø"‰û´z'ë&а±lcÑWX‘þô‰·€&%‰oÙ-¡'¬®Ø–îµ­èÁƒtâgï3dµ3Ç×;WÀÜߤC+߯‘ùÍW4`+ZÃñ^ºÀzÜ´z\—ÎF•û»á$­hÙ^Z _ ÀbÇ;±A«éPßbêæÚt‡‹Šæfoµó¨,[³.?ߟ¡©ÃìJû’ûIšçìm†TA;«‰g&åD… ˆ·Is’F³–Rg«ŒôSÒx =^yC¢"×úÏ!…¤Æ…-7CšŸQñØ(p^ú{¼8´È°VÑg› ì„nåÊZQ„³Ë¡p7"GåÒG·ßTIê/¬Tb™*÷@e3ÔÙGºÐNvÍh”xßX®x+Ëó¡P ‹þ¸/Œ £0-<øe+è]†1æ' {uÝ0ë´Œ!Ú”W¢D˜.EÍÂ3‰Û“5Œ@-J«yV¬í(ˆ<ñ»,Õ¦5T×Z}…sQ ‰®`3wÌa6wûY †ÜÃê@VË€îtºóGaW¦»½,WÞÇW"½î–©2hŒãaŽfœM‡£8U‹ÿž\·"*µÍ£¦õ“H%Á¿JLQív"ë¥\FŘ ÚáE'AB'æl€9ÌØ¶ Ê48­’óU÷$Ýè,-âM Aæ§œxFó¯rë ÄM ûŽzU¥Þð½ì(ÜPÒš Û»^(ªÛ™áåRÖì%Î’×”ß !p„=$#æ~)Ï¢sS7%¸êDàDe”AS™í%‡¦©îÛ’DTªƒ]èìþº&£•Í2ã*{Џú+³ª!T»hjÒö„7ÀJ¿;vdeÎò·ÎUWñÐÂìõeTî¬á;/©ÁÿV\0Jß@Üfõ@øï–i‘äViZÃ’C93ÍáîчÒ•]óѤ®ðeRËõ0 ßQ(‹"ÖCkL¦ðeWçÕ Ø"ø6Ü›öïôâ¡ÂÓTmú$²™ƒëHeRø¤®ªæåÆŠÜ’ôÈñй­²øv6ÈßyLæeU⢱ü'‡ƒw'ާ‰N\xüîÄú}`aÿàð•e'DÐÞ«E‘­̈ª›ûAqŠR“ÿ±#¸·P2a†FÓR í_·, NR¿;o°ýeæÄ{˜mþ÷ѧ”2kV"¹É±c×E¥Më#Nû®KÃM&âÆ±¹€G× ìþ->Ø‹œç½àØQsé7w¤y¹›Â»p¯xݑ⧔}Æ*F¦bB€¥J@ˆÍKu¡×bZÙÓk5ŒUE‚-°×ªÐ5Z“†yÊa­È\¸@&Ý倴bjÒëë¨JZ<ŽÆÏÞ|‘Qñ2ž¥aú¿<ש?j?n?Žþcž¶±_þ_MWO´ÒTØW“ÂΊÅxø‹m'=ñÎø¼¨ÖãcöÎ8¬ŒsÐdìëžZ,¹eZIÕu>~Œ©‡Éle /Ž×ð+Q{ óNoÓQ,ˆ’Ñlq ©ÜÕRà ggdÏûW,ƒJTHbZ µ¢‡F/sÈK_Ùñ +‘Á1œÃÝPúY:G Ûª®dTÕ"f¿ŽÃœ\M‚5ô…èMT•£ÈË´¯[®#ݾDX5»Dlõ“/Qºì÷f”Ñ|!]Ÿ\˜ÐÙ2%ç–hü—QþyxÔØ°®8è•t×QßÔÄä?¼´‰ÀV£ƒ©?£gcÑŒõf.|¹4ˬæ=P ’³IpiÞSU¹hë 8NÏ/pDZ¹7=œ jÓ«]Á?€%k±ôðÕ‚ÿCÀð_ÏÆ]1A=0Jñ(Âû¥±Æ]׸çÖMª>ΫÀkJèùG"p ô­‚r^xJóh'a™9ÝÌ ïiˬbUèñ¡™ZÑŒQ ßsÛŒ¨À*²º‰òSõ†gœ4Ýþ·¶R”Ÿ÷•/ð:Y½ÉIÞ0;ÙlÖ˜®ðL]¨\:ÓÔBlÜ6«x˜ê<" [ÖŠŠóΘµªž„¥ŸsÉ;ÁÈ™ƒøÕË./ѯ3SJ´òT%…/É=N¬ïê¹þß)*› LíáêFn-óøšEÇñUÐÀP4bX ÿ §Å@ÿRugeIÜ*[–ƒbp'N…§ˆ±G8_wÆk”OgrXW¶îÐVM®]ÆŒn¼’ön-Ú Ê=r™ŸQ=îx0èªv]®È̳´õHÃk5RÉ@(CÂP?TŽUš¿‹~(íZ)¨Í«1‡H–æ|I.(Æù/ޤ±tÏY^ì»SêÚ…òKjîïÛ> $èKçÒtA¸ G”¢}ß’PÕP(w•m~•¬jyî«;°õèÀ£fª‚±«].Ðò3á×ζknWõ™Q¸ÅãÞ>U]uAþ|P\C€4ñgäÔ£òŽè”›ÄwwMü'gÕ¼L€{xcÞèf ]³ú^ .¦ürœãL[똑Çá ƒWª/òx*hÓ‘‚‘¹ÞÔâR°·Àƒj0nD/;ë jðNYvÜ[Z8Êì±u#ݶ…ÅΟ=—Á-ÍŸhyU§¹­öÆËgf<| ;ÉIëf|“ìMùýŸâlˆÏ¬ê(»á`áñÕ‘9qîƒ[’éú›>À¨7ßöüzä<»#S`¶üVÀ÷%×hI^¯Uã}tÙ,j6—_-#B€Ï”žÂª’Õïç¼9gnH±Vo†µç%aµøË7Á£Ð;ßk¾ òÿ=¹öùoÉ5FæI~ˆ‡!ýtíÏ¡ñJ•páU òY• .Òj^ÚC´£è@OŸNœìmÒxÚ%^ €{)ß)–f½ŒG!V)Ÿ1\ŸJ¶¾ý2z$²°»‚RϤ¤;ÞÔ¢¤ ƒ’úvX1¿onžÙf°V%Ú,½âÝ5ÞÒX3ÃV#0†l5ê΂}=–J©xCP%€UØ·.™§ÚBX $XøÖPa òë¬RÅ‚ÅH¾Èûo> BÀ­p†õÀCÉM| Ëý ã"%M-ßO  «ñ›`A»í/£ååòjzx29{º®ø¤žXÉha (˜çhý_KŒäÜóÈNl­žÌ3X²Ǿ uA¾…¦(Å~n´†âå˜Vô1ŸãârÙÐLÁ¯5,\`]äÕrƒ™ Dl0 ”ÔàMP-7˜»# 6èëI .2¬Þ>D•Rƒß¸úÃÞ®øZË—öÍɘ¨_KŽXRÈå}N0dMzæíè$aüvtñÓd]Õº¥ñówsM¿Á?ëõó[ý]uÁÓÀE‡\îh]ü¶v¿ÈÛb§³¿áV…M«“ûv3K ÐØ‘ÀÆöŸrçoƒ7˜Á[€+u|½kþëlÖëâ1èe‚sñµôBòÞàªãyxûFï£á$äãdpŒè†¨)1¤…Ò˜|”DªäP`Ú%ÕçÔUó¸¹ H}™•Ç\¤ÀZ3°hް"”2Tbn'”È ˆ&RÞîÆ+§ éX”ÊE€¿­^/þÙñ0,Ó€°N˜ Ágm” g}Ù|%4i³¾ä¬SȸÎ8þ[]h–ú!C…ÊÕYoy?J‘ܯ"¹Ù*ÎJpâˆt˜EMLç¹*eá'Ó^/Éóʪš:„)OÅó¼—<’˜ºLX)\‘ƒbäê`ùâ²’#ܲìÞiÒ'íoîì+ÒbaÕZ«r§6•¿ÂºkaX{·qÞââgM¼l;±ÎÛï7’¡à6òX\vŸáýF”qß>:> Š+48°Šùú¥zµ`è]eÅ}mIÏ¿*Ý×\yx¦æYC —«%Ÿ4WS±~X¼àî à­‚Üí+|·T…£Ùº°¦KTн²´b‡[¸‹*¬¢Bc.G¨EtU˜­Kgá7fùcgœHúTëJ"T7½¢Õïrˆ¬ŠïüN]#ѵPɵlÖUÇÙ%é¿OÉõ®^"$ Z6æÔ×ÚRf¾M'ûVáÃÜÐm˜x[¦St¡=ó¯.ÒA"7¥<³~Ó¹$òn{4Í/ºXvµQåt¹FãtŒÅÄ ¹xñuCxÛKþ œ¥k,NfL×4"»®1#‡½AA˜&µ„s ë}Šâ`³mÆ 4¥ràðVÝ(:Â0jÈãÍ¥æÉaïÍ ABе0T³]}œ‘ÅP÷hf”sQfµÇhúV¡ISoœ{8fì—˜Âj|ƒ2Maô¼jênj}~6;FFsc'A­Þê[‚ÃL¬Ò<s€½ÏÉøÚSszAçt³ütB,À§Ó« f„Ü¥²ÓÏi6ÍQðÉ•[]þ)ÅZ¸r¢g¢O ÌÄy6ìJÞ`Æå94—R£0gc¶*WCù!oÓ© ¥8vA¬ËæLÅ^²ã¥ò î@PSŠ&[¶zÚãPæÞ,–Ç9•Øç¥ü{)o¢O¨ žO¨gWã¶ ÒRø aä—ðmЄ)øKVÆÁ_Šå,›—P{‚F!°1Hºî䊵eaXÛ¦{¥‡kÐøaLj ±)s™T¸§t×64ÿü‡ž§‰E›Õ*×/ãÿÆ’-X«…\^÷‡é$EÛR,þƒû 韣ŠÊT¢ÃäËäí8]4°øsÄâ1¶Ïøú;DÀò½a7Ä×Yz>3MëA޳K¾­as$7%ŽÆôK s[Œ}Œ¥û]Ö«ÞóŠ;žõƒ¢áôRÇϵ"ëKm%¶›vö'ë¡ÉîÊ ’=ëCߤ»ævn)]ݦ7ÌÁèñ(Îi‹ÎŽt9®êb(º_{ç{€fͼ(åµú`g¼.xÂ’þãd÷’}”ìÜ“ºü,§BÈI2©œ¦ÅМªã;{†èŽîìÔ#Ûa¡ƒäPLY§p(ÈC¢¡1»¦Ö\?M‰NY™Ç5ý>Å&’`˜Û$ä| çM‡½1m†šø§.I'bñD®­Ã­ó³¥ ¶Xç¾ÿÓ×Ééôœµ­^šÁ£…ª¹v[E=F¨½Ï]Âs¿wùÞâ˜tIˆS ò‹xÌ·ÞææVˆª1ÅÕÎs`–RÛŠG9`5¨!~‡ÏÈ»^›oµ(5تµüæ*mf˜–Ô{¸›‘MAŠzŒ‘‘ïPªéÍgTUËgáý¶¦Lf½&G˜ÉQÍ8QxßVÌ^ø6¾ˆlùýd†bËPïœY¾òÍÁ¬_ÒËéetšŽâñ˜1‰Ä£Ü1¯%g^dÚ\=_ÕeÃtã«ÀÃÎäÉp¢ê‹1dx—ü![©3Nÿɶ…ö’ÅÐ.¡j÷>þòJA÷^ækXšÌ§W¢s$}k<:-8UÒ‡w²ÚWm}c„~Ò®D§˜Å’ïD_ª^«E‡DrIߺA}uŒ¦jÄy?g¬²;…`¿§ãi3;¾­pÚº+* O±¬ $À§ƒ 뵡^†ÀÊ.Gé€Íj0*æÊ,܈!-¡áUÌæ'Vœ 1˜½Övi1´’íg˜p]ûX[.\Ê&ƒ ή8„麥›æNp .¥Æ]ømˆØBO&ÛQ†·tÀÄaƒŠgt ôáΪ€( }g?÷5e…D1›±AŠį$ íV¢¸Äï¿°F,¼»¨Õ­Áø–0WCq/É PÑ£áÜhžĺõ‚fÆèû…çZˆ  ×µˆ¶_Q×…¥öRí–™ÿ6ÖœÎ=‹[K¶"ÛFKþøsÒð ˜P"û˜Â Ü£GEMòFølÔâ¦Åb+®_Y5²ûn:ÄÊF@TúõÔ ×óEÌà*6É,U‹WŒ']“PÃÅ gfþèØ¥TØÚ8?#œSû€×>×óçûƒ|ïì ?ç·æ± óª(¶NÕåLƒ'yVëFÅ!­2®:c8†UmS \ïÒFL®wŸaЉœã.°,°7¬‚[(ª 4—t¶o.0Û»2벨Elµh¬‚t棘¿”Væä2E©µ×¡ÓÎüž}á~Ë™¥¢ÇëNå¶hrIöu¼Žˆ=~o¥_Q±èª‹Ã¨¶ÊÛŠ^¡O²×ûÂF…So7&—-J<ÉyDؓǎ סý_çÇÔåÂ0mÌärÉJÿÂëh|QaÊX/öcžœM‡ öË3aªÏ6©àD‚ª ¬«’ë>|ˆcWKõF³Ñ5Õ£%”åyz>ÄTDðÊøƒF¹$õc*!¨Þ5ø8¡9UùN+C”——}\.¯Žo`-ÎÉ-þn|lª^¶œðn•“«—úØ*˜ziäYj(ª(=ËàîÌS/´#eÜЦó"õ[ÂኰsÀA›…¤$%JÔƒn5‰.W»ûàÁ/ϱZ-ÓÈÌ@AÌ¢°È@üÙ=N~Ÿ¦cqü0pª€lh»Ó¬p:ÊFÀÒ¥,µ‹,y¶ N_ŠÑ„ u¶XüÞ†}Ù`ª²‰ã83³ï·}—]%Ÿ‰ôc\aŽºõBŒ°Á¹P[t  ÈÚüº|‡‚‚¹¤ÆH§žûÓñX6ž¡#º9©±åsŠwvn4åNÿ~§³ûnïx­Ñd)²7άDTX„}=ŸŽFto¶Çz¸É–—±ö^UÎ)˜*ñ×™~È—€Èq«Kt¹;Qí&­ûê(Ç—L×ùª]9Ï1¶g€('<c,K W¸õl:ñ]Í#3™$žŸµ,íM6†¦ŽŸ!Á˵Ó¨s±&|[Ó.MH}7„ó•ÈF :düÉbŒš£Ó¾¶Ô•‰­3Œ2 %`Á6<þÉøÑþ#J6ZQò¸µÛmøcýÙ­Ý4ŠgZgóe×e 4¶óÁ0 F'_zÉh¢Ia¢ $‘pt‘]f(ïað¢ö¯ùI8°—ø¥'Çp~ËÁŽ‹ª|Âê!Œ",Ì8*RG`/*/@xj‘†GH%æKxmñ–Ú(P,ýÔóSÜ <Å4ÆIç 2õvãáyÒŽö‡ì8ÎŽžìqŽaƒt‚‡À×¼-.Q@7)‰ \/Cí]è}oÜ y‡°Ú!?­º}S@Tg_/u®+¼½´TjI‡Ô2Œ½¹D§á&šAJaª;Çé$AcÚÖæí¥à%––?B.žu§‰:[†ÏÏ^KgÛ9˜ÄãÂumôt¶‹[dßWk‘>éÅO¼œ9(‚~)ÏŸˆõè‡ „=j¬0 úÃÿªXNàa)€–u¬6xÅÎ3(ŒÁÖ­WŒßW5ôEwÁÈóäuý˜ªŸw;'Ý“Îëîþá~gç`ÿÿÛ;îì÷'§â²Ôa0Ì‹²ˆâö}É«WöÅzhø’[kùþáÂg^bå-·Yycs­•·qï·òv3.º )6pã¯R¾ù0ÁA<S DžùiŠÐgCb’ësÝY¶ó³ßò•E>x€QlÃ~<îG£d|‰éPŒŽLì²Ú(V‚¾¡›Iêƒì4X A&\µ¹õcžsG@W–6¢Gõ0‹úñVœ`L€"Ñ^ò3ªø w£—ÑnQ® £j¿Ä0$ kdÌšÛÕtkIƒ;ø_ö¬áÀi?Jâ»'ùz€mHw„"³ü™ƒÂ» Ûý…öò0›$›è—L†eÍ uìw˜ø Í8ý(KÂþ…÷®´ð÷å³,[&±å íû\ë—ÞDÚµ¥Ãßmýw´ÿZË ·k|10o±5‰|[¥ X5/±ü|cNCÒ7/ŸãÀÖI”¸Fš X¶<Áæ¦"¨…«Z£ñ×)n@ERʆY½¤Ü“´ªƒ ²Y¡)@:¾À$l;d~ã‡%yõA÷]ŸÆ’¸/[²¿¢²dGc$y6À‚\CJ3Èâ>Ť\ž¦çÓóe›DYjïwÞäcl‚jû(>E³G~‘'ëâ™ûÎsiÒÔî÷_DdPVÄ>=ñi }`Ú‰±‚à7ÜR|aÒ)á.S Ù6ù¥‘LŠD¬ÀæòŒì"üFbr#iŸ·y] ±Ño.p“Lzœ‹´X%¶ 7#R"H<*JË„7ÅÒ_N{˜t$Ïyt¼0ä8Ù¼—èÝR¶•xp_çÑÕ3FXˆ9˜`Jy¡ÔNƒñi&‰É$ˆÅŸ™:–Az=@ŸsSåé"/°h±­vWÄh¶±K»VÅ~oà·aJÛ/‘`´¡2Ìà­âÖ/ð÷èmÒ€‰q„Ds·52¥[@: ÐI5 “úb>”¸(=¨FéÁ"Qúb>@]”T£ô`‘(ýa>”º(=¬FéábP~<8PZZ[õÁôT³˜™÷óÃé` $±íˆ?78QB*Ò(D)óC?̆ëî ”Nþ@ú>ö ’K›6uð¥ripè%;g° ?~Ê•%?ÆÀ˜G'™^®¼Ú´~K·kÌtNå3ê `rq)_̉Lw˜›cSÇÙ(EC§3ȵ|_BÒ!Yí89Ó÷ÐÊv–×ðÁèðè`ÿ°¢m·c¶K×ÐϦ䦖BºÆ—š$Jëc‹<ºÎUî²½ /®”sjL‡Ôº]\ÛLæ$`äLžx;zMÿÂ%'èx®Â2KÇhhôšy‡KO‡½Á”$´ÃøP=Ádž§Ã×s­ü0ž$€» (. Ã_/ DÜ8üt¤²8™×³Ëø ÈG ËNÄ“ñä¢S|(Q I_E‚‰$Wx Îò~šûâgÝÏÉ ˆìVÉŠd°ÜRÃä]˜¼KóÞ‚[ÞHßÊ^”’¯Œ§(ø®·¢Hõw½-œ“ûÆ»rÆyȾ:ƒ¤y·#úƒ1_ànÈç[õÂx£,Ú&’Å `^¾Xµþïž-Ú¤eNŸFpKþ¼ÙÙ+ݽï!–‘únÈmx¡Þãø ÍIùe<ž4¹ýƾ]™vWtú;uáÃ/›ØB—Å+  ­Ç9­#ùÑö:°¬¸Ó—à®j††;ÀÜHCg áÈnÃfAklfœýkÀIÚëö(8>Û¦7vóÓ¹KÇäË&ÆPë³l|ûl—dßž¡¶ÂJ¾ë3¬µ“æžÇ)x1¸ŒÓ¸)9A`Vø^TK:±?œYkx@+/–“Q˜°qy™ôS:äaå)Û®¥.þx|͈A—ðN¦µ$@ÐöRág7[U‘M‰š©R‘Ô‚Â#ªú¬1ÊNÿ;éM"ÎMÏO\ŠÓ¢ªUåH <ì±VÊÕlÞXy“e››’øM}O›M;Z)†ž™š}…¿´¹9šŸ†Ó&âK™eü¤©ÐÐéçöÀv.Ù¸´;½Yôà]Ì‹ZŠÔú¨p65ÜÜ\#µtåG3”Îju£ ®ÊâŠa ºùŠÔ”X;9é|‚ÇØêÚhrÊbНa»?úgcÊÂK„e×ÓK#Ùb&”œw"÷(Íë䜒sW—JNc ‘Ë&ÿdÅ ±Â‹ìZ¾+T—$à „¸!¾Óψ’ël:VÛÀ®4@9)M1ç{WÍfª²oö«ªPšÅ@QÜùé…ê½mÈ“˜‹¦†ž^žbÝ °Æ|6_Ós”ðµ@ö5N‡&õ°jÆ@9lÉÿmp=ï7ú”–2=Õ䦜ƒn¬@*‡ý$pH¯às½—'w;¥æ+–êÜ–œ¶cýœ¨q5Ï÷XUgfµý$ذŠOö.­O0€>w…Ãä/Ä‚Xžf ÁFPîù0£¯Ù©nñ3—|´ÁÆàúÄñ•0ó-Ћ‡š&J¬Å·˜úliW~Ñ1n:"Ò8+æÓSnT¥ïâü„zÌB¨nXŽP5ó|h Fªž œÎ-¶¬·:ƒlñe5j ­çÊ.Ú¬KrJÖœMqZ*-Ã2/ÕÍ@áG†Ÿ jòéÙ-P³ÕAŒjWA8gs£eæä†hÎj ålŠY³Õ'çSôE´|NVá»ä‹Wâ Ï.šcu .Ò 3ºi$ 8ÇØEží/më³%î­E4Í|X ÌÖ aì[íÁV;Ýêë:tï1Œ³öP3ÿzû$äëîŸuËÜ%àå;èv®ÜB7šåíÁÑ«ƒîo'ãý÷Ñÿþ¯é"?ÓpÚOÔž]yüªŽ@~u7²ÅÕ·$’_Õ‘É¿&"¾©üª®Xþõ)ä¯̯êJæÕÌ/›_9Âù•#_öôuDô«º2úÕÝ éW߸”~U[L¿º+9ýê[Ô¯jJêWw#ª_UÉê J&½ùe…y=¯u’,‰Âq¨j¿¿|É^@œq‹¾k‡bãtÒ.Š †Å=Ö^â7 À™ êv-Pßšübo“0¨¦ÉZ Ò‰tRéä®!}Q ©©%H=¸s¤¾¨©AêA Rî©?ÔBê¡Aêa R+‘Z#Ø—BM¥ŠNÑÏŠ7ñ,;Ì&a¯2 ‚±¿‰.Ë‹JFh\ò¿Í ”çû–Þ$ÓÄE¨Æò8é§=X›x%êÏú)EOiÖž~v£Hbr¤P•Ú“Òóúa¨ãàšÆ~⤠å!œ~Ps×sÆêŒ§-ð™¾p›Ñ/ ý-j¾[«dìTwÜ‚r˜]£­‚™å;|Z¥\ÐüF¨ûžKÑãgä@œrî[|p;é¬S4=LŽO³ŸAúÔâ:šõ´½Šƒ­šn—úÍL”«æ‰s+ÒºM/r*9¯¼_ïýãÃÞn§Ûy·Ó1©,ZýÛÏ1ð^*Öí^$½O¹µp|ø}¬SԴ댕‡,1Ÿsy$.¥ü¼òjö2½¤à3¿¬0ΪßpËÇm8½ç ¨~Ê›»8¹J¸Ò·ÁÄjIv Žm–¬qTôÄmʶ¡¿m¯ 4IL Qy¬’„Ë­ÒÊ!GñÑV<:/“ÅU‹,sŒ †!eIœG)a“3ØÏHÕ9@…úCEQyä•kà´’~4íG^B ýf„p08" H ¯¯åDò ÇyVµ4[è[l*äµ\ÑÛ9ƒêÏÝ(ŒXû¾S€ÙÌ©:œ&˜ <—$Œ¿7$°>e*L>K°Ë4§”É0Ww¿xÄëTì/O”eC{»qL•[…"ÿÛQãõ¯Ø3k(ÜQÎ~Ê‚Ž”Ä±É°ÁI„“~»Y/uPåu£›?x7вüN%žBí¥YS é(µ#Ưˆ©”Ó$\ecÊb)” L¢ÛEôþä×Ýèyû‘“I½OÑeÆTä•$êböå{!ƒÛ#½ä:ÃÁÊB³k ÍéÚ@´S_ˆ’Ô&j‹ªð‡ûÂçI#”û†5Ê<ñÅÌÕ zˆÊ`ƒ]«g‘ÈÊÙ ºsŸ<¯Œ;£5Vq»‡&ÕaÅ^ÂR ¬?ÞJq}%LhnHÕæÚH-N¶ø­|¡“ãÏ¿‰7Ú/[ÁËóº»×¸Ñ†ãníêUÖÍIMVظ÷æAé”óL™Í"É!Å1q>Ü¢m”„`Ä¿˜Â÷9ŒÚ±(Ȥë jè½Àêà÷UŽ|±iPúÞQœm¯Lñû†ï­µ8m6¾)_{¨»j%M\ •ç*æúÏ0dŒbPŒÜ ®S@ûJ£l¬(ï¿Îc¬V¦ÖÐÙ ¨;uÒjr}sη*sðîħŠ9v¾'£†H. r±VâPeR˜ÈÛIN®Æ¨‘ÁzÆÍ·dR¼[9ÔM u*ʦ7èÛ»%ïÅøÑå›—Óÿø¯fûöwgÝ-‰Ü›RvÈÃ#%ÿ©›W| Y=eýÃlÙe+ú#væO8^×0í—y(¯37ÅE^E¨m ?•f0ôÍС4–84Z—£5Pè9’»Q¶x®™«D÷Öç¯sµœ‡øë(œ²"N'Nv~K-O'Ev«ñ\˜¬P%Œ8òJa”òaÖMKYqM>¬Ä‡2V\‡sÖ›[©)SÑœª6\¥²76‚S®‘²#ùs.%§Ú5/Ž/ò¦LµôÓb! }=”ÁRQP4Ä%«®{YM©@ê¤q¬´¦ÁKç±Ë/t½•à-§S«¹—Q×K»økÉžrî›É€¸£f\Q‚ñ–±¿Ø’Jaðîžxë¾ÓËút\1àÀ¥AXá€IlºRíŸÛ•vÄïÚKs—«uÎ|+4Žü&Umá“=\Y»“Œšˆ©áãµe2Ê'k¯^.ig@(‡æ± ‡n¸„§ö‚ß?¼È*¡¸23ý®eíñ«lVï’9ÛNÑ]œ´QŽÏ’Ûü²ˆ•.X•¯Âf?„Ú‘mo+z𠨂gÚMl4Í/ºXT×°ßΩ|äò€h †tŠâ½,ž«Òqx’‘¾+ ÕH¬ËüÞ\: 0¹ùÄ´Çõä´E^Þ¼3ëÚ_`NŸ%úÝRcæäpƒ%´œª#í`Wžyœ, TL€£«T,¢ü<™à©ß‰ì<é¦ý|‹VÛ\’ºñ¤YòÆúÁ~ÌQ´ñ!‡v5¾à³Ouc|TÕ~’Öκ.ã®K帗õ ’áùäÂY£|õÿ¬hãÑ£²y¥IÍ­ÿ§‘©QÂ{¡¯Z Ac£…ã;ÀÚµ¢0³,®î??¢åÿÎ’åV´| â#þ;É.—£?Щ~ ÷~W°°ÇMƒz7iêx8îj,udßwáÆûqŒÅ¾²¡¤Râú<ç®ÄÆ%…-æÉe<œ¤ÖH¹€RèCÉ3—ÂðÃ%`¯ÉÄTc,És  ~~PÏ“›7 .ûuær4¹¶U°1\Aã>¥(eåŠÝÒÐsª9+4.PÄÆ¬C¥>{æÐh)'¨Îð£:gX5þ©iZÏÉ`ô0Ì7Ï œßãoÿ=ÁßžÌf!æÀ* _hÎìHþ=¹Æ·ñ'Í;d%ÂrVRŸ—à@¡qgñ·O ¼¼:Ö¹ÑlX|UVÉ iµ˜ÞÆM(åE!ëã“qZ›¦ól‚=¹j›"¶ÂÕ¸·®OÉ5²¡Ò$8!d0.´÷µS9ýJ2Q9®,ˆ‹Ñ\e;Gƒ3"©wÒÇööÅ›‘w…˜½Ú›dߤgµœ ´Ú2 w*àn$“Ý‹<6!N²î6Âì=ôl î"Ño¤µ>¾è‰=g0‚»üÑSV¬´"—¬Qí¨;„דa·ˆ¼-ö*A{NsVsr¥|UUñ=Ðx¥Ñ.à]-îlýèôÚót³œep¾þ«ÞüBçJ Þɵóž/‘Sf²«`ïFÙú0TC'Na*±~ª@ïXb–AÕJŔҴÂã¶¢0äºÌ¶Z j¤Ê^xrš4>Çã0±-û`‹†µ1bn8qª ó¼k“òÐVÙi¦¬÷‘÷Xd-¼ºDµ…ŒpÝH«P¦Zæ°êK;úûÁÎáÛîî?þ±±±D¦ÊvBù¼û–û,–óÆl-äûÄÅKUò‘!b¾ÌzŸÖUÝúþº¶o\©E²â!×d£Ÿ8>XïhcC'YÏCo·ÛXì:”g00‰H° ´ÝŽèÛ†®’¯àÚˆ>Á‘´å«š””úª‚nx‚¿ºÐHEè Ú¾µÃR&;‹^£Ñ%^_’k9Úò[À”‹`ÓÖ:â×îÎÁAnˆVô*7º­¨ ÚÅf¨‘Ñ÷ÊÈ{l#†A²HU-˜¸O…KêMcnÕövvܘ\¡D™†ãèÚïüòÕîP[*DK)C®J¥³Ä`ZôùTŽ_é0z›eç %v~iGFtNNöŽEc©çG–dK Þïì‰ÛëaáÙì8ÂäFø&sámÊE©BaòHT¬~í¦¾<•²Õ˜ŒóGIˆTµùíÃñÞëã÷;ÆÜÜÔìܾ‘>%ú2â2×ðÓ›qv©ü°ÔÈ-)¤¡¨À˜úí¡(·–a‰pöÙƒœÔ{ÓtJJ„v^C;q¿ÏlÊeЀ™ƒ˜3Cq="z[—DN'zG/2y…Šˆÿ)*!7’!¹>‰\wKJI’,*A7`×ìÝlt=NÏ/& 2nsbVЫsœžN¹ õ°OóÒKít,9QOSöÓÇúÌ-vÆÍ¸0F6åp† ¸âžR&áÃ…ïðšçÚ¾yv e.S¯¤—ÉÄTÔÃD_.€dÈèñ‡ ‡?–‡Ôø®6*M ¦BðVU’L®ªÂ»=³$ÌøN/ÅQ5 LháE«íO{‰…_ÔÕöÜ)ÊEg>ëQšéXmÚC]É 3NÃý?È â¹>˜P’µkq‡R¼[W(°,"¸Ío´òHj —s*.fé¬@×ð-™Æ”ËŒâ%;“œs­IÂ7©Ë¢Ev6¹BâÊR¹±{ÈÀàÆHQC¦-JÀ ßÀßíŸD'Go:¿íïEð÷‡ã£_÷_n^ý~Ü‹v>üóxÿí»NôîèàõÞñI´sø¾=ìï¿úØ9:>Áa–wN ó2ý¶søOdBÇ{''ÑÑq´ÿþÃÁ>Œïvö÷NZÑþáîÁÇ×û‡oáÆû؉:äRµÿ~¿-;G-šºØ3:z½ß;Þ}w^íìwþIS¾ÙïâtÀïèÔFvŽ;û»vŽ£?ìE¸¾×û'»;ûï÷^·˜7Úûuï°¼ƒØ].ŽsôÛáÞ1®Á^nôj Ýyu°‡ÓÑj_ïËÅe™¿v‰äÝ='À’÷áoÀË,jçøŸ-ödïÿ~„vðcôzçýÎ[Xcc6v`“v?ï½GØ%'_tö;;{ÑÛ££×„v¸Š~ÝßÝ;ÙŠŽNqOö˜×;šFÄA øûÕÇ“}Báþagïøøã‡ÎþÑaöü7À@º½_®qÍL;{GÇÿÄ¡´­è·w{ðý1¢—°¶ƒèÀ ÐÝŽÝ ¦dÒÂÌz£Ã½·ûo1Û'68Â~Û?Ùƒ«õxÿìÓä@0íGZ;nÀFÛõÆ%çín´ÿ&Úyýë>Â/íNö…|}»ïûêX¼¼Åÿˆ‡Î…¶®Ïcòe‚ÁÂ*w%©¬A½¡½ˆ~?Ή=1—° l>㦤µƒ†4$‡ƒ÷G»ÿÞåÙëªO@‡;ÝÝ'£÷$¶¾Ú@ÆØ…­:é¾ëj寨’ü-À°ÔÀüÿδqÔÙÊèãÞDyKP™[Ô¤“ÞD®»g¾ÚâÎQžÐMe5–Qò@§“d"ý”ù$¥ztƒ¬*¡mÕ½öåÄ>ˆ_OØÁëÊY¾,!A¾E‡Îü‹ÜçõÞ?ü`-\M +ßW@\Th§2uç›m©ž«ò;¾‡.ä‰c½X~暊zÍ!<`ë­ Ê«@à‚‹þn¼K#]ã—”sÙiD¯ÕZZ¨ ¢ŠS²4“yIËÏçÁ•Y÷Îì*ú â^2莓sD®£Fªàľ £žšœEKšŸ+nâ.ÒMÙ{ÐKs€÷ ¥#ôaC1–J†âA^?SÀŽÊ5ËõÞ6ÙÑ?Vó˜U¿É2Î8Š 'éSªP¬›Ê #ÌŒv&Š{³ kož¨¨J´áæT޵°VÒgõ.f"o‘:ŠvJ‚“Ê ì“kÔ!£·Kýˆs5•F¾Q ˆ:—D夿ÔbDfL¤º ]X€c±Ž†fww{eŒ§}8Ù¿OÉ5¨)V†~KDÖi®†×x6³8OWô*à®0L›¥ÝuV¬0‘³8IÊx˜$ç ^k…×V¾Êi†6Ø‚²óa¿+Æ”×{ 7ïuO·ìv߃¨ñnã¼KWW÷€é؃–œ¯¢S÷TìXlì{— úA´­–ô)¶1çaG±`k\ÄzáøX¶Üqìõø|˜ÁYïaôíD-Þ;ªÌÿÎb*$»hŸ²jõ9O0 T¬‹¬ÏÏÉ:<’Ù ²8 —²Îb[´|¦§ƒ´· šzi3v¸RÐü¿Êvìõ+h aO LSTs•ç´`ñṄeõ¡9g1È=dxôI‚`òB¶K€`¹l8ÉèƒÅ¦qôzgØß$ñØâ´ù.«ßh.Ùá {ÿ€Ûüdÿ×½î^äÇ Eï£Á£H’ìy‡ƒ2/=:ds[3ç«9„¶…åÏYÚçþ¯“³(“©ôV`E/£G ´ý!m‹¢H­½Êæ®i °ÖÑV Æ1°XüHáúƺR§)æ[Â>Ç1V¹ññÐ9§R°¥ÚR¾*9š)ɳ€ô,ÄHF«Žb¦ ¥ËË‚ÇÞa§¡N«¹¼/¨Êá¸`Ûø&Iv”ÑMB™Í0\ŠI¼98;9v>M42”z–vl¡¾ž±¶ù«؃5k›+YКúY0ãP‚ ¨C3+’ËZ4åæ]@OÞr~Wy{è®…)Ì`S†³ ‚îElÂPcåœ|n«þ ku“À©¶[¿xŸáòŸÑ­AñòC¾àyUÐ]†ˆ‘P}ñ±ýýt¨~iªÂIù@ÀMÂÅe ^ õ}´A]ª.)ˆ¿†L³ó "–ü0-b#ÄU^W³ýpy‘8âC!W”R¼^ÓÓ4Qí`¾>Ç ÍPžá›["ôÉ«<ùÌc•5îêî<;o‘–ÉŠ®`Y~åü'JÀãFL[°YŠ3» ¹ÜÏÔÑ^n’Å}Ó¼‹!yŽþhÄÎû\¦M‡òP ÐkS]ïÂK¦‰¦! ˱ €÷ÔÓQô¹x“Ê‹:e3mæã ô{áÑý¸æ¬°ŒŽ®(·øíuóæ„õ_@ªIGííŒcC#Y/Råè(ÿ_éɱA>Iz“¹åYвdÃs¾%|+P˜çD!rxF/"D}|ܲÓX¤m¥‹Á½ö›Ü]¬õ¨0‘d˜|¦wwç¥4-‡Ðá—¤7Eº³Å©Ê@Ð Óî½>j\ÅÃÿÃVv/»ln¤SÂ.ÀÊA„:–•a]ös§}p¿·7öåJ3•4r;dçÒkI¿$9 ‰Ä|ÄFSt8f"~ÎøÝD˜öY™$‡k0iÙ€žC˜-¸ú–㢇@Ý6#®‰Xå{Ž¢ã!d©ñæò6IÇ_K“ríû·—\¾ƒêÁÁÒpo›.Îlš»0³g!šZJ@/@Í» ­¯)„”ó‰Í>ÝÇ­D|TŒNé–ºµ8¬éÀsZ.½2^Â\)hˆŠ™ ±"·ªò ®-a˜£¿´?HHeî'ƒDY§´ /\=imš#Á,Al¾ ñ«kmZWv0†5×¶‚èhˆrÒ \9íQ¨Ÿy›¤Cбº£Éø…wñr‚ÔÖýGÖk‰Cú0bÍÕĤ§–ÔËÖ³+r#9a~:ÀÕ1?–+Žöto“É;2ö5 ¢Œ¦ u§ß[êY}ÆAîî4§Zb¦Qèã2à"ÜIn¡‡ÖõdÚÒ9áK)øìD1Íî–ˆ ªÕéuä‹Ò*-&¯‡’ù¥/« /ľ gñ äLµÁÚ!]ÔÑqñ±FìÃÎig+‘uü,jÖ§)vI·£Aº[Ö,Žå¥Æè6YëáíA`ô?y™Ž­hª2Ì™5¼xãäÌoE#•ØŽ-ÝSLŒ¹•Õ^A‡¬‹—…§hØÛwÑKk8ÃÎtÑ¿Iq©Mòßè6¸E³E1¼ø‘ÁÇ8Ÿta%Ó¾ýtHÞ?T˜ào* žì½ìqFÅ©â Å7RÊ¡õÿÍ£4ì§n'ãJEÀ¡#4pÅF2y[¹œ¬RÌçEB/BA@%Eá\&ˆÑ”,J9å­â˜•×œÌ Àžóþp¼ºlõ¹LPÙÉà i<®£ù[Àщìë…‡uœ Р¨™B†Yvÿ„—þs0xuýZbþÔ‡¼³r£Ù‡ÖEé£4DU+RËs<Ò®·HvD]TÒ³·ˆ9²+V½*Ö0}i…¬Z…¾vÐ)ÒÛ­…ÇXÐZx°ù×â“uwË"_ÍÇ@ðtÕ!L4P2(˜tÜVÖNŠù.ODÃ/Ñ&%½ #©Gî8ŠÇ93x!lûh‡ÙŸËQ–t¢ý Ç­SçaQ@‡½äÁNX£Ø³Ã:첑®¸4pÝÍÍá¢I9Ÿ¶jw=w ûKm Ç­“7.Ý,H$UKÒSñ!ÚXag`ø‹$Osy/aôfüÜ=˜-´Žã2¬/„ðu¢&Q7Ã’W;1ïšoó#¾é^«ksLÆ±Š„è*«•Š+âwz]ÞeW¨ì;Ã\Qæ]ʦ©ƒñU‘´Œ.S<òqz~N~‘ÚÜE’Pœ\_ž¦1rw<Ð 1=ÍÐOzè) S^eö–ÛzOmƵ•oµ‹pÆôv³­GqñÐØ wh4Ù[1HëɆݚ›Â?\úX‰¬\÷•P­¨Í4Å{ª$oœüô§4OÉ? jWÒ¶Ø£Ãkm–½°¯°Àÿ–õëñh”Äãh¹´==‘¡Ó7ûh•ö²äPp€xÉ@Ðyõñ?^r$ÖpÍ[•·îá ÔÛ­ëŠÉ¬ˆ0Ôt.™X´Æ«D§ ©[3±jb½æÂ©5• 7°’x­íýüu¦á*_ÕH…yà @Å£#@üWõf’ügæE–ÿz®ßUUôPèEöÌ6V¶.x”w[ÒaeţɶjJ¿Á7V|q…3þßÓjT8‹æ@{ÞQ…b‹âZ9õ½|¹òSDVN†•ä'¸”ýVXÓÏp;Z*”gdÖ—'µPõuÕðJí¦rÍïI6WXSµÆÿ1£";Ôº"•uWá6´q '}ËšžŒS=TúÚ:žÄJqàZH¹›̶rH¦å¼—Û,qª~Êb²Nº­ÿA?NU?^0ã/MBÓ7ˆ§`_—öÕBÝQÉ…" gPtÓ°áT^ƒ(Ø^CwŽlX>»™e9Ç ·'ÅÎ}a%?¢ö«—ð÷±4¥Óøið€}ú-Óƒï§7 cÐBRÄ{áÇ‚du…_r!ôà”¨1ú±&Ê:È6 º< :zFi$†éhŠ·bSRŽMW4Ž ÆC„{åô#¶^‘,K®RŽt¸wš_±xW¢Íeü„ª•i{€ü"OF.ÔÑ=ÀÀ*/vçº1&Õ°\» ‘>ÆÎ2ag!RjUªÝ™ÿøL6!t(ÔD­HÅI:.Dbö¨ô#*ºYø™áBÔ¸TÕÅÔT=´»F¦\…æÿÌ(xõ‹©—`3š­(D.ÏϦƒj¤, Ö%v6NZ)ÕV2ª[¤Âãa’ô¥}\pÄ£`I~÷B”%ƒ³¨‘g|‰€Nõi˜]ñ(Ùù•ââ”×'cÓçùR K  ǧ{£¦½ûÍÑ#>?¿ž¯Ë hн‰îSÆs$^³ÈR‹4*o§ú NÁÉ%_<û .‚.%–ßQf9Šy“½$¼†þ²!+»ý®àíú-!ÈÝÒ\^qúÎ8»Fµ[»åP}ôV×þyƒÁº’5¢ %5~Þãä2ûÌæ>{ŇШâÇâWì¾ Œ6ÈA‘¼cÃB’Üáq?©¼,emV:.[ª­Gý}¢ÕÀK®¿úÛ_nîÂ!øÊÃõn}ñЭ"RÝYˆÚ52RÈ¡¸'*w)¾€•IîÞ’â<§,¿]>ÕUô×*ÔA(Ö䪿5ÉÙÔUà#ž• .¬¹;áH¢Ö[8Æ Ù©ØîÌ;Ç" £³tø‹d0ÊÍÍ•ö‰ªÈášÊ ÆñÇr²^ЉTØHžÒëAOþS ‹Ä8_L;¨M‰2sczu!¥Qv×Èi¼-ßø¨:š:Ž_?1Š>ªÌ%lõÝAÿ .9&ouÐÉõBDÙX–Ž€k`lLšúØfŸ%~6Ùl——dÔ}{ÌÐÿm3žÐ/ g²¡ÚPÆò¼Ê ‘TÊÅ€rTFN~ªŒ&Ê×LèÜ‰ÇÆ]ÄÜK2æSù×™–D'È)õÉ'È"qN¢2Rª”ŽëüœFÁèó|AÂ÷¦Îåð>†Å*“®Aœ–¹€™s§,")„XÃMsŽÉmÏ »“„šhTßÈ•dPÉýNÁ¦ãn&"OD2(þvmÐni‘\'½„òæFkzæ5kãØ¾ÐÙšÔßK++§Û~…½ íªxÆÔ©Î¤I^FL7šêøIÅ®—œN]½‡ÄZè™$Ã>ò«<3ÑÈ^ŽÑ¢< ¡`Ð.{ÏÂò<»Ò l_ËXŽ¿ì=’º~àÒ0¾l®”# OðUòE˜6ùW~müS{Ø)o!+¡µB‹Ö´qª —8úEÐ »”º¶W gª9;6ÍœiÃÌSð¼ dA¶©uúí'ëû~—gKö Â/¹ ÿœ‡ú³F‘2¡ßHü”ç|N¡? ñ/éÛ9(ô-E‰JÔ LüA•0ë÷2 !/jã$)×$¡s@K Ô(â_žpæ[R7ØŒ…¿Ãê¼ Bˆ©ĺè4í§cN­‰ðTé¦=€ž](}Â*Cw%s+uæ­¹67a¶B=÷£öÈu媾=ºÑ±c UOcRCö\Á²|~«ÐŽù3ì‰ÈÉôeE.Ö–÷Ý §LÇuTºòH^Yb– ðXì—B '*_¨å¼Šâ:qg%]­eu±ï9n$„&µÍR'Jò¥(ë˜s]޽ š󵜞 `*p%&UøI\„…V¤é°¼šßÀZ¬ã'\: Wˆ9[DØÚ²+ «–øš‡D×|±µ0Q¥äp0äS¡Ž“}•!R„O“€‚ðÁË2_HkªþDÒ¬ð¡Ku{}löëbBªøÑpçNjÙUõë½!ÝT‘,’ͼ¨0Vuw©åé >‡ AK\‚JåRâ-Únè€bvv6M#C$o¼k1ϸ  ±KIšÉÖ•‚g‡íÍ2§ÇÖ—b㊤Äû¢@룫LH¬m{¿Fäyz>$^§ˆ"d)Ñë«2“˜;…ãɳ21m²‹¨M²areãØºw(žHª:¥: œ Nb´œ}IÁcä¼Q!…¹oèToïLÐKßÖx‚ņœ~ß ú’td/$òÑ ÐŠ%£x¥Œñdò Ó™#]%dôÑób¦a‰"Q–ek*«b¡î%¢8‡_Äc+¸p‘ý–JãVÓí"x¶xµHeaIE?“t#å ѦäJÜÚw‘“ƒ {Ù”ÞtéªDVëSµSAA‡Ò˜ò“gSŸ¸(¹8šcè6ê—.ÿ³-ôûg6UGVUfêI5B;;™^ØPy]ö>Ù™âòl€ ŽGX!׿@;§œ3YðÏC>Œi?‰9 ·£ˆDaZD’Ï!šŽˆšñ|â`\ÅøÌ$­Ête.ÁŠ˜!JÂ4Ý’—îE0JÑ%÷Æ%Zƒà{ÎHÐÀt<ìÚ%'²&è¦CªÀ…H§‹1 j_%:DÑå=ʘgËÅB²s½ØyüPÂøÞ£%¹KÜ.£ªÏqt’Roÿvþè·.¦îî¾îì¿=ì6Ì ®åöOb‡“ïu?bFOµ4‰'NÔ)Z´¶ S¯œx[ƒAúˆaI{"E߯›šå°¬ÂºdíqÒb¾[ ( ˜éý…xm[Gd+°º¹¶p2kj­Ç?Ë'ˆ|•ÉnsW ~Žq“º±ÐK®¦cLm¼ •ž@*2°[¸â{:³ºë'sfÀ嫹0ÞÞ›¾çRf´7ÄNzTÊë¹ä‹ÖDõ±ÞŦýê€[“»–*¥Šˆ«;Æ’âíÉñf—‡¯açcZ5ô˜¤ÉÙN®§ƒ $ ˜ËŒ«(9m„ÉwÕ“—Ü%ÚÒ«5YO] -BâZ]4y#ÛÁ¥ Ï?5¢- ¶#UÐ=»ê™-ÙÎ^#Ý P¯dÂ*(1ʳ„­4|¼ù:Ü+}s+„¸»~~œ¯ÛRuæGLmjÜnSÅ]G¶»#Z« èbæÇn»× (½É³÷â1VL‰M$‘,Ø_œ1%ïšn+öEH¬»[VmaNù–ë¦;HsÿÉ•ŽŽê~ ;Y£<“kºkY½xqEŽ70“êÛà­i ö›Øj9Zv+!+hÑ?ú‚¹yl§®Áœ±¦(§òdríÌÀšzÄåû…µ GÒ.вU‹¹MÒÎý³pRÁ&cSF›SJ¼“85[ÊÏ^¡"ÌÊSö>¾>MÔòöp —^¡¤sÒ7”=\9/U^³ê7·’´Èöjeu¨JÑÐAª¿Í/_ÏÊåpd~ÂÇÀæ‘é ®åK~;φ'1œ$•™ëÏÒA‚¶w<˜¦§á¤¾+ä©(Ñëˆ*Óç÷“«â†ëù&òUðzT>Ou/‰[¦w3qQ— Ô|zJ‡‘Í ZÒäg5:&Nä4ç”cÛ™u·4ªo›â‹¨ÕK’‹¹Óü…˜ì¥’oSŒtÚªlß`z¸ê‹N7³®<Øo6õMK8å¬Û«FHl7P†] ¶ÛøOF‘?g b 7‘?-‡Ÿ€Îò© “={QWò»¥Äßp>OB2©ûŠ9HÔ#p1ÏŠ7ˆ­Ç96:óWj…f*k¹­å8§!·ô£ßTk2ĉ¬mó,vÅeô—Â2U"žËˤOQ(Þ¥ÂüÀ1¿s];k·¹’N•Þ㇊#NˆMuWÍúíÝz7yúé]=¬½´ÄDBÊlaû8>ѹ–&"[˜BRIdãÜs ÓOŒöK¡L@©ª)ßšXÝô³"Ù‹~`×Ý‘}õvg:[ï¢#ØÓ– !¦wJ9Œy1Á¼ ,^³Bäï\j­[ލWë4ŠKÅJÂÒÂ\[˜W‚]»h7û{@¾›¤«£æ[Á=S¸É(«ˆjî-)Ç$ǹ6òñ ¥çŒtõ(¹¥!ù8ì“¿ ^9m«ß{Ò½ù{'£s­x_UϪޣ‰oéÕIõÁ`ñAñ}(”ÄÀªNZˆgÒID+ߤ¾ô¡³†âDôÿC'Ù_n£h䆞kè4`§Î,¤-Íê™ã®uKUŒW’VÔäõ_ØÜL¢-w"+; -¤Û ÂùFï.,ѨAÏéVVFå§_O Diå%‘™Ž6¥¡·dGC ¿‘⯹† ®ÁeNc”L[ª‘ÍBÃry|º–åWHì¬Ëਠ÷‚(øø§˜qÍ¿5´7ª9Ðî‡@Cñ;}ð 4ußðŽÏ¬—¯qm»±–Nìh¤º`ýý¸QXÀp( ää¬!ðnA™E*ÊÍ›îµ,á«#úë ‘FÉ@¿êÝ>7­®*Zaâ[ª@6ɼËA½i–Ú2!Ų¨ÖOe[Ô늴SS»sžŸ4Ÿ×<НÞ ¬xéÔº*+ý²Ç a³Y5•S^¶j>«!#H}\‰òÚ¹}_ߊƒ¤èBåœ~Qa"­ò«œœ”í.-þ`‹©-4”÷nž¤+ò€…¦ó¶çqm=—RüxßP2ŒõÝc¬þùFÓÆ,4]à´3 °º<©‚´…+q }òCæ§Y+há*Uüô ®bþažÖYx ä,þi9+ Ó A ³!nŽDš‹Y.*Áó¯ q‹³Ìb@wÇsBa7$Û¹øËv¹ -b. meF ÊY;Ùëñ±ÊÛ¼ó/>;ãa“É_ULì¦sVˆ’>OJàd>&Ÿž|#°–ŽöSÅ*˜—É7?}ó+¹ÁhOg¬žš|û´9«pÂÑl¡J7»mÑ„—¾Ÿ]iÆú£r¡j¹º§cä~2'»R“ Ç*莣i~Ñ={Ÿ(ŽN£B%•—QQWû¡ÄMÉp/ß•H Ã…¸ÍºÙlVs¸ò]<ê•ï½Õx”è¨ö·ÖV}࿽µè0ºø%ÈÅ^MÒ–¶™UÉöeæs­¼Ûy¥=nFí;“ƒ`¼ µ+3Ô!&Ç–ˆSÚ]eÂâWj]½TÓ"3"Z ÔVÅìt,¦¯K®¶“ ó¤¦ÍªîÉ î[åñ ÷¨]£&н5§`wÃ:@¥ 60‰í‰æ?½¸„øì¹SYÕëP¯)V1É܉îÀÒceþ›—qoœYõc* †…ó97* -Ö®)3kY-£XYŽ"¿´Ç<5uªn±Â%åñ¯¢«°Ïà¬TßzŒ†¹xË ‘†KÈͲáø¤=>Ï79¼¦hÎl+H`ö,×¶u5З]s¸:ÛKy…¿ @¡R~îZß¶ ãÈÍrŸmåª}åv'¿k“”É9ãâ™Pp˜a‡•KØ‹F½È}Ya°ðïloOÞå3VƒÀµW%ó4ÍåLo¹Žêí9&S¬ºI%§Yz9ç}ýƒãüD3ßZ”Ò‘3É>´«a‚+_»L†BåZ`:³/ H@g‚„€/…Þû-ZS’Þ¬ØÅ;£D¼”lt‡/¢È¾6 ¯È);Â|Nà®±vzSU0`雜u^¹™Û‰Õ9ÒSœÝ´,‰ø[%‡1m#g?Þpõ…]ñºµ"ëÚüSþ=!gk70!;\4Ñ@þزÁ ñµa_€hð4+ª«h¿æoßúÌsª1cYöß­”@.¿t,÷0eQCÁÛ¦XhOC!ÏÞÊê£[‹Ú¡ŽÛ-¢›8ש“¥?N„š•žlÓZ­çMhˆ©;W-+ýW5š)Ÿ8ǃòµíóQîÆ£Ø:hÎÇëÛŧëÛøò ½8(~\Æ/Ó´  ó¿J§ÀÌÝMlúÀ–å­;.’^xÙ¨“ŸÑ‡ô#‰üߥ.Ÿ#­Â©*i®!éÕäz ”¦’sÍ(³™º±NÌlHîÈ/ÍIú‡¹¹œ,žAv{I>Û´ Í\À9”7‡ê”‘:”×a§¦†‚GáJU#ÓÐtiEïO~Ýe=Ž”¼˜2J'Ã%…¬$w:˜pa 3  ¥+-v^D(¨< à]˜QFÜx ‡E’ð騕ÓéyËP/6%BS8ä%e±¥åt3ÆÈST‘saͰÁ” ˆQh.ö·Ck­ÚNjL2]ÂPø&¦“»¦¡É bšRÞÉ3½=+ÊAÖí«bªLê¥ÊÈ6ÙêÀµbI …°ÍÆæ²ÜpH[ ´šwN[bt&îçÕ)çVno Žê“[ʲÍåi8ýªš£QU!‰¸¡š²ëÖ˜Üôè6ü–~æò]²\Q—a•ƒî/ΪÀkRÁÀ"T¾K•úɬ‚«–âÒÈð°/?8ÒÇ ŒW@¬J‡É¿jœâ¥§îVÿx>íÃékÉÈ.õ3}7–ó¥ëNÿ¿Ü‚kôß«ð©©b{—Ý× Ö·ӇɕABÚØÜYîÍj6§œs‘;ãßJÎþ(“ï‚÷¥,@CáÞ¾ë*ð¯ð>Ï>;I\ ‚=×êbEeǶö†Oýeü€ó¿RÖ¹D±0ÿ!5ìò¢öBƒˆ±Yòwá•Þ#4âiÚ] @T•"œÚ-3‘N¬}€ É\Õd³Ä¿ò€oÅdC•uñ{ºË£N>æþhV¥º2iD!ô! ̓JqþcQ—ÇÑ€ÿ2•—Ø~ÖQúxl×t„á[(O¨È<]"Š¢Æ?i€cÕåhü+Ž/ð½èlGägC-Ùj@bU<È3g<Î}N‰“éÂ>É:Y¬`Ziƒëz(m?žp´0 x_çöT ä̱7#=£TÖ z¦‘Äÿ8›©Õ´«À‘¸D êóÀ2™ÔP#ù A@ŠMÓãEKIN?ɵqE?àÉÊ0~u¥ ôL -£iac¤9™G3²ßQ‚MÉŽT×g½’FXŠÉz¹¦Å=´HÆ’ Jæit¸—¹ù¹ŽV#˜cÑßàö|ðÿÔ5¼¤Ü¾;XaÇÌ R,<àZ…úIÙ8=GÿTøj„²{¿Mûj)!IJuÏ¥8zå:,Ehè$›è¸èn¤õŒåv­EÆÙç´O„9Ôe|ÑC©MÔ­Z¾ò¶Òyé$(l© læP7h£1@ž'ìÖLÊ•d6½§p~Wš3Ðee Rß3t=ŽJ¤ñ¼•èC’| ;2¦WTGÿ$uOœ#BÇÊçwœÔ¾ Rñh“Æ }úY˜·h?78f/: ÂûGí7£íÑ,ÉiÌùB,×O¯× ƒ”{8V£·>HOÇéú$‰¥FÚ(ƒ¯iEÐc–[ÐÖ]ä-˜äÁRC:+ [uΰþòOòhÒû þ€"{„£ÉÍ´µs«¶»¤½»ÛkÖÌzËYU‰ÔOñÕ„­n«ˆ„UÄ¥æç´ÒVš öÊ@yh‰_~TÜì p»è§9í±fÞ ÎrD6R*Æ;8‡5Ë䯖Â2c:½fàP¬™eÓó .4B«1ì’8x‚öþcz†Ø}²ÛýuïxéGÀK|~©3­50‚¥éä:sçöSäDf­vq YíæOOž>m²ÌSÄE®‡Áf0 M8£Öݯ.sp Q[¼äI¤+\n1XV„iâM²‰k®ù:ð†¥z—Ôs(vœ*áŒüª„ÌJOB ëmü¢þd"–GÈûª«Ó’*œ-ëÄ|q‹€B­ð¢ÇávS…{ÝœjóÖºÞ@ìÈeê÷'Ññv]z®‡•S,;œ†ä±q¿%â·†B _[Ú±Mã%£ba{];Çj5÷mXžDËÃæ¨JÎ0¹Z‡}+RB»¢9?r:­)›V­÷N\C7ôèY#­—ûêZhÉ‹…õ¡‘o(dhB1íu4”lb¬¼õíà"ùѰ0]sÖ†w*°I"x/h§àGFà/‰Ï,ZÄçÜ–ù.oéš¸Ú G"nVØäO®¢¤Ðò¹U*c-Êi¬P&¥‡¥MºcÕ{3+‚Ô¬Ò5:pmøì¿œé¿À¦Û7bý’VKÛN¦°Úlö!rÚhí¡f¶‹áfôš_¤#Q¿ÏLEÓµÿݹÙÙÓÖì³9?ÿÒ{coKûºåÞ„6¥”‰Ýu…˜Òˆ³¸V€ûˆb{&ÑQµá$Ÿoª6¢ui^NöÊÁ «äê+qhZÍû{>¡Z†g”)·w‘¸^&ñTp*Wè³xh ü)ÐdޤŸ^²Ío%GhЯƒj-‹öLž©]Ž4Œ²CN Z[ÇWn)çO( Á-°84a§’þ\[ŠÑ @Mq‚Íò Ä·´‘{œ±ší"ÌFÎàRGžCªð!©Ïi6ˆM~u¥w…»äºy‰ÕƒÎf”èö¯†AcÅ/€ ~EŒ\ï û»ƒ$[¯S9öJ´WÂYìÆÉ9FŒåW”‰©za‡q:C„\Ñå‰T%)õµöjWÑ¿z(稼ÈÀ-Í@ÉÛ0=£@u¦æIíÓa_ ± ¬i“—óļFÖƒkMwuu§Xé4Í :¥æÝ-òÄïpEE“>eñâAåÝöxVºM¿}0â#¸`Ú„—Tœn;;';¬aÇõm7ÂËòÇåBŒÐ&ä¬\ç‚—¤'Âdg!²6уø”šØ¿ bÐÖØtǘ†<=SÁ½dÄܽ„€i0©:Q_Œ:õèl:Fliÿö%äG™^yÛq¯U*.l* áTžj+9ֈǑ˜¼‘¦:ë‚`·tØ ƒ@£Åu#/#‡ì…ÓEž™N³õ||Š2—}J‚d(1ê¹pùëÛÞ‘´d E†x¤ ©[ôGáä*ê"$‘üYt.P¾X/ K‰hèÄìÑ)úHœ®GÇÆm9Od;Q(PÉŽéõd+´n/o¡­Yn€w;'xì}è잘¬0²—¤Ô½àmÞÆ:À¹sÛs”hŸ‹'ޤ—I7³qÃ.‹‡xù£®ì`˜êZÑòr+ZßhYN^l‡¶Ï~x Ø£F³.KPw‚„]Y<û—”#7GY6V¶^% bj½1Š4eà#ƒódŒÃ©BÖ*<àóN’@nÁ€¯Ú0ÅÓÏoPƒd¢Ü3n÷+‘¡R;]S?ÏV˨r¦IÁEºó$øq„e¿IpºÜaé¦Ç?Àc¬ƒ ±;Ø!ÕÂFÂæfpåÈXTÈpPÁ›­½-Šgï¿m‚\ÔØ}VK)ÃÝP|ì‹?qùà\ª—Œxj ÙEÁÙäLPCH{Î nÕÖPÅâõí§ZïLgb!ö´X5ÚËù‹œèÀ¯M¡Êê ¸/$@°ò[•j|››⸼Mô°…#ˆ7š9U‚±õ ëÅγ`UÌpÇ™6^«C‘MÇÞ•Óƒ$'ºbe5˜iEVV}ª\24<¤’ýdA¡gè y'j,b¥ÂªŒ™U‰l±.ûŽù¹,¯è$c‡w0ZŸZòu¯°ë€:açƒì6… Š^%„~÷™“~KmªîReL1CF;ÚgE‹²ryg˜ˆâÌ=¡9_}g‹i‰ÀŦ¨”Z¢Žuñ¼çPIù¸dJIªÃ¯>¾"±z3ɺ<Þ–“6ÒÓò«xÔð:(br©íãQª‰PâœØ|W*ö&+­‘à·›¯DB¹^fb€Hõ×èä­nEyª‚jäâI¤„sªJ; 2“ªÆP%s­vsoú¥ËçqSU.”Nqï€a^¤ÅÈ5 &;Œ~z¯°,•HiEEqª»ø ÃÉä ‘?ž*e¥n{Ì•;jYÛ¨]ûä6lU¤n`ñÉáÜrm¯6vØ­Â~–{]!;퀎XÙ·À\±^”ô Æ£bóâ[4» [:xŒ`KXèºñ¼þ ^ðKucRjUç™Ó²F±c1‡}Ì“W× Ù‘XÑðoò>¢;µ"ãç-H ê¾6ûÁ äN;×ù¿YÉûLâ\û/™¢ýSõþ ‹±å»Œ (õ‚/l¢•.¥¸•JÔeúV÷:€µã6RÍU‚è$:KyÌ€#¼šR/¼š$Ûšf¬é‰hS–m)· +ð»%ª  ÅY6½”·å\ ˜’¤hðJž1U&@!Luëên/õ…Tø­}žLìàêbç‚ըЄÂ7lªµÿa ˜a-±kŒº1ºø ªF’’äb—^8&gUñ/8eèk1Þ{ÓB”ª‹–Τý‚bû†:/+[5ÃO¶ë•V=É ýt’Ò ¾Ç “žä™K•zÃŽÊþ-ÔlòÀQørÁ2ÄÖÑ7­vÁKÞÓ¦Q½)‹p¿±i4šåE5Ó…- ® ô¥OÌâœeE5!N»@Ùñ —Ë¿EkÞÞÜdKã¿yKY6Έýtœ ÷>Æ}[y7ŠílÓ%6'ùVžc“ø“Ý«€6žl²‚½¡ø×7ÀuäÛy‘7"æOÈ#ÑêLJnßcNAflz*æ’yèOÈ“€eN:;ä3ªs J•Y“5aÈ'U}oÒ 4´ƒâ„Q’˜V€"Æ6 të̲ÝÍŽ°Î…xw†EÎBCù³tNŠêL™?0%o³GÚäÔ‡ÀÀÔ-á9:#…Þ1Œ’î3fÁg@óŸ øÉ2ç{o5×O—  ’&éŽõ󥄸&+ªzœþ¦´¥é¾$BAóF…c³ÃÌT}ý ±Ül™åiÞ5ùGHúëóA…iI¥=¼¬œß¼iØ%é[þ”æ°PP;óa‰{‚S‰ñr°*‚f½,È}–²5Á<ðÚ ¦43f‹*ÇÛY¸2 ™I~Æ¥ v:Gï÷wE…ÇÃ\Z^ó Õ¿ÚZäb“Q¨Ûvóû’ÄñÛ"6Τ_H½ížI+1t•3—®"QT¬Ì™µ2Xc5òBÙ<¸³/ƒ›ge¯Êô÷UÒÄN™.Bá!þЧ.u{—çu(x,¦Ð[+ïXÚ<ã;§êñ0·ÄFeÇ*®@og%d7ÏÚxýW¥ .͵ët'á.fä¤m_aʼÇ(u›ûéb½¤¯n¶W')fºÆÓOû&G¼o±±{HrŒ!ŠDÌîûËM7…­É•NlÔ¤2‡Ê-Ìü]—¬ÞuøY¿ÿ‘þWÛerÇVr«K0¿¹-I"“T™7œüþj`Þ0{!’üœ±SŸKOŒ²ôÁA˜ƒ¹ÈÝã\ºÎbNßö—Z¢=ƒ³‰_@Y¥_Jº"úáJR=6³Ë¬Êà !NÚ¿ë’‘gþ/.<¥ácVkÉÕ¯­à)cTÓœó’ªÞÞ¢rŽ ÐYK9ý¡8äÆ"¦’s…Ø@£W‘ÛïÕÚ‹¡p”HI9ÛieÓ2 DÖcú›,3ñ!øáÕÆSÖŽ5œ9G¼?ìDÆ’Ù6]d ¤åÓJ”{š#퀞Շ?·jDìšüdKÅu’0d£¦H&9¬)q²>è´ % ,·+ã7dŽÏÿµ~¤I È„² Yq&ÇWBbœØ N„dŠ/‘têé–j|²p?aÕ˜ñÐ3o“´ü!ËÇ/6¥ ¦Ëü¼)&-ÛЯ`· $ÏnŽí%ºðyª¢íÿïXÚFªSËÏ /ø“iT®P,LGqå“k@Çù}ˆFãì"=E%{™²,›T±¹ÄëÈa‚r7p=ÀX²BÑ +à^ÛãVtGI ¢ÞÀRÊŒ…i¯&&×Uqë_(Ýiä•0HN @4Õ°ˆQ @ú€-ÇD¤Äª8=MŒ HqlÊ®ò¼ý¨%f NУH-Ì5zÎTjçå¤,æ‰ÈòÄQ9¨_šœù öð”òî*ÒE³St•c†êå4¢Ô)YôEyÓpfäàØ1O&ÏŒKGs!êìGIç@²ª¶",’%ÉÀªe$<ÃýþcÉ劕¡hø~¯óîèõ£Æ«xLN$$LØ vqùÍVL»?·40 Œ³,“±È¤xZÅb1Îèì:üssÆmpZ’ÈIÛ #µ"ú±Y5bÍÑxSa̦4œ#’ÑL§âžúãëÍø ½{iËæ®"„ÐV³Z]1ÂÀXw ±zva¬I'Œžs.-qPº_⦋*pÛ*BØ.ÁáXBŸùȱ‘ Ìy2Š©Õ e/îß§X Ëñ¤ÄÁ,Qä¦p޹ÄAØ&zTÅè÷ÇØ©s†“¤1ð+I¤ƒ¹²vy†_ÉßÓ0ø¤µ‡íàô¼g—ï©'žKžb…‡¤ò¬Ó{éé4E—®¼‹ Û=öð¡§ŸL(faéGá%oéLˆópwÿý‡ƒnƒwR²Îÿ$¼7ð«f›•ª¤ŸÚ \µUd¤yÿ÷#ÁÂ3j˜•«³gõ2–¼åZGèFK¶r¢†–Ú>¶À«Z²Ån¾HÏ]þÄÿ#t_}Ü?x½w|Ò}×]ò‚ŒN:¯»o>îbœQä*N{\Bñÿx°­"|– ÇXnñÞ†/ç tÞ*¤wÛÌJ4¾das±×Í4.Y"M²ñ93Sî:Û5æF™ÆqoÙ%ÓWç¯úp~îãpãǦɘ±äÖ¢ $| æÁèôãè [\’êÛwy’úÊNz~xr¡´uìXvu'¼y­,qçÀ(ãD.lÓL0A;R<èv«<øª}9¨a¤¶2&d)uØÇýè?6~jÿÜþ鿨¢Y ég¢ñ`” U´”xŒ!E‰Lâaõ–锸&p†µLÑDB 2LbÌdBÄ N6øŒ§×8_IŒƒ/Ë5ËÁyC¥žù³„€ZfGw6J©igcNz¢¥µ³qÇ4åÖ醅£mG! kÛ‰—­sŒQÝ ap=vëQêÎFoÜ“kMr7æ"XûÃã êmÁÏsS°tª bjñPrË+Dk‡¯ßšÀ[8ȉ±Åïi½6­·]7¦wûÓÄÿ=¹ÑŽ3µúv‚ëR¤|‚?>YÈ)iá@·=)ˆµ(~r`æ:0-DÙbýá§'þû鯧H:×8IÔò;9M…>?á×?-ìµp°4ÄkÿtÞæ>o-DÛœ9&-óÅÓš‡þ{z«ƒ(Ô<ŒÔúû>…¯Ÿâ×OzN[8àbÏ*b>ŠŸÞÙÙ¢îk[ûןç8ÃðßÏ·>Ç2Èg™zü-ÏsÉP?ã?/ü°]üN>îTÿ|þo|þ[ˆ¾¯ÎìÏædðß³…0hNÆ@½þõ˜C¡Ï3üúÙòŒNp—|÷2ŠŸÝ³[±¢ð¯e!ö‡ç7à'ðßó…ñì|…zÞóá-…¯Ÿã×Ïïœå´p’¯Àvp·£øù=÷¹5÷i!¿!døå†ìþûe¡,I¼![¢Þ÷¬©š5• õ þøËWá[-œèëñ.¤Š(þåž…-„…µ•ß*óÙxt ÆÖÂþ çnjÔ[°8âžÏÝ‚Ïú¥à }5آپ:TàÀ‚a”G÷LqaLÑlt¬6–9ä·oâ¹zºŽ£+r»¨„üìouB®±\¶$ê¤Âeµ{Rð?Õ¾ËÇ{':ÝÆdØŠÞ4Ù ¾¯=}UYK*{æ–iŠÞ¨BM—Ææ:³ã4î§=å¾/)ÉߘÜÏÓ¡Îh«jÅCφ®-ÙuTjÌcãJDÀ9ƒ`çzIÎû/A‘©.B{ØÙ;>Ü9ˆÐ{ïýÞag=®£õèõÑáj'úx²mðŸãh÷èõÞ?üÿÙû÷ö¶q$Q>ûS°çM¤Œ,K¾_ÒÞUd%Ño|[Iîtïöû[x‘(ÙÎ¥ÛsÎv,’ …B¡n¨ú)œ®#¨\.Ë€ôIFsuÜt»¿ÔºµÖûv·«j@)J—UÛøLežÎ¨‡õð‰,<‹³‡LDrƒ/ÎÔløj3î%"ÿšÓ:­uê­´©ñѦÍNžrI„h“,½T3Så—ùÆFïV¦ŽéRÈcMþƒó€!'÷â\öœ0,Y|÷DΊïÔÏÏêµN·sþ÷ÆY·@÷"^¼Pm^¼ ^^¼è¾xÁ­áÏèNDqå‘@æ[[ŒE `¼{{*n“©õHn'éÐF4)¨»)ŨOëØìO/ðžG­ ÀAoºBHS¼É¾È]Y’þé4TÙÍÛ4?ÿlUŠúdJ]&–.fÿê_ïbŠ´n¥«òvå r¨¤‘J`çX×°æÑ$‘…H¬µêIéy:”±øÜô ýWß9R0Ö±ñRMQÞË+˜ºp9€ù€ij¢ÚâSá›úDdñ'mB1=HŸÖÌAäŒÅ`º‘ªOµ‘bü®kÁ«‡‘í?ì~«æÜoUµß2¶[õ±·[uÖvS˜”m—r .´Ô9à^t‡V³whêÜ´S«_m§n|ãZÊj°‘Þ`ãÞÚ9·öÆÜ£tã±÷öFž½]ŠákïòÌk¾)},D99°°(§Ø˜Ï)20ù ž±ñÕxÆæÆ32l¦7Øü™ÌfN&³9—Él>6“Ù\ŒÉèóP ó#2žEúXˆ"s`wQæµ¹óš»Bbh›_¡mýéZfƒ­ô[?0ÜÊÉ·ærÀ­Çæ€[瀥h‰þª¼p‘>¢ïkµ(?Ýz(?ÍXïqÖ­¯ÆY·Ÿ9kœò2l§7ØþYñvNV¼=—o?6+Þ~LV\Šë™)/Ï”éc¡Ý’cåeìÛÇØ3¨çA,~û«±øgÿ`ŸÙ`'½ÁÎ|&ìä<væž ;}&ì<Í™PŠ–íùtø¶§Ã"},´÷rÐÑ¢'ÌÎSœ0´ø ³fç«5»ÏgÍ×?k2ì¦7Øý§Ýœ‡ÓîÜÃi÷±§Ý§>œJÑ>S?þ1µH íäT¹èQ·û´G]e?èÐÛýj‡ÞÞó¡÷z™ öÒìýÀ§ä^ÎSroî)¹÷اäÞ×;%KÑR>Ÿ—Ïç¥Éæ÷±_ÈA㋞¹{_ëÌÍØ':}÷¾Úé»ÿ|úþOßÌûé öàãz?çq½?÷¸Þìãzÿ[×)½ì?áÏGø£á‹ô±¿É±wö¿¾0wÿ=H4Øÿz·œ*ϲÁ³lě٠ZÉX¹Ê|C-ï•Ðêü;¡ÕG¿Z­|‘"I –¶ÚÏÒųtñ=I‹ô;jF‘Åø[žºð½ÌÊ·`òïö‡Ýse[J%FÚ‘=b™ Jþ¿‘Ii=TS{¨.ÐÃFj ô°™ÚÃæ=l¥ö°µ@Û©=l/ÐÃNj; ô°›ÚÃî=ì¥ö°·@û©=ì/BQéDYͤJ³³°r&yÓF™ ‘ÞÙ J_¼³D¿xg3èñÎfl…Å;›±+ïlÆY¼³{eñÎfl›Å;›±ƒ– ÚY›)³»Ô£¢ÛÉÚM2ý`þ-žÑWu‰¾62úÚX¢¯ÍŒ¾6—èk+£¯­%úÚÎèk{‰¾v2úÚY¢¯ÝŒ¾v—èk/£¯½%úÚÏèkZÍ"üê\ÊŸq0i}ânrK-±çgv^}Xç3;ßxXç›3;ß|Xç[3;ßzXçÛ3;ß~Xç;3;ßyXç»3;ß}Xç{3;ß{Xçû3;ßà&š½E«ùöhúAú±ÙùЭ×NN:¿]4 hžÉ °cñÑüƒu‘¾« õ½±Pß õ½¹Pß› õ½µPß[ õ½½PßÛ õ½³Pß; õ½»Pß» õ½·Pß{ õ½¿Pßû‹íÅ6fuÆÎœuð/¼ùs™; SX˜,3Ì,a™a–àË ³£Xf˜%xÆ2Ã,Á>–f N²Ì0K0•e†Y‚¿,µ=—a53ÊÐ×å5º6“[àè,Êj–ecÁQ6–esÁQ6—ekÁQ¶–e{ÁQ¶—egÁQv–ewÁQv—eoÁQö–eÁQö—Û•‹nþjŽÝ?Óš±<«YN¼y×YNÐyZNäy/ZNøy[ZN z‡ZN z³ZN4zßZNHz [N\z7[Rpzc›%B­¯[5*„¤UNeRnìÐòtÙ‹âÖÝ:²põ®lYÍ –°n¦¡3˜¹ð̽?åb(wXZ~zö’¾ƒÕFœ‘;±B;ah_;!ÞÁ^nìOŽõÞ÷¯‡e}rwÀÕu÷úf¢µ+TUqÆNpcá黉>Ÿ¸Ð €¾óËùlÆC@‰; ± ç³ô\*¡‚à@sìø…jñ0ú±¡ÿؤøG¿%d´öD´§×ÜÀºò'7–KQVØ[~k…U{µX²®¦1Œ…1bXÛ‡¿….î'7`‰€îÙžu¸*†Ä eÇÁeæ(®ú­ûAàô&Ã{¬wD€ŸÞNq`1cé?ùn¿NÂÅÓ»íŽ}×›t‘ŒŠGüH´Âú{mçŸSÇÃÊ<‡ w–Õøõ¢QïÁp¼’%g*±h~C—¬º=V«¹¾ÚÈú*}¼/)ËJý•Õ i‹­²±š$êW–q>ã6•=ÁJVVh߇LH’7€] ³F¸E€ja£bWÎÀ‚¤-¼@q!£Ð]ÜOmjÙƒ Ö6ÂfØh¹-‘ö<ŸhGTŒ’m®œÉãˆ:Sw~¬uX–³º=تH¡……¿°@‘c‡÷T:È£:F Bà=@šÓÇâXôš~c DUìÁ æämC*Ç<¥Oü‚÷¨#¢Óîõœñ„8O8é Œ.†Ã+»w‹Óða3«)QU¡ZØžôå`…¢àjÄ0ƒÅ¶ŒÞ°2Õç{,sg}ªã[>p׳‡–õ¿°Ú¯B¢G* Ó`“¾3[S/¬ Ð0ö P%ÃI£ªcÐ-¶c1š” @cWˆWrc\Ù}ù£;žÃÆ,´(( ¨^§^Ù¨CŠ$ꔇïd]AÊŒjˆiŸ¾iâ5õ×° PÑ·˜ÿ'Ø#ÐV^ëæ àµv·Ý9î¾»<«clzZš¤@ÃÅ×ü=Nî0xîðtíÈj‰W±âh„RQ±î ×7{áx} œes ÜO62i´|ÜlÃb„£ýâ·níì×›ïϺ 0Rž“• üÖ*‹b¸ªa¸VYÇ4d,×*–]™‹j»òý!Û(홉y¬P¹(ö7 ìSˬ€:÷*à÷™»%üìû^£ÖêÌÕÁú‘‹®Ðfb…¨—eWI€°èJ‰Ê—9 «6þH‹fÈ»‚XþsÑUÜJ]Eêé!+)@Yr5EÓKqþ° ¯S¼•k¥±Ê뢫½¹ÚÔÛCW\€ô°UÕk\|¬Ãúç!ýívnjÀ‚¿‹RÄÎLŠ ƒ*hB¢®ñ‚…zÿ¤DbÔG_ˆb°>ô¢T³;—j¨×Ç¢âcR¨Š½$aµç¿!é?v¦*,9¾(eíå¢,êù1©K€ú&ê®?€Ð°¬ø_ŽØô{KQVº_”úösSõþØ(@~:*ŒªÒ×ö,Lõ ¢ÄZ÷mÂŒw²¿4¥Âÿí/l¡ª,D®4ÄS¬€ý«‘-Žga–“So »ùÚü…zG‚ ÇvϱÄÝÞclZææYýäò¸Ñå_⿳F«Öihñßv÷C—Ý-nh Ü¡cÝÙ¡¥>GoCÏl¯ }Cãéh\ßóíãµkÇs˜VÍs{ÎØ{“òM¿ÂÇçÖÙyÇj7;ÖÛ߬0MÌn‚¯êþøžÝŠ• `U8*›^¬ÿµá½Ž!¬R蟜¾ôr´œ¾‹#]MÉ­€ŽtH¸žúÓ çГ+׳ò6ŒÂ’uçNn,? ýé„=†€8·Gþ¥y/ÇN0r'0ôT|rûè/QÞ&8ôïØ± ÇFä5¥žœÉæ­{0´ü„Œ|.äoÒ³]öÙWþ'|%ðýxþðY"Ê´†Ðö¡ìõc`ÁˆÀFÜ‘”³5¼H@`¶ý)•„;Pà<ìI̲ï÷È=cËE[‡õðáM`€‚׆âiÁà%v ÏA›Ü™ãRkìœX)€¥À½£5pÙÅ sw~€¸{Ã9æõᩃ¤ Œ|83;@†}€¨ÐÀ ö‹>B0¹Câ”EžJ¤+ÜðHpR”Ç´†b´ç>4ÛVûü]çc­Õ°àï‹Öù/ÍcØu°Q:ò…Vóý‡Žõáüä6«»žžuZÍ·—óV»Y­µ¡ñ*½«ý†¾¬V£Ý¶Î[”n¨ ýÁ­ÚY§Ùh—,fͳ÷% úÀ͉œ4O›¸ß;ç%:ÙÒ:g6ZuØÁÚÛæI³ó ù®Ù9ÃáÞ·8þá¢Öê4ë—'µ–uqÙº8o7,œp»úI­yÚ8.c®£³s«ñKã¬cµ?4§‹ýœ„sЧk½m¤µ·' Žf{Ül5êœVôW@ž”°£öE£Þ„¿/ ˜T­õ[ItÛnü×%|/­ãÚií=̱0;°HõË%qB”´/ß¶;ÍÎe§a½???&´·­_šõFûÐ:9oâ.Û æ¸Ö©ÑðÐ ¾€¿ß^¶›„BJÕº¼@þ\„5ÿHkÐú˜p}~†sfÚiœ·~î´%ëã8á¡ —°VCt´{õŽþ Ȥ‰EóµÎïOšÀøë üà;úØl7аxÍ6~ФÁ"`ØKš;.ÀFËõÎ$ç­®Õ|gÕŽi"üâ{ ‡vS¡¯þA`_n‹ÚöQp€Q ÿyM»¹ GUøïÛ»÷¹|´=‘V ½Ã”ìGÙH1/´Î€aRà™}}}Ï"ŸjÓ…¿åxïaO;âÈMó}fþèz'g62ÈÜ´€ZT9ÖÑì›ØV8½âÞ€ñÚÈ%9ÊÇ£I|”“O:´ nÙ)‹¿iñB"ô‚z<Ÿä‘ÛšØNXÔæ;æaÐ%p*D¢ 8<…âŽl/@Ëïõ¦AX’!F>óN‚È  Y( Ä `Ãr‰êÓ €eÞËe‚<œ'Ê'}g`O‡“pb5.WáoèÞòqÂÙP¶¬þóÉ @N@FÓ }ŸÂHB`ë½>¿x îY;Ì ¡¡u‚#Ä£CÒˇËF4Í¡c÷ÅzÂQ1‚ƒÊÓ‚’\ |¼¡[F¢`n1„ˆc3ü±EsH™"’y8±ƒ‰ùi*©J çØ/ÖªëÁiëNV À¹ˆ‡¨?qbn€Â†íÀ®²®lŒ2A*Øt¼8¨‚£1¨,«6A<zu{Ó¡ {ÐÜ QÔâ§ã±L"-¡æ±p™¹j)dLÏhæ’˜€q.Ä5Õ¸aÈÁXžï­1õÝyÈ8BKhWЋ‹Ó£þ·¿Á&½‡¿®§ ïbTâ}_&=Ûƒuȥ̔Ñåõ83eäBMWVª%èÈšÝ$:ëø—4YÈ%²„ "úÄ4K>¢ €˜›¶! ˱%°®ü>…ÁÙ¤vÂZDnK;äN€?ÓRà7a _Ž}«‘“"H7ÌhFÎèÊ åÖ™ì-¯²4ÄrãÔðt¾ÔO%4 „eMˆ²¢ü}u;œtߨq^q±"n\oˆZ¸w&E,ÁSm ùd­J‘#hb¾Ü LZ,±;ae™¹“{œ\Š• l¬(ôPMŸ)¶V}Iq+’ øûk¡&äXŠ•¶dÚµ—ËaN‚‚6¾æÏŸI,.#״ԯ͗Ûœ$1|Ç-™1 KÌZòij­—äèOÇyôlÄöË Æ@J QÛ/Éá(òlÿÈ’35Ü×O‚?õÅÎKòüÎÆ&¹xÿ,ùq¿zկݗäýœƒlÑŸpvþ)Ñóh~õ5P¿ö^’ë/¶"r²=}þU)™®¼o¼D±Öû/Éç5Ÿkέ¿Ø¢ÎßÊ·_Bcñb}U+JeÑ%-q£¯¸®ŸÜ`2µ‡Ö¿ç«\—^ r0ã°-PjÈü€ÑðµJð‘Y¯4Eü0*¯8{>Ú÷§UyÕô—Òy5¹UÞT° ó>Á/£òæ˜ÖuÞo?Ѥʻð¬Mçýΰ‘TyGÍÓé¼ß3²²TÞ'Àß#ê¼?F“*ï“£÷ItÞíI•÷+¯Á“鼚UIª¼ßt‰žTçýs.ZŠÊûm—ð«ë¼O°®‘Ê;_åú¶:¯„/¯Ò«9Ü­7‚8{ ÞÙîðϪöjó_Jï}lÜäÕ{3à~€âû«¼„â›k^Ô|¿ýLšïÓ~4Õ÷;CGBõ]7O§û~ÏØÊÐ}Ÿ¨üþ`(M(¿_¿O¢ýþÈxOh¿_}žLýýÓ,KBýýÆkô¤úïŸsÕ’úï·^ï®?ÁÂ*8öõM5à@¡‹”£ÑFºÆgÝÙ|ɱgã=J³[ _÷“3¼çû¬ÂEâÞ@Ü^A-O†²Óý¾˜ó½¾ûp95ñŽ,@w†ÃHו7a„¡“€ /öЉŒ2ŸÒ}MÊO÷QT½q'&J/"Ýñ& @qôi÷æ3CÀß— øëèpÁ>Œ[Kv»_õ’¯ÂC&uò©¶›’ÖúsÒ{yÀ¤´n²gõX×Ýc×ç¦û7ª›òùšûó5÷çkîÏ×ÜŸ¯¹?_sÏÍ.kEÖ,öl^¼þIÆ~ÜLÈ_Е]KwÔ}èè s£+ð$š²$ r)môO6p›>ìQub-v¿ð´Ö©Ib¹\¨·ƒ½Þp ÇÁw‚¨iÏÂG”¤]òÉéQ³ÔKŠÑ3©1àÍE!ÏSq q­Ó]V[¨¬áõÎ~ðç ûø®3¥K¾æß5'Ç]¬Ò-Ð%Ë•ÅA”l£é4ü¦ëðb¼qKÜë¼€|ð ߈o+TtþðèÖ<®}}ôhj`Hlز‰c+š ΊÁ¦š!xÅëgXtHã‡@^Ü’šqÑÂc€nÃ:Ö­ö(B õòÞ™´ *§Ïð&Å‘:)”`ª¹à1yë˜]½žLµKÔfáO\0ÖqCŸ¿¹òýa‰.dãg“£’ªnå¨$ÝdæiÔŽnscã#•¢ mXv¡K- “`  ¼²_•¬­"•Z(l¡žËI稤os¶~¶ÖªâGUÿ±¡ÿØä+B­µn·ô·ÛúýÇ®þc/ÞÉ>=bµ†B©ÎÂLHhð ÈB\}&ÎpÇÉðž<êÕŠ ;R5gÎXNVÎSNQü»%'%磼+g"þÝOÝt&ãÚ"³Šo´7™›ô¶R”Æ“ìoªÅÒŒ·9zØœÙÃV޶gö°“£‡Ý™=ìåè°!Š)ƒ¬=ÞMÉý†(j÷ÒšÄÒ´a›Âµ3ys[9ÖP²èïªö÷†ö÷¦ö÷ý­L>ôl[{¿£ý½«ý½§ý½ PKŽÚÈl+Ö¿­}ôÓi?…N% Çí9ÿÿŽr’õR˱þ8íëõ´EÑÐ2sSϘ îøÇ›à¬}û´˜’«ÍAÄíWADöÔwQÄÉã ñÌøöœ}|M¾¸,ªåÉ›åxDÏ(Ïsè~«ãê¡K$…£– %©y©fËG߃ÜñX‹*%ÞEä?çâæ~¿WÁó±‰BªAKèNQ☭ý:ËS‘‘®M/IR¨†?“ÔâÊö¦* ”"ZƒžIñ1í>?²MG#ÚSÍO¡Í4žú×µà:Ä ´ìæHZ0ñýwj·EÐNnœ”v¿FšÔ>•—/8#<¹ÍÒ‹.éUø}ËÑÜh ¬¥aßÄ;{£… ¹°ªo"<+ÅØÿS­üvÒ¹„I8_¿p?èá)P7иrÿ¼±ªøïßþVT€/ÉaÜÀ•¢ÂÖ€}+ø€øÒ:úÙªF_Èy”jVÌg/ˆÅD}‹’AÆü‹Lm„vžvÆQ#<,ä,c›c‡TÆ_½ó¼RQ$Ãlêo“Š¢Nöô·™R‘)ì¤Å8†Í¯Ä›v?AÉ^ðÞs‹’9¢·“½ˆ½{jßÊþà9wq1âMn‘(!™è¦ÆÂ'±³1E‘ò5à9r&¶¬úÅá+˜×}Já+È,:1UNm8<Ȩ×óAaT1#£³¢Œ'Qoù´={ƒ¡í¤ŒP}£Ï£GgE!rXUmˆÁ‰×7܃åÒ%l™ÕÁó½(‹{I§ªå¿_á Ø!W¹NÛ®­lŽÎL‹tê ŒŽÿÐ¥ÔªPÎ2ªÒê÷`N7Ò:Ü0:|ëOnÎ’÷a48Þ|Œ«ÒìÏ6dÔ’e-­þc3 ôÍ'}ã ‚#?øú­´¹l-7FU8ž3Fôùè?¶Ó&·ýä“Û“+!O;ÁX½ÅÓ´ï,7ãM1cîæÌšf\B(¾ò¬õ·»i(Øý*(ØÒPPBH¾%ô{i8Ù['[N´-</ '%„æ»Á‹þc? Iû_ IÛ1$•¢ïQú¼aš"T–ÃÛv o ƒ;o%‚+yñ¼{)âá_Ù"¾}˜ˆ‡=Ìñ¢qYÄÓ;~/êÐñtýgihÌ’”ŒÏ[È‹:ß|b࿆˜¶µìlæÊBƧ_WЋ†Þþ Óû>D½žeçœKÒ1>ÿÞ„½¸Ý¯„„AÜ‹ Ý[+¹e£É%ðE ïE4ý D>툫,‹¹…„>£Y^¡/~å^:pYê ®Ã7gÁÙ†ÐÎn vd9å?Ôu/4–ëÞ*©ÉV~º }/»([FæDQÍQ]¥´ªú"ŠyR&ŠþêYQ¸ó?9Áзû0\ª0gzy]oHé•ÛZ³|¾1?%gMšÍ9²#¯h¾Ì¹F‘U'c—óPˆKt±á‘¡¦NçA.#Šc%º]ð³ ŽóÎDÆF=ÖŒJÀÿD³¢Î™ŒúzÌ–(öý gI,;SßöØ3.QPøÏšyèÌEdß“` DÑÏ_ 4ÐcaBÄ7š’À#c¥DA¼_ 3*ªj÷±q$/õ>9®Jiúµð¥–ßÂaŸgìÿ.=9îÈcüUñ§Åž ³ú+àûª|dòз(ë3¬–h|µ ,7Dxl-p Núrº,¹Ãž&®{V»s²Æ•È1aíbh&ù¡ôL–Èh©¥([€J¤!^ȬGQ[L¶DÙ¢(þM}/¥wÙÃÎ@æop^sñÎÄa/bZ:Ì\$’ ÙÖ'{8¥ÄE¶©¥1LÇ üc7 l)•!ÊœB9P 9vzö}-ì{ ’iæ´í¡ °Û½ž3žXœ©¦‚‰M†„# g’)˜0‡Åÿœý£D©ùî(ÑÓ s…n0,ŠÒn0SFôùk îÙy§q`µ]ŒÙc%Àå»’¹õý Ø1ZÑ¢¹¼˜ÿJäöãô˜uJ-Y(à–Í^…¢;—Lõ‡Mæõ‚S¾.c¶‘ÐÚÆ˜#±4( ­6åªûÑŠ9¥?fߌ—¿‰=”2$~{Tà¨ð8·QŒ¡S=zü*"'%â9"­7iÒŽÏWDßW_ZNuÎÜWhIL3p¥qÔÎÆ×D\)oƒ˜–iV;ðkãQñ^ZYÊ¥—©„ ç]*ýÇæw½n¹l.¼Ðê×&üÚü–ËžóóÍÇ¡’Îv)JÑlý¹È&wƒ­Ò™úµ¿¶~ ªËùùÖãi ôpBÕlÿÅ©6wƒíG%ó’ÂßÙ†'Û^ÂÏùùöãî“âô‘÷JÌxÓÙyÞ<‹mžÜ vžx·©÷;ðkçyï-öùÎãoÕ.ÃSoWýíîóÞ}â½›»ÁîWÝìê×.üÚ}ÞúËmýœŸï> §(áÊ}Un¡ÿØ{fßëÈÝ`ïòõk~í=sž¯Âyr~¾÷tŒJBKþíX–þcÿ™ýðü+wƒýï†á©_ûðkÿ™ý}ì/ççû_ƒ[–J¾Ž©ÿÀ@†gþùW㟹¨Èñïã=a±LGÖ½|æÂ?4Îù¹F˜O̵KDZ*ÊêÒ£@§ŸnUâx+—B­´¯,çóÄñ°& —X³£+QÐ&ÙÞ=Gã¤D9YÞÏfS’{§A8?0'u^ËGèÌbùPŧ¶LÌN**¾EðNN$>,ŠçéqºT8ÏÜEø!âzr¯à£ø|‡KºT¤Ï‚4ðg ùYˆ€ž.öçÏ@QK=ˆŸ£§ß¯ô—$è¥âƒq< -(´ÔúVCÏûêÉB‡žt#>Ç=q ÑÒ»XY#¾}HÑóæþ~b‹¾"7x2ú¾‚Œ•|1Gϼå>úfÌè9 野Bz$NVú¾Ã‘žYÛ_).é;á…ÏJ¥¥Gd¤?T¤Ò3k}Yš²ô]2ãçØ¥çØ¥¯ÌÐcALQ-¦‘ŒYÝê)¢îEÎ%#JÉeº¡k÷“CaLáôjMäd Ë–*ÂdõàcÌÎ?ï­Ní!ícÓ8p>aâ§Úñ‰5ü‘5p1¥R9_æ|q¤`8»(Í O÷´jè1LÚÈ͵PgßQUbzË:-g'ÒÏ5—”äÛ)óÁ·Öhsi¥ô›œšÆ‡ÉÀ÷£1 $ÞÏ5ûŒìÑÙÀ¬ÑֈȢ‰Ú5ÅlA/£­G@Q,“.|ÍÈ=gø­5Ú^u3F{ úJÈ#£0¥R@.œî¤ÌROðŸ¯ØÄí,€Þ9ÏA1mÔl4ŠKÐS£9V˜ Îw3¦®×X ïØÒí.€þ0<Ò”°¯º ±²¹Ödo>ôjK­ v`öXžœàäX"â×Ùˤ–¨„~»eŠÕhȵfûs¤—VxȺa?Öhå› ™Xß#/d ÁýN3^E"×ÒV+9Ö–!Ò @<Â"SA h_Y`µV7çš“´½îÆš—òHR%ËÒ„ð†ÆMHÔ*ûšPfͦžîBšPfg_GšY†(e>y5¡™ýÎÖ„˜d¾Š&4·ŽN6òjBs‡(d¢ [”ç÷__ÊU=g.ÎòjB¹F{ ú¾½&¤•Q›§ åÃk^M(÷ÀsPœ)†ó7ߣ&¤UmË£ -„÷¼šÐB0<Ò|ÏšV3.¯&´ÌºäÕ„'Çe Ðüݧ iìÑ„°ny5¡ Ë£ =`!PMH/±·”&ôðEί -ìéâWzY Y²°Iß‹w7\¨D¡ë4–hÐjq¹Ee”kÇsœ%~<°Ýá4€FNˆ«ˆ%dñ+,Ë‚eÊÿ9uEý}¦2ЫmÕ×xÎØ¨çB…^>ùnßûaè^ူ@–38½ ­ØDU§'÷X}ˆI{éÙ!ÌØy5RÅ®†ùÏ©ƒs… sçýPVž‘X%*³‰´˜* r¥ÞùP •jTß @«%kué\P`VÛúÿY Ûÿü³U‰H^”·AÚ‚‰Þ0iÕ!áù<ÆYZ#¿wÛø~ù­¼¢@˜°cpM  ­enÝøõ¢Qït뵓“‚l^²°=X("£á±ü ¤ú‹ E$ä­‘9 ,ôGN×ù<€˜påRÇì|¨u ±/K–VŽÚä-h_ùŸß¡1AbÑØý°lã«Iao“®ós«!ýØA2áÏéH@ù±eÕz ëkWôÕUÒérU´Z¥Ô!S`“öÄíÑv€ÿö¦x0÷ÙP$ˆÅ !ž±$šš¬¯ÔÁ³Î䥊›žù'B;ñ aÕJã4ÉCŠ¢JPßM3¢} ûQ–„r>OÔ¦ R“[ABË„MfãñPÃðKÕËh »8 ê®ø¼ïc}XÏá/a÷\‰¡è mâ]°ˆ6 nPhV„íÚ¹qCIö: DÒØzìïG~0hásm«E$dœpÐ9š'·Ñz*Ò]5÷àªì N¹=w‚‹ê{Ÿ€ ©SÚtnЩ@}­ÛgUÆ$\Â3©ÔïÓ6ã2Uö-ø".i<ŸiûŠ$’Cl˜RßNá ºÆ5úÞ5") i am"ua@ƒ@î¿p%D¤J˜ ¼ ¶q«¹pZàŠ!ã”…²ÆQùˆU"ª…&Ìv="2Ûó©` & VÙ½"õÜ]T\˜Å…¡ëvX» ý!ˆ Ä%JL 1Æl_…HDô>êŸ0M”jðçh,ݽÚ7…U{µX²âÃV­ö-‚Lˆ‰ÜLG¶·6\ÇëGÂdÓ‹"…Kƒ\ùýûHÄ"<[¯àÄDÏÛ‘ä(:ºuæhk! õ©á«8ïàC»Á±°á\R)ÊmÀEû‘Þ+àL™PÆ)ñî#l‡aˆ>ÿJ0jxÔ;äß›ÂãÁ™¥ÔcÐi2ó‰ZkÑÄ•›C vL x…Ë¢1ÀM>*âm§U‰À¶×,%ÚBZ]£xI+:‡‰ãÎ4©A‰Ñ´˜Z›˜Æ+ÚB"@’KC sDBdÊb OpÎØ(Š•÷œkªˆËÿÝè‰8á°°¤T¡/‚(¼ñ§C€—Œg?¶#IdB¾vçÎÑZßEb‚Qd1ÉE%½ªm? ioIµñ7]Ço¶“lo£ÐôêCÆ–í]ÃD}•¬·$Ù€%Vª @ù’s€S¯Zø'°Ç¿Y«¸aìÂúŸUëoQk€ôN_W…Ìw7.½ú²[Ù^p]ä©o~Fz²^¾¤à×{ÈŸ}á`#$ù,lc‚P°w˜¿&¿g¢£{mK|ïhÝ"uéΗê’~EyFÞ× GiÌ_-#\!8ÿˆÃ¯Š £ÏžDò02¢òÁ=SB Ñ騔®ÒÁIEÇ®m>5gàãù¦ÄEb늩ÿ %ŸGhl‹‚Ÿ³hu>ŠÃK þh« l‹†KÇ e®4.s!ц“l8XH‘XÅ©çqgMBÇÓ`ìs=UàŠ°õ¢ë“ëÜ%—ç¶ð•ÁqUœ6ãÛ,¹K.IÃ!2º0 yàªßå¸J‡£è?z|K¸!¦~qûÆl‘ø° Þë@‹·q@‰ñ#XŽÀÖŸd«O·Å’¡ÒÀÂð”‘'w¨±fíRàä?ÝâüqÔ xÛÚ¨ƒÃ¢ßØãñ½ªÝ‹½de”'×¥õÄá­”ÜöW÷âØ”ê‰ëìM\{"Å-‰ù.PLõ ) tF¶KêÈCÝ«+h»pPÙ(yAISå®:Õ 0-¡Õ%H1ÄæMCgâ\mSc8Ø0S(¿‰iƒÀ jL OÚÁÌK¯–\ÕþN~¦z'5 õSj(¬A¦C¶‰!Eøa¤_GÒÔÇ4tɕЖÁÑL•jÍRUq-KÌXÃP.œFY€º±O†iek‘&ãæìƒ¨ê°Ã°ÝÇ9Õ?ÎýI.#Ȇ®††dÌĤÀ*‘Áí΄ ˜_ü`‘£1ÑëÛAŸ¯û™Œp$Ÿ³u‰Åà±%á|>Ù¿¯“][Ìqõù¸ÿ÷Ú>E6?ÿ:§?Ïv†Ö ¬='kK°³“±Í‘RvÚ‚ÃF^É!óøI•&6Òé&)YDÓ×§3[ÞØ˜M”ùäÌù,!“%æóÊ)›19e¼ñpYE¶1O~Ùü±å—R4Eùl#¿Lƒ­ ªÙ³„óH8Úz7žÅž?§Ø£íjyØÄÁR'ùÆ_K6*ÑŒgÉG›¹Y§&%™èBŒsq *e/!Tm>D¨Ê<'S­Í¹”šWæ*sŸ-mæßãd™¸XBHË‚9ÁÁ@ym+E^o>ÌÍ0z·9OžÛúóÉs&ëW(ï7—•÷på ª“géïG•þ4’o>‹„z‘0SÜL9q“ÿõ$Džõ,)qëQ¤ÄR;žÃ‚õþ²™ñ£H”)œa !s뱅̹{ªº•_D½¥É¤Ù²hJ–¶©j°bS7Ã*b}\Ñu.†—k—Âÿ'ángH¸ã­¯/åêßoÍ“|·ÿz’o)B‹|¶õ8ÒpÊ;Þ*¨1ž…å?•°¬‘ÑxëY‚þ HЋͦ·2„iä9Mšg>K¨Þ~2¡Úh‘äù ñy­'ƒã› þ©ð^³„L¾ý5eòL1$UNß^j÷E/*²ë(NéÏÒV3U€ß^’[Ìæ_OžÏ\%dü‡®Ý'îïÌ÷ÇÛ߇ȯ?Ûž§ì<«ÈÁKªä³í¯¢àÀ5â³¢ðçW4Jo?kÏÚƒ¥³îˆcÒϘ¿®2Á³Ÿ¥Pì<¡B‘vfh½$OGW2âGÅWT9RxÖZÈηÖB2%£TÍdçaÒ­¾—ïP2Ö¥d,Él•eç¡*K¶ôm5˜Ì•]B«Y ]‰þTpvç(8ãïWÉIëcgž´û¬e)@±~vbïw¾‚„XPã?«KQuI#Æñγõ¬C¥ +%ÿ²N´ŒîvþÚŠV‰00KÙÚýŽ”­RÚéôU¥™G‘Öƒq(}[Å,…7.¡«í~ºÚ\/UÛ}4=Nç'óUº´ó¯”[¥ÓÚkë9[ÑÛ}DE/ïï|‡zß\*YB'Ü}4PÇë§îåPÇ»?¦Š¨¿;OmÜ{V—UKzå³Ýo®J"Pͳbù¬XFŠ¥F¯ãÝgmóYÛœ+1i,Ξ²®âÄOÐg哱0KÝûÎP£EòÄ{bÿ`üxÓaѺïNYMá¶Kè¯{?šþš)}¦ê´{O¡Óê\k¹ÛùUoKÆâÏVv÷žFÙÍdÝé6CÁ¨~,-8“Ö–ÐŒ÷žB3ÖÞîþ¸Êò~Ney¼÷çQ˜õg{ó”èýg%ú1•èR„rùlï;S¬Ó:Ú+(`Ÿõîg½{ŽÞ­ÑøxïYVÆ‘è2{ØËáê‡õ³nab–~¾ÿÝëçiG¨ÖKò0ýÊ:{ÖÉi™?‚ŸÂµ—Pê÷ÿ J}¦„œªèï?±¢¯µÙ{º+•qÝ?[çOÇÒ¨<Õ°ÿä–€RÖ ¡ïñTùã2éu cÁþÓ fRóg7¨V0Œ÷ÿÜÆƒ´>ö窕gËÂS[býìÇÞïÿX–ÜHú³âÙ±ŒBÛãýgãijqbI!3³³ýìÈÒžm&6fÙ+@ìú³,Jiçò“ÇÅç <(Í<}P“F û_ÂÊQ­üYÍseùTHµòä6#À¾­9D§²è,m¿¤G–ÄÞÒø‹QiÙk3ÙóŸÓX2—ê—0¤|ë=ñýU¯¬µ¾n½?=¯ÿ½Û<«Ÿ\7ºüKü·qÖhÕ:Ð…°½´»º+Фîï÷úfbmT*@Ÿï}ÿzèXM¯WÆ×µáТ×!‚蟜>>ÇW-§ï¢Ü}5%IÛöúÖ4t€±Y¡? z=¹r=;¸· ‡%ëÎÜX :á¿þt‚½Œ|Þí É×€bœ`äN&NNÿ“Û‡?&7öþã@?ᇢ>L¾ïb£QOÎä@€F*Y ÀÐò²žßw¬Ñä3`$°xÔ·}åÂWØçOÜRúZ¸6؇>²×#ö€FNPÎÔð"Ùö§œ‚;Pà<ìI̲ï÷¦#Ç›ØrÑÖa=|xX ¤8 Êr„xZ0x‰èsÐ&wæ¸Ô;§ `iDpGïh ÜIÈ3ó¸;?aè{ëÊAúIøP44ÛVûü]çc­Õ°àï‹Öù/ÍãÆ±õö7xÙ°ê翵šï?t¬ç'ǰq¬ÚÙ1<=ã­yÞjc7«µ64^¥wµ³ß¬Æ¯­F»m·¬æéÅIúƒZµ³N³Ñ.Y¼E›gïKôaw°““æi¶¨Õ9/ÑÐÉ–Öù;ë´Ñª€Ÿµ·Í“fç7ò]³s†Ã½;oÑ®µ.j­N³~yRkY—­‹óvÃÂùÚ^q¿{ýÎHkͲa_ÂF¿óƒ[dn´ñÕÿö7 Q¶;;¡Ú~¸{.tàÂùê gÂÝŒrAùñþ¾ÒBßò…fíI`Wý5ñYù¦ '¡;ðúÎ`Æ1xzÞjtaE`m锉ü-`¯7œÂùñÆ^û0½›ÑÑÊÊ ±·±ü›zëí™´ØÀCœu3š+²Æ¦÷É¿u ƒ¢˜tÙ¼8‘°’ñllúnêÑ7d³w¹½B3u’>€ÑàÀ½q{7VÏö» Fmc7Ñ5ö 6dµ6?õ?I4&Ölã1CäAß¼;ÂGC¤øwð*ä±, –1@s5d–l½³ nÙ)[Ñv„à^{ÌñmkT$XÐs±¼’"-êÓ?Za'ÃÊ ‚¥Kb…D"DdïÚkFö-@6©„ÑUÑg$vÔsnŸ†ͲûÜž;1†/ËcŒP”’ ù¸[0¿²þø²’.(³È¨‰Ý5Adñ;‚Fü…uá(WØe|õi),"–"-Š'ðÁÂéøFŽbv~p €½ÄÝ¢.PK üÌÆC÷ç—aÐq Ý~9œ±]ü«ÿuz“îx”¬—u¤­`[}µ4 bR¡Ï4ò÷“À¤%~œFQÉ÷êóµà0,ªO”Há/|-~ô¬[ÐÞ—dûnAüñ•(A˜)—¤žkA)%r%}žÙT"ö§ôq‡ puAê9£+‡„BÙ‚°ŒÓA+72Õ‰úù×× ÞRO ÿytÔlU7ª(îž¶©[…ÐqøýÍd2>X_GÎ4…~×@¢¼†³jmÖKÓžpë»kŸzeÏ™¬ï ®z›•íÁÞNÅîWË7“‘E;ŸQ–¶Ì]œ£ þJ"d>Ñë4‘~Í‹ÎP†p˜à*ÐÙJÞ)âfÌæGîÈí…(_ƒ½±?¹ÈÉé€uIâöœž†¨v\9=uµ_Ü`íÉ´ïúxÈðÎ/K¸¾°ó´§ˆX‰à­ýýR>øw¸0±n6*Õ i#Hµ(¨ºX7>*/Æ}=‚³‚!•ÂÆ#Ïø•h £}Ñ|ÓƒUkNØö®‘þùt¢½8Zv5ó1i¹ ÁC FW |ᤔꃈýÏl«œ¯Y Ÿ~2 ÆU,2ÖO?SŸ‡ÖßþÆ0ÁúÇ lñOëgë5}Á;Jí[~ ¤³²ò…(>)MýbƒN4] ÖnèÛýà\(œÌC„›Œy)Ëa.}Z¯ –þJé‰$ãéòÅ«PI/aŽýÂÞü` Ô!DŒÈ×¥Ÿ oŒfÖ‘„žÐ4ã &D t‚<O²²<ÃÆNî"a~>îM× Âz‚qX¾§=ãS6ƒŽÓ¹{¾ÍG­ÎÞˆž¢bHÎuê-îÙ Ô¨ÚX ýÙVXp=к¼ ¦( çƒmb–n³ÝÇ[#G°Â5[\@Pó‘jé=K9{B¦ç“p+’,- , õa" 3Ú}{<Ñ)Äîõœ1© fsÒ÷˜CŠB«€ÜDg?pàŸ½¿š'#R1ÇÛˆ+D”À´ñ±ŽG>Ì´×/-‰Tm‰sõ[°Õ§– >}s o¼h©Ò÷И”GÚ·k“Òž+kW6¬h„!IÄV• Ù?Ob%éhtif® ®Â¬U!$ˆJ.ÈGÚšXè€Âln×ñЂw/­l ¬žöj‡þ]‘ô/+¼ò¼é« ˆ·nµm¿ì¢—¬[^wxýˆkŽÝÆ—å>V«_Š êõ?”òœ.ÊU*VaêÎÀ {}2™ÂA†ª™¦† †Ii¶ðÚÇ-@û¥_N¦ hxôpûE`÷3ñ6 :<¾EØv…%š©L@BFfKY`¿;^Ô((Dè Õd .î‘¡¹QŽVO48 Aˆ5}˜Ï6l p:1,¤áG¾,£aíÝÓv½ûK£µòÂâæ¼ÂxÞ“…|u€h, GÁJ¤¿ƒ\k(v_Q,i´½fï¨ò ¯_·C&½N£ ºKÊEjínU}Ù½¨µj§m`Ï åÜ“Ÿ×ÎŽ»•î/µ“KõmÑ ;ÍŸríLhÛ°ŽñEŸ_ÛþäˆÙ =¾h…ðL›b&û`çDŒƒ¼Ý$ç.†z”™WÍ™KÐBÂ5s2pñÉNaì@ƒ ¶¿ºÏ¦%p$ ùª¨zWžw-â6„*ÂKQ˜ª@î¥ß¯pšŒµÀÅ †=h,j Ä¥ Kå)pÅScLáÉF ñð°®ÃÚÓ›[Öæ¥Tz:oéÁ!kÚ /œŽ0ݪi¿¸E&iGˆÂ#w`ÝûS`¬2ÌÆîPªóN ¶ÄlÖs>£æÁé‰ß#3ž’= kÁ\a¾KÈx7~˜½2nHºª£RÛëç§Í“jíV§[ˆ>7ìªïß(\r–lÑ€½‹^Àî•ÓEé´‹çX׎ºíJÉŠ’AË@æ4bMö½´àà÷BÁD}M@cW°GÚÙøhîÒÀö®ëŒFbØØ³Æ7tÚO—Î2ŒÒ†¡Õc™Œ5æ2É Bëû¯ÊÚ–rxãŽåžÒà—<\ŸCÆ.Óó(mÃÜh:Þx»¡žËôRâ), Ü8]¶^»Bîj“Ò®N† R½p†¡Cd¦ Éß”D ƒþŽaQ&Ž2úô3ÌË!ucBrùTßO(q0Àó[²³ "Õ卸ÁŠä• õWjBBv’G£¥Žè?¤Ä#³CËÀnç&ðï ÎgRSr(¹€ZÛ»'FOÂ/ncèA³@¨¾€?×àS\²ÒñTDÿÔÊ#â ÞøµÞ Ïi›`l YV,÷+äíÞ õ†1¯”¤Oä ¼±iûã Æ‡ ·ð…•SeàhAqx%Þô¦A€„%‡ '0F9¥%1ïV6Šl -Ëà -B¼ #S(|†Ý0٫ŤE)YÚªü!Ьá2æ™”?ÖædQØM8ñÇPO¢ù_ J]œù ¬4†¸9Q서±Gqj,꨺ùuôuôuôuôuôuDQG#;èMÃò•ï×N` Ò+ë-¿zÚ¤‡ ÏA’ßa÷y†ÌƒÏ8*Ùz¨zgÁŒ;‘M»ø]¹×=Eð5V‚ÄWpà«O×ħ‰€'í´Õƒ|ͧŒÒ˜ˆn©5*îžÿ S9{J„eÓúšúI )b úÁĺ¾o…î¿Pðø7î¤^hÃÙß Ý[­u:”WØ…fØÀ–%uqÎúkÕ ½WîrÕ:ÀßâËòxéÄvuËÏ |ÀkšÒ§ú:‘ýæµÊÖ„M«ø {ãÉFÖIºqšêˆÍ–œ²&{]€ŽQÔ©0´¯¹Þ¡tè¡1ηÏ7”“dÐ ¬˜¾/¯ð¸Ç àÐ04àw =\ÜîлßE D=Çüo\v ŸœàÊÇ뵩ƒæs{ø0à"37`ŒdŽ+Ô!†Còj ÝÛ ¦žÐX%ÁÃn³±œS˜'yÍà§T%€Œ(Æ){ {š=ŸÎ€/ \ûׂ¼ýDF‡8îpYCÇñJl€ÀŸ3òåÉ«ý©DTûþìáû¾Ó ĶŽv¿Ð•¨9R¼Ã )ÙýÁšYÚ•d9÷m­Ó¶ëõT³àˆ¬UŽÓgŸˆÑ!,6²?!¶©€6´‡¡ãÉM®uH^1Æ1‘:K¸gŸ76î-2 †@¤ó`3Š{ Í._£Fà.T·_#Òz% Ô¾à5ýø$ˆ…HB!À,(Ƈ]%ºûѹì.”¤J;¡ôß\ž5ëçÇ Òè!êN4˜¦æÀfý?ÞÿzkÈDÖªåêv¹²Ž3^ç3§ZÞƒ×ôäcTà»ÛÛøouw»¢ÿ+ÿ÷ÿª››;›»•­­ |WÝÜÙØþÖö„H9ùïŸiýé¿å›‡ fgk+uý77¶¶·á]uscsg{gg§² ë¿]ÙÝùÖÿ{^ÿ'ÿ_ü Øö³1æÙólŒy6Æ<cž19®€IŠRMÐÌÒšê;eˆ)hzFQ7¼Ü€Fälé Sò ‘Œ y]»Áæ©ÂöÅM"q%‹"/È»…ÚŒÐøä˜†¦®#' û –¶’XãÀ:­ ¸ÏÐ…óÇ–3„§5´½ë©}Í!|7ö'GÊ€¢ “ÉHëÇîdõñ ¿´9í²@à=}=è,Þ£ ì–'„ª.Ù¤È"‚­£3g€Äz{Ym‡Ò­µfŸã¤2ˆfð"ø÷­Ú©Ò*§èŠÇ³€Â¯GŽÍñ’#JÙ„ÐwAž ïYF–;UÁÊÐ9Òû†õ±ÙùpÎ[öžà&:n\4x5;ì¢Äî)¢—ì'I½[Ï¿Mïp`èªW~øwxpPÙäÙ„£„LD•sg/©ðoíšÀÚÜ[ǰ–ží†¯¬Â•zúŸÄпvÿ9%zGbµ;¼¿E2²,êÆ7Ò8•FH¿„ÓM3¾ÍúH»SH„iODú1ýÑ'§GwVž…·gáíYx{Þž…·gá-Mx çHo%ËqvoôŸ×#Nøƒ6ÖiÏ8ÎcKwÂa!íÑa(Jk/KO ÿ\Ýkž=!ö)!IÈjz7œ(ùsÙ9§³™â?çœ×3š=ŸÄÏ'ñóIü|?ŸÄÏ'ñR'±øøÄ¿[:Ÿœ!è2+61Îäð5m ¡@–¤ëŸ¼Çþ”ØÞ ¤SãwáÐ,º0ñ?ò¡.uÞ®üahÉK†¨Šsä½4bD®Ð\§®g ßg„‡!°=ÊÓËvG$w§‚ØO~ƒ†§â ÚøÂÏŒá6^<Î@G×x"vú*Ô E8)ÝyÌ2Q)¥ÄÿlÒ·‰«qž¦üØd¯Ï‹OBŠSw…ûïý¦˜+½ù«n¡˜q/P~D>zï>e¥“lжµ T#›¬Ð=žOnà{ˆŽ5N{}…$Ä…¬ÍúŸ@¯>‡˜g„3¡….¹L`¹ÕpaDò’&EfˆKf,„Þï’Í­‹ÑY½Âqå C*xà2^×Ö¢DxâÀÖ{Y“G ­±cOèrÙÀ #ŸŠ(3öf@wküÈ6Eâmß™ÐVº¡óSÚàÑ™® O·@ÐB†Bò”[ã¡àê:Ó gP!ްhI:8ê$21ˆMqé ¯CÃ’GÚ>ˆ€îˆâ@^…Zâ¥A’E‚ªÈð)̤JfŠ`òÒÕÔÓ¡ìçt  b{òÅÓ¸¡ŽÍ&÷Ì&Hß¡/1²-®ÙŠP–+™„á‡Â°H«jcKSãDw}qc&$wE ü%·d¿„1iñùHÑG@š–Le.ãª(tUôˆ@¢дdLÛË~kVÃÆô-4d|O'¼6¹sì[º/qëùW‡2›Êµ¼²0H rˆÒ-†t‰^/AîÃë0è­ƒ)¯T‚IÇDGSþy @¼ ÊŤ år¹¸*ôhÆ©~|OZuJܯv§j;ÖIYiÑ„úÉùY#ºÝ°&‚ qÛÐÕõ þÛµOÙúžSØ(ÊÞ3ÿç†ë hÝQXŽ]ˆÈ=¼º¿Î€Îî'F~rþX. 3 ŠäY9XbâV¶hxNœ‘<ïçö#”뎱nŠWxt9Œ?)fMð£˜áw:Á»3¼Ëš"ˆ~Í_»­ÆÄKMÐ'!sá!/OIÍ|þo6=_t>´µãE¶Ó›ñä&–W¾9zŒÕêtšÖbššÈ®çã$cCµ;ÇŠØò Æ÷ïÇ?c|¸¸üUŒðábí2Þ?ì9~¿f¸Þô³¤óƒníì¸uÞ,ÊyÖ¼~à»ýXo§µºœÐuÞ¶~MtØÿH½È{…c'¼øãßÞû%T"Oý+ Üb%¢y÷¸Ñþ{çüBïFô’ÙäD»ã8Nö‡ço›$)E}38™-.>54jqqã{Ù ZÅ«dƒ6^Ê·jãñ:Û(÷Jg¹™ åDŸ]üÉÌ ñëèü¸pì“õF?õ{ˆ—QiQDÊ[Ù9°æ3¥RLª,ÚÃ{´*½K÷]>\SéÝÍU¡IÅøÑ hÈ>àHà3ayÀŒ9Ñ—)¤·ëüvr¡jGiÈæ}Ù½_Π ­È Ò®½k‡­”ÅØö±Ú'®C™ö5ËñnlJî¦l8ÎgÒÛI9f³,Ê­©HEs0žbGÂTå¯P„ÇVÿùÆm÷€Hü‰ï¶›³iSx0OgMe“ Io3gs8VT„ÇäΧ9šNØ/á|î aG}2±Y¯Qö4¼6|v ÚšÊd;õxÉé1hMb4þKæ¡>uÃžÜø³Øklü;©½/àýÕ.º0‹8e•K-4R÷Ř%tÏ™= ⯆¡Êâ´ð*·íL€;Fœ‰dv†×1 -Ýv­‡ê|f›á}5Ï$êÊßëÌS^鸭zy~Ùî6NÚîÛ“óúß­. ›rŠ$fª×½^”Ò]ï!^ÖŒ¹‹㬜¥áˆ´j¾(]2ójY5q& f7 ˆçág'3<É2¯?§·ÁàÔTc­)¥hÃmZÈôŽp9ÈTÓj´/O:b𠴜ߜ@] OLÉá Zµ“.Æ‚`¾B€îâ²ýa|r)'*›!)k.VLصÜùª¾f•™½ú' Æ[*†ÊsAw~AKž¸ðf6x À&OR7Ùc¢c>°ÇcáãžSŠ+ã½ ÜŽ÷²aT?R—)î½ÞMà{î¿È &vÍétâ  ÿœø½Ûælƒcþ¶‡%ë½3áßuJ&…â\ëHhŽ‚qY#•Ç(£‰L ‡£miu.DnؕٹK›œšVõPfÀ¼‘¬£Êþë‰UGƒ³îIV5è6f X㌠Éë/0ˆØ’9»j /S–Ù8•è 0Ý«:ô¤›…dpjµžZŒ’¼˜§tµ†°7Ê›ùF‹IÎÝù"Ú¶±…°µã3Ö†¹—.ñÈ C>cžÏ °"Ò娍Xì h€ð×åYóWJŠ’Ñ‹¦¤‘“>p0²¯'mäªÏŒžJ;Âq*Bÿ,«p¥ëëøñprþ¾[(‚†þu4†ö5žcî ‚)²u ÜTñ$( ºÄ²å}' EæÈh)/ tõÇ:øN´|¢ÇMÓøÐ4¶‚(“ å gÆdô¡heÒÇà Š¢.A棈æV§ßX(Ê­ˆl5Œ>ÆÖð^ò>g"šõU;lã“Mhl=odO´œÅØ{TŽC(P— a„2Bn— !¢äaJÙÓ»Sl›@lþÆÌñmLªƒì1eråÇX Üc+Év¼ÉæFɺÿÂ?;[üÿí¸#§éºÃaÆ‘¶&;'›ºCJß¿Å,ôáºÓ”­+~h‰še®6uÆpRš5JJ£8cwÈô9¯qËß"¤ñ)ªäü%}*ó0é_:%Zp?Ö‚ëO!­ ±Lz¦²…óõ1æÉ¸„sºó+8äÐo5ŸcÖPz¥·ùIë…r»JP·[»@²«wR㣙D#Vb£tì£É…a4^z)E‚âìüDFí½+oA¦¿g¿%Te¼dò¾O¹^©ŸÈYú|¿ãù~ÇóýŽçûÏ÷;þê÷;?õEÜùTŽPÅê†Ø"\Ú Ó¤5“ïD;ƒRHx5ÊÞ®Ë]YßK¯46Ó*tÙ±Ýí­ÿû¿øSº8³WrŠ':…טñ]í´yòu „8ïì±;°Gîðž…5ô ºÄqWËŽÔ鸧>3¡’Þ}„‹ËÝ?¹âQÔœ={ì—ènÏ­Žì–j`hô®HäŠ.> õ‘ì^$(pbÜ~Y6>è¾…8”@ Ê/šùE¼N™±] óñ.1²…‰ÛêÔZïÊBOƒƒ\Ô¨‰aD¤Nê@2 '¹e‡úÚ†ƒxxÚl8h‡š¤·Qq=Ù°žþÒNó¿y†±]N½¢õò¥ö¤ýKk«˜ÆbDàM¢Zó×´ï1R*9ÞÍxú9íkŠzJ¢Ð£p¢n‰R§E!HɆ"²(µ‰ @J¶ú¯³_S[`DRU×/5ž,R‘ÿÙ/eóöT·qöK÷—…¸t´Ã"ÃÁ‘ïvþOÞækékmM£ Ôß» ]1Woò·8£|ÓKkøi¥ 6†Èú‡FýïÝ‚:¤Õëw*u“é§Å3<æÕBo"qÈ÷#°8ê! ÆÄaòÈwÍ:e²D´7øÚ"é ƒ„…ÜE¥‡ØÍ½1ïXo§À_Iñ€0÷:È•f¿ŸAÑÂ3¤ˆ–÷™Àœ¢¨¤WýŽm6fí¬ H #„…°šJàik$Ûøxs»ùKgû÷n Ž«&^Â) ©žGœàjql|‚_½~mÕ™Æ/y±o™u^¿ÎiTª_¶;ç§Ëä§Hm™[‰Èh M’J–Äñ/ÝÆi­yÒM¨[Ñ+k5-B=¢¾ï¸=Xïš¿b´Çg~t\Ã.þrmæ——…·ÊoŸžÕNø6²±%>©âÿÃèËËNðf2‡ëë× ˜N¯p6ë<½õhê뫆ï0‘iˆnž5;]zÞÃ)˜@zúgÖª ØŠ*|ˆYeB”5bŠuRÖ"6QŒ¤Ç‰øXÊöINéÙ'ߟ]Ö»¤nU6+”L7T}m•7ËT-Ò˜ßû:U`ìZ¿“Ũ {y]Å2Ößd·§Í³ó?Ž^`¥ –NÈP¨ëÙ–Xdgž©îÚÊR´h½–åîã¸0îäf* ÚHtm.,lí@[›{Û‚¥¬¿f-•Uߣ&U03´êô=²Ù:6²^ççü¢[( Éz•ÖÑÏVu»RIìÐl8%Eèn—+^Œú¡Å,ΞÑHÖ U,óÁDsšÛ=Vá,Š‚¼('Ña è‰tR Ôb]eåe0³äš_gúÑ=[ºÅ;‡r2aâlÙ5P毿v1лդlÕ'Ø òk·Kb/EK‡“þÏôJ×ÞôËßþöGås©ZýBvì¯ w8#wµŠ‡×·ƒ¾Š+ 9J˜ÃPä»ÝÞDü¿’bꑼ¦¡‘ ,!À%yêâu%XZ™ŠI^VGÌD·ï«›¾âŽ/Ù%gÌðÿþO©x£R­V6ODø¸åŠ™¸&˜V„³{s´kÍÕ,+±öME³}òê!ãs‘ö&ìRâÑd¢sya¨Ä9~ôM‚è„4#†‘±¢qX]H± ±YâëEÑÍ+_äâûžÑd…Dñ#Ä®Ä-K«Z)ïÈ„76…úøCºÙ TÓûÛßèÚZ<_’ˆ€Að4õ%5§&éÒ¥ñ5†J¡A¨^¾½S®”pYOšo“Ìáyá6¶Kä ¬>އ‘ê¨âu6•øh«¼Et·UÞâ 8“ª›;Gv ,õE‰žz7NïV\¯ÃbsŠJ¹°ºЧHö£1«¯ê îõʰcÊ~p½î{îÚN¸®¦»>²=àóëö•[¾™Œ†/ðÑ=fˆn/i$óò¥<—~ŠlÑ ä³*ˆ/˜©wqolO‡Ø ˆOxA(Þ¯5…—o‡vïVZér_„Kxâ÷ºòðÖßÙ\ù'1òVuÇV¢¼3¯ÝFe³º™l·›c¼½x»íòæüñv+Ó!=Z»-<c ¹Ý9†ÆÑŽvñ¹œ ­ØæöSwÅÍ@ù\øÂ]´ôúñÑež•·÷Í3R§ðVæwïÎ[pjàµx8ã³Ë3®›ý nÍÚIó¿ANšÓÛé9h<Ù¯E&‚‹NkÆGx׬ÛiÕšöŒ¯.Ïšÿ…ÅâEWÑZ>¢Î#N´Cy2Ž"ÌS<<=T)×¢˜kx‹¶‘4 óáî#¾átnåÔíš9!ÌŠÑùÍ`#Ó±‡’#αpÁd)ÀQèuy8ü4"¦BìäD ´ÎyÚˆ™t»ÀM»2‹!{•5ïUô޼f? 9ì™jò„9Ó#ª ÄÂÄD®|´¶ù­sdåzßõn§#4º—oÆã8¨õ‹ ÜØªý¶ÞXÛ•¥AÔ¸f(Û7Ê’dô1>¯m•7Ö9'/…`R>Ÿu,\ÝVªãI¥Ú»©TyIùEÙÅ˯eŒ†e)n•7*•ÏwR×mÑ ü œž°h¨0ðÝÆBKYÞRÔ2¯Q?q \Ù§dŽIäz)w{@q)D”â´PqNô¸ÀQÜÂé‹U+û. í –šE,ËÖGG&âëMÌ6¼—÷ðèz”E¤зkä¶çíøSF¬ˆ¶Á· dÀFËOäa¬™ê}5Oõ/qð½F#„.qÜ•d@ÜJÐŒn«R¡a8Qáäp_4˜µ9o§'¤‹›˜2 Õ7öUYÅ9QGci¯Cƒ#]ÿàì¬Ox ¤4«ñ~šaF÷!å‡Jü0Ò™"$+ö|oM.ÏyÛQ^C G=úå›2]î¦W| E4qßo?„\Hfá”èå¨.1”ì™ü›’6ÙçëáßД<¦e=hZ‚aÆk‹P}3\;AQ&¡T+UØ/”.&#'0¾¥Ë±+òÊËÞÖÙñß)¹®¸¤£“ŸÍ©QÖí±ËY‹el»Œ²Ö´ ßæÒÍ,µ Ä?Hä_E‚4Òäé7±Ê1uS¿>Í›){êçžLåR²ÞÐ…g„+Тè]2#«¦Ê”üþr‚+J‘—P­ÌÛÛqd‚˜»_ÌÒÊ̦ PL°½h]ùrz½Õ¾+{ŒªWà¢^ ©óxk4Õë•ÙL1úN¦ <…†,¢£ ‰‹£ûì«’)`Ý9݉ÒïH7”F2•gk/;´Ê/¢hD¶ƒ¶u§6JzE"´4 ‚€0q jf ðR¿?½¦K…Ñ• cƒ©éèþ1ÑÉLP5‘¦o8F''óÊbt`’3Œ H¹yOó5më.׊.§‚Ýåg¸€¾L00*á¸rLPh÷É…5¢ä-F6€åб§ˆ`S¶o”ƒU’³¨5ÖG¢LÏÓP¥¨‹Ò¯êéUIq¬X##/‘ÝÇ3å^)-š—oÏ[ I×…€†–µWý[4R8<ˆå|–cÚyþ[)ã$_!B‹MDÿ &Ú÷Ùé " Ç0é§VúÔQ|NæÍâ.P -à0žù6Š3dÃq²e‚qi­“ŸÇ¤^]ÅÐí€!>Z?xdÍ‹Çqã Ж«[$£Ù›aÅîFídÒ²1(u6giÀ¨Ó‰R!c·ÁFegs{ƒÍPZ¢,¼šÇq~ ÆKÇGóŠKFÎÈìdLF²qùODa*U VÈÛ -%Éû3¦YžGS……º+¦hZ¤}°þÛ‡h’N%@‘?)‹ çØÝ¾<»hwëõ"'#ò¬ àõz”4+–¨Ó5yÊÑ´†ÙØ­;³xsâ%ÊÞNy£TÒ{cÀRÂ`ÖÀ#–xŠŠQH4›zCÊý%1r`Ô¦´S| T4ßž‚"±&Ÿ‡õ¯¶&.º¶X(iìH‹8•Ñ`"|³âÃ4Tn€2^ÈÀÍ Z¼qëPhø7Ïwn¢·¾Ð~’µþœ ³óN:*'„¾”1äH¶Ã±"``)"xîÀ#‚|#3qìÇN†4°²ÊQâf^•Oú„α¯2Ô“ìÂÇ(f“ú(˜ngL•<ÒÊH’A –ƒŸ¥-­ïŒ±ž.äœiä Ò2Àù§´·†œ2AßÃ4Œ2˜«œèV"±2 60Ã~Lç’š–zvG³\ÜqŒ¦H\Fîù6jÊ)U_ ºŸ•ýM%2 s‚ݨcä”b2!úî˜t¨²eÍB, ýœTÔñ¡ú'ã'ú¸UÖpûÚF-UIÚœòƒÚ¿hгEM,Š““‰ ÿxþš®PFÕvTt··ëÝZ,Db¯dxÇpì(3žñ Ÿíî•Ý×í“ë#pŤç’á{7xåjz]â#WŠŒ5òß3K”Ë™iŸ3.RÁŸwZûÿÎÙ £¼§š:’,Ø•0‹"b™EQVŠY5e×Oø²L}97iÊH-ItÄtdEŽa* obdiÂÜMè°AN%ãû!;%\V>»*¬0åXq­ ©©h䉵BJ#¼QÞ-ÉÛ47Uð ƒ*£ ²È¶¤Šž4·¤‚G Ìغûå %%±kµkGÃöÙ­œt»R… ÝÛ‰éšë'Ü{öÈíu{v<á.Úœá,ÏÑe´ßdð­TÌÝòˆ M¨R7°UYºTý ³fÁa^ØyÚѤH¶‰=Zñ,NW8Vä Ã^ï ¡ßøGÌ"$/4 t—f¾U˜†Ä©˜æZ ›çœö5Œª¤x8R|Öyé|Ýž;Á &>"Gö-ZOíÐg#_äø ¹<[”R8òô“¥^‹UêDLu"Ãå#ÏÈAZ²ì~ßZ;NÌáçŠe(é¶ÒIñJH˜*ÐÈ2B1YÎØð–°þ›®¡2ŸÖãýOý·¼ó«?˨Ò\…Ah‹c¤9P^Ф¸¨Æ“\rªìÞC§”á(ÐÆ’á¾£ yc‡c=ÛóÃ!h¢%Q{y£3ü|–ƒLÑ/ÌØáMwd×éŒ84’€—õ¶ó ·"8z ï*r­¹r–þý#ÌOky­…ئ² õ1pU‹üÍ\.E(Àì¸,šÕS»Ñ™ÕÎ;ÞS {š­ kó[„OÕuα¬ßü)=ÊŠi²+Ýך൴›õ$)¢R䀤*9ۻ׊H ›¾Gç }B§Ü•fÆ‘Õ1(²˜ÆªTÙ›Yв,r–’huá³D/OÜ›}£pt„¡ˆáI_í¨4OE3leqVò±ûèq'’·ŠÃŒ¢GÏÿ>o”jÌã+Êæ“ÄœRG$úÊjG"/¯¹F‰‚L3¦S¶šê ç{~DèUÂ5 "ÎC5­TT6±* «0¨][Þ€ 9û¥yܬòë—Ç5ø¥Ù^9ØØÁ¤©¡¸a†A“l¯u1–5 IBÖ<€ñáS–“ÙÞÆfQvOC[”_ÒÁS­ìY9‹Qø€Nœ€›y0™ÍMëô­¬ a]ؽ[ á;oèSX×Ît¤ÁOÙá9D«#‘ àü—6_Ž·á|@4W’ø¥Ñ‡hP ¥eKš†hqRâKfôz‰k÷EUâÈ$‰kÅUÏušU@?áZxY ©º±¦¹á‚ÖgêÌð¿¢Rú°±!O½aLßжמÉ>m\Ù¡K"&¯Àûœèj c©Nò¤ó%¡Ë$ò¶È` ¶s2N¹³Ø¸ jÍ=…±(¿©BßUØ;Q­-,š7ŽSÑ–Ìáº×Û*o¼ £qŠeýt0¼³C»pnÍ]ÌDh,ÖT©+jàÌ+Q0ÙIbœdm»JV€MòS¢”…Ò7Ñi‰ÍÅ&`ö‰þº{2Ù—”üïNârél}Ù§,:,¹°‹è`Sø5Ð —L›$I}üíÒâ[@¨¤ q)ŸÛãí·öE­‹@ælÓ«O? rUgRy£-anZÎ8à„ÜÒu@OJ4ÚQ‡;±êé33RFw:©fÛ²Vü©ïgV S;ÀÙ#òìªËÌcPýÊã{A ¼”7e|J2Ç9ch7;˜¯ãˆi?ýôS"Ïhe?-¯M‹óÚ´žóÚ<çµyÎkóœ×æ9¯ÍŸ?¯Mm û(À{ƺÚ*ü÷íÝcÁ¶Çަ”"(‰ùô ­(°Ë#]K”ø€3Ë( ìJü>õ{·‹% å“t±¡ªMJ6n:¤ÑÆ&Îï±í¬þvn"=D]ò¥JHÏE”Œ¾'› …/‘-†o8ˆ÷H}›Èz)ÔœÕE«àróµZqàIÁ&p„Ä\¤ø*¶Þ ÂwuOw”C჻f­TUUc¤…å ªÄw%®ÒºŸ<\ûª,#ÈÚ“ißõ£[¡o¬êÇ&Ê’âØ„±Ëz÷‚‘ •/n¦…ª '—ü T>oïWRrapâ^Åšv›t>qÉy[±¶§â ^­Ð]<’к…Ëâ‘\.¯BëqÈmÊt›ªp œ¡Á¢D.ù8üµ©BÇ€°ÀÊJB^” oÓ™(£…´»h7ÊQˆ°öɘ`PK'›¥f“‘4Ï …:¶T*Ú #¦ÍÒ%Qú19C¾5*HöTÆ "¢âò½´öЗ (^³T)Y†Š®Â£”bËÍ­ê+ÁybÝ "Wßc_œÈ¥ä­I}Ç ™ŠÖˆ>xsû¢šø¢óâ,õ'ºë1û¿Lwñçñ62F€ÿVg„Í™#À7:ÂVŽ࿛˰{øïÖ2#ì,8üw{±v—þ»“w„½ïÎaÿ‘F€ÿî¥P­<êðßý#“OD\FЪäH=Ë#ÎA*L ÃÐ['™…Ñ·ì¨$·}ö·%ãg5¹Ÿs75n$÷í²=I\ë7“›öQ»7¿ÙJnà§Íü¹ÜÛ_qpóçN’ |;XÌŸ»Iöñ-AKö°k~³—ÂŒ¾o€ÍŸû¢N,Ê?~p_мVád:H»i>Úõtô'èQ{W^íöƒèR%]£ËΈQ&÷Rïü!KZÊ9'’áPBOdá)¯Dãáèh¿Q$þce%Ñ£9U¬ŸÅq=«¦<ÛÏbÛLùv+åÙvFû”owSžíe´ßÏVt½‚–©æÝS‘n\•œ¸OfÀ¥É.ÎKW#) Ý?ntjÍR@TIÞ·d08Vyq0‘¬³>eŽûgC¸o9ƒ7#ÐZP˜`:”¼ŸÝ†*¸óPÓ2É‹Ne[­ÎËrêšÉûõÔ½õ‡ºï/›ÑƒCëË¡Ð2¿§7—GZoý°Í ïå˜%W©‹øÿö·n«ñÎÜú‘ÝÿàÀÄÚÁ‰0«ß_‰€¾È t¼¿‰›·ûý®j®˜ƒsg>šrtò0|sq„׎Ãx ½r8g(ÇÑ=_XJðÍíV懩œo„ÞÿÞ™Î郶p×áo°æî,Ôm8èç_ì¡Û§Å ¦dnÁHï[ë [ŧhžAF9paŸ“x±• ££E5 µ>KT§’”¬rÌÉ5¡_ †êPg¦éGYj»7vÉ‚“-E‡µ^±¢Õ®ðj¯|yà`Õ<ƒUi°<ƒm<Ò`›yÛ|¤Á¶ò ¶õHƒmçlû‘ÛÉ3ØÎ# ¶›g°ÝGl/Ï`{4Ø~žÁöµÁ¾Ï’t` áæ u)Mµ?,­?¾¨|ÎÓß/Ñä8±^¯-í‹—QiûŒÿ…h­×(—™“ŽŸ8z“OØöLˆãGƒaŽ@|bDó<°•.ÏžÊHnñ:&UTŠð±l‚q£,MäW“2üW}8k¾—0_³¯Ø¼/‹™ýÎ\„‰†~Œ(À:·…Ia˜’ݧƒ÷IÔ)ÃÁsp¶ù1Tÿó!tlOh;ÔAd‚”ÀÁ1I¤QçÆ,êÜxRê,YƒêBDZŠ ÄUxZÕH·$bê°_|‘—’ø»šIÕy¨zcUÇÇЇPB楮Ï_Vã£hÞÂ7ø)|ñÒËqÆeº»$F—C£5žb;m,¸6ÚN a&9d’ô#PÅ{°E_3öÑâ›|c±M¾‘o“3ÀDJ9v½…’+}š¶ÿ7gíÿͯ±ÿáŸG`rïÇÞmÀ» EHæÀÃâ»e¸·†¿729Æfޱ™“c¤÷ˆzsÁ ½ùôçãæb[gsÉ­å‹í% U4j”¶«¶fíª­¯¸«àŸÍ'Þ\‰›ðtsæ–Sç4À†Ÿ>tò,áïÍÌݸ•g7n-±õ¹˜<âþÜZpn=ýþÜZln=Öþ óƒÍe7¬…jž¶u·gmÝí¯¿u៭o²ƒ3ZlÁ»­Ù»[îk¿~Ì ®6Ü=ÙÊÜòÛy¶üö£lùR 4¸ý·ÜþÛO¿ý·ÛþÛO¶ýåü`ëáüÀBë$u”Ævfq†oÆàŸíoà RYCF?Ûðn{A¶¡öÌ?-a<ÂßÛ™e'GÙytŽ’Ù#r—¹ËÎÓs—ŸËÎ×ã.°ü`û1Ù…ž ê2ñìÎb<»ßšñÀ?;?ÿI´Ø§;‹¨*o’\‰§½|=öÄcÂß;™¬j7«Ú}RV•å#²­ÝÙÖîÓ³­ÝÅØÖî7d[°(ü`çiø˜…îPê<£íÍâh{ß GƒvhÆ–ÑbÞí>LSLq„Ý}îÇãÃß»™œp/'Üûjœ0 âGäŠ{ rާçŠ{‹qŽï‰+Â*ñƒÝ§f“†tÐ0i sÃÜÿ¾&ü³÷cóÍTŽ™ÑϼÛ{lnÊ(Ä~¿=[eXàï½L»Ÿ‡Åî›ý#²ÛýÙíþÓ³ÛýÅØíþwÍnaÙøÁÞ×ã¿ƻрùÂÝ´¸³ïˆýª­³ÿãʼnûðtÿ‘”ü$‡.†q€ï‹U3\ð÷~v¤^%W¨^å›3n–Í=fŒ`eÑ ÁÊWˆ¬,&Xù±Ø9¬%?ØÿüÝÂ`cú _¸Ø)W1g>‡.[½Àá¬Eª´%çèø»‡É†îÈEÒ¢R.2O!¦É |µœAS]QweºâÊ›ÎæÀÜj]Áú¹¤…êÓÈkiM\übeÅ¥Z·*ÜYoQ½x[`šŸ™,úL†&k½‹ûQ•—5Œä%ÆJ´B^ ˜ÍsjŒ»1Ü’¼¥U}I  (6 (I¥C²9’ÍE!Q¿6^RÔY®Í\È4ÓaÛš ÛÖÃ`cŽ*žl¾¤€´[©Ðâ1•ñöLˆ·bõ~ë%…$$àß΄£ô9ìÌœÃÎÓÎAýÚ~IÞÒÄŒvfÎÕôYíΜÕîל•úµó’|/‰9îÎ#Š éóÜ›9Ͻo7Oõk÷%_³ÞË5kÒg¾?sæûßËÌžö^’é$‹ýܸ@!1I5Í<Ü*ß/FÔûý—¤¸$ÏØÊBBM€‘¤$œM!áˆë¥¤b¦‘Ô·œzU\êâ‹§XŠ8E7κ 5z“LzÄ·¿°ò¼Û3Guù“=œ: Vóݪʪš¨jÎ+2YCmäj#g4~ÖP›ù‡ÚÌ¢œ5ÔVþ¡¶r†Tf µ¨íœ1ZYCíäj'gTFÖP»ù‡ÚÍé.Íj/ÿP{9 YCíçjÁ‹£É=¼¿¨&ßÒï«×è[¨ŠýÅÍtÆ­Va—ÀËõ jäà€`*–ptùˆnÙG÷[_¤¤wnp>nA6Ó²$ïý×0‡ß²Œ–Ýë9!òöYy6’÷hß;“7•£,ƒ¦Lµ±ô ©“ªÈI¡Ý;ÌAPè$Í5lª°¾Iò -óǯ#ù0âÌÍ%FU:žªO€§j^ž6óâiói𴹞6çàië ð´•O[Oƒ§­%ð´5OÛO€§í¼xÚ~ÝI}º›út/õé~ú,ÔäsV‹›˜wÆ›Ì7›™o¶2ßlg¾ÙÉ|³›ùf/óÍ~öL $˜ï2¹Œ¯„,c>”™ùÔtRê8æ,Rd9ÃDIJ³ìd¬°bTt<„X1MU~ø©éºacs6pŠXwÙBÏc§§:‚n†î'ªÖ}Kå€Ç\ë»ãÂßT„°gO±ÌJ ®òs™[fåôµ¢­c÷Ð Ê.Zwö= ^È^½þüÔß\ÚFwÁ¸Æ“ÈI{‘ùLšéSß±õ 2[c¹ÎÛ²ŽÑ A—ÅŸJÖÛóóD!h¦·¾O‰¹£"X2ñùÄõwe ìŒZÀ²‚ïÔ±t2õ€ùƒ<«à¥â>6 ˆX$ÅBÑeT©OVð“«\Ì/LU¦œ /î[¬£|KÙొpÚœôLðTw ‚U¢9jóA"ŠÅ*pg¥Œ€/yˆ¬·Ñ¾Kû@©*À…©’ÃÉ:V ïcÇá:Vr¯Ë7ãñ‘D-O‰2i§ôZâ^WâFV £*frqS*s?Øç]ïÖÏÏÞ5ßw?\\H^qœ²Ý³ê¨Z° ËÔrÇ™e©ÈI½Žµÿ­IÕ›—éÿõêê\V$'šµ0©<V¬LÉ -JŒ ´¸¨F&ŠÌrÁl…+&Yb1Þêtš8‡ØÞÀ 6+,1LÜ¡¬ASÙ,o”°æp¼þšØ|4"j¨æÓ1–R›u !å9r¹ª»dz8ζ› kËö/´Âï.Ïê˜b¿v"±‹_O±¹¨7ZÀpÓX©Néw¤ôïTÙ  äœÖNœrBDˆªJv Ä*½ŒèNÍ[Û|ñ6×õ勤»VJ8KN´Òà…5GFu{éÃ'`e%å4¸tÚ78@~Ò‘µšqs £ŒJœãZË­Al-*‘ÎS¥ŠÚ3L!Ã@çk‚þñ!Ò~“[|g' §”‡N­•l²Àcàéàh—ÄÞÐ÷œÂ•?SG4KáXˆ -$8!†C6— @ÕP†­vâzÓÏ%ç$ŠDÓ3.ÀæX͉í¹Ó‘e½wâÅTÈ 5,:°'&“ñÁúú[•û®SöœÉúÈöÖ7Ö ¸r¬ì#N«~r~ÖÅi)ún­5pá‰)wŽ*AŒÏ.˜Š?”ªÊp|Ž/cUÜ»®½³¬S0#óÓníì¸uÞ<Ç}ÍëT׃qI¨$d˜ªµNQŸ¨¹ïá/'¸!HlLË`Þv0¼»+ìÖ.š]âÝûÜÀ¬e¨0#ör´{2?¬ˆ©.ž¾ßfu,¿N-snö§É9ØN'b^í †Õ•ü Ò8ökaÂC|¥ÌíS¦t±' c{~€ŸB‡¢<²¯Yû޵¡E˜F„íN«Q;¥€«¤Gâ|fO‡“eØið»©v•ÛUž bãÎrÆë–.0Œü+.“H5Æ ÂüØ<;>ÿØîžž¿m‚D¦jØGÒ)>ãÊ@‰Fp½ô6òM«“ºÀÉ©g×½ÏøÞ,þSÖDNrvFYøÄrÌ'c‰±;­þ¬ª’™ò1™‚©[»å*ÑcCº¶I°¯àsd° ê«1ÞäãÛ)âé£tþþ²‰ßõRX% ðÇ@´chßwí¡,ÃëûwRŒñ.¬w  8r)ôëÀÐdˆŒ›+xbûN_äúoïÛ&­œŸ`áˆV´Nkus9šçíbê—r í¿wÎ/ECAòÔ&×¾yöþ£W­i‚þá‚çïáÿ·ícãÛÿ:3Û¾k5ðM¢€,Ñq£ÖùÐÅŸH Q¹ÐñÛB§m±®ÄÊy—Rý[)åÜ‘€, ±]Àᤠäfèa], àFôWíúÒ¡ähâ`%ÃßGHÔ öwJÌä¢Ö‚Ý f2#`0ÚZë¦{²O:_1¸N<¦e삌sDtÿÉ\»ïö@Eì~(Å|šJ@øû›µW®”d©à‹À·ðEóí©¬óZ»v¸öí‡ ËQK€/,¬œJI©…ƒ}Doaè:hZÝX£]=•"Жt¬(bÖûî…I3³^÷AáöèîQ$1 ÉNÇ Y»˜¹êD.Ž'U…Lq3a €GZÉf\{$É2¼(ãT‹My(ÐZã ½ŠŽMéDãJ%7%n›FóÄ–) ©õs`ô,nÌÆ'·ºZ£wh]vÞ­Uwh.å÷Yèê£% ë^'vÌÇæqO`<([·»ÐAuGVNp¶¹l4:ruVÌœž7ÀÇAj©rÞ•#¤–Zlg{·ÎDǺdéqüÕkgÑYؾ<é´»q<’UºÁDÔ7û7ªh;NóŽ\ªÝ~gT`€:VÝÁ*¹©d}÷@ꬤ>Óó¬U ´ïhÇ_vÏáx˜IMÞxG[°RØ$×Ä…'Tt[×TZ † C‡¬û°@n"¶ŒÕꬡ{눚õ$b®¡¿"ÿ´¬Z»Ýhuº¯ÑáѧòÙEëÍkµØÁÑj_;«‡¢=bf5„¾Ç€óôlب•ƒUË… 5ÒåLy0SDZ6ÒŸÉŒFŸÓ nZñµ«Ù¼¿<¿lw' á½=9¯ÿôÕôÒå[Iø¤Dz`(•E\†Ž(Ôˆró› ¼(¢Éèâ\geTk\˜÷„!ÂT¡Éáù8rÿEZ2Úw]9LÏõæiù¡m Œ„}¹¤ŒËÁtÈf<:Éít‡}Hä¢yg<f‰âæ4Ò{Šhl‹‡÷ñ'tÛøl#{ŒhAxmßù¾õ‡$øA×qËå²õ…~‘øîx{Ùit/ϰ:bWR©²là´ìÁÅ@>Iõ ,Å»EÝ`[ ޵U ´Ä¢P¶^ךJi”ØfFøÊ8*uv+É­ÛLá·‰i•Úam³P˜z8P±ˆdhŒ“ñ®YKv‘¸oì0j*›%‚E”º¦øÇÐÁýÌ™Nó5fyˆIä3Ȳ"'²²‡724‚6¶0…ŽANr ¯'«6ûðãÇËq³];99ÿØnÓ|Ö- UÄë|jÙ è²»Q_3á$k>}…,hý鯟_ü†¦ˆä,ðöÃß£ì ©“ç“Æ‰IÄ8MOøÐ¤ f :u=c8lÔfBæ£d¼UŠtY‡ºñ}rç wQ8…ãÖP’CäÝ=cË8ºuP;‡ÝrqÙþÐ-…&PÀh¢"Ÿ9³[ž_ˆ†_âK4{,ÃЃûïíIƒô¦µÖȸmñáVuc·˜·k&GÏ ´!é»Z¡ …Ö©‹¨õè3kO›Âކ[hÕØ×X´¡&ò–³«{Pš@ˆšùHv’PÓ±Ñû|íxøvH©:Jϰ¥ÉìæÝs]¡M¤šûjqV[_¨°1-ôíyëØ+ò1"^4—ب©’Y9ÝìÖøÀv6á㨱1Òóg7Q†Ûøm·&ès@³8n×Þ5LÝÛžÂQKÆqñU$R !i¤Aå=¡H%Ó™úªÕ)jýiú'™eBÆÅSB¸À¾nA‰øï <غíµüuÒ|Ûªµ~K /Mä¬xd ¿§ÐAé†U(šQu€Å{cï.ú I¶\ý¶&ÕhBXZßÚP(|rC÷Š¾ÂªP V‹t Ò¿KìÄ¥-è.m%S)‡!ez»Mœî$ì["è̶®Éâ$âr|„³s`G°8ÄT<ŸûÈ:â–ºÔ‡+ ˜`­Ðnh©p•{‚uè^õà’ѤÃàó““_NQ½ü_§—4Oa¯¿þ7+™c¥:~ýµö¶ÙýÀ*zÊ4Ì*¦«$˜! uh)üHaõÞÓ£è ›PImnê‘öfј„]œ‘“¥#øjê',JÒã¶ÿË âÓNÿŽÌ»À=vCÙv–KÕ®5;Íÿ†£¤qzÞúMñ +¹ìªÏ.ÁjBšçaæ†ûa.ì©ú÷ìîõÞ¦X¶Z¿âˆÂ=éÍÁTw%ç^ ›ûZ|1jÇÇ ¶ó­†eÑåcÌX4øó/H4ÀÃV¤sƒžÚGY uµøzˆc5×rð‹®†aÆb¤Àž-T÷©K¡Å÷ +Ï+âÎÑ)âW ,ëQ”ïyQ«7XxjŽØ­AL(ïs&ÏP”£¨qÉØœà©0¶¡5°J°ÝiïKh|záˆ#e6GÁLI¥èÝÀŒÕ複èìCéM65’¾ʘõI2¶1ëËü‰Ç<_ª8Im!ç-ж¼±K25Þ{ ã[œjÍ‚º¥íP¸ßPöeÛèÍ ÅwydÔL’ðÿÇÓ´=GwÀ,ê k Q^q€+å t8|§Í0øWx—¢p°;„çƒSAÕäÈßFÖr–ùXáí “²0<s¾4 ƒôãî…ñ3¡Óš/ê‰eë:1ØvY²îý)4BK†08ê]²& «(M¶t}Äû>2\¤Â*V­ÖjÕ~ë¶q«h¹è–ÇÙå)¯dIZIÓþGßw1x”B*ˆšŠÒDê2e"G‘J{2©q#Ø<"2Qâµlh?jüƾ_´ÞXÕ ÌœäûÝ üßЮ£ñq‘¸ZpdÏ|€WIèQÊ`aËVs #”Íõ!³BÉa˜«æÓÅh)T-'r™¬Óu*aµÀéIëRê€+š›4Â÷(VÞÇ826&¼.Š•ïbލ`"^¼À7̬õ ­ÿè ^á H´Huž[ºƒMKyPró»–¤E1̃ƒèÑý›‚¾g‡„:+Ô¹ÝþOÆWÖXUëÀZ«þcŽ8âì0¼¨L·êRç*‰´Ðô8$ŸBôÅÞÓ.5Vƒä8Aå¢+#SQt³–ÁMЃ¢–œŽ2•òÞÖø&òõ*oG†òÈ£{3 9ºûÈýý" û4]V°ÐÆ!·r ±Xµ-­y©@Rœ-`|½TŸÊ<ƒ3¦Ë˜É«ŒEr—¬ ï”B²iQ !änÐTÒ—¨>ú³‚©·†ŒÖ*L„ :~…1VÇ£ù“aПÐéϽˆUB»%yÆí OÙ^ÑÊFT4‰K +‘h±A"DèPèµúë~Ê7)Æf³ÿôÁ?&F¿]ßiã»f¼ñqJ3‚*¥m6\²V½DBQmH’öÄr+Æ¥)fùæXùúß)ÇRˤ¯Ô{X7ÍMW‹›aö{ÔOñÐŒHêù0­îx”£+[±˜6d ê3ܵV§Y;ö‚ÎŒ¢"6xŽçO¯o`½¦ƒùL —”%MÁ|Åzy9ƒðYãÓÆ4Ÿˆ…èHêírª@½vGÔ¶Ðym-Ô¨NN°,<êÆTÁ²þ­}Ç×¥Ct&‹â¨¨ÁkxÍ~vu§ú5ö„_‡¯Õ‡kGÉ/¯É[ñÀ¼ìrÔ“ô ø{DÅÏü1½À¿ÄÔŒÂð\•`¦Ló20Á]clÖ3M`Wò!?Ô#¶6唬IHá§5‰ze'’%ð#-OY]Cê;ô0‚Ù"DhÐùù °¨ÿBp‡wö¸­ÑKË.YúÏ+ 2 EÌ.  wI­í2Ž\œþUe&dHcœÁK†O$Â/¢Á‹Š½Ê­Ôj”¥m…M”`EÚìoçÚù\¾9â½Lg²ã‹óvóW«"qŸ-çz §Ä½ç8€´APûz6@¼c`GШx(PÕ’yind-t‚ä óeNƒÐ®È\<žB~‚Õð‹n´&ï¦Ãá©=éÝ`˜|—ȉ3À1ˆ 5Å5@;´åºañt†à–ùáÞ¾²—ëž{c L¯ð@VXà{}B8À»ÎÎpP䑹qçüø¼pg{ÿyMgO˜Tñ€mbѬ‹¤>Iáà>HiÇþå‡ ”°l÷“´ô¬1QÇ©tLHˆ6NàÄÈ«!iÐÆ¬ËÌ€z©ñâ+”2ä¼ý4oö_qâ8ç\»|ÖÔy#&a9œ?•ì¦ÆÉEg$1”$«‘lä#ÙÁ9ÊK}¢){¶giôB¶Ÿ˜' /B¶¨;ú}‡~½™¼º«®_¢ uﱟC˜©;­ FbáÉ »dGëêIWèí¶+”6¦ßXXŽ.ÿ8”6´ëk¿¬}>æUˆZˆÏM¾€vbeÎÕh7OÑùÂè³ ("ž›Äኊ0È ßl5"qšO$†èO1çÃMNc¼'g“u„Â<„ŠÇ¹(îEº1El2‰ã59O$f‰(îB¿×aصȆ‡65C×0Õ4ï|~âóÝ;ƒ8XÎ^F‘$ñ)Ñ\†¢! M˜5„£1JHÐö×ÓqT\lžÜÎA*ϲ Jy³ÓRíÉ0&RªxÎg™0# :âÉDÆäÿrÄ=ƈi¯æ CØ‚f4‡ÙZ±ö¿‚¥ˆ:ô¯¯*¾‚âr4¥²]œ¿ ƒ…Ü ¨õkøy(É#”×0jʸ@òSváã¥*g¦ÁSÔ䇒n”‹˜£ˆ¹›ÿºã·'€~ÔξÄÒͼ ©@C-“¾-ß §áMÓøÐEg2Àd|Ђp°«Þìl²¢¼G¶ÍÚrr¨mÙ<{w^R¿Dôeô Ñj·¢ŸïjÚI|Ó∰øÁ½B^ #œ>¹}qøº2‹àl  'Ââ‹=i0ó5>¶Ä²yçFÝŸa«7&Q¼ŠhPϺöIzš¢›ü–¨Í¤¨¦b!Ÿ(Šæ2{«3ûKÀ^Mбôú%T:E¹¡ŽÅ_ï E0=]ºEÞýo÷.¶žÏH{‰iSÛô§^îM|Ôj9Œ«‚2›ZÆüò鈲¹`ÙxTýdzêq£þ¼ØöcÏ[ª÷NM;ã-ööâE´*¿ç`'Ýî;´[ƒ¦ÜíR _·XÖð§jé‘ÌaîÌ?¾/c›ïk@»¯@v‡Ã˜l•™$Îêõ¿‹@‘ÒË¢CÓ€Õè~ûšu|ÊTÇ‚#¹l„‰sc2Tн¦µ:†Ø;XF]TÇ£K^Iµn¨˜U ¯0ŸƒÿÉhx—â8àRÜÎá<DÀp/‰X±2ÚŠè!ùY—W¶Ôm*ìkQ§*ÊÚ:‘¤ù»QÆ—˜1E&‹ºÂöªõ¢§ý@ï(Þ¬X±Ûäž"*±1â¡3ˆ+Ž&q{-œÜƒ°&… ´°ÉGÆÊ}õó>å_ DfTa¹ñÊ $¶É[rä|‹Ì ¶ueñîbßzå^E÷Y)øßòóÅÍ„hûÇD;ÆíÈ»òª “ ™¬£«±, cÿØþ*€ñnâ^FëíËzà x»åsgÍk‡kÛáÄ¥,cÿlé›ô[Òч´Â¼"éu¶šÉÐá{mÔ¸âŽÞŒÓó_ÝÍ\:ò?9‡ ¥Æü<ÃJÏ™p_ZØEAý2SHO0_FòÙ}^žá?-«~~¬<ÞÂè4û×A:ïZ”,´ŽÊNFö"»ÂaÙcü“•2Òˆüé7®`æ¤{«à”¯Ë–üÌÆ{ª¯™&ÛÓ±Ôt> §x“OÝ¢‘Ð?"ïB*œÆa,™z–bÜ좧w(JÈ0èª÷Ÿ”wÃè+4]æb>á4VŽËL9<ôÿN¦âæ!ëïhžî;ð®OÇ¢ó3CÈæÆ{I·Da\âÚá'Œq}¶5Á𯉰ÿk1`d¸±ðˆIsµDXˆDe‡BæUkEh­Þt|ô„Š$ñÙ/k¼ts÷Êq<]-‘×èй‡œ%° ᨺ³ÑËq5Â@d$¾…û€í÷€·ßœG‚PF÷ëî#Cm§¤öðq3˜Ê„\ÊßPÊôO˜LrŠëE;Œ‡”×™N;•Jiehd €8rÑ~ÝÑäÎB( Z.‘cQD¸¥4Qd芑ÜׯÄZRN½+‡öbBɱ– ͸º·jÇ'‘[Oã¾J{ÜñÍ¥*ÀƒÏš€þY&)ŽömVŒ!²qS”xwØÖØ'à…å‰/–#ޱΥ@16*†9 ï‘øº8Lº:*‰<$§Þa´`tY^ÁÕ‡ƒl>d´¥cÀdW\zlÝôD‰o`ï—$Ö±—ÿƤ¡)*—HUŒDdDÑ þ eˆÿ@’e¥Ï_!ãx‡M~ Z»òùLŒæÕ; EÖÆØô9DVÜöÊÄò>pÓÓ$,´¼Èܤý{ ŒhÎ÷ïO1ÊŒØ!‹fÁ”pâ6d«¸¼Ó¼š@¡EÇC-{¨B\‘Wb0€FÆe`YcprzQÀr@Þw‘½,ÊEâ‘Vç×åOºTîj2lŠžbœæèˆ3Q±ñ̺Ü:HÓíç—'Çg¯:äŒ<5†KÍlÅrçÌ,8×Q‚Z%©² äbô!W¿zD¡¾E¾ êÔÔós²QÐËÃyldt²ïä·ˆŽúNè^kˆ¢ÛÆ|aÙ+²%ºÚ†l™ò}| ~Šôù-x©`ô8Ì‘4Ík klâ°|}$Pq`õ¶€¼¶Ò³Ïwj9™bá #Ü| -ž;r…kn¸pìÏz-ï óö -’8°WîE³ìrô!‹ââ¶ø¢Âe€I\YLçæ"à ú²A“3"MɃ!h2£O1 7—± ˜±ÍÊw“œ©›"u‹†IpÖ-r­h1q~=T#]'4#Z™£ÂÄO÷Ãá–®bøëÀÐcÑ?­Ä ¾XprB7&õ} ‡sà'"c™")^ç›ü±¬úr,8thFò0yks´ä±ƒiÎØ\"þ–¥L=l‚„fØ‚÷R”‡s#p‚>—y²ÈšYÜe‰}P(ëj=ºì#ø¨eŽüT%s‚´À9 m¤'•õ€Ï#Ô79Ë63œxIÿÄ™­ˆ‡¯­:vâô%¾:~­òøÅØ~úŽc¦­ÔU6V’Âõ ¯¹¬ªx +F+ëìøüãY½?¢¥=8PLìö¨@='ãá0¢©ACñ¶fÞ# ëK¥¦Ôf>º¥lïU¨$€²œÑ—¤V›‘„’]>–J`¯c½qèÕùg{ÒGþoÓņâK¡#ûÂËd¡=Y4ê‹VØÓFÆ ´1v_EºÄ@@ø²Aˆ<&Ø*|‘ÝoE¶['hU×>ÐÝZ LľuFv✉oÊ8*celöƒ’؆BêÃì4òƒûrÖøí~ìò¨ñÀŒˆ*ÀÉsu?Á«YtÉ fgtûç^=,NS@c:»@T¯”/- ’¡Ì)Þ$êR.ÄâdÀŠÝ4¨*9Lmˆ±ž#ÔêÙ¬"ø.P‘O„Ÿ7)çzDž”Zpý)ä•1yŠÊß¹²²D·ME@äÅj"žvòÕb½¿žíô𜻮ÝâŒÒ‰MŸ™2{ïõnßsÿÅ>âq€¦LàbF†F#q‡ž÷BKA*êÐqÆl÷((ï‹–gü9tùú\(e)ݱMGcÄ2é¾â²*û8¦ëœÂ $Í©ã1­eÉr\”¬9£¾ˆºÇ AOþ*‚ùTƒ°€³Ç‚¯žh…§?@ðáø›J)õêKÅ’3¥¯<ëµU­T*'òßG5âM!kD}A‰È³=?DP /YòÒË—”,Ø:Öã«qvÞi¾kÖÉàHI4Îü‰;™ƒ©žÁo`ß³%‰ÕCÝimÞf†Ö7äA…ÖâŠ-f¦’ ˆtþ6Gøâf&ŽHùIOp>;½©ŒúC§î½¸IÛg 4 ö2¥¢ O¦Š¦JýG¦/7‰¾´>c€ÒÜG™Ëz÷•BsHñ˜Š:D5JÒ©1“yXc‘ Gµþ¦€1ß!]]€·fZöÅûÑtâ|îbtlá%ÿ-¨L¥ý;6Ú"2[o/Ð*»PAÈ–¢5'™ŠyŲhÙÕ<}¶î`£ëòïP?¸˜x©·¯Çñ$OČѠ÷ÐýÞ­ª!P\.9Li6õ åßâI©ÉBžR|66'‘q¦ÆT>Úî䤮1ÕÃÃ(®}îD%û¢€39k˜´BÀajO)s—Ù²¨Ž#,?p+?I²Òj¥hFÄkñ 樋ÿUr”9ât”ÉX…X•¥åSF­$¤Á¬Cƒå– 3䬑÷F¦»…sÝFÛò'oܱ¨˜Á¼JÏOoOÐ ûE†ëD Km:ñÙ&•Œ¡×ª$›Ö@ÞIƒ5NØ‘MÿÉŠkí8Å×ÈÙh@ßHNÁòõ¸Ècþ†Óˇå›#—¬$T¬†LàÝ©Ÿ ; ÞA Ý€Ü/Ò˜„‰¥…b[CŸdËð~tå+"Ÿ{sò°Jƒˆ7€©‹D½!K)Ð=•TKÙƒœÂ.gæSuÙY~™QÕ )·S•µk;„)a DÊÖ @„¯¼\Ú ±FLëóo³<½.ØJ&Ñ÷zÌßÉ^µ­¦+2Lê q#2{Q8ª"Ì+q ™« Cï4±*q«ŽpÉ"#À¹Ÿ|{7š|ú,F,#FhÜ ¯Dq?FgF1ÂÒxYŸ—eÖé2®)ËŠr9§®÷þc‰+xÂ'êc9œ8ŸÇÅKQU¥9ôªBÍwÂG‚è§1`‘Æ’ˆRKç‘ËeÍ2¤©Xq²ó Ç}(¶|CJºlËêTúYD•-xƒà樯I5ª$òK½ƒßaèú‰ëÝ¢£6ªõåäçX&:sð0˜Ùð=Fò{ø€-+܈¼ÛWÝÖáñp¬ 4nŠh•(À˜2nà ֚zX¤ ‰›¦?í‘ÂlJ†UTL¸œ·AŠv4±¥p+ÅšY“®îǶH˜Î)Åi%äÖHÓØŸÜm˜Ö¿S¾,ˆ+–òæ»81§*ŠiI‰†9ÞÅ!§C¨ùPÉà«t_:~UJ‡:9pÑ8¼¨ï Ý˸âVØ-o¯ã5w£Ar}éò”±Û“Y¨7¸UEÝ=½"WÔ‹Œù± ÆipN\™4  Ω\Bí©Ç¥ Š¿M8­•j#`Øù¡Ÿu&7~?ä+Iœò2;Í¡¾&`×3¢Š&À^à8åË òÄvQ‰¯BytžµZ_µ4ÍÿuÆ–)ðK‘ÄmÃe$ôkð×kGD‡‘}˜$ì_×ú#zN?FÓáÄ]‹D>혠cFF€•()„–äˆÈ2šɤäy@Øúk×ÒQT mù;,JÆú(˜_½&.ǯ\É ‚× ÄJÍu øßbtÃúè˜è¢Çñ^º…D¿ÑǘÐ&¼I8ÒöTp-?çgmÓ N%À ;»ƒ¹ÎœQ ûªPš€Kö…\iOËó .:LV$É·„¶Ã—éܧĮ³È$_>ÜËÿœ&êf?-=?Ñ.Âÿ¤ÐY r؈þû‰À,*õ_ugXMÔE÷”“1‚%±üÊ;»’AkGÒ'B”Ǥ–v>NàL$ÔŠ]røÁq"—".ˆJ¢ÂÊÏ-È9­QÄæÄéœÒ‹tÔ¢Hƒ³-EÑ¢é/3ŒI+2Ÿ[”bò»œ\ÊŒ¢Ög¡Ô¿;G†]‰hèØH²•Ëš¹F v¨ö™G*²ÖËym'uŸÒ¬7IYùÿþoE7ÁÏM)ž°šg}‡Ù!Ð,EÊC‹÷܆ÌÙ’þ@•‚U«ÂL65ÌÁ"íOª2$‡}Ê C.vÿ«…¿ ã %OÅN`Ú·‘¤ÁQïqÁ@}mifDá ¯õ´òÍ#…X‘#„B]l-÷Ù¬ cQò(«7 HØ7ÀDQy-™A}Úýk]Òô•IÄa`S<«e·&K“q»ð¸ñ¯µ1°».¨§pÝåÌXæ~¹6tE„(qÚ¬;ÉMP€§$ÇòÔ”‰`Ô.Áàaiò¤"ô@–EÅ£rmÓ®ŠzÒŽ^khÿË•qWЋLªp»ë¿/Ù… ®IkHS¸Ä®§Æ?ìk|¡lK´¤A"…2¦÷úF„«S9åAáÌb hõ )FÐfDŽl{i®».È5ˆì$&IuÅP´Ì‘¾Ú…©¯ðâqyö=̰~µõœ;ÂÅ:•µþä¬oT*[ë•õÍõݽÍýí²Ž?—Ä„Í*ÀqóO$âyÒH‘aL6 Æ©‡1§|%&«î¯ª rzdY“ûó úQÅà Bþ—¼Qxíîµ­_–4C|†vÒÎÐG…6Žeì³;‰ÃéšYdàd;éÖ[M`›˜«‚Ãd^'{Èew<œ6%ÿl:‡fÖ,/°±!5ÖQ;SºN9+ŒžçuYÈþàà@çdEYlVVHËÔLÜÑÙ¬‡ìÒ†×KËÑu“•„+ŹŽ=ºç¨úÒr]«³• *¥¨Ñûä«Ò%“ÜAQBÐ ó§~BJ³) Ub䊀ö5¦©™°yÑîã-|™Ø…Ü[kêQr6F-µí(?‘û4Ûg U.ͧzˆ¿æÚ»çº³]âÒP&7þ#øþl^„4Œâ‘'W /¸oáTHvFdóeÆ:¥0o“ðp”]Ùäh@5Q„\†§$æ+Öò/éTOãÍ¢|iáO˜Æ…y^Ÿúl¹~ÏKÚ¿Wb5;ÓÏ;Øb´—²e4äa°F oˆèÖ¬š\u3Œ2¹+{‰UÕ½Œ,‘°‡qX¨V*Â. I‰Ç”¥p“:vï&飰!<Ã2†aU·eŸuJŠÊ,1}ƒ¼PÂbÚøõôÚnã¿°u {¢¼ÊZjýÄt´&£‰84ä8˜½}H'5]Û Ük“Ö±š#'~e$]WÆa ±eC™–l#öœÃéb'¬±"$W Ø„”çåùÇØ uN{Iü‚R»›nrué¼;懚LùŽ_Š‚ï+ ƒÞŸJTC;::VSÇ)ƒpsiëý· òi¢ûÁA†h‰š`1Êÿ.Ÿô¤u 'Ÿ¬á(lÆP§ŽÞ&–ïyNË—é é_«þøkÎÆîLâØƒѧ LÒÓ„…å8²U+Ýô¶2^ôx{¡E£‡´Mú¿Á&M‘bÍÝIS‡JÛC=*!E[®TŠK1ƒ˜R‹ö Ýä EYú‡qܨfW,Wd,ñKþø0Mú舞sILJ¨`ÊJƒ\x==²º¥õõú(ŠÒH¥î,eŽÈ»¸vÑT<âA¦ öø.^;ÂRЇ\L5v‚RÄÆžI ŠÃÄËçùHG¦ƒË´»ÄÖƒkÒ¤¼žÁ-£ ’3˜î³UÄ3Ù)ƒîbhÈ.l¾¾:¢”\ÙE¶°(ÚÄ>Ì@wŸ­ËHUE2“’!¿çB}öü5ÜGÕ3Þ$¿;JìÝt!bi—˜Œ{Ÿ2܃£§½~<ø#ŠýQìkxõuyOó ¥š¡µx W“”MŸï¢·«ebUÙ9IÅ`Dq`g8Á^X;X} Ͼ¨²"p$>é"âídW:y(üÊ•M~Òg‰Ç¢¨@™¾DS.áü¥Ìñò–Qè‚;}¾9SF·ß$.ŠÎ?Ú,Pây]È®®êMH[{ÜÌN¹:"d–ï\vÇK/Ì¿œ¶‰o –“8¥ ËÃÅV1vEиùm|ý31ò‹h“}ùR‘(“ ÛòóRŒðŠ‘ñsVv’é¤&ŠfúÏUl"Q%Jj†/I4k„RÁ›x(Uð=¥ }‰nPu+VoCJ³ˆ×QNyvàÂp×fñâ;YD&ª™µ°Û„R¨_6_$ «ïe-B†•½ˆuÁç8çÇ|q‘’ïRî~Yu3\‰âjùsf8eódÜ U¼¯ CRžÅ§ÑÞgÇ’\q‘´Õ UÎÜÄ'oTE^„Ó£/›b:D³¡t«“Hùye-™žÕ‹QZ±XFG¨¸=Iéc£vi<çʉ,å¨ûÚ"s¼³F‹ Sº[  8Ìl¾ñã#úé¶ cB·99j£$SDežãΔÁ@Ö˜Æo_õµøO¤~‘¡“#cxÔâÅuûCdÇBwйÁÔ%Âh¥Sñ,ÈØoe-%ýô×Dx\#ær¢|}ŽxùDø"èCË©´¢E~Ü2ìE}õ¸¸ Î‹É"æ­°„ô ziž5±ô]ó¿­’,F­hæ‹*Pβ‹ èB#³äG(d‰è!dÏÏiˆ\á - ò„ÚE“Y{¢ºd%‘üš!£ˆH´ÇÊu4~Ñ¢Þ+ž/!-b}‘À¥çŸï/À‡•û¯ä£_€ù:>ì¾Ôob’¦R6î>Þ:÷ÑýGe³?&«XÜ2¬Ҕ¯ný‚Kt%5ºÂ*cù™À9è(Zoº?H)qcÇ 4OdTç4 pœ£èeø¸úöÄ&G'&Ðð §¹(ZÓ˾ژ…o¾ÙȪò ÛÔˆ ’×S­XG£y»1‡¿.¦‰*·]^ƒ{¶]]í:¤¿[ÿî õ¼ôU îÉaµª¡i‹—*ž0¸ 5JøH´Z;IµKV¤( ÛW*…H2»ÖÈ çV, /°®uÃΦª]”SÃï¹zšQ"“}‘³æ5lâײAq&àÌZ¡7¹[’;UðZ-'¹žý3ü*4J'š‰¥mÛX)~ÿU×J?r–PWÊ>ݤ“R¤¢«ÊÞóoò¦µõ ¶Å.™j'ïKø»d½L‡KŠºåbv_òyUf97ø;>¬Ÿ|¹O•Y¼G^%½ÿdV~V“™‘˜V·Ò‰~â~ia6íÖ$² î ‘΋#}ÿ–ª[Žõh ¨b9Ü8¨ètüj®©”œMÙ7®cU™Ìœ²|e—îÆ’-qÞ·¬,µë×%ré”dÎ.Cÿ¦g¬«q¦* EIûãáATPhEyQdy9λõZJH‘ëqÔîXEý†¢!×/’mÑn‚Õ4œaïJ7n}‰ûܾ$\_fyE¾,uåí).¼ÍïìÙ¾õ^`CÓ/fæ4=\¯O¨y´òôe®Æ‘GùKû怚Ü9ŽÕE„-L $ÇÀ‚>ZB>Áø˜"C-ö@wWb=‹NqLRê”G_Ý9 Ík’sB*STáDÅËõ“Àv'á nØ•ùïüàv¢ˆ#–QßDìSuË®†ÙˆË“SÿÓ%®u´ÂÛ‡ª0ÉæÚ#ãÍ­)}q™l´TÖ,–ÿ¬ DÜ1 ½q怢«•tØÈxÄ>Á.—þ!)Q¨’ø,ã¸ÑKiZÑ ptåï‹cE(2ûhNŸúêJ>è1 •h$ðÅ#D ‡Ò,€ÍQh}¤Îƒz“r^Ÿ/RÒ.ʼnþKf´]kõ÷ßWãoQÛ©è_U%“¹r¯¯Q-ˆ2p8×â¸É)_Eˆ€´Û…¯w¶¬·ÜEÓ›¦³: ¸õ°UÔtO‚þ£aV8ŠI†(Oùã°\¡¨ön0%6§lW”v²wÃÙkëPMV.¿f{Q^lˆ‚Gãü¦ÿ_œl‰ øôÝŒÊÎd¢®U] ¬Áо‹eó¤’‡ŠJ–4$†è0ˆx*4ÒŠŒOr&p’;“^YÕ‹™¯kÃñ] ¶8O­B°ÚôN·yƒA³"U'ô±‰~Ϧ£Ì~Aš[²ßc÷ÚdôÛ§wËõ{âß¡Å?µß!½[®ß6!?½_^˜åú½3áÒ»åúýu‚??âç;ü°;Q3“3©ÞÅÂNp0ÎKKN JïÏ?G-_¾Œà•#È$h4ZÇÏ^|}xuâç"‡¢†1Jö’¥’k‹údôrTmøgŒÇ²¢Á° ¿‡d:`õðàÀçF* êƒ20,6«ßÝ`%¬¼ø‰ß\9×ç ˆ–Tþzm͈ˆÓ¨‡#܉¾Vð\zÚùfÂŒBµÖµRf{Øc¶Õ´8¿g!W5A• ª>¿Aá”bLE<úy51Xܽ]?mÿR'V/òš =Dæ|Í$ÒJãq¸ °ª\U'µE¹ÝïB €¤<Α£²È6N–4¼PûVϹ¡ƒÑóÇ ªÑ„a(JYMâEt·¸œ!*¨ãTˆ!x}B)çÚôàsLò‘þö¼uR;;®w»’îðŒ†ßéüFÇå ¯™$€ÙO&÷x†Ö­ô\¨ÆÂŽ€DýÚ «%Ëø½Û(Ûƒ&ø¼Ší±×Øëñ4ÖcÐÓàúð>D€ðJ‚°äþdLí…e¥`ª{zþ¶yÒȘøúk˜»Eiæäp„FɃ®®‰/l™)¿¤³R»Æj7‰V¶V=WéÌ™`½3_/£8Ä'Æð“#^‚/tñ+Ï/ÐÇ^“Fɧ5¢:‚\¿…4‡ÉkÅ(X±TÞÁ¯78w'g‘¡Jilw™²]šV'œúôEb}gošØöÄÀ3–M,i[ñµu5˜˜‡ü¾‰õÇóÖ;ì»Þ<Áƒ>ÔZ*QK6Æ ;È žBTéwÇÍ–…¯Êᤋ…n£“öE JAœ %¹PN Ï@ð|jÁ™½ K³= tç19ßD²$Èæhjú(hÔAàyªYt®â8=[Ü Cz¯\)ËRVèè{{Òèž¶ëݵÖYóì}[Ô‡ÞÚßßA¾¬õ ìZÀ¨#9P›¾/T€l[› W’¶b/¾L^ZrúÎS!…õÁ‚ÞµAúóø\üÕ¢‹³%ë#VAÀ?¨"‘àXÌÉ‚Fø‚o¡ErÛJò,­XŒd[$ ü”±)—IÛ¬ÑÏ6›¦z7:M ë›hÏ{ú¡&¹óô'Ìj´fùC¦4dA3¦©i½–K3Ô’€2Äj!#†À‰AQ’Ÿi»VL’ €ÙQêÜT¯}ê¿R[ÈDqE&ÁÇz{ªyU€gÔ2Jˆ5 YJè8â˜ZÉLÈÚC?I¦>C‡3Ý P™¢AI4бÝ0雨xÀTOdÞ˜Œ®Äi pe1Á›[:AàMG&§uè­x“\*½¯÷Τá}2HÅv³àxr{þßÿY»3åE«£Ò_s¹eH1^zóÐoóÉ |nݪ‹nåXÝ\–£)"L"ñ«©ÇÞd‘Gç•ôo•ã…d¸ˆyd°äĸgêÁd¶»{Ï÷‹<½Fìbzwä!¼ìÑHÝfê ÐÅe`#æ-äKlÜ›3OîEÙgÝo”Ÿ(h¯¬ªÄ‰”|¡E´ðjò߀WPˆ¯ ü!0§ QøVÄ"w…ŸÿSù>yõ{åUÑúj~áM¯ÚnöUcŸu8ž_t Å•Y¦©Åx®êÀ²NWX½»LŠ»}åè-Ö ‹ü¤E6eåéQÎG=ÎDT0ŒÈŒ£Ô¥À3Bß“¾F ’‰bh¤¦}å` E”¹8u’8Ò¯ˆW°MÔѶœ-œr°@L÷æ;ë(‰¬*Ù"\µBo ä2ˆ;–!&”ä²wñ“ˆóˆ(*áG®TYkŒ«Q²T¶,éæ_ éªqü úÑEª„+qAžœ´#{LÆžlûì¢Õ<ë¼ëŠ@q…ÓÃ*@—0%r«ÅÕJ¢Ù½×ùÄTÏ]#\Ü mP— o ?U„·EH¸E™F¤>"eã@Š$Zý¥Ñ²Ž~¶ª[•JFù8E¦´ •Ê6aV÷SääUC°&áU((À)1p–ìJÁ!Žœùâf¢†èØ×f›n÷—Z·Ö‚}†¾G“ɉ©cÛKfâ—ÀékJùpŠðÄ'äÓ\…cZF 1qÌ}:‰gÏ6ú&Ý!}¨}gøžGögw4ɸ [sÀЭÊwEûZÞ›ˆ¨‚b1З‹0†îB­µF¹8„ï9”æW¥ƒà†Éo<–9¿¢+™û€t8¼†ÈEˆµ;'”¸@º¨ÉÊ™$«Ìac,¦³ô¬SzZ³O'à©ìdºÄ-3•Wø4Ц{{jÖ~r¬ù¿ Ãoôú¨P-â­üÂÞk¤9PˆÞ­5«Zá*„råkd|èŸè~ Å„sôµÃé~sHu¨D¥y·÷)Ï/½ô¡5]dVñ‹F@ޏÁÏËÞ&Wéÿ0|$¶áÕ›­£ƒƒK]¼uCéä\S)Þ ±¯ ÿ"7äÈî;W +´µByû°¢®ñ‰rv6e PWÒiµa ¢¼<Þ”TK†÷ý9KiJÉ\rS•©CIe^2Üs0ôm4n¯‘_[îVàJ!²;î+`ý"W„ÊpÁÙÐBÔ˜s.²uØÆÔªx÷]‰Jºñ!§?ga…*)Š,Áp˜âw»ß ® ¦ŒÑqÔ©Þ ã›Ptñí¦-a"Í žCQÖšHYkjPÀÙSŒë‰âœÜ‹ÌÅ<°Îʉœ®äGþr¨X‘^B{ètKŸGð@ ø zC©‡»"¢ÇҬ׽žâÈœ²@–¥¦ôhëð·Ç¥"oS»M¼KZ4Ú4çÆÜÜ(Ñ¿;[l¬t&=Q`)B²<ª¢,`çÆÐÞ\ íJõD@Hfš›|©EDŸE¾ü¸?¥«èãËE\þ2«Ä@T†ië<‰¾`UMÆûæÆaö7´g/g}µõ´³5ãÕÓ̯ð£0ñ¦Ç%ÜŵFq€ KÆtkÞËi±>hFx ¢@1Léú ç~Gio@ùLÙ«Fa‚Ø”¹Ÿ¤ØÃëðî¤ö>Œ…Yw±ðÏv÷½Ý/Ȧ­ejgiÃ\¶ÝógôBèdXúg*,m̬žÓ éO•:ën»ö Ÿ¥†‘S ò;@eÛ!B7¯LJëØN‡§Ávµ@W O&Üø*duE¬Iöõ»vmDï1u*´RÆI†Õíùãè¾ìD× l¡ä©!+-Â?BUtÉN!øá÷RIÅ(ø­m1}$ “¹†Z©ùÐqœ‚YèN :cÅvE”ÁÀ¢£ãCÓ¶Sã×úÉe»ùKïàü½Ûjü×e³Õ8N x¹$L|NQ›cý£Ì dÃÁAâÊ…¯S¯Dٕ͵+7=‡2õoÏ`Äú`:ÕCYî PIÒ§o½æQ½¬ %ŽÓÊ\Åzñ%»”¬»¯·!5ã09ªìüø½(d½âõ^"(ÌÖ¦ràét§ŠvMâ( 6f¨rú!!©®¡æ]r=Áʶá|Æ÷œûÍ t Ýë–†ò m/Â&º°Žžâ}§kç%ºVºà1ÇÌrú^ä…P¡û´*6mÚuú`]Ð2‰¥ˆô´cŽ…õ€SØéÕ˯]Ì ¥«ˆ#õ[øÏ;è–8xܲ‹ß•˜yè[æP¿†À[›þ;§þÒì(ä]ÏéÄðÑ]%,_’ý$^•v©ãŒ¶VWþê4Zgµñóâ¼Õé~èÆì Ä]þŠ”˜UIè^•oŽŒ‡÷ẳÏïlw{<õ\膦ˆ‡<¤ÆœÂVo\`‰¶v .¯|¤,"/ÔKüiõˆô?ó¯ŽùÌõAørÇú#6,èO@ 7úq&Énõ'Ÿ¨þá»ýñ}@ÉÔÐzT’ÔÛôzÄj LÒkÊ„†U  åô1°{Åõ}qS‹´pœ1ƒž\¹ž¸‰8BÝU:?Y¢)Öï«"%²®Œ±ÀÎM<ÂèÛ’Bªš¥HžœYŸ*SOÎ$*ÞjY¯c’#—ç!°ðÅ<Žtó{ÓÈÖU:’¨{Àá†a„x™è„lVڴɉšð²0‚¥À½“ÃÄîÎB#]$]êÃS,怠Œü 9iúXxQl–K­ÈÚ_¡?˜Ü!ñÈüã2_€0Žâ1:ÞL´†ndcé|h¶­öù»ÎG?,øû¢uþK}ëíoð²aá-áVóý‡Žõáüä¸Ñj[µ³cxzÖi5ß^vÎ[mº°XkCãUzW;û ëK´í¶uÞ²š§'MèhÕÎ:ÍF84±¿æÙû’}€†ÚÁNNš§Í|Ù9/ÑÐÉ–Öù;ë´Ñª€Ÿµ·Í“fç7ò]³s†Ã½;oñ-ã‹Z«Ó¬_‚Pe]\¶.ÎÛ çwÜlƒ Õ6Û",^³4ip ö’掋°Ñr½3ɹD«k5ßYµã_š¿øè¡ÝäCè«ØW¥¥§°‚ú¼ÿ¼¦ÝŒ•]­Âƒxxæ•¶WÔjˆFðŽ(øô‹¢=ß*h"QÔ¶-V)A# ÚÀú"³$ò !б U‚»„Ñ8°Ž§tyhx±51Yw ]=MdbÅNH(æ€])µÄ³}<†Âtk)/_ÜÓAEnâá=0¯à–CÐVBƺ¢†­ôú6RÌ¡MÄ[C*³Ö¬ãsœ®#­0þAäù¾U;5ŒÖtrPø5¦§Hsx(S¨’Yµï¢Ítx_’I]Ã)ÝÉÚò÷ ëc³óáœ7ì#%è¸qÑ`’ovøúvO÷ÙiþIGß‘N vüßSØW@[(Ò™ŠçœS„’Yt‡4TbA@(Á죎Mõ\àäsÄú›7òàµ]Ì‚õmlj´‡¨ ßÕ嬹¨®ÝÝÜ G²ö È):xÛéXñ²D†ùC=<[ÖBû#J:ªSºð~ñ`RŽBÑSEµ~îǨK-#«–­ßü©)B­U>ÜÂhN^9_ÑUÇ8ºr(Þ!pD2cºfª¯:Ëܵh´A®~ϺÆÔ·®Èü„ƒª™DÃqr[xK¢‘ô˜°¹%{!è2ŸpÔ¥t•8ŸmÜÉQI)µ6²Ëï‹úOðú˪”ý*(©õ†xKÊRåx(©z?ä÷´V«ØjcU ‡©4¨ z_y«\¨”Šñ ØBÞ}ò º½éÐíTÈD”GUTdç~D‚9Ê™/î­+Âá€JáO)‹•Oþ$·„…B²—íEtBÁ%tûDÞÑÄ›âj9PDE6ºÂxfR ²‹¶@é+i)ñ¶1Ù.nÈìt'$‘¾_Wצ¢ú ì ^ÝàÚO˜¢‹Ë¿&´ c«o:WSjqÊù#žU®£Õ !·ŒÕ<·H͂Šq´k7,¡2 §áMq±"TÜ ÞÀ8 u ‘Ž Î—Váõ[àŒ>oú§8H±`|õ¸ª""”ÃÄd¨â8ÿb¯'jEÅ $£ð3G„!gh4 x*dÑt±€ŒŸãF€Æå÷΄­#!¾²B<Ql«¾&[=³… Ÿ²ÓÌ΀ˆî †¥@ÜýfÐÚ¼F*‹`Aè+¶¢$ò²NŠÌY0ß€à–•~)×’iH'‡¥Ž-ûAÌPpvÙ‚ê,:3ô ÎG|݃|¥¹JKüô:ʼ/=eÆ,1œ™( ûèóÒ N (ÅÁ_è1µ5úvŸg€^t™wÞ Ô ,ÙX~M:¼ ŠÈ8°){•‹0m”E7²7û^aÄÑ•?¤ÜRÓ±Lévf'ÿ»ïxîµxQ´Bû>’ ²@úä†.V45ÆÖÀú-ƒ+»Q¯#ÆÉJ¶z–,³Äž4–Å{ŠfýTSnÀx9/ŽŽ¥Á.e®U@†æk‘¢3¬š\ó(‹éÌU)ê¨É'{°)[)JÉ#™ŒâÐà|®áØF Ê&›ä,ë#Û)(zŽLQ¢¤Rre€ ÿyäÆ?" I XöÌ &"²s£ ;”}be¹Æ>6`ýѶ:4øl­¬½ßæó¶¸Œ?èè`˜ìE›T(L–áúS $d ±Ž;Pr‚&(/ÌQZdŸŒš•™£\¹å4¨¦„ 9  ÇBGèkmFU²Bι­þ9UÁ/Sˆá?@,Gɽ.èj®SzQ¬®šY„&¦[*²\¹¡»`PM&‰°Â½H¡IÑ“$&ÂQÑ¿sœuÙ¿¡­a×Ș•ÕJ8.8%%êP&£I ™«B$Ù¡ú=!¥âbç‘EÎÏ0º«Jê±=¼#^ˆÒMJTð5éj¹3£#¢œ_J4¥H˜ñT"ñçxÊS¹1$ "½!ßÎŒ$z9Ôª §™I3¿”Vb%”Ò…CŠ”t!Bøhï³L(pç¡í´/Õ—P7CH몰\FûA…dZèØ,qé´o^ßpÝE¿/kúÒUa;ŒH_Ï#ÿ kÜû›•»ä*Ææ-Eä-é¨?´”}80!ÉËiga::‘´nET‘bbÓÄR“J’"².cäæÍH<¨®WãwÂ@b¥—`ꬓ³S,™Ì²fÆÉtŠfÁB—b-¯¬ÿ°V±ÛUZW©ëUC*æÛæ“;_—*èHÖÙÑI]^(й«ˆþ ¥„pÙy·¶‹ÒóûBžž!©‰| ¯©ÿn½û\j“ôcޝvç¸û-™gï•Ô©þBÍù)‰^M%Ò”(Ó§9Ie<¡’¨*ÃG\äòV§[Üx1sþB}¸ã‘_Zw<§i =õ™Å&ýþäümí䇚w®)ÇæÅv§Ùc¤é%&]`V®P¼°§ç‰•š˜Gï§Zg÷± ‹£ãE$7^þ¦Õ߯¬êgñ²–R#o…¥)«|êæg茼q)Ô›/SŠÜ fbµºÌÌ“žFM•ÐËŸH-JÞ¦²þPµ!‰/L2©‰s!W:5¦IŽEÕäE/vÌÈXj(½‘®%íZûz½¤e¥”L÷ ¥ƒ/›…–¿,6 •>åéÖa‰â »Ðh7K/ ‡µ°OË~Ô HÂ+â"D^-D– œ/-}t^Á¡iXæ3¯ÌSˆP©årN³ú¡IèP'”;PëQ³ær”Ê…ST‰&å½C]ÆÖªµ©’1cþÆkô‘˜QU僟cö´¨\U¤˜iækÝò­çâQæA}]coB7][}BÂ+Ó$÷Ew7(×"ÔC[¶X!*¨È3·€¹Ž+Ýö”Þ—WéBi¤«Þx:½Òm.Ù#ù^å-E‡)5æ‘-¨¦Ä‰É^?RÜIæQ’•NÏ‚(èøjsFè1sZ(Ó«0>ÊkðèR ߨsèÎsèÎsèÎsèÎsèÎsèNZèN8'vŽU äýçõÈv‡üAÛà´gç±c{DÉZä&|P õ…œ«*¡p"ðY‰ÕWïc÷+ÙÄá7"¤…RŸRh»â ÌoËü©ªoNêú|”¾5òt¡’5 ø)#R(Øæ ±¯K€×9Ê]þ,߯mNt€U}0ÿÆîE¾ÌXšX4+îóbj2áP‰Ä}lî§ d€ J%÷uÓ%&žÓj¤Š·S‹¯”õxè‘3Š¢ªWæD9ËåôX™LVPÒYï  eL(£,2kK3Œ¼Ù–. :‹ßûlsâ6J*7~?”nï¡OÅ­ÊÚ'2II[^‰Œ}=a|`1!V¾<çŽ)Y °tš0‹àv3ñ¥¡£4½æw´¢ÕüŸ@—ze„×·4ùšÄyQ®žÅtWÔ*Ç7 ¯‘1WÀ9WX‘$E±Ž2OŒ˜«¬~nÌwD/¹(¶‘ëœÿ„ƺ!„‹)ICd2Ó«…)9TÍWµ³vó•´‚“$ßon`‘f,yB·òÙn/JÆé^<ë ø;úœh¾aä]fˆîñ ‹o½ºô\ä1¯Jdñ«î”%ÉPÙ9¤~nX#'ìZJA0òê…HI»S­ü¦’”tJÒ@ŒÓ‘pî bJ¡#£5~"«gG&Qš&"kŒzs¡~Ñ­Õ/ŠÊ£²m«mª¬.ÒqI-“ËŠHPRµ@»*Õ‘àÉEÍŸV °Ôñ/'ƒêN:õ™ g¬K|É T}Ã%3Hgá%ã±óø¾–M_"Z´Ž+XË9Åg]Ýô­‚”0ÁJ!w¾bÒ¡Î5´Y ÈûX^Ôy„ MbêÒ#Ó)ž…£1Fë.²œòe:ƾL|U1®1ÞÈùƒxF€ÃÝŠù’uæžÝFƒ’\K=ŽDÏO¥¡œY‚É6þ9]Ñ öáMhÞù nB-ÂLYŽR¼UíT‡á§’3UÅB3¬HÍ…¼a–4ËïQm_ÀÃ4P[ˆ­yž tŠc“Ó–Ô6bqUs’°5¼6¡ÿî#44Ï¢ çX’¦ Üä$,å&È ®»^øÃP—†:ƒÂ5"SÏL:KÛ¡%˽ö|V0Z^¹‹Ev­HºneEï½qm¼òb 6Ì©3{Ïr@¤;$Ò¶|&a?Éz ýõ0&–kQpW½= SÒ¼7B’a4’J°f…C4‚6Ë/E'ç(+ˆ”/4[Ö,8P°™·…hÝ“ka÷z~ oŸÔ»õÎo éLN^T.ã(ïÏ.0É‘"´s7y´PÌ¿FIFœç²;Õ¢t¢ žÚ½ó¶õ+†·‹ÄHþIˆt†Ðç7Y} ö˜`ÆÞÈÅ…Ù"Ñ6IeZiÄ/¤AATFÕŒ¯¦ƒû9ÚJRÄýTóîÓ ™í«"Ÿ¿ çžâHiÀ˜æCŽ,©ÍóÑξ—|M>í9õ¯¦ûŽ²Ù‘ìzÒу±bÿ¿ÊF5ã`åFMo‹3¹Ù(¨–"O(7f_&~¾Þ¹þ:{¸ÎgQ+Þ#¥“ÀÏéí-|Z0Ë‘D½j ”ˆyè¡ú=-­!_ø#¶EpC2l¨8 Á/åFÓ½¢¯BN‘ İ¢ Œ„Ó,G†^û0‘6€ýfÊg–â¯}¥5~òT‘A+îÛ{vˆ=;Äžbϱg‡Ø³CŒî²ßâî.ö½îóú;>´Zö}1%›'ºe0]ä8˜ëá’u_ŸÒ±¥‘tLsÌç˜:öÅ…NöÂÄ/»[!ÌkïZÈ3…)ð¨(ãb¾)½Ù‚Ž ,úrë´†)lIšBQ’f Á×áQ«ÀÕ$ήbع¾/h#+¤­r†U©0­)ÞKÆ%W³ ®÷;QwW~À/Cq3à†Â5JÀ‡‡~“ÓcA#ñýçѳg§|A»Ay…ø:3‘.(2/Ëœ€dwÌáI2¬T²¢Ôé\Zݦ-ô‹Ã¬V­µ5$ÓÁtH#ºÛ6°Ô>‹OšEA1n/®³ÐVc±É!Twr1ã}·€oû‚ì Kœ¥¢ú4PäP|iâ6rPfj8TÉY&†Â –c·w}EÅülÃ3¬qBçÒsÿ9}Œ]ÿû?ïöNµ'ÓŽ†u^¥Ý*Šì5Ðþ;ëÈqøƒèÈi„ãŸè†ïüOD5`m›+™yÊÈÇÔ2îÄH«œ±œ,8ß Ê‚"#¯<6ŽÉ+× 1wÑ¿æSAãñµä-‚SV6ÆGmÙ\¿ýe2´HIÛª)ÜrQàHk&}sD²Ò*â}}â¯#e®Ë ѱì„(°h"0j+Úà©„V TÆ@(¬þïv¤ÝåÏɱ’X5 çñ~‰Eš]âžIRÞ×—G…r3¨nQàœµˆ¯~%/%›ê@Rʵþ*eã(‹-~"·t”ü8¶^ú:JN±ä *öQŒÎOù¡<;›1Â*V‰ä·uñ£”œʸ„1íPÖ^ÿþ{D,‘•™¾ÈO$Ãßø4,qN1Zêu{–Z'žLºyÊeÖðºÔöDÝoÍ\[š¨:w¡é€C]Òù-tC¶/¬6~m¬fîUÙX,= Ž¢‡žÑ‘ØkÎÏÜk-rœŒE¦Ÿ &eÀšÜ˜ž'ôY< “âFìÀÑò#íºƒˆµè]‚Å¡šß°'mESrè˜)7Éêèç¤e 1uÈ%,kSʾ 0©\·D  @³tC"rYm%rÆ(¶¨ÎTÆÙqdËÑ1„5ÞRñã<‹#X b™2aüFÞrÓ˜aXO8äJ±‚´Î¨…”¥òGÂ2:1=ºÐ¹j"è~UqSŇD­7½¸¼Ûw>†Šgíy‰¡h±°¸WDºhë–&ÉöÖØf#uU™Ù‹yž©C߀Xe¯$¼K˜ÌEu)VJ‚ŠÃŸj– z;f%ŽG0Ûé–&µ&®ÇÆ_pd…­(ÐÀN0e6š¸¥Íµ¸˜ö&œ@*ÊX˜º©":fT\¾¬ÅŒý(›OÎØ˜Â,[&¹á}|îT;š¿^ ãïOt  òèBi×÷Ä1¿B_úo­>:äÊŘ|ø €èj‚?œNøœÔæYÏ…M/™¡@–ìá2™£épâÂ9F[¢“F-°ZwŒÂj/Ê*æA&È,Y«Wv°¾Ž*m`ô Ÿ”­c©<:˜v/5ðbKɰç˜íõ\™;lDN]ÒR µÔûä?áöZ-³T.YjÑ·ü¼’…£B£dl&ÑyRà‰å ™Gƒœå¨‹ÀšŒ'!¾¦P~þZèŠäÒ @øLªGV×H”^ =“ žÆŠò9ážH*1Ê*È”œX³PiPm«jî Gj{ ´#Ʀ¾À. wL%ÀÅÝ(«g)š:” £µiê‘Е#Bá‚h£KTª4Ë44[u UÄßHÎwCæn!„­¯±­rox‰ŸVGB‘«¨I“ú@6`©V«ªËFøá=º$‚¢¤ª³UBª¨'µ[L¬ñJ[ÚR˜5R„>9ÖæÈäµ`t¡ø!rê²O˜z4c†)k’; Iz£{J‰áïôm¤‰çz|Ÿ¤÷ HŒ!yÍ&q‰t"‰HÒÃê¶Ô¤´ÿýUI 9ƒˆ§ûøý÷õß×™ ÷ǯˆµ(£½áHØó¢LsË’:㾧İþ€]On?ë%µà²a×è\ŒJ8u$^Tg(ã£êX¤¿Sì':ÿäe ÏCpg S\¼Ø3–Ò9yd&ôH+ÍGa„ˆÉI=}\•îŒ5\Í8Ã÷³F«†ñ "ç9 ð@FÑŒ§£qôö9cö…5ôž—oÊø†üΜ§qÜì``ʇÚÙñO?ý”¬F²—ÀÕâ®Ös×s×s×s×s×s1.F"J#8Q°–ÌÞFF¾'LÖÎL Ï'<ŽaÃ^þ'À£+”Êe„•”ÞEv½Õ¼è`F×”ãL^WnÇ»¨ô<*L>pÌíŠÈ¿LZ2Q6MDïe©m@†NÔ?ÏzÏ7 ¨ÊÅàHr¼ÏøÃO2‡ƒÀé5èRã0+röËêÏèÊ[,9^åè^vš' Æ€íhEUš‚÷g—õn—Lξ/cÈ)Ũ|–—öC¾<;¡[%Tÿ@òà©,K8t¯@ÔêýíoVA˜D@uf¯æçÏö•[¦ë/hžž^¤œz>Èú¯¿Â¶¡iYQ¶ÙkËÒ<É¥ Ý®]¯Ïmø¾Ûw@nBZæVÉ´Á‹‡{ïLp' uýMçHs\ØÖÍF]CՎ̇ò¤£ãŒ·ôX˜ÿeo4!Qê@{ÅgMS.â íLè#êd•îhõp%}ÿ1a}‰g„EuÜÅŸØÚóîíÂ彿GÒmüóM§ rÔ†¨í`ɼ˸¡«SåL¤t¨»Á‚ÿ—UÁOO­®²„®QÄ„J³ÏB+e'Ëörç‹ÃûwþI%eRw@ýØÀ}ˆe=Ä\x*‡+™{6ñí7:T+^UH!ë'þPÉkÖ”5xoÈé‘‚À…GE¤©4RÉûŸ$Á“f¼%¼vHP§7ÙŸ0`€ò@»£)}B7$û ‘ËFÔ§qó7°áJô7þ‰§@£G|D;“^QZÔ1Žð0QþqÊË \e‰•3<­ÿ3îºÑÀ¹CòŠoE>`üSH+'t’2ÃJ=amÈ®¦xa!šÌ™ ¾’U.—á³#£ ‘}°–u&¨¥`4$=+rêÅxh2T¡$åÁ½„^:=x‚hGJ”%¦°Ù >`Þn¹º7ŤDóH6êØîP}8¡¼Ç;8IìrЂš–Z3Z…;ìièx×0{˜3LySäeFgVÖf92º­t{çu¨?âÁqDü l@jº‘k€êh ’cýǦ9äf®!7Þ`'Ðvùaõ[& [¹`Ø0”°ý#Á¡ÿØ6ÚÎÔ–T ûx À8ô,z°cBº“ Òí¤%ìç«@«¿Ý5AßÍúN è%ìë냯ÿØ3ç²—k.»s)aßx>ú}srû¹&·7cr%ìó{š þ£Z‰qúJ®ùîÏ™o‰zþ~'ï¥?ðòxÕJ<”¨ÿ ÆûØQ]ÍyVWs£¦Dƒü¸ø1~ŤŒj>1£º±¶J4ÒŸeƯ˜ˆTÍ'#U7—@`‰†ûsbÑø“ðªùD¼êÖ²8•Wpä¿z=ÅÕj>Iµº½4Â#(,þ¯‰uã}Lâ®æ¹«;µ%‚áy!ªDÕ˜òPͧ=TwuYJÈóÚÄׯøÓ„ªùT¡êÞã¯T‰ y^®ÙËeÌ?¦×mäÓëªûO´x%éyYÁxO1%u#Ÿ’ºQyÊ5-\Ï û°…5ÞÇmãùîê“/s‰€{^ëÇ\kãWÌx°‘ÓG±ñÿgï_·ÚH–Fð?OQMϱ%,dtáŽùƸÍl > ·¿=Ý=Z…T@ [%ùz{¯y‡yÃy’‰K^ë¢ WÙkµ‘J•‘™‘‘qËȈ‡YùÐ-ÿý-¿õ-ᩎç©ÖJ4LGEÖ·„S§:žS§Zhú(ÑX‘<‘¤ %\SÕñ\SÕÅG!› ØÑδЎõ{ÂÁVÏÁV]zpû X¿'Ójã¦Õ–žÞ®(ÑlÝÖp[cÜ­a}K ÖÆ;¬-?ÑR¢)»ÝâvËÍv‹õ-qÈYï³¶ò”÷N‰æí6Û@w±,jHÕÖÇ;ª­­>ùíT¢É»=åöÔÝï©$¤zâÀ¹>Þs}áyì²aÀm5·Õb«Y¿'ŽÍëã›×+Ïhã• n÷¹Ý÷ð»Ïú–8ü¯wø_¯>·½¨ÀÔ]Ѐۖ¿-­oÉìžã2ÔkÏn“fÔNun§NÛNµ¾%‚2êcfÀ­?÷}["ܸÍë6ï4oÞ¤D€I}¼“úâ‹ØÎ%BÛÓnO?­=mýž–©,S_z9;¼DXrÛÜmó§¼Í­o‰ÀŸúx?õå¶éK„*·óÝÎ>;ßú–bªÄT_y‰| DørÌÀ1ƒçÊ ,¢Ld-ŽU_}±¬¡DH3øÃÌO*™.ÀJEå¾¢$ê•åù"¯ükŠÂŽƒ8èQ1B,È}årySÕ ¤ÂÐTÑÑ Ó6!œcãV4èrz®Y‡å©n! cï|Ð:C0‡XkOôWòŽ}UÊ8ö΢^JæÂDbÿ4 Z¸Tu¯GE*}®ŽNe&{^ÐëE½ Këb¡W*œ×ÅÂæ\YKí~ëLÕ-¤©ˆzT°‹%MÃ>L•x,PõóÀïÆF!Frv:žqø=€ú±D•å¿T§?nÊârð„ \”u¥=/Ž:Yä–ðz~ŒµŠ±å1ÖÄbŠ¢È Õ.„ô"˜`¯1rp=Å"+JeµE.$(ªæ6*²“é÷`–G´Ö0£`£l®ˆ«soœûßž‰Z4.çÈeT©ðe €‹©µ±úäñ5Mã5nëײ £. H]«…Ë.Ì[ñީᬭ1Î ~œþ5ÉG‡¶¯l¿8´ýÒÈöËCÛ¯Œl¿:´}ea$€Êp VF£°2‡•ÑH¬ Çbe4+ÃñXÈÊpLVGc²:‚Gc²:“Õј¬Çdu4&«Ã1YÉêpLÖFc²6“µ1¶õpLÖFc²6“µÑ˜¬ Çdm4&kÃ1YÉúpLÖGc²>‚CŽÆd}8&ë£1YŽÉúhLÖ‡cr1I[%µRý¢PWU9ãñuQ¥|šé uQ•FÐÔHo¨‹*åÓÔHÇÑEum-¦mn$ñ?áwšƒá`8lP áI z?ŽQ'œø—öƒá`ÜËn¬ÀÛ±#-%;c{¢zá–ÀÁp0Æ…1tKVŦšh[Zæ[ÎEÀ­ƒƒá`L,&kÆ&ºù¾´<C6)Úén1 c䯬'6ÎmNË7b§¢GÍ­ ƒávgÚÿœ±Yîc‡¦B‡ÆØ²èwKë`8'P¼”³Ad«ZQ~cî[<¼rëë`¼@ïÐòMñðûÕŠš`óâɳ#ã™»VFl‚GÞ°Vý„»ãFe8ÏlÇ®ŽAøÓ´kíÚìaŠýrã`ZÇ<¦¥Pæ”°ªÐèöòÓó.=^)%UEÉÅZNiÝÝib.TlËíìé÷–.OMq6ÇVžB9ï©c2XÑÏq…)ä,+ÓUöѱ—§À^¬o«SÉltA{Ç-×»:……e›yzlÆ.¿=½L‡j;®ñÀU·¦¶|µc5OÕ¤ ÚWžó¡¢éŽ{Ü›—·V™VŽS"ulçÙ±ë÷ê“aB0VljîÐgS«N5ç¡wìç¹³ë[íi1#°ã@·á@µéç@´ÊŽ ½,6d}«?A¦£vœiNT"œˆ–Ö±£—ÌŽ¬o‹O•9ÁÐ:->%nDkéX’cI’%¥ -=i&ãwœIr¦¥'Ç™h{rì)Ÿ=Y¿/?}f“x¹çiËO“CѪ96åØÔ¸lÊú¶òL˜Ìäåx¿Wž0§¢¥rìʱ«›±+ëÛêsb^0ç˱VŸ:Ç¢õql˱­»`[5,<;&sz6ç{õ…gÁ¹˜º‹wLì˜XR½ò<ÙLìIúßë•çÁÇ4­yDdŽ™9föÌÌú½úŒYÌîIxëëÕgÉÏhSsLíᙚõ­öÜYLq:ùZíùò5ºcn޹=6s³¾Õ_«ÃyNÅI@½þÌù¡Ú19Ç䦋ÉYß_ ËÃÉ>ιÁâKàs„_Çì³›ff—‚´ôÙ̺t¯ç K/†ß•ˆ„ÓsLïI1=ë÷å—ÊaêwË÷–_ß# :æç˜ßSf~Ö·•Í aþ·ã+/ÿÚtLðù0AëÛªc‰€„ÉøàêK僄+ƒÎ Å~+P8ÄÍüêÖÂnàýÖØ9j4;Ÿ¿ìm5vš^óÜôZ?ŽgfÞ¾õg~g6:A«õf=I¡â§£ ³Ñ€›^{ƒ8h{ý›÷‚‹^]x~-yWgaëÌ;Ä}ï8ð|îHwpöÏÅê }ŠÕ…û¤A r„ø| 1D5+6à†ÞÖjåÞ)”ø™¾@2Íz;Ã]½iìHõah—‚O;fÎz˜á™¯ÞÐ3_­= USHµ#mGÚCH;DÆiEõ†§ÕúCÓ<]#p„ïÿ&„ŸõvÆéMõ†§7ÕÅGÙ t©Æm ·%îlKd=Ì8ͪÞð4«ºôxû„.é¹Íâ6Ëýn–<'|ÕžðU—yé{œîdÐm¨ÇÚPYogœ{VoxîY]yì]F“T[Í—º­6U[-‹¦2Nƒk7< ®®NÙþ£DnºM8õ›0D-㜼vÃsòÚÂ4îNJ#ⶨۢOw‹f½=P»aô@­2µû–Òÿ¸Íë6ï3Û¼Y³ÒqÜ0¦¢VîM ½Ü¶vÛú%lë<Ñ&µ›¦±©=ýN üܦw›þEoú¬·3bpj7ŒÁ©ÕŸ ' TžŽ8vàØA’d=̈LªÝ02©¶ø¤x¥ûuŒÂ1 Ç(Æby 2b¶j7ŒÙª-==B Ãqlı‘Û±‘¬·3"Ùj7Œd«-?QÞBŃq Æ1˜{`0Y3"ûj7Œì«­¼ê…ÀÕ÷7Êåò¦×†÷ZýÎu ùðâ™p¢A§mB9G­h€àf'èžöÏÊž†ÆÀÂØ;´ÎTàÇaÐSý–¼ãAß; ºA_÷΢^/<îÞyÇþ)<¹: º:0>ÂhEça ½^Ô+áðN[-/ìÆaܽ¨ë]ôÂn?ìžz@üÖ™'ÅM§w:8ºý’\ððÄ ûÞM0œøƒNß»ô;ƒÀ+ôÏpðßIu ŸM„tv:žqø=…ýFÉÛºACýTˆÏ€š“š a'Ëð¿ z^uýæÆŒèóã°ËËwÄ}ïÂïõ½è„ô¯"I/‚Ùñc Y¬Zb™7PjÓˆû›€ÂnÛû-ŠN;ø @¦‰õ{0m‰4"„A(&˜Q?èuýNçß:÷¿<#µ’¤[ׇåEÁ1‹ÄXab×4׸»_Cãóc˜Ï!¨îÕŠ–‡ª&Þ;‰þ´Á [‰™ô ìv ^¤Ílš]Ðë5LßÉX@$u‡óÇ]½ Y®c­`–,ÎYUd`n!iI«b n±¬Y Ä¥FYåé^ å¬qÍÀý¯sž¦3býQWqKö ‹_O þ KÃ(PuËyGr(b1ëHY¾¥1)MG&÷D&K9(Ÿ2RÉs?N@Bh-;2º1¤úY‚ï'BCY®ë é ½0Ž¨îŒ¨VF û VV¨Ç ˆ ]~ŽÒnOi«c`ú™Q[n`Ñ É<ÏŽoA„•±]ü/…3cÜnCŸt2â¨óFÔY™Í/šD3cnM·t¢ç¨v2ª­NŽdGºcGß MSH£#ì1)ºv«€š#îÛ…Çß!Å« ^GïÃè½~ûÀGô÷p'ä>vÅ'½ðí·ï(Ìm†‡¼ uo»„¢øÜ±÷ÈÒ]Iºòè7 ïw÷P ¬Û;bï,ßy€±Û@Óy÷vE–¿œ­•·§Vî'hßm¬'vÇý¡vÝåxÁûmõ/ɸM÷K<èN¤[U/pVïý²šÛŒÏ6ËËÃïPº÷ø¢ögåA.“ºMúòR1=Òî¥[ËÏk çíÝêÃ]wØåR£„¹«)Á3ßÓµNîà6¶ÛØùI}·Sæ‘çº×ë‘ÈÅmx·áou:8å z²ì ,>ZB'Ç 3¸«ÉSÄ!(KÙóáK›ðÍ1 Ç$î5ú´qJ†ý øÆò#'ŠT9"]ü—c!TŠa*y‹J´ÿT9ËÊt¥ uìű—)ªô2µ<‡25?Í|¥«S˜ôÚ±Çv¦½ÀÔàE”9þidÔÚÔûŽ9VôdkÝ=EÕ-¦œCU¦º8ˆcSŽM=¯’œOŠwQežiå\Õé/k䨗c_/ ¢ðÓãiTmlÚ2é×jO¤P›ckŽ­½äBéO”ßQuÅéávõ§T–Ò±<Çò^2ËËz{ñ)óAª2;\pñÉçu¬Ð±BÇ ¬0³¶ú“çT…û1¹ãÒÓ,]îX¤c‘ŽEŽÃ"ó@,?Þ yœ²dµå§É9 eŽ}:öéØç­ØgÖÛ+ψ§Âl𣮠óº÷ú§õ…gÁ… YŽ;VìXñc³âŒ·ë•çËŸar÷È+χ;+0uwßÇ1jǨ§“Qg=¬>sî 3¼Þ]}F¼›¥¸»ñä¸càOˆç¨½ÎÓ¼S¾^{¾|嘻c?æžõvý¥p|œëdl?ßן9¿'T9¦ï˜¾cúÏ•ég=\|y’&} 9°øä@‰(à ' œ0xI ÄÒ •0ó›Èˆ¥##ENP8Aá…Ì.Ó—_²ô€éO$;–_–ì 9∠N€ä ¬‡+/^ªÆ“)+/P¦zœ`q‚Å 'X&,y VÄA‰ˆ!oV_ª¼!äBgæí[¯qx x°Æ}OI¡sÿ{{aß»ˆâ8<î^?òqàaÿ,èy¾‡ÝS| ML„ÏN¼Q.—7½‚ »^ãŸ_v>4‰V··Žv EÏï¶±ÁîþQck¿±‹Ä›x©ù¥P,Ï";éúç0PMârÈÖcÿ•†9Å,(€cý¥j~©™_êæ±sõƒ%ó×eóËŠùeÕüRYHB©Xc©Xƒ©X£©X餯S±T±FT±†T±ÆTM©jãÇSÕSÕS55¦ª5¦ª5¦ª5¦ª5¦ZjL5kL5{Ѭ1Õ¬1ÕRcªYcªYcªYcªYcª§ÆT·ÆT·ÆT·)ÉS=5¦º5¦º5¦º5¦º5¦Å…Ô†ØàMxw'üM ¾-wKÈãm%B‰g3~®bF±}!瑩xé歹ÆäýŒŸµ5D‰Á# ºíðÄó€-³ZñiëÈ`ÊÞ¿ÿù¼ùefæ'µBôÆ~+–ßz]¿“úoDFFg»ûÛ{_?ì4å·ÆÎáþÖžøŠ½5¿6v÷šŸš$¯> Hm¿yã]ô‚‹^Ô â¤ÏUöÚ]ø\‚^7Ú^; ä ¡¿^Ðê‡QZ"ŒVÔmHè¢Xè_Eðô{н«³ ëâàE@4gÁ¹Æ^³¹·»¿Ól–=ï[/¤¼}‹0<ï$м_UoˆçWa§ãõ‚xÐ!ùp<¾._-Á/q?ðÛØ‚9‰:è †||0°QkÐëÝ>RPwp~ô` a¦çQ/ðÚAß;0Ù8 ù{Öï_¬½}{uuU¾ð{~|žôË­èümëÍ›ùÿ_ó°¼=ãÖ|?huÖߙãxÄå³þyçW|§¶Z^šùö öÉøß>ØßÞ‚e8øÇÎ~³c-yÇ~¯˜õë.¨¢Æ+Ã%^•¨„Ï33­ŽÇÞ—^ÔZQç3¬¨ tª)éªz{ü¦|Ãû93“"7`ˆ@ەߊ MÏGRˆË²«­8zøèVmÝKþø'\.¿ëù²Ay&1„¼ÿk +ƒ¢tk7€U<ç†N$ÎÒl¼Û=‰Ö‡4Æß{ç4Ï?Žý _ü^? TP[èMøÚ ûCg¶`ÿu:bCâVC -?â\¥om-î·ñŸ®éø·ßˆŽè[63´o¼ò.ýÎ (®›T ¹’”“=øažò°Ô#Ò‹¢œëQ+CðÖsAÁl‚sZ­˜^g@É5Ã×Ös@\øÿžJH¾Ä›lœ@ý`ÉÆÊ$è?ú¨ð·‘‰%È5FŒ\µE ÞŽû@‚m"øÞú.§ÊûëËnÓ °/YëÌïyßðUBâg¿÷=èýñ—°K€/G—A¯ùmÅYйz1pŠ4 Zß‘|_„h‡„@)ÀÀÙ:é"„àî”gâfé€3Ó Â+È{@…°”½ý¯{{dÂt¯½…y"¤6 ‚>Oбá)¶¡áûÝ~2à*ì¿ï`^Ô0öÎüKˆ¹“€˜xþO€¼:BÙÔ‚¦>ŒNÀ"lÒ¸: [gÌYŒa\„­ï$X(ðxzÜ1ÀhÁ.½n”XYèÒ'(ÐkÔí\³XìÓãðä¬*ì:–\¿…— ¦vã}ÀÓ£ç/ü(–¬îYÈáÐèñIØÊjè'Þšæ1ÓZØ ûÐ;à Þèã"ï(hÖæJh*PD;¼×V°"\Ñ«0†UòŽÂ.lBnÉkóg„¿E8û>AAîÁƒ¦‰´à#ò{4¼+èHÀ@Gg~Lmä¸ú³©†Ñß €R7¾w£+†óCÓ-_‚ÜÂ+)<ÑØ3VÝ^rƒ {À5pËd­õð?z©ð*ë50Í‹Å?ª­7Ø?u¤A»mË&õã(Òd΃ ’3àù"ˆ ·—Õ!¶ÏØ^3¿†'¨Á3ÙÙÛÛýr´{ÔÜßÙùpÔürðu.ï[àu"ÜNƒ‹‹¸rêT$!d®p±l nGAÜ}êÕwêýX(²”nÔȬ[ §;ëEƒÓ3/èt‹æJ8„‘y–vƒ£‚>A¿í”WØ2À5;qê.ý;úõ?I/®::k0kkRˆ­­eïÍ¢÷îW)¦ë,„Ñb_€dmÇ„Ü óˆºNk"-‰_EƒW4,üÅ9a~ìü÷öΗÆîÁþ‘U°&ÁVpÑÛW쪋ۧ õøº(´.?ÏŠÄ'mq©Í±þÏ=}ÜÛú­@šQ·)ä_Qm‚ IuÊŒ Ô°7Ú(¾¡†Þ†Š>´“^tÎï ºHî͠׋z%ÁðC’j$±ðqŒvM<8Xׂ†,O6"À i'ù!ËÛ$pØN@ô!èºw5â’wŽ[Qšdà¤:ÓUÔû3/;C~¡¼ÉÌüõµ." I%`Ä„mœ¡Tg ‚`$#Ž?2òvÔ­y`—…-Ohuö¸ÁrçŸ×€j€m“ðNê–æúJª,Å!n‚’¶„0f)½À'+ÂÔÝbÔˆH„€! ë<Θ¾¡Ú3êUëuà_ â³€÷á) ß8ôZ(:ÈÔZBíêuÁ‚%(R%eUë܇ÅÿYn^†·Á´ê5GÝ )ÊFfjŠ>q ªq·yÜÑ:õ“g¡U|£L-¸Ù~$el_’ïF ôÂ^€RÄ|ö ’¨ ÁÉ ,zÐí3ïC„œZ4Ó³1¥_à¥ÿ˜S¤µ^·B”ó²|Ø=ÚÚÛ;ø†è—6·ö?4·ŽŽv£Öh‹ä"—±Ñ8Ü}ÿµ±ÓüºÿõhçCs]/æÒFÇÿ¶' ÷ÚÿŽq2ðqf„Ç€KK15 dB<‚Âú!tu­,™VPÐûÍvˆB•È‘Œ8TXy#ØGç° ø©ö§#ùu'8é¿Æ'¯{áéYÿu™öIG¾ÚŠb^ÔºnöÏ@ó z…7z5p£„,«æ~»ý¶œƒ~O HmÍ0Kø7ÿ$ÏÿïÿóÿýÆ-Òî;§íìœÛt~ÝòUø=„Õ ýrÔ;}‹ßÞrûyѺ©ZÏÝÁ¹·3A¿ ÷·÷ý³ßo•¼ï[í6ü{Hã£<%`$I‰w «õ6$MoÛï´h¿0Rñ—8%ÿD3õÍþæ+ñ\ö¡¿È†ÑÚÄ ­‚eŠÃ;ôÅV¼–Ö“ xem\¾ë±k9.'0Ö›æL¶‘½Â\ÈP’ËÍó£ÆÍ¦é ê&ô湪C->@ƒÂø#뿱¦7<^aK÷;¯Š¸IúN­ ̨“kÅLQsô¯!b×"kÛ–> 5$¯äÀÀ)‰VôXœkFm V˜! <`R}¿ÓDAÑlE ±_ ×&<îI\Aüeç€ù !ŽÆ{ÈÉ]7\*vçÄ… =qìEÊh;þŠðZÌyÉ™JjEØèBŠ |Æ–BtB,Ý þB ÙR-±}!(Ÿ–=:;‡ šÿŸ’·óß_v¶Í£Æ!~ ú­¢ÔZ¤EÞPæ!`´‡Ž6 ‰>Úû¾°g´]+o >·zÆá²ÑÏŠ’Éاüð‘ù–h jŒ†3dE¡«¸Ì"A…ŸðËÁèƒXSÞql ÝÔC\óf¡õ,ÿj%`ÉúÕófàl¢=y—hvÑnmþ¿.͈ O»N±‰®E;Ã=±Q¥,Ù9\<ˆÞù?s¨Ë£Yö_s»’pxÝ΂% º!fq–\#ä˜ôcvw€Š™„b탄ûÙÛù—Pq-]-c²J éÁ°ö•½>7‡c®ä˜PÈ;a-oÆM:-‰²ßCËÀôàÃ>€ ûAìÆÆá×\6õ[ÐGjÅÄBe˜¹‰E}¥{lòÙ)-Õ ‹Ei¢,H¿ 0o±çÕÄY&©$Þ,®k‹Y¹ÙÙré‡ ]owggÇ;éDdûÌ“KG°xæc óа²§®'NÜô³°è @äE]éÏRk†V4YÞÅ wÒ`°<ÆtÓvÄç_qt?õizmctèàñ{auaçÄaaåÑ|^ÞÀlK¼¥/ƒÞ5ˆCtuH?%Ÿ ÚˆÙç‰Ö rwd˜­~ç:ù V탸/{Ò&z÷”ì 'ÕÚ>ðéB›»\“ÿHb籚µ"ŽÎA÷žG.ò:éŽA²ˆhì%&¾R’ë)Ž,íEíDüÂÆoxän"4 £¨ 4_Ðà“3¾©×?èUMØ'Ë‘AøÌ¾vÀ¾faéâã¨À“‡› &Ê#(±ZXkv+j8 ¥Oµ¦FEmL‹&ŒJ%Èb5ÈgãœUz³I³ñ˜H¼ávb½i#¼‰\Ûïµµ§v‚^åCÿ õò5BZÏ¿J.y«åf¤ßô,f£ €›Â[ñQ€ûBÐ’NŠä®>Â.®˱àÍt Pnsa’åñ"Gì™<¤œšñ ¦r 6„ TŒ·¸¹¶öuš¿‡Õ‘¾ˆmá#Æ#Czð+’-jØ%ÿ»ì*Fk²%%«ÛßÔ6ªv p¯Ì%º[7!Z¤1袅î‚4‰hôÂè–çnC.ÈÚZ;xRš{—¼¨’Gÿàs$qŒÍƒ qÂÂrà•÷£èýí šetÿƒ¢š˜vx™@I8‹Ú±xxÐá ŒƒV…ÙïSŒ…O6Ð¨Õ càdÐmÉM‡eö)SHNl«ƒšänì¸P#0Ø£¾9䕃m"nŠ”é%Iç˜õ:ýprQ†¹ã«8õc’öø\x®øgF þðSá@;b2çËPò:AßÛG ª*‚…„FDç½Àf_ÉÚä1¥uʾp6ˆÝ÷l¶}SeùHÁ-L1%{'ï£}çúÂ?ÊÌ©O’^À²…ï fÂ~/åü²‘UÌle]6[àféWö×颛xmŸloÙqxzŠªÕ©J}˜ˆ:Ä C]TG„é&¤i¯y,\8†‰½@‰f†ÚB”ÜÍè=‘˜©¾ƒR*ZÈDÒÒø•Æß-urËâUÁ^þƒï¿áEƒMãa@ÞPpJAÌ—°ö¡µlH2¥5Íha½ŽÜŒ%!Ä ­CEnÈ^º›âÓnOì–$òÇ䬉¥¨Lp€>ÝQ`ªrÑ,C×¾ú}.]à„EjXѰZ´L†‚ìnóPôþK?ž×O×äÓªzZÑÊIÏ4ÕÚoÓz…ugxú›kk稼ã²þˆXŒü"„0 tÈzî·z‘¥}½q‚Õ—Ï6ˆWws&ìÒÕ öüZÜ gÐ%Ù Z ý¸×h~ÞúoT:3 ‡‡ ‰¦A}x¿'A‘›ý¹2(Œ‰.–!¶Å—8z" wÅ'tª±×Dºˆ³fÆ×sÞcö>Ð_^¢]#¬…a>ŒuÜßé ébÐ'O5Z½bP¸˜*„ŸÏ­ð$>üQó*@Xnlôb«›,úô‡þS:ˆ¯_ì~ £¬$$TýX #uä\¸ô·»mÖY8(]j.gQ§Íç—Q¼M‰Â)Eš©lÏü"¢ 2@~MÈkÏWÑà£h*®5𜡸¦vNB<ø²¼0P®ïçË(lÏ Øëy7~Äýz‰#SGíÁùùu“•QÜ|t ,tÊ€8š<^'¹ö”íJ¥ppÎø|ôû¶·\®€ÌY)/ÉÅÔï]ã´a;Ÿ Åíl1Ä„¾òшÊg)¾.üÂî¬Á¡I™ç¶ùWÕ7gèµ¼>ß)}¥NÐç÷àBÑ’!»h3" 5-Ô0ÅÚŠÃÍ%z€ìù`[$²m ¹ÈÊqÔ¿ [âf3,Tù†)2§ ê³pt,˼DmŸÝåBTnL+W‘´¢ žØxŠ¡•f¼‡.á%X@ì˜Aªöag5Ônc¶Ö V—åpmï!í6ºgíxrþ©¶€”!0òª3@ŒOIÆo–y[üë±x…f^ í}v)ðÍSÊÙpbL²í&_L: ú‰N°eâÝ’8õë´o0 ™ž]õ" q#¶ÍòfbTÀ¨±ïÐìxpʾS^PŠ¸Ð‘ÌìÑüì·¼ƒ#ï¿­ u+`àh%é…wˆyªéÇÜ~â£S÷š/ žÐåQdÿüÄZœ ”ù<ý5/ò}d8ïý8ó-Üÿ“x ©XjŒÛ¢7q§RvJÛdXìHIäà!¶9Œšõ¢kéÞÆ½ˆé7Œ †kk‡°Äá¯s¢küŒÞoç£>­ Ž?gØ„X' ì#*¾º¼ ÛˆðŒ›Ž¾^µT²H¼E†¿ÑuÄ_ä`*69‹^²mü´™^CD—¾§0ÖâfàRiKx¡ºCé§u­åà¨ùmwÿÃÁ7¾ˆðE†íÌsXf_Þ{Tˆ‘ü÷ÓáÎÑ×½†¾ÉsE sß¿9¬égS¼Úüûèëööηÿþ¸µ»·óá§Ð`ñ¨¯ƒ›Õ¸.»ÀM‹‚8 yä»­1æt[×ê4UµDI<,àm7¯ Zx™?÷̡֛œõŠÖ·qºÏ »»‹îÓPkN©)ßGAÿëÑ ï4"äÀï}ˆ®ºÆc)yc­\Ñêæ,áµ"2¿ÄKIˆê=yKz;j{ò ŠZó Ñ|M}‘ħ¸Y4§ðY*–(.¸ d¦'bêð´³ä5Å4G”Û™¼rÁ!¸§ À“uÝgåÃë3 3Z2Kɸ9ÎfKh'±¼¡Ki¨Å7QýÀèRRC„1£t|¼$^Ñÿ%_@ašå#ß#_^âÝ×⪠*yò6cx2c:…ŒÿäIÐJs:&ü8¯@Ñ™*_ö'@ì¦4‡D!è ß =8>Mգ˒tÆèò‡Ô"kÊ{Okžx¢oBé{œ,$ci(‹è66¨šÄΛa{Mª½²eqq›8è7Í~K-¢¼Â*BvµŽ‹JAŒ­ƒ‹,JŽÙk‚¥ÞUÀ†BÂ×aüxU1˜ÐI ÊJJ‹¥ªåASxæâ4øh/d‹-¡6—Ò0È$ ΃Ü5¾êÂÖ; /$Šåd÷¦N&:˜ýí{°ÕmŠ­+(¤¢Xí]˜ŽrÍ~ª·Yú7ƒàùG‹ÉY´'2 ±&™$+þ1Åg5)‰Ö<Ö"ùš¥\ÌI4 u÷Ä›»VÉ) _„½ Ã+yçQotÄâen «âr3kñüº}¡7ÖõÅ1¯€-áÀ)¢-¯XGee.[Gîx»ÄÄ~îI„M"3°‚ŒÚ£ïáÅzÏ’¹rNƳ9ê }x¼E"zBqZb¡do¹L‰¶cÆÝNrvÉUýÂ-•0ã…ŠD)¯‚v³@4ôÿ­vÛ¼Jý“tè+o`“¶Ý jšWzpH˜Q½„q,Çè5Ö½›ËíG½¾²)î´êÃÆ6Ídzãî(ÿ–صCî#¨™ÞMÚíB×O q¿ô€Æfÿ+ìÞÿÒ!jÊkÊ×(g½Ïîü¶{ÔØ9ÌÈ7ø¿â’GûÿìÎ&GÍQÙaÂJâÙ“6Sn54 ˜!CN¦¤1 üÑ0þ“Î >ÃWOñ¤áÇÚÚ.B¡¨Ï<“VÈ%Ù,óm’‚œ¸=™©…½‚Ñ¿¥­ƒ-ÚþqÚûÒÇÍ~&€±ózμ‡e,—yº, ¥‡L×§ F«M´.E Áé+4Ú3ÍÑc8TãâÏþÅÚýÞ¤l té£aÓƒšic\7²«nÚÙþG³ Éj :}!Ѱ?¿É LÌÀ†ß«wǹ6 °Ú¤CZm{t;/gzó¯+6œû'f+êdÐAåQ„Ì©].7¸yUØÞ“4ØkŸ¸ýcIzã²äà’÷²¥M¢ù¼LiñfƯ+ª5zB´§_M/ž23PÅJ«¢Ëv‡È/)•ŠÒ!µüs+:?÷éN$ŒôµegH¥·É·ÄeHõzY·˜˜Â1lãû‹E‰GÔmñV‹áÖ½ÖY¯@òöué5Q!2Oñû;J"x 1Yz"ȵ°áD s…7o¨)°Jª =Ìò: ”æ%™nšÂ¾"X™ÜŽã‰¤ ãù¬LN!O¡*q‹U†¯¢sH3ç)ñæý¾ Ûè™[1Ž$>Ž.:%%³7ð)Ç?itˆvÜEtAÈéJ¿rÆ$ (UZp‰NŒz²Ó ¼•åÌʃöÊã!!êŽÒ"W4÷•m›sä8”WÃ`G~1õ Ü?Yÿ-‘p8 €­·bsmMn4>ºÔæ¸ÏéʼnC†j§Ìuv ë½¤wîyÍiOÖþ/ùاq„Q" Љ“EÒAµÿ[»Òu uÇšR|H¯À®í‚ÛŒ|´›’Y·åq-¦{³ï¹a`ÚÑRS1PœyÂÓ(º|VR @-…öXÒ‚Ø)NÍÓ³Ôr¦ŽÑ^ƒü ~¼æÔ9”-3øaYÍ2‹%:&h]_S/¯¹9úðù29¼7<©ó¡ØKÕ¸¤cbLšó»ß Õi#ºåÐðDô…‡Ñü%ÜûbÄ ¤tO¢"‘:y̦(5ÃÐÈsï2Gè¶Z ÎVyã\((Niæ’gg²][û„NÚ¥q5_T²ÁiÄ7ö=gƒc2{¿»ÿ]õj“ ·õŒŒüˆì½dlwÍóó,)ƒ„$¤$ެêàœXæE+zo<ññ…¿o¿þsá5ðíÙY`Û³ogñµðit¿{°ø˜b)Py$ãZŸW¯ãïžO'R$.ãB–Ò+›Eœ´¡&Å SÈx …OIDw'måMe™´¨ÏòÌ%ß4á«Õ\[³ü™o$ú%é5NK6ôqJQ“Ê>^dJi záPH$l,jÁ‡ÁeŠëHNc+œ’›¤7 «I±íg0Ñiî[c¯ ¾È÷Ç”“ç æ…M›Çäƒoçsom¥{,6÷vN! ÛÛ?iÂoÃØÝÛ9ÂïÜۄʪ-ÔŸCT¤Nñh%eUX¨ã°Ë‘‹s¤ÌRk‘>…圩«ð¥]©®ÜPW! Eª+·ÐUÆ &½)( Û©£ÎqêÍ%g†çlŽº îFäJê2- õ+Æf°z“¿åùëʃõ y~Óð¦hßÖGNP(Â.ì³b-ìð*ÿ/º R¾ª,æ•3¹~-k­ÊhÜç5Î\ ³±å»±,ËIDSxá›Ç€ì¤ïÈtéähQ¸'„…ÿäª8¦†#Ôâ¯uœ‡çu%Ï(«„!lûÌàS Ór;YÎP ·—»8·ñä®Íq“E‘+'6äÍßèÆ”µ¯$¹÷îO&OÈ5MQ$j-Ht<ŒhÎä£oçÁC$ñäúP‰}‹Ê “¬‡ppdf1–?7ÉÈK—:?7¥À±Xœ’‰–6ÊomÌêB œ¤–6©Ïf;¸€ÝsÒñO…Mr®0­®Ï¶ql\Ü¡Í]Øc@°b2#¬ÌþHªÕ?EÏX?&seKFgõ‚%øExSt‹Ø{ïÓ…H? kF0üI„‘n3²b®6¢ L€\¢+= RæÅÑxìJÔña†Bê‘”ªQÐ Þ½–ƒih{¢E™Î~ŽrË—½Ôz¥„Ëë“‘WÓ S &èæÊïu)!†úw{Èã)0”„2¦† HD9¾N_æD²ri°¦Ï>ù¥ü&cÍĽ:á5Ú|ÄÌè²_,X""_ÄL'§ÅWÅäøŽmÒiilrrNÊhXáßj³ª¦Kit^u?ç bG¸"ºrsÜó»­³² 120B©¶¡Û/ýžˆ6ÒÒîÝ5V¸ ìëEEA†šžÒ·oùŒûçLF<€:ØòbÎBºøö{8„Sh†¿ º®è*Raã<9%§?ç‹>$Y}ʰú]Þé…°øÝWÊ4EÍÄ~ˆù3¦£¢š"/^>8íDÇÐ9qmNfÝW9bÁP œ¸‰Þ0êƒÿ™ ÛAÑî­Ùã>^ÇfIÇeÅèà®··ýp>F©°xB؃û–œFQÛJo¹9GWVîãC‘)èý˜Í§V¥Ëš‡”¿áW`®˜§¿QÉRA¼ƒU$§<¦4+ðW>@'wùa€ì·ÿo£šàÉ·º¡%ҙǔ·‚,+m ô6öplˆÆíßÖ.ú𢳔Á, /8¥0Ê3ÐÕ³B%JŒEv&ÇÆÇarÜ4Þõ1‚j;:––‚›ù|Aí\ô¿ÍÊÇ>’&B÷‡E1¬MfâÚpl¶ ©ÉÄON¼F…ƒ«œ@%q1`Œ:{›:¸0s0ë#JþåΦ€z•@çíe‘ ›‰)µ9E «étÞDé9ô T0‚B¼“¡0𮊃!ÏmêÚ—Øè÷*kkœÓ¸© )Þ1þí*lã%zÿôcZžë _>ižÍ¡æßºØ!ðò~Z‘¦“Ûh¼Ú P¤F‡¥¿ö®zþJ‘%96vbPy ã§({_I*™&¡š‘°œ(u¸óùà÷øóqçpg{§YhÈ2 jr™uRó%Ï,ú`^”CúQ)E÷<’&,‚ p61p­°Òöo·¦´!Œ†ñˆ.I­”A ºX‡¾vßöþ{겉‹X|gLŒEÞºˆDq„…wáÐ %ŽJØk]ajËOý?j Ï="F¢ÿQÿëµPÆur%R¿1™ˆ%Ê´K7±§ÙØ.É÷ÅÔ(¿Š”–ª>‡(¾ÒƒÎ‰H“t odð‘ÈïÈaÅ"ƒ*¹œäã×Et‹oz¯‹LæLIÒbv1åä‰y¢)ò)É•ÈáÕ¥Ôôa÷»p‡‰1á¹™Ad0tؾziU.LÞµÊU²à‡)]kÁ8@Œ$-q× ±òÅ5Ó[–Nü²Ú že•„aGÛïaŒ©E¶NZ<\násÕiPxàÖSyN¶7gŒßS]sô%ç(ò†Ä†x–‡ÀâOÐ4÷¹·ßžD’£½óä# ŽãKÄIî]½QùÄD9ì¨?jþæ+)PÊÆÙ:F•Ë#õ*ï»{²¡|œÒHòμàíײÌXI.9¨ŒâÒGâ-y•ºÁÊäÑÇÝý­J9†©é|¥BZ\‹_€ÅÉà|#Ûq‚ÁˆQ´i³ ýj6úm19L4«S:Å}3]¢wEý¦'ô M£#õÛŽÄt‹Îòc_ûa,n‚t9¿§ßëù×±³ÀÏ;ÿ¢Ó~JI“û}¾ ÚR7æø«NOGÅ–Ù¿VÑïÞ•ÄÝ’ïR€bfd™¶vóI2R ¾ ±P2ÆÑNÕ©2ycu¥Uðoê"á[.å™ǸúüU$€“½HÇëœÅÊŽ”OxŽÒ?é•hP ›%æ)WÒ•œLkŒaX‘(öh^ñh¤‹šóO«=¿¡6UºH–)ËÍñš+£Çcž Yáô^ücÿ/5ºÂ«?±øŠáæhFû%LcÜÂçÔ Úƒ#¶¡kL@©Ä˜LŸDYAØv¢S@?WË–Jì¹Ë0ÄùÈ^’äJ2@´ã„c–z3tãÉ']N¿ÐŠ.BuSçÙ$#úžèŒˆ;´ Þ )…üùå½ß¼1¯÷ÿ’‰ë?¿×ð·X´îŠ ‡lEòª| e1{VÅÆ–—ޔ䧍 ïãà4ƒÑWTõÞ(eL-awôÔsi7ÍE„ô¡L¬îÒuOÍg!ô…ÐŒ·ÀBpÔz&DŸaTÁ¢á+•gzî²SÃu¯§CËuïÍ›°oâ:ê¹°_bˆ ,‡ýŠ ÀðvtqMˆÙ‘ùC­‘T1Y’^’ÏNÄfÇ&ÇÁh/®-6Kìu,îJBHWtB6»Eø_±6ìýqÖ쑼#áΫÎÁ|ßÑÃûe§ÙÃ)¼Âž™£~-ÀX4+ÕĦ[ñØÎæîšä1#%œ,ˆ;g¤“Ô„L4ÏÄBa`åÉxxß ¸ú•Ê!ûnŸ¶,µ—YÕ0¨^éDWEiSSl£¹¹C³–LYdD͵j¢XTŠYX¯(§îRv’³B×­§SÔÂɿ޽C1ÚFt z-ÉÃÞpLUˆ1*f çmïïŸëy/!êèw>Àô/8‘¼Åè#:ÔôÛó¤mgx|¨Îˆ™NUú•: +Û6&~ÂeQŠÄÇÑ‚Õa%[à´‰O" qOþsÔúþ:6`’ë…‹¿íW²%Ež«²d øs!x®ìĆ™µá Ws³ÏÂÈ´Æañ=ú ŒU‘ƒ{¹Òן Ë`»œùX#ÏÕúÑÅ|'¸ :ò¸Ç޹""OU¯(oÂÆ:!áñ–’;)›4ç€1Å'"_§÷ÅÁ‚ZI‘´ˆö tbBˆtú¡%´{À11Ó ]ÌÜáJгMinä}ú,Ï °xb³ö¥<§%ë‹[܉_ç”úbþh)Úf–/¦êµ‰ 7“ºËžÚ&"Ђ¶И\!Ñ5-éªõƒ.tîþ“ k·öáaA´–á÷:?Ψ¡n3?¾Ûa"0Gˆß‡ ñâ:y.›ñä•V©ðGÏoÎaáš0º Y,àgêN´¡Ñê>ÿcB7u:n’á•ñÊÚšÀ²TëÚ2¡?þbdXÓ²(T”£S(- Ò¡ôô£K¯½·¤¦ˆî³ZPþ¤ì÷Aˆ=‘e¢­ô\dg$¥³`û³,¾½z¥\TR/£/‰¼$âa1£œPМ‹ž¾o£C˜®Þ ?SÜ?èmi1ôNïÓ‘Ë;ÿ©½Õ8í–ÆÛ¯åáFÉ,„T@±¨ó&$»¸–€"X ª° šUYFÏ«-0t/ùMü ÉÑæ@ üe¿üÁïÿµ.ò-JuEå_KÔP\ûËÿŽžñ#êžðÛ¢2o‚¬=°-þ#Z6å¢y×XQS 7šô˜È“f÷LÛÙØ§ôsûZ°æ$³±Ès˜Hâž¼^`w ~>õ5t©ˆ¦~Ñc3‰è§Ï;GG[¿-ë¤t%à=âT’“Ä“,ä ¨ì@4ÚFâ(ØhRò2€Êàªw&,q}ÊlŸìíãVck¯‰i¸¿ê>¹Á¾ò†•HÀÿÅïõ9õÚÚ÷~ßïˆdÖ©>÷ö‡u{“þö£îÐ.)ãøÑÑô$„sÌÛ‘¸ÖÛZ…=нúÂrÕ+$/í‹Àm#†ŒÔ\¼sÃ>£¶o8ˆô0®º@¥Õù|F,üýLÿG€Âþ€#ÊŠå¾|9D4|Ý?ÜÙÚþDáÛvdéJYÂĤ`Ì@lÑ.¼¦ÒòlöZoíÿóa;ÍÄÑ—ÿ ü;“ÏZƒÉbÒiÖïÞˆ² Ý]“Vȱi+ƒ-Ž"*AŽDUVþËØ{ ø"#¹/k§Äœ¶Ê=.0Ól~Ý)›‘"0׸š²O´ØAõÄ”,ÉRæJ!çÓü£d/"{Ua 3ù×ñ¥s˜…PÛ3Ç—µcÞìílÁhh%êµ$êk5iò$ãÕvJŸá…÷{MCèå¿nŒ±( ¦4ƒ¾ˆ:2wðoAWS »´†4}¨QILü*Q¡©Ní”'sfÆÃ°£ÌW?ùñ~peÚ(";Ïóhžð/MŠî zëÖn½³Â é§|æÇÍnpeÿjNi"ÇPîRÆ¥ N,ãäY-9†œ—dFbÚªš¦Lö¬,ðÛãp/b]¤õãÂï¶UBo³ÀŽQoTŸ¸$j.d²ˆí½-Xúý­Ï@Ɖ²$f:z¡ýó¯¿6ýU½ß(ò×HÏÂ郩ТLÞ@é‘3‡‘ßw ´`6M,¾…íâŸVzŽIf£BºMÐÞߪӽ'KµãþÔžÔ? jä¿B ½Ú×…âúŸú^@Â)À¥dÄ}„ƒ¦ä&Æáîû¯ج_v>4×ÿ#™†­œL0#çOøÿÏ™!ƒœªv~‰¹½Âßòèê-ók²§_ ÚᤳüïŸFº¶L»ÞH°—ö{MM…æc“œ’Yhs_K¥¢5ÞD®’9Ød†Z‹ƒL¾$›¸ÒD£7å±0YgäDÛÝßÞû ²D~kìîƒèL|ýÔT±8TØo-–äÙðn·Uææ×ý¡ÓÔ w©3‚f2":ß§ÛK]q¨FO0j®Pž#!¹ÈO (TŠOpeÊ><:½Ààù>ºCD Ç¶ŽŸÖW5UÐl,/.œ}]tÍ󿤸 12rÙÑÛ–¡ïêTtN  I¶qÆ.sЛ=w“7H¡G ±ðœ£Àsx‘ÙbìŠÖB çVcáÒŠ\¬(j t&zhôÃH£>ǬC!®)Ä›%x­ÔSzrûB7Å£AD0ný­AÈq xVHà¢^,Cãdm\ hxJ‰Ñ`(çBÏØéc®{àõXN¸Ç‰²qtÒÇ(8IY2U^ %\)ªË´ÇbÍòi÷È;:øØÍkǃÏ_~ßý°óÁ{ÿOøqÇCÖ~¸ûÛ§†÷é`ïÃÎá‘|žî³X88<¢@è­#hl}Þú æXX¤m0>ãØ%G_ß5v ¤½ß>ÚvßÝÞ9Z÷öŽq ½i0À’ î Þ€Ïï¿í ‰A~ýÒØ=Ø/šÛÁô)Û[(û ×û8g¦ƒÃ"hÄ­FÉûöiž"z k[ˆŽ#ÀÞvÃ| ºdÒÄô|½ýßövÃZ|á}Û=Ú)Ââíá »Ô9Ptû•掋c£åúh“s‰V×Ûýèm}ø}Ç/Þz8ÚäCèÛþ$°¯î® `õÖÀîþïSÚÍåVtîþ_g~÷ï7|ó»E#—Øñx­¤Á¢Óû(Ë){£0‡nDA{>Þ_Ås6qWƒaUqëË®Pf}dC¤Éz\žAüªRD_³íU>Ë¥>W­—ö‚¼d*kË"Ã`~ÖC£s]¦ô9x"S~ Mog«ñ‰e4N[›ý¾´NÐ:Aë­´NÐf Úx„¤-yApâ·Îÿ÷é¹vø…#ô}nù'Ap?’Xš¾Þ@Ýã ßTõxÎe iʎð…·*(#—âÌgGHß„õjˆUÓ&ǃ€£úV £òÙæÌL*Éû{&¯g$pØô‡;MÎ-ÝT÷eš½A·I"/¨¸ó±/5I“Ž{Á~î½KÆoË3F–ªï.•lÁÌðÆah„î¯IÑ™³ëÙ;ÆÁG T#MÇ÷D»]1§ÃAWÐæÌx6UjW¯ƒH6+@‰LÚ·zòk²òeiÿCºõ½òÔê²3Tê‹ ècLÞ_§»ÂÈ5áE°ªYx‘.ê·zvo ÅL‹&.‹piƒø9þçš²èÂlÇ??ÏñäÒõÛÊWrÉÀ7Vw1Õ@ÜÙ.¯Gqt§YÑÛ‘2`Ú&ÉÎz`Ê{/­¨ÇÁòmžÌ¥©ÊØ#º k`UÄgäý*úŠXýC—aõèøéºß€”+?ìªEÕê‹k²¨¸ì”Hq‡: ¼X¨KlÒ§j±$®ØÿñR ýˆ#oÓÉ¥5Ý%ãîmXùÓEEdT¸P§3– ¬^¹Á”ž‚ç¥ OªsÔ‰Ež 5PAAæ©RÀ%NÌêL=‰\óêÄ’îPQÛ ¯dà°Â¸j¼s\ˆÂÕC.z#Bþc<÷þVÌ[òΜÁáDa_ß\ ºør™I¼Ц ¿Ô† j‘t8^Yo"3óºõbAžï­±w»ÀßþÕzþ“h†¿Ð{ó›\Û‡ö1(q_Q”ï`¦ÃÆ×ÃýæQc«A:k‘þÍH{MÖ™Y¨yH’tkDÉŸ{P$Ý¥ð~ÊñÏÔ£’bqÉ2ÎÂ2£ä#2 ­é Ùté2 –ÆKÿ½³Êø9肱¶ÞÕã[޼›Ò±$e k8?“0ÓÁš €í¤ ÉÏbK‚ØÃÓ1,ÜZ§ º@uQ—v÷ e…j…Ô(ÂP[æßÔ¹¨ž íñ.IÖ1û2ƒ^YÞ“Àµ;Œ0­£2‰ü’Dׂù™º†yÖ ‘ÓFR?£ìœÜÇ¢˜=Ó;õKDwÈYp86$–ôkO‡;ßš;ÿ½½C&ñˇÝM°½àïŽy÷b+ޤ!vÕ™3»NˆjÊÆWá&ø/©`z‘]SÈ)¹cæÊÁŸ‘[C ;©" ¬^û ô¡Q—DÊ*£–Ûëâœ\¤³â_˜$ Šr G™AO¼S¢‘º‡¸¢ ß<^³ë rÁ¹æ`S ‡KdpâY`e0ì ¼ö›Ó¹0f:‘C‘A1†ð´ßWé;ý|ôn„µIAE•tê%&#‘k4êQ 5 ¦@ Óð¿°ÆÓ²v.dš”ëB‡ß.ÐgDX“ÖŒ¾[«užvýN6«hƒÒ€Y°Ú!%œ—¡9åä™:ó^s3ð.Ê$ ß;œûÝy ¼àƒ~ ÓÛJýpï÷ÚrÕå¯Ñ‰æ/”2F3•Ù%¤¡Þˆ|¥â%3hM„c*PbBH[•°åÕ‚DM ®ëÂ…ƒÄ]7¾ÀÊzø…É_ôLFL¬F”3ÄfÖÅš”lRrM×ðçÕ¢° ­iúg&á󈳵 úª6 e]dI¯M=ÑR—Óš†x­ …¹E«w¡M¦1eªÒ<ʸKM˾¼Ì¹‚Ðé ÐȠ亩Æ*ÆeÒ# ^y&o„sÞd ùôF¥ã‘娕ãA¶€¡Cò””¡ŸÕuUº"f˜ÍÝÄ1€ %i£Ø¿b¯kà@ç1§/MÑÐA=U‚’©äÊ0@¬%†@’EV·A`8$‘ÖçäÄ[j8ª± >äêxºÜ˜ÇYÂå(ÉA"SøY>DBœ(‰§(Ô‘hšxÄœy… Á!Q›³´1ÐåàAOxgB]_˜¸8'›gÃ!/õ#­¾¨i­q°€vÍ{äÖ•_ÅYBâ^²P(è Lú‘ÿp0%™IO•þ1ÈëÌUJv1=Ö"ÿ™db­Ásô”©Œ`(§ÂS |"PU¥ñVÐC¿v EiÒ²„}¶ÊúþG(æ¯ã¢cœ©6P&–…‹Ou0ÜX{‰Íz¬Õ|w<å7Mbƒ&ˆRØ‚\¯1¬_ÉôIå3 ÁÄ™3±V M`UÐÙ¼÷¹'« Î/ú×É !æ®{F¿TAJ%º³Àär±rZÆ–˜s>¤Q¥%{qD†^£ô'{¶8™ˆõχ"¹Y'Ç=¿Û:áeÈ㓞+¢|T°·ËŸô1#i#ËV4UPmãënC€Z¢ˆm/‘èkùr3—ù¼1‘nJ $RW4$DÒX\“¦ó©®÷: ðµLp…>h÷$`¶­Ò»©VAÞÕ†ß6â‚,¿Ü*½•ú&—0­DŒ´Ì—޶Œå-"°?"òR$..‚®(©IˆÌÃ)/¡ŠÍ §¡úú>]¥Œëº…¯å´Œ=FE3bU¤Kæê—B¿)NtÕóã å3º`¤¸½)æ è¿PÄQQFWü(R´{ª&xOT›SV­²À‰ÔNàb.9/“Š4èÆFПPec*¬ö×™=mðÐ_´ø žØûT$[¹ü<‹mpÂMPêðæ§ˆDð;8òk=ôZæÐ¯¬9s$d…ˆ ¥žÜS2`XD:Ðô9T\ú}£¹\VWúG€Çš.Lr*ÐýÐ^ù0!EÖâRÉ›ý!ÏáÓ®'›º;ÀDþ³°U† 7“, ±á-ª’B…6©Uö÷…yük@¥ÞŠ¥ …ÛÓ÷øE¯<‡kœh]œ-f¶F%å#‡ S 2ñ%¤Yü9óø™Džêʱb,É~t…Çù†€ç“o@S˜z„êpÎâ3ø‘ÑÃðˆ—ü#Dïïûë£Ýß>}ý¢ãP8û«B”°—¾í~DÿÛÖÞ·‚ñÚ«WÞ7ÞŸá7óñ»wƒ:.dPþäwO¿^Ѽp>öÀpÙá䃋_ô,ºòˆ"QÄM˜4’™3?Ó„í¾íþ÷<…݆XV:€ sÝêQs¿A*[ùlÓë„`Võ®K’‰à™×`†×"Œ¡Hk‰­²Ù3ß• l, D~‰&DQÕ’PÞ"_TTdˆÂ¯ÃF†ªCyÜz}ãÆ,JÉ$;áyØ—TÂH_CºtHsÅJòR]b—BB$ùQ¼.Ïv€t|d ç˜BðÞ ëX–¾‚% Ø^aö×á#Q_ û"è‡"íÈý½XZþIoãÕDZ®X¯à{,õÂB•±'ËŽ¶#98Qçž|™áþ ±xƒc¼´¦ê¤ˆ†ÍÀU‘&±ø1–÷` hõºì$@»šPŒ˜¨ƒR…ûööš÷zë5¬êŒå0:TT C!u ]±×ØDXõå¢,wÌrñÏ?9 «Å“ê¶±§_ÿxMC}-ÁgmÆuïõ¹x¯ûšy›©‹D‚µ°ˆ}hö¼ý«Â™¤R#öZòå?ÿl'^n­cÛáiØ×¯}H¼¦aqyh²7ý¼Ö'Fë?Oôó®ù¼«Ÿ÷Ìç=ý~«¶Q   å&1µ<þ.Eƒ`‰˜Óc„P"°dóžHÒ YsMwÑ*¹œtT·(Å@ÁðŒ&–Û ø„@õ2øéÝlo2 ¾y’ÙldØ"žÌÁ¸çÈhWì=öÎÂÓ3¬ª<ÀK™X?1:H×¾o”§—˜ 9çåÝ£ G™<®4øY"Ó5£´% ¢JX÷G–1CרMîðÚ;"µãÃn9S÷ûJ¾aü)ldôƇXö1J·s®3ì^Fßë¢Íî2ô©°pÿLß®$ÄÀg¤Í>³!øRŒ÷Ì蘃Õ@|ø¶½=‰"ŽæPªÊ[ÿ8Ž:€¥·òc¿'ÞA‰JðÇt³A4åxwìÁä‘‚1w8\ü"ˆPÃ`íløõ,vnVÝŽÚ ¿[óò#Å…ÝAÀWøé ÉKƒ1Æ5Çc1Îðeåšž”D|o“JV)ÞvõEú cáTdV°ý›{Oãb\øÆw2<éÂW'á;¹Ô1iCfàš—G?™§ Y×G$¸QP·÷AÃç“C:7›Oã*2®"R”š¨¬Tw»€g gíùñ§Ï'êù#a}”Ì Ê÷>lÚÙþêÆâ³\•!#‚bÍ4'äØo}¢€²"¿hî§²0¤)Od`l¡©[õÊct‚x™—»—ê‰Èl_F ÿ­‘¾Úø²mM<>‘£ÐC°1PD‹£":e“[,ƒÈþV+{dއ³á’3BÆÏ”ÃÔœlQGÿuMŠSà µn/L’ÜJgšù™ xb¹73¦8ìÖÁ8—LðJ=»[ð´Ån2‹áZÝF>\ñ±¤¦¸¦b…ò)ø£ƒT†…'gŒNÔ¹ázMøZ{”Ðçi˜¯Ìƒ’!ÍJë2üû˜.ðÿÈ0>õÖÙKœÉ““‚\k=™Ã>ž7w5é«B•ãçÐE±Ž¼L%j,?oµ3Í¡ñ  £_Å•Þ|Ò@¹[MfÒÎX¸Å˜¹qÔUVºfMEÁñ U~ÛÙß9ÜÂxÕcŒß<e±½&U¢‹ÁùEùBd ž§ÀãyNF]ÆŸ(»áE­ì|Øm`¶ÛO[û~ùå—tZè—Ú¥…vi¡]Zh—Ú¥…æ´Ð—¿Ý±CÿO¼½(.eçÏ"j8v¤n®©+1tc2Á—n–2š¤#ü•±Šìö޶w¿4@oËzdZŒ,¶›gëóÅì÷gD ë ˜Ï˜2_G íQÚ‘tJ"‰Ø­*d̶žº 'Y›Œ=túá]§¸u"gºCÇê$#듈¤<Ý¢¾ÌÞ/°kV^£Ë}kÔ÷x òˆT` ìâðž$¯G/aYdBV&¼ÁÈ=«Ô:<éºÜFcÓ+ij#ÒDdŠßeyvá߰,n猴  þ!Ê¡±‘QÈ*Ç”µdê(ö^ž…@?½ü¡/²Œél /G'¼>úB­—¥CÕlH¹ ƒÎÉÙ•½†ô·ùÝk)äéb U®FwEù^Ï¿’¹úJÊààDÉì˜9áˆÿT¦þhðuP•NæÂ•ã>ÛQDùfUÒ°D½7=/#»×&]œ†Nþ)ÇÔGº‡±˜[Œû$ªE‰”Uâp¬¨’ äã$\‰x)ÈHD¬å0å‘=ùÓvåãU<ôÈÌxp?Ëœ ³¨YºJOÉ©2+îUèÖE/8AíÌÃîw@´ ðWò>DAü¾ãŸ%nvù˜/ü–È^&£%©{¯¿}Bu¡(s³«…0Ee\EN;°lá$ŠÊ8Œ‚V$wz¹ (Oû“O£Ö#ïaÖ¾î\•Tx .Òîþ†Ùïn‰Ä)Íí­£À.U¶Á¿}rz™œÎ‚}¯=Wgp4½RfŽy™þßg3Œ [²·Ël¤ò½°ku^Dÿ¡×œdm<èJ¿…Ð"lýIžဥՓYÞÏi BRët¤R-þÊü†iɇXu @B% ôù£äÅýà⯢7ïý“®³Ë‹0‹·èÏ|);ÂÙNc®^æ¸?™øØv”sÅ1•œ}’0È2 Q¦}¡C‹ +ý$ÙâÂe¥ä]V©3øš]²ML'ñÒOÂn· 0‚^QŽ R¼íy‘¦¾×ó¯ñ|ª=cF^´Ò2ü’(ÌLqkÐÑ£JèE)òÐðžL¡˜‰54féýM·5K”¿PLm›Ó£Naâ§râ§„Õé†F>ÓsIhÛï…~WZ:£—K^8§`ÿòòº(Y†@ŸRÆ "N“¾oîAÁékäf¡"Ýt¦®g©¤ýb±yi–$¸²C…úV6ꆘ‡FÒíLþi‹» ¥nsI¦ŽÅ)´Ãåˆë$e¶7{Ýkàñ³ç!ýE•uö< f¯ç0¸Â®ê&‚53òœHæšû‚Ø<©qЊ2·dD¶6 b€‰‘•>(0ÑÒºžZ%¯ppXžL^d" ï<ñ}­ ÈŽÒÜT.|}ã5Ó«Ì>IÅPÆVã"S†{q8"Î[¨¢±^âŽeï0`mß¼[ß1J6”0{·tàÐ\qï7AÖ+“£7D¢1#pΛóR‹ûV¬aYŠõ· ¬6ð’MÒ°"†¶«Šv@c43äøÄC5ÛN8Z³©=àC=ÚD=n~™" öŸ½dÊ¢²ñI»Ôk.7>™•hË#”œ]úþ,oõvt: &Ž™¯ö"èÇT;æoz¯Ä/ŽšÇ¶ØüH³µýµTBàj[OH¶¹4›7€\ÒÅyÝ µ DÇø­3Èq²î3hRŒ€²¨pqW%ÌÍcVùd8Cu¡tTe\‡ {–H£+ÇÁ 2R6C·>6v LÞtV{ô 6DÆ”ĵ.Iô-CeÖìUËé"©£:uLn†Í:5—Ý(‰c].CÃÁxš½ùVþPñÉÔlÊ?â·é€LÖžbõÚ¬«£ñv T+ÒMÈâ4h €wÙ øÜ@4b³ž:”‘Fz8>ÕïjÂà¸à")áþa°Ä {‚Ë*t>¤Çšžb­„k€Ì"“`$ø*<1_‰|Ë—› ·úägiµhöï+æïÒT%1,.MÅF4‰ã°t•ê¢ãS æ1›ˆºé Ÿ6b µ6A”½÷"‹z7º!*{/8§ gy!­fÜHN߆¦BqºŒZY[8[Ö¹6ýÅ…|û ¥7_þ¢ Þ]9r°|¥w¦!ïxIÈʧ‘!œ€\òq4Vtž¶¥u¼1íE¼èöX‰›ËÙŽ†+x9ÝSsI2<ââËÌQÂeºžJè C·ƒ,µ€'Éô'ÂE´O=Sœ¨cĸš\îŒûzkÒô¸ÑP'PÊÝÃ'œ=Ò½ÃWºQ7ÃUÈp$UhGÌhOÔaEŽ®”1¸ ò"V›MŒb §Ç¿ô£ˆGÁqÜÝ#H!HE O¥ˆ°Xz²çiúZŒYe¸‰¤ŸÆC7wÌÑÊKÃÃ<‘|‡Gâ=MÃåñÜ@?­ƒè…vóê˜È£~~¿»µq7² ¡H°©Ž¸‘â¨ÊDüö‹óqÉã‹k³.={ ¯º²¦#Çn«bÉf.‘ÝgŽ+6ö˜/³Þ#ÄF^˜sPÚÂ$@›/¡ÝðåôÉvÖÁö!lºƒmw°í¶ÝÁ¶;Ø~)ۣε ¨[šgÚFâq·'«,ÌÂëkcwÒ‚ÂvC£Œp‹N±Œ°~&à›f¹á o~Õb_=º¤…›O[¨¹Ð6§8 ÀiNp…¶}k~«fx…ÿ˜7ã•kk6>÷{ýYU2“åé”(©÷RìÈÐÖu sxw0)Ìþ~ç8«youi)rÑCGŒ˜Ôo"óóØ+¬xÇ×”±¢÷pæzQ¢¢l%¾ÊBju0)‹hr¿Ë´&³@6TÞCöj±“Rè4‹xôu·AÜEç8i/ð´}Ðe%GfWÄyqÆã °Fá§iJLðP"8Ö·D‰@9Yófá_"5*Fµ)Äâ>ËE(Ž(…Œo¿Jyà»0[Q^Ý Rc½úî¶õwìþoGÆ 9G¥WhGƒcÊQÔ†UþÔÖªŠX×"§®‰É¤)åÙa¬÷ô4C ÑÑL3ÊuƒÓØÁÇšíÆ&µ ªòœ3Ž’²ÆéÇ4(9D,Õ¸&Sëà@É+*KDìÁìLäCÁ©ò«k·ÎÙƒ"}‰/äÙ)­»mÞåüµ€e{¸Æ_]âL™ò‹Bæ{Äøoáñ1ªPñàô4àr3œ‹Åt Þ ®-®™|íÒk¬Mé!'N â’ ï°imŒ–Æî1ÒÈ 3A7æÓ1uÍeÞÎ ŠÚc§Ê^[Övµ¬9{LœòÆçÒÍ0Ý€3ª¤<”lÑ uN ƒIeN,ufw­“äºç˜Zd%°»uïâ‚ÀË=è Ö½Çg°AÛsfwåü /ðE‹«ç8ˆ¦1eܘ{@è­`ÖÉìKòÒš~y2‹vowÿ;š_‡Z´vCÓRí·;á1š´ú_¥#3735unrä/2•=RƒLàÕédД•æ×NØŒ×>w·›ŸA=ûïfáÔ@ló|ÐÇÒˆ:7v¨_ò8€)aÀº:¦q=&?ÀDZ}ºtlÔà–~pŽi*WQYvu°r¢@âˆ2¢UÀ¡ATãí£¨~³?½KKl ŽY¾EtzeŒ+)éXå¡Ã£#O’jáḬ̀ìh„YZ¥`”ÓTJDF ±b>hb¾&.€Fɺ$,!(ŬÖïýÓûçÁ×㽜ñÙœicS&º0Ö× '#Åz¨œW7¢AwdõéÎ`™ÌDz¼ò*Èÿ…Ýß„†ªDU7øÑozïèuU}Šî\tmþGù2È\FáŇ´ÞE_iî‘ã-Ì¥f1®ÎE ×’}4L¡`˜.tQ%òÀ\Òº^‰Ò"Æ€èÔŠsê ÿ†Á¸€Ì™"#"†“‰bõ>f¥2j$ÍŠ:sgcñlo³d>Çs•MfÖÔ:ýsu³˜œ8Ii’ý’âh³ã–" ¢JF;‘:"Ÿi%ÆÜžƒXL€ËÊQ*; ÊYPå­{R}1Q¢/røê¾)³ÊÛ3eA-ÿÏ(ìŠä.ÌKÙ²ˆ›”9žu"¶ÿ…|‘‹Èä|‚~?ã—½¨õ4ÏÖ÷«léQÎÓüîaÀóuzïê /þ.æ7yoüB¿ÉþÈÏ !†9„†øÃ"’¨È&#ʤyÏ$dü&«b„º$"#]à–XÇ” `¡t dǤN66SÑ„ø&*Š /`; ‰OÖ-70í &ÀÄc°ØÎ Îj(Ø’OŠ{eÂvÄȵ½&‚[*õBæ-1=¢²`ÙÌ=¥\hcótùæ–q"ä'\gñ?Æëø†\äuµ-ñÁb­¶á‡å…P¹ôâ sÈ>åZÐv,Ž2Ó_7Í!ÀáZªW‚ý‘"[x¥ÇžÙ,цäîh܃îˆÚë¢.¸nð¤-Ò¬Pp£ðuÄ}3.êÕ¢ *þ ”›qfúÊH†6dÒ¢½X”Œ‘ª­0giP£:ÊèY…Å-ìþÓ#ø™?Ô™-¯–QR’¦ú)JÍš¶I»3Ü)4#Û4Y”–FT…w$æ7G¼ªq5—~sN¿šLâöîÍ 8²ô îÁjõËðV¿¨V™´”1†|:=˜ëdŒ ,_B£DëXýýr³þ~Iõg1î¼®Oz!^-Kòdâ·€D±43ÙB’lz•HN 2M÷ôFYþP~bìOÕZÒ!“¬"±©Õ8©í%›30lÜXXÍíj~S!’'Â?JuE¶ëü&=¯Súšä{æXMÑhJFó˜­{&k ô{%±ø–}ùÊ:‘ Úìï¼’~NÐÓ/÷ô‹Ý9bUÐùËÈá‹„D•ñ,€dYG”z-.L(lhq4‚?FÑ{¿÷ÞÿûfÁï‹¢¸ÏæbÂ@eí(DcÕè"ÑÚÛ̇™£©XãMÐ$T]Y7õçý—\³_Ɇe—œÇE0¸Áà"\Å0Úg=^áÿuæw¯ñ|÷›ßåF3¯Â<ÝŠ–k']G⡨tC<ä}‘-;ؼ]U=¦E×ñäÊW×oÈ¢ï^³#¾¡Ù?©r™Ç¿Ê.¾0l¾kkô™·’qáÞ&ËdyjLÄp}ºüÍ÷ËUZV¼ÉÑ™‡ ‘Œ^Ý©ÜRjR\£FЈ Eɧ I/¢dÒ L<ôÝÄ’Çq" º¬¾{xÔ/A¥:¹»$Aä½jâ»ô€ê78”ƒ¡@c5­ZŽð@`ÆÏê`ã•Bã\QÕR4æ,~|%õÇÆ«¢Ù¡@@æÐ}@yÚ‰Ž±^”‘ºávÂyb…»‘e¹žÑly8›æ“Õp¸X¡Êk Š,Š‹èQ?jö{<À#ƒK% ½I2DŽT¦Lý©DMäùdû@¿§T–‹b4Üë„Ãëé·ÛxYÓ()FóOÞíu ¯A‘îëÔ>tL‘Ží>¡¼ _÷æU ȶDL(üš–èVÎë[ GCZŸ‘Bß é¦uýj=ã†1†¼çyæÁ]ŠÂor"Ý1óQÍÕ¼òG^ïu†¢^Ñ“•PìiàÉw¿½¶&šœCöý È›Gm”S̘Fët®×Ä•µ¬åUÏÚ ˆHm]Y3jÁOCc0ÕNš¹©*ƒd!§­Ó»ï »€ž']ã¢ÀT<‰½¶úº¥‹Ó)`Ö`ŠBV„ɸ/¸{ss˜È±7rAù—'“F“áŒlP¾òk÷˜©M¹¡DRI×Â&"§Î$*{ ‚"‹OÊ«µâ¬ÀLÒ-rÁb±Ã3s ‰x'îz3k5¨‹4r¹±â‚AHÀ—’ûŒ«SQ1K²_ÖŒä.Ì’á_ø1¼ bƒGRà m#¹D²ÏÅ™—%õIB›W(/Ï…”T‹+˰>aÍÄý¦Jþ#O½$|j™xMV’e†Ôs¹/}\°kÚê§’<Ô7&BÉÈÆJ4Â?ÅŒF’0£CT­öF•õz|î¾ÛeÖnmÈ©ÅÍã¾—’FÉ PeÌ× ˆ9¹K«¢Ï˜Ž®kdu¡€ ºƒÃÓ'÷2›¼²A˺Ƥ_‘:…Ìñ†Zܼ|¨/B¸ì•Lç¢ÁˆIwdÉp83£ñ¶i$öû¦yfbÄ&‰_­p%ÚecÞ­±o²5>4_¿ìí4Í+¹ÄEô…ܬx'²¡Œ¼Bc}-Ùš¨õ)¿V_³_€À(oMê¶¿2ÝÙÑ¡³kr0ÍÎg´}à3Zv~Ɉºªª°+Å9û'y£Š«†¦&~ŒÔ8Ô3JÇȶ³ˆô÷g·{@m•Ú;èr€¯Hû›Ôa~²&ë¿8ü 8Z³ j,Às¥œ€Q‹p0Ô @`F < ¦BÊšŠÈQÇUÜe‚Šd‚mÒº÷Æ;À Ó¤<&éÒÚ?°˜/z3¿cŒ[šqÉ‘]ˆß:¾¼Í^^‘«ºü‘ÆŽ gþ;âÒõ»Ô°»×´JÎy™HÞüÆôùCûd9–¼ïÒˆ¤´<Ú’$½ 4Vñ„"£Í\cI¤ñ¨ìZa?Ò2‰U!ÂTV”½:¦Í†\³!3Y¨1Š`qrW}‡ï³ØKy£lw|íYK\Îôv—4 èù‹³ú,D¥Â×|€òþyˆ QS“Å3¶F­— -1çMØ2v##=©¶F)j½@yN¬Ú>”)xˆºHŒ>,õ÷.&K—nÐ¥)ŠÑ²^€:v#¡²é —PÜR^l Œë¡³Žd‡¤`áÑ0ü×£µ龿ËfG)w5+ØN+$†§k¦bÀ·A·6­ãn¶-ÄåD.}Âú”}¨DÖƇÓ1/€7,ym@”Z©ðÝ.YMûŠ"ñš PŠ(ŠÉÙÑñ/_±å/'&Vuæ.Ã\5”¶¾ÿ2OS.5ت´ý8l5ÅfØØ)N'Uø¡Ñóæ7¥KL¡„ÒòFœ¬vB‹ýRzSÓ–"ª d¦óÍ ŒÄ[kÆË02Úײè:‘ý¬~ž¢AL4Ó‰üv<«<$¢.«(*LUê7ÒGbàÊËìV›vØ«x}L ”ø®€vÏH@+¥‹´Š¶†\0çh6D™oò Ì1Øàö0W¤nËtkò &S]f0ÖW†g< ,8rÌ!¼2‡'GÞ ¤ …Àn¼õEpâÏ̈‰k1»û/­Ïxk3*Ï·j«x®¡Elès¢,Q£aKx™*hFÚ2(Ú&Ø’÷J¨Þ"â&ЇFØTóCl¤É¢úüõˆÎ¥ñ,|ç¥w÷µzXòŒ ¯Eßçìž;…-LHú¶Ì /IÑ̵|¾e‘W3qÛ쫞° IÖ”’áûT†à‰=e^¶¡57áËQ"IéøÀfµÙºÛ²ãlp”‚‚B–-ÈHÙ]òÚ’üƒî¿>æ­=¸(‰ CIM½ ]i6ŒGR~/ ððtì`}=ös3Š&ö‘Å‚FÑêD±•ƒ_LóùÛ)JЋ„ò:Ã~¨Â(eV‰èpsÆ&CqfgG7*FðAûQࣟ5æ$¤ d¹\+×ç+ÞÚ öþ’j‰ÈÇ: Ã=,XJ7«=˜O4CVwA‘$C9lEýì QcB40õoäÞ|Uõ5›ÀY2{\]2õôÓVË«•k0tÀ ‡’hе[•¬û$0«ÃuÓýª‚ÐGãauIiCÁ¾A°š–Ôpè,7DˆÙ‹|ºš¿fàGŸ¬è.à…ýï4ÑDA7<•¬¥X’­ªeÏn"e&߆3ù^,(š'²¶¦ÔÊ£Þ çè´“êÓñ{Ñ\o<¡1Ú_Eq /ú-,ÄÛÆIÀ¼í|­Â ™vÐ ‘”«ýZ—@}$¨v؆K|…CèA}žA·•w9tý—_+ÂiH|ð„WâM%­÷Ú®Á°+¢ð·pIzÐíà‘½,¥£IP܆¤Ø¶2!GØNšú™[áQ1‘ ï³P‡·a~/Œ£îF#"Ö\âT¸$ä½äw…׊âý~œˆ´a˃(Á‚ÆCaC«¥úÒ5Hg”cVTÍÜù?xãÑBVºÝH‡ÊtåÙ£ÜEÜEI&–‘ƒgAçÂÈ­mjÿZhý<5m®±Õ®S]”´ÃMÛ¢Þ¶á}+˜G¼EuÀ–m,Ä­Š0!G#*ؤ”û|ßì‚ýü¹$ µƒÖ SÌð닳q¦ªôcõ—eX«8yÊ}<ègÏ@+ éYðq‚¡‘iÍÍœ'¤ñKÅD¦ðçé¤C‹ù26A"I Ùn#íÍq@7ÙTt¦¨IŠ ÜÂ>oÞDúrxðÛáÖç²Ê›/ýÑ(в5¹sÔk ©šW©=—éÖÊ@«Ø}BCâŽäá·}‡#74Ež”˜-¬e3|.³»?ù¬$'ùcÿ¯3¹á|ç2ç›Õ³Ýl8+³òþZ.³ðÅY›ÎL~#ˆ‹$‰¤u"töã(Z¿Ö ‚rÉ[Æ5Í$†P›?o5šÛM Ýÿ­‰)ˆ–›2àдI1ü™}‡Å^…±þCHùK,0—ZálHrÙ½[ýÇÕ’‡Ñ—"™aFïîË<öA[fnSÐPq]@úéÝþ¿?ùÒ˜$€¬hxÜ·UÑ‘ñÛ\áëÍþ¤èf3¿Ì؈ÍgD´¦©œïIˆ3QÊ-Gäø:öΟ+÷ “+i¡¢cˆ¥@™poŠOŠÅÆ`:â½joÎÍ[’Êø›S!½?Ÿòæ||ä˜lsJh‘—ÍÂÁÈ]¤Úªš†ˆÓùmïàýÖžh9ñÐn5*ÑXeŽëÛDlÁ_Ýhp™²ˆN7-É­‡˜€¢Æ9ÇŸ K.Î1¯’¶UI–kØk0ï ú­¢òwwÛBÁ©¢0HÏ;\¼‚œ»"À–ÏLe,"oÃ]3Ô¶0¢Ð?9‘%sØ®Éò3©raˆÌ16ÓžÉ0S0P.ª=I?¿ˆ²ê±°æ™ÚÌ]‰˜ ˆt”¥€ZáßRâœèz&·µ2²tðŠyPÝœIóR‹áäEø‚qZÛ¨(ŸªxP}å½ãjÊš{k]@ÍTéaH0’” Í7v'»:#c«­¨º¡'ÀHsÔã¸ã zúþËkúkib²åmW>Ó3cœ= Ÿr³­ˆCO¹Nè8‹´íJŽ}aY¼U”öŪÊÜbd Йßó éN”•¶/ÄòÌQçÇ„8¬¥úŠËCc7’“Ê õ /ýˆ¸óܰÂÄÃðó„¬Ã>@ëDa;ãDÚìÆêLi¼=8?¿ÚÎÈ¢ä4Ä‹ïJ†b4yÍÛ¯Ìò®y§v„ÔgÿÇ6Æoz:p$7¨~êð|pnD¢ª˜t‰MÃ!øúï×h¶šñ oŸ!¾ Ekkɘk|S‡SõY5þÅüä&šyó&v÷æ ue&eà¾7½‰DޱôZBÕ/¾{§1 S¿ìt£Áé*AWß)‘Èg±’í¬©w hþ.¿þ4’œÈxbÖiòE^s8+\'YêHÓ J  C8ޤx€ëó`s¯mÈ~T~‰LÔÙãþi,÷Ï׊Å&Îð”»Kžâ‰PߺfBѾÈë2cÞý¶Ó»Ðó [¸OtÉÜ1Æñ“ ‹fúBx»w"¾ß/Gäµ6y¾Õ Rˆx>ˆÕÕtösÚ¡2â)YÉáZè°Ð(8æygqÜ3Kâ0ûQ&ƒéÁL3š¿`>ˆ|Ž‚Ôs{ÉÌÄ#w >£]ò“”ů)ñæZ>Aw†ªJç§×Œr|_ mG‚Q7—ø»|¼7`–@*qØá”ÈW~OFâ5ov[f!à‹‰Wþ5'‡›-Éæ³ƒno9aXÎlYñ:;N 1'uöȈÀ€¢æGV !61XïšpÕ3â }#÷ÖEI·Ç$¤÷u½­{ºjð…fÍE=ìPm= DHô.$—mfy!’4™K¦Gž5%}-[¾Ö»6R¥æÑ7®€kÑ$…ÆuÔùZŠŒÛ“~!ÔDª†AØ…×?ÉWKû"tÈX ¯âÅ!Ì€¬€`zNq˜Œ¦&E)ð{ïrÈ7ÝÇ:mµfÁûµr½¼XTÝ‹#]:øÁ¡O»°§AèÌnÛ‚üaÜ_w»ý¥º(GGœ$îDÑ•¦ÄjåD‚ — ±¡S/‚zÜ,\]?s¸<&Û54 ªúg]ѵظ~Ûp»[©T£ƒ?Ò‘kkCbJôM )Bs¢Nõí>+zñDÆÔ‚â½NÆ­Šî4ìäöuD'íÆv‘ÑiÝÔ@¤iŒQ “v"8ˆÏ[ï8z³«zÁí7$ï@f '2”tá\ãÈ)eÌ£w•öÀ怸 Xj’Ìø˜·Íah^ A&nGC]hëó}ÌX%Rµ{£t¶ý5÷²È¸8tÛ$3ŒÅ”Øi´ðz‰M/ §Å ª%¢oüÞé€}¢Í£¼4“ˆ– Ã^÷.bòÓöß—f ÓMÀã›8P=cÊ)ëN¹bQ‰±È¶Vœ´ˆ×1¯ÙM²5£ : @Û#å+›¸ð%‘ã§©wEŠbNd‹vXLz`fá‹Áé¤}ÌK›á83@Å%)бkÚA„·§:Ò"JîW‘³±¾Žå῱C-Û8êÙñS4J‰]Š¢$Úñâþ°¼ø"ælI›±l™Sf#µÀ ç)LXcžYý=\O™iîµÇûê úóÑïÛòb+^ O=ÖU„™nñ.™½¤·^ûå¢<2á[s«±ûûNóÛö§­Ã&Vú¸»¿ó!Å2¤ÏZJk™tÆzEt[2TNÃ"J]LÌA´›“wâ¨úB t.ásþLÀ8îfF'Ï¿¦æ; J ¬Èypõ®©ÈH£dÁÃû_„Yh~>Únþ¾sXôþýoO=ÌFD1ÍhhŠÛŒ`6jž“ð›F’loQ‘ŒHŠÃm¡gaæ?Ð"Ãù6X×ݘLñ“yëTÜœ¥ª‹åQ)QÔA—o!h%•ŒE*;*ôzÐâR=¿• ©ñtè_Q ªÖ—=ÿ¿Jv¦“\ô%NYü?þRÇ,t&À„Þ;¯¶*mHøüæMÒq^òÄáR lø—™¥!Cl©Sy¾ÃcœÓ—LjÕIÓ’‘^M$ìì¦#iPõ'HÍHþØãoßrí[Í$k½®Ò v5tž [²oÀMRÓ¾ºÅ”¯Æ®Õóx‹'g22jœIš˜»ùâÞËtÍ %æÚ8¬pf+™ ¯Ò§ saždžÈ´žlÚQ,´ÚT<.¤Ö)²ù#nŠ´{¤*t⻦󠟃ÒÌžVREtÚïUà1Ó}}+UáAaG¹"KNH’8ªê+‰mÓ?h'Ž&ø%;ÒúaóI•¸NÂF½9¸˜ª² ’ OöØGÄt[6æ`›S¿×îˆü©ÊœVSN?ê„€_uç•7„ÂÛaKG€…±IÒè½t¿›yën( ‚PúšËeFeú¦Ó=‹w×g"jmÌP`Ù= ÂüR›hD%lð£2¿Ô'b =ø0Í/‹7s â¸gFe­{˜I˜ãЗn<·6žþù™ï,ßj²%ðÄ&l~Y¹õìKä)cÀü²z'è(! gƒóKe! +ÜäX*H…ª 14\)’Þ5Ùr¹LÙ_â¡À³"¿¹|#ù“«¹K…5©˜ô ?ì•o©| ­vŒ8«—˜…×ëÉôèóJx øÚ8ÕëðR pjTDfeq~Ÿøª+•?¶Ôl†ÈG å”çOì*v¨½ÑûúLÊÇ‘n^M4ç®’í_U ê®.ËaE¨ÛS¢^'è÷“É³É RÕQq¼šxBÉJ' nO¥$×+F$Æœ'MÖÄd’ «é;}zÏ@ÚaLgG8`݈‹!ʱïaÉòK~Û:ܳó¨ùåëѧf¡^YY(Î踅5N¹e¤ªàëÃH¡2jò"§•ω9TDÊ=ó}fÎI@íGíkY$‚CÄd3SN 0qgzØXø|^Š(Ç¡ Tù‘¥œœ&J)âN˜ Йs&Žê¢«®`P’\b#A ¾¬bšJŒkõÆŸH0`á_†œ„*º{"Ÿ%Ÿ,ž›WŠH!-Z¢nK@a7 Oº‰ ×IžëÉ "NFê#oï#aÔ¥ ZÖYm!q"} |iŠò‚¼½ÑÈw[ ;%Øã]æv".NúŠ)=üH™ù¤3ãð* r¾Š÷~M ^—Ç¿™Â#ôЇ 4á÷¥ ¢†0Œ:?û÷ÏtµúMº‰í{3˜ÁÖœ}çUV²ÞØ>t¿á}ŸwÞŠº™ ’o0¦xÏ9dÝïš05Ú8ýæ g¶Ä)çaŸ«ªˆPH9Š-GÝε(Ñ£»lœŽ‹pKÆàdWeµÿ>ì2OÅ5äè:¼JµEÎÏ¢Íþ`¬ÿTGs#Î1Å­šœŽÔN $+3F:§žÑÔ”ƒ °(‡ï v [Ê– غw2ë êI)Ã)Á&÷†]„‡WŸ"±p樂³ˆÞ 1>«ø×gÆ•:ˆ¼åÀÔ!Ø$cËT-$3aâý¿òRË„%yªÁ6Nç&N€‰s.ÜZ4Ú^ê,L\÷8›k?*¹ˆíÏ•©^á•_¤”(ùB5 ©~ s°$s…gkaI ìÕdÊÓFãÕæ”*P·TUŒE¶+g©LO߈£¥÷IâK(›£#§ÌÌvtÁ,µeß6±¸Äÿž}•@ä’g®2KÕ‘eŽ3Ó8MÅt¥E©@aá ¯ùK{âzƒýΛ©!ªbi@°íȇÝDY& âgR )€›–ùåÓ ¿!ÄÞîfÁ¨Cˆ‘E€÷ŸÒý‚}*šG%£ØM³›ÓF¼¥»Z[“™òå‘…˜—,‹P3€¬A«o¢g=?,d"8DPjqé5þ³®™’åѸ÷Þ¥Kè^:y«›4`=&…‚Oñè­e@•ÈÝ-ñà€yþ —Æ­¦¿ÕnJõvcƼºª^£O^Pñɪ0“QÛ’§Ò{jàHŽ@‡üÚPmM¬™…ýŒ bb~ýžŽ“Òt³‘sžämZ•óÒävçÄu ºÊ!aTóê&ô2.© •K,¹Ë5ùŒ‹6,&ÜVg˜§/’‡e’LµÜÖ#ŠÌÅ] ]ïŽ ¸´ÌÊ#qZG3ÛµÏ@¶øRЂlâð‡pûR¾ñcu"jÚôì¬Ý§´R\ĽÿKÈ×éÄMã,U†X”*Ïê$Le³lÔÄ3» RYµugmXžT ¾¤.;\ÎNHËt¥³*ÌØ>L{Íq6²Yù–%X;û˜§mk¯¹}°OàßÂûTTÖÀ>°¤ŠìnxKv¡$½Î³¦¿8¥÷̤ƒ’<÷˜D£Í%äTI°Ìè Ö£†BæÀÍ ý¢í%B:£/ÆX欪ÒâÒl7È+)=ièí+SîÜ$™ˆçsòŠÇD’¼¯®µ ª±‚ÒE…¤8^Ï3¢&Bÿ«Xö"ÀÏo^ â³&VÞ(ÄqžŠª~:m5ÖØHîà!;wcAˆÖ[ïÈÔ~<ÿœ¹óÕëIðÅ´ÇŠÐV¼P×*çY %Í“Á%£âµy¹1Û#•äb‹“I,J°áfrq6#×É*Áç÷Ž‚@ÚÎôÂ1]þϵB$ãMr]klVt?; ËbÕǖߥá çN/ˆþMñ.¸j>É kõwcÖ–’ÿ¼qä~^Yª<·‹zÙΘl{d^<––‘Ön¸'Fr01wɳ†U0áÓ,Qcœ ÕÂfÅ 2g»­6˜.®ÃÞ‡NÇç0ŽÉ¢-.K•÷YYô©€ŸœÛö+ÜQîÐ+DôýP‰'Ÿ+—“›CÔ“¼d;º¸æh¥êBe±$óeÀØéç­N‡ƒ™ˆØ‚Þ¥N0z´CDïñ€oLtÛÔ/èmq4èµøŠ¶¸Œ¹0â’¨.Ø“·í¨BXÔÆYɯX £¨ß§:ŸäÚhË‚æ-ˆ–ÌÁ¦*¬Ÿý514ÒR$^!FF7Ô ¹= 0Yú°ˆü$ðÁ·"°4»ðsÉÜfÏ"ö@ z|‡ç˜Q.w С9˜-h¯ ßà—Ës›±ˆ²TÄ5j ôåhôVe@8‡M× ýN¬/‹¬°QÏÁ˜Ü¾?ªü Ë "ÊÕ¨-‰Ä?<³.ƒ‹z±ˆ"TUm¨fPL2 †r޹q;”´ »¶M´Ì·41'DtÒ¿Bâ‘÷8UèçÊÁ¢[x‰h+ŽÅ H–~Ú=òŽ>6¾mîxðùËáÁï»v>xïÿ ?îxÛ_þy¸ûÛ§†÷é`ïÃÎá‘·µÿžî7wßmQÙÈ­#hv÷ñàSg}Ù:lìnÝÛ:ô¾|=ürp´ãáü>ìmïmí~ÞùPƬÍûÞÎï ï{GŸ¶ööìéR¨ê·ýCœƒ9]¬¸·‹Ç¬ØÍöÃîáÎv§¥?ma{têèËÎö.|¼ìÀ¤¶ÿY`vþÏW´8¶ö¼[Ÿ·~ƒ9Fciûë!å£F”}}ÔØm|mìx¿| ´íþ¾»½s´îíâ¾íÐ`>l5¶¨{€ˆƒ7àóû¯G»„BÊx}øõ AEXóo€!é´þ@¸>ØÇ93íìþA#>h5JÞ·O;ðüÑKXÛBtà9ÐvÃ| ºdÒÄô|½ýßövÛÙßÞÁзݣ",Þî¾°KE@·_iî¸h06Z®69—hu½ÝÞÖ‡ßwqüâ} ‡£]A>„¾íOûÚšBBòQ½ùÿFNM¾>oI6¾VÍ"¹Ž–j”þÓÿ÷ØÕáBÂñžöNQ†ÎKxå3]pJd•å‡Åé~ž$‘…ÀË× öQ_¨Þ%_Ÿûy›ê ç$ÃÎàE‘/HhytbÏXblnÎÛæô(2P䊚›#?‘™ ŸÖ~§©ÍïC²½¿5>‹§_éùQóS3Y¶cÂÖiuí®!dµ°cÀ™¶>7ñkvu7Öœ¨l2*ò ¼œc68LH¯±”¡HTŸ”{ ˆHa%᪑Pqº1È.£~•õ«}ɤ1ú÷ꇩÐóñå| (›z¥§»Ý“ˆkÍšO„†ªÚ½òü&õ¢Âün“:+Š’²ôkA¼U,‰|ÌðBA¿ù7ú]LnbäѦ·ÖUm,ÎlvGcT\weu7!0¨ï W\vÝ’²Ä…õ”†·àm=…HÏ®H RÀŠR¹7ѹ¡Û½ÂãϨ(Ç–«Ø¶ðµ2cSûr+ Ž[ö€Šl|P|ó€2\Å”šð?(k–™ ¤œ¢.¥˜¢<Ÿí³wô]µe ÉLºCAkE~æÏçc{q9Oθàï>ø¥Õ‹Ì:‚kô¯"‚åó2EãcP8¦ŽìêiË&#…Ña€——wyR¸@Û04\+˜»ÃX° ‰°²“¥fÿ· ZúžL¥*{S&Ö.fžÎozUý&©k'÷N`ëc7Áˆ²¡H2‹¿m^bp§(Te0æPBZ¼_TÉXšÃ#™àû‰fvtÄeØÃzlÞ²_.6AÀH„M§âèfÓ»ž¿[AY}#åP¬µ¤Á‹AëC%^´ÒõYDúCÓe»í*R¯còÖNÄIŠñ©!”ù3ssä%T?$ up¾íKŸ2w«±šµ³TÙZ±’ÜÆ\Mu߆fVëɾ@±Ú†N¾)ò#•ˆÞ1C!å™Qƒ°ˆ³ !MLb~s+˜ˆ ­¦¡éùmwðK. \ÁügÕÛFcÒ‹ƒs rh‰¬z’<%åQêÞ³©jŽ;Ï@ú‡@EKÚ…xÕ¹jÐ) ˜¿v©¬(2#)*Ò¡$mκۗUSy!^ëvÂþ5‡MFô³@wŸ¿ CV@n‚mª$‡‘Xsöâ©›ziŒ‰T·±•‘£¶-¬±•nQp¬nQIצ0óc˜ü Î"éNñÝ;{Ž” qÑ›zNŠh^ñ, åd›ØÝX¬ÐI†°X²4zþE?…w8Qt[ƒŽezؘŒœ+ÌŠa°¼.fJœ€wÛ,[ ]Snñuã¹rgª­dþzÑï¡xO‡u âüÒêÙÇJÞ] ûæ,¼Z0εi–?°Úe­¤ZÀ5n\ ¯eú<¿)8‚©– %í …«ãɺûå÷Š‘…W°§2ú!ûÙ}¯›úßQ' ©ÆN•Z£j!ÁÉͺNG›j˦ó›é¶ÙMéÌê*4`_‚y󦜩7o ! ZÉ€¼YrwQÜ¿?³;d+oç]Teí,/ÏÌê„§ ï<{ÖG9AiØ®(§@ÜÄ`5Ãè%CégÁˆ’"ºT"þûßrl‚eÍïdâ—‰GñK–E@@_ôÂK`ÈNz!ºï³ôOÀ.6@ËÓè%ð5dEpz{ò7ÚŽ1ˆþ •Ä6r›{›ÜNqå|ž*Űðb‡J5E“ĸ31ŸB¨ ŽH¤%ò»±p ºa?ƒ›¦‡’ÇW•}H<ÑV‘ÓP ò]†:,;áÌ‘¢ìÆpňS.BeKú1Ú‘â‘!¿iᕽ–JňïŠ}| ²ò‡ª¢n$GÇ5Ää꺆’mÒÈø7#)‘„,å \\R§T¾™)½=Š„ÑA‰Ï¸òá9xwº ƒØ,ÁØ µ09©çÊÒ"ë&Æ7sÚN. eÏÏ”*YÚH:Ë&¯¤º¬"6{ÓjÅr˜%“»m0²l¢aBYÒuªE–4NC4¤g±Ò!bV)IÇÖ&ÐbRr1Á„Å^âRkçÆVÈmKû…ZZŒ̯ï‚×2"S,O¼ÛˆT³XÖ’nuÊQÔW‘0yéæ¿Uö¶9vMx[fdéäfRçÜnf}%N:Ï”*÷—È0í§ê!Š©}«ª¦¸?q˜Fb€¼K¥êón·Õ£~Õ z¬‰ 0 ‰Ö.±Ûòªl×´dtèÅýàBjvküZ“o*Kør³ÿµÃßo¨ÿNÎfaÛï´8G ‡]r‘Š.©Cz_l'%ƒ”ûdbÞn ýnpå)!›¢$&UòxZ¿˜PŒê±aâÄîÎÚ¼ÊJÿ³×7S-øÛ¨¥MãȲr8º˜JÒÐ)yT«G˜pæPÑz ø¯,ÑeZKž v‡—Láõ6V\Y®õí=MÛõ¼i f²ã>{äE]fÃ5:›hJ²G»âµF]¦»Öt^{¾³nÏããBÈD2Þ;ê6V² ÚÄDÑV  5e!+åÚl„é=¿É”·n“?TXhŠÃ&&bšå¤8FÒ„2¶{.Š&Ï`®À @Ÿ5sà‡üEó¡½Ð 3 þ™wœb”Þ(énšGJxÚeg<á$®²Ä+m÷¤†•œ±¸û>šõðo‘N£uY¢Õ3×Gôf³Súí'çÍòkkrxFN„œ–¬Ê‹Â"vÔaŽzEñx/뱿ò+W3UNU"/zƒR¢Ó0-ú¾¸Nϼ5lUíRQ2VAÞê¹9>11d’‚{‹ ä½qVÖ'8ý=k}õ @<±a5Zr˜2EóÑs#¾ák)ç1ñ'„,«°0dئ;%~ØÎ:*Ϙ\Hë#¨_ç’ßÌPÍóÚ!×Ö…ÝÃÇ"‹ÀøZîvM ˜°¢æ‹"«²-c!H*>—AéŠ(<-ÈÊ=>Ò™ÿØ÷[ßKÊàUÜY”™é„ßE0òzâ(Tû:êŠXFj CÀ+JCrJr‡ÞV=Ïèë#û·燷†÷ZH´*~ò1ªïJ¿W¥Óš†zžÔËGô{ozºœ¬ ~_šºÑSÀækZE—ކä5:q=–TS“>®GPëm~®k´›c˨×ÎrU|ù¨õòÕ' ÌcAy1îuK¿§ÅTÛ9t "÷ÐUšÖ™»1N'Déñ)%) g>: B•(шH… $Ï©£A>:™g¿“àcšeÒd<ñ„5©D(ó‡Ú{"Y5 zMŠÅ„ÎoÂÊ¢ggî=¨¹—ðŠ¢1vkSÏfb·°ä”BªüáÔQcDï>ªÊ=ª……™Å°8¢L¢fC ÄmàV§­ç#öи àÍ£¼¢*sùNLJãW-–„%©v‰A70æ&šM•fsËæé@æzß–‘ý‚ *õ-*ÔÒ¥ry6w|=cW—v†I\p­iö:¶½“|…L,ãñM”9#í\ñ'ÕükLcÖ§’t »2iÎí5ªÒ'T^»$›s|*V]} ^‹/ü® pÐèÓ‰ää(QÁG7 ÃÚ²V†+¥¶ñ|gVâðN3¬F‹‚ 53az ‡{»ØWQówœm[¬.jŠid4¶Ð=VH¶Ž#–eˆeò˜ÑÄ(>‹ø]z“/"i_‘+SX±òHM¿Sþ-5¼ *Óü%±*ñ)§’À‹v´Cð«DçîþQïm5vš,è¶ŽvT¤pë,Šb3;T “`Û«)ÿ“ãâòŸˆOü:dµJfü.âG4ÝÑÍxè:ÍÇ…¬wÐöç5ë%òù“ð¬”-&eqιÔT\OäKõª@²_ÌÚmé¹äÔ­)& ýÖ´v˜$Éœu[gRë>£"Fåö®r™S†ˆ<èIû߃­nû®Vp•yº‹“užÚ†š“ÍŽµÏx3åœJªICiËŒü¹+œ[[u©ªï(DŠ:yïõ‚V^а+èT÷}­SrqñT¸D),à£)Ôˆiðtø» [AÙ{?ÈØ¼x…tv…|߀‚ÂÉ>Ôùðå·_L5 l“îãF& UiTŽ–ª¯hÐ åp8K…qî“·%ˆjÃfeðÄàd›ãp?»I"0.Ñã‘pÊ šÇ]6‚ þ™ÁÜFq¯ÄDî€iå’”f_²† œá‹ ùÔHD€áBC¡S0z«58§£7±gQÏì³=aÆÃÛ÷½º—â‚T,#ÚµÁj6\Ì€3ˆU¨’1’~$î²aJ ÌA×i¿ñ 9þ.ùL^‹}ÌN4!ü62/Ú;X[‡´Ó÷¯˜eæû X6þ™½¨9!CˆíA±ÿX[‘çìoðãïh¬å¨)m ¹•ׯ @%°úŠeâÝ9Ö¨éjr‹¹V—±Ò·MdñYÐeGdú¤¯ž4ø|T`F„'טñ­Ûû×&hÜâ»m&?É€úµö2‡¨1}'â cÅ» ºaíQÜè·Ô¸8õgãñzƒ®4ωœ¾î7!1é–åI¨î+>£jîB ÐÅ¡¶¬J` qe†EùZ’¼F¤ÌGâ1î g‚ÍËH·°ÀŽÍÐÄÙ8&Æ…Úݾ"ÉØ¼"‹lMœH[W©„2aðW“QŒRòñgŸÜÇeä‚4¤‡[9tH`ôɔ¥ä:LC"ö¯ûâÓ^ð¯AØ“ÇÿœÁH„L–Å{*Æ´±lõöñÚ´U·.Áª|ÊQ—½“*)ÂÙ©ëN RΣ®½K/`KÁü8ôLÈJVô¶¾i¡µ©B&ÒŠll¥Æ=Ú^7ß`¸É 1Ôê”klçCå‹Ôt}zØ¥huÖn_¹nðßbÉ~»Y°k ¤¥ÂñK/˜ º+u—Iu†¯ÐO†¶©¯gY i9)Ú&iÕŠð  Ö}DÅC®#$‡Ôzà.QGÙDì\ôäÝj{þê6B·ð`köWy4'“–ñvY±Ì “ %4Ú*íô?ºõŠpe.“ð¯b,‡‘ˆÚzû1Š(ËàB½·O|÷Ò’[O½Oƒ Ä ý¦Üß œOž? ÕâxT‹,sKoâ92õšÂÔ“& É…fYç¯4îÈÅÞ,Hg mä›§?°Ã+ÆšÓÈÿ¬Ié —‘þa¹1Ì#Ñ1¶…u×CÂr¥ƒÍ@Bó·ñfœÉ½çHrŒl›Íª™ã6Ç‚`’&%Ù‘ÄèðFcƉÍè y㢭 4ñ„‘óp¸/Û§¸ÀçB‡Æá>_&á{êÛ–ÖvD‡t€VÖôs­_³‰s Ùxz-#XѧȨ;Áz«Œÿ0ñdm¤=ñ·„µÔ*œ:\[ÓY0:[;D°3ò¶>csxåõ«­{oÞˆŸtèS Pô½óæD ß©EÕYÃB£Ií {ÇÈYÈ0öä+<‰$ 7o¸…ž’çbG0-n4¿Ù¥Ó‹•d©—š s²­zV,‹ ÃøQ¢û&på1#ãmüª_”LÈx¿Šàt²9!ƒ '^Áû%ž2ƽ ?Ñ I(=ï²ÐúÆ›};«á'š¼y§ k~Sÿx¬G¦G.’`éPqžžàaÙ}”'¨•T ‚ë÷mZÍ]\ƒ\LÁz†8Lo9uœ$hW¿«¶žü¹„á†&µêÃjš‰ubm]uÐÇ—z¶€ EC…™´Ž”u²Y˜Óc ‹E«+Œj7þ“Céówݯ:%c òN¸_S”nœÑô5ÝòådTxíã&”!0ý2“=½AŸìøª¼Ù$é¤ÜŠݾ9'.¿›Ñᇚ|hš^ÜbŠö¼&›Ijð°ý‚ž5úôû‰h‡äîÓöåmb&uçœ% ÎÞðåV“2-—²ÞÊ ²Èkƒ% Ó·,ʉWíÄqŠÔsAÛvuò× µ”±ÍØ rô¿^ȯù¯5¿‡‘}yo&×ÉTûç7Ó§8zŽKú©œAò×™ä,5fì‡BÜÏÈg–¾b»11«k¶¡Ll±uØekK}Rº®¸<—aÒ—u¹Õ‰>7r3²¸ô›R%ÝŒ÷ó^ecŠæ¶©¹–!þT…Ìe§`òM³ëBæpìðÆ”Bplké·²_ÐáwÃqäm¦ÇÉzéRJâ~D¦Bº™V‰…wñlØØkû}_^ãTŽ{– +ÜtG‰ü[‘—¡º›)J‰w²Ã©ÔÞ_Ab#N|A>o”qJÙ…J3H[Œry´"ðŠøè°»|9–µíÐÆ#UÙ¡­“šìЗ¥6 /™xú*ˆi&x¯VÊÍé$^Òê‘9êÄK8¼‚câ'TAŽLí'[3åå(„«*ï£p»>“F}§œ16bC¥Èh3Çj[7îÒe€”ú—¢¿WëMª¦5Å­s€Ú‚•¨Ä`¦uQ´á)„\•Ö€dÚUDp k‹Ù ü%›kjÊ[¦âãû+ñ VÆe^ã®Å/aìwºƒsäôÂ_EïOQ|GÕþuóµ&P{ð:ê^¹Ê{ƒ ‘Ä,Ó(£¸åüÃú9Å…u¿e¯hÒ„¾Y,™t•Áȹ/ÞÃᤎ&à¹QŠ^ÿBå¿!â6tP;Fœ[GóqYjèíΑêÐ3æB”Å‘o•¢»'Ä›´=¾$ÔV93ÑC—‘0éõÝv¨¨æm}UæŒýÏÈ·Œ+ØÆð²¼8ÊßÄ‹z]¦çI;¬• lºiÚA‡7ÌÂÃR­Œ¾ã¥1/Òqª¸4Và¹P5Øó”¾©’ÜÞÞìÌ:°.gd»Ö‡ÀCüõ!Õœi:ˆ“‘OQ§ô²N³Ï†œšùýF „äBÓtê¡9µþ¸Ë,¯«ç7ÓŽïÞ%0búK²[ªóCA晡ír¡Äòç”Û[˜&a—ö/¨drÆèB( úˆIj1£™…nËâÈœöV\ ã›èꢼüví‰~l8š#Å@ä®ß›Ç‹nÊÕ.‰Sþ—ŸÄ;AQ© ܆ß*ŠÃkk[Ç©`YVqyw©/êFS"Û+Î2`¤‹Æ}z…ÏxÃǾɗ˜6Êk¥»·ñ Þ1‰#*Ï%.À vË]`õa ˆ<^=ôèêf •‡ØÄSz »a7“¡ßdÞ&Q¤<õéø×wùÃOãâ%eJMŽ+YÝ==ð̈Ìôˆ ¹¾ÛÒe9œäªÐšüñ²'³WšÅŸVX§B//dÆmÊ»MRÂ(ÈÊc‰Hi&S ¸6ò7ªiÄWmÄ?0¾A÷«z—Uí%ø ªŒÿR*…su*¥:dQÔwDáØ‹d~©¥W¬–·b5kÅàOÍ»¬e-|¨Á‡Ú4¬ ™yÞþ±6Ë[›`yÕwDüÍ–ÛüRO¯}=oíëYkêÞe}( Hü_Öák}ê)"Ý¢>dR¿™¨ï¸Xw@6æ—Å4 -æÑÐâ‚?‹Þåâ$¤ÏáÃâÓ¤©ôÃÅ© ´Å;$4õ—ö® ¯dçÞk,¥)q)—FS"üYò.—2 RÒ¡ ËA‡%ø°ôŒ(3ÌÒTíÒ=’­úŽqïdlþºœ¦éå<š^›¦áϲw¹l’¶¤è$ÇÍ'mø° –_ §[,Oá/? á«ïH>»Ì/+é]±’·+V&Ý’+ÞåÊpudŒÍ¡6Ö |]yÑ{%ýpe*6ÐÊ#n õ‰í7”ùe5½»Vóv×êÄ»‹§ª6Ùªw¹z×› ž¯Â‡U·Û’»-ÌêTlÅÕ)ÚŠê;’è´lMóKe!Ã˽·S+ 7ݪŒµc¡‹ËʽíÙBG¸ nûN´}Ó-Sq¨°0Å»Z‡Èz:÷yJ%ë|«’»ó+wºóKØ?|¨Ü˜È/Á0€©‹ŠãwÀ 2žNÉÁcåIñý„vÂSáÖïGµ•ܳÚJõ~x~€•ê¤ÌDò¤V1&3ÁØI¥êøÊ½ñ•|@•é8Y¯TŸ8×ÑOh=M>d}ËG¨äÆ#Tj÷Ì•ð€¬ÔÆdO’+å=ã²' H2)ü ;«Ô¿z$~•Ñf:H*µgÇÅôÚ}ϯYß2o*¹‘7•úCq9ü@+õEaLÊîKëd»ÃØQ¥î8ßTq¾Œ§Ó)U©¿~¨ŸÐ†}~Òú–dVÉ2«,>8¿Ä¶²x»h¡ûbœø»ª,:úxèHÓ"XY|‘V?¡½þÜyn RF€e%7²²ôx\?àÊÒE¸e°cчúG²c »¬,9þüäùsF›éˆ­,9®]±ÆÊLâåñqë÷ŒãJnŒqey ¸ºT–"e"ö®xºdòš½ãGì´²ì8ý3åôO§#P¼²ìøÿ×Oˆ£¼t‰`}˶¯äFÛWV¦A>ÈuÔР‹ÊÊø;¬¸ë/Kf 47'*+N¢Œ-QôbFNƘ2Æú–q¥’{¥²:ÅŸC'•ÕŽ•Í=JÞd8¢F‰üˆ]Vܵ'…´Êh3W‰*«N6ÝB6é'Ä¿œ´Ê—VÖü3îdUsïdUž‚ìÂÑüêÂãÅhkÉ5ü4e¤Sp„(Ãy`ÏUwÛÌIµQR-cͦã†]uÁɺ;•ugÄøœôWú%!U3n*Vso*V+OJâ€_­LÑ퀉£‚“¶ñ Áˆ±çª»ƒédäÍdd>¤êtÜ?­Vœ½g ªŸÏt2õæ2Õú=+år~ÎåêÓ”°ø\Λ)9¢VÁêN͵ø‘¦çn(;©{R7£Í”ä;¯:Yüà²X?!6ë¤ó]Igë[Æíöjîíöjí‰Ëjü𫵩¿uB[ß7Àž«îÞ¾“â'Å3žNG®‚jÍÉö)íú ñg'íïGÚ[ß2r>Tss>TëÏEöã€_­?½»x¥*jvRÐJ~Äž«.›…Ó[i:2yTëN[˜JmA?!Öîô‡‡Ð¬oQª¹Qª‹ÏN›P@`Ö—Õŧµ'G­PºD†‡!S­ÀØgÕåzqÆtkm¦#¿MÕå·y*z‡~BrÀi"¯‰¤ eä ªææ ª.=?ÝDR£VR —ê’SR2”üˆ}V]î#§¯gÕú–‘˽–›Ë½VsìP V©!bj.UÊUVÁc9R•Õ^jB­ËRït[§ÛÞ§n;Òtd诹 ýN󽙿«Ÿ wºðËÑ…­o•j¹•ju§׌å~Ò*2ôR«;ù‘Tdü {®¹N[vÚòãiËm¦£nEÍÕ­p:ô]éÐú ‰}§U¿T­Úú–Qÿ£–[ÿ£¶ètì騸z©-º\–沜HÙV¶T¹3•müˆ=×\e§w;½{ÚôÓQͥ檹8müþ´qý„4§Ÿ;ýi!)£*N-·*NmÉiì·ÓØñÀ¯-¹ü©7ÏŸš£º+}=Ã[>JuÇØgÍÕûqZ¼Ó⟆?ÒtÔ:ª¹ZGNÇH_?!%ÃiýNëÏÖú­ß3jFÕrkFÕ– pG6~øµe—»÷Nr÷j `xèÌHc@Á&þ†=×\5,g8ëà9Xm¦£XÍUs6ÃãÚ ú i'ΊpVÄ8V„õ-£’Z-·’ZmÅÙwmSà€_[qÙ£ï= àhãBYéóøÀØsÍÕˆsv†³3ž¯‘ñt:êâÕ\]ÊÚzd¤á£Ïа纫+ê,!g 9KÈ´„2vÜtÔR­»ZªÎ>zŠö‘¦=R¢œÅä,¦»µ˜’ê5ië¹5ië®&íCÚP ¬Èe½â’Ð>~Ú‰Œ)GšTÚ˜ÂØsÝUÛuv•³«œ]5Ú®Êx:†ë®Â°³¶ž‡µ¥ŸÆåì/gÝ·ýeýžQ©¹ž[©¹î*5?¨5&¹‚6Ë —zÕ™eÏÒ,ÃØsÝÕ vš³Ðœ…vS -R}:êo×]ýmg¿=WûM?!eÍYt΢{X‹Îú–QǼž[Ǽîê˜Oƒ}‡Ï¡—zÍÕ¥™ªº49†ž‚“Ò8ÊÐÃØgÝÕfw6Ÿ³ùœÍw?6_F›é¨G_wõè%ør,Aý„ô;g:Ûð1mCë[=ÃR¬çZŠug)N“¥ˆõuWiZë!i8ÃoÁ4Õ59a8âo´¬ugC:ÒÙΆ|@2ãi}:,˺³,eù‚-Ký„Cgk:[szlMëÛb†å¹˜ky.:Ës*-Oüðë‹® ד©Â5‘ ªìÎôÙ¥a‚âGìéÀY£ÎuÖ¨³FÙiq:lÕEg«:[ÕÙª†­ªŸNé¬Wg½N«õš‚´”aÏ.åÚ³KΞn{?üú’«÷ÄK+˜†­Z®¡A¹Ù†-~Ä>‘$œël\gã:wªmÜŒ6KÓaù.9Ë×Y¾Îòjùê'¤†:[ØÙÂOǶ~_ΰŒ—s-ãeg?Ë?üú²«>èL䤉¬á`ÏH#Îfv6³³™Íüm挧ËÓaI/;KÚYÒÎ’žÐ’ÖOHu¶µ³­Ÿªmm}[ɰ´Wr-ígi?5K?üúŠ«{ùÜê^–nhr+8ÒðÖ&7~Äž‘\œõí¬og};ëûÙXßC ­L‡m¾âlsg›;ÛüÖ¶¹~Bª¯³Öµþ<¬uëÛj†í¾šk»¯:ÛýÉÚîôR_u…}ž{aŸ#^Yî§ç™F<~Ä>‘fœ=ïìygÏ;{þ…ØómV§ÃÊ_uV¾³ò•V¾~Bz²³ûÝÿí~‹(Ò^€Å…øü~wg6ûî~cçpkÏÛýüeoçóÎ~c«±{°[þ÷Ðð¾íÀKøçÐÛ>ø°S†VØPèQAì]SñNzѹÛÜÛö1ġ߾µ­¾È—øIÐFÇ×ôºß;c9•šYL}ŒözHÃQuø…ûS*^•xßš°$úßn·ôNüV°á­­Aû~Ø=…à| 2Ø6½MÛžÛÁIþûÔCÞ"N—?.Á#“ ieó•wªl­ìwªøNµ(ÞYƒ÷›…ST¶OA׆P–öú¿ãýgȤÞ,ߥžvûIì¨9mÎyïƒÓ°›Ðš…héWžl\蟅q ‡Fÿ”¹‘þ‘O„šh ;Ýöä#°‘Ñ?}Ï’LQL‚v† ŒÇ¢iÅÓcÉZÈì¹ûq0|ù³HDm‰ôËkk¡Å+¯5èõ`ŸE_cvPÍê@'’'ΨYÀ ¥Æóhý‰r)”‹¶×ú0¯åw:(_Ð&¸Žºíùèd¾çwOO.K,Ä4‚þÎ/¢.éqòï|0DŽM`Ÿ!ªnekº¤ð‰!6Äèaç½~á—­þŽÚ^øß›7j ä#Gj9šÞ»w¼l”ç¿Ê…^W?*ˆõðç¤ë9«ÙîªòÉb7sÈo2»1H¡P™+¾sj’¬l®'GQÇÛù|ŒMŽ2lRïNLˆá“ â‹äoŒ)N `ït0 Hìþ™ß§÷”† Éí  y…ç ]!uv½vtÕE‹¤,š²²ýigûÍBr7!P7åÄEc×olx³ è T‰S˜¨ç÷QSSÄë3yû=ƒú½ÙDSRSÚáÉIÐK(³ø{Üo¯­1vÖ-(±<Ç:@“Fé½3`oŸ­ïAûƒ˜n#Újá²á:lØ06 ¯¤9¤°ù-à]Ø Ð¬2†à‚ãv×@ý3ï" »}¹Yáqh¬J/ˆ/‚V?¼ xÿÆe¯ ˆ+qæ_÷®çƒ:Ö ƒþ5®Ü‰Ÿ‘—4`°zg>@!œ‚¹×é{b[—ímP½W¯LÜÌoJ.àýûßMcj ã²[Mõ/¯^¥Ts‘[„±ë)i¼«¤¯EJd1ÒgCèH¹%~åoÆï,ÂøWúlü¦¥ÿ®¾'áW-øÕüª¿š¿š€o²Õ¡Ì‘¹ ²öÌ×äÝŠÇ'{Ì ˜¶bC…95Ó’7—^*š727II)n•³;¼ ?fÞ$D~déwu”΢Kü ¡e‰À3?è~ë,h›Ã~Ìm¢Ï#bZq‹Þ½´³Ð}wKŽÃ%IÑë33yZ^¶´ã7 Ým4¤À?¿šÄÒaüôl °¢ÂyàHŒs’Jsî÷€}ôbà@–@Ac¶ýˆGÊwQ"É%)ÏL¨ßÊ­¹>qCZµuû8shƒ„î1Žlk2“44Hg¼ •K-tb£’ ´Îë3˜^[“‹;s—ŽÂü3܆éuAón}&ßšAs cMqfâ`‹‘>ˆÚí|x&;©‚ی鋨ÝÚQÊùµ†¿Öò=ð¡jc»,jÓಠQk¡ _¦Ã™Áã¢ñ8çÆ=:7†wÀ4?fµ¬jSï=I¡]láG 5¤æ\0ä‚©e¹`jR;­e¹`jÊSËrÁTS.çÜqÎçÜqλvîd6¨å6¨9oP¦7(¿fÁ¯%à× øµ øµüÚ”z›ôçÚ‹õ†_>ÔáC}l]}ºt4úg:]vÆ å8+ï)»òÆÙ‡cvPÏê þ2|…) Ä•l ü(¤®€ÔÃñ‘Žõ,‡c]õ,·`]¹ëYnÁÚ0‡£se:W¦se:Wæssef6¨ç6¨;ßç£ø>ðëüz~Ý€_Ï€_OÀ¯?ߪ©«yêyÝù\s|®™¿ê‘óÉ:Ÿ¬óÉfúd'°˜mkb’†Æ&¯AÂì¹½ã¸þÐŽãú:Žó}#èþ×±\Ÿ¹Ã$Y#½Ì‹wãeÆlE7õ4sÛ1½Í‹Sàm΃°ˆ¿.N⋆‹ðaql§ôâSsJÓ éŸ§å¦6ÆíÜÖÎm=Äm=¼æ cv°˜ÕÁ¢ó‹íO!îjáG ‹ È¢s®?’s}1˹¾(­ÇÅ,Gõ¢rT/f9ªëÃ\àÎmïÜöÎmïÜöÎmonûÌ‹¹ ŸÿYúùð-ø‹ ø‹üÅ ø‹ ø‹OøA¿³èÎnx¦ù»¡5º3wæàΞî™Ã.Ûœ¤¡Á)Æk0Yo0²øÐ#‹St0’ï,}̸ü ¼ågvÉó£y¹Iw ù¬$‡wÀò^~FGÞùîw<„÷H|ùáŽÄÍ/+#ÏÇWîï|¼„ýßÁ9Ãóœ|圓‡°‚ï¬ÜÑYº©ÿŸ®À£•±×W^Öñz ñCÿ<ïwžçŒAî ÞÄ»ƒø[ÄÃÑÇì`%«ƒwÒÿROúS@HŠÛ@øQÈŠ²âÂ)\`%+\`EºòV²›WÔaóJÖaóò°clˆà\ ‚ Dp.á¥"d6XÉm°â"\ä Œ\HÀ_±à¯$à¯ðW2à¯$à¯<óÈýyÅEILi”Dæï†éå¢(\…‹¢pQ.ŠâIDQLà5·½g“44Ãx n¾Û‡z¬MÌùu]½«è3b…‘¬Â£Õ±ÃHV_zI 1Fÿ¼ÌÀcþ.ÐÄš¸@“©4ÞK—1;XÍê`ÕE²¸H–[D²¤€6báG « Ȫ ‡y¤p˜Õ¬p˜Ué“]Í yXU!«Y!+Â)\  ´q6.ÐÆÚ¸@hóè6™ Vs¬ºÈ™ã"sî<2'Õ‚¿š€¿jÀ_Í€¿š€¿ú‚"²á¬ºˆ '”ù»aºˆ!1ä"†\Ä‹rCw14ÁŠí¤¡!½Ækp×Þ>¬iõ¡ÃšV]X“ kÊ?ÌÃCùqÞV§!ìÉüRYUY¸ÿ(¨äC¡À1ã¡* . jŒ€¨á „¬…›ÂÀœ„½0v,± ¡J„P1ù_V%¾kŒ¸@+hå­^v Õx"oÜ­¶¹×\4—‹æzìh®4±±‚• 7ñ0Ip šâ\`Ø#†Á*dD†ÁSyø°¥C¿«%ψÓYäâÎ\Ü™‹;sqg.îÌŹ¸3w¦ãÎ2e$så\¨š Us¡jO.T-¹¿ì ¶Üa æ[ÈÚc ÉM¶àâŒwLNé¢ãžUt\æï–ïâç\üœ‹Ÿsñs.~ÎÅϽ¨ø¹IÎÖî쉚šbvÌ&IÿûíCý* ëWYpÁ~cû 9¦Ð‘qÃ+ 333ðÚî~cçpkÏÛýüeoçóÎ~c«±{°+üáÀÛ?hx_và%üsèm|Ø)C+lø)èÀs7AŒþÍ˰Š˜?Ç!9¢¯Bòÿu®Ï£ÞÅYØòNôpvóמßéDW ]Ô4o´ûMtî%fýuÍ©P A‰º ŒõÃã9¿ÒHuÈ##D# ä%žTóâ?EvЫš‚9¯R×P4Œ—xZÅ–üX5Ž+«¹ oÉM–ÄL^à⦷™/5A{e&à™Bî’Ue ý~ŒÜ£ÕÄÕÞÈØß›€Ó&ö: ðUÌŒ’º7ž%–9ƒ_é%·ù”Æó§¡»S€Ÿ™ˆjSOjÃé¸6šŽkÐqÉszC5F4渤n…%ß„î1`÷¶´/aŒGÿ5³Õýîñ^§±ÞeËÔn±eÒÔÅ¢|Œ­T»íVÔm?­ß`õѬ~',õ~# ' ‚¾Ñþ³®Üt3bôü]lH g¼MYO¶œª9Þë4]X¿GÙÇõ{ØÇ©çuVÅÇØßõûÙß©÷‡ïøÅÑ;~ñw|êé"ßè2Äí‚uOè6ÜïÖ܇°Æã‹Y­Ÿ2§ïuÂÐÁ£0–Åd,©ç‹lÛÁpŠá¤ž, gAK£YÐÒƒ³ L(Kxyàv7µî˜KÉíaÜg¼-ãÂKwɼ$¼ñØR„ÄÄÆ{ Tõ( +^žbVœz¾ÌGIc°èåibÑ™°V†3î•ÑŒ{eêwêé Þ>½«dfŽN[ðÀÞJ÷q'ìJ–¿r,¿$àŽÇöWFAr¬ÿŽXÿx¯ÓÒ­?ФXy‚’"õ|eŒ‚ibºÓ/ARï­—)«£eÊê•)™PV´¢ØãˆDq½;’AXÊ¡Õû’CFRªÕñeÒê8Eùœ\z¹4Þë´Ú°wEŒ­>#1–æxc$ÆhxŠâ-õ$?•ϲ²0Zä©DtÏGæ¥ÞÇHÓGJ7b1™|ñ…$B—‚’²)Þ¤4ºQ'.+ Á–ð}t¼×™^p_>ŠÄÍ sn"7=¯…qÂÒ%†ff~Å[á ½ËÉ7>m5·>¿ßÝß™™ùI? ‹/üVà…x!°ëwR?Æ5<à—­Ã­ÏMüj½Á/ìîoï}ý°Ó”ß8B^|å–_»ð`gçp«±ó¡ù© `Fv©QWÄ€õƒn ‰Œ¢ç øËm“2s}ˆûߢè´Ì€xƒ˜²f"”ÃÞT ÅÞ pxº2PÔáÿà­Y—½oxñÖÏø có$ü–ÕïöCØ,mCÁýÔ6Ü ã.Y#mõhÓ=ÌlîAà¸ðò®ðŽÃd”™%ø× À”Xb.mïøš~P=HŒìrƒ“o úb·o‰ûð({ŠžÅÇ(¢QÊ•Äthý³^‹Âr‰Ë j5±²ÄNeeMŒ)ZÂV9ñÛ7€A\hètÓûÛ+—ËÞÏuÑÉ© Z–¨EóyÀÏ?óßñûæ;»ûG­ýÆ.Pb“ÓÕlí@#|÷H ²ä)t!=.ðLVÂpÎ!^†ÁÍÂ:6éJßîkCitR(G‹¸oÍS;ºîFq¯i¸€î^Ÿ2¹ñ¡œUvä¹|ôNð5è®þ`èÏ›J‰Ayâ;HwÀpÉûYÎê[w×;BK ñss ûÐà¿9‡W_d@ÙŸÝàè,ì¶:ƒ6Ýd/ÚÁù!Hš§JÌbQv:öþ†f€Xóúϲ†*auL`If™'…S¡IË Ö|ןÓð˜é•DNÊ´tî_c>:¿{Mœû´çw¼¨'GpÒ‰|dóœ3ˆZÀ |dv=qw»Ícx1>¹Y¡`oƒØi‡ÄL×$¸9o·¯Rà±÷ñnPƨ…vQ‚.–ÓM­wßÀ»ý9O)œÄ#X™š„JúU4Oïzè¢xÔÙɆzu‡d,9d/ÀGö~¼ ;ÏïÄ‘\tµZÛEbÝ6ôªKŒ†€`è#ê8&þœÑ“'[êû¸ýaA×®´ÍaØ»] øvcsFŠðµµ¤Â¶)(µá‰}×àm¬[óŽ&#C˜C Ie ýua¼f‚ßLs`—?³éO>kàinUá¾Û̲w1ø‰ÐøòœbÒøfسEWŒ™3pQ"4_.[ÐËäת7Vå^á•ßëù×Å?öÿ“{šTÙWò=VC ¤’Þö|Ü¿†CÐË]oËq¾ÒC¾Ët½£Æž„…=]ë^oI§‰_‡ NEñ‡è†¨Cr<Ð~PÑ )'бJƒB×)ã@ÂÒéQ0qØß@¯°Q·9[ •Ê/u£.È(ærꀑ‹•L)ÿXŸ:3³FÇÌ7Ï}‚ juŽBJ:AšðÎá×ýæÖÞ©*G…¢Ç˹XªU¨ ™ZZœ­Óõ{€cÔl”GXFÚÂ_äÐs³'Q4[òfýÞ,ëpðñf•G$×:ó{(ذmüÇ_Þ;ïo»µ!.Wñâ1iÕë¨×c,iÂ]ýk’ wòæ ¤!GÎÄÜgýY1]5Ùµ5Jx´„#†¾rãM°Þú_$ûàÎâ‚Ð8½M/×ù­ËòÅ >kû­ï还õøX=<ÿ”Ê}z·a‰rµ¬Mÿg¡jè›jU2g®ÖH-“–µÆ‚™ë…cL/PÊœxí¿¦•y}ü:±20îo 1Ú«pÓka¼ŒRñ£n諘óËñëÄB((?³‡Ô}‘1¬õq—­:t5$òÆ[²Ž®)ÑÙ¡y½2„4(ÔW~¯­r[æ‹ìÃÃj¸)õûF£ç‡ýx# 6%^@ ›3j°‰×¤TI>VʬCs«±Hw·1$³<ÍhÝI'[ÊÖ¡äôd Êhnˆ·|M T­ð`œÞþpj¨¢bêVêEú¹Ä ‡÷ÆÛOŽAx§¤tÒ½­zÙZqÝ¥q:‘©ÎdŽS+#жõ#YÄÔ %$B´Œ4? ~\tÂVØï\{˜r5$E74FË)Q A}½D'ºw) mø¸K-!*x—û²{Ëôí'ß3Û †«\TRFÝ¥7XdRø“·GIÄ<¶µ?8×’\ô œ(6Tqb‘þÞÿ5nkÐÂj//–Z€(iIËX¹%Hµƒ Ê~Ç¢|CKмD?å3þ(Ìp˜ù1DI¶S³VÃÒ3É;×%MÂQ.¦[Ampq!Ii™çbæ¾#p[¸a+tÒ"I±”“cù%š.+ù¼&™R# ŠJeauŽO€rGŽA'Â`Rw,‰œY ­YƒÃ¼ËÚÈ1ÚÉ ä–„†7kâ~xV©{ØC¿{—õ‘sHßíÖó(!€[Ï%qµ5k™WGGOް‹ÞåâÈyfßNµçZB@w;ßTÉ¿lä^=†ž=!‚‘€-¼Ë¥‘¸È¿è–ÆG Þ3N7_²†<ôÉM„ ½Ë呸~y%_BÕÃüCb.Qž5›‘1Ù™¨dš/ •ØÞ»\‰ÑÑqá ¬JŒ-–¨'èæÑ0›šÌšâXa†·G5‚ñ.WGb|¼¨GëãŠH¬—°»éÀ|2.'S‘Y¿ò¨µ¼ gôj8€±0ZÍt…KUà/ÍžÍÅ)QÏÓ¸BI(•<}µ2.VÄ*U*㨠c,œG‹‡ °1”å ÇË#Α´©¥,ÑžÆzZ¿ç•êØØ"bMª÷¹ÄøÀUF%7=¢/Ñhžâª[ßrì¯Jm2,\±rµ!ü+£MÀIç¢)‚ú¸Y”h\OŸ6¬o9o¥~J!àb}ëK.ø@VF›Ý“Î,A7ÔÑM‰Gi•ú³£#ë[Ž·¡²x[ª*ð[’³TÆqH‹ú†£]“Î3‹Æx¦7 4EcØáàˆŸ7µ¥ å8{*KwB%êá¦DÈ ²ì–‰ˆP @WF;ž&y.EòÜ'#KE‘‚ *²,ÑØ_mZ¿çxÝ*ËwG©%êfšÈ•FF;'ÅÃpºeLŒM¼ŠnMno‰fñ²)Øú–ãþ¬¬Ü1=—¨¯‰‰š¡ ñÝQÓÐàÃh‡ì¤Xƒº/㸢šAâ%š£sMçÖ·oteõ>¨¾DŽOú k´Ût,ÒcòÏ'}#|í"ŸGãîÆÒ¨ 7A¶¹–·J43·òvƒ5ÿœ‚ê½íõ:Ñ)vé¶DÊ–cl, mô©Å¤›h§0Άm¹Uò½C·K‰æèöÌx{& ©šsfS­Üï.*Q×Om+ѨáÃè3¤Iñ7ùžb æm,¹©†» Go¬ÍÖí®›î.ë÷¼°ºêìµõ‹¸šñ7œ<ØÉ±m&ÚpâØž6M>ŒjX}ÝÇ8+¸å†[PEðF,ÑìÝn¼›Ýh}Ë9Ù¬Öjo–hwBô¨”æFŸ¶Vk·SÃcGEÝÑv-Üž½=k}Ë9q®Öt—h$ÏlÓ¤àÃèSðjý÷3ã[nj¹';=ÏÝÔÊ•i(ÃzS—#ngßÿζ¾åÄT~Ÿ—h8whª7»Œ–u`0Îf#³-Ù!›fFÇ%Tc×3ö' ¤gë«]Ÿ´ƒ[¿D¸qûÿ¡÷ RNTFué‘8‚ÜiK«6Œ-X£\ã°5Mø2:R¤ºôhæ³FÅSž· ÖX"<;þø|ù£õ-/ nmº¹e‰†>ÝW«§ƒe¦àà ‹kÓÏ;yÝïñÆì1ÐaÜqÑ—ÂE­o9Ñãµúà©%ÿ¹¸?Œ±ŠIæšLÄX?eæšb¬„2ø0:¢½V"–©à¾oZlVqØìâ¡l¶D¸w¼öeòZë[N<mñ©pÞMâÉÞe—yf=û\7¡Ûæ³_Â|}Ç ¶ø”ø0ÓăÜÎ×|xH¸Îhf\¢UpÙqäZjLµœµ¥'Å£K4ǨoŨ ‰ðaôÚÒ“ãØL!Ñá¦l[Ýveæ]¢UqÜqð,nýžs륶üôøy‰¦ó<ÛÜ©Klåx–'aêR.@µÑ7qjËO“Ã3ÍeùP¢‰9!qŸB‚p FßY«­>uiÁôôÈ™‡Fˆ %-’>þ„È(Ñš9¹áäÆíä†E 97öê O^Š”hvÏ>å[†(‘É"F2Ž#J„aq’/JÙ€ÈÑ·ë ÏB¦(Xõ…GÎT•,Jœäg –­ž“.NºÜ¥tIBªçÜ¡¬Wž‡¼‘G—cl¡#DLž 3†ÐÁ½>ú^g½òܤÍ}²›•´õêŽ_ÊA%ZG'‡œº_9dýžs«µ^}&R‰&,DSÕ‰¦ÇM ýðeôMÛzõYÊ©ÑßteÅ+ÝVXéw³×É­‡•[Ö·œÛÆõÚs’b4kÁKkN”=º(çÐC}ô èzíùÊ4ÂÂ4fS¼©`S2 Ûáüp…tsÒíñ¤›õ-çx½þìdM]pܺxÓ#ðð"|ôÍôzý™K>BÅÔfáœLü)É'¬;%þJ´ÖN:8-2Ðú–s;¿¾ø¼%b‰¦îR9‹BŽŒG,Ê3Nf¹b‘V>ŒÎP_| ò‘)uª3·Ž#$U|‰éµ…d‰VÝIJ')§SR¦ ådM¨/½ÙY¢ù»ü¸${¼¡hOØ–cPZ"ø0:“C}éÅHR¦ÛéÏö›/N•$M(fˆÓ­¿“©N¦>™jýž“Ç¢¾üR$l‰àÄìS³´Vðat^úòË’·LÅO$Cô ÝQ‚“¼Nò>MÉk}ËÉ*R_yQr¸D˜pž”0–° ‡úèL'õ•(™™®ŸRfqC<+Éœe;T<—ˆ&œŒv2ú9Èhë[Nž—úêË“Ø%B‡+Ÿq“òc‰m+/ j"±-’E·Û´‚ðatî™úêK•ßLåO.#½–ßC®ÊŒâ%¢'É$~’Ü"ÊœÌ;‹ /T®—'.çÿÝäü×Â]Àã<Žp‹˜°ËS–Ögt6 Å…-噿Ÿrƒ›ŠzeÍ¿DÔBRÿí[ï}u EÏït¢«Ø; ºAÏï‡ÝS¯ÄýØ» ûgÞ…ß> ay¾}/:ñ '~'€ÑöA± ÀÞÑu7ºˆÃxMÇOž7/h3¢›¨ç]ô¢ö …ýÅÿöþ½«$ɇ¿ó*ªé³F¢… ¾ồͬ ÂÖ³X$ÆÝ¿é9u ©€Z‹*F%3=Þ×þÄ5/u‘¦{.Û}vÇHÊKdfddddÄ'â¿ÎâtKŸñ8¾ŽS àg§—/ÚKo$y0Ëã‹Ù8¸½ŠS"›f£8˜^EÓ`ƒüåA–q”ãè2o{Ùõy’Â0³4ÇÖ`,׳ñ4¹Ç\$Báó˜GÜAšÇ2¦5Æ$†Þ°%(2Ë¡sl‹ÛŽaJ/fé»04‘WÐA†S¤ÆŸ£kìæ^f;á"øHÈãà¨Ù§qÀ\ àklè6 @]’æÓ(&Ò8½M†qi¹hî‚(Ñô)%Ãq”ç嶃íàfv>N†:™ÛÛøõhó›|uCß1Cëù)™Lg0Ÿ²dôãéÙM£©¿06@!Îgð:xO©0ù‚ÿÐÿôŽúƒÎÑ ×tÃA·?÷:ýnxÒÀ‰î S´ÊÔ¶d%¨A8ÞÇ0ëŽÜ£ÞÞ*Ÿ éÂ쎠”#ÐådÚßÉEð–Èy×é‡{ÇïßôŽºþËžÁNœÓLùV# €»¯3àËØP€ù=Ɔ>Q×È|Q°M`Îà:.@ûkz•åNõ5³'*÷šÒ{ ü/H„v»M}å„aáÏ“ìZG]Iµ©„¥©˜mUúv=¿Ó†*ém§¢m“Xÿ*ú'׳k-í’¨ÂÇ$(Ið{’jÈ8ÇÁÛ,»·á–Q"»,x¶å#‘C3ëHG"iÔI“ëhL¢"ކW YYâ`#HŠ<ÊÛD[cuMWa»vöþ«Ùò¿üð®7è6[Ô?Ê.Â$ºÜ¸‚’üÀœ‹æ:­àíiçG)|Ù±òÎR¯ ¾HÞ1K ᔀ ¸Š&ë-îk7)KO­Ó ¢œ8iØZÒÛa–}Ì@27¹‚5"+ý)š$|8µ¢[JuÕºùEœÉäÒ”5çVÔÿ¤¢L!O²ˆÖÅR>IH|à¹öÉŒ…$Úm¦j9Ž·çJ÷[+ó­€…ý’'üÓÉóä(ô­p‹˜Ïÿî™r¶nÔoÛ¡$nZi›hÖ‡~ª8óðâ„x¼e!Û;¸ËfV€HYj<(Û ÏâÁm¶è8^†=ùü5'7óW…éɜۮéÀ|é!H™3è„ wÙxOž½r›pjRH)æ­m‹> .¡xáÛgðmŠÐ={oˆ*޽\Ö#Ø,~Õ—ÏÏÉóªZn+ŸÒ·ÏáÛç÷šµ¥èóg°…}<æ,,N懋§÷ÅäsóN«;ÝzÓ+µô~}q¯ÅX~4ÞxÊËÓž•%ª*ýrñº½|ÀºµÜ~Í5,Õy ß¾¼×ʾ|ÐÊz#®^åRò[éª/¿_¼üßåò·ÜÞþñ¬Púö{øöû{1È÷_Í ÞœÔ3K )û'c˜º&~·˜“~÷ˆœÔr{þgåªÚ–~¿þî^<÷»Gå9oöæó_ )ýWáÁªÒ¿_̘¿ÿ…³åRñ¯É¤¥:¿‡o/Öýý/ƺÞü.fãRþ/ÍÊU_þa1ÿáWàïBý?ü[ñ{éÛ?À·¸×.øÃ¯² Zî ,·#Z8’¿]Q×ÄÖæâý²µùkl˜±.ÿþ»§¶¥­MÞæ½v×=Vìq×Ì_µåw\‹†ˆÛîÛ NGÉ)Ëïi+øÒ6Š/ðÉDŒžhß ñ¹!DÎn‘½—þl?Aÿl&æ–ØByØé÷ãÎûn¸¨nÉŽlË?s þq[Šß»4,‘ÊžÙM¤o²Ñ]£¹#M’O Œ´§n†ÈAg4d§ñe’O'wØ ¥}Û¿ÏÒ„Ì®ÛÛoãiŒòøÑÜØ5o0ÉßâQH”ML[mÓ/-5±9‰¦ÈÌm¯üñí6ÜJøß·Å (puX;ŇÙ^JMâaxÐ;ì†a þ:îÃ& § ++.E“_p~™4¾­Rò>žFѶÄÝ«Úæpϼ*$Ôk¹k_»M—";6õ›/eVºtÖ8"½ G³ëë»PHë §½7gƒnxvtÖïî‡;ßï÷úÃÃã°[O~ ;Gû! ¢÷öȽwˆ à ÿƒD.ÙÄ‚i³=lo×ûµiåÞtooö%€6÷³ò`…Øâ »Á$ÜÔ<ãëqÍ«LÑQ³ ¿‰‡ÉÅ]tE ¿á_rÑwx|{Χø’…ÏG$óÙÅEò™ÅÏ#|FΧëZÂ/ô¦‡ü*›GA4Æ7Sz6à'zz­÷Þî謗^d¯X¦ÓçÛåg_áï|:ÚÞ†)‡zú~mš9o§ƒ¬O¿Rý#C‚þ ç³d<Õçk•ãó€Ó€M©?Žžö虲²ý†}´AÚ›£ &0ͦÁm6ùˆ]@ù8í{ÿm|6Ž2úf¾óàV½yÒ,Ý uz× fiò×Y̳pÝÁtŽïP˜F0žN¯×Ö¢ñÍU”ÂO`·ãó4È$ôù^g)ˆñ|˜áÓž=`ë÷n&ðûçVIð˜Ù"?>B+¥bÁׯoG~¦…5Ûwè·ßr×ß„÷·ß†]X ÓbH§ ðƒ¡jG$N·óû´#·„ CkjÎ}6­×d™=ª…ÔÊÉR.¾Žef+aø§NØ9}Û‡C±A‰5btáÀç‹~G6þ_V3Êžñq¨k‚¨ÓmSWàÉ=™ü‘Zb¦®o¬bø++_H?'t  áQ¥½ŸtN;ïI„TèížíwCþÄÿk+„ïBv“º¹›$—WÓàÙæ&ÞGÈO)è¥CòEèŒÇýœÃV‚“íS¸H€^Ü{ßݽéú ºê ‚þ;¸_øÃÅvŽ?uOq îpƒ7] ´óæ°‹ÝÑh÷{§Ý½Ëþµ“D’;Rÿ¤»×ƒ¿a^º0¨Îé-i¶ßýï³.ªB‡Á~ç}ç-Œ±±xv`‘öÎN»ï‘v˜’þÙ›þ 7€C4x{|¼OÓÞïžþ©·×íï‡Ç}š88]‰˜ýΠCÝC+0qPþ~sÖïÑöŽÝÓÓ³“Aïø¨ kþf(íàÙLs}|„cfÞéŸþˆMã|Ðj Ç^¾?Åé¥Yëàtôaöön1è&“fÇußöÞvöºXàúÐëw›°x½>èQçÀÐí h£å:ðÙ¹E«ô‚ÎþŸzH¿”~è÷„}húöÞÉìë¶èÌ`M¶ƒÛ(ýÏKÚÍí!ÜNÿ(ºw—QÚ”²²Û÷¾ûŽŒ+(zP'Aeœ5^Q%/eA(‹Q7N.@U¾˜wtïã¡õ­(Ñ‹K"q0bà.›i̲…~ò‘e»™i<Ä#ç:Fï^ñ§Û± lXçà´×…Û7ö2k8ɰÅQ AöÓ»bFè—˜pÐÃ… Pj®Ðcì;þò½ëýÝýË΄j—×I¼Þ¾¿{úŒŒ³¢COCj³w¢–䂯ÑëgN¤ãÏ޲GäAMoN½½ÖO¥äö¶¥Þõu4ë鎥þÂþÓ O¬ ¥¤}k­Jð‰üV—ÔŒ„iŠ:ÑïÓ‰~Ó‰~Ó‰~Ó‰~Ó‰~Ó‰H'º¾ŠgãØS‹ÞG“³£÷ñÁrJWšO‡ãHìWI–_ÜŽvo>Åh_Þ]Y)Yàxæ­€"4:q”ÿ”&I GYÊñ¦ ™àÓlögÃa Ê¥µ¡DÀ/ãªTè(K¢i4>ˆ’ñlçÂR6›ºª)IŠ¡¥T×­h:ºz,²Ažß (Æ‚ƒÛô.´ÂƒÝ[ƒYµµ0­ds1¤A€ÀÀ~O¦[^ª67ÐßFw¹èÐegKBœl“b7'1*æÑŠ ¨qúeŽÅ¦ý4½QˆÏ­²Å͉ƒB0¬Z–K¢ 7 1ˆ5äX¿…­ÿäÑ%l|}ØFÂÓÒ´ÕM¯ø›ù¼~ÁQóÇ`u*;?9uz°¶óÑ)”Ï®¯A… ÝÏS|„èóç†%Ñ),_…ίÄ_dÝ߯S~‘="7»Ih è1 þ”zžó<@“°SnN" HeÝ,ñ¡^À ÙÇàf¡’—M¸!š«u¦5`ªôcšÝ¦HŠ»&f-Yîs€]ˆ6=ô@©?r»ÛîoÃøïZ“"AÎ÷·Œ¿±U5ä=giË“ê²AÅÜ èô^Èþ—õ-Î’”.÷¢|df Ü“4‰ò1rà»*Æ>‡¸J¥r‡Ê‹åOõYp2ƒù¾(° üÈg’Wj(kx7š Þ¥;¸ ‘i:àu|ó€ðµñ…õø®Øü$¿„óûÅ‹{ °²ïå;.÷j,Ž|wîÇ«3áW5’| ?r(Ûhó%Äaâfá¾=ä_6•žÁ#ˆ$ÛI¹vâmm—<+cv,”(,L¸!‚Z²Qíõò…ºw Ó¿c¨¢>umäçâpt÷ÖÔ2ÒU (@oùèPs²SÓ´G×O‚ìF³_5 ?äêïç·óD”×&÷ÖAwp}+;Ì—VF ¼§V#%$‰%•RnÉÓL+ ›°iç†1Tp}/Ჟƒ¦M´’`ŶúÃp­Æ¢iòå´RT§N¿ Ük>Í rJiZ_l_ž› Ùª‹8©êÚâ+T¯–n3Pl4OþfN•_Óð•è•ßâ.·Á’i‘£UÅò WåΊ‰Ê§‡ï ”L¸Ýòà*»ÅE«U;Ö½\ðÄ+“ø-ŸRñxÒ3­y\¢®Œÿ» –aÏ÷‘‹e.s¯ƒM¦½Lê ¿Ü&iðWñö©eˆ`/~†ùëžþÞý᤻7øÃÍhÐ9Ôû©ûWñð#Ê®›CiNøŽozÒ¤2ž2¸‚€ „ͨƒíÌx|{Tî éQš}Y—n6oâ<¡Òò Hñ{ nc¶§J¥Q {%g Q<Ž/‰H¾6ãïtdebyœ\üû4žf“ä2Á©,À)„¯€gaÕJÛ{ º§GC²ˆ‘Õ§ƒæ™`#Ø?¦{ÙY¿K¦üƒì:oO;ï+$Ó»(?ŠoÝSü-æŠç¤{/.­k’uiÃÃË{ çî¨&så!0PHKÊ’–šÊb¤c»Ò¤¾E:KÌÒºYðPWz9éS7S"‚ŠN#ºCïãN²ÐæTz©z9åw‘ÓßÞE~{ùí]ä·w‘ßÞE~óa_‘e^D~<éîçÄ%žD¼òŽ.P…R ¶œ #uÍ@ÙŸ7<ÇYþ±ÍPéFô‘‘í6F(DÒ¦ÔáË “£ã«. .D°#XNl¥n;~Ìf,³ñNWùdx%Ñ'flj|RH~À%J ±t(oï@ ]ã‹Ö¡î»MlåÉÝ1dâ¢à"ùŒøTÆW‚Ã.¬žk÷÷&BïxèPò4f—vtÁ™ôrìyŒ´+ËwEÝ<ȲùÞ&Žòˆ'P‰ÜB×7œÌWƒÝà0Áë±ø ` ÈG¬zqÔ@h.eGñg˜ cŸ„!éIÈ à›+ч¤% $°ž¢ðÇdÜÄ&¨= ŸRy ø…H/Úb4Ê‘­ˆ|Æ[f;GÕ®%Ãén°ZÓN ’÷ ­U-Ôä0 QÑè&—Ö÷wT`gÅaŒhÈ$·´„@z`‘g@âr¾À`„½™OáK²Ÿ ·â|ž3µæÌda©vÅ?©– ¹©·äÔ6ÔûlaÐÃÈv,ÝøÙ·¨ÉÌÆLŒ~zÇó«!'9o8Üì1²{ªíÌ¥d?‹ó7ã芟9/~r5oÁZ_0ŸãàÈù?\ÆS;f«ÈÓV?APÌÛ˜”ÑD›SµÃßv-ò›Ä%x¥¤ç°Œ›ù”äÉTÌêÆÿL÷̧$ Öp¬kúà´¥p7ǯ7v•ñÅ–˜I{²Kœ&Içc™;c42¶žþr[žHÙ»»Kƒï^û%Ì–3½™yN6&šRW«*ìËžiwÕéÕ ·î~Aý£û!ýÕ¾™åWáy4üØHé·âãËJ%À-êd‚öÄé]CD (9 Ù«Ð¦9ªŽZåè<'Û²Z(Ž"Ÿ/D÷²ëœ5‘9V¦·j"Ž+‹¨·ûÁ±SÏfG⃚ü­Þtï: Ä@ƒˆ+nmdZ˜eÈXEar`ɈB‚·£µÒMáÒ·èÜó¿ŸDi>¦«yP¦‰µ´‚HÂQátŽb”mHx”:&´ áS a³rI%Y‰f(£D–W®LÙ'øâ⯸æ Ùh`r€NAýMFE¸VÙ$†§B…—øØÍS˜’~HGB¡ ¤5ŽòÄ¥Òi^܉vCŸ@WB¢™®¿j>iAZLË,5!&&Õ4Éu2Ž&žŽàx Tk  q:ý÷Px«»‡½zâÒtÒa€'¹[ ¯ÐñAÊ5Nyx¢1Š 3«^Õ€¿¢m³*’c+";ãIs»x<#Š(iÎq…ê¿:!aOÂ9£«;-Q<ú'Õf¥lvû¯‘ΩyË}L’áÇ;²ân{>Ýjÿ5îV.ŸÇ0A´º*F {òZ$ân7VÖQÛcN¶3ŠÜº£¾RSƒcmLºÝå4U…¬P½½rÚ}ÛëÃõ1¬å“Ö¼8k]­Â¼íȦNññ¶e¤ìÅ$&‰S”Gî!ba¸••‰[•Ö7âq¤¶¯QÌ9亅o•VV«7Y“ðÑÇâú£ä¼oòÌ% Ê›ÂtºûKF†%³$¿rÎ¥Dâ!ÍÄ˸Z¢†LxâÝHnüÁ Ã]·K‰&ÂbD1þA‡TÚ†dö¢ ýn€_%†XÚŒs½TPÿw/¢¸ÄPïþ¡·ƒ{'÷_)#J+ïó:â„DÚæWîóLB${Çû] Í~уkVòZÒUºs¥/ûÜ~15<Ò¶!àÖ‚Á1™}~bĨ×#‚IáHSr ¦óðÛoÝß~À‚5šð5s\[N?Q…$ ùéÑ+*‚Ù wÝ”u¼Ääèâ5Eö¤XY‡WÙÇQÖvwר46¤¬™¾Ø^Ì4âöe[–´é€Ê.ˆ:Žç vÙjÈøﯸF° ¥pæ Hé\©"Ä¥º;2ð4z /‡9ÓÂÝÅ8u­{ïjZèU¹ƒŸ+ñitŠæTtnM;…ZÅÂö”ÞY,GÀBèLC¡†d•z(Ãeñ~¡îþŠŸ¸ 6ïC½ØIv¿­ŒáUíÇã2\Ìòk¸ëw5ë€COeJÑë« <.›¯ˆ/”k©4 Ð 6eÍ–fæy*óPf<L¥2`½(}™^c“­ðáÉ£‹x~%¥IšºéÊ+¦cÞA?WŸØkw’ŠÖ W²!?:ç‹ó›Ãe„]ôÉQ"J/í»¿ò•Î:TqÕú'½nñXÁ…¾´QsÕgÊ/qhRþ t¹×‡»‰Q”µYçS'ÊËÆ´Ìiêi!hƒ9S@R1´³q’÷ÉcÍŠ¼uþøèÓceëýfH/:MÄ&õóãˆpU9OÑAä£ÏÛB¬s›Wy1XF$ ’!¹¥Bí²S…‚Rɥ󕇊¢BaåEµ°ÔÿüõF;ûWZdÕ<ÝÅQW„c—ÑU–]Ƕ@Ùàïü/Ÿê­ÊC܃zÈ9^Ë |TW/EáWVœc°°¤xª{óä\Í_†ž¿rЗTýgú;cÊÍ”‡î”É’»îß‚:OZÒ°ä"›î©œ:Íùbp‘¥þ¥®vóo÷'‚ÎTyáóv㉀*9—ŠG½9`£¯ª/ ·KË–¹nT_WçÝ ¾=©A²z¤‹Â“eÙxîc¹Í³ø€êûrnˆ%?NxEÈ~¬` ¿âËI˱«Itb±<Þ}Š’1j(ä”vœ‡I:û̯W#öŽCÝ˲3øÑ8Ï`ó|”Ç[ÖÆøˆ´eÙƒà*Ê­‡ˆ}ÕŠòbÓçìÙˆå#×$è½(©úø£ÿfçôíáñ›ÎaˆžCGo)Ë!{Gè,ˆE°FN òSJ¸{d±áT"KÓ vKî<¡ɦ×¹Þ&yì¼óù˜€hêµÄdN“Ä󘥌¢¢ËIΈ˜hœD9Ñ–HyŠZ<›…7ÇQFÑÃó+’{wb´XZ¡x6Áù!­´][½ÏOP¼üœåÖz&Q V”®ÙÝCà'e™.e `øjc«²Š£Ì&øô^G+•»3ˆí /|)ál£~ .&dIRIßSdjƒ#ë6Ô¦B*r;B"A•M hû“E1\²ÉH¢ƒh!È’숳pI)ãQa¨&`vq1^Ä å<ÇÞñÙÌB¼¥¦˜R¨gå‚ð˜iŽàº}3½Zfà‘D&;g=ÉÒ¡"X$æX@‰aÏ–f$ÍG$°ãωb¿e—è™ÀÙq9|#Ýø[<ÉøaÛÑdªf’ú.Ÿãˆ5o°z•åÓm”*«Ñ¨0Ôþ†CÊhNEí·FŽdâapÔ«@ءҤ3 ÊŒÐ·?`‡h9»¦N&q³!÷N3ë›'FôQ"l7ì/åðy@kÜÎwjŒÃüø>úÜÇ,°¿ÃMmks³6€P2BÓÚrLÓŽ|·Ïâá-lœw¹X¥E»pbíÃ^¿ÂbúåQVù5ùFHþFüÙfÞ’ –®÷iómŸ¦f /s’趆KH(µ˜MÜ_ºp¸NµZ^[â”Å¢ùA±žOã!ìwuîÀoüúšwv›—†¨õñueÃpÝ/0¸Î ©“p²^zÆQâæBéÏ8_gå“jŒ•Šÿ˜5œ+À7¿>nMxP°þ&1[nó«ä†C³Œá<Í¡eî†ã„£Ñà¹Å&Œéö½&#Ç?,æœÑj ®)n ÝïêQZ•ƒ_бøÚ×twIic*r#͇°lnŒ¯»ìxKv?#ªyqõv«‰¾Å(-öòä³ËÓéo#|.".»˜Û $• ^1œ[’Ýd:ZÀ‹·f'xõ!Ž,8¾j ó;™ÃIr³XÜ ã¹£ >©5)Ñ âªÎ&_ª­vxÁ™=LfZІ¡R¶p£I7 óõÆwŒ©éB“ƒ”\7n³àf6¹É`ÕÄOÔ},…)¾™Är¯5ðéÇO´üš?ĵ™áÜdàæ°çppzÖ}*tû]ÀK&H‡À{3ä~tn“úϪˆÙÀó&¼@“éÑÒfé·„Áüqw'h·98>}߬·‚x:4Óå “¶ð8¥K³ØùrW¶aBi¬SE&â*øŸ:©Þ¡ÝF# þ#À쯃ͦÍY®ø"¥Í‚ïháxœÇKT4,¼z¤ø?«È Ùh´êä|W—LFcŠv8LÅ«×YʆŒê 9o¼l6‰xÒIH'ráqÌýI2Zl~]%¿CמmèÆ4^ ò{—èˆGÛâ":qQp špÝD=°Ï¹ñ¶,?ÙŠr²Pþ7,Q°¶ðŠMÇð#ï¢IL¼Š;Aã D¢ÈåÉ'‰Ö¥É$}»´‹„¡ù‹FŠÁøèqìð<*Þ ÍÐ óœý§" »À8OøD@Bµ@üP/É.úHÔøÎ!¯þçŠæI"Du`œ«ü´5|‡[Aºú ï–ÈlpׯÝ#ßÃq6È|ý¾Ì „\Ôø½©´)”ÉWøÍvp¢œ&ÿÊV†9”m&¡'¨7Š*OˆSFò9$'‚*g ÚQ€yEq¸$ÕMnû©íqš|Nü³Y޾MüdZ/朠@3ò2åŽ8÷86„«‡ÃŒð?ô@eb!² VZsïDt“Låî'Ûå.¶dq[\½©ÐЮK6Ëo÷¤»»þœ¶l@{ÁrÝ*~FR½ýöSjù–ÐݨXZØ:½‹ÂÌ¿lÙx…<Ž Ñù"{ìlZ*¸鼸qˆ€—X«„úQ\†"J&B=T`9ž‰÷…«Øð~7l'—I*ô"«\øö _·›$Œ7‡Ýð}/üÐ9=ê½í‡'gýwaãÅï77ƒ§ë(†‡87l'Â#Ÿן6W|Jq&ËÔÒ=/¦ÿ&OÂÒL&(4±iÓ>}B²Ñ ,ÝyµPçdÁºã™÷‰½ÛpßfPœEŒGí 6FYÎË…À›]9¯¼,tÍh£e Ùz©zÃäcw :] E×r‚‹ð°8­rÛ®v7ì"”©bŸ×ÖKÝ4x¢g£ÞM+ö³K¦™ÞÅ+ç*ùý¹gƽg‡ýjÐ*ö¼»½ML ¬ëNkO×Ùü3Y0ʦéú†ü¡ˆIó8ðø$l(ƒÉeÊÁ"‚QVÁòÀìu£tÃ"¶hÊü6ºièFpdÓ:²Ž AY‰çgow¹ "«}·Vá<ò`/‚Ö<>ì *@¹Lók¹œ¢YÚæ-æCO]]¬b. 9ß4æ€á޳æ.`‡ŒwO‰Ù…KµD°2Söh€Ö×á|[bú冢Ȧˆe‹Wâk|d"ß}j˵sh¶ÙÒçþna|¼=ã´D´4Ãé–wÊÒ Zsé-Ét¹Áe^ÆS(ñŽ5¿lì †&°øê*3 ¨ãýãÆ§q4;( Ím XÁ€šãèbJà. p‚Éð@ÝHH†ñÔÊA°ˆÑ8£nx?Àß-ñr=)!³ ZÒ"(P”-pxí$‰E¬HË$¸R~ÕïÎW¯Fr‘4Ñ}Ézï…ª÷†l8Õ¹ÜüÝÚá̹1•c2”—"|)Inf㈀mD[CD›1%ŠÏò+›ž Þç Å¸Æø‰uê=tºm6Š…øßæã/7V?†VÍYä/P„M)³œîc*¼XòéIPÀ0fm±°Y^û'€ù‘ϧ Î4ëX*e0v_E ¦hºj¿§’²©ÀµXpDziˆU²LÀ®Ø U†KçÁmš ÊRmÚUàÿÒ{]A¢£(¯¶\ç—÷#°°Q¡¾óÆdÀ$ÜœÂó3‚ Åj K©û4‹ÏƒèÍ-A¿òªç„0’½G«Ù=§l®&v_¿®¯d®à&•” (Ç^Ùƒ4LZ¨–ø¡R!7â'oáFR`¼A™ 6 Mè\‚60öƒGÅ@˜¡õ:°5É5€),´žä¬Ô ,ÄK¸¿x­¨m;$–êdUê¾0BŸo£&¹Ö¶^OiK÷ãéÙ ð^Š&g®ßn¡AMö³ÛtN9ÉOØ UâȘ˜Ò7Ѥé×+—ø›[bEÐITœi¾Œ`_ÿöì%¨²¯;ª7!ïäh )ÂŽ ùŽUŸ Wñ€è±f˜àVnäyXïi+èhz•¹ Ù ôÍNeEr¯nÕ—.€öhMpÕ?BÌTj5±`U¹]³mØSÍñ{ʧ3¸á0æ L8¡ä^Æ]ï ²©P&2XíÂÄ_1@º¥º9`œu.öÿp¸ Õ@à ž ç¼ÐŽc&z™•*öwM9ÐÈÚ}ÙeN!d&Ÿ1«IgýÙíþqÚ5HѸV9±Ê/4ƒEfÀ'8º7¸sˆ©Ók +:|¬Y¬húç¹mO˜Ýv=¬àv!Òä]”»°­2Üö‚ÖM~€9=I¢€wÒ`NîHaíM×͹£SíÀ\áJcþþ÷j2ª|ˆž ‘BõÜ™Ðz—Ö–‹Ô†÷#)ƒi‹&¢&é'q`ðÓ•¨¿žtÄJè&RJ,}ô˜æ°-íŠ 8N9¸Z,ŽØ{$êÔÇøŽ›ùÜP,ª ŽjùˆÔ\'v ÷–À”³i2N¦wÅ£ ÒâqT€ôrOrD›‚Öè4ñýG@­€ñŽf¨írSãä/ü©j0P^ 2¶@Ný”=0„ÉTc¹!§¤‹šF~…‘Š¡!·^Ø›èc‰œ7e\Wn4ÖOJHŽs¿ÄìÃ:±0N˜Î˜Œ|-¯¸È'Å=Në1Î./IQöi°c"„¾ü&ã0¢ˆ€›\’æÎ4K nì’œ˜ —5äÐA"Éé³íéÙQØ9<¤ˆ‡>¿-"€­ÝS’ÊA¨ÔMá8ÍÄ)PùN˜(]X¨[ðµÒÊTM‡3öܾ Gý hT¸ýÀiU¹Y#ÊÚÃ7"m`ÅÕ4ù ƒ\N4ÓD!sTµ¾ám¥"¹¨¬;ÕíܪV‘Ý)C–Ò&RÂGèŠr»mÂÈœ·ÅVôˆ/ð>4*—”¨Õ9=f©õàN-ŽÔ±~’²êêçl§'Ö"ŠGÕ¶%úoÙ6$´úøOÝÓÓÞ~—AkÎŽö(ôZ¬«€îà ­-“Á—.X(èÀW­ŠÕÒøGF®òø¤¥ò|“$ͼÀƈ3h§sö²#f(@ç,TVÆÉ9å8€ó…À‚"ŒNžåH ™,ÝKO7qœ´êÛGpŽÉMÛœ£Å5Pþåáæ†,¦¤t„tnè3u$G²q鬰›ðåçà°ó6ìw`]Â`WBøÐí5ÌÑyÒàC³SxÚ71ÊL½ýEôçìFܸr6 FÀ¨G&Šy b8ž°ãÛ礄º&G'(¶ŽÆj@ÑÝOŪ³Oœ‡UšGBã"à|S¨ ÀÑ ›pñDI=Õƒ|‰ºm‡S¸Â(6ß$Hâ"g‡WY§rÕ¦,†°-Îb¡­À)rG¥aŠÆL@4UÔ,¹2EçWOÀ $‹|¡º¸È"!Âöž2лñ¤IÐV$0öâj0–œZ:æîj· øᓸ]râ{€¹³™5UÅɨ±\>™Ê‹«06L®À–Ä—ñ¨‚1Yd’q“¾ 9ö,Ô¿V/‚xEô:O´~XA†!à»ïæ°7&[¯Ÿ‹{bO šI*T8NìÁiÂÚl=[ð„3Ðr>%s ÅY€{ec93á§ì6UvãÜßnÑì¨RFó'²dòÝãÞ«v¹ }Âkü6tý=jÏÍ —«ÂêF ýUmê¹Wy¢ñÓEÊárouîªuÜèÒòp%ÛÌS ÏÞ!—±ãê.û²c½œvÄh§ŠŸírëÙi-£&¬Á È(ÊÂÁ:v ¼lÎwöã‰<·élLV¹Ï@1ÂWN K‘¹©+ÔÒ³<¾~äà;é”yÄqrs-nÂ&4èRþgã¢€!Ây1å‰+‹ïì=·¢o ¹ßqo9TH‰‚ági‚H)!öÅb©¯Î"©1ÀÌ•oÒD‹<·1ª6ŽbSÆÍêx /CEÁ gÁñײ@ö·6¹Ê»âTY¥ØKuÛK´èB$Û°*ÎHL@Á‰8UËôE’+ŽM)“ú¼?¥©0¹ Ê3ú’Û ±êNî<ûH9‰áyÅ“¿*œGC_Œ½ÝscaµÒ ¢4zy Ô) âKŒ™‰uƒv~?j·àý‡M(δҷdE´^iƒ¯GuÊ5/а¿Ïg­1><ÏïO ,6¯#ü½Ö&å´,bÄGKÒ}媓N­§©lxlàCS¥_kžj0@†ºR·~™××~dŇ”‹ÙX^˜¯­OÍÍöm‡Þê¼#Žl1Ö~t_”:×ÅfìdbûËÛöµD嚦áM4)9 :«büVщ ¯ºîYjŠŽœP.%Šnd$¼]‹†´_º‘ÇÈÆxÙTk8Aë5p_Á9nšäR-‘1„6ÅC:kÅÑ2XÛX£ ¯mZ<º4,Ý$­jä¾ø3™îáR Ä*Ÿ4ž>ë :Ø)& Ü4‰tÐSùÑä ƒ»û,^¢Ã*d½³¾ó¿Îg–]ç]’ʃÁj˜ûØÓ« ìãhˆ×:l¦ŽetvÓò®Ú¸~F ;E)ˆÑüε ëF$FÀXá4 Å"þ™“<äopoD£L(­Buç©Å¸Ù^«;eƶ6Ó¸‘çɼI;‡i»vy™AÔþ<& E^9j}{GHhyBî0¬½~èBX%s]Ê•'ÿ‰ Bíø¯a~ÆŽýngðŽ“~,22SÝ£ÿìTƒ×·Xie¬µ~ÞÛ¢XfÊ«*¶î^ª¢q')ê³ÑÖ¼€é*m¬UQ¢î{«wTýêœÏús5Ž4Áß…zº•Ë" Xo¤.!MO˜Œ´ Ž­*ö­‡³›p:ô VÆ ?UˆîTNqßL,¼ñj¬+L”½`ë¡Rã°e`ìD¾Ç#‹H£™]ÇrÄàez¢c."•ÿxOkYaש^Ë:T´š2¼|‘“¬Å›^u?«ñVh{õí¹ QÑ^úè6XÃ@QXÉB÷ã£û.zÁ6d4Ý'ê8Œ-õ 0ª™Ü³.¢ÉrÆ"WЊlÏ«áJß½ê;p Ou¼¿¶ÄNË/ÜzK_~% b$ž„I•§¡ëFklQbÓ³â‰ÈCƒ€Ç|±±«C2)K=yµÃ²Åã[C“kµO9iv+ׇ¡p«Ü ä(+تª:œ‡§Ž™‚ùùÁGº3ŠV´èâXé É?¢K{¡š™~Ù3;OD§{“ÛY©Ýåæþ³SÑGÍæ¦UÃͺ_¸ÀGmYá+­5O^Y¯³,G‡3—£åqnZÚJQ“ªiÅiĹR-’ɰÕ7¯9B§]Da¸c¯UrL¹&·¥èð(*È'³ÿÑ`…Û§J·>J' sÍ ´:ƒ—#ëœÈóÖÅ9úÖè¸ó¨f¹²¤¥åZÓ¸EuÜ`!qKD¨œ£ð£‚µ+箊,ç~DEkl‘B ¶ÚÉ €–[Æ#1(z#âðÎGmÛVu1w`AÊ}_f¤nÛðƒ—ýԤ̖¢®v²]N– Å×òBŽTW¢i3þeÁ\#ਮÑ/‰d>€oWb_Õ˜Z?ÚÊ«{nÏo§Âí_›2Á„%Ž^«s7èÒZô}Ti' ¡hCß“À/—£!ËžmÎÒºuÿaÖÞ¹'µ‰yù'²óÊqAù&TÇ ÃuN²‡@*\ >…5À¨ýÚ’µsœoÄ9­s©ûµì§Gñ3s³éźûúÖìÑZr|kéC»¯ÚÃZ7Ö¾óØ…Õ_8–¹TöQæ5–‰ÃoÏ)˜—Æ‚Èrë•ZOw½%Ën¤ë+J Ïuµ Wqîn°Y-Ìþa~š¾o¦ä]™çÑX^”EîŒ e†BÎ7òíRüÉ4²ÈÿÒQù-5ûeÁ Ù:/¹Ìˆ''?î7JËÁýU¦Í'A4 ¯²a( O«Íœå2E‹ç2fÈ:kcaG5D­nVé¨fo¹ƒ*ºGÐ"¨O ÞéC|ppÝ\ü_ªÎ†¹Ù/OGµ“b-5uŠ]5fë(³{lþžç¨Àí;EŸJ{FKð¾çXéœîÎiËåœíÁkùTr¥4VNEÁs± >à)i"¬ÍªY±TsùkÌa84Ç$¶G÷ic”òLbøÅÆn(‡+ÑjÇéw «ÃR$Q´“_ŠD£<-œ-ÌÊ¿^)W/dÕf‹ã:5ší¾´ø1nýaz&Á…kà ®Šà¯$sIB–¸®ŸÐG˜ÈywÙ‚èõ¯.U}ú…öq>ýZö‚8·™›p®þ„‘ÂOݰJÙ)¥T[—ÔjŽ/ãLÉQJÂF÷5²pZì I±fz:Ks·/ÓæQ•=­èÉ/ÿ2Ï%^GOD l’\r"Nœ>8)zS|bu‚¢Ä ÞœæÜ\½‚[¥-²ç4¦‰¤pW8™ÇH¦N‚+§>ÍïUÎM™±7SGùÝŠ8UàºiÎÚI¬1>Щ£‹!|'O3±«“ÚšŽâϺŒV‡U¬2f•‘%¬8tÌ»­ƒ%Cëî|ro‹§*²síŒK5_gµ=,´MR¡÷Pã˜6Ôý÷mjáÝ2·ÐÐjôºÂ3GÕÕr9Á˜.ë@Ž…g‘´(Š”ñüüÊܤª&ŒžBø™hºáгAÄÀºŠÉš³!‰-“zø¡Nº¤&€>®¯8W¡lÒò§À Q²o3ºñEL.‡˜‚’´ÖÈ©éySLëµI#‘t£v”(ÈO4*AYì•Z—ÈRàké?ñÓJ`I ø×žÖiK]^ã;Í|Ì„y©Ñ)û˜3bÖ&Y”ÂPîOÏ)bÚsæC³4:ë[|.›"ªe o9íx¯Î÷.Œã±Çxa (ŸòT…c\ݰW»l³¯uaËBãD‰ÿ{ø7¬:˜’ŽìI4,É\1ø ï•lr¥¤à$bB´6Úû.´ŸdhÁj Ä¡¦_“ÀÓgZï±Ì+çrÉAB°«¬'šS-‚ú”PÅlðXâ8• 'ŒïcÑ•Õnø„P¯éÐð ʼîßÚä¶Ò)©.“XãÁ®Y“Ä&”«Ö5ú¥‰•%ÁmÛ-'zŽ~¡°e ö´¸_âP2ÉÕŒº§uŒ{¹ü£dŽÓçL•#šä¨Ñ Ûsf°<GåÄè÷_<†Ù»'A±¨5‹È馣‡p’ÿX2—iQÝp­ß=qÍk û™ÛE±y¼ Jò„Ú¨ßI¦0ÝXrcƒñ¹ÔëÏ×c [¯_QÍWá-+4fµF“BÞ,ô}HJ$nž0Ègçù4™"èS"‰Ó$í$è .‹è{öÒ|2‡EЇóød>‹ˆôZÌ'ˆ;u‰_aæÆùlâ +°o—‹¶­E'|,¬Á£ì>hƒþqtoÔA›°ML£àÏ'Y4mgj]}]ÓBÓã¼8ßaêE ¥få´FÙ¿¬zC;øeÂP7ü6jw²Çàžˆ.º_ÅÊœŒ‰É­“l–«Y%œÇnæ„ëòÙ4jûÕúH݃à*5¸â’Ü×¹™•hlû™jš¡×`¿1ÁGWÓc4qJ$ƨÑk5ÑpÀ Á 9 ºƒN¬£˜ÝPvúBq'ý ‚À 鯠H%¦ãrä 5s*ÔZQ¢Ï݇óvsü+ZkK÷QC–ê‡ÂÕ'T{jÜÏ}γ…oè¾ð_ö1ݯåFêÙ07ÊPîÐL߈-0ç¨ lFOƒL-˜.ÊÊÁ}#OÓß¶·ßÆÓžTâL!ì™Ä :äiz…e¤e“JE÷ºÐçtWˆ‚tè—#’\8ãh´/ãøvHù[¢Ü3¯áfe2ÈÈ5DW Îê+BÿªøÒåÓPT|=6Nëv&MYkÍdHBú©Mƒb°³˜:Ä»/TÜtâéÈ:R¬¢ˆ;A“Ÿx”"4Ô…MÁb­?µøÅiOäMnWÎó.»Méc1Ÿ(ÂÄ` :*Ê&ÊWÚEŽc[œQú6ñ³?º9bЕžx±¨Ž–6"‚&’èÝdm9tO:‡AïýÉa÷}÷hСtMšøå¬ß­NÙ„¶ò”–uÿ…ÂÓnÿìpVÝ$o³ e‡f·Œ|¦-a½ò°%Ì «YŸM¹±a²uÎå$ûJóªj‚eT %TŸ¶Ph†Æ‚XÇ­ÞwECÍ.òrØÁ„KätË@ÙY *õ³þìÒPhLoJ™Ø¨x†÷þ+ìþ°wx¶ßÝŒõÙ¬#ÞŘü…ˆg_Pø„À ¿ŠxvêD+üHrOõl›ü#/]š Ç•C¬ì¬®rtÒVH¢Bç'®Ï¥?@< 'ÃT,üÇ7b•St®:€ÖX’O õ&ÁÄ@CØõõ£mKÑ%æåIàѨNmüc£¹ÔÒUâ=9“»lx+»WÕF´"öÈÂZýV½xÀû´hžÛ¼æÜؤ‡·&¸ µ†lŽæ~@›Z¨ì9aŸÔ÷=c?‹±ÅIüo7üO%\ûlÄn=¡_XLZZU_ÙìÕ›[UÄäÜÒÙQï‡æaxUòø¥Âäï ]ßÔÒðõ1¼s#›ñ§"ANa?óou)r–ì@6w@î§ÅègsPã¯|w’$[´˜±§:»Ž™BëæN}•ã5E.´é Ƈ‡)³†$aÊHv0e‘­EHí,µS=›f ‹]ó;3‹®üŸ’Þãý#á>¡Ê;•·lð_šô|`C»*î+ :íÞs`ÕûÞÛrur[…ævß´"͈,.P®;ù‡+JjÏ*Ý÷¬0¶ˆyjª[K8Í%Îkžq… :>Úìȧã¹ÁËôÍCŒ<Ž–¤î#©z«[RÖ'xãFœC”w+_M¦ô Pzì”×Eßáø+ïuÎsú:†»žÖÞoÐm1û„oÄ7¢i;»Ê\Ô;j/¼òŠÏÁ³çœÚE}Ò§gÝVÐý᤻7»ÿÝ âéP.yÄÓ3Bç²Øawmle˃I`E3Mpƈb¨¡@tˆiá%Ndö`Þ‚ÔM~NŽ ÿ##§)ðw­,HbÁ°Ë(“e¯Īù ^ز‡N çd]Æ÷«”å!œ®Ã! —¸y‹›Ë:… AµŒã%p¦‹cÒ"T,§ ýkyUŽŸ”À&3[˜^žì*B­ˆ“­¤’˜\bãqST>ô_¸¸¼šxÈ';y‰ð1ÑJ/Qu¢{$÷Y”¬ýŸøŒ÷NwÁ9ä ›É“ŸÍ¼dâgäD7ƺêGÀuªàF1àgBÓ(‡TVV,àŒ˜ê.Ú&ÙAY §_ÄÏ”¹ØYïŒçdDãÒƒX@ u"wíÈí{‚–tHð½‹Ç7saû::À=ÿ@Êuo¯>ïâ7%‚Ч•}L^pn™jÍ|¼åþÔpkÓsŠ頑Ď½ô,ÅÌ"©"i6@äeN‚zál±ŠyOÝ׿ 9OÝ€–r‘“YN˜î¤&Æ‹ÿü.èœvöºhbMÍf<Ù`¢|–s+t6™„]¼Å_‰q%HQüV<àï{šœd7–v£âXÓ–Ý8¤Ý«ëê$N ÂÖi«;¡‚K3—è@1v:Þκ¿ÇèêœGiÔšÅ4N~Ú¦ã›è¯³: €=ùAˆý¦A±I‡±£FW½ˆ ÞK¢šëhBäER"À£­e27Œ2ÔòŒ'³‚Ûh"ªRxfAdAï«g“ÓÙÓŒ3wò ,’ßsß Ýž½jY÷]Ðx»O ( 6Ñhıå^Ì‚kQ_q³„ò‹›hkUY‰È(&1r^³0¦ëNbáP·o4YÕÀ@œvÇÂ_8,P9­Ô W¦lJœ­á‚3”இûH_\0?yù"î8TC$õö·B¦íIBk9N>ò£œ ºE¢`–¶·=Y-°·YÂÔ¯MÀ©-^+ó1'ÜA–9_ÁRqoï²[äyÊÁœ ̘ó=¢_ÿˆFc¼Å„h&šYfCri²jûnrŠlÜÐ #æ0 'ãx9Îþ,j£ÎMnœ¿bº–˜ð}H~iVLÚKÂ7tœ³š‰´›7“sÒ»­’T%°x¨S\z§YH É:cxéJ<ŠÑ6Í Rþðé›i &:Mº-˜Ò›½Ú0¸åÅå,‚ΦÁbõ%Á6J³áS[E*¥!—‰%[U’RºŸªä'*ZÍKûÆná^Ì*Å=C‹ï­b÷\ì-\¶šÜ%±~asãÞM)ù`2œ#`Ú„r’’H¡(¸V4`‘(Ø:8ŠñÇ=ðÇ/1V6Û ‰þÈ+C¾‘ì6ÇqÚ’œDžÃP4¹üÄ8õëðçsö$¾u*8ÊänBÕå‡CWh¾¼”z¶+/ëæBÃî™[·ƒMQ0M‰¸ÓŒÁ¶?%ì|"kÅñ3 C׌)!](A^ÀµøÎMÈØ¡f g:¡m‡’i8F6àhIG¬b=×­ QÊgG½½ãýnp {ü>Ý"EáÔ¡‰2-Ý &£°ð ù¡q "ÞÉN.>3œ-qähHôé†ò'  ͆±ZÚ‡‰£ð­/ÈwPhí]ß°*Þýï6ÏÈ|ÌÝš8EWb*!%'pgü ¦kE/ÅjBcÎ:ƒ LŒ¿gÙM{e ZíÇð c lµûáÙîJG4b#pˆÓë®e|•‡ñgò·*æ¬XÆþ2yhõÁÖì[ïÚƒgO°-OÞtÿª/A䄽þw˜6Vž¥ÒÁ{¾G4ˆ $ãõ'X\Wÿ"3 ‰ ¼¢…ñwîÏlØû;sÁ—xêk×ýÁ þЕö—x™¢vù­ªùæ°¾ïï…:§G½£·ýðä¬ÿ.l¼xþû?O×)ž1=¥üb9pv¯õ§xQAHkè=xýÚ2–a-3Y}~¥UH­yŸ„ ÿYö¬ØX…¹-ÎY`øK™àãWÊPRÈX%Ò,½»F¿Ð8]ëS( Wög«`)*fÉÿþr8 ^Vhu8’Øx-H†É”ŒÆAò&¹¼$ïÿ¬ø%îñ¤ þg _̇ÕÕx­ ÛÕ†îVìU¶£› IŽl'"ÉÃt6‡c ‚“ÿ ûlÉn[Z g_ìü0©tù ·IlÂ`ôKSêçgÐP4¤pïee©¯¢‡RHR¹b‡ž;+Êïj¨î_yé+ÐmŠÚ!çUkzäcxl ³–‘vƉ°Ä…$›¿òŒû*Þ»‡ð«–€Žœr÷Ô=„‹eúz#O 1òEí.'dì«]—áâyEádçÙèu¡¹5ý‹¯-…Ž»C“x'FqºŽ'—‚²q›}ê¥ÌÒøgéUtss×þgæ³{K·‚\{4Nûâ\È‘Ù\ê]X¯ô+å[‹í$øØÑbEÏM›®˜*Š£W([wKBéƒr‘*6½è7]j…6d¦¯L7Éð£;H¹xÕŒÒ@£ßa¤Ãlî«.”ÛlÖê@”ÃF³ip­ÌsoC&" QB7MzV$R¬fîÅ\)=™§_j's‚Ñ=Cb$½#Åø®Æ§ÅŒ8¹Ý4j›3x &Ÿ ÌlÙÎÇö=¶ÄÚ©g»¾CЦm Æ¥œéIçiuµàÿ{54ëÒ$þë,™ˆe"¦±ÍA36Uo Óu5“kº¬6xKPã¶N¢ËiÏ9j%¹1Œmj’®–8ò¦wñê8Ïen^clo“‰þÅ¢ë`òØI‰¯Þ@ŠëZ·yx="[íÆøu·‹u<’Wj¥Qê,Æ­ã]!ìA¢(š:k^®ÅL2ÓC¬a@ÊZ ™ÅøgDÂÌ%. E®˜6› w àö_Ë Gµmcgè 6¥@Þø®Eš©ìnØ I/ b±]E—?¤“#{3ۜк•1Vƒ‘Éxùññ•I-»1çw¹l—“Ý,]˜B¢Ë¿&)ÍüSM½ê*ÀS¿9†—}ŠÌ×Ëåñô?Å4=6E5SJ”—€îI´Âÿ¨‰{ $™þ`?ü‡Iïèí¯?¿·s‰¿ý'™áûSY +ãÎt½Ï¬¨ÆBçéC6䢻$á~Ÿ±0o¥Ç)àpÝbœ×¶ ÝÚ ë_Ј:¾è7|ìe3ÌÊý•M…ÁQÈ™óLp ôQBÀÇñp{73•D=ß> îDëòKÓå ù•NöÓ0}ñ›RÃÖ§ˆ"ñ½lwÆ×Y>íþu©LsI7LøOfä2I#Ìs,Âá»—Ч0qÃg®AߤpèO’a8N®Ai1Äoo’Købk3ø.(¼U˜1íÔõ?1ýO~þ'^ÿ¿tŸÆÃ!¨ƒŒ?5žðt6ïQc2§†ïç\uUñÞrä}æ¨Û9ýï*û$:ŽâhrŠ-¿FU<ÜóF<ð…°¶‰è–UgGþßç?–l®ÿŠÊÏ\Ù @nªË.%-$Æ€´%zP’iFSIÿ˜3ŽWÈf”«#I€)ÊšnwÉlφ\â;¼[¶§¢ ¢KQ* 8skÚæ ø_Z+¦8êä’Ã'ùf_#Þ0€= —?˜ž9;=‚ê¡è;&5@NvûýÎÛn(¯®çñ8»5¡ÀvŽø²¯e×6ÛÂñø88@À¬38¿£iÄÏ÷’V‘\3Püðoo¹x1 òò9G _cÌ!ü¡¹Žœ€b/–No>kâ©Möªöœ&”´¥€µ ò)!ïä[Š&w6‹ÜI0PìÎzáiS@3fºp›¢ˆ×”ݹÜA9©%ݯ÷q‚øˆ,~]É5Õ3£L†•üXFGY¢±ëüÒ[Û´èdƒ=4¤§f‹Zlh³ðY˜¤ÕƒŸùˆ¯ ýçÞ°á’Ú,°Ðÿ†ÄówØç&çߤsÚ?.s.Žk..ë'ÔPñ'%yœãªïÓ¸N×›™j!7ÅŽr3›¸iCñ‰û¤F3I5ÎÛ ¢·ª0·GášnàXt%€ÌˆEì|n脟ÙS Ûȉڡ ÝH^×q”º$ ”ú*tcÚlç _(‹'ÞIÆ£¬ •W H­ÉþÉ9Üb…xãPºƒ2¥$iCn)¯zÉÚ”Ä(Ë|vCðJ´óI«õ’§[G=Žý”DšŒím<¥žMÁ=0xÔ¹MÈAÙà,Þ4eÁì9Çš“ 7¿éS4h€Âíý {ÎÑ„ÈõRüûM–bÖÛË®Ïq›$Õ¼þYFeR°Õ- çkÿ™îz—`›¯~ÒbÇh;E²’Ë; „ ÄE¾ð?¨ãÚðsU+Šƒtßf¾Ð=m꓆ ©EÉÞDCTu[eæ4 6ÀràÁðm[ZmØ&šìð…µ´þ s4èu]’*!¾`QÇi<²ÒSF24:ëÎŒµÕ ¶6±Å•j7[柊ÍåébXÝ Œ<3À,{¹¾›qxà€d¶HM¡É¾ÕÕš “Ϙq-·É‘LJsAŽ£P~s‹!ÏòtƒÝ,[¬1˜82«R@rcÈj*gx>´ ”‰ Œà¿ãûQJ‰š9×Ô °‹oY$kå™ ­]ŠÍ—^cdQª¹¡ËË1…Pîʲ¼°T³PŒf9ž¸<èæÍá³iï]wï¿Â†i- ¾yM®¼Vg@¯@·2ŸÁ-«;µ‚U¯µ Ï TÁO,¯‚÷–ëIÍ8è\Ýqíë–àŠ?šÄ¤ÄS›§(ÉKyÄá:ŸÉU2™“ÓlŒ˜ù(p¯rfz5A6ROk˜Û GRéÅÓXX¤uKª\œym?¸Žù}i˜N%z›òO0;zÉ*Œ5N.b͹$ÄÕ“cg—Ìêç1?5±˜€eªàïÁ.Í”BÒX9ãä^¿v뀴JÞæ³êU#·Øóo½š ímo^)‘;ÝzߣbS«GÅ—7Mý&,°¡æf-÷Æç2VûŸ’Vw ·çKc¯¬ŸVµ¥ª×ágš±…xå8 ÉBmD .hO[=¼XÅœA]kI Ýß:½Ã³Ó.î LXr—À,#ÆHÔÊxDÞ(ÈМÜÚ< òã'Äm ”V–h6ÍÈvH­S< ¼Éz¨ønþˆ(Wöǘ$_ 8#NQ\¡À%U•)ð×H|ÐTE=Â}ñGÍx)Ñ<–ã³'Áe’”¸w Æä|483VDI±fw鵂 Ô;*€ {û½c]Û«|Ð9ìw—«,qÄâ+ Ä‹j²NO»êU!>Κ;®Úëè;ŒoœG¬w;ÄGú¹À™šõ2Ç4Úeîƒà$ÎnÆŒ¢’3,*§Î»bè‹(—9M{«D1ß4¦xb’Ç´œÆx¤oŒ&?Ë·ªìbŠ&„„ƒäm>`Kƒ3Lvݶ#¥K o€·ׂ¦q]Œ ËÓM bΆM*÷Û¶ñ»vº0ùDŽŽ:ƒÎ¡þ6V¿zµ¹¸C1Ñ0ÂnžÍ&hÚH»JÀü“‡³UagÐ ›ÝÛ›ä•íÛ :ƒÐ)Ñ ”Ø:î‚ t­ 0Ö†#¦ôòxï7»L(ŽÄLîܙݗXSÒ#ɲ̾E‰¾¯“iEjlnZ£þ(Ú Á „⑜oNHôRø Û™ÆÉ9Üy„ÒF«Á7b‡8>‚ÿéôŽºDèÊ·P ~Ù^š(•ŸËM‘H`Ó6}î÷a~è½£5:E¦é–EË"#è#Î’ôa'ªr<øÙ.çÄŽñ…—ñ¶‘ÄÁzÉKqðîôøCƒýШK¾ÿtqMÍm úÆæ³Ü1 jMÒ!oÇ_Ú°D´k 8:.Ò°dz’R¿0ëwËôÖ9úñÝÉðBÐvcxOϸ%fÓ‘;ü?X'œ_©U'O›E *¦³Ø¡ñú\¶ýª ,v`ÊܯµüÂs¸ û¯›Àíì›GÎU%È<¸äm|\…HÀ/Ä©ÁªLöÉ6 ×ÒýçË6E𑉳wá K Ø­ôä©Gò”°”²_|ÚÕ”æä{¥„¶#£Ï•&çÍñña·s6œ2­à[óÁ 4  Yxµ,·“Ú¹ 9ßÔÒÄU¦Çµ¬ýJ³³€”_wjª¿—dz‘uâ}júcb€¯¢`&6 µ.Pýï䯫ç6lº&–³ ÐI²—ÝÜM(ô÷Ùææ÷-EL„þùñóâϹ>Ç#ú)´›s®Yl“Œ.9]=EŸÅoΓ_ûp‡å-1¸O4ò²‘ÉÓØ¢ ÌM<j2ך#ËBY˜©6HŽ×ñÔÞËð|ô Ì9&š(£¨O²“Lâi$vKÆ»ê|ðM.|ÈR¨Fi·gÁ1u0¢’ö~r’µ„@‡Î¼(!0Zc¿$ZèÂl–çkhP3Òú²á̆éC¥§x5#zY\àX;ñ·ŒvD¤¸cpw$â—7EœgÉa" Ûþ–‹ÏóŠæMÇæ4Ÿ‘œ2 üÁ·”H¹Æ,é<;SDÅ{¡¤eP”Ž‘\5ÐÒ§ù?Ñìˆ 7AŽJ™·èd0Nïzý |0øÐ[2ü}rzü§Þ~w?xó#üØ ð•ñ´÷öÝ xw|¸ß=í£}øöhpÚ{s68>íc3«>T^¥ßàC{ šyp|J~=h:8Å'n¿ôŽå»wô¶@è¶öÞ÷PrpÜ¢®Ë5ƒãƒà}÷tï|ì¼éö?R—½Ávwp|ÊOŽ'ÓAoïì°sœœž÷»Žo¿×ß;ìôÞw÷Ûè#rttÿÔ=ýwÃC¸ØÎñ‡£î)ŽÁn𦠔"žvG£Ýï¢_=4iÿÚƒI"ɶ҇§ütaPÓ[Òl¿ûßg]|(9 ö;ïá¢Ú‹gi„%z¿à”ôÏÞô½ÁÙ ¼=>Þ§iAþ§ÜŽv‚Ãã>MÜY¿KÄ샼¥î¡˜8(¿9ë÷h É¿æôìjš°æ`†€ÒÔÞ§¹>>Â13ïtOĦq>h5ZÁ‡w]øþ§—f­ƒÓŽ¡{·t “I³ã Žºo{o»G{],pŒ }èõ»MX¼^ ô¨sàèöŒÆŽ‹´ÑrøìÜ¢Õ zAgÿO=¤_Ê?ô{Â>4}{ïdöÛyŠÌðoVý}¸ XäLjëžvp@|lm>}¾õôÙæÖB¤ Z06°§OÈHàxþ„xLµoî‚—kí@ý”ºû½n2àåýoÔO­ò8[ê,ÃK§BKsÚ ùÿ/Å{Plí»°R¿¨8ßD:[Þè€b“L„ŽlºLÃo_µ— É‘ýÌm,(Îá•M¨’ =é«L»lH®éÔ¬µŽäÞÓÏ>¸öì%ʉ®ÙjÐXÏnŸ¶šu%ŸKÂÿ?“Òí¶ mÊp8%ÙTa­”ò°˜)V8-\4ødtÎœŽª2  îÑCƒ9R14ë öbA'OüyÚ*ä"³ÀñÅûFÐ×0kw ƒ²„g´®%û9)î½ñãdœ}NŽ0Ä4…ùFÀ,`Ï!_“Lá%g…ݩвJ @FåšñbU¯Ò3óÛ‚u¡Iƒtƒ´œºuÑy×֖ÚnÍÓ^.Ý´°‡«Iê ‚…yEÜ4`V\O<ökmogü•RøÁGÁfì㺤yV%¼#"ÐÐm¬oܻٹ¼öBÍéyÊ>8/IC:Á|©À6×Q2.I)Âå%XLóüŸüÝå$›ÝämŸèè­Ih<Žï˨ՔLÉȶbv·,çNƒó(‡ÍêXw21|¢ã’¸ºØ µÑ Uäó3:Êiâ2f#z¿ælò¦äËO!¡á"+ei(`÷Õyÿ¦÷öìø¬vá’¾Á¬'ÝÓ0P ¿¨ÛI"£Ið:pºk6å–µCÿ$aÉhhÕ¶|ª]³¹²œoµ„þÝ !Ürçʨ¤þtU<¢Û´ë耵”Ã&ø3VÙïU׋$!‰£•{:X/åÔŒÝRË7OP/[üXޫеðEs^¤Â «®‘÷=¿Å*¿ÔùøìAçã³Ð»‡=äŒ|ö«Ÿ‘4¿Î¹zÿ*Ï*Žâ7ÉWœÅÕ†ŒêÓ¬Ž]ïs&næ…ŽJ ó€³ùñF´DŸÎ#žÕÏ­³ºúëçóŽðçÿ G¸Wãù?Õ¡òÏ¡üóJ%¡…?üs+ Ë”|þ/£R,ÝÆóÚ6ž?‚Zòü+Ô’ç5RñÓó©&ßb=‡)åùƒt”çE½p”•zÊó =…–âŸV·¹•çêÐçÁúÐó:Ö¯Ñ æí•ûèEÏK\Xì°’Q =þ—èû«†÷ˆúÒ‹°¾Týõ‹yjÔ‹O5Ê«ñâ_ZñºGùPþE­¢ÖÂÿ]”µeJ¾ø?¥Ö-ÝÆ‹Ú6^<‚jøâ+TÃsƒO/®~‹• á—Ò_-r¥®øâßVW¤eüwÒ/ï_åE…Júbãá é‹y®Fe[´K¾¨dûbǵ»ã ê/7â%hx”á>¢ÂúòŸSa­þúå<=öåozlE—ÿ§4ß{” å_ÎÕ”[Xàÿž¶¼LÉ—¿éÕ÷Ô«—nãem/A7ùºùËgà§—_©Ÿ‹-TìÁ_JQù EýeÝÙ¼pü•ÊúËß”u¯ÎËÿó þý«¼¬¸¼üŠ;ÁËE½FK^FBÜçnð²v§ ˜»)pGøåg` Zuøw†¥Âc*¢Ê8ÄNîø¹Ã0_̦èþ·ºšm»  Ÿ¶‚ׯñì®Å“èÖÕûfn½ÃA]½Ws«Õv÷jnwok»Û[­¶»]éŽ"8Læ Að& 7%$Í› fL`UE#$°›ÝFbÔ8²‡óòJÀ 'ûÑèR£¼ S‚¡;Ÿ%ãé†KÀÝ,§`ŒØ ô¤Ë˜@§8ì„#º Í7wÁªmdÃI“Õ„5SÊZîS 8Æ’ÝqB‡Z)tGC^”ÁŽ2ÕSfÛjK^EqF5Џ"JÀ½Á»mĨ„ƒbP ‚Ф¶ÃM­ó×Y2Á ^I¶+8¬\yhÒeWà:Îr Gý"º´Ã’…Ûûî;nãŒ`¸ßÎ’£OƒB¡tÓDÑN£O‰ÄKxS5å„%дÈ7|È„ßfAvþ?ñpjBÇÞÉvÏ>c,ª Q܇Q¦©Æ¡#· ¿åsf‘ÃZÁžækúC”È ¡Ÿr} äš:v&T\q²"G‘&w_g“;n‹Ob4dŒ8Ç•­ƒAØw.%¨Lù;çV„ô¤Z-"¶"5຅¹ ‚çí9â8• ='´ªsVS…c³%9¾(è’©ŒÇ9΋Lšb¸;ûQ9ÔrŽÛ¬´1ƒ„nâpxgUíh^´5Bsß &bÆaõœW&ž#­ªGMî7*~4›–NE™`q“Ún_?ZБºV0^ƒC¬¡EÇ㼄ZÇÉK mtm`!Ø)yÌR(ŒÜôapáDI®aÝ…ˆ3_øN€I<„IÉÛø+Š‘M² ¬ÇsÈlÀE‚q|1m¯î”‡Mlt:ù«ü,Û……¦¬U%»å{Ç+9ùû!4<ì º§ 'PÍÝímΪ>»ÃÍÐ^Ä)ê>œp““/Ïéãð1ú8\ÐÇà1úÌíãícŒãíüq¼}Œq¼-Œ£:²‚g«FO‡Kõ4xŒžKôôö1Æôv™1½}Œ1•8Úâ²âTFð“N~øqœ hY‹¼X†D4_ ë]㊫±Íþ²èÕ[nÎv4¨‚óû8ê–ú(ì‹9{fÉ>Ë}ÎéãðA} Ê} æô1x@oËãx;go2Ž·åq¼3Ž·Õã@¬« Éb²ç¨va\1Ê,BL ušÔCÄ]DPzú‚«HAnÓW º :2–à̪…‹DÅ5—ó)ç@`Ž7Ý0cNjnþl^uà¸9Õ¿YT]È›&*zo1–6mEy¼¨5—  bÊ­)¸åUFÐ$áR¢‰qùvV‚²ÀZs®d:ëlÚž«ŸÓýÀˈ«õ¨Å@uºøCÔð¢>âqÀÕj£H#=Ø5yxx’×÷àóÑÃ{ávõdÇóU¹C*ÚËërÿCµf]l…uyPUëb{¨X—õR·.~Oþº<¸#o]|kk]^Ô a‘ù¦ÖƒÃãNQ¨ÅIΩQMN”rÓÊõênöÏÞvïÑM x¿Ž0«£y¯·¹ëºú´E'Ù§g¢ã  ##¦_„Yt/‘G¦P×®JINÎO6Î#4À9Ö>4¯y€ÿ7˜,/Â;šÉ”ÅÐVçÙ,,GDÊqr›‹õ… ‡é(·hItP¸iSmš ÍFÁ€0ÊZˆƒu¡f2·Ø ,c7¤ ‚8B Èq^–ÓU¼ó0áSHvûЏlw¹‹Z‘ªJV{²˜)ïK—‚¦ÖÌÖýE£̖t[;[_OÖÃfËØˆp›î^®^ËçÕÔU¥a]†"·ÃÒ¤- ®*öå$Îh]öQWPßLN6~É@ß?ÿ„`ñÚÒ'y]!˜QEÙêòÂ:ÞZãöe»h4õÆŒ™GŠö2§¶‚—íMIØÊ.*aŒ(ýÆ1gD˜¬‰'úAžò$€D§*è"±|›äq1IËX´Qê +u’ѿϰ³£èhn*_bìÃnEöÞfã5‡(´`þ~6?Á»ÎàãQáåîusñâÂ8ùûá‡ÞÑþñ‡¾«yðIM¹Ì`*ßvûg‡›¿_Ø!®%xàxÀJ°×ÅlLË–’t”ÝæŠHwý2èïÿ—^%(+ÊIÜžäq®^#…?K΄îþßñ»»ÿ…@Ñšîk)~7…ÇçâWÎy#òÊGT9Mƃ ¯”‚ôÉËÄ‚£ó³k\Í®£t.Ó#L 'À|¨À!Ê1Ì•ž¼FG^ÀL29zä¹9#­ÐqÖÎÄG)ðeªÎ‰™ž 8UxI•R«—KC}]`nådÁ1¿Ç*|£÷X#/öWPœ6—`Ew÷]EwEOŒ9{1þgS7me#¹Š153)•6o†‚¥i|ËÉh(é)÷Ÿ«h²Q]M6U·[e"ÏÄIq°³ð•­X÷d’±#máÑlNAz:3i ñh•º.§x¨£TÖÍOöPH´³tÒ‡ºÁ}ewÎJd¹‹$Éât‚9. «y`ÝüI7Ñôªå­.¦;"0wº-¶ŒøâI¶=ÅüÜÄX„“RóÀœÃ0óœ,ÜâñÓ‹ø(.rU>„ëŒx”Ę|2¡ÃnA˜töVY =ƒN@ÉÇÊmXÓ“é]MMªÒDé^í.5Ï*Ô^Õ%¨…N) :\œ=™:Jš‡ÀÖ’Ñv}msyÆ{‹½="E¡¿y@WAïøD"bwMš ¼:ÞÜ€z¨s—c¸Ãù8ƒ-½Ý3Ì‹˜[¼®©íu…’x¦±ãÒçõa–±R2õqzGâ)É·y|´·˜ÁñuBÁ %ž [A¢U:l6˜³Ãð„bèüâåq}¯Ø¢¸y 1ÂÏ|Âo`žGÇC‘îÁè˜#~dwœw’@²¾„黥xÐiðŸg»”8”ÚC%ð‚¾åk?ý®÷`3¿ø­ëé„‚S‘x –5ß™a –mLÊOIÄY¦ Ÿ8O¶\Ò‰­Èýú ¤[&JÇÜãYv§Ÿ²´Ã¯ÜõZHrÑc @|„j|<â„×Iιà*æj5x¶ Û”²h>gu"NŽ8?ºŽu¯ó§ng°íêPrgDª’,ê–F\³bBEƒ\^X 7×ñÑáÐN@ÍÜh"¼h™™&ⓃÆrÁ‚n±ä²çLeJJ›`Ú$QÖ´Àb)¢Œ§˜ÁóÇ®­ =Añ<Òw4Yó=ôX|4ÉßœO·¨]èŸóèR&eªOöuô–CxsPÝæH4µ··™PdOËô Cê'(³…©Fm å âžU‡Y©K'*ãxô”½ú*Ê–40ŒØx348ü¦ä4iT*(Ïþ†wvlà æ—Ѹ~´Uøq÷¸¸H&^ŠtAˆÖ<&]3>ËØ“11¯m¶…5“¢iÉ¥ZÂíªÉ/)·‡_šÛ¤ëÃ*®Í*³;ß<„ã#§¸ ‘µ™Éå ÄvFšRÛРiPƒü*›GzàœÇÓÛöõ9 w˜º $æA4Œœgl›Bè%Ïr6ÓxÀApÿ-Î÷8ßôøÎÉ…î'÷’‡RJqd€YÞËÿËꆼÂèäÉbê–3$cÖhìù¤7ÂaÅ3þD_¿Âª…<Ž»’6—ÝUi)ðÈéíÓººe©ËkGV–hBv\Ì]˜ËÅNá0}ç³KÖjX»7JÎÜúOrÐîƒã~ðƒFX}ÈŠÞÂ!PºoÚFP[:?ü‘ˆÇç¾M"FVáÔ!Ð9Ž*ÑhiK¦y<¾ ¸z,Hç ’ÀykÈ9µ4ÿyp9ƒÝ»™ýS£ñmt—›í*‡¯qõ%ù†‡"CÂÜa㫈¤#Té,Fé3’Ê‚%m ?ãŸÍB«ú’e]aZÕêTaN˜‰’FñK¦¡¤\Êæ¢»`Ò–›Z×ËÀ—ƼkõöBlÆyâ"¦5Å<‰=g†8¥¸rõŽõå«l1–쥞èztÉÞ© ÇøËbøŒþ¼ gÇI<‘¾i‰¾áä_È&OuµHfQ2_U‡¶±É»í±¬Õ‚& KQjYE(™°§°¤€?»!íà!Ü! k„º¶OY‡Š÷@JOçôÑýïÆ&ú÷Šƒns§ü;¨çÅß¿ØÇéŸvpÂBqS.'šæˆ_Ò° t+ï’ÌùBæ$J7vƒ;©Îèêúi®!è+%©)³”’d7ª’öb´IæÉñ˜¿äâ5â¦0‡ÓbË1Ôk–¼³£°sxHsЇ^d©¯<#ásÖ¤)ß¹¯`ŸÃv5,gCò¸æÖÏ~à ê6ÊÅ;³»óÆÙ¡{9½$Æv9ÎÎÙ6fç )ÀÎ#š‹at“³YÁ•âx$ÉôüÏY¿йpg Ó0ªêülÕXguÏ`h8(ZÝ^ÊÓæÆîé,EÕ÷ËÊÒyþß?ñà `œ|c«½õ²½ùGÿôò:~„o~_ðßü¤ ÓßÐÇ&ü÷ý‹øïÖï^nºÿnn½ü~ówßÿÿ¶ž?{þýËᅦOÿ¾üÝËïÿ_ðÿþ•þÛäÿÌ¿ÿ"ÿsnþþ·œ›¿åÜü-çæo97˹ù6ç¦\ªf°&ÛÁõU<Ç’޲Â5ÞG“³8 Ýa 7užLô¡›Gž5„zÞ$cl8 ð6æ7¶¶Ÿ"”N¨œeÂÍlr“¡òkЧ9½»Ò™¢Pg|ÍDkM‚öø[8“ÐÄ/ S¦öå^éåjõ’U'nluÅ\¥(¦§! ->©DQÃ-jë XùY°_þv"ÿv"ÿv"ÿv"ÿv"ÿv"Ó‰|¥Þqüÿ]Eéº&|ˆÒ¦cǽǑ\:u~÷Û©óÛ©óÛ©óÛ©óÛ©óÛ©³ô©s6M€ÌÅ%sïqò–MO¦Ù(vÞ# ÏÊ Œv°Ë9ƒ]QmvãH:¿8PƒcçXâû'=´ÆûÔs ®¬”^m‚ŸíUÒó sC9â ]Qøxúâ¬ò=›L%z;ÏGŠ”ŸÝJÙÄ™'º#¨“[ĬS*Ndül 2ièa’Žð½KŸD“©„8Héi¦bÝÿ½ƒh:Zˆ½Sã! òD0ŠS¸£ 4_ô ᘎݡzì"*½  ã›)G*‡h¬œåÖ±ÕuÊdi.8Ä0yR  +‚ ¾, ɃFúà—é±Ó öÇèZäÜjæŽW3¦rŒËahœùÛ¸Àò|RT¥Àv¦¬½Âë⟰ãçAô1ö—à”çmBoæ!¹º !¯^ ¯þ¼b|ëèmj Ô 6ùÂcåfÄ<Ø6f«Og׌äŠóöÙïg"â^÷d¢£`r÷Än8xwÚíì·¨3S-ç5•…B4°±ðBkôGô§V¿5\:·þÂ}V·®5äÅ<žæ¸¾è*¬ñÂÚ¯ÜÊù·§ØG`˯9 ¢MÄ9,³ç¶F›ˆšâJÄU–÷'ìdHs*îðÊr{‰ÃÅÙ™[“h€`¿ jÄ^Ž=\¡Ï7°¾Àá‹8§Q±§×…¦Î`ŸœXrV5aO¡†WYÆhv#¡¶èoË: éñÙÊ´"/.FµÌ€píFÄè5œMÄ}u“l–×3Aý/þwáXL±ØÉ±3êô§ÁÅ‘}dJ¸ê¼¥ÑwtÕëA6…º45dñ¹7&,¤þÅɪ×Árü!DE6} !YzoÂÆ¢•Åçý÷øWW9ÿ;þá_B¹Ö€m/¥©aŸ&Vå¨P€\<È®§+¬,l̵—âºÃO(¸Ãº€±9‡©‰+‰¦r¶dmLêÚ`”|vÎrHû¥¯±C>;/’“._ŽÓ k2‘°;wÂRªN=²áKÖNÁŒV^®¾1I&˜4…dOE{•\ì ¼Vêø•¶·ÑŇ櫶wÆsöD¦¼¤ÿ·’¶Â.šCªËâ9턪‰N‰udj–ÜÔÊž(º3éΘïèÔÁ³™c5J¨Å¾_®Äžäžâ»–›¨Oqƒ7Žú¾‚=u• r˜š³ƒläq+{Öû;Û«RáɲÆSº†mÇ8:RÄiQ‹J¤ã_9áà\‚ݰÞÂÀÒjšrÝ «D i¤ÎRàF®û£A`c,T,T)óå‘èv|äieÉè„DÍ8 ™œÓ¨­Üõå9zAµ6ª(A°Úwµ8Òóš?3Ë ö#“ñÊðYuìø<ãv;&õ6SBþ+E7<ÿ' G勇å,œv±†J 4}z„5U”h9@˜p2dIµu9?«8’q*9ªÍë’\Î"vÀ6%dÍ Kp º©û¼ÄÚ„áyYBS?ÑTf³Ë«ŠØ:Cª5+’ÙTb¿±§h¨Ñ8ùÈ1Sv–"’ÂPýZQ)嚆åX¤†ZÁhÆQè »w6N`*§!£˜¿¨’Ýp)O.]õEûî Ió§ ÛŒ«ûùÑXÙYj¼f÷ÐG‘õ¹„(à¹YŠF>Ðã‡CÞÜ8ƒN,;zOÞ¢”&¬„Á_CÚR‘N^¡PùgqÕ£ zì’œ:@É!òSòAý,ž¤rº©_©2jP])&w_ÓéNð…Ë~Ùá ÎïE€'@e@¹ŽàSuþrõ¡œPÖûõ‰ßn«žŒííîð[ACf­)ÄèL¸M,ÒÈ„.U®[î=š) š.¸ÏƬôóWz{Û¬£T ü‚þñÀyÕA銻8ÀÔ=ä5Âúe®ïGs›"WfŽà ªNш Ms3ÇtIOøö4¼¾Yb!ŠD œ_øþøMï°K%?(X¦ÂÜë¶=&¼•u/Î?Áñ×IZ×MMû5Ín$r0Èù‚"˜p~È¥ *'4Èz˜¤o?Ðá¿•éÒˆ[$¼Ào¿Ááß!3‚’Ԙ׮½‡³ó*!˜¸x2ˆj¦‰ð *Þ£á$~$p0|Ó¿uûzµ:ùSø‰š I?7»¹Ñ%Áàê…Ý DÀeLôväÒe¶É¡ŸRÖ‹®)77c‚&¿JÒŽÅÄ ¶hŒWü;/ØB74Øy·ù/‘UŽWûdÚ¾ÿNÈc…ž D§"ßo¾Ýg¿†q–9n~á9{ x¯D#•£Ù×8 î¨ÇõŽú¾<± d×Kl#À‚#Ê/Ñy/ ýЭMn¢§0kÓzšáÇÑy”g HO ³,zM/eˆm³$Ñ2‰Ò|ÌÆ"¼¡SÖF1×9¾5FŠòì,lK$/û!Z@Î)Ûe²þ Ø~¾Óåæ‹¾ãÛP‘ZuÀôaÆ‚¨r=€Àh8aD1`œ¢‡VÓ‘*6MU*tt 'çç2²óoñƒ¿ErüÉñ[$Ço‘¿Erh$‡Í¸s²T(nF_Ìòª<ØæÏù{H,¢çÓþÍŒ’xǵõ²,Ú'ãXò¾íPë·b zš>œ-Zû·§÷¥hþé^¨¦#`„£Î!üqX©/·bO…_§4‰9" ä±û:WÖVC«¬°¾cñ»uÀIÿæ€ ("µI^iÒ _KpÄÇ0ê"k¬R´‚ÿÁÃ*0½ j®œiµF+ª#½fñVmƒªzá¥Ñ7g5µà‚/‘BX¿dÿ+ ج6^†ž? ?ìu]5zOÙžgúÆ-êªÌÐLéê°ýa çñÓþ˜¿ñôŸE‡O/&qÜöê’÷¬S÷:¾¾- ½Ð¨ [Ý/¯Æ—® N„Å—ÁyIjCªŒEŽÔqti ? ~ƒ/Œ|ÓÞÍ9Ì zºV‡:Ö{~$q X§;l@=x/JžMÂÚW쑈0ôðÇ–º!ܲ¶ÄDbhÛ ©D¡½¯Ï†í+Mo³ß…ƒù´"ðrØÅÑô*ä‡Å<¡ÝÍy^æ]Pt]€Wè:GtJÚÐ6f!‹áGïôjBZÕ8Ö óê½á·í%ç‰?#MênL%‚¶t/µðœ_èHUB³Ax(|Põ‹&%4^*ÝÚ¼:ÁÇÎ8ÏNgé~’㺌(‡Ü”ûó_‚×Á*"Œ†“YŽäwšÖ|uÇkã ÜØ?§òckŸã÷a–êËF¡Ú>óvÕ{Àé•ÞCãWPìn/g§4~,9HÆÓØ)sAŸ …A'/Œ¯•C<žMofS[0£Ï…B'háF+–-GFï­…²§ d×}X0[xBß…Ào£béø˜Ú)IŸ …úW³‹‹±ÓyÎ_‹M£áGJ~°ó{åÇ$íÁ*UÄg ~ßdn=ü>”ÀiV¨6@O‘ î ’zîÀ‚x¬:‹(߬J‚-Ü´É(àYÃ]:2X´°Iÿ¼Õ >¾>Û‰þ‹r> üŸ ù?àÜòeˆ¾!Kºœ0׺±±¿±Ì:<þë,JÈÕo¤¬whüšIEë¢|Ví|wzfRÜÕ×tÐΊ¦Éø•¢"s¯EdÁ^úž~fÓ«ýÜhÖÁ¹‚BÐJÑ"A»Ë‡2Û{1Ø=U8ËcÚ› út(&y8ÞI¯œ Î}© Ýò¸(­‰„YpKîÈ:yŸë4¼ñ_çÒ÷BÒOwŽGS0Š(åu%cïõƒß¿I†Ÿ Éi§7f5ÿ-#ìSþ™Uê£ö›ö¶ºÉ©jÀ—3L—kŠâìÝ5%#¸¹<´Š¸µD®hyt6ñýLì-lC"ÇLbmš5²6¢¨ZΡ ZŒÚÜ™îÞdÃ+º{y†óQ3Ý'^›“×'qåÝÒK§ÏŸÑöiéÄÒ®ƒluc¿Mgñªª%ǩ͸æÄš[?lm]1Ö)é18Y9€Çaš ¥ uP|ß |ý6Ë’'½Db×%V Èç4(Š¥ÆŠ Fâ,u0V?m”j¬3Í…ýyò Æ/ã*ép V'$¦ˆ‡76ÄSÁ<2DsìÐ xEœê$~®—‡2Kóä2%ò¦Pð–;y4Š•0‹øf3ø£çÓŒÐéÓWn»’PjÛ +•HÔ°Ð#äP×vÔå‚È_?¡ùŒr‚GLW?¸ÿÞÑN¥¼0:”vX{Éø+&:fŠ6‚­³fðualõCõ)…Ùù.Ør²€HÑ„ îaÁØòå’a§×ðï5MÀ_EŸÐÐgòTÉ=n\¯¶Ô˜A”7mNÒD ”ôLÇK¢g«È‰GpîÙj üe¾“[×»îÞ…­àÕkîðÉþ>fH¦ó¥õÒò¨Wñ® %`] ŠÂª­_–ÿK{uÇg ]7ýã/OÃþ¾[$4øc°lÛtíH"7ùÀ$µEFäeU©GìDŠÊ7ÙNÝPìk-BQÚ66ŠàÞïGŸêBA×$"Ú/+(ÞAPs1aB$Üaçm£¦…jAñzP¨\üYj/…ZÅŸµê%Å¢øüîÜóéݸHKñçr-½iÖWt,•®$…âü¥”Ðk*Ï mȯRSJÚ°šB5ûƒ”dÕ®PŠ¿”ö.S(e’®¤ö‹:¿hYºÊ‹Ñ—RB®1…"ò­–)Þ]Š¥‹¿›zþÝ¥TÍÿYj¯.…ZÅŸ©Ö—f‚èr‚€zÛ\{Gﺧ½AppzüžmÒ{‡~wãÿÖlÇ%öX·iwŠm”¶T.íÖR­ÒÖƒZ¥ÝZ®E»‹Ò-ý^ÚzP´´[çÕ2ûίh6l©®lB(.{´T¢nÏA•ºM[jÃÙ€PÍÙ§¥’² ¡”ìÑR gB)gŸ–JºûŠºµ\–7!ã=Z*¡{AÙ¤å2¥‡¥KÛµ¢^aëQµÂn-Õ*m=¨UÚ­ºL¼›&1‚>‘çèC’d4›$p# ¨=‹Åjð•`Þ¦¢•‡~©ÜîÕËn ÷ÛJî§ëØÛ­íð´ûõ<¾¥¶ êÖuØ’ŠÐI \ºjTþn¹ kËV3’K\%ÏP»|ñEq3übÛ ÏŽðí2,˜¢à,M$6þ‡³Î“á &Ъc:8lü>ˆS((i5©NÈu¼”L'ñ Îxlç1ÇØ‘»s8¥w~~Òá\Š#DØæ@§L_üÈYF)j›'ªØíS=nåvP ½«&m¸3ÃÊRêK L‹ñuêì»Mìõì»­Íø¯‰Võ×ò, ‰Õ†ªäÚÆæçä¿æj­ÝaJž 9ƒìlzñû†ÌŠH³´(4'R}éÕÀÙ­ˆ>häPGWŽ/ò\C´¶„­a“[ßãe S&e Y¯&Þ†Ÿ 7üÞÝ%4Ñ úw×çI”Çý¦mWÝÈ jä0IgŸ›bZQ”¬é„—LÌVél<Þ˜¢ŸFJŒÎ¸Ú~Ítvbì>⹓¯7»P`Iü«lˆÿÀŸ†$| ç6¶pâèuÛD¦!JÏDû'£¨É‚dk:þ¼D[ãMö–ž2dC@0úÚ¤N=¹e¼{c¡Qò)¡­ÃL…]2ò½‰òd(ö‘àdLÏîvû³Õ§?e¿ñuWV]L[tùUÎ1–¬H ¹äqÿ]çt?ì:ƒ³>¥JšAÇÍÒkÎÖÈÁ«l¤cHAµXŒI°%r÷•ìÒøŽîs ÏpÆ#~lW7ÑøsBY¹Ägqœ©7ÜTRXÚìX8ƒ&dxíM¦f+úâgM¥K‚@9lY[|Ðq,½¼ã€ „I¢Ð¿ØÛ ëÃl8©ú9÷.ŽèNMñ•kÎJØ$PZ*NI¥À'{LŠÊ1˜œÓ`’7תéF*#\uŒ4žÚ4È^“O± m1!ðXü9Ø%*›‚r@_æM9³wiðØi’†ùì\¶9j"ŽRÑrÇ(Þq2N9òñ` ?|3F·aÈžR¦Ù9¥Ÿvp¬ŽºKâ†5‚ %ä5ú–‚Ó‘¸ÍqÐ~ÝÛ­aÃ5íº3‚. óQõ<+±Úʼn†y³éÛÛYîV2erWŠ/"Ô–>áµÔ”#¥AªWò¾J;÷f’Ïn¶œƒ`ꦟŽ'ûIìM( =NÄ\î!C|Ë6øÖ‚s¯ùéÑ5•Vc¥éï€f׿6æxã‘7Jï]oê¼{ÃaJ@²´ãK>6ÈØ¥ÒŒ¾ñ¡ks49O¦øöO;i–&1Bƒ`ÇdßÈe—ˆÜš‹‰¹-^îe Á¶øñËY·IVOg¾ò8®ŽOOg)šŽSfX5$yuYŽ;mó¤ï'#™ìþàP-Œ¶PÀávÉÒlW!f$›fÖË6BãÊaRò‹;+à2 ØÿÜM°ÍÆÊ=­î$Ù>Ñâ»®Q™¢KzÂS¦Þ“`ز5lWl;AíC©øX%HýgÙ æÀÆ|V±‹0¹ ÌËèô±_cÌ ã{fcØm9§QTìªt„ìˆ+qþW^j .§›xÁ;gÃŒÎPŽý¥¸&S¤`¨Ý×Á°}_bêÊüü ~B ?~÷]2U‹†Žš¡6Öᵑ÷õÍ—`c³–ïØÝ!q‹ƒÐÓó)ý¾,»²ÖŽ&Ó¼Üpk»|Ld“.´Y¹pR2þyx´(cª¦ÒÒ©h™âUO#ÉÆÔÒ//ˆìôEÁŽÜ!ù$"üÄ\Þ“6AYÓ$©•iỆ9»øÞ!ùY*‘ÆÀݾêî> >ñ&LZPÜ#ÁKœÙH@lÿ;PµûºüödH‡$ÛÁ§?'Ñ 9‰'%DÐÍ@<ò8ß´éÁAÆé;É'½}&~¤ìÌüi–5€û831tòdƒÌÜ0å•%MýÏÔH ýÖ›œ]•©µú—[†{ Äe”jЇR,Šf™÷(®[NúË•O‘ž†µ,ðkͺØ)xY„Füú¨:±ýõ\>¹/¨$oú jÉ6vM®ÝÂËÔ5>}ñ¯xª^¼t2x堣ɔ_¾¤&Ýv_¾,';ï_D¦óêådHÀ‰’🥠ÂlßùSDkèqˆ±„·ä Ï£N w9ðÉÆt“.[â@¿_M§7ÛOŸÆiû6ù˜Ü€LŒÚÙäò)~zêV¥²Jd~îšB¸GƒÌàao0U;ÞO°Ÿyßll¨$¶â„yò8ue¿óÚà—Dq`CÚŠWXsc÷­`5œ&ÌËÞín£›FcýSóÏÚÈ_Z}öhù‹¼P,'jäÁ\èî·9[­fyUËn¶æí%ÎFøwì%ð‚ü8ž ˜`$Á;h•½5—Š,(¹Ì²F˜ vW\ì¶}l²´s]ãízælxƒ›‹±8 Íqåè6íé*½4¸Îð&å±Ü£(ŠǸƒ;Ú. ôű×»¥µF¼úéÍñíêbΞÏ9~\S¬ë}ÝëDžxz‡ƒî)6«^O\–A³Î3›,Â`"ûÐ=ɵ}з°—É4ð î°Éˆ¯ÏêßWe(,bi'Ô­Ýuˆd61òLÞ¸XCŒçX¥ÆØé‡ïÝè&®˜:Òe?Ð7Åc™š±únOÑyžgd{ÄÈÒ 1,Áý5·ùKƒr¹ Ýý ΃@ÇíÏ×&ߦ±Î`ÇRNH¤Ã&K.¸%1_½Ê äLu™­TGH>Š™ ´\b„¿*À•8·Éx4ÄËÛ qIjäŒ5ú ôµÁWkÛk8Yk?m®Yk,ÎŒmdò1w•ÕdZÊ<Ó5›äh;01+ Ø16õ.ˆ/.`ÊŒ‘’äG± †áD>·ñx¬/D8D>M…ŠRŒ*¾JíŽÔîlâò“8<ÕïyälvŒ6Áº Ëõz ÖŽ}ÎÔ¢lÙ°.Ò²"îü(V ܹoÌÁoŠÔ²Û¿‹Û´|îO| Z±‰Å¹0êšÀÚ8ÊÊèùM™‘,|V,¼Wò¤A»?t÷ðMò]çhÿä`Réµ}Ó4Žíve K¿ûÎ"5Ò~¶íb¨eïè¬ö»Ó½w6®íð¤ë‚ Ëw1ËÅ.úm<µ³,äì‡Ô±uê„÷#ÓØÿp|ºoI ñý¦snTSC«¸«óà&Ìc|[EA¦ñÞ—ã윯 ºaÇôR›SDŠ %¬Ä|U¥Ä ù¿êÂõ¥ÞƒŸÌÙüP‰¨I|}ò¤%ËåäÂà2º/!ÖAï…i{ÛÊ~JÚì^øJN”¤{L CÕâI‰ñDú"¦ÎI6Žm*baÂüþ=îóÛ{@oïÄ æ¡‘OÍãÜFš@‡õ©“ælVèäŠYX¶|Ìé¤WPœº‹‰á¯ú<šo;"9ÞúÌÞRŠmÂÉõìÚµ@SÓ¾«nw©­xÿÉYI´´µD×Ó-ƒÛ*&cóZDzp—Ý!„Yi.£Âz0ÃpÓèk;Ï’]ºýšb26ô5ÙtÉÝÝdéaL>3´×a%¬%]b’ëk¼xOczСX?Wva©œ[c½!8PoegX²´;qøÄ Ïsº¼²¶Æ›»< &?RüE†ÖÂò ®ð™Ø“£ÎR–RøTŒÕ™ ’”î{pNŽtþÓ5ºÄ)ú¬-Á¾Ü̼`eGD¹b‡ÿþØ#ôeŸÍ1{|<Ùñ/)‹R’ÌÙ`V¦uŒjçÓ¦Jä¼­ïdGª“6ÛWÈ#¾’ÑwsÀWO±Ù^‰Ç½|"»Ä»‡ïÞ5„ƒ£9‹bñš¢ëWÑ7J0•Mï»JX'¢åã©)/­õ¹ÝÈóA"|Ni]ÚYèsî¬pvq.ºÏý¾¥nkÓô=,IŸ1P,ÑIÃ%n˜­cµûj”/“¬-¹¿ ‰òÜDv%¸qÊ9ùÄ<æôG¥ñ=2¶å²-1y͹,uCoœXr[¢†Ë&_ÇV'ñd@=?zÈ"o-èé±ÙkPÂ:'´ ½±ñ1šu—Çnnèë–=þ™ÙqÁ|»+5Ç—Å\z¡Fsµ2ñÃ=ã… ©ëz6%§ƒÜÍ «žÃHyAEɬLšŽ^jýNY1°ëF©äúžK Þ'¾/¸¡ÆœltŽÍ 縆gÝ"†3ב%âÂø¿^Q7deŽňœÄ—è^4A£ß„p!ª—ITaIPQ 9¿€6Çä°¤BÎl+h šÂM.z ÆRÈä€ÏÊœ»Ë bœ›™j¿¹SÁÕâ§o˜í W|9{)#—Fû‰‚4¾uŒé6_¥lDwöžÚftr{¥/í× Á “ÂL30"å[Ñ¢ß^&o$h/sP›ù4ž.ß-¿-hz¥*w`‰»ÿË“P/÷ ªÙa—œ”ê2ÙD”OTÓó‚tº–ìôÁ÷V‰t.½˜¶ c¯ËÕÃÅþZ“ÛP`IÒÏi]òãQE«üÃZ¤]jŽÝ¢¾¶5/Ÿú¢"ŒÖ”’â—$ŽŒv§¡Àô=å8’eI(L~ý¼ßÊ«g{ÉvŒ3§€þPÖuñ^ÖåªëþðþP¾Óù6àÔ<°{möam¹°Eúî² å÷êDY©’'ïGè[йÁÙyoÝâr]³/ 6\;ÙÙÄˋ%è¨÷C#T‰J‚ SPüu}Ó0®úØZ(î˜IC_<Žn*A‹i ¥Ð£”R£Ðû«ÓWõs…bXñ¹>’ƒ‚àßšæùù„>—{þæ€vzì-Ù«lMî•la¦[ù›Ág† •R‰ÊÒÃbRÚÒ¨¤T½~׊Ú]ö@‹FáU6 %O©þÍ]38'æÕ, ¹ÞYÚ£kD0d•+v¥s°úÇ~CÈo´!r´Fdo[쬬7íÔH\x,äÇÑÙáaÛËì»͘s?I(ñ'Åúã°;îkß©ÏÒ#noa }ù6¶L˜3Í©ºòn$Bà²ijæ!ùçý“O›7aïùí 8o¿æŒáÏÞ¬0þn®sêHàÐ|gÀëRÂÖÊä‡?Ê/ùº)”SF¡ã‰ù¶JZÈýÔWÇii$)_I5ÇG8Õ *kÃýö—øœ_ÀÚÈŸ¹¶ ôs½uíÂß‘;Ë‘êtæom¼j·%Û“r!g²Œ–[x‰¹$¨û¾Ió€IŽIc+¿Äyþ÷|m#ìEãYp~g·Ø¥„L"†Õ'‰`m윉Ì嬗Õrïrz{—×9n„[Ö縂ú]5w&ÖƒÀnÐá ËpâÃYð&š ×;w‰œ\ú훚\Ý…dàÅAvÓØ‚šÜ˜ªév.SÇè@‹…'ÔñÉÜv›œ±°]xt˜[§øÊÈf¬£cÄîuCëóK8q«Fæd2Àëâú@ž"ä!†2oA(zÐîü½ÌþºÉ%¡¿‡}’më£Xöb ("$ÖÚI$.U€Ã‚ÂÀ ’»}ê>Uþo*vvŽìÆú#v¿Ã?7LSˆe„<¿9ƒ›Ý„Ó!ÄoKl`#¿9uûàËŠðÙMÍØâh޲ÛT›ÛFæmZj¬Z%óBï–táñꘙ¯/moÃ9uv£ý¢£EU0ª}“WÛ#;£‘ò,=Ý)8 êüK0ž¿rµn]5»ð~[™Û =­õà„áë/‡Íú’^[»^·«Òʾ°ÙdÄS ^[bnÛ@ÀE7ˆ”¢LSšÓꓘ}køBÚ0y÷¦­ k$;&é§ì#FØã+„ä¢ÉCˆçÓ3Iír²g@”kƉ#ü Ç€ð c_ƒ²‰[º.­:àƒÒ 5Cé k«i2IµwÁíI•«{ˆûD»úBéÅN¿Ú„Ðwa¬©ÁhŽçC’Þt¶C™í( Û½¼{}3½£L‰Â Õê#E~TrTí'‰Î±h3óÍ¢.öð•1²Ù¬Y:i%áð¹×ž,4\»±ë‹B˜Ú¿»… ¬*8g¿y"lc×]L»ƒäæçL:éœvÞóøúà‰{"éÀN‰€oXX˜”&ãø†ôÆE†bÚ*Î5V P¿ŠÒ)úÉ.¼…˜xmGf.!O¯½Øð}Kn?sŠJ¸@ɹ±0C…{’Qhd:–ºVzwïFˆ\Ò°‡kTþÕÜÜ‹? ÀYEy÷ÚíQíHü%©FýL”d·d,Üê¨ý´ ùÊõÝNµV‚=±ÌÁû_ù.Z?7‰D|,Då_+稘üÚ›Só„‡F›*¦UÈMz Þ8±þܽ£þsØtÝPòô»á‰(®Xm6Ž&jåë‚F˜?-Üd†Ù5&Pbxbr¦àgìHðuÆRãà‡1ÅSnÂFsKòÎyK²k³Ë¼ð“BCÎBÏÙÂPC-ö-3{¥Š ¯RBn±t;9Ƴàõm8WÕYš;¦ÒDÂÿÍÃ<ó³A>àh‰œÞ…ÍJ°œæÈÅÞ<Íð}Aš­ó·†p©Ò`4£‰ä\é‚­ ¼*Ûj)À^x'q>u/²Uò©¾Æð‚aðñ¸0#{cÒ÷ìHsÏšÜÒŒ"Rn¦8ÊÒÎè]6´Ö$#95ò۱赌ØÛÞ¦êV&‹‰ÝW5ô6ŒÝÌH‹MuU ªà´íÝ„é\k›BRøD#ˆnÝp}žràÍ÷6Õ­9øÆs0‘o ÇâÅs%StQÙ:ævŒ†1 Tk9€Ú"KÅ÷aÐGÎ&‚b¬^"¦Žø(Ng×D×Ãá|$8áO3¨wô6<9=ï² Ò{ ?vË¿âJ(¾wüþacÍuÚ@ÏàâGž¸œñó(ž"0l˜‹² ME^šxXVê×ݨ}ND¹z÷¶„Aõ0®°n.`\¢G#¨·b@Á ¤Ž…úIÒ"L»l”[ò‘C X>T,¦3#=N¬œLÝd%r,˜h¤Úx ކæ3Ù:ÞKE ÊàîŠ9eŧd¬.+9;ˆaµ€²†Ð¬©NzW·”Ô72ÓTy©80šxÛ.©¬˜\BIЧ³›§P4Ý@}Ź==eÌn» x,É2{Á×¶ƒõÝ'^î$¸ßû¶ŒA&ªŸã1Uvf&ƒl±ãÓ ³Ý–-¶T¸¨x¯7JE¶Ø1äâfWæ>½T<ŠVô7¹Fõåg¿Û¼ÓËqq”‰}´PL”tBÌ“I6î Í…Æ]¶Qá™64Ä4>Ú4!ûÛ¡{  Ì„XõQ[Ó­HJJg`­‘Ì{[‹ ´MxQœÆØqk·ñcä²G˜•Ö¤ÀÞ  —Èx'›™¨§b ˆè3gÖæH²oXu³³>w‚«þ’¸|0Ê¡Äû"âK¿w7µó¯ë.«Ô(n†r‰"eì06»A¥97ïŸyZ޹z1IbÍ^ˆÞ¾cJäSµS}¯u˜_¹W‹&kWVó^«8øÞF —ÎJŠÔ 6úòKÒŸA‘DPˆP„/UÁÂÍTm »®âNÉù0ƒf8&€—”Eˆ"x£S jˆðòBæ 㳇aÊF’ÔÉ5¬smÌ@¼D½‘°^bP&FÂ0Ù£RtŽ‚k©ëð£8ŒÒIao-(ûpî,z,YàëýÌ›]Å; ƒÊïñš·à…Nõ{g³€ÜóÞH7<ÇÁ¢>ŠåÕäå.óPGFù/–{ì¹k†Ø}Þ•WÎ6Jú4iýp½ÞØRý‘ÿœÛ!›¼\à›IÀ{}\\†;I4hr/ ÀO×Ìs™‘V6! "‰}ÿ‚=/ÉQ.Eð”-;»¶Œ‹á…el‚À½á¦bfÆeE°üRˆ¶† ¿;_e7ç ;áüI#Sï/3iþ|4W ¨õ  “¹’Ó¯°‹gè'jßµô¢G :så"Ü 4ÃAZ&ÊÁpnrcÊ/Ö2W?¶Æ$·‚ÜøˆOŠyb“˘™Í„Ò¨š™Ê†ä]@9$á²hçμ¯È5ÄÃ8K/‘E\§.zþsªÚ?y=Ò³Þ­ì,îò– B@ížNP!4fa9锎®#<A®ò›Ýª•¦êýk7œwš÷tç«ÊûÛ9ž‡É·˜ä^†Zþ¼(TRÙ¡4Þj÷ýÀñÓw:¯ö9‡$o¡ìî$/Ñ‚ðŸM ¾Ô3ìÉY76¸ÒáZ“¢ÈjiN ‹­K⊠Ì>…#Ÿ‘d8ƒyí¸}Ó$é 1ÐLørqßl;-lTiÂ(žlöDËÔâI–ã-L¡ïèD³“î›JÆB³%™èºË:N~¦(n÷x6¹9CÛpÉúÃÜL¿ï²Ûŀ㠓eÒOŠ÷‰e+ëXÞ;ƒ¹A³kX«³ÏÀ)m%õ\S?[ùű‚hWxž€ÖwÏŸõ|˜Ý7ÓÉ«:Ëûî|;úN]{õvñÝ*«÷²féŽ{Áb³„;&×T/x®à¼õ÷ŽOºûáà´³×E$òh8Éê¯^ÕOMÁnÅ#’w¹¿MÉwßP-h®Ei9p í 4Xgñmñ7›‰+Mb¾µaA±y"òׯn"pÞÝY¿Ûû½÷'‡Ýð´+L¼’ÁUù3²t šæÌ4RÂA=D •²!¨ß*è’žß.zÍ’0”ö2šŒÆhZmOØq4EÕ©61²Ch«;™¤Ù>õA\±:;S¥ç(ÖˆO¥ŒŸóÄKDįÑl »S:D™2ö Ðn‹H«¢ƒbƒdD(oUsDr2Q\ŒÛ˜£pDfX­ Ï8~áÄ9ñÛ4@v­DÙï1é»+Yã<Â|:Ñøˆè÷ºxÂ9ë¤êºŒÐ¤ýAWüà"âàZ-¦IVÅ‹TR.Ð¥. F(~wœ÷Çó;AújÓì‡~X˃UFI‡3d Û»E!šßP°#l™›ñ,7WÙë$å”h4äkôZz¸Ì.ê>¡™óüp°ôØŽ9Ê£ñ¿éå|8À÷ÞüK³Y æ«¿v€üWKÅ­Ôì[#Ø›äò­œW3‘¼xÌӓ˘cº‰‘(LƈÑ7nØü9R §rcšmsqfP:' @räó„4¶aÓ`ʘhäqn„áÛ£³½0lªû_ÿO{ŠøÝwÁ›Y2ñ›J¥5Üï_P4á=i¾FIÊDú8þN)…ÌŘ ³tiíòtìç’Š©ùuKÌ’ï_ÐR ñ3†¾<Á2ÁÖ& Pìù«º7ÄUÀÖ”ãÃÞÑ`)Z˜”ñx.%µÀËõ À=«¡.ƒâá ]®ãÛãë׌„Ž©b˜ç\°ÔãýãÆ§q4ÿç%Iç6œ)ÍmMè*Ï]_0#]Û; ¹ÓÚKqô 64ç½(éHJUMÍX_ñ5]B)¥†?aŠ!­¸#{Ñü“'^¥òÂì6 çCš’íº.[åµàa!  .äí’}ýeñeG¬^b«1žÁ'¢xx hç:žÇ‘;‚ɦ”:›Y2ЬAO7ñ_gh˜08lÙá6Ò#G€XnìÂÊ ‚õ¹bsJY1ðR=“üä ßÅf¼ßªë*•p.¾6±ƒ5›lòv°Ÿ‘P—“IÊô«7;#Éñk tD†FýäfSá9ìÙPÈÃÔs“Á¦]8ÇH¶‚¾uüóõ8”7ž¥*û>Ú6å ³œCÊÆnd·§ÀñëW2w°ÆYß¾6æuC®ìº²R_e/NãØà×ÝUotû™+úYÞâIqnþ¥]nP3'-t£œŠäµ•—ÜœDˆlš¹é¯2BîF—ç¸ÜÑ8‚©Ô—RbÉ@ZJYÒ9ÏÑ1%WrÙs¸ÅÐ,/ Ô6_{îk\P+÷é{Êw;áé³}8à‘UÅ P³„‘Q`¿“Å›ŽlÓm€‹\~Þ¢[\n ÉôæRÛ•1òcí\Â(Ï)¢;Òý§ŠL%ï0­#P£Qizø.Xý)]mjì§é” '˜KÊ®LåŒ^a–Z,o‘ ›,·„ÞŠùãAmþwÈÇ6öu›H¹… ›À ®6ðOL' ÅCL,Ý ŠffÞG½ñ"b W¹I*“’ÌýbšLèÚTZi¯áÇeß«â†kèâ aj­YˆÇã§2y˜J޹•t’¯pJWdÒÚðóåôÊ mÆ£×8¥¯¥Ã°J#Tj"ÙôïφrÝáñÛ°ñ¡szÔ;zÛôN&ûÅêÓÐ4Û6˜ƒ™øÌâ_«Åz–]8e %4£´qVÐq‚㣘8°J@ ©©ÙSõ5¥5Ž'Ÿø-Zöp™É”Yro>(·ñ`–À–´3³ÜÚ9öím€D¦èIé&ÇóE©ÐGbƒÈ&+®zBûÄ.ÕNùGgÉVìDÔÛžÝmÍǬk}vÉVÅíöeó $M¼´AÎð°[teÐ[ÿ'þ»a{þð€ø'Œ ùzŽwNÉöîÌ 3„¶bE6ñƒÁ´{’mL" X<±ÄÌn¸gQ‘®8ÝŠ3ÛÓá-µ†’œXëÔ/©ßìS‡î vf\Ì$­˜m}>Ás™ êMks9ÐmÔY$—Òùë…úÚ÷uv‰Úf|ˆRjì:¯Þ èŒä.•~÷$(Á7È0+£;dÓÐÔ¯W±WÓD›QDj)°s¿¸ÿBŸõÛÀön¦ÕÁª®šVÛLaZ ÕÍpqvñµöI!hþìVÎ,VŸ7³þ¬Îï×ék)žµ-m…mlnì:üëÖ»7+W·~¶^˜7¢xåöÑEmžR;@•)–o›UËG-שñš\Ø”IܦV§B²[±q¤ÕL¥ÙÅËâ\öu ÇÂ!›+JóB×¥F¤Ÿ,¥”µæ¦cí z]pÁ]æz[:˜¤¼–°¡{â<[ŠréÈn§Çá$Æ ƒ·&Ýb‘dÃlŒoJôj’»ð¢Ç F#k©`ÒA¨õCy x½ÕÞ\U E'tv•¬"–"vÜøc°ºµ ºÕêæªT—ù±ž,U:Úna¶–rÏ(©ERŠwÞJkÕ“v“ß­ÔÃ¥ôƒXß*ÚíŸî…üWïhÐ==ê"Šcø.\ùß´ÔXFÌï»Gƒ%£¬I¨ù­>ê|ÊS`¹Bóçü¬‘%ZA‚¬0ÐŽõÛÙCÏËÞÅNé()ÿà‚—• µuŒ!<ª¼-éÓH«º½Bëµu†fàŠ‰“éÚæ´$Á1;bå·)ª§ä5WÊ |Üç‚ôðM üù/(Ù¥Þv÷Ãõíõ§öÃêŽK QÅTÎ!Ç£‘Hn“Êy¨·rÆÞÙ=§…ç¤Á)úãÚΪ¨¾`ÿç qÝü²mÿ|Z¢Bà•A‡c’]ªè”N”ÑØëlÕ&ÒØ-'2ÝlTsÍ@¨šÍÝÉ-’,;ýT¦Ü¦Iô¢Lšƒƒ>*ûåì¬P†b ¸SÙÀˆD{v¿ût»|¯ˆ4^Àa*òZX‡¨È] ÇDGÿ^$Øc‡3â xþðûTÐN¼;}Ng}Ì?ÞÅ(‹E)ê]Š`>š \@)GY™‰0);—²×ž:)·W\:­›/çud"Jû¶ÂöO©°ÇeˆîkäOIo÷nZ üC¿Ñ„œøjgN'z¢ˆˆ±a÷òázü´ÙÃíçµ¾EÖŸ+‰+AŒ ç+  Ì%ö€pR¿‡Ý£?…꜆…D‡ü7®úù$]Jºï¿F'jà˜F}cæ·²oDA,¿ ‹Ö€üÕÐ/ å ¹(ʹß=@Ìcœé_®0ÄfÝ|&yË ÙÞFå`’]¿å[§ÆjMÅÕ/š A®ž‚x.æoɲ»ÿsrgUù×T":@¨ œB¨ç×àÔ‘0Y¡lŒÅ”kI6^ì‘Z“­‹€}Áƃé|v‰ûÔà§ÐœKkÑcv1­Å@+n½©«ŠkÝyß ù7¥•š° p¿Žökz§Üršf#¯k«:ˆlœMŠ”ó£@;‚W£Ù4[U’?(&P! )‡YÀ~–‚#±Ü!@ \ÖüUºI@£Pp ÿ]i¥y±Í §MZR›‹ÐýèQ ÆpMqœŠ4Ûê}õ‘ -Ø(§¶ãºÄ¿¹²hBYcXfF%§x«BÄéôv¨Ót£:YyÐ ÍŽ\UÕÝÕÌ u܃·¨ê„Fèv¡ÑQRmcMîxÛ¹ÒSÌ;ˆ>ƒ¦Û†i^ExDg’¤@µ)Œ]Ç+ãˆ(-˜¶‘ãpÇjB#Jµ-µÛ©‰ÈB¢Ò;bïB2£z©š=ôCYÀ̦Ëp—ĵjWÑ‚†¼F(T?­‚’÷­\@ÝwôÐ3Æ$Á”ÅÚÓ5õa‘„a,ŠÝªˆc€‘PÀ1æ§F„/²I[ku9ìr"t;$|}¢º%ßn›Þð·§?­šúõæâC;è>-wÕU#0¤AaÀm‡=©âCÍX<£ ®Õ„÷k9ÏT„Np˜_%Fwž[»ŽFÅþ×'ë‘§´@> ùü£ƒ®¥dþZ|hز8.à°¾GwþsÎ!J²|.S >&¤:1VEZ{XÌ'Ö) Ôn½¡è%Òž'm,»à[ŽÀ"`ü#Ê7!9‹dŠÿ¼Õ þ€ÿý…ÀÆ6m\5í-®Í‘/*ûÕ/1J*ÜÒbøÖ5Ê$Šìâðt,c¡m0Ì”XùŽÌf"²dF™Íõ3nÁŸÈÑúŒñÐ;êŠaqP ZýñN¢Üç²0íæâˆ"Î'âÉÁ޲Ü$y?ì­ÆË³BK©¢™Ö,¨ÞrœËËBŠÉ<²xwHÁZ­oÎÞ`^Mþ&'ãšàþßÐ ¿FYu¦”+f Þ)ÕÒ?¾>ÛûÛ>~k²T~šn^€È¬ÕsqþsAøDºo'¯›&ˆ|ks³Å+œg.:àŠ¾ËuÅ:Þ¡GtQôSé› bQàF¬s‘jX¶q‘Ñ»>tí@Î%<–Æ{‡­n¿|ùœ½ Çø( ;“îv™™ÌÃ$}žÏ³„Ë|¯»K±F‘‹?°ï†NŒVÜgèL¤FéÚn£õH¿ð.´”ðUŽRIÒ' v•†ÔÏ¿Åt³lòIñŒxsáñ‡# JDkýÎS—a`x./¥0KÙ¥øF ³,ŽFjžØà€$ ò!‡eAUlSÕ8ê-;o9ȘœˆüðcŠþ3ì-Ús ¸±)8 €¥bŽ ÜËÒKX˜`¬-Á’4÷Þ¢ú¼7‰rT•Â5jdw.¹$íg ÇaÍQ’œb‘öÊ Ÿ€^4G3 ùž©Ñ`ØtÕ;´—pMbc³º'çCÐŽp˜çMõ¡$­­Íç/·^>{ñòl]¾ý.Øzö>7ƒÿ°ô9ÏâêÄ"i”†ÇʼnšH7žð2«rÅäJ8»›MNˆQÑæ«×¶_·q™Éìî6 ’™4… ¼‹<Øqÿ­:-qÜ~ÂÑ*$9 ÅÜhîµj¨á–ÅK#d'tp~J¢à:Í@#¯MàÏ!q×yB70ÄJºEæyå°{‚žívÚ’ ܘ W×r™ ŠVB4©i–—Y¦È9™×Ô¶Æ(YÑÿày!Sm|•Î-ò%z'N*S–¢7=$¶l!bÀWw†Eèà.gÑGº3r6J?tÐõëñÖ”2Õ¨µ‘,••c0/wpCïL.?åP #C8Ç)½ÞaHðTv~ö‰²ÓTÀLµK„·½^#s8Ñ­]×Á§Wz#yq…Õß`:ð[IÆ1jb»m­š¡NП]Š H>^m@Ç´ê =¹„xS^:Àn€ ‹Æ¿Î¤5‹… §œ¾fo뀕nBX;úþye;•ù…o¿ûNMªXý;-¦ÐŸ“¿lìÚî !/P\9³2o®}ybçŸt<âQ/8³¸1øíÆ.+—hK…yxòÄýI*–¤Ž÷jê$‹îcRgóÖQ§e´ÅTænd±µóìHèÓO§³´¸ícPb;¤½ã˜|Ѓî/ÛÛ况½= ›üÏ\Î/:–Ì-L^Ö ~—nQ}VØsM#vþt)߇oD(SÀ]˜º8q0-þÈÿ×:Ï-ƒÚp':“ïÕ¿#Ç@Cì¡Pk5·Î†lm¯pÎ6¯? Âóåµ,°´ëøXíZTšÉ&åxÁœ®ªÈžù0oÊ;7q gÌDHÒæ„0;u-,‘¨©µ±» ËfM=ôÁù˜Üäú¨?yÌô@ާy<¾h×4ÔôÂBeµ [‚)ü#‚Dž{áæžúŽo½½ðýÙ ûCظ ¹"ú­0n¥ÆÃúÞÜi> Ò|…h‰§hBóœñp–Píb —ƒüB7„Ýà2Äüzõb¼V|âœêü¤¨Y–ä)pï¬?8~¾íÂ,œ¾ýS?lZqTS‚q¶á'0LË6gÆà\DÖþR‚P[W„áCÒlÅŠ‰à×Ù'¯í¸·Oö¹&Jj¯(Z›æ®kL£Gä-G[×”ÓpÔj÷œ@~÷rè5ì`DzûI„-1St±j 1vµ©SºTUw9××Ç̸4Å]î딉 Oí‡í"À÷¥†ŸuÅ$M™HŠË¡?’1Ÿ,•««Ô¿Š²Õo߯éâ: ìIÔˆë5'Ó_~ävéÒ‡w(ˆhj¼Ž¾lWÔÒgm£ú;þ¬«nD´Û;?:P@ùðjRn¶¬m¯Q¯ÒlCjhoÔØ§»R+Í`{™b-!g£<)e-§h×\ôÜWNµä¸ðPÚõ”x¼jØÜÿœ4‹–µsžgcœÈ΃Ìú÷üjKìú-¬®~õÊbgþªVåȰh×è\—‚´Â¿Mn,vce©S¸ <Û<©Ö´\ö®jÂUùŠy½ ¥›GO¾Ã<àï‚-3ß8?·{¹»Êês® ·QêC@S’®øyðàÿÄ¢ZÒ7§A$i+ôsïÕ˜9)Žè¦È¹òâCÈh·Êf+¸ã£Ú¿!&*q Ú:irç¤PxF‡Ôž¥èv"’wû³dÅÜé¾ùšuÔ¥¶+% [^+sèB ﺥ1‡¸»W [Mqgô‚ˆßÓ¹£¹gm'-ß´æÖÑ–N•MWàÊÁgÉŸs½MÆ£!Ú˜äeÝñðŒÅé™_V(K‚Þƒ@!I¨&ž_¶‰ÉGÉŒ’ä ²‹ê3?›à è—°¾Ó«k1QÑ£L|q–n%çì2DXʰˆR8ÃÖocP9㔞5m.1uõtàB‰—ºŸ–ô Ó-`câ‹ï8Þ­+ÎØ"kIõ/XǘAôùm‚ž mÑD2à•'tÛù¸½¶Í1ŒIáN{i†9‹µ©wÍŒ…A޲ã´þGi]“çáË&j>ãØ.jUSßX<—ÊyS&€Ý×¢K˜ÚñzUÇ|t6V x šd*3›j÷!Ç’‚HIÎ:.5¡_T‚m ÍK9]hyvÂ3,ÿ¢¦3¨-ÂùOžÜ—3Ÿ_p[W3´´ ®F+5",~ ¶Ž©Âc¹ü Û54”K)céÛÙ1éÊ@ÌVï%[¿EÝZ±eb¢ ø6n$þA¢ñ))ú4(%‰fâVõ =Æë5“Ù\D")yœ÷G«KœõE6Kôâ^¾WhgËC0÷{­®W0…ø5noÃGÍÒp¾ûάy(¯Î èÊscx\ç\/W¯L K1/ɲÒ¾ÄQÁ?ùòâ²®) úy¥’}1Ó§ñe:Æ`³öªFÞ¹ü¦0}Pâ§&ßÌTGÛÆZKÜ9˜>C£><Ëb‘’$áFêʦÕ1 C>ä;4áüUªÛ7¾N/›ÏÕéËuFQ~e9û¦…SQwò”²â÷Jª¯Ü˜ÏÅfTsi”þl ÁÜ…äòÔ ™ ¦ûB€gåîÜ{ÞM‹FŠÑ hÂ1‚Ùzcbn4:–Å6lÊÓ!x - ©g76!eÇÄÈ0[käƒë¼®­ËšIÅ«ìÜmP] ú° ¤‰j½Aç#¥-Ñ]­8ÑêœMÚŽ¦nr祯áf?µ ùFLûçÔ7µu)\µ´”³ß}çʰî{ÝŠûêþÐÝ;t¡ÐÑþa÷”€Ý<ìÓsm룿ŸA“Öï®ð¶Õ½ã£Aïè¬ ývN÷ÞÖ±Á(¤n 9IL‰âiŠ'7î>ö}GDâiÅŸcHÀ6"Iýǧû–°ý+Ì{|ýÐ"<0¨[mûLzKÏøèÒ‘µ˜2-ó¬mÒ>Ð]’ÝÝÉêëN’Sãy±")ÚþÂÏø˜aÚèõèli#›pÃI´ÆwM7Ï?r2AÍÁëDó|6ò8®¦Ó›í§Oõíá:N²<»˜âÕùéÇó§[¿ùì/XïÇ3ÛÉ-Ú´i?yö?î}þÜÕ^ö°ï×ÁæçxóûÑïžÿœ:ñäÉI–àµ("zyœ‡ÃÝT<¯¾ÑHÚa#> àµLúæ´Ûù¯“ãÞÑàá­•F:·)ç1Õ+ðÇ9r»~[ÕâânŸ$SÃ5|OÏ9Y!ž»œl!rô–ªœWì°r~Wv0ÀF׸ôšE´uˆY¼8³É´ðHßfpœÌ\ %ÚÂ&0n§„÷Þ^éStïAô1®N¸µ½½¨«êþoÉ$º[ºôÍ0QâÂkXç°Aѵ¸2áñÑááÞÙéi÷hÞ[íëxå5Ü(zMVùåŸw)mbÍ’¾ÏÔÃÕÌaë!Óî^vž9}á˜$ÇÏžíÉÇÁ˜/øÛ³¾•àñUá+ÐBÃrùÍÃôUóÉð ^¿aÐÚÆ.4?/Ý ÁX Âý…‘Åš%µ°¶ãêV²‰Î8÷B‰„%«Ybœý0¢ý0)å· ¼„T&×Ý2œü¿ YùËË­ª·~åå½ïºT4' ÔC°*|¿Êj™JÆ|Q óþ+€V>²k ‘è@‹¼õðü,öúñ šFcY ãýP”º뎸*b\ *ËbÔ†_žNFuî»Î/õŒWEZüš¿yléq¥ÈA½+ƒØfïuýöSjñXñstsXÊZ§zYô,z' ô@ëìWóœ-YеÛEIl$J²‘@f3(ÿU2!Sé¼5ûU]miÒÆ¥æ™Ä¿ ¸ÕÝ/=ÅÕÿy¿Tñ‰­¤ A‹ÜÄ¢µ„¯­‘ïu%Ìņ£ò ·ÇO«KÐÊ”ðTü“QUŸ36îÀÖ½EuŸÞEeü{(ð);„*”æþ:Æ|~³ƒ}äh¢ôÒ…4©þ6–©ãHŽ[ñÓ3¢½ò8P že¸VTз½]Iv½¾éÝxE´. •bRîÊzȨô1·c:?HXš¯ä\hAëÜ¾â… ñ)žhL˜Ÿtë y×fà ü‡O˜ °ÂiÍä@ºîZóª0 $»O—4-¯?°E&› y_ž,ÓÅcNâñ“VÆÕªX ÞWHÀn õ÷g‰eÍŽî=øHççLCû2vÌïf…ï?¦ê_’ýrÃËcܾRÏ“ê0´ÖÂðåÕ‚Búo­<([0´Ndåk¸áF²éiq¡ñ ôÃÿæQ¥¹)æRÄ…¾šŽÍ›GÂÕ“B°‹ËPRÊâ$7²å)‘ìí¬•ã%p݇s¸9‘³Ü³ÍÍ—O7_<¹;¼j_M¯ÇÖúíëãÿ/úu±Ð û¤°„¿ïÇãi¼^)®³[w·±µõý‹/~÷üû³Ãf°Ž(cðßÙáNÑos|õžœù¤rŸ†<ªÃiµ~ìºï½÷Ý ÍnCÌ* a[Òd¾ÇXMýáì°sú¶K)ÞvOégÊÛ¼ã$þ}g…<Ö ¹èfœÌVa©û”ÓGÛÉuNM|Âñ~lØïüˆÐ!hžÿ»Øqóƒÿßð'ñP| ,öý z¡ôèKK~þ³ŒÏá Ž‹|ñ‡?|/ž©¦‘8MŽh/`´³™+¤KÍ; V¼,”gƒƒ­ïA+™ ã@ £~O~jQÖì!a†RZŒøÁØ&oàRBRpð fä8—´£I<»Ø ;cp+Œóç¿´½ƒÑ!¼êq‰$>†ƒ¨¿o¯žì}èNe6¶·;@ ;›^l}ï¹ Dð½Ñ·š?Ê¢cKöà ¦—S z¿TÜ/2Kt¡ µ¨¦Ž§É›;x ŽFñtÞØ; ;{'­`³Ed´¤ùy×E$ Áç°Ï{ï:§ëÚ!ŠØø–¿üsPjþBïñ_O„´Ü*ŒSß$ð«BïQ,.™UùU/ † =.+2 ·øÿ ô6ÁBt™L™Øo!/6”Agø]HO– /kyW«ÈeºªƒÌ,µ»À¦ÙV°±µ›µä# ížvÃ/þìR¢¬ö”0?:­—èÁßÜ†?qÔO=J‹ŠDFƼƨXïÛ,ØÓôÕpU¬ r¼ ®¢On%Z ̆oqgé8ùHL;¼¾ÁÓÝO˜N s FR”¢FÎöø%‘äDµ9©¬[ %ÜÑ“.5¤ZÌ”xÃSn§`2¤çàJeÍ=þ£û×Y4ν€ó`|•·¼Ü`r•[™‰¿«»F`øub¿4‘+î—¶d9„gŒº¥ž^Ó¢–c·û!n!P"ðjãœú‡Ço:‡ú›¦¼B¤K3=½ÃÝ„ I”§ð Å2ß3ƒ½ƒçãﱕ³Ú±JGLæúðj8 Ë,õ~â ƒK'à°®n’v‰¸Âð<ß"Uát=¸¥-"†‹ç?ip}x±*±9u64» ¥s55¸„?'Á’‡Þn=£ÖÅ5 ‡ÁìC'ìï© H‚¤U¾‹˜Ø›çûö s1¨Z—úµ(€\pä¶ôXx·¬zjWG-ËK¼z²ëa3 ˜q?ÁU£ÍGIr˜Þ>t˜ßÆî:¹›ðdÏ-ˆv«<íØr¹ìi^kô¹Ér•Œ2َϱ}9í³.‚™ÛˆÓŠñ¹-;8=í‹$5쀱W'Ç¥Áè)´•b1³†<˜öÍ,¿ Ï£áGtk³‹ÅZ¦¡@ÂJ6XЄ…iòÚã)2h-.Ó´»ùmtÓàÖÙÎ97”lOý¶Hè°è•MI¾þbUdbàDPÅ5æ–R‘Ó¸eúŠÚ;ý~÷tð”o(7ƒ‡Ð¯')öÜLÎ鈴I-o ­å6Õcýãh$y.¯f—±o{ÅdåÙ5ûå;Áåph³¥LâGô[ô@ššöŠ }{[%:…ä9£Mz,ÁS`bSßÜ)ØEËÞŽÕËíU›t-4Çõ‘¯ÎÄæ´pÂý‹Lë?|F+”Ì·ÖeæóT†ÌÁ2nðjžÊ;©~ý 0·kšÕ”‡PãçíÍdêˆs&¬þôÓæªÿübf-¼U~è+nFž5“$#{Pm`‡ã™œõgÙ/~ ƒÓ³îÓƒÎa¿Û0p¾š6»&¢`Éæ Yê·OøTÏ^qbôm[?š—ñRÖßõ#Ls)–ã JgRcÝo YއpU]¿òúnƒn¬”ŒK Ið%³0¼Ü7v&‡tš¹`çFÚ‚Ü+”%¼¬£SÒ SdJ蘴„cÕ[®YHt,&„,móÂ7òÒ?e$¤Å/G•F§;üO‹Õ´¿Æ7Þ P¹¬^ئƒÉŠ@ëZÐÙçú»¤Ž>’YÔṉ̃hÔ¬Y;$ãÃïnµ"kS^­b¥ü* û²Qsúâ/KvÆ‹hå~ÁÛŸvù¾y{Ø!-´&ÄEk,¤¾°»jLU]̉;µßÆ£dŠ>5„å?¹ª.ü†Ñ»˜ø}8ÃÐLå:ã/yE¾ÿì>Eùbz/(¾`Nc“äòJn|ÞïÎߢ»ÐN>50–H†= 8[©NƒšwJ5-XSEOvRvAËÎ1&ûS¼T¦fe¬Ÿd74Ïd”à».Ø)Æ¡X*ðWaí„bž¡éf˜P—0n-%WÊKä?*(îVà¤-8ßDXOðõ®½Ô¸WøØF÷ûŒŒjZ&,B®ÆFf=Ÿýí§°m`Ì£ŒáJΈ6ÌØ.n+¬ÏÙÿ}zµS)™Ð’­ïïx,¶l¢tÂHMí$-P¡–© Ž ˉLÃ.6^s+߸¬8)üàËc¯ÌBÃvA‰£p4ö+Ĥð@ˆIñTF¦Ð4.ôz>ÅÌstý5ï.EŒ Å£™ÉvÐ^áJ=Q9øæ”ã|ÝÀîO†xIùG(éQ£;ÒÜ_ƒ 7zÝlo'SÍ•….0ÐuȦU‹þJh)Sœ$ú•lîuhª$w.¬&ÿ‘6&kíÁ¤Ã÷†öÿBeôtò Ž?{Gñ“~ݼrÆ »<¬MP«0å;%Kéʽô¯•½É1‚»šØ¢’uj–Œ òÄ?qD?[Ø&g¥YÙ Éx§t¶:!æ…ÃØ9Tµ?g³¸­¶™qèØMþÒôbÌkú*žáNgfHó{ãsÝïÎq‰ª^¦Š‰k.±á(Ê5LÆÑ·0fãj–~$û™s P3Ѳ›Öh³hs^4 sù’Õ[I+hÎt\N²Ù ¹skIÝ_aKX»íÁÍ)c :¥Eb®â³¶J±2 ^½Xñ‰ Ü;¬âIüƈdœ0ðdjžøxæè;}ïÚvÊ… û·;ïÔ n¶Ž"l¸uxèÞw˜6'KÃÇeüTyŒ‚¹#ôž…÷(¨sì˜Ôi‚)Ž¥,Ó1Öv°fM&ß}']Ùcô` ý0#5í·8ç¡÷”Câçc â<™4 QÎFÕtê8/CÚ÷†×·½Ð~=§»åºûÎ뎦¾Ð}7§£ïæwdô^!äÂAÆdÌë}U£ßßã6Ì“\y¾Yš`PÌB©y…ëì­9Ü ··ésèUþE˜×NÎg;Œ€.þ•N.’Q¿¬güX0Å4[ˆò/øPSŠÂL7ÃU”‡1IíHÆgœÔ]ýâGséN‹Ä”æxêÇ ‡ì–Ï62Ä¥‰ŒæŽ£ÿÑê€:;KÙ·=;T̸r°mR§JŠŸ ÉÕcsõ?ÿ3ØxeeÃn‹?°q{7øî•#àGþ¤¿þç®rCq“ÈyJ¥(ô“3²Â–•M¼@­IPßöøPøÌçÅLÜ\­*é„ä—@Z(«!^J9|Kõ0ÍsÄLÊJ(0ý5Ê@Fˬ÷I +6Ô [z±2Ùz'5¿4«/@~A¼¡P2ã çZB¤E“µ:±3¢«Ø_ .Tqf$2{7 Í@!££eËÐ'[V HÉßä·«í%¼!ÛîÅ9 ¥¶0•æ *Y`Ǭ¢o75­ì¾öw…±J퉽’1žÙ±˜³Œ¹@¥$"‰bmV•Û©R;2E!ƒs™ÍõÃ#ýŒ “ê‚\½Ž-X^F…ÍVsÄk¿èZøí†ßoS¾@ãRåL¨–ÃI/@ªÓ`•€BXòˆ~ݹùG=]\]ÇòkLXÔÜk¯îؽS8°•®úײ5›ð5m&–ÀånV§)ø£ý öÜä6wV–(”†ù2ß°é«ðUÉëo›Rçx2nscµ/ì$;GAÑè~}ӅžTôb'·3úDp Ô@GÎ[єҌcŸhmÒé%«ªLí7¾åzRøÉµ"KäNO´:w/›úáMÐКÆbqÅÀq3ƒµ¶bµp[±Ó °'y^Êž·%…J…¿ ÷(Y¶“ ŒW UMø%[ ;všxòI\/þjŸH#2i , EDÇù0º‰GmÉ8C‰pÂùë`í§t ´-`ìh’Äy;8Œ#J‹6f¿-H‘F&–qo¯Ôi Ü_—k{^³ÕvÐÚvHûs´aR娧ÈMrô4ÆMâhø~7x† ݉7é@^[]Ó/ð÷ ²ÔÓ×Êß}GmóJolÄéH—•®™:eN.„â©ÇõzÀZp-qD·b™±¢Y-+¾ÐHeºænCš“j_W±,á Ê3µ¡o¾Æa…¦/q_j¾TyÔZÂ:~úiÍ7.&…g›MS®}^öKÍ­Ãu¤If<!¤ŒáÀʽLï¬[ÖoÄí˶xɆÝÿn©{RpŠŸâé°©~.ëZ|gX§'eã3ÅfRºÞYn,¼ž%£¨û¼S Ù•xqþ8Ccã"ËZÁy4i®˜k9|…GÏKj~Âß“K,†¡l å†c„–ºí`*®òO“âOÐ̪­EDn ¨ëK§Ž÷Ã÷«Î$%—i†Ã!p'¡BRÈfýL0±Ö^Çùßëô»Ýÿ^GÔoPž4·%Ÿ½šß˜i¶.Š Ÿ¿õ#*êO9¨ÇvkO­8AM§šÐr~«“åZZÕ•gÙ.—Ü]8ÒÐZñ}lòz7IP€Ç}õÊW€¶·Ëö ÓwËv×,X~#-)#%[¿o`óÄè= -åèx…BÛñhõM0oã)V+v®ÇÎÒ”œ7‹>±îë%ËËÚ!Þ’Ê"‚ ¼+ Ñ/–,§ü–uZ^—¨´ Í;õråO­o™Ýq¬XädÜ¢‚wõˆtóûÔ¡:'9W›Þv n[:ü¥¹ºã žäèªþ…Í nÛq«Væ’7MÞ‰üd²”!£ÈÙ~Ô휖§}r:Š£É t, •‹œ°µ¤£a±Þ³Ô‹ÎA°"P‰×%—'˜±­{×xv¿†>—ƒå72?£}ž7P9±s' ß_½vÛ˜ĽâåMon£GF:ÑÓ¯½…@Xêp:v…úŒ ñ5Œ½–âI4nÏ\Έu¹€Ìc¶Õ3<ê„æ»gN}Ô·è5>Tx&m‹Gò«¿Þ¦ôje¶ß#hÌ" '£6h®©f©Î³9užIo0¯^I ˜RT ½JûÑÙS8| §·!ÆY4=ì Æï@üØ^1u^¡‚²¸žF·dX+í\jš;Á”†Pý›öûUÈYr«9¥Ÿ™°:uê/wdWZ@à—qÌ~©Ù˜¸mxyFæâ×Û÷MœwÛv4¾ÎМ.ª5gÓ$z³ùJ'U"ê¾IZ@ÃÛÍð[»CJì:†Œß‹À£l[¼v~|ÂGɦÂ`iÂÆÁþÄ>cN‚NCÊ&Ü12‚?DG-ÍO×ëv»Á… iƒ“^¢ª3Â÷˜‚d"ˆ¥"$0cª´ÛCèöÕû<´Ût<´Û·í[íîƒGûö¡£} £Ý…Ñ®|;K1š¢ºØ½ŽVzÅšs~Òï>B¿â-T]x’–»²§i5J™9¶þáG¬8XÓ|s‰b“åÌ{0?§Íg.ó5 ñ•LñÆXŽ9¢<î¥9ÆN“Oñÿ ^ñîÁ*GÝùlräßLò­‡îûüÙƒknݳ#ǵZ`ä©þlIp] –M?ÉúŒ7Y¢ñ|ƒ¶†%’O>+UµšÐré+·$u%ê=Pƒ[•ïV‹ åï!Xq —ù ®ù:Îy÷,ÇAó¤Êã3Ô\z1cU³}ݦçë–ZžyêMV5¡~öBWºöõòþìÜ€áu®—eÓ¾¦²Dƒ¼IzÍ‘{p3S„5ÿ<7‰ÈÕñ/ãØxœØ<¦ÐÀUtGðtí@p|=tÕÈ/Ì8ßúøè!7 ¢œ á«Çùܵ¡Ó.-“ ‰ú÷¿›2&ÿ­UoŠk±l*ºZéO-)nÀpè˜C¸qói7_ÿÂäßóÅä#tâ{¹E!Ž.úްíÍ3H£À`«|Û±-îΛ[ì‰NÑÊ‘â÷§Nl8b»ÑÚš ŽiOw?8±×»C6ì¤lRÚH„ì9ÛzÏ—âÖÆàÓ,6åþñ‹F’Α=ÊÂ=âøup”sˆ…ÿÅ9ôчúà5­G@þuVûvîÜþ{­÷cö¡+¾À¹ú=¾*ßÓÂ9]È{ù»Ónÿìpð³è“¢»}±îHyi ¤ŠåfKošsY%5mɪã –«I!yÅ·ÁœäWìmõ®]Ùmìu5i'e\Ë&Sy)t`âì'ì’ˆnÌF°,ÔÝ0©æöâv³ìcÌn$Ðø:J7Ð÷Ñ•$‹—çtŽ¥d*éY]ÁF ±£Ççm¼,ò8rÂø%71¼Ž‘¤G+…Q£zD„MÄ00±Ðl}ß„ï»ý~çm7<8=~r Äàïu‹Q¨Ó{{t|ŠéÑ‚Ø/e]|3»èÃ=úz±ù‡ï%'¢ÍæÙYËyÖ3k:]šŠf ´W™¶¶$&r—F{Â%ú™µ¿`wL‡‚›t^ÛÛÞ4v<'÷AvÝl±úžy6› i)på¢ü#3ÓØîÑÞÕ¤¥X…<°ÑBPpoƒQNbœ?6•Ý£-;©Üh6›bž+F#¿G;º"Ü T§é=à¤O:0óÖÊEfqñÕž$¸5@.áÄß^%pGa ØðV³\|"0äéD ïn4WL„Qž— ß¾o.EÊÕ$þÊ)y¾€˜躾¾9eþuÔ¼X@Ís æ¹OÍÞUv“™Dh§“ŒÖ_ä;J¿áßEŒw 7 "§}ek`ÎBJš€:Ý`8å îl’\&xCqÚÒôd¡¼J.¦š%%f K¹Ù•$%FÆŒ4f·oƃ¿Z—홺Ñ`Rh Ï[jþ}4æLTJDò‘‹ïî¾R«@Ús¢J%³ '«^ÚŠ\9*˜œÜNˆ¨ S¹ŽEï2øÌ"£Ñd`bOnº£»Ï%ISÅ# cЂ¼ÆRdPÊ®b·Ï„ÓwEø”Œ*FB@ I;n£H‹ ”i± £gßmb¯gßmmÀMô—…VLeFÁØ­F/õ»Úüüƒü×,d³1<.Ùe*,õö…ÅÑnaŽÄ*jÕ#·«ï4ˆ”|„èÞ /ÿªé›äRW@owcÐUq›pwîR”ˆ~õº v °*táé„Á3ñ2 =».½;õ 5PkÎ4~AÏ\‚ž• Úª&hóóï7ƒ¿{»÷‰í¥…B›§Ïg F¸ùy\0PlPZ\z„ÏÝ>/ðÙcð×›²î²SÆM:>+ôýœI{a:Qž±ç=Àá%8Xz ¨Í–Ôtâzú]d˜\B'n3GÝ&ø8Ê•€^K±"ÉY '„›¯$~GAå&x3SÐé-F18¢¹vÎ' è̬֚³¨!µV°ww tµ‚þÝõyÌq¿‰aÓxpq—¬Ýïã!wM B£½ÕÓžLgS­tÀ)z‰Žmjáuf9èÙl<âsz4¨™¨Ž¤—ã¸æ<ã”Y :aXù4ÊÓÝ×þN ;£‡ˆƒH¹„&AdÜ –™-ö Åò/%èÕªäzÜ`à¡' œö679ýñçýßon¢ý¡! ÈÅŸáÏRFõ*…„;˜ÑÒ„–4­e¦¥0è{%B2¨ƒåip×Qþµ[òMÛÚ ÖÌf£j:›&§[£a&jj#w¦’~À£}óóf÷0ÉÝJ^7Âi¬rq’ù‘yòF²X–¡™¥y8ŸMÑ:{3É>á^‹hw$½¤7EÍ`”ãP!çªTUP³B]¦±ZõDYâVDßÓõRnrœ[q£µ·ù*,û3¹¨fìLÇ<É`µ®nä5r˜¤³ÏTüÄhȘhš[SxÏÆã –*„,쌫í×Lg×!çþFZaAï Fæ[Îìú<&YƒéÂ…Qð;J¡›c¶á`ƒK Ìðº8N´¾ì¨ ²5…\@ôöÜÙ·¿ÉS@–ž?DM'g UÔÙ¼KÒ5ÖæiékíÙI. Ì;ÆÓfH‰6X%Ôó–BšZ–Ë×|â0j߉r„½„Q»f*ìÚ¤{åÉ08Be~œŒ£4öï¥Ôå…çzJäMWKeÇýÑp°èÆ–$´_–“ŸßóqœR—fmü<ÿc0évfs{˜ö=8A‘”3ž…Ð*;ÓB÷Ò¸—3i– Ú‘õ»â à†[Œ Hy€Í2Iò¼ÔÙ"í>èP)dæ4„•ÓÂûH‡•äV‰`&ÎÇ#–„¦xe-7[´ÀVH*ì:I陋ö’ÉÎI$Vctÿ*]Íù^Ž´x¯KÖìm– œþùÈ~gœ‚K8÷æúÛXõÒÞ´Mµp¿ÙYÁpΘó©zó’»F+ŽðΞj]Êöè—Í#dƒNÉf vx}£É­À&è=íþÿìýycGv/ ÿÏOÑ‚gD€!ɳ$MÚ I¸Ã-iÙ±s‡½‰5©­UM~¯Ú„Ç,QA¡èUOYiy² ›€™Íˆºô#7r´–uœ­‘”oÓ1é ‡f5b³Œ8’½G£t>f&ôøpxxñãy—Ú‹’ñŠ7éüA™FF”€~'é(œDn‚'áèlü€ÀMØÛ"½Çü°‹ˆ9ÿ𗪶©­|«îÛþlóø Š/ÁË•z“ÚK+§¡pW¿Š&ºâqïôò„Cö? ;§Gý³Þ‘Ï2òe+i3ãUï$ãy›°l$jH«Ä™¥Çµ'›ñ1Ëä.IïAñeÖzÊUÌ‘ P:¨a\pV.Îl4kœòã ßh(§§¾cýì™$UE#¶þuný$iV°…§O¹¥}›ÝÈYšõ{ÚïÆL<‹&ˆòÌ^Ú¼e*pÖZ¸7æ &œ'O.Ñ×&y('Uæšp?6§D}°Ü±ïší9wü \UʇféwlÜK%æà#Ç©Èu‡ø¿Ö—’4R]Øj޹¹ƒ}U¥áTñæ¿Õáßfœé$xf·«ÛôVó ]ÚÚV²BCÞTBQ¨fh¸Ÿß¿øz\!¤S^²xnŸ_×mE•]£$%–ÓxO&õmЩ÷õ¯ ÀèA"{9NVŽú‡•cfkûãÌŽƒø÷rfdT£?f¤:ßðÊ®å+S²¾4çáìLÈ$}Ù孞Җ帕FÊUŒ¼½bÊV‡„¹ÆÑ‹7@oÐ…RSôD° æÁÀ ‚Äûþý‹šy9SfP0+SqsÚ­å'eŠt×>hƒJ$Sd÷€§T½*iMÔå,/(9c ø³Añw2 èsZUA‡¬¹¡l_¹^Hk‚Š[¯Ã[—Æü éµ(!ŒË ïñ”c@s—²™äÜgû´Ì{ŒÞ‹ ™2Ø ¢Ìôc™NÓ5`Ú/ÇΗù1Dßl†Ol¥á„æ»`ž@fGñÄgg­7iz3‰v/¢l±ë²9Úz©ÍKÓš€­•Ðý›¦”Ïn6KQÈ-=ÅAB5 nœŸ8ƒr#·Y«ÔkZtáÓòÅÇ~§mË•Îç{à5¶“Ë‹çöð-zŸ€R®Åõ8±”n6‚Ô"¾!Xm÷{kËýÝn»¿Ù½»mX¢pq;Ä‘a´aý…UåD“p–Au<à»™'œ£mÑøMÿM·m jOÂxp\U9­áˆ $ŸB¯@ü˜µ‚/hlYhãAsÖ"]@ÚÈ—Šã­£™MT±x·¡Q)\P] Ã«THálžÞÌ1s7žö¹iM’5è9™#àÿLFâ–,(ߘ±ýúk€™îФ¥vún„;0&OÁ]Àš¼ÃVhú´$½b5ç©y6Ì §E˯*8°a.·éº©Eƒ6ÊÖ[,_5þq£5+ß#—jÇQ~Ñ'QÈéËò‡/km! ¨=÷w]2D—lÏJ»7·)äÃâ!g2 ÙtKº4µrǬühæû¯•KÍU¨R:R^xo˜p0B÷“•.P•rÉkíɰ¯†-øï”Á:5Gãf†’GéÇû.úOÆ\ž|,ÍÙ4]—,a?]=r%OÎÇéd‘ÊdS¤~ÿˆ{#UjÜïÁÌmȯwæuo¹šþk!ÖAwÌO–‹èãq:ºÃ]ý©ª›¿‡Sø}¨e!• Hâ Ý¶iAíÝ‚}bzKÀ©€}ÜßRùE¢f_× WŠ“z6‹—’ž—-©›“Ö_¢‡^æuðÐ2ã0÷ݾ³«F»_1YÖ¯ùË û°W² Õï ¢¢šä†ŽÇSIr|à„3ó8Â…9…WKx£u¹o ©l Ûzðqz?œ ÛM.À^PÂØÞõ¹Xß¶Ó±=aÔ*¬Img ‘×`—jn•Ñßœ‰ÿ,ýe€q:f‘TÂòŸ±”‚¿Ìئ³&ÿìÉ¡¹™©çgúÙS9.?³GN te³B&Ð ÙýÍ.‹ûô0‹†l@ÿÆ#ËpzŒ Þê;ˆÞ<¨ÎòÙ™ÏÇNö=þT/N¡þ4„Ÿ°¡Ÿ}ÈŠFëXŰð?†/ƪt§x©*‡cØ Y3·VF‚ïÒÊW꤉vÔ\}RSs´–·Æy«°ò&jTÀ•<¶Çu í6ïÁ?|EdCÒó¾íþeHdm¼Lææ1¾IÌŽõ"‹C¤‘ªŸ„üŠ&zx“i*4G |'Á«2KÑŒ3Å“hî´º¦ÐÄôF®s­ [ñ`±øGŠŸw†•86W½¾:ÕÞÓàÞÌü¼‹ðit¢,W,»va5•EÜK‹YÓA]¬KAj[§(°}pB¥š“õ¥ ³ç^ý]±Ï¯¥t þÏÛ¸YØx•ѧœO“­QH˜†Zã2éÔã{·Ò¾À±¿‘v z„NccÊlbYº_Âq9¹ïÄãøƒ›¹_Y YòÎÑÑbv/û]6ÉËECNZžŽÛà‹âõºUa)¯+ä{{~só¯ª Î¦öI»z ^ézŸvNºC•P¯hÜUÇl9ùB²/²Û?Ìdƒ’Ô2µ€!c™¢Ek¯HôVì@§S¶Vh¡”Kÿ­b£„^¤ÊËPÂo2‚uÏŸ~æÊdâôê¯æêT ÂH¾%,·ú­ ^B2¸•Ó-Êk¬ÌžOr*¦¨ls_ãu­c(s©-jf Ô·DãÓh]só «gUÇÝ»|+ÖMU×áÐeVüÙÉÁ^Sž_¹V@ë<-o‹{Êø7YaL…•~f8&ç`ä–œ;?„¥í]׋g¦Y>/xÝ^l¸h ÎÝdáNÓäú7­]bxÄò݆@Ûì]²ñ²u”!þÆ¥ÌÏÔ[M‹¸Cñ ˜»4­²žà7‹WÌÀ<Ë©Ða/"‚s^/u]Éz®§¥ÒíoÁÔ3/Ñßæ]ð§/¡?ÄØ”ªFÝxÜá±Ô©dD¥ÊÑM¥È^nHNUŸ‹Ö‚O–îŠl9•z!P ÅZ`iÞ±k@)"…;iS¬þžŒ ðû*χõ$ºç×ûõqçÍpÐù¾Û:•<&ÅÎ((¯è/ÀÂäàLÞ„;´p rXšâµ. &¸Ž£É¸é"ø ¿-|ˆ)" @…eZ£yÙàð2¼Q§øã¯yçuÈt—VD€ ŸƒO(ÕƒÖn›–.gªå |ýÆàòۇƎLSªýPed²ÊQà}H—‰¡. l½¾ x>@77«2øÜêTëÕ›¦õR e±¾Lâ5gÈB/¡\ÜõÆîA®ulJÌËÿ³ÊyˆE 6õqþI÷Á󨜛”Ö"‹ï–Q¾‡“èG)Ë”»—\’¯Ñq:Bo¼ºÿ̘#ÀD¹† ŒÙŒ³,Y³5æÂ‘ãžÇ`¦¦h0Üo¼|!§8Ç'ŠÁ.R¶¡æÍ­U‡¥h¬ð¬ÏÞüÀ߬ɩWÍ"^§`RZRħ™k7‰(ÿ0Ã’¢N&¡ãÝXÂ#w_69Ìò]DŽ · žãèчQ­›1ö“6xùdxµ†eÓð0y1ÑM¼ÃÖYcÉ.NÝæy•6u šLÈ »Ê‚¤½_ 1¦@ônÈÃìüP)Imì{=Z¶CL1Р×䨥ØX,ÏÃòÚ`gÚ"A?DúMΧ³ç’cÂOâGN¯‚|æÌ‘5‡Zà<¶–Bh`ûšÆzCeaÙ äʦhÁñPÊm!s>u9í"j,©KbìÁ>¶³{Àk0´¿¸Là=ÿ¼n²~^ÇP_:ÆÊÔ Ù}7”ÝûU(õÆO/~vSP6s±zcnŠ·xƒgK®õÝù€)3,÷‹Qõ€¿¤%Ì_Xµ$zªç¦7õ’•‡_ôÆfx“ö›ÝxήO9ߎš1„ùŽŸìv@äGDqÏŸò8s˜peß*…4ÞjÏt¿û%;œ;î°Â´.u¶bI×lPݤWœ˜ë´°À+û´ò²?ö_õšuGÀËÄÚX ž#bO]ÞpOp¡|)>Úilð9²Ê.T?bwdHnÓ{ ©fðÌœ¹‚Nþæ™Iµƒ(ûaøŤ‹È5‚fg¢T[-à(L*&i˜ ‚?3݈£Ë½£ unÎa_„ ÞŸ™lñã éì*.ÂÞ·…«ÝÎü½Õí¿^ßCî"µó]îÉ6xÊO?Áw­³æ©ÄTè…ÇRÒ!MJ{xù›†·¦ñG9úpÎøÈUtgŦâÉ$º '”ÚEÝhžfXbNù^ó³l[DZ-½Þ¨5g¾x}Í®–‹µí¬iÅLæÇt ÂðUx5y(6‡0Â(v‹>Dö¶˜O< Had!`Ðu™\Ÿ’Ý€7±ÜU.ñ}ês*Q–ó2ÁÙ8—Ã^׎eÍ2E5ã „@lXC.þ‡Ž©ÙŒ·f|"ÐGÌ/½î°U±³ÓrÜ1ÉÝÒ­¼) Ñ…swÜÏ"u8]oŽ7}Ù\áh)  ü6Í Rr¢™ Ê‘B‰¾l®u·ãp Ëžd¼J—Ĭ¨òcÁ  ¾ Õ!—°¬ô&$%'1G<6sŒfÌ ÉñX–¶*ky¶¢ ¥Äˆ’KÐ}«ì*IPs’Òâvn„ÏZàéÅ—ËãÑhPÖ±BtX&vVû‡Ðã?;B„30ÿ+Єß>{ÆŽ·1B(Ž@Å…ÂÛ5ë·øJ’z :ŒT#YËz‹eåPš†ÃÅü {$ßÌá×ÿòòëF«Ä\»Ãö®AtÛ•Õ§cÂÿ¶‹„€ ŸyÅ1ç,ÛûŠ¥‚PʇšÙ,%Éâ XäApòÆË?à &œho´Å’/è®ó†Ãúas24‚_ö0@¨¬^¢ó¨Àúµgn] (Øýá°{~Ñ;;üö3Zm–?üø±°Íz‹Ì!Ícüù‘;ý¨¶Wu%ië„ÙÕçÀ\ü9Ð59ï¢þ¤0êS·ÊÚ¦ÀkÝšäuÉGœ”’“Qå$AÁØžȆzlå ¢«¼WM÷¤9€’¬K³l„ŽÊßVõÂGK´ãW2_&hgDŠR_5©oUÁ/U×#wêßEòd…t«–q°wÈ]«0 z¯N¶³àãäJÈ¿Åì QPApeÝÏCpÚ²qd^!ˆÚ£"CBÉ&Šä`[zþ „9 <Ò”!gy§î¡Dœ94À=§2 ¿ØUþ¸ Ödt4ûmÆ)à‚ ~æi–^/”‹M_ U0Ê“Þ=LÅvÉš’ub™‘P: ¸¯Ö‚ rçÀkä@'°CŒWò–£ÕP®pl¾i6A!Mõ`Kò¢à¨õã“õ a‚%ï]dùè°^ìðƒØ”«_´Û;´A ð-©¢AE6 à7ÒsäªSó»®M""Ã!Í­á9½ÚÚÜ5t)CFèœðÊLGuxž ìdúœvöÃÜäòª\!Iœ‡ò6 gá8iéó ÍEHk%Ì„uxN½½2ÚýÜÅ–ò¾È-HÓíÞ^.€á‘Vƒ;miä‹¶S˜fM¢ETœ®çÜ£M|èë/mDb´ë`iÈ\u°mÙI¬ä/>­¡[#ðÁŽ2ÎJ8À82æßÏÍ~š&v³ÅÃ$ò FÓÒJ6$edF.R³){<‰ø»Ò¾¤]Â…@—ò {#â³K¨&L‹$d­±ç—‘ͽz0tta Îš\Çýºb »D(Ú+¤ÅÔPÿòtØ9>FmÑÀ©idÀB/¢ÑmÐc–fd F½¤¸D]Ù$¼á I× tøÅÈ%ÄÞùസt<4lïâ«æ@\U`¥ÇBŠ —íŒ ‚m… "ä+M2š3„‹ö´1 8ð‰NiPoµZ Wý‰V¬\C J 'ŒÞŸg˜9.ì 0Ú¦)‘¢4éÌGã÷Œ`0X5M«@/ºå|–f.2Ö÷*%MŠžƒãy:CwË*8ÇÑÕòæÆl…ÆÔ[FÜ(ƒLÓLÁ”4Í~Œ"¹‘&‹9äöMà \á+‰iæ-…8U´½¶¨¬˜·€ÍŸþè/[¤3oJ!->aj{š Ñ6¹Ý]HH´ˆB´·–4`·AÖˆ0Z ñ@G1$Áu]&cV¤Ææµd¾2ï`fÄdoè ºÕ¦Ë…óÉCÓ°FF†¸ŽG^QrØ="êÎoço»cˆxHLË ³n#%”¯Ú·{?õä[)>â™¶¼K[³«%$”F_x‰í=Í™ªE§…ü;-XÉ·À ÅeB(’—!¢¡xEQ/ÚŠ‡S »œî3F˜"æ~&L‚µ¦àVè0¨gÐ7‡&/4c ç¯K´NË!¶†¢e+ƒœ‘ÜÓ *]…źlÌãT‹üQëþ6\xŒV~‰ÿÓŒ˜Ü £Ý„ãnë Þ„u²lNó°F¾Xë"aY»…¸¢,gct°ÙåÒóZ&ucYê,аÁ{_Èi€ Ói6¤Ìè 2¼‰ “ ²ËYšGásýÞ«Úž×ñ&ÌõfðT¹¥5ƒ»§Õœ'ñ]DOÔ|©üÓ°˜Å_¶{òèa·Ì–Z)ßA×z7Îä;={¼yÂÿ}•ŽÍ+U³Ó¹2ÿ®9CÍŒÜGµCM"CS—3`„¦à¾dþWøE°ŸD”8—‹¹Å‰at3lœg^3ˆ> ½Á.Ÿ\e,àD³Å(îäVü9[¥ËEÃ6ËåfP[í~\ð ƒ*ä2'î_Ê`yË^sí´1g°‡ÝƒBƒë*—é géß8d^ø²¦‹þ»àÎ"˜:¤7^ôˆaW^mO? ÌžÎõ6žy^È×!h.0Ì]Ü¥º%ðW™3d8ô­~¥Ú€ÒzkJ“<]ˆè…Uü蚸oP‰È£j*"*¶Ä¯·X‹ÿoÁ!!”)ê¡ý¹k›Â_2ÚaCêœò0÷§E±*]58q —ÑU É :7:l zLÞhüÅYœ„K®Öm†ªç¯J;èù$];9P,Z —³ábdwQ,çlï´úô,Ëòaî(,Ìó?„0ÛØÊ–%a ®1¾#êhå£ÔÖÈÞ•…ŽV©ØÐ<š;e8T¹övÅì;N,-½•›œ5eHy2°œ„wQ'÷ùÂZ¢°•®ÊNý{ù×ü{¨+<Þ+WòÆ­|Ê!Gå×f?ÝùáÚÌzeôÉb/rJ§\ç+ž"‰õÜ¢Ñ"éE Öñþ2çn‡ ~Oè/¾R굑h­nË;‘-ˆ¿_‡5'Û¯Á6²št˜+êJÕOê^®Ð&¹o¿pÒpÃXŒãYœáÑ¢ûø 3¤Êð²Sã€?ŒER&Ü›DÃâË ´n]Å™Vð匹ä‚€ýV¹ÙöašBè£>lû4 óO&Ë…híÓå‚bnmY;.Ó!Àô2mž= Èú–RùWCafË«IG,MPCÐ?ê zpÌêºdì¨G@Åì_€T)„y@˜ö$Š(s£>˜ãÔÎÁÂrÀJÊÏâÆ…Â»7«N)¨¥Š¼jfˆá·§!8ËÓõ¹äVë.:§½ÎEwHà;AwxNDô°œ„snÏf0ÃZËŽIBa/ZÐü6^ÎåŠMŒý¦X5«ßhP¡Sóçz:ð3ÅqU>¼¬¨ôV¥ðlèVa(jËb1.e¤½–æþ2ÑX®ib],p£µ:l2–Õëó%úP59êU»ÑJÌ39U‘œš¡õŪ¹I Í©º• î)¸9ì%sa,º@è"Xzۘؼd»é¡fçàÛuÄ:‘›Z)D$„û@>^dâ—6 ¿3†|RZÔ]ÓÕ@©Ä¹ÛB®‰ }¶òIC‚7N£ z hHdØyÊï&ò;˜MÑkp,þ UÖr¨Þ²°“»x—µQãˆï}ÉNÿ­ °¿b]  ¢Éõ°YºÛÎÅŽ7›5u- µ§¾â~X˜ôGÝgï:[‚ˆ?Ù-™dò×¹›Œõe.I"`@ÊÒQ’-ÝÚÜM„4 â4"ᬫ¨Á¢¡XÂ*à•†JfÝITü°@“âít5€ÒZœIlAb ûlc$ŒBmÙ`TTú·ŒˆjVŒHtÍ<&<µ›—ÛXMú–)}…†œòú7 »o›;âÖ1…µËú%F¸É¸xESÊM Wøq+ùEP°t|…åb])Åjæ(?Bìp‘"ßôøÑ‘볡ÞÐ`cô¤¬Ð?­^œr!7Ž<€„âf.É* ªí¾)a…ÍA[«Ú¥v,ühcÂc .IQ^þeT蟧>w»,Õ}ƒ(©GeQU «”¿¥µÖj„ÅÚùw5bÚ‘‚Öu¢F3¬{c[ol¬N;aY8š2ý–Ú ¿Ù²Ž¸Â‚Æ’2c8¿Ë äÖbßXÀL G·EâàØjê‘ÝÖ$fðS[ÙX‘£¡HAÖ%hc$ì‹ÎË@š~·*Œß€ÊôB6ë iÖ£Fà€ ÒyÍe9ƱaE`18#³r¾€JÌá[¢í ·‚?a‘Ÿÿ©Öªb•N–ø<åëb™t‚fO=¤žwÀ±ùÛ’«¥HÝ@¥LcYü¤ÙkƒK¹vͪ+®om1Þr¨RUO äÐÝ+2éâ:ä8SW?7‹ •)Gå‚ý=•#y&îk5þ‡<×ìx¯šø7:Â\ÓŠ¥œx´ fÊ«¦ æû³g¢(»å Or/bÓn è~®Bè .{ž-Pþƒ…Å/;DZ–^}¼=éWa ‹8­å2É'wi±•:Êð£ãám:Ò>{ÃÖ¡®|ªVÕ¦ñéûyo·Ëëë‰ÒÈl2@®DjfåDŽY2vÊ–A#ç¢uúf¶È#pŠaPЛ¤š‰1¥(*…#•Q“…Q]&™WÃá!çËȬw-¼ô¾_Wbçòí¥TÄk† ý‰ù˼MGdeU Ä‹˜2ÿµ “E¼xd= WgÊ Õ£«Ø'w6YÎAûŸØ× ¢Ö:ìh/žš?ê/Ía‡ ¦±šý3®5ì³_{Èï­ªFþdj^¥é]ÿ7ÓõÿЧU^k@–pe6Ýô²qËÒ aØŸ×-$6Pá/K‰‘J<²œÖÌÿ÷Œû¥¯`-{iøoh†‘ÑýänŸ½äˆ(’œ+Ï6Òì8´>Ž}ÙZ»¢M²“ך’ÉeýˆØ¦¾fX²<74ðrxÌølù¦2æ×ô?ÔpmúÎ0(…’%†áÝ.§a²K¨ŸIìˉ´”Û¹•ˆÀvwš&ZYŽZù;ÿ PÕ!?8Èüɿ֚(‰úóe¶Ä NѰ ²CO†Þö«hqq` fv‡(Áqt/fGÏ„UH‘ìäVÖÁžÛÒEñ•ÓµÞÇ侤W*Ä÷ HëÚö#Ðjü¹Æ¸fåus‹Û^QÔ/÷U|=Ž®ƒáÉàpø}·Ÿë]*Ú¥ÃŹ_¹‘÷IM‚{8Òíùùyzˆd¦3ëQ³d½Ò–ųXLÛú{"†èkV—èªX—#n%¾/ùÑý…q´a_h¼a†¤&ty,ª´UŸÝBs°+…v ¥¦²lKõ–Ù Bn¢dg•|°$怖ø®ÚûH˜ `§¦Ú)äÀ¹çzbJp{2tF‚¦z>Ú»¸/ {÷} d*,–ã8%¤7]œïu aÎp^m„®Y¾ñ¸4ud>Cî¢eQC¦1ÄùBÀim`~Éë—æYØMâÑñGÐÆ_—Ó·%RÃugFb@>ŠÑ’=ßeÈ‹Xã·x ûÅÙ`ø®wztön€&ÓüÇáÉÙ«Þq×FžS¢ã†§9ÁJцí@àT¼ÃùeÁIze®>¸i—JïmúS3X|¡5ÓØ]$Uä.„raÿ¼Ž&Îv²àb´XÜÇ#4¾¶Û…¦;õ’cSZílP¤gÏ;7„fñ :\<ÌÑ|k _ß7įLÌ‚»pxv|Öu_w./šöC¿{äþñ¦ßힺþØ=>>{‡~EÝ0øí=Þ±b‰ó·g§ÝòÊý‹‚ÞÖp —ŒGIÉÌ0‚9¶¶RÍPœ²M6SWË€ýW}â§Ð.K[½K¯ÏúÝ7ý³ËÓ#øe/_×­]V)”§…m—·üZÑ€<™Në„ ¼°O$½Àù5ìœz4{º£eë—;!œK!~ýÍÿ"L¾¶#˜Õî$YŒ«‹ø2¿m±-ð²V¹Ä¶Ì×µÊeµeþP«\9)Ê\½r ¹ ÉSi4¡†1aÓ x2ã*XgÉ>€Ž„dè»^Þ”©ã7"Um»\MEXÜ1`á÷=@\r—€žUD_Úmz‰aóxaÎÂ!}ïx’ÕU£F —‹´–ƒGp !^(gŽþ²øçt3ÿøa±»Lb ‹ŸYísº5ù£¦7z¸1|[­±WyüɃ¸pðöVÑ´¸ëgP…L=jgñ-¹ü­M”Ö_Qá¥3X„wMDFƒM’‡¬)ŠÑýQ˜£‹Å0…c…)FÌz¬=t‘èçL;‘ð€FkLµi´–¤5›æä*B Í?„0Ý3{o©1Ã[¸X¢„ˆ­3ÌCÛBlxâê' #ãHp†è΂hjF‘Í¢QldËdåâHà@!NCn ×Åy ѦC™˜¤iw3%CÖ¬†‚ê HˆVD>TøF^Ev‚¨‚aŽyPÄ5ÜLðnkž©Î9ÉgyFÄ÷¸žš—ÇÂa})Ÿh8¿É(]Ï&uøÐ„ X˜Ý_u? ~5çd… ß,¬¬ÀÓàùR ÏÎs^‚’6z ‰ŠÓ¤¼Û¥ÊŒ¥4Qk¿¹nb>¤ ôÈZÓäFm€ÏÐgNÍù­ùÉúžºý*‚ â«&pÕÖÚ¸”ª¤º›ë#úǪGÍQ/³¸pýÆÝ’f~ÆٳXÖÆcN¢º› '—#NDNP«Öç“°±¯c}_ê†ë"P°Z^ÚJúÕn—ÞT¥±Ü`‘¬ÇªR,“‹Ê€/]{Ÿôñ·X<¦qÀu7‰ßA þ¿÷ ÚPÝ/Ï‚—ÚûÒÏ9!§T5úæk·i™\Ô°–{ „8ðÉô4 Û7VÞ"¬‘N#hGÙ•¯ŒqCÄ¥²,×2QwæÙ4‹jhtN^Ó…öûJ mµ(cãk Íi›—ØÍžÍδ§“î°É?ºwÃG=&Á~`–r\¿Ã<‰àŠÿ΀çÀÔ æ=ðïnRÖ';^Zû^²øÃ×A¥†â^Žß^ÏSsG>œÍâ¨^hŠ]Ì?sÖ6ñ;™OL³æàÀ0ï&¬AIÍ‚K 2øŒ½,«äVÊWîçתá/°:†ìçøÛ6™¼5ãÿFg#8yÛäsÉ™% kHDÓUó·¸EþC¨SW/Ù|Í8~Ú·ÿýÌœ£\éþ2Aõ'œDt(lAÞAΤ$ò­ —¥Ì•-×:¨U´Têxñik#òXÁy”’È<ñ_»¦»ö¿ü𾙤Wá„ãŒÝÀ*¶»œµÞ³²ÿ3'µ) Sî&Cˆ™U®t,Ûâ2?Ç•Kµj¥Ü©«5ydö¹©´ÈOª!I°Ôø”ˆN¢eÒ›,·.íX.B \ÖJû³Nû¿a×ñ“CHxA[)‹ë 1JžÎåoT0fz…óëV2=èÌûРפP¡íu.¥ð<¿-VñöÊÏÙMBúájz«ÌnîàP\÷{\îþ/üßO¿yÑ€XAÊ‹9s¢å½¸ßwûƒîÿô‚аàìPXWD„5? µßÝým‹¼Uq Š¼WÓ¾6êJå<ÒFU=Ʀißû55Ti`+Ö”vK3ÇÁl8'¥(›VÅq*çü>»Å’<ª æÅÊÖkefÅÊvee=ǰèan}™ç¯+hYþ×òªßÕGòý[Ö_–øÐ•ßðÏ"˜å7¹tRš}ôXǼÖwý*}9]ïg®Ðo¤€­Lr“5cÕGQ©‘SiHö°ì#’9+_0Á«1~˜NÖø±w§³ÅՆ͈TÕœ‡MÀì¨)¾ \’—-zf1ÌË|k Œ“ÃöªÔ BÜNEAçÊ1ò „…B–a‹Cz¼yUDÆ)|ërQØèe§Ü>«wv utÓùÖ73X0^}ü70ñßõ÷‘vÔ? `r8 OpM&»€8`¦C§#@/Žé{€×0»u(³,Nõà4*8ä¿~¡‡%˜´<»Q6 ä‚(ya=8þ£›Y‚ˆnAcB¶hºX¯˜â¢ f‹fbW¶’ ¦pêDÍ@ÔAFý ZHÈIg¸áŒ(¶¨EF’tçe1rKP¯.NÕ¬jYÂjó¿M†UStÉct A¤p£äŠ9ñâ¥< g(˜¦Ha\2ª>þÊõ–gÃÔš>3˜RÊcú³ÚóÔ¼nªt1L- ELò·aÝJé(ÁÒ±øçÑ­0.'*HõÙ{ôˆ†ÿÑ£†Ø:¤­)¹8ë¡~Í%ý ãaѶ»¡€¥†CíÝÏ8Áɦv(Ø”Ž«k.…9­\p¡=yËŽóK©‘nlƒµd·xd›e-máókâ®Ùs;à%a}xÔ¹èáÚ7$HxÍùÉïÿµÄË k— Ã^åò…‹p@ Öa%kèÅŒMùªá“A—dû®ˆõ.¨ÄÖæè¨Nê¬Ò˜zQk&ª0ØË‚Yxšèò™Ó\¥¢-i¶œN!dß Ñòh"Šã»ÓeacdÀ«ü¶W©OiÀ)èq2‹há–×ÃÍ!Sä ²ŒÕgÎ8%kÄÆÆÑ$žÆ æ,É‚«’~2h7õÜEû5¼rµ`ÆÁð· eª‰&YHÞûФ, £ÉrL#LJ˜É*ÄÀå¿i!óx\ìžê ØÀ§Âðy©Âg«z“YÌã5èdšøeJw_08…°Ç6—¹ *†v3Uo›Ì_/Ñ d ©*ßÚªú¥Ý~4+ÎRôdêúw++éâ >îÀz¿ã¾;ˆB‚Þœ\‚±Op^® ÇÐdâ…œ ØTäoÑÇxQïþл²݃ãö<ÁsIÖ’±8éU¯àßÛߨÂÙèu︻|œN-rß‚ÅÊ9˜6Ôòz[Ñ(+5ŽçºP‹˜AUO.WM…¾£xŽzwsmúÑh9Ï ÿ1Q[iG(H-g³()=f›ïwt&uýÀ±܇I£Íy·E?Ì\Þ•‘³÷úHãÈ ˆí æ6lç å£+8Ëù &¶Ž$Áñ¢åÊ~Ý zÇWH¼>¤“$)NÄ d¤iÅBÎ-nc7 ¯0ȵY¥0›Ë<Š8/Ê?F¤6ì@‘…šA „—“pœ j<0cOÉçÊÐ{ZŠ2 DcAR¯Çq>4½‘Ü p 㕞ò.²Ø_ %†@Pf’?˜UÇéå¦ÄÃm•]oïRÔ.Zž&ŸÐu ¶µ‚SJÙ)ú :à¥,æW›þdž£èÇú©°n¾ÙT&E‡“Š×šŒùE¼œõvãr.Ó£Ijxª^HôX1Ù1±ögÉJ>ÆÜÚŸ!"ç¤cÂWw29ذԉl…'¿’8lHA˜<4ÑfÓÄ£.¥=ûÿ@;8)®bx°z5Éj«é’³!ò Y}qܘÉÒ435<Ì Ë@ÊÙÒ›‚âø½nr3‰ÄÇ´@ý^ïÁcJ½ÿÙmLiË‘›[líËÖK¥lkR·èõGK¡–‘ÅÌ-ã$¤N B(U8ø´Ñ¬Ç4¾¹¥g2¦üé šïI"0½DÚ“ƒì«Ô“8ÅÿÒPޏ°p¸Šƽ^„Â2p£[WæSÙŠäÿÓ2\û/¢;†™0ؘtäˆÐh¤šDs†ƒ ƒ9Ö :‚–$¾J)?È%MùÁ0‚˜¡vºeD…7T pè¿Ý”°¬Pk® 4 ]Þ`µù½á¯îÈŠK¬¥*¶ÛØÃøwä‰ÈˆgÇ|yBŸÀ“†¨Ó¢±µêXqÀ&óª÷Ôa¡ ’Æía”ÌLå¯ÖÂÈ£kœ”‡¬ùÿo '­ýxÍÜ!'`UHptq$‰V¿A/é%Ü7Ôêí×:#’ÕìÙÝUþÙ^l–jÖ!—éZãÆàß@œváŸÐbi[yÝs¬ßHmÕ˜m(XÑ–Rȹ̮ßä‚m÷k­V«v`þÏ7Ïù§ƒLéÕÿÁ¬ ™Õ‡x ¦¶BTtf—繬·Mpùñ‹úwvPÈ#Dôb<€ÂL1'\4Â…ýéßqCPIä:Ù€ Ö½xSö®g¥šÏÖ#Œj–Uõˆ5%—8¨Cåàe´û„2ËZŒãb.‘6‘sè$J™`È ¦¾[Èšå“ ST£H9¹ïŒë’·¦áúšHSÃ¬Ž‚ÄSn‹"Ö†P·0<é¾y÷‡¯‡C4¶å¾ÿùæ;áßæ\›¦[·À‘š]Ž8°ëxŽØÀj †¾Ì"ÎôÎÒܶ+â;I‚€'i¥JüÝLžQ.Iûfd1΀㚱“¥XˆÓ³ãÞé…ÄDsq ,'ŽÝ`8 Û!eÕU[ƒp,¬õÜöܤ}z":/Ã…M.¥L-³Ò•”e¤ c ª¢å$ÅgopýëŸ_PrµÐì2<{’ý ûo59üŒ™v‹—¡ ]û7¢—¥Ðlù°Kжâ?m@Rñ,ë Bç.Hð€Tú,xùo¦?H­¶ëR«ùÜW/Y¼‹Ç‹Û¯ó-L¼é3kìzñèªf7çXµýø^ãä3kš“ç26~1ûÖ: èc ^ŸqY°’ 8³è-žûø;’¦ùÀeóä'œßO5ˤííE@ôJŒd?t-š†€üó‡fPûùç ¦é/`WÒ0vîçæ-Ô¨ ¶=}Ïä–ÃÖ¶òÀo|W*¹àZ=M3®Ÿ©ÒŸ¯êÌÌÆkð o%u='Áë«I£¤0œšóßà9ƒ3Éß•h#ÃòJÛq¥y8;Ä®ûªäÁS–ÒûhŒ9$#tõYæ¬GàlOC«ë!6” èðm÷ð/CÌë=®{Í‹¤Ðô{%i¡‰S‚çªìb•T±öÇAH£< ¥(ïšhs©:Þñ(ø‹ê™¨Z”æO‚\Ûûïkø¡Ä·ƒ×J½¯ÕòéØa÷µ`V‡Qš’!qð Êö‰²'¥R ¥p-›žßßlhÿ¢–÷G˜âÕ¡/š9-Z7°WjäDl:Fo°XÉ¡ÐÒ¨R§Ò³Û6 åE ¬j œã¡(çÉò†Ý©6j• ^Ñ¥gÊ*‡…þÌQ¹&¼¥(A÷Ú|aá ZfU“¬À¡ø6¨™?0¸×Ð ø³ñˆ½Þ¥ªÃUÒc_åÓ3zµê£doU#Ç9¬v Ðn R+C­s:Š w!xæp\Š¢ãg”Ü›`ÜÕ¨Q ,ChDøéÙ3/v^kHõ%=Ą̀¾ÚQn<^vI¨èez8¤é B‡p"Ä ÅöŠª]§ª|¢ôÅÏ ºWÖ¿8à컑®ÙŒÚü¶Áê¥ÌR…öÄ<=E5mÉkÅm[^‰n÷} ÒM“ïkµÒ)ŒÁª3©žMU*µË™m9ä+ÔÔS«!Ç&[…‘ÝúOZT›4coEŸK=«Ç.}§7¢yãµ–nÍ‹\p û2Ïñ£Ñ*‘èN’ßCüGm¯ð_åÊoBͰ`îQÌNnÚ!‘U,ÉJ0 áá¤<ª{9YŸ5‚ ”ÊÞ=¡,7®°ƒØtÞ¥À![t­ÀD_/jÛ¸Ï|E+Ü÷ºfÂñð6Ñ“˜ÏèL—¾âe\‡¬åÅÕ–ÃgÅ݃8º­qC(2鲜E$«ªÖ-O—»¼Ïs·WM¶ŒÂ=ÂstCBg½S¾$¡[ƒ2WNè2ÒeEÞÿ›o?N'âaÞÆ—­桌’Q UæÃåÅëÝ}_ûV¯rn¡)ÅÒFw%û *W ô™—<û<2·ïéñd.ÛÎmôÈ%؄Э=)#­Lgvøkµá Ô b‡¶‰Gþs©m%ÀY)>k·}ãá)tõjyuõn{øìNŒÜøApM•>»¯ÌÙ8»pþqZý¢<‰6¡ pr÷ ‚ A ×I“ªÄ±,}O ¯IVòœ|¿þ/âÕ¿™'ÆêS“zËP³ÅË+TéõV‹Ø°M2ðuR6{êfZ³ù+e«µrŠN©Þ2 U'eæ¾(Y·Y!RÚº¸¾ µ[](IOêÂJü| ê·jtêÇÃÎéppÑïvN†ýîàòøb0$'«ep ú ðCÃ8É‚íýí&8¤™ÿó{Èl¿O¶•ƒN Ü ´}<Ñ£'#—ž«‡ öûk Vÿñ#úýÜFñ<¸>†ãh¾ˆTd}?†§«éÚ2 IÚÚïÿpT“d)áä&›¯Shô¬Îæ pâilÖÏUº`-øJ“Ï*ø9LñB'xÙ7{õb{??{¦â«]oúèßû¹?ÍýÛœçÇ£ ¨ö{Ðg<Þ]®±©ûwç| Lí½jG9{‘dyÅDU²Oƒtt-ÞíÎüë$¼‹Ó$aµ ­™oÄ1å¯n²Ì(ÛH¡ê(„0„+Â}‘” g¬À|†fl%¶®„ãñQ„oA¦€‰M£i-êOñC3xÑ Àv˜^×ñ­#þÙ ãáµ™áÈ[çõðòtpÞ=Ü“°Š”L>tczçþˆ'ÚüñgìÔâcÙ¶`¶˜êq?œ™é=ÙSƒËìüƒ“Gy\fq-¤¬Y#™fÖ“8¹3‹"0[½s78èüe½0nÁy¸…–‚M Éò+êŽx_ jU ¨¡>ɺ>•©XPP×þ…‘MâøìͰþ®Ó?í¾!JNo<óBÃEÚÎMžüvP«”×L+7°ìŠáú÷‚†Ót8éòæ–ƒI">딿”¸ä]›g|±æH¶„¸ -çCøXÂyö­-õÄE#ypÕåÏÝ3 °C[2$­á_ÑÂ釽*tt›þG9ƒ¹Ïæ1]¤£t¢TâÒ˼›–Þ‘_O"isG“³Ýà@d‰êÎùcKéÒy)¥íÜ à’O†t7˜Bh¨n á†ýr‹³ûÒ×Ç[åìõ<ŠìAr§çÓ’³u3ÎØȼ\"{øTëÑÇXPíS}²Vžbwó°É6ñNrõör &†‰%ÐPèb>ܾ†jbd˜¬ñ¼ÏÄJ›G#ò¼¢Óå|Qà‘ÕÊí‘W>Mб˰j»äæ†iâ¡A~ü§†oà` Ãú(‡ØÖ–êݼ-î]h A$Fœùß§2ކ·I†øv8<¾<ê ëO…ùk·§†MüÈ(5ØZÊq´°Êħà\÷±_÷úÄù÷QÖ`_Fás ¦œëÚüÒ33=@§7 ýS—ᄱ=Ë´ž§3aÂÌðà!—˜s!·¹Ù[º¿éµ{üJT2©1ÒðBðY6€ ÆMEd¨‹ÞCÅR=I(Ûnßu'ñ8¿8³ì$œ„1ùn€Û®‘!T=ðÄÄ×X!×Þ½-á+‹=µÛìžï~¨Sé4ü8G³ÅíÎóÏ€‹z¾yIˆ’Tåë' TÙ€.gir…†$ÝàÒRâZXÔŽ¤Ë ÕÅx­‡4“ÐNÑ©]Ý£¾º!ãbK)¿ô,mvE)j¾K13¢³s.­wMã`œ¬@+ª(íÝX;Ò!Œ#gáâVø¿vUa½ª¦ víýk†p¥iõ²€Doä(ˆ73gÄYË›·¤Íý³¢ È ÞCIÛãÖXRšÍ5ÿª½¨©À4\ˆF|~æ õƉvàÊYüšG”²\®Î³$”ÿÊ0È‘k†bxï9|Þ§ô¸ŠF! Y¦–'¯5ELϘÖyáÈ+à"’1¤”øÌ›ÁKüÿg NÅ¿Óû­?Ú÷ùoU‡H랪ÎÈ&›5,îÅìT¶š¢Ä*R´ª66‚1¨˜:£|ÂíD5 &e‚W†Ë.o~¶U„wÍHÃä« \ÁœÁφuJpÎ %¹6{K™Âç°3ذŽ;ùB§“!ÇФRÆìħò‘þ­l¨Á/LÂÜhO<ºoÕrŽ L\@1(Y a¹× “ËãÂýK)˜“…‚àPJ1¦Ë…i9ÌQ”ºÌ½Ên—(ŸH{BwÓIäÚƒ4¡‚~lš$¤!Hdª/¶l rCð‘d×{fˆ¶éÓüyÛ°!ȃÛʪ­Â!ÞÉáíÚ¥Ý=à*bò¡ð\ü=pBH™æ¼?DîPŒ@­‘¡Dé4rè®Ñ|;sÛ#v1˜DLT¥“–ì94ƒ—?¾ö‘}4¯¶Š àÇÕÐÇjÉ6Aó·h¶[#!T\ ºk?*ˆ ô-®jÓ¿G~“þoªE«Í±{+s+Ù\Ú))Kçöjž†cÐBeéê]º³‹ÐN¶¼ÊFóø a7\ð¹Bá.ŒY®ú âA”/¤ Î·ÜÆñ8zÐÚRårTÐ÷ÕHˆ$¥n#žbCå?Äé2#«@iڑx¡X¯qËïvĪSèÚÐ:Å ‡ ¡ÒñŒxÊP.…ñµ‚£”b΄1à[ CÅÞñv×ë:'âCŒ’MÔ UÒ³ìG4eg£ËQuæŸѾ-J¡ÁÈ !8q¿Èðܨþâyü¤èé¦K[táé’ ‘ƒ_uG÷Ö\RTÜ»¥OtÜUɧ“Ù ‡Ø»º›œaPîã«õ%±ßûÿgø‡éäÌ÷qG8Gcÿ NpîEØ[ý$|™ó»y® VQ¸ç7^ÜÌœ1l´l÷ð߯-Àp7ŸÃ¦ô+KzS’¯A’å ÅY®»z=ªÈ†#•ŸƒnÃáÓ¹û$.Ò$®M—›µÎh—Ó'‡0XÈ&Ò,ÆzÃI²’?–ý‚» ;—E£%€ H3¼mÊ÷(Ána¡@mLš`Ó`xÏR!8²¡Âzef)Ó o»ôEÕ(Yªͺ¢ËIÖ$bC„c–‚N…Më4°-£ej‚2FKnÌ•—5Ø©R\IZiÄÖ‘ïõ˜øë“Á÷‡Á¿´^Â1Lgf¹ÂxšŽ£&©FÒv`»Ln½—†YEè$q,˜:* o»œº¨"ÀžÉ¸| ‚“¶dÑ£¤§ mˆ´ÆfÓÌâ#,ù äöáãk¶Y€¥–âH‹÷ ŽŠ †.?0ù‰dêóàjyÓl>À&ð[L®\…[3(Àb@Šf'jÁУ;™|þ([DÙqôætøìÙ«e<£úƒ2ØæP`².J$5V$qͧY²’g`¦}E³à&5WæìLZ*m;Ëóžö ÿ6æ}ÿÿðò&³³aãGÝW—o¹PòWgýc#ÒR,9À»C)ö6:bxoV º”pqع¦T [é©®eUý¿uŸ|ZEq 1ÊWC9>«OŽßõÊ##®T•Ú$Lóa+„y"GºÈ*-8äÃ|Ëoçiõ2­Oê¹áÐóCzä8Û¹}"¯"›úò1ËôèÕÙp\rùV^üը̧Ý:lpƒË/oéÕÍÝÚ|ïȉZp@ržDF'£49€î‘iP+Æ£òÐÎåiïÁqŠ‚Yãp¨{ŸwCV›U¼óùÂ…bŸbœB3C²Áp|Ÿäêƒã—+‹Í!²úú:‡¢;ÃôÆA=nE­<§ß,¹IJäªý”ß òò!0 ¤!dé4rcàß(·þFBzº\dñ8ò?—-÷5‡YV W~/œ¹x×f!„±„Sp-õÜ1Âæ Ð|ÁRGÕË» ðµ€*Ò ’ÐÑCM«²‘¸µå¶åÄ ç¯ ¼øŠãáû6—áÎ9‡Ty» ‚ÄÂÜ P¤\+3UžÌ“ôæ<“Ý)È*Í£ý‰Ý¼ÊœÓ‹3Û‘©•/\ÖݬØÇ“%Òüüv–od¡pé~Š{^.ý1sgdgZf¬›ƒo iRÈ3·Ïs)j,ôžM´±¬d“Ôïn°7ðqžyvš0¸™¤WrZ"—“ „Q¡CËEÊ#ZÃe‚U•~(‹»F.fM—¤íƒ<÷àà9ça¡øÛAèqGeâÄ“³A4†6Œƒ[̆c0_²‹¶;7ŒÎ$¸³j@Ó¯ í ”›mŽ_K¶’©eÜX«ÒµÊ=øTMH¡2_ &…3ìÀ¼åÅ} ‹µ¶T"9}Ì;ã±ú¥î•2t Oó<°¸—9S¢žÍÑš‡O­p½¡¡M%¬šÊÉ3#É8pÙEè‹bXT½ŠZÝXÇ쟺¨~¶8|œ¡³yЃÎ`Ðí_ /ú—ÝfÐýá¼{x1ìþ{3ˆ£]´%BüŽØh…«Ox›Œ™ÏÅ/”•r¨ß5Žð]KrÓ-Hæf3Ð=· »#&üäuÕÞîä páýo†Kbq/ÏÎL“…  ŸÄUŽñ*~Øg­ò÷4¢ßœÓÊ]Ê´™EÎnÐ;»?FîF`!˜÷:zÇ©¡óêO¹q%æ“vC¬*ôOc1ÇðE1Òˆ*w„HæµÏ†¢`ý6¹‹¯ËM·¶cåŠ ë Êfw7Vñân-L¦¸>e¯Èý ºŸbxÜ~–.rËÃJxÎw±©\ó!Ç–ãy/– ø;oóU(Ï›'¹"¹”,øNÉ©ëË¡.Cñäþ3£Ô›ïQU¤OòúÜìû^ †—û "¥ctñj̰®ùK7 Õ†²3ÑqÁðaš %Ú†^¡¤Úc¯ôæßSuÀùý^ÕqÁB“ôÞêñÁÃ…s#LÂÅÂ5Â/0ÒÁºa;o؃úsz5IM­n-i̤ rŒ“Ô0e€:¢ç}:¿kp(xì‘ óñÍÙ& ŒÒé ¢+.Üâqtµ¼¹0ekßRa£ù•jÜ(•9 ßõNÎÞ ð<ç?ÏßžvËê_8×»KÔëÁH^A‡0f•õ½‘€v3màF°XLnÓ4^k—41´ÁT·5D …nÝB¼VÅa  gÜ’.iˆÄèv}bؘàzÞ-ÕyJrU7à¿R(ܦѣÈ"ì1°‘Á‡Ôœð'Dƒ 0ëÂÓ®­ ®1dfÄMª ÒR4üD?¼2÷ÉгåÃáÕ2ž˜ã44ýÂí‘"=‰ÚÁàaz£¿d”×em¶=HýH)CP –½ÈòŽ•ˆl O8ΙTo9È÷†Ø50+°sÀžoûÁ˽¢g¾;Pf0wˆóW7wˆßvðwÏ/zg§ÖQ´—®&ÜÌ×ÔHWŽ£J¹]~‡®¦ Z¡O,§.#Õ¬øŒy{\=´¤éH‚{dlm%5â̦BÒ¾{YNÌKò²a¡fói\5')Á©ëøHÎDš|HïØÏA‰\$Ý41^C5r¤°)ˆºC¯5Ë“chÌ3$¡³|kéÜæ%$yÅF×»e¦ò0aG0D”R˜¸¨%ë;`£QC×PÚ-¾ühÙ½‹(͉²§‚:(Þq)íGæ´mto [ n}f¶A8èiÍõäã ©Š^—I–— •ÞN¶šÜ^_Ä-YK‹ê/0š×šp_Ì9zsgÑ?@\ó5·ý¥ÄNÒºQ^d8ŽÀ«˜È÷m<9?‹EØTWÜQ ùˆÚ]×D£5‰’›Å-qÎv¨_mKÙwEBÆð©Å÷ƒDšp! ¢¹,˜Ã½µÆ~13 9ÀÁWQ¦á-—Z Â"DµìaæÛœnä`›‚*é*K'à0n×[.­’vû_%«ÚlSª ®Ûy¿{Ò¹¸ìw‡”©wÜmm¹TV¨уPoÑ? .01˜§/uÑRóôY.ä Ì%Žóª /*µU`]CÑ.Œh—Ð <==F6Bðº8$€6H’JV0XS6òGYf•sÑGô!ëzáËãÜ© ØïhìœáAÀÝ’ s)0¦9G8½’]ˆÌð`2áÅ[¶¥*ž+`Û~`Ã;ðÚSô§H¼“IM‡ójã#8aÑ5Ëì€ ‡€‡aˆê™Üø¦ß¯‹¦Åõ!—¸U¦ÇçŠÝ¡+"y¿…æÕç4³†«€$ÞÕð*2>ÔkU¨Öpé™ÃÙéîEL…™Bò™g”",yÏ'5†º\c°œ[„>uZüà¡é**2âõU}ð}foÐ}K}wcæYKÁ?™G¥€ŸÅõ#k˜0mt›š!kÂiKøâ;€~ á ÌÁöÚÒ¥¶O]©ž¹(4.òF’Á ŽŠz Qz¬ã8'é Ãh.臅ºK*Ù/?¥1k)ý,ia9ÑËeÅaBþš(Šu'g¯€Ú~¦4H޾]ð=IYĤ¼ v‰ÅÕ¥êƒî æß;ì÷.z‡ãn¿Ö¿ðÃéYç¸÷æô¤{zñºsy|Aœ~ðk‘û¢ÒoΩ´ñêìÛÊÙy÷îüÌuàÄ‘ª•Ø¢…ªÒsÀë@BFùq{V„ôѼôÈ:b.ö4N€1%•ÁPd-C­­\m“2ʯX;Jòq’H¼û¸ Ïå»lî,ñHSØ’iÜ…”$vȘ(ª]Ú¿!\c‚i§><»¼^œ GfÝÚòòY׬#þñÅ‹MV¨—°¿8ˆTŒ × ¾3°é ËqœÂõAwÃÐ\&€9ï6œ»4’‚à =£Û”ÞQ“˜÷üŠüN„N¿KÙ-S+¨mY9õظ²”µ é ŒÑÍ(Xëþœ5ñGÝÎÅ[Ô°"[)}[¦Vâ5. ¤)æ:4ï–\iCôâ÷(ŸÙôûÃgÏì¤L;‡ó^Eðˆ¥ Õ¤¤È,˜IFÂm½°ùC/3°˜™±PI#·r)ÃnÞ‚@’a:ZÕ›Ô e`øÓk«¼šÄ#ö›$} QÖe²˜ÀGû´°åevý0 Ç“ïnp­Z£tÚhó9ÆÓý wËm+7d&ç»—;DMß7Ö ät?wJµ'+µjLÊWª_47 ¯Fdð]x©¹P]ÕVí ߊÙv^™“v2xcˆÝÐÐÏãa¿{n>!!dÈ~hî‘z~de[Ng-{SA»PÐÏÈs«=6…ñxkvxâô(Y/9AíÞõ€Ä@C.…±Á—J$æ§® {¦ ë&ekáòc<‰“ˆ%*`=óf:Ï›5"aؤ—e&jTi™?X ö@‡©“ªöÔda¶¥ï­äïÄØtßÄ xr˜G¹Â?ˆÿeÅ-ÊL•·„=¶ŒiW »‰Ljã,'5Ù•E‚“”Ê“;AÝqµ»7ç\d>Õ Ú¶‘µË_•’«ÖB%yø{¬EÑn*Ö‚!zþkA=–­a4K9&ŽœZí’f5{"¼5Ðc™ã’W—|Þü¼Óïœ áŸzˆç‚ éñ¿£±2rÄÌ[+`¯ôb'×ótHÄîL·Á{ˆ® Í-bJU8¶~ œmÖ­ùÊA<Åtkáõ&šO*Zwöĵ;î/ÞÊFa[Ké¯ZRŒDm‘3Ààhí‚B]­+m#{á—ß:°7öh¹ svÊ:ø[®ÖV`GÁ…ptB¶ù2 ‚×àаãGË~ç° „6±a‚Ž'É94‚¾6‡#³ÎúÜø‚·u…©Ü¹„”ÛÈ¢Xݨ›ùæÓö‘iþA³Jg4)šO¦Áô²å?ëÞ9s1"¤‹<ú×°Î_åýwP¯Ž»(F0𔹗ƒ·Ãúÿð§?Ïw86ÉïÀ¥Ä†"LÌ=›;Ï9h²<ÐÄ|lÔ`?ôùnCÑÁlѶh㪫†v>´¤dÕˆ°UÅõ=Ýxv›¼¬jš~*_›Ñ£Šò cX,• Ú# ›kÉ$µ6 M/Zî“õÝ—¶»Ÿ‘Cò(¼½¹ßKÌbn.¾_Çðákr Ìò ¸zXVÓ=œZXq´ü«ù2z‹{z‡uH¶Hy7I óx<ŽD±…Ò‚è[‰­]fQËo«Ð €‰FÅZQ1çyŽ-ˆÑR¹‚ÓwÿP (¬7HíÍuˆŒ8±pÈ2ªHÈb‹?ÚW&ÚÏ›}^a&+R¹ŒîTÀ0ÏÍã¾x(Õ%ÚèSÁ¿ydÐÆg±µ„”–ÀH!M\8ºuy ²aS‘oªøÔ8°ê]¿Å®öÁtj ª¬YU[æ¾ü\ï}1Ã4Än1¦Œ(\KŒÓÖuºÔ:­[,·M?ÿ ô3Ž>Öí¢Å2½‰-šåâ2{´Qí![“•CT–§<¦!֘㗠š© ò¬­[Gä\Ms²Í¬Éåªx0=Äx/«èßY6¢û9œ3òø'Ϻªæé?\s jv¬ès]¯1Þ– ²›• ¼k\ñ}í÷Ùûš`¶Þ'~þ ¯—\µëë‰þ ód·8"«‘öל0 ¿™»%8lj ÃÃhÐÏçËœ* ®»îl®@º÷µ9 lÓ*÷—æfÍä‡ `Mk\3àn··u.Cóû“}=ˆv;1ºw,ÚŽaѽν€—ÙÃøí$¸Íÿó›1m<{iësù“WCµË´¬kN¢í:ŸÈ¯x á& ɤ® Ê–9™šLü6‹#9‡ Ã, Àü1ÖqŒ &ç Ü(L0cœ%“à£29È£ùg3¯YÇH*éºÖ³#ËY™2#ŠžÆüæmü‹uD@)=$e“0= bôQñj‘ÙÖAÔSrq !tq5Ùcˆc¸ã±9öF¦OʯÞyJS‚Yš#v²B7ÉØo#\äa½ ØB‘„¸ ì~ß=½÷ÝÓnŸÁûT ¹A$c2zÆÅ‘±„á•­¿Pü†MƒU÷{í(ð‚¨ãÿˆá¯–ha³¬Ðꆎê±ò]Öò<{ë9’ÜZfA‰†¼E¶~B·)ùÝšþ?„ñC‘¬Gé<ºžP®‰ sÞCq6‡%v—§C0<ÂÈ´?2®‚Ú=cXpÙ§§&Ë=uŽ‹òæãÓàMá¢;½Æ'Õ˜§Š%ãW…C ±%#/cªöÖ½ÞëæSñtK2Ë%RZÜ@ ïðÞfô[yŒƒßÙn³Ž(§‚,„s rª†7 Ç‚“ë]bÓZa\((ùIYï¯[œì)"T°”Èô»(0“@ïó…øW…IšÃ¯%¨ºÛt~Áå¡Ûߠű;8?;ô^õŽ{?ŠðÑ,{3c:‘òl¿{Û= .Þvñ5:ýnpzv Þ^¾~}Ü=’SÖ™ß,QsÖæA.gxÛíªŽóç¢6){›CU¢òâ0=³t»©,×[â½í3‚|/±öêП%&Tì§EmïÊr6\ŒÚ¢¶L¨Q•e# @8` ·üü¢p>ÌM­l gŽ`»¦Š®Ä iD íƒáoÀfÜ»WßîÊfuÉç)_›™¹U|L3ym$¶¤×Ѳ€€Ô}‰óÓª{õ­/©}@W«.Þ9h·ñ×!¤±BTG'ö­²ßT„®†ñµVC·®ÌÛž±Ð+›rÄÓß*•ïÒ£T…¦š¨¹|¼¢ö>M M8ŽÐëƒRªÑÚ ¤å0Lâ°8W`íÁÊ&}8Ôû;$ãèqèHè9 ›¶¾Íi±œaÔê;Nˆò¿Ž' ùœ#­þ»³¼()l³¡biÜôBœjæß>%y-?çJGý ò-Ìűi*84eίJüxÅ:`W$Ø¡ì¦cDzîx`‹ùPzHá^ .ÃP½d×ýJ<Ô³g¥v@¥å3ãB”óàY¹-±rG¼VÔËa%¡Åò€*øÄAàêá8‡‚’¶¶ô#ð7#¿N!Ê¿¤4G÷k?$¯+1ó¼Å$-ÌØF dÌÌ=Ç®uBЋ@ ˆ*ñ@-/l ˜§.¬d‹!)ÐÛ5pð?¨ˆ¼œ‘‹’n@(íFmHa…*µQü]³|×Ô¢¹ÏªÆ0ÙFä[ž¿ÖNÉ@¸¿0^Î]œKÓÝ2FÃÇ`3g¥E©4ƒ«åB ;æQ¶ÐÃÄpxvDþa·¸Ôý ‚µ†[óÇb)Bæ”T&«¬YÁU‚"²&BQór(²*98@3²ð:2DÈðûË)±~U£1PŒw´Rè, °®WÁMÕéfNPnÎe®\j˜NÁ¡ƒ—õˆz'´\#oJ¡9£3âÑ­̓@ÌeÒòçyfì$F8žf®ÄåiÖËðHÞùÛàíÙéYŸ.iïôÍð¼vqvxvüÈvÚAïi§[lÈ‹@?Ž3ÅÓûIñ²–†’+&ð…C~>+é©2Á¹òšñ'uê2ÓÆÁä¡w¼l Ùt÷z8Z,pÂñð,®øOQo~!´ëZÎHHœÃÆ·ù¾¥äDL§@‰õœT[fRm·Š–˜°Ÿ)XÝFêâáaPGŒ‚ $-†Íâ°ïÛ\⬙÷Šƒ9F ­Zgžšªíœ%ì¿øª×wØÖ^ž·é½yEà91eTÊõÝIù6p òÖ¸2B˜%ð÷ïˆ#ó¹ht?a2··¿š$¼4{¡· «á¬Õû l¤1ˆ¯U’ bºð!nBHÔ»èRk_*|C:IÅìÅž-ѯ@ý©ô^?{¦Ž¿Y1Y«'OwØ¢‚ë‚nêæ±»MG¾¨ial,˜ò\©ð!Žë4M:ã·éȹ>X«r5/Ål”ž dK·&Ór5æŒ!©äÚÌܰÙB®,…µ|ú´ì"ªlxÑà´÷Ñ+Tß<—ŒXè ƒ^E”Y8ÇaÒqÉ,x«,Bw¢Ñ­ÆÕÈgXÃèÖˆNn8ZX\WÄßrͰ‰•ÅÛ“ËšžÈ n‰aù@|pàRìREžç›(1:6œsWùÛ›®Üo#*©­D‰2 G&–ng}/3÷–o¬—sÀzZàt½¨9Ú [³¥Ö'X _‰ÄJÒÅ4ËÝIóbº-¿²n2ÎA½FnýQÁd×ÞÀP‹pbcbY8&ONuÊ…U'ë~B Ø·aö`p¨zCgá¶d†} ›DôFýû› 2¯ ·UM²_a׆K9®µO6í·ºˆN™^Øï²!Ô+cÖáƒ>pÙº jŠ3@ZbóD…“К[Mqî{µ²¸LE³öü¸:ãüy<ïô2êìÒ]Þ{iÈSÌYóWà¬g eÐãõé‚…c€²™àÇ –,¸çî0YÎFX0Mî )_¤ÂKø©"¥JóË Y±kŸ@‚ï±ê(·Æ£;²Œ { €ûpy½ÏÃ>dlÛ…ó+À•C/éˆê§Úp¥Up¸²wE ¦ÛEòZŽV¯$Ì>ÕÀçÝÆ¥{@‚XÃÞ&>JŠ-€RˆL&Ôc0=„“ûð!C þ ÷ì 3—ò‹ïQ=nwÍÏc°Ü‡h²ÐŸˆA/‰Û¹’Ð:û§ÑGÅg—=í µ‚i-RkæüŸÐtaª!CíT)>Êà©’P§þ ô¸æ¡‚¢tT˘›Ø% ÉY ¶ß #Å6ñŸ æHTbBg 'As¯²/«K¥îß¼ò¨ÇV lÓâY¹Ž]¿Ö©i”·¥Î½ŒÏеC?u5c9‘Þ5j/ó•sžò”›ú)Ë‹«®óaCëTÅoüX&à¸xNzM#ýѺß=*'ÿµCd$)wƒU}¤ CF†Ó¢ñ±od­¼­Úï³ÒãVâS©l=áÊÕ­ò¸d8GBbêôŽ/û]uÅl–p›$ܦ$Ñj…#+ÝaRÑGp ‚9&Ñ#Ü EÉ<ÙC³p²‰©•³çx âZà­[PªŒ& ƒ™žƒ}æzðcÖÆâ¡Çt+„Ȧž#fë”Ä;’¿Ý¼Â¨·@RkÎf“Ø%×ôÞ³- ʤ`ÎîQÉoNkàÕq²/b‚r1á¤,å±!@ëÒ<ïµ C³ð%gIW‹XQz­UGE¬WR–êíiD½dñ‡¯½ ˜;AûbèÉÙü(6¼h~†ÁîK<®º}8ÊÉÏ›ÚÊä aßü†ŽJºIøX9%°¾¥'º%šn7cçÙ]À ï%æö²]v±²vð.‰¬¹:9í*Áï¹ê„l¡íj¶¥¶¥v s¡qfok•] ñ]N²Ê VÕ ?Y»Wï., /±æFkœßªÿÁ%Ö‹ùMð”Z«hï—]éûUH±y^ßì¯=Òß”ŸÓš»¬jjåݨ¾ û… ÇÏÿȽS<°7ŽC„Á Y%(+üYe"žôd.ßӜĦö }³‘ªzþqõºÅ¸ Qe¸P¢ÚE:­ß*3¤&“wÕc‘75‹?¸QSß2Ÿ¶LišÕ¼]Oê˜ÃS·¬ÌkV©Û³»}¡EµÒÆSS*aöxtÍà)C‚Ëøªö[å_¦ñqö'ôyAžŽNþÈF7kÇ ðˆ7mÂo2œ›%ž"ך ]+èqSvBÁ)Y97Ãl»‡ó«x1-¸‡Ë$þ/Ó*8L‰Î¹žÐd3–¹QLB;”޹tЭ‚Õ¢H|Z¥¿Ç7õ—(@ž%Ä@¡JM•Å0tÝ} -ØØÔaÕØ8ø}Ž î{ƒÙ³Ù»•R|mÒÕ"Aþßu2ƒµKRêx6Mæóz3pköô7 …}:/ûdœG±B‡—Ÿ6õí“*§idÕ9¹Áà¸2fX ÷ £Å3½õ…±•¸º » /€R·‹Å¬ýü9€ªµ¸ÞóÙsú´ÿü>¾‹Ÿ;‰ÎøàôŽß,Íj´ò8TÊ×HÞ4ÚâØ7ëÂ8ËĈnìBÓœR®5·h6\kj,Ò½¢yx˜¶ù¿«9Ý/Ó±²Â«~É€ftû‰MÑI[嚃6Âe˜œ‰×x±XšÃP9çø2Ì#|BDôj´\ÿY4AÊuý§Ž2m9èL"Oä¦R6Ž3_sí+‹‡ˆ²Ñ/Š£¼$ɇÑ3úå=€•÷¯®úSÌI‡ ÑÁSßWדȉœG)!³‚™*CŒèüK<¿Ò<þªçÁùI÷”Í6ó’)§ ¤NÍ jù#Ì7öÓ_mz¥â\±0ÎÉV“9j«_ǺZ1=¾VF,"³sçð!q-®‰;F#À8N<ƒ-oT$g6a¯uÖöÿÿ¾nÔäJ(àÿ~ö`¾ä8dGÔ^©m¯ú§5ª©õå]2Øp‰©wžº9~e¶óÀ¸€’™ùc…Éù_Êæg¦/”Æ›œV³CÔ/y’éìÌ‚ÎÙC[ë›KÐ-E™·ª2hWÀ<2‰Gn %gnß @ÒCœäÜ„›$" Šƒ¸Ð® QŠ C1¡‚ÑóD¾Ò9™#’ŽŽx\ nruño/šåáÒÁ³àeSkÒ$ìØ±G¼ëZ7 BhèMœz|]%—ààùø#9Úyþ8…(BíNZ’ ¬<€X©M6ÃPÌ’ýïçào=W0G†Åcø{K`ÒîÅo=ž 5™áðPßÐÃOuüÛˆÿ´d —Ç~C4,æZª¯IJ.Îê¶B›DoqÔgŠŠ×\‚±lìi×öób‰wæB ’WÎ@rG¬àŠÊs$c9QªôŠªD"ô&çÅ|Òn÷®ƒèæ0¨"Ë#™-¼Ž?6!Q%*Ì¶Ãøæ–˜ÐPq]ÇΜ(QRl;æì£÷þX R 'nHå)„SA:;ÔuîÐÿPÚlì‰s1«.. æTŸãž®T&¢¾í`«V.ƒÚbYPzâ{37Ôé›öI˜G$­»š„È&)ÍöÙ¾*P…›w˜ôü‘BQMS&Þt:…¥@}€~Z¨ ›óÁKˆ+#&×v‹ae|Ðp#rˆ‘q†)ÚB„'_¨V㒠αUO§ñbážýô14&š¤8Îtf^½Y8](F•IAç½µ!Vö»ª0=oKÁa»`m1†dª@šé¤9;ˉ`ÅÀ²Vnäm$aXK¤¤øQ¼ofCjœ@h¯³yAŽà×½†­2@glmˆÃПëÐÀ!›1¡Î^þÈcCtà¥M›„=æñÄÛRì†×´M JìEéÀÝÌ\l n÷lKxóx¸t_øm­>«Ùsö N°[èÀÚÓ‹GW¶ÎkàéÓ .ýþôâg2S¼Ønä]˜¹ˆTé]—ŽEäÂ9…s£µHéùmð5b/I\liA“D€0ØÞߦ¦Tp½®顿¦žýíÒÑwWh ²¶_S,†Ýg_ÉPa››P@8^|ölâƒÌ>f]†š>‚¹ó—š”ž«Ê‰š›Š¼Àb›—5rH«‘CD!Á½a‰}4õ.Ûö‹íf°}½‹½ýz;××$DÖº¾¤ÖY"`PÍ@IvÅ@4³ ;øÕÓf!e†æ0i0Çã5ýgÐÝá[ K¼Ã ¯¸È¸þ¯Ì_ˆÀP°"nÍÐÒ;ÆXxèö¶UçDªb¢B9ÊmIEgi%ó:¶V=trU³9šêìJ„ûÁ"ãñ¤I,R>‡Ð"-™á“úŽ×²9@¼s¯Ë>¾ÞÖˆkš‹*½ìÝ[z ŠÇÿŸì@‘ïÛ†' ÿã”rÕú²g -;ö•NBQÅÍüœqæðЛ_ª9;Â&/çj2«ø€ÿëŽyòozÆóÿàI³ä˶[A‰Ž"ÊK¹ˆD{JnCJy…’Šž:…åŽb„Sd ¦±6‡ŠÂ •tXÂUšZůGÁÛ¡8JëžÆfŒ#ñ€-‘cp «ÄCE)mKäo/8š.»;N¡ ‚ØMé¶Ì:Aƒ‡€áoYñ¸wzÑíŸvŽí,4^³Èe5dáV£š :KBM\0¼(cb@ͪßܰº7.qðÁ»ð6Ìü4%Ò«•Sů^I¹Àì7ƒ§XÄó;óʬ/ò\ŠøÞsOT™’Wë$=èÚõ•µ×©âLÉ8s>`öœs~7úsíF üè×?2®©ÊÖe£p†r`<‰!‹"ß.¥@q¢„3o‘Jü#À"MÒ¹ƒÿî;k ÏœÑ~û»m'0’÷w}”X~6EèPc)ô¦²ÐÍ<Š)öce±‡æ*厼r©—HæÊ¼¬nüìè¬~&ß¹øƒF›"ã(-|, ¼*f«GÊÂñiª)è´þ:M›`»jËò¾fþÙ2ÿz®«H‡ûßýx~6¸è}ßžwÀuãt@Q½µŸLÕï~<í¾éx¿þìM§ñ<“í•p›Jœ‡¤,a­:CóÆW8CŇÙPÃn©UÖÆ JÙV°ýí¶m¼Yù¹³OÝ^°½³­šóÊb 6SÁjoò–PôúO]k×­"* °,°¯6DElíi+w¢º$±Ñ‰"ija?ž]ž^7ÂíƒóŒ'{xB·–dsˆŒŽ¸~Þl`÷{EŸÃS¿ÛäDÎy†æÐúé9°!˜ãéåÉ«nÿç’îľŒèF £Œó8@›K‰‡R¿Š÷VúxeÕØ¿Á¨•{!­„Ô¦ ÔV}xRùÝ£ÄKë·香Uý»7QöÝ¿~÷&IñÂåÂüÑð¦ÙÅÀ‰ç|xˆèÚ<”D „…2—žÛ8’Þ5Ã(2 u¶ÿÂëð¡B;(£¢áœ=‡‰õ»HƒÜÿ8˜=üîMû»zýîáÅYÿG !o¿{SSøÈðe8èž›Š¸¦8@ áwë9i(¨º1oe™v™¬‡ãxŽéL`Ss–EÀÑÑdS ©Þ £ÊkŠÁwoЧˆŽFÌÎZ0ZàÕé¾V_ \æKsÞÒ‹³>?ë_xó¥Ü^¥YÁhBœ Ç´IÒ/:µ* ^é'® rlO¬Ÿß»ÞéÑÙ»ÁêY*g+D§Sf ÜaB  ´ü©D O:P^^ØPùTóx1„d˜&CÖ,ycºéׂ»:|÷æió¨ûý°{ÒéÁhÆ{[J 쫾êEm8¿ñT_¾¹ËüÚ î:†4üGÝRR’׫ŒÿO7*Uj©²>_9K‰¶º7ÝUž´­ëãèE×ÒÍ:É™B'JïÎÝÀ!ÇÆý†àóúÚ.•*< «–]7ž•Ö-…íå2‹Ì]¹[¿ªÃJàÚÝúÉPÐ^q-®%-ךú=Ö†Âi”oº$¹2Ö­Œ <,ŽÚË+°f䜲½Ð‘Ïuƒ@ õpLn¡gd¤VTFB3~>5í $UÒݯ™ ;q«;”×ÕÝ;gË#pû]±ÿ^ëywáõ{F<)ÅJ\¤›ž³BÂ÷5ëq\Ã#)]ž§be½ck/ÝáÙ»S,¤¦ÈÿÜgÉñPR>UÐƒÙÆÆ^Á:a™>Sѵ"ûÍ–%§ØjíU±„zEGd¹3äUçÑ4ýÉù²`¦tTËN*°­*G‡WŽçZZ˜ÓþW0,|µKXKÜ8Š”µ´ÂÞªaoxŸr£×'büRà¾ÖÀÉ*ÿËm-Ÿÿå }[Võù·eU«ìëþ™é¼2÷6pIðàöCì‚x)@P7\ödÉYÞljvHNZl×Hæ¶>´V-k=ƒeS;àç ¹¯Œ[7 !j.Jz¸[˜ù€@S¯0Á.¸Ò/¢-¡.¨(8[ÔñRcˆÙ2LÏð‡ÉiÂ1W‘7[t‡Î›Ô'i: `Ü™„ôĨFGin>ÀÔ}4™È¢X’(1 D<ÙšóW?R‘¿þL”Âüãÿy¯$áÆQ4šÓ¤d…Pj&Õ»tLkÐØÝÕ)MÞÁij4HXµ=––Tê…±@ï9£íØØ5*š³Mh}xØýùüŠ^$§ÆCDgœe Rsú)š¨0r9Ø¥‚LØ‹³‰Á˜LÄ‘ cŒÂÉ"v—cCðÄž7Î`IeF˜fW4àWÙ½°½¿ÿË»ú5Ô/!‡¸WpåJu°0°¸÷ÂOøgw$‹–ÞÄ  sÊ 3ý|‚S縚YÃ@#`AüqlÄxÐÉÏeLc‹Z.u(*¥÷ñ(r™õÊ’¶Š"Š÷ UÀŸn†0ˆ¬…9\ê²ôe±¢HŠ ’š.•ó ÆÇ!Wžo¿ƒ²è¾Š¨¦ÙOäbÃëäPÈ—]—¬À›3úÂ0Χ†¶‡y‡ñh9âxA°#Å %°Þ…E'DûÜf–DÁu ¹Q”4z‚ /å†e#§UÚg€?Òí"–NSçÝOgs›[å:†@æ{ör1@+ËÙ8Tr.5J¥ÉÁEXHv¼[ʈ…8Sâ,ñ2º¾FtÙ’{³‚D}UH›zx9¸8;öN4ùæììaˈѻ<=„h@LºaQÿ$"TEIjÔzt¼v MÈuS‘‚uƒ~„8‚/š9>ÃôšsIµ^øÎ}l3I&!š”|yÚƒPWˆ€ŒÖîK‘¨ÿïÖä·&O›˜‘ üçÙ•_¿xñ§¦Ü½^2² Æñg¸­hnU±‡†·6$öjI–àÝ)]}–.ç# ȺŠÖû ób—fEŠr•ÔC˜j<"!ÈÎ9Ú\bÚ‰ƒ…-M0¯ªó ‚Ü‘;á‘áû5%Ö<ªˆE½JÑ5„׃ØÌ×äI1¥…×=3‰–éq4 ©‡Ó²˜ÕºÈ@ÌlÇËQäÆBÀ²=¿e,[.ÿcÎ|•ŒŸ›ý n ©¬Ì+•¹…N9cç &wÊ|ŠÆW‡ÈŒ{îûz±¯;ºšAs)g¬¡”ކ25RT@«Ž¡fŒòælYåôzq‡G¸TÆt'Ž]åðleÏIÖÛÞ œ½¾x×éwó÷yÿìûÞQ÷(xõ£ù±žÿØï½y{¼=;>êöAçôÈ|=½è÷^]^œõõјÊ5ü­súcÐýÃ÷ƒ³~Ð;9?î™öLýÎéE¯;h½ÓÃãKÀ/m¦ ÈR÷Nz¦äÅY».Ö Î^'Ýþá[óÏΫÞqïâGìòuïâº{}ÖÇ[œwú½ÃËãN?8¿ìŸŸ ºÌï¨78<îôNº`—<5ýÝï»§Áà­á.üébÔÊ»Ónæ §¼êš‘ t‡³%÷˜–ûëÐ,¢ä1bñ λ‡=ó·Y—®™T§ÿc“›tÿýÒ”3?G“Î3ÇúúÕ1›txÙïžÀØÍ’ ._ .z—ÝÀÁ#\öA·ÿ}ï°;Ø ŽÏ¸p—ƒ.æ¨sÑÁîM+fáL ó÷«ËA—Cú—Àß0{þάiÇÔ>µ>;…9ÓÙéžõ„¦a=p7šÁ»·]ó½Ë‹«Öå˜Õ;¼ÐÅL—f1qbn¾Ái÷ÍqïM÷ô° Π¡w½A·a6¯7€=ìÜœÓí%Î6ÍŒ ·ëµœ›¸»AïuÐ9ú¾ãçòæ< z||pùßòê˵è,Í=š·ßý<¨ÿÇm˜<@¼ç»01Bï‡I8žx¾7_‚ã4‹>4¬èsB2+.e‹©µµ"Ý=å§·Þ,'CóE@L‚oFóÅ0úHN‹·^y¯4#u¢ùé¢R\k¹èš'<¿‹·‡°uÈ$Â[‘½þoí¶ÿo´ß0„M¸_ûa]}ÿ…•ǹžD¿ ÷ ÀÐìËg%ß³ü\o¸^)vƒùÚG‰KU‚Mqƒõö“ ¿ë½·±îQÝëëéÓà|§îþo%mV eŸ¶ª(™)ý—ÌD¯(vú{âÿÖnûÿÆÕiu9… ¡¿†uù"[‘ë`åVä;Ül+‚‚Žþ/½ããîÑðÕÃAï @Dœ}ßí÷{G]T•ÿ¢ý‚$㥾]ÕÕyvæK1“e!c¥ó0íҿ¯µ;,ôkÙq1ð‰ùµpVxÔ`[Ô'¥x ªŸßK¤Ú! ¯3 ¾æ¡\(ª 8x–áÄ2CLÈCŽ·‚1" ÷€oÂ…FÑE&õ¯V¶ÔŽjpwËéÔÈQy;aôîmU_Ù)bý %5o/âýØf ä8ww±k94\¸àØ@.EqaËKz¹ èæI‡Ä]x‡ÂµOôïÏúݣ˓s™“ü»²7#_‚‚d¼œÎ¢q£¶çì5"{’§:pºž²±z„”ÒUD(8ľQF °’€f0a­ªh"Ú„Nbð¢+ Gÿw4OÝYôž„Ë„Yu#íMŠHEµ<É=W/ÞÜ[MƒËn ;^ æ I›žN‚€r™¬ÀÑ‹Þ ç&SL6)ØByljâšdߨ"èbÇbªI3ò„B…Yl3¯Î]ç Ù:á„2™W„ÒI QY¤ Æ-6e_–Þk˽]`ñw9,ÞʺÜEÏÐ7rÃ9=RœœÓ%XlL÷ \ó~˜<¨Ü5ÒûPw(]'„AóZ°RX´„Â: ëÖÄQÝ›2ÂÊÒUâAŽçeW©|sZ5'“ºTÅ ÒrëŽp ^m¹w~"î ÀA3—êŠâÆHHÔò0æGˆÇœà´J)È|Œ¸ý`ûx{oeÁ>;x×±º,œš{(x±¦ ÄûtAS z¦Ú,Ìe6ƒí…ôHæ9‡½@n¨\b8,/™BÂÖIÔ›[s&¸©û2g‡R6†÷ΜLp#ñ.Ÿ$†Æ(8î}ï·aÅw\É«è!eë-ÁÔ¨Lø€‘í^\öO‹#aE._òÜ<ÀfTR_š Ò1ÂgZŠª…‰Ñ ‡k/¸xÛï¾[Ý‹KÁÍ C®N×;q¡´@wN!,ò D¥a·D䓳¢…]vBbB¤¼‰©Ñ† Fª%ƒ2SÓž>\‡}K0ãúQ˜g=>gË škX£Ä‚ݽµǨP#øEO¤‰ç¢I[Û´ÛÓäõûDG²ŸÂ‘ /,Ì,/çC"„í Mƒ b8«äO•ˆÚ`7¯æð5ÈŒQC˜7ϑ䴗·ˆ`dfá ñ˜š!0=89NÝpærñ« É@Ìtk‰5ä’&>‹É•çÉhØÄAÚ”È!¼d»Ü¸meáG< ë­x„^ëƒEU)`¬¨c¯:ZÔÀÉÚ´¬Jþ/][ZX’jÆÅ´°ÙuBFÚ  Œj$}° ݽ‘¡Ìc¾ÌÌ»lÂpæÑ-cö•né\Ú¥Q®Aì[ QpT¬P ¯³Ã—ÆVréÔ(¶‹O…‹ì:ÂÐ.¨°{îÑðzŒá]÷‚ít=3¥^A¨›Ü¢-Kq_ôQª¬¯4pË«O¦…—ší. (Û¤a/"Œ§K‡Ðó—îp*S"´°»‡o»‡!"I;ü3,º\ e€N˜ˆ¥a^oÏîç´©Cl$˜ÊÓ,¼7£§†þ¼w¡Zí6[üÚmåFF‰ T݆­äo˜ýÿÁ-S`æ43‚×lµ ºùpˆá&€iùõP_óz”ެÄ/wvqÓ´[kšùJÍbû„ÿû‰_ÜziO” á5¨q!ÖÍz P¢ ¢`lä©Zü¦$‘€jQH»ÄÒø"˜R"Ùx ŒÐqÃA4%ç›ÕF})»›ñ;¼û2H’+ARANA¶0£”Ó¦Š^C륧“Ï¥_vfûô)OÖü'ekaJ¡ÂßïÞþã®-€Çe÷eí·Þ`•/̈âïmÔßHä~0múúä“›¢]øåÈ©¹ê¹Ìv·^ßµZЖ—Á,>hu,¡âBÈjâ3Š­ðÙ, ÑúH4@óYÖ¯ Š-ÁË7IoÈ¸Ë O¯;crÑ7 šk´‰D¯:߇v˜³x¾ñÉØ°ØP'•te¾»âñïjå̦>ª(„®ƒ#Ç >æzìËÿ¸Y˜伫åõu4ÿéë?ýÃÊ ¦W7ýb°\JÜ'>AuùÕ±*¥]¿7¹­fðõŸþd—&n¤2x¶`Jnþ™Ç©œRK¿®Ûªû-êF]ÒŽ€ÈÕñÙ›a· ÁËÉ÷È“ósÜKFIý"±ë½ê†k$+ÓÐa,è¬]eøîµ 0P–T^T[ü„ê 5,øúsMsPGê4+›H^° ØõéýòOìNl!éÐêkId»mÿäÏ[M)«ËXæB²JÇ'S%ŸOΑåÚ!iì ~HFĈ¨GG€.ëü“û¯FÖ>·85=´ ]]Ò&¯'#‚C¸«Í¨žæs»jMdˆ(q¬÷€0n¢•h?˜<ºkà¡5zÍwvØê—•Õ´ôB£Æ’(´ñ ¸Î ø›¿tÀV ¶;â!÷(Ü')¥ƒ±eÀ½B‰xŽ Æ3òê˜rýñ¥wôœ•…ºµëÊ¥q;µ‡fŽh+ÐÎQaê—v¬¤iÞJ*‹3ƒÛ&å±rœÉ¿a­¤„¶Û¨:Ãq†ås03Ï÷C¥¡bèlJR¢âù+Õ+¨ùl»“C—ëOÊ ù ú—Ú0ûƒ›#‹²u§ó’ëUÊ[nÍã}óÁ5ìô@ù–í}È5mk¸¶mQÛ8#Æ'͆æû >e­8=kÐçfBËSU¬“+2Ðâß&±?FjYP>ô%qLLÏëJ­L#ò5¤+›‚_ª¬ hM´ LáM’¡f$†ÙÈ "<5„ZZ3Êebi o;®Ì«“Œ{2®ž©W‹ˆðXf†D˜Û.ǘ ;Èzvb 6Fe^ý Ulÿ|vGD:ÃJPJh‹¸ƒVÅÐ2 é“®Mdc l†I´ ®2LEÜPÍe«Ö ŽU¸%³Œ¤-AàêVîí¨*ÏïQCŠD1âA²{¥V‹+€TÖöf!6­ÓÓ×þ²Kž¿ŸG˜¤æ[BõYbk+©¦4RÿÈón¥cDenBPXÆœ"Ž©!öÊ6"¸1æí·»(šQR¼âª3j {Œ­hùôªzìØþv±]o9»'\¨ä²nÈ…ûè¦Q5Krdœwˆóú2´ìKP²/DÇVR1Ÿ¦4é«H¥ƒé_eÂ*^™ß2'ø[êÂsƒ~ÿW“tt‹xŒÃEˆ{û!Œ'ˆ‡Ž_ñõkˆ8ñ#ûh¼n1&ƒš²' É#²iª-jÎ_ýFc&Ìô² §¢Fµ­ÞrŠRr†¢"M!¯—–Öt¸…Èé8ì»Þ žRÒ,1ˆ°’B×\§¦ðËZE…Ç…ôºGyG'¿ÚK[í>6´› L*u™¢{@Û1äª71©Zh¬€ü÷ÊCÿò–Ð$»a3èÛPÞ šz7lÆS{¹æÊµbv”Dç($Ö¨UÞ#t¹ÆËU?GU/¹‚€ÊŠ|½Ð‚ºàünÁ¦õ5õH84 ³øf™ÀýA ¸8àCM“š¨Ö”¢«|.}«}¬|—E÷ý9Š,Á~\gKà;H@nóêQñÏ».Ã;yÇ* ï!‡ íÈ©ÒL šà–c8tˆXƒ«™)d$§pʱ€ëeërû—{Kù§œRÕÆ‰x†eÖîZNä+…L1Ù__?ÉòVv#1ÙêÇ µÊËnt`‚#ªòÓI¶yÀi“ž‡ûˆ› ÍÝ0y¦À©%õMçžà³²Â‡A" ë'ŒS3äŽÎIïhxzÿÛ ¾-xIµË+!Ir™â½Šä Õ.!”H¬7<¸çum©j§EcÏb>AÀÄÄP1¥¨P(zg£Q®xiBz!kꘪB[åÕ2žÐœÅx9:>n@x†h{‘é½™¤Wׇ<{Fae†Ó˜0s*ÔkJ LÀ>IØâ<š·ØTÒ#óò!I(†¹ü‚+›ŠŒ†¢•Íæ‰šçty%®!XÞº˜yGóØs›°:8&Lƒ§æ:¾Y’ÿ¥`+T˜EHÃ;@+èd*]5˜AÕEV4¡‹v„YÓBáæÑäÂLqRgd;p¨¹-´™¯íɲrjçü¥ÉxT¨Ï†a.°F—Üxž§x ÉE—$›Û45,YîÌ ÃÕó#4rNÃe4Æ(M;A”tÈQ²®ê/gÒ¿‹2Ä%1+±Œ³ÛœÑ€@[Ú‘=Át†Ÿ‘†e®g9–gWßQ#‹jË´ËJL¯äS߈yÌó¾á‚àÍö‚®+ý #äÄìœ÷_PCq…1íÏöƒÚOF ¢`>ýÔö<ü_jeßQ»˜½ñâ !îŠ2EÕm7÷ñikE…¦ø³àe°ë†ŠóÕ?Ê‹kõQ y0!IK&ø„~‰1„–ׇ¢ÉŠW(Êê'ëdü¼â» üqºÌ0n“È,šép*I蜚¢w†kø ³…í`…ãémAlàe(!)¾í;âžà³TZݺ‰ÀÁ”àí&¾Tžvl¦ê¶“Ä›Ö Eœõ^4Hy(HÎMÖò’¦(6èÆ$&º-Á9§!é¯sÞ *ણ£ð¸ÐP*.(ìˆÊ¼— ºPþ‰¼6¨‚¥Ag¯‚šŠuL̘Øæ;çVÀxÀ œÄ8'ãp>fË2]™½5gƒ7_ž±È¤˜u\=#½k—cÀë5‚Õ@ñ¸†šïžvÉùÙ{×.”aÌy¨-<˜r­°jKCx~W©óéu<çXz÷ˆ aŽ3ŽvÀ†›å@¡á‚=ŒDà1O/¼á™¤°žøaÉÖIBrXûRâtË$HJÑ=Ï0¼xN—‡ºˆßC vd >äÓ3À÷¡¸©K&ˆ [Ü)ÄcaKœrR`›â´ù `’'·[C…}˜@¾EÚÔö\(ÈøyéPkÕf 5®1å«*”¹#L³H¼ŸÊXoIÊž!RÊ5ƒZ Kí¹¥ÿF&”{Íà €ò&œÈ!cí¹Ûÿ#† o pîLk£>@Ê) œI¿‹(îozý]ˆ¶ý) tÄ énu¼BwI‚ÕkŠàb$“ãøX‡A^6…5µëjÞ*É7…ǽ{Àé1Ý…)o 3BKÌgnŒðV%“ýŒ©JŒ\»d´ÒŽõ>/:8SL£•óýí³ýTq•é½½U¢ì*¨‡¶üQ)—¢Ô(¸7–ƒØM5n\»šE ÞСƒvE{m5TàŸdLXKÈl‘sž(J \î¸Vp´ Ž ¾Èå"¤@“ÄÐ<æã"]Û‡K°Bè–3ï¸ b5"¯§°AWæÝN™ËzHÑbÁÞH†k‚XÃá¡çVº²²в<Áµ™VÎeÅýxÚãøŽäßã8Y~üYò}äÉ—@U Äh(FàÝEºËš*ÀÛY&ŒQÚ ^™«6ÆÕç¨õ©½Ø¨31,Öôo`Kn‡£>Æ"h¼liåØH\½üÎÉ*6N#£öúl¢¢$æà"ÐŽ!Ò&òµ_{MãéȧTâ¤ýIUZÇà‡I<ŠAiNy:ùà,À¬µÈ 8&ò¬+<Eç:ô¹;üob¾R¥ƒÝV¥¯¦ò¹[QJyt–'Oçµç;¯y¾~ÖQÛÖ1+Pk¥é:Vx4'\ÜÕd ˆ¢ÆÉ-x½‹ª×vÜRn0¾waÌ‘]òUì©9z,3â4üYåg#ÇCæB/óP}¶å]cpÊÊ-D¡™é#Ú”·Ž"ë)q¹—‡©ÞY.R®Oju"ëÒôaÎXá~5l2W­kñ2}K¾ºà¢@ÀŠX“Ì¾ÂÆN'ôRŒ7~k‚*½³("’*Þ+»³ä]ªÄZ=ª a6<ܤ&À‰iœL"ÖSKo‰pn‰ØAeæœÛ±‰¼]oA Mî‘ÞòÈn¶Ádî†ÓLÒÜ‚Ži+ËCˆç>hZ]R0V*ÏÖ^œ‘i·é*­Óz¼ÿ (®\,ht’XHiïým·MmyÏö5dq¤âgßvNŽ»¨}äÅÎ~úÂ<~ñ)0î žzÛB!ˆÛiDh¶F¸91rHløÇ3²^Õ¿n®°ƒÛÿô@6ªðºs<è6íºe6ž˜gÎmµ6i«wú2t}mλNÏH"¯0]ñ‹vÅwÐÒ·‹RZ©òBÄÇC;ظ1`ºKâÆö>²šÛ¥ªV±Q#qkŽ?T <î>6°{@ž¦¹+”]ëÎ1° #BÒÇUM<4ÍA2Ò'ÊCã€ü!#§AføÈ ¡Eî¬ÓJmÂY¼áŠtè^^P›=õ’$(ä4CÈv’&S ‚Â;트Ý:ÊéûÁÀôÖï]ü8ì\P.Œî@á¡a&‡,à%Ú7HCEÓëzIUCJ`A›ÁEÿ²Kœ³,è=F 7½'j#:Faqçf~õ§^KOuSæŸC/%½/ìˆMò¬ˆ†É ûáBí×n!yó0Í®©Çú<²^Ê–Îó¡!†jÀ¼gÃþàÓ±({Ìõ·Ê‡]Ö åYÈu˻֔D·ÌÕ“%4¼>hÍFˆZY“uìbrÙÒ®pzM/ˆÉâ¨á3IÕ q;ð^Gf­d2êxÕû\ÆëÊß+5NízÌØÝEœ‡W;<ïw_÷~Ä»×XáÈžµýZðLˆ R!¢:†oÂÈë,Ð2…øgúX>.K??sdUôËŽGKÂ: ëWøW (Jà )ÁuKÊå)ñUªÝh‘i9$âÏJ• [ 4Ÿÿj»?¾¡’ËÐàhÇ[tÿÎhiížt~žƒ›f¾¥Œ¼gǽӋõÔÙ« 7wð$/'˜PþÔlN§ŽÏ£àÜWÙŠgí'¾ÇL’CTN•Ý.:‚TêØꀵ`?øÖX¢ßÞ×ôÍ×÷¤Á¨í=ÂêV«ÑhÙEÂyHà†¼F§IRÛÞXoJÃdpz5øšá!Õav‹ñ·–'FnÎ&6Œ×qzã¼"ÃK¬·!›C¬·¨’lˤvBvâ¢Ó¿¸<7²ËY‡Œ2Ëro†Máizª¿7ƒMËP¸Êìv® ¶Æ÷˜ÒòÀC¹×/|pqDüÅ PüÖ¬^/…=ŸHóoRV™~ކ½ÓóKÀü‡ÊÒÊdâ-¯}vy±®º9–Ôîöûg}Wr·öÏ»ƒÁ¦Þ?Á<8² võª®¡åލ|GîeÅýÁ熈jnêú>X,±¦zùß§$ÊëJjQ±­êºŒ »¶ªp"VAËe2Ê3­˜R9ŒõkΈgÙ¥†4öâ㋦MàMÌÊ € IŠîQêxoC¨Ü‡xž&:·ˆM¸Í=ÌO4Š@öHçñM ´àž²Ø ÇñÜéü; õ–o †ëâ­[Þ,Ía|æürdëDxÖn‚OŠÕò{Ð9ä£MkçzØ:e¼'tVš¬“Rœ Ö³N“ŒÙV¬÷œ9xáhÁI/oÓ±õÝT.@`¯Á´deIE¤lÉ"Ï8ÌZ‰¦bŒ^%KTa„›X¢ò•6±´õï`èÉ!QØXt:(³x\7ÿoÈq3ðï†UÆ2ÙPtºo:ïaÞïA/ç¾3ú(åK"fA…M®aì¹Q¨èÑÔ&X ÜÚÊi·WnÂ&x›Ùí„NÚ[ð‹ÿK,Å•{ŒEc­.X…q£WóÞÑ;`'€#éÕé±Ã4Ê´Šò{Q‰( Œ%8=Í!^ÇŒá'C³(ÇCií³MH&®Ê¥àL;NÓ®yTKHG¨xÔ#Wí1çÖFZéá5WüÓz0_À•ÊWX¯]ó|ì‚Z2¯Už\!éyé|M¥{`1›@Û#¶®²ÑBvÄ)¿¬*r¯\¹™[ºJÝf ;©5éµ;í_ úà«<ðÞuú§½Ó7è&Xï¡¿[]ܘìðzüÓ×?¯âÜ T‹6S°ñhq¡JZ€œ÷[{áÅI]E“ô¾i%´÷‹0¢÷à,ŽÆ„êÌýJ-`˜#ñ.âˆ.`ΤьÂì²”±d CbãÌ­£n²ô!H Dá6/’*p6b客Å=„¾xÄlÝ<¹rT~8=T&áf©8¾Ü‘NýxÀE ßÚ0˜‡#åî̓ºÇNcà¦l‰ïC‹Ç>W¾7'oK«›B–ùž¢]y\²Èâ]ŠÜÓ ~õ˜v`Õ™t¥å<9¶Â1rT0Àê7×YŽÿO/~=¸§+—Ÿ_þÌ¿rŠö9Zõø¸Ý°'&;O•ž#Èû@îhÒ <lg)_ÛŒN6G»äZgŸ=_ßO›7›EŒ{ï aÛ:l-›̦:ÇÝ]å^ÂôTÁÞAŠtÈѼ1©gåúwMáB¿Û¥úêy©)!Ùžu¡¥a” ÔÙ¾àƒå #†p`¯í¸dÈ+³Ï9w÷*G1H~ÓsóÒ;7¢ŸW§ÊýXt*d ޽ WÁÐ…~^ÕiHx"‰_–TH–¾wQÅöÁh!øÛËŒx=’u\~ÅQ1¦CZilŸÅ¥|.RTÌUÃ$>–ŸYåD· §£…?öCÁß”õ’ð` ïDg~ó!3cõ“ø¹˜=:²›¶ ˜ñ%½Ü@ƒ]À`Ëò‡u¸èw¼ËpvrÒ9="¸âNÿÍ`ØxÜÐe{HÉllЙÜw¨ßŠˆù®ã߆ä¡Ã‘m½…=÷ KÑT«rmΧÓô¶’·×¥3û÷ÓDÿl¢KíCª—U½ˆ‚tá%rXý¨•ä´ë»‘±¿¸]fF‰²,†Èa°  lÆèáÁùèT¨ dE ;P:Ýå$¾9¶…káÝ>d˜NÌ4ëÐÕ‹£æšÑA.ÜTy{™UÒŽŲu×Ü&zH’ iC ùò6œ‹kĉ¦]’1›&Løx>Iä_èÌAà‘* 61åbY}HïPSrÅPî¿Ç£•ÜXUƒ”gWâu!£"”ó)ÖÖdJ[®î‘–)œÑ°ù€24ot‹(aÊ6¢³ã t¦˜–U@Y=Tl½¨€—÷|Z¨îûz¶xSBKzá Yƒ»÷_%ZÞÁ®w1|Ýé_ö»žƒ]qæp >Dë¦ZÀE°|@•ª3¯ªwcÜ=T·ŽZ¡«˜_hÚ·ƒUX…sæ;ÁÈúòÕ¤(8qÅãK°š0ƒý © Ê™©¡ï1¢™%@d Ê¢YÈÙ‘]"xE SÐ Ü?›­$çå»ÎÍá¦{mRV—V«/HùžçÉê²ú|”žŽY÷I8RßûTÒÈsJ‹'pxé ù¨ûÉNéüÄ·ˆyÖ ›9šP…žÏH†WšÄÀ`†Õ`¿ãÔ²ˆg]γøa‹ð#.€V…™Ü,A; •2RÀ/ ë T”Ä©ø"@.¸9 ÏbHŸššåšÆÿ-áœÜ%åûðAâ9ùèÙ°wŠ¥W‘°«„ Þlý™ô"øÔÿ?,ÉqzÍ/ y4,ù퉉©‹?½•:J“¿{7nx Fé|NÈÉÙ=ØÅ¿/mš}zœf‹y¡ vØq¶Q˜ÐÞohëæÇËéôÝ£âîõ§ø1øêYÿø©Å= Bp£üo8V³§æ‘V®ï02D¡Á[ÿ\˜Æ sÚ»èý‡¥Ž‰`HH0þÚÖKÆšKS^¾4 —‡|o«œ¡#Ag}ø?ÛŸ”lÂ3í"ÏbXÔ„\ò‘õ$3³}ÁÓ¿*|õå_i‚¡ Ó€ôыϖ)B>–d©e…6Ç#÷² ËÌ¥ã”ÉvèÔ¡-MN sGPsóá)ómßµy€‚!ù¹T‘0R0‹ ƒ$³„0ää`KC¨í?^P*‰G¤\f~o:¾±|Ù< ·Ù¿zAòjzòS+(<à/\EŠ“cyѺ±û²(K¡¦¼šWôÄéSä˜+IûÆçÄe²ÐÆ„-­ë÷µ;£{Ð;¤䓬µÌËe¹Wš[¨ž³µ¬ã`¯G†ösµfðz8è^¼>2 Ï@¯®!0ÿ—›ý“›¥4è…šñJ "wÝr¹Z(¨.kk“Èí‚5‘Î"· §ñ œÆÆc²ªLGyc7_;_ §Ÿµ@â&\4ÿ ÔäÅ'^œ3Z}󛯩 OT_[n÷…Ĺ<åv‰nUð¿h´dpM ×bU|Ã5(ºúG z¹^ƒH$ùòyª  ”_>õ4ÏåJ݃ޛóþÙk‰oGîn!(0Á³“‰4¬|`ÔÎ#Þtò†|,ÐŽVp!ÆuxÆÖôäEz%«:›Û¥¼Z(@XQÔÑHžË0­†7žbTøŒ˜y„ôüe¡™ÄÐüÛŒëzH÷Ê Ò˜JJŠsiíè\Z€n|¹=ªjeápfwd~¯*Až¢à€lÖnØ{sºÉI±sb^w8çåszZ¶jlá)Ó‡ÑòÏÙÛήïiwËc[ah_…¹èX)à‚úžØO©F̉j¹ã!Š[C4ŒïXß½"f-Õ‚˜òF®›ˆ‹ù—²ØŸœt·ӳÓOÎ.âÚ̶-ÖÁ"‹vÂz ŵz4`ÑÁæ™Áì§ÓpFñjMð¿ö»#CñïwýÞEw ý´½þŠž÷{ßwL%CJÀoo•¾Nã1tj“ƒyìüÃñt9åQ‡†Å%V°˜M¡6_xnÍ"ƒ÷À.l²ÃP£)!Ù¥8E×,°w/¯Ð-XübqضG]¡&¥Ûhñ$ŠHS •‰Œmœê¡”ÑxiŸ0ÿ¹ðø@M¢a]Ÿ3¯Ã9°=Œß¾ö<è¼êÙTðÞJÜ ›þ\ , þüGr2 Ñl-U Ëž8‰‡Gœ_×FtbKwfíñwäÇVñ ™£õç?î•»á")û°ÖÂrÔkäx—záz}«g²[6ŠöfZ8(káéS•Ç®2 ÓΫü¾t5öq [žó/¸Iãûñ´\©ÝtËÕjyøöØpãh,“¶ªf5]&p±ùô»9ê§ýÑÑ º••ÓFr®)#·Ž®2y´µž>õœ¶ø¥lxî[A•_&ÇVˆ þ¶„è3gQÆX¬{‘$:Ë>LîE*{yš@Z1~~çþÆœ¶s—ß¼ÀúÏçSp Íy aÌX‚Vy YÈÁúÉæã Ñ0‘%>àŠò\ªìUí¢cQ™sîf®¹ÿ ;°và·‚üV‡c2‚C¶N: .ì¦ \0k«KkšÁ$²V‡…’+sÐQÚ¡—0‹#ôZ©w@>tn~JÙñÂs–þ{ÇuoIøâ¸noœŠë¶µ6ë^U%ç¯ë<•ÄM ÅdÏÑf½—]£¬b]í²Z,-è-»*ú¥âr!Nœ0ç§Âñ®[À÷áþöC>’g˜õÁ°P"ôì®Ò¼Òj CO3ȹÅ~ž§í*oð>¸‰5„`㛀 {iË®þ®—m˜$€q4#ÙdÀo@Iç¬F A ðÿJz„+ÚÄ",[Ï!x81P•äxð¯æ5“dW¨—¿‹g3ˆµàŽÌ8¥'Ó¼­ÀK9Ѓº³s¸ý1{ §”v†Œ»eQþ1èÕÑ Ê7þ¥²¢oœ#}³Ê©ÿÓqU¼@Á@æ¸búØGò ð½ÐãA@þË%6ؘ´©=ñ’ê¡ü]¯mø0¨VÌѰ¸ä˜ BC•€·OYMàåÙ+í$7/h·fÅ?õy2ÚEzÂu¯ ÐÒH5èl¤ú‡‘¾£‡—5¡Ha®n‰wp©h“rs!äaY“λ]®ßBj„c¨9—°Zðë¯<áŠZQ“áÊ`>½¬«n=Ýu¾ºèj¿'3@9ô3†\6?Ú`}ÿ.7ççO;‡™ïUÍ´(:ª-£`’ìZ8m4éÂÌÑj:žerNÀaÈþÜHùhfD´ùà«øºµõ9·µv™€âÉêÁ× ñHVž-uUß×Ðw D/×|iÃÞ.¼[ÞÉ^üß¡ÏC<'¿kpø×îHà± À=hýÖéXµÉŠΰ–4Ò D^Í;l¦3¶}oYŒÇÖ*_É¿cDÜ2ÿF¢ Á¹×åm®kà"Z¬…ñê玵r`E˜ éóFU=ˆ[•νBæÍ‹áÊÚí3à ‡-ð#G—ç KòH¬Ê¸ë©‘K`=õ_aE6â°tRŒùeH@ïôûÎqïˆç24ÿ¸ìVØlÍE 9®L÷ù<žÆÙ2ɧ|´öìè¬þaŽ'ßÝ Ï6€H5Úæ²Ì&!ø\§“ ©ÄG·ÑèŽ}1ص¼°vñ4âd‹”c¬rÖkÛ2õ¢9%{CÍß싊‹–)[XH•4§V¥Â>`•:„ øo¼œ }¼?¨Ý£?"Ã!4«† 1ÅÆÜJ>Ø|è¥rÆÓaŠ”ðÎUVz¼ßhVLj¥Äë-ÕÞ­·9‰v;÷˪£ç®¸B%gˆÂš_«M(L›~ô_KsžÑÇ;þ`É À­ ½nLðPëo,Áåùqï°sÑ:'ÝaçH‚¸0­¸ÀêÖóHÚ¯ˆÑ3_ÑHiçõwv,»ãÞ>B›ßÜŠ3\^¿¦^®¿©ðî¢&ñ†‡©¼…OAîêRÎdúÈ®ù̾apÂ׺¿÷Ò<Ë#6¸êiþ"k¼—y˜½;l(ºyÄ.'€èÁØS•>ˆÞˆ¾ø±£~ó¼)è|mÆ"™Ù6˜«ËW¸ýë¶¡ÂÔPCÆàn­¸ÐVè*V <˜õykh“+TN)©¨Âp°-r·ØŸùzÿúkðÄ©‘Íæáä³¹ÿÂ$†¤jóøji#øÄ'†ð/çìLv'Jƒ–â%¥èœtIà–é\BòWçØć-H€ce˜e;”NÀK,Í0™’hU¹RÚL¦¦Ãˆ_³=!ËÃ’°š×ÚIÒE<Š8•9!¤ê™5knX¦ÇÑ$Œ§ ÞUœÝºÈ@ÌlÇKÖ}àX(rK¶ç·ŒE!ùùì¦ÒsHUŽ¡ySðNj㳠/Hè £æ &wÊÉ jD"3n÷g¬Ìhf 5Àdàô|QxDh$cóÓИ¡LÓ*FǺ$ÖLྈ›6*½^ÜÃáá“å€fó˜‘p Ï‚³…‰Þå_¼í ‚ÁÙë‹w~70Ÿ÷Ͼïu‚W?š»ÁáÙùýÞ›·ÁÛ³ã£nÒ|=¥(²³>jyk©\Ãß:§?ÝÎ!œ,8ë½#{™öLýÎéE¯;h½ÓÃãË£Þé›f`ÚNÏ. ‘ãÞI8kb×ÅšÁÙëà¤Û?4rìEçUï¸wñ#vùºwq ݽ>ëÂÄy§Ñ;¼<îôƒóËþùÙ ÀüŽzƒÃãNï¤{Ô2c0ýÝï»§ÁàmçøØŸ.´söî´Û‡9è鯺f¤WFŽ6ÝálzýîáLËýuhÑ òÕ׃óîaÏü .;fRþMnvÐý÷KSÎüuN:oÌëëWT´—ýî ŒÝ,ÉàòÕà¢wqyÑ Þœá²ºýï{FÌÝ ŽÏ¸p— "ƒj§sÑÁîÁu®waJ˜¿_]z¸„½Ó‹n¿y¨Ó ³çïÌ ™‘vLí#\ë³S˜3îYÿGhÖw£¼{Û5ßû°¼¸jXŽY½Ã ]Ìti'ææœvß÷ÞtO»Pà z×tfóz(ÐÃÎ͉0Ý^âÜaÓÌØp»^ûǹ‰»ô^£ï{0~.oÎàÇÇ—ïð-¯¾ÍÀ»4÷hžµƒ;¸Þ­yøðÝÍ4Œ' § êA?|hl™×'†üʆ ~cØóI|Õº=€EžyxrfúìC-5î-ÙTù*š”ñÙª0Å…`Y÷1NK*~ O¤J¨ŸÜÇ}=  ;(M±ÿ#¼ E_U³²v¥ kúçéivè€ÿy…\JJ4ª«Ê_¹šÃÎλ§Ã È•´ëWU!Ntñ|ÕV—1ü_‘52Ë .‹ÊÞ¼ýþý6H㮿ëOÑãSY¤éľ·*·7Bšç3E…ûll?ßFôð¢Ç- Á%y°XáŸÙpƒaõ Öšq $›â]LÚ¿E‚Rƒiüœ³¶lÅikË9£wç¦Ö@*Á–`Ï+Ñ‘1Š>ߨ$ ä?A>ÆÚóÚ^¹-çZ­¢¡}¿N>þÅÕVðcºç!ƘÍJ1š8Ÿ\nuÓ‰@ºÆ çL(„ЂÝ:KI9wN&€æ¯!kt¤'=ã÷ïÍ”ËgÅ@Ìr¯ÍüUÒ(î2ÜÝõÈ ¤Å΂HÁ†/>^óVZÛtd-Ú*¹ÅêB»kÂÊŽñl¨§³™¨óÌAú2§E…Ú¡98Ä ½z™7\ »F )~åE[uŽ™ ºçC'²ÕG ó§Ü¡”(?õ =s„‚xÊ›‘e`×yëÓ¶*ïu­—h™dK4é]/'­-8Ðz hkÃF÷þ²ê=†)~:{vZþKÿÂËÀ¶Éu•@¯¿²Äe&+ŠaHQÓtwMcÉ„êÇŠÖºŒ¾sbŸÑýø§ü;)}0Š~ûý‹mŠÏw7¼‰¦*‰Ú Eó7…„€j4øv¢ í«ý~L—ähñ.ª:ÌSÍÓÎá1-Õ ¤4 Z‚ÐÁÝ6<œ㥠>ÏÌSu•~Ä]ÐxYxIDjW-ÑŸr••CCrãi À`FŒ ™ßY»â‡ÀmCEã[Û¸·k ã§œI¤t1„Øëè2 …Y´ „Ifdõ¢³%ˆ3¦)«T‚îǶíFY37è9âZG£Z£ÕÇÒ]©]¯iÊêìQ¨.V5ÕÀã6\5 ŠÎ$e2n*·"=3 Û·½”Òžü µ¬í²Áv¸_J#ÆébèF·ïÇ´j@Â?‹­C»ÝMÆÙ;³ò‡!˜FìlëðPƒ8lúÍ7rÈŽvm…V¶„d,ÎÛìE3p?N¢äÆ”€I¯]ûƒS Üð{…3¤\Ú: ÏÈÐÒö!±ìÉcÌ}òZo{9”ñh5)²¥†wÜ6L/èL\³èif9É–^JΑëÀ0ðÐhÎhG‡×f€Üà?ÅÅý×èïgúÀ­ŸÏG·æí“Í]áµ]ù–W4nøñÊ*ßuÇ4_0òì>UÉõ® é8ÝIJl™ÎºC‡Õû5;ÇÛº›?ÿdÞa¯Ê]¢üñÕÅ8‘8 ¿þú8*æøéà`­¡\pLž/R!AD,å>¥X¡RÂ¥ˆ–Ž#Îu_¯31 ‡T¼Iè–¶9o Ë„”ÌÒ’k•,Ý NCb(;%„Fê×(DÁ´|9ÒÂs6ñjÅb9÷ÅHgæ%H$sWÐÑü’mxm*nÝ^ñ˜·Ï®½ýö r€´ó” Æ#) íÊä†>2°º ~üa‘žÜ9 lÁ¶ÔËU³˜5>È+?ç4+ÆîŸ»ì:n"žêg#5ÙS‰3ùëË"»°¿â«}x¦ž‡ÏñLé3Zy@ÿþ'J­ëo?LÞ«Ï÷4}êÄÄ ¡‹¼gÜ’[}æÌªC×¼<ÔD˜{aí®D‘œß·Ñ€á\š1xÍéäÉ(ãÌU“Éüþq:á<”Ðí J¢®Œ‘jÍ?ÌÖ^I$|¨¦@£aÕΚ£©™†kŽÏBn ã¡á;ž2® YÖ(A@þ;š§A=jÝ´šÁ˯%­ _~M Už&„s{/0rî97ÿ—„nÓÏóÒC|öÑQ‘Ÿ*‰ok³À(WÕ.àúªànA˳i7îó—ÜÙ… ‡W¶MEÿã3±ïÆØâSìÂ]=~Ô;¸+ë+BŠh ^lBI7îĦÉ(Ä šÕ•Øm/fŒ°W¡òÏ#@Üÿ@)2å$·VžÕ¼*õóO–žÃç¬|MoJÎ%Ê©{Y^ö\ö7¯š s³Ãì)×QÖ‹¹‘lÍîåèdc¯œ2éƒS¬=óû·%y¦ ÂO`>"°/ßU”)ÝŠa=)þ†MÀpv Ó…é“ååò5N÷·†ø|s6êÔ4c?‰Îæ–w1MŸzTVY€‚àøüðÝà¢ož¾ñ€;D\Çœï‹ôrqýòÏJÓï‚V†Z)ú&ZøŠÒ:7ÕÆ€]?ý,ª}QÍv¼\ëê=6@^g‡…Aæ {TmªRʼn Û×!¤‘ÏP<¬Øý0§ÿö·}K€8¹b~o«wÕ>¬ Šúª\ ÆÖAšÍ"Î(__-Á² Õºó4Õºû4ñµuâ«ÛÈŽmï;´Tïe}ÓŒ…ÿ·ÄÌÚ„;ý·îZåAÑ䯀ýYuÒÖ»·«d±¾ÉEh(QU•ø–Œ!ùœõTB* ý´ùâšù[U}¡Ü(¹N/m¸+µÑ«BìÝèú‡¹Ôåƒ:MÐf•;ðÀ£Žãì.ƒ›K«‘¿šÅ£½Šàªh«û0ñc­”5 œ¢˜ƒò›Ã%£ªïߣÓ×ü=ýfHÀáκ ÎÛtys "ã¾_E.9a‰/àˆ<¼–³9¤V˜<(Ep‰ŠÍìê n¹—u®²t²$M½hr)¯û’êú÷¸@™ ¡¡Ü>³b¯HÙŒcŸ[Å}óǼRøbA¢0¶JB[=ïZ3º õ:ü hòæóv¸ "_¾1_þ{»áª½²BÙÿØn8B€?€‘ÃüÐÞ¶Ÿó‹Å¾þ¹¸a¥«7"t[ÀøR1…/8¹É=rdØjКN®”öâ¹ãѬ–ÎÉ÷­Pfø 1éª0øI¬j ¡©¿Nòcä‰2"‹‰ ^Ä=ᘮö ·3öZÖº–¬l£= M‡Â¹osç}¾Äï »hÞw¿ÝóÕŸ˜´|nÁ¾"N™N&ÍE(à.ÉÃÂá+cäæ.DŠGÒ(§gñèΕ R…•3t,Ñeÿ×ò‹¥_D<ÝHø´Ó¹^N&CÙ\ Apš|­S%uÙÖ ZÔ=i\‘c7\nëÙ³¦«W¢¶î7[Á×k)&7ær"igˆ@3œý8¯º"¹y…0ÈŒÂI8WQŒiLer ÿØ(ƒ7$Ô¯ˆôŠ|¨Ó„¹Üx;NÏ.8ˆoŒfŽëæ £t„#È8y¨bŠ‘}(¼ºvQž8â‘@éAi¬wJmJˆõIaüØ¡Ç(ã1L®3”üF8_™mÑë†<Ò±ge}ZUô8°1j…Q08?æL"CraéhèG®N_tLüµÄL »Þrç¬>…À—½ø/ÀrBʹߤãH‹Â>gÔ©¡•BAAw­¯ 5ÓZ³æ™¥Ž¨Üët2Žæõü)ðÕî?xÉ®sÍøOÓ&ÇÀº†k¥©;Mö‹D¸·kèjÈóE*R|©OSbÆFÐóë¡f^#‚k„ù"^ý4ÍSÅÌV>YÇ õvïÙt*êMî÷fœjÙ“éà°âNnþ"Å1²§k_mŽ–+ê*½c¼>†Ó;Pg•)[„MóÊWo/þå_þec© n­sÃpá±rËo-å(ìHFCàÏþR<ÈBÁ=)Þp†ã ê-¾S½k3AÈE Ö-& ,ÑSX´&Ÿ Z·(,rèÙÍGsºøV9obô©P¦rë* ܈ç+Œ>§µøŠyT—_¯oW8ETùB¼lHíR3bÆDblYÈÆäœˆM1äå*r Ì ÍN{4Ô®ÂùóçÀÄ"mH!È¿Á—Vp$Ìq~ÙèKÉäѸKÝl «îV³Üɇtò6 ´ð`ZlµHó].Ysè¶ì§'[gdºÉ Ö ÎÉäöíÔì+Æ«8Þ•¹;¶èîk½Hì¸Ý|T.dz¹AAÈÈ(ø\Ƨ€ƒ›«†³ð¯ð§Ê ¿4+|hÀ®Ì™îÀŸì£ßœ…°RÍÃï{è,ÏcÁÏ  ÌüëÙ3†! ÍjïiYõYíøiûñǘ÷ü¤Ê/Ã8i¾åp¸ãjdånè+|Ó=êaj u*dCè±0o}X^ø¿Áƒÿ<ø¿Áƒÿ<ø¿Áƒÿ<ø˜àÁvà3FAý? côâò.LüÈAJWMè}ã€?õ ØiÿÛu†.•ár¥ˆ… Â\0 !{¹ÏÓpF~—œïa>ÓQ8i\f&@±„+¢`¾Êg?÷zÝ>‡ÿ3$šÂpÌ‹0»+ûþa:4íêœ2sçSêàËèÃh1É5Œ¨ô%Kúà묪/ÌëõÕéy}Au€ .iyñ0‹*†fH óŠDå@—dÎf™‚=?Ý“€ ÛY1û%e©À— óØ`–?D•Ø>Éüa–‚_ò˜ÇèBA§¢Ü] YBRTšc<ºcÉ•µ%;,>꣑yTÍ€&Ô8'®+a…QˆäØÎg1Ò ½„‰`¨Õ0x¹õ:*—ÿüØK/z28"ˆ‘SöãðÕYÿØÐÃÃá°™]ß"røìÙ«e ªP{ƒàÆì(m¡6ÙÌÄæ=ícôÜé™xŸƒžân°Ÿ-Ñü@&‹—{¹»ó¹ýñë=/Ê­¬¾éÈPKîhU[Þˆ<5ˆ,BîØsþ·ˆ¿l-¢)Hõæ´ÃIG–èâ`ëÂp!f€Î^\H]Â&€ú=µ†ÂG@‘¢—›M^‹c¦’X·n--Z%hnw78Èyĸ&Aø¸`_I1\H!úª4¡òáS^¸(„ñ%ÂFµÂ@Êx±^جäÐ-‰Z[[ œô&ZE>$@q/ÞÄ:þ‘µU¬ž' .ܾù&¨!){^ƒ¿!ÑY<–ïðÔ-Äó!ç,5¿ÂnpÜAÝmÒË#…nNA‡TxýØÄé@¯~Ê¢É5¿M³›!œ¢!-"ÔÀ ^Šñ¿ÍÒÃù<|pE@Fp&wæjin”þm±'mHþÑ žªúî_Ø¡…Å“úûÁ_ºýÓ¡a Opåª]H@–-72$J`Ñ7Ûcz=§SÛž$RœDá]Ʃ妀æÃmÓàK,{@S3 D£¬:‡òq±EÃH<…±‡Fg£3`;p¥=×R®ø‚î_ñ8IZöò % <_bJ%«j#[._0ÈÞÀ©5Îa¸„òùAüžÊ6¹q”†Õ&¦›Göy˜å#ìÔ8øÆ®A@,f,j–ù‡Ÿ’@Žï 11uH°ztxr4I`Ø;}}èeª„©?6XéŽ=`.ëqÉ™îžý%7æ²Õ ·ÌžÈqü&#Ó³jõ9c'öh¤æ‡?ÿ1ÀÿuY£)gŠÐ7±AØk?˜ÊÙŸÿXŠ5íòà¿’ýõ¬blÖöeɲäõûXµ5‹ÍÄ-9Z;oÀ$[5Uñ\ØÆàÈŽöªûðÁLé´–Þ¢,1±Ôá ”Ÿ=àO[¥ì©dû´»× /ÞBÎÊAçu EYÉÖ`E³Ã?ÆYJ›¬ŽN4çv®'ô¢8¬óvÛýͺ|QMë˜àÕ °·ÃpæZ㯅úÓ#ÀÑö#ЇÊÍëO„_^°PpŸØ®Ž®ÃÍ«®J'ºª2CÛ)Ù„ÅœpÎF7ed,Âqß»¼”)%QæÌ3ñÇ£e¶n™~ìe‡@Oà¬êœ%í6~æõãZÿ+­J£…KäÁŸ?ñû±ïð3n~fÊ3£ô=†J¨9Ä@óP2óMEˆ jÞëW#}âRü’&é}4nÕìUF ­^zodjÏAá__Gh3V0+¤ô1+)l1‹(ÓO–óa'bÉtkQÍý3¥B1õ§²#„'è4]Xõ3XlÜ¿ì}#ˆÅºX¡ Õ–È%ÍŽ’øÄ‹åÅ»2KÀEÿ²+Mœs5S5‹:…ç2u‘õœËYKy,?,ïÂû°Ñ†æŽn¡ì`OQºŠæÏß:æ<¨úïÁq:ºËÄŸl!útFm™î1 Æv/LGˆþ2£d‹Èíà{Ã͇(S€ >çÝ.³öóçÓlœ´ÌFÍS°€Zóy”ì.³ç“øjΞ³Bñù8ÊîéìyþÛ‹?þÛþ¥f³üàž£)Q¶Éu»}„v¹M¶‡øYtù(üÌ9»óŸUr¦OöÂðÃò_50[uþ÷b \Á,ÈfƒËyÓ·Æ¥¡>z㺺º<’Ëd²~,ö(.1²a`§á.ô\a)bðr~éñdæ´ÌÌ«_Å ÂhFÊ¥ÄZÅ… nÓÉX5„wAÔ”ûˆ²é´Ê×â-èq~Øô2"©'o†[åPU5.R+8G”¦9avK{ÈÅÜÆ7·°zW!M»åíCÓª¼]Óê½ðHiq®U/ °ʼn0á€ùHž_ZäïP£}J]ËŠk ¹xbË„Šùs/›ªeHèÎzäOÃÂKz`b@òJç­Â½' jSÞ}s#@ªÍMƒ{ q"ê~žä&ª?]õ6á $±cÅFðKðÂ>‘ÃÓªFÕã…¨¹1ówÞ$DwÛPÈ¿_ÇsÊ‘Œ€Êì%ú˜Y4GS5´ EŠuÛVÕ©xæØ%ÿÐíy+ø˜ÇNÍér6¶éºV®’™Ú×ð(7—nŸ%*üP»éæØ›»½‚[s¾>†Ã|JE/ÕįÌÊßíé#óÒ;2ey•‚s(ú‚:—a;Wï–îÙ,N8z|üó§Ænµ¬hþ çþQ)µÌÒ<²<òš_k'œÊyЉ•‚ÄðƘGä_YNñDÓñÙ$Qr-ôAóZbE„f¾E´¡öéS~Çô–}ÝÎýjsKé,Û6ÀõBFø î»KpŸ· 3OÚåý‚ÞJ1¿Ll~K”ÆÐ×dÕEªš óà­Ð#Ø­šÎ'ùÉ7¢lQ¦["âuÉôËh„ ;>[^™Èÿþ*$±™~m£æ ;dIpT©Þ_&è ½ƒêSøk͉Ò"ˆÓ‡ „"Îr®¨õ“0NpH;”©]îÇºí¹Ø-Å…Z¢º'úpŸ»>L1ûâœ3€ëèÆðñX ÎŒyÆÌ_t.y)¸I›ŠIÄ[^œ--,J^®¼¤ÛÒxZ.í–”Zhèú\¹§å*¯5,ŒÛ\8–Ï%—"LѦGx+ŸCLÝÜänÞ¨»ùÔ.*{$ŸFˆÇPZ åuÍÞKÀ B×è 6Ö9è2þí_[E¿²6å-Ü ½Ä¢'.Ve˜Uÿ}ó qd€éÒ…ºlÓ’;…¬Š¿Ã¾›©>{7—µ¡¡jÃÎ`Ð{s:¬—Wlo«h®.yC„yí)v6|0ñxXO{þ¥^E(=*ýãÐÿFòSÅŠü­lIèÿC,µ ´>*Ó –iìxh¨ì”úš(ª!ÓMY„cITÙ•Ä“¤Ñ“p†$TÓ¬fÖ0A"û^¤ÊOŒ}”<Œ”×ä@$gÚŒ)MD M¢l…'‚¤”©uƒÑG𦠂…AÚ¾¸Ù2ð–I#-K:GÃsÅÖaÈØâX³ž&4ÖxÂ<@?*~ ;êÂùÈ@ïóThK#Œõ û9TÚ±…€€áÌ>&%ŠŽ–´%áT׉Q Ä!ý¦âë½B˜»-eßcËx3íUùZ}‹±cpwÀîˆßÎO¡!<™.TT«t¢6g’zžËÀ+ÔePÕ ² PWöyb‘cË™„sˆ3B:Ôƒr6òÀ™V©¢9ÏÇ(ÕW¶ßnƒ:¥¼ÙÎRÝvEï>×ý5hØÕâ~uSQ2Öf´bÝꪀk^ EÑUjÞS<ϰY8*XÚh¡:Dd¶PÇwábdÎ˧úI­¯jó©?¾ˆû…™í}x¯¼µCØDùÖè>Z¸+å‡×mŽjl¿´•܆”u^Ú}îajñîä¶d«òmòG\öÎMâäÎcÊ.ýA•¦´›ÝƒÓè[0ÛìÓs4ù9©£â±Ðv‘dS[7ë[?)6ŸÌ³D þ(2„7}ˆ~IÒy7[£à€‡|‹ß2Ë ¢Íe9Cê[8“Á8\„,€º­ô‡¹¤ÁqtÍ#»Ù#´¬7B–Þ䮤 ¿†®§¢ЇõµÄÔ<À%פHºPj¯+MQUŸ¬£“ºü³gñBk¸6&DñÂ'=ŸC~>›ÉГÈ#E|d[³ev;´úzáöyëTÚøXZ[Ï+/XÛñõ62'hj4РɇèÓô†@©8cnjhYòµÚ W„˜J>ð¦•ã?IÓÛºÀ¾y/&²+buÆ)F4§­‚:ñ“¢@ ²\€NH]@#ï{w.%õƶ·‚Ûó©dÛÏ~å­¬$h]ÃÇÖsZ¬F™k‹ýöþE£ŒKßû¶k¿ŽºI[–Èýÿuû-\â:>QißT”n¡Á'›3‰_ŒëÊößNÿJèºf¡VÑ:¿Î³gŽ:ýf"øi=GO1¿Z½Š£ô‘hCƈÿ¹¡AËI(§³LIš×B4g'Ï8Z=h¬»>Ãìéì›rÆ«Tݲ1)*œª=qÉIçˆã3©"EZ¤f¬k™#¦›5²ò•8åˆÑªwT:1¤È%²ÏAEß’Iü­õMÿ˜#ÉuAÉÇv: Ô§£¢›à[BìynÌ &È É‚áFÚIÆoYM{„Ê嶊׈ÍlļGv.ôuéà\Ô‚YDòK§G^wl㞺%€©Q:»œ!•àåŒÁ§‡oûg§½ÿè¿äb<ü÷ËnÿGtvïŸ`H×z?òÜÚThéqÉÛ¬Üÿx®ï\Äh `·Å€ÂUzGÖ”bþoøäUˆZWFéàKЕ1gg¡óWØZÅx=së¿Þ²µ‘a«Ô®•7kôf ÛÌí½ÛŠB`Êñù÷g½£ƒº3ª³íL±6”äМ‹îpp98ïžuÜ/O «U¶Á¹E+lôŠÛŠdu­jTœ¨1Ì_3ÃÌÎ3°sQŽ*lçŠüÌua{´ #rÎä†S}z‘AÌÕ-êÜ$”ïGÙr*GÁïÆ–Ñ.Û%EÄxq’&1‚€ª–´‘!ç¹+×ò¦Y´¥^¶y¯Ò¥Õ‹n–í!e&¥ÂÙªÓ ";Œ5ý„©ó´,Â[Å»NcU½²!•"åºSªÓo… Yã„ mxVE=Ké.©–}·JóCµõIÏ@ÊmI0ñ´ìEr‘å®f¤y ˆuoio<eV6 Ó~ÅGYMÍΙÖÀ£2ÃD¦ÞÇã„“#Æ‹Ó\©™£,ÂÓØ[ßþ£[voêP:SýXI[©hýýØ!ÿe–wMÝBÍl­2$”´ŽÔçËZxå*§²¦Ã*½‹o¬ËMâK«#+_ÑÑŠA²6ÁrñZ—ƒî€Ó÷»äy*8YÐï¶ÌSjA‡QÅüMD¬ŠS n(B\º­~·Ýþ[¿«°½âlˆ¼ÏPq”óèbY·Ñý)±á+æ3\(öA—^Šˆ~§àƒ/m°æ€êx¹ÈC_1Ý&WVÀñM(Ä2WüP71±™ƒ÷¦áÔ1 þݰ:˜/Ð:¹Áã‘ê ²'·˜ôàìêOQê2[…£Z‹?ÿŠ`³ê'ñBpç`ð"ó’h“Ÿ#J#IÂ^½6ƒ8B^:à ÌèC¿ ©FÜv>™G-µ¥>n)ÞËìt¸ Î÷4μ™k4ª?5M¨É7©»—Íà)Öh‚ž‹G|Ö\À ü`[Üj@OuØi¾pèWC­Ä9mÖÿÄbøçdízh¯ps{ú]b³à=áiÛ1攤Á$Ñá[O»¤ É!Ó¹æGËYÊìm¹€Á9F ââ_=,(, réòÛƒk„P¥F`ûiI\ª ŽU'cQ’̹ùƒGHz/ò@~Û Ã×€~~S?“ œ¦3ÕoF ØkÝ49ÜФáà__“/ÓÕƒÌ_Ü… Œì”;Ù(Žâ›ØÎ‚Yy’ÛfvßìÃhÍÍÿ…<ÿ¶½gÎ’®}#Rµ5z®¬(ÆÝ'ïk_ýî÷O·ëgÍÖóöÞ7ûß~÷Óû÷?ÿ¿_~ýô·ò)Üt?2;[6(¯Ñowž™Z¹½»Ñ×UÞ_¿OÞÏß/Þ(i&MýÒ©Õ!]H~m(_ˆù­Süí?¼\"å+‹µÍ¿€$ ·+OOíýûQÒCeäÊhv:ÊFá @‘ÿk ’í—³‹?òDüyø›ˆ#°KdVh|t̳ÁâÃý»Ú >ÒápÐv I'†F*¾ïˆr%¬—yÎV#þµfË%¬›Õ83o¾žP+¸Sø‘»kRzáOàüi¤ßqa‰à6K;«DJf‰æª·¼è4ýK.ºl{¼ÝvçÍ»b /¦hûÈ|²ºäµ+É'äýõ¶_$)IrEæÅ"ó\‘¬0vï>å†5(N`UñE±ÿE®ÿÅ"rEî‹Ctw5×ã»’ {®FÞðwùéSï@Àèˆ=ÿ¤cÕóE¶[Û|͟Оà-+k¨45+±ÁæáUQÞb#+¶Àb/ØwJP]F Ö(g¯±Ö<ë#9Øy‚JCÛ—O!|0jƒ{ ¹9ãŸ[~ä>ÈÈÝ•1øš¹`¶¢äaÄ8I'g·¦#Ù½ù¢>–h糨ó*;ƒ•ñ™fìA3yz¢aLNü®x¨Ÿ97R‰~$&# šh1uP¢í´!ª51ÂFæfv %S%_{Á8›k¸e]aÆ$Ô9:¾îôŽ/Q³Ë+Ø5ßV¹;-1=—d×KxH›ÁŽUòò*|Û v8ëÊ„¦Ì¨Z,Œ]oI{ðÕp±ððclÀ¾ë}ð€b(,-ÁOñÏ{Aü왑ˆr¼ßvØù'R\%C¼¬¾ÃY/]Њ»%÷ ÿ·*£Žj0>Ñ'+9¡ -Ë_¶D³Ô¨Ÿø½L¢ñ÷½èßrËj.õû÷îZÃRÒÍÖR''7)™)œIHã}8wÅÅ´<÷“Ï8…o‰;5zíø•ùO$Ò±FuüœU[¹ßÿ©üÝü G·ÀÛh•8êØ þw8xžæÈç øâsù]å\r‡wƒYxLy½ñÓÏ¿|úµÖø» O'pÝðb7-#ýè‘[AÙƒ'¹“ûšƒÝ ¦±a .Ï"½‹’Ín_åõ{âËr¿#ÁKÅ;†AZw@¢a¥#QÙ#OO&§üI¢LHöUQÁ¶YÍXX0Û"GÌìB•›äýHåD x9BúŸ>!]s0­—AG‡Ñuãà÷œ°¥óHCß+x¡ü#nS㺴|rÎÞ½½Š·]9GÁ†õ»dî+¸?màÍSYHÛTÿ§ý~¬ËŠsvÉqr¶Ä³G.›úÏìÈó¨Ù•Oìïï‘ã­ª‚;u—ôI!cæjoÉ1­ü|­¹r|½d™ß©cÊ _ñEœÁý{„õ· y=~«Ç3/–xíý]ÜÚ6Ïg‚ä æÕIˆX5cô¯ßm#ÇÀ!E iÚ”HHËz*]-í'ãdW¾ëS ôªÃdŸ`²ÛpªŸ§°O…Ý¡"†~áÇ=fï@è‚M¿EdsXä5¥[[9ìYpü_)x´ÍÌ’Ñì¡ÉüÞ¤uº¹13 ƒûpŽ'ì3£ÏR"(F˜ùþÐŒé_[/Z”/Õ´R§¡6åý13ÇIó"=Û‡/v®x8ç91}ðeWT£¿+›ÿïÖÍßì¥Ìþw4û»EÄå—yÕæe•Vúî2 ?Ì8?ý ij—ô­Dà0C ~ÍiCʦ,H˜Ü<ij·äp…¾ÇˆhRÌrÊJÉ$†B"7ä$Ë)¸#†?‰,J4•Îyo€ö(o`„³QË£L0X²-Â0ýœC®(5 )Ì dy‡o½ ÚX®áö&^ÌŠb3£Öfœý¯âkˆ€³¹§ÊK×kæÿ0èå.R¶CÒØM´'yÀËû[Ó5PL†õ)·Ù¾èlÓ.è ®€CÏ'Çœ@Š“Ì‚Çñ ëþ¬ ™~’";°õ›[¸D”Ú$ú¸à\kÅM…”Îކ±Õ‹ûÔ¹%á œ¨MíòÀ{nÜÞy!—=HN)s”NÒd‹"ÙH(òŒ¦ ÎaeM# €TÙ1l¬=µëVÐZþCNséY†SÌÇî3¦7Ñï8½i·å¯ºü1ˆ>Ds–ñÍUÓf);¬Ë_zA´óã4œß‘M¬ôfV†N_Ÿ™õd?þëçšÓÜÊ¿ëôO!‡ç·¦<ÿ½²|·ß?ûÿ±÷® mÉÂð~=úÅk$,„6NÀ° Âæ„Û"ì$kûÕÒZK3ŠFⲉ÷·¿uëÛ\„ÀØIöàÝ ™žîêêîêêêêêª#ªàó æÇ·íÆqcÞÈw7@–Äi*F_¥d×ô/©súá~£>ÓAʱ8T¬¤Àíþ$VB7¯%dÏP¡“Õ˜¾ÜB¶‚{Ï‘ì#$öHÕÝÿèáq¹­Ò‰ÔHš£št|»SÄ] Á ¢<²€Ø8g‚¬ %1i쩸Èm`ïÍsWÖý˜8›FvïÆ#foj%ò=Zñº“!ýYª˜+Ãå‚ñbør·IUˆÖÝ7­×íÒÓï¿_)ñÍ[ÇGÍÆ¬Éiwç`ŸFä@.´³ï´áXLLT4? ˆ)‹Ò'ÊëÛ&èr‡§œ½‘gw¼»YHG+ s“w<Œy(¢uò€, €é¹ÀKB¬ŒŒ¤ÛÆð[È ãnÓ £0‡ñ[/+ö+ñ7”D°Ö6 „²Îù»½ÆOù’×½_YëýI¼»ìîì'Ê/š½pÁÜ9…Òç½QRñálTP›ï¼¯Y<ù @R[~å"ÁáܶØpaÝεc‘b‰¶i Š·+Zã@2Êf ¬þ2‘EŒ¢JÞ šÛ½Y—EU·—‚ë|ZŽ€Ùwo¢/\Ö9‚€ÝSv'#•YDýL J.Z¯ÝjïàÕ1ï7züño¤f kÄñÎÅâ%±œÍ¯j†ÆjMGçÄnÇQòû·fQuÃ¥éÓf>ŸÂây)Ö¬»š–7F픋ævD±áH(½Ï§¹ÉþÇÔÅñ`hŠ´ç|ö6;,Ü[Q.< FßHñ5|ÄÌãnÇ‘sÌFØEjŸLòQý§nÅÉg­ý¤c=\…ÎðRYÑìÑÁΖٽƒU ĵ¾˜«Ë}9Ë&;zFé N£C‚9­çßÄ{yWctã†w0V.:í€mÉ–êT¢¸½´¶ ¹ `Æ/N…²ÑayKÄà#öÛ°äT\N³cç;qãüHð– jyÔ@YÐ^S*( ))â’Zó? YʨÑ…‰ÿÜv@‹g6³ÑC÷,[‡ ®0¦;˨âF‘Ñ´õÎz2\ÆB¹ELµXÚìB·›­îæÐh!VÊÚ~0b·¾$IûW%ëo£WtßT¼â¨èfvÉ l€‚‘Êšt®°­bl»{‰íM$k>¨› #Ãw¾L·½¦N´8--­JW·é¢FIQ(qgÛó& úZ×â% ºWfr«îRŸ¸SŸ¶‹98l—`#®ÜâóÞ™Í M¥ìŸ©@DAʹ@A9—Š¥óäºý »:šZœíIêœ>µ9ìw)õÕ²‘Ú§ÜO»¯Ú%Ù¥¢yÀëg­Š¦˜Q*úÑZ\Qølöz ¥•©ŽÂCÂ,¹œƒ¸Ê'é·hhwMk§ßì›  ƒa)3•B>wÁºR=–`ày )3KóÉ" \̺ªé%K`¯$Ó ù¤çì§lšb JR¦ u©é#|;˜z%Œ€ãpñbÅ{œ¢åò´:\SuBZnÍÑÈ®²¦ëd¥H6 ÈôºûÀ[="=›¦‹©}ÂùÃgàczkV|tÿ¤ŽFòÔ0ví¸£‡MÕùm†£½wð–,ƒOñý{äãïß³ª>[ïas%µ÷5+4©^”ŠÇͽâ>Î4ùŒmƒJ{W3wFì¥ËFÆ3†ãº˜Sª÷2Q©Û+ŽÍ›dÉÒ[ýez‚µ§;!)Æ)L•t™>á`iÑ=¸È†OvPrœ:-x+±PA+;[9ÄAðQô£ h·šÍÚÍý-Ûz"Ë^÷t ;˜¢lBIÈÉ*]‡¨ÀgsO-{Øêk}ÆgœD¨ââ‚Òqr»ï“ÚˆæÕX$ùå >lVž içŠG(§ìW- Å ÄÅ$ØOžú£BNo¶šÇÚ0æ‡ r!µ,‘xÃñ-Lwö$8q é‘ãÚƒuºž±æ¹ºæ­fãøu_µÇ‹)N˜q_(¬®’9Ø (¤6Pfë…ÿ"åJ›¶þèì"é2×»!V5“ãÁ%YÎñ2Ø Æ;u „Yº-f„‰Û²!ŽóÙNå2³b'ç4Ö“ ŸÔ1ú¬H>ÆYžlç (Ûr§2ëÍEú“³&Jˆlæºg“Ä´uÍÄò£Å ¡q“ƒÂm+8™œ½D÷ç|s¬ìKYùS2~U ìÚê„["ˆW2 £wŒ³ÎY³­öQAxÑE!š»yþ¨Gš8òFŠ…»—XìÍÙsÆ”«zxŠ‚¸ÆroÒŽ#X‰ßú£Rñ4ŠŠev"˽Œ…‹r\upPTlÈ b+!þaªjÒ9gÀ6tç¸>äží¢AfÐ3Ͻ!-èì6^µšÛ;?µ1• º÷š¡´ÄÞjC/­å]ùfÝT[eO€`_}XÕqôf8 F%SB¶éx!!yY]Êeݸ>ôGh©:eçØüÉ[^ZÀcáU¢›ŸhÒ»sj^VXA{Z2ÚÅ›”È=јҺ•ÝÇбäD°c'—<Ýô%o±Þ#”‹Œâ«ø×öc€œMÂŽÒÎ>½æQî­vs?cˆ¤ ¶J7È5ÝHaú1·3èUQºk­GŸ6J†ôn¦‹uo÷`ÿU{¯ñî)²¾ììÿ1¢“wŒ€Óö£Ë˜ÉAÀÌ,i’©c è ajë*´Õe/D­…Z5FÐÔF /ƒäÌXI¿)Õ¦¢Î?­9”¦ÎVL|Q›Wì»×Ú±µ¹²„ÆtÉûK`‚zc¦%W1e³ä®!-ÒýºŒ+º„;n‹£YsÑB¦ELÔÁr±ï•y¶†U¬…E#ŠÛ£h@v)¸¯N.¶¾ßäT¨¶ûrÑ£Ä ë«æqûåÁÁn{ûè`vŒoÉ™ºr²”¸¼³™¥’´, VÝuW” Å~-ÓŠ êÕÀÕ6¨ÅØ&"½¶Ë){27,µ|]%wdƒaÉ.SÁÑ Çdµ|jJNN'ônÕ"0¾g8E¬K˜Üœ¢Ød‘ªÎŸµ‘»¾”œ¾9ôÈL—þÞ@\œsFê‚5xyéòJä¹ }eTó»˜\nMQW"”C&wéi¦áÜEsúAó¸Ä™ÊD÷,aÎõ;Ô̪ŸX¶4*ËBǹn}ïQ1òcŠªÂ ¸ þ+ï:ÈöÈ.Zîˆßm%Èî-}¿„׃i €¡•/ËÿmÂäfÞ0íì”'_ëøüf_2Ó]¦_VEŸ7ÿn7å8w¶‚Á¥<Ñ$ãô©r ¡b©ÏññÒœô¸Ñ"¼9>|s,”ÐÐ^RP´Tþ§½]É×FU©y  2i1¿xéÿ;èƒÕëËÕ¶ˆ"ä&a±wBu$j»Á–+ÛWƒþjѺämcm{‡ÅJÂ`lbb° :_Ŧ]¸˜·9 ·I,¦–ž·°Àvr׉œ;dgeU>§Ë²¦‘ʘlå´¼s9ÎN‹K3V‘+²—VEÙtTLÔ]LFMÒRæÑ÷; hS\òøÑ§T˜oO)×RDýV û®áõˆ|²/ÕjÏ+Þ+òˆ‹@G®)ô=úŒúcº“¥oò]tjß¡]¹+@û¼¸É*L9é…tHÐŽnäE ‘sɨ«©VÈ2mˆ:±1n€d.zè¤V;Ö`/4¢ûíö´9A Æ«‚]J Hž‡32à¢k¶Ð—¾ˆMþID¶PÒö¢Üø†âŸ%&k/»fq¤aЂ;}¿7@…C."P¡Õ/ ¹)ap!W4zx>¹XDaÉ¢ÎÄ8p†B‹0l5ð\z•Ew¼ö™B¶’¦ VãöƒžÄ£6šE‹ˆðjµþFcÐÇܲÁa8tGm…¾†RÑÔQà-î1.v#X¶çh½~‰Ä£8˜86í0C"MÞ£&ÚbÿDj›ôz§åµ¶aÛôàùðèàíÎVsË{ù3|lzhr´óêõ±÷ú`w«yÔòû[º ÓË7ÇG-Òn6ZP¸Hßû?£ ç£f«åyèyàAGýãf #Álî¾Ù‚…­â ¼Pƒ@vwövŽ!çñA…ªN—ô¶½½æÑækxm¼ÜÙÝ9þ™ªÜÞ9ÞÇê¶ŽhÖz‡£ãÍ7»#ïðÍÑáA«éaû¶vZ›»½æVp€z½æÛæþ±×zÝ€}ŠÓ\²°ÿq¿y„m°›ë½l¦hú‚ÕQkù@›ež6¡÷ñn67wðBDó§&4ªqôsEÀ¶šùà£·ÕØk¼‚6–nî¤Í7GÍ=ĺ¤õæeëxçøÍqÓ{up°EÝÞj½ÝÙl¶Ö¼ÝƒuÜ †÷Ç ª @ÇAx~ù¦µC]ò~óèèÍ!žo—aÌ„LPz‹úú`ÛÌ´Ó<8úAcÐhT¼_7!ý»—z­ÝRÌæ± ª„Τ†™özûÍW»;¯šû›MÌp€€~Üi5Ë0x;-̰C•E@µo¨í8h€ ×¶KÎ]ogÛkl½ÝAü%?ÐCkGȇºoóµô¾š ̣Ѫç:ÉôJÿ8÷ÃkT–þè‡evøÉs¥KoäIÁ{¡Ç¼ÐxÛʰX+'ðÒ™U›Ûö>Úßã9O¼T’äO¼…®x„œ ÝçLDËwMqó¼cÃþéàeu5ã˜éªâa¿8ÞX]¥ç’l?"1IÒp†¸CWfYŒ‡í:Õ§ˆ˜¤†€ljÙb”P”kBt,žCÑ •/¬Ø®Íä”ýÂ^#Œ%‰˵Ó2VèÓâvØÐí(B±„e’~™+¬^¼(Éi›4å±ñ¡àã²øG£.¢†G%ó¹â¹eçËjå°ÄŽ‚–Öc,WÅ£1ººoçV€ìEnRçåq;EªÜ°µì6: ,Rr HRV"¼LHÌtÂs‡<: ¥g$ê“zi%o¸x¤ôµÄcf~ÍöþA»ÕØß9ÞùG³½×܃Ùßžš§±µ…ËÀôLé°`Fä%`ÔbwB¾æ¤iʱïfÓ65 ¢Ìèî÷Í÷`$7'h¢xr>,†®Æïž‘rqÚ¡—xE³Î¹Ž±ª}4Fwek–§³oÖm'žÈÁFg~HŽìùƒW FÑdHâÃaøñ5i°q %%{7šÀÞ¡j¹ -ýËû«·$¢»î•ù(Ɖ<çi—ÕÚRÇþ¼0gûãAlí–ôx»]â3+}êjŒ¶­-ý„^ºÔ¸¼û×ÙPÌh{ç9ÌfB‰Ìæe]¤ ]‚‰ ©  “YÉ… àrI‘òð}M!ZÄÂΣKjÅ–’]"ÉI³ÙªˆÈzDåyQ\Kù…øˆñ±brõ°îÕ——Rž?nžOÂ-¶ Zy*öÁ;§våÊìå„Ï -À¸Ãžƒ½ ]ªÁ»LƒžÚ~cœ“.n  uÀe‰Ÿ““´[µ¼B‰¼M¶A!B]\-8Φ˫:60ó|€£¾,Ë fÖåó)»lF¥ë,ôÕ¤™Â-¬‘®UÌ4OûÏš†i¤¤G·ˆÑl¼¢žyõuc 3yK<â'˜»žjšCŒ(D%‡–Ví]°‡]Z-.Í/­ÝeTÚ í4Õ†F‹Ŭ´½º(Ib ׊ÚÎ|ñN’;Ëìr…—,ÁÀYtXcÓe¸¸I#[* f2hƒ |;%-¡0™NHQ L³„×EãëHW³Ï—Lè»UÊ_ªïÔ¢$œ P»÷/´Ð2e?ÜdWcO "×t}š‹ÚA¬ó—±¦ÙâU´¦È‚bn4+?•<ÑÒœ…Ôã32—Ü©ÌÝ`&³ÆiÊ|î$gnz"ši˜)UÌšŒÅT¹DfP‘äÌâM»±„ÍÄ06ÿƒNCu[š,–á»]7ßNt;¢l#nݰò ØÑáµùÞ>;-Á`¤Ð#÷°Ðt ÚR›Ã8éÆ&¡,ÃLòkÎ÷ý%P¦xßeyÚ\)Åký£.é4“1L¼ì•!Üjñ¼·•ÓÈÖøÞ»›ÐQÓ–Jôn„{ÚŠˆ¢"u(YCôäË/WP'ÒÉßH!—íÖN¿¤ÄÀTÝ€}:‚‡^œæŠÖq¼E‹k={%˜¡žLö|—½väù½.ﯻhkCHB¶Œ25oŽi&’0y'ƒyÄPhÖЩ᧔PöQXÅøˆ#RõRܤ²ÞÂ[ú'ãSožKÅä:µð2#ãƒî£ÅɆ½b)ÏÚ<è&ùgxœ ÿ·Äü ƒàJ3ü>ŽäµnŽŒ1*Èÿß~;§|9sOán•Á¼«W¼ï?¨v©[·Ö#Š­Xw%Þïm/æ[‘òÕ^M*#TT@F¦>¹ÛJiïéËEø]é».„s"¡ôv7Î4Jq0Í¿œ¾üÌå›wf׃Œó%ö{Ö6)qŒØ(&ƘŸ] ë“Øf¬» ÎJlu—ùjÕm­Âæ2‹½d´Q/ —™Í³ÂTŽFþ5ñA'& ©D ê#9F~©â+ðˆ åâ™ ·Þè0\q“ê9®S…zì®OÙ1V4¬À­#C¸1iéL»³ˆÓ™ý7» Úol7“}+„7¾îƒÈîú«µ\-â†9#ŠóªkŒÏÞ¬Ó‚”}ãÇ¿ã–ô%–Eí?/ (iãë¸.àÅXvEö’9k^³‚Ø©htísŠÌìSÇç&èñy›Åˆ-&db²‘è ½ðb…ï(ßë˜"Q1°´ø' ÿ9¹áWUÀ<#°ôèØ˜jµ:Ç –ur=;“ø”×ph¶Bµ2íüŨßWÊ›.bÀ!.bñ*[õèn™Ç‘ØíÅþà¤w6J¬&Eß"[h&º]‡UIõ|žè8Ñlv—ƒ$?¦¡Np3Öú•©C5kSsFpV >'®ð´%59dêvÑÿ3B›£ñ›ËginðÇœ›î5qN슻OOåÐP‹'NȽÛQľ†ð➦œé8ž¾Å…ŸVˆË-W¬ÑÐú]: A%/ElѲ-ÁQpŠ2 Ÿš«sÙQ$Ò°‹j£-'¸RÌHKF›#,žP¸1#BÛG¾»âUNŹW–Aꊖ1«ZªÕõdbÚ?u"ôd&K•á‘2ÖÁIÂ1:_UpïFÏ2.Vj4bÐÍíGõ«ÖÌqýÃW¼¹ˆÿxŸdŒ/e‚˜®–hT‰*3r³¯Rà Œ±c:@â']G¾²ÑK®„7vQJ²÷Jaä„„åéìãVlCóŒBÆÄãIg/m³Ìµ¼É›jeN>—ûÝÔÿ%cÄ·M³92[!ÃúDn}f`A¹ÉûŠD0­¸–³ÀóôȺ‰Ž^p=XõüF)æû ìoNP,®åOdêyr—SꜽÖÛMã]üÕá,¸#¶idcà}FlÇ5’åÀGËýZ©êm)ó± êG~WÜ‹;ãHŒì£b: `òìC’'2³ MŒlÁžô-¢é^›Uå&ÀQ’l¸,‘;9d[Áão^QM4#ãvg„mlûÛBL†Þu¹ÀŠûQ¸pê|¬ß‡ÅT˶Ã+rOƒâueŒllYåÇâ¼›ƒ4>««  tóؤvu8‰ÏÛ'@'Ò«é8¡çA‘nyÿÍÇ7¥Ú‰âîɬ:YŠ/c§““k9b8jS®N‰(!¿lðU)åâ}¸#^¹¹¿vË|?% rI!uÊi’ž˜Y1™ Ysꃨt·I AàL™“-v”Åh³:Îî&n¥Õ!]ÉAÆTz…PÊ6€~íÇûÁ¥M㯃>ÌõÕÕ¼/%¥ìÜÛapÙ&‚o Á·KtÊWV–ÞÊù~ö €¼]JpñRya#ß,Í8pZxžâýpÛ®S:.=ÒõNj&¤ºÉó¸Ò9¹³L¾'OL‡qWp­„… bÆöÅ0…ªÚ«¤îš)ÛIi›ÊC„»Xt0’¾–q¯ŽY=¾nÐ5]_ÈŠ–E(Œ%I½¨³Å²h$bFã“R<|f?ÏÖËv'‰Íêåõ<Šû9š ¢g)­Hþk"Ô(kF3¦ÃF‡ÐJ~qì3žV¶oЊ¶-j!œ„®?bœMÏ`ܽ¼n*ÉõH:=¤·í‹Ô‡üˆN®òÙîŽÍöÎ{燽óÃÞùaï<ËÞ™óZçå{Qçcöy9~)§œ*çp1\±²&ÎĽj§C%b¾­KçÕ“,£tµqŒA¿ë¡B¼9Šá)Б²ñäZÎÂùÀ—Î Š÷]-hÔÈAHÆ“‘Úß BõÜÓ™:ÇË;Ñ%¬]xzÎþ3ðì o7œ’csã¯H`X±   Ëî“]ípÒ×—v)À6•ðæM'<8þ}X¹Vûaå~X¹?×ñ/-Ž è±P/Ú§2ñá²N˹°åµ'×0FµÅ#_(Š9mŸ²ý¬ ±ëAö±òõn.dÑ0Ï F‚ñe„¥AŠ˪×ÕµMeØ4_‚· òIŸb»›¸µ>åªä3þdC Û•Þ·¢ÿJ¹1]ÅÔv þ ÉJ ­·àqÕ«YºÈ9|2jÁܘ Þ¸¨ÒdXZ ÇF)ˆ@_Ø:™X4€~ìBT,>°“G}ïѪx&”•Ã(_èÍM}±þ†*AÍVk™&Å cKŠ×¦¸ í6>ÁÓSWmÉ'¿;ò Åxwä±’/<Ž,ø-Ð/)”\ÄËv»ÆùCWRÑ(~?m³®»nF¨û¼à\8 Q QN £E»Yb†©MŸºñ‹Yzç¦½Ž M»†]ø!ƒ'¥0é°F¸å•¦Hy¥a†­q«TqñØ‚²ñi/è¾¼Þ7YÓ‰îZà­MŠOÛøÊ³ñ!÷):ùQ1oðjU½™®w‚w·o[¯UÃFN d1´ÄàЧP–_‚ŒÇ" ‚]à™‘Ö¾ #k¯¹)TQAùWQd’ƒÛ(‘`ôóv­WûíR6{DÃ6Ýe½kì†Ð )šõÙ%ôÂ騇ö×°²]k7ŽÉðÃâKS…Æš)$§‰@E<Þ°¯îéœKÉœãËž›õ&ÞËSÙ¢4È H¥æ–}U Í Kyr»ÝR‹ýgv?¯®Î2ˆˆm]¾pãvBÁ¯î@†xïH0è³Ø8„%ca¦‹sA `¬#íNKœ«$ËÙ¿1?›°b›y9Ì™P¢‰ 5 ݵä4-`?ð31LÀÔn–jÞ a%„#üHYðOxÌõbÜf²ÃÍ¥ZOÚIJüd,îÞ„|*eùLNQ#›õv(6.1Ô»$Ý™[Dg®A«­æe@ä€RÛ†kUf±NÒSŽK&“hô1ë § —ó®ö¦‰^ÍãMÀ‰œo8³–Ô!´ØÅ† ¸Kc¬àp§m÷¢×ïb>ÍÎûPÌ!¬hÒ£elÖÚi¾Ü\ù^4¥î2¦[ÔêÌîj¯÷•¥¿®WõE핪™Â»zºº¡jÕº”ÜnÛX[Jap™'ûSy,«íçoÆ8¸òÉÝñMƒÓä|Ó(CFç!€ØƒñAø G|Ð#>èÿ¨zDåV†¸“a-"²„ÓIŸ`iM#äjÉyž§Ñ¹à5­ñ„#Èé¶g†)(Š.±Pø ¼­E]Ð…Ø5{ØÃðŒ´¹Õtu˜q±>#äUnŠMtK~-C®á¢¥)›’ÈíQ©…8ú¤%Ћ)]Œ¡QÏK›~ç%Þ`2À¾QŽLNÇØw…ø ÿþðÿÌÿö¾ûD®IV!g=èADtf 2 Ž”‡¢¸E/ýQ}i™¶ÄO£¨}âÚœ¨\ߎÆÌáñ³Ÿ=üìH8‚ŸôÂŽî4é<Ž~ÄV9ƽn›MÙʘ «pÎ ï6·é‰=¾i›NÎ> ¬5o~ˆ¶b”×)=_>ybûÂýQù»ë/ê ê€)ñŒ Èpv ë솤T¥Ï&0„0úÜ'ta›ï'âtIŒ½v‡Eìý”.aáÀv;1)ºJóCt›¤wS¥ovâFxî—tSÊì“´j˜=•Ÿýc&ós*æ_3†‘Duc›`&|¬®˜‰^Á½uë=Y·z™ÄãHã™I× ÞM…5ú|ó,vX”ÜT‹qHìØ‡*ƒú©Ëìtà/÷Ø• O†LŠ©¸7èõ,Nýø…)hóy NµÔµz”ˆíêI ò50Ì2! j´ÐRgœ„)rÇO]4lj9GŽ"óJÁ’ü’ãMät•iÆàÓ·êÊX“í4Ûðн1ÚÌÊ%Iò“ŽþFùõßÒp§ßÀ^¡À~Úe2p§Æ¥“sZ*íцž0ót´zËÛi™™iãOEÐÉØ9¨séG'æú¸§®R¢oGtñÐ!þÌ5óIIJGK_s;5A¢¼p8p%ÍãeÖÄÇ’öPz±¶hâ,áŸ\ÛssÖé\†gíùp2Áº¥.›j ½X¹±Ä[³ ±°÷Krë,ÜÕïvñ?Ú-fñuØ9Eaïß¼"g»ävqF%§ä¯^œ ÁçÈ[5Ÿgˆ» 'Wgò»“§Iª¦u¡T+äŽjÉö‘aœ:Pcb5ÀßhÓu\«€‘¡c’^gÒG.¯†g7:+•õ #Qì“·½v tl¶÷@Øþ©]:k÷£³ö`2¦[ò¡Ÿ0d1nfY£æŒ4Ù1ð$Š¿ŠnG"Ôn^Bèha¬ŸÚûͽ8®žE¬´º;ñ[S‚—–‚®ª1ªÁW{›?´·w¯J“ýï„§Ñ[JÐÙiDýKÿ:F§‹—r²E÷´x­÷ xÕÖî««–¦8¯ê&ÚŽO©ûœ£ÊfUË^]ìzõ틤:y'UšÜÊ (Òf½H@‹äË—@b+t!ûlôkYôJ=ÚŽS<Ž×UvPÑcŒü‘KåDÎd¢°üÓ*òú™SpæÔÑgȾìò™fsÉÅö³ÏZoãö8jÇ{C€‡PjËMnœô¢.ŠóÊOÌ8RÍYàøë ½hˆ*Ö.E¾&¦O~óŠ’S-l×Я+ÆfÓî”?†@:Tàé$ì×âóSåî‡OÅtghß?¸„ZÈå‹>u¦É8û³fQöªŸ¹ØggEñ!«ùfz~ãLe=}ÝÈÌk›¶‰&L˘TB^h&±+#\béAÚeÁ®ï‚$é=äX»ÈÀû¥Ç &FЋNâãZ 1Â"‰8ZëzpÒóùã""óÅ80ívÄÒ€Á üΣ,‹dœ13¬y¯}ñÇ@õÏ>îýäqàd=¡ÌEŽ ÙÇ‘òG ¯ôe» ‘g×í¡pµ¨n9²çûåbž:_ŪdNrp Õ˜Õ¹¡vµ­#ºÔZ"×­’ô®ö7Táœc´b¡¦‘q>Hyu—'góáη½S¼|¸¿Õ|ùæ•f{öT„é¤"Ʋƒ_cÁ€s„ …‘Ì~ªÅÞuY‡Vªj TPøVÇæúº'g¦>ÚBDè7X6†(oahf˜²—àkiØŸÐ[AÁÝ)V0TÖÊzÊ¥Yè•oÄ/³Çžxõ5ûJ‘t™^w†³Sdtè@¦q’`ï7¯ÒFrÿ,I94¡îâ¹[†C[î”ØÚ%3r<È®â\å 6~µšW`8>ކ¥BâtQƒPî[ÄNˆÁ¤:äÑÔíër&ý ÿ K`Ó=œ<œÑ<œÑ<œÑ<œÑ<œÑ<œÑü l½÷(@Ëè…#ýoTtºœ}TÔy€9ÑÁ*»*8Çy%¬Å¹°{Ôrk{p±Q…x‡„i©Š*_ÆOl_.ÏqÛÈÁ§ù $øõ¥¸%­ÜF'­o¬®JŽRNOŒ”æ‰#®{Í_JÆÝüï­xlIa˜, (ß g9”q‘ÍÄ4YÓŒšèNïwAíÖ½—tÊÞïÛ‡;ÍÍfûvÔÀ{A'¸IØ¿í~l¿í~œ­ä¬^­GʉŭµÁÎ@ÒVö¯0ú÷ˆÜ—ì{Añ–c›Ãfù¦ÿ¡0ßc·D´ybKt H=V6§½ ß9,õx‹¸ö:Åâyàý+"Õ¡¬¼òXW#>ÆÂ%›¸ãÇÝóÍiU×/â­%bo«°Ýô±žøÈ`ÞÕ>dFïvŽû1^ £³'Ê$LB¶úü¼ð!éÉÛG9.V¼âZFºÔÓûàú rŠ–“1Éi§ ÏÀ]²˜Ò¾±6¤*1¬¨Ö{ãM=çKÿˆŒ¢{¤8Õq0Zˆ'ÃaÕã6\ål.†ž¯`@>Œ>g´Û¤€±|†`E˜å ÈF$ÇœË+»Aã{£™Ê M3)ž3ží|½Aš-¨@t¾4ôñ ¸Stru˜ì/MªlÍ-rËà[¢Ã"…ê­ÌÍïî ˜LEîDO»c2ÌW€P§ÁØhhgG6L¡lÔÖ•]¦‡3ÅžÓ6Ö٢ٿyEŒ HSLB÷VÛ½°»ç_½ìÑÉâ8 àHhùýœÎþy›¡6ob¹fpôû xÜâ8v¶'ý0ÎÝÔòNÑÏŒüyDJ ]N“„Ì›Ήª•‡ ™™·…Ð*ú¿× FÚ܆ úÁ)‹‘ GE×G , ߥÔR!ª¥ˆL`¬W˜û}E¨’uS0[* ÙÕ ?ΈŠf©‹'K¨ê ºgÐU¤Ç¦Ø–ºÇÊ=i+{¨»ÎFþð\ëx`¬z]\̬o>Ñ£öƒ³‘LsÅÈö¯«*=¿[1ë 5Åœ4áá!N9²‚ ½9‚:§¶~j}"_äbp€aOÇí9YgUxD­êù} Þ®#^Š?¾ É­oJ5ÎÊ¼Š ÒÁ{ ÆÂïŸE°Á=TÄ=‡p«ù¸¾£žº¢tYtÎF\tþ¦õw4«¬i[ð!%0] Á ª Mð¨½4Ž™¹)u[H#":ÉÏlê:¬òYÿ•° QCÔE Ú*þ‡0EA?¢òï?ºnLÎpd€È¬ó»t2€Cѵc ¸A¸¼ëc´Ò^Dƒ@ϯÏ6(2j0g'™í–²˜l5M_âY&õ÷dÅë—+^©_ñFe©ÒˆÎI?–‰l1‡`hå×ÃWµáÆdKy> T<‘RZæ#¦ T°ìWdÈËcKX"Šˆ´ÁR¡'FUø°—˜×킎حÐWU^Ó?YÇÐÌ`Iž GT "ªH¯M'4j…‚¡›Fu"EOÖB–Ê¢ä—8¨ÐE6…&È“°‘‰€ÑÙƤúe/¨¨üe¶[ç[jÀ•u™+µí\Kª);x ÚÑä|‰ß¢Ž,–FFO™¬Žå¼¹eñ<‹áU<¼%.-Sªlàtý(ú([…Äòù¾Rgje­&È!19ªH°â8Àc‚,F)sZŸýãÁ…畾U\ÚÈX,»‡Gtx “SObí§§ÐPWƒ°z©>W£ÑÙ"¾-"°¿6—þú]í¯ß/k m tN¬šS›òQí,+¶œ“YT”F½«ÇÌxŒ“zm—s²Ù°{.ñ×…Ýó¸%‘J…‹XY™ë¼Gé¼´}S®1ì=3UR¼Ð.FšH¬Â›œøÒó¯ˆQ…+û„¶M&OÙÈú= ËÍh0œŒƒ’e.4oÜYÀY–OÜÑYˆW[ÅðÑ[}ÕÃïkˆ}‚¬;¸¿Ý ïk x‹,ŠDZËZPYMÁ:²©M$²«ÃY¡}ÛeH=´tžÒmTD ËŽ ™îb& IlŒI"`:ø£Mr ¡‹² $z3&r(9³&‚ɈԴÈÜë‰lw!zÑ$î_/ Á*]¼Ámž@¢¼dˆG;3jIàtÑ[õî!È»KšAR¾@A3¡8BÙ¤êµ&'q+4Zõ°¸æ³A‡Ürchoé%ô*T‚1žíU$¬wˆÂÂ-ÆüK_n«ÆpqÚFê^àÆW5!¢ù°0ލAÔw—Ž?Â`{a`,E£ŠîiìCá·J¶b^K2;ÁÀÒÂË–tFd½h> @rp]ŸåZZ#úäþCsèøX·íX /P «X/ ÁÓɸˆB½¥e@{ð‰¸ )}cÿ<&31~zá¥ú|ÇoFùH,öU¬ŒÐô«E/mSG×–DÏ?Âì?iÖ‘ÉžA]D}¬øá_•’¬NÛ|ÝÜü¡]²3ùª\p–ã÷UñãM|:S«¬|´RÖ žŠ}¹»þ¹³EÝá°ÇÌ´¦°Å²UXKzga{®i÷åÖV¨x±hÙ60Ëb·F]{ð²°猨*5¢Rý@¡ìè«é儯}ÐÄ´Hc,CPe§qêgÇÃLDÐUâôºQŽ?n”êÚXö0Ñ [Õ`äÊ÷K„%Mê/‹õ±y¶˜ÉƯ榽µWìf#”Wûª5Nˆµf2]´˜—P‚ KŠ" µ•Aª‰Uœ/2¨I¦æÓ¥¯Ñä­ú ðC±Fö™ÿ)/WÔ ÌŸÕÞ É$ÈG¸ xŸ¥dÅ"5EË`¶ÊBG{!JQënú [§Ñà¶1°]Ã;iá"|È,¯:ÄOO‚޶ƒ¨äò¤Î ð$Ä©&S$°0Í\ò寫U VûhI¦—MÅ|z,€ŠjÁ+¯¤£Üf‚Sk„žXˆl=$aPÞ­ ªŠºÉ ë5HÇXEß#ö¥®DÕzõ‰zTq Л¨ûQå¤ëÊ5°•ONUtãétÂâS«©d jóÄýt8›;4w9‹Î‘³èŒl…¨4Oßá—†Ë'ùYø*¯ý¸ ’€ÃxrK*åúiCü ¿×GÝ„%‡)ö€€“wТó;n?¸“þ„x ÆYf^ÄÛÅ3¢0CçˈjqÕ¾X/ëØ¿KÆÌ¬öèº( ÿ}º—ƒ¦hýhDªx›×#‡3 èGJÿ¦«&Q {ÄAÿ"@ xî]}Ж‹mÜaI"÷E÷½Ýï2§¿agoÍ;W…ç‡}¨‹Š8%4ëuIñÅ\¥xÕÝ)*)ˆFi-±5Ô¤‰™ì³bç.˜W&óÊ– tbmhçeö®‰¨9F‡ã,M[¬¶NŸÚj)±ŽH|^#Ï骃Òã1˜R¯ |ã‘1¨2d.ªHš/L¶VÁÈÁKKò¼ÀñÁ¢Z{AaD“±¢,µ ó•œÍ±”N²Mص0 µæÒR ªIéè‚0' äkYÀ­u£ôöZÜ<]\Õu†À„²LôYgN n¦ Ó³HOuì·Ë|¥‡Ïù¿­ãίs®²^F“~—î§1¤\E» vø!úˆ²5ØnƒÕV!V$Z'´–Eºi*C¯¢Ä6¸,®ìrŠh©Tvš*VÀ׬ªx—Š©ª$›r—¨YòæHBLk¿“ Æ_Awµ‰“a­å~f`Y®(•Êl’x tDß윫«ÒÝ2;ÈØ8òÁ3VŽg±E×Y¹ªu?vd>uc/ÄÛ #µe ˆæð3£ýBÒÙÿºAß2*IÅFSqÞ\x6kðæMä¯Eãj”c UÄD¥Ä<¹ö\F`a†`CÅ ¬&}ÊrmÃ’#t-Ík.¯®âÆç †r0U;•«lœºkœ²[ÄáyìèyÛm¿£˜ª;a7¸²÷‚ކë›{,Nì­Üa™sÖ2}ÿùAÑ:èôÐ̹hÀTøgè¡“„¢6ù¥‘O^ËÃ4Z³ÝŒY~cP #{§ù[ÁÉäLÙ[ÞeíÍðY=u¡µìgkl?ëv™¾×­Ö´Òô_\ö_ÉŽûWÒ?¾Ö)T¼9LG°Z+&âó_ÚŠބшLý” ÛÂéÐ1ëK?lØä¬µçW8á[ /»Rz„¡2ùžsÒǰ²,s<+Üó` ã´Ý•+xx~DÌEµªY´§g¸'“*3*xWû°°a9ârzùuæ#­–$ %\KÅÒŒÔ ‰EU/¨ñ„Îíü±âóŽ­ÿMÔøÍº—•CŸó®ä—âý=NžÒ}½œîSL®ý܉÷Åæö Ò%ÝÝ¿OÒTèø3I£{ÕÄHÖ^>%ÏH½¦£n¢â)èÍF΄µCÎi ñÿ1ãUšó ó1Ö.«ÀÉ2­ölŽg‚NÅð'(AFhª«2 éËd.ªÌ×N}ŒŠ«ÍºÉ²8$Ï÷˜LN‹ÄÏÝ`±Np$À‰ºçŠj.ÜL…Êó—7§¤Â9Qìté¤LüXîEªýDðIE‚º¸AÛ0’ÎfšáŽ¿Þè÷u.Ü-qê];{BÙÁ·«lÓ-‰h2–­ü »¾vw†¡¸›/%”e™‹(DDÌ‘m^u7y ›UVQd¢lâ÷&Ù-Y#0×y¦ŠpÉ*ùƒ}ˆ"%æë½gƹ‡ä="šãß´$¨ò%Z/Jäd>tÇŽoqÍ[‹–q»¶·Ô““½ Él õ)šµ)¼aS¥ñÌÙ\Ùk†jì}òƒ4uYãgÝ$æìä;0f«öõ­,8H0ÁÜï [·»Ž“æ‡ÉqRhÆÉ† c¯(™jÏÍø>$“k[²¶?ÁpðÄl ~ü$Ù_iðMÓ,Jp×Á@SBöN>ÅLù©cîev}Î6ÞºõàÿçÁÿσÿŸÿ?þüÿü™ýÿЦ&0‡ZÞ_úòJûíM$T¹ü “ ˆ’ÊI'?Ý~ïÄuòÓ›Paàÿ?Á8Óñ¬rÐjoþüêG‘ß~3IõÍONÊ^c³ð­§!MBà£]@ÍAƒ<5Ü2˜ƒöÀL—ï°s#ŽN1 ÎW_{%`úr>ãAXΕ·G^};õ~ (l'ƒ;G€Sý4³c\ÛSó.úLõ_ÇPù¹¥±ÆÚÈõ£D첯—eyŒý¸ú®D$-eø_œÝ¡lÞ½û[¹ Ÿî…ÞR¦YJp”áHŸB@#Û-c7ˆüh9%µü;b F,žsuãÍÈi±š¸y8‚+fOd‚‰>nÃt)ª]ÂÈæ“Àgô;¨c3ux¿êø w žÿ$ÉGÃkêK¯Ú—v,njMœ¹èTŒ% ”ª‡ðÐSù‰''²lõ¦Z(è[•+–=n¸„ŠL¡Ùbk,;²S¡•‚¤háÆ³9›v,µ•’kÆ K₇Ž‚…QðË„îùęӆ;²CtÕ¯ ÈQ=sÍæO I´vÞ6Û»èþ„+ȶ’?JÛʤ-<Ø49Æ‹š Â,ç¬^šËãIhõÆ@uN ɼ§ô†ÿý”0#X—òvN½ùùë1C„b2Ýê´##ã µ w‹2EÃH )E¨‰Ð¥…óÏ”¬{a9ˆZÒN"(·çå•™J 2ö U¦x›nè\²¶ŠK!bQ.¹¾WGdqÄ»"Òã0°ï‘K« GòÓÜÌãk#tÓæ200XYn_1 Q˜Úʲ‡ TÏŸXÐŒ4[61°1Ì5òAwÑv}.ÉW؃’Ťaöv((\7ošªšì8Ù¹‡þ_`f²Evn{Io©Z¬™v¥¥âH™w½•hJÎUÉZLˆd° §O çµ}¬µ)á@ârž3c¨q3Kp'FГ-•ˆ/Æg”=t¥ zVÅã½pEQ“+”Š‚ûEð·²ÓøÞ*–vâÃZ¼! 5öo^1º@ç|*­˜ÅÌóˆÙ¥f* —ò¿)KÔ@§<æ=e§S4 ŽÀ‰`ä…€p[‹f?«lÙ¿äK ¤SÖ¿1dÙÅNPÊ!L9’ýUÿZo€Èý3´u§ö"ru'Ì|rø†Þ ºh6À7ñ€Wèø)EñGÌ’ÆQÄtJô—‚~œ7;©¡ ÊC”µsº· Ú ©‰æ!MË-œ‡4ÙÚes¬’ú¤ßå=ž}Æ<Ö M#e- 5s›hXægk+DÛq·~óé“mÇkçr$¨ìí–³R'† /¿öÂÓùL ¹ÑÏ!Z C?’"„ž^ÍDÍ­1Hïn»St%ì/Ñ S ’ñ~ƒìþeÐZÎ#o¶OðB0€q¹Û¦h†"t¾Äl¥ à: ‡éÀ ²bn#a³™è±\[Î |i Y4ñ©NLe‡‰a‚º8]µá´ØŽêö躓B€æéS,aK5Å¥NJ­æ½pG;ï/œÎ|ü8É/¿™‚FÖ)uB Ê Ç| [O¯:JU +ÔãX]ñâq =Ï«‡ÆàohÛ^†A1ÁS™ƒó€ZñÐ@¸"–ª­ÄöuÕjÕŠ—ƒ)Mw%×îxsèºì/Mô9HÂtkÛAÙ+l‚YlÜRÄT×@ã¢ÅgMÁ–Õè©¥Ç 5ÄY«’ˆZ]¦«¢m+Þ‚2É^Ë~hfˆ)™ØAäŠUK¤ÜqOQfÔŽ½aFÄ™gÓ‹‘5…¥p¤k³ÀÕ âípÁ4…±fc¹<qÑ`ËŽe|˜Ýþ(û* H¸eÁȹ¡}*ÄÅ#éÌ« Äœ–¼†ÜQÿ­óÑ­îÀ†½îpŒ§ª¡Ky±‰¦2ðÖªè–V›æ\m°§Æ†äÓ ]¨;À:ħvÕx0’6àºÂ6 tC.“G?ÓJòãÇgR%¾ÔZVv*ˆ5ÒÃÕbÿÍî®súsLŸ™õ_(ˆózŸ¡ði+|TŒPÌŒ÷ÚCµ7$‹ÜI•Ø'¬íhš¼†zƒøLáÆŽC´r‚@Î:'MæWõÆ®w%üs$y=U¨’<3ŠÏt|Û9ôàÄÚrâ’¢À–;ÌJŸ•MYˆÍ¢øà2°Áº@£œ®«v8þÖ?6ÐØdÕÜû*¤ ¶®’ŽQßH€-ïìÄHŠ+ZÓÀzO¬wØÂí7W½Ÿ£ ©¬1>/öÚY,S-­OÂ>šÚ’œoϯ"Q‹¥¤X8Ç9g[+@ÔaQ˜@ 'ý^Øe7YÖ•äA8†×€ŸXß~È6.°£s¬ªr  S?ô„¯..žõÆç“<_äÃxùÁ£ÐÅ“~t²8 fIFjYìFxq3Š>¾„ÿªƒî·tÔ­â è7½nñ®TâçŒý^?Æ•ÜîúYS¹Ñ'ÂÞnìììº,4Ùq‘#J)k pYˆ¶E°GÇÓΕþTRg†4I€Ý´K(žœ·KÅ"IMýŸ)ÀÕqV+È8i':¢q~{ × ä™ñ•GñÁ(Ö¦J ¿®V@k‚£ÎîUn­þÓ|ò’"171Ž@zÃíIЙ ÜE I±’<«êâHn— â—¡Žeæu7—ów¥Ú¡ŒýgÒn€&¸C4†–gµ¢!z±’úÌ&qzѺÛ8ŪÒŒå~–Ê(ÕTjL`ÿý+Î/DêVªte_aŠßØé€;õw#ì¢7þÌn¿UT€”9ô¿ÕÀñq  ]NS ¸(Zå8™‘–‰›®Ö†&JŸ%ÆÞ7.#Dq @7I%y4¸­ÓïZF eèhO²dÇA@UðÚb:sŽ…:w:Ð|KV™¶)¤2R K{ü¦ ;>¡Þ¬ðÉ¡,*1*wüLßÍ4†:f¬¥œug˜í¬$.¤¾Y—•¡ÝÞÞÙm¶Ûø´‹&Gm‡î‹N—‘­œtvâ9+cØ©ºxó œÉ"ºvâ¼Ítþ4âs9QŠæ˜à„“ÍF`<µ§˜¿+iÖ‘GV·` _‡¤¡™ÉI:(Ÿ²ÇÂ¥¥,ª¡ag–”¤›MÁŽ¡3éûãÀvÁAç{°¬|Ôš¶j|0P„{âU£32îŽ+*à|o\±|vá;Ÿw©XÑì™kˆÁKNúE@-µsvñ"ôÅzj¾æõ:BóL²Œ˜AtÛÁ¶hËç,lü¬u¡£³øv j"TiÛ|ѾQZ³Œ[ö#ç 7RÁØ‘“”° ÍW|ˬ%¹§¬¬ Atð,³Ø¹Xo±š4„XøÊ•ÂDä——Í탣¦ò?§FF6–ª´åEQ˜àðVs·yÜL‰DH*Ö» ®¯ ]Ñn‡`À†’úÚ×›Relr­›H,­½ Æ*ÓA˜Ú)Ç%›óé™­`>e[#V²âK"CôûèñJ‘»Eâ ‚¸[dc Ê="Ìöc0Ó]•ë°Ã¡#,WÒ'Œz£žåmòðèü (vF|Q´íŒs›ö—ë¶³¸SL íq¢KÙ–¦éƒN¼¹ù½± ‚4äúƒQàk{[ ¶&«–' 5Rë²{‡Ý>l·wâ·=⼃/[Ç€ \¹B••ºú,ÌÁ“o¹Z0\<Å]Ÿ”ÌCU)üD/@Qû¬LC5ä˼Ìõi?û4>wh—þu,Íà½0é¼S»6dðæ³s’u#58‡ZÊË­5wÕUÂDMy"#Ç\ÚupM]Ø~+0·xCÎ|»dóÙŠW,–“‡]Ø»*judûé ÂAC©÷ÓSÈÅ…uÿ ÄŠ¨=µa¶é+’LMuÐ Ô-ûHéä-ää81>6 zE);W6B#¶Q/YÇtŒ2ÑÂ*×3³¥^ Ë"yÒ½ìÓ¦üÌúry~÷©uÖÛ÷dÓã>PÆ(~(i¡'7Ôšu*‹¶îW¿óË„gµc¿¯óCŠkq¢QÈ1ÚÌ4U84‘‡”%ì%(×m.$Ø}nKš0Äðú²lzŒéTf³ü&Ñ}SÖÆ`ÚÒ(k¢„×EÅMÉDP”xeqÒÒ팒(Îñ&VuL[µð›S9åu Þ3V%Šð› ˆ–ˆ÷yÜÔ$œ±ÖËކ÷·;3TH®N-,&dåÈÈz’ÇÆ$jÛ¶“ %¼]ÁÜnMÄ€P¦c µwÓÝH;²PRÚ´QS…—Ut¿—¨ýq ÁÁø^ ï§Ð·kUÆòTÞc€ÍŒ aîÓÛÝÀ…LŸÜee¸aœï¼lè±þœ‘Î[Qn^O4¼‰€ù(Vj2Ñäï”ûE-zÃÆh¤NÙ`=éõ'Êæ1OÉï¬V–­EÖˆóFêܧ¸–dà±À– ‘÷õµe^|¹nsÍŒŽòÔ>ÅE&“ðzQ©ìè2óá#<’ÍjGÖÚ~‘zKa«­8Ýí§*®¼Ftí6XGj@à\¹÷IJX2DŸv`é Ü;=F/޾‡ÙµnGœþw¢…è2$ ' kId}p/{¸›UÃýíª¦(`wøªì§¥Ôª ÕX¾õŠ•+δì¾a(s-¼³óN1ï¦ÛÈ%4ž–f‹ ó½q9a'J*¡Ì å”WÜdËòÖjß *Úñs‘iÍHW*,"0_º(ô/?òýQÎÑB' éæ#m‡th>d¢p |ŒTj"C|K4Ùý•M y·H<}T–èm¢79H.œúctÏ=VŽ™F¶÷%è+í*)—ÜÄ?RØÝrd“Ò.éÿï|•jú¥BË¡«A`;>úcÑ÷m¤gOOc.•É?S–ÊI‹N´½÷ã\ŽÄbbE±;.ÈnÇ @…ñµ,K踕 ¨„ÃøtÈ' áY Âë1qgÛ‚?cÔÒÖz´†æ4;óºÇt¨Ó·Ö´œÓzÎæè‰›l̦Ò±§Ÿ¢R)Ó<[>;†é·øœ®i¨°]|§¹ïœ©;¶ã|Ëþ¦âqìc½·à†ƒa}d¬†× °\ e‘‘\‚©¦,Þ{þõI DÆ&Þ̧hŽÁá ¢¦möoº›q1ÃZ7èf¨æ¡ç]拺^ ˜³³@;t1ê^¥cùÃEF °o:chOaS)ƒ’˜¶€â?‚TDÊ ¶ó% U£å–Oì EšWõZVz©Â)”¬fáÆMÙŒV’EL™MÐ9Óe@€¡Vúˆ2€‚ Æ"}sÖD¶ßV,[Z}ò·£àÓ±ÀiJüQ®x\Ih,0·…+a¥]s‡’‘uíì׭ʨŠÉ˜"fhBÎX \–û^®É#çèãÒ–² ±àï.YoBì4fãÙ¥ªÔÎá–Ý•’F,Iò·éΩèüK;©¨ÚN0~-TæˆY΋ׇܕ~~Ãsc6 <¶ìõß&Z\g&dÍa©{câ{ý’!xæÉ!­}ŒåÌ3åO_.\ÌA®!)ß\òþú|ïÞ3g!:Vi2­dB’ïð6zL"' ÊæÉJ&n²P/WOttißøç- /ŠaŠ™+PÎV`­µl(‚š¸-'~ŽgzݬC«j!ébÃA˜vµá8‰pJÉhg@{7¼?qs.-w©¦³1µ¾ÝÃÀž?àTÆL£ ½Æ¶Å_ #ßhb`@Á™ÅÄŠ{(hŸ˜öŠ]iç,*„—sCŒnû9l›möpæ÷a› $ÚpòÜvt +5Й"Kà5;„À‡rtì³ ÍÆµF›U#͆dÂ.qàìØ¡{QTI*¢½Ôª Aq5Läxbb<Ò0e©’Np^ÄÖÆîü„­Wƒ®)“\¼Ü Ç£Ê2ù†@ÿ¸Ø—U+x‘ÉÀ¾°4Ô•äÌÚðèª4jêž·½&=B¦g#Ï‚«»³µ¯6RHФ“èÍ6ÈMP }I¤CµËñÓ E‡C c>­†Þ¾ª*Ò.yrÓk•;¦š%Îï*ÆöUNÇ,.åÇ8‰'ì_ƒmgy-úOz˜ìðÀÅIŒÕÊTa¼VÔÒ'9"rëzpÒóC ƒÖñ.âŒq ±ÑXÂR``§Î(ªZÇh–Ár¥¶6ó\š‰qâ¼:~ Ç™õÕ«šå…TsöÅp¢k%Û'•˜{QôÏÞ9݇d¨*ÞSÖsê÷Øïu™¢óÂ€Þ Jº¶´¶K[%×1Wy•Ϥ8zн‰×E+” V7LŸý¡! ™]×ùeõ@+âšZ#1« g[·B׬eA2«ú6-¼Û°BhO<£ëÇíí S`ÈP&:E¯yttp´šZÔŠ¶7Ñ@œtH-drl<|ºKäå¹$ææ›TY€h¡“»B…¤SÑìªí @&ÂE¢~Ãhd3@W¬XåÓ‹1æµæ©ÈèÿŸSy*^QUWgO¹'Oì+OtWÈž¶C$EIÏKT_Sª bK_|;Ìõr£KŽ.‹ñ¢Z,§`ñ!E¯6üÜÞk,«§ýI|n˜€â}Áh”ü„ê×7ûmXKÛ¨Rj‰Õ˜QV ÓRKÉ8±ÜØ1 Ũ,Áþåò‘2ù qâômšÀQåÚ‡9H+ •…½x &v[\R·Î~Ôà;¬åëáÎܧë¤CÁðŠ‘ªÈ¸‰dÎt­kV?s›ßÚÙ*¦, ïVýªp0ï]K†Vet%k‰c<‡ÄbÇY[nBj[É1 *C‘ëPÚNÅv€(s‹Ë)=]Šä^”n•çcœ-¾†ibáí¨´¥I[áºæZÈÏÚs‹@oÄÑþ0)“ªa&›÷Ö f`ŸaèžÝºmSl MÉ,«BýÑ19Í+ÃÛâ)]ÿN5 ãšñHoŒy§@¯8Â1*ÉZ+Ã|P…­4ã`.ÞÉX‚ÿŒÝ׎»i¨Íµ † ÑôŽÌÖ£¥˜e0GöIù}`RdéôÚ9ý»ñšÞÈÌ?‹ ¶À±éˆ×´¦ç±¾ÃAkgt-~“ÄË4.QzKн´ ™Þ˜¢CiHv´NO½ Õßf.÷ÚS÷Íhª°›‰ÝÁå¬Ë™ŒŸö·ÄösŒ”å kzåðâÙL-sÚ¬žýj½+RGiz/³×¢™+c‹¨ÅFÄÏׇ©s_6çú2 ­Ðäç„”``\IÅfúÇée€ô?¿;!gI^U%š>Ñ[i}lš8&ÃÔPÇ9§ÒYôêy;§ÊǨS¨À°\Ž)[¦¬Ãj¬ÌóêôaµœRó@äH—~·1ò¿ñ¬<Å`ÌXÌ:ö¨ ¿–ÛÃÚëˆïš?Äd5pf)Ë=iÚ%’&K\¥ÓIJ§ÿ~MÕ;d]{/ãñ_67¤Áù—kº1ãN7ç@mÆ Œ+gu° ì\E;‘«º…”¹´fD1U‡8Y6uOÙ¾ß$î.ØX3«Ê›,Wç$•?ym¦2;ƒO±(ØDÙZ[)”cû¢¾æºmE­…›Íƒf5á°ì Äñƒ>æslvåiðÓ˜]“ÎÄ:jPÆXtøxr=…cÐe¤i§¯$Š+‚„>ƒ}9t¨]†®Ì ¯ÝϾUŸå¤V:à)s$I²Ú õue@9_N»Ì8UåCJlÃk^¢f Qöa+ra±Á¶‹²ˆWÑ^ìÓjÔçÇ }¶âT{&Ü6eï›8xy}¢D~ S€.ž|¶'‚ü` _qìsO'f& µdI(›q®8;“§Ž¿sŽ$ ‡: Wý†K(Z+k<: ?@Æ ¶TcÌG;-´kñɵÔ†˜<´u!Û\Ï@úÆE~ÊQÓ(èD#¶i¦c"Pºé,šlË‹n¾2 äV0~3Dì7Ùé Y')$ëC2ŸÍaTî¹Éºé£… ÜõmˆÜònQ»€í»×hb—{®‰"'! ­üK¨É§NÌ t•ItЪãØHÊfÆ~Gt=-Ѹzcí€UËÆA]wµíû×–Í:[ˆH´K³ã݇,2wäç_V#!­Ô_]5Ǽ¹ö³7IqÙÒÄM¥2¤Œ|9É:Í$ô¥`´jª:§h:˜øCÕU('âtöò/5'Š.+¶¦ªÀ é§IŽüoë‹-““ê…|/¢ýÉyíËÈê7o&èN…õÁ‰Ä$~Çr?»Þ}…LAjÀãïáxdYI&ìù7Gh'Ý÷+jÉôv)+sµÿ¤QW1'†ðK{Ô§ƒüºº %lH©û¼mXÉõóäòÒÆ‰Ã)`6}©¼Y1 Ò2‘}'+B^ kÙÁh©Úms‰Œv8Ípâ¥}G>ÃA穾ö€T…ÐãÆ;çêªíÔÄJ±½”§Íª¾üd÷Î,­•ÂàR¹ŽϯíΈ}íZJçš]VF+ô‰Š«À—Ts;^‘Ç œ®2Õ•„¤=ÀY&YvÇý'³çRÈ©ž÷™{víVýIc Û?k¬ßïbý>Äú}ˆõûë÷!ÖïC¬ßYbýf§-ä*‰Ða2Z§³…x^ôFQH·‘/|à<'}Šæ¨¹Ƙ@ŽÖ÷ÏØO ,!ýÞGT)ùcçV0š—W 6 —€´xPÑÎ0¯‘©¨,êóà ë7±¬Ïºß“镽èÇú\‹®h»èñ•¶r¹²÷ÚùvŽVµ¸É½Ä±“PÂË0Ã!ÙÓWs\Ç=ï­ß‰›{xÕ ÖÊH:Aø· \ ÒÕåOlZIåk[—TN¾ø4oïNÀ|­ª¹ i³¸wóc"Øܓȵ Žž :ä0R˜ø@”<¶Å£¬¬O÷ŠÊõ:Z§N+¢`TÖÁ» ÅÏZ£+ª|Q2{C¼*‰vö°âE,ê™ÊäPní›*«(ø"Ã# šH§ä ­B1˜Œ£V§¶3E Al˜·׉è m¾å¼£¸GÌnUšNí®ÒN…¢šñ¶ãMŽ Ôì#íˆå·ß8¯ÞuÈyWÒµ”}4âK™f$‹æZšs} µ©6;¹dŠ¡× Ìdü6¡wÉö˜Kö¼ ¯€Táõl|nŽ‹!-ì †ø[1¹:mñá¡@Ð~³–Ù°ÖÇžëPóþS÷ëJ@^¤°!O4Ø5sÙ/l­ëpìü}^ºT¬†Äðø±WRõ¾«}À±™{_›Ó DœR²Øº–ÓL\”l+‚È”ÛçwXÕN÷«ô©µî š/½4H¹—͵on}NüìjŸN¿’_"«]0.P$sdìi¬˜ÇY/Z§²ztžxu_#Á¬Pæ;Ëû#~ 2=í"XŸÉ„¹„ÊüÃ0D£ ‡Ï ØyJuüÄä®$0»ƒÐÜ sÝn(ù/œ!þóâ`Lx!Ÿ`J/! SŠ'Ý‘Ï`óÜ,ÍY^)ûötk}ÓÛÉé#'œXDA.?ÕӘŠí/«qBîLr86S•UA‚‰CT¹QküØ!+n)аÙÓÖ½oJóä¹Ú2ÌDâiVâöœmgd[×ÝLŸ÷üSQè8 ѹ¤÷²h+Û¢¦lL#^ÎrŸäëIµ¿' óð/@ÃtÏd^Smfs"ÖpsèWw-ïé0ðÚéÈNØ›¶¢‚]¶ýêN$´Fyó&ô×1&‰hÖ£ãò1³¢R‚õØ­k/ñ¹=Î$mƒÕÙ.‘ uªó蓱SÑ™ç)áBù¹4‰' HtPÞÌú ntÉ DAÇïtI[®âw³+*W_0íYÎ{íûgrFÌ}`WBP 1ó˜æ½°$”5¦\þÂÖ×àKÊ ÏOžèpA)‘ ²ÈÆ ¶ÈË î #žˆÂÅ»Þ'’¡Mçð (Jž2nZ·"¼&‡n†]®…„÷7}·Bä ÆJî)‹7OíÇ7ÜZ¶cæóF@¶zÅŠUor)ý lë¼w:;ÿß#§ü2å°OY¡ØN)ž xÞ>Ðå]‡}@V$x[Ê^ Áå*ÆVm>Åg2Ýð½! ¦cGQÙ¢¡gì#Æ#à,˜N"¾€÷l×N—ò8lÑFaè­Á¡µZ£X¥H=tÙŠŸÿæˆÚÀß :#+bžrœÊÞnTÅÜå…ûöØðØò&¥ ñÁƒ:À„.*´OÞm§SªÍú4ëpŽÌ§:NÙѼÁ1AS– 7´„3MÂP®r?…þõLy_ãÜOÓŠÅQ>.ñè"÷ÛøjœñmЋ;Y '7é(Ae¥+Þ «è†ñ†'ЬÒijè $‚×ÍöYDP=OB9/¶ßüãYs:ù÷¿«vË8 ì7öšy…HßÔIÜz³wh ¹MQhu'ƒ!6á/ÿîö/ƒÿ§èïËòÿgÏêË+ÈÿWêOŸÖëK^Z[zöÀÿ¿Æ?%äU~CðÆâ²‹·@cÜìÙS,^šîãöåãd‹}ÐÖ~Klø”“6E¯ýXƒ¬<‡æýtä³qùJGE ;×D_Ý7G ñ*¯v+F¹ ¶ê}Øìõ¯+Ú „ŠÔbì5o«°VØŸöÎ$4’~+ÍòŠg+bú)zF{ÝxÛlï7·^¶_›¼/Â`Ü=©žo¾ ÂnïÔ>nC0 ‹¹b•œ½½Q¡Äy6^`¿nÔadY„ªüXû•ëîû×*r© 1„‡›‰kºc³¨Ãjaƽ3ô¦CJ›3àmûôÝSÜþZ»B‹§äßOkyåVÞÕW¤àR2×ñïS*¸RK>×ÔßÕ~V‰)¿ûŽÿ¢_›·;GÇíýƒ}ú%1z»$­›ç­º›ŠŠ· ô†~Õ£xüòƒ?¼}ÊÒ3¦pd+L Žgû ÍãñÉ5]vè04tB~yyY5‡úÕbÅkl·w€`* oøØøŽÞ4%~Aw2mûcóï¥ÆQ³Õn½Ù„õ®UQ¡tP;‰¬»Ç%èÜ'”%"Þ®âˆé€oIØ åT Tàµy·p÷Þ]¹ÿÞ]ùvïÊèßÀ¸õb•VÿP¡³Úè´d’ʤœîê•Ïîê•tW¯”è:ƒo ƒCînñþ‹àQw82tÒïñ(DSèž©}OzWB²¨ÿe‚BÂb0î,biŠ’è¥æþÁñöÁ›ý-w…Js(ö&,µ—"É?ÛÜÿ1&HD4ÔÇŽ:²·É‚e±¼“èlWü˜†ç€F!ã[¢IP¿8 ž)ÒÑv:xºeS˜ŽÀhì73P”=A[F´¤?’:—ˆä0A${Q7peW!øÙkxfSïcb'•Ü9‡êxwhÊd"’—kó`ÿ¨¹æ–åDïÎ2»íÌõÙæ÷í¸©;ÚÖáÕêj8ŒâDI¢´*Fl)Y½^þÜ¡_¹Ï¡_¹¿±O êôÉòY#´rÃåGËàÐWØâ&LDÈdtw?cj×—žWkð¿úï/˜Ï>¾·›yC{ÃÀšJŠ¿ÎénšC7Ú9rýÝÚsƒþøáSÑ ¼ñ#z÷»ºZÿs5ƒMÿNÌ÷ËOm¦èجÑGuÕêR´q·î ·ýA¯}Ÿ3þÉ®‘Bvö3(à.óãÆ È½¶4JÔ)ð[åíÈwçã(ì—vö[[Gí݃ƒÃ—ÍÊ7nRã»ÞŸàKù HD_r¦Í¾¹_1'¡ÓúÂËâ[QM$+.• ‚^‡”q®¹C]6tÄÅÞÕŸ}`‹%Žc²‚‰m4OAøbZù?@M+lr2J™˜®«&ê`­ñwOþÿéFþ2"“ÎQç“ËWæÕn¿áo Úóõ{Î[ðê†9ÿ¹:­‘ˆ?¿ÇZÁ˜@!LtËÿä÷¥;p¯¹—Ý;û­c¼ÌÚ8n²rl³ÑjB‡bÂþ*§_sPVWňgu•¬˜ãRñ´ˆZ%üsJON‰YÜJ/× üQ缡WãK¶XÓ·¤ ÿ:šŒ''Z‡ÆíN»Òøí'[Ãð¿ÚíÓ]º¢‰^€îÔ_¹ý°¼|‰öï·îÒv÷(Çí†0þ3ÒÁÞO÷݃«?c?ÿt|ß1¾ÿ{¢uи£?%l½½KO´{Xm;ÃêÙVöœ>]üû¤±ÿó}S‡^ÿ¹zäAÒ†§‘Òt¨÷¼lu>Òæ“Üé𳽟UiöžV¥ñÎH½Á¦-lŸÒn$J‘þRȵ«QâÒ³å4„,u ZËðÿQ÷käRÔŒgI]õq7_¶Ú‘lD¦ÈG㲿ƒžÞ¾>hÿæ&‰×úfë0êÿ¯¨§[rrEÇÓñÁ(ÔØwUúßê³eo}ƒã– €à6åY´“Ñ^ª×á/*»ýÏ£ËýèhàO@µâü]ˆ³öûÑæ›Ðy‡ü'¡Ñ§2Ï ŽqwûÒýH÷éïFº+/£ñù­ vå(v%E²+é,YË>T×^—ÜŒ¶–Üµíª¯|m"=Þ<üíÖ»°ý÷­ý?;[ªÕê«O¿[©ñŸÕïà߇ßS4XdüÅÈX¨“¯H‹£qaK <,#“A W È´¬ú@Êw‘r¡G½ÎÃ&ìk ¥¿Ùkílb©? 3¶ŒBD`(VÊülßVîJØ<ú^H|kóOCãYLù¯µ[’üPJÙí…ÉdäÏ5Òg¿Ö5³Ó€.{Y—ÍjK©çÙ®™Ív»¬¶LŸ~šqz>ÌÌ{œ™§ÁwµÕzm‰þ[]®=½ý´LøÅ­h¼MÂîŸHeƒ&ï)LË Í ºvÜÞ|ö|ù¹£s£ú÷KÕZþSþbÅ])9Báë­@H×ÕÙä¸M´-¾ú ô¹Õ¬Ñƒp˹¢Ëý!fÅ9ÿÓìJ&‚YR°¤4ÿ¾õ5g†}ËíÏ&WîÌ®W ˆ‘¤ÑîÉw««‹ËKè•‹‚Ü‘»y )a¹§rB`ToÁì›þµ.þ=ùîAû/X74ÍÜ]ÚJøý¤­ ôáo5ÿþ³×{’·¦ü·k¾2ÁOµWþ jBçƒÿJäyç#ùÎ9‰ÆçžO|(TÛƒ*s8ìUlZûþ‡—LÌf÷÷•V^6¶ÐAíýXRµ˜o"žÿ½Z| ÈÿE7­xÞãM†ž,€å÷ ¼$™µ6ÿˆKzzýþ,úú¯?,ú3Y’až?é9ŸŸ-› Jòû¬Íš¾ôßKSn;ýßörïVÍJKÈæ ˜tØÛÜqñ»eÚü2ýlþЈTÆñµF+æHlˉñIQúp#íl§6 ñü3ŒöIÑŸ|oˆž Ã3ö”TýŠÞðîÔ;ûÍ/×;1ªŽÛ¥ÝÞÉÈ]kŠ9Þ“=||÷‚pø§È’bëð9©îDÐ)äÝÞNñ™6W¥ùQ@Þ»‡#˜T?¿dæ7JÃrùÉ“5;–Üê*ãQÂê¹jU-{ °æi0VsU7Ãöá`7^©í܉*fî u_:Eó_dÑHˆ 7 ÊWÍ0'™MqYz4¼^›êF‚)y2æ y5Kl—U°[t øÌná H²gß }æÎN€uc_Âÿ3£J¤ôƒ[ö?·ÿw ñ…ã,-ÕÐÿûÒòʳ•••Úsöÿ¾òàÿýkü3ÏñHÐï“Çs“6îö{ä=׋:.yH'¼š°;rêƒrïÚ]]½:ãhô‚¾nxg¡M¶@p¤Ìµ$š`j*šZÏ{áI05+šš•Ř²&­÷˜êÂE±Œ~k&"Ìn3 ½.Aõ(Ê”` Dòå™p¨¢O@æ‰W„¬ÈcˆÙZF…úQDõ4èrªòŒºŸNm i%zA,BJî /žŠÆbmJ©6†#šR¶gœiTWîˆêÊg ºrª ClÕá$>o㲚ˆÿ‡”§ó£+]«0ûƒÂü™íµ×òÓ’+øØ@¯ØpºþØ'gS*2Á;ûËKêǃ£-ïò-Çž: `ÿcˆÆuo¯ñC?––*ÞÕúc«±Õ8nx—±¿à$©…1 ArIÁÑBrBéo±ËH FFPjí¼:Ü9lV÷ܾ3û?ä—†XâêçþCÔ½w÷Ó£(<óbÔ!E§B\U郭ƒRwtwý~P^•Љ>ÊóÝ”“@{ÌFåÀßN(W—›´F6;ñO:U˜Š­ÐmMä,ï»:FÌÌ8û }® z䟹Õw࡚šAÊ«s&råû‚ìïžZ|<š„Œï i¤ÙœÙBRîÊÑ&ȬàŇv(ÉÒô:ѵ¦õãö'Ïò’83q®‹ð~ûÍK$£-q ûé a°ö6qKžíeèέ6±ê½È)R™QèÈ<.X÷ž¹‡¨ƒ$×äú8Ù±¶ëõÊ™§¿Êøìï¹ôzš\þ ‡¦7ëÿ>ÿðýß³z-¥ÿ[ª=ÐÿýŸÔÿEÙü~®YU¼ÒÏçr drUÅØ~Mo€áï³OwÒÐ寻t¹÷ÉLýÝÒe3§ìY–f¢ü›׌q›å…ЬRÚp(ÍXÌÆ,#Ðeñ×¹¬¸UKÕåêÓê³t\ªÜè“ÓVíؘŒ`à\ú{P¯Ý›zm³¦æ ~¼ z£îª7ŒÈêBº{#?ìFïßÁ(ò`µî÷àC/¤pêÀ>bÿ,[IEšµÆ]k¥ÌÂ_D1ö4­3º°WIiÇÆ†a4ãŽ? º¼âK¨âŸ)=÷û÷ø÷ÿTçX³}kE÷gó‰/‚·½üßä.Â?¼s'<õtžƒyåá1¬JCÈ6öOúmáÐ Gp5„E,èò€XD"y°@8æ-3*,›Éô®ö!™ÑÊQ¿1ÇR*lj›aùFOS9ªn†g© 7Ãʇ»3\ø3îùýÍh0„âñëý2¬ùØåœõçËžB~>sÎC¸CPêÒÑé)l ½úÊ3þ=™q†-ÆŒ¼wº¼‡w),Mã—ÿ¶ýë^ôÀ‹l^Ä,§ÖqYÎÒËy`9_†å,=ðœ/¢¦Âþ–~ªïYõetQ¿¯{àB\(“ =\òü?ÿ£z~G£ùç¿Ë˵çÉûŸKÏŸ=œÿ~•0æ<¼:·êuž<Á74p Ñ‘˜&‰#¯ ßBB/ œ´¼cbº#è˜ÖP\vO{ý€ 6¶ö[ÚcGŽŒüp[ðˆÇ#÷й¨<L†î!5¦'²ÒźųôöÞÈ\¤¿R„¬9_7Þ6Û›ûÛ;¯°µ:; wÚ;#l»ù=î‹n‰ ½ÆN~[‡Í&Ýu¿·¬Ïº#U…Çýæ‘¶Œ4ÇéÊ-ƒß·Ùû½xl¿ü¡ó ¢Ñµs‡7»Wzq™±S&ã^D§ÙNò (-`¹>„Qè\+dœóW8ôÞIã,wo×T"]V×cuªrke$ZÈ·AŽ*Ûê>èM™°7f57PóóÒóÐïQ© µg#”s õ–€ò®ÝÞLæ•Xœ‘?ž÷:ç=0F4F™v‚×yC¬XÕ•ê¡T§ßŒ‡{o—ë· Ÿôµ+ËhôÑ‹B"®…èɉXêŒzC¨ ®xÃþ$Fì¼ݪӑðYï"\‚ñBtº°½ÃvƒÀ©iS-ÿÛ[F–§ ùŽÚ¤Àp ¡êŒRyÃ; ÆíýmœvãK#h册 —!Ëlùð «q ö®Æ“̧sìa<ÁiØç­¡‡>zèÒ†<{‹ÛÖ~?º¤þbV@ Ÿ½à°_ðSú¸[-°|oí3½Uñ]oß^>æ™,_V¡ÁV‰R·MRÒNt €`Ï©I.±»ó²½³¿sŒ·‰g“¹[x¬®új芢|§‚ «c¥e± õ¼ÿdõÓꎹ e—ø‰O—ZÁ˜ˆ<\Ÿ{Ü2# x%²¿&WEeït (Ÿ¢`]±/…Pz}Ý«-ø8üÈ@•iã„ÑaGE®=$°f(¬œfjt°°®åÖd¤l²À· U!FÀÔb(ö" ö)Áu!@¤ü$P·÷ç…$R5Y™ÐMa‰ËÐÆlJˆÅdÆïÃQï«&'-w-²¾7}šU/¤}´ò§?ØÜ¸må!V+½8…"GSŒ¦Êû)i¦ë‰Ã+ÅöÔìO»ß2LÀæ HZ_Õ‘´„é¼Áø¥ÓþèÚ唢¤ º¶ñêôŸL<~Íðldõ4$W·ðIlÙï¸N!iÚ $ʸ°PÝÕ‚·9>ZÆIgfJ˜L\m³v¾`Ôþ¬Vì/Íÿ„êQjØA)þ„»–¾bce¨Z§RÇÍÅ["7Ó¡:âzŒ ±R¹Úi­F®óDqgº6Q¦œ%¶³½%ÞL¬žG<ÃnD.[]ög%ä=éiƒ‡~Ŷ…­eVrW (œ\³ªh!´¸°C]&(tÅël!Ä_g(îvØ“á¬Rú á8@§l!¥ÛC ºgLFÔl|ŵ%f`Á“>ìr^àþ¦âá&hƒ!Ø— öÚÞÁæí½æñ냭¥Òò²Â~K–Ï3ç±ÇÐèrË!šû4j½%Õ¤ê-Ô‰Ò•vúÄzú-¿ ö&0Ê ÖÏÑå¨7!ƒÒÜâÂïO#1Xx«õ™®­ 3˜Rz¿A§ ! M~@£‡5’[8CpÏ›²NU”º°¡œß¤ý}g‹Fû—^yǬ~Ö4¥£-ž´Áx%©™9)qK&( Ön_I¶Ò÷Æ0¹`M¿è¡I» „¦ £Ž%‰=+19´ Ö°®Û aŒ­AT”G¬: ‚+T=UÛ6Û|÷>çÞø¼nŸÖã­ÀuÎÿx}žmvÇŽ´ùy]©‚ØLíÓD`Ÿ?Z¯*îƒ1’‰*ÎÑÝúÙmxª§A,÷G]¯‡†>:˜+õ.ž©>‘ýî)jP´¦þŠFf·‰Àô¼‹åŒÌö6/ªí.­–¦K*Ndm³¬·˜qËvÉè³kI¯÷O&‚Á‡ý©ª-‹è3êó¤"òŠ<ËHËà0þÁEÀG$xH$tŽÀ{rm¯Æ¹ ŒÄºRÛƒ,‰ë£ ;;b+þ8À^Áa€ªPÕ8@¥1]fÆó?Rbñù â¦6³Ç#:h«—вÙ_²ÔVñŽÓÉ,{@ë4ÄL)evß¶ á0 3µ$Da°`—<†TèA… ©yà CØùô®Ô€ÜÔ?´›Mt m|;²T¥ziKdw~J÷“÷+aÝGÆGUQ¢ Vz+mU`MOZÍeIXµøšªU€ÜØT!75Oï ¦µZ2g†Ó&38óå´ºJ7FiðQoõ‰}¬…ÆôôFáEo…Ƚ gº‘GêNÕÄfxñ–ÔŸN[TªCYöˆq ABÙ•-íS82˜^ðN[0¥­çѨwÖC{§u4ôJz°Ûz•ÁøJWàÇôž§2bºz6îÊ=Ü)ðº +ÜöŠW7ÇÒº©¶ó|U§Á"œFÂ$ÕË™~Ö7g@p¬çð-ÏÓ ®PK.±"~e3•´á“* šÝ^8¹Zƒ²ŽgLªP›‹t4š„!i€»£)ŒOTì÷BÜéÅ6è"°žèÉÈ7NW;‚£kÒF°¨Ð‚SÞðÞÂÏqæíp­¥™2ª«ŽïÙ ZÎDŠÞí‘~šézSáŠS2¾†wà’xF†RÍÁ8Ss;@õÔ÷^ÿɕڕ¢(C)©À±Q), U¤ËÈ)“Td7ÉÖœæ4!ÎY¦2Ñ#D²±0éheç.ÏP,ÎÞoZZE‡q¢v•0j”4Ž&áN¨;²”Ñ¥À,³ÇÅ)âMYBJVó#ŒÊÁÜÌ"Bï4$–b„¸³¹Ûh±yb©»eÎNKÓO÷ÛoÕço¿mû­Ê¡©Y·¥Â0¦¡UL쨓ÊÒ’÷¸tð½ƒPÓ«•ú´“õ!ªáÝË?‚x~Èi?Ý¢h‘Pv@Ü¡’ìeÔ½ÆUñ.8~ZóîñB”±½¡é—”Y[ÅÃ:çÄH„3«Õâl]À]r¿ [ŒÏauv¢¢÷ cZ%9‰3²¹Ô–]42Þ} Í­ R¶^@ç½FŒÛªØ»à0yÞÎg¢ç‘{µ…ÁãVXóÍ××ÉkÚƒ¼y’4ý‘á4ñóàû¢¬]N¿_ fͲ?8Û ^‡œÏÎq sA;:¥Á1#ÞŸµ¦L3h˜Ç6µú½³sÔ!\ž÷ÆÁÂItå üÎ(ž9 BÜÜÃöï2ByB ¨,m“!4ŽÆ*Â9E#´ÖA¡Ä—Ð{¸ýˆÔg<£sF€Þd°«ºX T/2ú*áÚÃó¬À?CÛ1ŽXHVó¨ìôÃëñ9.z½˜%ÊÅRßã7D•«0da/rB5žß“€÷µdû‡­#Œ/ÐáÂ{ý¾¨#41€mè€78òjµx{oÇ1¾iÅÉŠý›k–Ù#y+ν.8НÝûŠC²Ôg¯5_rÅyE#K2EŠ·7-E­6ÿ¬Ã-uGeuCÿ‚ ¾Ó}¡n”ÊåiÒÅ}uá\¦÷#̰ ÍV»•©Çü»Ý(Ìñ¾FfJ Ø»Ê}ø±¦YýöÖÂÀ-®|*Áááþäuü¯ÓÉ¿ÿ½@Jã/ÿ«V¯//ÿ¥¾\{ú´ö¼V¯=£ø_KÏî~åøŸã.úêωÿ™¼@˜ô ÜüÄó»p<º&7 T|³ï‡gst ©µtÁU0êôbš•üt¨‡¥vwßîmSVdv €ï„ɲ6H&Ñùд‹@îe ¾„#G”ûÙ¡µƒ^H›©É@Á³4Ë™Ê\JÁH¢´©ÁOï0åd˜{_›ÃÄA0è ¯K²¥¤“+¹;RH‚LN¡äþ›Ý]ut )ì_¿fì»èð£M$`CHm÷BåþU>­=N½8g"«n¼•§Ú+ƒáøÚm %Uré;S§Œf}í† ä&IòVézïºêç›§ãm:¶•´¿!Lúó´Ê@¶óqöKè4ª¶TÙ¾l ,©zlÇNò%¿š¥éÕP%µg7SC<…êÒ£wb´1¾’Q^nT³³UMÐO‰ñ—ì7‘šÓ@ʪ}Ç|Û}Ÿ£Ð-½PÝ+·>ÄÀR,ìØÎL ‰gx).Ÿ\“Á†ÅKÐÑÔE1G?SCƨâØAWh˵¬¡8ÞÙ;¼EOf˜"·o1eéêÕíæ-]¼øg/Ý€ºq 'sýó¸^t‡m¹kY¯×í/ãNö—/>÷U µšn!V[» ³²ø\–‘¢®Ï`«ÐµÌãÆ>ýL²Ùz›É@ò)…0M'šË—oµ6%€\]ÿûßוarvþy€–ž­T £Ï#Ò"å]Á¬.­.¯>]}Vœ>î$ô"ËZEÖ°Z{V[Y­=¯}·Zû¾^Ãi³´Z_®ÃzV_I Ç·\ºg¬æ~&j‹´6tàJª8;ÆiëøèN}æU¼Y{ͳ»-…ÍÈûÏÕgO+ïfÄîÃêw55®«ÏÒD:Sß{júkÃä¹ä¬ψDoS¥E§Xk©.ý÷/*3m¥o·DåR…fB«+Ï‹SW-™il—OF½‹ÀëNðŽ‹/^Œ³ŒYnö†‹U”§“%ËIù–°d¡Ÿp[²¤ñohŸdʵÙTÄv8OüÀ=é‰Cz⣠êéhðÓÔ žY¾È¾Ø2¢\S¼ìû¡º•ßFNL`sÓô£0H„ü…”›fiÎÒq#6ÒÖŠ"à ½VWrfÅ]ÁþÃ;]`;æK^N9 út@éÐÖ¢_5ÓËÌ)3‘Ìì ôÓ©~:3Ó"EÜ5Ž_ÐfQ%° öˆ}Ý÷Ó,M_ƒ6nf6!H+[téî6+ÒþÁñöÁ›ý­[ÛÂq?ð?V#¬è>e‚é: Üð¾¤õ6ÕÂ;ì¬S­˜][z|ô¦Yâä*9×)OíOA©*ÞtnÑN¼šjkʳÌ-Óé‘ö)y¯˜¥[Ÿ—µÛ³ËC¥’—WÕý¸1ôy' ŽEŽnä(ÞØ¸ëE@ãóQ49;ÿ›·ƒwò‚AìÅþ){Iÿ p+=öN‚ޱ9ŠñdŒâÈqÌøU|‘ýø ›Ä=¶}‰WMã$xŒWÑ R4!dzQ•oÕéÇŸXKj$‡W ºcĦölrÚ$æŠë"è÷ ÄVvErá'¢ÜLN%ÒÜôŽ»V7µQO”+÷×NàÖÓ<ú9»öZÙ¤¸äûÄò|;çH¸4—•‘íû|vpÇBÝä¸[Ë 9ýí(ÕG'7`v¸=ØúH…ÞÝ‚ð=f[vAhÚIǨ“v ¡\¢t0^†]HÉâ3lÝS¢§ãúD-¾0Ü冖*SKZÒV^!³Ì™‘cL¨ó¹©ù[Ê:Ö%Zäüb¨wŠ ‰ñ!»s*¢ä)ü©%Žø@”:éT»ÁiÑ®œ¬Î{éèDOS5^f0rq\2þ­ÊÓ•.M«´îÖDÎQ0‹#.ô펎°ød,‘eBDB¤.-ß°‚gtà %8¦èR²¥™=¼LÃ•ÓØg94ž êy.¨¥T¿áÍt–¦aág긧_¸ãߦŸÞ©ýj°ü.|šêÂãˈ»0ž½Ÿ}¥>¬ ¸M_>»c_žTóÀå÷æJª7e#ÎãuO¢4èO¹ýºr«~½ãN·qeZ—Õóº,ÎòL“÷ÆUÃg¦¬Y±ƒ)¢ï§µ) |b5šù¶@ZHO uGH¾Í›Wä«mÊ’æôV{àYqÄõ*§îÖØ¡|…]금..bÉ{A„)w!¾÷ÞÛ¥xΪ t1:M7%gÑ÷e^N¡µ»wÂ’+<¦_ïØðÜÖœHk>ïÑÔë}ãÝa¼7?»Ã;.¦©×Ï¢´‹ëç͘‘ÎW äåŸÙÌe—Ò¯÷<>Ë'ú/1W–]"K¿~æÐ]øý^ë¡wÒ£~B¤K~ªL™³áßïj÷Òþ§†a>ã6?uzàégrI¥£ˆ–ÈUoåém`ºÉö¬NZânNÊä•jõrõ&±ñéM‚Ë\ »¯Ž–ðÏ2þyŠžáŸüóÿ|‡¾ŸiÑì]q󡲯PÙ=÷3‡”“ow"l¼Ýʪ5Ã;j§­¤ó›æöÊsû³¤•Ô¬^q¿r+R?Іqn[Ÿ» ÚxÝÃØ>w”|»ç•è;lFÆ®S5æ;3vµÚ ›WwVÜ[Ÿ|çôBòížûäûÄÖ’(#&¹~‰Nžpµ»õ>þ¾d•ïÍ XâøÞéŽïïÚSášl6ôŬ±†÷j‹U_úîOkŽ•6¼£fSIø¯Çî­UÙƒáøèmUMþz–[GQ4þûLF”î¨Wg´Ÿ¬H˜Ï?×Hþ^ÖtoƒQ h§E8ž Ðà&üt)°ªx.8—S‡m7KÓ÷mó¨…q¥ZÇG fbg¥x:ò¯œù£»~þ¢‡Få|,Y*$©¸â™<9­…~£Ó˜äýÍbkÒA#çÓIß)†(§·"h÷J›£ƒ+ñCE·wúA÷v››ýÍæîns+ |~ £ËÙQýþûrù&-!SWž‚0&í`jñÖZÁyëd,¡¼-Û—¥L­•û8Óúåy%çìv~¾,ǬbvR[ŸtÖár*›Tâ7Î †BSÈ'çñ¸sCÉ¥L) +L~qb¯.FmA˜Å€¬³ß¬ŽœùrgNç¡‹±¯ÒwFïéDOé£[’tÒËÚåÚ-õÒ_(?ÝÆçöÿ¥¼÷}¦°ü-?¯?Oúÿz¾´üàÿëîÿ«Û‹Ä ¤ ¾òf§u¼Õ~meœ„=ÈK>$Ùi¬ùtÚ Ç}‚\!¥yÅÍ",CRk]`è²ÁfßB~³ßoÒ‘áÙèh?ìr-žÈÁà‹–TÕjµðí„Â66h¼j’;ÜdÚË7¯Žš‡GÇÉÀÉvö_%SG°„ ¼8ò.ñöj¨>;Sçev.Æõà´wF ?´ÊН'߆ZÓ¯øî(´ÉW»; @/ºôGaƾÿ ÇQÖw2¥I'‹|÷ËIovCn3´£ÃÆ9£ë†þ"Vï °)Õú¹Õ~³s€e<ÏÏu¼8aò‘2ŸîÏ·œ µÉâÆÏ{/vÛ¯w¶p,É5òæyÐùx8ŽöŸ’é8²îбô"±”(ÙQ zè54ûÊÛS_-Ï4tµo€–—Úc[ ç{pPÊ]„‰ô`š o„Þ{{ªÍÉü§eÙþ¡[:𔋽ÒÑcîFA¡[žVö“Ž‘w»qJ¯èÄI]Y›>@ýF4kÌžzóëä6¡íde-'ïwõýó.}_­ãÿòsoÖLîï—nÊÝ4¹—–žÞ˜»nå~–—[àÒ?†›q{Ëä{¶<%Ÿ…çÓÚMx*·JèâDßmOd^ΊŠŒ“Ùk*{Væ%•Ù7Ý/©|µ²‚ë"”Hå­;Ô‹ßå×nåä—ÅúÊ­;ÍÝA¬pîüɾÅWW‹8ÙWÌd_Img…T¿/P¨ÚXÅ{÷‡]}i`®žžÞ;ÀÓÓUsí÷Шƽ5ØÅ¥å›!/ß gœ7‚¬Í®ö%zµV]ºW‚ºùOvu¬Âz 2 ¶ü>šÀÃ:+z!×ÝÆB}úòZ,f¬­k·áÝŒÚÕ½¹T®j÷‚ÊO?ÿã?ß:èísá<±‰Ï⟇ÚÒ³ç÷«& ǽÐAíÞ@-Ý3$ôêr°ëK÷nõÙý!hÕîÚ=öÿâgÃJ®\3,6·X[º_xK×÷ ïžÁÝ´û€±zu/Pîˆ7eõ¿%(‚ôì~† G ¡­â¥áÕU aso€gøó5ëúj•Í*©Ï0ÔŸ%T~™º¾ê˜á-¯>¼¦r°uPꎮã®ßÊ«^÷±Þåy€Þ³H{I>š1š%ªÔtHŒgé-Ô«·Ý‹ÌŽôTÌ¿d3V| vÛ$W(¼GÀ(!~ÀÚ«¯Èf_ô—üï/û—êä/wÚNùupe"n!då—ÕÒOoÚ¸kUêºò„È”Ö;áýmºRzí.ùµ“Z§Ö½ FRäKaÔ¨½¬mÖ¶¾F3lÄk°ƒ¾Y柭iõúÒÒòòmF_JÔfi‘ëùäüoÆaæ(ŠŒjŒÕÛ5=w£ï-xõϘuéÉv{€™“ié`Ôî#1…îâ²»”Ï¥¬;õ-ˆäBR‡[‰Kšà4:ʸݙ]0ƒdîV6©Ðž*å+Ϧ÷áLʲ)6eÛ£ ØŒF£Ép¼…“ÊÒÐ>±]fYxÞ•öÇì¹=‚ûÞøzx§½DNŒ‰î{ô11N—åƒ`0 ùi…‡UÏÛð;€ÞIPÊ`º¤èwΫ‰h*d´EW•Ò_ÊV¼F ždîL|2ËÝÞÙmzó§(7Fà ,!´*:è£ële;GœSºÿdrJ'Ö½§Æ+ Ǿ.ñ‹½â–$û ÚÚ#h^ÍLK§C;ò5•ϸ+Ð Ò¾ä§ ºK=¦Ó¾Be0`yµÜ2ì­êÕËG–‹.°hBJà 7ç~ô²}6~6}Ö’ô©…Î/ПÔý9ÔýEšdÓRf½³ºÈh¯‚ñköš nôl“OSÄͺ&êyÀk³/¥=ÂíýØ\n–÷cx_²r~‹æú€a~:Z¨>ÏÏPŒžUŸOC{uµŽ¿½áÅ ]„µCZ±ðàîôRsYw\æ„n´ZÍ#wã"ã”qåi»±·³û³¢Œ7-ˆͤ•)ñsYî|]öÂ.ÓÀ´˜Ù˜8}L\3Å‚þäÎ×Ñê)¬ °u‹´ÐsžßïaÀ®õw(Ô <õ}Àh1ÞˆBw׉K· y]Arœ~—.à¹ñÒÍ]`fÕî|©x‰ù¢;Hf›tÐÒ}uPó`{öÎIPÜ{{峺{™»{ùæîVs<‹ÜPC³z㟺ôöòÝzûíöÍâs$ÃÙµLp;O}SçŸ%%Z5†˜·G^÷¾s·Ç.ÝyÞf?ðGØZŠ5• ç×ëIj󤥛fÝoé)ÿ¼#$KnÊûuÆžµ·É¹u›Ý}—Šì¤;ŒŠ¹ÛÜT‘jn™ú en] z‹×A|ëZt™ÛTôs³U=Øß9Ø¿K™ª„TG9r÷ŒuÇé …÷øÇ;›-¼±w|ʵøäÀS—\х˸×ñN'!9ø‰½ÓÌ.ë6_ã—vÎ |šáEaÿ1€|0²ifÖJ±MNøÊ7'£ [õ±OTpMðÆ½³ó1€ìD“!îZ"ª[£'Hx=œø(f±³÷n0Æ9Tµ¯Pò¾Ci:{Ð5ÈýÌm¶yûjÛ<ô_ŽrUJNWmZ5È%ú"›Ú•ó4ÀYÅ”uÞ]ʪ³­"[šÏ^vZÁ©í¼º¾º[EÊÓ¾\ßÐw8Ç÷žVŒ‰8:DÿÖèóF ›¢¦‹ÖúŠº†¾6Õ+>³9¡^šd].aØÆäÆAV¢fxAA9é l;/JÅ×09vw­f CO1 kÕqãÚh…x}é;8p~H}vc›DW¸‘&ñ4sÈ]ÈpéÛÂÆiß?‹½ßäàk{·ñª½sºq´ùú7;I1Mš±zGòáOö¦Qç2»D>>ÃУ;«ãsTθ!šI@þE Ç’’ÎdD” ßÐLÄt~(Ñaל!Q©u¡¾–8㋆̱á7VjRxøñG¥‹™¡P@윔>øJ£D­P±Böö¥3¤(=r~]†zeñºbï!täìûƒ“®ïLΰ0ä}ÛZªÕ—«^isé»ï¾+daÂFé5¤GèHܽÐ3ª§õqûxä‡1/M´ŒÑíþ!ÇöÄq‡E¤wÚƒ¯%舃‡àeôS¹kß-½…ìåîÁæ;û¯Ú-øm·Ê&vAmÍ[œ—ZÑhE_¢è[Pè&øöæþñnûfÍ>AD0Px€âÝ(è ”: {WæÀÀðHÒl$iš¦%È«è7 íØn¿joï*P‚•õ¹ÅŸe>{VíkY8îlŽÛ W¼Ü9£~7ME„^S}/êHõ ˆ²M©’{ÖT,RÌããå%Åñ¬º¾ÅÐŒÞ TG—‚’>Y 3]àÍ®¶uq±"º ®›½f²«ƒÞ™Ï˜¸ìZݳƒ·ÒO©Fk=8<LÐËà eÕy’¬È› s«kì 㳆…:=¥…mƒ°‹¿õž¶iR•ÞA¾ÖÎnsÿ¸}ôf·ÙúPñ’I¥w×Aü¡Œ@»aŸ}q°(X\ÎFþ ®¨m¯Ú›?ýThü„?€ÛÞ!@i·Ž·ðµ^G `ï ÍCGSþ8]ÌÝcÂ!´Þ¼D{º—Ç :l5Aþ`‡Ç¯š-‚{°Õ„?o›GWMJxÝÜü¡ ¢óù›j66íôã–•LFé¯\ó¨U ƒq÷¤z2À rÇaõÜîX•ñOÔê¹Óí¨Ö…o{þÇE þvðæøðÍqá¶þ߆þ(âÑÅç9€›>ÿ—ž--=Åùÿìi½öìù3ÈWVƒ¤‡ùÿ‡öÿÆç9wuÒ•¥qžAébªÍ=$~`Š—rÃ5z©sÎð[â$3Õ_®ú ¾.l˜S5ë„ Fà6†£^¢ÔuÒ¯ú~ v=é›G—ŽFã›ú ãRf4ÏÎoÙRR™—¸TÓ–rÚVg€ùÓ²[gÊsó2ÕxœÛİ+ç±ú4Äe-ñ×´>Gª¼ëäu‹×É™çñwõœÅYè“ñ¹‚½#häStˆ†R½z‰›ö»Xú\ËŸ àéçx– åµ¾Aƒ”h5@Zªx¿ÖŸ/UêßWj•ú§<›déÓͦì™Xé œ´>•“ò|±yi³¹^³§|}M k(ª,ÏS±:0rî™ Iúw Š yOÄsû¯Ñ€?a4^8Þ”‡£­‚ŠÎC…(Måú‡ü6¶äaFõý¨‰úC«(ß “Ž%çæ`æ%²Ô¬,0i̦çÒSDgƒ/Š©ªbÏUT’+Å#ôÌ ñO_b–¨Ì©H>¦r%i]Bk½Íll§ïDZ·³¯0kpÃë_³£#u;ïÄ’—aøª QÄññ®[^èmDÔ(q½(*X 6V¹ àï3ÄòÓç°´K„ßÃÏç9‰ <ëôǽáç #_=tg“ ÒräÌRAº(y(…ÿ?«xhÉ ëϼ­d?.Ú#Ü¥{†‹¦Çwy:ÜÔÚ°Æõφ°ôÙ–ó!d¯ýc%ÐÔú_ŸMˆÈœ ¥™-ß hy@a}e£pi:™š.O²|oVí‹IXµi"V­¼vÆ\IA,“øîC{6M c.•)†%š¥Å0Ï4Bmm-Yú=ZÂ|ñž[²ü{´„9ñç‹ÆµÞMT¶ý±·á„bþFœ9~3åï¼³VÄt³&Ö)nháüoÞÑçl…óûú›êú}ìÌ—nØ™Ïdy åOÿ}ZÒ¯½µçIóÕ¶öÄ~§Ímþo½}ÐÜ,«8ó²û•íö"{‘‡½ÈÃ^äa/ò°ùcïEH÷ÿ_8Ìç+k3Ë•Ú×¥jdUzI´«èkÄ&3˜Ö—Ð#üÏëù5}-ok§Õx¹ÛÜ*8Gh²Ëc2µ½7#ÒÈ‘Üfî-çRÈ];ë®Ø¹Ø?•xÊpi$®ÞÓ}Ujºk­<­>ý®º¼T­¯T{ášW1þ j‹¹ÉÝôãoÄÀåÐó#“—î-zË®Þe{W¹Æ>È Wõ ›œYºòó·ŒÙ|Û´eæ6ÞÔìëæÎþz“ñK7÷x4 ;>^ãÒâF32³ytKÞ˜ÜóMy|xaãOIæÒ<ùûê(·…S;ìÓ+ÐÝy|ô¦YBr½BÍaï·ß¼D2Z¥Š¸Y÷„»‚?²ÑQ2ÞÍHïÞ…„µÌ,1ä8_xæ:_˜ÕÙÂ4Ç ·‚¶Ÿ…¯Õúáß}Äÿþ̰߳Æÿ~^{¾ô—úòÒòʳ•••ÚsºÿQ_y°ÿþÚ“iþB¦ÝÚ;Þ5àûÀ-õ?å‚Gs¤ƒŒ Õ Î&ƒNï7·^:§åzDf°iÈMª7“eÌUŠŒ8ä:–¹“ÔïH|s¯\nIúý,Kx}m—®„}Ë÷Z¼—?7Û›Ö±vQ©? >v{£v©[Á[„ôRê–ÕÍÓdñ©¥ðYof0¿?‰`p.‚ÑI£·ÂSª\+à22ˆ:Û¨€ägËä±TÝ‹3 dÜðN¢ñyûÔôú½€îjG;ÊÒ§µ¼²½áÅS.{m•œš%+È(AÏC¿Ge+¶u#n›ÞQ7P7^©ÐÀÿ´%}ê¥re¶Ì°~ϘwåVWt!³³²›nõöWjø-±[¹;vwï=df?¢CÝG0CÆèÊay“˜oe£“ BŠ-‚w(j­psK5õ©æÑ$ ç^å§?–(¾ºzŠ|µÍÞ-¤Ùü½ ûªnvúÂe8]c=do?F£Ž‡åᢒvÀH).Èž:¦TÞðÐóVp5ù§ÝøÆÒˆ ®PNüRpYã$D0è)¤ýÄi· •áÕù.ŒT…¯Î²›‘–ǽAp‹Ñ˜Üä_ž£‡š·ˆÁhè  º?¾P;€‹,UqgÔÂè™ÚéÒ%…Lš} ¢°¹ªq{«ýæÑAé± %r´N$%[¤6sðXÒ>yëV%Jà-w.E×ÚÙðØ»„1ƒ ßéñéF*†`ëÜt§MÛÓvuà êh@2FøCÀ&ÇÕ‚#5¦žLÀÙ[µ‡Ð{ùà­êæ>tE«y\’¦©úF>6QØX§>2¥uŸ©wÂ\Öÿ¤ø£ßN>PØšCÃ3ÒD4‘Ö/ªã  ¢Žò £’&œ¦? 4x°•4Q *óƒ>^¶g²LXÅÓŠ˜Çã kü¸ü Û-Áépý†ÎýÆOˆvÙÃ9ŠÑ ú¯Ý÷aQ^. Ö­ß \’•IåùáµîîÞÍñçH0 J]ôºÀ•:~¿ÛýÌj¼È%³êìÔ‚ý³Óʦ›0®¡ò–“Ä!»Oh»ÑaÞçðFw+ŒŒg|.¾ßcUaÄÇçÞ†ø˜±’`›M ¬ô7¯|‡0‹•(X£ƒ|õÝ]ÜS9‰>4#VN<tT€Ž‡ym4<ý>xòäF¨¶"€€ØëˆÒè뤓DGSòkbº0…(A¨è§]*|L–ôv7mlˆò’l €ŠÅ’ü¸° ‰ë@–¯ü;*Ÿ@ð%£sæÝ–øV°§ˆRV35Ab‘§ËÌD;0iqÈ‹˜™<Æ0ì"&’—püXIçÅÉX¤øþší&Â:iþäáæÀubál´wÓ›Iîg  »³`Ýñ—h²ª‡‡ŽÊð#p»ûîUnI^G$ú©éN aœ«Aqw=ÜšÈf`á”Ù£ü¸’•$°ioh««"w [ 3žÇLEzUÉ…ºã=@Þƒ_‹š­®šgâ‡,œ‹ ØŠS Î‘¡ªUoÒ¥—v‰’*êc»$ÞßT’•òýÒë¶ÑýŽò[¶ C‰h<ØÃ{ìœet†ágIWÊ£$B\–ÙõBýµ[ÇGÍÆžò fë1Ö,[~âPfÞcy‹â|)—QGÍ7­&nJH¸fŸÿX@j‡R¸H¨è»- mj5e„‡ôžéÓÒœQùÎááÑÁñª4*XŒ¢Eí6~¾uå‰î}³uC÷ÂåwïÖ«£¼ÞårºÂ—=h.‰Ú&VnM1˜pHÄT^£v÷ëJ}ˆ¼¥üµA†Å_æƒ`½VzÌþ€j&„Æ‘a€ ã^hRCâ3?ÐŽ[¹³O1ºû?'‰Ž³ÅŠÊÛJêãéA'7'èõX g)јù²`ž¶còAÐÊš¹²ƒA­Ú‚ïHV„qR…Ó4¼õL4xC’Á›Gó3ð&h7áÄhðV8¥˜½u8aíýqH¥æ4¥¬Ü‘TVR´²’³À™/e f ɉŠþ`t´2+!­üÑ(iåR*LY6µwf/'òþC>Ũ`m+î^<-ÂÒ†+ÅòTER²zì=”ÜâÚ«êrè­ DaÆ ÝPÝZ¼_õÒ-+SýšؘåoÃ>–+¿GìʦßCì´ ¯uÊ~ÅeΦéüY99âì4 V1%ÆüÇ’cD¸S{PÚ~baØ}¶õJ#¾à»eE0’b‰ ’¢—9%“ÙõŠäµ½%Uªýf]‰.{ü.k-¼+Œª§ä+J™éDèåRÙÒeíG ¾„ª°¢Éõ9Õ‚« ødê]WõÚ¶ URN`‰ûovwù¯£Ç ÌŽ"ÃDdï'°Pþ7£ƒôe‰zFJÐw8½gÚÜ i¿Íï^íxv KÿàsÓØÃ"& ŸV¯1¤ûg^1Œ¿CLa“ ›I™(ˆ ž÷n©öô»JªäìÚÉ!*1ŒŒÆŒ¿Qz-ã"’= K)—ŒŠi>Ô42óÊœ€®9t'DkíßMÇa¦!¶‘N,Ig‹Ä¨?œg½ù]º¬ ¡kõ‹;•ÒZ+ÞRA‰E‰¾1ïñV’JáÖ1k˘Y/¤<*d¹ð®öË~WöžP—½«°‚­>Y÷–ø‹,è7DYà@bÇç þ£? îV‰IÉÕŧáµÉc»Q‡scØÑ;çÐ ôÊÄkû°ÛŸœBöTˆãÉ€•Ül˜Ä±•/ƒ~]gÐA­ì¼iY Z‡õ|’ΰtˆ{Èö[í×Û;?5·Zÿ0‚úç]‚qÁ ÁþFl k#·wí¿ïl©`·ŒŽýíˆ?9>`]¬eú7+lÞiUppˆÎþL%aÜŽÚtígZmìS¤ ;2˜*ÍYHEùÖHþ}kóàÍþ±Á²žÜ›#p)(«+Qu—’8: ï†$3']ѺÌ3¯¾¤Xæ/<;iÂQ²võç×î : ÂdÖ^ñ¡5@Æm ! êaÃ$e‡Ÿà‡ËiúÆ\˜õ2ôX,vŒÔ±f¾¹µ¿Û0(ê–?±S-‹¶‚J„ލHîÈÁûžˆOg]R¹ñàþ’fBÄ‚p˜€QœŽA2¥êf'¿¿¿i¶ŽwöÛ›»VKš(v/¼!’ÏCˆyÀï8cЬr$!ÑðètØ@×}­7 þŽp”“šÐµ¢°dcEÕ"¢f"Â>dsÚFÀ²QdÑWóh*À\õ8j1EÀ·¬.p¥õd%Zz_Õ»†rF—%Ø9Ë´GŒŒQ¯+Ý9z Î@hN”¾GGÇÐé}ƒrÞ°}2ZLU/‰óg}H‡XQuWd\³´·¶ˆN§˜âñYÛèœ0ñ&}ÜÛ*‡ýÉc¢H­-ûAï ,í4~ŸºUPÍãýB%O6U®¸É7»4?ß&ÿd5þ­5Ëyì1G4ÓAëa_ %êŒ ò"{gˆ»÷1Œ.m1e‹s8 PZA1á T â ô˜Èt"Ò¶Ø‹:hZ¨GO¶°ˆö£Žßç î°ÝÁÊ;“Ñ£F Ñì‰hµ=;‡¤Ëáz íÁ|ذj‡êÞÄœ]û½N2ÅÀœ8X¯ä;r É² ±Y!£!MàF¸è0ètºJu(pXNì³è8?ŽÔ>@¡  2+6¤\B”½ [ñíô´¼få¬[91£•åíGl÷a§/åÛ( Jß)ÏÆxxÌGÁiïŠU#K ´ÉñÚ¬±:m[cí¾ÌH¬åðí Îú«ê_|}Lêk@ÔÓÕ¥æ[ù“Õíjâó‹Þ!äÄïß×´AF?Ž`½ˆPäGÛ¥ BÒèâ rˆ/œé0 «Zý– ‡gö§5=sôÍÚq”Ø2®ÊxÛ]hÆÔáÂZš‚:_ȉûò§#1»†òM²bìB± úÑ#ŠBØ©%Â9ãCö$ÇbÃqÌÇbû½N`xnìefz9éõ»’£Äª‘I(']öù× ìŠIóÉ­H¶b‰¥‹ÔÊ|À5ׯ±¹¾Ø89ûÔÊIØ›^¸mHEt?Áý¤Oj4¦ ôzŠîÁêpŸ·Ñ‚ƒ·øƒè6ûô­\Nœë6‰z-Õw‰VÞ¸@9+•`?{!6.ˆF  Lå3HÍó¹…}ºÚ*D†J‡µKQ A©áц¶årÅ™vi^Î_= Æ0c*:ꔺì¥ê¬Ê“¡úîICª7È‚™ª›ªHn :Ãë’D½2=¡ôT”·œ:–QG"œ·–•]±õˆô0–‘’˜ÙöFñØÑŠŸ\{›6Î0êu»ÀáN‚~tYÆÖ!ô*p~u ¡»s?Rì/Á #dÝ><8:^S…Zf.Œ'¯\˜[²sJa|ü>&D¢1¬M!)<zñ¹2?ÓÊ“oJ üc¯dÀïì5Þïµ~K&nÉ838<­~V ¶L|@5•oÆyYö¸™¨ÀG;ÍV§›Ã.OAKÍŽJø£Î¹Çaé;X¢$¿[Fiç×"ÑŽÜÄ9rv«Ñè ߯ç½Q·z]?­MkÔÖÁ^cg?ѬPêqZWMjIb'JJ~ë¼£WüÊ©2#ìà›Vóíf>hÌÓÒSlêÓ^ØëwSAîœwÞ T}²/ŒGÅÀc•²R7D˪ãS .à’ÝÞE¯;)gZœàP´Í!‘0Œº°ÑŽ‚„Ó¥i¹™8Ùi¥eºÁXTg1ì9a` ÿâXOÉS¶ °€íÍcbÙ:6Á–51¾±sD²fèö˜ l@ 領-ò}jÍö'‹WrP¦(é˜óYlQåa½d5*×ZCáÛÙðçiÒ¤¢võ|›ìluÐ-·íj=IÀY±×–ä7sðüRm·VÚ“¾{WöA™ú¨>U”&]ý馉„—V %[ÖU4nbn#öçœ$­“º(MLe¤é×PvhH;™û·,Ú:Ãֆ븡lW‹é]¥ ØðL<ËWÁxvîZt1“_[òN›Zy§"bùG™ì!pr¥åûL¡ó?YR§9iÕ(«xttÅ UDѵ۞OVPO{VeêRhLW$Á×Ûò"»8ex5mûûn¬6Ÿ:§Ùrš$³ï´-b»±«’J5-û›ÚrS+WAŸ©ÏR£ ã$ÖjqRŽð¥š><žSPNêÚL+ÇBÆÅ²Byœ7†ŠÂX¾mIÝ@._ñÚÊ´›JF|5ð1¬®ÁƒK½xQJ|Ðqç^CÚi ‹Æ{!ŠqRÌý:§wجnìFa ;œ3µ`<‰-• eŒ)µ]¶f |A÷Bi3+†U„A¡jØÆA¹¨hGù4g©7#¦#Ä¿BŸÈCÉ §‡U¡²n^Ê@5ÈŸQ/h @IBS9ú@ü&Ÿ6Î阇³àNÜÄÇŒ2iZuËoÞ’]’“§™0òyÉøæ†ÍIþ¶µ­–ìzaâW4Ñ7gµžéƒDý’œÕ”>Ð &Õ Yd3²&Û9³šaG ¸+Ÿ4QqéŠ] «ætCñ»ÓÚZ‚»ÞÜ^¸ël"{LxdL!b>—ÀÍÕœywøb^<9(4§®Å¨JAµö3i ™Û¨ÿ8­’›ªr”@±ìvÉ6 cõ ¾fu Ó“aÏô3ÒŒ’„2pÌ;÷U ©]ROŒ-F±öæOQ/ C¨¿š®-^þ}ŠzèÄf6ãbª8W°ú›ûSAÏëâLóA´­8%[ž’j•6¨¨WtKµYÅ©m"ñ¸Häšy¶ ReÑj¶v î§b˜Ÿ9òÿq‡^Ôpa¿~ÔC [ep †°Ä•œÓºÞ¨âß É¶‡AK ®þP —(»dIÈò,. Ù‚Ôã9fvˆˆÐ²<•n ÆUÏmºjŠ–™ÈGY±l[€u½íÆØÕÿ;Ø9X]µßKI¨çeoc±\,âÒè-m<®S§…î1L.Ô.¼ÙÝÝÜÛZÇߢMïÂÓêzŒÙíÔûGŒV>èάëÅÃ~oL·F¡/ýZR|ôÿŠŸ*¸…ìœÀ1kCgã•×IìŸUÏÛêÅH–tçU£ݟØ,œysâÜúþα¿ˆ`ÿ ýj÷à%ì›_¶Ž ä}Sv„ÿ,¡åÊBT†vê6ÿ½¨}[‚<óÃ(î]Í—½UÙ±`^½µ5É£¾BJ!ˆýNá´W(ü¸ö×ç sJ(`7\Hç/|ÉIdŸÎÈÏòZQ¦`ì=÷'ñˆ¦.»«"È s­Ï½ÿ:ÿætäá¦ß[Љ|Na;è{f +€öN&½>t™ÁLà ŒìŒ–{//œüÒ“t[Á¼$«4£»ôcêk˜ ™ã@7£Û¸ÇçU3/þ óâeÃÌ‹GÖ)zïi|q’PîâOÿ$¼…F{VmøgÄÜâOêµèÐO!2–A´@Ì™ôvh¾„ô)èÓT»âSï¯ñgU‹Þ‡YÕâ—95ET÷@½%¢ÆIçd³##ÿ«:ÝÙÃøXŸ‹ SßIÔ½^Ÿ#gŽ)ÈÅGõG4[h;8&óbA66̽vNî\ýôþ}©:ÿþ}9 Ø*¢Î8Ggë´#Bâ Msü7_4çË…ÿQ5A&·.ɳVø„ùÏd¾êHõ-@u(Á•vN½v£Õ&„lìþà]"4ôø¨‘A`‹‡dÞ.ŠNâPê¡%s€b–s!'=b9À öÖãk–3«å$®½bñBémôëryN¤ ƒAûv£è£r_ ݺd%4¢ÅY G_ró ×Ð[§ëž¥5ž£´4¿{ÿ~ñüWöL.øNlžcÿ"h#~àÏšGOî8Èßh܆Ê0}-t#€@™-è²L/&\‚$+~\¥”c¤s,>ª©L AýÓIE‹G¢0(¤jtå"¯n¯K¦×èÒ%(€ -ÞF€ŠaÁ<1¼ÆŽ¥1MB¨Úû'P÷æÁÞ^ckÀ@;I(c¾Ç#D@Ñ!OË(ÈËöPY3øê‘n ®Wö¤Gç„*ñ·pʽ!¥t ÅL쯫è)ue?Ô­äOkÞ(Àæý‚°àŸÄQEtò ·º7/+š® WzƒTnm{hÎA“AjÅ h¶úD«Ü!è<šv1¥ zV…^0 –«5ïÍ;û(¾”œ_¬V!è4@–ª5–ª½âo¿ BEœT“!zëö·Zlg˜Þ|MŒTDEoßÑ ñ¨i®TšÃ›8}œ• Lž‘õ7é¢<õ¬ºT­?­*b†æâ7’xšûo=üo¯±³K„Â=ö´Œctõþѯ¸qdXì5”‹P*òJÄ+<ÉSöt›2®“󮈼[õõ¹G°t¶–Öç6èáéúÜx€–íï¶¼p<(ìàFtw³ÝØÝ]ßTâ5¿vû¯Þ4^5­’‚06·°qÕ‚à˯Spä D&1ÞQ…ù3ÄLE‹Þ( öΙø_ã”È/ÿkåN8ÆðIð{Šæúl¢!«{á$šÄ07˜‚« 3á­’šÁUK»‚…² Ý“  ;YÈÌ‹ä0IÀ]ÍÄ̓ýíWíÖëæî.·1·üzé-¤û…b-2ç®Èûˆïuƒ6žäõŠ\8÷/dm"_žýØ×©]// ¬À’±Ø©ß×hÆÑV]LAñK’ßýq)B3Upâá Š®zl^¤gt•÷thä-\è…+å¦/ ÂÒ8ШÔ¬X×TQpß„zT¾)ôcO0YžhyòJ%^¡.æ¯æA‚ƒ¿²Námõ…‹+Y¦É’z太¼Vš^p =‡hæa&‡íš9ôW£;€µ=èâ56øÿ/¤W\wÃ/›Ç½5ÅÐfìG>a”‘9ñ{¸ÓÅñä[#¾:Ûø'¢3W-X¼½¶ÊÌ‹X¥¦ý€ùx‚†‘CÉÓ°MìeéÙ3%žòÚG“ ]¹3ÖLƒCÿ 5¨P +¸ñäDn½rå–ÿýšœk2Љ ñÉ^í\ü Þ ilÚFc³^´41ï‹ïÓº˜÷¿‡2æ=Ž=¢óÿÞߣBÆ:·>'3éeÞg*fÞ߃f¦ÈCƒŽ @œì®™žäˆ TÐY=×ûGõòÈïü=žtÈ :epŠÔL&$räûéLu“ -nhi8˜ÅeC) vèhh½–À VÒ_=ýu‚8ÃÜ<<«iœq#”WXå! A×)o7gv¾vƒ§!bçs‘A QLÀt…×zY¼‚9Š„X‡‰VÖSIÑ^ªZ$(dÇ!ÑÙ âÝ*’•’“d5#ñw`Ô‹ž%ï%ÆØ`ÍR¤w܆Q»¾^\s¾>²ßíîì7÷¦ä(Ú°üõ÷R¢`×±tu,9uì8G~_„n±p™£7Ô! P’ø¾ä|üXíª0+Or ¡«©÷ÿ|_ô¦ƒœ³EïØò˜ñ£_m¥ bЀU@ÍÍ×_MûÕ”¾ºeïáOÞßYóY¹IŸ²ÈÊmëE‹ž˜Æ_Ìfù}ñ§÷–ÚS€ªþIÞ‹Þû÷²–Ãð$ Š¢6·h99Qß?*•¼:R”W.Cæ%wÖR@¤p ÔR’¥y¥ò HlÖœë V'õ-Œ $ÐhYÿQ2 ²€Àr‚ÆÂLÊl4¬ gPz EY{B/%t ¨KPg‰äÏÓ–h$V Z«‘€þ¼EÔ¼Ê}E”·|Žìrí²ù$áÙH=” EšãzE§?Ö.‚v rM‚{—8±Éïó©AUŠ"îXÄ(h¤Fùö«4I”½¨éÑI®‚(Y„… 9Üÿü‹Ÿ®Â#%<]jƒ]3µuß®af“¡-ª®ëÙÔI(Q‹fBÊZn‹)¸¼%$zø?V‹º­'%¸M L¤/x¤YðH €ˆäNïSšÓõJôÿœ¾çšfíxÞƒeöúiE™´–ÏØŒÞ´µçm3S;kÇ÷°›ØÍÿAvózÚX›È³×=TSi:w«%û±ú"è—™P`ä½j­Q;ܧƒ2…±°ÈqGTÝ@â׸÷ek™jÑYžSR£ÒŽZÊ6·š;~ÜëÀî}TÁ“hÏ>o†³¶Ø§éÝYÌsx“áÙÈï²Í(‚yZ]®>ÅÓmT ŒQ}:ê>ìHÀc>f?[ðňçÿ…ô®ÂKN°ñ,Å€§T•Ž—ÂkVÉãV)îáÙ”B¡v0ˆGeEm]Ås@T€Æc¤6_Šð4ðà |ºÆÃ‰‚X ÒàtÎõÐÂH~¨Ø NLƒÚ-‡–JÓÏÿü«M‡ bõI)Œ™aª“¢s<À3c±ø7‚DÚ'ÔÞì£S<~¹P„>•7ww6vŽÚÛG›ÍuïÕQó]»ÀH·Ö ¢gvò8Y yÖAŽQQ‹ºb[Y~N³*âr²Iæêß6Ž ©ÌÈh¡;è¸Hg«ìr%¶pý•·{êZcö¨¾†Vë—Þ×­B]7™¬Ò!¯uÜ8~Ó*ä L¸ 7šGÞç̽Ƞ”Fn)S`?Ñž<ª>yéÊ BD-ù¨@Zsh.Á#¯ÐÁsX\ @"€µqèÕŠHÌEÒLE¶*¾Wmý¥à‡Yžˆlî6P"vǃ6_N&QÆã6ß3òµQ£Úó™šÃl Ô™ø£k…«TÀèf‹âž·Àª$»/ÊGZÇD€c!¬k!ƒ[*¢\¶¤ ä”}¤ÄëÖ½öU’ム²Éx?Ljü‚˜üÓë¸Zèo@#^œ[Ô[÷¹¹Å34¼ð¾Ó€ »5–Hj£Yœ{$¹çZqÑÉøÈõ ÜÚÁ+(*7~2É«ÞÜOhäñîÿ[ü𾼸Høßüâü£9ïýoÞ{_Sß—1×ôÓ¼/ÓǪ-Îj$±3­"¿‰úµëÍ-þºïß[Ãó£Å_YÚŽ¡úú"?ÿ‚?ŸðÆBŒ|u~æì3.ß2^„ÕÅ5ï—¹ÊÈ¥iÖ:‘—3y“ÏldcCÜE¢l‡&>™=Ib:Èì¦åx]QÄa±Â5æªL¡`1Å,v†¢.[0±ð¾ÍTþzLn~OùbŠêhn§ =Ca…ÎÒ ³à +3[­zQë\A¢Åw‡™¢_ò/ÜÅUþÛ}“.Š´œY1rUdTFmð£x¦ ê=q~O¶$A—ó,â î…ŸÎ(Ò Š4ÌßÑ™Ú@69"¢'°KÏ©`Üû7¹a è—³Qt k*8؆d!ÍM¢k¾ 8ù§ñõ°‡ÞŽ™øÝú5U$T/âú½ Ä­‡wµ@L¶¢÷átTVËáüúÒš>±—ãuFëK¹ª)ÖÓ:ý_Âk,Ì„eY²þþÚM|š³”HÓ @þGu)b—现¡Pª Í£WÕj5s´Q)+ <Ê;°¯°–‰¯‚Î`èd—Ç,têª3›© aw?:‘ÕÊóлŸØ‰z>]Úf%Y¯ù£³ ŽZ` &1ʸäꎦˆßì=*á-/·1Ù£•­Yœmh¨£¬ŽæF¬#°G°Q,gNN±@„½¡æCÀk‚_¼ú?S†0 K!ÖÄ×<::8òÞ±ÎßÛ=xÕÞÞúÏc²÷€· Å¢ÆGµjª HZ9Š¢\E·’Rv0W‰ÆIdƒÃ‹%*•lBˆÒ…ó£7d”ÛÃÊ= N6%ˆwhˆÃû GÂcwUuÚû‘•ˆS5Í ©aƒ¨½! mH¥uõuMt’­n[Û>zš°˜ås Ø·èç…â£åâ'ëøàt>®'ß%’A”¼‚U®á|Òƒðh 7Ɦ-Uª´›qIÓ‹­º‰6÷ÇœDŠ>ÊïK>ŠiÝKA­¯ÅŸ˜rɱ ©Îƒ¸Q­B129þ©&&UÊÜ2¯ãkZPš¨´{„AISˆd‹™ÊU»““¾Š©óbÑ9ô—lëêÁª_sqP¢%.þÓªZËÐÊŃ€‚4 ¾üZU«/¦f>Kí¦Ñ"ÑI)‰z|ñ}Éuå„ZË0k·-¹6G®„‘v+žMž\¼…ˆ¸x!åZ"øú2‡ÉV¤Ísã,#ïÈÏPg‰$£v?ãññúœÒ©äì¼÷¯ýA ÅãÉÅåÕõ¿ç$ënóø¸yÔZŸk¼ÜÜjn¿z½ó¿?ìîíþý¨uüæí?ýüU >r*yäÀ‘¬ÝÞYo õ×êKËOŸ­<ÿî{Ä±ë€àB¤„¶O§)FlŸ2g2§³.ÙY­³b6Õg»êÔ–4Üη%ë›9#.^1‹È‚k.OØ@sj÷ù­÷²“a7¼fÕÛëìùç0¬¥ú÷Ëõ…ú÷ß}_f]wЋ½ø䇫ªç­.” L± ¡˜ß9À»G¸±‹¸ó^E­MçÊÁ‚É´öxaQmFTÈ&™ô·À~c„Ñu*d1)ÑÞI$øˆÅp_Hfàh÷-Þ%ÝC€~Ð ÎS M¢p´œ!¹<°Ӟ¹,  Š»Bª^X~ÐІOšÈQ'¶»êY—d(‰ “N„©žì²³êûè‡   Òª(ÏðÚ;žô·7×É`¡½/¿ÇrgàŸêæÑ•˜ÑyÎB8_Ö÷)ÇÜÕõûÎæÁó™Î|Y™ûŸ¹µµÿùV^'ì\´ŽóOÈ-ˆÏÕu™­&™9¦î"xloÄõ|ŒÏ¿ûŽ ¸í4€ØWªõzž9´’ƒ<»zQµÁ¡- [çÔáQ¶Q §tGöÑ#ùÁÃPõˆ›{s%®«’Qõ¥D ~X´‹Š°‘ÌI¬1Iöê/—JÔò ^öE6ÈÚ½…ØFZ5)+?/Ea–=*7'öÌ 9ÒMA¾IƒÆ—‘wa¸âUÉT/{¡·×ú¤ àâý“ëæ`£¨ìCÚÆD“‚gcU)¿Tö¶þ÷Õá!FÀ¬ÖžÒd^_ÐãF¼&ðæ„íQÇ2‘¥|QÀvBÆ 2®ØG³*<þ³3ô†Gs\(¯§’c eÍo¬¡CÊЗ›t' |:Yⱸõ@ôÃÄ­½$d #¸ºáÓ Tœ J‡¸ÉGN"2¡. ]Õ¹ÄÂj¶õ9U«ðô\M ê"|†®åjñÍ…áÈâX¨}µ>'*3¾|kéÉÖ3Tgt.š†@ßQøC<ãkÅ]8ÀzS7ÉÉÕ7jw†Ãõ"‰_$€\ÿuÞ"ÿz芑]‹ÿúîÿkÛć¿¶ÿz6W¼-&ú²„N|žÀæÉ_‡ÃiuN?Î+Ì÷­ÿÝÚ9b­,®ˆÏ_<®y/ÌÐSâ ì¥è¢‰¬x¸œóTHÃ_^ 1êüòIhì•Zo–«K/êwÑÂân/œ\•åÌ 'ôItËT`–,¼£ Ëá„àã˜na£ú¡ÓV5­ÿ³¤+´9÷BXv7NÔUõ_p/‚w ×h+•ovº³N¦Zl ?vúˆäÜaÞÉHÇ'ÑÉ¿ÄkwçåÁËÿmÁb‰.²Šéÿ:C[5öge÷(Rü6~hÊ#b„N%(`ó)›`¬Z<.66h¼j¶÷{M˜ÞÆcÄœþtÜ8šòUNËa…3i­ã£ýWNÏúüò ž¬;…Þí®ÏͰõŽ »c½¨AT;¼›µí£öÂõ ¿=© íq7@÷ë0wLÃÈ'k䑞ò®ß¾•D½éõ¢êù$Bïuã- ÿs‹¢S¶Ú¯éžÊ{/¢§è˜òã>ó4U 5TéRHnéB­ã­M ûÚrJŒ»0ê”ßI„2 y|²j>ÞÒ z³ÁH½8Ó81ƧÞ7¤¢B¶QC¾©Ò©Ì^sïàèçDmƒ`®ÚlTp´òºPHö5û,Ì)²³œ1>½pÝz³õì·[Eò`ÒËý‚úÝÝ*l#*4é/ýiA/ápú¨çnnZChÒ¨W67¡Y{Ðkz@:žÈuóïJ4âçÎpBt¨ÑÅ,ü yø3Ñ“êÁ‘#ô`½î òÓOøA"#øÓOCøŒÎE‡…Ƥ½vÛÚm´^ó«Ààg*Šù…â  6ö)péX5ù§Ÿp<¹ÕšBúI?̶]PÂvã ?Ù˃ÖÎñÏN"¾¼¥Ê'áØÑþ6ö`ý¡7X"Q¹×îFc«ã6.q…Æ?Ô‘ëÞ€lû°°³Œxw—xËaûðèàÕQc¯@o1x!‡–ÈýíƒBãÍñ³;zd¸ð€òL¡±¹{°ÙØ-È:§–«ÂæÏ¯øâ>wX<êèz·Ç ƒÄ&T{¬_6Ð4tK×´˜:ø‘‰€Ÿi’ñÞ’öeÿ ã²Ý*àÞ¶u$CôÔC! 0Œéo÷º=ü9úøÛ O#JŽ:øÒ’ 5Ô á²è ô[ Ûè k^¯cœðÓûêwEcA …:ʉá=àW~Äi œ~ãÑ"“(°tD’ HJ¶€!2GR,I 1޼SHXÛ³Åç/“hÌæÎ‚Ù¥ ï 6…FH;ŽöÕîœ4RÉ1zr·G“>^4à4åâ«s-w³SÏê7´‰j²ö$'z[ˆ˜?ú½«vQçÑûY8i÷ g UF­áÚ0¢%s'ºP_ñ¾üA›û³  ô >C§MbYãlµ(סhâŠ(î@ô¬yÆ&2MÍ7³–Z2hå˜cßJ®Xø7æ€hºurm‚2’ä׷σþp]¿É%LÙ -‹ÎB4!à!M¥Æ`§)¦:Þð£ýîÈ_#j÷0EP`³8(ØewR¬õ#&ÙN¢ ðìø@3,纻 µKØ?Øo¨͊‰u|ä&ÜŽ‚Iͧ¬´xršJsçÝz\¹‚ÿ˜d×ák¦†[‚øí^/\iš]µ9þUO%Ð(q²a€1–ÑcC³®§œ¢1)lW—¤žÄéÓ¹q€¦ÊBÕî•ÅÓ(­j}”­tÂu„OW‡Ã(æ^? (N+ÛÌå[;æeMa;c¶{å1«Š×hf'ˆm ²Õ‹2;–ˆÏ+襮_ñ‚q§ÊÇß~§ I¹5 /Ç’3FcI4`‰ ‘{EDèÎo3¢“¬Öéºqµ,œs}îѯV >‘—Å]ScújØp*ƒ|š³Ù6fÒ+Í)æŽ_¬ŒŸæ¬À.]0—X*ìϰws×û+ 圽á7'ó§E<)²Ö+»´¤Î¹‹›ø¬ÒyL6g’Ñû‘³h|šSëf*?¦Ï©Õ•¾\(Á ¯“ÄK²›'SxϦ9³Ô§ðà/s"¤>C2ï¬ÑO19äKøß:_*ëÈÆ—ÄèÔ†N ;r~™½ä†…lÒ” NÅãäuÑØN²Gª³(ÄÐTðxÿÈÔk–š 66_ë!¹«*!Úÿõ¿¡…(%º~½T>:ò~÷ÿ­˜_çõ¹ÊÅŽõ2×)E=s`¥â ?c?K}ÓГÂÐî({›×°îÚŽ/õB`¢sv{þYÅdw'´¥Æ#ÙÀ……²ê=d‚~åYïýù’úI=ÈoÙék)EMëó<ûÅz6úi}ž!K¹Gº5®(7pfçI=Èo?#l($1EÕšx6úI£eeàF ñ)ª±XÞ«óF~w¬ëÙ<ê'õ ¿üã¶ÕHÒTƒ†4'?!ñ¯ ìœ ö‹õlõ“zPÝhI,é^\`ò7-ßLâUÎ!Ådm¡ŠÒÏæÑí-•“»J­Oó6çÍ~Q­QùÒM±Ø§.–ýî¾:oz $Áz6éV©zLËÔº<ŸÄ%•’L°A¥¹Yœ7ûÅî#U[F?±ÿ‘)¨Þt£PœƒŠ1_%óÕ¼*£¸³³ÿÉQ„k-Òá±7]°i°s€!nd¬š¤vñðøîÿ[xRu0ŠžsúfNÙð^ÈuŠªlÕ³+H4·‡îëV†TwØž|’0/¾T?,¶ϤCôB¡·Ÿ¼>°ÌBQöpNEXÌôm ^&Ó;®?™ü(cd†÷Q¢¥ÅÂÿxY§¹Š7'èËì4…ízi’"Qˆé)ñ¨žä71u8³Ì–ïæ-0ö‹yÖOšÞ9s©“DǹúI=ÈoA.%²|8oÁ³_¬gó¨Ÿ4®\.+w°ÌJõr‹I)EÐPiýÃôücOK¬/1+ßglKx[ÂÔe¶)ú}!ó]¯D:Éy³_¬góè”WòëÎ4'žnV2‹l…Â|óTеŽêÄD&÷Õy³_Ì'ý¤f·azÎ@"Æüæ—Ê2SÐñf0ÖP¥P!…™y6²ödak3Ú2‚a?È/þœëN6Ê5òÎ]Lï£y Áz6òt>šÏ&ª­‹À†[ͳy”§ó8 b|ŽFuª}x6L…¬ùuéǨ5& ãã>ê'5h¦hƘ‰¢€‹¤žÍ£~Rò›ÀR Š¢„˜·¡;oö‹õl-Ò<ë ¤tkŒv…Šä½:oö‹®ŒßÍ£~Rn»­Š¸é–šg>J2!ñî¾Zíçû³õlU'Yfõ)¤LòÙ<ê'õl6UmfÔ¼ Öy³_¬góhçÂiÌYEù“úÉER²1Ž¢Ëš·Ø/Ö³BE2eb"LU&óÕy³_ôÀò»yÔO©v¨ t[” u>B2!ñî¾Z4Æ)ögëÙêUMF¯(… Ë|³_¬çDsuQi­Ö4λ ïî«ó¦ ‹æà¯´º¦lnJ2Át¥Ns_7ûÅzÎè €ÕZ=ŸF4#-d¼NMfK¼»¯Î›Ó¿‘t³J˜ &õ“z_þqûEÊr‡ˆšyÞ‚j¿XÏæQ?©Õ)ŸÆ<ªS…rïv•œä¼Ù/Ö³yÔO?sjh¡èœP™é)ɦIs_7ûÅzvè'õ ¿üã’¤‹,S¦{è3ŸnTFZ:Éšª&5™-ñî¾:oIpÖGó¨ŸÔƒš.úéibíµ’úI=È/ÿ¸½él—œ]PúÅz6úI=¨änaä,ÚE{zR*E÷¬•˜xw_“­¶Íuëm$t»nJ´†ÙNOgM¥$LÏ9‡úù=È'ü¼¤TJ iHL¼»¯Ù=(õ¹=(–ó˜e%fô ¦§³¦R’ É”:ó{PÛC,°­·,ñ)‰¡ó9÷Ë´b9éùE2Só²g¤egM¥¸Ù0)‘Å}ͦ ×Ð$An×&1õqjÏO)<½hnÁiÅr åÉ,—=#s2+&¦²%’³ aô“1ÈD$õ“zßĨs)e6x˜·àÙ/Ö³yÔOw.—k¬ñsžÔƒü&ð‹-ôb ¡Ä³yÔO¡8Ÿ_0ß/“^À‚¤û¤ä—Ôˆ²Õ¥%õ“z`ÄNË’å,{Êšÿî¾jªR)ö‹õlõ“]T~ùÇírîxÛ¶g>‰m*%™`Í•æfqÞìëÙ¢?¨5Ö6^é-›‹ô³yÔOêA~Ý~Š[ŒØ±¿Èz³_¬g«eñ‰É¤ZçÚg¸æZ\ì†$S“•šLH¼»¯)ö‹õlõ“]T~êb/ýê¥Íg´3+ÑîU+=5•’LÈ€äfqÞìëÙ¢?èAvÛ“1Ö=5.ÖC¢÷ð‹ôYÏ´ËyÔõajF-#­¡K>ê'õ ¿ F–N¬Qç-xö‹õlõ“Æt”£J3vŒ\"çÕy³_ÌxлyÔOêA~-5õIk]å|£dBâÝ}µ)…RìÏÖ³yÔOºÏLÍé~c³o*‘|ÔOêA~ùÇm¿m=.=ÀI‚MúÅz6úI=¨6Øð3Zq¹ÅÌ™ ¦ŸÍ£~bÐÊ:ÚZŒÅÒ\eL<›Gý„oÝó+e­¾ª€Ò7‹oqžOþ§ùr5õxšOjÅ/{–OõÙ'ùID³Îñ•ÎÔP½Ý’¨°ÌŸÀrë¨p îŸ®Œ‚}ájªáÁ•¥˜¿²Yå•:|e›÷ê¼Ù/zu»2'Æô¨ŸÔƒ»à˜«,²Ü˜šeíÈOH¼»¯Ö‚{eŸ_ñy±~6j²nפ§ëÕ‚¾j#åòÞÝW N±_¬gó¨ŸÔC²ãLŪçÌ- ù$r©”d‚Ó_œæfqÞìëÙ<šÎ4(¤{“ÝJ;¬Âžb½¿ê½ÿÿÙûÖ†6n¥áÏøW¨‹[cê Ëi¡nK ¤<%!/6ç‰S³ØkØ{×Ý]8IÎoç"iµ7Û’æé6`ïJ#i4Fs9Ù^¥„IkàÉš4G©ÈˆCWèÁˆ|ž˜£p;«­˜Ÿ:Þ;Œ[ÄNõæÜºFªy7šÍ]©ª^¯Õ¿C92^•ä««¢:ƒ—&T(â†*–Èåq s'2s£•¨SìdoÿÕ³ÝM™€ý¸gä¿ãè\*]‚xÐXkäGÕ¿o=ßþt“ÒH(̘È% &MzjZÈTñ3ûQ'”I·H®Qq;3­[Ò`OFê2š=‡âbž‚qCr½´ E鸘èVo—˜ë‚5š‰Ýš©˜W2«Êº(Š*p.ìZgîªqü{r¦Œ4q7¡‚¹éTTö³lFõæ&IU’u òªd Í3gv=”¿k‚C!®¹Älê+LÙªH¬YN†f3yŒ„Òh$ÃFæ"'V½a’¿äÀ3˜ìƒe S?5VÎZ•kŸ"åòÚ ÅJªý*n™j}a¯áõ(ÅyI2Òj³ªúªå9…Ú|y.ýå9¥Þ”®Õ‘'„#Ó`)™¯Ýò{.ÿ“‡ ø^? Œ„…¥)q'J´ê‰Q²÷3²Ð¥TFsI»2zéö£òÂë‘hŸ"tû‰écYŽ0®&ŠB”ÃMc>© Tg!Fú–cçP”!Î-FQ)uíQ¸ É^PXißäeÄQ\t SWæœi¾|Çÿu8®°Ø‰~èn·w÷J°U<†Jš!‰¸”×îÛãˆ{ç] بû!e¢áè¢Ré%öäÚ5ñš¾ÁÀůÛ>jQÂ#üZ*T(ÃaÀ ¸ïISÅŠÓ8oÔD» ÿ(ìÔªÖäÎN;ó”4Ԇǎ£ÆdGHŽ}‡÷gB&vÐc¤‚l<˜ Í­¥æ’|r4¢qt%O &1ºÍ[ƒf–ÚO$}l’gQMGâ§ï†ÀZ®Yn ×œnÇä‰H9m‘Vª’ê‰ìEOWšú$ˆØ1,Ñ.ÝAØÔ8¦Œ’±€´}²†ÂOý·šq—…zchòÌñÔÿ¬)›žZl¦ƒÞÂÄÞ9¿9ЛÒDÀÌV‡z0FüJð%C#ð2ãLIÄéåkén݃í·kéø ||¥ S²þ;MÀ7-TȽ–0|×ãçȧ2_‰¡º×’¥îì©Jƒ¤ØJ}Æ×¯ãø'r÷íœ"Þ”J¹Q¡\‡B|k ãG»p¾Ò]ÓÉIƒÞ…A €[‡–e5ÙMl›+&³+'~^—3x « ŸÏ]Ý~nË9íîÎn˜Kžè8S5ÀŠ۪§t£’ŠU+%Ö°&{OQŸj"÷Æ â TâŸþ„BÏHS²uÊWž ©ð1ü:gä̓X‘9—Ää“m 3Ço`£ùåðÙn8É”8£ÖtÌüa4¯&'"Þ†e]Lì0¡ƒˆdhîT’‘fLQâÞK1ÛCñZNâ‹g<̭ɬ68æ5Ã%Ë"m,ó+Ë*²±=…Qƒ§Ö}³0PÒ‚:È8ˆTÍ):ÂÀZHÒÄGù}জ­hÕ$àõü‘TÂHõË€7­W°é0Ó^.›eìhžŠ‚£Aá51rò.TÀÀ^É9ó+E U(âk(Í\Ûp˜0 ´e¨h¹´Tïea®™ô¶P•S5‘ö=ß«Ÿ÷zâµXŒa˜!Sâæã Æ©idç„BƨNÑüÆà²¸H‚›2ÓŽôèððª+ä°¿g9žöýÞD'9LT¥Pg©¤q+Õ·õ)­Ë(e Dz}¥æ}Цô^K”ø½œÚÉšŒN³:Fw3d?¥ü›“°Èù:ݓöơŒ¼‘îÀ;wZ%iÊœª„¦ÔÓ*…9uÄ8,ª#e_- wÔƒ’AÑ©Kí» Ÿ–ÔþË®;¤ž•o(á6qe®Lx pÒÙâøå^ œLU)_Ì -å #è²q.idÔß+„W:fþN!ÂåBZà'/÷v„ 8'E\Ýú @¹Ìëó 0-)q€_OäÈHÉZg%+)ø9Æ™ì|°»*½&˜z²òîÀâWêîË|§MIXþ bI¹Ê©l¬„•!GW4ö©ÃiçÎEŒi³€ž‰œ€îÉÞ½„³z]å–áˆ÷µ\C¦ö±‘^sfÅÝ1QÂd¡ß§1†º[Z}a"F¸OIâ\Ñ89 )¹¨Çž0"¸©8æ¬Õ(m•\R“ö+žgÔj9DÃ$6Õm.*X¥ÎýlrNýø¡þcCÉxÁ%Vÿ” sTðZÒ3õð·YfÒ“I¡jê.Þ YÒ¸²n•nìø¦ƒoQ›oÈÊ]ó®Á¡ÃöTä«M¼¯2â4Ç×,]Lg®{/Ò7]iKuËß‚€¶ÄÇV¢M(@û,ßPñPÜ>ÈǪœrg[†±®†c…fͧÊÌA¨<ŽIÍ”8UÚÂ}ø£Ó ëœè†uYl «Ñ°Í†ŽW¼XŠAËëõL÷² Ê F»Í×QЇf£ñá| ÈèsC,,«zC”°1\ÞÛ¼Vš±›P—kòÚÑ,Ú’÷Žê]úyrÜ¥e>§8t‰ë ,±3wèF×›¥T7’ýRÁÿ3ˆB±À„ýÎ (s‹ÚP§oDåwmܤ§1 Š©!EÑh„Ð# º’¶]@;ÊâŠSô%Û—]Obf+¯Sü·¨¦ŸÌ,Þ ¢8ü® Õ\æödv’u§#©itÒ¤ £T²bª+l •dMÀ”LŽ»[ʼnÒú˜-2‘ÒðøVpzg`´ècûÀ4PhÆ¥@ 4-%d†ÙØF˜²ÎL©›¹cÓäᬆm´°A-®O±€õ|;J_§¹¡Áïbg Iò!1‰¹"󮜹¢³OÝgãvY @aS4—­Ìî¬å”«¡g1µ ¦¾$VÕKçŽ/’ (Êë¤ÊÇßãEêø: cáJ»*6ÖÖ7Ä^à8âØD—È^öü ȈššØ÷z]}ÇMð]/¢m€õBYºYª„b9×½!œr±sc´lÓ¹@{Щ^zF{†l¥ÒÏ_S9f™±™¬’— òÄò2¾Ž“I'_6äëiµ1‰K-ZzWW]8=v•M¦¥/®?%iÑæ+ñ“G¹"ÉŸà óSÀø8 (fÉ–÷\hè6éõ§ætù=X©–ÞËÔ·”óºU~¯?×­òºõ1~‡DÕ{ÛJ/§$²2ënâÁø*b««÷LæÐeÇD±¤X³B&JðÖ’é/:9qtNùO‡½Åp¸@Ù ¾)Æn¾‹_;Uæ#ú½Õ±:r}›#/óÌ|d)Q•îXV))¡¨7$¹ýøÍ#èÀ µ‘æQÕÈy\Œ@³¹P˜ ævâ-zðVþ«ßV¥„ |]ºÆDf‘uÙ7!Fï3ƒ¯R=ƒÕÃüò‘Ó)ÿ"rÌo,Ù%~ eÖAÀ Ðh/¶êDA^’¥WU$K/i³¹0Ý;úù Ïa•1ÚÄ&ãÖÚ¾¯){½,cÇ,Ú†2ýÒ7y$ÒíãæѬd–)-ÅM¬—yÒF>¹*¶„B~´ùíæG`ah²¦ßh#>xª°WÖ-”JE/1˜ÌMYÌÝ2˜{örÏ^¾ örÏ\b.ÓX êøfò•˜©Pñ[s‚ò™Ù‰~Æv 9 vîoÇ^hP÷¼å“󖘸­Xå”K“rˆÛ©_åS(·õ3ªe±ãY4žãö_l7÷_Š•}4œ/Po݇ÓóPl{öð:tÃæ!ßXÒ¡ªjž¨ [nÒ!á½xº+ãWT—ºîØþ®«;èûUÌÜ'>q‰Ñˆ,·¨<&%6óp’K‘Þ‹óZö¹ÿ¶¡É$ÿt—ÝŒ(­ç™szrèÖöxÅ-í>Ï…õ¾´á4ì£c ÓeÝ#òÑÓÀ†ÆÚá»n÷z~€JÑáu¼ åûÓlIïçecÚ*•wå ^°ªn×Vªôc¡Ç¨SÖMd„ŽN(g°Á7L@+„¦~•«+6¢¸uß„ Q×n g—Œ¢Ô\ho r©ü°´¬æê‡òÆJ;½Ë;RXrð–ÑO¹i=@KuM?ô|òkRÛ|à$· i¿î;º{ÉÝ7pBô3yÀ.gâ“Ŷï›r­…ÉÉâ=E>~Ì*¿[-òÄ2ΣÝÌ‘q<ž%ÖÅR]|ûx§EhøÓ¬£¼Ó 4–îñßïh˜7È{YŽe¹ã¶ÜÁNRw÷Ò<ï”÷>« &o–þÂóâxœæ)h:7OYø¤(¶Éü(P$¡™Þ « !¬RD‰—d;Ø·ÏÆvþÞGDz‘b&Ÿî ¦[i4³çŸ ‰OïÅß Õ8„ÏŠé­›s¯Ø9ˆîäè€e°d«—¬·æ€ &h\…7ü¢YÀ²§¬ÁÄ멳ÕÞËçm<žÌu Êœ¨6Ÿœnrþ)åôçþÐsÛC<Þ!£@èùf£ç÷&>‰4Õ­¡!±±èš*ÿ(úNoˆ7õ8,¤wt?t®ìÑxèÔÄ//ê/_‰õu7·Æ9ÎùÈñȇz±Ü×}ЭwË%ìžô%‘aªC¨lækr&F6ª§ho¾ðÇè”=¼çWnä“Jƒa^¸½ :¦#†n/bÆÐÃàæÐðJuKùGbñ3€öŒþ£õ †Ná7˜¾n÷ød§Ýí¢Í€´¬¬¡ã^M7ŒªROà  ¯ï‘™,"i(=MȨ€3(N^ZÖ „`i™(Àx¥;¯îàL<„#±x¨ì/Ñåþi»GÐx¢é';{À ˜„ 4è$9=-‘Ñ÷š ðGvÔcÕ•‹ º†cX "—}»‰°]T—¨0RqÓ¤ž¹öx¤­[ynBÖÈx;Ä2Q¸FE:øM+ÃKû:¤}€ Öüñ?1JYÇ0Ð"ÄîE)-¸ú¤J¡ø9n=19ô"±!a)EôßTÿÄ“c3[ïñ 4Fã÷º{ÝÇ£ûºÌ×~,b¨ó_£ÿˆWs–¿Ìu_~§7æfÃ÷wæ÷wæCs¿û[óû[ó/VcðßÂ{ó‘ïÁ"þ÷æ5tj¥`åwxrýà|Ç¡b“×é¤VÏ^¨ëŽÒÎ4]£DX˜u§®PòÉäá銟/_ÿôWœÂ$ç[û!Í­T1…àôþTº9âàD< mvc›‚>³X‰_†Ù”KÞ¨ƒ8Ž ›~Ëaaoeˆ°Ð4§ú‘7å9EÓ¥ôÄÃá t¼hÁYçÚ=gú¤«Rw=çsM8§O¶<åϵz™œê¼YvïvreÃSæÖ(¡¦öØÿ Ãs`Ò•3©(—Xü§’v¨MÑÆfæfÁµ9çdÁ¤,€¬MÏß” æ¨ö¹+olâ⌠yFu¨&CÃÄoLßø¯²(IùóÝöÆÖÇ[ Š`9}­§4Áˆgz®!Ì Iu˜ŽO0)87«·šÉ(6tVŠ˜³÷³@ÜÏtNÒ~®*_ ´8N\Ê*Hü4Woïv>h'ÄDX´¹ú;Äíñ:$›‹ŽõBÎæ˜Í6ÏæG´ål±z^ß äÿÉ¥¸bt6Ç“T:˜ê Ö-ZÔ üNá1§?U3ÁÂCh¦—øÓŒÝ“•ºäÿÐ-¬¾øèäÉ/‰¬|{c±Ñ¦<‘ô£Œ{<ôÏã8àäW=î{˜î"¤KGži²?éñ>¦/?ñ&n蔂‰çñ¥¨tË®ÑUœÛ7Õ ¯m ëð‘ïEð±Q*íG”ÄÃP9˜.åŒeQ¯É«?(:õ$¶}ïÊ"u ¨pp¨2’F*/ÿ\R‚åayô£8FªPéÇ/1VbÅÈôbhG¨6Éxr“ë6†@¤‹Â–8]Ñ_>|€™£d ^5™[ƒ–ÜúŸ§%ù~DÕ—Tá±`â½õüKO× Ì:Á|uB³N8_wfw3ê”(ì™ë5e…1ÕÎ<Æ,Ë‘°Šù4 r:ƒ(vRâGÃÂWY8ú'Û-5 ‚YkÂK½Ê›ñsÕZòEhËß|›'sHâC^Õ&¼üRf¸!æÊlGaËD.¬(qbg†¾ÿVLèi9>Í¢±døo%J•„†}cŠ€Ó_8*t,6;ß8Q‡7/²Ô%8J1ßmá9—¸5Ö`Ã`‹MŠMõäxGzú¼¦ÏLJ/Ú»ÕdàDBVâµâ6ò{ºƒyÌN“>̹Ä>ž® •ÉäÖ-wüµ%t…Ó¼©Ö5:BϺ$;ØP²@‘léÁùç‘ü£T™Ê¤‘~Ö"íPv½NµÙ鬷âÇì]÷/Õ«ùÇ<Í´LX{*s'FQ¯Þ„O(FqÈQûgrŠV‘Í NÎ`‹Äô%¼n&Î]®ù™ IHô±…%°NJˆ”¥:–ÍyLÎ¥uš·2ÒÀš3 ?Z²ÿŠP„Ü$jÓÙ,xà´+&SNŸ= {(77š°•KqxÁXÓÏEñl˜ÉÎ`B–òçb)= Kw:,#-͉÷,æMªsSS·½sá^bÖ¼#Î;9çà8yÓ3%š©Â=÷M_µÄš4ÃöAØÁÍŸ‹ £f)¿<û4ä ,¨Œ #ƒÕ†´5œ†¾r^U=á‚õøbzU?•Ë«Ôÿ˜ŽTÝLJ±¦Î·r|ÂëÄú#¹q³ ¤‹´*ñX›Ëä¯z½b åà¸ÖZ©dÎûЄâð8©,†È9HpìÃÃBÖÎ.ìzè‘ä\á-M£40¿ÆÝ4_ˆU¼@I”\Fÿ%å(’iof¬$¥Î ­ÝQY2E5V0áæWKkræsE’|²°ßvŽ÷ŸÀä“E€Ÿ¤cÀâ‹€zòòéÑî‹Ã£š~¶À—G(øf™J´‡O tÓK×.¡3Äü4äNDN^‘’é5ÛØ¡Â 5Q ¦ôu#BD-”a^<‚ä39–ìIäã¡GŽNú5,†°ÁË!âÔÉë­ç‡Ïw6øQbŸj>ßÛÚ=Þ?Ù5ƒê³Ù%eqFœ-PS©pê :» 솷n‹m=ð¬Ì‘Ó¾5šfa¥jòÎb”Ë+Us@cso1Úº*sàmb¼Wˆ‡Döx£E™Q’R©4a¦Jnè’NÔK”32`³9+çh![)Ýì/šÃÊzˆz¹Õ¨æ­Ôƒ ‹•ŒF†ýŽò ‚R©*cûW­Ød6ïä+cžû5ômº5§U%CC§Ì?3ÍUñ±4HÚf[9 `©FæM§¤¯ÞÏ?&2wßÄ9â´£ãË~e³h……ÑR ]Ÿ£Ë ¿xì%L°¬òD£ö¡ÂF+(ô8KC+6zØûshköSL-5ÁËì›)#ŒSÒæ3;¼àŒ¯äÉ ]ä,º1­P’”lº¬ý91_´·ìÛ÷Yé`G !vþçé‹ÂM†6éŒðúØUàœÃÎ]Ù(&^£û1é Ƶá2ÃO43`s+(Be&¿‹OFy‰©alÅóÜ(|4[C‘Ђ‚Ûü6!x-q#4L¯ÁxøÑxÊÑÚeÆ’æ¤Må¬7’ßàUZ_åOgà”%è­3–·~»¬©â{jÄdV}&okŒ•jŒN¸R¤UÇ)Ø—¹ë ²Úe=ç2.;­ åsZP@ ¬._TŸòdwkå¸;ŠÄðqµtC{ɽ˜uA“² A¨Àø©LEM `óM]0ñf0ÅÛ€U–a´á¦gzSéRj¨Jº›A“>™ÐyËaÎ4çÀªZ–JÝR±, ÑG²?‘d¤˜áÒ²è»tòd*ôKLÇKš5%8‘6#äø”:d)†Ü½lÒh¯„ÑÞ)‘M¥ŠÈ§P$‘Jó´4¢ëëÎÞjö.ÐŒéÂöÎ>‡•Èà}sþœÎâRþ––ø²ïc’n=›œª”ô÷ñdqoÂXÄ ~Þp wÛ‚}BwÜ1&»´\iîá“läÌÛá{’EiŽjÔÑô£7 NH $×)ý˜Y-^ô7>ü õï¾s¶Ãøò‰55¦ˆdìÏðÇôf!; 6ºÀWW÷jÖRêAÅDæ¸ÆÏÂ2Û̽ë·D9ïN5Ö'/yù‚Cl³H9cÀ¼8iUÞ?:^ˆùÑ`ؽëF,@Ýà&WdÄ(£e.žÔúÖˆþ Ž7oÔXÙ¸Í,—ág4ü‘˹9³ØŒž-‘»Ÿ>aD¿Î)¥Æä?¤±¬àõt tNƒ‘)_VØm‘®|1Mbâ„bfAV©%~†Q^Îü>Ý‹ò¡kZ. ²Áb7Ÿ¥õêÇ­J3:–UfÌJ)Îê€ïÚ¢Þƒ·œ‚R—Êõ%¦ªèo*ëùyŽÒYPe•J4³Lé>de/Ü=÷&-)…&Ÿ–èÇua¸*×T«²ÞX\¡Û“+2ˆ+%ó0ÆÉÕ§&f4¾àw)e§³a™×¸^˜ç6£AYP=–å»áÇ!Å 8€uV¹Sò­R^2£BãŽnÌÝpxšo×(ÃPI¡3 <+á¾/«Çm§W ôÜ¡ä¡1Fk"d ­8tó¢£fºcÅŸaÊS_éIf…–ÈLx& ‹w;›ò³+§OK}âÉDÓN¿†þÈÈÈ2ÌÀ4Ã$¹ž±½G?°/=Î#+MµizàS ÉDò͉I‘•Jè´çjkt,dŽÅ)ˆYÿaO]™¥VûÈ£ÅË&QÇ@j™JßòO¼I8=Ð4nÔ;P3ö…0¹œìΜc¹ßS‹d꺴¼œÚ\’Lx˜s 4x=7,@ÜP”…o:$œà=$%[œû¾¦(mÍ‹ÆR‹Ns9 à fÚ [V: û LßwB²Åõƒ·BZÚ:ëç”æ!ìÉ؃ð24¡(¦`à ˆFˆ‚ߎd&½³tÕH¥‘žÈ=Þpø“1ˆ‘=Xéð¸¹ÁÙ¼16a Òé•!ÚðZXñü<²½ÈíˆFº2ƒò0Ï  '& ‚ĉáò?"¿Ð4MÊ+FÉÕËÑd¹Ð-Vu6J‹9YÙâÉñNÝ G ~†ëUQµ´CVÌé÷ŸŸl(6’ë{Þô1SµÚTsÛú+Ìï„{=â±uùØñq*€ß ´y‰›"ňph‡,ŠÒÝ—##6JÚ ¹W|ÏÕh¹¦ÑÄßÍ×½ö›&êcñŽ€V:~‰‚þ¦_%ÇKK‘Š]?Ü ¿éi½ïá1¿–S¦_S7Ô’Cå°Œ•$ñqx¼·N;àqûP5Örþlö?JêMS#+ïhV3^#VžóÝ(fOa4 ßÀ§$Œ3Љ÷\ ÓŠW"ø\­œ°çãGl+¶&’5Ðë‹$V¨Ua{8ü7¾€C²lª‰ª$e_ ËŒ5å4˲ e°¡T2-»©§-½Â¿ù†m…)pS?Âó`…ḂÆkq3D°ÀµÚê#æn^r;Â+aé¶÷(•¨þ&©S†óöw|‰1>oÕ_Éþê:ñz<´ñNBæ§¿¼­ÕëzÇOvšu]Ùà>¸‹ë/èÕ‡ýywIçÿÅr?&ª/±Þ 0ürôYM¢;˜…8¢wÑ¢¼ïM®¥Q/²AÀ@^ú9„5¥šª ó•Õã§’•INßšŠ:=Ⱥt€ÒÓ•vü[ÄKOãƒò<.v…º!°n¬ÚÊÛ¸B'ú˜UtIªÎ·f’‘Ö&ʰYDè 牚–]Bô.b$¥Ü’o l {ÄÁd£Ê:ÝVÇ}2¨i{y,ðJU±PÂ5I°bl÷Þ’—oœÿˆ[DD`½8—Êúl—ß§™Ë^`Ü/—ïS3ÉÑMÅK>.Âÿ7÷ªVrFZEdúX)åÔ=ní¿8ITåG3kîlŸl'êá³ú?~ø*ß\ÊTñÂèÔšPÆaœIÛ›·gfÝ„¼©åg8•ÛÇ8ÜÒÔñÁ)“B¾…þóxãÛ2ÏÍDŸ%<¼ÙåŠôlŸÁ^Ò¼T-9øꨆƒV¥Ta±Ž8´ ; ÒSÇê,wÊo:T˜bÑ7RhJ«:dÇ‹ûF=KÚUH^Çò¤㔦;¢³4£y DÞT$ÐJn³%ÝD¸^…ÕHá̬üØ%ÅٙÈWTª‚g9å%‰Êóg“ÅçkQ? J¬ /QAºm<Ž_PM¹Åþ/| Åxh_CÜ /ÎIêÔQ3FpRǨõ¤eåºØç\;àpLÔ0Sœ2W©˜£¥åxŽª <ÝÑ`ü÷!Q‹Âý±ˆ9°PÒŒ5?yUaSÀGãš zèÙk€±LYƒ¬¤Å$^‰SŒëQ¬ê4Ô"‰J mÅV,§¥äímy72ë•qO ³ÑwûêD•ÑÞÍÉÔ–h o\_‰ „$´“ZRRŒQ-9¨l7äpûá9.± v»1/¥‡­t4C$D }çø º Aî ]à@RÊ^ÔQ\-”QÐQš¢ùXWƒæ¸ð|´IÝN¨VI,—Žu¹˜“¶§zŽIeEÚtX#8”ô€îÄ­â]yjót!8;Õµ:®:ÔHà=ûÊáPªÂ±©×@±× K˜N*P ¦y *9W>¨s/†ºó'®ÃÈ^kŽ Ëâ&1Owi°.àÀÁak“Kîšý”`XØ|Y-©¶á(û–@o*C†S¢T¬Óa3ªPøCÊkbÝîÙD½¿*±}áOÍê×2èË<×Ù(2×F"}dż€ [5|À9<‡õÔ|QÉœŽøÙÜ%.x‘´\d…-÷Qã£í¡­1`FîˆÔPwìö[ÈéPX‘Íó+)rÈ? ±¢fWT:$à–¿"}*"MhIεÀàÌx—*oPp·Åèu —\Ë  ¬±Ø@µ·Éµä-ùÛãörá{òÄUA?œ•Ä1NŒ¡)4˜&CyY§îãJ±‘ ÓëùzjÓž“8Å÷ ³òÝ+ RGöK ã¤bǨö‘ñF†ãËÑdë;AºSegþà˜& ÅýÉht-ò!m¡ [k•7¼¯)K³BãÉbéû­º‚_Ô‹Ån\¸&8–é “h¡¥JˆØÃ )•'YQtܺü_q³ˆæŸÐ0Kõ³§ú7´¢&¦ò)0ß[3Ÿ\þ„6Ð)]Ðî(¬îÛ0¬3 5¦¬ãn–Ó/M£‡›ëð$¹¤v ýÔŒ!~càžŸÌOT°EiÚF%1Ø$¥Grê¸{³8Ì åKäÆðÐry‰‰ìdé{¾RÌWXû˜Ibùä÷¹4›D ¼ÓN6úªùîÓ²š´ÇDÜ2H­Æ|ÊéÛ´Ì;#éÇ•”‰6µàƒÖôä¬TÂPÜÕÒÍz2©Y'Äû’JÅ‹ñ!ÑÜÍcfŠö‹$ÅÄP©cÄVØ1ñ—p439F‚ÓÀ?}Y‚Oõm ˆî+±$_Å;Ùzh•6³AsB»_';ß ×Ç3lò*›Ø<ûugÿ¨k,´‘ øÌ&6©"M5ÃÁ%š¥Üž­*ÓÆÍ9ýa£ŒÅL9bMßü¦¨ÉÔÎKjažÎºâ¯K»¿D!¾ñ®ðpV0~1FؘDî0¬Š Ûà$ËÌzÊ0õþac}µªV§é¢5­Ãº–¼Œ—íd<;}ñëZ‹¿žß¾h4c4À #ì²ñ°ðÒ 9ÿÊ]®‚xÅë ¸â>Ý­»l÷ÿÄ­{G1—ƒ9±nqõ®øOz0žóÕ{Ú0˾|+FøËÃ_ð9Ãô³º°Ðé\ÖýÂäéíß½9 äÊÏð¼Åoïååby™±¤hë‹•±[åd7Kų~ó¥Kd‘Z¶òÙ'>m‹Ô "øâE,npR~ÿlû×Ý:*#?â éðQu‹“âʉ%Œ<å*Q˜B4ÇÄ%Ȇºï¨„Ío›ã&pž°ùú#e³Û<¯œš9,ŒÙFxìrOM OåbŒB'z UN*â~èÈD|‹Ýb_ð¢{ÂfiégBåçŸþúë¯[-þZQÁ‹–)×Á£\éhÂ|ØÅ¸D¤‰~½þfSìb XD2 ÐÒY8(+ô wƉ²Œ>ML€y½G­Ú•¡ìáO«²sR¯BLÁ%ž(Lþ V¹ _QÙR!>ðÓ%¯ \…£m`YØÅ^±ñNh_'B(e-m6*ÁŸE' ‹·Ï׿ü%Ú}Ý"‹èKG'fB-´ù¡…AÐì0œŒÆdZ-¢‘,%“-'*8{î#È'œçCØçç”Qé'ó p½d¿ f)Ô-»äk tÜaD`)kCòü ^öh‡óWÁ¨–¦çX^_ûnã; Û G‚—À?&/æw.’»SJíëˆLVDêLÉôbUºÜJ0ªh­&tvB¡ ØÁžLÙ ]ÎÕ¶N2Îâ`‘z£Lô†¢­ê€ÎÏ/èlÃgXRÁÇ@} JD¦i4•ßlˆ~¨ì>ß©”ýqøU©ôOìD¢«À¿FjBM6nß*ýâʲÑGJzxÂø}/“:¬i4ÓWVn•ú U™TB•äWϻ얹dJ‘Ï¡Øí]ì,ˆ^0Âà´o=ç¨v0?%¶ˆÒNp•jµD´4†>á^èЇeµÉŒø*L1Äè@aÃs¢æ;×¹lŒ/Æ?¹ýÖ£‡?–J22E„ P¬®èégÉeÒlÃJ`†quÀa$T†ô­whå)ÍfY„ñ“eMºLÝ)±U"Ì 3ÌaX¤wŽZëšÒU€ `¾ 1ïÊ*o·Û»/Nº°îíužÅ.l-(pÌZÀ§§¶¤}6$$F#“ÛÊü=5éð #dA-duuEç–e@Å­' ©©ºüŸLOÒô6.G}ÿ’诌¿^3l江ÉT~äÆùïˆ4heÐ"ìû§ ºvÉF$.ù&î–P˜V’‹q'tBå16¢fν Ëgx½oí———zcýAtÉ¡¡%ðæ˜R•èF³bÙ¢xœòŠˆM†¡ÁÀá%Ꟛ.à=¾Ìr”kÝYAÁ¦ ³°9»SYEUAc‘àúšÝ)á&`aŒPõ¡˜ÒåöT×õéîI']Z_û³’*̾¬—Ì£ê¡VI™°áÛÔXæ$ÇNù'`e=rűuÄHG¤%ÖE1÷I¦>u=Ñ…<“–š«T-‘`U¬6K%׋J#Œž¿<Ò q‚¦J•¡b2ç(m­T"ÒTIÞF¢R»AÁŒñw£üÏgðÅ´3|€Ñ7N‚kór31ª­U_Àùœ¤µ2Î9^Y2D+Ç®óR1ßwís£ÊQ!Eƒ!ëLñ¢Yõ o4qI]¼ŒäÃGÿÆ-zȘ¬…î%çPâåWLxRk¡ò¦s}à;ÃtѶªhâõâÍj³Y9•!ÛÕµ‡£– ÍÖ&6!'’'.¦ì«8È”œC»‹S g3.»j‘'1(Å/U¢Ä²j„å7ÞÄ̯¶ª+ÀðW=0 OQ?¤¿}ú=îŸñ{$,üpv&ÿœÓß‘=¦¿°p-UÎçßgÿRqy¡EAŒSuš0*¿èÞYqÄZÌ Œ’d¹”æöæœýíX|bp”þQ–›†hf–uz€úFcý õ%ïÁ¤Ø-µzæUשçWèªÚ—чà´Ç®@À ðeÝŒ.]Ÿí¯Uš­ÓÝW»»¯NÖ¨°}„­/â¦y Múø“èJJ²ãR_FÌ7nåÕ¥ô…Dõžô€aÉ;iÄ g†•“>NÝÉ)ªQ6ç'{¤YÌÈßYp¢Š_Û<|ò?ÆÉ‰_"÷—dSæ÷·—âãÐxè=eªçè‹aíik÷/eOXv¼Ý.Œ¤ÝíªÕÝxë€(RZ î`ÊÞF€=¤e"rWuÔ×tg 1í `z¤^±‡‰"U3§Ú¨$†[D¹ù¨o•SM•nCâièÄžW,å­’ìTÊ3åé«W&²ð«4MÄÚ]å›Ñ*¿WéVŽR± 9c\@}º—z‰°—s(êó„S5¦Úé"ªÎ 4+G‹ .‰·v1e8ÏxòYI^=¦JʃCº;2ÿšÆ¢UgûÔÏ)¤Ýx¡%`O< K.÷/t&kșѼ©.-¥&iéÿØÝ–çýÕõÅͦëœ7F\ÏMHiÛÒœ3 8f˜iZJæ±N4”âÚqsOÙ$:élhRª¨n$Œ£Ó¼&J>?Ô"Z œ ×Âi~…mv+¼±Sa»Ð§ðN= “»úÎî‹ý£Gæ1Ãû}ì;ãmòXrîʈJy|ˆq[X5pwE•c2yúK=>‡¯rß97Ž0:Zb¯¥Pì!ïõ£·À -0=Ž93¹ ˆAÖ'ò¥ È󣂀š´_29ÝSP0îJËZ¶èûŸ?rZ˜Mîx‡Cž` ¼%ºoÙ¢¬QbG醆÷hØ.­_‘ƒ  ÊÔœ˜¶*ö ¤Hè5qìíF³¾VÃTöUh:·aÕ®¢¼V&…Öa–D²**‡ð¬‡'è”6uO ȦȋP pË!Úá¨KbX»®¬Ü¤Vk)5FZQЫ"½…Xq®\SsQeu"+~Ú¶¶iô´‡¼‹3º.6ÄñP<õ\ª˜rˉcKF•²[i\`ü¸\ ¨™â`&š…C² Õ¤YxÈÁ›·ë ¶©T@âãÊÀÐHt¬¹*7‰Õf%ÛPÉȽ¤ï )÷#oê,/L ä…o¾²ô©Ö$¤Wê=¶a­ÔýŠ÷â¶,ãÞY};¼…QŸ¬Å šwšžŠº(íÇŽ'Þ‹ÀOى㹒=³ÙbUº€¦‡´Š:º3ÉØ¢Šb%Ÿ'ªalú5¦¾}/rT¾%Ñ€A¥€³¥3%2á]ER!b8i+¶ò{¾Ïªûu¡‘ëMB*jÕ}âøÅ2E1c¡‡ T5 ©«Ä10“F ªÄ4ûb¬ÊêÆÁF@–L¬2eh+OE‚âÇáöÄ»SÜ“í9ÝK–}^Á£ˆwÃ'¤¦„Ñ×´±Õ¹ªŒAî\WdV+bHógäñÕçeï\áîëFè¤äü9¡P^jsJé ¤Çʲ¥Ô ØXHÏ´±Œ1ÞQø®÷ñÿŽÂë?»˜b»7Ë7ø"5/†+ Bçÿ×S!nã6Ò3QÏ£¹°C G];®yªœnÆë—&(öâ(ä3ÀhÏ)f õè»ÆÚô–‘›F{/*É!Çüu…0ZIõ1;âÇxðTà’Å«ù!+µ¨4×Cñ ]+‡“Ó·¦‡‘0 N½‰P˜ónd>ØEÃaNo¢ æìJ¤“b;»/žîì¶4@ •_ʸl.õ1AÃx®^¶PŽyHÒ4°qᎱ¦R¡¥gtiyÕX©–[Sj׈¸®Lë ü¼¾ÞUëŒC² ñ_…“¯ &= ßÌV·´Ñ·S ¡¯¯‹œhมêçµ™ )Gy•%Ïï_g~…Ë ·Õ~@ú§0z'?r  ¶^Äx¤ï%÷ÂK·×µÃÐ ¢•Ðý·ãV\/ªŠZB~=#½E‚›{.Å@rïŸ[%þ„ï¯ß¬Tß«A6›BÆó½·ˆ‹Áпlé5鼂BNsýÁ?6¾[ÿîaSBݺ€Ò°Ûr=¸ží(pí!àE<-\C`ŒRÑ„xbºgÀØàèû°ñ]ã“X¡ 77•h+e9Þ‹ã@yá…d¡zÓ¥Þt¹š5- |_èóÑ‘ëe¨¸/#gtæ ¦ã"››üPNÕ|ИÊ`L+°Ð‰VoZýáäÇÕdu*hX©nå>5ArûPñãÊš\cDìLò¥Å¬ò9UÂD² È˜J.&ºä÷'+­—{¬=°8+DQÙäÉ]FTÛíÅ;ºMÉû9Vè…°žztZ®Ãziõh_Q×® ýíïìÀ 2UÐÕn™ÁZŸ=„‰ï†ʬým¦Ät»·ÛNMXé Uå—-+|ÜÎN36UÒr¯³œ·zŒq©ûMù~S¾ß”ï7åO²)¿ÓÌÎÜ‹Soî` Îã{iFIé•K0ëV§¬û@Ñ´n´Ç˜µA^Ö ýø±r¥Í5ÎM}e´ŸÝ¢çf♽¼P#o©øV÷ol¼š‘‰ 5ˆvTRxŸKþÉ&EZ]]ÛÆU²5eª C1œ€Ìo‚È´Àà†Z-™Iœ$§*ãÒ=£k¿lÿ¶‹DÂíÚM%§ç~j Üo5ÔïR¼"·½›Ô¼õ1ö3Ït}½d€_–ù&ã÷%àca¤¤ð%?Ëdö˜ÙW¹Õ ö§]’ÉæoûÀ=Ã@Ôñ iÏ£…ÎpÈc½¼p#¹‘ß"4Þ9{a¨[µ…%üŒì^à«,­­ÊFãaãqE> ̈hm .‹'vïm8´q,h^ÙºçÒ.-s8²MîXÔUãë÷Ét¬N†s}<É£•æQê³1ˆÇg0 ÐngåµuZîtÞtªÍN§³À¶ñD†Âgþ;Û¹ï“øEõãØÞ§ÑñzhÉ­æ¶mû…EÜhB ²‘Ú×hŠeS* œ4{öØ‘èFk=R³ÍŠ1ô!ꔌFŸâŸrSý]¸c.ª²1ªI~–FE¥S©à/Ù4}-nÕ&u„Ýë¹}t9Šó¡v†ÆŽçd¨ƒO0Ù¸ï…%Ïïb c”«8¶Ujb·ýËa«ÒùêÎe!VdFezCÓŽ­íƒC`ï‰18Í¿k‚N’õЫ%«¬$ òÑ'c5ªlY¥*a2= ³4c 5Ž7ݰ¹fz¯ŽŸ"U²}#=[¸  ÜFäó¸™EZ€ÙK—\u&7~þÎ ·¹rÆNO™ø>Yíãy¯·PúÄ8_Zr×ö]ävmç§vm·èÝ}ºÄ)‰]Û­|rûr’º¶“9]ۥ¹_ £k;›Ðµý"椿ˆ˜IÛÚÆ¼Ô³˜Æ‚<âËc jÐw—\µ=-·j»e”»g33«¾¾(þ¯‘œ¾–fàUÛEùT?÷ÈË“ÚΤImsP®û©™©m!µˆ†¤YẢ‘#8­vÛJÝKgyN®ÄwS™ïŽD¾{‰ïžÏ–øî¾Ož›WÈK¦2‡ÅxÁýÒŸ²ô©2Õ ôþ„Âóÿ{‚?cÚ"n «9 ƒæ¤wÖ"Lî|WI‡hir•š®/ƒé˜ÃI…C4rbÚ´‡”#Uíè‚–çÈ4 áp=¬;Ɖ6öè$wòþ*ž”ò2§Ê1EŠ~ £i¸º…‰bë¢Aà¨/MFªâVüâ_bGjf ÈYÆȃyu³Ë¼“ÒrScªqfGl‡ÆÑn£&\k©¦µ%T¶Ì¶ÄIõØÚXŽ2»lÓSú~ýÛŠ¨|,ÿli¾ù_¤ 0G1—d)¢„Bý1übg¨Z ‰žù î÷ {ñ3³àó‰î^ý´"¨HŽiCF÷¥çy!'J©"óyÑÊL~sór”{}å—®¯üòÌŸÒ²$òƳ Jã^µy§ªMiKX*%¸:¢ý‹ÈU„i(—yµ ­>ÂlhôD¥eñ"ðß!7¤Ðk®UF6[®œù“dÒÐFi¡¼äq¥¯J‰Wf&Óv·-Ée´t®K¢þNÔõ?åwþ;7oïQ ´üwÍ£–g5+›aMsÑ0áBg02Æ\_³;%Üà, 2ŠŒô¤c©Âòs0¾O#Öø¯¯ý™ŠVdöe½dz«‡rh¤ I¥Í·©±|š¥Ìdï:ñÕíÓ^ÍNzõ·Oyõe&¼ú”鮿Jvu»TW°š©®àk"Õ•Nt•—æJ%¹º}Š«öM3\µçNpÕ»u~«lv«¼ÜV³2[õâÄV_BZ«%Lê¥rZ}­nϪ =R:—ÕÉj¡iù›¤±šg–nª7#ƒUoz«üôUéäUSSWõ¦e®â£\*ÇÔ”¼U³³VM…˜îæI«“*!àÎR ÔáEìŠöwßÏÒ&M©:‹Í÷¾û~aFŸCלj.YwÜ@Ç+ÿÄg4½¿ø1ùÌõñ‘Œ2‚Ré‚zæ³ÌMšB8ô/I.¤ìïäa¨t½uÔ>ÿ¨„" zäO×eëìÙóK£aû&C.ííìŠU±²ôBìxU±b”\­ £;øCîl•8^ 9މUG¬Œá… ÂÌÏVÇ2&¶än‘‹€ä{ã×îd} ±Â 'çUõE¶WÓ@kxÆ`‡~b3ïl ö/ÞÉ/9ˆÄʻژ"“ hN}„w€w|ƒ`«²8ÎÕÊ»ªÁšCìâþðxO)‡½ž†#˜Ÿúöóã}34"ÅO—¥µ/PXä£'çÇ£É`Àžd¨Ù¨t®~ù¥".œ+Ã!¦S\DÝ\Æ¡¦¨ÖŒ|6ÐíŠt<»GÏŽœáurc8vŸI6#yGäÍGafíPT®*ÜÚ +×ëOzÔA[¸‘;¤8]8x»ßgÇÀs‡ø6Ç|4~9¾= \ãðâÖÖ*_µ !åõ[›#cʧ&ƒS‡‚À¾¦PN:w¡ˆÙs0r…\sòÌSÀ [­5Ùšôõ#y ýl åŒ ÐæµÆÀ‹©Òq½s»¯ hÁ1Pü$ÖŦ¨¯"ì?yç¯ÇÔWLb€hÈvžL‡6¢‘¢)tÞÉD03¤pa÷*"…¼ gž!ãXì®\UqƨïWÃÞcÝ÷×øÒ®b×Ñfç±,í+´kÒ9P\Ñæ…½.ÞãË•ÕA•‹ÙÕ­ñë óµ¬Î%ðñØvŠ¢DUõB­ æ++«ÕÙì„~+ÎBÎ{[% ¾¼ÛJ Rr™ÓÀ€ëP &Öªh€Ÿ_¯½D?ñz=~ˆ)ĤΠ¹ëâëb–á»a 8;l Æt}äuÑ)-Õ·A\«oÛ¢¾ÓýåÅËWÝã×Gí] ¾êáÃîî«“] —ÃçÇÝ®ÅwJñ.7v†h+_X"ÄíK¹¡\f΀äÌkW¨°Nª£s²›#(©e•£Cð²ØnwÛÛí_v»¿mH\nS¤»ºaЕXËîqŽ §ŸU·'^Å>]0®[›x:ØvºµÔ+ÓƒL«èËrÒS(-X*Ê©‚®,‘ðAKÝ-d‰@Â#ªÍÿÖ¡þ΃»¾fâa¾ˆr¶Ö9ÛŒ!òϩȜ:œé@ŠrÝi’ìú_Šš³xGÁËþ8’±ß/g+ãàŸ¨Ëòä…VH UAÐlPÅ=-—ï|qtø˜i·Ý=¬q<}…-¢K·ç$’WQ}À £á™oäzBïÊåìN ŸmÑXPòk2“å7Ád1lô&£AHÛ¹Ìl¨Ø°¸‰Žº*“ìêŠ3´òÒɵ±,6Œ­ÊHÒz³ŠŸ4¦ñv[{2QÖ™|~"v™K4»€*»êPNàN(·¢„²-†Ð€ÔAVî¯`9cŸ3ZZ îP`T²rÅõ†é€BÉ 3†€ÐScH¸äUzCN™ctÊ+‘?îÂ)¾ïÕ¦ÿàq»Í™mYvÁs¸HYºäü­·å8QkÛÿǵ¶ïó´Þçi½ÏÓú_‘§µ}Ÿ¦õ>Më}šÖû4­÷iZïÓ´Þ§i½OÓzŸ¦õ>Më}šÖû4­w—¦µýeimò$­ír´¶çJÑÚ.ÊÐÚþ ZÛ‹ægmç¦gmOÏÎÚ.JÎÚNäf]ÌÐË&÷bZº„ ×£K’üfØ{Í¡ÐìËŽ.ºÇ»;‹éÌâTß“>¹6íÙ?ͳY?MÐM Òç#ñã„d4Άô{ï ãïÒÌVFD|›+ ˜Qkeíï¿ÿÓ¸Í Ózo4¹¥nÔ™_%©P'|-޻䤨»÷ÇP.PwFänY )ö«»¦>ìÂÙo´žo?Û­ìŸpÒ†¿ÊSyé"êÎá—ž¤Å\4U쉫dl+á$™L”rꌡX‰CDzhÓ;ˆ"FA6/s†¤Ÿ#Í¢K·#4c|³˜¬k¶"á¤ZŽ}¯pK¢9«P“l’뱕ª™%™MНœ2&^Di‡Œ5»¶¾ñàá£Çÿøî{ñ£¥iØõQ¬ŸÛŒc7àen¢Pꛄ]ÆõèH>éfXÉZÖ¦Üd+¤ÌÈH#ÑØQ‘Ð~HV1»Š'ýäªþ`lÞÞD¤ §@e’çÕ™Ð쀮ŸÕ$ˆoÅ:­5)8ºwö0 '.]?˜ëÉÙWõµ)÷ yŒÑ}pi¼ÐÃ;27¢Þ[d¡¡ïÛÁ™Q"ωWQ1qeWö¢¥{Y2äœe±¾¶º²ñÇúZ•ÌÔHìz¨Îáä) [‘'Œq4€ä¨××2Q2îj®'LúÆÜsÚtègy’È,Ý”x`j¤¦:P§xƒ O𩮦H¡=u»™r6Mg‹-ÏSó…ÛÇm³uÄ (ßœÉxÍ©ó4¡˜o³“„›b)¹Ñ!º±6¾z¿ZôXÔ±6ÿxÕlZfˆîŤ&:Èê·î”YGË&0Î ©iS¥¦§G»/îàªÁdE|ú%É©"«ëj|þuÂw'7Дœãï;”•w :Ð<Í%;`ÉÅ…¬‘¸ñ9Å5àDÝÂúJ8º™R„D¦ÃÅËúX_‘©ÖFvÔ»¨Ö+#¹‚æü“ yd—³ÿ&²E¼ŽîV¸Hn³¤ b˜Yñb&ËžKò  ¥ýéNd^vŇzÏÒGLM‰÷ Ë ¢j†D@e¦îù»·Úô©Ï¶ø ©¢¾+*+ö‡³j%ÍØû@§›nYª*-­X “ §Ý|™b÷¿S¨pîXžØ½#bw~‰b÷v"Ån®L±{#¡b7ÅÞw“bÅîß[®ØK°8áÒå¿“±ûyDˆ|"Ë[)b÷S‰»7“#œO*Hð´ò¶$KÜÔ5>O Ø%Qì&EŠÝ¬L±{;¡b0‡P1˜)TìÝ^¨¨Øg«½J,Yì©'s{ Áboš`±—/Xìýw ƒ;,öîH°Ø›_°Ø»`±—+XìÝH°ØKñü½¤`±÷÷,öæ,$Nx¶þ>RÅÞç‘*ò),oñýM¤Š½O%UìÝLª|R©‚§•÷¤;”*öfI{I©b/+Uì)©"¥åÇÉ Òˆ—RÎb´Ê»·^G ´ú¹7© Ñ~Œ ÃŒ$Àå÷Xý¹ºÃ>–K„U"~‡%`I¶ÊFÑ-®óÕ ²íF!3Z™ù˜Ãþ•äþÔöu0NlKÆK2ü£xTPŽê”¶ŽUëèSõiXhTŒèkÜ$,pBÔ@Ê ü<#—% '4e­’Õ éêGPóR†X¦‘ ›»6…†zAàÚçŽôa®Iç†Éf$¡dd4i²ëm#Ur¯.*è‹JgmýQå4ú`N²’´‡åÅBŒÍ6Lj²ÏB8‰8Óˆ42Ýé4ß`,ן6ù£2@SœaÔª4_ÿÑ|ƒÿV›F§Ñ¬h>Þ¶=ßs{ö#Ò¨&yä½a¿”HðÒ:•éumhñæ°~ù¿¿n~}^9•ux?OWÐ"°UÖý³r,HAXJµª`È6­ðë´l©†c "ƒIð­çÁNK1-”-K‘Í> WŒ#\ã:RqØ[À4be·µ§ÒéVËL\MÂsCíã&¡†ºi?Ž?$î‹|—!›kZÌÆMpÞazeužX(JgEÆçB‰åyÓÐá x@Žõ¹Ž &çÔå÷ÃH³ûƒ;¸>0l 6mÆî œrîÑGóä£TÃTJÒ+W³¤èqtŸºPÓX\ŠßÆnËÉìM DµÒµbFA[úz:õy…ÌÔä-gÆUé‹À¦Ý]×ô!£¦!‘ÓÃxŒ‹ :ÈÍæˆ­ ¹ƒb/¯þ.¶¿~BÒ½å“Ð¥t%ƒz͘(´k.ÆRW^’¿ÂY(1j Cm“@ýƒæC§ŠùÂbÆSË®½ù“½ ¬ï%µA•^v±¹¤|…®€ët®ÚAÂŒ}¡Iª©I<Ø™™BfÖ;º u ’Ì5psî kÚr°óÉó d¶€é"1ÎT# ›35¹V0”Ìà t£/˜)'#g|”#+5Ú-’Òô³#®’M1ÀLÄ_)@ *TÙ3‘½æB¤~"ûÐìOˆ§1áê¦Ï¿9K^¾ÛL3vØ??–UÎ% íšñÛDÄ,%?'Kiþ‹XO¼Šå”·¯Ë ‡'b*g«‘.šãsLFcà‹ôÖ°óòÙ‹'ûÏÍ€£ómOú"n‘²7ÂB!OÔñ«uŸ®3?ô¹œ¡;@’s -+ßµâR÷‰õŠëÅØúÒóxªž–³½/M'Ž›³CM9)Fh<ÿ¬ >u»³²|æ.ŒHϲz?'û/Nzw¼*oJ2ÐÄJ4jÜs¯YiA˜ûsƒæ±®Ä›Ò<³hªÐ"f–yûÙ“†fÙZaæP]4™>TOýæ}Ѽ$¢ Ê‹ÉM§õéjkõðzt†¨_86F½žq`#ÕxûpoOßZf$°,L+\(Su3ù^އ{¬hc“™uÂGŽôPcf†G 8<1VꑎÃÔ¼Ø*Æçu‚Ý›æ9£f‘úÎuu™Åv¥,œ–…'.Vñà1«ꃻt›ƒ‡0Ì6©Ã¥raqfO®h¤ Õ¡²ã¹‹RÍMj¥â,UK™„›A"—hq‹ÏŸ‰N§cåäŒÀÇ9½À ¹Å­t¯Lø“hñNr°£/ 0ÁàÜÓ5{ä/'ðìac515•T­x&uŸ™Iv¬Ä=+?‰éêm”f[š„t¢õ[„ùzÍŠâÕÏÏß(XlÏ»¼‰½nh˜ÿàsR,SÅ[ìÇÀœÓ‘n¹óÖäö!»šÞ†3¯õž¼ÌºŠ\g_¹£ÉH ï<ºÁjãXS*†U¸ ¯œü Æ9/˜".^‡h€Øíú]€±hH—¬b)ì4%Gjm?iï”´í©ìŸƒ}?ìÿë|<Ö&%‡žØùŸ§/^Ôd E$4:9 ýK1“ÁJt-ÎìþðÖ*‰©ýˆ"ݳžµ‚Š3œÞa<|á\õ‡ôëkkkâìãê°’g“Á@$&Ê<©?¡¸`çCÿ c5Ú$±c@¶] “&¯éO€ p´C¦@þ骠¶2`¨²H¤°¶›m£ðL¯Ì•ÖúÆÆwßmI›Ð_I;O!¹÷ü"Rö3ð÷Ü›hœ¾ÄtùË$蛘uY˜RÑ×tL^ .tÇ=ð:‚>FU|&) £{†"Ǿ#¾†Ó'êëx  ^^ØQèc8ñ)¯¯o£ë]Ÿ_º*çùÂ>ôœó^Ï$£ß]ïû«æ³]s¼HE!’Q½N(ŸôB¾øì·Ž1#õE­Œ8lµ§19 èär/ríáðZ ûw?’^ÏÔ Æ_ÇÛ÷ô;q#;ÄE\“•¯ý‰Œ…®Œ¬AàÿÛñ,ROHåKñej*…Ša‡Ãs«¸Ø4`º5š`çô`e¨d9Ï[<¿­ªaìsú¹¼ÇLl»p<ñ0e“b‡y@‘@t¼÷3œWApu¸<1Úæ©7ÅwëßoˆßÏOš¿6_½¨N[XÚ¤èBdÎú3÷ù‰JÔàÑ”ÂH)´FäŽr6Àh£8»Ð©‘3’¡¿çmϹ続Mnã£Ãc9ý·á…IrDUp@™@fC¦Ï$Žé¨QKý£¤ Ü3„ý¹IÏ\ ×s\ };k¦Øç Ï ¯ñË pœ³°='’Ÿ0$~¬&ãM‡À Ð}' ÅÓ÷ƒïƒ¨\3þ¸o‘º“@§Ýˆ?W¢R(çë° sŒµÒ#:5Ëãù-ˆ| à5PèTæ[1¡ãñM[HÕ)hEGËóøÑ£—0ð¿ ¤O Yk°&ú·ñr§ßÇzöÀ]íßêr« ŸÀm%L¦^ŠNS<<]¸òªxpjP ñj÷JÏÿï§ÀE "$z½°ƒ~Â7k»+c|¾·ÿ´Ë_eš…u·÷‰³0÷ G&¡‰ê.z™8̱‡0õ^YX%tiP©3*ƒ¸Ò²ò”œh÷PfMg{ŠíK0 t¦‘ðÊxÏý}uêxïTœÕ\Ô$¼O1¬Ž( $úª fˆû1H|É õõ0‘»xEµÞÜÏž3n¸è s*]Eœ.ú5žÞfŠQ.œò“$o&;%GN¢PÝ“áÎјcÉ$ða‰Ma5V-v®-eúçL`ñÆ=÷Ü )Ñ``cÖ}à4Ó\(ѽ‡†ðí„!fQ²GèÍH¶ô ;¹hÖ¤¢žj1ޱ8«FFòتA±Õ1gÞÀ*Ò¡Rž§p¾ðX­ä8’w·âI§.Ì®“¨išƒ›Þ⢫€=ç*sJÝRýæ9y |ME›‰ÆünÈ‹´êj¿hY=8¼¬ôýÙo-kô.þ~ô¬e‘¾¾#^WÄʳíýƒÖã5'¿VÑ|ó>„iç *ߢ߯5?å0tuG~“4»OÚ;ûm4Ü>nïïKûpõ«Q ^‰Jg}m]^ mWqu`Aqfãþ£Žœ‘Þ:žb·ZkB‘<LV…ùC®ujœï´Ql3 ¸“Ç/6ž´*ÐfgíáüZߨð›çÇ/ä›õGø‚Šà¿ ›˜c:¨e5–TÏ’ ××´—@çñ%þ«vë·°¿À£‡¯ M¥1Î G¹ÌØ_u ö´ˆå7U¤.ü.–"#Q¤ÔE³ØyzŠªq]ËŒ]vŒR(Wô¤†´è]#¿›-ÌŠÒ•£ç§X Ë]>ØÐ•cÏhJ)Ûª7‡ÍU‹¡SÿuB=Ì›«ž{uóÆ RAKúÈÀpfLŸËÜð#Úƒ]ü3á7)SÃcÛöé~>D…|wXWC –eE$¬‡æ™ä&ÃÕÌ™q¦b9àÂxi@ûh^1¾Èûtìõì½ ÌÌr',0 n $#‹Û±ÁeI—~Ðw=;¸6­=j”­Æ •F)¿é"2ùÒöv |A÷ Œ—kaf5mÀË ÞÖTÐXÒ|“Î åTŸ°hˆ;7Ùwz2¢NßïÉË98"*Sú”5«¼³ë ƒ½N´Šoí{>“ ÷’'o©.ß{ž]‹‘ÍöÑH²R² 1ÖÅë×sî\½y“¬ix%¥‚4.&<¡»~I¦YV6ö½~¨lcËÉ9WQœS™6µ>Œ‚ÚÄ®ìÈâóÌR·*¨ïB{Üwöi& ò† ®à{EÚ“†h|´¬ ø ’Ííª=¼´¯ÃU²é¯QKúžþocÉT &ªQÊžÓm÷êõÃú÷oŒ D¹©Ú仞ҙ#Í#oP%컯>šÙ’9o»{âõt~­ÖÏ@Š|ýìàÍñ±^Ø”æštBú× LB €W­.MºECãR„ÖrKÆK´^¼&š›7Bž©$õU’~I _l¯;sû|©ÌÆ*7½P61H\ÑÈv½Fx1?þ¸úî±ÀP‹¨uG¸ ?гƒƒâ‘¦;&/éJI] â Fyir(—¾/w"ÿ&%Õ*Kpx’2ÿÍABrü$þ³½ë%Ih OfÚt»åvR©´‰‡æyÈ@È9ƒ[®q÷+{4F“iPÀ-y ­ëM_†ÆXamwSßßÙÜd´Ä²,~åˆ+.E¬G''Êl{íõ˜¡ âѸô)@›ôžðÀ*~±2vÜÕºûà»Ç+UQË̦À‡ÕŸ>ŒºŒê—hø‹_`˜õǫӆ©„QT”K-­ç[ÖæäÓI !ŽG* ¥…F(ûßXeû­Ì0áeõ§â…“ #6ª.ìqè÷¯oÈú óëØ,»j$WèvÓu»ZíŽ2«^åû·ü¼7ž¨› wH³ªMažË=Dï RŒÑ™Oꇰ£+$9„`0J´LÑ76l; ÿïÌgCu2¼™x‘;d2F‹ü¡C|y’28š9‡+{€%èÅÙ›;„ª½áuµé¾~üµBñqz‘¨þÔwˆís4_àÍ@îÝ•DË©NìEã=€;¨’±4VOs]tõâž8ôJ¹°Ý·“RÕÅxrµ¾ÖØXCº¢/ë„£Î#×~ü0a8:{ÎÂxw¦_€XëñתHìÒ¼NëbûñÃ~bl¾ å8´Æ.,‘~1Û«wÒã×¢n<©® œQýiE¼>x¢Fõ§ä(xc©þôºÕVÅ‹íúÑþq›å”NƒþÌ?¸±½±Ö}üPŽnX`Á»À°d·Ì^Us—É<½ÌôN’;’¡t# *yý‹ý¶`gPœþ[ŠÉïsAñ qU#±øÉåŵøÐiØ$p|èŽÝ~A>4ƒùSt²®Ú6±ƒüÛ•¬–÷v¡M2Çdÿ ‡–0òªV«z%쨋ãV-ø-¬*"ŠpÒz°4!-K<.â¥Ê<°! <~ˆï?L¼~ü0a<öÐ'®NÃ11;?Ž;#t/:sÄ9ÎUˆºQaÆ~»Š»ùÇ/è÷²a™z¦ ço5v#âOÎp@ÀîdW[tâ%«þ*‚bb˜‡7O§«8Í»=çÒßÕ±&V|Îw¦I3ö9—³7 ã#ͪùñOïê†t œÈ ¶ôB«¦âŽŸÎI §Ö§ €ì¼Ýš ¦S™& ?< 7»pðPþ}tCäýŸ²Õ¾a-ÃI†]l3Ͻº„?£töòùþ+íH³ªühnÖÜCíˆóÀ`Ã$¼s¼>ºE÷¸ùŒéF»ábjñ̨#~“1£çÛÏó¥ÄÕÓxÇôzAõ’¡ò^rþœ8^TrøÒ‹¿rk‘¸3EBž¹kž{7ݲæë–Ñk¦à’TÛ¨»Î¶¾¦aÜ[ ’!#EãÁÍ–ˆòŒœ»‚¶*[Ô<)¯#¥¢¢l3fLFSh•PÙõ|\àôÀóè"…q«s,вº+©è /|8”~à\ÕqKS5?B¤ûu-f=é±ð2··ÏžôÚýgw°wþôâwÿ_ÿóö×áÁè™÷Ü?¿øóÿGáqt2yùî·Ë߯^]ÿóßÿ+dΗº#¬°ÙYi4:ÕfØi¾î¬¿Q¿Ï·šçV §ÇN,±rÞÂ+åÒÊ”‰3®zòçõ›oD.L•Î%ÿçØ/õ‡Cüz'öKÖ—!öààäððà."Ä2¤ü±ü®—º·#˜!Vc«ˆ¿œ±²«ål÷KÓ©c±ŠtÒ!bãçýR.õGz*U'gq [0œ/“¿$Ðpw±]§ðš$âÓ5îùÎÌØ® s_³I-©¢ž—æ!˜…C»0¡ÌÛÏn¿¤ÛNÅkUÓyo¿T³Õ$©˜ŽLû¥$?I1ý”ý’ž Xઞ\L¥;0`‚C˜ßsíÈÁx1:úE¿Ó

ºñtû(W&Ý>jÑ»{é³Xú$}é)Q “åDŸK…ÓsÆ…’bMüè³f>Á&g%=I“y„³OsùÍqN“;á) Ô”Ó®Z;\îžËÌ:ã*|}‰©KR,F=,Í ‰E´9LÇ|ñÙ3”$ØOar,•<çâ”Þq ¸Šªˆ”t2 noìà£üØ%—ôV/˜|,•n›‚WZ/âç½ýƒ]åÚ1ƒ»æW*:‰ÚA׿ ØÛœ¤0¹šB ²+Uý/Ì$0yèÏ,ÓÛèâ!è’Ø(ÁHÖÚÊ+Ks’Ôº˜ž¨Ž^K±§œW@:^à'¹G­ÔÝÄï H_˜”~|r´^õ'W>§7-Uâ^2/–̦ò)ð‹Ò¹›åtÇKÓèáæ|G’KŠÙè§Ý=w¥Grê¸{³8Ì åKäÆðïì _ÌKLd'Kßó•Y'~‰µ/Œ™$–O~ŸK³IdÑ£>“I½ûì÷زåäé^Nß}ÎÑÜýA@ŠjÌ»k“c$ØxêÞZb0רütbe`{hT}r%ƒúÂ6†£íçûOî`O`@¹Û¿jé2÷›@ñ& qU@ˆ_ÌŽ ;ZÎô½4•,n¾(¢Iq¬øñ_'cæÑ|¤¦PöpÇYœÁ|‘üÄDÁIšSxKå©ò÷|f–°©ðö¥1—äB*èviJYTâ,`:é—Ÿ]æTM'…N5÷Rg®ÔiÒ‘&SîL°$oOIž ÿ°œe%%{.‹'r‚f«”¡€($Vh?r„?ì×ÃèšS\EnOiL£Ã«®ü¦‚$'nAÊPV'þáØÈXa hp=€5ÊJ½‹‘ß>Tâ‚/Q´4}‹Îñ.‹“h&cæöÄ*ç=þOG6$ê‘è”i¾¸ŸVÆp!°E0%d°ÌðÌG…°r°’­=ô{o»&D‡÷|àÞŠ c;Ç)e=?ðzúÅPƒjm@ŠâÔ Þ¸˜™Lµ%ŒçÝ*¿Ç?u«Ünc– œÚ˜;äŒÎi D‘ˆï_ }D€ôn1_u»K XžQÙ’UÓ-è¨Maèp“TaµÔ?ãäÒö¥¯GgþÁ |l‚nÁ8ä´IÞ¨±€Pd´9¶œ÷çÏG)g°e+vž"9ÝÖ´üäèhi»<ÂîØ/t›La1œ„…¶§“bªø„~ð–â&ÊŒ¶0{çW ÂGQ_ŒkžÃãx9qÕâ÷ º”–ÉÞ –ÊñÍ%~úê+±U}ól#ÙÃûÞÐѸ9ìî¢ ăUÓ‰1SPü½á§Våõ“öÎîÓ£ã“7u„ñLje O kÉ)¡º×s(„"H,œFŠ:Þ&¨c;jU:+¯»Ûõÿµëÿ~£>¯u§ZaÆ× u¹6z:Ö$rN AZô‰~Ÿ¼‘Xæ2 «b*ù§ûÇ'¿«ú*P‹bè¦H; cô"SüKRÈ‹Ã2`˜l ˜\ŒKGìA^‰ÿg1C.ÅvŽâfâÒ¸HŒ£TFÒ¢"ó„eHc3ÕH üÞóã“—o¼ˆY^:|’eÌ)ïj¼öCº˜37‚Ét“¤+ì²ë¿Å¶õ«‚â‹Tˆ)>ÙÛ©äÎúM{Ü•ØMœÙƒ7êR´¡ÝsÈgüÙ1žǰšLÝ×SL›‹—´xøìÛ‘¯_Fï‹cËeYNäw¹PËÂ…òCÝÁ̬ì‹Æªè¬4`©”›õæ¸b•8ÿ!åöF®MÙyS«¶=/”qY} Ä«ÉXö ëŠ{ÔwzÃî…ï¿mY¹íây)ðD·‹qy®ô‡CWîncÒ¶-Ù5„×ÅÝc@ê;Vg½ÇóJ5¼ZkkhöÎ`0çk¼›,[ɨõ z ’‰N+,° !n‚F’ãÙ3™An;ùƒ%¹ö5‡Â¦¯ÄÒ5ñSúv LŸe€10û6úª_°QàÁ­ä7¹µˆ'7pûA^VeG"T›Œ—úަXí%3¼®I“‚í;æ™Çì–; Ê™”‹º"h˜Ár’¦“bƒ¡U­T‰®Œ²e¹€ÕßÕœº ’¼&MÙ±"¿Ûý>œ-éCå)”%ÓcŽgÜȦì5ôꂘwìy :ßtÖ%Q/ˆbžèÊçED ’D1ù1CDΠò‘¤Á'AÔT–ãêFϲ‘$Ò¡Lu¢}t°‡Ê(’Gè.( ZÉÃØƒVÉH&E]pÏ’eNÉûGT®:ï×jëØÞ¢@\‰ &ݬœbJ>N_Õ#]Å‚'÷Ù“àšæ$eb4©˜B;Ñ®Jî¸:Å´T§¡ ®¨e «k‘ÞŒxdLTE5ÁR_M-!Y“8•qÂÀ·¶>V4xk¾#`öu¶<ãÊΆ€7ø{àFŽ>® ”¶>t.Œ¢aªwn²‡Sn{LÈíRŠNU€Ga_‹Ö-z×(ÇÕ¥¶AÇ–vt!¹ëxéf_¿ÍìÅ `{ú„3c¥nwg…†-W šÄëgÇ¿AÕ0»'Ršož½Ÿ1Ü÷OTJöìAý’~ÿU0Õ“Õ'¢nèð±YþÝêA§,|ÜÒ¥›´÷öÄñ?Ÿ=9<'ÛOv›ïa”+”`ü&¦ »ÒÐ)Ã/¯Ý7fåcªÒG7V—1YU/l¬®Œ]8¨ªªÍ÷TÑìÕ›Öz¢ bõØ`Y«›¢ù>Ýh:»V ½ZÇÚìXU„Û 'ga¬„Þë7µj ÎÉõ˜ !7ßÚ…¬Xß¡[SUÝ÷w‰³Z÷ÖÄþ¼ °Ë_ý§¹K;ÐjçCó½ÜÚlF¬}+^>ßÙÝê<ãpÔúãÛNuu¥š©÷Þ¬2«"]bÐêX; bGþÓì¬tª ê¾9Á7qaÉv­Ùùð¡4ËôØF‡æÐÂ×ëoþÓüãõÏ?½QˆÔð!ýÚJ÷…Šó QÑ&ógšL!"ŒXúœD­†Wø¤õ‡ÁY¬ll¾¢U’Ë«¯—Ä›ÎJfèTñþ[5Ú)3K,3#/7Ë’ÕI—Š3é´×xBƒîUšÀ,νIwùÍ~EòKVùP2‡íŠ«¡B"Œ³?#³Àç]zŽ–ð¥´Yîj‰mãÌØ×¢…üÁI Ú—]4„‡¾ôÆÃIˆÿJR0³Ú–x_Zv<1K$¥k¦jÀ·J´ƒª'ÈZiO­¾xÿ1¯­ª$4À_©¾7šiUìÊVVu‹­òWÖª[Kj¼,b¶ÚnÖ=åÙmÇo?«ávbŸ{Ž!@0•rsáÃãlKϱÇùÃYþнâžl’æ-Ïûƒ˜Nµ?Š2µ_haWD’ ­\˜búZ°DGÁ%ôâ•ëäC¨Éí% ÕY& a;FÅî¸Ïýsâ®)ÃÆÃ'­b#ö#ÀÂ+Eþ„Ѩ''Ê¡€RÈÇõ' ‰8ô Ð…b³xÝ¿g(•HÇNszö9† G¡À˜;|…iŒ®r¸ÓйÎÊ•¸ï?¦Cá.åÔÁE2½3ÍrØzÉÄ©8P³Ì;pæD—ŽCIPP.nŒÖd üÛåókã‚åI„²ƒ ,}¶¡ûûþóâÇøI·ýϧðã¿~H•ëþÞÞÅílŸlKQL U;˜¶D0¸židÎÈÛ Vå€3J2 gÏæ¨ö…s8 øYÔ‰ãû•P'ª¡‚:“¾_—ÒGvRw@ ê¶ŸŸ3š…ÃÁ ÛÅÞSf™½¥ïËô9=ù:ƶ )Ðìà›ÆA’ÉÌ6C§è-CQLv^n¯ùê’b@¬K²¼º\pQ†"’ ÌÒ.Xñƒ¹™tëïˆï‹³tX)åPk¹2‚€3#PDjœCCG ç0…(H&½p $æiË[ÅÊxkE»šÌ -ÏÇècî¾8:|z´ý¬ ]|…çeÌàêôåèÃ×oD«ôžîÆ­ŸeÑŸ'bñ±f"œÂ@Z·Ð X7DsŒäÎ4,C‹k‰ƒ|éãVIÓ6‹'v@¤å‚ƒÒéX¦m %–Hf€T¸w´» /º¿ýº}t"qIžÔx¸%À°SØûÇ+Uš%é7{¶b)cª’!zÜu±×joÁ¨4œ[Ëð†QèÎF#ãV€žâ€^±­ÇÁþ“ãVç½U—‹üKPùز´º,Öüs%½]ÏöMN猕™+ò¾ú¬Â’)4¨Ù&8€œx×KÈËËu‰vn…ØrÞô¨-çOPi‰%éïiÁ6„¬´æžLöR†µ¤}é¸~qmÒ•ÞxF8ÚØøÄ éKÁ"HŽœ!¤ä~›äU Û™º½¾´Ã͸®ò¾Mœ/ø%E‘)0%ju¬ò‰g‡sI©ì?9’§Ì÷äòlBg¤RxÇkŠ‹*(Æ|‡FÃ0‹tú {Ç©hÔMÎT¯gì(§Á½Ÿ.náÅ3š¶EŠŸÞʦË›ÌO´MÞTc¾¼Ðaÿ\å6¾Ø}¢DZ×eåçJ‰1ºgTq¼âHÏ2tåõÏoÐm½’’‹ ÆÞ›Ó³A…©|–Ͻ,•0‘ÐÖ"*ƒS½Ž"e]–%[J>hâø=éÊ"ßÂÖúq  3 ,œ½U6Ën)Ò0¢ ‚ÐÃÇz$åf1deË+%\ºd”^ÊOÛíđπvJ™!ê¤JÒ#3æ•"c3SÜÚ¢FšlkdÂsbvÉ’* ½]†Ý?'~ätIKÅá¶%8ÏÿP©T þæö•ÉÖSé—¥[¼4z 4CþIX'$‰3TrÛöYè' ©c~ʆ‡&¸çòzan¿¹Y÷ü™®ç`ú¼E\ bûø­?Ë8Û,Zh  XéB7wv³Ì&ꈵõ=þÇwßÛgÀŒéïFè ·”Ø"]ó£.µÅ$†wv6[å™bg'aý¤KvÈ- mª¾‡wÆÏ/´éw…²^è“9gL´{”¨ %èçÛÏvëûÇ¨Öø ÍÁU0ª~Kž[ÌP\Z{Çxj%ŒÄ±„©¶ª’k\n±PK3ÂôÄÁiʼ? [¨’€i‰Zëâc– ÂÀk½œ­§7›²¬I1X %u)rne:‘G#›%-w–sÞë`>â•2íÔ‹ÌÕ“Ù|Êé~™Ü|3aqœ9í"©1 6RèX,RD¦“yFîé’“- 6‰¼‡:_(0ysÄ~Í­Vd © w¡ðÇà²]léÕ“ÂögX@9½Éö;òpíûǪ+–Úd6q¦%}³5«°2ÈÃ?­ÛÄAI¶• %]$Þ«I¢´‡½É)¯×ëb]< 6„8~ëŽ)_·g[öxì¬fã|»l¯Ð(q¼Ú‡XRl½‡iy`¾pÿXµ,ƒuK× ý^‡£QA—>ˆÕ×NóMü½G¿à¯U•ƒ“8Èó½ž.¢¿Ž';¸ÖÏå×DÕN}5ñ¾¯Ô´³…ä—B¤ÇÞå9RÖ!–ž¥Ò¿Xá×Õæ×_o‰ðë?Ø€ÕºvXÿúkEs} »T]jäëhW_ ïsÉ®,ÙÅ’b?—$Á?§ÒVì"ãåä¢M2ç9©^”½[Ù{2ƒý™CÖqö¹ñ]bËð@©‘nÎ}›$äø#É ù\}µ®M„—ŪV \âõÌö“}ÊAé ¿…¶û“[ÐÇÒ4Æ!Ûï³xņ;”ìÖúP•¯ciiUð"Óݪˆ\ êßô’’­z“ÉÓs£§ñ*^Å<°”¤ié—/_u1ãk÷ÙáÎ.°ýÒ’^QTŒR¸¦‹=~¨‹Ée—«m’¡¯8»ç­‰€Ip6,“‰^E"·Û:tÉ=ŸŽõßEé>ï<¤œ&ó‡~ò†÷&¤´´ÊiW‘<„8@øýÁN}Øÿ(ê#g8x°qŽ0‚ÈQÁÒês¦¸‚²PÔ{°—愬E?Ùø¼×ïk5áœ÷B±ÞXCý¥çÀ¶°…r'1Bi‰UÅê ¾gÄ%&kÆø,ï{Ù¶P¶Åó²"£ÛŠEa &]Ø /d^l¸?4 {©œg}\¬›3¯~¦É1q)ãºBIóB‹%ƒ\pú|ÌKƒ@Àx7ëè?ª(° m₇Àš_²©ßˆ¹½³á|§]*•„îÈoÊV‹á6\;"“ÃF¡êR…lc(%{üÄ“Ñm4Œ~Aëù 64,ͪØtë³¥*6ÒA6A·&aîEÌ'‰ö:Šî$Òë(ú¢2>Û~¾¿·{|Ò½£äÖ x¹q%Zé÷‘‹#3¦1—C£_LœÆd_ËE£(ÍC<7wR4•t2oÿº8±S–K”šïd·g1°ÅøÕÇžrqg±cg³ª¼iȯ}϶f”MañKâU¹«múJóÓÓ¢f§ó°‚2Ÿ=ìlªÉ賩9¿B›„6‡ðÒÔfˆæ±£ÜÝ$ 65SÀ%’FÑüùu ž·m1²=w€-㸧ìóT/Ò’9"j²°$!ø6ù³Ð8b:^@²Ó•úOÅr^ÁÁ(¡áú1i™ò£*vd¦r«$ 7Y[Ï)£BÝœqÆ2X·Ð,e*P/åTs›§aÊ©¡Ç™¤àÍØ)7V1ŒøÂ‡~ÿÃ*&bô~‚c?¼M"wx'çFì ÏvŽÿùìåÉþ]Èd T® ¦^¶Œr÷"W±Èeà«,¿ñKw¶œ3‚Ò "¹9Ê (Å Ì݉0Dñ”ê~ÎâH·a@_(¿I¢âÎN‚SyO ý™:÷|hÖÑ/ÆÝ—Ç|Ò‹«°ó¥¹èfÑÃ^!SʾþìG¼¸ñäé.žÖûƒ]îÁ.IU)™Ç¹cIï%FëH¨ÞÈé»ws¯Á ¾°Ýâù³Ýý“;Ø%PîîÀ¯ZºÌýnP¼h\â³)ÈŽ–3}/M%‹›3E4)þ?þëäÐ<šÔÊÎâ8‹3˜/’Ÿ˜(¸3Ùs oI ÌÚÆöÆŸRp|üðîDÇÇ¿DáññûW…ä㇭¸Ô=³Ÿ!D¶ŠèñË$¡«ål÷KÓ©cAqI'O äç±H™¦þHO¥êä\‚åb çËä/ 4Ü­xYÀk’ˆO׸ç;s ™ˆ¹/ŽÙ¤–TQÏKóÌ­ÄÍ&”yû׈œØvŽÐ‰Óy/v‹Šœbʈžš—¤þŒ4DB, ‹‚Ñàxa-üþdèèpÛ˜/n:_.®XäÓfaS'®y§¶pìÕ–Ò‘œtŸ½<8ÙÇ0Ò/vÕò\ZO®U@I Uvé‡Ä’¸tj|40ñOB›¥âçãìZ8.ƒ]2R‰ïøf“̧:‚µ1Y½3G×BºÉQ”[ùK1°%Åóéc”QA7]Õ•Ž(xEUop¶Ú`€1Òµ]ÿ¾­ªts”“Û÷e‚fk} óöÄžw=UP×n ü õT÷³mˆN©Þ¿ÑÁíá·úïÃZ ‰q2#ÞMá/ 1w)ÇD ³<ȘüåŸûD% Ü3ã á¼KCÿœÃ(Y‰†,¬ÉQB)u+Æ!µÃp2â=çCP6ZL)ò€aƽIg1$IرÙ5²`hP&™Ù7ã^ };Ä1]º!‘;0ò$S¢€lŠ‘bg¶XÎÅ^ óìb}3M¥âÃÜÅK”g;žCi:7ãÅþޱmÅ}.^À”¤Q¥WÌÆÙ™Bæ©L«qæÄ[x€ætµÀ´ $§Ù¸›v®0ÙAœá”²ÔÝ„]ÏP͇ýnnÝÛðî"˜1ç|œ;2@šüÈyIn³ ¶J**”Š© ²ŠÜ6kf}K÷úRƒ¢.—p’?YˆÂ%=gæ Þ*°_Ñ8 Và´â·^†ð«çt1ÙðMÖ^~­) .®pËUŠ—Ò¶¹Ùm •™Å¨ÓïrFe̼¬ˆå\UÐ\‰é]¼Þ3Cª™Õzf2ÛTS‘6·`›$¶Û¨œhhFÙèGÛÏöŸ$k$@æ0áÌB22·ksâÖ”t³âsñ¬×Íâ1Ü-è|y+)mÍ)÷ë%Oè)ˆ(Áy8 ÙD¢P$I5ÙO¶Yþ/ouqä‰8¹ó”>‘ S –Ë'RS67+Qýã>»-£GTÌ]“eT®ÒycR¬7^¯­o¼©ô/ºöpè_v'ì . +åËa]Þx9üˆŸ ËaEÅTTWç‚<7ê¢f3Û=ÌQ;o«UÌR@ţƕðUÊe$å`â¡TOÅúZã%­á„f¡ûÎxè_Ó10² ­2h2ëÕá1%/p}$vwõÝc>z܇ipqõ$X‡åbÇ÷*‘¸†#ëΫ Âÿ”ˆ\úþÙvûðøUwg÷ÅÁá?Ÿí>?éžl=Ý=©Cõµµ8<;~¯­~÷xµÎHønõ?’ß_¿þ†ãßd6å9É;ʱ%¢Ž×µÆ<o8£þNú™ŠñIOô·üìGyç‚D0SÕ%ã0T)'€•’Á=ò[)”}r›â¢X0lU{ùr™OŽ( ’¾X"½. 5 |¬¤!å6óé]‡Ì>¸ŸçŽ}“#éÄ.ÜŠÏËuy+‹éµ]S¨ILf·™?(UÅìTL¥eN8šxçŽL,‰g­ß¶ö·Ÿì Rà/‹úì(¥k¹!_ËøƒX¡„iA@öÓ¥5С3¶:ÜS£þ`v^äc˜}™túFÑ¢ùœïEÀRBJ «‰Ë ·wM†Q€*‹eqa¿ÃflÜ)Gv´ ¬ý£×›ðëͦ_åÁ*ð;ï,Ö«Q¦?g '%Nô§Æ…p65 ¹à Ú% ”zA`^¼ÙÜ| ·7ßàï\ /ê‹YÝãÚ üƒÕ·©úö|½JMWu¡å¡-Ãw#.åÒ‘N¦I|üª¼¡6Û«j:äñêfüˆÃm¯·:–LE e ÊJØÜlŠæyåTtÊåõŽ•†sµ¹š ‹)в€V7‹!u² êBk@­f³"¿eaO™¬²ÙXÍ(ëê Q–…@\ΙçHý §DqIfÐÀõø=Øý`vNäüz‰34'!™x!ÞkÔ¡‡4zbœ¨ÜUŒðº‘¼¾ƒ2ñîQïË'z¯€/­Ìµ|¢DúB^.vrg™nÇŸ {ÿsâC{À H“,h$”m„™8ì6r}­‹\ÐÄ®¥>ˆzØ*5W(ÞàÙ­‰eöZ#y:£·ë¿•éåå…qüõØ]ÒpóÝ1ž}dî,Œôn‹ Ç#éS:1 LÁ…Úæó^ÌÔ]Nñ9z¨¾TH@f»I…ã„Ã~ð–ÒÄ,‹3€'? Ý‘…‹#?Øaè~ƒéèvOvÚÝ.nbRž«¡B½ÇÉËŒªÎpÕ;Lf ˜c@,]ÊÆe»‡LƒÏW'5Ñë!n.C¹‰Òý~àOÎ/ÚóJ(`K†®Õtz±MðQ–…Y">¾†­üŠ/,ì4]IÀ°à$Ù»à|Èð¥;ÑN.»øUc Ö f8!Ę)-Q¯4†á hPZâüXfç Ôš0Ê­¦"ûeñ$ðß:Þ&,wˆéæ@Ⱥx7 b£„ŠëMœœ\Ü ¥›ÕHòÄýZcúAÈ¡í9œŽrÞ]2Òù}<ß#’À3SrH0¤•L߉€‡à½ ˜ÓMˆFr¯kt‘}Œš¸ '=d“8f×ËǧÆÿ œ[à5>,@ì/P|’l–È”b‘ { è–äc ež¬JMÀк/Žv_¶»û{»Ç»°\zCÇöxùBðÂ*|ë‚xÕo'bÏê®±iäˉaxÒÃI&ðNrñòyÒªð6PN¾6Ò3e*-¤‰¡(¥y‘Ïh»gÐ÷ úžAß3è¿?ƒŽÍÚææ¢DÞ›Èô:§õ²_Ù,2ù*,Læ\lëH 埄• JÕ¢¸J±»B)« È¢°,÷÷ªþ°×„çN’±!±¬^t=JµQ¢oˆB›"×m/t¦)vÚžÚ2[¤5»ùIXõ1á4ׂ™Y©ˆŠøF¬]­ííUE«…Ÿ6ÖªxA>ÐÖÁáï»G+½ªX©ØñCKàço¾¡?ð­òïŠQüäð勲¸Qõ'QÙ®ˆo¡=øR¨*6BU ÄÙö:, ¯´ëVt7?+•å 2Å‚QÌ3 ÀÀÒÃ5c$·—–eåW‡G+°ÖPweÅ¡V¾ZT«ÔúWò >¨¦¸¿œÌ³ÄºÁ—3_ºâ±ñ6C÷ÛouzˆhJ„CLb ª5…:üR--Ac‘? Þâ½›¿— ÊLh®MºÅç9v–Õ†Ü`§Û{Šó‘ïQî³3ú“#ì 9ÛÔ­è̱GÙ ×ý¢v¤™ñäúvdJ$r‡Ìà50EîÏÝwŽ_™Yå÷.—ù6t¢8ðטF.KB'²åâ[bÜ*¿±Ýþuûén]ŠiC¦+ª‹m ªHÀPVøÖóÓ/=?s™›. ¯Ú|ÿ-úÞ BN[2ÕºtĹô;9p dF©1„Ý…-+¤¡…ϪG™–ŠŒžÝAhzs¯”GgMYÂÒ¿%-m¼®3ÄæöGhØ.öà ÜpvÑFá'ûéó—±q‚pÏ=ÔU>ùŸÝö ºÿIDÖ|¢RŠ?¬W ê‘ F•è] V¯ÇÏœ(B[ ´Ã0ÁaˆžÌàÁFµ‘0•ü,âß5ê6>&Íá§°FÆFÚ~z…Ø:ž~Á*£¥›GÙBË0…Ä6© K}ò¤G3Pçl≳!f׈F§_:Ø‚á2У…¶ Ô…"œí!WHÛ£? òY½¡ê´*å•ã_vª¢¼ùã.µÒwƒjS­”¦ÿá&žwÉš?´¬¡'ê¡•*°>}ÿ¿Ç¿tÛ=:Þ?|Îü3žø g}ñü°ûôàðI÷øå“ãZًݨ²«ÅŒKT.TäžÊoãm¬½mJC±ßÇ”Fo1¸Qö¹FSŸ_j¼˜]iÑ«ØPâÙq}çð8¾´"'º f3`2x:sÎqI±5S$¨4Ð.%s~ßnáh—7 Ú_%~I˜—ÝI¼dš­&;8é‚ßÙ?JoZZeFpRŽ{°"ÐR]&ÛR_€ÂÈE#i,†\êi» œn8¹¡"ˆ@Šì«œÀ±CéØœ=”±±Ú‡ÈŽžo?Û=Î ™Â^oªMõÎöÜð%Q[Œ'ƒ‰;#ÿ­c^’a ´½O´‘^]ɰ?»+%ß6 ¯ …V€íÃ4$±K%â´çÞ¤;ì+ú! E~T*ùйv»Un·ù£tÜoK—}Ö4’-–v.ÄNáýIÝà}í6q>€Úë™,ñD¾ÀÔ`â5¨Þ'{a”Ûá;-è{":ßÞp¤3õ­åKp¯×E„‰²ÚKÆÓV9]NêmK|;¢ÃØ Ðë‰V$%#pºup~ åÂï«…Å=}¶ýt¿Ým?ãqèo-„#!ºwŸ‘ºx V$éŽìs·Gë2¿ãÝÞ¨rw%n§bú‚1úÒ¡!±½Yûòêm&äÕ¤;¼¨¢NA|½îtš«oÄ!~ÚÄÏomyM¶ŒŠ³‚ö©í!4 ‰FNó€– Û© tC1[Vsh5*C_­’᧪Š[Ê#÷ÈœX2:2`ψ h¸Î«BÍ| Hˆùh•õ­|éH^’–ña×liiúúX²âÊÂb_\àœ;W­Sà촓ě„ÑYi¬vªÖ)2•7T,¢îþRëQtrb„ˆmQ>”Èš@Ùª”ÓýÆ7ºt¬CA+%m@Eœ €cHˆõ¿Ù(•VWWÅïujS«…ð¬£ÄçIÈ.¡l3›T¸NX#©QÕp?îOzPS†”"‰J„¥®ÀéùçžûoØ–ÆÉ…#¥ 4NTÁÙí(Y¼—µ2]!(hh:é¡e 8`Û`àÈ0§Ö Î{((è5JPúäçI†ÆéñÒ©LÊ0!ïÐ2J¶«€”0uOgÐýs;è“õŽ?`“p)» !³ º‰¯kè—O`pô—6k+‡DCäÁ§×xh ¯Ã¾ÂäÙçÀ›`›x õ ÆÙä¼.»ö3lî ?8/éh"´Èý]+8Œl2¬I½[I®‚$¿3$#<šÌZ0‰Uˆšil­)™:ñæî5ÏuÿÖ"wrð —ÁÙÄÝ¸çØ§ï·åÿÃÛòMwáûM÷~Ó½ßtï7ݿߦk(¤cl–TÄÏÍ º@¶µ_©Ì•»#Ó²Ë ŠžÃ^àŽ£RIM‚Tbü½}v–Å1,‚žÃn¢:"æÖ¦@Ïâ]OÓ@hæ T¡½W ëØ>J¤ Êa¤} ;Ô=¹i¢x$ X©•£¢“÷.Æ &çÔ.7ŠÔ•!ÆËåF-ƒa Qñ™C·Ò€Qn“ÈCO¶Ÿþ¶}´ƒ~ý¦Êñ™Ÿ¾ˆûÔÝÙÝÛ~yp¢ú†‹S…Y›g>–c46Ró´Êpz}‰öRÒÚæXƒ—b­|aY9n†w ·ÈÛÄô>Q!dš”›ý-ÑüC¬~ÛìWD2~"FšÒã4†Ò:MÇ<-•ž™*7X’¨§ ËÞfH¬õžg@õÀSiÖêöo»Û'b÷Ù »7ñɉ Ü «Äñzö¶ æàHÆ’‹|$x$3v°©ÁŽK7C½ Û;wÓü4”Æ{0B[Œ|¦ù,åž.:\•ùÀçì^4¼FP—(fá ¤î¾6ïT¸5­j÷EþBšy=ßžO—‘Ë~ü­ød©¾=¡7o™gÁPu“!…÷®×“æ3[¨ˆú+ÍeêØåkñîp²•yë]ä0‹‡RÝ-Œæ²ZÈMQäò'¾Aƒè)gÞB*<'F5»q¥ÛX|L,íÀf,ì8jìt¦•um‘HÕ:ͤ5˾“FŒ © ›.Š.G-êAØaèž{*Z%ìfF'à}€ ©Ì +ëU8R ]I]6Ðù* 2ñE 0•*lŸnÌ(¥‘ÏÒ#³(}Âʃª2™ƒÓGƒ!<‡þñiÈ`Ó°mAÿñµ±„*ÎìÞÛºt!bèæ8dHúþx8´¨`°b…®œÅÅõ J‘4¨uœ—ðŸ û|jéùÆ¢^ËNÄHqñNpŒÍÃpï\àiÁöl“7в‹`èðÈâ„cwìT¤¶!É£)–7EBÛl0’?vÞ¯ÕÖ;Åæ7å4ˆM åŠYI¼þC¼YUxî4ä­¶Yé›L¥rN©ÍÊ)`Nî/‚“lYA¢ZÇ¢å]kYÆ[+€¸* Þ¡NB}¸(,o’%©¶;埀ז5=™ÜP1eBü®Ç åµ$¯Ô„š†çY³!Ê%‚7Œ(³°Ë KĈÄѾ¯ AÁ9v>We°À-G‰?¼}!{Ry6Œ±ò@Ú*¿”"QÃJîë‰íüj,aäîûIß6J ÔW© ÐèÖØwfðŠ«q²ÄiÅŒHhÀ¦²Q¦™Ïâü;%=ݰcjãö3ë°}f~À×é• üÌÜ· âÔ"SvÝ8zݦò’Tö¶¨—ÃVVÞ»½œ§Ò df¢Ê•ò›©`ÄòJþk º"}U*¥âÖdŽª­NÙ‚íb(ö ðêûíFJµêÚÒàŽ@õÆ#çV}$PhÔBÈþ6×ÑE(ÀxAoŸ¨î¦4J¹­ÔзJlåʶµ#÷ÜöC= cÌÐÑxÐdï<îUSÞb¡Ã M´Ò±ÏÐÁv? Øë䘕æèœˆÃ*÷6ÝèÞþ«g»›dŠ“¨ÇtPHxüÝÚÆš ìgY² ÌU/¦àÉ”JÈ+õAaëKƒöLã£MÁÔL |ë]ãâ\`ÖR‡î[ëáZ¥1Ïø¹]8æ8¡Û‡ÆlˆúÈ&[E|Á>P·æ`ÈP)ªI=s`F[»{õH}xŒyÎÐïaÉô>»J0ñÐÒ5ÃæÂ¾öÿu>Ýú ¨Bó^²÷nx€ÄÄ #¸»NúÀÝAÆÇ, ™ 6Ö Þ6É{º>%o»)©ž é2ciª}Æ œžÕ°V½ÈÇ%¿ú§g’ðÿ{þН(Ñ…¡ýí·µØU.-É´X¹‡ËCJäûµX_§Çˆøžctô'£qc¶¸¢ §=`çÝÃÕg/tG Ûpº˜÷œž‘ % ¾þ+ÊøÀ«ð[Z~Ò(©ÞH Ò„lf;Mkᔹã¤o#‹äÓßNྃ?¢FIˆ}%sFUòîïóú™4 (‹e¨ûò¡äàÈX¸Zâ†Õ³]é?F¦%R’Ûahf¼ á7åíªj³Q,›ò÷ AÿóËàl P\üÌ1§~¶¿I!·aÐ=Ø)¹E¥ˆ ÿOìÆ…ÔônŸC7Œ@úËâùöSôˆÛÓ3^L jNñ_­Rš!H'ÎsÏÛtúï"Ù~9"& Jß#âðÃúšþ´>ÿÒ.¯b!‰„)mÅ¢–®¯D.-cÍ)ö|@n²°ðóíÿàD“P©î”g_¦™žØP»ÞœM¼>ݧ·š!µÒ<ÙœÑHz˜¤wØigÇNÑ õ°þ+|®¦æk–x]©C«Ý|¶>Ǿ]= û«õso‚_0àMèA  Õ3øRpä2ªe<¼‘€9$²¸úîq÷ñC•þ†{r‡,Óx:=_/wÂc„I¿²$<[%•áS Pü«\!Ïp XJãÍáüi»mȽ Ž®¯i‰Ôî‘÷uõ”V«®`<8÷€†hÁ n1°û¹Ö;ÄwuM'ƒï-Ø-INéRïÒ»×RÁ¶µ4k¿Zš¶QÍ#Yĉ˜Ì–Åž}¸°gzŸþñùáû5õá‘üÀ˜K/àÙ™ôSdž‹ôÊ*0çUb/8†MFtÚÓ& ˆ^—˜‰-ÔÆ+}8Ù¡à†FG Òí˜Æ¶ˆäÐ3D€9¸£VÇvžùf|ÑèÈÕQ~v®þð@€ïD>ûOž‰W@(ß5ÖšŠ¢××ë5±¾ÞXGòÅ‹6ížO†ç)œ§Â埳pù'ÂSA%µy£>%{·ßØÂäÞmŠGž’½ñêñÄëˆ6ì–aG­J:¿ÂóUõ½#^¯×ÿñ¦‘óâ»Æëµú™Xb çVP ó3ñâë6urñ¥E žfdó)Ü}.At©€dè òˆ÷2c©~âÔÿŸ<×Ãî˜êLÛD_[..–´UñTqÛs.C?|ÇOüŠ>M‘ÝL3ý¥gcÁCs~øpÆ”&øÚ¼J…/ ÒU"ðoccrI þö`~¢ûköÖjÔJBZYä²Úì QÏÄs¯.Ä K=ÿAcƒŸÃçGïè$zG¼—Ï÷_ýµÈƒ~ö¦-Ú™}(VÕë&¢i4ÌcÇ=»9Ï®.Ô7cÍ¡mGŽ®ˆã9) ¤¾Å ‹ºÆ +ÔúŽTâŒ8‡ Ú ¢äªyÁ’o ¢;3­T¾Nœ›µVÚ/AëÍõ楜³p„³Â#L¯=ŸÙ)†Â¼3SSDZ.ÎîÎ ¯æ±~’åhð¹“[T«TZÖì¡#û-^¼IC:¤7º’°{Ñ„bÉLe˥ܥÜÒvYw"Ÿ<©GóZ/ÏknBêRñ;%'ù—Ø,O[ü÷VË÷VË÷VË÷VË_¼ÕrÌB?«½²nvÞ½:.=¿r\ÍÀË“¹¬[;-œV ã hE|Ì— tE3hð4Ys>!9aðÌ^ŸÅ²ˆ¼Ì+GàQÎ9UpœxÆRÂçí®“³ßñûŽUº­³•ÑÓr¶í›I,s›Od‘ÕîXj1¡JÁ…<½¥CuKyVã õÌÒîÖ9C²r%›Œ§e®X£³œ)‡Ëô&arí¬cx–uKœOɸ“2Ƀ$Ë[Ûc w¿Y«×ã´™úF$³ù­Ëí,½d=K³;Èn‹n4Ø™þ4¨9¬81"ïÞ ~zçH¸ÕÔ\6éýw³Wsm,é óï-‰šÆ7§0{eÕsð;tSíaä ´dÆ©¼©‹j”ùx%”¾; À$gL‘Q",.ÚNQ4_õ–Ø~â+ð'·9ý¸¬ú¶©Jo˜x¿?ÍM?ÍÝÄLÒ™zKüD²"RƺÉélÑX aÓOaY䦞äÆÒEô‰,Ýr¶äMNfÈswÖÞÅÈï‹É·—¢Aùg³ç4ÆïÓ}¼5¢ÁÐõ&†Ðr ¿¸ýàšú躷,l¢Ú˜kGΈ£™Pv/r)ÔEIG‘ë'*"%aÀVñ)‡47Ÿ«îâ³dɾÆÿ)£€é¹¤YŽ…„ûýû~ÿ¾ß¿ï÷ïûýû~ÿ¾ß¿ÿOîßvÐ'Uªá"Ž §ÿ@×­ipÔÚƒr”ýκC¿gª–•U‚ŠOÇ+ øÉ„ÂÄÅuT¢4à××:þð¢âÅ%;ÿ `fù8PRÌÍP¢N©˜"„0PÇ4ž&à¡ïö‘í܇‰9€z‘qXãªÓA}óoÆ¢mßœcL¾Je-“Äe”Y$ ÷ïÛGÏ÷Ÿ?ݸ³‹Ê¦Bâ`…6õ Ý ÔÿU¡€´Ò íA6ã·wW 7¶>J QEè-ÜØ´GÊÆ;yñ°h­<ÝpÅÒ±ÔH¯”vª±¨œvžšòpq°É̇ݾ)Z.ŠxñC.’݉Ǧª}ŸclŽ.{Ýu¥×S©JÖõÖñÊB9ý8­ƒ9{HèE !á«Í¹ü¤:S:¥Ë–dëýkÏÉ«™½R¿“=ãV+åçÏ€C»gÐXˆ˜òÞ9ž‹—ô¸ËŸS#Y£;vÇŽÞû;•JØl¬Šf?¢5Òëý A9ÙXEò”÷»ôb§KÖÏyƒÌ}صÏB8‰œÔ[è8H3ýRç7M¼¹Þ$ì¤à…PIO6, åÝ…ŒÀ‚r£n€ï%×Âû ‡®Œ_5(y¼ya2Œg\~MM8æUR´€'0ñ—Å/¹r¨ D Xô»¸p“¸¼ð¡-]×|µÌN£}Õ•PÈY†òÁb,Ô±Ýsêq°4” );Õ¬2¥¯šàú*&2%H„³DcÜic£{ søÁoŠŒÀ(Êú˜º7-ë•LÓo¨wØã1ï±RádÕ23:ßsÄhr4 :بèt%Cyr0ð8F'÷œ†»ì" lÔþpÖûÐXí7V+ܘ2ŠÇB)ÙâYÒE.c@ôKôáµCºÁ’¡Ã <ðA­>Ja¢U¡4~ÛÝý½ã]Œsûä`·ûA=íî½ÞßyÓ…þ”Airkq<\[\5¢M!|k@Œ˜…³Áâß²a•¹bŸU1Pº{dG†«¢¦Âˆ¸ÎJ†Ñ*ØX§~PR9)eKÐ6Œièö\8~†?€ßcŠŒ«ŠLÈ\žãÓËTpPAy¬KhÜk7ªpèv¨w-ÈMˆÂÃîŠÎ¸ã<(Œäa÷5ñ jŽB-ÃsñT\8àƒÐ=tÿM‚wšÐ_Ô|ó¬E <)¹K¹>Ò±¸vWŽâ¦‡¸Ža…8Äümpˆ MûÂ&ßÌ3$“´Ë¾ÞC~0F•;Rq~§\—@æl@À)¢Ioîqì0œŒ¤Zâ’O~TTÖæbô[‰ß\2«N$SLàåÚW9ÑÕdÖN™KNËkI2ª¡[ô`¡õᢼðÇNSw &þG¯>\P¤ ùî{±Ò’©–Ò-©£µn¾èö‹þmn¸ç«Ù ²kT>ß[8ö Îðv³²ŠêA–ô–ò÷áØ=Š%ô`œëù¹ƒÅd¥±7.HC¸rµ«¶gcúXå?Æ«‰¦©BA°ÉõÛ‡ó.Ï­QƒP;°{œ"Ë\•°2å°»º !}Wj`(kuSín‰Õ)ƒèø§'fä nìì×£†îÝèš|5sGüáÿ—t ù'¾—Ê µ¿p+áŒÎØO!•,9loÍ/ÚµxçaìåЩkN./²ÔW¹¡¥bqki®ìPq«µ8°édÌ©‰ðov56°—‡U„"“–xÊÀJ»$9Ë=0Ãî|¯N ÐNZÓIn>G­$ëüteÍd‘Û«ƒœw.ò°ù l ø×UÆÃÓÿ”¶ŸcL6|ðŸ•^?Œ²ÆðDýÁF59¡SÄ‹úAB¦ÈÔP*3ÃötvÔaѸPdØ4¢(ÉcÓ&lyÎp'<,å*`M]ˆõÿã‡ÎøBs™;Zž2® ¹¡ð¦9UȇŒÜJ…tRœjIy'~º5 ÈVqË8÷Nè B('m;:XôMr>1ºU7ôÎÄŒf‘Œ*V¨ÂÏLÍWÂÇkã.µí(kv*•毟´wž¿y-Þ4Qý;+drÑ©6;ëbgûd»¹6ÿ WÝ®7êvuxBŸâ‚Í?öR>¼ÞÞ?ù]ýZŸÇšÒc¾î¾ù6W•i¼è¾Þcm&=¼@UöëíúÿÚõƒÈ OºýáðCæ 2a5ÈÓàt¶b×.>„Ün'ÅE™äæåxåAzf”oûÜ©cÀ ¡c¶ÖëP»ˆ<^?åe¾Dg2ìa²ÖqєȢîÿ𕼠kzÌ©Þ\"B¬ï†[qÔLÊI69°ã1ÊæK¹û; UÚììîá9ÿ”©Ð#|Ib"{½„ÔÄ”b¼iþÑYÙÂ\­«h’zâ[كιGwª@¤LV‚V›c³âŸlO’$¾SK¤Ý&Doœ.U0?ˆ²8`é:¡ì|d³rG.6J·ýã|•îôçýÖýkIó¦;P2"û'—\3šÛ˜)Çá~6tn²M‘…æÜb‹À¹Šxð>[Tf‘Âr¤\¢üžúuYn=á£Ø¾²ÿüødûy{Wœì=S_rde%F#íü§´$áïì·ö_œ ˆŠ¾‚\† éæ…ÛˆxöòàdÿÅÁ®x~øüø—í£Ý¹èE6«¸3ºÂ AM!rclZ] U»ï¹Ñ‰Œ¬fŽ–‘âþƒåÖÿ·Dô¡x­Ì&ÉYý†5¤(tZáJiÊ‰ëž ÒÅa3¸WŒ iÁ‚‡J£ è­kýÏìîçíNÂ2¾áÞ³Þ·¶JKÈ¢—¦–ëX´µáVnv;ëÍsÀÛX˓ހzÍÚÿ×IÖ´TØK˜1T `)8ï% (Õ5ìyÚ¹‘ü=5mD®ÍIâEÒ$û~Šv¾v£SËnDî»÷v“²zÄ9-jÒÂíÅÙŽ/æUj 8³Ú*­ær²ZäÞkÈ»qT™y‚öAûÿÊÚÕúÿˆ³k LÞµTéfVåÈèK+âkÒš Ý^¤B#“TbaR“Žœ‘ÄÀ t8qÖ¤¾ö9*¾ð»Ò·ÁQ[EÁkaÂÁØí½¨ÔñGñIsãÑcñ«û}]ŠÇræD—xo¾võH \»z¼·×æ¯ e÷â™ÿ{3s%ö0ôÕe†GáYðÝÈb¦1[Â+—öùd %Sh‹µÚ)PÈcï¶Ÿï>«—ËÅ×âáÚ÷ESlˆÎªØx¼±þð¡øV¬?x¸±þl|·vš–”r÷´è°Â|è~°²mLÊþs‡c 4•Q§ž:o¦6þiP¤ØßÖVÑx0;Ô¸b7èüßwƒÏ¨ŠàÕñ´Ù‹RøÚ¼t)7Ø"ìZX‰îd4t`~[[KËi |)Ê!Ü‘¶W¾Â×x#X•7Ã)Ù=ÿ`½{#…è@? £kê¬ÊÂcħv¿/SkÊ©ð&(~GíÎॖ£p—¡¨«Kð“‰.Ý6‚v_²n)qÉxÊéê½wh•`ªq:Væ­ïóñÄܱè}‡¬Ïi_ŒKc€ŽÔ£š,@4Öÿm`ñÇ/ ‹R|ZIÄ‘qf¾ŸV‘§$+îVxŸ«Xü@ºU¹½ªO¯é´IZ‘툕QçJ¿ì»ò^ðeÌæ4Õ ÀþOâ¦4ÿ¨ÔYw@¤n²v ÙYßjNUˆds§ðÔ5Ü«[âãÖÍêÚ9Á§Ïõ°¸ãˆÞw.kj€Ö…‚®Lq2í]´e›äÀ‚DÈÉ㌕¢@²q3Ý…âæêÀ6• ¥÷Tv2Íp­`ÙÞØèo)sÊDa½X.£_É«5qéEµtóå´ôIVÒ'\K·_MBÜ Ùé¥2Ï:Y¢%bn„9Wó\ÅxN$äùÐr⤠ÓOèévwöº]<óáV»+êú^U½ú1k˜‘¥È'„%²A›‰(=X¶úM\3ÝJeÊž’z·ÑrΪ6¨HŠÜS\2 ?•áAÙߥîÁŸìíˆNã»\cšš$¢Ñ¿¶—Ùh|§~i$oÝIî©, «Ãc‡ÊpK†6ióC‚1¯ âçYF¾˜ŒÏ»O=$0ʸ0iCù=rÿ6rCØöØB5_ŒÁ:Éî€Ä¶‡$ªè óA3ÍcÂÍÀt'¨Ñ!š ¥!bÆÜðx‡ÖS÷+iþ›kƒ"?ï„™™"“ƒ"ßIDç(šeè ßÁ÷ê—è‘aΖZ˜ãÀjBø߯7Ö”óìζ>nþÅ+5îú·^—è8%åKÌx:½IàFèi݆5™ÒõÂ=¿ ÏH6ûÅ»jÁVh ¯x”ï3Ùϱ» J»9˜å¾nª dç]Lhð,8ºÔp® gìI•b#y!žL075à3„ÀùsâÂpãNª»(ôÕºŽ.È)æÒ…ã¬y4†ÅÙRå]ñ¯…|d–>±áI±|Í,Âé–›ËH†R–¼A²¤¹“á‘O§9WQBÒÓWÇÓ%>ÅŽâ^úf6¾Ðu5›Éas¿i~öM3阓ŽË£ê&U1©ðÓ×÷¬+õ¹¾² ê艴>›ážàxëà-¯¢ÖS6v8ªNu+Š3zÝÊÙ04Ë¥$ô›˜„$^g»›™é?y´¾!ê¿Ðï³g›ÇG»¹ž ¹-Æ6  o“»%æÔäʼÏ2*Ê€üƒý'´O©ød±E99c&ŠãŒº—C?Ô³môÒÊ ôc#²ý[ÆË×Ú (È=Q­áþçùAúšÕ >áüÈu™í5zþp06`‹L³½,Yd}ŽÜ«×M£–„Z®ÿ9µa6ôš‘­”#Á*$óÝuÀ©´ú @—ê§+¹°ß‘KYßǼùÓd èô‹œ‚¥MŽ„G;ÒWWj‘Ÿ0Éçóü®ãEÁµ¦s2ƒf?xv~ÇEçj,‚©nI2”U‡9e)°µëmrQ@Ç‘~ Øs[È·Å,ƒ¾íÞˆ`üîb¤ ¨à“/švd·êOâ\YD(G“-ö¥c¿•Ù-ãx*C÷­#=!YK–.Ò”ƒ¢#‚àN‹‘IÞÉÕØ…õ»Å]¼@6Žý¨`SñÖ¹¦Ð•U"ê-»„u±Gã€@¼* sñH•Øé$nX˜W¹¡TĆ5A¡Ÿ) !˜>¢§| #Œ&«þÂ"€·¸G?fÜåÈýÆZ ýúUÔŸŒÏ +ìË·d~þž¢2®¬tÊbC´`‘œXU¼§‰ì¤‘'ß}ÄÿLï‹ú$ÏóbI‰w¹9M^#!~’¾$aó :†™ãÔòQkÁè7±’ïkžo‘õÿYÃ^Áߡ߸­*Ûª ÀÕ¦ç×Dz ºú5”\1Võ›Õ¯qô9ÕjÝø.å)³Q[£…ûª:¹^ ¿šn+ôMFÑÈf46×À [§¶ÂwÁÃÚªšƒÛ¶5‰iQE¡‡×Þ|П«øùõ#–;Cºé _®¼v—Š’ž®xY£¸*Ëòt“/_¢½H¶@5q–Ït0–3 ÷·ñ•^û›7o„FydJ/ƒrÁ:0›gqEÄÛu‹ ’1«õXöã)RkQ"7¤àÂ5Éü˜“ðÔ˜¢ÀÀ(’’üCvÆÑò"LA/ËŒ\ì gµ1³)–ô¼X9weÁó¬@ð„7žOßK}¡[CT$´g1dk 6°Æ4`ËÃ>êX5ÂÆ1:ü§DÅtâh>å Š !ÇSP˜²ÇÔ°0§.W{$œÒr°(k’89lSš;-a÷ÁŽàLä¦Rü̈†Ó~õŠðØl3:q±œûm-Ê¡ ÌÁ{¤Uæ†ô€äÜi 2¦N´{E5ä(kÜ8MÑ™{Îm«Il”rµL•ùõAé‘9E2¡ +›sx‹¡f¤‹‘ Ýâ –L‚>ç MÄϪ© (Q`÷]ía¢r³Üí*w1â©x)€\¼*5Âf9‰ËÙùSeST …†œs&²îi±6SjÂ)ç褹r†9¯­o(îŒC ˜ƒ fÎñ?ÐŒ yÇ"¬œÆ°|f¥¯t†F ;z–ÆW=Æ›V9SXE–7ro»‹¥9R¹Aaðaã&Ûm4›ø1“p¨¹Jq ãâ°‘­6K%Jè× Vª¥÷¸hP œhxbm«ô±Ä1@xÝ^4¹–Œwoé^shVsd¡Óo©ikšŒø˜‹f ¨ˆ÷¸°›¬ÉOÄ(à+Ú‘¨ð.bµÜì¬7Õë1~ø(!¬è¬Ofã­Óþ½sÉI›È¼ t‡Y_–³c°N)h-§5Fl‹Çëg°ªùP$_2Æ$mHêê aÄUw0©~š†SFñ ¶Ž;°Gø?¡ÜG\*‘°&A;œ²‡³å5ž“À÷vƒmN  ß6ñ— ÌÊì|ú ë–b¦?Ó‚âLVÚ”RÕf…77ùØ*Mµ¡'¹ú&—‘—ÃJ9q¯d®³O5Ö<Ühs˜ ZeIÍ·…7ÛÅIÛ»¹(<å>˜j‚ÍNZÉ+*¦P—gfK/3Q~$®3̦Þy<ßúñ|dV–in΄ÕÁ©0{mUn43€øKÌUɳ5Èűª?¯––§nµi-ånWK÷ÕýFu¿QýßÛ¨–n½E±¦d¡]d¥öW¿y]“Έë‚W™Pj/bñºœ,4GäþXëNŠ5Ô²vólÄ‘Òå® Ø·TÃßÀa2qM\ìžs—¥‚a !óÀŒ'¤~æ§ë´¨›ŠY}4zdžM-s—óXõ”~)_˜á¤xé-cs|šÿ”Ÿýº³4¥DEÞÙƒe;›;jMÈZ³°¦ˆNŸ©)ÉchF”§˜õ wO"ZLö/QŸ¦¥ ÔŽmæVø5u­º&Þt:Õ¯¹ Îú×çÖi%};ÅÑ­S'èžÈt¡;r1s)ª¡ýKÒѪ, P¼(é“_]N¼îB»ZXëÙ§V…$Ä4ìa®ÌOÏtÉT_ ‰J¹ÝÌ2&t¹"QÚ†.ßû«,­Ýsâ"eûmP·¡é˜=I·Ã+ÂlÄrsäŒÎЦhÃÿLè>>9Úd¾h?ÿ³’>R,¥¼ùV¦Ö¬ºõº¹ºòlP\¥à³ "Š:®d^=ذð³•ë1YÍqºœsÜîh<ƒVÕªYxþîXf/¡4ThÚŽÃð°12su-@õÏ~s1ŽD‘œÝf®Æfm4)î}úûô÷è§G ûîë‡béÂÛB`ñàé·Ë¿6=Ûà­0»†]ƒ™Ž=7ƒ|5äKûçì‡YÙ ãìlŠÊ<±ú‹/o–Òö?WØŽcé:ðrsÍ4D)Õ5g•¹‰¾ oà4ÛÂ3hQeŒ§iV}];®wI§êS×Ü(¿#¢B¡"ÞÃ)ÐÆDh½·\ס9pi~©)ÝZÂ|ÕêûÏ^À2Ü´ÊètÙMÀ‹cg‡ˆë?º­Êß.æ7Eý¶ÒJExR=ÛÚʉ®’‡G£ p«8ü`b*š¸HÙ]ÿѬ“*¡ÎÙd\þ µ(ŠÛ3›3£‡Ëøá@`…£™ƒÈ¬Ÿ§ G»(–LOƒ"Ù„I„IÙBç^•'8>'bXQåas&Uuêt‡Œ–$…ùuk¢ÚªDÁÏNsF•]Ê&k}þcO?ÃYìªÐɇG²(eëÒ_‘¢F‰¤ýzªf"ãþ3çàx‡,BÉpÝöˆµ"ªÇ mJ{!9ºÞÅÈïÃéå!Ðò°Ï×XŠŒî¸È0’Tƒ,·eý|øòäÅË“Ÿ“Äu ò’Oºy¥y KÀ5=ïÉGÈØù°ÚØ}µ[5£Ê%üGÖ†“€N¶xº³åì³œŠ‰~ 4cJ#7ù\ÿlûùþÞî1P:`Áða°¦ÖhgòÀÞY9Œ3 FÔUY’$êümÛ&AÏÙÌ+NFÓΕ‰õ$~Q/îd‚±URù*—Å6ËP({ÈÄÏÁÈ ¡"és¾@Mk%··’)ÝE}Ø+7•3oTÐÅÿÌà×ù¼Zc0—Ug?W¬9F çÊ=0ž@º^+ãCe,™ &±^±)ÙþA,á_eø{ƒ­`Ú™£oòÄ\ØãÐï_åÒ­Gžæ9/Ù}ê¡F­<öÌ—¬>›¨µ÷s´’½eï:L†P¨EÿtÑ#I÷f0ˆP […C¨”¤º¤ÀÒ;—=”»€1˜ÊnêmiÚ ‰C§~СIŒžíIšJ$ûÌ/ÆÔF’éìTfë˜3)%°wNpæ‡NWm´­>Kõ[ ¨ ±¸\:ù7úÀg:e~¯8MG ŽL%ž:eŠÌÑì(Q´SÆ`ht,ô¸B:¾vApàG w`¶9§“a¢Ï³úY?ƒ7Cg®þæ4˜«ÁCmc…C¤£äÞÉŠî”ìÞQ° » "¦¹x‡Gñ°Ââ¹È`†2ãÞrî~‚§Ž,æ)©X±ù”fõç“«iARžŠúE:Èâ¼AQÊJ4#2 l§ã<9ÞÁ0Â쇡’LBN¿Ê‘ƒzß~Dk _)ÑÛß~KY`[Æà XÆio‚Þàq.b寑 ø¶ÜöP 7t{ ªf$<}áIrÚ삽T1† Þ&žƒ ðH¡¶b«¤­l Œ¦ÂQ4Tq=@Æ lÎÌPeõÖ†öaôÓ¦íæ‘l„²uhª!Í3GEÓ¸pè›eñÒÃ=hâÙ‘ƒñ$%=/€#MÊÈŸóp¶¤S Uw‹©Œ5«ì½9? Ú9'·ÇÅÆõ²ú¢‚=ŽòÓDK  ×ìsÌpr=O³86|1F’L鯡•‹ñäêûLì<®™÷(’Åeÿ¸~{F×ܲýÛîÁœøÜ‹¬Kç³/Içó­›;¦xOÜkköý(_bBÙ!pŒÌtìÆ3ˆ•çGß­?|ô ~MlÙXuÍ^¿¯¼kÂøü?¿²h+|ô Ûw£üþ¢¿§Ô¥ýû§ ö/''ÜsÒ¥E=Ã0yhµÿ¨dô—·m›-ý7ŧ’á21×î,æ6 K²z!ðõm(CÅÉ(eÏèÐ…^Î@ 1ï¯!õi#ñBh†‘8ENqß;}ïH`¼þƒi†^´a†á¹©–ˆÉ•ÑXùlKqÌØv[†ù=i¼ÀÅð7,oYœ[ïÜPLIì-®Ø<,Åh«Ñ/ìp\Q²,¶†”6î£löMWe¾wbô`»\h¿HåÉ¡mð×a”æƒsHà OÕN€«6DƒÞH޽Š9ÝpŠ•Le2Ù·bõ–µiNÿz)R õ¼óóL³Úz: ¿©ÒÊB4à Gc¦î{Z-®ÃÿJã7ÕŸUQË&*“ÁÌ»™ƒ¢lˆrv_âÛY‹É³ŠÑ.e‹ÕSåù›òÞöôÑSÿ9Ù?vÍHs;Xx°~Œ¿¬˜'E÷ä3‘ÉrN >³4øù9ÏyïFá4òQgÎy×ð(Þ½2À`hH=çÜiã³ÈT‹²Iñ”öþ¬‡îX%®!QΤ5ö€ü¶Gî…¢áy:yQ´Õ›!¶á¸‚â2‚ÎzÝ•>-RØ¡ŸTDP˜)o¬eœé.½«Å¬e}2uw#y(²‘agá¤X–¡öoTÈ®Ÿ³†½/XoÚáî…8säó†újÇ¿˜8¨Ÿ‘ CwTÇððÄjØ žt¡œŸwººt©³Ø¨$u§Ûu‡ã05W¬Õ"àò8/Äåv¢ìbÜW6ƒµ”Ía‘P’8RþpÕÿty¸¨Oeri» _Q n‰ ®`†eŒ…©ÝDÅœn¢êÏšU"31N5³ÜÏè¨ÿËf&nÁKd &‡ŸÈ+J¸¹”ÍSdÖ™-…Ý ¥v‹¤ˆ… Ðã"¥â×bï©i¤¦NO2‘׬ŸsJÒó1Ó±sy&þì±ÄWuƼW™4][vVY%Üž§7nãÖS:PñPœ/¼:ݸ^¦9\OÎÈëºâ‰ÛïCÏ„‹G{%§Ü?·uBX3ñsw¬’*´qú³ÈÍzS¡œ6àà4ɸœ¤ÙáJïåý§shW>ƒþÎw¯Â |ü¹Íòûw×»læü.þ8 ˆ˜¿úÑÎRÑõO¢fÇÚt‘º©›¡´õ(¤ÑïÙaºœf*Ò7Åâk ?álÆ qf¸èÞõ–ž‹_˜p^N™ZÚp|6ì©™¡§ëo”èÝÏ֜Մ`öürAY¢,dñ“V(͘e&eƒœIFX`)=và¦ÂÄäkåž >‰½ƒ½Ó½ƒ“Ó­ƒí]qº{üBý(Êø ½û½´$á+G tTlYªLË*Lˇ°uº%^¼Ü?Ý;Ú߇'Ï·Žwwf “¦w×(7Õø#E¶ «½ƒ¾ ¾7>uG«Ñ›¡eÄУ™xýßÝј·ˆ˜ÞoCÏÙY{ŒÂ•Â4C_"Q|8‚}v­<»¬ß#¯ hwºµ_Óm½Ã2~¡IåZÏÚD“j3Q®e‘»My=Ú­µÆÌÛïœ72P9Vû¦ÝÿÓ¸C,çƒô©njÎ,íÌè&$õçf›æG‚åC.câ˨Ò$Pj­V ¸ÿlãÙ¿³Ø5ÆÏgÏUÆD}žYú«Èþ*7eÙ"­VáV넼¢tYNƒ¡Æ¢>Š$Œ¨Šúþ˜SlFýÿ k*\ð¿È&£Ùýk‹ßP«â¡Æî,ãœ=#G)J4p.¬¯CñuØjùVZ]dµÊ³(˜gý¼¥7TT—*ZõK fESNà…“‹îù0Vµèd ÂìÔÒ̼’ »Ûɧ9ª·Jªõ$Äí’uH÷ú:²+ÒíµùzÞ¿)Ü jÄ÷ÀÂD5Ÿ:†œð^sYë¿¡nWËcŠ"çÏÅ\™ÙÀ“Þ‰r÷âï…MÍ2·«?>Ȭ†Äø+<ÍaDu0º3¯ÖÚf#¶~g¨ˆý ±º)>mÆ¿gï€)ß OE9Söœmäç(üÒª¥„¹¡xdß·Øà@®f%C¤AB½o¨$}yò ?}ñ„(j4Í ;±L1[ØFÊ(Ýjög•Çýæ¿h°sÏáF)0DYH ž#=ÎLϬI1zÃÕ½¡Øæ {ÕÁú™S2üSæ«#X=é/;s Ï¢‘ŒÐúU)° H¨ ÇM#Ñ P$A+¶èÜóÂ. cê ³„™¥LƒÛû¤¯2o¡­¥`¥ÆÉ äD'Ú =tº>áá‰uû±X87Ùk?VÓŠhóŒ™ VUL„NwÝq*¬,!í•d)Cz› jæ€å#2./³ý ªºDÒû(nø¯ŒŠ§£ºCû½`d$y‰˜K¦2áqÊ)Y¯&:nב96Ç—#t¶6SvJE›²'Rl¶âøžïqèWöžàºÌ ¡1PvˆgêôšŸMÑ‘9aè35œŒÜ:œõ'2 Ï¢~# »?‡¯`x¾˜4‘W™ÎéÐ÷ªy§ñ¢oƘÄ2niòÄ”€ãÇ$Œ^ =wàúl;¼, uL©ÞC´B„Á!Gû[/ö÷žÈ€ÿ™„Ñ×g£ _϶?œ9Æ0r1pƒ‰¦ç[Y~F(•3L#òÍÒ V¨ÓgŸj?Ë/dc09>Ú ›\l8¢÷ mýLÈa—ßÀ¾v³éÊhâkܪìï´_´ÑR³²Ú>»7yN7òµlQ’öŒ¯¾8JëW{¬_õÝnFÁÕ,PÅš+a,„QÇ,AúÙ¸EŽŠŽ:¹¢˜øãÑáÐõ_ì½Ò/^úÞõ/pÿ}êߨ¯×î¿YåøY×Wøš vƒöú{àó¡ÐúÃ7E—?:/kHh+EwO½zÓV7IogÅ‹§MíÎîŒIÐñ’ažovŠ!سÏ2 gŸs,™ÈúÈD7ùüèýc#RéA0v70EÀöÖÁÁá)™/Ky j¯\1ð..Çð"’q0:3 †¤s"`Ø(ÔÀáMÉì˜k¡ßŒ/Åi¦(þ0¬XZŠ–Ê‘<±\¡×½¤˜¦!f›Øtîpj)JAû^2Ý*_ÿ†Sè^¹•‘kDgå,8"9øqd/º,ݾ¸TÍ“6\¼à‘Ø6ŒÃ¥Ü#ŽÁð Õ弿©_Â,¸Q—ཛྷ[{®Ÿ)tårœõçnhô¬Dµ™u3¥Ô-6çHœ5_èÖÿ ÝšŒ›×ß ’Žîk†‘d£|Éú& ׸œ[dòúa(ýŒÆC{ÝàC]TŠ&¦l-J\a 3­;iMнkƒx5 iûwó ™»›îaÆ×o¾AÏ6T‘Ð`FK†YÓt'+%þ[.aPR¤ç¾Ê­{­=dè@ÀçG(G“l]—³È¦…ó~ýñSmSš(n7ÕÆé1}ÏM%ÚV3¨S­³0—Ÿß„©`µò{Å8½eHD<¥ázÂá{8`àC'1%–©c0<ŽY Ñuõé#Wžv¹ ö»kzÚh!—ák„3ê_Ê”ghH€‘cw€‰lúlçÒ!‡Ù.î9ºx@]Oeüìôá¶Û»C2„ø):†á˜& GÁf)…<´©A`nzYtq¥øÊ&p†²Íà—4Hž7R -æ„BÕÈ{v)åË-WsŠ;7 ?Àÿ‘C7iY-žÓ–•3«- ëËZ`õ'ÁnÏ‘c¸üZEý~W(Bš„ÍòƧ¬_«ü#l¥²®lÉvh¯E¯¡ ú2%ÑLÝLõÎñ‡äo<[šHøYq6¬6 ¿q/à+Jï®4OàS:ƒS³þžŽ1ùJëN©É˜®´i˧ËîNÙ!.³Þæ¦"“Ù… “¦­·~h}³&ZÊì¹eÑö?-#û—ÊD¥Eý¡˜‡³%ZÊßëÒÝ8JeSPTzíÊÄ2™+Z´Þ‘¨=;F‰ÎãTä6îqÙÇk¦{\^Q"–wœ‚꬘äpàsfÑÿ9Ì$˧goátÇîÈ Ç^7,8ÀŠ+Æ­RÁ]+G»&#!W)“èÜGpƒm¼Õqö6µÆþq£¢–©¨d%7³9 E&f!ꇶ5@6‡m÷×f%üØl­¼ÞªÿÛ©ÿöf£UýØZûx‘h>U£ñ±¡ Éæ©¢]›“q"“Íê}²Ó©óÇ:fT΀hSÈÅÕµæ¥)Ktâ¬dD´O6Ëc_mmJFnY†;áÜ.°“Ñ+#֦ż¦a–Ö#U¡r W—x „2c^ya_@FÛ;ŽÉ9ˆ—xJO-ßÚü$>p¥ÞRZ äv‚ Y"Üß”+¼/Q¨tðtSÐãÈ~âS½^% Ÿ«L1s[gꟶ¥Š™›øÅüµ~ïž’}â„”Q¬uziÖ7‡·Ã¯¢œ)Q»õºQ¬dþÅ?•tóØ [àï‘ûëk~ÿ:+j|¯a"ªgPúS…)ÒÖ/?©¨…ò‹ÁÀ|7˜„}Lí‰U€UÃr{£Ñ ÂETW PF‡lKhÏÇÅÌw°´Jf¨°ðc#ƒë9‹Q Dt œ aðþ`ýäèL‡EÉe¡Ë­ö½•hކ?-¼kH­å1#¯µR’‰©;8å-_áe¡˜3c”R‰ˆèÍÄ¿C»šð2þ/™Ï”þ?efèÔM4'þ;8’ý’4rno†.Üê€H(A,3×M+Š\ƒÇVIMT¯?eª¬ßj ,{kéFµ¸“e·•º´Œ,‘/n‚ f•&‰¨6£¯Æ6F!m7‚I…i´ °Øœ™Å¾{™£3;Á„¡aÉlAwþKa¸ã]³Clº(H쩳£¨óþ¤Á¯{“‘JØî£éQÇ»æïÜ‘è3p¦’Ì¢lx'’ úä&Q'ö´”þÇ—|ï ðÎß{%XÙqì’´1§øIÈnÈ0‚²u c©ïØRI‰žfè(A©ðçíõÃúwoîvî’hE*ŒØZÆ3ÑDXÆ =uBc¨µH³ÑNÌã™ç­Pìm=~(ccÌ·t<¯ó-®ñ•u<‰uÞi«$­´ÞFÃeñ 2–ÈN†8­ëöwìëÌt¿3½®”Ü\óxr9@K> ‰~2XŒ"Ì 2#5*H`@žF¼ÁJJMñ0]QYþJتè…1ý:¹p}—ù¥ë¬ Ô> é+v¥¦ôìØ]h§khвÈ×$¶Ö Þ»ý`HÉCßÂ¥lL]qr༠(½ûû¾]*0µFEþ!;óÙ6͈>°p±² Ïíö³ƒ—Û'D¬cÌóýÎëuäeä‹{‡ÇX®)¾ûG• ¿$’X˜/–a>¼ó Š3â0`éD**ÉF¢?­«J«6cú5´Å͸Njþ”ì=a®¥øJpŠk¸¶ÑõYÀzðdϾ̖¢”,ƒÈôL‚+Ëep£€‡¸ü° mñËe„ã“(ÂbkýièF…7$Eé¥[+ɉ(#%Ë ËÈü¼'ÜP©©ugÒ½Ô°1*+ÛÄÇ ò‰Äûn Œ:„Ô`»>‘UŒ « 4<6,‘`èì£q$ºMCÒð+¨Ê¹žA# un°o„bÀ¼sbÀÖVg@Oí: ÛçøcžäHÒ¢ä)4a”±×[ý0¨)S($AÈñCgqä¤ßÆ %“1v9äð¸:À­Ç!!ëÑX­Œì‘Ý>ÜÕEœŒ|úýÞlëuœÝ:lEéÜÕ ßh5%§Ë›©ý|ôÓç¡¡…eê¨{ÓÁ”Ú0ûgB}_c? Q2 ¶!« ¥Œ=Sà ™0<×øh&JõMFÁ”0"ù±¸Šž)‘!¾kp¨õûòÜŒ@t¼ñ•׬Zy°Žóöøa•›!)ÁAõPwÌfPpUxïõRP0›1VSžÚ(T„'Œž ‡={-ú¨\¹Î»ŠxçÞÀNîEsg ’!FUž¶÷·vöÿÅèL_½ÈöØÁØ€Q›°á;.-²‹»KeÝCìRX²EtBÐnÁ\îXæ\‰äutÒA×YÅŒËgÕJQò` â^”- ‰‹%ê?ÄЫdœDd6øÝfü®•ñú¥¼õ5-0– 1GÁ•‹yÜŠY¿(Á7 Ü8©³LŠ-S.A¿È>Aíc[‚<)$šK·éŠ¡ö•#5Ì/«çB‡¨ ú†À¶?ŸDy}`ìhPEú?rŒšÌß)Ï®ÄÕ¥‚2ñe( ºï„Úõq•ùlX§Q@Íê =(IÃmƒ‘®GUB €ñ=ÎÇxeS€ðŠæ:=ÜÑw‡L\$¹ÁZÇ o¾R;lÛÜ 1çµ›Ýç..3ð¨IîS³¸ ~\ì/Þ‚eÀ‰wVxúíŸ«Ñ üââ9º# d0a€²Ña‰{)9Z$ Pam"{E ^´H|^éÙ…Ã-kç™O ¯»u± Ö¼7"cñ¬ª­â<ž£ªW]Ù3h©Ĺ[Q°•‘É?uĪւx2h©dÞ•ÃÔJHk²‡´½åUhç(BÞ"‰D̳‰[jÃ#ST£(3Hraªn?Kµ$B~ÆiƒññÙï*6¥$Šê;Äs„Ò© pñ —•Ó™© ѲÌlK9•Ô¦UÆ‹ÞÿNHGäÛ²„…³îï:¢ºì9Š 1É.†‰×o³¦Ü.sa‹Rñ†ãJþ®£É•ÇTHv:zMoU~(ýkö*Æ|%ÄeâÀg=‚¹¶”Ù»-_Q ƒ ŽZP0m¾Š•ÝÊs…pT@ŠVFö’³ Í9ó'l8&í±ýÊv3vQísP©;¤¾Ó6#sø~/‹S£«Á\»1»××{4s«ñNãR"Bw~±ðÆÉ”O64ÕÈÄ~'N3Vº½hk²bfÿ }BYÝÔH²Q< ªE[5sÚ wRO‘:½É]ØñS7¹#÷ø{èC%G€’-¡ÌzJ°©.œ€Ãj¤3CàL;?ì*K‰2^ý¿ °Ýë÷ïÿClaõÃà€Ëëzt ÒBKy7YH +È ±Ÿ³F\}-VÑÅì¾}xÜÑ¢p#ÊC–(ݳKGJ³ØÞµ‰&YÛ|;3©éÒ@wà~D<' V#¼ Q«¡Òlz— ßù:G§ªH,U£eÓR€QÙ=¦òÛón6rÛýÖ^EUØÛÆ›ÕVµ-ÝZûš2Þo’­îb#{8P*¼„ˆûW—¶/;'dÖ´6ÅÜupïº×p_ã-WIéúù;®ÄüB,Нþ4 UÆž3EåÔlØó^?|ô91ÄŸ°7æ?M…b' S”ãßFØAKò~SF™1†¦)$ ô©T5¡Q}µ¶ý@yÚÈëð‹,¥k>S ™Õ@¬ör< ¢CN%#ʤ+ÕÌb‚µU—Óëõe™ŽÿF©*;h£(`²P²$%‹(¾ÀÂ(z©“ì…e$l‘ŠûPbm÷æ-:huûðêÁº¡vOb3ïWa)3pn]34kúP"7T xtÑF|Ð…éÔ˜ÂU*ò»³¿Oo̰쵼ÂXVmØvðÅvI«”Íwaß(8óLw³UÆg*PL¯OÌïYùäù.4ŽaD½K”Öfn [e z›¬ƒiI†ƒˆn-™4ËuÿȆ¹-]PÙûà´–Â\¸ï(ÕP½SE5¯˜feIÍÚ)'¬ËAÐν뼆]v¿,J|Ž2Ý™ß0lüH$ï söX¡dƒQÿVùÇM­bª”ò8?Ðïç- ®BñÐ’Ò,Q_ú}ÏEµIMjö•(_(·_ä{´M/‰I“#*P¢"ÃáÆäÅ#ÚeŒ>sxuµ7Ð-cú»h±ù–ò²ß\4*g²”¤á†%.{m¿iÔÑ´3:;bBä—CŽËyŸ¢ìð@cœ¡gÅܤŞ•žÿì—hRLA!̓œ ¢‹Ümë$‘ǨkøÓX®áÕÔÕÊ"eÓmxuË5˾H$Ū¿x>Œ/`Þ5s…–½µn_“ägŒ*¢'?o+ÒlÎ7%}¶u˜zÐL;Ž•ÓI³²ê4$ŽÌ:ÉÄ;›å½§'ò5<5+›Ú‰—-Lµu)Fž‘t$Šì‚UÊ8ýaYìÃ!¾sx¢3¡NÌay5Ûà±ò …3ßÚD8¾é³žPÛÒèÎòIÔ• lýi\È»t|wc[XØí¯)Tç Y?Â⟴:_ÿzÒìzÑ®[×ụ‰ڇ­H¹Èõ¯§=m¡´]^^ ËÜN[ðû1ðoÑ‚{Sÿm«þï7­Vuã£h´Ø‚¿¿…s§rß?iªõC B jìg€©Ah¾é8Ýw±’±Lï¬%G­Vã¥^ñiÊþUårJßý xÁ(Þ¹)=EektGLJώ·~_Ûà—lÓ^<­Pó×åj Ÿ=Ѹ1GmMÑ%ìÞë[ ®&ù^‘àr*0v9º±Î€„lUSÙ|Ý­ÿ¶ 膾<¹™f—ÅY¿ Ð~¨´¢Žø…ÙoZuÀ‰=}§Î´I JlúvÄSÙÞQSVAÛi'o¸Qö :ȶ #ÓÃGºD„˜HRnTØi@èø¶Xqí [XGÒ‚™ÄÝjÍ-µK¬j^ƒ/׋Û_/þ,{w¿Rü‘âd”äÄÕ¾£©\ËâQ$|ÔìåLáH¥w×c¸Êy_fÚµe#WDJqÙ.ï…”ðÆ‹IßG×èÒ†Aï†f+WâÖ»é÷¬¤ÐÌn¨;“Œ¤UYÓ9—ø+ %.ÉÊîøtíü+CÚeHW*]Ü.(h¡h 3™#ÜA‘<ÞŽéæÏëœ ¼ø mF¹X%^ZÄŒõ•ÅvïBæýû£­µÿ’ÒiBOœÁó‘ëÊTn½‘søç}ÞDpÑï§Àh×rˆt‚ÉØ¤—i°Y$kö]2]F ¶UÀÇ÷Âêk(Äò¢¶aÝ^¿æÅ…#®tþÃ,ˆÁ·èwͳt¹3Ó¤ |Ügò`|7;À\'‘T[ëèÇ’lL½lEEê˜ÜQÉÔ»‡öš½–(o¦÷[¢Â´n³i,|h?˜ÇyMîlz Mޥ㽛ü)GG.w" eÛÐ×%Ý¿ã)“ä4¦ G!Ð ‚qã2¸ Öè1@oùÆe¼àxXŠ9ÈÅZûáäú;Üø°v_?­Éƒï±+;bB….€=Ã>î}¦ä&=ÔÍõ'&e‹,‰eøNçutcú *Ò Ã? >;.e` Ÿ˜&)Ÿ§-‰ vI>笕ÕÓ‰çÔ½Jþp3Å=?pý÷y}¶ó”“ÈŸr2.r.*.ChQ÷üèå«6ºßµ_îìÆ}è ÔÌJ{˜âÜoö[+5c%À–"—ûóøaV?œ·Ò%QJ`ˆ$_‡ÎjÂöo‰°ýñyp¥.§ôÃïÁ=èä9”ú_Eéðbè¬ßo+ÄèvCó¥Uš‚¹wÄTÄ—lŒX`ÙçXOŒ]/îQx’‘ûëÄÉX—씑ô·YÓ¸pæùQýå+d9B±ÊÎH«"ìWpÛ›0"§\ÐCa€&=ª –󧥎¬Ù‡":iâ2 SÏý¯&˜-ü’]zÔÄ g Г¤ƒi œúÜÆ6›PžÞ@Ü‘wýúÁŸå©ý·àʒº=ž5ñÀ¾–Dkbåh·ÆúœÝý§Õ™Ì¤¦±s…|— Xéøð|àÆÁP q2oîF‘ ÿÀ ½J*»¯£˜ÒVG®^º#´‘ÿâàp€ë/¶éfD¯ù×úAÈt‰C÷ãàœü{‘nÞE@¶?t#"(8pUvŒð¯4p¨‡öã‡æªÅö1ä}€Ñù“v³ˆUÊ4ÐOsß óy²„)â?bœªz=Õ ³¦5²a¶ãÀÔ¾¤h±O4$è÷0Ê2ŠÉ!¼œŸÛ%¢/«ô wÿÄ2Ñ/,˜¥Õ 9¶e%¿7 ¼^ú@Ä(9¨=âï$ÊÅ@Ϫ‡‘[wÌðþó…óeISß[žNÒVn™ÃoP°m’ictJòf¨ßévÝ!»SÅ ‘7r)ˆQž;à3sh¸î©¢Œ¥MÖÒk؈†ƒWG¸ZBþÍœÕEíFg¥^< k@,‡¼ÈSËŸ±^L ßÏÈNs8@1>Œåc¾7€ƒPè ¨ûnu u8BñG0t}•U¾ƒ¿ðn··p¯ûs¹“ÜË¡‘Éùõ~¸þ!~Æs uµsŠIB$P#ÎzüÅ­O«Ìdï%ãn4U$Ìè OQSNUI[òCƒ¢Ð]õ›-++Æx ˜ÆViIöhb»Ê,T­ÑÆQ%êïî¾mT0@0ÊÞX‹‚åÀp ;Šæ›otÌŽØ–Þ¿o–WØ¥F¯_´hÄP×{®W¹´•޼H»hµ#êå••oåʖߪV¹²-Ú²ª¬æ—ߟ%¶v1‹ÕFwKb*KIó¹ÄѲ>D¡k•¿°Ã®8‹:âðüf8­Ìè‡3³μ.þSüïĽQç~ví_ÐK¨`Æsœ„’BLyÎ)¯,ü}(ÿ>JŸðöo¯7ž“©)Vú¡R¤ÉQäöß û£ÞçíhÑ€6Ä-67®Þ¨'Ãåé䔶㋊ã3°iS®Ëp.ôHþѧ°8Òœ)nÇy™1Ý»Ö6L´¨È½=Ìçêþ6 QÜw {4uš“5FvèW™ÄMb3˜JšÌXÆí¿\º’¿À0Ìh8¹²ˆ }¯:CÀÌéþ9²¤jÿøåAdÖÅþõЯ+¬Îèì3` €úM-ŸíK4Ó€r‰JC'ωJ†ÆÃÕG„€Fz6ªëcê6ãw†ž3‡³‹i„½˜'`¶œ-:$Ns…Ý཮Ÿ½'›>Œ—p-àó!܉_ì½ZU;}urµžAA»ÁŸ|¾ý-N¶iqÁöHðCø“±6‡©jëhÁàI•¢\5ª·Š÷µ¥ gÍéîÅÑé>žK÷ŸÓ£§4)õ±3ºpÇœªCˆ#—¿â `1´VÂþáø>«¡ðdœÅgýÏs$Ï-¸vêÏŸJ<-•><ý™RU%ò)ÓdªF‚ÊÈÝTRA¨B ÐÔkŸ£öˆ2ƒ4-òÅ)Ǧ@” Å*Î]ºœÿ“kµw_ín·ŽwŸî½Û‡/ŽööwÙ7È\Jž¨;vPØ eú”CœîA¹OQ/ó#þƒ™¥é4‘Ëi<ëÂ; u`5ºMW&èïOÉu2j)ãeBCÃîÈŽ1µNóž—øÂ2¹mr|ˆ.á½)Qîb jåeJ‚ýÓöÉ¿Nâ¾]ƒ‰d;Áž—ºI²ÜH‚JÓ‹ºÜ¥Êo-ªÒmYØ)NAE–N¨#¶fõì½ÓŸ``€xR9Ê“˜™!WQ0ž› ¥ÏþŸ3—î¥Û%;Œà,ãÅR¸XaZ¦7ÃÆÆ)Z.ñB)}ÊÀ9€Çe)–î8×t#¹—´t‹š„Èü¨hQÔÐdPtµï”9 ýuÿýÀ¯»×€f¸C ƒ]ÓÎÇç »h.‡ÔµåÂt :ÄYŠa^)ÕœÌÀ#­5¶Ç (œåí¼(;”‘—þÊt×bf™°ÎˆO%—AR©l¤/e'JO$µ7î¸>ê·ÁÐÁû–—ããnŽŸn=ûyëxEOAb Õh2²§l¼AØÞgÊÜW‰ê؈E¥ñ fª@ÜR8¦ÃÙqgT‰R»>/§V=ébªQ“@Ådë_-á0?«‘˜â52¾Ó>ÖûVžÚͬ²ÛÒó•½q›,ã#,XǪÊHè`uÜ!”ºDPH ʶil‰lL”4]5SÀíªnEŠ$dffê—ïvÝ0äÍ–Ù/8QÎIµ¤Öf7¿2šíõQW5{­3 'ÞOÒ?/üØæÌ”ºL̈[çûŠñ†YÿR¶Û˜·Ÿ€‚zÓ¶Óëµ?õQL½¦îÑ@J¢(,y¢Á}hpß v9 2ØXÏþ3‚Œk¦"¿y”¥­×4ò?Æ"Lxlü<ÿQMyt©CÈ—Ôû½~Á‰œ.;xÉ+Àé♉’C]ÌaÃÌ“1÷Þ“ “yR¢G { (<î‰Uº “{x¨”ýÊÂK®Ç˜q@¡ôa „SÕs¢Æ—€Ê¨»×–Ÿh'ËG)9ÑÉdd¿O`‚s8¡ ¬Œ×& È*>Lð8ÔiÀ¦U2cò‚I<=_öp ¢Ýîû“ÿWÂuÐ’µm•8-o‰:'×o¥º™p0=3¾ßÚã h7+œü ´â³¹0þdãÕbG[ÆRÇ[Nµc8[×uv±¦¸¾Á¬@ ‹eÉ *¸/x’3ÈÑM¿7?ý”~ŠV)¹Yä6f[xLaˆ‡óKÀÐ8³îéÑS 'ÓKzã yJHW•™Tîš„$NÙ4kŠ@àÝžiü;'‡’qš“*µ ± œ ÓiðÚẰ€  ØMðÈ+ÈÉ—ÔÛô Ç¿OYaUNí˜Å軂¢ˆvo ‰O•/¦ò==œÏJè{_(ý|”^/c.­•¸SjáDÁ7Jü}i~ÏØÉd?^¬ˆò÷æ& 9ä¿gÌyùRI¼ä»Ò5ÏÑt;²õ…-ý–~aKÿ+ÙÒ» áû©ŒL²xYÀ0`+_HÃß4øMÌWò`Œ¡€@$J哈XÁ…‰B¹-™èñÏxáI•ŸváQ¾\xþZ„B.c©0JÜñ…GÁοðèç Ä” Y¬øÂ•œF1äÚå]xH ’÷OÜ 4®qb&•$I5IÜu.þMûÎiµ† “uü\‚ÔlÉp%ê)òÐQŠ&ž®K„´ó®ß¾$s]ÙÒµE}çùÖÏ»íý§Ûm´O(Ž”sÕof¿a/›ÌÐ7î5ªÊÚÊúLj|c¶Ñ3ŠÉB4­œZ8EßÔ]\]ºdÞá(;Òtªù£D¯€ðÏP;} ¤D†‹Ki»N’v¶uÊs+g°œ’ º¶^_êßš÷7ù·´'!Ò–æšzƒ&„òÝ:WCÝÝ$$ ÐJ¼è‡eÁCgÿ´r×DÈ)U¶+@ŽUÜ+:€ÐHFkâeTî{BhûòEÉOèÅà'uŸîï´Ÿí>ÙÚ/- 4µÁ~@§vöùíÒR¬MÐ2Î5ÖÞÙ7êf׎Qµ³‹Þ§"ÔeÕs8bÁ(ñ7ں¬¸¿õïµÛ‡¿ Ÿ!óÔc AÓ SÄæ”™,`+'«†¢yu~àŠaßcê[ž>/ÙH4pšü’Q^Î*^Ï^¢H¬\$ÖÙ»bHÉ’&,£S1XùÐ’%ãÐòëÝ7ªðb§~èÇ46ட¿÷B¯»z|Ó¼ôz=—ôûh/V3#£aÆ%Æuq]d–`Õ6Iˆg#èßÏJÁ‚n ÊhQš]’ƒéÏôìàåv»‡ÅÊÊŠþÙlŠUz)_½Ø;€ñ¶Åø¡ŠÎ“Qáð²SâÜF(+¸ÎŽOÆn»½²oÅ’æoVµ –šŠXåŠåz¸Nd9Iͧ AÌç*R9 ‹êjw¿fn¾ÉU"f1AƒŠ1’¶)Ïû„ʇï‡(ÓâJ¯óÈkuz¯LÓã5UÝÌÊdø¡´d@\ ±LB‹(òf)BE2ÛN0DT¯O<8Ì qé“,˜Õëwûã!mâÂã—O&{’"âw¹+ÄôJ¢N]ÿÿGg?ŸÃxòÓQܲrãñ'È—µ, cEáy+Ä QŸ0¬½†ßêÌùÑ8(§ø­ò8gº²%¡ó3z-#QE®Ä!ŸBqŽ9–Ô`ôVì†*¼I®Ã›¢Ší˜Å•ÖЃdö®Ëú}äëpÀšj¶vU¹QE"ʵŠDõ1;K¯™HkE8¶QÒ‰,é`Ë# ÙîöŠÔ£F¿è®²Êlöü—‹T#©{Ef 63ÊãÁ¿Íâ1÷ñùÞTi¶xj©<·á[†âã0X½[r²sÀ›·•#ýSX\eWö…ÓýÂé~át¿pº_8Ý/œîN÷ïÌéª}~†·¨f!ß«*Þ ûAûü\°lk:3l$NN¦Z£¿‘p9&kž&›e·‘Î %9O ·©'Œ °Fý šåFQE%Íw:˜©i9 Óz 0@~~F·´ï…ñŸ MÕ,hÒ¥-~W CŠ%­cÚÀÙªlhg¸L¼Dnp'§Ç{G¤pàGQÿ™£d©ˆƒF+&ðVVTVº°lNŒÍŽ¥À×éU½çv&V @¬rnʼnÏl‚5YíE@Ÿä®“¯hf$7EiîE=3ÜјyŲÆ6Ï]z´Pâ ε&.‚ ¨…ų]_b. kO+™þµº’fOëÉÜ7Öç$ÁÌ Þ’ÐùIÐ’ù¡î¾‘ÜgÄ1‡Š¿Â„¯ÊG•Ö¡ÌGÕOh‰;.«»2]`—všf´tB¾‚>KõØ._`ËIÿÔ •U@Ik'èc@癩u“aªƒÓ£‚sàÓÉS}±µ÷ª–‘:ÑïIŒñ'èBƒA)0ÅÐéº5oã”9˜±ˆ“#ímÛÙôÂñ®Èý´Ä= Í®L‚ÂoaôÌ8‰Axø A+füü½%kÏjd¥MGUSÅÊ:0L´›y¯ª¤ŽQ—0Ÿ±të•yŽã=ãɈ³Æ¡q`›£pÔÊø Þ–I¶•c²æZa¾jP¦vƒ 67—–––Õ2¢ÝEwŒýÐo; ‚$/Z£nø~ô°¶:µªœ7!Ã($€Dì†É­¦Ày>s44€åJNÝHÍfÒJùrþ]ž@ ÄO}½ËýØ0síïDÝÄþ^/œw°ó& Уª±‘Ë´¹ÈݰStÑöÂP£±dKÅg=›õO}åYç+ .›]|臰í€ÛÚ,¤BïY€ß¶1Âiy[J¸µñHJ ] ªdµÄõ‚,+¤4(-?OÁ$› YKÕ/üISšºÄß–JÛÛIJó%f» 4"êµýêѹ•xLùš¯½b…¾]Ü»'Œoâ _Ôßœ+q·g¢ª¼¸£z( }=Rs?³ÿêUá¼zÅ+ðêÕÜk€Us! íVËp}_ˆ… W zÛ0…Ñ;è׌¦ÿÈ«™}[ùWF†õ&©qøûb: åð8Á0¿NhU[DÊç°4ƽ±.Å (É”e<‰±¢¾k ‹ã؇|„öT¼Cè²p;xפ¾–F}»rF>a!ÔJiT©ÇaÇÑhÓl7ÆÇ×ø’ I*ÛÌE·KI™•Z'ž2ûQ}¿ãèÓe“„ô!§¯âàhâû¾7ðÆ¡}ùŽþ{'Ä‹þòÐvóät%¬^¨$¶5NSHŒª˜"äL(޹°°'QÒÙmlÅw!f¸¯Nk¢ÛÅ ø”ÙZK˜Ç—#Êá$õT·^g]ã 9¨oø¦4Tea±Nnü±sÍö¯vÎ Òrt¥±+%ÜâT5w`›«-\y–àz©Czf´ŠGÒ3¬„ÏKK„8fçÓ­€:hÓ ãÌ0iB‹<¡ÜB*ƒ·¡‹çâÂíé» ™ß„x›h!=¥ìÛÀañýÖÄv„$ÄÎÀòÎ=¼–(nÛ.íŸ¢Ôøþ©Ãá¿m}ʬ;õ(ÐZHZÊ|Pèeh‡¾ò¤Fþ„”(¯aÒÛ9´5u‡Kè¶T.£`[àM°'ltüŒØH¬\Â# \MÚ`2¦Ìr¾Â¥ÈT(C¬ NšÌØØÙ”‹[läaˆÅe>ï åàÞ·bõ&ãþÁdK„ãê3Óøüøê•ñÕÈ#Ò4“ŠEèØE°l/%–ªé7@òìS" ½²¦3 i¨±z¦U'²þÀ(¸ãte•ë#³#ÜM ¯yÈÖ6ÍN~ãzðÔp¤oø`4…ª@^†F$ëV÷Þ= uzõ$Ê×]“ D?ù„¥Ww«Ûmë,’eU¨d¼m–“åÚ,³Š…¦™RÕã!²qQè†'®¾~—5÷ºëÉ0’Â|k× bpÇ‘ü g‰׳P¦-#>°`Kr‹®Tz§:¼zWí§ümib*Ü?ù¾’4Aš FÌVrj·€ã‚aN†:À?½ñ4'RÛ1H½ŽÛ 3Ô×û=:¯.€ùó#öÈØ€•š8­†K)‹íÕ͊͘,AXhîn#…ùšƒP°T"¸h¦*̵¡F….P\7Áñ_ǪuÂ> wâ^±Þ€ˆ/n ÏíâÈ-ñ …d1Ã&«õÕ:‡V±Kq$}×ánG#w×Ût¡"šÔ`%½î%¬=¬HȤKZESw¶B—ôôŒ°5¸Î­[iÝ_{T9‹Ù±Íã,fÐÁ“U•9 œ1]Ü­BÝî8QGF}Ýj5Þ`´ë7øQe_ñ¥°?nV¯ß6ÞàÿV-»e7*ó·àoѯÌû­—²JX,ÃÉCál©–ê ¥ŽØðëü÷uãë‹Ê™rÇ»D¦6Y!²,-ëþÁºŠ¸†~•¥K‰V Ù¦~€–-Õ°V/˜´|‡,„K0f9ËRhl¤7fARwèPÅåø´pÿ@": •žmoÛ±u–³e¢€‚¬.ôÈÈ{WBå$$Ú æÜAOûIJcò†lîéȳʹJÇ®ÏL"¶ØvE285ÀŠmÏ[xÂëÖL Gcá3\åÙ¾˜M@ÌøHO§â¢¼ó°YÞ{z²)àŸ&%ðlŸìmo—Ø0°ó/úÒ÷Me@5 @¥8¾r5ÂY~lÚqþs]¨al®ù_ ï‘ä¡lrN‰Z¡ #bŒ,¹ù­Œ. ·\ W¥'àÀÄÓïZõºÌùUÓ0Ë\ØyõÕøc¤: Šï•Ó½ú{[W‚òpþêÑæÂc{ƒ9Û"¤`•Úvµ`¶i]xfÅD „èöð½¦Cg‘-á*@D»Z!fþÉÓ ì菱9’¹ípÑX°¤}Zt-0˜V#nö'‰Z kbIô"îï`^æÝpFB%²IQ #R‰È':û¼”Ò7‚siîùµ«8Ï ¿ZˆhÌdü cJI¬ cISq΃‰O„˜SòÆô¥…L¿qÎùŠ)V ÕhÃÛ|ç×Ësñ6.R‹Ñ¼åÜ LªÖZæîå>…©-Ë› ±1geשּׁ+¥N&˜ó=–3ïŽZÌ­D ZØ;}¥ÕÞ&)õÎõ=ƒ¤g’lIb†æQÿ†}z¤Z^ßÆØ¢…ÍR0‰NØh³†Âí‘ëŒ\¿aQdªí„¡å” ¤Iƒq¾§!W[JM…¨KKÛºLys†–òöÜ¡Ôr„d&Ïð ÅöPËšEô­Ž¥wå«~-¾ñ±,ëarnö-©(øóºˆoG¨_ôëR7T'¡<‰ëŒ¢Ñèáël*›rò!´(9¸<6Š´HT·ÎE겈Ñ0±«æB³ÝÆþNì1¶·á¾Ô‡ïFF0w0ß^½z%öPꎩ²¨¬4pÑ`§Äxhï>îž×»××LOöTæ¡§×·±wòR8èØ ã1Ìb~  ×+/^DÉf©=clLŽßõÐFAn„ž×C&^j©ð Š›º²½wǶpúv)òÑg_bë,çw .Ýþ°`è?ÍWœ šðŠyÑIì/¼0å+Ê4¶J¢³€‹0C>ŒCE—I5[Š ˜­E]Lz$*'Ä ñ%0g‹3"z]Ò¼ÀYr£äÞJÚó®¹]àƒHÞÁP!&Ô}i¦º9ÑsEf@Þ˜))%¥Ë–CQQtaq^Äh"Ïz®}%k¬1RÊ FtŒä£0þðÂcTh8½÷Àº¢P!87ÚV'÷9 g§Œˆ ‰Øg©–’7ĈNqÔŒqûmÙV#ÀÜŧMX_©d@Ö˜,°Þn«Ø0=Âû CŠ!Zõ}K’cƒ6 &%õ¥Í,^5µßå4³¨¥Á2Φ`¼L•u^Qä bt+ê«ÏX…nš z¾ia¿4ë«€4–6ܬÿÒ¯ÑbYrÑ=þ» !%#ÃäHiñú]1/3;@¡Í€»pÍíVŒ2žH¤d®Ñ·H¸Õ–‡°P}Ê ›’ +d‰=&ºoD\l,é6ß1FZ²ÎÒ)Ú>‹,O·érÞ®,¸{ÍÀÅÚƒ³°>ºñK´²EhHv7׎{‹n»áëT(¯PĵsŠb 6!¼ð®•äÇZãÐjv¼ n_­·]*¸ÃTÒÒðդƅ®™3mY+Q“™ö£&(¼‰´ñò’œ×" L…æL@FF@‹ Ê–9âË.Âd£À`™™ŽŒ’Ä:Á‚ìñ·§_¬Çù¾ë¡&ÆdQr̉ó $ ‹£’ƦoÙ©†ÇÄýµuuNà£m°×’T‘°™ìY˜ß%ÊPÄñÐ^'V öÞù ËÉÀ„Á¢RÜòÚïÃP׉ÿVö©,‰ˆî!Reˆbg‹„T‘³ÒRB_gV&çõ%îLJûn²€ºdúï ¯Û$]4‚¹„èT‰HøÈž“&Cäø‡øóDù Ÿ,š… ¦m·°'•åL;ö£”ÖQlâDY®­?+$Ê”iÑqϱ„Pž~¤žh C5i®`à=!ê_¡Ì.|u|H¦5»>§¦H]ëûZÔº4Ú`-8‹ióLÆWSü«Rʬ;/aÂ*?*$…~V‘}YÂy:Æ]ŸÌpS|(äͤ§lã‘ÓóPþàôFüêQ²œ¼»bäXt”Q“'’7!†Ó@ÚÙˆQ®:s1,Vní9b8Œá!ÕÏù)¨þª&"ç†ÊÞ†lÕ'£ñeêMžò³Â`·.(–AMü,õeìG4‰HíÓãÞV¯úOܱ#ˆc·ï:¼—> "FÇé3›Èúy€Æ¥R äâúPÕîx#1`ë³J"þfœe£#42áfê¼Ø89Þ­ÄyºÔ’¥J¦×-±^±½d²pÓ•È%"VLÇm!3;ªD¥˜ê¸´÷Âc¯ÄW ØR¬´«$“Q‚Üñ˜ƒ×èyy‡(}K°À§ÁùÏmÂÞ\·"¢Sj-åz‘ëGìeÃtÜv£5ó&ÀíÌNˆÀ!I fWˆw¯ÖbÀ`"áeß ºh(˜Ä·²¢‰ƒ’;êØMÈo#žÆª?³´¯zäŽ í}£&ÓŽß2¼sðº0‚Å ÞUbÍì(W³ÒHÈs‡ctá‡÷N‚²$øt:a µ˜æ‹Ød}‡°3hšÒ6#[f\%ÙNÂ˜Ùø¢”ÉÆ+Ã8)TG»˜æÿ.2ÑÅ3³Í’†Mzèæ$bcU¿9¾Ðí5Õ6̣ㄙ¨F ­ý9Šqãí}ùDT~B/[+¯ßŠ7«­ªX-7Zk õyˆ*8ñ§Š62HNnó¬7 Eýy–·âzÚû ÝeãÄ8È`QY©˜xü°ŽºMŒ¤¡R_I©’éÚIë´ì¾¦ äsGó ¸;=÷ÎàÝÕ “p„±y6ð™Ù•â½GµKæ4“²¾#«oHr£Â§°|m™à MP?'Õ[0wd¦§ì Òʾ«~¥ˆTRú¾³˜uW–³«ÚŠä@ôJ rŠsüåM˜Ó3îƒ)¶Ùh%¬*¢b²¬yÚ,|ØLKq,ÔÄp@2"¹î¾à› ©“«¼e²Zdrb ɪ̵l€“[8«’eu’¹ª~á¤[™|âmCÎÄØ9¸ôåür~9ÿ À¥»:ý–渌ˆôm¤¦Üþ²Tp|›T—ˆâóB—ÖEg°´\J 79 0Ýù{®ál!o®9lZ1SdÝņ€ùÆdô9mG–,‹Ýk)sS[iï7œÈaÔ¦ÐI¢4Y³õÖè[B¼¾C öòY*öçMžÍÒOg»÷{ùÅO;{Ç%*ò¡‘s~N#ÀÁé)¿{ ÐÏâ˰¦T PJrëȬ ½G 6~è·Ï½>|Bê–äÇì¥)•‹~RÔ¹ýšxÓjU¿æN´Zk__Xg•´fÓpPˆ )4=EÔD³ oàõ’w`hOw2CŒœŽ!|CÊ Î˜Áˆ }X4‰*;œHœÒ…êDTҊôKKÅsÔ:ñŪüŽLZŒñÄqf2jÑRóÚZ×(*åœecj¸»‘àÆ2ù¸ßË[€v[Çmñ&Ñ+h»‚aIP‚h;3ô;±o QÒ,Ë}7³ŒÈ5}š¹‚‚Ë¡µ‰ØÁ4ù2­‚»p?_I^™–¿r!V kVaâõ^¼µå…'¿JÎm8)uK}z°ná m“8Þ¤AzUü°è¸½Áp æª=´ðú/ܱÌÓKy×{ýáÈ¥<]$¶›©Énµ^ü,f"*±"9gÜ\ O;ÜòÅë†bW>wÜ D»¼q¡7Od𮕔• é߯hS17l¸$õϳÌÞ— ¸§„šqYü_ºÃKŒŠìZnnâûÿŒ:þÙAÎ6ü"tnB•ª…H"y¢2‡UVšUÒÍÁu°žº#´¨¡Ú‘Ç^P„ F©³ÙVØh}íà ²4Ÿ+Ë’ÂË”ÅébA´°‹G“ÐP‡³ÝŒ!á™R~6‡šÃô5³i-Iº7˜â0‚=ñáaxõ`ÿv]X ì wöÙ«Wµd—jÝ>õ|>`Kú'?oó‹Üû2":UË€ƒ"öÝ0¬I‡*4ú”zG?PÞ×,×¾zgŸ ¡¦ÜgDeÄ¢ÌÉ63ùg…{yêâ5†C,)›{íüÉJžràܧ_Ôuø†a¼ð:— ïL2ûE(•«#ŒÿEÉ=°d q”9ZJn"ä¤â=ÊéÁÌußÙ;eXrǨ­D QX¢Z}ïÅÑþÞ“ «Œ©pÚ1xŠ'ÂŽã¥SBãÆ—r2õºd30Ì‹yºõìç­ã3"ÞÀá²|E» †f‚Õfe<šð%aÆ`…7Êc'à¨pø:¾¤?ØZ2co·îå èsúP`PF%|DzÊUGìåDRÌ0럇/O^žþ39ã¶1ç²èéáá~;»¼Î3Uˆ˜thÂúºWíÝW»Õ¸QªDb÷Ç£Zñ%¦D]76ø"øbë`ïéî Ì¢e"=O‚±pÌžÃ7+“2ʼnº*Í`’#Õ°`ßÒ[´zÕYÅ95ϵ7kÉÕAÆ7¿£ ªQ‘¬Í’â8.îÝKíœ\¦€wN.ëÁ€ þã6¬GÜþlv/_è•rA¾#æ…ùÁ9ˆ„´k˽9 u«³qkÎUá÷‚ÌaUh^iàuÙiç­#+ê¯$Ñ®#þâp°;úm9Ò2’—5^/å ©ÓŽvªŠ¡J|½ôº¦œŽœPÁðÂM‹_y!|ǘب’¼†mÛS„Ÿ{®'É,ä³ùav™\K¥s¡ýõ±=’¶dÝ)Y¾ä—}môÉ&³¥‰]:Ã0èÝ}&åTA°î£öœ@Ôlò?c0ë´‡•c臄æÆmÔJ™'a¡F㌃2ûïÉÉÉPo´¬–µIöìØîÇ–Eß[tÓ•nÂÇÄ+Z·¨G5Yy“¼˜6²ÀtõjÌp™…訨™.¹'ÅL†¥n'J”Š„ m¼úÑw.àaµ* Lë)ÓwšÉijK`üÃXؽäÒ¦ë˜+›çb›ÛRæ±Å"*önšV¶!ìKJ¿ÉÿÒ¦né]ÝJíbÅgÓ\µÊ¤ÑR[¹UÆ >d ôØBâSÚÀó+ `“±×gëd,vî÷´¾Ö;ð¥ïÎÔçŒFsåœ(¥­„ß~lÄ{b+}Ql%ˆXK]»Ôñj3Ðßÿºó¯¢a…ùk’9;xòÞáÝýBO]BIþUDa1º»‹Ño£ËOfkî28žÞ¹pö GÞ{gŒ37vG~hœ­j@p9 á›D#ZSLHw€.™õÇí“ÿšœŠ~lü¢Âé¥Ã>ÉK$ìÂu¼2ÎqiË÷>šíJ––Îf܉8Úªä¸EùOÇ×J5>‰½ƒ½Ó½ƒ“Ó­ƒí]qº{üBý°2x_-¼rϧÈFÜÂÎîÉöñÞÑéÞáò²T˲²Øß<[§[âÅËýÓ½£ý]qpxpò|ëxwgšeŸ^Á\ÃúG ²´hXm¸€·÷|o|êŽV£7SëˆÖÿFYzýßÝјæ1ÍMJ§÷ÝC 5Ö¯DH‘¶vù‚90B¨w­R¡ZX¿›®x ’¾#¯ýš¾¦š²Š8<ãžÒkpvñÝ'£íDÙ–E7i¼1—íÖZãf‘ªe]ÝæŸc:û*: É%“š ù`3†ïôáh“á×0óŽ;£w+ëU.†˜"Ž6åLbÀÓ12<¬êŒDùÃñÖÁÎá‹z¹üI|-Þÿî±hˆuÑZë××>÷ÄÚƒ‡ëkÿøÇú·÷Ï 7»\õ(ò#›NXi›Î|?´•¸Ã¡f$ª6~ç3¤é†îê%ðáñìê.óJsòl)ØL6ÜÈÔ)rÂlí»0mU+ÿžE±®´uU&˜’zèëEQ<¢0K“aÍ`Fîð-°¥Kmu[4{ÉÉØRÁÛ18¬²Ê¶c9ècÇÕ(Š‚`á|9#«&Ãu[˜EÙãëëÞñÞ+™µšgAy¸zšQ÷]¤-x’(fŸ¢ÀÒiä‡Ú#Nž˜4*ÎU[35bªjk ¼yý—ãZ}Â’³¾4hî÷p)ÿ0¶oVâô$†›©¶‰†ÂÄDüžBF(3 >.%Cý—ÎQrÀŠ3RsuŒ…üÓ­²óͪbô|ØßÞ¸M tŸ0„É5Òèw«¨DÆLôø„AXœP½ƒg'á?™4ü§ ²À;l…aÐE*ìÈžßµÅÊO[{Õ¸•®ÈCî‹ÉHf´HÞíUŽSy{¦Àöꂎ" Òg[vXb®ªðÔ·èÒúü¨þò‡Üq÷3®Õã€BÎH>šJ­D‰/ÀÅe&* (–sH!EDÏê3r1Ì¥Œ ;ìõ‚ÕVª÷ëßmÕÿíÔûðéM«ÚÀÄèhºƒEàîÍ7펂†ÉŒÕÓh•e{-Û^mÀØxcçD–·?“G"Y^Ê.mJ¥‚~aîž\¾éevòRzÖ¼bá,~·ýmÅm„c¢¶:¦×éè~Æ>ˆ9;ZÀžÆrpÀì EùÜÌÑþ’7ýESÒÞ-Ëü„mú2ùf8ÃâlóT¦VB+fiÑ€´;ìâÙìÒ_}ž¢,£ÝŠÌìšùXV‡”øÖæ‹»Ó Þ“p¡r¶L #Í݈DHtͰsF½^/E h’$Ö0‚læ‘ø‡½†%ôvF}2r<‚^÷¡„…›4tûïõ†’™¿q¶~¦ pfæé²TŠ„ØÖ z̓~î|ÒKKÅá—?wGɽ´dê (…9˜'ѽRÖŸøßx0l{°Ïš…Rñ%%QŽÊWDÝS{¸‚m.™Í)‹W±Ê F3¾u´¤™ên½Ý¢DsTdúS×¥Ï4v^ÀMA]t‡Ã”íàÆz$ûÕQ0ƨpšŒDd¡¶Äëµú£76eÉ"ðú¦(CNdr«Ã>Ì\óT 9løñ{2ÀžÍ£s8s©lê3õ¦®@« ^¯GRØ|(BWD™Ñ.pF];S-¨ï2íuS‡÷ToÄ…BVðëìò´j0!Æ9nã`ýäèÌÒ—ßìól–ù˜6! Í—ø7wD2’ µYUgŸŒFŽ·ö÷žÄ‚ÑäÜÿ¤¹š~ÚĶfâèÉéBZZ=µ™™'ùöçð”\_Vâ3¯ÄBg^\å¹Z5X‘Ç ‹:º+×y—]sªé󳳤âøãúu‹Á&i³ròË?’Óø|¡1ˆ…‘ÇꤵüÝkà å¡Î¯³ª¾þ ”þs/7‘•ÅÌø¬ä£‰¯¬šû;íã—m´æœ-o£Dæ9’7n”¾Hëþ ¤u£§È%es”¤0L}ÑáõQ"½òÖ^í÷ÐG·µ"ðþ)£d{­ñײµ{UÖ}º½˜¨êšbï.ðCç⺳½'/Ä«}–'øâèh»Æšö:œïòzw§JIýuð.¼Á$Ý”!K-m°Â¶ã{(¥téš¹´–í~ý ãô7ŠüêxšgÌöü–!`û6…Þò™À¹s¨2îoˆÕMñis~w´ øVÎn=ìmgè·Íž$ÖÍ0ƒ[ŠÌ RrI9w~5Ä '¿%¶#1²€7$xd§^楉©ÿ†é *S¸Úg9P.?£Ùhññÿöh.`i&­{ý8NTæg:“Ü#Sìélhý7ƒ ýøñåB—b£‰C9í±ð›ŒÆèC?À[PF%ŒyOÙ´Èf°ä=*|;…Wç*˜À™ØqeZ\·%÷ÍGÅèþm•AZtcB¥¶yžÕ]ØPåZQªœ®Qº)˳#UQY‹Üø×A.0³ÍqÚÚ8<øöÛw‹Íu*4¡¿Ÿ#ßAìvGUKŸ!ÊEjq|wŒ&<1H:ÛíÝý§í6òmˆ »¢®9Võ釬ôiL¼Oh£bÐq+’Α>#æª-6g‰d|œé™p \šæuHy1–Å/Áè3 &˜f3xHËoQ}Í~$0nt÷ˆ@Ì¥8 ÝR_MC•zÿ¢Ûõ>þž66¬Š¹Ø«þ8 Íů¾H&à 9!)¤ãÁmëBfdQѹUJ?L¿Ù€IdøÉÎ=Ë3¸d.ý¡Â;“Í[Hef&P<Ëßa#w¨¾Äã;ý9‚Ál,ðl^Ó˜¥2mìJ‘:°¢Ëd²(ÌŠÏ4uæ<8Axþ·ü}(ÿ>úbàø—3p´dÄ‚¿¶‰ã­ð³ ooËT`®Ùp†6´Gª‹š2Åœ›‹€Õ1¤Ñþ;6÷߱é"i\ëöC{í³yÄÜaÁŒF-Å^Ââ‰8ñ1YEÿ=’ý«~kµ2£ULö•ûŽ%ð·5ª¿½ÿËÒ­LçãN3-Mƺü¥>@w­¿ŠSRj2RÜ žCÞUÏ2dŽg$BÆçÂú:_‡­–o )«…iã‚Âj•="B³”¸‰Äi¹¡’>Ö¥®Ä¨’UøÏ[1DSÏÇó\¢)vQä/¤ iz· ˜9%ðHögö]—R-Í 5þ¢0û¢0c…™þ¥á÷Æ]hÐþ¢ ´d°Š¥LwÅštH¤$—ù^‰·ä,2¹—4ÿ2GÜ„?‚ù‹ùA.Å#4Ì3q™‘Ÿs Ê×ûï0—ÆÉqÕð¬çΜ?z‘C—ÈöÜÝ¿«¿u€Ç)ºó2Ä W®x—cx±[Óá|¯\t 5c>¼ÞïÖˆbÅes®àø7ʵ˜‰(©ÕÐT¨8qúWÎMH ­]Q{®ã‡â?xq:@J1º¤Q#€äPWºÁM"û7pAÜÃH; Ü ‡®š:-›«F‹;‘âí^“‹KÕ(ªѯÙ„ÕÑa|èÚï±r2—®óþ¦~ Ãv©#ðJN!3€üL³²…ú+‰p¾É`%·}\ËÈ‹›)â¯l@‘ü@ÓMåV(Dkif ñg¡YÕ*”8œ&ƒ#¨‹s’‡«Xå,0–ôÞu1Àötà²\N (V–öóQÞ?™öI‹Ò@w0»ÀýÀ´þÉ8Ö_¾Â÷÷ýÿUÄûë«`ôîók›>_ñdBDÙ ÛÒ¨žîFùüEˆÔËû{»‡Ÿ6`¿…Àºnj™°áöÍ£’"õõ1ÜÕ¨%3¬r¢Ô7ß`èývgâÑDzì4U{¶½ÍãÏ^½¢@cé÷þX† ÕÖÏ»[§b÷ÅÑéáñ†zËV8^ˆ'î aœr Ïz)(=ððÂcuàtGÜžd0º.ˆ®‚…EÒ“D˜¥éü?z»]y°1‚n„t™øp÷ ÅM0ïüàJ¸×è ]Ýð£CvBhFmsæ§e±cXÚ¡Pßéº2¯,P´sî#n GÞ{¸¸¥ŽÎféÓfI*•Úý1áØ·ÐRÉ7ͦ¼q–ˆ0Y¦[¡…Bðå•ÒjKÔÏûãþÂNV³ôMõоZ¸'¨(Ü󆣂Âô=*ÌWåµõaráùUSe ïBïfã°N_Ú*¶¬oÅ–•³[ι\¥–eÁ<ÒFb…à_«xÿÆ/ð Ͳ'a³ü#üœqÛ·Ê?ÂB•ueK¶C»9z-SçP\GÎ(d麖nHiâ°¼Ów­ô z:f¤‘MÃ\èô¢Ô²ËℲ[¸}-ÒçºC€ßaHKåŽŠÑ aCcÀÊ‘ÚH%eø®ØšàN„ÍÑÆ÷Êí•ðí·$aB»±!™±Ò„[å ‰E&­¥èE»¿2ÖdêUßÇ+Mý˜þíGTF‡L»š»P’JŒ¡³pXõûµãO–¼²¸÷¨8vaR5Y¯ëûD‡èdlœªòã±ü¨%ÿØùfyO¨!óü‰Nÿˆ’ÝîîõPõnp£fVÇÅñË…G‚EÙñÈù+ e¦$Ô©.¢?MZ*A§œÏ#ÓYe%2„DF¥ÝõÏE¥¾_•Š £¾Ír¢0s1'æq æñ¬0ûy0û)˜ýašK”À1=KÍœ¦›fËÍr™LZ¼©m›-'(ä¢}ÁÚpÀIÜÌØq`Ûúqh:¢hb{(ÂK¾¦ãvQGc ñËÈ,½÷Ь± è+]a§Èóîí#×éÝÄë«ÚX˜«¾ÇbÑÍg#ÆBÙÝÊ ;İÜ4†ÀEj\‹WxôJêAE mCa«ü¡èû'E’øî#Etb%ªUï[¼F,ñIPAÓ%™’$+BU™!_362î»$PÎÐçí†Ï§ËÄ 9°80Øs¾blK4;znbßa&Ìß±‘G&z¢íWJ°æ«60 ‘-ðæ&¢è…ó¬ªØ?=TG˜,®Š–ŒÄÔ˜Â) 'äð¤-¶HžBìØ}ŠÉ0ª PYr¯‰£5E<‰²Ã6LÊäc=çœc+§:?ÿNOÒôK[Ø4›XÙt,˜"¹¼ؕۗ î9Í’½I¿ùئ,ŽTtóÀ¥+• R‹óÊLÐvßu|@\{ŽÿîØ(btl÷Ú-É ÍR{æuÐqÝ<ÜîhŒ6luúpmaD"{è$Í |º9«„KŽÊ,xd QIñâ9Lz©|àáñ)^^€ËxŒí¾ôh¥µŒ‡bIél_Jin™åôá@Ü ™~½)úîØ…íƒ'AOØ}GjÃmƒ‹3»À:D`2Çz‰|#š4Ë;œ7&ÔW¤äv<­‹{÷,$ø;§Ç§’QLݬ²¢” G%]ä5FÄÝdJ«9ü[€òS *ó06K¶©ñíº‹ÍpB”¹b0Óë7ü ù¯ÄWùó­øê«ÊaZñ$Ü·7Ûº½«>-õM+²¿°ƒª¼Îò>ºwO Œ×;÷ºt,1²@*]WýšpÇ]\ö)äóúX©ÿÒ¯U²‹}ªÔù‡Ô|¥v‰½(ÆÃ²Ø¼ÝÚ{%Pæ{èho[ª«zúªb²k·LU ”T¨Hdbo ŠK¶&•–ŠûûDu8AÖrפB™M+ É£3ð.Ø;/ûø0¸rGÃn2ôwèÒ™ˆi¥¦e ž<6ìø¬Ìó3vÐ û.Ù°”Ð)G,T×Ãug,{ý>/ ú¡€+•-²†ê˜<§×SW¤J}@P*t÷E0ÈgH÷±arÎÇt‰""ÕûÞ;ëáýŠ=ëpÛ¢Goü`]Ô¬ëÂwpusëÎÃŒYÊ+w\XY™ùÏH~´;rÒ©Â Ë”•Ó‹åV§ ¿UOÐ=-ÖLˆy…pº7WžÏIc>¼z@»îÙÎÇø3: ¼Ðt—ƒçɘ/âκpêÂÓ×byvå÷d÷ÈN“Œì€usD*®àYÞ^Xª¯õsXývð«ÚÆg ³~4ÌE*<âBÎŒÔ -€ùb‚#A`A¿$å¦ïj`+õzÏ 1bOÝ™Œƒº7ÀT#´œ¾wvö÷Û»¯ð„¯”r¬-”Ù: ê IùI"²”ƒFø§çŒä2Ž.aônŠ‘CÚUicª’i†CÏ9e Aa0û@¾xÞÞù†p'Æajæõ.A¬Äû»ÚûÏ…‘¥`Yìüß³£#VÏú:mÈkŸJ"Ký™Ör¼±KÇ{7™¾Yžc1Û@x¼æÉl6LfÜk47ªIM±dÉì¼Î˜Çi¬?)–-JV#ï×Ïa8 Îu-íÓÅ…ë»#´Ð•±—ˆÚ™{÷ÊÕ)s3§p4ñ)m¼_l9óâH÷IóE=Žxä»]u:æN}ý'䇥ðMòàS ‚Dmêz<~Xïý8Úâ-<íˆøñÁ:~Œ@ÈB¶ ÆxJËJÀ;¦\ÐAZ×RtRŽã%O÷OĦ¸/u ç¤>õü>™ÁÛSÎc#˹޺™;>yºít c…á¬0¬U4‡ÿïà fBeK-gK bØAëN›0`W-Ò×hP0çÒ]ÊNC{6®E§‚Iô·:7Óc \^Õri(ð{¯ÊœÚ9üÞÒtVΑéÌÞ4öT³{Qd¥ÂòÎÑzgoC‰5`÷uñ¦&C ÈLÃ.¸há 3UÎKÝëîåãoYí[솰,P‹tºõìç­ã•œîÕð¾[mZcªç`;–¨AÔ'¢Ý8ž|®Kÿþ¨v}$ÊÛ‡‡ûí½cüïpÔ±Q~ñó‹]ýz{ÿl§Þ“¦Ì»ÆçîµÚŽ¥Ì¾t$?ÉuÎÌÆ,ݳtWÌËÒ¬ D4ÔÞÑÌ@iƽ{Jï_ý'&0‘AÇÅåì,p‡:XtÜN$cÑΡ \¯7r.0‘û ¯ÐSøòäd'FÈŒŠxl|‡Õðaí¾~Z+š—ÈcÊõsiêý™1GšµÆÂÂÆ(ÌW9$¦xïý;3˜²óGt?#)™y|}äôd‘'󽛇d:É£Í §Zˆ@’2v5 Í¿ýNùÁ¯'âg/œÈ@W+~`°A!ŸþMG╃÷E<"ØÄ¸eÌÏË»”ý18WÇÐçê`U‘_¶5ë"hC'{Æyœ7£qîxã!þdÔ´)¤COD½$ÙÂY4%))`"å#\ꢴDv¯¿}Ü~üP!_CíµIhßbµ2iëlr¬TËtâÊšÖãwȯ“Œ= )Ëy¶Uß¡àÅÚý(ÂN·ëÇAÐRwüÜÝ ôüM¦©[š1?Ým»P³2q3æ›Y/´O*nBœnÚš°)ÝÁpLËãÈßé’¯°À¬/š·"ûÞ3øÓÑÎtTЙ?ÑP£WõÝw¢¢RSPÕëþ¶ÊLñº»ýF§« ©*jâ;¯‚Æð¤?qŸÁMõNVî×YWîWþ…:ÖÊçMH0 ˜ÓŠæéÿÉ ¶YÃ'¢,3Ç7^¼‹h»ûÃþEtkÌñ’ïølç ç*=¹ýs:pb÷å¬ëî^x‹®¼s_z YoŽÄv–Ct¾Ã’çy¦0Ÿs0ð1š·ã]x°²$í›ekÿÑÇ\–Ñv¢Qx–"6q±€,wƈÄIÐ<H^ïäî˜äè ¦YÇš÷Έ04þÏÏäEº›û²ö÷Rþ‰9¾_ð¤=?ßåäÖX–1BíX‘ÛéÙ\)æ‘{LxäÎ0En›´Ï7jBLÔàgÈ/—ÅSÔ¥K Œ¤|ÒÐ^é?HwUß‘w{P÷6>‰s§º,£†86¼Òu í^•!*«¡€ÍÜùC#ŽœJò›J»˜—¥ É]ø¢Ú¥Òr .=¸ñø;±³ÜéŽ'ph£ç&ìêÄljòZެCæG&\^ º#ù(L=+@¯…àÍŽpTüîÑNƒ•MN·LÆ(ÊnÆ\Q¤mšýL–ÌŠ£<¶SDÕ‰•áÇRbÂs˜›N0ȯǽ¦hLìvÛÀµ#kÿ:  …¶ç·QÚá£JIé1ѧ‹Lhy›» ãWÖª†§OIVÙ£ä=0[¨·þ~Ä@VÖ«ÚA«g°ŠŒ?-¬!VT…Ôwm—T/—©²á:‚y ࢩª%Tœy]º”Î÷SápT ”Õ8P§L¡ÀÁ¢Lø\qy3$àôÔ:®ŽT!àÚ~Ï%­––“'ÂÈ=wGQ¡'Þ{ÀSó€{ÕA·"ZIö‘†Ë®_G9"Ÿ¶IkaQ²DÛ°y’?µ>ܯ­µ>‰oÊI\€Î³’xýV¼YUóܲ%A3+}“ªTÎ(µQ9Ã+YÎ@’0ε,ÚæÕ¨–e|µàî¯WߪrÛ˜~@”úÑ,$|Dœ@©¶óü¦¬¸×žéTEÇ>¦Œ!O¼Ü¯1WŽD;ÔJ‘å3°>a—Â*l8'td .|ï7·WÒ>3"tnÐ"™S¤ŒØçAV„|!&‹Oé€bó˜í´ «N­zi:þ¡¨kg*·åF¯"Œ ¾–VÚÆ÷MÑx+VïaÁø¿ÖK1 „¯p¶ÌϘÿ¯çŸ ³¥x‰T¦®èJ?…”Þ(Û6\àÑÚWÁ_-Ý퉮›žù\Õ Ó§”´¾œ^Õ˜æOsɹR¸[¸ÔÙÝ*Ö#{çr”ù - €¸I­èŸbÓ33ŽL·2-à`dR–&檟ÁÓñ-‰}áãx0T×:[§btjY¥[²:fËéöçãsf6“#«}>' Y²:dS/ƒ6UÂ9C+wSš0chV&/DŠS!"ëÊ¥”¢“$Ž“Æë´TßiB/£~N2§§qj:ŠÈe±5DwkÒ‘OiH•g¨wa÷mü”>*×äá—<9dÕÂsC¤ŽEì‚GÄŒx¨Ï‰ÈÄMÓ±¹a$ÏšúÈ8n ¬.›x‡çP²g3EY•f?RµUØ(8LËJIãç ÛC •ÝW’t‘Óstuš™¢B™”B黥  $œ ì⥷~¼ëyÑWâ†{±Ÿ\ ˜Üæ:™}Ÿ„ ° UzÝœÿ/WÃâ«á—[‰:…7»dÁÏt»ËCe¬û§\õ½Í%&¬øJ—žÜÄ›¬«]²ˆ¾Þ%[N—œçš§è`æ¡Û½=1¹w%l$qéã9~¶— Všcœ­B7ÜP?=¯MŽ ”]sm¨\ÄLjK*¼D½«H9Í  1`«øv44X¿WÝÅwñ"’„s0ñÿœ7[9Û31FYæ¾é_Žô/Gú—#ýË‘þåHÿr¤ÿ—é%Œ@K‚ ®1ö0=3¥–Ú‹P–-8àCÄØ2â¬I+ ¯q5òdB /c Eu¢HH iQmô{!`>p°$Ú›"Ž-¨c.8`¸œ>Æ÷$2÷ÔœNôØ1œÃØ:`äº`Ò½4ªƒúænæ$ŒEÛž3#)DŒ’Ó–@0£ŒA_fîÆ/[Ç{Ï6Æ£­¤}–+Ä&V诶¡þŸŠ§8Ø¡sÍíÝèõMŽ.!zÏ 6E’<¥ñMjK帕§ŒDÚ+åýjÄA'‘ 6ÆmÀƶ º‘Æâ›…^qÍ p`r²Y«=ô†®>F[•JذWE£”-–‡Lô~ÅÜñ+Ô²‚Aeóígû‡O¶öÛ‡OŸžì¢[æ“ýÝöGõ¶ýôõÞΛ¶½Šõ3 È çWi’¯â¢G1ÑýAoÜýBÐã‰&Õªo[’ýPaVëÛ2,{Ï8hhF‘5$´¯–_ Y½gýó‹‡1T+}Õ ñÞDàøÃ“è×c稾tÞË€ºœ ‡CZ&&ˆgͪYÓœm¼qG. œ3¤ãÎJT%ÝÊ‹öCýÉð"wS8Wïû?«¼²Ò*‹uѪzjUñPˆ^ì$_º˜ +TX2[Ð+eø’:ÞõbøbÓE7`¶¤NÛ.»Á¯{“‘Š¥ëcš¢ŽwÎDjºèV”™JY" æ‡Ã´%eipÕËØðä&Q¨R¶ƒW’ø’ïï=Á,€[…Xˆ‡„ûƒì8y)±PWÉÇiŠ sûŸ`$Œ §¾;ÅÒÄÛÂŽ” oûRL€zgs—D+º,ÆÖ’Þd`ët¦Æ+”6Ú°0¬P^Xç[:ž×ù×øÊÏÄ:ï´a©·ŽÿEYÍ8Ž,¦hÍ“!NëºýÝ#ûº3ÝïÃL¯«£¬|u|Á1xÉêFB@hO%s ©?g11*H`@žF¼Á”¤•mî]QYþJت腱ܦXDE[2- ÛÇRÅ®ÔT¢S쮴΋ÒE+Ѐç0ƒtgÐ Þ»ý`Hq¹CßÂEÖ18—¡¬=â}ßžó!Jáe36Ÿm3’ëæâ*ËðÜn?;x¹ÝnÃ-ôò+úE³ oàê._¼Ø;8<ÆrMñÝ?ªì@Ï`ȰÛ|± óáWûÈiÆwE]Ë£±tZ½´Q2PdÉ ²#ÈjβxIºCìNIn% î è[“qáÀ =éi>_&tAÔ®£°g$X‘x p<Äå‡mh³Aã–Æ$2éAlÅ4/Ò,ÈïiJ/£ðªTã5†F’ÑÌ•ŽJHŽÝAe­ê„&"œº7> &Ñwc`Ô! ÛØõ‰¬¢™ŠFo¡³Æ‘è¶à —²~…¡]H$ÒSj–—x3PÔR0Pàû³Ÿ ÝÆCp`k«3 §v¥,cý•§O3^/MùpÙb«5•³19~L€œ½ˆcsºÝÉ»²­Ž¶¶‘±õêÑX­Œäº8Н<38·r¿Oj®zg·)~šáûÑC­¦ä4`FžÚÏG?}â0¦Žº7ƒ­»0ûgB}_cÿ9©ª"K8™}ö ”±gjìIÌç­ÑD©¾!êE1ãjàø—|êâ[°FaUå¹èxã+¯Xµò`]PÐç*7ãèàß߇SP³½F JßÃÄ)çRk¨ s@ExÁè¹pر×*ʸF0š;c27‘®ò´½¸µsx°ÿ/F`új¬Ø#ÏBrÉŽÚôTžÊCçHÆ.…%[D'í–+Wæ1P8M`ù¤3·ÀL±†fÕJ*ð>G®% ª(ZNK7PÂU‰P¢þC ½ÌÌ$¶ün3~×Êø ýj˽­iɰ¬`”8LS³XÌúu'Àyù(kcóÜúŠeRl™¢pÔÛ Xíc[‚<)$hL·éŠ¡ö1Ù„ ¢Å²Q„Ð!jr>éã¶?Ÿ ×VyGP"\Eú?rŒš”\H…ð_]*8!_öˆœö¡<Ìs% è~.UùÔ¬®ðуa¢pÛPšÀ*¡Àøçã¼²ég÷CôÝ!9¬‹$7Bë””UEEÙγÁk©íÍÐë:b;eq¡cŠÞöâ0šä>5[€ËàÉUÀþ"á-Xœxg…§ßþ¹­À/.žÃ¡;B(–¸—RÑõÇ—#JGPam4J׉‹Ä镞]Ît›ZàyæãgÇn]lÞ‘™ ΪÚ*Îã9ÊÒôÑ•=ƒ–šAœ»[Ib˜üSGì j-ˆ'S1€–JEO¢”E7Ш"îU“=¤í-¯¢@;GòI$"_O¥ÃU™¢bÉ9’\˜ªÛÏR-‰ŸqÚ`||ö»ŠC)‰¢úñ!§(Õy u¡„@¨b„üQc›˜DU¨ML.ïôéýïñšZÀB ŽY÷÷²/{Žv(ÐóFìœ6Ž•|; tf†’¿G9ïÆTHv:zMoQd„¯õ¯Ù[¨ó•—UˆPùrlmE9è“_a¶\´ÛÇwÓæË¡XÙÝ¡¤‡PA¤he4`Ãd Úœc0†cÒÛo@ñ§l7cÕ>•ºCê;m32‡ï÷²85º̵K³{}½G3·ï4.%"tç oœ@ùdCSLìwâ4c¥Û‹¶&Ù!”÷Ú˜t\è‘d£xT‹¶jæ´"uz“»:±ã§nrGîñö.Ї<#˜l m¤)™Ùç²2ÝIJÎ-‹²ø¿ °Ýë÷ïÿ#Ê5—×õ褅–ò n²h‘I‰TîMò“Ò\}Í0w<Ê݈"Tª¥{véOãHi–£œxE}°½k!L:²,¶ùvVþ ¿|jëÒ@wà~D<' ¦A­†œESïRá;_‡³Ã[A\Y5Z6Lô)7»V4'¬qŸu¬˜Ò×oíÕšŽ5Ðt¬-ÝZûšL 7É€Aw±‘=(…‰}…ûW—¶o™(GfMkSÌ]÷.yz­ñ–KP1òSv¾ê4…H|õ§i¨2öœ)*§fÞ÷úá£Ï¡˜ˆé þ„½1ÿÉh*+8IM«UÆ¿°ƒf<ý‡¥Q˜¡xJ)$”š0CIHUµš^­­E?Pž6â¬FÂP)p7fÅb>S ™Õ@¬örL¨Ihcã…ÓGÉ‹óÂtgàܧڪËÇéõŠú²LGŠ£T•ûQ0 Y(Y’’E_`a½Ô9e'ÉHØ"³!‡k3,mÓÙ$cØ Å{ÁUHëeèš{$O£k†fMJd‡—2ãEK=í]˜N¡íˆüîì,{-¯0–U¶Ýèx$¶K²X¥l¾ ûFž}Í3ÝÍV_œý®¸Ø>1¿gå“ç»Ð8Ùô×»DimæÆð±UÖ ð§·É:˜–d8ˆèFÑzH³\gðl˜ÛÒ•·"~@7C ì^ªwª¨æÓL¢,©Y;Á =1{×yŒx±Øý²d(ÉöU;àšß`ðG"pÙ Å %dkZIü[åuZ*¯RÊãü@¿Ÿ·(¸ Å @KJ³D}é÷ס­à\T ‘Ô¤f_‰òurûE†ŸÛœ ˜49¢%*‚÷NL^Œ ™7ö:W{CæË ðÆ[JÔvsѨœÉR’†ÇrZ7^ÛoõÆEå,:;bB^ZÚDöÙžÿì—h$¦t:/GUtûºM/c4HM?9^Mâ,ú3m¦‡W·œèlî?) ýÅóa4pâÇ­9"4r¯iwˆeqàŒQ¯óâäçmEOÍùŽLî?Ë:L¥Þ4ÓÆ6ar´OɪQtýlF J[IuÞyØ,ï==‘¯á©YÙÔ™½‘÷•ð£ ̆Úü&MX¥l€3òìÃÉ»sŵ@E–ÃBfvœaJT¾µJZÌjee+¡ãƒ®Àò—•tÀš&maa·¿ö°Ç+èúƒ|ÿ?iu¾þ=ô¬3 6ŸY*ç}ºu=¾[*œL­„Úbj_œüë„ÇiO[¨3ý ¯„en§-øïcã#PBþ-Zpyqê¿mÕÿý¦Õªn|Vk-úþ‹ÊY|ÿ¤ImÔsÌÒ€¡/)·\h¾ÁØ!±’Fjl¥ÚFUV㥦vC§ë†_Uc©+5Ñ‚wÑL’›$’çÞ¶j£Û8:>|v¼õûÚ¿´íéÓ  ¡ëuù‡³¹5nÌQGS´Fætᾡ€¢3\@ñÐ>Ù=Ú:Þ:=ˆ¢ø$¶ŒÁœ¨aß嘳¾fö2¡¥—K9mgdàź²YŸå|¦&eÅdñŽûL¾,ïf˜ë“‘jkÝF’©—­¨(â×½‰•L½{h¯Ùk‰"ðfz¿%*Lë6[raú¥‡öcñvðT×ôçΦÇPœ]:޻ɟrtäòÒ.µÝœž;²þ¦§L’G˜‚…@'ÆË`à6XÆ<½å»’ñ‚}ÿs‹ ´öÃÉõw¸ðaí¾~Z“ß3²Wf»„ !\Ýz†ñyÜÙKIÊɸȹ¨X¸Æ Ûó£—¯ÚèíÖ~q¸³ËšU¤Õ•œm1 Źßì·VjÆJ€M“š±?fõçñÃy; =ͨI—᳚‡°ý["l„d|\é Ç.[§¹âä9”ú_Eéðbè¬ßo+ÄèvCó¥Uš‚¹¸TØ¢lŒX`ÙçXO?€å¼rþÂ_'ÞHÆøaˆ ¿ÍšÆÅ*Ï0=1Œ8«ìû³*Â~p·½ #rÊshañèÑ£š` }Z^ÈŠt(B½¯Pcè?æx}й<ò..ÙƒFM¼pÆÁ7ú7èÿ¥À©Ïml³ åéíaªqïúõƒ?Ë1úoÁ•%Ål{¾àÔuìJ“1‹SGÃÛßA=°¶ù²9 :šÛ¾òý„’á•7î^û-öw3êÖ?®Zð¯°>®Öx^ï„oˆoŸÂ2dÉŽá»sáu›Öëo¬Ð®î3t?Àɱé&à]ÔÈ ðe;ðC7òø!‚‚W5ñøaÇÿJ‡ pø¡a?~hŽ¡Z<`ßœ©˜ØÌ …SÄ*åè§¹o†ù X˜Œaú…»•QyÝŸË®¼˜ìF˜LÆÈ³÷{Äù‘ø3®ct©ÓöñË Ôˆ+Yÿ6¹¥f2ç¦Ûå/ÉPü_᫪¡_—Á £ñ}²‡q ¢e{µÜ_/‰7«—W]gˆOÞfØx½Q[zƒfwðÜ|ý¶ùfµÜhÈg(,ä'«dâ°b<•–_ðgÓäñˆ‹d¬&ÌbI:’c¤)Z œtDj’w*I ®XÏ I>˜’›œóIú¡Ö8‚Û‹wòjàG.§n/]_Åî)©t!ñàš€o'’Í“qÜ:£à+srtG°¯t|ß™M6¹?uf­:Á5ò‹’-4[t¸Ç!äxkɘ,·†ƒËÕër ê<²&æ Ã^ÜÈëv¯x4[£a9Xƒç#;”ì·pþí ž8ªEK¡ØSß³žšxÍl&ó– £vÚ,|Ü'¼æ*Nî“É6N-+™G£œñ5Í@Îïó ô’+qàŽŸœì!_ÿ¼\Š4£?§¦è YµÛpËh·³Bø©O™ËŸÕædf}`2ë¹³¸âØÁ˜.ÔQ®ù¿‹ºaü EàmoõSD3¾{áã¿XôÙùo·ž%œŒU˜ ¼›¯þêgØMÂËÿ1 È»#ýÌžq¡¼CÚU‡9ò.ò)à Úó¼eÑ\àoÂ:›‘>ž™& éuÕ”&ÃŒŽöëg¤¤‹ÒÑ»ÙA¸®B)d¹ Þ±c8²?‡'õ(û.Ú} ‡ü7d†ft˜*²å·QõBêÁ…"Zú,ŠTÃîp˜o¾Ñ3bX–ÿ¾Y^a×½~Ñ¢C]ï »^åÒ~T:òíN Õލ—WV¾”+X~ÿ©Zåʶh˪²š_~–ØÚÅ,¦JRñ²”›4‘ Ažì>Û;ˆâƨ¦D=XОa—šEjx~3œOfô§™Ù›f^ÿú)Þõwâ[¿¨g=ûÕ/èíS0ã9Î>IO¦<ç𤀿åßGéóÞþíµÈs25Å*@#N‰4@ÒÛ·Ñ û£ÞçíhÑ€6Ä-67®Þ¨'cðäiè”Þ㋲ã3°iS®Ëp.ôHþѧ˜4Ò¸)nÕy‹˜4Ý»ÖM´¨È½=Ìçêþ6 QÜwŒ94uš“æ5Fj¼W™ÄMb3˜JšÌ›ð=f  ¿ö_.WÈ_` F5ï]à=GÊ>*ô½ê Ñ*§{ëÈ’ªýã—‘‘cx×C/¯°:£ëÏ €%ê7µ|¶gÑLÊ=$* <'*>AW_j®¤Çu}·kàø¡ç̱Ûìba/&ÅI˜-aŠ¿ˆSF¦]a7x`¯ëçGïÉÂã\A ø|wâ—{¯VÕN_\­gPÐnð'Ÿo‹“mFZ\°=üþd¬Íaª„Ú:ZF0x@¥(QŒÆŸê­âºðmm)Ãusº³qtº‡çÒèôè)‡¥#MJ}ìŒ.Ü1çÉâHÃå¯8(X ­•°ÿG8¾Ïj6<gñYÿóÉs ®„úó'GŒCK%CLNåYNÉK´¬‚I…h©×>Fí¥åhZä™SŽM(ŠUJ’¿gÛÛÙ+]Îÿˆ™­Ú»¯v·ÛGÇ»O÷^‰íÃG{û»Çì)d.€E"ªh…PFP9Äé”ûõ2?rO1˜YšN¹œÆ³.¼Ó@Q–Q£KQÉÑterÞÿ”Ù&£–2nPæ µ3쎼áóÚô1#d‰/,“‘Û&7Ø€èžÑè f”ÄàTÞXæØ?mŸüë$îé5˜øH°쇩›$Ë $¨D…±¨ËMPîžüÖÑ¢*Ý–…âüOd9à„:\jVÏÞ;ý † ˆgt£Ô,‰YÁ°dÜ¢`<7 ?sbPŒƒ,£®RÐU§ûƃ¯d J,e¨>.€ ã@) !¢Ul‡qÑKZ܉Šʒ* LÔèd 0å•JÙ‰ 4_Çüº{ øƒ¨oØåš<@4¿Šçr*G})Ê´ƒ§) t4 2ÃŒMªI™Û,F7kllAPTÎv&w5ÞW^H™–è™ÅÞÊ2œDJ.¤’ÄDÉÇ•©ˆT]ܸãú8¨wÜzCGØ[^޽ |ºõìç­ã= ‰1ÀtT£ùÈž¹œýa{ß\¾Pe‚cCU!”*˜ ÑN¡Ÿ%dÇÝO lã L$ŽäÕ׈‘E¢uQv/) !¡œ¹Þ(ÌoÑ ÜžÇYÕ€üÊvU«±ìSŽ3¾¤&1q\ŸWW«™t1Õ0I`gV&¾6RZ,ïrБS†3«=#Oëf^ùŒÝëù€éÞ¸M6òq YOLgÊxê ÜD”7DXH ʶil‰l t%Á‰p»ªkc ™Y£™úå»]7 y?fö Î@”sÒA­èü¹'– š§lÂ,ü¶½E¼Üƨ©ÛÒXV¿Tæ²û;”Íš<«öw¢ôâ™ ç2®¥Ñ'㥶¦“Ðco’%"0©‘Ÿ_÷úº™öþË*™Ý«h²pY™JaU`t.‰8·aiœ<61nvñ¡;w¿}t$ðš² ½ç¹ÆoÛ¨C*oK«qU*e²Œû‚ªÓÊõ‚,[ç4(m“ž‚‰!O4dmÝCnb˜—øÛ,^Ò˜a1dKÚÒØ6¶:ýRñ0U^‡H~(r,ž]wƒ¡þWO sÝŽ/G®ÓkïdšnÜ”X!bHe)û’CÝÕ¢X«ì: TF!Þ›Óeˆ§¯MŸ÷Í\x¯9ÆX'S¼bêk ÿ "‘(TÁtAýg¢|Ó²r¿+J•Ð5 ÐD"ƒÀtÈ’â8ÈŸ2:èz¢é!_N&~ÓÊ B¢ÀY@¥ssÑ ™©‹®Š#((/„°‡ndÞyÌN­6DˆFìBe>3vv·«|Q¤lÚõ¾œ:Ú úWˆžK˜~:ò½/-juO»!¬à-øèðdïU•Ž™2ÊÑI‘%x>·ÐÅ‚²Òïa§0·øhl\+­ºE>F&qâñÂbê¢f_ÍÍK ˜ô°¢¹µðê[Q9`ÁŽŠEwB‡ÍB7ô5i÷¾ÑˆYr.êÌ÷ÀP_ %r*q4CQ‹{ƒrÉÜ«ÜO1®*4US!ÝEý'9iõwò¡¯^ ¡¨Ô“þV—s¿‹äHÈÁ×À¡U/\+ˆ/(… «2¡û ¢\K8áŸs7Á¹aÅ.~ÙWkciõÿ"h©;wv èŠlº.â:Ï?|a‰ƒóº397uuI³JwpõHg¬àí2u7ÃÕ™obrf3/csߌnÜ0y’¯h)¤v gîS—šEîf~ì¿¡öç¼J¦V#ûšTšíJG!ðäÅLWI‚ÉTK†ŒFY85-ÈtVK Ï”ÞVŠŠkò)#:$îsF™r˜,¬þ«¯~ÞññÜ.40®Z8¢ä]œ›iàqþ)= Ëb7L—³XÉä#pB¶%yí££Ý«HÑÍüaøâ:‚Å)¡€´7 nÍo"@èÍòzi1á`YB˜"æSÅbÓJÑ{XzMjcËpÿ ÜÓǧ`Fj®¢–›Y5e>:-{ÖqDU¸›»à°O›Ò¹Á?›œØ-žÔ‰¨”D/'¤d;AIñ¨°£$ŒÄñ\ƒl›ø±)óZ#4’„±Â@V*B Ǥ~p)yS#š*€'…Qh¨[i¨U+Mwñ â¹ÀžG³áÕy0ñ{¢°mB2Ù–Þ‰uVIË zô'5yñÙ+è0Ïiáˆà ‘Ñ‚Ò a—fÅÉ[I*Õ8ò¥•Q ó´¾ó#8Mö²PÕãUØò†\3ðž%®£õz—Σ3kŠ|5]±ßãš"ã“×É‚˜EÞïäXSBºaR[ïO;Ö¦UéXã)Re['ÖéߊuSÅʯ4WSôcy¼»e ¶õÝ•p‡×ç³ I!¸ S¤åeæµ–9t1ÓuJŠ:.ß¶ÒÊ!ë3¥Œ.2ƒ"$'p´ö”X@-¯ƒÛÎÀy'EE—.¦ãP#»jAÛ›¤—U4Zå4–ñk¢{6ÜXöŽ÷^Åîûx/л‘åãž&ò¬¤rÆãQÛó=StЛ6lgw[tGÎo(P‘„"É}žQ;KÚ‘J$îçaÀˆ$ˆ¤HœC_ˆ)½F\2Ä’$”oØñ F1|bje'Ù§˜S]oØwCû.Ë ý¾×ø÷CÖ­‰wÕ) ¥‹î‹bÕ©Ùqd ¬™ê¯’£F^0âØb×P5;ÈmƱîðg3·éøÄ®|3¾¬‰û5뼩N‡€X¿BÕg(¬1wå|œ¡†‰‘+suL× †+÷«|Wøï¤?]X¯ø'k^­ëŒkúÔO¦¯ÛÄLnšúÔÒ4­lZKÜ'ëS–Ç‹Tö ½ #Û‘;w+C[›„pÇ£ð õeý wCüßáÞÁÖ“ý]Úã^g‡†>¿<ØÙ=ÝÚ~¾»cßÒîw6¶Óz`ÕÜ(¿b&ûCDB”H9_„ x©‚¯x ê9‚OwÛzï£áoš)Î?çñ'Ê(8¤>7aÒ‘kŽ/ïŽ éI“­Ð&úü¦F¶ô…¨‹êvš²˜_²©ŠYæ«fF(»|\î~0\-wi™{¹(µ£V%“6-$²ຘÌ'«tºƒÏ›"°ŸRæ¾Ã:‘7µ’‰f* i›z×F^AÊ*: ɪï´å„žl=ݵ6ãGtž«|kf ­XM–7cg¤ï±ìö…FÔ(åÈ9W2‰•‰%HîéáÎá†ø9W§ƒbVV3E\íy-¡R,·µÄu:y‹[|O¥¯¤ÂÒ/óÎgþþUžET¦„5ß*òvÛ1UA>:Þ;lï<ß=Þ;rÌdUÉo^£X(«ì"ÒÍÔÊÿq‡Š'š™C¾“Àœ9"þ6R*å•*òù˜à…\Nò;›ÅÓ-`pskYºŽèL±Ñœ:|žoý¼›Y]¬Y±sKE$¿åM`Y¼À…‰1’J3Ir‚Õ6 fœ5^¢·_åòñ9¾ýñ㣚±} šuÝ(#tLó³E®WÝo¿ûÈÚkëßÒãwßÉ?úM—ÿ•?¯û]ù§ýþ±|Š>Á¼®ºÃdÈ\NŽäŸe iOÙ¿á ää¢IÖ(ZµƒÖ“aÖåS%>’ƪj2[Ô_þ°½ý©=2ö¢&±Û°”ü…Þp^0H Pj(*0¸,«0 µXeYký•ªûÓ\E“v*«X¦®*¶@FÙ/Ú©|íTlÎúýtS¬L2zWÎìti*~Ì@™˜“8âŸ>»¦(sdˆB|¥¤©Ë.óñcœ\Á»’²ÏJ,m¹U ÐH±Ã¼Bs´/]Ξz>ç³`Ü…ƒoûtïð ¾÷´þôðåÁN#ú}pxÊï6ŠíL¢ƒoÊqž>ÁÕh6J±;GÚG U›ÿín…KË2…ÉØHzÑ Þ ŒI„Z²í#5…2©×ñ8ªS)Ì)pá½w};’é•?°'|çp°`ð×8ðû{§ß,ë‚›¢½õª½}¸³ ÿü¼{¼õl·ý ž€;|Öþeïô¹QX-ÜÔ*T˜vÖÒâ5@£¦ÈTè´ÝÅ©®M¹&Ï`[3”Ø©º”žuö1®cݺ®›½Ò™|²UÑœµà¢´Yµ6Õdg}”w ˜ÞH© %)Ö¯Ú.‰zvÚ§Ç/w›¹_ŸníŸì6+ËÕ£ Xªõ{)³DöD̃Cú`É”:bò ±»=fSUëš]R ^DtÃYì‰T•´ ––âfp ‚¾Œbeº»1«âÕ>•§íÀ…ØÚ¹[ù‹1Àع;`}L&Ó‹šòûF7ŸÑ•ó4?Òþe˜aA91¤R–ÌO¡‹I½üÌì.ücæNH4Žüc^OêÛTBõYèÒߌ E“v¦£X¶Íh´@±²_ÈS•¨9gšdîÅÌÑ”¦"Îd¥’ãØ§ÏK±âBg£áxˆ ^Ó ËŒLÅ2Y P*¯a°™74†Þ4.&,+·Q|ü²u|°wðlƒƒsÈLs’cñ™çÊkEF¥¼ î8=‘ÔÊí®o~*Ň„J‹˜°!‰.f$-ƒ‚˜3뚃µ^•Õ´[¯6bÊÞšä-UþQXtGÅpM:ag/ç¬õ/⑼Ç,-™ü¶Òk"˜ÜõR²œ½ª<5äX«=Ñcš`êUì ïŠ.†Lcçü(/a«*÷M á z–¢$6­5û±X³ÿÿûþ÷üoí>þ³f1Ô‚ƒ¡-r6öé ÿ—:þöïæàÛÏ;òöU÷¿sÅÇÏ!Ö_æ ÛOž^û©skÿ–'Ö~ÖYµÿÇðÕS6ù…ë_ŽýEö¹¬úW»pïdÊ6‹æ™™\ÌB¦@ȸ¥A5=ÿ½Ó÷zô9öጦS‘éµã)±ßÚ«¢Ñ¨œQe56 M¡šâÀh/-IVRN¼YˆXÊršB4ªš5š¬Jb%xWµ¸,8þ!ì¿¥N¼³™:É",«ÖkAŸáEÓ: ¤æ ¡óàìîˆ#7Á„½È%Åtm¡`E” Ýäz£xÈ“oe±çeÕŸL>›¯féqám €YÖG‰FÕhlÿšÞs3Ò VÌê2Œz—øTµyUg eV‹ëÝߤÚpñZZbÇ4ƒÐÁ¡IPáÅf›"¥àõæÜ’,‰9[äPœJ\™¡Ó}—w‰YJèX”eTýð¾¨_ˆú9Ð_ÌâWwFÝ~bµv ǯ.ÕŸè‘wA,%þ/rür÷¤YAµ¥‰q¥e ~:dG§ ŒTO(ˆvöŽw·á$þ׆8 †õ¾ûÞíGa¨‰–åà°ÍˆVv8º<¬äÊ8r²P­f5wøòôèåiûéÞþî†x S@l†ƒ!(å½h{þy pŠ¢¸ôÜ\‡ï]éŽÙQO¸dyåhkû'lô`ëÅnµý†¾œìTõ”SsEý5fi'67QÔün|Þ)¯MU(£ñ³§Sï6ýÌì"n€öáœä€ò±‰:éªë”ïçvJl€Ý§[/÷O7˜—6Í ƒä©@$ÉïºiD˜¡ƒS‡òÙz G˜ÙIfìƒ$ ܸî‹Ñ w0ßd6´÷ìàðxó%œî¨v.úA‹ÂuñÄ @­y~0âÝ|ziì ‰bš ãÏyctÁa)v1\2]Ål±çsÌ= iڣУ¢;¡5¢¸ð܇—jàÔ FÖ„Ì÷Cº$áuèœL°QÎ{ÇëÓAøxSFE¢¼¥š$~l&©J)—žpáùö|©x·Ï ²4Þ#HskZåüÜÌt”åîÌ´¹ò M¢÷GáÖ0¥"”Æï¥˜Î¾ýëÄ£Œ1啌÷íòÊÏpdd}ÍÌ×÷Î$=#VaÌ] Ì@Â÷.9Q“³ÆiÞB‚+Tišˆ«,Ñ¿q“Ò¬ô‹­Ÿ`Ï”W¶^´ñ‘N᪨¿“õ–òJÄ@ջΥ‘M?&ŽÔž3vJ™u6²AÕ/ƒ€šÇ…«fO(ô³ãÉ×(ŽÅ$Tx &ãád\?çhQ+¹{­jC "çBg¸5}£``ÁÙr2À–ƒ»ºÊËS„—Õ»ïÈ@ÕYh5àOcÕJÁ‹#{už©þ®þOöT˜ÖÒÒþÖÁ³æ6”Û¯`ð¬¤(¹ìd4Oy=jÑ*#½Ÿe…™ûÜÖþ:0”èrR¯‡—ÁU½çŽ)¤|ñ¥Æ =€ ÿä‹ÎöF£Q^q:atF4¦ª|½{m³Œöås Q8šôUBÞ(ˆkæþ«)©mm‘¥a¥üí W rOmi|YÊxÇ$ˆ1>ŽÚ±.6PñiTŒPS±ML6hˆnD¶{~Õ¾èö -97pE°Ô}w DïÙÞ)ol‡ŽÄ›{Í…ºmôª´³wrºý|wû'(uðtïÙKØšl1 Íå¼×¤‰ Ó†¥’}ôüðà_R”0?Ì\äJ¹â¶AèÅÍ4IK¦á:*SJk½Ù š…õóäVX©­+-èÄö_mdlº‰&´ß(ÓF¡†ï[|R9½‰Gï"™²o?;xÙ>9|y¼½k8ýwýq]þ¢W!.Yâ0PN²Ø¸çÉWÈX%ÞÝ„ LY¦__9Þß’ƒ!ÎÁ¹/CÆ|€áO¾ëWÖîãÕMìáß½^‰/•`Ÿv邸r½ÞJýÅ0TÇ'Îx€ „ã×k÷×®â?o(®¦@7Çn޳6LÐ ëµ,!({èKÁIÆ“°&Î{øvèaà“î%Ú77E·øî  &÷„nª&¶÷àäÜýååÉîñÇ“½gÛÏ÷wT$À—õ=¼QãX£S!†šŸ¯p·jÀ” GA·ñu¯clœ¡Uãn¤sìM0t}]þýË?¶9><Øÿ<œ¿<؆¶ÿñèUJ5q_|Ýk-@«¹¤‚W#o쮜÷jB…ïëÆ¸ÌEˆ…ªÔýQ:„ë Æc¬‰oÔTF£‡bß7ãcç_ý²÷t÷ÕÞéîΠתÆËÈç_°ÌÉéÖéËU×=Çu4ñ Q›1傚ެqçÓU[ú Ž\[oÒUq1|ý¹;ú“A—Ð+µ0NiÇuiU²ÓùïöÛ¸…h?¾\9Âýt!v¼5‚?d–3Èy®[îxâ™O€aÞÍðΡõ[œ xyzr. ¨z.0¿ðw͘sú‡²w{Þg0ßƒÊ ²ã0ÉdÓ~}ÌŸVé2ÒfLUsdEg9;¡!\ÁôI†?ªæ±ôUêXº0êªs»Q5Î#8„FÝÁP'°? I8^Oq#ɱ|FšÙœ›EÂAÅÙ£ØÐü N=¶µžÇËœžÌÌÊüÙ¬€œñÏÈþñ\}aûþlßb|_Œ§Ù¾$}þÂõý•¹>sµò˜¾d™ž/^l&–ïôd*ÇW’öj2Ϋç ß÷:pÄÃ_€4nŒ»C(Ý ”7~N…›gQ»oòV¿“T¿dgùüÂD s1±“g+Š9ÁЍl ]ô,k•uÙV”!èTªPtr"±¿N‚1ñë‘Ø£)½7 à5UôSÃ'pì'Là€%E þÃ[KO5¹qzú›ü¢‚óJŒo•–¬°QiT°r¥Ò¸Ø,-ÁGذÚ8äî¨íôýÉà ácò] ¶µñ¡Ñj­5Ðz¥1Táá¢åIŸ‡ rƒË+ep¥ÉFç)š“Ä ¬ÆÛYúÚ4»¥×].q$¯T¥µÂo£#¢ÑA ¿‡s¯ïÊ.6Œg& o›D/p^^øôf§Zn¨x%­53: Æú¦¡ êRpL/Vo¶Ö?ÉP¡"¹)Ú«È”a89”>áob`,1,†8b­âË6EÒEä*Âð|0üBÍ6¾Âèƒz<6êÌ4l2ì9t´qoc dÓªâ7UEÕë¯ðâŸXóe昗” NÎ`¬L)#¤«ôÕ…bDåröÇ Ø°×ïù&©ÀÇ —Ëâ›o¢RÉoña˜¤öÛ4è¸ – B-#ÅÒ= ™—ޏEµO{¶…Ÿu%çÀ Ë^.ê2®ö@I¡§Œø‚·ƒÃƒ]tâWtñ”+£ÄN”†Ã½ãƒ8üÕÖ0—1ÀÆ{¸88*¥ÒÎîÓ“f}‡n2lŠÐ~^â;v.üa“žÇú×˦º zˆ8t>|ò'Èu˜Ùµ¿«ä9,bÍÇÌb#¤ýžøH(¿$ǧ>ÿº‰Ü l–Ëóå¡ |P«ü²e7ìÆ&<ÚA¹!:ÿÇ öÌÛ¨ì³Rô‹aYgÔ§u[Ü!ʨy4;{ǘ‰Ï$T.Ö(¶Åø¡I~¼º$B3ÐH7%Èpvp9WE)Ý1k5Ðhflk—iJÙÑ K´ÊtkŸh,0†LÆÊª=.ªoU@?¨ð­Tv‹ðNÖ*•öOc¯ÇúÃ~†ÄÂGÂ|oÅÁƒFù\ãúS š N2¼w< MòçöÐëÅNƒeñU~kìzäíí¨ã¥ˆ"Æt`*i‚5·¤W$I„Ô»¸$ˆ²ûjw÷Õ©á'9h·ùŽâe¼J…îJçx]©$Áˆ…ˆù°õbg÷ˆ*}"§ÇÔ'ªùÉèY£ nØluݲ¨NË¢0j¾ WY™h6ÿËp‚Q eú`×ñù¾E©¨<]Ç=ÿ}ðŽ|4Øþ -ôÜÁßpûÕ«ìÑ$ÊÌ7¬xå?u|ÛÓ‡·}‹ÑmÿáƒË;—dAº™› ãtiƒG@‡3kšv#&údá1M" X¯ß¼OrC´éc!!ùÞ²@;z™(#E‹Ñ ôX1µæ üèV„;!‡·*(Žœ”Š ¤œñ¢$¦=AíóGº¯å×JË_‰òÉóÝý}࢞éãs#¸}”OüHJÆ"9™]Ët9QG …ã´É¯M¦‡ffôÛïMº \ŸC5%¦DÆ©çv&0V-S¤œÞL®i? Tp¾¸×^8F‘Uk’9­ZØ–RÄØ»}ׯòU‰†ÜlE¨ƒ¿ë<ŸJÀE¢“Ï ÏL’šÙVÁÔ.‹zÆby?½x^Š=pÛé{¿ñ¬ÉOyµ`Zž¸œÅãI0ù®`s|xíÒÎË­ýmèKn†²ÿê¦Zƒé}ñÓ‰/ãÞãþ}ò\ƒËË-‡w0é㇗ռ{'Þ4t)øqðrûÅNsƒX>`ëíõ˜gé¿aÀ½€#<„þ7&´0ùÚ=«üOë“ EC<–MR*D û:Ak@r;l,‘0‘äÂ@¢úú…¨hˆ•fÿVH80†cqpØ~¶ø¤}òòÉÉid°÷>,ŠzP5™•H8´: BŒH/csYA/ "“ÚˆDJÍJ©¢0‹^”pš<ŸfÁýþ°qæã Qß râýC4&á¨Ññü+€í’¤MÿüÿUt‹ŠDMû;w]‘Ðç(‡#Þ¡šÔ1t@ÿ ©ŸV §Ì3•ÑQ‰Þ·ýè‹OŸÜ>jÚc Ÿ‹¯Ã[5‹Z~V³ø¥’Œ@í®6NºU@Hê¾îB|÷pŒÏ±@²½NлiVHü›‚l•×X|kUbu É²Sø‘öÞ'gÍ‚«¹õJ ?“€*RºâŒ.šåµÍ¸P|t—ù[²›(½Q-A¡x[²Ìfi až%ËÙ«\@wí,&ôÖÏyàñ?$ê ÕªÁŒH1ÎäœÂ~@sƒx!U RR"¦8( H£UH'Ü;UÑhPáÚ¿BmáÈ»¸ÇâCÇCÏÈãé+#44&¿ˆ•¡Ógßz¹ÜÄ*›â)½¢h5›‚»·‘:ÙpS  1 lÌáãG¹D‰nU6qîd°“eT”(c)¥–%=CMŒÉyàº.ú”³ðk¬ŒºÄ.;cvŽ„ðÿM"e^ÈšÓñePø=²b¨œEŸIŠ€,B_jøø¾NíÕ¡9äÒVöΰ0mêð/[û?‰+„&S’l=¤Œ©!ÛuE±¤樺ÖÇ9Ú®¹üˆõ WäSÍúL»Jñn€‹·–‚rä}h ö0êGxÂTRœÀŠ+Wi¯PIBwè׌èPÜÀl7K¼Kïó¥£ùu«Õx³*ª"*ßiƒ­ÒË?<ú—‘‹î«BªƒúC”]¡ mºÁwzõ<#*pPó½Ö€… ‰ïÀÞàÄÒš£žø§3ÀîíÃ/¶v0<…çËø€4£¼B”ƒ$p$c©ìXÚL5’xðIsÌ««”ðGµtĽˆ¾n°o0ê:}=Jþ´)ÍX6éGY{è £r®)œ^“Té%©#å8í9²Tcq"hÂUžô¦‡»G ³}ac$–eÜ„õö}ñò—½d_ª€ÎO&c脹Ÿ‘Y·ï3W-,¸Ep‡,ÜT“! Cãù7Â:q/°½éª Ø’îÏ”˜‰i´TYY©À6-Š„Hê±QÐQ“òSìu{í¡­Yêv‰ãÙ=øYàÿ^lííÓ?à s¡k¸4•¹Qd\Xœ5ä‹++JqKeªB)“àÆ cÙ »¬5+e8ºŽNÖ›•èáa³r`dû'Ÿ ò»¨SÜßnoÁun[±×ü»„¾¸/·žíäríÞÁÁÙ%Ù_þYÐG.@ôÛ”…È›àîññá±xÍ·|±ø¬ýtçM)û.—õ†Yà{²u†ù£Èº|ÿL#95`E66šñÈæ'¹IÜ„„Á{¯çöjp¸†º“R: P¸|M§íú]¤Ø ÎÆÓÙçEc;i E»‰Ç[“!+Öˆ/¤m¤ã>‘`=5”ˆŽv;Kb‰b$*ëw¢îþ*îKª'‹­Ålñ&XF¨4MáŠU~`}о!¸ý'—/æ‰õ&¡¼Žt£üP1BiqM¬àz$7»öÌQ—>‰X¨¦¦†§:‰Ð¨7ϸžj]Ômo9ô'V.‹´Ç-¯‰JhŽ]ÏïJ £82¦È›Z M#Aòâ îòC'`†E·gVoá&§ñ!Éþa‘{®žAcå5E¸cÇ7Q·yÓþ¼uœî4^0ÙNêFèbª üBöA¥¬Eö(k›ŸJ$v£ßM£’nZ*š(üoÿånî ‡-.˱9"ÕQZ2ü(ãu‘•d¡Š¢XÌÔyqê¼ÃêôÞ;ðé‚‚|á©ÁK‚æt)e’Ç'Ôqê7ŒÙ à€_Œ‚+X>¼e8Tü‘@‡ÖHïˆ šeŸÆ7CxEñëÄé(7½€'ò¢È­9Þ{왨é,$Fa…æ×bò¢+y²4×7õq#Ï8gÖÖ³n´,‹B8•Øü¯ ÝʇÈÚ«¼v¯Ù*ãžü©xŠ+ iØš¬ƒ)õâ+!p 0æ­ãg¶mg®6¢œ;‚=9Tvàâ\a+>Ïæ D(-€Æ(ç‹,N%€0èYJá¼ôyéã O‹*ÓUØ|äŸBr"îx£àJàõbÃ'§L…ÃÑ´Ë++Õ*›Â}Ó\-6†ï@þïÁÿ XS̸44QÆDó š¬ Ìy5kurêÈësùŸ‘Bb?‚+•J»ÛÏÛÛMAäßSy»?S2Âk)¤ÇÿJuŸì•ë›V·rÆ)fW»pÙ—`*K•ÍMŒBM?ٌڿ@Å‚Ó!Ï2šP¼«_ßT…©0%5â†-p;p·úö[ºjÁz`ÖÜÇöÚ™øAÄ ð?³ù’ím–¨Ûr •º_Q7yÃHª\–l÷ÚUx¥„×=õöžÞ¤&üÐ0«Êíš,¯ïPнŠqðµ}…Fþƒ/[ä Eû¾¨‡f§Õ²Ê3§\_³BõX„¹,Ðn¥ÃW™‹"ÆW¸ư\¡ÌÔ‹7ÍC_¼8ùðŸÎŽ3n›…qTèT×ÑÔÙÙ²þzUìüß³£#ñ=ÞÍb$=9…7t® 7%¼ŠŒ‰ÆÔW#d F"ŠH­€íùÜDÈ,ð)+&y`+6|<ëE}x\áJy3•\M­¿2–1C‹!õ$Jø$!絘{!ú~B¾ž„%ÈH}Œ™úebq+cÈ=àaÄ„º¶‡Iþ ¯ú¬®Ž$q®™!"W‹.RHL‡j³CDXßí¢tet£®²¾” ãr)$e@…‰$åkÈz›k±`Ïè HÞK†N5ï4¯oÂ&ý¸ºÄ©ÙÐN 9] }D«Âù•NùøE•›eƒ?mC®ìÈQé –+†i¾‚bŽ&á) ºiUʲtEu+´be¸/×aN„ÁD¯ù·Wñ†ó¿±ªå/¯€ –*.Q`:ß`ôÝäŒî"3ux6BrXco`Ÿð|ì¯\g i´”GGå"‘w!·Å‡‰‰Ÿ"óíÄvHÙ±€WZ‘Õd ‘@‘ØÁÜf}_˜š 7+º¨îˆ¾…¨.Ú ø gr„¿â0".× 0:Z¡0ç‚nSpTTŒùÆy×À‹IîÁH#y‰_Ê,¸»(G_3,½®éwLZUEhX¬}ݬÈâ¬ï7Ê43ª‘Šï‡@)¥ÃÞÀ¢%[2èºâ L.ÐÏw=õžA›aí››¯Wãüä×GqŽòëÍðë×oã¾!_·¿¾¨XóöDûE™Ý /½¹÷õpXÔf 'C<†ëPžÕNŽéê°H+ wõ„E‹Z‹,2`J%-ZÌàöFÂÕîå è‰{×Éæp³uãfK–NÛÊÒ)Q&ß‘FëhŸ%•5å@Šz8iÈ£É,Èù¤Ï‚ŽqÀ‚&Ò(wÇòºCq5»@âÉ®pøAwܵb(eU²¸sŽ— š\+Y ÚmCßšV)röE‘5Ù÷¤UZÿ°®§Ï'• Ê–.Lû¸g/Å– VlâãïбÖ/óQ£Úu€£C±U¦L¿Æ0࿦^ z•x¾»µøn–¯¢2û{?% Ð«¨„Tâ%Ô+]㪔ÿY*èR©¢£àêNødö«‰¬¸-Ö~=+Y‘—«vŒ9]v¯Z% 8”˜^§  Ý;S~ž˜ÿvyU_z’•÷wlY$ºr'7àçay’?õ´R0îòŒˆ4€&PÄf—Š]Ò­Òtw]FbQ¼z[‡y·,E’E]Ój•ZgŒð}ìÑÅF:  š|£cFž¸[q“•8Ï‚‹vtêvƒûV&¢B¼dÏß±ôK¹gðÎ¥ VC·ë{(Åé‰Fñ“ÑMÚŽò2e—J/qLˆÝ¯9üì¼4¾†êø€û°~YÊzéö‡òBÎFVdNˆok,»$}”þK«lº´zBÇÅœöyv¤D‡†ÿ)¯}£íXÕDû¿ÖTØl|`;Ví,fü'5Ì Ìápv%1R¹¬ª.ÜÒ«0 sK^ ÕWå’ÿ‘—«hc¨Ž“5 ˰C$Ún;„`›Hé^oœî¾8Úß:Ý}“5ci}bÓJ”›X)—7Íí!˨»´j4Ü(•Íœ,#÷nTJ¾H–SÛ7*¨Þ”JÇ| ’ylžïë?ØÑ.Ÿ›bñçFšVÂåKX·1}šº¢½hó6^·Z–Õ:k•ß4ðjøMã¢rfI˜:×O«U2OÍ8Y¬—t#lR~¿&ŠÏІ.Bi¿:¿¡­²9x:¼!s1±² §Ôýµuñtäºâ$8_!uxŠV)r/íù]›ýxï¤R™¬ʺl‰‘®„+BŒYà <ÅÐ <Íqv¡c54Žž³ƒö&H€óòÎo0Z‡,^õš•2?TJᨋ·âJ™*¥½XÚý}x#Ÿ*¥?íì·à•|ª”¶~ù ~¿•’¶ænáoº@áWçêÝ-Î6ÑS"*L¢=3Σ\rÚž)õ ©å¥ÛF{å«67J,¾`öj™B™±ñŸõk, ­×W›?J—stâ#DˆL%×Ôí\¹XËK*YUÊ¢TPzbG…‰Gh²ÄØî-ZÍ…› i¯Íª¤^4*Ó¿æWŒ` 26 ÍÖ²x.9\¥‘•;%‰št4Èxô=ê'õ ÿò=óbCMš:?êçèQ?©ù—ÿà¿?‹jÊ Ã$0Ö&ëùecòØü¨õ“zùOl†’ͧâGù¤ä_þƒÿö$Pö9ѳ@‡ÒG~ùîƒ\Üx„F^I-²‹9Þs~[$·SÁ*•jJ„BD ß±§Jýk%Âh$ôá±ûŠ%*Q/*–‰ø瘢<'ò8ý¨õ“zøSæ¦p¤êÞµÀXyPU)ôÇ¿ïuÇ:Γd7ʬÀ3cô"Z&gÐó2˜¨O8óµJéØ2xº/UÈ}<0+ÎhÀ,µ¥»mñ,:^æmâÿã;áW¬À™_>*¾S?©ù—ÿé<1gJï’úI=È¿üÇ$0ÒM‹vÑ7:¹¥0 §ÉŽdì±™›øÈŒ^ød̲ÐäÉ&5ìÈ_\òiˆ ÐÈ(JùX!!I\cäN„8CÆËÅRÄ~5I'_6§@K)¥ÉÔ"æAI0vѽ$œ¤|Q†ú¨¸1yè^âmü•t%„Ýs¿"ÒL¦¬œÝ?Ì3Ãò]z–™_O ­GŸ,ÚM÷½¦l½U^å°Å"þ¹Âß+‘ƒùYÍ4pQÿœe– x'‚óˆc»°Ë" fÉ·Iê.7Æݨ7.61…§m7–—j€ÇrC,/76‡›×ø¿ {o>9|…òÀc9léœ)eø1¹¹¡Q”ö¢OéÂË‘ÖööNëZl´\Š<ÛÛ¢–ÀlJðêþ­c(ˆOVIyzsù…fleËäM¶Žg®Å)cuùÕ¬”“ù¹QeáIž/ýqÖúôxÏÄ|ú=cÝã­ƒý½'Fe~1cí‰a€1ˆNnã¬ÏsBžøS`Ç Ì]ñÖpÍO³RÛè‚Y—䤆6In~©ÛÙÞ6ÀmoÏZ+‰·Ûó`­ÊÎ`ÔW¯fåèbÝ~6s¿ùˆ oÂ6û+Áã ‡Õк©“,»Ø-[‚ã±Ûs»ýZSEoߢ‡JôñlMrÙ;%åºh;½jügn¬Î]÷#eêªówǨ>WÏü\èÇî蜂|'Ú5?ΪÐÑœEòSßfï)ÌÀ(H"_ÎÇ!Ž&~×÷ÏOs‡ÆÇYikç?¤‹Ž(*½˜±ö‹­g{ÛmŒÐïfZ®DYeü -#?%ÖiEmq`e}^òU¿ðUQ¸)©[N‰¹p+®ˆ)K•˜uW¡ÂS“TE/gƶƒ½§»'§íÏ{?+ç{ò¯/O÷b¬¯|5³<`wgï4&À³ÊöŽL©þœõî”ýᣦ²&k?~8+žx¸€_Ì|[Aá$ g¼YAlzÀq&f}žã§*¬åëgðü±Ï‹HÞÛhð$w(¦;{7ÌÇgžy¦Ýh÷nਅÚH#“‡Z^‘Yo¤—AßÕ rV9%æäfiºÃ6G Ï`mc߸WÐÕÔw¯Š.±2‹¶‘ƒ´…åÀÞ¬w" ñuV™fЛôS4ÞÎ'»{é³â2n´ ÒŽÉï·³ÎÆÙhO|ÿ8ÉÅd}žõ òÁ¦¾Íª7qF½nÐC¶¶ƒ^MY{8·Ì‚mènmè2ó¶Áúä,Èüe1xmP,°.2o ÏŸ„íý,ÈòÓ¼ÃK˜EŒÍFAV2àÆ Ì S?ÄÐôÇ¡zþ¥;òÆíöÆ{?3â¿k£tIJ€cœJüÓÌ{#U¶å)É·×-Ìú>ßé,+¥Ù˜Ô×™áRöGu„Ä`ƾ̼Byð_fÕö\ZÄ€Í׳B Âq&(óý<²ú¬kÿBw~Q¢5AFmŸ9¿Ð\÷ª,ÁKâË<ðÒ†+æëYÇÏ¥Û˜<ܱñzVÓÄÏ dÆÛ™oÙ$qJÕ‘Y&a e2!§JÍ~ß"!Y#Í׳CBGN‘›/ñqÖy²ºg¼™Â°R@ÍSÒ(óû4"G+± ¶£PÓ±°–#½…—IpÆÛùà [s¾÷´Ç\„íÄišþ8+ÆÜ°¨7tñѦݑDŸœ"3ß•±)Þ”Û½¾'vqÌ/¶XK,Ñm«ÍTÜ^Fá¹¹°¤¾*ñe>ÉD¯™éÓB~¿¬6…ûÍØæÁ B͵:L—™ãžŽ.\È&®åêõ¬ž†2'-Ó0v…ZÉ{$ŠÌÎ,¥% Ìø0=Ìÿ2WïÒÝš³? o±©ýœ]df´öö«W1;4|1¿=OLâËüv=ÙðÔ—5ö  YŸç]™8DóõìZîùæŽôV ೿…þjZk²Èâz¬i p‰Û鳦µ•º^+ÝN^©[è ä¹3ýA¢½Ù*ÜRl³ Øíô ‰† JÝF¯GT’en«_( ‡©rw¡g˜Ö^²ì"X_€íóC4d÷9€%æ×?$à&¾,¬‡È»Xo ÍCÿã_n¡—HNoN‘Eõ ð™ßo«§H´QXî¶úŠ)mÅÊ-¨gÈi!úzKýÅ”Ìb ê1òZ0>ßJŸ‘?Uha½F^ ±‹è7€SßÔs$šŒÏ·Ñw¤ˆDN™ÅõÙŒD²ÄbúìÔ×Åô ©µ\®©øHM~ZD/’™ü¶~$4ýq1iVîÆÓ_o)CÉcñ2Š-$KI¯_âãb2•Œ5\.KR2»¹@ÿr:Þr¥2HeQ±[*ퟢe{ÿTð‡´³/«GÓx>jpg÷éÖËýSÊBµ%Î'>á"ôBŒŠ„éÁ\_F(÷(r8{¹ë ¦#¡²¸býö9çŽÓ}ÇÞû2Š+'Í@—ýï¿oïŸR\xtâo•×JÆïJéöóºTó RÀÓ|Éì^22ù߸O/¼Àùj‘÷&’ŸÊ¿ûøíà>´Oàr·ãGò›ƒGCÚ¿¤ÅN|?òtã[˜’Ò‰¶¤È=NµäS|<Öç“BÖlìÏû 5ówüZ$_ËÇÚä“Ò¬8öÊ7y‚€,,–ï /ÞEجG—b ÓX-ߦùÍt’ŸÓ¼X­bEe‚f'¢ó4PP³Öoüù|²,~ÑBûz¶Zg:êÙkÃì _C©72š ä,ÀªØäbÕà- ž-ŸtÒó—Dœ¨>õK,/ ¹ œI8ì".^z¸£ún8VµU„WamzU—¸xmЙű²–Åß©S+‚#ñÔ ˜C=%)MÒ¦Ãx7ËLI%!aÚy Q2&¢Íú–¨›h!C‚ o ùcô+^$ãR̨ªosW“¿£Îœ ÃÎitŽ a¾ÝDús†™CD€Õ4c%2^§$ãÓ¦^Q²4Ø!r|âoÒEsd‰%1HHìÝ_–PÔ]õ1 KFßӴĬœë¯FmœnÛ™\·9oô£Â©%\™Üá<Ù>g”¿…—2[£;6£¯š)6ƒ f'P1žáË(˜\\ê<­}ºœ‹ô§ë Ý¢®E‰´9¶ï‡ŸáZH»¤Gv¶28á;qÿÿÀ Þ!2RwmÊ øŠþ‹ç>ãt½Q1Aé“0gÌ–™ë!gçð¼N¶„½¸nµôiz ²ì}ØaÇèiI..Élí“!'É ì!ÍEŒ²Ã”Q8bÂGÑA¥MÀº‚_&À„}e°K2fò%Å/春ä g†‰óîæàÞyÿª¼œ¶P'6ž[ˆ×Wªy†Ó‹;gXOn«ÜxÕ’žX±h ¯Î8¯Lp¦áa‚0sÊŒä¯*É#e-ÓO»è°Ì„²j,Ý—¯ô“hG/¿'›%ÕL++§{Ü^\SÍ$¶ÜgðBƒ{;Ú%rþ+¥ËRØxÛ8ymQÊœ¯ß­7ÍFiXºÀ¯ß~õfõ«F£´+Ð/áeþ„J4F«R†ïcA?J~Ÿ@¶VìÖ‡µ‡ß¶>µª6f@_Ã2²~ ¾¾†k-&åù¦q­¾mpëexåÃ'lÞ/u¸±©•d ì°j”z]Ùà^÷h½8‚îp/Öé÷Èg «‰Ä”p’-ëM©ÖFWo´|¨ø ª¤0 cáSèƒYsæFÆb,ŠpHБ¼òÎ%šrR'm/l·þ^½Íˆ bžbÚ>ëÿ³J0å„}J,œÖn¿"?ì{ãüXô²&¬Z(!ZSÔ¤˜ƒ¡‰ÿ^Œ/W¨àëµ7UÕ¾­o O|¯@Ã{÷ª21ö´Éà_{oÔ«ÿŸ½w}LLJ÷kùÞ/^š§@KgȤJH›Ü 3MºÔ'ñS°r™6¿¿ý=I–MÈ­—™twˆ-KGÒ‘tttt.!ð΂Œ êbp€F(Ò¢t‘(úE­õDGÊy›3ÒiQB°êd~0¥ ˆ^U›¨l¾‡ºýÃö{™?ÀÇä¹È‘VV5aÈZ$ļ³cKðò]ŒýƒÂDÌÞ³`¶1ãõøñäÚ^‹¸ •ÚÏ ‰a„x‰…Ó´ä yÀü8&àU8•)¶Çç)4ÆXZ™‡f³{Øñ®ÂÄ^rÏ_É•ÿÀ¼§µ‘GÒEæNñ(G;‡/¹7 Îw!Ë\–ãdåðt8÷‰_®éx¸Î/ëœû=[¹.Ä2}ÅC]º˜ÎÓÂÙì‰ã%Ê'<|íº}ŠAˆáIQf!CäËJ÷j¢g„r=Q¯óÖˆbö¢ìõªhû’æá¡Û”œǺ è£VJ„ ¸^¯ãYk‡2öö6Æ=0ãëø"ÄbÞv*`Äñפó9ýò²ÀG¦Ÿó'©2À'HÕŽ˜I?ö~˜‰EPÆQ–kMNgŽrGÙìá³¹÷ó¹£SIŠ?¸°eËpDHUÒG© ùf-¦†IÀtZ‘ 6>f«øÚŒNÃÅ÷ݶ•q  Õô×¹aÌP˜êA^ú‡îôc‡ÂLwúIkÛ1·Mœ5•çŒÈ¡ Ï+G©ôÂélÇŒÛ)‡„œ±1ípç £Miú“åIý™tsr”öƒ6^YLɾÿ|4—[0´ãÅŸ/ôS…é™ 32÷ðGc *~ž–Ì=TB5ü^aîAY¤,b ³×“EoÏóF%-Mð®UÃðK¿W eYhÄs,ÁdgÒ1ê¤ö8yº°¡âKñ*Û‘3 FYvR!›€ª3Ìó€‚1+m , tñf!rŠ© ¾³hJš‡%­ÝâŠ8Öå(Š®çFŽóXÓsFñx‡C÷§†Š“çX]Œøì]åiY—æ`Ø·òˆ¸°¡ÛS îŠÅÕií4ë ê€ÊétŒZ’—ï[ ÿʧ‹>–Ç*eà:¤guQÞ 6Cøê”L€5ŒÞOéà¬(¤§ ó€*;™_à†~~A^ç Œñ$¹Æ#³€p}ïó™1ëÙGF¨O8ýÄs²rsO¥R$dæ0zièná_£ú6Ê`‡«u#z#NqÀ<ÁóŒÌÓÈ•9¤ðEyõpóívý=Ö$';âë*QBÛ[Á°V³NÂy?_ÏQþêö<ÐÍj¯¥±0_HÃSÌ54Â|_ȉ¬ª… y^%‹òUñxN½Å(ò…ÃWgk³µ6?„U¯ðRbC¤Ïiùµ°ƒJZ¸—£ØhئvùîØëbö Á*Â%©*ÚÎp<ò9d°¤¦‰®˜Ï ø‰Ôh0 ÆÅÉZpHµI ÅRxnlË»N\åëõÄöü˜‹Zc^†l§&ó î3“÷3¤¢e3/.msDl,õΙÄýرelìµ þè i‚’÷ÀÜyƼ¢ñ¡ ‡£gbYœ0#Ž`>Cb ˜r5ê62øê3îx€­ Ћg¡tQg‰¬KŸ¦euÝD ¯¤a¸™R…â$f¾†‚ËFÚ„¯=‰F®=™´vuUJªÍ%±öD«eŸ©5ðÍŽW6…[Ž»DÆ*ÉÎHÒèkø0 ŠV1°2#‹cOæ€.[î…6ò¶@ º>®áüÓ«ŠRðoa>8Æ=|è  çXNéR×2A!’ëd>à¸iÈœî>ÿ÷ð¿Uàä?^õ?WÅsÞø|šI=û *èÅŒÜh]ò fÍ?׌˂v^›l“Ê Íž‹|”[Ó§P`ND]uZŽå¸1‹®«ªCÐŒÞ9Q:>ãÊê5Ó[ }×< ´Z¬š›K÷ÌDuV:’¡æ ÍD)ЋA"¥`ÌæH±Äó¬ÏüIþüÑgþs4oH+QD«GjGmúˆbÍø,ˉ+DÒl|ñù=ñêÀÀgpUÈjs1У uU¿pˆiµ¤j¡JM¯™ ‹b˜Ì’ ÿM† õ€``4*1:ݶǨR ) m:¡"¼aHúwZ:¦/Îþwá=½èÿ›_˜ŸËGŸ¡éÏbJ,,À™ ²Ýe*ˆ£}-êWÚª¡¤ w ¥†uá¿Z“Ž´FÃóÜÂ'¢ÉpD#Á"=ÿ®ñ‡ c!nq~æì3ÎÝ’.¶‹p†ü#óD;>Ú^zUÌR+é ytiëÅlE<  TÙqsbtüñ :ï$Ǫbxw½V ¥J?Ÿ8‘H 6 a!²Óˆ@’Bq3}ÿù3uÓÅbšÏ ÀÁ†ÕZæB ‹BRmÞd…¢€VïÂá±ÚùÏ ÅâçS Ï ¢ÁªŒ€å%šNçn‰"±_ãjY–#>ѲD-àc?”•Ê/zò[4=ÜïÔsÂ'J».L¯‡Ç5`–ìcN±WÕT¤áv‰ÆŠÉ2'o/0Y Ò„4=ÁÒ‘cõ.J^“‹¬©w-Òâ0 ³É.kY¡cŒš2H'ÿUÔ”šd‘lEëMcf5®Qü7©rdñ@Üdž'ÔƒËØ–Ü„pÙéHZÐ©Ï -W¸`¤)IçŠM\ÝÏi™jgBJS%¶vá4»½Í%Ÿ(€)2­©Ü›ú·¸Þ‡ò§«_6¶šýµ9ñ Z#Þ§´†k^ຜ¸º%¬ î»+ +…fÔßë›dV$îHÙ̶¦R¡kîh³çb¾Ð þ„Û÷é™…‘€Ý'h<äLXÕDä\Z˜#ÄÃãk\ $½Wçײ<±Ç×ðgl wÝc‚ÛoΉåáM6’Ü ¤á£qôAk*º·D™›Ú<€‡P¦ôxYÞG-ÖðÇž%„v"ÃÌ{ÔWiîq€OÖ®ŒHRt—H<¢»„Æ Å·4\‚gÕ>ñ¬EKŽóˆàsp¾»Q§mêz`>´úv‚'ç[‘:‹@Q^v£¸0?)e&9>¡]yšXûºÆPf’\ýÆ@¬˜Þ[²%%¨=û$41u½JPf¼•¤4˜9>ÌËî™éœ&/ˆÄÌRbª©|Fg”HÖ'UЭ£G©g÷CImUC¾Ä|¸Õ¨¢-†ö´wC<ôˆÈø|µN"£°½b1Õ1Ó;]ÓЋIþÈ m;#Ô÷ƒ&`*—Š£Tµ˜†„ò2òD=¸?ŠÇj &½,e;®’£ ù@RÖ¹H²ñƒQþ`DŒdy Èös’ÀGV ÓlR «¾Eº*}fn¤Dœ@7&ËT³tƒü%º 4Ž…³èè§„©uµž»­².­î8t[£\$Q¬ŠÝÒî¢ûiXv¤ÛÂcËå¦TÛÙhìwÚ̓ïKi2ýDûÙ^×SmyE…äN†¼ãë]¾îTj—Q}eC^\©¼B !s"“:9 ÏqÍJ~ÃXE‡¼È磅î,¥á< ]âÁdöºk%¡XoÔ9pÆ&uøM¡r—Äã!+!‰|¹'J­@ˆ[JXì)RÜ_°ð¯ZDp’ñ³„^Ã#ŧ5r§ ,婺è•ÔêvšüƒøÌkh&°³WtÓó{ì¡LJzc4D`ƒr.T¥Þ¦2RK‹•ù© ¾ï€ (ÔNq뫵­wl?wF£dõÁ€HqqR)-ýÈk-Å¡ã0±¥ñêêþ#ïìáÅzíS‘yK¥R©¨è'füüÍA¡ W+ -ÿ.Ï$‰TjÈ»(¥oåRoGôj“<î^QÜ*rêìwŠzþØÅh†)ÅgºMÍþ«Þ%Ò¨á†íÏôq[Ð1‰ÖÙ¹›Fì^²?"E@}¨³ÄÂ-»pGô~2»6ïÔU£ÛcäŠb±%1[€= –¨ )…é}´¼…žX£rÔ‚¢2¡;µ_È™ }yóæ9²_¸âVŒtƒjG)“æ9"7Gp*`aÎ4žD¨9¥à‰‚6IL²nvŒŸ€àYFI? ß‚£ÂsJ÷^VÆ^ô2ÕD^*)3J(¢çž:9ýá5`.<4) 塀#xæ)±AŸt¯mL†Ü˜Pgλ‚í© ½Gé겼ɤ Œ”í# TˆÙß2ÂÁnýj+9F]¼>ÉtH@IpX{¯ûÑ<µŒ¬Ù?¶`œ$æ‡Ä,ÜØê\1…®¯Ž„¢X±ïB °šó"?ü…V…# \:Î~Ò÷ŸUØ‘Û ’èôý)Dí´L2-ÈŒ†ö}p|™¦}ñºô%0ìÅi‡¸ô‹ƒ)É:k>ž€+–ªr÷öóÅ`nåë«Ò?#Áç4O_Iξ„œNNYaõ¹íºæ¯ä·%=×Ü1ŽÒs"Ë@f.iöáÂâ̤ò¤¥Ö”pEn§W¯ô ÏÿiÌ‘‡éÔsM·OM-º9¾šƒFVº!ËÒóÞíµUàQ>ƒJÔ=!¤ÄKbQñ½>ùÀ–õQÏWÀïsŠ>›•í{î9*œ3‰7K=Cx,(= 9ûQß&s£çÆož=ÁÙùÆõ€dë9úÓ>ýË&o”úi…¬ÖÜá•GNY8IUJå%cÓƒ)ÓrOF8c6Ñ€ýä-§«Œ±˜ÑWé´¢)Þ²‡¥á• ìÿˆµú…#¢Ý=vVYÎèj•ãÎñ´%wÍúÛÚn»özk{«ý;žZ6·Ú»VËØÜk5c¿ÖloÕ¶kMcÿ ¹¿×jºÞìÛ¼ bšxåŽéàäY@àtpŒ²˜*0³ˆôì4v…$bpŵº7ðåAáótèûãã>™mÀ¸ƒŽXàì‡)þ) ²o°DlÂ$µé¸ "ÃL…*D-dºM¦·#l¹'Vh-Ïø ' è ïvòí$#­Ë®¥èêô–çq©BBCK0M±c@·ÈßÚ>žz怎‘< •£xò œBZsm$ò„x´»½<À3š–ÞjmšE÷*îò·Aç38øY6«nà"¼yú¢o/²7[7YÌ0N T0Õ™§%þóÙh4¬.,\\\OqÑõNú Ã_xU${mq¼VËfdžžZ=Å ˜¼Ó²ÅúºT%›lSæ9tkBI-ƒNF3L¯‹Ñ“žñXh#º†ÝµÆ;BC~ïÐùÖï­ÎöÖëf­ù{ïç×fŠ[Kñž?n°¡2 Ïë,ãÀo¿ÑYê–0Bqq°ƒýþ+E6>*úø\èU|ô¬s[ÿ*ß¹–/@o‘TJÖÈà¨b5ÚHüùb[´#‡ÃåMÇë'À¹ REú¨ºR×¥ÿr °˜B¯álŠ#ŸâëGò6@Õ Ð“L<ȇ¯É–î˜ÔIªz"YÏ36„\c€&ᨮÈçÍ<ºC‡OLàïJ’TÁ%Õ¶ÞE\列arTç¹äo)¥æ}CÂuÁÖ)ç.‰uØï—°ð¦y5 ÕÈ\Òs‡Ï.’äJB7"ü*{c"ôyK…ñA®@R@ \êKº)†™ ÝŠ‘°#œ$¡“¢JáK¸¦CðLÉœÀ9\ùÙõ%˜pí<µ í…?ˆ$9U†V££d9JñMFyv4Ai56¹ ö±Ðã0C\Ÿ†yî¢cÑ.Z÷9#bï`ÓªE"T‡l9§xd´ƶ˜zmXK+ÏÂeÎñ inɶB $ë~h£nÙI¨mø ƽÑlÀ~9êž¡œ¶¡r4T(<"*.| ¨Ì›*ófùuk£€ m§Uúº}!%a6”ÛÝ¡B»;úÚ„Sy–@ Ë£‡{löGh6ÆM¡"ø ¨€Í^æ¥=„›æÄéà%º‰îÀG¤sêìq¼ b XƒÔÈ:®7 I»i8¾!¹‘^%?b¹]0Й1¡,µ.-*ʱ\ ´µÄŠ $›>ÚpÂÉ$]İôH¦',<{Ûʲ§i÷ËcÉPnXF™¸ücÄY€^RìxèÑv/^7Ô7ÞY¡ì-.òk¹Zlt' 8]_£éI€ &nÝ3T&ÓÀÒ>6”.¦®ˆÂnÃÞx0Äé%BçPYñŒùw8rÔÛ ÉÐåÁ}ìCt~´Zì1ÅØ8~L5æðÍ3/ÄÐñE\iq15CK’òÄ [a7Gm@§ÑÒQ½ôMOðÁñ¹¦V(3ÝX).Tê1¦È®’бÃÞ¿0´rV1Íà¨_7µƒsÍÒ{Æ®!#„ MÛ‹ë|(6ØXå¾c+˜¨bˆ'áÇ|TX=«wcû´Øe·kªVP?a þ-p;_Lé¡Ð´:ôdb…s{uJ•lw%ÍÃùt}4·»Sœ ªFÐ'ReóPóRøÑ@>‡Žå-fsÏãjâ¼(è 6ýÀEPÄ1ŸÑÉŒd.xŽì7ê`Ƕƒ';\uTX§aHOáX1óAâå•jà7[¹¥p`SÈFŠÿ"H©ã€.LÐyHÐQ¥g¢Å<¶N>Idh¯†]z§öf«Þ©ïÀqF='5öÉ¿4Ó]ãpY‹äèÇ¿´xs<€ê•à˜Ž}‚’5’_„ÃÑQöP ¡ {Ì$ÂŽÉIPíž±ñ[­¹ÉéåžÇm#qtרkp¾–1î˜{/:hVq4x‰`™p(úÆQòÄaÚxC(e¤ÆÀmŽ@ÃP{|Ê„ÔïõЀÕ?áS 8®ÌîYa'›…³§ð·'ñ– ie  Œ¦4Ê¥âRQFþ à®,Ñ!JÛr'B&ž„`âÑIˆÿj‚)™,Wôéø¥Å<™z—‹&¸,rå–ÏÊO—BÜ'¦í3äùÀTL¡äbââTQ}qȧ ý‡0¾%Ý»„""M—«ôo@ÑMŸð²È3Q¬ìRSFÌž¢X°8%² µ*ù3ýRGir¤-H˽ƒå¹ƒÉ—KSÛ"" `¦º=8q5ª)à(I£þFÒ¤¨ ¥wÐINèàÛÚœþ3C€Z"jØWŠì1É2DùÚœö!R2Þ%kÚ+ÅmÁÑib?AÑ1‡ž ©¾éõ hS¥McÞv°È¿´ d@G¿#Z¨W7ñQ8˜#!Û%д5ð°C±%yKÑçÌSÉuÉŒ£§8ôeC°„ì»`­³;¾å`­C»ð C׋¡B®„ù ¬ÈúÚ¸i÷(ôwk;˜—²­‘ä`%#2õMPäÍKåx4¾‹X5ž—µPšL(ÜBö-o`û4yIµSb=pC*¿Ä‰NȸcCsR=±_bÎþ"”I¤¦IJ{rš85%ÁWG¥jˆ9mÅŸ´&NƒÙŽØv¦kr‚†*&^Vq0E=ž0¨÷ß%¦µ¤t^\(bë)ö´ôÀ*•F„MeÈWhäOì̽pŠzÄT½:R‡ Õ-Ó  !3Ӧй‰ÄýÄdšÀž D³Xþ¬S‡0-&F”gìG"ϤÒKúšÎm+ Ý^ÕM IÈÂÏaßîÇsÃEê½1 ‰¥7_ÔÐá]íæË¯¸ÄdӱׇS«ƒ”I]ðSœØ)êú†“cJÃB2?ðM0”‹/«ˆ‘!êØ›º¸áŠ«D»üªkÌŽpÀ ¬XIPdB*ôE¥JÚ+¨¸\æ,§Õ`oóÆö†&«â-Ž?IÒp7¨C-20ÖÞõ •ú·DºÃ Š—AEÃ]ª¾ë‰â"Xû1ªtq´5»«Iv„\G&&`Ä,&Ëwä­¶Lø—ˆõÛ…q{áº. ¢£!ŠáÝ“¾^Ƽ E"!ËãáÔpÉÔá }R…dOì.EjêHj¦$ØCç8¾¢!Ï11ºCÓ ÛUo„:–Ž“bê¢î¢‹`bΑ„‹¸ËT]›SDO¿9¹‘ÁZØÀû7Õ}ߌû#ӱܱ߿RJJ….· ®¼MûWJ­È'ÂDÇß›=€Öï†}Ó­83Ö0IBáSEj|=¨ÄHjqlqÈ–¬0¥Ð=¡¤(¢Lë7ñšž§¢\ôz>6OìÈq{€í[—ÈU2‰ò‹‰‘´Å*þclÊ¥|øî%0.àœ8=“‚tóuBü·Y_Ü]#‡‹sŸ¯6&ZPŒý"¡/º»öò•t$M Ö;AÝB_CÎáYÑdµÄÙÀù6ËìÅóŠS#Ç7$zRN¢äuMPðõŽ 2ʤ¥O­UmU| Ž9XÈE:JÔ"SõÚ{Llc=K¤rBEÓ·h-ƒ¢Ož'vð.¯›4=Z‚1Pe€®KÚ¹êQ16D=c8æC¸ZËbØ%eˆÉZŠ“îYè&Ât~ühŽÃÛËË!\,¦Ú:„šè€Ä’®÷‘5æ`lUùpD„€“çÏÊ‘ø5N]AQÒ¸˜˜ÎM©cad‹•+­™ØÊÕW®‘¾BèßÀnl5 7žº¤Žu9Š IaÃU@Æ©8öûtíÄøÕšÈdO;æp—k‹Œ!£}l¦pO ÓÒ£n:oIYÒ2.4û…T—|u’+!ã(,ôL(&ƒ8Òúêª7’ެl7êK2’È¿Ñ6ö›æJn3¨ <Ã8 lgìw¶µÆˆ”äF´ÞÂÑÔ¯~­5×°1ÐŽˆX->=®MŠšQ¹°|b£Tv¯£²Ûø˜#b„Ô:ࣥ´w|q<çñm€&ÝÓ¦TÆ‚2ÈjYnª§Üâ–W(…ov'¯uÅ9Tñ„«‹8MÁªÖ°Ððˆ$ÈI'%”t÷«DüB;\ èÐÄÑŽ´B;hB:€ì‡‘,¼KÒfm8O!®ˆŒ‘P—$îârlÉÁ!¶Vø¶bšE!(†â¢f–D#:‘%œ& èÅU¹P?$MÜ…0NúŽ4e ¼„†Í8힊bM^ÿQêÑ7v7&´è…–n™•i™ˆmVHó`·ÞÞÚÛmÁîYk66ÈpC@=h603Šw:h `±`•¨ì°[µ×Û R“†L…›ÿá-£,eûêZDyœÒÖV‡ô:;³)”jÈÀ%˜ãÌðSÛzÁ 8#òF°±qZÖö¥0aç<õYKC³§a÷=¬ÂÏûj:õ\zgõ`ú†Ûóû´2w¹C“c²_§ªÍ‡½÷O‚\ûfÿ}µzkÕ÷ø tŸ îßÔ<6X”H¾Ð(¯ÍÖªhßpYVøŒ§ÑzœŠGÙ\êSàƒýr®"”\*wñÊ9O5H"Ÿsåµ£ô‡9TÚ7 àgƒôÈÑÁÄ‚ná!ž+¥£p.«óq€0³1Ú$ ùj2¤£IPìü¢¥2ÒÆì)=EªÅùI }¿%Ê&!£‘k«×Í~—µ?º]åƒ ¯>ÚCrnáhµ˜Aízpn)ÈË^š„`Ñc·ƒû>9zšO§W£!P‚瘟¢RtÖO΄ƒ÷nׄ-0øÀ¯9CÅç0ȼ­ÛUYÔ뎰óËtñ*zT˜½Ãy“šŒþ!LÞ #Ú÷Ÿ<ÖĤe÷ÒrhÒþÿÀpÿÏÿ¬þÿüW3)üÏÿ¤?ˆq‘{´\Û$™Âº„‘iÚ—‹b¾ðr”`ÛK.P0ÞIVÉ pU@Â~àæ ©‘öû@«+š-FÄ¢¤*búhËöÕÒŽº¾·½Ý¨·;xÞn–sn{®CW¤r£ÈËH“T#:7é —u>Ç'dêÜVf¡ÿs -©Cð#¶Ô¡o‡yÞp:Æ-•ˆŒmH±ñ1»õ_"_´ ì‘É/9iÇëmf ”¤.ãâÀÜ8Cm¥¿Ùß7N­‘O–ÌsœH÷G¬ž0°/!µÞ\ØÞ¤•¶½Y ŸIlGKÓFÏFXUa)ˆ 5žº‘ê@8YU¶%-|†€äŸ€ËpbÔ6zn‰/ Y=fcsØóÍÅÙNà4ˆA=f¡ƒP݉xÅ™¹?Ðgc)žiÒyÅçÏFV:â“ߤ•:[êÎÃ_áÑU12„*ï*ÇÝalÍäüˆk¢{¸2~¸TS‰Fðn ›%ÙµvíXU£þîÝ­/+;¢Ðý/, Ò”KKYÓÃ_\JÈ·º¼”…ny©õâq/1U§ë"32òp™™ˆ›¹Ð”ÐûRSÖó%.6“ëúº—›‰#ù°œ‰Õ|KÎ(ê¿ÄE§êï»ìŒÖøÕ/0ù^q¢q€çŒÑØ9Ú¿Ê“|¯%\¢§¾^˜X>’øQÚ 8I+©™L7 `$, šNè^ŽC;—Lm#ÔÓºpbr`øU0>2””ÉðâEžiäß 0EQöšxu…›,yÃ. M‚qA¡>X_´|éàÁ.`GÒwno,\»ÜÕ\- ]yàTÈ;0ä;°ÄÜSÜvÜ!†óyñBކ ²h•½QäIfÇU£|ûPgz¥RpËá•bšsCp²[ÂBgÝèÜøýÝìh~¡\,/K 8¤ ”@^¬‡¦ç[…Ñ卨íÞ£Žü[YZ¿å—Ë%ý/ü«”KËÿ(WV–_–V^.—!½¼\ª,ÿÃø®É)©¿ßÉ¿çÒëoZ {ñ, ’{êV¸#“ƒôŸ} )–9x¥%#û*•"[uÔ±ÂC›o|Òˆh|J¥Úè¥d3+¼´!5oìãtk_Žšp2¼Úû%Gá6v[û°Áépøq„—áÀÚU«B; Ž3dÏ[F‡i0OËEtÞ2v¯tRîŠ)²WÌä<ÇÙtíuý¨?é¼ñ2‡¡Eßuþ°{ÙÒe¹²¸”£wèä(Š•åWÓ̲¢CŽë?ÆÐ9 8YǺÀÞü¯|Oëm…ýÀïŒ:ƒËœVÔtü Ë“3Íh©r©”7>)<\ß«xÅÌkX ;<´?_¬W®0ˆØÀÇlŽØSÞchÄ;€Û*j]ÍðyqcŽ<„×x·ÚÿÍÖšV§uP¯7Z­<$ŠÏ"|QIžê-ú@©ñådâÖZ­F³ÝÙmdE-y¬4®k¢Y…3?šbü %q½¹¼ÒÇa%¹(T¨¹ð ~¨ ôPè‘ÝmænBV°Eùër”ܽÊÌý«˜TIZ+æ-ºX úXÑ:Y™¹—‹ÜËÊMÝ\œ½›Ç“Ý<Žéæñ-º¹tsQëæ¢ÞM½u¡–sׄôwO±k³<=¯§SÁÆ!ükB˜÷$ƒâ¯I õv•EFdÈ=ôÄ`z£éýËÐÊI4Tnƒ‡¿5Õs”ä·ITÝ…âî˜}ÔØ·zDwËLvW=+#õËÃïâRÞ0  ˆ"ýGHI¡³@½+ø[«Áÿ íºxhnˆBH… ¥É\ÿk⡎^wm×m tN+ ¿en‡3’àú‰9˜0Íf$KIË2¹ž=ºšž+PL“Ùà‹¤ð²ØË¼‘±2ðs‰?&þ ðgˆ?ý •™ᵋi®ÈTjFY4ƒb´ßµc;Ûí£FÛÖ®lY;^þ"-k6©q77Œ“á—¦Ö¿<ÚíípùE.ïÑlä¤MHîÂq†3Ùιٷ{A¶ëûpì×µ ø»–=²Èo»B+O+ôi…>ø ņ g³½¿ÌRY|Z*OKå›ÝÌÊ1›€ùµ¶½¥æ’¾©ýe–åÒÓ²üÞ—%NçæÁn½Önl|Çó’¦# µÿ•ÅM2Ïqúï iúj‚ªY'iŠ&þ®«VzQŒŠZù"j–x 4¶¦/0ïãÅJXy§Y±Š÷]'=ëÄØØj¡úF*DrðŠ›Gl*Jn®¿6Y¿êX,B£øÛÝÛ¨µk÷@ß}Zo%¶þ9j㜈)Ô¾æ_¼ß¸|³óìq(f \~<ÑÞèí!–Þ½§Î +ïNTQö½-c_ÜÑÜAý·,¶¥ƒQÉÔY¥‡ŸõfRÒ?ä5 ÕøÝÆ­/#²Ž…©x¸ži÷­õûnwÓ´ûO°š+uÔ˜œ-‹8[ÒÝP§oÜGÃÙï°?2€/²—Ó±‘aÛ¼hàïÏð°ˆOÁR©#YÁ¹ègÅônY#5A³¶=1é%5ÙiìÜ‘˜?ÿ mPë%uÍœHud"kú;èi}Eý/þÝKlºþWye¹T&ý¯¥riùåòé½\|Òÿú[êÕ`¶M×{xü g|21§Æ20¡;ÐÉŸ”Hlò·ó{¸@ª6ù»4ù{§ ]ø ]Ù<³ 1Oú–ƒqðVF£¾a;'îáò{üŽ›L×;XlyFDüM»ÅMX™ø÷Ûž§¦ÁVCMйsçôH2îÏÔ¥Òû"t/zýLƒ'¿ÛÃDC±ÓZéŒþó#|˜,T¹©ÐÒû$mìJ.ºñB4|ŸÒ}ÜFßB¶†3ʪìAýéOmâf ò÷dùk‡ï)Œ"<”Ê¥r•*¥ŠøY,-ŠŸ¥Òý¼¿†YïûE¨>Ëø îÜÅ´‘õ3#«Ú2G¤ÒîŽÉ)йMÆdoÄ–Gã‘f Š2>9ƒJ_s)ôGçÐõ,„ŒxØo”–%ð×Ë·a¯%=ŒãnŸ(â_"Ââ­£>^ܨX`¾Qƒ˜T •\þKÒÌÐäÖ¨¦–úõ¨)g¥F0—¿I‚9æû5çÏLô|×ÝÜ|e‚þ…We‚pUf"~-ÂUŠŸUQjÀ+ª†fŠìP]­™+&Š.¶ËJ¬8ꯨ™–ÄԋçóÚÃs'ú-óÃ-쇸ë›åÊåQ¦ü,s~’'¸ÓÕŒ$Á_î:0 úw½üZd&åxOŒ‡¹e¼%º¿ƒ9þhÿÍsÑñ%úÙD7ÞRÆo¬;— W‚ô“\–c6׿ÆR˜IßóFvß{ìïoXÿ‚Ã{;\wºŸ¿YÅëøÛ“Ó)ã;}„¿Nc§«¯gcÔoÒ1øFå‘·»ïHÞ™ýOPøñ±´¾ —¨L_Ú´’þ6º3Üÿ;& è> 7ÜÿW*/_þ£¼Ë‹K/+Ëxÿ¿¸X~ºÿÿ[ÞÿïâlûÚ 4å“7nã]X9- *¸™µö¡DÚ·¼s»ká£gZ—C~¢Ñô­€ åÚûY¥mC%hDEkE%}wï„F©‹F/·ö ˜¦@&,ሿFît¨óÚ•P6Û=3½ùe.¼¢°QV_¯ä’"ÏDY5ÀÉE9KLIžÓ‹Rô>qÑR((¼r½žÅD%øŒA´Ð½=´~†ÁD÷ ¢à¿œõVد܀þÊô²Óà†ÂÓ‡àÆÂɃP–¨Hí{hb¹™3ÑÅŒœò×3‘Ú¯,¿ÿVÈí4yûm(Û—’£ßž8ÞIà§Ê=s­ wÝ Y(7U“Íbî ú‹O¦ÇÀÏw!X~f%‰´ßA:ü©äæÞ´}e¬<²Œe3^ò΂+¶Q &”Â|»yÐÈ"˜5#DÐp$"f0¼DÛu[g°jŸLÛ¿ ÓöÊ¢fÚ¾[Ûo7¿Ÿ²mâ@©œè@IŽ Ìd æáªÂ.˨—¸Ë+ä²~Þ8ÄðÀvŒ²óÛ°ÌîYŽÜë0ü {ôl+öë_ <É[î&o¹å¡ä‹ÿÝ~ÿ{Iß¿ ùÿ=¥ÿ7ú_Zz¹4aÿ÷äÿýo*ÿßHÿiSÅËËó¥Ã¥÷È8²;àèw‘~—J´ß>öÖµ²T\ú±¸X)–WжS 5rÓšr›º‹íó2ŸI]Œ½¦Fo)yŸr<Ãvz}ÛûX¼¼ÅÝ“,¿ÌÚfgk·ÑÎóumîQÍ7N5Ó •¦ 7`D`\`tVncœq=ÃlÖlÀþ:Z)kLB–dêûáϳ¯•Ÿ–Ê_d©¤îQ6'}቉dTáø¸owµÉ%O$Ѽٮ‹ñµŽ¾ Þ0O’Ñ¨Ö 9¨<éªú æ’TгŸ®§S6'@3·œ8ç~³Y­¼z\^ËéÒrÍh8!°Å÷JÔŠŽ(%ò–Zh/?+À¹‡üšÇV_?Ì"2X¶$ÊI©}Ýûg[xœÍ¾ÀV’ÀH|¢YlAñ„çyËé‘7pæØ:µ=¾‹Âž5{Žº8ž~u⿱œ˜Àª+Ãx²yºyKS§Ó¹’õïʘ0¦ßtÕË[ñ¸å‡VyH`‹ lé!-?$°•‡öò!ýøÀ~zâ'8Ä{fjêºâïG ——#;¨j<:ScáL¯àMWÚñËÅûÂ8>.:~¥xÿ¦,&ÁP£¬ëP¸í¦òSÞøà c ½ñƒd¢ñ“p*×35fq*Åë§eÿW‘¡èJjORÁõÔçð—ÒNûÚŒþÍJH3 Ü£™yÿôÓLµß]‡æ+Ó¡Ç2I¾Õ¨ÝÁ|FøßñÊø&Fæ;4ÿÆÔìX»Û¦óÔþ¾u ?(&¿sê)Šƒw0P¾ ªo2ÂL@;jšÕMÓÝE¬«OCáÏâ¼~?ªCÖrÿz²û'i’€ôÍÕ§è§=šùù×dÄ"îîg_axñ´Âž® ž® þÂW÷¡—+wÔç³-y 9#MÍ81Ð6åŸÒ…ȶìK²ÖëŠòSÄŒüyR¨‹4øïv$Fÿ5>{ãÁð~J¿3ëÿ–ÊKKeòÿ±²TZZZ^üG©\yY.=éÿ~Qýߟý+­lüâ™®Ô{ÒuF}N"ÛßÎN«ÞùµÑL=G‚!2Ù.å°ú¾J;6P;þÆ6¯Ïµ2S4ˆ“ô'4‹SþÈÙ]ãܵ{Fë̽شû–P#Û|ã…"¤q'=XýîÐr²ò[ÞØë47öv·'"2ýl”rº’W×ò<äÚÒH6áH:r Š‘Icª„E98‰JAÇûºZs|ám`ìøö© ±É¯P½ ©ÝÌ\œ\# ›%ÊmON,ï°\ª,½_(}~{Г¼È¤0¿æ4‚K'Ø5ìð1úÈd;¤"˜zÊ`*ÿ5~Púcª]tT˜`γí õ6 (ÁRŒíQÚv y?ÚíLï´›£ Ïç‡ï3±Û!å^5~ø¶9?Y­ªÉB lû½j¹P_+Q{þ~ö'ã?ÿìžYÝEÿìÁHãËåå$ú/ú¿Xy¢ÿ_ˆþÿsáØvü3 ÛutctfÂë÷Q*±XŽMß2pN`¤®ë ǾA¼¡ D`ÑÅlªH–C˜SdŽG óZ2QGùàç'ó«ï"þÛ}Áéüßâb¹µÿZZª¼|ZÿÏøo_=øÛÇ¢±&ÀÀy•ÑÊüS%¿˜_Ê/ߤsôäúàÛp} ûC®jߎÛYù£¸=XJv{P™ðN»œ—ž © [вª;ú¢}ˆØX+»¿{œ@DC©ÃZßÕ¢,  «g#×éS|",]ZŽe×#‘˜‘UÔ«‹KÅe M5øjù¾:u½È†¶–r_3Ò hêãÂúòè>Q¯¦M¡/=¦ÛÁ3¦šf sËî°T­ä&÷»ÃÊû»íy‡‹ï`ß;\ª®äfØýWª?æfÙ¬–K¹·ÂÃr©Z®äzKdЕj¥”KÜ…÷¥|e)Ákeé}< *ËÕ kÊÆyXyY­ü”{˜ ”þT]|yC/_V—ÊÑ^,•z±T©.-å¦n³‡KKÕ¥•ÜÌÛíáÒJu=iÛ=\.U—a˜gÝ~¹L%¿¼õ)t—­vJЧ-aAÚl UÅØE-¬L;žYˆh²´TO>\.ãEtùÇÒÌrQÔ8œz·;ù„=¬ad ì^A׈¾MÛCHeåñhÞݹyK•jÞõ§¸¯)ñ‘Ã)iPq#mšE4KNlÔL@Ð ù¾ï a)BüîÓwM¡5_žÍ–º2ÊÌÙS¡,Îei:”¥§-û6[vå§âO/‹°¾`ã¾Õ®ÍW†í°ŒÇ]Öz˜£®0ÂÉøÅH0™Ò-6÷8‘†B\%ÖEw¸>Ö7„7TE0ã>›IÉ!+­~[¢ÞÛíõ38_=îvÐ-ûn×ì#Æo³DÊ­”–~äS\EKŸN%Îâ-á,&ÀYš Q•PÞÆ§óô¿6žØêꎧj±•—+/áRº™F‹¨–1@njùr39Oý!¨eifpOg«Ûê‹ô¿;¬äœºïáJÆ÷é$­mÓ}{Lì˜ÍȪ»?ÀÊC\|h€K×w<¬Üæ0A¿Ú—£i€?¥GÖå¶ø®ëõÒ÷'?N¿w¢±4 wW¾#íC™Â$–g‡²˜ ¥2;”¥d(‹Ó ,Ƒ¸ÏåéŸ+Ó?/>ˆë+Gà»Ò¶}Š¿²¼žîžèÑ.0ߟÑCªžaÅ'{¡¸ýEØ— ÖgÞÏËÊ7ƒçŒmg&‡OÜua¦+Å—¢¶ÜÕò>1û¾õ™¼¡Ž‘U“œš¯Íž4½AOØ!L`B0éuHûÈóþ3,Ò7Ç%SŠG iæþ"èÁWå÷êêË3 ÷u;uVâ 8úfù€û|K™æÎ(£Óqú¥›9Eÿ÷z†#À×Ã7‹\8F¼0¡Ù3]9ü/ßõ0qï½·>Y$¸Øx4D_d› \Íàúë)ßßÑþÍt‹_ÆÿÇb©²‚ößåòJ©²\yIþ?–ÊOöŸ_âßÂ|ʘ7ÞXŽå™}£çÙç–‡W®&¯  …ƒéô }ÛaËm ©aÑ*æ lS# [—–×µ}‹®hûöñ&ç ì] ] ÀzÌ/„lGot5¢rŽz·ˆž•DÓP*¨y)ùmkw±r6¢9(™æž c_?µ“þÚ°·€ðÙ2M4£GÂN8áˆ#Zô}pðïtj›Ûí½½ýÔ¼±ub\å4ŽÇv_ªØžô ݾéœNL$ÜcÀë]›·´œ™²¿4û̓ÿügk÷M–©»¡U“nšÌý¾±Ê<ew,‚dÀo¸N÷Ƴòág£œS¸Äú#°&g’B‘“É Õ­b5¸ÕnoÿºÃ“y¤=Ç"\ §.a¼Ï³5bØÈwJdt×0ûžÛµ|Ÿ~°˜ÀŒÜñ•·”`4ó3µ"æqïœ7vÌ€N0¼’îˆ3ñ]v£`2> ¡n,¾é’Ð Š ¿)Ù‹3‹†„Þ\X'°ø|ãÂ÷{Æ© Ýv×êåŠTp!u3M°­^GðEÙÈ×Ü×s7\ ¬Awx•ÕŠ…»äL ­d¥ßú7~'¸o1æu÷-膿aøù²ï>¤ë¡<âÄLÄÀI˜>Üä˜ÇÍ")qrÊ •øáÍû—«D«VrHÌNw)u,$}ÊD Io;açBTÉ(Øè[iy€ÿ CÿãgŽœtÞy«‘]qF¶3¶dÊuzAÏû®¯%\Çx½yâ‹þÆü_©Ú6l8~qt9úüßË•—ÀÿU–Êp\^Dÿ‹K•Êÿ÷%þùÖ([ß©ýÒèÔß½ë´ÚµÝZsÃ(Ã>ÿ©ÓlüïÁV³±a´›h®Æ»vc·µµ·Û26kÛ-øž²ó¸ouÁ›§V²A*ð½Ц0©}†[¯ÉÏ.<2ÂmrDœh‰± È •´<4í’o‘> S¨|U߬w6¶šÆÜ'žÚÖÞA³ÞÀ´ë\ e¢H–(p[»íFs³V‡&sÝ`~‡@:;Äø2ƒŸTÆx[û°·»¹õ¦óv­¬`V³Ã:®g[É0æ>é¸V0€ùþ(=½ø~sïßx–G½ÌkBæ×=…½7nBàŽÛýH¨z³³Wÿ…ðt:€4Xÿ?KaôІ½½U‡íaî“*s½À…N‰ƒ΢ØíÆæàßâÙÄG¢3§ìl&5YÜŠýƒ×Û[u£õ{«ÝØ ÁJÂ’(×ÜúµÖFÜðm¿m6jí­×­ÎÖîV›±D>iŒŸJ<Óññ–©3:ˆÌ6,›ÞoExKi ²~Ðl6vÛ×[»µæïÜ?=k±‹`Ò¹”è]öv¡°½ŸØ§cÏêà§ldšÐq½ÃyŠg\ȯP‡”Ùz\†YÌMýû„âH^­kñú°Óh¶®§‰ÅnL’†gFxVÓèÅ7žü‹Í}BÆO6~Z%”=¶’dðä§Œ«À¥4k5TlƪzŽ.V¡–ƒý›j¹“€?æíOˆÍeŸ«ÃÇ,vÀPØ®ïíì7æ~nךoíÎæÖv£*?¿"º ­{³½÷è<Œg«a0‹½À™[F³± $áׯäÐ(í‚òKEó—ÎMª Z‡Yàý·½æ/ÀÎ# d{Íßg­Ê&÷ ³½ªõä:•Ø_ö[÷—Ä¡¢¿ÂÅÝ´þb–»õ™+º±Ï˜í•>‘ƒ~O•ÿuIŸ8Xz@Ö(‘ÿ+W*K‹àÿW_/ø²„ò¿åÊòÿ÷Eü¿§$ûÛBs6êÛj¿Ý;hµÝßßjÍfm·ý{»€å­K’øQßF¤o^¬Ê¦ ëÜâºìÁ°oC@p/#Fí4šõ·±özk{«ý;vzs«½Ûhk¾×4jP~¿Öæî`»Ö«¹¿×j@çKûĦ7{X«Kžv§Voî!j½Ï‡¾ìa§¶Ÿå}.È”&¶pvn=÷þiGí ½‡yÑõ4ž/ÞãE6G;‹ûµú/µ7 ƒ[@÷œ>CÏrør­œßçó)¬ë îéáHÍÜ ˜'ÁúAA‘)×–,¦~wÇÆ™ynÁ|$³Sãe¹0OQ(² c ÅcWÆ…ë}ÌÓÌà©gÀ‰ ÇÓ"AP1µub\I€0ù€‘ÀœÅ$,íp6äD“ØëØî÷ ÿ ¶ø å“ë_Sm×è¹°äXÄŒ‡(.êŸ ºãdåIGßø¤–GO9‚>d°ý¨®íœdŠ4bä R*Uf"Ï¿wz3çíÚbþdÅß|.Lù‡¥‰ðßþ®ø»ç2{Ãêf×s±–ããÀ[3LŠEÝf çYQéãéޱ¦s…–uz=€t#+Ș}Nþe¨2ÿŒ¤Î8û€^áP\ÀŒo÷,CÍüb.Kf£±y° ‹g²ó°<ÍA§c페òkÜF2)X}‰Âyç!48—Æ@ ó*ŒâÛ ”,¸+¼uBžõÇæ2Ì’úÆqìÁx —,©}¼yB\ $AåyI½,Šõ8WF:Áû‘-y¿Ža³Ö®mg7\¢˜+ñzãùQµš 劒ºðbèˆnéTeÖYÓBn¿±3‚ð†ÝR;²ì»\Kð32¸#×Ô™%Ó>¼Òñiû8“†ñÏ=µ»¸‰äQæÞ=8œùʰOXüܦ@@Bxe¨¼7L’mÜÄŠiÃ*YÜèðß„BP‡$iîÄ¥Ó½ŒuEÙMˆí)„ÁfÕ%Ýhx†á‚.¢Ññ.†§ÿ´žàRˆ#rÖÛÑ£mv±qúÞ—S£T;x‡s§ñn³þ»™Y„Ý¡ü÷Ø6ì®ÿguGÐZ}O$ð›=²:Ê“…‹ExƒVi ˜Æ¸Þ;ÁÛ1Ï·òÁŽ1û¨X‹ž»zŽæ€ÇÈÁîƒJ6“H :HE\·ìFÐ|»o›Þ•!åHWÐòö™âb°½Ä*‹æY&Fžu‚„FÇ ûÂê÷sr[6!À<öÝ>Ž´x¤s ±g ñF#~FZ B Ffíc‡ÚÂÆm4ÂùุcbÀ §‹1MlÜ9>Â<ÒT7vÆ>¡¦?>ÖDeUy¹C€áRaz(Àr®pcðùÙ?¤ë–à£à³²gÀ’ÁÜDžLä1ÜÿÁ !`{þˆ‡RkíMzç´Æ *«ÑàÉ=žFËÔ«¼Â»J½¿ä€«GØÐ«Ž˜>7Ô3 GVþVÍÉøu¿Ö~+¸Z\— @~ УÕ'ú0}æ½i—3G(1êÅ\à)t‹ö‘ Ö€‡3åľdYÌZ^0'm§ Æš›9³kì‘u0g¦7èãµÆ±Õ5‘¡repm“Ëto#ÎŽžû‘òû8™F¨RFL|„-PkA6pÐrQý£K fDÖ‰*Á]Ýî›D`nV0û„ôHX•–I Lö‚O+L+ =öRÕÇV• Dñ}-s4— êÍ-d>X—CÏHk0ÒFÞEÃæ²Åù£\úŽ sB¶‰kŒÍÜÎV«µµû(U(^×ÒGsŸZoÛÛ×ÐÈA´‡i¹Ý‹R#ô¤8¡é³UÑ•¼V€4v`Æ0aÀ6…zI<¼ãËă%No™’·îQV¢‚4óÄRÐ^ õ}fE½.4Ês2T@å(‰À µ Uˆ(ý€°b'ø=JÓ”N‡†ŽfNM_iVÑÎL ”<­ÔæÜGבUC±%jRâ”@Ï3/Žáp©–o*+R9"Ëç( 1õþ@/pÓgâ7pÏ­žÚ§ùXйLfK£§¥!M±{º¸B惒µƒí63SÏFBí.¦´ùý¡Û‹Læ/ŒáEïCJñYPçÆV˜¯Úöm|gʽüÛœÂ5,ÒÝGÞ …^Pé¹›Oê|±Ád¼iÎáüµúÄ<Úo6`*e+Åå Ï#tØÄksø«Ÿ0çJUéè6¨ªjà‘RH Qœ®Õ¿?Cqjdm¼nµ± ª2™áªã}èìîµåéV+ÿ]9"Ž:¿Ö¶îÜ@ ²šWèÕZÔ±Æn-ó<“"åÅà3&i9R'v*X±âB¤…£MBtïUø/U„kZ|át‚uVmˆ;­7F³¹œù¡6þP œ&Á³½ÜQ˜¼¹‹c:tŸ%1tðÆü®ƒçfç6òž>£úWÅ÷@Nìx!,ߟþË—y4±Ñ™Æ‰uœ20ãg°= £„ ÉHgIŸ³|:nZq{0òõ äÁÆx(.wh7E³ 4~Pò äŽÄ‘&ÏÜ”'X—@´Æ=‚­Y£Èùû2߯<ìyóyÉnˆý“sÂpâžQçX×áí a ‹Î<µ¾OÒ¤àf@Î º-óáL“Ç ™ƒ®× kÔ-Ês„ÔÈsµ¦ÿ‘åbŽ wæb‘Š«o£±ßØÝhìÖ·-"‰ÉYDË¢3Ö&`<º^°P ì‹Ã”åt¯ Їj×PŒ.6‘¨×Óyø}÷ÿì½þw]þ唃}L€&§ßÀ',ùŠa®Ä€¬î™c£Í’Ò÷!ÌÀ°ãqÖÄã*´t¥–âƒxêÿ†rk'3ÒD7¢[HõĹ[≎vúIà‚ØDž¼,JçÕ:‰Æz=·p›,à7º¶×­Žœˆ%ž.¸¶Ñ•3–|JR†t ÉýØÑ¤|8ñD‡gš+<»m×7¡hã&ØOA`eá×?ï´ñR\ù]‘ÑØì$ÅÚÚ­ol4b3 ´µú/ü5,k­×qó3EÝîZz& älëô¼¬‚XQìÝ;Ú4U1˜O3Ù‡e1š‘“Å2§Ýî¢?™8TuV~ 0ëCÇU0CãßÔÿ*ïqÅbê ÿSp犫7Güq½VÛèÀõ_²‡Ú:÷GW}tÒ8 g´ÝÞdÃ~[ªh³Ð”F[›\, ‡ä‘›p2‚£iHçÒž» JÓÌá°L Jê´Ù5>­W‚ARž¶7^YÊøF—íV¶êÁ¶ÃBÚù4áÆ™(ªCtifœ`ܱ¡ ž %<z+Ç5ÒGB›Ø618Ýe+j_Ä@ò Œ:‚ž€:4oaå®9®c±yMdÑIkF:X¬q$æJ Žq˜ñþû|þ({hþ¬þS*üô~þ(—›[8*/ 3ïŸâ‚˜.ÐœÄæFvÆZ¦ùfœ¡`?–:ÈÏéû U~H\^ZP+x|<Ïr»æŒ‚éuÏŽô§\¤tJb¬ k Ë7%Åã=è±êÈIkcIV^rÓ«@¦¨ 2j£ñ× ‰ ì€o}8ž×ø!˜F=×F{ž ‡à¾œTgPuŸöc£€Q§°%ÁŒû Íj>èåyöm9#«/`ˆ;zœV(¾tÇt…F3‘÷ué#f!b(ùZmsŸ€ m¼kÜk•i`;cŸ²¦ .Q|a$µš  %g’SS Í÷øœ(†Ob/¼'Ǧ)ÆXŃm! p¸'¥6>Vj"¿ {Ž‹Û#ïŽAKj'¤ÆŒí™§y`|º€xÛø$ ½”+ÚX \4/oõ3ý¾‚Bsžõíz¼ì᜻¿=‚tÔAç^10Éã>\Î k•€ vPIY5ìÑå•å‹}îY¤S$¥zv kî£H¡½KëïÀ?ï¾4>óßåó³r£îp(¾à‡È¸¨a`FìÔs?âZàYˆl„I“¤M8 \îÍ™é+8ˆ6<]^Y#¼û–nÆki­å¸ãÓ3É@œ7zbgðþÈü¨–Þô ºD ©Ùƒ¡ÙÕ,grâ,ŽÎãèlq¬œAø•I¸o¦Äø‰Î¬©Y~$O)¼A†PWpGkrÙ¡_@gFå•Êby“d®S8qDIz´Á¯ Ћò”â+w(®0w‹‚sŸPvPÀƒÜµQðñ¼Çô~¢ÎL"?8D²ŒÓ6$øHŒð´æîPÈ¥ž- Mlߣ‚&él t¦÷Ñ7²¤>KÄ·ð;^ƒµÁw¤Œ!²Å68)X¾ožZ ­ï¼LÙ: ²jÝÆâRç…`!À¶†‰eB…ýºÙhìïìm4„؉ Û,B€¾#%Lô$…øœ”2fÚëþ ›Ã”MJgÒ³4wI”GASðH(ú±ü1*zF·:1¨³-YR‰³<Ð @©êñ­JDOæmT£§'¡ñRÒíFmƒŒqöÚÑ;2YÎ8ì­PzèôÜÑ54ÔOºŸÜm%ô:ܦ@ZÊMª5ßt»è T—ÂäÐМÀ†µ:°×ìwZí&:@@ÁBG´[ sôX•Õ³pó3|¼QÑPl]bn'RüžíO¯À’BœLabFö@¨ÀÐÕÖŒlO=µò£5ý]n±Èá’,ñ5 °µ]k½]Ëe„ÔÀ•3\ËÀß ÝF•C„ÎÞ¬ÐB ×›x9—-¢Ú™X>’ƒ/ ßHt*/HïÚxʶï 1ðÓßCc 3õúãFUÈ5Ì”‹XÛŸH·×¦"À?|*åN-Dç¨z >.Z:Å$8Ä´Û¤ï'qÀ@`´·-ô;,”Ì‹ø :ñüfó"βRÒåR§W‹šD×zÄ!ìmìUñ>ë' Â'‘ º™•J˜,$ﱿ R3=–>2×!í„qÌËŽž:HrÔ¦^k¡"¸È'KÅÐUÃáüQf+¶œfû%lIzöt$?fæ|a¨x¼òÏìnÞÏç÷“¾yJ˜bi¾qìºÀ{æpˆMZ‚t*‡õèu×JB^oƒâ ¤dŽÔâv6ù¸$dþ؈67!¯ ñ’GøÁÉÚÀC£þv/{H›íàö8’ðÔ22þBµ8?·°ù ªª³pD›ØQ¥·؆Ȼc)ŒcáŒÆPtêCIoܲ²”½\e0+væâÌís—ÄVŽêÂŽ EQU’˜[‡Šo&1‘J ±R)-ý(µ8ʽ *ûò½ ݳù°<Ó÷‘ÜR©Tâ& 1sÆÏÿ× âÄæÚòïòÃŒ!Ñ H¥†¼‹òê$[à6d{èljF X¼óÖêƒÌ‡UªŒ¯aZÇç‚Ñ<Øílï½É²z˜ª"­šÌ—ýXôÐ'1ä½-ØE§d¥ií,ùÙ˜ÃÏYCÇΪÏbÏý+¥äwr‡ž£O€IË(iG1¡³YÛÚ>@¦©¥ôG/ðxqA>”ÃëFúP€Á<%Ò¦¢ÊÜ4aÏj{(ª)xc‡¤ Ö¶\J)3•+ÉÈà *ŽÈ邺ÒD]fNŽfåfdÍþ±ea•W>7¶-€ä­ŒýÁ.ð”´‹q¥¯¡rØ&¿ N&Ó¼.¥á¡#8s`¿ýâàcêXƒ·4Á›Þ}Ó ³àBæ#åmR½‰vB48ÎmScÓ5¦8[¨åÙ”÷¹©XÆ2¼“¶;RØM×™â¾+$ÅÅý>ãœW­¿0±‰x/Ü9³8ì±ðð›¥_Ñw*Nmq,ŸûÃŽº@´†¤$èt(söð¿î°VøÏû6·koZs±špSíB' ˆµµÛj×¶·•Ž4K'Є@Ú×ãÚÒèQÓ•‚QØšËJ3"1´­iP°˜W~Jq˜3~H«H\ºýþXž1ñddщ ]Ø*¦YMZ“bØÏ\½öÌû\‚Hƒ²³‚¼!p¹tÔ„>K¬>êç^iF— <´¯ÐãëØŸäX…wÔ/ü*]“¥iÞã6*ÄNZ˜àaäðàÿÒw˜<€Á¤¡3J÷ê-@R!…·úïoÐî¥ó[0T(y´‰»áˆX[=k½R Ö2ªøʼ”Ü;ÈòªÁÁx© bÿç‚|‰ôÐIÄH9´[Q‘ÖdžMÊcÛ?"6º°`RÁÚ-°Ž «Ì]ˆ7²–öpdÏ¢Ú?/Ý­Ú›Ý=<î»h1c¬¨R!Ù4Œ.Ü‚ ,°ëBÂq tÆçdQº ᪥ƒ\‚¼…d·À{š4ŒÐ&° ÙdžPžøªÙY£ñö# ¼•UÅOt©biÈ‘džVR€%Ý4¿K׬áD~£™2‹oõðØBVhûóÙh4ô« ¤pWNm˜(œÔ2,žöæ¶±HRãèë´Ö©â ÍcÉgkà4ü‰ï75r:%iðïFÑEµµGœæ]¯H&¨-m3ÈM†ˆ-¢{*Ó¬-ïwm:‘˜=:Kˆ î4ü-£ÛL"ë̦¥;ûPwSä!ý «Ò¥ÁPºg®MBÕ’Ç… [¦×¿"²ÌÖ†Å$ÃRì byè¹çÀ.“uSLkøJª²ˆÇê¼!ícBÖ Ar´!ìKl.’lü`”?pa2$!6_C½U;×S§WÍùá}ï£õ$8F.ÿm\2EÄv±×¸ÁÄœØ;h…ºŒŠÿ&5¸#~½B÷gÀ!} @ÿlÌ5ëVÀ“b‹x~»xÎÁäú žÍçDt8 Gw%—Ñ}ɉ,ÿ,“æI6µl|Ñ´œ›¡«›B¢×íÅ¿Ç䊪? íÀ>9»ÆN„ˆQœ0¹§D§e#Lå»°çŽ"nŒVac¯%x1¶º ¦£0)Ž`¾i7w)6¹ŸHV׃=ú¦k¼ëÆkEÍ¢$ô¡ƒÃÄ_Íj¥Ô¤á:߸¢ËŸ Ý£S=•!¤ªç³'¯¾‰¤Mw…“UP™˜¥ÄB’þ+,’3‚?A 1"$'Š°Ô…†ݳݯlŽqoÂ]~º®\Œ¢ZÈSQdçé" m=e[Cözj QS„©ºj7Ì):¸1¿ã;øˆsù‡3°çÚ£jêÙ:í°RS™œ‹òîà•„€1.Šûo÷v¯ªLtÑlË×ÒÏÓ)eA¾ˆzÝÚ`“ê€e'äk€ªÅ=·5*l·—QVèE€…îƒq }# GƼf?ŸGçú¥‰«XÖ«¡(®V€I¼L¶q´æ¸ÄG?‹'Th”`štâ°i¥´«,Îù(@‘Ѱ*õJ…Æý¿ª"tBò!ðJ”)U§ œæõ(€í‡Uò¡ít¨  ŽŒŒc&öe.W€®‹£^JdÖ“y®‹?4ã™×Ȧè|˜c“yiÿ‡‡Vd •[ÄѼÄï|J,žf£u°¶{ŸÈ×!c!­=ÔÖðê†$Í›Rëʺ¤¸Ï,ÇPb2"80¤.j"'^ßž¼Fé³~ËÌî@…°#wÛž¤ÎS~~ SÖ$ ã\y =KØXP¸îÀáûz®’¾F®¸Ú@¹SVžˆOHR*N‘x<1Ù?­øÌáÑŒÔs„‘?™·Ä—<;× µ‰ÂmŽò3(´¡'`2ŠÅDÀlÌy…>£yNöP´b’}uÜwñ}”Žñ}”óí3úŽÖ”@:X –PD)üSqì}H+/Õ…‚íú¸R/,üMë¡66kA‘´Æê9¦¿Õš0Bñ1cø]ÏŽØg³Kz—¨š Q.l‘Ñù´ÕZÖ'¢~©_|Šü0ƒ}áNm÷ÍvC^èO÷Àµ( •ÅEÅv†ôÚy?XêYû# $°³þWùÕê¼'¹§Dtá¦5ƒî×Fr°1'ê4óÝ©s“»þ•pJDzZrG6t'2Fˆúª ñžãj 9ã$ªH£ÃóÄ÷¡•§Ñräß8ÇÃñ‡fŽ…hsCš¬¨-ƒ›«ÒâÞ$’[ÝÍÆ‹³{Ö¹¶ŸTN¨NêYrzoEþó~³Å<ìîµ ¤Çr;ÕwrQŽ¡F- ÷†/ƒP5z@Þ£}V=¶O0tpò8¡~§ª—k?ÆÏ£¶“ƒ)Ûx8tk0›=J'­Yàü†rmvi”¢@+{6 SGx4µšî³; o*Çv ¹¢ƒÖÛìa]%ê®DQB(Ñ=±2àôÑ/LuJYXg‚M ÃÛév;ÝŽ+T)Du(³ÆpÅY•"¸ºì¡8<'•ƒ®ÑÏE‡/d"AcŒí M|¡ˆVp*ë²Åó¦‹wGa_Á<<ä%Ty5F8úºƒ=*¯œìÁ€®«ù£C¤—¬Dm]E\иyáí‘|0Q˜*º~ðàRTNE4̬]‘ ¯°D–Næ”s9Xù¡c"tø`2»4)¸*­B‰èéNŠºg"ÍMk\æÏTSH)¿Xº#½íŽ›Šº[ ¼¬vŽâ+œ‡ä±#øU[w*17žxÄÀco»>KExèòDéb(mf’Š\dsëÝN£Šä0&Ù¸’ƒBPtÆLÙÐ(KØÒ“›.iƒ2 º”îÞ`·q1ê wȵ`¥F$Æò # [€ŒK3EÝ8©‹HÒ¾³#Œ©¼?E&8ÏB&9C` ò#Š·"ða@r½ÎG`Ì¥s¸2 zli^z{û´ôÅÑÕMÔžUô¨³·[×´u%M2ã”9ëõD)÷ßGÎ(ׯÐBKà µ '7‘ ¦¶y®Ä#CÜ RT¿¿ðEß=…ñ edIÃì™CURrô¾Ï-á#Ñ ÅGrz!=Bš~g`Uç¶·v»{œ"m¼z‡ÅF«…jÿ¿³Iêx$Žû†öù±TØ–=¡Æ£¹k´…3'×Oè 2æVëˆÈ| 6¥àÆþŠu• dµL‡ÍgŸ¬dCóY7}ˆaÂ÷,º™Ä4iuâÿÜdŸG°w Gà²ÐÕîÒx+-¬Í„2» ãƒl] I퀃·GhHIZ‰|œ`RkËZL Ô?Yˤ2)P±žM¥žÍ½8Ê}˜£¼ïß ‰CXËF4<¹mÔ²÷¹ÕÕIX"£ŠM©ïÈ8z6½N„´ÝªA8Á .6 ÏÀþ’Q޹Y»„UxCìöÝãcqO'ýYS.Š—¡,‹¹;¨ëQ! ÛlsGÁ<°C¡Ð}JÔ$c‚Aßv>®²ùßû 8– ›º³ôƒ-&¯Aþ©`;e±Yë”V^#x{Œf'‹dXÅѤpJó´#eNr J @‹ü>LÁñnmÄ1ít~͈h ÇrU6)0ÒS.ñp¤˜Ë®.aƒg|èc½= ‚¥)¤¥Ã…€ nÙ'‰&??œO޽ßI1Ô³ç8=»‡ƒ‰Ó¯˜z¦Õ8C…¢é5RÊèß0 нɳÀ#V0ܵɦˆ^`7¶N G$¥]«—W¬’æAñö£ïKeVRÏ$_ÐÁ>ɳSgqUœ7„ ;%8ÿŒµ qöBU¨ôebYÚ0û¶éa25Ò%k¥‹B1ͱ,·€´“Zc ø&hº¡¨Í@ŸE5¥4À4ŒTxeó€!0Ó#UGôo„+OÛØ,^eSâ ÔfÛa5D­Éïs‰£[¡™ ÏŸW3´Ô­?ŒJè¡û`”@Ÿÿä@xÔ„%a ²r=¬6>)ïÔSÚƒŸs©àœ°÷‘€W¥|5BQoñJÍzj'vÉ·°޶yògÿŸ)æ4ub¤ˆÝ,t\#]¡Ñ#ýä5Gý̳s-[:. T_‰<Ñð9Ø€®8ÆñTµHáJ£ ÛI¾š ObâŠ:C»·†DŒq 2丙È@¾JðÜš•ãbäŒ|r àÎýsZÜ.>ê‡wyb´âÚOÍf¤«ÅÎsQéW8|:TÕ‡b<7ÞÒÙOxŠZßžE®£÷·6„³+È`ólU`Búj’FFç`ÂN{xÒ%l~úû0‚šáºØq§Ê;Q¼É† AïÇhiÍìù*[ ¶yi¿ÁÑ Qnô¤ê,¼wè€òFÚqÓØ=k0]‰âc.ª¤>MúïôQÝhT FÍâ¸3œ?ÅtQ˜da,ݪpUðëZ9»Ékç$ôY—ÒÙ3•ÂK&ƒë°w8 ÈëÿS]7²Y¬P›c¨„n´é~½×6~­ÄÚšŽ›ð½,µ9¾‡bI]1VKïù’@²£ÊÅjMªVñ´˜7v]§5r‡Æ^‹6ë]ërÔYÃîR¥&ŽCNãUz¥Âí³s„ -ñŸ~ªüH`ÙB©²ø’È+~_Ó6&¢/)y©È(ßDÚ ô+„À³vDÖçìDs¢@P:<Ì—¨¹ìëZs.ûk.—‚‡’ˆ°eŠS’‚ÉRá™Ëb±Ü„rNæ=y+T&·sIÛà -¦í;äLyzvÔ”ÑE‚s32ÂBFŽ©‘™û5Cì…VÉ'ðÊ0Oâ[Í­w$(²ίküßÔ´ÅÔ¸iœSQ-©ì\\ž(¨øL!ÍP¦<L8¡Ußôü â”rÑ<±åe‹œ°?ÞP¡Y\æF3=©QOx6HÚ%ñÎÓ±¤|lÀ¹$ÝC 4RÎß÷ovr*ðò›FeÐX”Ùr_õŒ…»*Žú}l;&Ƥ×lý,*%œ›Žã^É Öžëû–c’vhðóÂÌA‰Ð2>×À&«ˆóÛΈø+dúàúèáV5‚Ï*Êv AÍW(g®ƒnƒ°†xTôSO`ƒ9|5é¼Åmé H¥aÛ„…Y(ÁyèO,ÀV¼ L¤À€¾{G’ã+27UÙüXL^ÚÅ:Ä€C·m‚ˆQÑç½C«'ÌÉ2ôž Œ:±9hè;Žï;Œ¸ L.‹hEŠÃ'™ÖbÝNº}¥IžlÙž ATUy/C±ò’É)!#oÜ&®Ú%áõ$&¯p^Ä÷2¸5]5§ÌKÚ ‚Yœ•:&âêØÊµë¦HiChnËqKÇͼÓÞÛÛΊ!4 eðP¥c_h„å-&ÝÎZþ9¼±+øi†ÆK¼'Yùû\»‡·‘_kÍ-dÄoП@C{`^©P†bº«• `’¬ËçuœÓÒ4¾h;“Ñ P ;0Ác~!¢W¢7X)ޥ؋ñqßî>*’…õD ÑãK¨v©µª|n=d/pÆA˜Å¥´‰º¿Ç0M‹÷s “téo¦‚N_6÷š;µö5¬©8ÇÙ‡¶ñ°w3 ÚéIóè…WÍȾž¿Ìä ¹¯ÉPæÌмÌ0F[¨@fÆ]Ó¹,2ö?§¬#Mé @ÄÙ¶ù.œ®ÁW®½ ˆÆù,®]£ÌAxÇ&“÷ez[ .3^¼Ðëe°Fuq„á•ohñØ Ú,BZÀù©{†›¼ÂúýãEç¥Kö†:„ŸÃµÆ¨ÓÀ ²µd¹éou>ГèHêw‹·ƒrW©ç†æÿ¨²¤÷#ƒ⯚ÂÖÜ€ê8èœð‡»FýÖùlj:pšû8*×avKŽÉÊ÷KòýËÁ”С·Ûó£óÍ~¤`í@siR‘N €’»³µÌ©3Ƭ¡#ºr£DÈw’Ïèm—bze"ñ¡Ï_* û5½õû Ï”é91}ÒCW8ç%äCáð.ˆÊñ;E³„ÇdvËÞ$Ê?ýø£\'ryÙ¾Ò®&2pb_Z½‚Œî¥Ç¬ƒ­ ©¢a¼ÙÚÀ…°œa®æµS¯R u;_B`ø$ýbÈy€³å‘¡ŒH~\\ZT°”bqùÇsZL¶yÙÛ½µJé§—åå2d­üZ\òt™ç¥¶AþP©9Ù™9lIp¶–ûðä­qÛZOT‚ úËÊU4v.‹N‘{ÙrNbÐÔ@Çʺ;ccT(4³V`ÈwðI^ðH0vd uö1Äþ·ëK38ŒªàdÕâ~îÚ=̳„Ñ“ëèxD~€\…1^mÐ-žPö!Èt*3&eJ¼ÝF“…é{Œ7ÛÊk°4_Åt•1!oþc¬µoÚ†/[&×|¡7LÊHAqÔÇ€82&¨ 1±{od÷NïÔ½ÓH÷NïÞ½i½K蜠3äöéK@y„«Í¬NïÇü@It»Ÿ+ë˜ =7ÞÀ$F[yöÈÊggRá‡OžÊ»­‰Wœ¬DÚsqúË#Ϋ,Êõ(|»pñÀƒtFÐbáR_QÜL°Ôq!È!“©‹;såœú|-#ËRÁPŸÕUxà@dâ°¥´ÉÈ!Q`Lr/€Ä.t ?ZˆÝˆµœ,£¼î¶,‡õ­Œ°Ü‹ÒZ9İ™7¹ ”׋4ù£‰ Tk†ŒŸñ™¹©üÿ-Õ·=Ù QôV%Eû8‹-³ô21Y#-•1ÚCmˆ&2x=Uë*mh ½û11ƒMom€¤2Y£ŸèIIóÌ"*N ª)OÄà‚x’f]§š  À‡†`Š˜ØêÈÂ2Aj–p'=§ N!Ä…‹$wŒä!`"™8 ²´cé?¨Ø¢´~tº&ŽQzFìÙ™ÍÉ0‚¨²ÄOm˜ºC÷ ½Ths QÖÇ?ÇT‰z$ÌŽCR9Iï@t~"W½HV"öLÈçèÊíWá”1<öÂL9œ¸¦v#6¡Ž˜þN¡->lè˸§ù`”¢–ðÙˆ†³‡ÅâÂ`i¸ò­ØAεCÎ,P ±8XГ²üÙr»= ~€0£sº)ù./eèÏ°ÆøZ.OÉ?D/îf/)Gß>FÄ&~IÃ¬Ä þøÔô’?‹&9Ãÿ“Îè9Ë?þÿº8(ù…r±¼\,-àY  ,u2þóÏb÷Þu £ê•¥%ü[~¹\Òÿâ¿ÊÊbùåÅr¥R^\zYYþG©¼ø²Rþ‡ñ]!RtFýýNþ=—N)~†5 çåâÙ«TJ%¦q.ÏÒ©Ô‚ÑpFÞÕÐE¾ÙîzßtN3(Ö8Æyby)ü²½ýëÎ&½¶aí9Ö–3²¨‘HÊ×ö)JQPýÚ˜‡ó½‰ûþ§ò“hå-9£hBc6éÈ‚BEÂö5úKܶa»;CÓó­Î|¶þU`ÉŒ;±?òÆÝÝ#¢ØŒ5c÷`{{5øLPÌ^Ïðüqâ.¿ÇÏØQö!¶f,c‚VÉÕe©sÔæ¼ñÁç ¼PÉܪˆÿŸr eÙÑ$N_Åꆶ­ÈÆ­ˆÖ%¶ þMoÜÊý[blßùÒáÒ{Èñ©t‰RJ—ú]¤ß¥Òu¤•ÑÓHÄoîI–_sy£¶ÙÙÚEsÙ¢Ewl¶ÖÇOBÒ-Àëƒä{ç qÞ€ÇøJUžp­¬*Åg­NÌ—åï‘ú—²ºÁe|m2G¸²Á¥ª £UÑ×HM£Ë‘¬ ãëRy•A²ª Ÿ£Õñ÷(&]SaÒ50éÆNrH0 Ϙ¤ï‘úSÍÆyƒ^¦Œ?k_ÐU/¿Ek–yU%ƒ£´šºN} û?ÐÊn÷¼ÿ—W`³/WV–—Ê¥å—ËK¸ÿ/WJOûÿÝÿÓjØi¿Nq…Œ·µ_¨£Ý®™mjœÁÏþ•¿0À½9†pòè ÄO$£&z8õ¤ëŒúaŽãgh(œ¡|bë6û!˜# *J™,zN‡s¨A}hý$Ð÷“ž^¨»ÂÃÒìÄ|¨”MTA'EþyãÄïðÞÜ«V¹]´Ã ĉ=ý6©O¿ºv¯ín9£MÇ8q vDb¥€ß²›“Ìý¦ÅŽ@‘"åþüÈ舭ãd@‡Q%ZV(P3ÓqST›v!XT\µw¯89¼.t„@f“Š6Å^6—WÀTJ\Ò([MçVçõZt—´~C}úD‰N•ߨž¥J–],Õl:>¸Ó&dKÅ CÇ4*tÜ5H1è¹Ö–ÞÆ5`É…#žAR6~fH¬M[+›ªß )“N&Sq´'7S×&Vt±†h&ÅÉ‘´zÁ„Eõ‘Žix@:£÷ðC ŸS{‡>©ß¯ô {ÑËr–¼!óäŒ5fBã» 74ͳ- GyÑ»[_"­ÃS\樔YU#DØã\Ó†BdäàìÇbvÞ¥yŒktT…[ÈB°ø?T…1™$rjˉÒ7:  ÏÆ–™¶`c7¶"¢s5y¶ê ˜y·¼Õœ R®ÏIDilª‚Ù„rSÑe$lç·G™Öi|Â# -8·é´Åéà_¯išª­š$iè¥Ã x,b$ªøÁ(b­ä(&=zw2€9ÙÝqßô4 :ÎŒÁtÈñZ@Gå ѳ“Pé–°“ llÞ`Q¶Q¿P0c1&Pu>ÂÞòXrlœ º;¤I…lUeɘ§?Šgfþýçã«‘õŠsgƒ2rC ³Â:'ü {¤šj؉s½*‰ÈÈDGË€{d¯d´[¯&f /òÚ-m$ ch÷:#Qj ­y+æÚóÜæ"ô‘¡ÑŸ°"êÛ{»Î¯;Ÿùa·ñÛn+x>h5šÚ[»õ¹µõ¦þv{# œ87ä^(´äú ÿy† ”z–»;•~Mö…Rím`ƒ°ÓhršˆÙ_2í“'ÜX…OQ|ÒCPd ìcmê…š¿€ã¸À´€;ЉÀw _:z(e‘…“PŠD¸¤¼÷‡ØZNVdx¹½N½Ù¨µ?ïu~kîínÿíæÁn¦çÊÒ’B÷Él¸fµ&b²UD¥Ò³lÙ“(ÂqGó ŸeÃâ…@–& i£62'éÀo¦¦ &I0T¨ÍÉvõòd(§ØLè/.< OK%½§?ÏÀµJ@‘œKÏ|®ûmk³ñn C GFÓ•‘jÐçéû3$U}úý«™ê %@böšj5&1‹šë<úÛ蘓bì–$Î*Ü#$¯&^ø€’EÅ€áè/˵xWMÓ®EV– &féåò2e€d¿SŽý³Î‰­Qyé+ÎqŸ…ê¶/ §kT¹¥!üŠõr‚ ÁíkA3€2Erlí ëe ;ÙÌBFœøB$:3«¬äþÕË–òCdgdží5ÐÙ ŸE'o«B5*zwÌÛ)@;öcº|ù¹í¡Q3ŒŽË«¬ÚVp' }ËÊä±;¾…‘¤r¼ ÕÃå§ž}Ä*±Lž• Ô8‰óFÀŠ8üümUç§Žƒ,*KDñ&KåtŽ/iFÿ¿¸)ÍÍXïbü¯lt…y'Ü*OAÙCŠð‘Õ„ÇÐÚÜcíI|U\1óø…&OÿcëÔvÝü ë]¼S®%ªVÒ²WûÐîŽœÕØôð„Æñ€ÒšT­:C7v =뜧=šeÆ‹9í\.¤~$¬ ,Ml¥KN¾€…ð¼õ8@ú!Qy¦ºÄf ÁàŠ'¹5O$"…J¥ž6í“Ô·¤ÿ1pu½ÿ ÐÔûŸreqqeéåÅÊâÊòÊÊJéå?Jå¥dºÿùz÷?ArÏñ À\q-4Ë] #,ZÔ[ιûÑú çjÞ)0‘n­ìÄ,—4è÷·³ŸÝ©Y?3Ç꣢IÞxmúv—IÇäÁ‘5@Öa)]–Hùq%þ!ÌYJ—?.å1ê¹´`ƒ€]hÄF­†»¶;*´ë⡹¡ÃõŒi2×ÄßÚ†x¨ãƒ×]ÛuÉ~%ÜŽ2·£Œµùdªÿ6_ôuÔlú±ý(!Cræzh)4%OOÅ{”™ ý#5/æÌEFû‘VàõÓ\õC¯}ü±‚| «² ‚¥|lïðÒШÅ~êöMàÀ·ve[k„†o¾¥:ê9K0 íöv8ϧ{¤ÎÔ·œÓÑ™ÌÀ+yÑVÌŒ{Zöv;õÚöv–,L½œE¦E³(›¦´®{ŠGUw.ÍïŒ:fŽ¥ÝÅßì~ÿõÕûGʶ¬QÉ *^(p´pr|@zëú "…]¤Ò‚8e‘åñ yYBéHŠiMa¡ÕáL<(“"í¦û|äb6©ñn¿Qoãyº‘Ö˜¨×ˬøäa—O¹|¼Ù±e Tã³éO™pË2ìÖÎò×ß“®<”‹•âbqéý5´ZžqyS‡q:ØØgoŸ¾kà.i0Æ”!:}Fcršq|…Ïh¥éE›Ç#äë´ †ÈÙ¾é¡ ‡þ¶ë~O´±ÛÚtlÏÒy ÿë*6L²²9z5Mq©Q„Þt$YÉ"@äb¿qŽ`a&:²h­ÙŒ)UÆYü ¦(ÌO˜ÉË×Ì¢>øìÔfæ ì:WBKE ¥r_´X—&ºŒº-^ÂÅ1°‚nfDÌ´ºgÂL%iÍ–~Ñ–©K5Uf«IëêÍUUâ«Z|øN-ÎBŠÊ-šüZ™úuñ:VfBV(YùΤŒYqY²r18DÆÕ\áš+AÍ•)5kãw3­ÜPõ"W½T½ø@^Œ!à#×h×÷åÝI—gShrÛ;ìð¡i¼«š<âVO!õžDŒèaÔ½'±ž ‚îGÑ÷c¤æ/¾)LÐ>1Œ÷Ùöà`žDùÊg-à~ÌÅS•¿+{ƒ‚[X $Ö†UÐéw¤âSiUÿÚrq¾Õ]@GWu6+4uñS¯Mò”™æ¼ÕaS÷ó(ø—ŠjSõzâ+%Áô‰XØüNlÖ…DXlÞ@¢-ÝI‡ð 6ª:&ƒ1o`{¤véÀÀ$ÏbRÞ()Ï21sBÃTXšUJ%;óäcËò™—Üþ鞊b-…WâLì[N¯ÃŠÊÒòi¹¼´:™Ñ³º¸“ò YJ®CÏ>7GV5âÆD¶•†ƒý h(4;€¯¥@Yÿ‹joŒ*u¤ï»p†ïØÃ%mÑ•._n²'! O“$›X9,¯§?!%¨›~c§Ê­`”¯Wã½¢5š˜‹ÉÖ³Îu‚BÓ|Pý¾ä†­xó÷ÔK–¶ô~³ožú²ú•È~\S²dʆ¾ô6Õæš|VëÁ;_ap%w¦ñL šØàßûÛ`vìºÑ™;ë ϸa›ÜxHÙœÑØ±en ÿ‘-!øw!óø”ï{àN¥|ãÆHÒX󌧑–çVÜyœ¿yaÄÓ8ó8O•(hN@ü=÷–ˆY7,·›DÀá”yWÂHŠÎ9¤çbnPdúiê“q[Á“:åIc›Oš”wÓ¤L¼„·0˜ ú&L;WY†‹ÇYg¿#¥t³ÎJ†>9ùo"¹qåf¥¸¢OÑUæ¸|¨ànóó£õ[€w½Ó[v<¶àì=—6òá®_ø3Û£®Ëçûn¶ äÔ=¿ ¹Ñ ¡ÅÙÝd ÉUߌ"Ùý{ɾ1â¡ðq;‘º‰²ú»×u¤®Þ?Ø>Ú.Pdš­BˆÄà^ x´Æø7HqfÙŦSÄé›&8³ôû¢3¥ã zƒî£Ø' Îe,Qt"졉#¶0¼cÀ¬‡5ã±ÝêŒøN°½dŸ>uvÅ Ãd‰ÿÝÚÐ •+‹¹[T¡ˆâmê(”sODt6ì5 ㉠û›3aŽ«h¢x|´ŽÇÑ›Çf¬DŸb¶‚cŒ›Í;>Þs#¸ù¿“y7Öû÷"ŠI w]TÑmŸYNkÜÅÖvP£ ô²Š9…Mš×uO¼“–~ãñˆCï9®Q£ ÇF¾ aý‹Óϧ³êÓYõïÁf´…Ÿ~뉼<‘—;raß!³å¸’×⧇cµ‡câV~Säí6:˜³%Thx"GOäè‰=Îy÷‰N݇NÕú}·‹$j,™&NŸè#`FåÍ–uíVÌ®÷}_ÿ‡‡æÞEFy·c;÷²òx4,̵>†r¾¢ÛÆüÂíÑ±ÓØ¹ 6ÞÚ§g»=wsiú&³Y<.v‹ø¿[LêøR·ŸÜ‘c˜ÚXäó}H“ÖÆ);EÂq,©ðÝŽe³5e¦ã™Úµ’WM™³ÙWlj„p«³,n:Öñ¤h»-Ê *þ&ZQºÙÚ7þ·ù;º³ÝÝk4›{M㫟2±HÏ[»Fí:,]›ž]›®-—+†8.Âi1T~¶“ã£"Úlš»õëJŒ–ЊPËY¹ÏÜóµÿ¦LzøŠó~ÒÓã´8rðïSé²BÎ\+å»CÜÞ.‚}Æ.ΰön@ÅLêt+w߈']AÀh7ê_C4gÑQô¹°µ¾b\ÀaÁ8fŠƒFžÃFk÷)0MHrƒGÄJ¹R®¢ÉÌ”ŸÅÒâ-Ä,“‹eé‹/–/6µ"½Z½Zzè^ݰéŹy½Õ>wo¯K…v«¥sk äÄÒàsÿ7³—ÔqhæSÚêûSÿ’kìi•Üa•Ä-û¬ š„+µ¥§Uñ½î<·r0þ´¦n¿óÜ^Ç»q9ìÛ]{´µÏËêÈ•Î&œJF 1³[ƒÕ³1² [2>äùs*bE'©JÖ5»R$Ö²ÿ$WwhøÙ·`ÕIÄb@NMTö ÄÄc®Gób9ÿ0àz(¨TÈT˜ä rÉ·§t¡ Ê¡|'_–K¤’í‘“Vœæ5Ña²Ðä«Ë‹ÅR±´PY^.âðŒ:¤KÕêòÊËÓÒv9v Üž ß4¿#ù’œL;’¨Ç- 3a§¼T,/Ôª+‹ÅÊ`)o$8Ü=Æáâh”W`"– jøoþ[Zù{†@yd ´!ŠŒóyüKñ:ÙŠÿ…HÒ-ùCÖûhþ Óÿ(ÝN`óÜ’õi£ÔóB@ËMÐõ¬¬ç…îÁ¦ÙÞÞjµsÆÚZLªÚez@X<÷JÕ,뛑À¯|9ÿhRÐ2É?Ë_T Êñ³*×OrÝ»BÙô þU«H%©Ô6®ôÃÓÇ•ïh·BÔÜ û­àTMGæHúŽRc}·›¾«!üêÂïñ™Ë1ã3ãÈÆÏûENFO6-O†ÅOÊÚemÔôƒb˜Æ¹ kmt…Žî{6ºÙC×êÀqbdhW’)˜AÓéQDGÛ0òü‡Ê€îÐòØ[¾eûg Ï߸€ƒÏò†ë>ÚUX=Ÿ ÓG,l]­.…$Ÿ9R7r³ë·ýâR¬_ÿs¼WÅ)’¼ %Ê«ø÷ç5ß~øAúÅ Í HPâEV…‚£ü^PÜ:Æ,Gl)R5²íÜ,[ÃT%«Ûí…Wú†À±â9]ˆJ.øý R|òîÞ? ¯´ äAôä)ä Í kšXÆs |bÛ²–iñTxò@Q8= í‘E0˜9ÌÛ0´‰`*2j½ˆ.$hý+CDhŠ‘ yA^nÕäÖæœ{ü0UÅÆ+p ý>¬ ¾ÝÙgt°N®Œ¡0Ô½p½€QXU>Þ¢¼A®9©IBã)_`>:ã~8òžlß{IÁH?Ò9ø‘‚pÄxø<=¢kK¢›ñ¯e{äÈ W•=tÆø¦C $ ¢$³#{`¹ã‘ÿMú˜©›€è¾’6ßùâNx%]jAx}ß.2Jm·ÞØÞŽõy¥ç.ÅŽÈì¸yc°+¯¯j€ì)ˆr*Ûéà¨ÐÐPgáoÑç´5ãlÔ( KòGþµu˘Y—9á»’jáKî{Âó=É3Ç6Œ„w#æÝgÏ1˜å•±´ócAßÌŠ_rD'µüjŒ¾—è7¶ÕšÛ…n0+P;öÝþøËÒª[s#7ß𵮜î™ç:îØÁè ¤yPooíí~ œÂº„³Éù½pú·Å#±ãÛ§°áÐ#Ï8í9Lö——¤³ó‰ ý^Ïè/²'ÐÕÆ$åþ¢CòÜ>qzÖ‰ñÛÖîb%q€°Ç5ä‘&îB¾G®ý±]œj|uÛ 7á*9ÌlúÈ9ržP …-°œ‘Õƒá8r0%\õ‘òá†sþ«Ù[$ÃèXÎy6ýv¯Õ®moÕZ4PÀ.ž@EDMþJòͦ«©¼cû>²‘ýЖ>Ó¥¬S¦õý-{î+àXôÜf.?èTþ‹ÌdÍnç!4­£‡æi2Ï:™oœ‰éc÷tì]œŠé§YxÓ,YLªe/æ—òËq÷XóÌ6ùÃÒû &ì& íð}“©T7¶Út™tÊÔ]~°ºËAÝÁ¤˜VuåÁª®UÓàZÃ’²·XÂŽX‹î÷>à< 'ž;0¨Ýù²H›qÀk³ Ø£ÌÓŒÈýÍãU™2^‚³ÇëQ6Ûx=Ê42^Á &–ø†wúi'ÚÉŸvòïq'Gå­¸ý¡4ex¶/8l±ûùÓ¨}³£»úÖn«]ÛmoÁÖס¾^k5`›Ç›dË÷Éß‚mÁþ:!¹ÔD`$\ô·œ,^­žˆ¢ì*dñv»Ê¢J7³ÖwûšÚõ/US$tùc£0)„æc×;@ñ+l{°³]o´ƒYóF,7úˆõ%ð¿w¨ñšh&JHý¡Ùµ Ì8‘ˆ0Rÿxú§þu ˆ’B¹X^.–g dåpZ<+ÚÎÃÔÖO+KKø·ür¹¤ÿÅK•JéåÅŕŗ¥¥¥Òò?JåÊÊË•ß"EgÔßïäß¼¡wÑ0ÞXš³X=f/øãسŠf×8¾2ÌñÈ=³ÌžåAÞù…T ô¬Û±Ð~´/ÝÁÐî[hñ2Ä…îǦowú?”ˆåŒÌK,ù|Lš>ok¿6:õwïÊe‚µÁ°F®QF€Wî˜}l#äŸ{ý“®S<{ep ¼Ÿ*FamloÖw;oo†æÑÕÐòo¸µÛnÿ¾Û`²åÐMw;{ÍßgçX£ÞñMàví×3Bƒ£…Qw8L¼FêÀf†¬Ýßkm½ÐxÕê}ûØ3Iõm¥4àþôýöÛf£¶Apß$Nèì7·öáoÍ­vR©P¦›;íz0Ò7õ·ÕÞ€qž‰z:¼í­×³Á£‹µ›6·vß´f‡8À™à]ù xI|#Äß[µÖžæL«μüÆŽ ÃsȃÝ-ï·3‹ŒöÆÀ쌂öñ9¡Õhvvk;Ö~­ÞÁ9h·fÓnE ½ÃþøããBÏöHþÊ §g¸ÊFxŸíCÀ‡;06}4+S Pïñv»³÷úß[Íø&s›òñøõ&‰d£1áèÌö èÅGóšræŽû=㘢0Žô  í¿ÔÞ4:¯Þ4û{ÍvLEèrœƒ&¸'!¸q€#Sa yÁsš\Î'z Dt^î_ Ž›gÐí™[Ø®5yæ„!",ŠÁ88Íí·èÚ¯fkko7ıðrß„)#zg HdYj:#œì05 Çu ˜Ð3½žè<ú£ÂEÛ÷•?²¡Zý­Ã/°õÿÞÛÚ­½Þnܸ,k»­-£ž¸#ÀZ¬wÞ`èÌoþõùJÀ§‚íØ£b·û¸üÿ20þËÈÿ/¿\ZYY*C¾òRi¥ôÄÿ‰Ïm§Û÷,#­†½x–&“.ÞN® œ¶Ù·ÿd#w­¼úW@eÈ éÜ…íôÜ `ôÇv¿ç£ Ãÿ\œXDרèìîínínµ éë®o[µí­ÿ46RÏÑ»ç eÄ5–RD ŸîO©° è²-»ÍýÙ‚îä×x&᫵àr+ZŸ¸)ˆè(DX½l.wã›^Œ¿#Gˆp;µíí[×úÜí[¦3f#oÙ™ë8,8Ò?A+¹7ƾTË7¶Z¸7mt¶2P'%>橽·±W5†n߆IrÒ7O‘Q;£Î8na“׋Q¢|]ÛøßƒFó÷™†õä*¹ûu4{±(Ø…Éoõ¾Û9þ-¯­or±IrbL‰ŽüÑÈ6ÆÂ?„ü«YÝP~!Ê…f·‘Uª´òûj‚ÑÚ,³¿³)ñÁ2ä=V4˜ÀÈT)0C‘)…p.²¹]{ƒÁ_ëÆg-e¿¹µSkþ.ʈϚ?@ÌÓR…õ€¬ÏT¦½µÓØ;hïhåHÌ¥‹4·AvC&Aö¥¤ì»{í û¸7ìà1J,'9ØØïài/hSw†R(N •ò]Tfè ŽÎñðtÐØ”¡´öê¿tZ»¯6£€à°lÙçÖ-a5ë¿ê°¬žãý?ÑNåÇÄaÁk™ýÖ,‹ëBm\ Y*-q0Ÿç–l¸ð¼4ö gç•£ƒÄ»ØI¯åR¥´XZšÌ]ŽËMyK˹Dä4šxÄÔ'‡CÔ»¤eÉ,v>Ò3ù]õŒsi=9 Gú݃urZ8™µ“µÊ;Ñ™½ÚÖnЙ¾ë~} Îqráí½½_ö[IŸYÛIÒâöÏQvÞš£3­ŠkÔ]àÏEüž\#üÝÛþµ¾·»˜òÞ ªW¢¼ÒöŠSöŠ'Ï -©Ü¢)ˆÙ‚J›'çJ,u®ÜYÓ­"ú^ TÝ*s°]wd±$Ç¡ƒ%jCÁ·F#’ãØtØ ïY«xZ䲂x %¢HŸ¶å]ºÖ S.:(ØbòÜe~‰p ú¾!ó‰×Øœ]#‹|ø—‹6™‹^ârÉ}Af”ï±õvÃyå{$oYU*è”04o{c§K·PÇW“›ëdu4QÂøÐ}¢*è=’W³ƒÉFèV.oD¿VôϳB*O‡T¾’ j±`ä·›`DÈW,¬hžI‡šžÓ>Wf`ý"*ɬŸàù"®0ã×Ïy•å°×¼YáÅg&[^RcØbÎA*_”[žòìÆž…^ÕÈÃ&ö Ë9·=×Á3+¹lë¹Nf$ü ¿ƒÅÀC^W9ÅãOO¼`Ärã†qm PFåO#éhn&v<24Γߚÿ¾ù~b½ŸXï'Öû‰õާî ;ÈwÛ@&wŠ›9÷ÕÇ õ‰‚º¹Õ›wƒÄðZ¸%ãã ž``£­õz°i,C.~¼T6 éF¶–swì“[òøWjÃ]ÿ<«Ú)ƒå‘N ñ¥ji¹´R-½,ýX-ýT.UËår¥Z^,/UËË啼°‰NÏ ÌŒsêÔhèf;¿%Ìçò'tB€£©§AÝ7nò¼­hù®§ž“NŽ ]] ÷T‹A‚GÆP¿’»¥«äiøˆ;¬ÆžUuÁ„Þ1¯„uݻ묣un9†y2¦R«OÄŸ2ÐJ©˜Š®å8îüúv ¾FXBÄʬëÉ¥¦ ¯;0@“ì#mÀ¿Z‹ªU“·Ï;<ñ,ëÅ<‹*äš-å»IßC“)Yøž´L‘±Çøf‹ŒgÃ9Æq†–K?*çålz{¯^Ûf>ÝÝ ¾JÑFNÎ:oMç•lZlÕ[{»äG.õž…ZLÄtWÉéþeGøj:~µ’ÎÝåÚâvs[àbÆ#èWFE½/}áp„™ðß>íì9•uQ1õº‘£ªT"C(\6E¢kŒ„Y†åk£ˆ›. IÇ.i´‘“ú¯%E»•ÃòŠôã ~—éw…~_ ’©„A?Ñw“~é·K¿=úµè÷„â,ñz¢Ñ+Z£©¹˜l=ë\w8ÓWéЬO@YKð#›ì¨Þ%î0,µv-ŽQÔ)ˆÖx7F›}yõçŸWƪѿøø`§•Åtî6høÕôlÓù3\Ê&ÆUº?$G¸jÜ“»äÀ„?Ëø¿{ù©r •ÊÒCYÖ€Ì<°Ÿ@Ižq¾9^$F(Ta"–JF0ƒt®™·vÜÙZìî(—aý¡Hâjz3oîM×½’vÙ€ ‹&±yÈÞn6ÃF3Å"RŸ5»|ØÆúW(%eæc»os$Ôkõ\—ô\9ôDø,¤Ãº¯uGgŒ^ mÛ_j ÛÅTJT¢ôß„²¬)Æv`˜¬çà ½¡’@Kƒ*bÖ¡ÙŽ14½‘Ý÷Msö,`ƶcUñ³Q€S(Fpª²Ö7=RvÙ¡*-9#iìÊók(ËWª¨ØMJéˆ4]då[ G³±ÛÂ?ÇîèŒ/¯ŒôÉq:'Ê ¢JvLjh› Tš¿ÈæˆùÇíq½Ë­‡óÃrº¬½µ/5Í-,(ñKÖþØØˆÔ¼]X84t·}ìVOâ‰xýãàä‘«¢Ä[F4QqÍ1(É: ˆ9F`i‚t„'ŠªiŸ¹Öx4£ðJŽYçTßb¹ ·Æ¢aîøv0Ž;(šŠ¶C[cñ(j‰J¶‚åÅTÈËy’Wc–5#€ãøþ…=êž)H !’ ½MÏáŸwã2ýí1a¥A<ŽêD¯µ¾ ßwäùn1‡Àxa9pâj•¤ÐûyÝuF0`Û$ÊlÑ\Z#ÒõiRT“(›Ò *y䤓Žsi%&ye°CØQ§ãY¢|^Š Â÷äu>hvÙÇvÌâŠaJ$Äd¢ÒUž&˜ø?IB7:±÷e€.À©r4Gt²éÁ•lV3¸â¡ fqè2‰ë;î7žÁôÈÚä+ÃìŽÆ&cp°ï?tHH,¬‚pÁ QlÖu¸}2O^T5]]!áÆê& æwg"èLH¢?å7¸¥¹¸ñR:ÌÌ©Pä…ôM~néù&WhÂßÊiío®÷1´ë’—€Í _yî|T§¶¡vÇùº+:êërÚí·Ô½5}qš™µdUùö‹­í»ÞéÆÜr eíº/;©D8¨³WÈ?˜Ža †À±)jm;"`7FØ´¹@(<»G¶JB…'Øò‹x-qçÕ_ÊkýN’≫Xîj’×.‰Êx¯]*XõLkúÖÓubc†¦ó6k$í´‰™…0Žm§7-[œˆmùîüÂ-öçM@Y“Ðs÷e¬°þ8›ôÜC;ÖqìF• ò´œ×Ô3g¶ã%#e º†ÆsΡÉìØRÞP©pby ®‚»ì`ŒÃù¥Ø}Z!ѲsÅëNn·FÄúÐÑÎ+„”&¤/ôC”áÆ Ãê}öDú«¶E‘¬Ê Û’›\P±: wßÂ8ö­¶‹i[´¼@õ,+›ÐäÜôîìloß|ñŸL¸u7ºª P¿íß§±Ä éT&¶ç7èCâÃt•ÇYwQœÊañ`ÇÛ +±E³r/ò4àXtÊUMdéêÒ-®t*¸õ’×¶E‰Æ¿Ø¦xró®øè|žÞ}è :ó“R(%Y“{×-&Wë¼{¯¹%ð·ã·ƒ§’÷‰(ÛvÉ&¥©D¶¶cvQ"`{U”KÌV&AŠ’#™²‘]ëë U‘ ("ß;Á>!îz8¤Šú^ìvèÈŸ7ÐM€Ò«ù‘*¡ô”’+KK¹U,7ôìssdUÃ2‹ 5«$bÆi0N»î¨)ZòED‘A9ƒÓx’¾&L'ð¨3!úFI2ºë~ä‹–1ßAÔ˜0gÄå®É~ lÆ¡(,ÕGRqêH„¥Ì¹ï‡P|JuK®å¾3ä¶ÌKÜ ntî2;Vî!u«î‹_±qß½·Ü¿ã°«nÃî‚\ÅÄ|ÜNðo¬3f9ç_Œƒ»Q®ÀMºÇŽfïÌÄ),|÷l\Ät"áP|‹ø uqÁ#¶'äó_fÔn{k1òâáL±'e-÷ò‡ Ûqö‚ ‘eõqh ²5À½oퟯHÁºŸ:®gõŠªŠ\ežJÁë0¢ï´Š#ƒõýjPçÓÚJ3>Ò4”x"LþÁqÆñ›RL(?šb£‹¥èrþ–÷åjµb¬Æêê4.å ®.ò›ÏA ß±Þz•¼aÁ•ôÓòy ©.ù‡íͰ€nw2¸ãÚù¿±óQ²wYH-îÎ=—R)OW >éX¡&Û5û‰q\ëYG¹å“F—d¡»àtè*ÿž5+/Ñ.˜Žï–jãqåÆûKï2—¥eÃ7¨&ÆÿsÏñ C87»Å³/ÿ+•”++ËKåÒòËeôÿ\y¹òÿåËÄY0 óÃ(Uî?à›²ôÝØmuö›{í½Î[å“YOCAç­nÐ%j8 Y¯ ÐÀdÈ‘*»LÀ}l Óä«Ȉå9@݈*†“¯ëö•¿zt)-ÝT f‚œT«Twå•–"( –ÂôñUŒÃèF¢Àß>uð:U~ÐtÖº~±öֺ܆Yàb¶WFÏ™°Îã2óõ!‚Îc¶<‘ϾåLÍÏ®Z¢ùCZ#s4öÛn‹‰æò))¸‰6þ¡l›4š«Ù4„³yˆ™H¾:Þ£†²ýAW«‘lÂfVeä^»voÞ`mZ¯`bÀ ûÚ(<°û('—ARR!ç|#2;;]ÞPp„û`(-Ésk³\иñ€l£ÐŒ«o÷úW[páÖh;Ct¥‡@|W*#˜c‹l0(*_ò\í_”ù–( íÒ{ÎZ#Ÿ˜1/Äòˆ M†eµø >‚¹7?o¨É43û`øï[åôÊh”wLÇŽûhŒ71ÐÅÎcìŸm9£ÅÊä*Ó  «ÕP™òÊle&—oÃÁ1Ùyß/ÔíR‚)Òâç?¨ÇÓM(Íá&a9‰UEﬓ ÖP%`5¡jÆy;Y±ó"o'+Ê'|·êoW6¸VQݹíOúÿôz#ßâ)$ä¢öEŒ, ¡¬`D)“t4 †` šMè+qÄK³yçáI3õ%²ôþ2YR Gsw²XDÌm0c}“õèCÞj0$/*Ÿ@° ä<ëÀ°ú~ë~NP‚h›>! °u…ñ˜`7,$‡k?¨²j8¼µ1t’ÜÆÝ¢µw[;¡lbä"cŒ¤ºihÝžyTÔxì˜yŒJx8nÑ‚›1}c ¨â’LÓ¼O”çÑQÿnÀÖíÚqW„…Ûƒ³Ù9£8"‘*èYî¿Ô«MÂpѺýæ…FÙ:YÎ}ŸmŠEWYÝ™ÄCA#"ßíF/©«!ôjc×ågt8Üà]†ÖîúÝTTÞŸÚÎý‘7CC)×ã¶” ì¦6µ}9J\ ôíNkV—å½0F—£¸¹N-„or¶Ã#p—£{m*!)"BŒNúËÄþ⧺‹è)"«•M½\ÊÎ"€Nï»Îes:³-ú–wžLúðÛÍÐi×n»üõ²OÏFEäE=ØÈôN­äá{ç’l‘d»ð°;Yþ‹_¡øŠ¦¥yæ¿¡6ù"jSß°®(‚EvÍd »æm1—Ùçì1Ÿ<ú!ßòlSL]˜*°sžÉ—‘wÅÖåÐöD¶cƃä1rM9FÜ~ $h &ÀU[ÕÉò_È%šÖÉÊ6Þëøæ«œžì©ÔyêU¶¶ºæØ'Wé"¾‰H9eÎsf™=`“Rlúجw6¶š°¯‹©¸úŽÇv¤j¥+N ’!¼ÞÞ ÔÚ{;µ_* ÊÚrXö©“ªÕ),K§¶Ca¾áKa Š, –Rov0Ø49¸Ý0å,– =dN‚½pOŒ‚ͼÔ<{/>pÈõÓ(¸pJ>L(¨¦}‚ð¬ :1l´Vê÷1ü töˆbª¾¿ÏMùÛ2—Õ’ ª›ËªöåRõwï‚2¿@ø¼ß~ÛlÔ6:uú’KA»Õ2µ.ÚQœÛ= Ctf©h1󭽃f½Ñ"Ó–ù·P¾ÑllÇ姤$O‡ÃÌoK„è#ñÝÉøÏ?)vPÑ?K¥;‰`ošµPF|ÀÌêÂõ¿7 Swíf ú×jãxi0:6{ýâèr”’ð:²ñkÐ}j¿çÄ«èN.(°½QÛØ€ì0uh„‹}Ó(·ßºX€¿I¬no½fœ¢ûšÄ–Ï–A0ûa,ÍSšÔM¾¯?Ð îGR_k‹b¼(\*<AaºOO­×÷60šÕ¯fíM£Ó<Øn´ÖõÈi;— ç_rj¶ÛÐæf C͇{œJÉ—NßÔpx;«>ËxœbŘcÅn÷Y|þ-ž=‹ùNûÅ) Ã5«‰¿–0ËSrš„zóà?ÿ‘ä#;e4x¤s…¹[ÛiLÀ¥œ3Á³8vã`g_”f‚†øªr@®Ô·¼ÿÛÎØÿËK/W`Ï//.®,¾,-¾|¹Hö¿ðùiÿÿ"û¿6ÜÆ©åÁBÒw|…ÇCw€z009VŠeö»¥1‡¸™¯ËV‡,!בŠÖÝᕇjŸF¶ž3Ê?ý´T¨”Ê?›že-÷dt†š›îØéQ ½<±dûÌöC ²}ò/¼—"ƒÎD@Õt€)qúöÀÆ~ ÑPÓÇ͘‚àAËp7\p=£g£rË@wÏ {t†1ñð¯ ô}àöì[ÑΣ#±¾‹ae¶C»à¸nƒOCÝ›ô‚>À~|ê™üÔÓ“hÎÜ¡°`µGPìðljz2îcCpsùm«ývï mÔv7~«5›µÝöïyì©\¢=5÷m$F«o^¬Ê¦ bO0¯=ö1" Ê3Ž_¸ÓhÖßÄÚë­í­öïØéÍ­ön£Õ26÷šF Êïךí­úÁv­iì4÷÷Z èÜz«Ñî ïÜúu¿Ö~ ¤nÝ÷º=Ûƒ}lÐéØ~çÔwhÚ¬ŸhÛ±ÅÎYøÓÈÌe±øvãׯv.CƒéPà ­Uz±úªˆ#‹tÞîµÚ‘"$7K.{g Ä\ÆxñBÿX?h"MN†,ßD›Nlü{MÄÞu¼±ãÀîßA” ÿb›íš`nî“Pkæo…kü#! ûWÎX]Uoó9Ãêž¹Fzðj`,OjløN¶ÌiG92áš×]žhK&•˜6^½¨¬ê0¬K˜•eÑ>Ë7»ütf’5Çåwßt,j-éb®ÍÍ!ÒiÏ_•Ã>—̉\ç“´âÚ0„*ø:&玌£gï‰AŽýµ£#½S‘ª> =À扑ùÿÈÉi xŸ 4Oû ssÇ>þwˆ?þ@• §éj TñdZ?ÚÃŽ«5@‚agä™vpid¹ÑŸä|ëŸÆ4 RÓzCÊÅù¹¹…¨™Š]‹:aCNÄÍÜ\¸»«Fϕӗ|— ƒ){ôȧHkÑiƒíࢸ^ ƒ¨EÀÚüçBa>”Ð_˜ßÊE{Ù‚µÔ Њ@ÍÇ ƒÝ›Ì³7ì^ؽ(ØþdžþT°ý8°}lá°×ؼÏ%9üw;ñs0«`n.´¼¡=r­" ãØ³Ì1ð0Ü?‰Y!Jñœ(]Ï»z©ÙP5kΪXàI$+— €|´¬á©‹Ç¥ 8g€3üxŠ2@Øgˆ¹Ϲ…õýZý8!­cq¢•™‚×H>`Æe~œün]Z]-xÕóaƒ»èW©¾á,ÔOÿi½•»ÎÅk8_‡N«{i­½×Ì¥qu{)!'èøgŒ~.+ÓrF¡kpÌzNqäŽÉ¬çjÕ›[ûí¸L[»­vm{»ÃçfÊ!“°¹Ì^ÇG¯ôM00•Úáh»{ÍÚvG…¬ÕÔ~³~‡:” ÊìFKER°\8 %C½.®¾…órÖSzQKÆ÷õ ÙÅ\¶ñ®Ñx×Î……É2Œ €<")G©gú¹1ø Ž~*!åÅô**ÔÎ!uä;Ì-åÌ.É”Šƒ%šJâµ3Xêô¬¡?‘¤X æe‡ºÑÁÀÖ%í ؾé%FþÌðRÊ.nÈz‰ÙC`×;þ¨‡¯åòô"ÃÑú8Ÿ’ ÜÈuûÓrŒdØ¥iyüñ©éMÍ!åtÓòü?÷Øwaž&ÂYÔá§hv™ ¨ÓĘÁÍ‘|gwsëÍ,‚Æ~cw£±[ßBá5#˜6¹ŠÌ:õ½½]‚'ëÖbI­b`“íʉfi ™Rs£(½¾Ý¨ív6·¶IÚÁå‹ì\H¾uÍî™ aWì»§¸•ÁQŽ.)Sƒ‚8A{K­·íí\Ìœ×s¦Dû ÀÏä‡P£Ã‰tZQŸ´µ?—Ѓ\*,\S´ä\HÖÉ$õAêé{¯ÿݨ·u¤¢‚·¾›Š/Dƒó)—ªít~íôGj~ÃKgS×y )aòóFc³v°Ýg+¡ˆ®àcĘQZ†TzsÿÏêí( :I*¢$ƒÅ¹,¶H’ËHV¼H§ š/’'š®åÔWÌ ²6½²ÊD ä¹sæn¼0©+•ˆ\1¡;ú·H‰;vk1Ô-ré}@—“Ú±±Âo\~ ­ñ¹ CÓó­Ø2ô¥`N-X@µÙ)¥—Ó‹“-ã”ò7´»0½´ïÞÐzß;ŸR|t™„ãÂÀö»±%ûö¹•X%ïñ£É²€pÁ@W;HŽhó‡&¶šCKL¼ÔMDÒ$_ÌE–´û—˜¯§sú$GšLÿYoqÔ†¬ß míþB:ÝÞÛ£mFPPàŒ #ót­þî'Š,|Û°ÃI…ºJ\ûÜÅß½ÛÞðäµ(¼Bó"7<˜¦ ®1·ehmÒP"«Dyõ4fËÁíD$K$9Èw JDˆÜ×¶šýÈF´ß™ø8¹ íÓ.Dâ6•R¦ÁÓØÕ€À[¤L‰É0Y~ÁšÖYÞf™]¶Ï­¯j™hû£ºM}›5£Û¬ÚfͤmÖämv=x¥ dÆ­ÝúöÁFƒ/¬‹ë,4óºë)àÖ»žÊ"‰<â¨}u Gh‹ÏíÖ|#ãl”I¾P¾Êi‹ sYsÜ`ÜG¡Ñ³‰o‘Ýó¦\˜!þ+íHÓŠ+"7-‘ÏÄ:h;œVœÈrrq$@ÓŠÃn“XXî†ÓÊk[âÍÙ`k¼9ï3äógÈ4(Ü4gÈ;ç͹p½1W"ÎcŠ*¢)Ùã 2žü6Ÿß†žÖ"ÚÂOáN";ûpòà‹ý:®aXù-ñ7Dr$– žq_7ér_Q¯üU½HÕí¶^Ý”=¯~»-Oó#] ü·ê…Þ>íÆõ‚ M ˆk½¡½0ùy’ö‡É $òA®×·7ä(¥fáêwcê×í¹ÂI2¯ p#š*{»s?—%Gð)‚%?%ÈÅxz÷.4§ß½›}R«1VJã£pb‡«}@~N›Üz_hvÇv‡GªÐ»wÑ1„”˜ 1#_Â'2Éñ“ºK¯_IžaÊ«V«îLNzJ‹Í‹´‰yOuL MN|](FÑJ2ûº^“èjœzRèl ¥EÔ„ð+ÕMòCÓÁ‹™ŽÆÙΉ¾ìôìoÔÚx°¹Gz–ê†Êù츟w÷râ:]^DÍç yGQ €…‚ÇæŒWÀÕž/`4 £òê…~MÍÙxjõ:’»ËJe@d“55A˜@,òS³´µŸ“Bâú"Ô0 Œ-†šŽu2Ê‚o£AŠ0Âó8k¿ Bz¤ï™žô0P½’nm Ëìž‘¦à™50\#ÓIm’ÞcKH¿h[X”ý¶ æw4¯+’`7É }rŪ5|ûí—œ‘Ad¼n¼ÙÚ5>ŽëÈ (¥UãZÜ'Û#k€wÕ%´Ø)¯ê¹Ê2ñ0牑•_Ñ?Þ#gm=‚‘=³é f„î©á£ˆ1"‘Ç Ã>*½°ÿŠÞgS‚ca`T*Ĉ8«xZÌ3RQWT(S,€éC♉AÿÌêÞ¨5€*®è¶qwBÊ<''–GJ1|qå/°± ø§T{%œFç"û°–a¢¡F5üÎZû€•Ù|ÉŽE´«u¥r‚—övZ¨:a÷UÖhàW%ŧR]/dÏ‚r…?÷!Õh³:¥ÍóSuñÖå·V}o7Å®ßu‡’Ëf£~ÐlmýÚè´kÍ7 :õóWÖ<4<‹5©Ç£«N×í»žßÅ?¸Hœ:k¯·fœzðÔÇ×ãþ~¼Ó54ŸZã†óïNøšãF *] àHu¹Õ¢Púï{Û{M çÓÊ¥Â;TKÐÔG&k*%2ûæ•?ÝœO@›k7š;iãŸ~Ìz<ê#^X•€tÍ_¾¬en.’•¯ãCÀpH2ÿßaiu±<ÈHzŠCĉ• ‡ Ë¡DBN\ §²ø²–Æs)8è"tµ¨ó¡9:똽ÿëøÖhŒB žå¤±öwX5õ¥JKÆÿ\„ÿf>¬†¡à|åÍeì%ÁÊíãD2Ÿÿ;7§U¼ðù³¦£C¥ »®ÝDÕ²ßÛJ¸X3C-XØÎÿçšl¨¼_˜—Pf©D‰Ž{ mÐ$Hñg&T,¾/BûŽæ?¿_8‚/3 P ¹!FFV%A=ÔL`F‡Ld\2N“É­Þ\§ª—úÍcbDj6>¯¦3Æ‚Qœ?ZXø§ðߪá粘š[8üïÂûù¹¹üQ9ŸÀäþ'÷>¢Ð‡ébw¹t–ŸL››«`šö’F–n®¼Pëì?8"£ìµ6¦¹@Ÿì“Ø!o^ »ª¬§´®—Úr-ð>Kû*Î/Šm‡;‹€ i*<¾7®34(úHDfææþ¹»:ýÇ_8r ˜5Úd¦f”¼†è;Ë‘ÝËáS #Tø“Ò0‡Ô“ûüY’À…~†Ri¥rùO±F=™¸ªðDž5ºÔlÈAê›ÞààòžÎ¥C*‹â–»—Ó«¢2²ˆRccZ%6¿Ž‡k÷¿‡Æ³÷óU‘V¥7ÊuÚ‡UÐ'2ŒngÆýQ¨f¹ÖÊ¢ª1Ì' £ïž†Êâg`{ |eŸ5N£“Œ£ÌQ^x4cxSÉxRI¹ÃpIë DØT1Ù×"»fR… ©"›l•,—g€Ùã!€K“2¯@Nš™)¬XáPîRruò|_™áÄ„‹3äë²Y¯‹*`§Ö;cÐÏÏFXU#]y~:+6Ø’\ŸÔ@ãš…Ò?ßÂßežðJ Ðeùg¼“ÊV–BJ(ÍiI×ê™ø8¬‡êøÆϾ`JåÝ÷‡{îû…äv>RÅW¿¿?´ïýÖ´Êë¸V¼HV@•@$­íö]h‹>j1é„oâ26­»Ð•Cx)¨‰"k@¿°utB#¢<‡¹¤¶>µ) m–AáÔ d1;ðOŒGFFš¾T X¨×8·^Âù€ð¦á ‡zÕ‚J jÄ„6CØZé9Ë“Ñ*8•ô-ÔÁd“l™=Ø’áÈF+Í6~¦Lø´ÿý`”CCÄxM´J¾9GNZ6ŽkŸ$^Á:ž$Џá5vÓ»ÎÅ@Öm4±aÄwSDƒÇ!2% ðZ‰¥è¹)KÅgÓÓÊb”Pø«É­N%¢>7—œ+˜ïV4 v·a:äî…IAìØ*"¤Q€ÉŒ“C¥Oᘞ¤«<4ZŸg™L¨ÃÓ#<0 Sd–9¢¨’,ÃK-Œòëà1X&é’î@›ûQ£L£ ø#{Ô·˜"!2镘.q"@ÆØ0^ ó‰Õ3`ÚŠ k §«ÃÕKx6È^N‰IBÞ ]ˆ>7Znßôlß(—Œ nßÞÎBÎ>G40Fž©\Yp.2"ØÂè @ Ñ‘Dº`¥›òšÁíïµ¶Þ•RéG67ò¬?ÆGœì£Š†ñ›ë}¶ͳ ’ޝÐÊ<î#½„IvìKÚw­-6k"S­4œ8Œ¬tÚe|t©ÊHòÏ:–:Y‰b™êy ñ©œîHVøÜذNLœˆdA}áiA[KϳÏÉå/¯ ÁÀu:œÖáüÌy t/0Ÿ“ž8 §E.‹ Î`w*‰ŽÊÌ_:ø¥Ã_Tм[8á@±*?¥vDjʈ1ÝòÈÞËB“wacÌ›ªÐ›W\à¿N;œ/vN`‹ÉÕ …>d¹,}ûD˜öCþ|¥ œòДE]¢L{ÝIž²ü‘ªS¦€ —Vw¬5¦IßZ^AX¡÷x x8k;,£é4vÝjîíî4vÛ°¯À\»â'¦#À›ÈˆÍ‡±02T±ìå…g‡8Ýë +¿~‘˜mû]8’ÂÈf¹ôêp»6ñ"Û{o:âΩ =<£³+ãÌ<ˆ¹˜<Ä€ =‹¦ “ä`¢æVŸá?ù!"'‘*U*9§å $e Ÿ£×”ô`c%¸ÞHˆV)-ŒôÜzå™(hó(5!Ý „ ÄÅ̦„1òÜM‚ŽÕgJl¢Šau ˆ$>y&á³ì’§°K§°5ãNçx²ããcOÎpþLÐ?£Äsç—­fg?þŸˆuš›û×*Ö ‹X¡Ùs'RÈJíZà®k¶€tò eZ Ç]ß!ÌBš±¢+þh’P|çòZfn=ÃýÖšAæ„[­ÚëíFçm­¹Ñi4›{Í–´-d¬ÇSW­yŒRB~r”º©<Ô€Ãw›µ­m!æ4äÀÓ°³…ôE˜ÊÁh«4îdĆn’±M’‚˜ÓÚ›z·ªM’ ¹$‘X¾Ò«C8‘N þ™Õïg×@ÓFyŽõÃY¹”É”ÈF~€Ã„»-^7¨ýųî9Ì÷¬]´Šy÷­s ûWùxØ8 |¾Í!`ÜÚ3“@stë'fb`Æ èÊö—»#ï/VfE=~F^–œ¹n@¢F6Ôa;òì":aºG›/…¹êÔBÊgö áHÜ`?0Œ]‹~K|w`ÁVŒ1hc§x&çnÿ“øî%Íh'@UìÐ0´x̲1(Éø&†Ý¾ ==`ü²°g]xöHÄöÇ''öeÎX>Úˆ·,Ë0û¾kdHRsÚï¢wQ¼èŸe¨[œ˜©`ÅîbºØ÷­‘˜6„.±7Ó3ÞÛ¨^È þ¢ß×PJ ¯¤«MB ¼ÖbYªÌ‡‘ŸÞ>¤šúÛFýªMy'áºÉ©Ó:Øj70}ûawü1v`ó÷Æ»vc·%|׬³ÙÐ:TÑî7Í­_…‰V’Òe^%¥mQ|ƒ¯mYòb’‚«uõ¢{¬ßæ"© $î´gH^X|ŸÏèö‡"Ïñ~X Ÿn(ñG`“Qm(ãDMV/?„`×ÀxÒÀuYœÄT×p.ü½¢ÄÚA‘ªD<Íz.¤r2¥Jã“ù¶Ã¥ÊécM”§Òu­‰Hb*bËo&„K .µË0ÃÆCt;>Ù ©%g+% žŽqí'}…#qla©ç:ñA*øg±åú#Rð„¯“–C6Ç¡µë ÙM-Ä«´‚¢½^YLÉ×_¢w¨þ@Ïã\ ]@HkRa@š+Ìe¥ƒ‚Ö¯çÏ9!ªÆmEûò©€•ÊŸ{T@ÿZúW£@Þ£{(GßFÎnp&Ýèž Üž1þáÂøtmdV3jé Aºw%?“ÐÞï[ÖÐXNÈ«DïÄuU‘Í¢Ž ]Dz'ešz²P€©5ëoa©µB8*ŽL¯xúgêͶö‘y k¦c$¥T&¸üÆ…Ó?í! ‡ºï`ÖEŽR€ðVÈ:T¡€u¦äF%e`j¦øìÿ>ÏQà-û2·ðiã©h,œ#W‰14‰?ËP›»}Ëtfm¯°!ÄF<¢ ƒR𴪔RT£ùŽóíßùód:俢Xî ½‡Öuô.ž9U™æ­oëÊe›Lg"µß~¡„ß~YO‘¦çz½ŽOý½'ˆH—î¤Öù RB.²´ï1éÑÜ]äÙ7&³‹Ñük®õØëèé¾îï¯1§r\7à6îå¨à»wë¤Ç)ÚMO”¢ã_½­né8]Öšà ®þû²¸ü²Ë—u4y øßöÙ%ß:?AÊö6*R?BZë÷ƒö'ŠgH=ØÙ½µK‰ü¸žÎl¯CS‰ŸDÊ®J‘yÚ*¥ )oš B=À;1o–Ú”969Ç|Å¿ðÖØ}ÛÞ¡æ‰GH8ÿÛÚ¯ T#,#§²¼­§k÷uñ¨Ò¤s€uý=ø8X$y”;€õpŠ–£ ïq°BÖSÛ¢ÇÛÔcRÃ\ßÞÀ'5)ÔRØÞz½÷úߜƔ&øM޲xTih|ÔÒ>Ð;~ÝßãÔý=xÛípø»ÎöºªÆvP'lο·:lµû{Gú+ŠI^O!I½3ÈgLÝÝÚDnK¶6”ßYlA_øq=µKhÜÝÁ§ÆÆV›ßði=í¹ŠIâ‘ÒÄlã'H‘µíq-ôgeI¥¬,­§iÊ%…xè¼>ÀY·×lk_ƒÄ :ÅÓ³à{ð'Àîý;§9`‰‚IAžƒæ¶þ^ƒo‚ÿÑ¿‹$Ì£»Îà,z ä‡Ö{ð¦}QS3œä³R_O5k»ð€éü´žjñVÑÂAúÀâé‹8JÂxÇåCïø°žÒúªúhûrhÁœÏºþÎ_™)•ß”£-xF–1ZVO r…a)£ÛéŽ:¼­Ëg™ÊX•Ï*•÷õ"Ó5ZJNÁ„§Qü¼ò7`iP¶Ñé¹#ù]Kâ<Œq7_ée]¨{2×…‹–J/®œNGô=š¸ž:FŠ1ÅOëìDó;ÂþH̾mú*•_å·îp|™îj\•¶ûžë_ø]|•mQ#xÀYœæ¹îHK¯ðÍ•#ÏOrnËzZO!óßa&”ÔàƒWö²xW!Ÿ+ªëÁ›ø":.ŸEªdveΠÓÚ+| ú¢qâq=òè³¼áâ9™×5?8œ,ßÖSÊãÏ:?QJàãg=xƒ/È•É*Õ‹HG?¡o2a=…âIþÀOòþt†”Äë):êT(a=5ìˆü)jpä¸Äûæáq_ „/úÓ;zO´×õ”,_®VÂÖ‹„SÖS•‘ÔxO\X2U½­§„û'5—ô÷õ”¢bÚ´Œ¦i¹ü0í Ó=æ¥þî¯5WÊ“Ž#„àˆ.¤> §sR$¯ãÇä›I æ”Oh‹_ã>.?±lâW?ñÓ´bhãšøÍ;Oü†ö¬“ßÈê8¦ãdÌ“NvÈ1éÊBZV­#4Ï‘½|KàÚ$Nžµ˜©”æ’yÒŒÞ3Nàš¿å¯+ÝÉ‚šGå½sdÊ‹]øŠßƱ÷~½¿·ÞìÕûz?¨Oo@u5pGõŒ=Ð ¾r-š3P”mR©bë`ssë]£UÕbþßEEEVV,Â_÷øÿøfˆ·s¨po¡"4⬪ü&§ž­WS±²þª‘è@,öf Öy€'‹+‹­þ%L ž©Û¡¸BâÂè™ðW ióJ×àû¸ ª|«† ,°'¶>4){]ï=‹ª}ß\K=C%)T((i@4w·Ï÷˜Ï¤wÌgzã´‹‚äŠ$ ¹¥z#Å©Âé0Rò¡šx§£s>êþ†ý­ÁP‰1ùW0ó¡,Á0ˆ~ªK¬bV€÷¤… êT3yñ`Œ¹uå4Æ›I.hÈÃÂåæ³EÐÔõÀ¦’ÕTj*^ù¤ó¿N«]k´ÂqÂ$´—:›ì¥@W¤%;u¥`sr©ÛA)êºp(.ž %_šKÅJšYE>x0,œ•aÒJí±ÏŸ…Gâç$Z« ¤ä“¾†&ï9“×P´·œwj[ˆ­=ǐԳìÚÁ#ÇÜÂü-ã/(`ÖÁlí #FãЙYTœ›Èt0ãÝHN WÿÊ”–Œ?¥¯hÌ܉=MÞ1J]¾âçUCWíÃ7ø»à»\‘¤0ù9‚€……ñm@Èö [“æ[_Þ/± [Ÿðëµ Ï1‰×3 LS5âÇ@º!‹$‡ý£Ê‹õäÂé†p‘cÿ[»¿äŒÙêcož9v…ÑÒÕ¨ TÕ=-hPbTMNø¬ÌD=AOêÔîÅ u·ÓúÓb½!”Ñôé=‰É2Ñ›P½7õhj[âz≫ºK‹” ƒáÞÄ|õ$TÏÄ ¹ÌÝÔŠh?¢¤«š­|œs¾ ñ_U&œT'.’©uG›>pýQÿŠÉ£P v˜yÍO¡¶ Åä™Çxþ_¯í@ó;íæAc=tS Kþ“|ÕiYŒçŒDéÂÀô>ZÞ¡Ox»{ìz¹ átïq«Pnû³áøï1«Þµ ö?ø¨U°ÃǬ‚œ >f/Å/P {c|üŠÈŸããW#=B~š¾Ì4øRÝa¿–_ òŒùøõ°oÍG¯çqëxèš“ÐÇò4úˆU< ô¼ÞX¡þDüçP´ Y~Íe×7ð@ÌBÃçy†Ê¯æÖ #–x°WUȉ)(ÚÀº$Ôª_K*UìÝjŠZybú#ÈP¯sïƒÓrÀ¬yŸ3 ;m-v6à¿}øoÓp17_l] Ñã’Dñç©ÍQNkwJ(aß™êfm»j0_V¯eæ~Îìê›lÔ ·gM5Œœ• P:°¢~.öôö®³S!ø¸µ†G¨ãÿ{´¡ú¥"jÎ@Ä}x»‡»8Äâ`ögYvÊ]ñ×[xý‡= ¨÷ퟎïðâ›$“ïÞEìÝ;<ÌEÁ?Ђ°@³tÉ5Ä šÒ™¿Å¨Åµ9²ìt¬O ÜÙ|à¡»‘v>å}Ç2ŠÆÑø±ÕÝcÅ…ÙèѼ9ýÃÁ¼¾8§þªÞ¤»3Ó¸ßÖa÷í\ ßìÿ /z4…°)-ƒ<þ™}ŠÊЛT Èx§Ö„aŸ››— —fßÕU5ý™¡kfˆ\8°ÂùÜ)1A•—â¶>p?ýÜ€‘E= aJ.t¾¨êœ|Ðge8Akb MXO+DKU;ÕÖ{Ã@f¯ÔÏNìT—Ç´+•ý¦‹„T÷ã:Ëði#V×GL5’T—ê²×õh¯Ã õ˜^«y›zC’3-ª5ÒRÂiÈ”HmR¿H~?EüÙ­0šXS:Åþä«Â¯|‘CŒ=“.~ýPºÞiòV„ëØ(ü!zKIAwõW¨?H~æÖª"š¨7éMÒ_ µZ‘Ô|‚Ǫ–L³&ôš@q¦Gx&¿¥>æáÑѹdúW•s†vM•64ÕJ_8ÿsàò@OÓ_¤É¨àYbœ]e3­Á§ëUªYakôÒ«W“šuú¨h¤žV©; m„™æœñ¦ÉZ¿ïÀ/ñÒâŒ4ÆØ¶£¿ ]ýMTž)Â5û†ìYà¹gdP«:C^bWÉ‹¡áŸ¹ã~ϰí‚|È¥¹æ×E=íUƒ<$ã:î“ %¦…óEHf—³èÑqò!EŽDyôõýó’¥guí¡E¾£.\ô(Jî£0êÅÈ5Ìs×îIŸLÂé{k.8éb a#ĪRgû¥æ‰Êéx^ynl³õ¥‘Aáú‰ãz½ ú°I#&…‰ îÛoù0Ã`u:îˆ\m …·.Úh¨‰˜yæY=·3Í•ÚÇä?U ,-r`  Cih ù4rd ðC˜ V hJhÝS2º9 50ÈòšÅs>¨Agg³A€.…!Ø'J7u²½+XA¹8¶&Ð+TmÖ}½ë-Q:£å([ƒát†\9Ô~˜ÜEü=ON£¡ëû6,Fèü *ÚÈ­žy ˜…còàäf'(«—FÑL¶û1ã4ÑŒ‰FÒÙ*q=P"ýž Õ°(àyÿtífžw™Ø©!qR )¥î`ÆËÅ$“.µHÀÉRÓd&Rh{Y.¿(t\;è½þèèÉ7º²1$ €­?ŒRd?ªh‹æÔ˜tõiL¡@þZ½JgmÑVÝq‚£»ãè‚ Í4ÀšÊ˜ÂI^¿¿öÁ`çDéÿÎÍ]øóU=æAZ£; ð3p.ís}èµ`$‚ ”ýZ«•NëFè3„ÿƒ¯Ü¢õËÖ~2ˆKnÆtï¸I 7€`d$€  7 W¤‰ $¹ù;5®ì—ñ8uY¡SôÍeÑ1ºW¾ˆscP 'Sƒ#%'7"½äÜ[oMüÛª$´*Ìt4€ÞxO­W£ƒF„éX9Zæ{M9î_‹È!6š¤µˆI¼ÛÜâ_˜¢Ú9µÈ™šk8<&K†§Ÿ[]Ë’ud¯$ãœxžh¼dl€,­ËùWŒòܦà&aÄã›!êËJ\#ãšÛJìRa=£«ìdl£jIö’4Ì£ˆ Ÿñ)‹¦ ÀÜ롈Ör.Gòu™#ð ë͌•ŒŠ°è?Ó§LyƼîÒ‘b¿v?\ˆÄÐÅÎÓ¤È9/ñ e*‰E¬8¦Y‰\3ÃL'fhüR` ¦=ªM–P/às„R~S/ÔC†ˆ˜ìwV|/UÀgöÑÌ)} Æ3ÿâ1~DoS¢hô|¦²ÒÇ„Xö•³¸h:5äF³ç´X{sJ,³ø“¥½ä°ù»i¾l¿L÷ s¯Y¸¼Œ¾Ä‚¨l*š8GÀ¦;SòÁhT”yaʘܮLI}QEQ»LÞõ+)Û+7è¹<,Fs®)Ë<þ®\އ@§ñ…Æ„HŒä¯z§­ƒ6Ð3~ ”ù†ÇÈ|£‡gþåÿ­C¤ÃŸïòp¬þdö—‚È—² *ý_= ‰êzñ—1ÉìK ™ð–aS†x®¹BæøÍLhV‰Çð<¦e‡<³ ÿú9˜¯ú¡IQáÖQ yyÞ>ŒB´gSe B—}Ñó®ŒñÎ9äÕÂKÆ&_I‹ÄŽg ý‹½Å#ﱉ€<ÀÌ=xÓTÆîRxwuPEVÁæòÝ%‰´RCðE™} Ê5<—†ùyh¨Ãu™xw0$züÊÁ>F7¨˜°Fµ. iƒù' W:*›ç®¬¨è˜xxðÚð9š ¨-X×™‡eÞa $"¤Ý³FU˜záÊ#fæCRcÈŠö*R?0ó;iŠõªÚˆÁ* Q”ØI~Ï›9¬ÍÎ}œÓÅ×°‚Oj‰’yt=séžÎ¥ðoï0ÁÀûçiÚ!³{ÚôHY¤¿`Z@ct*¬)ŒóôtÑ`™"8y=ô/í›n—ž·%ZdêÙ¢«ÆùÆ)½ÄgªfšQIJñ´ë1ÜÍ:° I¤t];Ó¹¡ÍåXø%RL<ÝÚ¢=47Vë#ïG_ްQþ:`ssS”ÇŽ{ˆZlÄ­ý% Ó´VI@˜ˆA…‘eK»‰BÁXxwù”¾Å¾Î:±«Î à–ÏFªXd‹ŸJ°_ík,0£Åž@X´¿‘é-¨/æÓ_ȳ)%§†<Ë—€¨þ¨V¼„:ë{««Ÿè¡\~öE’´&\þQ_¢ ãÇ`uЈCÎɵ#Yýx™¸ûãQu¿û;V‡ýç§rÙþ"îþHëýÝ2ÕCÁ¿ `GÇ_›§Çíã×»"ßMIƒCÁõ< /g”&ØòûWÀ_¡ÅØ=Ja‰–´ õíòØYý{!#‹‚*LÖžû«·B7óµ·CÎŒHé¿99š5½‘M©BálkÎBL5ꕪÄñðªF¤Ùß—2Œ2¼äaÑŒqs‚ü¼‰…Èÿk…Úa É£63/·›ã©¬T,æ¹Y¡Íãÿžxo&z°"N›ƒá-©4ÌT;œ*2ã^á—ÝÂâŸp <6(¾=yH¡)t ‘Y‘ïÀ´Z2 œFa¬8ù&¯‡“m4³|Ë m[¦¸W˜ôA/{<,ËÔ¦ïù^7X.¥ÉES+˧€l°Æš¯iUÄËXz"ìrMgqáBôç“i-šøi¬@oZI“ç@™ƺ]LdçáÇ‹p§Á‘$Îß-þ»‚¹&‰HRˆ r—|ŰJH†Ð´Q%F‹Zß"´c¨å[‰Žúòml'E´Ì·,L‹6óo607šù…5YWÄ&'ñÆãä ú=Å¿ B3n¯JÇ„…\ücMRÙ0u}dm ¨6ïk¼‰8;BòF8™~Ù°&0îåUøo#¯¨âÛ[Â§š §ˆ*W©DiäÐþP_&b®*Ø}|CÀ5ÏO[F¾<.öp™rYfÖ¥ªà'‡šÇÞ%†1o´>">ô}pãá™\éc&­ç tE±íµh苟 ŒÅþ€W~™M¬àZTŸ>ÅJ³­×¼©r_зƒV÷ âÀñÿJ‰þJ,I›ÏEs¡æKâï6~ÓIüLÈçZZü-ðÔ’K­š$Šä!º’(#^´€tŽi 6‘«…¼¨\Ä}¬üRTº4ͽiÅÜÏñæÀ#ÊÑ3µi'ð\¤ÙáÇï­J ÝYíŠþ 6*{#zžÒ¿wD–WW§ùpWHÉe¸«/ä(=uúª(’1< l¼Õ=¥‘÷(Iúê/*—2rŒE ÈÆ® […©cø’ˆˆýÍ“éûW¸­—®»¿¦lü&yfmTfsÒ¤“ûo؈ʆ±FrlCa C4ÆÝ¼ˆÙgǯûåÞ.ͩ٢‹~¤o´ÆeY°ÜSÊÇðx=¥£ŒÖ{›¤˜øÞÚö¬-ÕüÈ=°€yJļ½´™ÄF…ž;¾§õEÞŠ‘§S_·HD–³jʲRa¦OÕ™‚mÉltÃ/'Oב˜¼Eµ›åâÃÉÖxŸ ¬,<ôÙŽ"'Ç^ç6Šó†*3^葃£˜ÓF¢Û]õcWaˆU=¢º+ú€¿Ì¯˜W*úŠ¿ðk´Ä£ÕNW(ÑsÔå_`MTsµäbÔ-ÆÉ˜M¤ûƒÝ˜Ç$,QJ¿F¦"zqfµ#‘E°R“!–ôÉé—Š¿ÇJ÷ʆQ»D–°¨ý?²±ùDí(kíQI|± {>Ö+ØÅ¦—ðÈvmßé'¢hGŽ8ó¶#Ò?'µ¸a”hHA±¤ÉJ.ÑtÇ-½;2Ôÿþa«yÜãk¶X)ß‚ ÕØÝàg‘…˜èçƒèÍR¹7%¥‡_Nv€õ`yÒÅà/ê\¼n m“b!OÈ,Ì€7×€@ûØ£.Ä–´/ h¾ýû H­¦vß±ý¹ Þ·‰Wò<ÂÊK“œ/å“z'Û)b^â"#F;]¦ÄµæJT·¾²êhN‘niݲ rXJ‡ê} ¤Œ¶û@)0÷¡Róö¡R¶öRrô2QðØå rü×¥ÊR×¥Jª(¬Ë^ºW@ÊáL—+JI—*ÊAE—)ú`±¬FtÎÌï±›‹Kex(œŠ‚ѹyL:,1ê\̤›3órˆ¹°"îÃÜ»¨8bjEáüÁT™»ÿ¥÷òa7G 2‘Yz’‡¢‡Ý\.Á^™o°ãGŒ•Ó5&Ø5ã ·ÅüÃ`¶ß¨6F¿bóm†“Èø5 #høæßféÀ(Ä˱¢š]Ÿ?$wÅܱ¹üQÖª3{…wH›¡]é[PñŸ'ÉŸ'ÉŸ'ÉÚI’BTâl¨ÈâÖc—vç¸Úøïøwu:¥Èdx>¥tÊåˆä*R«I,’VIR)5õ𳂢+û (êj(!DL†‡Ò'o:Ç¿íŠ}ŽüAÿÒ?/AÌØÏÂȃÝ›º”¨RêO"L²çË ©RB'ËPµIGű›u™ç(¾€,†„6™ÚBhK!MZ„2Ð<õ_/ž ;’¢}—:ó´Ë¼îbþ8Å®wBÎÈ|Ðë«•”•ÜJR3Ä š=I°.1½Òœ’É¥&%˜”S’äPL`àHL$ÁŽ ‡ D›$¾èãt FÄ€EEÞ1Ȥ‰}üÛ7¾Üü°ÝyÇ å–B«B­o€®¸âªÁÊÉik¿Ý9ï KÑðãØ IÁ@þ&ÔÌR|kdSˆT|`bîuq9 šÒ-…ÌÊ-.]1i7ŒDÀS¼¨ÉýÏ»{z,Ù/¹K+YŸØÐ^Ä(¸hT¶ž­7*Û¶áõñ9« =Œrƒ1nÐø»xcùŽu ”ó}wÐläÖ la ™"wìLœPQoÒ½Þ º`[AX"¥È¥ ¸ú”o¼’«wZïÐgo7÷—Ü„¼\«Ô¶*Õ Jü›š1û[ê¨ÂÛ››ø·öt«jþÅÇjm³þ—Z}{k³VÝzºåj›ÛõÆ_Ä_þ7ýÇ©ê¿ÿKþ{"s5ˆ¼‘<Ÿ‹^¹Àó¹èýO-Ûš¼0^ÝÐÊ‹\Å`jõmò7ŸŒ´[?qòÞ«â!g½G'àuq‚Ëí88µ§ãûÎßJPLˆƒãî‰Õ¿¶C1½ŸÃ øSAç˜ßA±zW«76Kô*šÂ¦µ‹üӲХêª+Ö`Ðû}Àž.ºö-¢üõ;oßY“é„/o’_nÐ {nP2@-7¸µ}­;MÕªÕu‘‡]b¾.•°±p"îîò°ütyÚ/c{Ô |,B1*çÏú¡¸šk»¡XÃ(…!X€-GL@Zûg½Öÿpêîùþ~«Û]§îÑ>…v£“óø¾ˆˆ%öuª°8ØøãDÌMkv»­Ó³Þq«(kY§ê£fã±äŽx–EÐû@üô“xÅZnXÔÅ£¶å?ŒA(mtÈ}ó">:Œ¬¯?|ñ ‚ ÔRäfQ€‘³{r0T5_^3G³qè@K¬ 4ÕZêÂñêaÉ4ò¼ÑcP Î\>µŠñökÔ¿Aã[lf" -k¬4Gb]Ô7Ÿ®‹OõÚöz½'ïÎz­úe)<õ…x6—ÆS[ˆ§¾4žÆB<ÛŒç?”BD##æÐãFª'~7¿Í¥ó/"(-Œ‡üß{=_baA‘ àÎ…jzEö]ýz”ü"U”²zç–fëeóþž|ÃÚDü_5žÏ‘‡ì¡8hw›/[ÜAˆÎe<Ò »ùpýͬú—£ãÎAó¬ùCôµÏ¼'¶;p†rQœÝF«"¨|âëÊùîÃÂãñ«ïLJŽ¢ .ò*ÒÃB¿Ò+Œï죻ŒÍÛ{rWKÙßÿ¾%µ|GE¢4™yxØþ}ý}:óg.y‰)´SRû€ê"6¥‡ê¾×žÓÃOf+éÕ?ò©ô-;ÐÄzüe™#±9{ýW–3þ?òTÜGAs~†4CýÄ->Z㥿]Ê[ꤥàÀGÇáÙ‡¿?í‰|ˆ¦|÷ÎAÀˆ…èÚ¡ž˜¢ãÈ·ó{â¨uô•[Ù:ÇÑË$÷…Öv\®Ÿ{‰5åþòçÿÿ×ÿÑÒ  ߯wVeëÿª›ÛÕ­¿Ôµúöfu³^oü¥Z«=mlþ©ÿûwüWyŸÏÁÿľ7½÷ÑU(jÏží $jѬ °úW3 Ùa Ú.Påp’FþÌî_¹ÞØÝWŠû%Q‡i-׫µ*b:°\Ç‹.½KÛåT'¶?qŠˆÍ„ë¢XÖÅÄ&óžÃækw ›ò`à Ã[X«TÀ¡ÈóýÙˆ*¹€µÜ{1ùS/àRèÅàÍBÚ6š3bD{h݈\Dëè:}ã y£öµ.½›ÚD=#`× $mÓ)a¼¦ ;MoJ©®¦øþô”Lå  ÓhæðJ#° 4ÖÅõ¨*l'Eù99ª´+gºœ¸´q@ñ… ­Á ¸¼4Ñ™Î.ÇNß ï±xq$]>bαxíreÇ\#Ûoþº¸õ&FÏAĺC¼*d‹ðÚS`”B 1ªŽðŒû€Q­KgŒò†Ì TÕ‰Y­Ñqõ´å-rõ&PÕNŒnŒÎ¥è„§¶ƒ®ó–3ÎË6W9{#ètl·ÏDCä·`Ñûý+‹>w߈ãæQ+§)£x_†à„Ž5ÆèºTõƘI¢e¹®=&˜îoÇ“n»›«¸CCCŽX*W/ÐÒ(e‘ž$¸X{?lËg` ÞOJ¹ÊÐ!¬­îþiûä¬Ý9ÎÁ˜½¾Œ4JPV Ùd×fÝFô”F+Þ™ëôå°«ºpLqñäÛ¿Áå7ö¼ëÙ4ÀÁ¢µo‡3dÈÇ!ð*°/Sê%?y ç‡KF]‡‰©‡WzvZ²c”ÃBÀ›ÁX®VxS醰ûõÂÖm“°ìá-ú°ïl_åçpÜï¤M CO4ß»—mCú\QîèŠP‚C+s ²àså5œß¶îg/ƒ¹qÖ+[ï ‡€dâù6M@ΓYTˆ>dšÃÓÖÙùé±xÛ<‹Eop`m|UÊ}Š4€|4aö Ø küK_UªS{ÀN¾%u +“×D“S¯Ñ†¹æxƒ‘~Æáàòü¡'?ˆ=ñWÂÝs8(x|ù‹?eÊ/Ð1T––šk¬«Z1íÐ/ሟ„så) ¯ü‘ª¬¢²“óƒ.- _8žËBУ_möGÆ›GÐB ¯ÅÆ€¸‰ÎNL€îó·ÈÌߨ ¬X)ÈQâ:ÙŠþº‘Ó~÷ÅÄÀüðƒlgùÅl0•cW€ÌRwöÿÖ:ë½l”2Ý=üïÕA¯Û:+ÎcXj)”žå±)սأÁ.åÌ`røSŠÿ(jÒ/±´Æ·Ö} !ÎÛÙþ‰°o0Æ:“>ðâ6Žß-ì îkØÑ8jÙˆ˜M ÷ÙÃ^UF•0‘}&]‡hž[‘ÏÙ dQ‰YB^ú  ¹Šô RûËL‡1‰ÉˆàÓ'ìë÷+(þÈ¢-ÍhyÚÌ&&Ö(M»Â3ŠÿJ!ïJL ¾äþÅüŸ Ì.¿7kôtk+ÿ«kϵFc»ñ´Úxº½EüßÓ§òÿûÏ¿ŠKÇÝ®rO€4U”µJi`ûCâfÐ÷iˆvÎ"Î8ÖQ¾Ù¯|`ʺêÈåÍÜdvÚn¿’Ë!qZ=™î°|¹ põ‚ýÇ¡”á/¢QœÃsqïͤbÄ`"A|š¿A"*r™ðÐ@…@ºØ2ÜŸJ‚ÖۯѼ¤ÒâœÄ!pj.§€y©àŠbÄ?ÈêÈs)e+;qÑPUH|ëÀ¬Ž"°uÐl_Z —èÄ[a ƒ¨º­Âv:Á%“ÿÓ)5wx£íPxMb´ž3Àa¡ÆŽ£…Æ>Gb ¼ó:©'~º Ãi°»±q{{[¹³Šç6ÆŒ#ØxÁ­i¢†TE$@K|š0¥ÀÉnÄ:VS (¢ U ²¤1ˆža)M»Ô °qï/Ažd5’ †%åítPüªòz—k6@"Æÿó Jv&§„s Ëô½œÔX6ԫЃ–"™:šâo¶€OtñÐ<8uëÆÆ)æ_ŸÞ4ò¥ ù€œ(½’‹ÆèÉDú¶Ÿx„ÊòÕ/råìʼn–A©R’0Õ€~x¨—zûø°ch$jRv̰V¥ŹÅAñG$Î!$+Ì)LU»ŽüHÈŽ»‚S«é È)ÅE£xG £`A´ÑÃEÔbN$bÁT'd£¸5Œw:â“:ßJNî4$œ#VÍ‚iWS@³…2¯:Ôšî”Ú5#'¬Ö ðïÖ•Þ>ðò־ܸyº'ÙxñÜÚ»{—½é–õóá^ÄHÌQvˆ¥²ÿÒŽ–-I‡@Úpå ¥ Œæ¹æÔÙ}oäÒ´A„Ø?9§žS+]lè•–6¥´%,Þ`Ü-”Ž^ò8¯-^£šÔƒcÞ²úWªjl©´Y¡Œ¾Ø:N±…\íí•E9­clqxVeÂVÒ¿¼³€Ý§o,.Q+1¶•ÀXgÂåÐq¶m /S*SѳdïÆ°¸’ä¤ÂÃo‹‘KFͶš ¨`bMõ âµ7 Ø›‰…{"]# ÍQwãC,€TXò¢‰®qjÁÜ7yyáã²ZYëývÒ*5Ï_5÷ÏÎO[§åÎIë´yÖ>~ÝëþÖ=k!aÕ‰7Áà,“‚ľ%¡fæ—‰®.Fû·Öéqë0 ;knÉZ/”Ñøèª…ŽuÞPÃxO`'¶ÎµQçT¨¬m`:…\ŽRzîåßçÎñaW¬VÅE‡®ë>àŠ-½ÂÞB;°ƒÍÃv³›Ëí/¢JäÇŸËuXI¾ BAùj]”ËWöxª% EH6ž®s¨+$*X>ÄòÈt•‰ëÒå‰,B7IïOü“ìjþá¹0êS¯ÜÙäÒöM Ü)§¢»œxC.CÊó¹œÄˆã‡;3"!¢¸ª¹ÆR.÷5\'Q y¶RÞ`À›™ßçMŽünq¨ž¼€7¯O;渓S¬ÓsvDΠᾆ‡‚NãŒíåsgþ½xÿqÖ;On!bœŒ›xÂæx:.ÓvdèÑXúV­>áÜ®ƒKÂrÖ”©)Ê­±>ËŸkø -§Êe®càÑ!õü¹D¢fànæàäÇy(Z¶XéÕx5É9q“`¢Deàp½©d§Õµ#éU¥Æ‰Så^‚¸­Eiå‰8G¦" ’çé,Ôʇxéµ¹Mì(¯¬yµ¶ŠÉçb±þ½Y{°›×4¢'â&·”‹5¼îdtŲ–ÓD•ίJ¢öZ¼]EÔL£ýŸš²wäxҟФWKf_ˆqÃèæ’sá®P”B#n! «•ëZ :ôðÄ@Í£²à©1ÈOÙ@ª‘ÔÜ*57‚#äúéä@ºˆéžPpÁõÜ!⨈wW4¥¾/áýw!°C“Y¦0MûÖÖÅöÓFÏO Dø"B…¿bȶ7è&F¯^Q½ðñ(…íKõbB/&—ã6?ÚãËüxsQ—UãsžoO/à_UÍ/èßF_\Zò¯ÝÀ¬Y—6t‰_ 9›ÈA›w( íT·j$ѶäOƒZõÞ ügŒÁ´¶}wÇìú5¦‚›:Ðe˜xz7tÈ6 ýF•þ è0T ºÚvPàß-þ;ZòO­rQ­}?p¬ôÓ…{«Þ«ö_ÙwÖÈ“]pO±´³³Mžñ«¶Mˆ3¥Ö:¿×«U9×5oÂOc ± ñD5pºà/ÿ'»°J]ÀíˆvväÒœXw¿ã‹KüGse±ÄùM¥Æ¿ö”þ ­‘D¸à?—¶|°/ÕÃX>Œí¨4tU?Óªå{l¾öú¡MÚ-óg¢ˆï˜%ðW¼€¿õŒ;ýŠ ¨“Ÿ6k0ÿœ+ÒˆiÌ٪ƊàϹ"ÏâEÍt‹¦[?Ï}ôcŸý”Û±Û‰zèyÍØŽ˜G\ÖDüç|ÿiíZ$_˜ÅÌqš¤ð®ñLDú“[«Ö žj+M¼;G-ÈPþ ¦0}üìqúKû‡žÍvâ/ñO]ý¥ÏO²jÖ9vÈH¹×P³³ƒŠŸºŠÜ=¨í;LkØÚé?é‰jê÷6Å}-ŸhÂô3µPþRûlêÏäýoM@|¦ Üõo¨kô¤È‡?~ŠÍò%¡ h«ó#JmÁÊ—›ø±¾ùÁŠž¨ßøÜ £€ž6?È·òÏ%Û.ù£auMÔ)ü£_Mùì¡¿ü•Ÿ.£Çõ¸³}§Çv¨ÐDv³£>Ü<‹ž.£ÇUXŽ^h]yØÒÐá“þné‡-ù°-ÿîàÌ…¾"ô³KÔ ¨™½3Dð[ý­©‡ºzô››†„sg&éþ­h|w;¸éîú5ªýŽT÷tˆÜ…¶È£ô¢öìTç³8ï¤ukÌÚa/çA¸÷sE·2ŠnÍÝN/¹,8ZÿÿþáÙ‡yš­r¼¸Zº«¾zªÕõýÔê8rî °É¸`²Ïô…ܬëE5ï@ÍòŒ­Ò*ßþ 6~–Õ6è´Ÿl1Mº!Nàv{Ki&A-…ƒ㣓[A×wÄ|Xx5£³û.è[c{J%÷nd…ö×w“+²/S«²/“m•ÅÇéÅÇÉâOPm‰ ÷Çi¿ |‹ïƒaeÉRly±V"Õh!зÀÒãeÝxŒW$6ø#D±^"yàÖó"/qå¦S¡kQÔ§"ÆK{ä¸dÇ·$ h¬8k¼Õv¶{Û¨ÂHê›7íc©'¢sùO»¢<®Æ\r3…jT³V†ÿÃQ"ù¬í¦Y¼ÿˆrÛû®¾³Â7q-öûisµÆw j”yEåß[á¶=,&%e$lÊk‘h£ŸY¤)¯ÅÄý% þfˆ8æ‹­móI&1`…:&ÚÄ_™(´xC¢$³\ü”5%èhPØ­rý(;ñƒ/[òÿ½‹V ÉPô–¤(ýÄ#~«…)ý„(ó*ý;3)T©Ÿ¸K© VüðL=€p%"p°øåïæ£¥žÇjªÆÆT¡¨¥žQØ¢(g釱^û,uñ<ªòPPoÛÑãÏuõ¨7(üzg‡[‹â? “ÆO(‹i-µñ7Cˆ‹ŠLùE6ý(3‹múÑè ‰næ/¹3•øÿÄ›Q@‰p‰b(¶™¥XŒ‹"vß($Ùÿx!¹ï"q.ù%¸XéæŠ5’ÅiŶª‰b,ÚÍ{–,6×tÊt)âÍðEüÔBÛ‰BÛs…ŒI“âÞ\xU,òÍÚNJ« $½x)ýæ‹¡¬—(ÈâŸY4>–)‰’ŸþÎb þ Ôÿ%;«¥H êÏô#K’ê§”% LJ“úÈ“ü~¶Õvñõ<WôB‰„ꊕæ³Y)dªg’2åýMŠ›1ìú'ŠœòQËœrªX)bšÏ—æ›èHŸÑ?cÈP½¸Ù‰ ß<3Ÿ/Íÿ Ïsp§×I¥ú‡£˜RÕÓ–ñ¸¥·õStB‡ÎØŽPûÑjS¬ú‚)“„=Õ¢Ç z¬7 ÃÒÓÏ’­úŲ­þe›ãNžìÌó#ʽü‡Rt|k9˜¿‘$¬ûvO‹QÉÅTâ†Ò#xâäÕÁ:sÊ£±w gsØ¿>YVûH‘;Y»2Vœ>Ƕ0¬«¥ 4y]"8YoëærIÝV2J÷€U@ƒB6™Y¤Ó…æ6v¶/ƒÁ|kÝTI ŠÈ†6H™÷”UŸøÍ(á ò|;íˇÀB7ÐXÊuî¦ýÔë¡*cÐØSŽ—CTÅ+g˜"S¢\bM²Ñ³£ .­þ,H ÷‰©°pç;×éÍ L¢«Ð™nצ†îÄž'ÆXÒ !iéo£º½“u…†ß̺™Ñy)©Ç§ F„D×€ÜP4ǺXy-³ º:L˜MEæ[lµµÝFë*EöGQ’¿©Q¼n4Œ3¢+1ü[κRLÌ–åqħ<†µJ0 .TFs· lø¦B@F>ÙSHŸS:,ÁRwá<¤1­~Z?ãû˨âÁäŸi[_'Çsv—Ù”éX-0(%Ë_Zc €3Ã\޼S–`ƒ{c8¶ú× ýÎC’Lk2)L¦-}ÜbGoØű+nʹœÌÙ#ñ±›©9}üâÃ;S¿ú·³ðmºg)d^’¥—¢Âh$§aßõû©)iP± "«¶r?E;Ú¯I›·¹Ý¡€ê)@õ‡€iP‡Á6ÓÀ6ÛIÛÉc+º¦ý?=)„RªbEÑØdªéfÿ¤-zŸ={<Ô°d8s3i2–Ð…€/¨äë¢Bߺ©5s)444PHø84w—Vè.³c‹ŒðOæ)…Uqm¥‹@ “]`™&ÖüÃ’ØÄ‘e ’B)I¡ŸŠÈ·F¶¢ðRÈÉ’ † =䤓8ê G}YõÇ8Äs¼!/É¥m9ù›ËɼöBh³[ª è#­>›•ï¤Ä;ñÂê,n(@\ø)‡ê¶y¨ŒM5øçhšrkäl™“X*© ¦wušUü›¶|¤Ä|9+éÒ î è¬%g@˜ý²·ªÕ…?dh±…¾êù`Šåãàå'â£Üd%—ÏÍfm#¾ž * TTÏC°þšþ£ŸlŽD‰7Ýþd±.\VµZ¼n‹ i¼ÀÖü>cZ0©_xŠŒ@q‰sxWœ) õØqY'³¡®Z#Rú¦ñ(ÚóÇytä¥xqVËÈâWêV•lÕµUr’Õú5e¨žjµLWW“”ÝÆ— ØI`ÂÝÁaµàk ¹•YãÖ¢É.>ƒ˜ðÇ”-w5%MrÆ‚¸ššÅ²y*_¿q5ÍäÑ5–‰`®Ÿ‘‘&ýC×)Æï¬¬ší|v]Ob¸nÔ2à¥do\Ô³+LŽÊ³ëíDmÛnïS(üÔDa¾X°jc8v ð ùD¼j¿;jíbl#¼lV7W»Ú¼z¬VãÞWQëÉï£G,ÿtçÃ3Y^?Âûg ~ù¬ñ}šEc\kl?•}޽)= ‹·GÎܤòáu1F0iDoJE,Úb*Çü“F¹„XÛÙ¾I£”™VÕqƒoM"ê&Â͵oF¸iâûfl²ÀcwÙ•QwŽÄ’qØàÅ3ñ#Ýç›çα ªˆåü³9È`šƒÒú˜£q¡e€âSPÑ;þIŽðqS#+vYel"Ö™Æys47b ó˜îI#{§´#ƒo%b°Ð„?’ͱF£Ž/¥È2µ2óôú6íÊĹ³ ß—7ª“ƒÿÌÖÄöÇiê"f‚f¡}÷6KÖ¥oÌï@­Û踣ۇ´¦Ò¡ š`©¼TL‚Åâ@}{ň.;Cߚؙgpäe(AÖæ=7à×Ú‘s|¦þ~…?Ç ÎXc­¼€š¥.¦¼Á·äÆ&”ßaBà „B`F}ÿ(M”7j(z•&¦ÊPeY\ß9ö¥—Ƶá—9X.­M+{©PdKøµ3“°lÌl¦W4”QÅo‚…')¿Q¥]«ŸrC@Æ7 #D(¨`ú>°ÀiRÓ&´ ¾¦ìlãµÔIÂ¥#Ð[ãl¥îÏ›ÍqÙ·/íq ¥“ž¼øç)IŽø´£Ÿž¥õV º)ë¦ÜFNWø£VÍ«6ª É“XÞ×Ó׬s1GÿæiJÕð öç)¯t†ž¬‘[tFWñSú1Œ_‚Оb´ ó,a—õ¬2âvrÑúü¡=_¨‘vz»WjætÄ„¼þ]4¿W›[ÒávÁÁrº¶¶‚Ñl  Õr¢¢ÕZˆ ªÊ<7½ty§›.‰L}¹°ž¦hÝÑœ…\Áõ<{e¼‡¶')eõ7U8°³ ëoº°¿ °Ÿ,|³ ðM²ðÝ‚ÂwñÂÞt«Ê–5Þt»Ú//Pyx×Nš¬&>¸ï[ûÐLÁ‚¾ ‰£Ê 6ÓÖ×ü=”@¤¡bß#ÒQe’ à2uS^u »h¦bdj)-Ê×)…0VÍÈs3ôaæd¿) ýôúp¹ –5•ßÈâN/Y\|:ºÐeÆèe0‚ÙTláuHçKŸ5ȳE¬‚*S^Ë(õø{À)¦ "–~º…ÁpèŸm:åî€ñDK Çê7éÉ 4°qÂo³£‹^éæ„zk‹Ø“ƒÆ'ò¹=:æûÆ’¸RdçiJ9¾¿Ù¢?×ò$ñ`°aGêl}ËÀÈqõ\á¶²âa+g ÛW×ç8\aó‡ÿÖøþ•§ÚªÐ”|Ê’3uc‡ÜR64DSöÓ›ö/íÒƒ2‚àaBïw»"QÇ|0LsŠŒ>çZ–0 % Ú¿ª• f§#9{®Md¢$²Šeýæ8Á¯Å#Eæ¢)튖B³`¼ä+ZdÝÕë0] ±5'èL#5„? *ü³ŒâÄM||øÉ û‘Ò·?¹@÷‰,…QàØ[_ƒù!íDü“z¿Š¦ÉÑpgd¯Øx–zcCïã¥ïdñ»¬òw&€UVOkx¦ÁbpYK禮«/@2¬_ ‘ô¶[ v&ððyÎè!°¬Ñ·µjÓv4$-¿2VFdFe¯¶Òº¯ç¶[àLOÅiJá±Èä>ÏEq"àiðt¹Ë󺆘ùi5Íüd»Âz¶ (‚зÂ4‹Tâså×-†öýdCnôþL[€Xàñ„%˜¹õL)>Å`¿?P’ZŽf?Øæ²`›X#«¶ëu5²êº^PÓfjMÌ·gWµ™ZU*”YWúÝÊXü{†s2µó±©z e '±Ùüàë†5ðg®›¦óâ½Aߤ*t[ȲC î';ôï¤ IkѰ‘¦!—n¤™Õ…ivrá;9òˆx¤‡´ŽªpÜ5ž¥SJòRŠ“ öUÊ.>G¹C˜Z–=ÖÝõ8Í+Džiq¬z–\OÊS˜ŸlTÅT pv-c»q°‘eÇ~?ÓÔo¢¼–ovj¬9íãSŠÞŠHÃkýƺK¹Eo”AšÞò&ÍF$^úF[‡ÜL§kŸoîàÿÓ6ä°Q­•‡³:a Ö†<޲5yY'—ü•iaþ\öôdÞno¥¹clo•o)£|»ƒnáÙŠ1M=v·ŒƒÂ]êíÉ¢›µ; NÄNB)øÙyè zpkDZìBÄá 0ÔÕ£oSðˆeø 8Ž£Sö~’b/ˆÎIYôG8E…†.š#N³LíLipeÀV3ø+†Ÿ7b­ÉØ*+ ƒ)¢œ– 3Å™(Ö1OÅíÖeØA,7ñ0à¶7ÁáUᕱ̺кևô«\p»Ú_¦ 2ûŠ“t—t¥ø¥ fflFønÒŒ #BBzq¦“ñšQŒÜŸöŠZ&NOœ'‡‡\+Ó$Þà*Ã# ¤JS€ü–‹št]MÓp£Ù³Ž*k®U·²ƒ/&!à;^-MoÉ-¾_†§|VhÈlš ¡Ô-&К¶°:²®1Õ&ç!¯?ÊD3Æ,w÷e3ÉÍ æ¾§¢ÿÛÂ|¨‹ŠÄòï¨}oÆ]Œ†Î²¸V8#'¤û%‰²²¶ <"Ške Œ=ÀÀÍGªamÿÒ µÊ¹3kÒìgY¥I@9Þº’ËQôð»kfޝá8<7c˜Ó²PÒ!,V.®8\(Tˆ2 YãÐö]NbtÞ=˜Ž ·*¦öÔ$'‘F® K(“ ãDw2™ìðÚÚÙñ㣆 ûUçì‘§ËÙHÒzbÕøS⬄Îëýy+Yˆ‘#ó´L$“ÇKÓx×ãéuPÄ;ÇL¶Ù=(ò™j2:ÏïTŠ©dÕÛXÙÅ#˜ÉD2{²õP¹”âˆëIøí¥à·|ÀG’d"”~RŽ<]mÀ &5²ÃyíG\6ýÒX}'Ê …Ð(cÀN#[ÿÔ½¿‘ù58}~¡ D¡hÕõCEÅà &'è]Á¹®ä=³Ê~¥¿ò…yÒNT~‹zÏš§?ñmÊÏÁxb$€rS"S¼U¡EOHGXè3¶8¶'ÍÑ5oùP­®?D*ö2pU!ð|¥oÃ2žé©ÁO¯¾4ÒAH*Hƒ‘©d)ÿ[ŸR&QŽä’@JQ«ì‘©œîPV.å¸ BÂÏ üÇÍijÕú¡,1à¥?íòÔ¹¶uªs7tÆä#'\f f´ÓÕ GuÒסçSqLvêôQ—)†¶…j%¹Í¦ë ïQ‚ÛÐSáx:ZÊ)ñû QgnŸ8W:7,ÈAfœ¬@O96¬þ8š‡]äNae²ÖŽ`âðPøÎ@%ŽþX.™)0І ß`MWÒ×x!؈Ý%/¥Û’ò1¾¸¼> Ó­= âžÏI&s~c¸]Ö©Ä‚kaNtÏ¡Å3ÛȬS&Þ€ŽZ¡™ñ=¦ºœÃQÅ|”úÛñL½ð~JI¡9µí­u¿>§^ Òª 4…ò{¡J?OùÎ >æv8{nèßGìJ>–‚7Ï*€bÕš<@ù’L‹ÙÈ)¥ â°eGZ•hmiBXÞx_ha ü ì›JêlV#œÓYó겊0óhsž—Kï³Çß:PeàŒ0Ÿ¹NÏ åÌo×€wTÅx†•Pãf¾ÁÜ–˜jÛ“Iéa˜ÂJ.S—p ÕÒ¼©Ët–öz Î>ÏwõYC‚h­R×1™&kì RJ± ¦¯=q¢£S3‚÷© B û'æw¾M:îü' 0 ˜þi;ýËý¿´‡ÛÚkxg!`Ùø÷¾Ü¨F8bwÑ2|eiþ ‘qÈ@ê;k›6õ O¶wÖdP,MêI7œLq©—b–•ª‰@Zœ”ÒL:?å”K™§‰=MhÊDJ~L"sÿ´q^CpÌœK#}©Ç™“"Ð#mú§òÊs6mM£czÔr-e\juÁNá>ÓÖü¥>n/#†n o»ôi+5¾/Ó·dýõ×[[³è±+àµD¾¾äWïÚÉør5-ÍG”)ìç¦C,¥•ƒõ<Òktd4NfXLc¿8*RŸmΘ¡EI®e*GM_f®¥±*7+“ÕÕ c<Ä0j Æ`Ò»Í5Zïêפü5ç#Öì&*OÓ©C¤ïïæùû5f%íK0Òˆšæè=[{¦ñ¨k:!åüªPæÒ"C4—?õÜM£†G¶ªs{t äâÔt{XŠ<Ù%çÙ4¶6…Ã3t2Ø:Òn¯ä¼ ä+ú€OD|V—úÀ¤‚¼%ö$ºã\±S§M coäpZl£HŽ =uœ}3hÜ”Æ=úV”Ò–˜×‰SzA<¬‘ãeØÔL—ÀKƒÏt…+Å7ïºÔ¥DC!;õwºSˆ}§ú;ëБo¢ïÚ¯IšïŒŒv¦KÐÅE¬Ä`d~§ŽØwÚþf¾–‰•qcuн€ÔhJõAÖ°Eúƒ¬*­`4=Ú^O—QâkŽô ¥‘ŒA²i’†´’£¥îé£y™NK¤ ê'çgßãDÕô‘ú<·¬µ‘o\€{ÄÕw>Øûmc•±nä?š7ÞiÀ(nåP¬B²rèá^Gy1Á.¼²A ÚEk0(_yÞµ(ÜúhN=tÆðaQÀPÂeÊ‚L á¿~¸+òkßìòñCÌЂEþk÷¾ü_Õúÿ$ Aw ¶à1÷—ÿKÿë—9 ÊÀ„mUª0?aÿ7 =·ÒÿNu³[ÝÞÜÄ¿˜¦Òü ÿÕ·Õí¿Ôµúöfu³^oü¥Z«?…WâÕ@rgªúïÿ’ÿrk9±&ö½é½OV Å~IÔ«ÕM´Ehã ,Ñ•ŠŒ}Ø{xW<±·íö+¢˜ow÷ó¥yµg϶×áŸgq<ÞTø¢ À"ø‰íO€ü¢–„ç ìÓûu1ñÎðž™ Ð ‹3a³x(|~ܽGDÓ™?Åxx¤ÊŠÔ” m[™_@“F¾¬GªPi[XE˜úºGÀº8}[ò5(ÖGUŸ¦SÛòÉLbk·ºˆä×öÙqÚzÝ<=gÀ ˆ"¤Çû‡çíãר>:9lúè¼BG­Óý7ð¦ù²}Ø>ûê}Õ>;nu»hvy,Ž;¢õ¶'K÷ !‚6½l‰ÃvóåaK¼êœ"̆Û=ií·›‡ëÐâÓÖþ,†cõÔ9ûãnëΔͣæklÂ)ÊŸÔ¥7ͳn*<…ŽuÏϰ¯N;Gâ°ÓÅ6‹ón êhž5† Û]¸ é)6¸yLMÚ?kwŽª>;mb;Ž[¯Û¯[Çû-„íÀYç žw%Àºhž¶»Xiçü ñ‚¡4Ç-FJãŽ3m¡V´Na Žš„øU|pÂ7à\sÜþx6°Eik/°ÃÙ´r•ÇÃ=ošo[½ãt·uÖk÷ÞÀ!#ÌO°O -®\½È=ƒÈÆ ›§'ÍÁÆ-j_wÜÞ“ ³~(d¡í0¾þ…?z˜±`O|¢ÿ«®/ü?ñÿïyަÖÕÃA“ƒÿ;9ëç$‰¥»}üе{·Y üþºáºœ?l¢©ô ÿ¡hŸÜl ¼–UÝ A<£êÊð¾@H{(³B ì „~å¡y*ïú÷Ý] ]_]:ˆÝvH)íL¦3Ìx݃Ø<œaØ@TÅòeˆRIS+Ö5*(P®¡6šì‡–3F{X¯Oò@W6È“¶ï»^ ([븃D “fh‰vkQ«Ç%6tkZ\ *P»Q1{¼Ræ*£ª÷;o{­wû‡½CPvIQÁF2 Œ]¬÷@‰Ígë ÄHèU3yÝኣ¶ŽœÛEÌ!š–Ðj$q=ÄÌ­ã…;B-c|ËlË 8¬6«%9縼X´¢ãA®ÇF§Põ¾gaz0º“ ,º ¹?Yß̭/ç@kÛhÊ´™Õ^y%!M¬àšœk,`¼oUjòHRRbÌ…íÆØ,ÂúllzY’“5±£Iœ¬6¶·eU‹‚ÒíêßxI:l_ÆØ¢vqnÀ>O—+þþ“l ìfEH4ÖÎnhÉéò”Ç¿É;—F­…iZP£ëŠÎIQGS’$*’¥Œ’±f§]ÊY§O:ÜøªM,ßp%Úü¼5AžÝÖYäœ" ªD©ì..ëHu_wÛo̓ 3$ ‘bÍób køiš%á<$­¨ %$ž LÿŠÚ ¯Ô1⪇E\³ÙÊ©Ä%Ä”@æOœˆ®O™àŸÆùyæ>TqQ£ãŽv!¬Þ1ÈÍH„ÿ°}/ˆ¶c4¨U}ž!‚Øq†/~LllÊÜIˆMÁÂ/$íH!¾åŽìÅõÃèÀ¡0³Ÿüv¼ÔIu]C´ˆ—à)‡á”³¦¾¦®œeÅåoZK Zc¡éR®¸ØŠ›=¸âP>øž+Îàj+ V=6-Eæ®”¬=ôÐvÔ½—‡×Ï‹’%DÈ•h—)5(\ŠÒ"æµfCˆsÍßcÓ}Ãp$v/oŽôAEkÉ<§ÛþÞJ°Þ8C ¶N}P¥fÉRÍ—û­W)TDËãn¯}¼Ý<88íþýúX §ðœíø§ï=w)ŸÕZï²ÖŸù¡w­*Õë¶Çß³¨ >2õK)Þä@Ò[}îb  b‘(Çk;,C¤°Ð‰Ò:›uav†f;‚e@®}ä>aïS—çÌ×J¢±‹)v~Ÿ9è À¾ýÈmÁú%­HUA +L-í‡]¹èå?âë¿¯ç¤ >¤€~Ÿ@žÚÆŽá1S¿â0ŒË·clu1F‘•† ÞèX"]ÂþQ–={nVZ†°cwúIršêÅçT:œ¦íCí܈yÌÍ…ºŠØ@×–¤Â»áMÎ\ļjÌIõ ¯¶THÆ¢ §æK³e1½›^|†°Šš4YzœÕ¶»‡qÂýQZt „Ó´ó È‡Þ àÝÅ¢z7>‰¢óëõž£˜zdîÜxø´D ¼ÑYI¬,ê¯©Š“ìÍçº@â÷‰06UCýHzAÙâ.È ©W«ÔˆÀ¥ûÀ¶ñ‚/*ñÈØ,–´L9×)VlÅW£¹9ÍÝœ¾…±Í/χ—ÅÜZzìšXrE|™We˜Ê2àè‰Pщ€ØXÉ%jÀvmHU‚ó÷Ÿ„Ts©âuõç&þiÇ8(X,ê –Ê£'gnß$ÉŠ¤õ.:\òQ§Ó„áb©Ðžk{³`|Oר()³¯D±ylM§xêøö­ïÖ¥»Ë€•TÁ•3Äc‘ãâ;Sr¶‚ǧËÇ]YD‡·ˆ—p ‚'èÞâé&]¼CËY8¸‡\ø‹§ŠÚkE¼²pJx模úš‚ï4aH~ˆv /w:Í•¹Bó¨sš`º"–ÃS\ ;j²ùë Ý‚Íé`¶úÓû"±b0ùëŒ1&ïÿ;u lËfÄP´†ëâ!†?Íþæ R»¬ùŸ¦4%Àå>oUTDžýœE]Ï’ž`A@o`·0…"7…æ+²ÚÉz›Ñ5l?€a;ƒt\eXƒ4_wð"¼sz&©dŒ ŠÀ&\tï?gû$Íá’¦QdE£§uÉå1Är m6ä2&˜’°ZC<7ä¨0eÅïÈÃoX”f`ŽK`,‹)ž5¼½:fD¦qÀŸOK%KH¬!ÆI%|ïAÒªŽ† ò`¼k৤ûfeU“¢KÀ÷³¨‰]!i<ÿÅçSÍå7Ìà#E¿o­{Þºò’k†¹ÍÆäy« ü™-uR‡#i?ø—?ÿû.öÿû\òР Þ…ù·ØÿooÕžVÿRk4¶O«›Ùÿon>ýÓþÿßñßþQóo­ÞQû¸}t~Ô;mýÏyû´u Šo[§]4nTjàrlaÞÅ}äMÚlkûÊ+šøvv?µ»tÜÅß¿’{»u‡ë+ùµ{?¹ôÆéßö»ÞÌïÛûÞdšVa—ˆñ+8¢èJÉχΥoù÷s¨_Ÿ·dYãñƒ©r'§ÿníŸûE{Bì—ÐE©KÎ@­Té t̆“7D*jž¶º=5fyÞMy‚W,Š)cç2ôÔoEÍ\ùø§yrrˆ—Û ¤¸s~ºß"¿Àö! I1Ÿ[Ñîz?áÀñÐÐxwFK`ßs•Ia@P×€–Ѝ:{Ü./^ÁÉ›Îq‹L/rOX%yÌž]Î fX‘«J) "…È L´§aÖ69¥Åß©Áh=Ó“/ð“díP*‹$²Ÿy‹U‘[Œúçtºâ¦V]Ô­Þ[LVôõ]kÞXÎØbYå³g¥ÞQs›üN7ºVíÕˆ¥…¯(#¤€ÎÔêUÝîùšK Fv½Ñà@k;ÝwPU*„wÈö3Ç PòhÕêÉ ÃHÎÒñ•¯ösçÝ´MÒ÷+Hrxa Ü@xyÛªPò¸{XÊ€C}¹f€¾~ó’6,é»Ï@!ÿ(X†1¡5Uˆ£E7è Mdé³Óó–1 Ô mÆ¡==èqwÆ`œž¡dcPG×îÛAÀœ%­RE%Aí½â•ÜœáÊàb¹é¿u™!ê½)eó™ÐXö= ÚpÆNVmøo/N:K/ð´^MÔŒ_ð,øãÐð]Ì®™îg’€ IúéLÀaß Ç逯öÏ3€ÌÏ´Ò`Ÿ-žé±3q µŸ‡í£öY6äE¡~*äðýlH{âù÷é­#à«2!aM .Ó‡ÖÔÁËE€:°À< FðtØŸà1è³ý“EàÎ0µ¿Tñ«ì}HA:S!»í×ÇÍì51¿{#ÈÅ»ŽÁK•  C 2õ"P ù™ZéÙ¬ÅEÀãeA¢Î'’nÀÓ›‹bT÷ÐŒJt¤7 ³*ù~1iu¼~b§kÒÚîì/Øé<µ|k’|ÒD}NÖïPšiŸv—«î•oÛ/»¤¹{"<¼o’Ò_ 7*WeQJÖÉ÷Tã{áÛƒpôïhXÐ$ÚyCöHµÈŒÈ u{`)Pá¬>Ò÷Þa«yÜÉ ˜ªæ1ök¸ÖnkÿüøŽNï urÚÚožµÔ§c˜…³ƒý¹oŒ þ=>Û«ÞUy"”DÓ<€ÅÙzÕ>n£–§[\ý¤Úñ÷ÞYa€óýr¯­KŒF¦µ9t/AÚžHâ2…ÌXYØ„ÆÁX'$g ÖýM2ñ,¹H30héîa$|ÍE=gÊäàf8jîŸv”Æ„:¢úÑ~… ¹¡zt<Ë+ÕO¨ÑG½{JÝ)C•K_ºyY7*d²ª/ÆY|iC¯„Òƒ€;E€ãõ ¨¡`ƒh­>XTËò".õ?-eF¬„¥ËeÀHh‹ÀH¼[NKš §eÒ¥aIÎŒ`I"}xn¤¬(¬¤ÊÒ‹D/¡ iKÀ±ô¤áXÎZ®->)Ú-µø¤ä¤Ÿ”±–U¢UBÒr°RðQ°RDZn¿( ô~!¡a)H’=„†$)åA@£:²é_®:©{RPRKõ ˜’:$˜’O„‹¤‚‹D„‡!µœÀZ¢X¦Nfé…ª“’˜ÈJ eW€¿Hr@B×C?Œ7S ,˜9XÒZœjØ&Ë+ ŽÅ&F¹&cmÀF—¤”w6²å£Ÿ&Z¹;”ÆÇì¶®2G qã̾õ­©nÐüÕÈÞÌg«ŠJüð¡æKí35“/sQÝã ŸÈã}qÊ}Uü%‘x‹\°¼kL½7­æݦgžX_ä¥ò|½«Ÿ¯¾Ä*ÅÏÿ—y>íæjÆ«Ÿå‘ÇîaVVVV?ñí? N瑉Ѹ·”xi\¨ÐÊÂÀùÚñBŸú”³Úœ-Òëm·¦ §¸uAè8+¥ËK‰,É–Wµº=™GN``L|C:¤roÊ€ìâVÊÍ1¹ þ“O=ì¿Æÿ¥WëŒzVèMœ~²nu,öšg£ö~VÝÊÖ}0ðÑ€/?§ê;‡c½Ñm! e)ŸŽ¢}¼Mh¢À©§ ­€+?‡ç Q ®åРó‹5²óéhºgÓæëÖBTx‚ÜXã¼Hí7o›‡,‡0E¢4õm ð‹îúQTVWXÝߎ^ÂRÕ(/…<¿ˆÈnDž ©(;(å¾<„N.2‚É@ú d…—íŽxL;%LÆ.03¯Û¯p"–ÆÈü™û¨û:Ä,ᲸM˜ ´'_1Y'‹'«›˜­ePvÍÙ‚u÷n3ŸÝìÀQ;Ú%“ò“b‹²ÖÅ@LLê¦V]Ç«rº:_X ïÔñˆÆDhÖ}âò–O:ÆÉZøÖ¶®¥ÐÍVÍž‹6lÌ`üÛN·VÝ J3åTcìÌ5X¢ï[Á¦Töìì5“]á¡Á§2Ï WÀðvCLëöq8zGãÎY總¯ †N·ÜʉEø*Ø|…"³=>ÆŒVR§*YÃ2SÅ0¯[gÄ—jXS!ëbzò¦ÙÅûÁ—­Ó ’ ‘ úÞÔî9ƒ%WKD4aëà?û tíqØ<~}PšÂGô+x˜G‡HÛ§t•ás§²Væ²Ï|“¹à>{äððyä $T³‰h¦ô¥ºýÉôQ´æeûìxÿè$c—Áê li±,F˜ºn+ng‘\ˆµûÕXA:je‘š¾çº  =j dTû Œ$ÔìÁRå¢,|¾m+¦ai|§­–ÁJ¤¡cb] -쯇±ÚîÍã:X[Ço³²yÅ—_á›N÷ìåo N®¸ÙÏ#ñ¢’h1^‰õQxcEŒ,ĸx²ÐÂñòéMÏ_+š5¾ü ]0{ Fo8€#mùö"ñî¼:hþ–ÖöÐGà.ôx|—be/8€ãó]–G2tY¿Ž§žÒ±?ì%÷ÊO|]Kï|C%bÂàt˜c6cÌL˧@ ‘¾…£Þd»…‘+‹æ Ó”—*щâxÿ£|ÕÑ“CfkAŒ¨¾F_ ûn ÇF,ÅtÊž[F;)úe®äu8"9wg›¼@æ™Ã†W2uáЛ>‚0ðŸuNJ‹Ê){Rž²„)]9*ýIljo^„ï‘g#á[x6¶k÷«±.<}»#9§­ý· Б³Ý#Ña&› ”^÷=²…]˜öLt!N7 ƒî ‡²s’5CÆ”?BòX0å}Ë l͹-…ðìt¿Ùmesnˆt2u×J@ Li6ÆÁl*‹ñà|ADz«x °°Ó®9”Kb<~p(]s,—ƺp,]³ïË¢\ÐwJøHNí×ÓöYë-É0W4Ýï9΄.óÀËë]:c”éB¿õøò6¼Gé¶Xâ\¦öé`ñRVùáö9“©RM9à’«ì5© M£KV¹¡¤bø®L^Sî)ÝçÔ¦p×zÊ$ã䄶ӳߡžžó%¯=óM¥Vh™—½)ãUzè28½€¾ø%5×wþz‚x](2¼ŽnÌ0{o¹. öš§¯ÏZÇgl´Ú:;?=o›‡ç­nî ¹Û¢9 ½3òvf/­Pc\ÚŠ—Á 1ÞltE9ãøîa‚^½']³Ñù9´®mºúÇÜï¼$ø€ a´ï)A‰Ctnbk ÿƒ¶/VHKi4³CÅ¥0…sF7Èš±Øƒ\‘]­í¡[6p9ÈžÆB`¹vðÉÀ.¨ !¯éàŠ\•¡‡ÔßgxŸ¹¶åÉ·ÕÂ0Dè^[©T躖£·4Eª',ÃKhý¸õØ·-èT\ t‹Ç”÷ÚðCj¶# CA|\{¨;§Tä䯔ü¼O›'mÓý{HÅf8^18~$w{Û…WôÒPG2«qaQ¼Up¥Ô°ˆB@«#ò$ÌB帋ÐÐ׸KÉümvVÞQеtš Ò€†žûËG3NP4¥Êj¹ñ¬–Ô„ªlQ‡¨`ÔäX‹³çN_ÊÈéÂ0 NÝóZ³Æ·Ö}™|áb…ý“Qý¶ÈGøÖòª™†h¨‹Ö£šÛÜ6Ë=Ð{¨žbY?P±1çU&æý‰xœ`‚1Ù5 FÏ ý ŽŠƒn7Öß {<@’1¥)¾ÀDëkqõÓüý"I7r‘K°Ò‚HÅ—óX,ÃÚH+ÚHꏍ¡Š0&(‚O¤–¼yäÚ„=”Gº’Çpj3> HõLŸsñ¥‚†ˆoK”r鋨.ò)ŸUb“×GúÇ-‘TðÆ1-®'µŽ´EZ[PMZù§¾ØüÌ5#öU6ã»3”›žt›ïÞÕjBüü³za^löÞv›gÀáPe±l‰¡}%ŸV,ùl—Æšxz£Ñg¥c6}6+»:Œ~afbý-{bâjo`ÚÎ:±+º|øi^Ã?1M{xµWƒæ~ÌZàwÅ–Ü«Ëø*<<ЩíJƒunÆèÃq¢:7F7… ÛY‘<ȹÅ*kìXÈ}“•å4ÂX $=V® êkúT™âs&µ43ù¸#Y*¼6·4œÌ5¼é)4m˜¦ÂÞJó°‘Qb¬r J•¶…¦[üñ+êrbÃ(8Ö  h?OÇ„Ž¡†Ñ8Î~Ë©7¬Á@ŸçY¥ORvz€³`²1܈‡Z3cF#gKÃF—Þ&…óáF©’l4„ž@]Ì8ÞÃÝQg#Õÿ–} P„˜MlŠ&ò:l›ãöóFh7|Ǫ’™" cì5Œã–æ1æ·YbçŒU\ß×ÁPgh$À÷þ]È´Gwë=YƒJå=Å;ão#;ì¡Þdø²û†á‡{fÎøâU"8Z\T+¯8Y5ü^I­;ú«8zmÔ™{²‚µ©á-¦ÏƒhcüšgKŸaà ‘äÃTG…0ÔQÝ;k½C6¼‹:ÈÑj1ô¦½ÀïŸ"ŠåßGëEÚUàzÉÏcƒÚæÞ}ɬ‚,WbVa,Éå«0êˆElzÿÁiŸÿÿŸ¿þ¿ÿÏ×49†®xa•ÿh–ÿÞû ªåg½k¥‹÷¡ø°¶ÇŠÿxïÂK¨m_ß¿¯‰÷ïë¥o/Ùø<öäÛGdõýûbVGÞ¿—³­^~øQþDœÚÓ1Æ3\-–ØhõÓ—¬Vü’Õ€_¾¹ú_~ѵ¯‹(2¥’~ãq³’u€2Åœ½ÉåÆ!=À{êKÆ(Ûî@oR"äGï*º¤Æm¬‰Uo")ˆ#ýb‚LæÓ©r Q,å$1,. ÂÔ< *8@ §¿’˜‹¢ØqTEXŠè^¨BUÕ!ƒôEÈØ‹ £IâGëȰ ¸Ÿ0R… U±,9Ô>UÅψnGþ2QÒ…G~7/ýðCΟäɉ;A¨ðÍÈi3ÿ<Ÿ3¹Éåðð!£}Ê,ñþ‹ö.´:ÿ¾·~zJ±°„®¥@Ÿ¶Þ¶ña ðz 8¯5ÏÞˆbëÝÉiJ‘£æwNé&+«é_D9mPù¥¥L‰ŠQ“²0?zÚ:l5»­t`5&ˆPôdd+y …^€sk5ú†ý;⾉Íïãé ïän½SËQÝõ¥Þ—Jê'ì}ú'Ù»/èÛ¡Wùâ* (vVvT]œ©@xé=>yH– ?q´ÅöñYëô¬ÿÝT²ANß¿Á/¼È†™1_Ï”)k¿Ehe?|mïÍžÚ%T)z¹Iòd`?lÿÍðÍjy¶§¨ÏS†Ë#…”Œ«‚ÿ‰$^^VÉ×eS]Zæ¢ç‹)þ±##ˆvÏ_½j¿ù‡Í3}ÅxF¤Y s»è"ÁB¢aHgÞÃVa@dÌâùäû-?ݪ˶µé@D‹åžŒŸ(cQ—*‹ÝÝ>§ÐáäyØnÎ Mi)êZ=…)gÈ5Ï0B5 è‹Ž[;uõSl¤iò-•pÜq@ãÄq—I4ÜbÒ“lA)š/_¤Qè`©¢XºEcNÐ}?ü©}°ß9h‰3f› ó!êaÿî„çQ¨Isn8‰]˜ƒ ŸñK:)Šåyª“lv&ÁYšÞhŒß…ÔüLKxS+B º-G MF¹s"žpWÞõJlJSBaŽá7w3!i6Ó‘?)ŒEˆÁ‘—¡Z)­Ìа΅ঢ͗°*Ï(Tëk:°ÒîùË(Ìm-tâð4J‰CžK[M¦ZŒ|3»¤ê¨\±ÆC2ãêçÀÅ/ù‡µWy.ïÏÆi Z´* B¬Î/ˆ¤w¶uGëM­îìþ!:¹=RÀÙi%Bånt´‘˜×|I‡ÐE”Pâ„ñ>)ÇÞØã©IV"]›ŠL,ëfÕ[rsJÝÕ ²™Xô=Úþ½”›ï"‘/`ó{o›0³Yà …Ž;=6ôÒTH;Çh±Ô#ÏW$jÑ4.&4b¹Æ Šq‚²×Üš_3z¶¤ü[|‹-¿ds˜òM¯G ¬½‡4qIÁrqœ`$’^âtùòAâ]èßX&›ò¯˜;S3NFKæ[ÅÆDi¾äçC‹Ld\ \Ì£ í÷©Ò"ó]^üÒ9>üí‘sC`}æ~ÓcžoðC{dõïù *k§üèz¼(mïùî#–„µ=Þx@ià(ÁGÒë¾ mßµÆTÄ0[šM¤B=8¸†¶¯²B©Û–ãÛýN‘¢]UÖÅ>öV13+Æ«ÎùñIð°»±%èÞ™§¯B TJÙ(hQO®I=]a°|ÚÑ‚yèºM&x@m3+­w­ýó34yä[nˆ†ÒšU!ɘ؉KïÆ¦6Q/ Øõ@$…OÓ©Maç'™:2+0_zGžÒ©4aÀ^ÉÜ?E ±.®GUa;ÉAÔŠ£J»rVQwedjà¸m ðÆ¡« %2»;}dÂÐ3x7ºŽ÷¢Á–¹Ê0}nlÀå0êlÁë]kB˜õ©ï bÝ¡ ÊMÈßÁEnÍLܬâZ’:pæ„2aÔLÀ4DºêĬV„hS =myT ¼´T;í;¬/À>;“é˜r+[>Îø}…×áÙÁBuý&ˆ]'›¢!ò*'ôÅ¥ åºoHÊÍS;ñ¾Lö>ôB´On6)î U; G'Aÿ}Æñ¤Q÷·ãÎI·ÝÍU\èéKEgbѶÈÉ ~ ãØù¥qÈ•åºöX¼¶åãûáɺРéѾ)(øXÊU†µÎØýÓ6¥ÓÊ¡cËûáËùj"² XdCu÷8TVsèrº‹ÒØ…~‘Á‹OVѼdî5@”IO¦`Æõšƒš8¤×•7>° “¶VK4»™ÓùQÙÅF‰ç©sÖêæâ†.·è¤2pªD™«±VyZÙ$ˆæùÙ›Îi.¢^²ËŸÿs"ê¿!ÿkµVßÚ„ó¿¾YÛªV·›xþW·þ<ÿÿ-ÿ=Yû~ÿåÈàòŸFX’^¯§Ÿý_ßá?2=hôß¼þÜÃOðôQ|…^žÄ{ú,þY¹tžÿ”ÜxÞÏaO%åÓ:€~–ïÉFîIŽ—¡s·÷K\mrr ²Ö»_röÝïÉ"«ŸøáËÆ/i©Å~ÉÁ>8~v9ÖÅü¢ŒH–T‡¿ärÇÀìJ¢—;?=ÜWa8 v76ø]åʺ»«öFîÀf“Lœ*¬àÞí_ùžëÍqB#Þ#̦úÆî-«žwÅ/±L¶¿äN9ûX°+ôc؃`áÕ>Åvß嶺 ]ùXÒõt¿äK,¸ú‰‡ui|Ó_"Ô¿Ì«Ý~ù“ÿËé?1|îè_@ŸnmeÐÿÚV£±­ò7žnC¹Hƒ[Òÿ ýÿ«ÀÜ’ÁÚîz“ 2X>Š.œ­”¤¦ZÊ:äª(׈x}|Ž ;È\ÈÔå˜ÚÈ;¬=à´wÊÕF¹ú´Rm<OÄùÙ>…Óbfq¿$jÏžm—±(¥]%¼B¦RJGm·úä@9.5@‰) ð½ö½ïwxýøiJq|¯2ƒ¾„è‹]é[/Ö©²ŠÎÈ-[N™¹±n%›<÷Þ #ÚbR‚H^uȹx„Zô‡?ÇX5ÈIû; ¤˜E#óšò¸ŽÅ ‰gâÓ1¢ü°À\ÑýlŽÂØdöþ¹°tîÖvzu ÎWYñãÚzDÞK˜’¤)”ËuÑÔžF(oí+oj+ov¹Ëâæp6^§à¼¡@?“Î9º"ý&~mžbfŠßžGbšw"¦¤P†¢ßqÔ:ÝÍ—íÃöÙoØüWí³ãV·+^uNESœ4Oáp8?lžŠ“óÓ“N·…žö6Ýü‚±ÒløáÞrÆuù7˜=y¹@nɾݷh–EòûÃSDù1ܪ   Š©Òÿ¤NÞÛÛÛÊÈU< 4! 6^Pkš”¥%¨Ç¾ëÛS•`q#ÖñJ¦] ãJ2¾§edù!’P,•2»Å‰Ù ÷Þ¡:Q9Ù`,µNË­s•üª–·\¢ê%b:^òT)ÂÎäŒ`aƒ]xÒäW^.‡FÀøeõ‰(Û¿c°?LãžÂî_y¢ö⇺ȟù÷¢°Zåò•=ž¢IÆ8hTŠIÜäXË œÃH(b=Ösð¡\v‚òIÌ­ÿ–rl›|pqßX²×ÐaÌgIù™)¶!¯´ßHc¤"-(Š'Éa„©R`û®°] Q¡ÏÔ¬*=>ÎÍñg®jÃK«]曳(?C_fÂ% —†v¦ÚJ±°°µt_MX‚+gš\}.óÿlúgÌÿN¹NÙüûŒè§Üþ€.ä'§×§Í#q¡"eàÛ\îtæŠBê·Âº4+¡Œß2Ÿª¢PÑÅaBiqâ>ƒ™ƒ!Uˆ.mŠî- \"ž‡]ƒ ;´‚]êǺœtf×a­MÇÖ=ã¥×‹Æ ß`aE*"¦@‹Ô c­DP¹®M¦ZÆ~ÞX»Õg•ˆÖ=qùz² ›PO‡ UVð—N £yÝ[ý¾Œ?¶ï´ô=c_ê «äºeMv8WM³0äPc+yHl.RJS†ÙÀ¿Î R(š€3r=´¡¹¥;QJEÌôQ§.g¨Â ú~‚ßeÕ¥_${QÉG«yõgsµÝÀò¢ÿÙôÏÿò£þzúÁ5¢Z«1nA‘6e#J™u¯¨˜Z¬VwJ]»Þ-,ÜÕZAžˆùd¹e©Š¦+ªV;°úHÈO¥OÁȹ!)‘4Ü{r‰±O€AÑÎiGQ~õ—üsøµ]ÈQ  ü8ë÷m{€ê[r5£T-•SEø‘EñÊŽà‚Yåé'ô…[¢Í¸Ó`®‹Ði/5D¶¡Äêä‚ý~4˜KÛ<Ç&\¡)]é G’e¾ñ¤w»IIÄJHÝ/+ä=ÿºÌtÃbD{S#9Aøx9¦-|EÖÛ 1±-8´Ô‚€u“Ò¿R H``د-uEoˆO¡óI…î¡h ¸åû¶Ma£S’üð JG“̭͇åÄqÉl1Pú¸’³ÝÐÖ$íåµç¬¤gùœ=NÂÔêO5iGhüPƒ)·BEaÓôÑeÞŽÕ¥ˆx’$0͵$mvFwȪñª€Q{ ëȚuRB{è¬Ä,D½óÓÃ=“yÁ—ĽädÅ>à”š]â]ÏÆ-ô ,’:ÑSó:Å ©P+7½'5¼ÿý-3nÊyÃ4ø³¢F¼Ûé@Õ6mqsJH1SŠ„iñ¸›¡øi5Ùî U׋xÉ6,lÜwz(ìÌ+á¯É&ÿ Œ®xÎ%ˆF,3w¹jÕ‹KN67æ ©IÔ€R ãèú¬«ÏÑöuƒIá£!6–Ío¿åG…ˆÍ—\ wOò+rù=ÇHûÇζº~Óì œ ¸ƒ\UlГåö>r­«µ¼ø,|˜9ÛøžÏ°éñßô«ð´©ï¸áPþ+x”:OSS± Ž`Ü"’ƒ·aïLƒ½|A¿¨Xý2S0Ž”§R1îÄ8Æ‹åõ^›ï‰Þ|rîÖâ ŧÈÓ™¢Û¡Ãð†Qè‹W¸Ÿ›¬V:aELRˆ‚jOa~‰ó‚þÚ†{&ý«qøâ ]÷âÖq3RÚ‡ôäk[§ý­É76[‘lد99y•Éæ·4Ž[o›¢X)m›ºˆ„yÝŠÇ€¡äQÖEM­-óL7iZAÕQ=íMÍ'Ƈ“xþµÏÈðåZ¢P¹/p\ü|ÇAúQÑ¥‰¹&Î/IÞXš2SS7’çœäkŸñ<ÿ†æÝüWðF‡À• ¼Õt­ñý0ƒY]QI²íJŠúê¦sÎMÛíßçÅûœ‹—ØE@ m=v^ÞÈf-?5ª#jvdÿ”lù SÂdÀ‡änE}!ÅdnsdH3[k8İVRr´Py¥Ù–6$´GÓå Ñß—’ç;r,Átæ;xƒ¥‡t'²râ0.mV©xn€& nmiâˆØ'ÙB9x%‘IQl¶ß­‹ƒóuÑ>m¿! 8’Û+D%:7ïU㨒ý%¶ð-Á¿ ËCrI?†ö1ÁS:X( &Œ53 êÇ‘?àÎ|štŒs6– ¨×äÌD%1dÅQK­'ÑeÄB{ qT"£—[” ‰NÈaQÕè@mIšLL'- h‚ÚY4SÛ¾ÆT/¸LqT1)J4ˆ''Ž‰æˆ†…—´DéB©*%`™|oåA^Ñ`ñÊ0:5`à6~mž·_ïŠBœt˜ÿaéúú*–.¸ âÅõß“u±Bµ^}Ü}¦A1®}_ZÆÃºIR^Èȶ´#QpEèØW> ¥–`0#¦6)]—*9-¢iÀ´Áÿ.¼ÂÌV»h3=(_¡çYáÒÆH·åV¤|ƒùÊÐæÉï!¢_ø¯îŠ|üb(/ÄÚ(õ_»÷åÿªÖ'øÏ ÿ¼I”¤Ç?<׆ÂçgûÕÄg åðAÞ4á·¼øóÆø±ö¿Ì›ƒ÷½¯F3íjõíFmÓ¸ÿEûŸÚÖÖæŸ÷¿ÿ–û_ã>ˆÅ†P†¤½¼×ZqXÛ•š(¯•#­üø† ]½Š¸¹;ØE—¢'t fîØ™8ØðiÌú˜îùämmì /4ÙSÉ×G'«}¶a]Gu;]þYòЦ¼JáéߨƒñÍ꺺D‡)à/¨o¡¼®[·úæ•ÈsöÝëƒ7¯x Íß½ær“Íž3ÎxX¼hî+7òJD³î‡uqEàûÌ-^ôšGéE>”¢BYhR‹«¿”>Àÿ%ÚÑØn€ϰ0b5Eæ7V †f"IMéÛPÝ5™¬¯YÕ%#£;Y™”.¥ãAŸc-ÂÈÎÀ°@¨”r°eZ¯ÎaóÌw¶ç…5éõ¬©£üÚ÷ xŒr°û`'¶4'ÇiÃGÚá fºæ /ânoñFØ#RÑ#uA‰Ë!N<4š§O’ òº¤^Väþ¿X­!àóÈÖºäç‘"¼jž5‹Éš«UÞ/Ð`tÀÓ­&L¥Š¢.¼z²[&UYvUà²PÇoꊠq e" ¢8úâêI031¹ ÂМ“Ä´3t|€pHc wM1Ü‚u- »\ø^^6s›C¡Ör+Ÿ ód¹cÐOCù4'§ÿ¡á¡ÚÇ)ÉZ;iï9¶þ=uu8°ƒÊ\(Mx†é—Þùl'“˜ïJ|ù/ê n…4ò V]tý˻ԅ¸øì+éYjž¿Ãƒ¹×zw‚‰—ýïafN‡ÚÆéðŠR>“e| ƒâE<‘ßâÅÐóçЃ†n:¼jõ{Öì®7pè~¬°ÊqA7 xYWi=d*ë.eÿÁ¨® ­F0Yô@«ŒøŽÇº3„Q™ùh†¦OŒÉ,¥uÉ °+5]Æcê¬I$_¦Óm»> ùÎØ¡$D¤fôü{ºÙ×\ ¶—XeÙQDÃ"F>ib£ mcJjK#Ië2ðÆ8wÐF½aÞ×) jzåÝú•w]ªaµþÌ5búÊ”%–ëzxb®c>ݾÍÖžìùf6 ¨næÎ8¡ yú]ª.:h5/eЛbždÔ¾Á:é·(KÉÈþ!]·%˜DG#«z,¬MäùTÖ"kðO˜$ŠŒìcž'ñÅ£Œ»Ù1‚-µØTHÆSÆÙ²Ì*ïQ­lö‡KV¸£ µÔ3GMÖú£šƒæo1ÆŠäjq_šŽV4 Ø®‹{A“gÓ3bTírœç‰ú¾Wx‹y¼Qøˆîž"oàÈ‹]ø-¶±ö¾XY{_Ê$ãgâ„\l× ›Õ£v·‹ÈJùsÃÛvß´¿@#'ÉæÕqmJƒÐ+”RB3W«¦+:]*`š¡…Y8s ¶)ÖKâá]lŸpô7BLÉï–(+QAδÊ2¤RÑ®s(°ý}Å QRÑ+á'f«8ì÷Œ£öIŠ` z”§%M­œ¦_iUÑÉL –uÚ9žÊ¢ó–Ø5ô[¢%.Yy |ëö„K½ýäýŒ*ŠTŽÈò Y›™ýÁœm¶-‰ßÄC#ouN³XªMŸáNH+&KC šf÷Lu…*ÍóÃ3f¦(Vjã­®äŒõý±?H,æ~ÓÛÁǜ泠Î éÑ<øo)¥ÜÓÿ)ÜÅ":y¯ Úèeý¾ô°d¡å‹&#è: 6dïøR2ê“ëèä´K©xQ¯lÕyň˜°yvzÞ‚¿¦„‰f¬Ž{cATÕ®@‘R ¤B‚¿jv[’ß_œÐĨ•/»gØ„Õ?ÿšñjq>ôŽ;gJº5àÒ¿B ŽQÒ/ö¸«r`-¨kûHYÇ?º½Â“‚²€TŸñ•QÍ£»ß9:‚-žƒ­bîB™c–ÿÀxXÃÚ|ñ÷„ëK^·0u_÷Z§§àÌ/ŒùçATü1Û+“óUrç25!‹édÎÊwæ(xcyº°‡y‚ƒ|`®¨ñ}åP¡“®Dƒíûì?aû2&:v;BbR®þ52Jc`Ý‘ÎR$…1fjÇÛ\Úq˜ùý”ÁÆH÷0³Ñú|  ÏZ3P(Á >&òSimÅo²1â fêþD”ý!ÉG”MBL®q´/™Çrœ‰¼ò¨ªJ=s9Ë3]8°©á­]ðÙ)EYÓiµK¤àC£ói|>“Íèæö«f¶·›íwÀå«ÚhW¼À­µ¡ÉZŸ^“,ÎhMÔEClŠ-±­çRš±tè¸râè%ß‹ Ûê'`B[ïÎÊÞ]h⸳€ŠæËQüÁƒÀÎ_a¡—À™”ô8ã{|.@# µ—¼'ǦiÆ£*Á£c!¢px&¥Ÿ?“!64ÏŽÛ»»|:F-iC[Þ1†ÖhŒˆè“€d—rOk™A×Õ­~a<ÖXhÍ«À™´íA΢8™ð^†7D­—×GÛݪí"ƒ‡÷=4@V {twoòœ[ItŠ´T+—°ç®å:»L—Žà¦ÿT|æ¿“à>àgõFýéT~Á‰yÑÓÀŒØÈG»ërŸW!²-6Ò6á*ð¸7WV ñà°¡tyo‡¬xl5Ý<®xÓ#m&è)f:äL¦Vßdµ’3Wqr'W‹k—¯zEöúrþdgöô*׆ù|@Æ7P_rG{jŸDÅ›½ádšúé ¾iàUR6G,Œb`²VcKÐsÓàßl¸3`éê/tÛ÷ALR¥F q$Iz²Á/„‰è‡Úðí¯×#÷@NàXFAî‹((ï1½Ÿ2™Iäça ‘,ãò‡ ¾«?p(¶{ N˜”&NÌÐ@“l6£@¶Ë¿F TÊñ-ÿ ãëù% =Dw¤²ýänk=h¢×ñ6EÚRnRóôuR™Z¸²šZØ0LètxÒãĪ({^”Ë<£åT0,1`SVߦ ­Þ¨Clßai˜Rþ,® ˜’AH¦°°Ég‹9tµµ$›ÅKOŸ‘þhϼAWG,r¸¤K| CØ=lvßìÞ¤ÖÀ…3Ý+ÀßÝ&6Áá€.߬ØF×›y9šV,B¢Û™ Ÿ(Á—„¯•?EБ$0îÆ|ª¶W¾ÂbàÙ†Å@oáõǃ¦‰k˜)°·9æH‡bºéñ'É8¡2Çõ“'µTuÜ é52ø¸iIŠ!*HxˆiwÈÞO#Ù>´ÃôçÖ“DÄë›Ý‹9ëJÉ–KK¯65IF&‚Ùítv)Þa Ê ˜TÐͬ2Âd%9ÖÓ·Ù8ÌòYûÈ\‡ò?Î1O«8{²+j³ßì¢!‘¾­»j¸X{_XÃÍŠ-§Õ~G’Y<Ÿ(…¹\+ŠW*Œž ˆõckD#ÅÚ|qéyÀc(Tlº´$©ö£ßß«J}üš ‰3Pš92‹;zÅâ’ÔùGj#•áR”ã|)~2ÜûãÐÚÓ)^Ða;™bx»•µÕÂGYÕ~"j¡´úw#»ÝÈ7DÝ+e+g”*0…¢³R )³ 'è@JCöƪ \Ïo¯¼1w)JÚ¥ü˜PµK3bëÐðÍ"&Rk"à¨Ô«›;J¨ÅYÐØ—ïeèž•‚R¢š~©ä6«ÕªŒŽÈjæB°þkR.K‰-€a[·>-5¬0¨ÔwIRKbIµCŽA’h–€À;os¢>ªrX¥.ø–uzI §çǽÃÎë⛇é*¢À|©Ù߀M}’sPFÞÛ†cPvJUjF³ø,VñA9«,ÌñÀUõY®cб7ˆëøW錤mDéÔV1¯šíÃsdšºÚ~ôÅ‹[ߣË5sßLÔªúÖˆH›VˆjwÓŒ3 ƒöù6ÆÏte|Liµ­¶a*,äJTD@2QËm¥‰ zÌœÃËM­ñ¥í„QŠyåó`«ÑHÝZÀÜŸOIç·œWúû ¦mþËd8ÿÎïÓ;:"™£Lñv&×¹/ÀC*ßnºýŸÁMûä(6¤ÛŒ9™Q¸1b6ET”ˆ ûœØIúŽ—ì€‡=jÄ0Æ9Fî—Î+Ú¨’‡ä©-íà £'¤ƒ17ÃÄI–éí÷:1G¾Ö˜é6¦Þ–r øÈ¬9î&)ýÖÖ…t4í¸S¦t†­¥4¶¸ûaiÃÝ©b'VžbY=‘í+¨yn‡ï1)Ù¼ ±9‚§¾­½µËõÊVµ´]irxã)°4ì(‹¾§\tMзJ=~‹”R†]…ù€Ä.KÞ“¹hô'ΘÔ,6ç‚H÷cêl"s*Kmôý17`ïLÁ·+± L|Ä(³‡£møŸ!cOŸè²“I0j¼Ph)G¦Èá˜dr¼U×¾ÕHÙɶd*·ïMõ˜sã¹; Òëøœõö Ƹæuë18S ¡Qþ*@b¾qýj›BôÀ©-®p?|›mh7LÉHÐíQáâÅ?ÝE³ü÷?b¦“îjª%ÜB¿Ðy¹£dæm#ÍÚ t!Pþ5Òy€‡üGz4l¥@¢Á”,EåfB$†ŽÕèVä͙Ům… fU$¯@½ñx¦dL”Œl’òå6…NŠk1@Ž2WÁ¬½ð¡”¡Ò âl Útì$©1lÊ/°ÆhŸ{o8}\*ð@ÊHÆtäØIó«´ãN:ॠN×dyZ÷xL  ±›—.8äX§8< §+›­0X4$£ôïGè’‹¼íÿöš²ƒÿMêÅeÙ(drB­­Ÿ^iT{ ~‹:/­÷ŽJà…¼np4_º€<ÿù  X" êT *D퇌'fNpD,¼µaQÁÞ-³ ›ÌÝÊ_ä *=íAd/¢Ù?o݃vóõqÅ}=fìÐN’OCxë•%eS¿SŽÈëà&!ì㚬¨!\UCÁ-ÈGHñÂõÊ|¦)ÇcKšMî µ¹¯†Ÿ5:/`?âÈ»E ÆãD—*¶18ŠÌÓNŠFÉt Çï*4[89Cå®<¾Q–Äfx×J»©%Œ¶b!ÒËz×»ð¼®üȇVˆ£¤šeã–îlÔFÅƒà ¨°%z`ÁhÎY“$å¢1-Ì7¿ j hûUÊ$®ËÕDÜHIÿsÞ9kÄ’_•?òøëXª^dÏp'§Á ˯ʯö»3 únb’m}ÂüGÜÓg+yéVæ‡&Œýolp›zàM€Ì ¿õ¤û!½ÇB”çÛ&ýÊ|7aÄÝøÂ·B @éðOòÈÌ*Çg.—Ãî<¢Š7­æAëTsÄÜ´²XEûøU‡‚ ÉàŽ¬i7Ì<{†"=»ÌÙiû$ûœ=ú:÷(·>´š†æ'è‘x‹ù„biîQ'áÍé:õ,×*Ï*w”±Åf+#äÀFž7Ö¥”p1|ŽÙG:ÂêD2dp§Ã§Ë˜‡Wád¬ã”o€U/WŸnL‚EO«àç߆¥¶)±D{“ŒD{SÚ›«E9Px–ç"+=ëöZ3™y’hàœD#ÂÜ÷wá‹âãcÐæ p{hTbtaæ˜Dy@”'NÚ"Ž‘Œ¦¦c+$2_Iºæ¯[0¯HK4g²ds·| ½(ÏP­B „¬xÁ¯ñX‘'U ìÔº›‡Ä—·²FŸož~à¸Wiä.ºmUDß¶àÈxÕ:ì¶2Ö0çRDÙ’úš%Þ©Ö¥ŠyY8#7ÃÌf‘élV»àã†Iଖ!x&Ú‡ÛÆ>"Y£¯‹Z§Á3šÇ²1/×ÀEã'¿?ÔÈÅ£¨,ÂE7Jnªö!Š8§çt½¢˜ 3å›Aa2x÷Ç"•Þ­w­Ö»3’H¬É’„¢€' +˜>“È:³kéÑ Ô}*Ëý UÒƒph[ XJTªî‘>.l[þøž“{‘·a%˱;ˆ£,óU“wSJkøJ<Í"C}—¿2H«ü. 3èëtÛïØ¨)°dü‹á,D%¸âÈ8è¹Ô‘çI3œ—¦M“n˜ˆ¾"Ýu"¦ËÙèI­ºSß!m°ì Zl± »7žE˜–ÞRñîæ/Ô€°íÒ44…MbÍÆäõBá‘ý‰‘4ƒÂ,hÃ4Š©KÃÅ>}¬=|.sçÏÐ q:ÑBÝ×!ÕPëˆ)Ä Ö타O¾zò‡Êº‰¦Q z ù`DañÓOد…\Ç›ÍaÔA?ÞTXÓÔªÉF!W);IÛŠ–ΰ6•žówKózmòµÎ!'užByX0S qR #ž^¡Q†YƒíÒÆXÕ”»pÈ)‡ s*‹¤4ͶU¨ ò'ð(C“2ØÏÑZBÃ|ÃÛƒ.YÛeX ˜b”RÍšÂÚ*®nÜ8ömez5ýÙìmmÖ_är'¬‡Â`Ö"- –¤LF6žuyªn<)XÎr™UŠÄB“°öÈ 0â¤y7ÇOV>âdO¨H® Ês6 ÐvH‹­öº^éÊ|¼’ËÁ|ª¼3ØßoœïûªuÚîœöN”ð@–Ëù{;0}tØ´?–!ýˆ0 ¤M¸µîe¤(î$…•º²9’u„(»ö(T¬jE–hÕErM7q;ªg4¤¦Áº!ÛI!¥Ž^*1ˆThg°~Ò»uÇž5·ÚQüö>LÏ,Ä`D€YY(L;Iû@óu6ZÍv vÓ“BªŒ œÒCÊhžŠ“ѧ­#‚§ôSzÛñÎB5~ŽÚ§¦ hªƒÉÄýq|Ï¥û.= Ù•Só³.UÑxõjF¤‘k.©U›§6ÌËãaîû÷Ca¦¹ßrè͵oÉ”Ô1Ÿ fHAŠ®kK2cXG‰ƒÐ¤‹h¬.òX£USˆ‚RK=£{hÄbIoƒùˆŽt1Â7@•”ãf{g³V¡[DóC¡;ÈWR‹sØ. HàÊlqSÔË“Vž#Lrƒ˜ù‰ñ:|•&ébʺ Wui«øþ’íAWùX–Ož×™+½'¯ò™¡ú”Öx"Žã~ g£È´Ï%ƒ;Jgä½#YBÇ”·Úb-DXc@Ùò(Ýl:Pam9ìû•4¡1/árì"jd.Õ*ßÀØ`²‚œ4ævŒh¾2>U£b©¢ÿ ©~˜}%z8p†C›|3ùn!'ã¹Ê+ ˆ‡#…:fHïM§ó7Q¤“T†)É‚±çMñ”õíÄà¨kn 0MmÖ¥’5Õz¼ËÆSËh<»GÇ Ö2Z…ÊMÊ=¥bµåÀ¾#DnNOÖ]Éõ0È‘?Ú[­Ñ#ÕØë{37Ü«åP;€oeÍyx´Õ&»)öPŠ•%J³*ñ£)‹|Ü]Ê?&æ ½N6„c‰­&^‹Eí£‘øL`dj f’ÇÎóuÅyñ"aù£>|(}ÜëñâC²žŒÀȵÿ˜L µ]ê5nt±*Oãz!Æ.“ê¿y îD\¯ØýpHŸ"Ô?ó…m+àI³E¼ £¸]¼ ×ÞÃâú VdŠ–J®`Æ’“EÊÁU!Ï‹l!l:h^­ÍØÕM„!3êvã?cqíÏ%m&ëÀ1»ÆN•¥ŠQJ˜ÜS¢Óª–Ž]8ðÂDqÔ-tºJÀKñ%0‰°¥3H%„õfÜÜåØå~îµ¾Ð7ÓâÝt.Ø«%±=\þ$yüjÖ€R‹¦ œ†öˆr©•É{.²š‹ø¿l“Ÿ'°L¼‰øog"Žì{m}ÿ“Í€(FNûø þG*:ò ÷…,“[Ïr¦,4‚ >{c#Õ]YÊç} š\‰1׃ÔσÌRYhóió ò+ žö‚‘ÿ¸gLD©ø*$¸>9D㎂ÄQPl¦‘qxѬD FR^dG %‡­5)ÚZ-¾ mÁ)øØOÒýÄX~àl û™PD«Â@HL|íÉzv®%Ê[AL-XêAíQ¸“¸wO½[ ¬Ì„_HßËlÅ‹à ÓeÂÌÕ‘¢´?YýòCøKrŒT𿜔ÔèŽÝx.4±ô”3ÀÒk‹ÚÇ’EŒX°¸¦–\´X2׎˜~N Œ*ÊFÂé¢\þ2‚åtp6ªOfí`dÒ‹¸"ƒ¡gÊ“œ.²(L.²„2|úª¤° g¨Žæ3ÙöõÌ_œw[ÉiÙ“F7ÖxQ©lÒúus5»þ{SŠBž¶º@g`;¤`fƒâ„>zn{I¥t±'îåB /{«‰di3 ¢òÞ WŠNmiꃱæd¾e› ò1Xù3œü‚ó%ŠÁVL=NæØ#Z÷äxኂ䂌QsO0)¨¥E!¬gi)è oè`(¡x¹ØH;ÅB:9ŽÙ÷tês×Ì5EÆHÑí†ÅHCfT`~'×â§Ÿë‘õxN¸›[ù…D;å"CQéåGuiýBaÀäJ•“7ãßvu!Ò}AMöòOò9ºdêe÷€Ç˜lv-Gס 7¬#­Ä¼p[óhkÇãþ¤¸04oqíc НÏ×À-ëè[S€hi«z!J«p’‹ ˆùžë‘OŠÊ9Û=Òºé¹÷éWý•Õo.pfŒQU ÒÕëç݉&û1 ‡W¨î.˜8#Ü^„;ˆû‚AÛÉ Å˜@=Íc!¢‡H ;¥dx,šOL½»1À¨lE)RL–8V‹rìI˜ÆÕÚ†4.³—ºŒißógî—ÕzþK4û«µ(ÇKË*H “T_¢rhq`FÚ ð™3‘ Oæ»2º Šmùe£ºÆZ‰“„·ª0#QBºáÁôä—š:>j–Ó EEè3ú…Ê­˜×É:¾Mi”’|à}>%ýÀû|\a´dÒC“ ¤ƒÀÉS9}°žÀ±gô!¯Ó#”ËNPãN½µ)ͱ©Š0æf/É: ³DĈb–ÜâEA~,ÎËR©Gÿh§†\ÁÀ¬öxjG…Ø‘Aê#”ûUåÏ”CK8¶5_¶”%ÙâÐÏIWö,n*vp§Ÿ=P.§À¬Ï.ƒ œ¬ÿÐ{ÈøM) #ìEÍ ÃŽPM6–Dg6* ;BŠ®:¾—ÑPù’â’óöP%'bÉ ÉQ#¤ AJåóCE¦Ü˜.½Ý¢ü»ˆ–#ÿÆ¥8[0µúv9@gOr¡@3M<\µù¨ c”Ýê®l6ZXý«Þ­ :@pÒn}Þè=*R2{YòX÷¯Êàá¸sV&ÊÇù\Qn »‹™±áÀøeF*ªFbÈ{²Ïºq²ÇÎ@Ì:´ùÿ ÿ$éÄ7?y˜å…ƒÈ¨˱¿½Šþ99“ëç¯x¡Ê±4#(Êð•p$d?5’:â³iÔô-§³ 3¤K6‘+:ï¾)^ìë—f k4¾Ó%ÆÅב Ȇ'bS"ŽlÖÃåt$kdx{ý~¯ßó¤ Ÿ¬/KÏZúE5€¹ºâ…ž¾L- z{iŒ|óhޱd‚‡?(•"He}µñÊC£…xzž O­C]‹ðgߌìJð:º+LØŒÜ<#*¾cïQñdúZŠ}æ­Ë0Ãüò#’! À BHEG³2Ffïž‚GÈ*º©Žj ;?&&BÇaУàV¿‡þ‡eO¿«ÓK Ìw’¢ψžV8,íãr: £Ìl»ëå’q¾¢ð^‘ƒ½¼Ç ×àõÌ•üªcF3ZCOÄUæ}¸hËj”oÚú!«e¹|aûgx†Øz6}îRØ£ø¿éŸ·H[9Ä?Ÿr°=8;0pYcOi4‡’nÎÒ‹JçC¶l”ÙàA³¼j%sx'˜ÔZ—*µ”‘̆²Ï‡{…\!G ò—ª‰‹‹÷ïßçß?y¿úþ‡÷…÷W©ì‡Rã7ï” ÏnµìCéùóiX¢ÒY.¨ï½x¿²¸N‰„̬w£<¶Q]¹¤çKAg„`³F¶‰ã±?ö./¥ˆJ¤@¥(Q“vi…Á=B#CLGT>dgoÊ"…ŠåŒÕž y±MÆŽ{ýœýÖØàD_»µ8Œ0Žrñ°xF„ãXÂb3Šöˆv^#ø6‡*O'A l[o‘œ3R<”È‹€r 5Т` Fr<’[ 9™ªÉ¯‰„éPq„Û%e“F£B´G!cøwâãëÃ0ÊÒ©-‚Åûå`X†þübíe”x§ÔP+Op>Î'—_%·bÔ¸D…²‘;Qêè߉9qWk% …jÆ»6ßÙ ìF{(\™­˜¼EìÁºf•d)JôêŠq ¼(È/€’ g¸ÎÙ¤Òºœyš,¯ƒ+6kÇÕ U¡µ±…°µ°ÆŽDù™ Ò¥j¥‹B¹Ì–[@f±ÝfUÞ›}3æ7tmoÑ>603ßÙëáÎ36›wâTãµÙqÙþÝh²²›H™Ý:­¤ø}þÅ8£­nÿ.ê1 þ«>ÿ=‹È å [ÂžŠšÎyí6–tZ„íÁÏ¥\$'t® ù®Ò¯&(#ÌßKÑl Ob‚JKà‡'þšcîÁðcAŠØ¿f¥k≯÷i¥"ýä=Gý\ç¨ŽŽŠ˜ù\y"¢p–Ób™yGa#Sjl' „>É‹*êMÁ1Ž-Éëù"#dxQÍ‹(‰Xrð®þuQÂHõã§<1Zií§fó ëÍÎkQö¹,êêcIržˆ7$ûÉåÒÝÈ·)gÁIû@FY„¯V&fè§ib&qí‘Ç‹.C°yöŸÃ«Ú:ï}'ª7ÙfŠ ›@x¿ÄÌþ‘EÑóè˜W&Qä/å Yôäc#ÃF™ˆÖEÞõòØ={2 ïe ù±”´>5=nçGhç–©QËDŒŽ—ÇO)]”>lE˜KoWÆÈy»WË— =}ÄÕ|äoÌL¥ ÏÌèzlÃù—ÿÚýE‹X) m‰CoÓpc0‘—.°ñ{Uvp½Œï5åFñ=–ÄðžGµú/ ;ªƒPQ2KiÖ4gºaWF•uqì¹ÝЛŠN—ëcû.ì†ö´Ddœne‰ãR¶’ȇKû•gÎ=éÙ³ú¡eרzã)‘Wü¾glÌ¥ýÓúRY:2¾I´AÚWH…)íÉ¢=.ÙK–D… Šn{Q ð„«Å—ÍÓÕâÛR)U™Ú k” +‹+f³ZD°ÒœqNá…ÉÕ¦x§YÇÃ-¦ã;Åqq´”1U‚«K‰¸†§‘“9V߈½³1Æ~Ø' Dû´ýŽ´¶Ãy»Çßù—^¶ø6m—t:e‚]M+“D•^(æ’€Ètˆš¹èçú›Y^c\—,“ ¯Z¤ñÄÁÇ€–‰Õž,ô§ÿÎ\H¬Sï<][¥^ÁÜØ@Ò}´@#ûØ‚Lºòúø¼ÄÖ\9X£SÀ(lÌ!c”7éLÆI (®ö¥ã²ÃÉÜ&(’TPûìzäÿ¬ºïA™õÇøÊ‚ué_§Uh…€kàX 8æ×6;mÊÄ_äsçZ]7‚ÏáÌÞT0Êu‡¯P®<nA£†ã¨é§ôÚÃo1‡ Ù¼DàŽ B§ßaÛ¤k.¹Æ‚<ôÂG¸5ïA ¥0 ïÑÙQD†äò^›ê—zYQ¥ùK»ÔHL 4H+è b”g23:uaj¤s~¢hÒs Àï;Ìøï–2²*Ð íH)|RL|A·“ÞX[Å»TÇ—B”Î[]Ç«à<ƒë€£îU-¯Ú%áý$¯ŒšÇ÷2x4C!5§­K: ¢\˜œ:&âþÒ.TŒë¦4©!Œ|x¤ãaÞ;ët‹r Å <ì’Ø›au‹I·3‘{Y oìÊAÞ ¡©`™÷$Ûÿ9×îñcämó´ŒøöáÅG‚hÄa%¥ 3ÄtW«PÁ"ùE=ÿ‚kZùeTw>-ZaG¾ßÌ/$ìJÌkCÀ¯éöbv9vú"@£Q í1WCR|‰Õ®¬Vb•¯þR2/?()½§.¥-´ý½´Èùè[bSÃ"Ýü³ Áhc¯:§GͳfX ÇWe³›Ñ1HOF(I¼jFöõæia](n< 30µî <¢]4 sÂa×Ät]_zP¾¤Ýò-†Äw8²JÕ-k/«Fªq–Åk”U(¿±ÉöŸ~íE—?ü`ÖÿB°Eu~=Øâ™µYæRù©…‡¼; 8Ë›Ï[—ÝM ?ÅkM1§Id7ý&s*Ð÷| 3&3‚áo6eÊ#n8ä®rO„xIì–‹d÷#ç’[2ȉ€ê8Û© ¼Š§U¥R‰ñÙÔ:Œ¸ú qV¾d¼ЏOá 𼤠óœÅ3Ixƒ ¹Þ„ `{šK‹Šlj8òÅÙÜ+ŒÜ‰è:~eÒ£ }žèO’Ir¹ÀÍSm„s¿g¶“¢L™_•Ë'_z¾â%ï úÈH«QŠjö÷’Í’¡ú9>9‡1ª=ÛÙQûDm/'ÐÖÕD†Î=(ÀøÁ£=3•ŸV›[—¾^> DwN®¢B5ž·”‰†xÝ>ÀÔ¸°a­®™ mÞ¥£Õ`X¾„À¼}.F™ÁÔž €G†2¡}Øil64.­…hlíì”*¦gÞ]oæ öêÕgOk[5(Zÿ´¸¬ôéªÌµ¶QùXîÂUÕ™UlI$[«L±(yܶ‘]`¢þ²qÍC™£šc4þA±VR#ÃÔˆN:¬HÁÁt„ßC£¡ q2,1…¯A‘ òÛäàv˜Fr»rƒCï\§(©÷Ϩ<”¾-ž<×GÃPª<ë ºÅ“™1?F…FªÐ(«Pæí61…6˜añf[‡kö‚Ö«\®ÚÕԃֱ̰-Œ)Œ_¶Ì)®•‡aˆk¾ ecÓ#zàªdÔFÞÌî½VÝ}U÷F‰î¾¾{‹z—Ñ9Ig(Þ(Ó—ˆòÈÏç2KªÙN6?7$Éã~µfR`z"^Ã"Æ - Ž Ï®”ÁKž:¬º…WœlD:ðpù+ç–MÕ~”AÅTŠx…ÄÈXw¥dµÈ¶”a qG–oV>_6» TÖO4ù£¹ U+ÊSæO|fnª ÿÿ†ê;œo}¤lqT‘A!%#x¢¥|ƒhCò%£7ßš ÅeFºöÐ hV–‰âxk$•ÉåšÆ~FH0Yq.b€t­Héx!FÄó4ëK>¢  |Ø` –Ì&“ûH¨a 5KF)U!;%§ŒÒòS¤ M3÷š8Ìîwd›?hØ¢­~Lº&Å(³ vüÌVÕDˆ(9ñã ¦ïÐaBÅ×eÆø§”jéö¤Ûq¬Sº$ÙÈÎÏ•J£ÙFäÉžIý]¹½•Ñ€ãs/Ý”ã/÷ôiô!-ÔÃ<:â㎾<ñw3Œr@Ôã–Øi¸Üİ6èÐÿáĨ¥“M™p#QèîN%„îߊ?kµÔ˜^Géd1”Ü¢2îЛ†‹ŠhoÁe”µý‚"¾mc¼Z7L-3v.q Ò¿…Ê+ýk0Y~Æ7ye|ýÿ©)©ßïúekRv@~ËüÞ‡ÿGuNÖ÷q¸žH ”õöxy8¥÷ü?6«e(äÝøß·ø¾ýÝêËGþô—?ÿ{ô°|pá×*µ­JU¥Q|¿:0QÅÓ­-ü[{ºU5ÿÂS}»ñ´ñ—Z£«§ÛP®V¯oÖÿ"þW d•ÿÓÿ—ü÷ä¯bãÒq7ÔR6ÃM(ô1.T»ZÀf¡‡Ÿ2$3tRZFšôÚ³gõ¥´è9m^¼WÀòå*Àmr(×å 1i@ í¸R™“Fü^`˜uw -½Ñ)P— (TpÆô±º¬8tú¶‹ŽL˜â›àŠD~ò&«#Ï¥4¡ãï7Tª¸ÑÊË’‘ÃùX(QLpJw­ ;#n²i¾)5MWÞTº{PJZŒVnË(U义jÕöÙ›Îù™hÿ&~mžž6Ï~{®o HP§à9“éØA]¢åã!‡)¾ø¨uºÿ š/Û‡í³ßPEÿª}vÜêvQ­.šâ¤yzÖÞ??lžŠ“óÓ“Nݲ»¬µÂ‘ÕÙèçÆv¨ÒÞ ìÐr0öƒpKÝ2ñËÀÇÚæÓ±ø&äÁ9£[sO†„Ý·>—A)8‹Cj4î1ã ÜØš&{g“°ïлB^Ë,nÄ:VSLÆ÷zU†z㺲|òñ¶ô s%¾È} é[IˆÌMèÍë´&”‚ãù8!¯w¹fe¤cÙêíme1“SB7å6ûŸãG€W÷ÕÒª¢¥Çó‰[$Ú¸ºâͰNR<ŨÃÃG-Ú8Åüë“ÛF¾ÄÑbâ¸d)€Wõjc©Hï#©Z½=VµSCQÛÇŽ2˜‹I-˜°;uc¹®u¥W¼¼µ/7~žî©sÒ Ÿ[{—cï²GçÃ=ó¥vÈ,¦Ãœ’Í?)}â‚eùJåÀ¸ð¹‰½÷Qº’Uófú÷õÊÚÆúzác.Gé4öòïsçø°+V«B&JýËuØœr>޼™z^’ó÷W'›Í.pðr- ØA£|µ.ÊeÊJ þcùÆßKÿô\Ãò!–G"_æøÉª<…톚ǘÛ¼ÁLÀ߬Gª³¾›Xæ5(wjsþÓÙˆú-3Èù\NbÄ1ä¸ÿѼ‰âª>§@Œzp]Vr_s*ë¥ÄY'o„ÌU‰Û‰¢LT»Ÿä}Ïq'§èùsR”¹G¸¯!ì028­{ù¦_§Õ!W@!¢æŽË*8<Åò”§Æòƒx¦ÜíAÖ“?åQ(ª"컦«±óYþÄØ9åP‡ôV®•z^ò€ŒÜ%¥ê&Z5w3'?ÎCÑÚÆJ¯¨Æ«9HÚiù$˜(IM#ÙðÊ€%2M:dIÁ•3 ŸÇã”ì ‡ç¡ `AN-ÓYX‰yŸèÒks-šÀ~w\ºœªyµ¶ŠÉëÄX\›ŽnâŸG¶«OО¨ªõ,F¥”Åùí2«•+¤¼¨”:½À/ èf&j[d|±ßƒ•×{yÞ><ÀQTÒ?Ûø‘Uš¦Éqì…¶™Aˆ(Ÿ™ ƒP8Ä(Ir|†<˜—êÃ.²F«Ö U’ù€·N€nX°Èe||Êý£k,ÌÏ0ŠóÔ9¡ÖeL+lÞ‚ RïÃ-™cšüÕÅ£Z°ˆ¬¢»O>‡ËXÍÁ(h+Gh’éøø¦Ó=ëíï*t—õœF(ú‚ˆ¼æ޼2ÖIQisª¶„°¿"Cê*çx ¦Ž¯ÆßŽ,fB Ørb\Øò=2”Ü+ðüæq~Q)´÷~õçç¢È~&ïW¡ÒXòZSM_ÍtûA åýªÂ—GR!ëø*¤r·Öò¼ô°ú!œ’ŸÎŽNÚ§{ð^‰O8({‹³‰\‹êÓ§ØœÉ5. Ë_e€þèý—/ÅBF‘)P‘"YÒoêÍsñE|þLué¢À¡tޏ44 ªfuµ,?â·d»°·ˆ´d"Á—WWâpÓ–þ•ýŽvåB ‹Y`åÈ¡Ë6W ío£Bƒ"ôÑÚ64 6ô¦ŠÖÞ±qó"E™N)³÷°m¬×†™—s½—_¥W•¾žzðí±|„ñ•Þ!æ~Z_•{d}•‚TäÄúz)¢¡ÈRÜ=GgV]âY¡Ó– Fûbÿëï<ýgÏøàZá„Í«}2‹ô4¨—7°Ìß')'V¢½f¡{ý¼>°ÀÐÁ¿Hñ¯Î£lNÖJ×SÚW6,°Ô+'·‚ä~}}­”l}[£ñor …ôoÈ$hxIïh|bÛ¦ctï3cŽ)âÉ=ˆ@«;Ý;¶ø•yhâ ÏóÌÅô€éŠ£+ëç×ëWüY8Bí°=˜!oµY®î”ë›äjQT1a6*V¢ƒªËžÌϵGYºv­Fâñ5]çw¬wÔÜÓ>n!i >”'‰ÿù³ˆ—”öþ´uØjv x? ^•ŒÃwëžµŽ"ð ÁË’qp™µ8‚¿Éª^•Tð¼™ò«&ò<î CÇÝ}^ÿ·±V’þ̆,1¶ú×ÒTOƸ!6®È¦NÿZŒÆÎ%°¾+”C–‡1™+¡+î•å^9l¿Üßn=—[‘¡ “ /Ÿ[ÁKœŸ~*·:¯bûÐ+ùø§!Ð% hAåê¾Ö§e±×;ßÇJz½’¬mÖÇÆA){+7pì¿D%Õ*ØFkápèÃÜ ´Iµüãjœéi™$ǘà>Ùßõˆ® Å>ù`ÛŽ óÊ|<p 'ø"ʼný@¾“$…dg¨r`ˆ̨ N÷¹••1å€Pœ3mÙŒòïâˆ-·Q/ê'¿”$Ea@Nmä ÊÜ œ3rIÂ2[VaÒ!…D3ežeßÁ“È#¥æp6…ƒiW¬•×Ê®F{<\[7~[Þ,\[G8£Lß×H:^®Él#ªAœÈÓîS¬C„çdLM[‡¯ÌJÖdp¦Àã´c˼ñ0"V_ætd!M©td:. ¾¡y(‚Ì'P³Ø‘#Ú²12œLHþã¥amF…ðšÆ…}e¨*1§?SB4¼t“nÏt×NÎB*ó¨Q—¡O~µ•³ Ú ñÂÏKº…‘€ õÃñ^žÿ"£uu[™‡[¹‡VL@bë«×9¢‘Óø~üŒ[WT~#ÀÓe•ñæ3KÍ©’¦ù]é#²ù¥OM£5M –?±/qiRgöègY¢ÀãYZ‹•™+\5ìqT$¸§¹4‹¤”ØŠ#ÙÛs…l¨þ÷ß ¼Ög¥õÑTpýÃ~_DÈ‹jùÙ‡÷¥ÊÚêúûj¼VV´Zî2˜\FUY{_´/ß—Å”p¨6£Ñ4ëËê'Æú%¯:…TŒ±L­.Ög¢„+l•ÚÁ\ª´Gº|0FYCÕn¡².Mœ0Ö†Ú숃÷»¦¢HÖÿlwÛ³‚–h«6_¶+K­ ›VtÏ ö4å2z‹Ÿ?;íÏ“íëÏnШ_†Å°ö9€=Ûÿ|ƒ†I+ ŽcÌåÝ’“; dÛæàÑX\¡}3›Pz5Iüä RiE©x1”W?yÐR9ð+ñ Sgº¶ûÒ¹I¶,íF’¬ùÞ .^±ú¨+\@…Ë—T>9úÉFmv#æðáVÈòË7àµãÚ†÷i hPüýòMsK´æÈ¸x}5' }„y"Ë/Ú¾¾ö–E‹e—@ÙõÆÎ`Yœ~)¬äé´ãà'ðNJùÓ¾Ñs©ñô—J©.C|·d‡±hÁ©=ð–ƒ÷±dbtœi°Û龪í®UÖ"§ƒßÊpú–½`X‹>ÐÖxzeIpªŸÕu±Ñ]Û¬T‘ž&4(_ŽO>J³Ÿ…u{- Ÿørpµñ¥ èçÚVeí«plF8 nöû ÒJWĊký¾."LÓÀGÒj„-½±œ1<Åjƒ.oÔˆK;ógÛ›Ql@ßÌúú»öìÙzaE†LÈñðáíâ% ?sÙ§ÑX÷:>ækœ:S™h9¾÷ü§ Îä¯òPM9BQÀH©4 ¹ŠãéТŠAÛOÞ4{ê\0ÇOõšFÙmy¶ýƒ3&Ót‹÷E`¿KêJÌó“ßx_Û˜âÁ§[É>ñú¢38ßz»)ŠõZu{³”æUéܸ.ucáÊÖòÅ÷›ùöþ»³TTAmAöÍV¬|e[B4l§ÃœìgMûVêérPOM(ª©¾°?±Z¶¹–úâþlÇë¨ìì¿”Pû‹ vPÍC õò1Pûï$ÔÁ# ž5%Ðüz¶°oÏLHÆÂñ‹ÅÓÊ3 ±¨Ž§ÏbbeSœ¸7â‡QÍÊV ƒÈžŒÊ½+'Ù²dÁ³ì‚ä[*L{ ó. ƒ6@ }‡B]1 %¼¿±ÇZ«Ô‘w Džò$x)½x%ë@’‡J~ ¶ú'oÏÞ}`¾:ôAÌÚ?h½zý¦ýß;<:îœüÏi÷ìüí¯ï~û»°.û{8ºrþy=ž¸Þôw?g7·w÷|DÕ1Hˆ¨\j½kŸ º¼ä¸ x É“@:eNg¾ãÍÐ7É-Ñâñ™ÇYïVôÕè*È”|^Uyªê‹NuB6'ÎÈZÛ=?n¿ë±Ê ÷vÃè´F™<:áÍäÑ´> š‹Ž÷á¢|Xꬷ æpM>xþôêQ¸&1«ÓÝh<«šœÆÓjÙ¹œ«l³EKê·G&L8曉gÏ×±Y­¦qmTKã Dïž¶»ûk»µÊEµVÿ Ÿñ¥ï}`³¢· !*Ó,à€=¢"‹ù5Û —ìJÔkTa§»›@ª¹.*GÓ=­ÿ\­í¾i—Ïßmœ ,¬ïîéNº{­P^M§V­R+_ ²üÝM¦Ó8^y‡ãv·&‘µ»ó¿»G'½ƒý²zMÚtëÚ¶¹‚<_mTn§Öð²b +g,Š-ËÞçUE4¯íI¢Ê’°q”»öa«Ýlæ?7øÞŽïþâwTxÑi…¡¾¾“SË/«¿¸9¥¦I-B ÔÖ˜ƒ€M¡^í`àïôÊI¢¿ñ[íà´ûó6N´úŽvév´LQUVvúã²{·Æ»÷w}m÷)޵þäN Þ+>™Y/}»)ÊÓš;¢êJb®ê§‘¹Ò _ÜrpÝívgn|ÎmiÜ6ç–¬/C~/þQù€J‰}ÌÜÍ7²>àËwãteªæór•¬™•à` ¦ÞØ^Ë® ¾Km›3ßó­ówºðúÎvï#¸³]êdÑ×ÙÄ„kˆ÷O¢Oô.S5Û=?fÖÝÛÊ`æfNÛŽÒöé ¶¬(ÝÞD‹Ô`uÃhAkÐnB;ì’¦µ×;<ÙÞìõ8Is“Žd± k1^’N–CÑKðŠ*r #Šq!’v÷*iïðÁ´·@+Núıͱ&ƒíÍÂsÞ4ínXËöŽ|WàKÜF”D uq¿srÖÝËçÐg+ÒgÇ07¯Ü.IÐô¼ÜílCqþ†„Šˆ¯IU&+æûî–mEÓc‚® ß<»\¥ËÇÑ~!„õ•ˆqC´aÐí@bßYâù —Ñ. ¸ØãšcDš(äÞ¥Í×®´\Tš[ µLH6+Y›¹ñ}†ÆPTä# Lú¸òõÇH>íÚånísw3Më l/’Š…ÿ¶¦– |¦8´ÜÑÌÙŠ§Öjõ¸½3ÃÇÍJ­Ò(ÿ÷a!¥÷3× îzy£—ÚïÆÚü©@,g„{!‚"x’ÂÑEj/­ÎŒ¬`° µßņö7&^8H¨_(“ _\ÝZ¯­7J_ qNXhbî’-¡~ø!aHÓˆ&NMš1cØÛ’âê£ÖóãÚÐPÉaOãÉŽ±…³àj:?ÐŒ>Ní»e›/j'œ±ý&™z;ÇgLÌÇNŽí(S=›Š«{ºJ—Xä ÊãËlxsO9V)L§z¾½r`Ùsd! š·BÜl!E«V?ì<°keÁ0æÞcEZ þž’lœáZ&|ÌB'sä±[yŽ•G{zú‹í#«Oó­öL~+*O·¦y4®§ŸXÕ+¶âÏEAŽÌŠógn^ lè¥Dù tïuÒh°9€p© 3‹»ÅÁ!7©Þؾ™'§‚B2ƒÛ¶—ãyaƒà…x%Kn¾Æ>¥¼>KÙÂô½Lƒ°XhÁrkó5®ýKj[ZcX£ñú¢—FÑËo©+Q›zeÖ¥Þ¥UEß–¨êÊÀ‘«J½2«RïÒª¢oËŒb|øâ¤£Žî2(¾‹t#Vsnܧӱ]–_ã‘Âx*%§?ËíGP4Ö&u 8z ðmVipç‡g§íw©³1ˆ«ðâo›ïŽ5Éu·4Žzµ^ÝÝ?äVÀ<Õ7Ño…°?ÆH¹~&ÉöG¾5½*ë»‡Öø”ô »çGí“.­pù;ï euɸ‚J´Ÿ~sf•šƒîOÇpVÁÿr‘¡%º²x•«Bl¬ÑDÇú°H7¡G× kÀÇ£A™å¸¢ˆO–?ê¯SJ,±Ï7JâSNZUFE¹( ö<öœÀØöÒ0óEŒ×ÜÃa Ãwýǧõ²”(Œ×Ü¿¹áÛžûÜ QÌÓ"¡XOó_ªÞ¿wóÜ.JÀ2w±Zz‚¦ã{ºù þókñ¶Ù(¡Á™2c5¾5 ñ|Ù¿›Ý=M‚¡b¶‡Ñ㚢—P ßœ6@%Ίæ[ÇéïF³;­÷$ŸÃç·)­TZ ³Ù ŠIÿì"’ùê€ù¨¦U'Š|VD_TéÓãlh;Éõ FNÙA†h)ÅÄhN3ñ³üo·Ù~÷óîE­þ¡RÛ­—8_qû¨Wꕊ ü£?@¼:=Û8ÙÇWJM¢ä”tÚtX”N=207HÂ;â Äoº•C#'êb"¨¸¡öÜ•‡IAiz‚…¼DYÀ6qÄ:gmg»°›ÔË6%ô½Öö¦QšötùNhât­ ›W_Œ´_Á ¾5èŒ,ôQ_Œ¨" kÇJú^ʼ°•¸ædlt}·Á&-è¥4ê[ÜvÉ+nHV1#?ÏB cÍ£f2©+†ó¬ê ^Ùýá=€ÈÜq‹¨ÈYù„ÿ ~ø¯½T½i¿X¢OÔ­"q4++ÓYóæ…"ŒAÞVž Pá*?Kñ.É¥ó.##è•~%2K– <Àë£Xã¤}293ES±ùÈ©HG¾¿n›+0O×䂾ØÜÚ~ú—Zû´LÛ¢qíeʯuF¢Ü5,«˜!¬ý®õ‡2@ÄjMt×Äg…! hႊªÌk_+qÒùµuZÈ„!=÷1¶›è½\Üã¹­:ÆÓéâÊEʇ¿÷q†*~hWÐK|ÆÉE­ t²üj×èh:*‡!Ø`Žxu£ºñm[]uhÉ]n²øì'HÙåÄ›Ý$­ðgE‡õ›R’@“ྙ†d-‚áãtYšÌ1ýGcu2DŸ«aNÈ@X`¹Ù„œ)¹5`7Ö¬C y$ø„dW×CÕ£Bš>wºiƒv ® Óž¶ƒ“wõŸ«ÕÝ—•N¥[™Ó½Xʉÿ pn\46?À‰ uCWwk•9ÕÒtþü¾š g…´)¸ê¸æfLÁn?ÝAð7'åsÕû7'çïx,uKS¹¨¾ä»št‰H­Ou6j?ǖěޥ¬mÖFXFßJie¯%±#Ubúßé#;¤ úö‘o ú½þtÖS¡f>ÎïîI’;4qç¡P°/DCù§£`àÙϺi(äÀÅÃ#'9ÿ­z£¤€MHp´{œ4{¨?ªõªÀN –P‹õRÖÞ1@êTÇJÔb£ï²Å€q™•×+UvÂÂÛ›soõÇBaî#ïí'‚V©¨U+uj‚2›àð]{üH!K¢¡LÕùļ/`a8[öCl ò12¥G¶L·s~ºßг7áN òl6Þ‚¸ $·©ÐpÑ~¢‚†os|é”dë(°åØCÁÙ\Q¥Š€`y‰H”±¼J 9»‰"D¼Mz|½í ä¾D1/×$p\.áy:@-P[ «m÷á1‰µÇ…yDj3£~ݬW\¼b.Ö¨'‹¹‰b2gl²X¢Ô—è©JIçú׬Ú•;±«žÌÔ6Ì ýµÐ#Í æ})Æz¦ÍD:œ £öhŒ!Ž¢fÿaî?£8¶•¶©a;;¿]5UˆéN2÷lNº*0<õ®¦³»5Α®ìb¤ÇšrŸ–Šd ? %Ñ4êTœìD!1”:”_*J…'¬Z Qb43ysBñ"=×›Ø@&("®D£°­Æ#ôû¢ «Êí½˜‡Z­RodàÉ¢š´#cŒñi…–t)•VDŸÅcÌq”19—2†˜+yNÄôUæÇ Ûµ¨TÓñ ó7ù™þ;ñA¬>0,³ÖFu«ºÆv¢»™ˆ=xý“zÆà “[ÑGÌ'%},< Vˆjáå?G˜€¤œI”‘Dµ.œ~½£ýí¿ Û÷=×öfÁø^ia¥âS“&6~xÀV8ä;­¼í{>'’àœj j¾b‡T€C’ÉÆc tb•äM‚Ò›&N³ODª–8ÍbFº·v=FbÓ0ÌoÄPO´¡þ`Òƒ… _xPèMÆ ê©4GQ"fqb±F#‹©Ë댒Ñiô¸›¨ % ]­,uc”Ѱ¹èi$P’ÖÎÏOŸ}0>Ìt§ˆmòçL°j*ØÚ³Ÿ^Û=:im8êz 俪ù.Ïdj'åû«)öFyö¡ÃTvÄðöKvà †I,;–”šç H¡jÄÄ1öòéXš}ˆEàZìÀ>Œ“ë¹Û‡…åçµ]S4‘é£oH©Ã0Æq¸ýÚÚî¾çÞØw|i>âô3z‹E"#Z™¿ÏÏñ~ýaTu=xæ>`·¾!ˆœÖØò{V¿ÏüA—Xm¸-ùKüCr4ö›·ËDýjlfw¬±³¶¶llK4-Ö² ;mþ¶ö[ùèd76ã÷“i¹ï[÷°dœ”›ä˜ùû ö«•wÏaûE³ü÷ìK³ÀxQmïs+f…ˆ£¤HÄïKx­^ˆn¡ÔýF¶/ÕF¶/ÕF É};ëÆ»>«~·q;k´âȕϥYÃäú›êè¾­Åënjߣä¶ßénL¦1û ÀìÞÄÚ?ýÚ*^5ªÕÚ‡„ûï†WOµÇŠñZñêü¿Aº<§Kimè<ùï»'´åôPÆ`ƒÙgU ŒÒ2;YLë½öÉì÷—òpöO' fåè=´ýKô P&ã`lUçFt³Óÿïûÿ]jŒ[9Å€Ñaÿ²{°Ñ€¿ÒýE½ÒT{m·ômwð^´&—6*ï7ðqšö‘†;صc£×Œªâ6Û:ôȃˆÒpdrË Ckèdð Nb tØDÇCϘȋ!ÂÆÞ)Z)ŽW×iÅÐFÃP¼ÄúU§{‰¦Ùxó°\.rÌœ9ß+8¼{ýkûøyîßn9Ó£öñë_·7€8îèv{3xÐF}VüCÀÍuõä¡ú¦)•µÑ~Ô¹3ÝY²nPîxV#s¼îfðí_ÈŽ È'†N–Þ­ÚîÌqmư–­£íÍ3š“^KÖÐnnGþ¤üxÓòüá3›[/´9¢åFD‡»b¾T8L[€Sßž¦ú'Ê+å(¦ÞwðúZÛ}}|®MÙT†6ŽPÃ9Ì@¾~QÞø€ùÖ uÓV1&èCÍZß`i­Úˆ\‹=J¬£‚Ðm,6“îÃQ£©"Œ¥OœnS¼9*‚­Ž§ú‹l| <|Ðå/vghk½û!ÏäOÏA—xÒέ#Ç} lФdm¡E!¬- º»Ô¡ÁqÍòi-‘Èz—v _"î„.ô-5Q¨³öaVF¼ÿ@ÅàÄØã hµ+ÅÈØ0?‰ ´ûØ€R(*OçÖÛ-¼=\kÊl—²Ê¨&'ûM,õ@0,õôÁR­·Û™2Ê<Íj”Ž…vÖJbQ>Q½Ëf˜“¨ÞX¡]ÆH:hò SxÁ{ǃJàUj†¯ýêÏxùQ•Ú¡‚ãîÂÙÙv_ËÌ»ßfMsü¾}ù/ÆNˆaÊÔaG·ÍÓ£^«ù²½dJ¬ÇŒCÇnˆÕ­AŠ·êd¿Û{ûêd¹à˜É6Iày#ÜåZ…#çMr—‡½&nAÌiºñõµï3å}8ì–ÀdÝ9ÁChnõï€É®_Ÿž ý›ïƒèʾ³Fžû}ÑIõ0&8©!±¾×qu]ó&ßÓ¤Q÷¿ÓšœþN˜Ð)Ë$–ø"9vßrO‡YÙ†2?¯~Š5óKæ{œ “OžR‡½^ÌH½Ž¿Ly'_åV 5{©•1%J©óez/Sê|9_çËŒ:uøqÎé›ÂöFâp•«:ü¦ä¡®/‘àmb‘ð1.”Œu²½i¿ÏªÃXKêV"Îók×K¡ðMb GÀï´)¦ÖÀ·çQÅÕ, á±sæ.¢Û¨i*Q’öK£CCùDzÞµº€dw¯ø^¹4€½ø‡UþãÃÚn!Îá&–‡.ˆ‚(ëŠû=i>]“A~ÔýQjÓ÷ÚÜ1‹ã%ï¢âkQZºÝÍ.;Ð`:í§¯”`—âi?Ã’ðÛ›c{A+ Iz1žX–ËåÿÏÞÓ¶µ$™¯£_Ñdð`á÷$ÎËÄ€“øŸmf“YFXmÐF–<’ x6ùïWUÝ’Z²lcÂfnïÁ3ÁVwWõ«ªª«««®S/ ¥=kDN ì£ÓjÜhú¼ ï*¦‰W…h’ÞUPÊC e`¡¨AumÜe ð~ø$R™¤â¦mùF{£±N†¹!—S~}Êr`m[un?ßR×/åùø6£]gƒ~¾L.(ûƒãîjÝ;ÉÀb@ƒ…ÇÈÕŽ;©hfÓE©U;¹°\ÖNpæ áCIWÛdZcþ6Ÿ^ô„¿Lz1¢ ­ºDOØr‡«íƾéúæ?/'Y#˜‹ÎR£º–òÒÁh»ûTœ†wå:.Èpvò®P­Ïé«rJÀÉÚxùÄ•¥Ékt‹Þ$DšüÊnWëtK%&-¿ iy¦ßîb4I0|ès*ÕôÈärPxò—´…˨Øßd®ò¼–ÛvIu¥Uy;‰Îuñ0h:Î.YM—Ì}Ép›{®“V‚ZµÅ'Ši­?U¸Û““ü5|g_ÿ•$0™Í9Xã¥ûFq!ˆP»þÞðBÇ¡Š¦\Yi±¯ =w*ÍÏöH¯…á÷e3Rcz©XRˆfJÝ;(?³Z¶€üB3Ü~›• =÷Ú»…1©~È‚°žpžSÆúó+aøV¸¤ôp…l%pQ< y„Õ»"d¹VëNkk4‘u=w ¤‹_å¡»þ»_θK û¥øÈ숀C# ÂG‘]"ú<*œkþ÷ûn7Œ¤¶5nE²†,"9~£Èláat7 !0±óǸÁ†ïOÇCfK£¿¡ßG4ª=IRøäöI€~Ï¢‹ âƒÈØõ$ }q“±äý †.}vñÒ?Y ¾?Ü• ×’ h[fH!ôai°¡çú~ž4i‘'ºq9™„€ýÖZ i†2ýâ½Ï\÷IÚ±ôù[m‘"§STÔ(s^(é6;ƒÖI[PZév vãP˜ý~»-¯kWìC»Ë`? µ°Ez¸=Hà#tÜZl‚P ¯zº¸4õ¶¾ox :¾Û†eëÜñ§¾þþøô*ÅN©žìqL½V¹ú»Á™—Þ¡Ÿå÷Ü3l“}à7ê½Â¯·x`86¼Ï<Ða[ñ†dú(ßQ¸æèV±%® _ðàC ¡ØLý¤C¼ŸXÞüç8uJ–Ìn/þ—l¢Ï gôÖ¿1‡º„Äféª|½#míO#å’ÄÙ5¦¶þÞƒv¿ÍÀ9¿&$þëù 7k¢NÁF$‡¹zcïälãÝ•Q#~ãçêæ/ý|ìé_yã\g–Ç2®ŸŠSÒCq‰_.\/¡¹k¯_]øµÞéåÔ &ê}TÜcÄM€ôEôFuˆE—mæ_Â}¾ïÞÖ÷yìùGÞí€%âkEº÷±aÒöuŸï²n÷€Ââé){ÁáÿôísØ.­òq“Š_CÛu–T f4«à˪ Í)¬±¯ñô¾vÖ†õy¢¥‡5ñ^!LæVŒ:Û:²–¯Ôû'Ýf/Ÿ\ðþmE,“é„{«V<`©.ÀR] Km–ÚZXž-Àòl-,Ï`y¾–Þ"4ÞZx͈Œ!¿;&’n@Œ¸2&¾kÎ;÷d‰U—a²0Íù­…òÐðn,gÑõš8Ó—/,E’_j©*r3\»Faå•#Ýti¿s2œÖêûlŸty•†åmΊ– —³n”2BìOëÄØ‘¾ Öµ#áVDÜQãÉ«±g£á”ž¥èb[rûé‡ä¸ï,š°`Úi†±GçR•<ü©‘ÞƒÞ”C·.¤å”R?»¶ ‘”§x3œæ¬a&߅݃ÄHù÷12±Ec»p‘ÒÄž}—®~œ„Ä¢Üd ¸ÈoùpJÂ& p)à…ä¯ëÅ.£#ræ_¬ ãÀƒ ŠJä0Ò‡xÜÏÈ>†.b,hÔzÄÁåApj¢5Å= \×öuÆÎ,í/y|ØšgÀôC`ÛÀ(ëÛ‚”°¢L‰;¨öøSË#7ƒa áÉ'„ƒçŠ Y–Œ«…þN\ŠàŽv÷’DU‰~7ì‰Ø›ÐôRH‡åÐ1kH¸²f.ŒG5w)@¹Ç'è©I5®¢¦Ø'psÑmÍÿéœÕ1Æb‚>ñÛ*:»‚dB{S;?åZ"ÅÔBµ• ’ðý|4—„q9*jZ?Z bƒJ©ý|”/f ª.FuûÙÎD•[ ¢ÉçêgM®èÏiš?Ýò¹³IaNöy¶Â" -°Ð]6LÏ=ͼÇ5yæêаLh£·ÚlÌðÒ R_qÚnï´¤xÚU³¸Þò-Ûu>ŒÏßõ—è>@ì)­  ‚&k,ÔQ¹-íEðL)f ²ùæ¿Jš–µ²ê©‹Î°Î’×ŒRWŒÛÉKW ¾ CFá}l*´ËÜi€V±ü–  ÿc 7HVc6‡½z…f´Îñ YOÁG–¥RÈÙö öЉ–šS›ù ÝKCˆ*Ñø°¿:ë’qR('áQ޼3. D×v¢ñLµŽ$gèY“€m‡¢òÓÀ[2Æ“]²°€˜˜]Ô$äPZš§±™;%Ó[ÆR¼°¨ÊµÍ]ŠXxãYg9h|Nº4Ó ]uIýˆm^K¥˜†1ÍÈ`ƒ!Ö5˜Ö« €YÝÛ»´Ý7® Ç1®ôKgª»Þ%&Þð‹½Ÿ&¯ÃJ¬à¥ñúÂv/ÎZÎËÑë„N¼Jÿp8ÑjGƒñxZŽQmdŠ»ÀcéÄ„.™`§î ÷»¶íÞàÀBŽ!|œ:3MYh4ÔhˆôYn•/8ƒÙ€É@ •(Pm~"¬ŒßÊ&£ÓvØn\  ‚4î¡ o¦.b±årLxÛÄôÑäê°xÔé‰ È,ñŠÑ´È¨ê5‹˜Àx'yû…©~a<Æ»Œ¯Âøwƒ¹Va®WÀhsÞbz.5Åç’Æˆø!(55¡¡í]{J~.ÌÊ®DćOB, ¯¥Cöª`©¬¬ )k®‰QÖ¢ÊÂÐ,•ɬ,HáQnOqÂAÎe¥4Á ÐyŠsi n¬ˆD,•y0¥€d'ZÂdVɬô‰ÊK+j^†CÍʵáYÈÌü:$¡´Î¶ ÓÌ_áU¹-"ùÜühê É*–má–D€â'2[ êl#z_om$KˆŠü­>Ëÿ­Pã3UH” Ð&üÔž<~žÂ¬™•b™ñb>ÄçȈ·ÏQÁ~DÑHLì³ù8˜°ý2Ìj½ CðÞ}ºE;¢ƒ@¨sb¼¢XA€ÁþÆã>²–ŸvEb´!ŠlÚ1+„a#éµ´:òn³Z;àõ&¬Z’‚iß„„ûœ²¸°ÌoZ´4ãäþB 0ûYæ÷,¹µ¹ '’y©i¸Ãâõíe+cÊzµËI§Ö ÊNM­4É"£)ËŒk0“IŠeÓñóTM¡ž­ë×…,.ÝöiM'"ÖÓ‹H„rƒíÇpŸCrAhI(£4S-_/ºŽ©‘é‘ò#Z!ù¸?¦]2·…‡X*¤š,iôÄšPäÓ(­`›£O9ËyÏï»c×§gâø5j6‹n¡†ô ­Hø1…ÛØT q.왓vëp7'Wñ(å΢L+/ùmMZÅ«M$—Fä‰4e¢Ù_ix‡~!y¾6ÿs‘BçPÈbà5×ÖEb ¥WAR¼uÚU„‰‡À8ÒJ’]+CªH)[¤4SÄʱRE$.ûïÒ¸ˆ:Æypñ»Â%)¢#—)e‹”fŠXÙ"VªÈó­3§´0êx¨4½a=­”“feÒôŽfàͤ•rÒ¬8í~ÙÕ o2j¸`NŒú¥[<+ƒSÜ•3’·v±åÃÙ{§ëM°sŠUiðë›øÙk·Z]Ò"Xí Õ”NlèjÙ ÏoÁrsÆ`…€Am¢ê¢Ê+ÛwAù^ßʨ†UUaÕ£ü·Ù}»óiçÕÎNŸÛ¨Ô³J½²öØ“?DÀ8ñ#ƒÒJU §q(o=ñ¬nf(mßñPÞdÍÁh­vhŒa*V(ÐO¯yzlà¿Úa'Õý^³Õ¬¥£#Çý‹=m7ÈÇ@”½J«Ùiø)wk2¶=Üö HtÓ³MÁÕ~gᤴ® rÿ|Ë_ï°v·G+e¯rT«¼¯7qLЇÿ’-åæ¶»•hºâ˜ ó2£¯­$P&„Ÿ˜î?,«ÌáÊqUr—34ÝO ÊÑ!Ú€KŠœ Ýß?=äÅVIÕÌ•_£ŠUzªJŸÿåQV¦«ÁŠçÊ^ü†Êu“?Z¼X;Š^<¨2ÖÖñ Ñêï|z±ó^ìó‚À°  ôò ödAÖ¨7ßSYa–Ðkº¢4ÌÙ£¤:ÑôB}|WvŸ? ]Ú^Ç.Œw!à+©^;«¥ª/«É‹ íˆp’?]–‚ (=H§4bXJ$÷ézJPeê Ý™jeyÜXI.ÌØU‰¾IQ¿˜Å&•\š»åö!Y>i‡*É2QBòŠW‘@1åë°p»Üþ9ÎÝzmUñ»!k²®p³€’ò¢@#.­íÉ`/£/’š7æãŒCÂyztpª†r²%'rZÆÂD‘œ1FÖ4Ì3H罸#,¤Ð¤£’_ʈñü¬IerfÏ£2eÎ¥²nÕÏÒYw¥›PtU:g©Oý»ió"K/Ðu5§>(%4Òã²>¯gY0 cÎë¨bõFM¹FÚÙ íU&‡æo™;hÄ[÷´ES!Â)F^>~ŠÁ…Ê3[.…,™'æ<ärâeñzØ/Ÿx÷òÔL½ŸªíÓã„:B€n’HÜy,q_—éûz3+(€ûx` Á¬Ft—¬‚År³œ üR«µc±óö·˜Èü#ùÓ:mWj=Ý`¦ÜߌsƒÿÝ"çIЋ°c¿b+;z·Óù¢å*¨935ÕJm]x¢NÂàbèŽÔÞ7ºŒ‰:±?JKO!ÛÙ3·&4cè¥b­‰÷?Þ`Ú—¼B²Å”œX”ÐpëKí)ån%ñGêÅC!,Ý,e ú¢Fý¸ü]%—º†F{´Ù©ïT"V®$´~¾z%}çó^•R-1Ú™}ûq»}Œ[Å/þ¤oJñš§ ^úá»]Æä!Y#nO¹²V!‹zËîÞbÌׂ"ØÚfpxÔƒ/bQéÊÝY 7gߨÞnËí9XGñá¿ù“”¶è åÆN5Ãã tÚ>›™Dcà4*±Œu$õEª3ó<}ZØ›JÇ6eR¢¡$o0äØÁºŸi7´ù•Ÿ:ã]âcFÑ„/oŽlß»Ä7SF¾-¹k;N\¹ö¶xõÈG¶å²^½)QO$_ª!™#Ð02zŸ'h#”ZÌç)ë©QILùd=ÌŒJz£4ÆÝâ©fè=¿âRb¯Ru–Òók½qˆlžµîÕ‰ZÊuF™_‡¨ÉÖ2a“´´€ ³•V"æ¢jù„œ­ADD1‘P‘TñÕÉheÈ8£â¯CÆdû] “ÐÑZ@ÇœZ+ra½|JæTARf$Ã^êEŒ3ž2Í`|t‡³Â–e¦Á^êØE.ØTùlZZ° S쥎jÌ[Ê[Ê‚µ²`­Å`­\°–6µ@íå®IsÈ+94C^‘ª‘7<+WçP89•ªQ8 ¹´r)r) ÙÊB¶–B¶r![ ä*išYµ4¯lš——-Ý£¬•S6£/šf3jÈy„x*¨Øš¢2§¡BúLlA÷¨¡ð"´æÄ „rû)zYOBЉ—zqïÌó¢z˜Z Moäâ…MÒ*p<º‰O0îNc<IÅOfWä†78?=<<<)îôÈÐ*GĬ¤Ûî}W<ô œ¡ã8/’§ŒPËŒ ‹€‰‡}à;1¢pßž/^8±'ûrß\yÓIÔb©Zñ]$‚¯×WTÄ™&^b—ômJÃG¬Ù&öϵ#½ ·6²ìcxÎÞ¬¦I«¿Œ·DH¹ ®ièÄrÑ#ºÛjHPB\A›uM { òÈ}®#-3$Ãd«ð]C•¸`\Î Û¹SW ºd&ž§¹£óñCè]:x#TÀ7À¡ÑLƒ8qD›·Ax-.ÈFÈ@H(¬0R’ Å[ánüz [%WgG{SL“È ‡®ÇÀ»4øA*ð§ÉO#—‰3š­ÊûZ··_®R÷ @Z›ÊLžÙ¨ËP ÈJñaññÀ’ÜÀ 'V@É€ bÃÂKŠërÅ?â袧J‚‚¼s/‚³bLN«Wáå³ Ë²\¾ÙÂqΣf²ÌÒŒJÎcû²vFžS!1â°¢N Äeh_ázŒãM´{Éi6¥›Jô0zå\°ë£õ£‡ùÐMÔ¬¦þä “k",–oøx£‚¹â` ùäf‹?¹ÁצnÈ‹›ò ȃjï_µvkó; ‚ÞNŠ%8JÄvÕK(`$–[ü»¸õTy|ÓJÔyËw„aw%¯10Q Ô´Ááè¨É A¡~⣖‚KEçg[TÕpòú“üŘ~‰¦ÙÐ¥ˆ> ðV’¢¸›Â™bìÔÓîQ«ÍC÷ŠMû*sÇõ.hˉÈìÐÝÐu/Bö Mûo¶ÿD_:ƒi´øýÇÙ¯^¾zõjç5Ø;` >Ù_ÏþÇ%£úˆ‹d ì7¢ˆÄ¢c7ÀXXd¤ƒ ¢¨‚1µAv™§^ËøÆ}[åáØ$¼‹|»Ÿx#˜^ƒMaGôíàýШ%4ì?<‡~ÚÝñÀà`e¿nð¶ç^»â×-‡ÿ®·ÃøçWL~„apËÊ,ÞØ0#Ù>¨0]Á,£ÏfšÖ` ¦è~pU%åƒ= ¡Th÷ùQ3R|vÆxÜ,Ä#˜®“Éà.b•A¤+C’í3¬{؇ž3`2tÞ»`àƒH`ÙHzUÖg^  øÙ™Lípª®@÷AHû׫Bßy׋|÷¾´Ç¶Aÿ³ïsUƒé? †}5@iúùþѽ0ûè à«y 8t§XÙõY-ô®öðÍÜ>,Iu¿?øwì ta@o95ìIvèâ žÞáSƒ—oH Â+—7]ÐÁØ¡s|°}wăà ~4‹öÐéKQØßûöô~yCÐjA•Úǰï6FЉ< ähÅŽ\‘ìL¼C²wöõô‚…Á@w~iF6{÷ןá_Žî€u† éÎ;¨Ò@nöoôãðß²†ëÁ‡ÇŽíð:àï |v fÃè|„›8ö@›¬ã¸¬‰.åœkñ #?poqHág0v,œxŸÜaø”H…ż€‘ߊp¶á{ÃN€§°ú{¹ŽPÊ5¨nSöa0‚„)0ˆm_°T¾ù  :ua½æûÃ)Ì ô XP+AÓ`4†ÖöóÕžØcÖ.@K«xáÔ›F¬cÿõ_C^¿@+“Cwrõן¬ã„ŸxA|Âéóõ?̾Ë:ƒÑtxµÝ+høõŠìÿõ߃!¦ƒ¬e‡üÈ䇈NˆtèÜ ¿…¿·Ãa„¿»Áå”70n~`Q¼9Ÿ z…`³Aòïm¨Îöµ vÛ‡!̯ªç£ß™2àÔ¡“¬ Ü᳟m hfá` 6ä#ÂÞ'ÏÍÈ„¿lè….õâÆ»ñ"oPª“:šLËì«Átøä ^Õÿ F ðãÝWóÿZ;»¥LüïÒ‹—Oëÿ“ÿ÷Éÿûäÿ]Ûÿ[­uºí½ûóšW]‡4 oü"ë–]ÀUùi §/Ð8¶Åïçú•0ø\—»CŒŒËK&Gs}™,åËÌxzé‰r›koä8à RÉÒ3%ûHQ Ah²4z—<“8â\ )7Gì‹ÍrtúPãtJëmñx äiɃ~|ú'mˆ0OTܤðž8ŠO„ƒšŽ‰Ï´+öŒHÔ‘#ÎÛÇ‘ó øâŠ&gdòrÜÖ '£Ýïs,ŒÐ…þàE@zI ³ˆŠ$É£žX™u-`dÂŒoÁAćÿO\ OþÏéÉù «ôÕü?ÖË×;3ï[Ö“þ÷UÞyÈŒe=/œúлWqm4?Z%¾yX©l[fÉÀª§‘»GºßÖï@±_ú°4E¿²o¨‰Ÿ¦h;PƒP“n„7‚‡v'ÁÞç¿)‚ IH­ÛŸoÀŠÇ]Ž+PYCZBúŒêMÊ zJžcl˜ýgoµ.2Vn?£›ÉíV§sÒ®ÔÏ re&õÊqX£š›Ü.7àt(7x­ÿ›ö1d…# «œÀ§3æÛöå “Ñ­ž½Mß"ìÕκírÇàÛ­ßF×ß®›|;7ð•ño!?¤QÍÂ)I loQw°Jlîõ}\‘Ô]R<Ô%/bJ­JßËoí¿Câì!c{‚{&ü[ÓÙúÖ ¶6ðÍao¬_s1 †§Ìð#ž/Õ ölc³Ü6¸Néææo˜ èn@cx®”‹jœX1úoÇÇü“ƒêú%Æ&öU´Çž¹ø?ÿÞüÅüÊØ·˜·ˆb…¿r'Áxb² l¾AW%•šâNéo¢D‡ÎÊIì÷¸ë,’¬¤=ÒQD?C×q½·Ï´oÉèþZ/Šcû"`òÐlºæ•ÉoooA.Ñ“B¸G±ÅvÍ’i™»; âlÒ¡i‡cÛ0å㾞">ZråëCá!rÎixÃèÎwaàã;±ßJÞYÔÔìàðè¿9ßv°¢3´£¨1IÞŽi&;Q‡y´ã7”…ÂŒ5Þâ•£r«³Åào½É7å󆙴ч6Ø ‘.ü¹ûiÚâm˜+ò[ÒI>­Â%"…¡4$}棂9„‰wåOœ-î@o;Âkwg¢ó†m$ØB×Ï]0Æ€àÓȽq´&Ðä§OøáLjsÕ‹ÆC<7 ¯òpLLà~òtd»ˆ,:tÙi¤GïVN(™üOïct¨i0høD*«$e`I­-ºïÚ}õj±ˆWùïñÃ$l}3Òé?AèxeýDC tÁM1Š•0‡ü|Óew¤q9Ý-^†?ðïA§ºÿ!#”Ï€„dÿ-~xBLQo´€/:ÕÿaïëÚ¸‘‡ïßî§P)¿bSl^Cî äpŒ“ø 6g›¤½¦ç.önì]w׆Ð6ÏgfF/+í›×@H{qîšxwG£Ñh4I£™Æû®@ÇÍê;Á,Ãkþ…Oð¿#øïü÷w¶¨Ð ;ù~ Íi~6Úø_å”ÿÝåïÐÓÇ¢Ÿ§Ù‚­Îk×K» äµ[¯×Xç{x÷æ;(ÿýÖ“µ-g)wv4»ã`(-µj§ÍV£Ç>?{Ù^²Z•©¤ûž 飗ÖÂÁd+¿šLÆ{ëë=Ï–¯ì÷ï˳Ž@`­#*–õžؼ:¹q¸DZAÚ7…Mè 2{à'¬Ú<ý¡UùªcªݵÑÖaf2…4ßô ¼ ~ öþq‘n:2ÚÅ.Z`úø·*5¹ònã{÷ßDw9BŠY¹RŽŽ¬™GG¹Ž¬„c£yŽŒ¬ðÈèÇEw?*RŒµæ8&ŠYyˆ’‡,u<”|:”ódD«á±‹©OŽÔaoÀœ6ñ4n|Û–¤ÜÚS@íƒRUÔ‰Aõ¿³[žpþ/¯CöÉþßØÚŽæÿÞz²½¸ÿõHù_åv_¿‚ŠžŽËWK‘÷øÆÒ3ë’B)WÅCÑú\ êý~åWvÀg1n;¤û|õ¡Jß5ÞwÛúå.Îg>ÁøRø¿ÞÃÌóŸ§Ññ¿#h1þcü¯¯ÞÏ÷‡­bÂõ;yþèiåçwüÒwöû²wvûÑÊÎéõ%ïnÅAá{øü謞ÇåÊÝÙãÊÞÑáJæ²ê0Õ}ê–0ƒE@Õ© Ã0hA}xÅÄf·}Éín`óm “I`ȇߛmŸ‰gš_z£þŽF· v_Pxëî`2°‡ƒß0qzàgà$СË9„tc! â½@èU*È/íà¯Ò3L 3*>ì«—®ó~{Ù·'6¼Ä…3Ϋ1²°’l’ðcIø÷Ý$ƒÆsÚð•¢×(_ ÚÌ—‚¶¾$¬Eö¬¥ý) ï ¾á—‰Lg4RîDRp:éS&Q(èü:_Í :sÅûbȵ[€ýHˆaˆ^àI±7ìwù‡àð—Ä?'å>-ý‰—’µ † Š¿òó¾ñQôˆüÈ_ ˆùFa‘%ã ÆGÙi#P±Â'_wÙ´yŸMVðzãÞ C`rɧÂ],’Ê'ÕZºU¶öK.Nü›.|a;ð¾‚Ïak ~¤ˆpŠ@üOÙ|ãXdÎýèöß&ºd‚ý·½¹±³KAx¿¹ýdëéÂþû‹ØZùBµH¶%øëˆ(zíia-.¬Å¿¨µh¨Å™Æ¤€.‰×ìrèÛCê©;ø-ôYA?åkÛm}ç‚§²¯7ð†ºu1~éLίZžÚ¾= ºÂà‰9 ïlwùÄt1æç­/„ÛøÆönX4ö)ZpWúö/HWú}ä©cÖûš€á¹LШv¶Œ¢ák³ÌWÜ3Ù 3¥*£V³~TÄôÌò]·+Þv»Åh/àíK°+¨ºôÎ Æ“í.RÉàõ1!‘>zoz"¸I&ù8b?¡{È ý .ùÊ$ôèæ&u_BáG3< ÙÔ”0p?uYvÏ÷neÝ\yCGE¦ºt¾‘‹_±¿Uá‘«b=Úæ1&aMë“kítœ¥øÓÕ€ê«Î#SËg(MÑ$UMLºÙN•dy‰SJrê hzÀÊ¢F\B§h_¿ù&IM+†q®&õ)ìk&’k<ïÖõNWØnzÕ¾£/i­š&‚|y`Ð …2¬‚}R-ÇÕæëníûê1è¯í¡–aŸ`ü·7ˆŸÑÝD ˆ6MR¡ TIK6]nû¢;rFadm*{)ɾšYÊEm¤\•Í2Ìä97H ËRB"ÌLè1ió)ùŠ‚J““z×&²CH²=Œ›uŠÛq!çÎGl8T%Ht°ê3RLôyû R\*ígY2 Ô)ó Š¥¸?çª%¶Y® ¡ªH”h“4LЫ8 z6ìØH7j½¨wïµTÍ$x7[…fv”0ÍR^¯×ÿS;ÚŸ©Ø^ ÿmÿŸüÀÏÿcss÷iÜÿcëÉbÿáÿ±ØÑ_ìèßcGŸæÐW•×µn£Sb­3z÷•õZþ"t‹ë ÏÇd}àb1Sê%+­ÓJï6´k­HY¼¬³Ž½8>/Í7Ä’ú¸4uµyrZédÔÐÅH°öD#sö™]Î<ª'í¿òË?¿K«E…<‘?Оᖰí_‚Ѱo®•p´FË+~•’ÿ–qº×­sáLz>½à °Áí÷v ð_÷s»Êà¯Xq(}ü!‘ˆgDE® þ~?öê6öj•G‹‰ƒ¾÷üºÛwIp…Û$t!ÃñÉÔ}–PXzFßoåÓ-}äñgØ×ôŽž~Üø a`ÚO8Ù·Z[·ß|ƒF_bƒÄb¡ðž}Ã6‹ìÿØÖ“]±H¼M‚ã4¼ÿ ÀoMpn"¾©œvŸÿЩ¾–kLü¼ý©HbŠ#3*PÅT=< °ê»Eó~J@”õ_[ÔþS‘ûb0Á@B}ÀùO·d} ¹’RBÓÈÀís«§{æx$P¾ R¤hâý.—O‘׿Èí*îÁ¢»2>Kw›£F»ËÃ"tÛ µþ]?*Lž¬¿†šŠkHÆ>ߎc/‘BÝà–-?wðrzÞ»é˜ (ÿÌÊxé0aRZ¨G¦nÇË:ÎÝ ¾'oDõÑ»b*Ý€Ø@IR‹X\çfx«µlзÂÿˆ\K¨.çMÚ0I8$àmß=‰"\¿Zt(œ_+!ôQãóaÍDÈòØHUƒs@>zšwŸIBqÀÝ #„%Ó O6‰íñhÏ'&š ‘ ©øµØ,ò. ~±¨íÖøDE¸+CmIÑ7úu ´øäS:ÝÃobÑ{;¸ä)|-œÀy«Ì¹•ÿŸòVõ»/¶Kâ-Z¿¿&fv©{ª`œ …®ÔÐ0>võ—¡j1¶(ŠL£ÙªUÏZíZq_L’SµÙ٣܂Kœªý¢­ 3ª è=NÜ×Hs”E_sⳈ©Ñåô†X¨oüÆö؆ړ4&î¶þ®mÉ" ¡¢Ú ¢÷jïVNd2IsiC†³ßˆœj~Ñ–Ó©—²£*¸;…†®=.xö mÒà21õÑB8ôí¯‚mC~Šáé–x‘p¢­ïââĽÌb‚ÜÅ:©äà„¤±ôLIüa¶ÊÏ€›Úq)YAa@åz°Q&,Ï)rÎC âzƒn`îµ¾í7`Òsöˆ%‡«i"’<1N~ Çž`б/áŇhS§x4·"ŠœK,ââ⊔âà¤GÆJŽ1ퟂÖ#¡È‡-ᤋ¥c´ªŠœžN¡‹Pj¹…ƒñ Ñ~@™æý#ÒF(/dÃì!!êqƒC3µZÕæQ­`ë‚)ÚlÂUÕæY£#!Cªªž‹+t~jh•°œ…é¸@•†Ç2Ê®ág™f­Õj¶ö,Ýõ[¨Ã‚¤ä PP:—A9É!sTéTöµò*߆VÍ‹fë*J¬†ã³Á²õõ‹Jý8“™…ªñýQó¤Rod j4;/€íG3Q5;õ“ÓlD0 M«öâ¬];ÊÀ# 2}¿î9´sD>HUò[÷)ñ]‡¶lcÿw{gkãItÿ÷éÓÝÅþïŸ>þcÞ¬Ðp&op P^.±KwJ{Šq …ŠU=Ø£‘I‚‰°^çò{Sî;ëã«ñùù=BA†íÃì²ýÁDÌ"“+ÒãÙßdÈŒ±»­·ÞÔg ïÚ ªqô]Ù\¸¸ã¿1Ç­%þÅø{ë.Á‰`©Õ[–ø Ëe:™)Qسjô¢t±t>pKîD£ÑK>¤Š^4Q0_Çñ ›€æs÷ö¡£‚²Åd·Ñ@Â`îp$‚ªÑ/T ¬cÊ´ø—DWíûNÑdQ¬È(­E‹"”˜ßTÐj‰EQ7g­cãQ¡?/ÖÖ– ®7¡Ü¿‡Å"Ka–Œ±2õUŒë¤Ó®¼@žÿPk[íN¥úüu³±aA}µìz.ˆZí{ îÒþâÀR'n1¹Žàä€:„”ó,ÕmŒåMxì+{:ñ0>*üÛ²õÕñQ«Þx •lG»'AšH‚€· —ðĈ渔hv¥U}e‰Ñ×ö=ŨãÕùuŠY¿<¼Úó³—¸N?Ö,¶Žé§DyôÜ:°£R úŠ5Ç0# ~£-†=Vj~ë>C,*~¼»ä¡ñ Ë…£çÅ5^¾h}Ñ<í`0Ðæü¤dó¸Ô:0D,²æ$Ä¥@xÃvÔÅ–5ñIh ƒÖ¿?p®e„1ìgŒÍse•ä.7Å ÄÌÐë2”EýŠ™YÙ†tÙSDå\Ç-vÐ<>r9S}óÂößúâ¤Öi5ßÔZßáY.ÈEA0¬/@'¾©¾éžV:¯¨å·kë È!\±¸.tE›ŸAMw)¶~\ñÀî}„˜ªUtT¸éõpØr¾Ó+Œ5+;Ùf.t0&s"¿û湞£wà‹b-§l{P"ªlñô¤ý1ôÆ8ZÖÇþåÄó†Á:àÂ{@O7žll–Œ­ÊvðÚú¡B‘qÏ]¨tkƳ=ùŽ eú† µ¸·_ÉÁ'ÇÝÈößñ¤’\¡ÙãcCáB޼ßm†4QbÀ¯ÔΙˆdô¾ßct•‚^ñ±þà c‹W0˜&ZÑhò†s±`ôSÛON¿ûþ¨J­‚W(Œ/¹›?߃٥ZD^çÓh¶#eð/zƒæƒ_tŒTm6^Ô_v_±’ »O².‡eµZ\Päa‡G7Ã>©qÕ—C…ƒYÕkÇgGµ"Cµïé×·{¨Êž N[ÂÀ˰֢à˜ùXb­´âXKHL^T(yŸ,xeë+õXA< .ƒÉ-˜ ª %z= ! ã›´0,×Ëï+ƒÆ„t0謄¹þØ“¿ïêx@éØï»@˜r1ZºÁŸ£îi³]ÿ¾ËØ yHB%$BÖ º7¥Îàºwx˜R6W eà„vž2 ‹–YÖ)f)MßÖËмvŸ®‹k?àÛ/`Ž„ÉŽáô©XÂ5šØ4\<ņøzpC¼ýªv| £ž`}q eÅú*KÝÞø" “Q£Ê>4\ÓƒÚói™Qa4lŸ—mYåÓWÍÆ{´˜Àu IZ›“‹AÓEdl €öB|]E/b­_ä˽3}¢).Îvx¬í«0z< ­y‹h Y_ò(ô«´ ?ª oÕW•ÆK`ÊWX]b Îä¯-è­“ZêÇãˆE©Ñì˜èUˆòîrJcM¤‰¶ä‡Ñ_¢Ÿæ P i#eÁ¡Ó»òXÏÂP¬—ᕬühÆ”ø·éÏ3ð5 ŸG JËs $ûÿÊÔ·ºÜaC'´••i();{9…°HnL4JJÈÔ=&ß§a0(Àô =ë+É2‘©¾oS²p3UÇ¢IO¢ ¢^é=’Äiàë›ïЏ1 ‹•q‘•<‹Q ÜÙ‹o_¥`å+¤k³xá+ò¢£W ‹_Á2ÿS{qCÑ7t‘˜úƒ 8ñ‘rù:|wB^x.á ^D££XòcÀº/š<Ð)|5MûM:OŠàËô‚iÂ``–Ò~Qq) V÷@¸”-÷– r‹J‡äã§q|Òùá´f”£ Ìü“QHß &£ è¹Þ;4éðKz9Ú’2 ö0Q-yˆBk8€Ù.n)¤‘¨œw–’j çu¹}cðó|z/e0ã }]iÿ]Šs‹·Q ­¸— ‡bm oŠéÔñý³âÚ†I®»Ð›»³‹n'}²¹•QVˆU]Ëžô'¬{ÊÜ4Ãá¬Û†ù8 ‚›ôì0ÍÌ/ÃÃ]Êò^ îZ¦…{TŽVíŒâ#¯?í‚MÌ”bÙO»;i˜Æ3í{`‰`ä/Íip¢ÇŽçÕ\½F€ ±² )ÿ ­âÏ3Ú1ËDzø20?»Í²bfÈÁn¬%Mëðûþí¤b0Yñ©*Kl›GØH$/ÄÇÔÂõ“xaÑ^0NÒ Ë^\¶»9Fîx:Ñ6µRy+à„Y3 ìPm‡¥AòÄ,<±Pep.¡)–a.Î?鯯¢Í‡ó½5]óέ®ÛíZ+?x­Õj4çÎ &Mç874(õZãu~àWÍvçùs(cUo§ÏWf¾§­f§9_5'hru[¹í-‡9Z^oV;ÇóÀv_ÀÊÿy=ïìz\?©wæ°þŽs›‰ÕÊñ\œ9©C¡Ü”èrAE8(ê̼ÆYq¹¹M—Zç_'§ù ÊúËFåx.àypw+æI½ÚíÌa¹Õò›æGâjŽ…ÂÑÙ‹„(‹ùÁë—óÿŸÏ¬œ×楰 ¯+ó,H¸J˜kAÒ©tæ*@ƒ<÷úeà³9ÔðY£”õâp6ÑoZõNíuž¥B†š¹ ]h\µ+Ýyf"'ŠßÔ;¯T™eÄQòÌ-µ9Õãf»–4SwSBÁ˜k_dê™»H½9ϬqS2 fgP·û²qVívs¡~]iÕ+G O*Õ,Ñ_V«D!ûî„¶úd¡X/š­jmí‹3á?Òa˜ï`Ý—Ý~äYìm óXÒEUÞ=â3¿pc»L áÌôøOTWû‡Fó´]o[eXñœ}¥E„Ä@Ϭòé)~PÁ¤5 ÌpRo/êâçÛ‹Ó5¹}Γ%õû¾HZ¹ `¢8€ÓPóÆÍWI«åb@Í%7Ýúi§ÞlXxG÷íÅóX£¶‹PD%iP·€“»Ü…jÊã¢Y2ú‹%i%§SwÂKƯU®·d$%¶fÙ%CU¹]qDxÅ‚9ñè–‰ÍÄýB àbà‹`¥áÉä¨ +–d—­´v ŽGZO92Bаpü/c‘çÞ•öG\!’¢ÀÀrWö5Þb§áê\¼i0¼U¢D>ŸÍòÓòæ¾5K}&ÝÜ,oðÆUÎ:¯š-«†‚Z“Ô½z÷S±V¿¸òb;Í r6‘ÂÁô-Ôˆ” »'ƒ×PÔ=UhN™.@ÆsyLGN?@åhJc¿D¬è5öÒw.AQýË\<§Wƒ!{>œÂò<“?Ø ‹´ª:LËjv©:}ÐcÏíÁp½pÎý)¶@Úëÿ²ßMÏÙ+ßûÍyWfMW3…RЙӋ g‹HlçƒIZ¶Š[c,Ú>c ˜|î[÷[hf.4Ëû»¬ÿiD{.OŽß>ÀŒõÿÖÆÓÈúçéÎ"þ×ã­ÿåcM‹3jåøøy¥ú®…¶6P;‘òˆ.…d—>m ÅÂø¾U+C„˜o‰#÷#q="’^"bV"-Ô' f‚Ëñû¢ “ŒœO qt¡4Ö;_AîMEAù8³òEoFó7gY+ªìúSùAXÄïÙh2Iïõèè Üc¥!üJ\¸!°i'ACq9e"ÃÍ^®ž½J#<%m™6ü-Õ…Nž:€Aâ¡mk_Т ÷¸ abAZ܈ÃÚ%±Àºr0‘/É#o"­/Êö§$“GÏJH“ÄfU¼ä³;n·Ó’E€–69î°SŽg´Ì*ẇe`,û×O´.ÄÖ{cÆ;ÅŠÙQq1’+¸°÷­ªTñÛ.¦G»å Ý4ÒMk1½þÏÍÿ¸O7¹üí#LOŸ8¿²¥¥¢`<öqÊ\ªÑ&˜„p§¸âøò­»ÄCØâ¥Zž ò¢ðeéB¥¬‰ ñ§®Ø÷¥{ür¶ u$²´ûžGDqÔ£[VXÙ¿`šÛåÑÀ¥Çö¤wU<ÆÃÁ¤°þ¶¼ï‘¼™Ãcüš}‹’TRHåCASèÔQpƒŸc%CóöcäWüg*{¦^…µ+ugbc’¢Y’¡I$R¨ÅˆP)x^uyݨ@}¯?­)%qÐËÁ„ ½KV*ÁBÜàN#(ïRÉõJ=oèáOX8<á <8=3K$Ø»˜>ýV^L[Â-¨<boñz”i\&EÞ›P\ZÛ?ÇO‘–ädªGyëú@Ê ÇŒ–ü5àu0X€}+&ÚGgcH(JrU% ïŸƒrlþmÚ˜ÁK1éx"ñ† L *F# ƒOí'ö%G—O¬eÿ‡’Æ=´i”‘ÿs =sÿgswgsaÿ=Šý'œÞDj ®š)×…¥Ü"ãŸâYC×p{xs‘;t‘;ô¯”;tðÄîù%xénî>¯w…N¢i~rãùïDÖ¯Âæ.rÅÖôøŽ8ÎoQ¼ý¾ãóžá?É%âI6LKf&1N†h!…q‘±B4‡™öf‡"ÛxØ×ìmúæ^!R¨M­8.Âê®È¾ý–ýý 2Y¸X\›?ñOk··’X‹§Ê¬°½õ€œÒøJÕGùJl|îmí<ûÙæîC ÛâȦc·âýj0Ìy!¯kìšXË9’” ´pMî¾/‚À¢ä‹k™4qºˆ'Iè®C<ÅQ¢³sµµó@T |›»sãÛzX¦mÏfæ"f8•ßซ“Æ4 $aò=ôrÁ}üی١á@À+°:!hë:¾Hùx8y8pܦWþéª.öÇxWAa5¢WQ‹iã:ÉPG‚Ê& GTŒµ?‰$k¯&èºp=Cô’)2ž!á‘ÀÖ…Òä9ƶϳ"~ƱGù(ì3L{eƒÆç«bb©V¼Ž˜+’H½§\d6K7O)eš‰A/½-.±t¥2£î­¬º;Õ¥7³J·ŽKóÂÅÒIޞͮÿ$6J 5ô4¹î^3Y8Ëÿ>âÙꌂš\à‡o æÄjä)»›X¶ÑÎSöïÉõ¶ò”ÝÜ(FÇ åLEÇÄœƒFfW¾ Ç«©èCjÉ–^P‰Ï)Šœ NÉO‹©8åxó༠œÛé8q Ý‰Î­tœ8üî„s3gë(7N…2YB£·ïÙ9ÿ1PæÂù”pîdÐiôw&NÕßé);GgʲéY­|zùݬòjЧ—ÿ{fý­™å77AÊDɰßcšl ÷Š~ˤ~:-j#zàßgµ6º/ÐE·Â¯Å”Éó×br©êq¥Ý6‹éjêW$x+[KÝ™b…Dµ’I“_¿Æ8m”´ËÂ^sÒïÂj°öÄAî÷£ô·Zœj?ÁdÓx磥8½ ÅtŽû‚ãÑ;ljê6$/»+{\kd”ÕëýûÝzz6ÃTWû»Òì4?Ö᢬`Y8Òá~ØáIµ#£F­ió þ¥a 6¦a0¸È….¼<߀D-|7ÞÿC]RïÿòhûÿÛ›»ÛÑýÿ§[Oûÿ²ÿo}%½½Œ®ý_.ÇcLõ´þÆžLJÛ[edìù-{9æµí:#öíå5þ{xk_y^Ùõž¡“è€Z–ÕižÕ[ ³—ZÖQí£{¶j­Ú¿e6y= ÷ý,—×1Q7Í­5Ûëè6ï¹ )™tôÄIo*PDð#p†NorÀÿé–L<†é‚‚0QÆ3­mbZîÚ÷Z½ÍˆjŒÉNqÙ1ì² _›ÏÿÕ}…>±"ùN­ŠIpDzrí£Ê‹jG“aíöq¤6‘ã¯Ö€Oa¢*ü/ æ´=ÿvþvìù-îÜ—{ÛþÛÚÀß›hî<ÙB[pcsûéÖÂÿ÷QþÄ=9> Ž¿‡º7¶$o·Lǘ™Ø1åbÁKq£îš¹ôŒ3Y¸xãLœÁEJb»h¡þy ¼ƒØ(ƒ×±ª¬rx¯®]k%Eá0Í=–Ƈ±¤>.ÍD]mžœV:5t1¹­“a1Õb2ÛÕÅÿÆrt~—Ù’>ùƒk°ãôãKë«)9¦½©7ðA"£‹`Š_§`ø»5è°Š9å7¬Ç ·øe¯ølV(¢È0#àŠ¼~†nÙÑà%TѾ,€xÂVò~æ×çlÿ’<ÍiÓO¤é›ÌîÐóÞMÇ‚£o'¦â‡çûØ.M=ŽÇuÞOt!ÞÞU›þ-îe@]çRä¬QU8 ÖŒj³îÇ€ç|zÁ ÛCÇT ýÒå¥ÓjP‘V¯(<†nd«ø#¬  ±å‹ê¨Uü{-†%‚†HOü®ïwQÞ ¼…øsMt[2f¼)Þà4e*I˜$6ÑDq~Ó¹O µGŒ‡‘!tk¡È­ß5É1Ÿ$rpÁ +ûò€‰$è,{¹[$Ò~jTA˜d‰Nýätm¬±ÆÙñqq_ÀrÇ,þôAÖ*«=0ªlÀz1Ê»wQàÄ–ž‘͉½Þ)ª{5ŒÅÑìæÅ³‹¾.Ö&Ž_î`(~KAÔëƒ"áA6|)FmBNj'³èd”žI±;е˜ÖÛ!¿xÕ#gÔß¾N`÷C(£C»Øïʵ;×.Çe|$ ¡Ô¿+ù?0Ô®*î_R\ê/cš7dR陦Œ%¼ÔŒŒß÷b†VJ÷Ã]t5P}VcÅôUÏ›[ÿIÎ \Mj“‘¡‰0´£ clqZS÷± 6þæSà°ªzW¬°:.*ô»úÕ³ÁÂ^9_ÙÓ”“®+¹–4º[É']EÏ`ün `>|ÞˆÈòãá-¦5ÖéžvZkæü–¢=U…¯ôa6ñÂh"g8Š6¿­„F‹iD+¶.­[^œg=w†Þ[ _‹0µ_*Uó¢yÖ8Š´ìut­ ÀêöÉø;fŠÛ‘|}€UO‡Ž¸JŽqedh(ÏuLd|É‚û\½Þýfþj€á|`|X%Ï#:‰ÀOÀ2ÔDJD²æÀ¸ _4êú=ÒšA gi&šðÑ.’NñÅwìwáçJ&Ta°T¡‘1ûˆ¶RöÔŒš ‹R“%+&°ÈÉoßJRbßhæìÞ”½ˆp‰J92D{^NÄ™óù~Ò¨ã«Ûœ.)g<„%6" # GÎU¹ƒrПYZ]² ဎJœšÜîÐÀ݇kàî=¸›ÑÂ\ãóƒ˜è“§vTãùðöæ°èçj¥Q­׎¸¨dT¨LÅö¡¶M²U)¦+L£€UÊábÌW9¥grû‡”x1‡½¦•ÂWÿ¥gW4I`³£-6-­ÆLt“;uâ†D¬êY6"À=ƒÑ¸!m ”iÝIÃKƒäìÙ0W$‰+MS¥½{?ªwsS½;ÕÙ}„P’úE¤àþGBöm† ¬†÷ˆ³ b4² ƒYFO‘lÌi ªxÙG ±×A†1@‘8Òì–ß ø#†=ðHé]ØÁ=ÿ @“ð#iàåšNý¤ÆÚ•F½ó«¾ªU¿k'As4AȬ‚3/ÛÜß%þG µ Š*^;E+Úuø– ÎÏ肎¼Ðþt9XއvO‘D"‚¦S™›«AïŠ:“ÄÑf·kí"¡q„Û$=[Ìþ”´Å ãœMyD˜ýåV¼Q'…YRf•~ ©R±cˆLG1 <¯¤O#ƒDŸ 4ŠÒr‘è3êÂgTè {0 0?…†œä¬Ç ð# ü{bØÑHò=°aF…Þ²”£ŒâÙ£›ºç¸K¬`Âl¥]"«|á&eP^oy-·Þ”z…s)´‰4²iô€ùBé§¡V‚Ún*âœPMI­oxÎr½ è‹Â×Á8|pö¡a>‘j3: kõfI•›bæg"7É8 G骾cƒqˆ‘^h˜“|®‰ 7l=IêÄã c] qs…€9j¥IIÕýÜÄ]7˜»ú`‘ú€ÀöǼÓµ}çÚzcÔ¶P'(%ô!ÕHãéj2ï­¯÷Wº ¦ú%A>w&7ŽCx®0e¨kh7ŒøUÒ4ño…Õ ‚Jq–‡$ZóË8l}5=A!ut«N¨CÖ%Ì_œ‘ •6öÜÍ•G£€z¾žÊÇg<Þ@b” áT©à^ã@š9ÀÁ;â±ÜÉ ¥Ô¥PN\+¥ÍídŒÒÞ|Ñå;ÍêwǵF·ƒÁ¶øØXÊ€âxr Mf–{ùåúpó›lÕp8vÁ¶òAOw3vAW`ÑÒ ©´l¨L¹Jžˆ+Ú<%'–U¼ÞÕ»à·Ú¿ “5åŦ ]f Ø?Ù&Ûc¥Í¤2/k…É&h”­°Ôf‘=SwéñCX>Þd¤â0Ó"kˆN ¡KÐéMx˜ ’-Ú"ñzÛå².ûŽP¡-m«Ðh¶/y¶9IT‘ÙCK –àù%ö7nã@×t»=µjînlu»ärÿ£Á0“'£ëŠE̸np"BM„3¤€ŒVÛAjÀ!—”ÆÚÇ1æüJy¹]ar„F,ÝB猥9aêG ”<œÙŽsÄ"Ê fÀ[þà–{íûN­Õ¨ÿÀ*#Vo¨Ç×õvý9XòGµ˜8»Þl´?¦åŽ›Œþ€ô(÷8äÁðt©Š¿{YK¯mÝìsÞcZåsçÖSëTO%NT¨¹#ÅÙñq÷M{«S=­ŸâÖ@ìcû.ÆíÔ¯(ØÑüž¬-µÔ‘í‡EÞ‡GØÿÃ~ö7ïþßΓÍÍ¿mnomï>ÙÝÝÝxŠû¸ƒ¶Øÿ{ôø¿r;¯´µ±¹°§·ˆö»ˆöûi36gÅû•§nÁ¤S ž»Í]KÊ.;,-Ω««š/ –+ª$×c<¨ØP•Óº:+C,fžÑªSö³Ø@тҹ‹ò¨ ×$ÚbLW¸Ðr(?2¯ÌYå™Fö.XMªF:ì ¾Ä´‘ô[C„jOóC@n H'Z­êkµ­ý" ä-R_À“DQˆ='›Ží[qúbËT`ÒN÷ç˜r ‚^öa0…¢öž»Zþµp£Œ›¼Ÿ„ßÖõ®a7òðoøs<1D°ñã!Pœ*qE^÷d£^Z ~Ï–ã¢VôE†Kᕺ]4:»b縅˱o_Žl”rdYa< 0Okì=Œrô%ÜÛÜýûBµ¿)Û²†ô§ït§D\ç”Ðè'¯D4æ{_bØl|†‚<â N~± B6%JÐÍ0δ§²ñk$¨Åâ|môÆE£~ 4ñKÏF¶ÿNÅŸ@w4´»'•ÖwÅHTKgIeõ0'‘€7tßs—à=+åƒÐ>½—°/Í0zï¦ØŸ7 ‹Å’ ¾Š˜ÕÌvëõÌvªÁ“»¡f‰ý˜ó55?g[;ßwd[g@Á"0ƒJa俇Yb?æÉûì0ÁçäFåè¨Õm4j-¥ˆy®×wr·Ô,q’N›­N.ºÐ‚ºqf±9)lTN;­™ƵUÇÜ´EËìçÂ~1´/ƒÙ‚/’=N¨`¹ÎW,”¯ ß¹sn¾D™¼ÐÙ%ØóÖœW«6+QMS}ž¼:çùd¶ò‹–ØÏõäÈ`ªŸ§­TVË¢»™qz?XV¬2Qš áxØ·xÔæ±ÓcÆ´4néÔ7Á2íiiÿº¿-qÉ}µÐXã œÜá_®‹œ~…¦nE&{æSÅàÃ>™­h]ÿæøžÍOg¹Á=¤]Ö­®¥ÝOvÖ-ÎÛ¬èL™s™Ÿ8!#h…&,:Ž8Ιå¬~N›nCö»¶ M4ÈOÖ²&¶ *‡¦õj¬_ –2n¢ýn¥Ñ–´E3‚ëË"Zl}²ÜµX|Âê ÄÐ6 CïgØ…Zðó$û.0ÅbËGkp\ASÐùäá˜mÜÅ‘›6Z¦Ñ• 0™Þ$ȇd~&ÎÚs¶^rq¼h8A£ËüO7˜ØQì°pzQ9>î¼j5Ï^Ò†²5]™fúepÏ0ærÁ eàØy¸¢™}qܦõ–AD¨Ò1hD€’……`áë$x™ùa#¿JŒàôBz¤Í|íÔlÉ”6˜ÖଇÐIÍNžöÇݸ§‚OzIà)L ‹ÍËÙhɹØkÂñE­Ù ÆÆlÓœ°ÂÌÌ ÍMÆÜÀÊòËY´ˆã§u¯ˆYkÑs‹ŸK—ÇMÊtÓ0KI'y¹Àß`¹¤jj „É÷*àÄ¿ Ý6ðÙp#0&‚¾/LvÆìÔ$ƒ4f(6ÜtJÚsÚ—d¼ùB5 dá€Ýϰ÷×;ÿSÆÝC]œqÿïÉΓhü¿­§‹üï©ûñCĬQ‚£÷•zÄ ƒ/Ôay‡I¹aNŽÍw]0ý¼êíE]l³ðÛ‚âza» õXiH®W‰×X¿JâÞ.†× ñmÀ½o}¾h¥Š0h FY”G‡VFëˬ-ÄF¹âRuì(|ÎCOi_TÉÌÄkÁÜFœßüt)z‡¸ÝAq8ìKÇ‚¹Åë ¨ Œo›…õ$1BnœÜZéùØ æà‚VÇÇbBx®}'.èÅçcƒ*™ƒz-‹jpÇa¡Ob„pNµ£m~€æÄcÈP䕘‰ÒÇ}ÏáNœ2ž #nJ¿®Ô+ÏëÇõÎ‘ËØè1ðòþô½þT\öºYºl–Ÿ–72‚³húI‹Ì’0î£õáýfˆH «Þ·Úuðlà|'ph»ŸÕjÜŸeµþ^Oÿ¨¶¨{yý·¹±»‹ÿ¾ñt±þûþŸwE,î? ãç_°¶ݲcЈ߾³ÇÞÔñGÎpð¾ìù—Ïn¤ 7ÒOëFšáEJnl¯*¯kÝF­ƒ‰‡ºõÞk`L­Ó\ºÆ™¬\\­ W¶HÉ£çñBýóøJë´BIŽ"e0ÛÉ:V•U—¦íZ+©(JÌܼ4¦úÑ –ÔÇ¥™¨Ñ›¯Òɨ¡Ë£½hdæp½uïè –Œ•0S±äHšfJÞ´,]Úé²Â·º ?Ažø™µB‹¨~í÷¼©;ÁÁ(~ Â|Q`™¾ÆV¯…Ÿ¨žeØ÷»ÜÙ~ô† pé%õe"±ÿÍ1áÆ¾v HE–-mŸ?¹%ð /åÚÆYp*Þ£íp˜AÚ΄ f¡2Á²|àŠûÂx¡>‚2OÜ$a³zÀòonNÇx¨F6¯»"néúž7Þüz”@EÃ03ï·ìÕ‹ú÷µ£ö².Š ˆ²¦úˆ†ò“Á ©GC/ £:Ññ@ùQ£Ý}U«Áðø÷QµyÖè0JëËÓºº `•F ‰—¿<`›Y”‹¦JÄ*\$Q#naÉfòäŸá<¡š$[Í'“àÝ`Œ%ã›h°ðå¡ùF±˜K†žÌСº¸4¸ÈIŽ¥ìÂOÌŒ'é\$Éœäô  øûß‚öLRÈónë¾jQÅSòVi¬æÙÑxU‘ºBîÚ#¼çêØèXÏEªò¦~OFe…V«Há ÁP”áÂ€Ž³Ø¤Vô(<|óI8ÔqäP|.ì—VKÄVUËZrC*‡©Ðæë¡:´þˆ¤}ÿ2-íûï³Ò³œÓ1‹¾kµ2º-ZC$k¡ÑI™4å*Æ`«E· 9 aÿ ½U+ívŠçþ0ǵFB¶Wµ,¡ÕËÇir(2U (õÞðоC»­˜Bš|Á@—³“鹿*áABCn°*Ø#ìë¯C.°N÷äûd‚¡Zš‹ùÂA!ÛÜ^h¹úÂz¸ÆÞ2}·¢³ò,>$ðÂà‡ ®"öŠåöŒðþ3ˆC­o—«Pq„i÷Ë _L|¦ß­Iv'‹9s~)PÌÕtЍ›«á‘Ì¥|>Ï®K•ž ‡5¹§aVY#30 sc&®ÐâÐm ùçZÌ>êŽÑ ¥gš?ŽÍîæîóz§pmþ 4ߨxÊ@ ®`•U4jÌP¢×q%ªÁ™%¢JóªÓãùÈCs¼JWeˆzk0q|¾ìUbªÍwBÇëŠÌ0ÃZN< £h#J.4Q¥2Û}èîœ6çŠÑŸËçWŒNBñÄ=d&4ø²Xª§FrXŒû‡ð<±¤É¡Zäà¡Ö-§„º·U]´Üy 5)Gì[Qî7¢“üÉ=G’â?ƒ¹ÝõÆüÈnû¶Æ²ü?pÏ/’ÿeçéÓÅþß"þó¡cáÐqçøÏ¸‹Õ<åá\føtè*Ý:Ú6‰‰{1¸œŠé•çj`Þ9rW^âo}GÞ•íºÎðŽyat2 :>Š ÍRÎ}SF’N!â·‘×Þìà]VXi@ÿDrCb Jx¾•”ä 0õŠ‘ $+/IºÜ1]ð¬Š_çBý0L¹Õ s¶8øÞ,ï–7ÂSþˆ€ªP K°º{çô—€V[DG·Ñè¶nÈ*‡nÁ[R2¨RfìÏÝç)r¾3%¢œ­ïš „ˆ½B!íD×p%Ä›Ìç~ÿKé]>%f°¼ kb¬Œì[MÖÎ×qèLy]”´”ÈJ}ÐŸŽ… ºq¢ÍX¢ÄGQw«Ð}!ÂJ˜ú¦OÉ(ø¬=dõÓë]>Ñ ßšœ ­§®ÍIUÌÙ<ÅÉ"§Úâ.:G¡ÞYåí5»·eŒÉ]ý'8§a$FŒ ‰mÖ(´D"€8䂯cfJ¢L¯ C• '6KLè ÷vjfœ¨B0}%tMù¤Õù½æÑÑ]G’˜IÃÓî÷ ·‘ÍòNyC÷ÊxîÃjÿ•7E¿ŒE(þÿÿûÁÜ?fùÝ]¬ÿþ"þ WŽ…+Ç•ãÛ•#DÖî´ê—íž(H+t\?©w¢e†ƒŒøp‰ø†äαšË3Dy@„©Vi¯´™sUå®ä«r•¶2‡gIÔedá5Â?M†k™Š Ðém(ƒÌÊå¸fÌðЦúå\þo8¢ÛÏrþËîo‰ ™cRmNÛ<ˆE M|•!/<Ð"j0‰4å~s9­>Ó–ñÊÉo¦‰§]÷äFYØÁtytN>PÙ6åôüWœÇð½ŸK¤E³îà§2,j`ãs`ø NŸEŒ 7>È5w’ÖÖpæº=aòPëw™nBO(J{ZŽ;Á­Wä>\V¬VSŒ)Kù!³ÿPéÙ— òŬµ…äd/µj6Æ{ï÷„Y7ÈЕ@¨TÙþ0öáüRN2ŒŒ6 Å.uü~6´¶×î•fÁ£ ñ%\åGÌ( BŽ&ÛFI¥cƒ’ïÕÆGfVÂÁ}ZÑgLØÞƒŸr´—6p,ÒaäÒ…ÐÉ Ë¡<{*jŠm^mÿ9ú'ÑÏ; ôÁJ«[ŽŽtE‘}9D@~°4†”ìxßÉí:£÷4†53ø)\›G?µÄN¦X;‘-Ï ÿOíÿïLº8% »ƒñîC\˜áÿ¿µ³ó4êÿñdsáÿñ‰üÿeü›çŽË^ÂhÅüí%ý{~؃éÎÁö½«rÏ=[xþ/<ÿÿ„žÿµN÷¸Y­wë§»èú¿½Áþ5ud×]ۑᅢ·ízÒCUœjÁhré!o}‡Îƒò]ƒ95fºù'­¯"Œ*Ï©_¯Ïtéw&ÜÍÞh)ö´–è,ú¢šÌ¸73Zß7J¥O U.B·ªÏ]qaƒ9ÌndX6‹_‡“AéÊáÝË[0sF§ÃÂ.€eêqsÔÑ„Rƒ0n¦¦ùÊê-ÝQ.®èüÝN‹wj}ZÞ1œZ•´>“ùÿ7…µG—ÿõÉö.ÎÿÛ»Û»0ûolÁü¿ùtgs1ÿ?ÆõæIå»ð¦ÔŽèø`ÒufY•*W§•“Ç•—Sª³ÑŽe}%"ºÞÒ‘T}c{rÅçd1ï{x³ÁGÃY@a,&Þ¸ø½þÀ/" `âïhëß®Q–jmôT qó« çù!©»úç¾íߦsõ´ÈS>¼¥í ¾R-2áWµ@÷ám0ôyr°Á: Žq÷~˜¢‚Á9%Û”¹2ÉiŸîãÈý®ÍÊÖWPLD¢ä×EPµÝ”†Î5¨wÐßýÒ•Ý£@ b»eèØïØÄ/iGX PmŽKÇÅ{Þ8 À«uü‹8U¾¢¿\WÚÃÀãwCl˜*Î1yøWì,¤Càz89ª2šcCE(Ù sz‰í¦þ¡;7žÿNèt™¯)Ðø+‚†òÀ˜,ŒCÛ‡b}ç|zY"ŠÃ†ñ;/7ÊÙ`ÜØ<…eµtxs‹ó4"ëåòº7b2™$ù#ÀÄ=üR¾ÊDˆMBt‚Ì•`÷6!Й¸TV% ‚d‚ T1ðŽhéòë1Ô$"ÂâÂ[–ßt!ñÙ’ð¦\J#L"âýoÄm™,bb…uŸ] 1/Eˆ±¬zÖ:>ª=?{iUNºÕÓÓP%Í’‘·‘-—¬"­DBG³ì±~e³JDºÍ.vQôÏŒ:,:¾™ÁÎÙH¸/Û=îן·*­z Q¡È‘5<´-kd»Ý“ M4ËøqZyYk-ë¤ýºú¢~L®{ë×½]û&(÷ƒ|²ÉûÇ¿¥×â7|Ó·þà’Þÿøî  _ã&½Ç˜èÀ·œ ´·7_ –QpÝëÂb«L“ !z§­&r‰3N<0ª‰!L)™âz8ct²U9àå•*âÊK ÏG³Ñ/¨Ïoé᪶#¹&ò8Àh"ƒ%ÆƱæ;—SиŒ;YñÜS3°jßwZ•îQ½ÝÁC²pÛ¬úªÒþ³V­rtR+Sû™²¡ÝáCÿ—/¸$©7£í­ðÁuøÚ.ü Ü ŸÞØ“¨ßå‚ìÿ"GƵEéfànohÕŽk•v­D6{(8ãÐÂ%°yQÇØ7ïhA:¹ü ‘ušGM®Q„zÆRƒß“m$º@ô¤¼E³– Õvó¬U…7ðû÷O…߂¾ †’·I½†ÿxm²z£Ý©—G}¯Šm?ಠó~dõèhÏP—âÐ{â-½ÃF>V6¨ÏŽëÕZ£M?%A¼ªµ£³¾´¬*¼lÈá²wô‚;liçäXB”T§šî¶ÏžÕ[ø­)Ë¿»äÔ‚ ä@().õ!á ô¶m´h Ì´[o¼h¢ú‘©K÷ÂcOö6ö¶A¾ù"nhãë9ã wr Fu…ÙIëïÇ=ß¹ ¢÷ìK租ʬí­&¼º†‘YÏöÞæÖÞ&_ h^nc˜Ž7·¸]‹¤& Ûä6Jý‚9š¾4nt\ò8\ÞwWútIôVf.BteVAË Fµ0u1€øWjý;ÄE9S6X‰co‘ßQ¨–ÛÌŽÎa\9¯ð0˜¶Öä5_:äç̘[“ÝzS6÷ñèïÍwiöɘàÈD»;{Œ0n–Û”P4NÖ±]µAs<¸Ò‰ç %rNÙVùŒ×‹Hă¶æ`4rúx»Mxn¤Ûb» ¦Òò.Q/7—Êì!/hÏxÃ[H†›º®ƒGt@ïAªçrjÓ¾!ò\íÃ¥±UO ÏŽ/(ÉoÓv¹~a,"„£+ÙxŸ7v.ÑHšÐ>c@·Ñ©ú¤s2I8\À}ž¦L‰R¡·ç³¹g©º¬÷д­º@×Öik…vä]ã´¸Dõf½€IÖV)Ú.Üæ‰!ü ­…ÐálHZžÌ¦%Ú\³š C LMÞ³¿ÙäÕìfV#Úš³"l¾¼AXÏÁÖƒfÐñ‘°‚Èš!MÕÚòu—fRüˆ&)¯cP‹¯Àäéžµk†&Ë(ÿ êʸîSvT2òF³{Ö8ª½¨7jGÙÈK®Wšº g0\I6Ò“úÉ)ÌÝžt4aI^šÀ:F³ø¢%h"9YäÓB2^²*ý>+½áa¾€HIv•cƒš9Ýô‚—kR{°Ânír˜ˆ;õ*4Î0i9¿“‹IM©FzÛø&°Ê¯¬tÄQ>?«Õ/»ÜþHßðÝi¬kH¥Y%÷1p©…H쉄Öq’^!ãP¼XÙ3”Mâ–]ùŠxb –tËLÎ/të" MA2{µör3 ëvåä$*l<¡8ÀKUŽŽ¨]æêX_+rÈD9‘ßÒ„ó\§­õ\äa¹\Ô!` qô)ƒ6±ŠÐé“ ‹\4Êò¹è”À)´ªÏéôrJŽ`Ù–?5´Ýmí%­äb#’”·-‹¢7–è4f‡r,q‹¨_‚âc˜| }¿g}qˆ› ð ­9XöëWöQ8Þ•Ç–ÀÔ/ù1,/‡–< eÅ(I£<‚v®L¾ÜâP£w8À³È"04¨i§ƒê#¡ÞÇýS€ o\’±ÒEdpy!÷yü*eŒ³¯7NͤGÀp¶’›çÝ‘úÑ÷\Dz€A[¸(Ewcïâb * N—Ù·lù[öl¦þöÙ ¼„‚WÞfå«ÉhhYø÷‹vWd•[Þ&h3Ú¢Êàõ¸‘XT-–©$BA÷.<ïàgbâò!ûƒá}Éa+ÁúÛò¥ü´¼¼¾~¹ò3µëÛÁJqÀ1oÂ2`([€—Éw€Rʬ&ú ÷Æ}ÜoÝØ~ ¿76·ðuqþû kX;ÊÁLyÓ‰G¦$Çny“ŸŸixºx¨"³ÁÄ?žNQ™ù 6ÿñJªöwž,µ-€^ §ˆpª»½²%÷÷t‚p»KÉÝšÃR~Ë|êRphÇØpLC.´í×AiÞhƒ n Ò®|ê‘\×=îÞ´†7ªè¸Ùøi¥ðò"·%‡­õÃ6ˆ={üÖÓÇÇŽŒ$È#ëq¯‹é ÁcÑ7õΫæY‡U?°7•V«Òèü°&÷ýHeOxÛ&¢·†ö;rû £U󺢾Rä\VkáÆGÄ}ÃF¿¨wx‡åE³Å*Pþ´Ò‚¥ñÙq¥ÅNÏZ§Ív wˆžUè-Ý ^ŸV:¯`ú=ä*ùвGÝî è^ºÓ. ÎûN”aò[Á)÷»Úqíuí- a’O²= È ÀëDªˆ+‹t_5ÛH‘‰?Í*!öUŠ+è÷­}¬žµ„™–‚+pâ4qå5[k!íºÈt0ZŒ xUf¡ß'¸M(ãó•>°«ÑþYdûûêiµ(ì±,ä{|ã ÏŽiŸdOƸ\ŠÍ-ñšEÀQhrŒ–é÷‡Á-Ÿ}½µ¯ãpÞƒ\n úœÀîñ_W6EwÂ{:F5î¾ài*«X ‘¼sœ1÷ áy—ÏøÝ%Þ€•»aâwqýð´Rý–g‡î‘E·ÌL8~DiœVF¿ãGƒ:ÜÃ'Õ#œ` þþŸö+9ë|SþkGøÐm×`6­tš­â޳^ß›sÝàJžˆ"±ò,›z°Pd`3ëÂy X‡â>ÀI@â„Zì„|…D-^7 ÓSü&L˜®z+²v4š­t­æEtÏ:mÕÌg˜©¢ÌY#Z*òË™¯h÷ ‹ƒkè \Ò‹C‹¶ÿ´×ø|w³rUû¾Vû¾ÓÝ,Z‡3lºÖYíËð|@ÝM–vNs8ãx&†j‹EOegÆÄPl³èÌaÆùG¬øË<9L=¨ˆazÂfPÌk—¥XS1NË–r;PÞ¨';jçSî Ø=Úp,vhtŠÇîh§ÛwÆA |´³n¿ïâ m—Bwã¡ãhw áÞ¿§Øˆ°4é“>>nn¦Á÷„ûÁ,0÷Ý ¨0¦x&6Äôl(XA¹8²'i`âà?Ç¿Md¤ð´Â“`ziû)…åqCjáÿçÆ'Oyß+Ù£ÒÏ€3@zð¼fŸ2œÌÄBúo8˜d€€^‚)9•¿ý¶³Q8ïÚOy2dW‰J¾˜ìK«UzÙîñyK-ÛÕÀH0E:Ék¼¨¿D…tT;­nkTëx(Au„C±ÈƒªÍ““fƒðɺµ–BG§+z–§|²¼V)758¹]åÈÔ•žL£J\•þUvïJF—/½ËÐ# y5ízfIñÒ½³+´„ó¯ýªv|\ŒÊ»f âÔlú˾VÔlƒî6eÐJ\‚Á¬"ý»/*Çm®kå(Ïê– üM‘ŽÆÂ§·ñâ_È3"e3ldÖåqžú]»ÿ ÷îÅ›åÄ}wII‰\Þ¬”á¸qnbÁä¶ï8´|C!‹÷B!]‡«¥?þËODÅëü¡­×¨€ë+]ª–[ó|ê¹P›Ñc}Ÿÿÿ–W›$TÚZ#û=”ÙÙ —®w4 l’ ´ÌÅŠõ*ÿô¿}»úÇOëoáÏ×x¤C-âúoÌWx3žÖ|!GöÉÚ[¬‰qFÇ,Â-ðaoHqv̨—ÚÍû„Ejfì/­°uV^}»¾þe€?à¿uXt­½-àÛâúÿ]ÿ –9ko7×V2P?o¾+²•çµ—õ¬^éèãÇ¥òXZbÔ»åå-|§=,Áÿ`-ïÉó+e«µ>-†{ ¿3ZŸCñ­5 å>“ÅñN½Q/ÑòA Štáý{”/`ÁVx'±Âϟ؇ê½K$#W–—¿lìgÿ¬¿u×HÖ+™€TÝÔ•m'Rº¸õ+†Ãïáz±ômN „Ü3ùã _²R?ã¬Ú~ûÏ&^úòå¾âaâ¢Ä °fB²‚¶òð,÷bIœól©¸dl_‰©¤_Ô«¢2²ˆÚÒø ^¡Êa(ÕÚÜ!TËÃ%ó-€ó×0_toØh)Ó©£¸d™nò »Î›N6ðšû‰bïü§7 Hk@%«‡Ù"»¦®£rH'kq(\€‹X©0xá©‹SBÄ?O#ŒŸ´â¶Û÷½A?±lÏv{NjIÊŸTL¤CI+§…›Â#–'ÖqÑOe¥ŽœÁ4‚É@|wÜë´ÒðñŸßâuÜ™@Y  üŒ~µit ˆ¤'GޤrÂÁU$¢®J,=z÷ëÔñS;°7qº &àz7¶ï¦—ë’¤’f^“þä½Ïåbl³\€A¨œÈ/Wÿ:ØäýdØÐžà.Q2ë}ý®Óʦ÷6¿¥™V.pÜdå†KM-:ñûÓqZa:_É(Œ‡)ƒ5¢7Mré›TÃ/8Izá|0qESôטL¢‹ÿ'^Ò€àßa5-x3pûÞ ôŠç#¡Æ„²Å'}âi>ÿW­Ú 7ÓÔÜSŒ¼Ø2'¬H¹„OEtÐ}݆†æ5Ô›M:†"ü/k GÚÑ9Ò6æH;mŽ´ùy>R°Þ¨Ÿ‘4X}gŒ‡é;›@œïÞž;]ÌjúŽ6nù²ü€ÉŸ$®ÎAåu\Ÿââx=>¹œ’A“ £ÃY`b<ÎÓ†f¨Rœð-þ!›š¨Ï1©0`4•€!¦ž2aÒ)IÔUq¸Y[§ÃEôý‡\Â͈\àrs"°Ü©È+v.rê«Ù<hß# ØÉ«oŠÌ/¶0ò”À“\púöIîs"öVr‚j-s•ÈÍI} &'RŸV Rµ|=î_$ÃèØ›(—Bx.®}0ë1C™•'AøŽ; Ù.:zË£wоd\ž‘>;=ªtjÜ-/ž+¿÷×û£Ñ,Šë9š;OAç P1'Ù³õ¾s½îN‡C¶õìkýn‹%óI2ù=ãâ:Ýpo´š/^`*¼¾k© u*‚™¥|·ÍWE+ ³ìÀ¦ -wà EwÂ=¼å×Î5‘5Ÿ¿ ï}à(ÜȸÜñK‘OÄuõÔåøàùr!6ŠŠ±¥ò3buÞO|;Ž›ô}Òèä¥bð{!±EÖÁk>Uú‡& Y&.ôÊKöˆ~Ò_% AÞOéÖ!Fá®?/‹Ç01Ïí9kê*"‚C¼‰ˆ©§Y‹2Ïï;>`€ÎU×›¬ê·… ϯÓÁÅ-¿—Ƀ:»ö›t™r=×'·Üi郸Š4À¸Ü?./o óÒæ¾µ)¡¸å€_‹Ò­i€•pH§¦ùÛ`ÁyO]ÄõuódÈB :‹¤;2Ø8^µ”Q»Ø¹Ó³1»Þp,_–×8Sñ޹·Å£áÒåÓsxy]4‹›j º¶ý†ÇEÞ]ÐMЋ ‡¢}ÉP‹ë|Í<~‹½Kô×'žF… ™mÀQ™ã!˜hÐÁÏXÙ â-§Ðd膥ååÁ’¸%'tŽ?Â0 ƒ}uÓLxÙq"ÌÎ/þlÕ:<²‡ƒêÙªŠ§jW›§hXòAfEüj“y±Io{|)·äH0ÆÈ}xå"‘e¸ÊFíM›Gy”†+êŽärŠqò¤³îôœÉ-l9%Wl8AY†_t)ؽä8t]ly(Q÷/–ºæ¨}³ýãk-©§(Ö"¿/T,-ä}T 7Òu¨@(iŒd¦}7®Ð¢S‚_2/Ðbìý++Q¨>ºØáeaVÚÚØ±zW`¼²é77ÂaeE9Ð _9ÿÂD%?“_^0tœ1{’«¼ëHh÷PF©ac´Ûb­“³þZ2‚"†~sàËÆÁÏ㛾¸øÐ@óqðkÿ}[ 'Ñ·Åõ²ô Á@–8Á¬¯®é1R},¯®+,1çÓ‰\_•þ¨àæ ¥QÞ1æ~‡›KÚçt*eú¬yã./«ÆÈka§“—%~Áü’Ke³×“À*FüÛ2H؈“€M\úyß2+9û³‹ &…m0îñ*F˜dlÍäDR3·¨²Í±Æ&47¡” ³š¹ ðs=%Rûj ’¬Y×H“ !xø %a–\èT†—6a|`PÙ6¾Îª´ª¯ÀÜjz¥ &Vùò7ëåê§ÝZã59ÊœcøV*šfdH]þ6“ SÆ;™Tä,§=Ò5e¡`.X‰&z>WfäD¥p³RÝøïÛòúx¦—÷Åõ?ÐùÒÕSºÆ{ühäóÃÈ¿¼¼b)‹8/½âþ ®‘ÅO\ˆ;è þ …¹Z[×ZÏ›mŒ˜@ŸãïšÅrmúÕ†_g&^× gñ›¿U7AÃ'þo£Ë÷<âXoôâÍw‡V<"K‰Èß¶ê¯q)u\®Aêo²J_ªøë¨vzÒ<ªñâápv˜F§_‡)Ĥ]T%“>B¹„h‚T$á}ºÖ¨ZáUãCñS½“7³õçðkxû0ò*„Qw±Í7Dž“p­cÑâcj1má/ÕùJ>AœšÏÿÅßñŸôN¾àO²—ÅO|wÚä/N›ðÔèrxø÷ßSP8;!V0†hËP§]&áõ¡uR©7ˆôŸ¿«‰X߇ò7¾mÔ_ÔpJô/àûw ¦äès(~Z b\ãÕŽêþ„¿- ¥_‰ŸôNÈÿodmM^ ý³»£ÞìîZÂŒÇw*€øÑ}~†rÖlu´¯áËŽ2 k ø~Å.çªÐ|BÀ|E!^…0g­cý;<†ßÄúCÿ.^!Œ©€ƒèo­V¥qÔ<¡ü¬=Ò7¡àø¯C«Íun5¬ Ä_ÈBäVD¯ð<£ÈÓ3þ8´4j•öy |ÔðƒþÌ¿ò¤ü¦"ÁoÝ¿M~×ß…P&Žð @ôº½I—Oòò·|Ë'Pù[½åz]=È÷šþ4^ˆ(J"Ô,~ ù70pú£ïMäwí‡ùuŠÁäÅWz8;b¾| ?ÅN‘ö–­ó+8Àò@ Z˜2¿ª·üQ~ë§áxï=­€§ ¯·ïùáþ,¾JZTO…¡@ÅOþÎ÷¼‰ö^<Â7Oö(ÿo®ò ý:´pYÜå¦&š„<ÜDf‚ TÓÃ'ñE4\þo½Ø“a£µÇCŠb)ˆ?-#´Éaø„_È æ¯éç¡„¿–OçYó_ô& vr>Á¼ .«Tâ=Þ‡6¾É‡ßEÇü¼Á(§Ý1½â?-oØ7e¼8ÄxœâÿoTçÈ~IRÂ!’¾@‰@" §?uõ–h‡Vƒ@޾¥¨1ß„ÒRkð0Ôÿâ'¼» p¯JBª§CKÄÆQò¥?ZJci¢}§A ü¦ž3uœ®ßò¤ƒKË»7>+¡P$PâÕs—@„/).RÎ-RÎ-RÎ-RÎ=^Ê9M%QÜ¢ù“ÎE1|‘™w.>¡¯óbÇÞȇ!“r¿Í*Ë¢š:;\J¸?}¸Ø ••ü-Ê3 »Hú¶Húö§Iú–ó-)åÛ}3¾-¾-¾-¾-¾ý9¾éùÞXV¾7ÓÂÙŒX<[Ú}\¬³xïÔhÂ=|Î\RŸS3rÝ)§™‰}·xÏ´^‘Õ«ªeRJ¸Ø#‡ÉøµÃÞ_h_Âû…æ{y‘Ðx+o /ÅÕ@|¾¤;}‘WâöžQX¿¦—ôA\ƒ3>áÅ;µqÅ®û’„D\š3ñ˜×ãz‰Ÿâ¤êÞ¢èf›ñ’n¤™Õ—Õ `~+Í„–÷ÏÌNÐ/]_Ä4‡¼lf@š·Ê’>…×Çz±êšXBAý>X¼¤º÷•P2«\x‘+᛺°ÿ^Ì2¾É X&⦕ñ2ärøN\žŠ¾tûÑWá…¨^ä=Þ|Šó;NQP~™Éx+o-/åõ$㥸‡¤ª’7ŽÔ ónQÏx‹—ˆ q]Н¢©ö’”ÇKù£ …W(‘Wny#µùÒlAÒ`|5ÛãAôíõn‡1B¯â#Ô„CÎ|©äëÊ”/Úx1_Š„ƒirs• 71`.!WIÂp• WQaP/Pµ`ÿEjà[Iò=vÑó$FÓã‰b;M_m'MI/•ÞÒQaó·¿H›T¶Ó'•í褲ŸTHì¶Sçší´¹f;"–]rS÷ƒÔ4†Ì†™³Ñvúl”þ‰\²£HÕdµ4YmÇÇŽùøkNÛ±©mû‹è+½×âCŠ|×x&·í´¨4JZÑ=üæ˜ßåì¹>ómgÎ|Ûé3ßvöÌ·>ómgÍ|Û3ßvÆÌ·1óm'ÌqÛñ9ÎìÌÖ!É)f¿íøì}5éòhÛ}P:ÛÉŸãôO»ñO‰CKûÐí×FƒƒÌaûš\ž¬lPmÃá¹Í‡MâwÛ[ƒL ÝÇ1ùšd¶Mƒí$#`;IïoÃ-·À"ªOÜÓ´sä›ÔÏüuºŠŽÃé‚IVÔQ|¦®Ž`CmÃ*ì(.CgGQiZ;ZNWÜß„E›ê;í£Öö,‡PZ<0RäÑ÷¡.Oü­£Ø—Á$ñeZ7GµzÊg o¶j'˜LåÁ"õ{”hSÅG Å”|âw¥ç¿*]žø5Ôæ‰ŸC…žüYéôÄÏ¡Z~š=ÊŒdê=‚I(øXTññ—º’!ÒÕ|ÆÇݤiƒ1ªíÓ‹&Õdo _’ÖOB“ªøSÑ…º? DhÿhURÿGY!§€è{eýSÎ`y.™Æý‹´i€>ŧä×JŒL„8 ðÉs@™9˜¨pˆ¢ '€"Cÿ'}Ó«HVÿ韄D™ä™Ê?å[Øæ,ÕPš?N)þÈëPï'} µû0˜Ä˜khýH¨Ö7I6”~JICé§—Jß„:?‚ÛTùf‘˜ÆOú¬~ÒG¥ï“>†ê>ék¨í¿*eŸô5Ôõ‘¯BÕGxÈCÑG¿qE{ëöcaêy“SͧÛMø–2ä¢:>µ`â€LÖð“©à¤ê÷4d¡zOÂ&Ô{´±R½GÞKíy-•;¼¶¬våäô¸9!{³v†õýI‰ÊÜÕ“¨®fíxé[V–LÖ®Ü-@`¯}<©½r˜:ÊÀÃ8µ‹ÈoZVBèÛ&É+ºA§H<öþƒü°“;ÒI/31E4u"!±'ZÇ…¹eÉ+A¼XÙ³Â]¨-ÐÈì«m]R]m¿ÓØü³,#ä‹t¶)£G‡ÑÁEõBq@„®=¢Ô9‚Ü&_Éoi‡S–¢FZÎG…AÎC\È8F}J'-TG äDV;™f`ì©ês*¹œ£“JƒßL£@,áKÃPã[b¸Åº%.€a –Á3‘ßùA™}Ë–¿eÏ–­öÙ‹õï©py›qÓ$v/+ ×<´ˆê¤ÍøB–U–È÷´Ÿª|Æüeüÿù/Œ4“=*0¸‚«=¥ ¬/÷¬Ä° {âÞüWkuñæ÷(Kͳ–š!1ÇTJA0žÇéŸâÎú"ÏJb¡Œç ‘}ÞQöå/Äj¼Ì¼‚I{!*¸(ÜË1v–ð+§ûó_D÷Ì.‡¥¾€”«zCC¢%¯þ"Lvû…¼6ý…Nœî¿˜Z‘d!§T§1Rœ*ÌÆaÉ{©A5ÌÑe$Ÿƒ®}òϰV °D;Uøæ²‰+ä{„da ¥b]èJÌKFÖUvß„0ÑŇÅËÉç9Ý2Ç^³gY™¼ßKM^(s$ÒmÞ³¶™'&…~TgÖ… Ä{žÏåEè¿h&Þ´w…Ñ-}ÞS]±•Ý[óvŖꊭXWA‚æè‰­»õ„œâØ¥«¾¿g}QâØM«@rÌ(R 9·îeSÏÒBÍÝ ì4N7O¿)³oBe<ªhbNPµZ„„ZÂ^Ó¦P)R%ØãaªÞJÉá/T™e´0æŸB*„FñE?Ï‘¡r%XWÈ–—××W~ÎOŸ%¯?–€ÇÚ„½¤{_.Ì”æEƒQpƒƒar@h,•PmÝ‚ŸI­¥™N ö…ÉGeàšyaÑ;["ƒ&·dT0%ÓžÑR1R™%¢‰—áì‚aÉ/ËÑœ‹%7\‘UhpÉIe§nîGð›ÑTÍ0©)aSåRe¡/j éyø,Pd’3H ¹B|°¬0ÔeDìtSÙíï+e©Òŧ•Á¶xÿžR ê?©#Ö——/î×ÑZ–RjYRâ/`ŒÝ¥pLÄx»Nc‰Ú £Opl{½ CÑpVùnÅ‚DÆ2!Ãþ(ÿ±Ï‚?dFÛ?è þ]<Ú ¤í±?V žÍ™þï@Ml¸KMø;~ý z$á%H¬¶tß‹8ØÊdA‘×fpô.B„=æ‘‹Oçzã;è}ï׆—HòÑÁ“¡ Y®XŠê== °†%1µXØ””ÏÊꈧŽ´ÐHCVœEmªèÍÐsqïÉèÊzÉh¢-ôø§loŒd™Œ«˜VaŒL#ƒøž ʬ—‹%™Ò(Mø’jàŽÑªRQÓk’«ÇÔ#CKoUËÅ¥Yƒ pû7‚+'@:·Êèz´Y¹4PöÃÝ ¥4²ýwŽŸZŒ4@»"•KècWd$$ú•i9ž>öÝ1ñTS³’Ý!FÆ«†ÿc÷IBÖ­ZËGî•™¿£ÒHî°Ç¨ÒÈ>öjùË¡:-Ú#ÔæP{ŒÊ"YØ¡J™Çí1ª 3Á=Bm‘\rWc˜îêù죦HF¼ÇªòQÙfå{œÊ̼~Yç#Ž‹HnÁÇ©Qf'|„ÚdºÂG¨*š!ñ1ª”9¡.-Kã#Ôæy|„Ê´L‘P[,×äãÕid«|´jõ|—Vi$cæãÕ|‚J?MS¼ŸW«ž9ôÑj5r>F­ZöÒǨ.Ìúµ=æDæ`}”ÊÜÇZûšy`§B‘Iöq*S¹h§:•ÍöªÓòá>BmZFÝG¨-ÌÉûq+Ó²ú~ÜŠby£:‘YøãVÍM<³6á„'#ÉY²ï¹k‚rúX.á8÷óüŠõ§£Ñí ºO—&܉ç@H|C~cP—ĺǒk±¬r¯ìíYD%†P€jU„UÇ{Ex{zQäBB‡2yt.ÊCf|ýÇ~ðÇÛ²‡çç+?ï¿MÃ-²&Y餃(K'Gðß)ü÷‚‘Û2ÖXîŒ=VêñD¼è/þõשŒÂáÓ©ïÙ‹ j-ÛÌcƬ,»Â¼ó_œú®È(z®Ç8ºç•êwíãJûÕaüœKŠ]”XdŒÁ‘¯˜€;›^úìzðñ°¨37äïëó_>JoŸÿòúûg(%ä Ô·+?/à®ÀL’ˆáGþÙã_åMD 0|X ¸u‚?±è ÖµÀ¬sBˆäH}³ÄdþÌí)þf2ƒ(å…g”ï¾-þÍÌ{Ÿ†¸›ª0– %q6LIÍ}JrŽ*~–~¨+‰}±BŸd „~Ë+?Ïßoö¤¨ œ¹Ú2×Ñó^JÓåXœÍÆ¿ÌXýËœO!×V¶÷A¨ÈŒÀ¢Ÿ­3y“[‰éŲTX}´£>Èìæü½•[yEÛ0‡Ë=W¤ÉéjËdÝBi}b¥õ‘$ÙÊò\ ••ëø³UU:_r+ª°P–š2PG»Vã}fÇæí£Ü ʤ=·³Û=”“ÑÔtÕ¤³k¡˜>±bzpÙµÒ}C…¤‚¬¶ê(äIne$‹d©" m´3Ï3»2_ÏäVB:Í9Ý_ï¡€´&¦«ŸE åó‰•ÏJ«•ê㬴ŽJâð¹*#yuŽ,‘¡r4¤‘>TüÎêÂ|’Wßèôæs¿»¶Ñš—ªlBæ,tͧÕ5&¦VÚõ¥gd^˜ÏUÍ(~äÕ2¢@†’ QF:Oò:«ïrõG^ £ÑšëÆËÝõKØ´Tõ¢Ø²Ð.ŸV»<Œ|ZÉ7‹”bá¹¥>Wµ"x‘W©x†J‘è"ÆyœÕ]9z!¯2Q4æ¸\vwE"›”ªF+JäÓ*‘ûJ¤•z[0Ô 2Ýg«DGrëQ"K•„H£}'ùÙ}¹:%·NÑèÍw‘ôš%l^ºrQÌYè—O¬_JL­Ì‹ÂJÙ).?W…cr&¯ÒÑKe(žòH¯üÏêÙü•W EéÏÇüîÊ(ÒÜT…d2m¡”>­Rú("l͈+UQ2Oîg®¤wæTS¢ÜlEVÜϲrôt®.›S]ií˜'DŽUVØìYJK1p¡¶þjëc´• D©,Jþ¹**Ή¼ê ¡3”’@é9âoVÍjGÒ7;6ÍÝUŒhNªbáLX¨“O«Nî%ŠVvœ¡Psèo?_bò&·.Ñ‹e)•úh—}Ù·ù{+·¾‰¶aŽPU÷Ð@‘&§«"“u ô‰uÒG’d+3F™©­>÷…™É™¹tÕìEYyRÿæ±_ówÔ\z*ßb,ÞîžZ*ÇBÌdÚBGý tÔC‹°•ÒPé&ñüÙª%żIÈPF!ÊH'J^gõ_®þÈ«}4ZsE¹¼»Î ›–ªn[šæÓjš‡‘OkFS]Ãh¯?gEcpg}£•ËV;fñÞÕûaF'çî²9tQ¤óĽ—f2›¥  .ôÔ'×SK ­‘ãÊëó>úrgnå5ëø?VAZ_Ï>?§ËæV^yÜbAµ@yÍtˆ2p¡¼þ$ÊëáÚÊ ©®«.õòsV\gæP[ªT¶ÒÒ‘Ç{8äÿŒþÍÙQs¨+ƒþüÑøï¥ªôæf)*i 5õÉÕÔ˰•šAWNôâsVL‚#s(%*‘­$ÒxOr~ÏèÅ2‡RôæKÎq/å#›—¥xsJç“+‡S+9ùŠÒ2ôôÙªÁ‹¼ú…À3”‹Dé2Îã¬þÊÑ yuŠ¢1Gþ»kÙ¤TU"X±Ð#ŸVÜW"­ì„JJo?[uáM^µbËP/Qô‘N5û «sçè­¼j'Ö†9rrÝ] E›œªŽ"¬[¨¥O«–>–$[)ÉØB=EŸ¯‚ÜÈ­™>K%I„Ñä|Îìº]‘[û(:óä廇¾‘ÍJW4‚! ó‰5ÌýÓJͶ¨Ô‰|ñÙ*”#yUŠ,‘¡T4¤‘ÞSüÎê¿|’WµèôæKÄywõ¢5/UÁ„ÌY¨˜O«bLL­ì´æa¨1ýíçpÌäMî°cz±¬àcôÑOFdzÊß[¹Ã‘EÛö~¡É"MNPf²n¡Ÿ>q˜²$ÉVZ^h¥¨Äóg«¢?ò*'Q C-…(#Ý(yÕ¹ú#¯ÒhÍ•*üîŠ'lZªÊQlY(›O«lF>­Ô,ðJ·ÈŸ­r 9’W»ÈêECé?Åï¬Ì×)y5ŒNo°{é­y©J&dÎBË|Z-ó`bj¥d”·E>y¥nÌן­Ò‰r'¯ê1Ëe( X‘þôCV/ÏÓeyUR¼¹ï¥žbÍNURQ.TÕ§UUQ S•üIÑ_á—Ï]…é<šS‹…Eg+2£šä®×ú$GïçíÁ95šÙ¦yàB¯,˜¥Út–.´ÛŸB»}T)OSs£÷ÉJN½ÿÌUœÆŸùœ*8S½éU$v{س;=g¿Í§ØŒ¶ä‡~¥¦7}†JÓØ¸Ph…ö±ä:M•¹öxâ'k3ýÓg®ÐL.ͧÓô²3ÕZ¤¢D 0úe¶äïÆùô[´]sx-aà Eg2v¡ëþ ºî£ {ªÒ R4^°PwþÌ©ë‚ÜŠ.˜ÕñÁ½| ý̥܂ÔlA~µ,tÚŸK§}$¹NSe©ÖÛÂvKàÐ|Úl»möD6×4öq,¶9íµµÖæ±Õ–ÚŸM«}DñNSl—r’~øÌ›Î¡ù[Xr¦b3*Iìy­?f÷|ÞΛO±™í™ü›ÑüŠMgæB±ýÛGïTÅæ_§(6õásWl‡æTlªälŦW’Üóaäèùœ7§b3Ú3øC(6½ù³›ÆÌ…bûS(¶'ÞiŠmò~’¬ØÂŸ¹bÓ94Ÿb KÎTlF%‰=¯õÇìžÏÛyó)6³=s€?€b3š?C±éÌ\(¶?ƒbûˆâ Ø†öäÂóGšF“o>_Uò$·“E²”—†6Ú­Šç™ý™¯grë)æ&~ÏœÞh¬)‘ðÝç«Jt¾äV(a¡,µb Žv¥ÆûÌÍÛG¹I{>Èû)£©éªGg×B}bôಛ¨’úSSáó笊8?æPCX [ ”ñ.$^Ïè¾Ùý1‡Ú‘´Î†º¯ºMËR5œ- 5óÉÕÌÈg¢jq|ßó åÂß|ÎêEòdËd«…6Þ‰‚ç3º1OÏÌ¡hBšóÀÝWÙ¨&f©É¢…Âùä çÁ¤5Qí㡞’I½ùœÕŽäÉj‡ÉV; m¼#Ïgtdžž™Cí„4绯ÚQMÌR;’E µóÉÕ΃Ik\íL#Ç›jZG¾øl•NÈ‘¼:G–ÈP9ÒH*~gua¾NÉ«otzs€ÝKÛhÍKU6!sºæÓêšÓ¸¢¹vü`ài9ä‹ÏVфɫhd‰ E£!ô âwVæë”¼ŠF§7ؽÖ¼TE2g¡h>­¢y01+š0q®C=#ž?[5£ø‘WˈJ&Dé<É묾ËÕy5ŒFël¨{é—°i©êE±e¡]>­vyù4TËù`âÊpùûsT)!r¨ œ¬J4Ta7)Þ¦tQ>ÞçP:mÙwUZS’TFØü…ºødêâž2h¨ˆëLºøßx"Ö9æ›ÏQ]Dy’Ci˜E’UG mØyž§tá<=“C™ÄiÎwWÅkb’z‰²h¡d>™’ypiMP;o¬©|ú|Õ çEnUƒàYjF ‹vñ8³Ãf÷BnÕ"iœs?•"š”®N8+ªä«’{J¤¡>nnß» ºcÏç§@Æ‹ÏQ‰D8’C%’UIiØw&¿SºoŽNÉ¡Sbô滫f‰6/I¹D˜³Ð/ŸL¿<¬˜ZvÏ›ºÿ¶$”qWVþΡ\æãˆÄœÊŽ Q $›2úãá°O¢íC©Ö§mBåcOÊ0O&,ëûé7EµvÈ1Ðòp,»ÞŸx(?¢œ=°Œ$±ó_þb£ìü—‡g€ççÁKbä>›\9.’òÃËÓJçU÷M1òÝNä{ÈsòbðóÿÂØ<ÿe1:óŽÎG”,mDã¬|é€Õ>)ËãLñø'Õ:Ñ3‡µœ4² \‘Ãɉ¬Ãœ\Üš9\#DÎ9½Ç)cئø¸Õy±¸3îƒ NÊh¤)ö¯7sL´sŒÈ˜R4¸›¬# Ùª1|ïy÷Ï7sð\CùSH\D¸Þí»j>òñ/‰Î5úpÚèW¸"jUr"K­æâV®a¬9ä>Ã8lSò0–¼X âƒøA'e4ªùø¯5sÎÇ9Gd¢vTÜM׎Èlí¨?È|üçÈ‹ùx®¡ü)$.¢´Hw Nó)õ€N|.M>&ç' “It°Ó“ΣŀÏ1à\¨2F±šËÿšã8çœ>çHNÔ´çÓµml¶ÆxyþÏ­óþÜjàSK¤e÷—%ü‹&~ü÷áµ`Mç}LÖ!iiÊ@Ah£_+¥éXjYšbÝì´Ñiôþ®ãOЫ]تÿÍ1v¹gë²OÓåŸUúÓ'Ãlù)Δd"¿e« u×Ù쌗ÿÕYé!FÌG–1Âóö^£-Ï©k0:ò>éikqŸøp&ÖþÅÀKxxªÃ÷ñOTl|͘Ôrް¿ÊééŸl`.æÄ™CóÓœ’*2ë„ôÞãyÖ©h0i4²ÓÐ$â2>?ðáI¬ý‹A™2(èÔ3†ïãŸx>ØøÊ1_æa•ÓÍ?ÙÀ\Ì—3‡æ§9ÅTd<ö æ½ÇužSË$à¤Ñý§8­L#vÈG8 HäËb§ àp*™ˆûqN$t\æ˜sç™ÅÓÇ?ù ^Ì˹†õ§?e¼ò‚I‰þ¦é™~<üàG´é|ã_“‡¿N_Ú˜×`´¡n”ÔÔ'obšÒÌÁ€´!!#ùË] ¤Z ;½yÿ›cínBóoŽ šÿÔã"}6œ=2bHp(Yï¨ÙÚFÝuvûtCéuâz¨ÁôñåE޾Ç<œ¼ï8Ìs>ƒŒÈOzB™H^Ö÷> ‰³`1“âžSÆ~üƒÊ‡k³f¾¼£í¯rZù礋ù2Ï0ý4g–!uhùc{Ö¹e 2qd²“ËDò²¾?ðIœ‹š>@èü2Žðã`>äXË3æm•SÌ?ß ]Ì£y†é§9Ë éxìÃ̇ãyÎ3¡GúŸâD3•ÜY0áø#™5‹Áœ>˜?¹f2òÇ9Ø|è1šg.žg”þO7ÿü|1_çâŸüŒsd o{CÇvK¢Ëö¬/JþÉY-=ËJüè_°2¼ Xÿ¶¬þ ˜¤`/XÏs/—åáĸÁÄK#ÛÝÞšáßîI¥Ñ.Z_.ÍÖIåz¡Ý©ã»! ßæ\¼Ð?ìæ cSûŽÝgcÂH4i]^ *úBþúK¡Ð-¡Œíób’š>‚÷òq̹Gôý¿ˆ6‡­¸ûÁZyu}mm¼E¿ß–á!XûïÿÝþéÇÒ?ákÛkûïWdãÖÞ–uµýåÂÄ·Ý5*î¿4oݵòÚJXçJc¿Á_³µK|ÿ»”5h𯉠üu£ˆ¡ÇÙm¯Kì€x0²§—è>`"Z\Ä+‰¢ß=ªt*(v¼’,ë¼!†ˆ&Z~IT–,˜¢|(ŸËËÿ¨Dçq9DÙ0Å,YÊþ`|ÒB.t¬È™áa²Ž‹Óo’΀Hù}Slæ˜Lb†,7c>hÍÿ`YS×Ð[º®:kD´)«Dd*"æàç˜6HQ(’1ݧÝJëbGÖÀÿ >ô>ÞÀû™³và$wà¾"Åó.qª{á{£.B¨9düî’O,Ø¿8™¨¼Ç3¦¬;möšú¨ºN(„Dl¨ä³‡Y‰kÚ$§C›IÄ(E)G(ª°…½›ÊÕô¼|ž!œÆ˜£8…KRŸ!ñú 6gÆh¾‡ ˆ!žÔ?«Qªàÿ…øÇiãÄäRþÁ¢%|xU«ÕZí½HªñzÖ°I*b²DƒxðÑÁ=sü$Ñò×Aœç)c(=iÅóq+m$%HÕÌát_ú£*Ê·ÙãÊúŠu®ƒX{þíJÀ‚é¹|k!ã‹, –üå¡·Þ”õl—õú€dàN<ª³Ý>ó§0Gìw`òÝ &WÞtÂ.½{ ¾7½¼‚¡Î@zÊH„ÇzW¶{é vm§P³w!±\ÛþÀ>Ò÷ÈjEƒN0A¬Q°˜ ›E’wBÃK1¨,p&È屆nL¦ÁÊሾ,ø§âÜ»‚ aégON›ªŒA‹ÏQÚ/×ñí ôÑ Ž*äKÈ€â>Ò´Udöo³ÆÆv®¾£ûª½.½mîy£2s8pE¼#¡W¦~0¸vºÛ¿t&Aõ •V;.€¢ûÎqÆÄ÷¢±ÖhÀ}°BÅn€›O¡¯¸†1–U}oÒ Ç=p=¾f%2Ä¢ôPÈj°^R”®¯saÅ…;ŒŠÃ%ìª'\q¯B¹‘ 2ÿ9~I¼,29ÖŽêíN·}ö¤Ûê@ƒˆ~t»§t"è$ÅÈÕt)ŠÑò2o ä…¤æÑVGâ®Ê†Î‡IîÜ¢î/‡^ÏŠþÂåÿU²G·¾‚J^2×3 š¼—{ý¢¢7 `ú¨|WIð§ÜËYÖñÃÍŒ:×AUö« °ÏFï /êGÐü>u,€]‡’hu€2þÒ" «Ä×Ý£Úi­qTkTëb«,Nª÷ÔÉÎÁÏã›þÏ’UÐ!µŽÈŒåîÛNû<_;P½çÙ³õ¾s½îNAŸl=ûzSg£€îzã €DHA'·@ÎûƒrdÈÆŠ§ÔÇrlìð•XúhIeÑŒ=s+€¿ä›,xùƒ’ \ÈPÀu¸ÄwŒ&,/#“×ÂK)Ëú™‚[$Wƒ‹‰i¹¡ðñ^ëVZÐuËË«R~–’¥Ù{ [ýŠÉ•±¼ü+]ÒzY×J`ĵí ãÈ|¡‘òŽóMR’ Iî‰?‚YZ˜«Ç‡V/2¶¬*]ôžÍ9¼òô¢ÖqU½ãdHÅ&>å½ñæ‹jB㕱^R£ä€×”naâ»çÓÁ°fê^Ôj·6 )lkõýùÃJøüR#`‰Ký’Õ zÞØnÒ¿eâ€h=Œ©Àx¯7º]mž‚2.³Ò¯¢µô*l®þõˆägNØ6¤¨Ípƒ$ý¨Õ 8T VøsO{­ ö– M‚|Huû´¢Ûrš?¾}»þZÿÜã?‹,@ËY‡Õ, úŸHí×P’a1˜½ØDL±¢ ñDlôÊ…R£Ãhª={•Ãu£s´# ³ª IÃlI¢Ç^¶ø?íNào¦!×.½o|¡'ѳ‡(ø2Ž`gg‡•†÷]À6 =kãç(QÎù a•Th¹ ·¬ƒ+î‚4’(8ÎŽ»Ô¢o†™G,½üm0VM»•ܺW]®Öjð 1hGìåê§ Ëâú ºµÆk"âYX´ %Ê—¿I‹tŒ¾SQ³”qˆ¶æ¢â9Ô¹zåwúQ*ýã#$I$œÿ¶•ƒ†á¼ŒÀXqŒhžvˆŽhõÃ<xÿÛ\uÿ¬ÛÏ•JÎöþ·¤Ö¿ÏS=þG#à”å›J«Qo¼ÜcKí链ӴŠ@þà|Š{PÌö{W°< p+~ì;špxžÁU‘ÐKCçÒîݲ±ï]úöÏ8ð ;ôøÝÃÃò{öõV¼öú„Ÿ0ÐQRCe8ñ.?°JÜ¢N∄+—×áÿr¨k+GPE8úª¯jÕïºÕfãEýåY«Ö5M>B³aJ%¾Op@UÁ#ˆ%é¸yd²qI£>ÃÏøÞ¿Ì„!E3JЕ.Rå¨1»!Ðe šw…D$ó,\꘥TEÆðÊb}áw #®qy·Á—éÈÞ±§OñAî¼.‡òº¤¯3Ú&ZÌÂ&Çïˆ#Âà;b‰Ø4™}¡ Å¡´M¯ÜeX\L0Kî«Åè‡PÀ!sIMEtÍ…„Ž"„ Òe¡l"63­/ r]YoʆDo²Û˜m6¢àž±IZûéÉË˾a^Œì˜o^ÑßÁzyý`ý’~éï÷¤–——Ç+âÇû+ÞèŠ#ï+¼)q©(®hÎáüú[­Õj¶öÀ¶º%)¼‡–i©Æ?½×ü”‘€tì` Ë­Ëp ãƒvNŽ*ÿäõlì2P|Ûqâ±»AÓaByì*~¬‡8`Ù?üxþ+Ûí'긴Âø9Äй˜0ûbË…qo‰íëcÕðÙTns±Íu}?­Àe\À²€¯{´­1¾ÇlÖ“È­a°Û´Š1ÇÖ^8Ö@¶$ùá­¨ÜÙeq¿SÁ™È@Eg=ÏÞ’|¡  2äiÖWÌâ1yà/„úgÞª߬®Êì)–ÜlRއ¢óT‘Î˪]‡3ÙI tŠˆnžöÈlåïÃhþuO9÷Au§­æËVå„VYÇãúóV¥%œèÞêMîÊ]îŸ|³ý/…?á¿ J--_I'f%õí‰á“Žíp˜ëŽò•ÖåèÈ›išqBì‘Y'CÚݰäè¦ÃÓ=ÿ«:­úiq%Ëœôm’‡ÛÄòa‘ŠÊ ·Hó2ßc¥¥ :YijìOIìR¤v\r$¾8Ù¾d´ ”™~[”üv½=yAT=Ë=xîgt\«4øá< ¹á£½×=-RÐÒ§KeºIÈâß%‚2]ÄÓÜþ`iˆI™ÏD¯C™TÒR-¥¹‘o–ó× [Îwó–hGIz1ÐU`‚¾ã}²ÌÂâäH=…†*¼ï  LL´‡4²aær~„Á‚±ÓØC†×r©¼ïp%»ÄûRú"é.Fôõ‚A.Sw~5%ÏŒ‹Àò ]hÉ ‚]EKÎL,éÁ"H …#$'Ü8D;Hôâ±ê V^OÊ9,~àµøl@3dÜlØ0,ÎlXóz~"¼že2 ‘ ùG²árg†œÍÉA_R`¡€³)Ô&h^¤ÛzÓ ¼Þ;g”O‡yËõ]¬Ùq's”ÂX—.!ä/3Œps0 P¾7èç/ÆlÏ™£‚4cât:8`ò–BK`hP¥¾7zçýÞuí‘3w!47ÜËüÅ.úsˆÊ…ï8ó‹ •š—.Jǽž  ;¿µû}ÿÅæc6Ã÷›«Îüî`6à ßöoç-… ¦üà£ws©ñòÂs?ÿ9drlû õlÐGãáíÜÅàÏÝJŽÞß­œk'þ‹w+wç ïŽÌ ü뻜¼ŸÌ]phOðþ%|¯çsˆØœ"8¸K9¼;Ç §[s”éOçƒw|ßóç*Œ‡ó(´¼éÄ}©ünüÁÄÉ7…œ&n^Ž‚É3éâãINjx 0sAß Ü¾wbêù&wä.”¶¬ ×-öH[Pà.nWÅÖŸüz°|yÕ×6ÖԲƼK–ëÁé«&|Ä}(ëj2ò_8âfÈ…gn¼À³øn좄[9ñ[ÖL‹GBW³’"h‘@í!iãGÙÜ1ÈЖz! ¶0„¢ö&à×ùÀßH~„OIåâüáÚPÈ~÷/ÂOð„_øÆV&H,%Ôæh|1¿¿Ž;÷Úµ¤Î—´kë6:îìLœrφú+ÜÅ w±Â]¬p+ÜÅ w±Â]¬p+ÜÅ w±ÂýŒV¸±e®Ôôe/K;g4"ÿîçoÚÒÇ<–3Áäâ9áL£ …-K­ºpµe®²äê*ôKÀ cúcVô1¬ÞÖÉR¢þEbzêÕñeì÷XZô(ô‘`!¹Ìðe€Ò§¯š2ŠWyèú›þB|´Á•J}gÌqñÁwÀ‚ ®„‹­\€ò 3|„:g}àsÚXt ªŸÂqÈ %ÊKRÞÀ`á5.¦®•…wö˜ºaÅÔÝUï1q ŠÉ $LÝgeÝܱIߨ1wuŒBÉ;Q70áb)‹FÜÑAšï¡0Üê`b¿ƒö{˜ØÄжj’„—Q_}ÛFßéUé›5©n9DV6$-Üba‘ý>";óoKáÒ·e˜¹Ã‡¨±¯0c/Æo1WñÈ>î2ÆLG±˜–$–¢9u…—¨#Ê/¡˜5ä‚h=4Ž7ŠÂÂ]L§ÐçZWéšÑP~ ½“¦©{ŒÂ]Y>mÕªõæY;tô³,ë°Ú<ªu«Í×µVåe­Û:;®µUÐxT&rë•çècEcûÜ$¿ß1FÐñ…‡häÑOŽN* œ#W´ðìÆ&Yrƒîà¸]@ËŠQ’FyBbÀœ£d¬yÏ&¬„:êä(ƦaR” ξÞ84“ž0¨Fâ®H.ˆ[|#9ÊrôíœsÖ,n— Ž_îklá·"Ù‰EO^h% ½æ/†VÜ[¸È*³ykaEH$éJè‹“r½Ü)“Þu1Eå7p±°ÝGÅ?ð®Æ®žž½ÁäëGkSÜa2n{{Ù`µÔÿäÉ{1è­1Üã€þÆ ¯j É‚ Õ!Ì,èï‹w—eäí”7 ˜&öù`ˆ$yX–¸£*Žôf™±úûOõ×’M °¤$4/Ý”Æe£ñp€q l{š$uTùàÂí;¬Òªµ»ÝWÖW<Ž¥zvÉØºZb † W—r&`¼pÀ0¬Z´¤¸LB±~Â’â2 –pŽÄKúSœ0¢%é-s`¹6JµgÔoÄ›zc{‹·æõÈ8É{3páSå´®ØÀ œú~¡KåŠèE®^ñwÝn±È)_ÊÞ·8y^¯ð2—»¯‘d}å€)v¡1÷[˜ÿÖ1¨ ´ó¶‚½:-}/¦ÅÁÿXc›$ø›› “w±8C§7Á[;ð!ö0(7¬±‚+$—"OJx¶ÏŽîô½D[fM—¢£s"`æ…*ÄLL åîëÝ ^BLÒ}0ù’÷ÓEÈ¡Jýû˰49>î© Lˆ|s&ÏÛGâ5±Sû8ax) óÓüRotj/[õÎ ¸`YÐjÖ"%ÄÛ¦æØqÓ©úwãûF§IÝit›äþ3Ù­†05j70˜¢âaò&Šò<èït”«ßT:8”*UÊu&¸Å¹>p©”ö…H¤éè—IoÌ«êýÈýMµÆ+àê¿$7 `^÷~ð`óºXÇ¿ ~huŠÕ()ðšÎåbäð±õø”lÅÞ[À¯äXàädr¤cºs–Œj²ñ‹;ˆ`A–°n·7Nüωﲥêû]‚V\UŠ“CØCÔ~ìbêöhªÃxY°f zŒ6ºPXI•f„v§Ò©WAj5•ƿԾïÔZÄÞ3–¤[£ºRÃÀ‘c(Ö£zãe—o¶üP4º\'™Mâô\è‡|íAð²Ór•ƒéR•ã¢c4,…, sa€`ÓšÇÝWu„+¦p°<”qÈONu2³y÷š³vû¬Z­µÛúEÿ šRÚŽó£c%0Éú Ž®Ñ¤? o$,•¡s –L*ÁËQTøz=²”ög3ñ¢Ù:©µZÄV¢]k½~Q©‡Û±Z:/šg£b'Q?9ÕéxhÕ^œµk ¶K9Æ]2˜ÃL:sb ~^9ú÷Y­õCˆæi¢Q9©iý=ñ¢rR?‘ü#ÿêíÙ܈€T›†Ù¦Í(ë%µæYGÇå}óE$ÀÛŒ2}â" qîŸÔNL(ûñÒnë¬Ú©7d7Þh€1°<¥.ŠúzÌì!ºç©¡ù»]Sf£i4#½+ÁxM¯ÀòÐjÚâ£ìÌ%SÖ~s0 y„hÕ%ÕÖ©7êzå¸þÞ¡[›!Z@9p'¾×Ÿöh-Ã6ËOËÂØe1·“ì†7+GõÓWǧ¨û5Ò·fTeb©aà.4mš­ïN+t@X¶s|âý˜IcµÒ¨‚m¤ ×­¼ìx1´/eVš(bŒ. ™×U…¬°É¾ý–mO[õ“Šêp3 °þ²Ñ‰bÜJl4[µêY«]Ó·“a’ý¦€†Žq'c»†‘CtÀ'É€ [•v­­î&RÈ#¡8àÓ$ÀÚQC}ø÷"õA“܇ÅÔIéŠæi§§É]€M–ÜH§03ºGÍN p;ðìè´‹[Œ,«+¨êjà“@œïð,ÈÜM?Cí;×ÎÐÃcÙB"(,‘¤ 㾃žrlèy~z8xdžËL†!§ ä¥‚G„®ç#¦àÊŸºïpñ,fÜë³'XcçSî¨á:7L'#šcÚÃó[ÁYàæj¡ˆØ$˜–à–"@ªFâ@”-­%·œy«j׎;™Ò.\ϑ٥=´ßß² Û§ÿìû¶¸F4%ÐC¢,Õãœ.Ëψ³ ‘{Þȱh{X…y'ßà¢Î:rïÓ¹'´ÎÖB¼!¦«¯Ró~+³ §'„\ l˜š—",×I”žãÑ=S¬¾¾u{ @l‘€§u~hÍñô§cã¬á8ý!ži}K #SÿÉ"0ºj§j¸o¹ö(6aĶéx(¶éä:ä²F¹ºàÿnñуÚ9Øâ^Â>ßì~ºútŠ=àe)þ¼ÆxRg:ÐwÑP‘À‚1ß%J·ïMèaêƒKŒÛ\¡SÒ´?&/ÿ„O“^ø Q‚WEºçÓ‹ ÇïƒßœÈg]Í#¢í·‹;l•,2?$O{î¡öêjßÃÑ­7@=s÷Ó1½ˆëKf«èÓáôÝ`üRµ{Ãkž.`¸Ú·>„:P\UÜ—Ïâþ©zF‚%û†x`Nm×rúÔìÁVõ7ûɳ nôŸÛ½wr"±ýËYªz•2kçB;VIç ‚’½=tÜbJÛÇwiàœ­œ»©f9ÀYäþr x ¸æŸ©4ÿœ’c0Rî ß×hŒÍíÁœgÉÜì¼Lo›0yÿ{>žæ‹ýù·R.úhƒàIÝGy`)ögªre¹K¿šÛËt°•kzp§#‚QeP‰]9q$pï…XùÈ~?¹¾‚ÉuƘáõîFõ<}³Ãc”ÔYjv¼ rþ‚’ÚtéÔÓî4ßÌcºÌà9¯ÌáÜÒŸ¯q$ã¨2Ü.àyÔ$ ˆ.ÆÓáCj—ˆØ§…?ƒ 97ûóqþL×øÎ:-¢q!q†ž$}'—d$–·sЇ<ÍÎUçA®Á3ôÜKjE6ðXÈ÷fÄ=Y13ⲑóø1ʾW†þh{ìܹÀYÂχ_¦ºqØ m cä4æ]`t‹)ß‘—áî.y²Ð~ŸšÎ¡wã-®Á$p†ìÆæQ&ܹŒÜNíñ8Up¼<žÉØ\ƒÆUÑ‚+B/]–w|xšo³W•׵K)“'eÖžØ*X9T©öØÃû6ÀÛÍC0…|¥¦>ãá  Þán…?‘ üAí] à•S޹1I6Ð6ÙÔE¢iÃ,ÒSÝönwú÷7wÂ-£üÙ5üdx¬u@5™ GÄch0æ^2\d´?ŸŒh7‚É$x0ÞMA˜ŒQÅŽ¡ ¿€.vÞO”_Pü-š\­ÔŠ¡2˜ÜfÁÜ8I& 9+E[ ÃEÇ >Õ"‰Çš­›ÙêUåÿ˜ !\†2a|çæ· ùE h7"Ÿ¼t9fÐjÇÏ„ûÎ…ãìâ$h ¶œØ¢³êh‚Di¤5²Aך•’'—ãÐc0òZÄäMx?ñoco/߉½†Á Ô’qŠQÐIJ¸ ç.œì ŸÚiúa# ço~ދѳœë7 `|.ïœâ˜öEÖrWß;åÇ1Œ pø2NèȘ˜±†rëz.Û2"« ^ŠY£=I¨ÐLÇ8‘A,ê§×;K.ŒÌE†NŒˆ*ø¬Ó9ø° x?¾-ÂÑŠ.ÄD®ÌxH<:‡yØ»±"ªÀ“Q°xÌdÓËHPxTÃ)q÷n®¢Æü¼*ù’ŸÖ—é¶i4!Â}y47›îÇ©fíÞ[s3LéÙûók^vÝqsö»³wصηea¦Ìpqo^ÎÉÊ;«LÏB¢ïËÇìùD U!üö¦3)—6ç§%\RtÃÏd+ëïÓÒ­ÈÀi ~ÏC9Ú¢÷§þNº•%ÆùÛ ™”Ñ‚ùéO±o¡ü)G”e˜Õ鎠Ó¾K44É ±)wŸµ4XÂï9Hð–À •THºÈ0«,:Qh7“|scŽÀ2ó yãNT1aqßÅK±5GøE­8Âic?²EÙ`{äðsgߊ²YmФÎ71øöAÒÎ]›Ê 0üühdòôÛ^´Í«®x}ÈöZã·³î|d‘ÒGmªóºV5‘Üó*«#BZpC îö¼ù¤ñÑ‚;l#{²GÒÿã–ûéÇ5íá§r9î1šØ^p/—QÃgtnÞ»ö,Ò9?–Í” ËG” Õ4NÄ4œJÆD*ξX3ìèÀï­ èþKØ)}æAÒ@fŠ üJ‘¡¶¹’OŒµù!ŒÄ©n¸‹ÀÉ8þ¶øó—ûÿŸ¬DÊÛ+þ?üÙÙøÛæöæÖîÎÆÎÖÖöß66Ÿìlí,âÿ?ÆŸr€ÜÝíõ¤y«¼½ÓŸßødþì}äü›ð{+2þw6ž>]ŒÿÇøsÿô‹„‹„Ÿ0¡÷íHP\ü®Ùx=´ûìhàb Þ”}{ Ïå¾|>´¯¾]†à3ÄÅ]àþ•=¼@V^×[ört~ÅJìj2ï­¯ßÜÜ”U9ÃÊHã#g:._-)[š|8µNþëÖ˜}dVàüHÉ£çñBýóøJë´Ò¥ºÌ2¶?¶×±ª¬r;®]k%EA#!11À’ú¸4uµyrZédÔÐÅ<‡v$-„ÎbªÅdzßMz+m¨3ÒöÿYúþ\žCs·lu•~±¢õ{ôö×~Ï›âE(Û¥*žßÁkÌ÷)Xýà.|ø êWái8ƒÈNs§#|MG$ù(c<ñå)4§Ž Ù* Q¼1XÛj5hs¢AMö-î•ÐvÄ;T@³ãc>Øñj¡=¢sæÊÜù€C Äðr€ÇtÜ‹'ΘÒÅ]™ð‹Œ¾ç8Fá%aÞ~ý-{õ¢þ}í¨ýF±™d˜@#¼¬ë…3éñØS¿N€ô$jb÷ŸQ§ðìÐKT(úh?j´»<Ïe÷ßGÕæY£Sà„Ó%9ѵ&\¥ƒ£H¤_°ÍÔ×È¡/œ2¥²1â<ûÝ`ÌÆv01¾‰v ,qDÈ7Šu¼£Q ñ݉² C%ƒp9B±&† öu(S_sÇ;Ñ@Úgäk0šÊaT"ð”gøûß²kŸIŠ©Ï±<ß2UûÏ%ל¿iœdìƒäÂ7‘Z$Ÿ+.½ó´¡ÀöUÿ^‚Ô¢½’ Ó&Ø SW8Øè…3y ”¶Nÿ;çæÁoŽwQ^…¼ûRG4‹)YloDk]¡PÙ#t,tÀä“£\Qá8ThµŠä9è…á˜,°a‚¾ÅhWQé66øæìuLUEIP([-áÁØêbà û÷ýdQ)µ¯IT8kfK#cç`5¼ãàš|hå…h¶ZéR)›«5!&€f/ r‹ûq*>ð^åS‚Ð(­V·óÃiM#;^L!Lõ¸ÒnÇ€Jr\k˜²Ñª}aÓEË £Ù’{¿[ÆîdbÛfqÅh=¶?ä}ØÄVÛóÏ(ΰN·ÑŽt@LâHÎHÝ÷qÉ¡}´a†÷õ¥ Þ[ sðÔÿ(ý™Wjóñ=‰¯†Zø1¢"~Šè.0€²‚hVñ›Íâ¾¥Q™…éà§ûùè5¾‰ûÙ¦ DÔ\b;•ÖßfÒ¸­&‰€8×°ì7ßÈÑÕÏ¢YL•,´ètÅ’¨LHŒ«Í×ÝÚ÷ÕcÌiÐêìÞº Äi•—ÛÄA¦+˜úæ)GCÑÅï "~0üb“ ÌšÆPÁS(É ) µ1i¼qØ%¬‡Ñ{ON°xTóóÈyþ-E­àIÑjC  TÿVÍ&3Äœ£(ÜÈ´-'éˆ)\4&õÖPBâméÙ?D"A¿™jD‘›hâ# -\ŒÊ!|%I¨ó¤±5íᥴ‹épò'B(Éì².ö“`ìáÍz‹,›-æ¯Ê Z”&‚ Óƒ(³åax191ãÇ ³'•£­hˆð–žÎ¡$„.ª2"Vu¬>)Ç„[3¶b¦QtͦL#£]J?‰ÕDâçØ7ÓŒØÕ¬Üû¿"tÜÃåžqþ³ùtw7’ÿyëÉÖöbÿ÷Ñ÷yúæÍ§¸eö/ïÊem˜[ÈúÛ_àñÐ…ÕÁd0º±ÁH»e‹ÝßÅîïŸ s·ËLˆðœ¯º] ?áÓ|>-qùP9˜ÈØš\ÓÌ#£›â­^¡ŸUxÑUÐöÝÐWDó 1‘á%‰®ˆzÍ‘Š@š©‘6U¨Pq3îžo½é©‘ ÿ/úÁ}NûçÖÿ¨ø#ç›Ožl.ôÿ£œÿ¿]²à¿ûJ$wš°à=f,~ç© ßy.Ð Ï9`Ñ»ÏXúÓÁðyæ,xç  ßqFÀ¢¹¦’ÃÎ+‘¶ñ¨Í¶ÙÒÖ6û×txKb _Û¯ž?YRÓ±·%i*c”&˜‚ž?O<ŸçŒ \çÌs©dû‡Fó´]o[e÷BËRÍ¢žiGK±3o/êâçÛ‹ÓÈv '02 }ýªâÀç¢U¾QGµvµU?Åd³Vøþöâ¹¢a» apH¼)8p®y˜E&n¹Æš}s5àÇ#ÞØ£{€cžé‚î¨óªŠ1ÔH7âÀ*µØ·–ˆ€B‚zÁ%[\íÄS ÌYÁ´¬Jú%Œ`›áN@Bù®Áϲe½ˆ5BËá"‘†â'¨Ú ² Ýƒ[ËìjN„ï dØá{0<ðD‘±XÕb_ÆUçÀ©g·RûÑTN0|RP˜k¡×_uÿSk5Q8p‰;–¸99PÃPu«ã—IzZµÎY«Á^WŽÏjm+.;|làÍhJ%ÅUÔ€¢€¢ÅvìeÛÜ–Äj®@K:Œ„/{BÄóŒpÅó£LAu€÷A¥X4=`t˜UÒéÜàÍj×j¬rÜnZåç-¦6b¿¾‰o©\å¬óªÙ²^úÎ%{5í¨™Oê˜ú¸C8öF›Y¶Êç¾u¯ióÏçÿÕi5?Ži”µþßÞz±ÿ6¶wöߣüÁ·àŧDß¡Hû°ê)±Ž‡¶wC¹ÇtR£mn%_ä¾Zw&½už§Œx<Ó½ð hœÑ´w…Î ­UQÃÑ`hÓÕÀÀ]crØÆY™&¾7ñzÞP¦ÕreÜË…+Ü…ýýÎÅÀ*¢UÜtD»í—i@V ™g`‡Ðõ®çw‰t_Í |6F+#ITž×ù†=¦½2žµ€æ8!^ò©LX4+0·­;B?z,ld`\$¤ )²+;¦'6'~„LPÀ9)Åh™Ä™Dnbeðiƒ@-aEyá¶|ÿ_í„óœgûÿîÀCDÿoß…þŒ?VÌx ·€7nÀ‹à¿ÖFðGõ½ýKûÄ‚abûn¦[,nËd5#gÔwΧ—½TÀûÁh:ÒVw˜ÝÆwDP}2E²m›‹¯–nø¤ò=°û¨Þj³'xs䥧|XÅovXÂ;„Ô†.“`ܵ^Taqñ¤$p3¾ÝΩFg>ŒkÄÄÇ2¦ uDª9² ´m@`¼ ‘„UòR"º‘‚A,«ÁšØ[ÁáÀótØxZ] ³Ð7{Üm¢1:È ]é(Ÿ%qZ.òŸÊ&Q[ ¨7b0XžÏînŸ`.={H;€ÖÁ˜i˜–ƒöØXÿÁ§÷™xˆb„jº¤Š 80ÕCOSŒ¢œê" ^î ŒZÏ$™‡_ãBkÊ>‡´F‰¼F¨.hÉaãöC I’í+ Á¶û8"çõ¹3¹A»pƒºfw‘øÐ'E _È­˜è¨>êiPjèEIXØAˆ»œýæø^IÔNe#mQ”Io$rÄöe«EE#ûõºÖóˆÕåDªÑ%¶§0&WÓ‚ÞOtˆÊ¢‹›-Œ’K‹ûE~0!@#Ìç›A}1?Р¤¬ñE)S››Ðì7#!ztÄQ¬8ÃÀ‡}rÁÓÂh´S€KN~è' €X™òY>w.®+öIîÔP#I£šIåbA¹õáô¡ñ pW8íº‚™¶´ÓbAÛœŒ0tñr¸ƒ9¡›à†æÐóÆìʶŠÇiŒœ¶R^¡Í@Ñ¡3¶}{âA_ÝIŠÝ{ íàŠÆs‚ž=vpjx<¿¯ ¶)ªÄì6PÛ¹•¦ºâÆZ5ã¨Z2u1QGsbµö×Ô«ãhŒ =‡ h…Káx#^LyÖßÌ%9ô\FÅ pÂÓHNª±¡Ó¥òœVE(m}’+8ι„}5ê¢Me tÐV¿\ ŠÖ¿ŽÕ`ßÒ«GèW =Ù`ÚÚüû&&£i£Ã5ñRyiï’xÞDˆ£F›M|%Ü™”PBÑ0ëDÀçÛÚ°ÇäÏ M§Ë+Úá¹¾¶´$°p—¯_¹ÃÔÊÛ᜸ªNîmàl¼ïmÀ_=Ú_Þ*ˆ„¤€½5è¯É„Ýšãý¢¬ ™Râɾ6ôðH{åå´wÀ¶„;VÑ›Ç<ú§6i ŽÒ4…ûÔ¤«Ìyj@y³­ ?°Â3¾Ã£Ó”ÈÍ™ë:¸¡*eY‹á~qÑÐç5òYÎuc S´Qƒ³`aulz róðFw÷ÒIÝV4Æöï‘‘2 …ý}wúÛÄ †…1ˆùÖ+I5';©øXß4?|ОÆámцÿ§7âÛoÙßÙl•êÚ,j5H$Zßš„s‚¹ QµIo[ —ó K¥l §€:à)jï?€"þðöíJ1¦WýæÆ?F9">™T%Pf2I",¯DÛ/aõ^Ìè­M³·„ NÅ«Ò|žAÄàÚÇ”oÔ9¼;õ+{ƤV[…§ôÔéªCVå>ŒPÚ<¡É²¯ù új9£ñ„€¦1Ê%ÙJgÈ>oñO 6-NwXÁj£f¶¯Á4ŠSmi›¤,PlÿçTÒB2õã.>ÔŒ‰¸±&Œmî›Éë÷nt5kŒw¦áŽÖ¬HïÇ]¿U4pÕ¯’MÏâw4D7”6©^©Š¤0 „°¥­{&àl=…[MD0¥Då– ¶æ’–3¾c¸"›-Á›RI­‰8ó– %ª0›¬—´z õ‡44X}¾z%2E/Ç ®^Ôq\®\ã5t+Y·rî Â3Uisa5„n•IïVÈãµl@èüüæBm—Æg\¸@%Êçpå>³Éº×l…dQP]³ªÍ‹É/@ï$KâtÁñΚ1\¼ªÊ6sè¯pþ`ÿ“h/:I¦Ð`N ®þqæŒÈ­H†ûl§¼YÞáÆ¤Gçê2íracs @Š|WºcË”ZÑávœÏýÉûér“ÚáÒDª_pq¦=Ü[¹JãéE×”˜jk0²P¹\>Äý½O¹@‡zç0·‘× 7‡‰LA^ÁÅpqƒ^påÔrŒ†ktéD‰¤Ç€¼ƒë/\£ó .š6àßñ”+VµK¿vïÜéSÍ|¡+g-àÌmú’2aAœ_c*•œ‘+;r1U´²ïå¼’°øóÉÎÿÐ!ùÚñËöÍ»ÇóÿØÚÚÞùÛæÖî“M„ÛÅó¿­íÅùßcüù Ńý±¾Âð)§¾÷ Ø0{ÂW_Z] (ã~pbKýc:À²CøgÈŒ:b¡€"°'n=’^4äQ'¹[äíîvç¨yÖ)³W8¡ÝzSÚW¼t¸¿T-Ñãäúfànoí2-0Ìå;÷¦ŒJ}çÚzc<ì[û—Ï뀡´µÒþdk»üÛ`l}e=¯½¬7h–ÖIjâÊ· G_¾þqó§"Ødj' ¦ÂÂÒ[i--ÙWt.ÇNÚ?´Ù%Òwãùïø¦iµuüBfâ³™ÚÙ£° ËõÿÊóRÚÕæé­úËW¶ôã—~úfiy½(Í$u*â ãe½é9ü&D[OÖ„¥ ÅÒÖ“¢e†éu¾®µÚõf£Ûî´j ×¹ u†UnC•s×xRùW³Å~Ü(ýã§oªÙ¿x¸Z[Þžq½‘‰xàÞñi¥S}•ŽxLb4ÕÆ>NûKÇõçU€,Eš¹´¶¡OCˆÓñQßé8yo%P¦ŠDÅ Í·ÅìüÉý¶aþßÙÚˆùÿlí,â.îÿ,îÿ,îÿÜùþOíûÓJãˆ=Åùnß^ÔEmtýʦï ,.ÑjÀg0‚èY,ÿáU }Á7x .õÂG ¶ÔI#Pƒ‚¤³‡»µô½II‰ÃçªÅguáVaû—$úV¹.·Ç,î"è¸ë/c I\"CžXð…~C; kį@í¨rVPçyÊʸ²d%øcpÇ y`'¯hz–£$t}R/³\~ÐID:N/¥Ë°Ðó9 ¬õÚöö9,ÌLåz‹¬L7Á2üƒ(ña.tbïÇ’óÚyË÷¯m<ŽùÿD$o €ù´II1˜Æþvٲ·ä8š¸„_ðÁËð’÷¹â˜Œy‘t™)IŽ‘d± …ªGº´/v7÷Ú-rÊ6Ÿ ý¼ÊªéçQ1¦RX=Ç¢ååuK‡ðydñ’JÈvΰ…æ—>!qÄä`ð8ˆÅyeOƒ Á&^„)¥é"T,KÌç{jaÿ«ûÿ¡8<†ÿÿÆæÎÓ§1ÿÿÝ…ýÿ üÿÁ:ÚXxþ/<ÿÿG<ÿgøÅëQ¡gåL£Ã³0ØO£ö?p‚•žÿ!Lwwß] Yû?Ovv£ùžlí.ôÿbÿg±ÿ³Øÿ¹ëþÏi¥Õ®u•ÓN«Ûªÿ ¢Á¼pÎý)®ö·66·¢[A1݇B“=™$o(a„f³TÀw¢„<Ï Æðù7§*¯+õãÊóúq½óÔ¨ßhAh~Ó –ïõ§b÷4âß±Y~ZÞMÛéRû\á+5¢]oĬ‡‘OíwÓsöÊ÷~sÞ±o¹¢‡0îav¦°§kfv PöÊž¬aYÝ $,aýí•ãýþ{@³ò¿míFÏw¶ž.ü¿>Qü‡¹÷b„7þ‘k-¶Ž[GÿÓA# Û §è;vxeªþ=Ã"%‡_‡Âè",t§Ûn½Fr…=³ím¼µÀ#2‹@–(ïXNP 6‡•4²Â=|ôu8ĸºŠ¿A^s¤Šƒ:2Ó»­±Õk‘åMÏ(—™NÎÈG˜TžJ!̧åVHi þDgÓ|C[K— Ù›ú¾‘kNð,_º9 ü@ç" ç>U¾9 Èž™nN£+ŸZ²¹bf†4jªD|x‰^fsyüÄtºËN!*ºä,J‰‰è,#çUV":óÒ¤Zf°‚$BÝ(Lcužtt÷ÉЦe!ѳÍÈ”•™›mÞ1ò±—G³ú$zõÍHì¤åi‰&j3ú.%S[r ³R“¥Ò˜ Óör†¶8T4E["%G[î,m÷n²¹Ð˯˜óë„6nJ =b%à @†s®P%=HéÌlnP0õ&1ÍÌ$zX8°(]#Ìø–ífßöœÍŠv,Ô©äT¸cˆÎfܵ ,V¤V _ŠSÃoª‡1ŒÜsD“˜ÿÌ%d!ˆLÔÁ(lÈ.¾Ó»Âü¥D2Wó#YÕ2oÖ&çö• ¨Ò3ŠzÀ‰> ¹q%6 §°?fcÓLÃÆ®Å\$,ªh”žÑšíN>T»›»Ïëµ>RžoTN+s‹±˜ŒúÆ¡õôÃ#¦¨¸÷C›¤:âsÀu|©À™12äfè£#m¸!®øÅ>¾ð3$!Lß–Æ~l¾Ž& Œš½a-'<´ŒJ‰¸£.)ÏŸJ¨§L+Ëfª+0$–Û”çl ‹Ö„kKõà3rôã Åž©‚ˆX4aöÞðV¸««[t’½¤Ù·s]\ƒ„±>gÔD—UìgÄ Y¸í}¤ý_Œß=¸,õ½àᲿÍôÿØÝÜŽîÿnm<]øÿ=Îý_±S"ÕfãEýe÷¨ÙÆm±k’ôö_îù?  u!€¬Ä^‘'´o_PEúÆïì¢9„„á*ˆÕæÓJõ»ÊËcK|„,…Ÿhc¬Öj5šÝWÚ¤´i¼¬uj×, S?©5_U~H¨7«ãv³ú]­Ãft_Ô›çõfè¸~Rï´uJ#´·ù" U«¾6ͬ€­æI*@»Ö8ÊÄÐî´ŽÎN³êÕ“ÓL€³*nÒîv+GG­TdùëÊq†Úœ£Š ‚Û¯Ò:•NÈË´ÔÛiU u†PEÎõvçÈì,ѨՎº'•ããf5¢Uë´ë/ieªÿA7GC4¼©w^qráIb1öï©=Ä0¤~@C0€õK¡ˆ“zïZþ‹Û>…"ìä-3p/< OÕ‚"A¼èVZ/7õØY&È¿Ï*DzeFIIƳe´Ã$Am§×&Avf€_ ‡«¯g´ËI%Ù€ÚžhgH6É8|#dGÑ [q¹‰ÁlÏF³3䉾wŽ©„0Ûo:øî ŒŠ ÙÍëÖÛÝ×Íú‘>xž·h tlCAÐx|C@i%þõòô-騪VÚµ¨*‹C5b`q(1<#³Pêu¥U¯Õ« ª-˜º_V«4˜ÉFîôì):xür9³oØVycÛÜ \º¼CÚ™ôÄþ6”·P9ø–íðUƒÊºyrÚª7:/hC¢R­a!•œr¨ñ©Û}SéT›'ULµ™Î­Íx¹Wõ—¯K…|ѹ"D뢂ST¿»A·ÏEí¸ŠÎ¾€¤ÎöV±È\½›t¸ã»v˜—XàÍ®7ÛÐJ–‹ °2^5Ûº;XXæÃ¬Ÿ‹æîTOcÐ1àÓyøŒ32Îø4õ·é¯jF1ŒÝÄ…FÂ×/š30ÇLŠÙÀ:5Ù#×´$f ó³z3±[tà˜/ ¬»ýŸäóÇùhVCbJ „ÏïËßPWO2›°@ }¸X^ÿï€rÄãÓÞhü@›³âmlÄîÿmm.ÖÿŸdýÏ·ÚÔ¼›° ‡°À‰lá ¶ðû“z‚¹Ê*”zËy?q|7¼Â*Má"$¼rdiþx^Ü×MMs#µ›·J8ïêµÄ&騸5Â/þ,æ¾8z˜Ëÿ³çÿí'O¶£ûÿO·óÿ_Åÿ{1u/¦î?áÔ­]» `y%Ǽ‘-cFÕÕ_'`ô‡ã޹aš [†’’;Á;:Úl‚7řްM`NÿSíðãö¥¶ºÀÅS„9ÈÊ%î8¼„wK…s2?ÿv”¯(…t…>À“óðÞÐŒqß’®z uÕ+ ý¥ãò–p÷YªE(Bq¼ð`ýŸ€7 €ò»¡|jòìÄÜ`cás‘HÀÉ7Q,¿ŸhD‡m¿j!”ä÷3WŒ8äZ¿OÂsaÃtüäh,¿VUÜ%ºíÖ›°Þ@uD2y¬W¢H$ÀÖ\ÊY‡Ç–êùg`H,~2üÒœRâ'Hº²]ס}ç¥wÎúÞmاF“¸tÊOõáйĮÅË”a9ùù%%(T.ßÞ.()Ћâ¸àÚLâfžÌͬÒ1sMŽXo1ÿ’ãó W&/†çÅ`|5ÛãA¹?Æ{Ö¡}öÒ™4œ F8>ÅÛÀáA]¾øèah2L[i¯>ŸÞù¸>;`èoHßbŒI± <žÄ€-²ué%Çp±hø Ë‘H~2’急©KiÁ—þ´^+ öߥ3Ás–3ÿfÆÿØs)bÿ=ÙØ\Øoÿ‰û{OX £#l¬±#Û€æiƒupîø—÷°öb¦^Ìʲöf™zÜØH¶öæ4õx²ÑhÙG4õ"våÑÌoêeØydW¥™z,¿¡GÖ¤aëý…=©m¡æ ôÐS¬ø7á ¯ 8“.^@‚_A¥ûšŽès‘®™Á "»f…^¯0l×-¶é÷ðÚ·ºèIéðŽºÈ5P7º½û”’;3O'¥ÒB—D¢êa'Ø"©:üÿF,¶\@¬ñ ®°VãáÕi­+É‘‡¡thF'Nwðža®s´Ëytsjîx\©àý¨ ®sƒLE¸Ëñ%¦³so7¾ŸŽqƒËŒîFû~² cF{ëë|,–¯ì÷ï˳Þ÷n\,¶Î1ôqað3™ß¢CÊW?«”tM¼WÃN(÷›››¬QŽ&š7Ë“ŸY!!Ö_\ ¹½K*`÷CfÈŽˆÜ´E,ĹF£¯ÆåÐå›d[u: =’Ö€w—l«ºôMÊÝ9 \o…MFßuÊ)=²C9Ü…:‰ Ú¸Æ)ãÙ¬ºùµx]-©8€ -XD¥M?'e°—¯–‡˜Û8‹÷¡(jSL0Åwa/0&Âõ`•õ¨ó¿\;îõÃmÿÍŒÿþdg+ºÿ·½½ˆÿû8û‹àÅðÿøð’®ÖbN]ü¢¨îð˜ƒÎVüöïò‚@÷M½±½Õ}CÄ¢’_ŽW¤ë•õW°ÿ“ôÿÕ£éÿݘÿÏÿoïÙßÛ¶‘¼ŸõW Ùï;Kµ¬X–íì%m/´DÛ¼•%E¤óèå>•–h‡[™TEɉo³ÿûÍAêE9iº»g5i$ À`0˜Gãðñþç³ÿå%±ÊöW¿}Ü;÷Žÿv¿r‹†¹6Šö·j ýá¶·Ëì?ƒÙ@Þ¶|“ü¯ÏêGÿ¡Qß?<fþxÌüñ—ùõ=øÛG•.æü8id:ü@;ŸïÃàu2¢ñd€ƒ–`G³ûÞ´àÌ\A†(™³½ã“dmÞ_;ò+e1Ã¥¢¡ã Bí:¥}åÚœäu9dîÚvð±ÊŠF–' ˆ' ]âlž:ο6ÄIµš”J3¦på ¢#˜}dƒ¨’n¨×ÕÛär:T†X2Ryø"›x$OEî;ð•xLf&f%eUJ1Šu* £H¸jUå©…tK:ÕSû˜jâ.ŒçI S„ ŽŠx7 Ä£°´¹¨ÒºXPv£„jóù™:ßžß~”¤¨&º±ÅÀƒù¾]1 _±4²ÀT,x©Ïˆ¯l´â³óH×@5?p˜=I±+? ™EÛt™],J>!ÉWZB>9é QO÷”4óWÈœ# ó¹³Ñ„S! _Õ×ùcåÓð87d¡+5úÂ5áÆtšÓ— ¹5<è™\ ë6&kéž©D, Å$á”n Pû=Oh×Ñ&¾´7–pÇs„ÊtîèkpÒkÇ#èɇp¢LŸ–%g)–É„C#'Ž ð„çT2³>Ù‚äß,„§Ã„ï€ôDZ}§wwH».|96É¡–6ô$ oanùQ@C…‘mðž k«I‚œkOhó“s ‰]‚G·~ò+–£Ý¨ÛÓ»‘¹¤h2ÄWI<†3lnÃ`‚öÓb·ÇVMÆ@Íe’äÕig²«·„ëä sάæÇ‹YhR>¾2I±—fÖÞuqç‡cšÛåùaVç¥Y½ s(!Ä0‚ކKáyNÇñ«íül·J[Z¯/‡wÑ+¡­þM~Ëȼ” D¦ Z˜s¥XÉÙÜχÉetNߌ/÷Æœ¹¹W£ùD'Æ1“ó¬Þ"Ȱl2Ùy0+OýŲJ¼¼j½^Û¯™©yE ?•eÍUN±Ô“$†”<B<­ÃÆE† vJ`?¢ÃÉ-%§Êpˆ]ùÃ_SùðéÀyAß}¶‚!ÿ€Æö÷QÍUÊ™FWñ°t\ë¿ü$†ÑƒA'c¼^‹@ÞÁÌ48Ì•R‚iÛ FÓp(N`IT3 êöó™Tj¢ò¬ZJ>̯¯ÇœNž–úUz jRkÓ8̸ڗ'îÎÖãÞSˆç­ÇÝmÿôÿ̬jpÂdzÞï®ÿiÔ뇨ÿ?hï?CýÏáÁcþ§oòÁDäü‡¬“M‹s5¥”€.Âk6òÁÍ $zdëþ˜<¨ˆßŠÁx‚¢±?œÆʪÂQƒ¬æÀêõÚÄ¥!«=8¹tÚTM^4°ñŸÇÈß šÉDWá@m*ˆ±l›cÂÆ=øÄ9ƒ}¸åXIb¢ÆÜA†9ž¤}Ø(†ó騀Bè83´k^öÛF¯ù£Œ›|RGõ±î¶„®-Hœ¡%GtS3a°ý¶GQ¼<ËsšîІHxOîo¯bô½-ä¾»8é¶ç"žÂ gRGh¾Þ%4Ve“ z’Ľ2‡Ó²ßzvŸéz™ÐÑ+óQ—áfŽdƒFðhúȱe¨—.Æ$=¯Ýök‚‡Ã-ž³!å8£pšz:Òñ1EÌöšÌœŽÒr‡²ÐIþF AR~Ü9‰‡͈gøréã—«ZúMÂTmÖU›*âe¾MŒæ…:¤eÚ\|ürC”t|¹ôñË¢t,ÜÒÁò–6´”>oÝàáñò7uîÙÖm=[ÞÔ3nÉ•§eVHÃ9nkβ& NG _Ý“vašk‰'ïzݾ7è#d—\xšïY—ZQRÀF¥°¶°3A ×ÂÀdÒŽÉ´Dd³¸ °‘½¬ì…¬aE[YHH¶U{h¨H *È@Ø.-‚÷/ ÄGÃÛÉŽÞVV@¼µY<)Ö’×í=¸•ÂýÙØâíp@Gi')ÆÞŽ'34l„ÆÃÍe”(ª˜Lc$ýØÖA°[Ë4fZ‘Í2MºW¬hMe&Ñ­–سº@Ã*«IAL*.´º¹É4¶U3jÀ…ªgÎ) /ÔˆQa3Ó’jœ­Æ)ïå³ÊŠV²º›µ+o¢+V±u§ÒÔ(@š.uÛíÕÛ«dŽE‰ƒÓÃÿvøqͨÝíœáßæÌŒµº«²´l†I—£Å`ÚÝþ»0/Ü30]ç¬cµ)š×*€F¹Í£­2›ÀT%F/3M±^ pš«½0ôÙp²xÊbPþÓðº0hÊ´jo½j§WTµƒiz6q̉R]† V6$§Ì À0 O@Ý'žÌ6ƒ£ÝžW1 Ýâ'»´™»Åùît'ö žMy©.ŸDgàÏâÛp8˜-U Õ`–×½pšËõB  Çxœ»W©Zðêå.û³µˆë¯»mËsÚ«„âi>ÈÝÇ@0´Ù‰ŽÉ0žƒp´ª¥•éB6O©BòYAÑì†Vp\e®PÇqÑé\•}Åà‚],HÑ¡‚àQ*ÆiØ 5ľq¨ÒpîE€‚QâEÏ)n4/‚_ë²na±Þ:EºúÇMŠKß霹ÅFán¶ØhGŇ»³ÅxG¼StÄ£‚£Ô)ó·íY…!ã4)™sÜ„\\f$)-{ÆÅ!S&³Íp‹S¢(æQâF1˜*ËêF¨ÃhL Ïß8V÷[ *Îàƒ¢`qú‡» Ø"P§á,ØxœÄð}öæåÇäNãᤎîœÄ"gñÁ€MÆ“)Æ£ŸÝãÍuzµü'¬g_ z°wÚ}ïÞ¬j‰#®PQ˜KiÍ%EÞ…&3É{7·²D-T¼SQä§Á‰ÈÓQp‡Î‹LÕ‰©3ü–udtÒÏCì[0­/§‹¶%¶Rì E–úh‚sD&8J‰±¿Ñ)Y•YÔ‘x¹ø¬˜©Ôú #©Åg+Èõä`‹†–4tðr•þrsk(µ`&Þ…U²__“Ùvå[t¨±¤CMCs¸E‡K8,:4G[4t´¤¡£­†æèáCs´ihrMoѱã%;ÞªcÇïØñšŽsä«DMìår~¹ø¬8WXžçÛÚJ®zºÉ,ÒX…«6r@·Xy«æ€.]mkÇnìtÌVŒ—ŸHÍr 2&#™–£ 94ý“s8Ái¸SÉ5§ÓÜ¿L¿·å=ÐÉí3`s é_f›u˳.û»Ø¬[ô ´à¬[´‘ZpÖ­z˜ºÝ¬[›g]ö÷J+Ú!:ø×y5²³>ÈÑÐÎQRÅS:”¼q¼s}PË56 ¹¢8Ú»SÈê¤Þ´ÄGkyº(@mSÝ(…D½%Â9‘žr©ÈŸÂäÐemÛê @viPúKxHH=Œù/#Œ0b‡héx+}/´¿¯tšáÌD\WzÌýÏæÿE¾'_1üÛÿ¯úQãÆÿl7ža. #ŒÿVöèÿõMã¿ d`*r2"¿åŸ—–& úNÔXâô) úû˜8è1qЖ8fì_øA8&ûá Чݾhv;§ÎÙeßM«‡Y*«ŽÜ|z ó5°8HÄAÔŸãWoš—š°BG˜<½„ÂXëÚWçÐõarš¡»8ÔD(Á'Œ˜«NPlv‰t@]R—?-*À¨(Aê× ˜èL‡RÀ¢ //ö*Œéï8@æuº½t˜V Ï· ð ¶yMINññAE#Îgk›8#Nj\£¿Rt é¥O '·#ÙÃÈL•î5M áÏ(8<ˆÇ¯<øI|0Zþp6'ÿPÔ9ªh>³ا¡`¤–ðs Ý“*…Þ¯Röé 'PlƤ£à.Çäsà ¸þœâc<|²dÑð±Ä­=Åx9)£å?•]ñØ•¦¹Ic†a;ª©1 ÅŒ˜?„3(‡Ë€:‚!}>†¸+¡OjijŸM~´¯Â4Ð+À6z}PlãŒ7UÝa7ñèŠv1’h´û\üÏc4 onî1þ±íÝg)b'&¼@†žàIDR^œöG#ñ/ ÖìcDºÓÉSÕéä©ÙcÚFQÔ§U­ Ã×(þOu:A†Nq[ð”EĉB„î˜Jèän’]¤aìe {2ü@Á8vÈA˜Žï;$^ìÐ^5 hUÓû— ¦2ÁÉGÊz…ú©ñx>KIB í`ÉBëËýø#Mö[ú…Ñf>ÅóñgKøäˆ"BM3«:()^ÏÓ©Ž©|.‰£ç«àÑìÁ®°ÔgФ®ä 1s¦d¶kÅ»@1 âвAŠÓ•íSd>ÔŽTL©eÀkKÁ(r{W(ûÈ4Ò9aEû/„bs4Cr¼ŽVV¬Ž˜Ô3ž4¸“`Ü&$àpdfÆF4œ†“™B¥«™‘ L¤KåkVsOåÌg‰g6¬HºòÊÒni7é.&¦°>‘_]µP@^`AJÂRSIóir~7âƒaaZšUIv£â6P4cTÊi²Û½€¾#+àé’cüÃÁðWAR2V¿a.íç¶ö”}ÒúÁà`r¨¼R›2ïÁf±â÷’˜Ø/2-CìPã\ ” ¥ö{È-û”ÂO¡ª{:ÐéãÚvgà•þ$åOÖ”’,VÊþŠIËba”¡4&>œb¹I,žDòHä˜ {°¦•´âÈtDã¯*¬qX «-œ|9ÅpÑíªs¶NjëvÚï¾²°ƒ£HY ZÿuÖë LÑ—>=ë6à!ŽR&¤ÅòQÞ†áŸÇÀ®Õ†nµš_æ¤Ûo[/ã]öOº_ äå5»_ ¥×m~)ˆöC@ÆàXmFÙL¸ºðâÝÿ‹ûeXéL_Ôµ XRo¾xú¾¾p¿aºîáþ¾D&óÂiÛÍôU¡–PÁ=¢ÁlIÞe»mZ4ñ!¯¾®¤2KKêPî9’¾v—öà„C–uàCâ(ÿð½j<Ûÿ—ë•×;ÝjÚÝTÒ}ì/¶Ýîë&Š¢gw.ÛžsaÁ‰Äîxým7+Þ‘²sá61Iá·èǙݱûNSœ5¹;mËõ¾Z?gË-øtfÂ.…& "–†ÈuaÊá('ýÊ_>*È¾Û NI€0ÐX0SŠZÑ Ã™õÑt0ÌÜê™çm9†‘'Ÿ3›S@_Jñ R8Û½Á‘‹âÑéHÇ Ãh[p„­±_®)¦æ±#¾ "˜›†¥k:¦éþðž)ƒÞߥkÚú7ß7mFlv®¥¼EFtq=[kE%~¡|¯Ö®‚,ðÅñÁìó›Læ*æïê÷ñá&î:?Û€Ç`|…K«ÅS ºÙ¦¼Y/»õ$öº·k(%k˜~a&_É]cýáiWþAï;ö÷÷¹]›ÿñàøßêÇGu,wŒù¿öÏ÷¿ßâsáÿƒóËtÄ ð¿ày ˜n £b[3Ûåû R¶péL¯0}ju¬ÇšË¤£E«Ô+£UWsw—•™å4tû<¡ÜÓz„¶˜Ã÷Épì'É“J àYÚí¿Vw¤¤6…7YYÿ :©”PY‰W¾¸>Ê ]Ç{¿šß¶qû^)ô8AóÚí?×cÁXKöb+WR;¤$fýžŒcŽºÊ+̤T¬˜M5ØcÿïÔ}YŠût!às~6Ã|TÐÓÅp|‹•ƒè.œÆE$ªP/åµ-ÇíŽpã§«ïšod¤5ÏŒ#¯ã]ÈU8CÅ:櫞 ö0žšÄÆó «H¯˜ “/ÿôåµ|š]¨Æ.W(‹öUãz†°@ _¨y“ÎT/oÛæd4C'xØ^‡ÉÜG¦ù(Œóõ·V0—‡L«Fsúæs »>ˆüyo›6Ðñp øv2“.jÄGƒ(™OƒÔ˜ÈØV¤‘ £p·â;3¹ î#KÉ“ÞÏbº†ú”ƒgÙËÌëÍðÜ7Å¿t)…ìFß Ê-‘žÎ£çî'ÑÙnï:[ ßÑ4ÝÌ1e‰}›Vd¬E( ǤÜò¸ÑIù‘îâ`š11²¬’´EbByÙ ºÊ%¢¼}Ë(Án‰xæT—Ãio3=FK Ü:kÂ3,»ÒJ%<"Á˜ŽeL@ô×äFÓ”?ŒHÙ¹YMÝ:ѸHL%J3B)E‘™Ê—‰ì›¼¨¯˜ãîTá H Ñlz¿Ã¶C;(Žíp'Ôžl"LT#i G µ’EË#í¯‡Féå&ßÇòe!„’BžÖJÚÑ`kê b:ÜD¾´kÀ@™N0“ÔЉx–Q×§IæÍИu5ææ¸½ü8|þž!ákëzL?úÓQÂ¦Š©yê(RZY§ÉŒLEÑÀní¾¡Jò\1º”œ°FkÞÅ>¢MƒIšxµ#{. ç'F¶¼T2îÛ„A Y˜Hõ¤›ÆOYåHÝj5;J¨ti!}Án\[%Ád%cá´ìÂK–[¼F½ÀqmY Z± 9({•ï†ÇþǤ6J>VèĬ#V!?’æG;wÃ¥¶5µäÕW%щè˜C/_"Ô+,HaÙ´u'â„ȱŽwì/Ƴ<¨—"ZˆloGr3XE0ls,Ò0Šø3`ÓfÁà:»Uú°B"²[~š‘mß4þ+BʤK¤iÃÑB9ªˆæ8DI)ÙæÕ|6ã@œÇ•Tì)™îÔøK¯èïæþ¸Ètu6ÞIēۥÚ$Õ®&µ(J4wXÌk…´2Uf“47OÞ“öÒÍ”„Ež·Æb„ õ^îšf5¹µè]ð#l$AŸ‚áœ}èMa‚Îo¬Š ˆà…„Âü‡hhz§g)KUœç’ìPXÚÑû(é´-y²Ä‘ÄÒ/³$1ä>ú‰bK€ø‹¤C)-(¡‹ŨU­ú’y¥¥=I 2­““ªÙ÷ ²ŸƒýýO@D‡…¿ +ʳ¥ÓpšÌŒ1ËS^†kY–܉iÿgÎKõ2Ø~ZLR+ŠzU5¶wElކ«*M wƒ, CbP;WY΀\%Û*oŠiÇC‹t¶ðË ,§ú¼ÝIqóiŠe›š-‚ô€;O®~Àû%å,U6Ô9ëyÚYôÅ&ÕRÐ,ËL7µ-3ëT,1/KSgŸ+uf¯¢3|{?­¨¼{1Ø£ðL]´ZªÅ0g´ !äU3E%á-]èÑ)¡‹@>M‚4H§qÜT}±wE('É–ë\–n™’Åú¶@®­©=Qó\Bæ+Ã`Çx ÉÎ0½çZZÌM9ÿ2ph+ÎÑ?åNÊÖÈ$¦K]ÒWÊKTN3Ê·ÖvNdV-f@ã]» èfÐCŠn–ôÀ„Äxœ,)1oé±8Gß•Ä?­þŸsÿ‘3Á€.XjÃß_ÿبוÿoƒž×G‡Çúÿo¢ÿϸó> ìÃ{É4çÛ[ܱ—œÖûö®tìźÛùö.¯û }{ÉÕ"ãÞ»oo†Ô }{±^aïÞœk¯ö–ú½{ÿ¤l¶ž¨dÓó :>(ƒ§ÅÀð¦W&¼²42kæòÀ™usIåRË&‘~ùd#hËnU išŠƒ!{ óüéËɧ¼_ø‹ëˆr½¢Kª9~ HÊföŸ úí£ŸˆW—vÿ.Þ—8õƒáœXdÅnŽôùY¨Òp¬ü¿Á4NTS»£s°æ‘W2-áGÉG8Ñéj¥%Ø™ì’0ÀY<ðú ðF#2ÅõÇFa,ôJ”ló/Æ(W~x1<]úîn€ËíHÖÔZýyúÕûõŠÉ}†"^5Û–ë~}†âi‹9šÆ t®JJÎáã´F¹“¢ûW ÅTY5­E=^|T4Ž‚½«{áÇAt|¡|ë oç·â¸Q‘ŠK BÌP}™Š ¼Æ÷ñcé‘>Ci3òU¤I.C˜0|\Ú¢¬ÝÀe`ñÀ‚+M Œñ ,FNW‘’aÍĉ¶<5c ¿ï‘x_5£„ÌNù VWXiÓÁäE¶q•)ü›±*ß5¿ž¬ƒu°ts€ƒùh2@óõJéox)O†ìH‰%‘‡þ>3;3y‘VaÀKjÁ‹¨ryJg6â;ÏŽÿ|Œ:He-9%ÉêOjqœê‰$«T}ÒnÐyÛê^XN‡< ÈU¬L”„É€* ¸NëT*D¯ô0v§ëËl)d\ØÒps໘žþt|tá$rqå‡còU§WŒÆè@ŒDCÑSü(ö_Èßø£sÙn«†,it SMìâ¾Öw©ÙŒt”‡;ŸÒ¾pÜ †R»”ÃŽí7¸žœ­´2pǦi«æ6ÝÃ^ãáiÏè, “¡?¡‹Ÿ„aá9O¥Æð†s|aŠ]àÝ»âüÔyk·ÜŸáë+ý•È[6çøOÚU‰çb¿‚zX)ŽS]øôGð;x½t¨.ì sœæê2_rKÒÿpin $+(åߪb¿ªñ¥F£Á¹mµà¸ãÂaì•ÓÂRáhÙËne|OâFr:ªˆ¿’¹ }V§‚/±ƒÊº’ûºd-4ÙnfuJ¸ U¥`""g>Ý?©=¡›lŒ|” Õ$Šã _ºUѪœãŨÀŠŒ'¢)3ãXñ#Lv5|¸»«Gjæ{£=é æ†’ÁG‹ec¸û£0Äžu¤eb“Ü„ê7¢B±ùÚNJ‘ÚÊ‹2N¨úEfVX-ÜùÕÛ¿+ :飿‘ÄVËS¸°aHn$„5]XÐrÙWÀže\øˆá àŒâßÿÿÿáúBLvw+«¿ šº5¡>½¿CµÎ.Þ»}§É¬>¤uúp0üÝ ¢÷“¸°Þ¶­»ýUieÓ6n² ºTCÃRßû3ß Ó÷¿íîYÊ™M¡"wŠ?Œr+ÞÀ»x« Tº em&JÐóhŒ*"Ø#>„ʲudôšxÛ÷“‡+àø¿ªÆx B–ŸéE;â`ûÈË÷$ueëùfdöÕâ;%ƒQ˜¸×ÊY…~mFGn |ÿ R‡„‚ܸ‹áJˆŸ ä‰ÌKk&™)Aò"Q s,ZʯŒ¥¼ÀÂJéøe¶±mèéø[:^ˆ@¿ŸAŽTE•%4n™†5PD±l4·—ònÞÇq¦þ&ö¯ &lŸÅi€ˆªS<Kw"øevq`GG’y`é¹ÛJÝ'[L¨Ã—(?ñbØùQÏx}OúÆ@+k“ª4Œ›Á‘NNTr"4ß”D9¬µªd‡³@ÞtóU•žWØ¡•2x‘-80"-k‚ÄÙ œÞØ$}~‚ý€ä½J˜K“˜ÄZÁül’*ŠO-åQ«ø“Z;°ÑZ„›ïö#tUAŠ0¿ ¹•áaÅ`•§$W³e÷²Ù´]÷Eéïîœ_íþxÁ £ žÐjßßÿ³ñ¬ñìßêúÁñáþáÁAƒîÿ‡÷ßâS{ÿ¤v‡¿à«?ø +?øϬ¼å%V}ø-Öþ‚k¼ Á·¹ÇʾÈÃʼÉê…®òhzç’­Û˜c¯ïµ× ñä !:0út8دAQ÷\à–SZàXâýžp0 ‚?Æ}Í—n«èâÁö«‹e¬ žû®Óí¹Ž[ªEÐçñ'ãŽc\Ôz=|¡õJf»åL3ï¯ùõýu¯šQÓÀ+¬ƒ ¯*¥ÚuH­·l·Ùwz(Ø•P?öþúd±Fꤞǡî'çóˆÀ+ú¨N™ GÊé*Í?ªßJ5§¯_WKʱYÂ%WmÜ{YU§¼ ÐvvuO.ÁŒ!Α„b¢d½cqë­…õ€:7¶- Sb'kn]†|þ3 0-!¦ºpz{Á½(˜Ýúɯbâ‡ènƒðKꆜœHüF<$U%ëáø\ M ý-¹@j|y|"óÛjéI½±æQ­~¼»&Hk5ú{¿„zߟÔJ%òO3rVPZ…„WO<£¨­äÇ0 îÂxžP,Ö4ìcnDKúüGä&¼£*™•Ìwe²ÕÍ­¾í]ö;âµÕ†£Îàe3«„0R¸BìR_4i‹ÊþÐÏa™öDýÁ˜2MÚå3–9†¾¢AÖõ|Lq?ÕÄÕòðXßT’së옆ÿRi‡ ƒO| ¨» FËò,Rlº—`‘£÷2pE‘´ÚÎÏv«”³ Õ½áÞ"Ë¿fÊ5…ÐCöbÛÂj»]€ÚçÀzž”‰€¨¦¯Fó  Ö³^[NÛ:qÚŽ÷®´làˆþHFt•¸@W¯í—"ÿqB¿Úð«ŠFëä¿Ãý¼üwÐxÌÿð­ü¿ À Àþõ ÀÚÎ…ãå˜ÃÛp–leQµÌvÊLpjF ;-ë^À¼ôJ&T ²azÅ÷ðß—a4ã[@}qwL«ð…Ô¤Tȼð#—Ôgà5¥?{^q ©JIþþA*kYõƒ‚¸ÝïwºeÛ逸Uþ”÷²—69d„ÑHNŠ[%K@Ô[ÉÈ*Rp§Gôž‘!tH]¡øA" ßYṏIŒÿ;üŸšúÆ\XoQcˆÔÈÞX¬èÊBg”æž ºû£È6£ûKj8&ºÖo+Pû•%·ˆ;–Yp(q¥’#»ÒÓs÷åËì-÷Ǽ§ƒ2K‡‰„§õÃÔ4/p"ŪєþWRãFSnÉ`ìî†ió ’ $TªšÔº"²,ù$f~5eé–‘|ô )X'3r"ìx6ãÝ(­«2,$…¦"RÉPY–%©LÍa™aTPk¨Öý£þ/•ÿà@BéWL¶Aþ;Üß?ZÿŽå¿o™ÿ‹Î9g¶×íyFö¯ìS™ÑÆÈþ5¬€Äøçg{0¢tšï7´V%ÿŒBò“â\OML³O£Ð'¹x£ 8i8%MöƒlRŠh¤²J×uŠáFÒWê¸çZ˜šÒ!§Î*Q S d3›QN“¼ˆhƈFaêœzÌž+»ÌZ5ê©™©ƒÓ#(­I)V•{|™-f³rïLq‚F‡c?¼åä=âdhРˆBú9šçâÚ|=\t Sª•ð ÞS´ø¤È-·˜ÎȆ¬§Uf7¨s͚行ø¢<.Upý0%Γ)âYG1dôÙ’>Tœ`üð4 9z߯3R7­ð ¸¢]© I*x+%h)8k1:#@“ýݹ㠷{ê½%%à{¯ß}í´ì–8yG1–›ÝÞ»¾svî‰ón»e÷]auZ˜WÌë;'—^üò‹åRòwg‡ÞZwÂ~Ûƒ5êŠn_8½¶¡‰¾ÕñÛ­‚HÔl_¶œÎYUÊuA’0óºUÆÌ^R“e\Ø} ÿèIÝ5yêxls3X¢gõ=§yÙ¶út¼ì÷º®LC´·Ù¶œ »…B~ök»ãÉœØhß>ƒ„y¦›'6k;”FÚn¶œ¾Ýô°?é·&аkW…Û³›~±ßÚЫÿ® `i*u;®ýêÊÁ{Ѳ.,ŒfY^Oœæeß¾@„»§”MíòÄõïÒ³ÅY·Û"¬]»ÿÚiÚî ÑîºD±K×® T”2~ÁÙÃøL§Æ/øcüÂóÈ !©Ko7}‰‡šô%5“¾„vŒ—Ôjúþ/ ‰ô%a¡_Jœ‚O#R=&T^¨‡H-F ÿšÍ?‚?™`È™]ý1òãçñóøyü<~?ŸÇÏãçñóÿæóž ½• ixymon-4.3.30/xymonnet/ldaptest.h0000664000076400007640000000412712000050736017052 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* This is used to implement the testing of a LDAP service. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LDAPTEST_H_ #define __LDAPTEST_H_ #include #ifdef HAVE_LDAP #include #define LDAP_DEPRECATED 1 #include #ifndef LDAPS_PORT #define LDAPS_PORT 636 #endif #endif typedef struct { void *ldapdesc; /* Result from ldap_url_parse() */ int usetls; int skiptest; /* Skip check if failed TCP connect */ int ldapstatus; /* Status from library of the ldap transaction */ char *output; /* Output from ldap query */ int ldapcolor; /* Final color reported */ char *faileddeps; struct timespec duration; char *certinfo; /* Data about SSL certificate */ char *certissuer; /* Data about SSL certificate */ time_t certexpires; /* Expiry time for SSL cert */ int mincipherbits; int certkeysz; } ldap_data_t; extern char *ldap_library_version; extern int init_ldap_library(void); extern void shutdown_ldap_library(void); extern int add_ldap_test(testitem_t *t); extern void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int timeout); extern void show_ldap_test_results(service_t *ldaptest); extern void send_ldap_results(service_t *ldaptest, testedhost_t *host, char *nonetpage, int failgoesclear); #endif xymon-4.3.30/xymonnet/xymonnet.c0000664000076400007640000024347313532325276017136 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor network test tool. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonnet.c 8084 2019-08-30 23:01:18Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #ifdef HAVE_RPCENT_H #include #endif #ifdef BROKEN_HPUX_NETDB /* * Some HP-UX include files fail to define RPC functions * and structs that are purely standard. At the same time, * their own docs claim that the DO define them. Go figure ... */ struct rpcent { char *r_name; /* name of server for this rpc program */ char **r_aliases; /* alias list */ int r_number; /* rpc program number */ }; extern struct rpcent *getrpcbyname(char *); #endif #include "libxymon.h" #include "version.h" #include "xymonnet.h" #include "dns.h" #include "contest.h" #include "httptest.h" #include "httpresult.h" #include "httpcookies.h" #include "ldaptest.h" #define DEFAULT_PING_CHILD_COUNT 1 #define MSGBUFSIZE 4096 char *reqenv[] = { "NONETPAGE", "HOSTSCFG", "XYMONTMP", "XYMONHOME", NULL }; void * svctree; /* All known services, has service_t records */ service_t *pingtest = NULL; /* Identifies the pingtest within svctree list */ int pingcount = 0; service_t *dnstest = NULL; /* Identifies the dnstest within svctree list */ service_t *httptest = NULL; /* Identifies the httptest within svctree list */ service_t *ldaptest = NULL; /* Identifies the ldaptest within svctree list */ service_t *rpctest = NULL; /* Identifies the rpctest within svctree list */ void * testhosttree; /* All tested hosts, has testedhost_t records */ SBUF_DEFINE(nonetpage); /* The "NONETPAGE" env. variable */ int dnsmethod = DNS_THEN_IP; /* How to do DNS lookups */ int timeout=10; /* The timeout (seconds) for all TCP-tests */ char *contenttestname = "content"; /* Name of the content checks column */ char *ssltestname = "sslcert"; /* Name of the SSL certificate checks column */ char *failtext = "not OK"; int sslwarndays = 30; /* If cert expires in fewer days, SSL cert column = yellow */ int sslalarmdays = 10; /* If cert expires in fewer days, SSL cert column = red */ int mincipherbits = 0; /* If weakest cipher is weaker than this # of buts, SSL cert column = red */ int validity = 30; int pingchildcount = DEFAULT_PING_CHILD_COUNT; /* How many ping processes to start */ char *location = ""; /* XYMONNETWORK value */ int hostcount = 0; int testcount = 0; int notesthostcount = 0; char **selectedhosts; int selectedcount = 0; int testuntagged = 0; time_t frequenttestlimit = 1800; /* Interval (seconds) when failing hosts are retried frequently */ int checktcpresponse = 0; int dotraceroute = 0; int fqdn = 1; int dosendflags = 1; SBUF_DEFINE(pingcmd); char pinglog[PATH_MAX]; char pingerrlog[PATH_MAX]; pid_t *pingpids; int respcheck_color = COL_YELLOW; httpstatuscolor_t *httpstatusoverrides = NULL; int extcmdtimeout = 30; int bigfailure = 0; char *defaultsourceip = NULL; int loadhostsfromxymond = 0; int sslminkeysize = 0; STATIC_SBUF_DEFINE(warnbuf); void dump_hostlist(void) { xtreePos_t handle; testedhost_t *walk; for (handle = xtreeFirst(testhosttree); (handle != xtreeEnd(testhosttree)); handle = xtreeNext(testhosttree, handle)) { walk = (testedhost_t *)xtreeData(testhosttree, handle); printf("Hostname: %s\n", textornull(walk->hostname)); printf("\tIP : %s\n", textornull(walk->ip)); printf("\tHosttype : %s\n", textornull(walk->hosttype)); printf("\tFlags :"); if (walk->testip) printf(" testip"); if (walk->dialup) printf(" dialup"); if (walk->nosslcert) printf(" nosslcert"); if (walk->dodns) printf(" dodns"); if (walk->dnserror) printf(" dnserror"); if (walk->repeattest) printf(" repeattest"); if (walk->noconn) printf(" noconn"); if (walk->noping) printf(" noping"); if (walk->dotrace) printf(" dotrace"); printf("\n"); printf("\tbadconn : %d:%d:%d\n", walk->badconn[0], walk->badconn[1], walk->badconn[2]); printf("\tdowncount : %d started %s", walk->downcount, ctime(&walk->downstart)); printf("\trouterdeps : %s\n", textornull(walk->routerdeps)); printf("\tdeprouterdown: %s\n", (walk->deprouterdown ? textornull(walk->deprouterdown->hostname) : "")); printf("\tldapauth : '%s' '%s'\n", textornull(walk->ldapuser), textornull(walk->ldappasswd)); printf("\tSSL alerts : %d:%d\n", walk->sslwarndays, walk->sslalarmdays); printf("\n"); } } void dump_testitems(void) { xtreePos_t handle; service_t *swalk; testitem_t *iwalk; for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { swalk = (service_t *)xtreeData(svctree, handle); printf("Service %s, port %d, toolid %d\n", swalk->testname, swalk->portnum, swalk->toolid); for (iwalk = swalk->items; (iwalk); iwalk = iwalk->next) { printf("\tHost : %s\n", textornull(iwalk->host->hostname)); printf("\ttestspec : %s\n", textornull(iwalk->testspec)); printf("\tFlags :"); if (iwalk->dialup) printf(" dialup"); if (iwalk->reverse) printf(" reverse"); if (iwalk->silenttest) printf(" silenttest"); if (iwalk->alwaystrue) printf(" alwaystrue"); printf("\n"); printf("\tOpen : %d\n", iwalk->open); printf("\tBanner : %s\n", textornull(STRBUF(iwalk->banner))); printf("\tcertinfo : %s\n", textornull(iwalk->certinfo)); printf("\tDuration : %ld.%06ld\n", (long int)iwalk->duration.tv_sec, (long int)iwalk->duration.tv_nsec / 1000); printf("\tbadtest : %d:%d:%d\n", iwalk->badtest[0], iwalk->badtest[1], iwalk->badtest[2]); printf("\tdowncount : %d started %s", iwalk->downcount, ctime(&iwalk->downstart)); printf("\n"); } printf("\n"); } } testitem_t *find_test(char *hostname, char *testname) { xtreePos_t handle; testedhost_t *h; service_t *s; testitem_t *t; handle = xtreeFind(svctree, testname); if (handle == xtreeEnd(svctree)) return NULL; s = (service_t *)xtreeData(svctree, handle); handle = xtreeFind(testhosttree, hostname); if (handle == xtreeEnd(testhosttree)) return NULL; h = (testedhost_t *)xtreeData(testhosttree, handle); for (t=s->items; (t && (t->host != h)); t = t->next) ; return t; } char *deptest_failed(testedhost_t *host, char *testname) { static char result[1024]; char *depcopy; char depitem[MAX_LINE_LEN]; char *p, *q; char *dephostname, *deptestname, *nextdep; testitem_t *t; if (host->deptests == NULL) return NULL; depcopy = strdup(host->deptests); snprintf(depitem, sizeof(depitem), "(%s:", testname); p = strstr(depcopy, depitem); if (p == NULL) { xfree(depcopy); return NULL; } result[0] = '\0'; dephostname = p+strlen(depitem); q = strchr(dephostname, ')'); if (q) *q = '\0'; /* dephostname now points to a list of "host1/test1,host2/test2" dependent tests. */ while (dephostname) { p = strchr(dephostname, '/'); if (p) { *p = '\0'; deptestname = (p+1); } else deptestname = ""; p = strchr(deptestname, ','); if (p) { *p = '\0'; nextdep = (p+1); } else nextdep = NULL; t = find_test(dephostname, deptestname); if (t && !t->open) { if (strlen(result) == 0) { strncpy(result, "\nThis test depends on the following test(s) that failed:\n\n", sizeof(result)); } if ((strlen(result) + strlen(dephostname) + strlen(deptestname) + 2) < sizeof(result)) { strncat(result, dephostname, (sizeof(result) - strlen(result))); strncat(result, "/", (sizeof(result) - strlen(result))); strncat(result, deptestname, (sizeof(result) - strlen(result))); strncat(result, "\n", (sizeof(result) - strlen(result))); } } dephostname = nextdep; } xfree(depcopy); if (*result) strncat(result, "\n\n", (sizeof(result) - strlen(result))); return (*result ? result : NULL); } service_t *add_service(char *name, int port, int namelen, int toolid) { xtreePos_t handle; service_t *svc; /* Avoid duplicates */ handle = xtreeFind(svctree, name); if (handle != xtreeEnd(svctree)) { svc = (service_t *)xtreeData(svctree, handle); return svc; } svc = (service_t *) malloc(sizeof(service_t)); svc->portnum = port; svc->testname = strdup(name); svc->toolid = toolid; svc->namelen = namelen; svc->items = NULL; xtreeAdd(svctree, svc->testname, svc); return svc; } int getportnumber(char *svcname) { struct servent *svcinfo; int result = 0; result = default_tcp_port(svcname); if (result == 0) { svcinfo = getservbyname(svcname, NULL); if (svcinfo) result = ntohs(svcinfo->s_port); } return result; } void load_services(void) { char *netsvcs; char *p; netsvcs = strdup(init_tcp_services()); p = strtok(netsvcs, " "); while (p) { add_service(p, getportnumber(p), 0, TOOL_CONTEST); p = strtok(NULL, " "); } xfree(netsvcs); /* Save NONETPAGE env. var in ",test1,test2," format for easy and safe grepping */ SBUF_MALLOC(nonetpage, strlen(xgetenv("NONETPAGE"))+3); snprintf(nonetpage, nonetpage_buflen, ",%s,", xgetenv("NONETPAGE")); for (p=nonetpage; (*p); p++) if (*p == ' ') *p = ','; } testedhost_t *init_testedhost(char *hostname) { testedhost_t *newhost; hostcount++; newhost = (testedhost_t *) calloc(1, sizeof(testedhost_t)); newhost->hostname = strdup(hostname); newhost->dotrace = dotraceroute; newhost->sslwarndays = sslwarndays; newhost->sslalarmdays = sslalarmdays; newhost->mincipherbits = mincipherbits; return newhost; } testitem_t *init_testitem(testedhost_t *host, service_t *service, char *srcip, char *testspec, int dialuptest, int reversetest, int alwaystruetest, int silenttest, int sendasdata) { testitem_t *newtest; testcount++; newtest = (testitem_t *) calloc(1, sizeof(testitem_t)); newtest->host = host; newtest->service = service; newtest->dialup = dialuptest; newtest->reverse = reversetest; newtest->alwaystrue = alwaystruetest; newtest->silenttest = silenttest; newtest->senddata = sendasdata; newtest->testspec = (testspec ? strdup(testspec) : NULL); if (srcip) newtest->srcip = strdup(srcip); else if (defaultsourceip) newtest->srcip = defaultsourceip; else newtest->srcip = NULL; newtest->privdata = NULL; newtest->open = 0; newtest->banner = newstrbuffer(0); newtest->certinfo = NULL; newtest->certissuer = NULL; newtest->certexpires = 0; newtest->certkeysz = 0; newtest->mincipherbits = 0; newtest->duration.tv_sec = newtest->duration.tv_nsec = -1; newtest->downcount = 0; newtest->badtest[0] = newtest->badtest[1] = newtest->badtest[2] = 0; newtest->internal = 0; newtest->next = NULL; return newtest; } int wanted_host(void *host, char *netstring) { char *netlocation = xmh_item(host, XMH_NET); if (selectedcount == 0) return ((strlen(netstring) == 0) || /* No XYMONNETWORK = do all */ (netlocation && (strcmp(netlocation, netstring) == 0)) || /* XYMONNETWORK && matching NET: tag */ (testuntagged && (netlocation == NULL))); /* No NET: tag for this host */ else { /* User provided an explicit list of hosts to test */ int i; for (i=0; (i < selectedcount); i++) { if (strcmp(selectedhosts[i], xmh_item(host, XMH_HOSTNAME)) == 0) return 1; } } return 0; } void load_tests(void) { char *p; SBUF_DEFINE(routestring); void *hwalk; testedhost_t *h; int badtagsused = 0; if (loadhostsfromxymond) { if (load_hostnames("@", NULL, fqdn) != 0) { errprintf("Cannot load host configuration from xymond\n"); return; } } else { if (load_hostnames(xgetenv("HOSTSCFG"), "netinclude", fqdn) != 0) { errprintf("Cannot load host configuration from %s\n", xgetenv("HOSTSCFG")); return; } } if (first_host() == NULL) { errprintf("Empty configuration from %s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG"))); return; } /* Each network test tagged with NET:locationname */ if (strlen(location) > 0) { SBUF_MALLOC(routestring, strlen(location)+strlen("route_:")+1); snprintf(routestring, routestring_buflen, "route_%s:", location); } for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { int anytests = 0; int ping_dialuptest = 0, ping_reversetest = 0; char *testspec; if (!wanted_host(hwalk, location)) continue; h = init_testedhost(xmh_item(hwalk, XMH_HOSTNAME)); p = xmh_custom_item(hwalk, "badconn:"); if (p) { sscanf(p+strlen("badconn:"), "%d:%d:%d", &h->badconn[0], &h->badconn[1], &h->badconn[2]); badtagsused = 1; } p = xmh_custom_item(hwalk, "route:"); if (p) h->routerdeps = p + strlen("route:"); if (routestring) { p = xmh_custom_item(hwalk, routestring); if (p) h->routerdeps = p + strlen(routestring); } if (xmh_item(hwalk, XMH_FLAG_NOCONN)) h->noconn = 1; if (xmh_item(hwalk, XMH_FLAG_NOPING)) h->noping = 1; if (xmh_item(hwalk, XMH_FLAG_TRACE)) h->dotrace = 1; if (xmh_item(hwalk, XMH_FLAG_NOTRACE)) h->dotrace = 0; if (xmh_item(hwalk, XMH_FLAG_TESTIP)) h->testip = 1; if (xmh_item(hwalk, XMH_FLAG_DIALUP)) h->dialup = 1; if (xmh_item(hwalk, XMH_FLAG_NOSSLCERT)) h->nosslcert = 1; if (xmh_item(hwalk, XMH_FLAG_LDAPFAILYELLOW)) h->ldapsearchfailyellow = 1; if (xmh_item(hwalk, XMH_FLAG_HIDEHTTP)) h->hidehttp = 1; p = xmh_item(hwalk, XMH_SSLDAYS); if (p) sscanf(p, "%d:%d", &h->sslwarndays, &h->sslalarmdays); p = xmh_item(hwalk, XMH_SSLMINBITS); if (p) h->mincipherbits = atoi(p); p = xmh_item(hwalk, XMH_DEPENDS); if (p) h->deptests = p; p = xmh_item(hwalk, XMH_LDAPLOGIN); if (p) { h->ldapuser = strdup(p); h->ldappasswd = (strchr(h->ldapuser, ':')); if (h->ldappasswd) { *h->ldappasswd = '\0'; h->ldappasswd++; } } p = xmh_item(hwalk, XMH_DESCRIPTION); if (p) { h->hosttype = strdup(p); p = strchr(h->hosttype, ':'); if (p) *p = '\0'; } testspec = xmh_item_walk(hwalk); while (testspec) { service_t *s = NULL; int dialuptest = 0, reversetest = 0, silenttest = 0, sendasdata = 0; char *srcip = NULL; int alwaystruetest = (xmh_item(hwalk, XMH_FLAG_NOCLEAR) != NULL); if (xmh_item_idx(testspec) == -1) { /* Test prefixes: * - '?' denotes dialup test, i.e. report failures as clear. * - '|' denotes reverse test, i.e. service should be DOWN. * - '~' denotes test that ignores ping result (normally, * TCP tests are reported CLEAR if ping check fails; * with this flag report their true status) */ if (*testspec == '?') { dialuptest=1; testspec++; } if (*testspec == '!') { reversetest=1; testspec++; } if (*testspec == '~') { alwaystruetest=1; testspec++; } if (pingtest && argnmatch(testspec, pingtest->testname)) { char *p; /* * Ping/conn test. Save any modifier flags for later use. */ ping_dialuptest = dialuptest; ping_reversetest = reversetest; p = strchr(testspec, '='); if (p) { char *ips; /* Extra ping tests - save them for later */ h->extrapings = (extraping_t *)malloc(sizeof(extraping_t)); h->extrapings->iplist = NULL; if (argnmatch(p, "=worst,")) { h->extrapings->matchtype = MULTIPING_WORST; ips = strdup(p+7); } else if (argnmatch(p, "=best,")) { h->extrapings->matchtype = MULTIPING_BEST; ips = strdup(p+6); } else { h->extrapings->matchtype = MULTIPING_BEST; ips = strdup(p+1); } do { ipping_t *newping = (ipping_t *)malloc(sizeof(ipping_t)); newping->ip = ips; newping->open = 0; newping->banner = newstrbuffer(0); newping->next = h->extrapings->iplist; h->extrapings->iplist = newping; ips = strchr(ips, ','); if (ips) { *ips = '\0'; ips++; } } while (ips && (*ips)); } s = NULL; /* Don't add the test now - ping is special (enabled by default) */ } else if ((argnmatch(testspec, "ldap://")) || (argnmatch(testspec, "ldaps://"))) { /* * LDAP test. This uses ':' a lot, so save it here. */ #ifdef HAVE_LDAP s = ldaptest; add_url_to_dns_queue(testspec); #else errprintf("Host %s: ldap test requested, but xymonnet was built with no ldap support\n", xmh_item(hwalk, XMH_HOSTNAME)); #endif } else if ((strcmp(testspec, "http") == 0) || (strcmp(testspec, "https") == 0)) { errprintf("Host %s: http/https tests requires a full URL\n", xmh_item(hwalk, XMH_HOSTNAME)); } else if ( argnmatch(testspec, "http") || argnmatch(testspec, "content=http") || argnmatch(testspec, "cont;http") || argnmatch(testspec, "cont=") || argnmatch(testspec, "nocont;http") || argnmatch(testspec, "nocont=") || argnmatch(testspec, "post;http") || argnmatch(testspec, "post=") || argnmatch(testspec, "nopost;http") || argnmatch(testspec, "nopost=") || argnmatch(testspec, "soap;http") || argnmatch(testspec, "soap=") || argnmatch(testspec, "nosoap;http") || argnmatch(testspec, "nosoap=") || argnmatch(testspec, "type;http") || argnmatch(testspec, "type=") ) { /* HTTP test. */ weburl_t url; decode_url(testspec, &url); if (url.desturl->parseerror || (url.proxyurl && url.proxyurl->parseerror)) { s = NULL; errprintf("Host %s: Invalid URL for http test - ignored: %s\n", xmh_item(hwalk, XMH_HOSTNAME), testspec); } else { s = httptest; if (!url.desturl->ip) add_url_to_dns_queue(testspec); } } else if (argnmatch(testspec, "apache") || argnmatch(testspec, "apache=")) { char *userfmt = "cont=apache;%s;."; char *deffmt = "cont=apache;http://%s/server-status?auto;."; STATIC_SBUF_DEFINE(statusurl); char *userurl; if (statusurl != NULL) xfree(statusurl); userurl = strchr(testspec, '='); if (userurl) { weburl_t url; userurl++; decode_url(userurl, &url); if (url.desturl->parseerror || (url.proxyurl && url.proxyurl->parseerror)) { s = NULL; errprintf("Host %s: Invalid URL for apache test - ignored: %s\n", xmh_item(hwalk, XMH_HOSTNAME), testspec); } else { SBUF_MALLOC(statusurl, strlen(userurl) + strlen(userfmt) + 1); snprintf(statusurl, statusurl_buflen, userfmt, userurl); s = httptest; } } else { char *ip = xmh_item(hwalk, XMH_IP); SBUF_MALLOC(statusurl, strlen(deffmt) + strlen(ip) + 1); snprintf(statusurl, statusurl_buflen, deffmt, ip); s = httptest; } if (s) { testspec = statusurl; add_url_to_dns_queue(testspec); sendasdata = 1; } } else if (argnmatch(testspec, "rpc")) { /* * rpc check via rpcinfo */ s = rpctest; } else if (argnmatch(testspec, "dns=")) { s = dnstest; } else if (argnmatch(testspec, "dig=")) { s = dnstest; } else { /* * Simple TCP connect test. */ char *option; xtreePos_t handle; /* See if there's a source IP */ srcip = strchr(testspec, '@'); if (srcip) { *srcip = '\0'; srcip++; } /* Remove any trailing ":s", ":q", ":Q", ":portnumber" */ option = strchr(testspec, ':'); if (option) { *option = '\0'; option++; } /* Find the service */ handle = xtreeFind(svctree, testspec); s = ((handle == xtreeEnd(svctree)) ? NULL : (service_t *)xtreeData(svctree, handle)); if (option && s) { /* * Check if it is a service with an explicit portnumber. * If it is, then create a new service record named * "SERVICE_PORT" so we can merge tests for this service+port * combination for multiple hosts. * * According to Xymon docs, this type of services must be in * XYMONNETSVCS - so it is known already. */ int specialport = 0; SBUF_DEFINE(specialname); char *opt2 = strrchr(option, ':'); if (opt2) { if (strcmp(opt2, ":s") == 0) { /* option = "portnumber:s" */ silenttest = 1; *opt2 = '\0'; specialport = atoi(option); *opt2 = ':'; } } else if (strcmp(option, "s") == 0) { /* option = "s" */ silenttest = 1; specialport = 0; } else { /* option = "portnumber" */ specialport = atoi(option); } if (specialport) { SBUF_MALLOC(specialname, strlen(s->testname)+10); snprintf(specialname, specialname_buflen,"%s_%d", s->testname, specialport); s = add_service(specialname, specialport, strlen(s->testname), TOOL_CONTEST); xfree(specialname); } } if (s) h->dodns = 1; if (option) *(option-1) = ':'; } if (s) { testitem_t *newtest; anytests = 1; newtest = init_testitem(h, s, srcip, testspec, dialuptest, reversetest, alwaystruetest, silenttest, sendasdata); newtest->next = s->items; s->items = newtest; if (s == httptest) h->firsthttp = newtest; else if (s == ldaptest) { xtreePos_t handle; service_t *s2 = NULL; testitem_t *newtest2; h->firstldap = newtest; /* * Add a plain tcp-connect test for the LDAP service. * We don't want the LDAP library to run amok and do * time-consuming connect retries if the service * is down. */ handle = xtreeFind(svctree, "ldap"); s2 = ((handle == xtreeEnd(svctree)) ? NULL : (service_t *)xtreeData(svctree, handle)); if (s2) { newtest2 = init_testitem(h, s2, NULL, "ldap", 0, 0, 0, 0, 1); newtest2->internal = 1; newtest2->next = s2->items; s2->items = newtest2; newtest->privdata = newtest2; } } } } testspec = xmh_item_walk(NULL); } if (pingtest && !h->noconn) { /* Add the ping check */ testitem_t *newtest; anytests = 1; newtest = init_testitem(h, pingtest, NULL, NULL, ping_dialuptest, ping_reversetest, 1, 0, 0); newtest->next = pingtest->items; pingtest->items = newtest; h->dodns = 1; } /* * Setup badXXX values. * * We need to do this last, because the testitem_t records do * not exist until the test has been created. * * So after parsing the badFOO tag, we must find the testitem_t * record created earlier for this test (it may not exist). */ testspec = xmh_item_walk(hwalk); while (testspec) { char *testname, *timespec, *badcounts; int badclear, badyellow, badred; int inscope; testitem_t *twalk; service_t *swalk; if (strncmp(testspec, "bad", 3) != 0) { /* Not a bad* tag - skip it */ testspec = xmh_item_walk(NULL); continue; } badtagsused = 1; badclear = badyellow = badred = 0; inscope = 1; testname = testspec+strlen("bad"); badcounts = strchr(testspec, ':'); if (badcounts) { if (sscanf(badcounts, ":%d:%d:%d", &badclear, &badyellow, &badred) != 3) { errprintf("Host %s: Incorrect 'bad' counts: '%s'\n", xmh_item(hwalk, XMH_HOSTNAME), badcounts); badcounts = NULL; } } timespec = strchr(testspec, '-'); if (timespec) inscope = periodcoversnow(timespec); if (strlen(testname) && badcounts && inscope) { char *p; xtreePos_t handle; twalk = NULL; p = strchr(testname, ':'); if (p) *p = '\0'; handle = xtreeFind(svctree, testname); swalk = ((handle == xtreeEnd(svctree)) ? NULL : (service_t *)xtreeData(svctree, handle)); if (p) *p = ':'; if (swalk) { if (swalk == httptest) twalk = h->firsthttp; else if (swalk == ldaptest) twalk = h->firstldap; else for (twalk = swalk->items; (twalk && (twalk->host != h)); twalk = twalk->next) ; } if (twalk) { twalk->badtest[0] = badclear; twalk->badtest[1] = badyellow; twalk->badtest[2] = badred; } else { dbgprintf("No test for badtest spec host=%s, test=%s\n", h->hostname, testname); } } testspec = xmh_item_walk(NULL); } if (anytests) { xtreeStatus_t res; /* * Check for a duplicate host def. Causes all sorts of funny problems. * However, don't drop the second definition - to do this, we will have * to clean up the testitem lists as well, or we get crashes when * tests belong to a non-existing host. */ res = xtreeAdd(testhosttree, h->hostname, h); if (res == XTREE_STATUS_DUPLICATE_KEY) { errprintf("Host %s appears twice in hosts.cfg! This may cause strange results\n", h->hostname); } strncpy(h->ip, xmh_item(hwalk, XMH_IP), sizeof(h->ip)); if (!h->testip && (dnsmethod != IP_ONLY)) add_host_to_dns_queue(h->hostname); } else { /* No network tests for this host, so ignore it */ dbgprintf("Did not find any network tests for host %s\n", h->hostname); xfree(h); notesthostcount++; } } if (badtagsused) { errprintf("WARNING: The 'bad' syntax has been deprecated, please convert to 'delayred' and/or 'delayyellow' tags\n"); } return; } char *ip_to_test(testedhost_t *h) { char *dnsresult; int nullip = (strcmp(h->ip, "0.0.0.0") == 0); if (!nullip && (h->testip || (dnsmethod == IP_ONLY))) { /* Already have the IP setup */ } else if (h->dodns) { dnsresult = dnsresolve(h->hostname); if (dnsresult) { strncpy(h->ip, dnsresult, sizeof(h->ip)); } else if ((dnsmethod == DNS_THEN_IP) && !nullip) { /* Already have the IP setup */ } else { char msg[512]; /* Cannot resolve hostname */ h->dnserror = 1; /* Make this a warning rather than an error errprintf("xymonnet: Cannot resolve IP for host %s\n", h->hostname); */ snprintf(msg, sizeof(msg), "xymonnet: Cannot resolve IP for host %s\n", h->hostname); if (warnbuf == NULL) { SBUF_MALLOC(warnbuf, 8192); *warnbuf = '\0'; } else if ((strlen(warnbuf) + strlen(msg)) > warnbuf_buflen) { SBUF_REALLOC(warnbuf, warnbuf_buflen + 8192); } strncat(warnbuf, msg, (warnbuf_buflen - strlen(warnbuf))); } } return h->ip; } void load_ping_status(void) { FILE *statusfd; char statusfn[PATH_MAX]; char l[MAX_LINE_LEN]; char host[MAX_LINE_LEN]; int downcount; time_t downstart; xtreePos_t handle; testedhost_t *h; snprintf(statusfn, sizeof(statusfn), "%s/ping.%s.status", xgetenv("XYMONTMP"), location); statusfd = fopen(statusfn, "r"); if (statusfd == NULL) return; while (fgets(l, sizeof(l), statusfd)) { unsigned int uidownstart; if (sscanf(l, "%s %d %u", host, &downcount, &uidownstart) == 3) { downstart = uidownstart; handle = xtreeFind(testhosttree, host); if (handle != xtreeEnd(testhosttree)) { h = (testedhost_t *)xtreeData(testhosttree, handle); if (!h->noping && !h->noconn) { h->downcount = downcount; h->downstart = downstart; } } } } fclose(statusfd); } void save_ping_status(void) { FILE *statusfd; char statusfn[PATH_MAX]; testitem_t *t; int didany = 0; snprintf(statusfn, sizeof(statusfn), "%s/ping.%s.status", xgetenv("XYMONTMP"), location); statusfd = fopen(statusfn, "w"); if (statusfd == NULL) return; for (t=pingtest->items; (t); t = t->next) { if (t->host->downcount) { fprintf(statusfd, "%s %d %u\n", t->host->hostname, t->host->downcount, (unsigned int)t->host->downstart); didany = 1; t->host->repeattest = ((getcurrenttime(NULL) - t->host->downstart) < frequenttestlimit); } } fclose(statusfd); if (!didany) unlink(statusfn); } void load_test_status(service_t *test) { FILE *statusfd; char statusfn[PATH_MAX]; char l[MAX_LINE_LEN]; char host[MAX_LINE_LEN]; int downcount; time_t downstart; xtreePos_t handle; testedhost_t *h; testitem_t *walk; snprintf(statusfn, sizeof(statusfn), "%s/%s.%s.status", xgetenv("XYMONTMP"), test->testname, location); statusfd = fopen(statusfn, "r"); if (statusfd == NULL) return; while (fgets(l, sizeof(l), statusfd)) { unsigned int uidownstart; if (sscanf(l, "%s %d %u", host, &downcount, &uidownstart) == 3) { downstart = uidownstart; handle = xtreeFind(testhosttree, host); if (handle != xtreeEnd(testhosttree)) { h = (testedhost_t *)xtreeData(testhosttree, handle); if (test == httptest) walk = h->firsthttp; else if (test == ldaptest) walk = h->firstldap; else for (walk = test->items; (walk && (walk->host != h)); walk = walk->next) ; if (walk) { walk->downcount = downcount; walk->downstart = downstart; } } } } fclose(statusfd); } void save_test_status(service_t *test) { FILE *statusfd; char statusfn[PATH_MAX]; testitem_t *t; int didany = 0; snprintf(statusfn, sizeof(statusfn), "%s/%s.%s.status", xgetenv("XYMONTMP"), test->testname, location); statusfd = fopen(statusfn, "w"); if (statusfd == NULL) return; for (t=test->items; (t); t = t->next) { if (t->downcount) { fprintf(statusfd, "%s %d %u\n", t->host->hostname, t->downcount, (unsigned int)t->downstart); didany = 1; t->host->repeattest = ((getcurrenttime(NULL) - t->downstart) < frequenttestlimit); } } fclose(statusfd); if (!didany) unlink(statusfn); } void save_frequenttestlist(int argc, char *argv[]) { FILE *fd; char fn[PATH_MAX]; xtreePos_t handle; testedhost_t *h; int didany = 0; int i; snprintf(fn, sizeof(fn), "%s/frequenttests.%s", xgetenv("XYMONTMP"), location); fd = fopen(fn, "w"); if (fd == NULL) return; for (i=1; (irepeattest) { fprintf(fd, "%s ", h->hostname); didany = 1; } } fclose(fd); if (!didany) unlink(fn); } void run_nslookup_service(service_t *service) { testitem_t *t; char *lookup; for (t=service->items; (t); t = t->next) { if (!t->host->dnserror) { if (t->testspec && (lookup = strchr(t->testspec, '='))) { lookup++; } else { lookup = t->host->hostname; } t->open = (dns_test_server(ip_to_test(t->host), lookup, t->banner) == 0); } } } void run_ntp_service(service_t *service) { testitem_t *t; char cmd[PATH_MAX+1024]; char *p; char cmdpath[PATH_MAX]; int use_sntp = 0; p = getenv("SNTP"); /* Plain "getenv" as we want to know if it's unset */ use_sntp = (p != NULL); strncpy(cmdpath, (use_sntp ? xgetenv("SNTP") : xgetenv("NTPDATE")), sizeof(cmdpath)); for (t=service->items; (t); t = t->next) { /* Do not run NTP test if host does not resolve in DNS or is down */ if (!t->host->dnserror && !t->host->pingerror) { if (use_sntp) { snprintf(cmd, sizeof(cmd), "%s %s -d %d %s 2>&1", cmdpath, xgetenv("SNTPOPTS"), extcmdtimeout-1, ip_to_test(t->host)); } else { snprintf(cmd, sizeof(cmd), "%s %s %s 2>&1", cmdpath, xgetenv("NTPDATEOPTS"), ip_to_test(t->host)); } t->open = (run_command(cmd, "no server suitable for synchronization", t->banner, 1, extcmdtimeout) == 0); } } } void run_rpcinfo_service(service_t *service) { testitem_t *t; char cmd[PATH_MAX+1024]; char *p; char cmdpath[PATH_MAX]; p = xgetenv("RPCINFO"); strncpy(cmdpath, (p ? p : "rpcinfo"), sizeof(cmdpath)); for (t=service->items; (t); t = t->next) { /* Do not run RPCINFO test if host does not resolve in DNS or is down */ if (!t->host->dnserror && (t->host->downcount == 0) && !t->host->pingerror) { snprintf(cmd, sizeof(cmd), "%s -p %s 2>&1", cmdpath, ip_to_test(t->host)); t->open = (run_command(cmd, NULL, t->banner, 1, extcmdtimeout) == 0); } } } int start_ping_service(service_t *service) { testitem_t *t; char *cmd; char **cmdargs; int pfd[2]; int i; void *iptree; xtreePos_t handle; /* We build a tree of the IP's to test, so we only test each IP once */ iptree = xtreeNew(strcmp); for (t=service->items; (t); t = t->next) { char *rec; char ip[IP_ADDR_STRLEN+1]; if (t->host->dnserror || t->host->noping) continue; strncpy(ip, ip_to_test(t->host), sizeof(ip)); handle = xtreeFind(iptree, ip); if (handle == xtreeEnd(iptree)) { rec = strdup(ip); xtreeAdd(iptree, rec, rec); } if (t->host->extrapings) { ipping_t *walk; for (walk = t->host->extrapings->iplist; (walk); walk = walk->next) { handle = xtreeFind(iptree, walk->ip); if (handle == xtreeEnd(iptree)) { rec = strdup(walk->ip); xtreeAdd(iptree, rec, rec); } } } } /* * The idea here is to run ping in a separate process, in parallel * with some other time-consuming task (the TCP network tests). * We cannot use the simple "popen()/pclose()" interface, because * a) ping doesn't start the tests until EOF is reached on stdin * b) EOF on stdin happens with pclose(), but it will also wait * for the process to finish. * * Therefore this slightly more complex solution, which in essence * forks a new process running "xymonping 2>&1 1>$XYMONTMP/ping.$$" * The output is then picked up by the finish_ping_service(). */ pingcount = 0; pingpids = calloc(pingchildcount, sizeof(pid_t)); SBUF_MALLOC(pingcmd, strlen(xgetenv("FPING")) + strlen(xgetenv("FPINGOPTS")) + 2); snprintf(pingcmd, pingcmd_buflen, "%s %s", xgetenv("FPING"), xgetenv("FPINGOPTS")); snprintf(pinglog, sizeof(pinglog), "%s/ping-stdout.%lu", xgetenv("XYMONTMP"), (unsigned long)getpid()); snprintf(pingerrlog, sizeof(pingerrlog), "%s/ping-stderr.%lu", xgetenv("XYMONTMP"), (unsigned long)getpid()); /* Setup command line and arguments */ cmdargs = setup_commandargs(pingcmd, &cmd); for (i=0; (i < pingchildcount); i++) { /* Get a pipe FD */ if (pipe(pfd) == -1) { errprintf("Could not create pipe for xymonping\n"); return -1; } /* Now fork off the ping child-process */ pingpids[i] = fork(); if (pingpids[i] < 0) { errprintf("Could not fork() the ping child\n"); return -1; } else if (pingpids[i] == 0) { /* * child must have * - stdin fed from the parent * - stdout going to a file * - stderr going to another file. This is important, as * putting it together with stdout will wreak havoc when * we start parsing the output later on. We could just * dump it to /dev/null, but it might be useful to see * what went wrong. */ int outfile, errfile; snprintf(pinglog+strlen(pinglog), (sizeof(pinglog) - strlen(pinglog)), ".%02d", i); snprintf(pingerrlog+strlen(pingerrlog), (sizeof(pingerrlog) - strlen(pingerrlog)), ".%02d", i); outfile = open(pinglog, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (outfile == -1) errprintf("Cannot create file %s : %s\n", pinglog, strerror(errno)); errfile = open(pingerrlog, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (errfile == -1) errprintf("Cannot create file %s : %s\n", pingerrlog, strerror(errno)); if ((outfile == -1) || (errfile == -1)) { /* Ouch - cannot create our output files. Abort. */ exit(98); } dup2(pfd[0], STDIN_FILENO); dup2(outfile, STDOUT_FILENO); dup2(errfile, STDERR_FILENO); close(pfd[0]); close(pfd[1]); close(outfile); close(errfile); execvp(cmd, cmdargs); /* Should never go here ... just kill the child */ fprintf(stderr, "Command '%s' failed: %s\n", cmd, strerror(errno)); exit(99); } else { /* parent */ char ip[IP_ADDR_STRLEN+1]; /* Must have room for the \n at the end also */ int hnum, feederror = 0; close(pfd[0]); /* Feed the IP's to test to the child */ for (handle = xtreeFirst(iptree), hnum = 0; ((feederror == 0) && (handle != xtreeEnd(iptree))); handle = xtreeNext(iptree, handle), hnum++) { if ((hnum % pingchildcount) != i) continue; snprintf(ip, sizeof(ip), "%s\n", xtreeKey(iptree, handle)); if (write(pfd[1], ip, strlen(ip)) != strlen(ip)) { errprintf("Cannot feed IP to ping tool: %s\n", strerror(errno)); feederror = 1; continue; } pingcount++; } close(pfd[1]); /* This is when ping starts doing tests */ } } for (handle = xtreeFirst(iptree); handle != xtreeEnd(iptree); handle = xtreeNext(iptree, handle)) { char *rec = xtreeKey(iptree, handle); xfree(rec); } xtreeDestroy(iptree); return 0; } int finish_ping_service(service_t *service) { testitem_t *t; FILE *logfd; char *p; char l[MAX_LINE_LEN]; char pingip[MAX_LINE_LEN]; int ip1, ip2, ip3, ip4; int pingstatus, failed = 0, i; char fn[PATH_MAX]; /* Load status of previously failed tests */ load_ping_status(); /* * Wait for the ping child to finish. * If we're lucky, it will be done already since it has run * while we were doing tcp tests. */ for (i = 0; (i < pingchildcount); i++) { waitpid(pingpids[i], &pingstatus, 0); switch (WEXITSTATUS(pingstatus)) { case 0: /* All hosts reachable */ case 1: /* Some hosts unreachable */ case 2: /* Some IP's not found (should not happen) */ break; case 3: /* Bad command-line args, or not suid-root */ failed = 1; errprintf("Execution of '%s' failed - program not suid root?\n", pingcmd); break; case 98: failed = 1; errprintf("xymonping child could not create outputfiles in %s\n", xgetenv("XYMONTMP")); break; case 99: failed = 1; errprintf("Could not run the command '%s' (exec failed)\n", pingcmd); break; default: failed = 1; errprintf("Execution of '%s' failed with error-code %d\n", pingcmd, WEXITSTATUS(pingstatus)); } #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) /* Ignore gcc warnings about truncating filenames when adding a number */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-truncation" #endif // __GNUC__ /* Open the new ping result file */ snprintf(fn, sizeof(fn), "%s.%02d", pinglog, i); logfd = fopen(fn, "r"); if (logfd == NULL) { failed = 1; errprintf("Cannot open ping output file %s\n", fn); } if (!debug) unlink(fn); /* We have an open filehandle, so it's ok to delete the file now */ /* Copy error messages to the Xymon logfile */ snprintf(fn, sizeof(fn), "%s.%02d", pingerrlog, i); if (failed) { FILE *errfd; char buf[1024]; errfd = fopen(fn, "r"); if (errfd && fgets(buf, sizeof(buf), errfd)) { errprintf("%s", buf); } if (errfd) fclose(errfd); } if (!debug) unlink(fn); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif // __GNUC__ if (failed) { /* Flag all ping tests as "undecided" */ bigfailure = 1; for (t=service->items; (t); t = t->next) t->open = -1; } else { /* The test did run, and we have a result-file. Look at it. */ while (fgets(l, sizeof(l), logfd)) { p = strchr(l, '\n'); if (p) *p = '\0'; if (sscanf(l, "%d.%d.%d.%d ", &ip1, &ip2, &ip3, &ip4) == 4) { snprintf(pingip, sizeof(pingip), "%d.%d.%d.%d", ip1, ip2, ip3, ip4); /* * Need to loop through all testitems - there may be multiple entries for * the same IP-address. */ for (t=service->items; (t); t = t->next) { if (strcmp(t->host->ip, pingip) == 0) { if (t->open) dbgprintf("More than one ping result for %s\n", pingip); t->open = (strstr(l, "is alive") != NULL); t->banner = dupstrbuffer(l); } if (t->host->extrapings) { ipping_t *walk; for (walk = t->host->extrapings->iplist; (walk); walk = walk->next) { if (strcmp(walk->ip, pingip) == 0) { if (t->open) dbgprintf("More than one ping result for %s\n", pingip); walk->open = (strstr(l, "is alive") != NULL); walk->banner = dupstrbuffer(l); } } } } } } } if (logfd) fclose(logfd); } /* * Handle the router dependency stuff. I.e. for all hosts * where the ping test failed, go through the list of router * dependencies and if one of the dependent hosts also has * a failed ping test, point the dependency there. */ for (t=service->items; (t); t = t->next) { if (!t->open && t->host->routerdeps) { testitem_t *router; strncpy(l, t->host->routerdeps, sizeof(l)); p = strtok(l, ","); while (p && (t->host->deprouterdown == NULL)) { for (router=service->items; (router && (strcmp(p, router->host->hostname) != 0)); router = router->next) ; if (router && !router->open) t->host->deprouterdown = router->host; p = strtok(NULL, ","); } } } return 0; } int decide_color(service_t *service, char *svcname, testitem_t *test, int failgoesclear, char *cause) { int color = COL_GREEN; int countasdown = 0; char *deptest = NULL; *cause = '\0'; if (service == pingtest) { /* * "noconn" is handled elsewhere. * "noping" always sends back a status "clear". * If DNS error, return red and count as down. */ if (test->open == -1) { /* Failed to run the ping utility. */ strcpy(cause, "Xymon system failure"); return COL_CLEAR; } else if (test->host->noping) { /* Ping test disabled - go "clear". End of story. */ strcpy(cause, "Ping test disabled (noping)"); return COL_CLEAR; } else if (test->host->dnserror) { strcpy(cause, "DNS lookup failure"); color = COL_RED; countasdown = 1; } else { if (test->host->extrapings == NULL) { /* Red if (open=0, reverse=0) or (open=1, reverse=1) */ if ((test->open + test->reverse) != 1) { sprintf(cause, "Host %s respond to ping", (test->open ? "does" : "does not")); color = COL_RED; countasdown = 1; } } else { /* Host with many pings */ int totalcount = 1; int okcount = test->open; ipping_t *walk; for (walk = test->host->extrapings->iplist; (walk); walk = walk->next) { if (walk->open) okcount++; totalcount++; } switch (test->host->extrapings->matchtype) { case MULTIPING_BEST: if (okcount == 0) { color = COL_RED; countasdown = 1; sprintf(cause, "Host does not respond to ping on any of %d IP's", totalcount); } break; case MULTIPING_WORST: if (okcount < totalcount) { color = COL_RED; countasdown = 1; sprintf(cause, "Host responds to ping on %d of %d IP's", okcount, totalcount); } break; } } } /* Handle the "route" tag dependencies. */ if ((color == COL_RED) && test->host->deprouterdown) { char *routertext; routertext = test->host->deprouterdown->hosttype; if (routertext == NULL) routertext = xgetenv("XYMONROUTERTEXT"); if (routertext == NULL) routertext = "router"; strcat(cause, "\nIntermediate "); strcat(cause, routertext); strcat(cause, " down "); color = COL_YELLOW; } /* Set pingerror for later use by NTP and RPCINFO tests */ test->host->pingerror = (color == COL_RED ? 1 : 0); /* Handle "badconn" */ if ((color == COL_RED) && (test->host->downcount < test->host->badconn[2])) { if (test->host->downcount >= test->host->badconn[1]) color = COL_YELLOW; else if (test->host->downcount >= test->host->badconn[0]) color = COL_CLEAR; else color = COL_GREEN; } /* Run traceroute , but not on dialup or reverse-test hosts */ if ((color == COL_RED) && test->host->dotrace && !test->host->dialup && !test->reverse && !test->dialup) { char cmd[PATH_MAX]; if (getenv("TRACEROUTEOPTS")) { /* post 4.3.21 */ snprintf(cmd, sizeof(cmd), "%s %s %s 2>&1", xgetenv("TRACEROUTE"), xgetenv("TRACEROUTEOPTS"), test->host->ip); } else { snprintf(cmd, sizeof(cmd), "%s %s 2>&1", xgetenv("TRACEROUTE"), test->host->ip); } test->host->traceroute = newstrbuffer(0); run_command(cmd, NULL, test->host->traceroute, 0, extcmdtimeout); } } else { /* TCP test */ if (test->host->dnserror) { strcpy(cause, "DNS lookup failure"); color = COL_RED; countasdown = 1; } else { if (test->reverse) { /* * Reverse tests go RED when open. * If not open, they may go CLEAR if the ping test failed */ if (test->open) { strcpy(cause, "Service responds when it should not"); color = COL_RED; countasdown = 1; } else if (failgoesclear && (test->host->downcount != 0) && !test->alwaystrue) { strcpy(cause, "Host appears to be down"); color = COL_CLEAR; countasdown = 0; } } else { if (!test->open) { if (failgoesclear && (test->host->downcount != 0) && !test->alwaystrue) { strcpy(cause, "Host appears to be down"); color = COL_CLEAR; countasdown = 0; } else { tcptest_t *tcptest = (tcptest_t *)test->privdata; strcpy(cause, "Service unavailable"); if (tcptest) { switch (tcptest->errcode) { case CONTEST_ETIMEOUT: strcat(cause, " (connect timeout)"); break; case CONTEST_ENOCONN : strcat(cause, " ("); strcat(cause, strerror(tcptest->connres)); strcat(cause, ")"); break; case CONTEST_EDNS : strcat(cause, " (DNS error)"); break; case CONTEST_EIO : strcat(cause, " (I/O error)"); break; case CONTEST_ESSL : strcat(cause, " (SSL error)"); break; } } color = COL_RED; countasdown = 1; } } else { tcptest_t *tcptest = (tcptest_t *)test->privdata; /* Check if we got the expected data */ if (checktcpresponse && (service->toolid == TOOL_CONTEST) && !tcp_got_expected((tcptest_t *)test->privdata)) { strcpy(cause, "Unexpected service response"); color = respcheck_color; countasdown = 1; } /* Check that other transport issues didn't occur (like SSL) */ if (tcptest && (tcptest->errcode != CONTEST_ENOERROR)) { switch (tcptest->errcode) { case CONTEST_ETIMEOUT : strcpy(cause, "Service listening but unavailable (connect timeout)"); color = COL_RED; countasdown = 1; break; case CONTEST_ENOCONN : strcpy(cause, "Service listening but unavailable ("); strcat(cause, strerror(tcptest->connres)); strcat(cause, ")"); color = COL_RED; countasdown = 1; break; case CONTEST_EDNS : strcpy(cause, "Service listening but unavailable (DNS error)"); color = COL_RED; countasdown = 1; break; case CONTEST_EIO : strcpy(cause, "Service listening but unavailable (I/O error)"); color = COL_RED; countasdown = 1; break; case CONTEST_ESSL : strcpy(cause, "Service listening but unavailable (SSL error)"); color = COL_RED; countasdown = 1; break; default : /* Should not get here */ errprintf("-> TCPtest error %d seen on open connection for %s.%s\n", tcptest->errcode, test->host->hostname, test->service->testname); color = COL_YELLOW; break; } // color = COL_RED; countasdown = 1; } } } } /* Handle test dependencies */ if ( failgoesclear && (color == COL_RED) && !test->alwaystrue && (deptest = deptest_failed(test->host, test->service->testname)) ) { strcpy(cause, deptest); color = COL_CLEAR; } /* Handle the "badtest" stuff for other tests */ if ((color == COL_RED) && (test->downcount < test->badtest[2])) { if (test->downcount >= test->badtest[1]) color = COL_YELLOW; else if (test->downcount >= test->badtest[0]) color = COL_CLEAR; else color = COL_GREEN; } } /* Dialup hosts and dialup tests report red as clear */ if ( ((color == COL_RED) || (color == COL_YELLOW)) && (test->host->dialup || test->dialup) && !test->reverse) { strcat(cause, "\nDialup host or service"); color = COL_CLEAR; countasdown = 0; } /* If a NOPAGENET service, downgrade RED to YELLOW */ if (color == COL_RED) { SBUF_DEFINE(nopagename); /* Check if this service is a NOPAGENET service. */ SBUF_MALLOC(nopagename, strlen(svcname)+3); snprintf(nopagename, nopagename_buflen, ",%s,", svcname); if (strstr(nonetpage, nopagename) != NULL) color = COL_YELLOW; xfree(nopagename); } if (service == pingtest) { if (countasdown) { test->host->downcount++; if (test->host->downcount == 1) test->host->downstart = getcurrenttime(NULL); } else test->host->downcount = 0; } else { if (countasdown) { test->downcount++; if (test->downcount == 1) test->downstart = getcurrenttime(NULL); } else test->downcount = 0; } return color; } void send_results(service_t *service, int failgoesclear) { testitem_t *t; int color; char msgline[4096]; char msgtext[4096]; char causetext[1024]; char *svcname; svcname = strdup(service->testname); if (service->namelen) svcname[service->namelen] = '\0'; dbgprintf("Sending results for service %s\n", svcname); for (t=service->items; (t); t = t->next) { char flags[10]; int i; if (t->internal) continue; i = 0; flags[i++] = (t->open ? 'O' : 'o'); flags[i++] = (t->reverse ? 'R' : 'r'); flags[i++] = ((t->dialup || t->host->dialup) ? 'D' : 'd'); flags[i++] = (t->alwaystrue ? 'A' : 'a'); flags[i++] = (t->silenttest ? 'S' : 's'); flags[i++] = (t->host->testip ? 'T' : 't'); flags[i++] = (t->host->dodns ? 'L' : 'l'); flags[i++] = (t->host->dnserror ? 'E' : 'e'); flags[i++] = '\0'; color = decide_color(service, svcname, t, failgoesclear, causetext); init_status(color); if (dosendflags) snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s %s %s ", validity, commafy(t->host->hostname), svcname, colorname(color), flags, timestamp, svcname, ( ((color == COL_RED) || (color == COL_YELLOW)) ? "NOT ok" : "ok")); else snprintf(msgline, sizeof(msgline), "status %s.%s %s %s %s %s ", commafy(t->host->hostname), svcname, colorname(color), timestamp, svcname, ( ((color == COL_RED) || (color == COL_YELLOW)) ? "NOT ok" : "ok")); if (t->host->dnserror) { strncat(msgline, ": DNS lookup failed", (sizeof(msgline) - strlen(msgline))); snprintf(msgtext, sizeof(msgtext), "\nUnable to resolve hostname %s\n\n", t->host->hostname); } else { snprintf(msgtext, sizeof(msgtext), "\nService %s on %s is ", svcname, t->host->hostname); switch (color) { case COL_GREEN: strncat(msgtext, "OK ", (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, (t->reverse ? "(down)" : "(up)"), (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, "\n", (sizeof(msgtext) - strlen(msgtext))); break; case COL_RED: case COL_YELLOW: if ((service == pingtest) && t->host->deprouterdown) { char *routertext; routertext = t->host->deprouterdown->hosttype; if (routertext == NULL) routertext = xgetenv("XYMONROUTERTEXT"); if (routertext == NULL) routertext = "router"; strncat(msgline, ": Intermediate ", (sizeof(msgline) - strlen(msgline))); strncat(msgline, routertext, (sizeof(msgline) - strlen(msgline))); strncat(msgline, " down", (sizeof(msgline) - strlen(msgline))); snprintf(msgtext+strlen(msgtext), (sizeof(msgtext) - strlen(msgtext)), "%s.\nThe %s %s (IP:%s) is not reachable, causing this host to be unreachable.\n", failtext, routertext, ((testedhost_t *)t->host->deprouterdown)->hostname, ((testedhost_t *)t->host->deprouterdown)->ip); } else { snprintf(msgtext+strlen(msgtext), (sizeof(msgtext) - strlen(msgtext)), "%s : %s\n", failtext, causetext); } break; case COL_CLEAR: strncat(msgtext, "OK\n", (sizeof(msgtext) - strlen(msgtext))); if (service == pingtest) { if (t->host->deprouterdown) { char *routertext; routertext = t->host->deprouterdown->hosttype; if (routertext == NULL) routertext = xgetenv("XYMONROUTERTEXT"); if (routertext == NULL) routertext = "router"; strncat(msgline, ": Intermediate ", (sizeof(msgline) - strlen(msgline))); strncat(msgline, routertext, (sizeof(msgline) - strlen(msgline))); strncat(msgline, " down", (sizeof(msgline) - strlen(msgline))); strncat(msgtext, "\nThe ", (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, routertext, (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, " ", (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, ((testedhost_t *)t->host->deprouterdown)->hostname, (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, " (IP:", (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, ((testedhost_t *)t->host->deprouterdown)->ip, (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, ") is not reachable, causing this host to be unreachable.\n", (sizeof(msgtext) - strlen(msgtext))); } else if (t->host->noping) { strncat(msgline, ": Disabled", (sizeof(msgline) - strlen(msgline))); strncat(msgtext, "Ping check disabled (noping)\n", (sizeof(msgtext) - strlen(msgtext))); } else if (t->host->dialup) { strncat(msgline, ": Disabled (dialup host)", (sizeof(msgline) - strlen(msgline))); strncat(msgtext, "Dialup host\n", (sizeof(msgtext) - strlen(msgtext))); } else if (t->open == -1) { strncat(msgline, ": System failure of the ping test", (sizeof(msgline) - strlen(msgline))); strncat(msgtext, "Xymon system error\n", (sizeof(msgtext) - strlen(msgtext))); } /* "clear" due to badconn: no extra text */ } else { /* Non-ping test clear: Dialup test or failed ping */ strncat(msgline, ": Ping failed, or dialup host/service", (sizeof(msgline) - strlen(msgline))); strncat(msgtext, "Dialup host/service, or test depends on another failed test\n", (sizeof(msgtext) - strlen(msgtext))); strncat(msgtext, causetext, (sizeof(msgtext) - strlen(msgtext))); } break; } strncat(msgtext, "\n", (sizeof(msgtext) - strlen(msgtext))); } strncat(msgline, "\n", (sizeof(msgline) - strlen(msgline))); addtostatus(msgline); addtostatus(msgtext); if ((service == pingtest) && t->host->downcount) { snprintf(msgtext, sizeof(msgtext), "\nSystem unreachable for %d poll periods (%u seconds)\n", t->host->downcount, (unsigned int)(getcurrenttime(NULL) - t->host->downstart)); addtostatus(msgtext); } if (STRBUFLEN(t->banner)) { if (service == pingtest) { snprintf(msgtext, sizeof(msgtext), "\n&%s %s\n", colorname(t->open ? COL_GREEN : COL_RED), STRBUF(t->banner)); addtostatus(msgtext); if (t->host->extrapings) { ipping_t *walk; for (walk = t->host->extrapings->iplist; (walk); walk = walk->next) { if (STRBUFLEN(walk->banner)) { snprintf(msgtext, sizeof(msgtext), "&%s %s\n", colorname(walk->open ? COL_GREEN : COL_RED), STRBUF(walk->banner)); addtostatus(msgtext); } } } } else { addtostatus("\n"); addtostrstatus(t->banner); addtostatus("\n"); } } if ((service == pingtest) && t->host->traceroute && (STRBUFLEN(t->host->traceroute) > 0)) { addtostatus("Traceroute results:\n"); addtostrstatus(t->host->traceroute); addtostatus("\n"); } if (t->duration.tv_sec != -1) { snprintf(msgtext, sizeof(msgtext), "\nSeconds: %u.%.9ld\n", (unsigned int)t->duration.tv_sec, t->duration.tv_nsec); addtostatus(msgtext); } addtostatus("\n\n"); finish_status(); } } void send_rpcinfo_results(service_t *service, int failgoesclear) { testitem_t *t; int color; char msgline[2048]; char *msgbuf; char causetext[1024]; msgbuf = (char *)malloc(MSGBUFSIZE); for (t=service->items; (t); t = t->next) { char *wantedrpcsvcs = NULL; char *p; /* First see if the rpcinfo command succeeded */ *msgbuf = '\0'; color = decide_color(service, service->testname, t, failgoesclear, causetext); p = strchr(t->testspec, '='); if (p) wantedrpcsvcs = strdup(p+1); if ((color == COL_GREEN) && STRBUFLEN(t->banner) && wantedrpcsvcs) { char *rpcsvc, *aline; rpcsvc = strtok(wantedrpcsvcs, ","); while (rpcsvc) { struct rpcent *rpcinfo; int svcfound = 0; int aprogram; int aversion; char aprotocol[10]; int aport; rpcinfo = getrpcbyname(rpcsvc); aline = STRBUF(t->banner); while ((!svcfound) && rpcinfo && aline && (*aline != '\0')) { p = strchr(aline, '\n'); if (p) *p = '\0'; if (sscanf(aline, "%d %d %s %d", &aprogram, &aversion, aprotocol, &aport) == 4) { svcfound = (aprogram == rpcinfo->r_number); } aline = p; if (p) { *p = '\n'; aline++; } } if (svcfound) { snprintf(msgline, sizeof(msgline), "&%s Service %s (ID: %d) found on port %d\n", colorname(COL_GREEN), rpcsvc, rpcinfo->r_number, aport); } else if (rpcinfo) { color = COL_RED; snprintf(msgline, sizeof(msgline), "&%s Service %s (ID: %d) NOT found\n", colorname(COL_RED), rpcsvc, rpcinfo->r_number); } else { color = COL_RED; snprintf(msgline, sizeof(msgline), "&%s Unknown RPC service %s\n", colorname(COL_RED), rpcsvc); } strncat(msgbuf, msgline, (MSGBUFSIZE - strlen(msgbuf))); rpcsvc = strtok(NULL, ","); } } if (wantedrpcsvcs) xfree(wantedrpcsvcs); init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s %s %s, %s\n\n", validity, commafy(t->host->hostname), service->testname, colorname(color), timestamp, service->testname, ( ((color == COL_RED) || (color == COL_YELLOW)) ? "NOT ok" : "ok"), causetext); addtostatus(msgline); /* The summary of wanted RPC services */ addtostatus(msgbuf); /* rpcinfo output */ if (t->open) { if (STRBUFLEN(t->banner)) { addtostatus("\n\n"); addtostrstatus(t->banner); } else { snprintf(msgline, sizeof(msgline), "\n\nNo output from rpcinfo -p %s\n", t->host->ip); addtostatus(msgline); } } else { addtostatus("\n\nCould not connect to the portmapper service\n"); if (STRBUFLEN(t->banner)) addtostrstatus(t->banner); } finish_status(); } xfree(msgbuf); } void send_sslcert_status(testedhost_t *host) { int color = -1; xtreePos_t handle; service_t *s; testitem_t *t; char msgline[1024]; strbuffer_t *sslmsg; time_t now = getcurrenttime(NULL); char *certowner; sslmsg = newstrbuffer(0); for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); certowner = s->testname; for (t=s->items; (t); t=t->next) { if ((t->host == host) && t->certinfo && (t->certexpires > 0)) { int sslcolor = COL_GREEN; int ciphercolor = COL_GREEN; int keycolor = COL_GREEN; if (s == httptest) certowner = ((http_data_t *)t->privdata)->url; else if (s == ldaptest) certowner = t->testspec; if (t->certexpires < (now+host->sslwarndays*86400)) sslcolor = COL_YELLOW; if (t->certexpires < (now+host->sslalarmdays*86400)) sslcolor = COL_RED; if (sslcolor > color) color = sslcolor; if (host->mincipherbits && (t->mincipherbits < host->mincipherbits)) ciphercolor = COL_RED; if (ciphercolor > color) color = ciphercolor; if (sslminkeysize > 0) { if ((t->certkeysz > 0) && (t->certkeysz < sslminkeysize)) keycolor = COL_YELLOW; if (keycolor > color) color = keycolor; } if (t->certexpires > now) { snprintf(msgline, sizeof(msgline), "\n&%s SSL certificate for %s expires in %u days\n\n", colorname(sslcolor), certowner, (unsigned int)((t->certexpires - now) / 86400)); } else { snprintf(msgline, sizeof(msgline), "\n&%s SSL certificate for %s expired %u days ago\n\n", colorname(sslcolor), certowner, (unsigned int)((now - t->certexpires) / 86400)); } addtobuffer(sslmsg, msgline); if (host->mincipherbits) { snprintf(msgline, sizeof(msgline), "&%s Minimum available SSL encryption is %d bits (should be %d)\n", colorname(ciphercolor), t->mincipherbits, host->mincipherbits); addtobuffer(sslmsg, msgline); } if (keycolor != COL_GREEN) { snprintf(msgline, sizeof(msgline), "&%s Certificate public key size is less than %d bits\n", colorname(keycolor), sslminkeysize); addtobuffer(sslmsg, msgline); } addtobuffer(sslmsg, "\n"); addtobuffer(sslmsg, t->certinfo); } } } if (color != -1) { /* Send off the sslcert status report */ init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s\n", validity, commafy(host->hostname), ssltestname, colorname(color), timestamp); addtostatus(msgline); addtostrstatus(sslmsg); addtostatus("\n\n"); finish_status(); } freestrbuffer(sslmsg); } int main(int argc, char *argv[]) { xtreePos_t handle; service_t *s; testedhost_t *h; testitem_t *t; int argi; int concurrency = 0; char *pingcolumn = ""; char *egocolumn = NULL; int failgoesclear = 0; /* IPTEST_2_CLEAR_ON_FAILED_CONN */ int dumpdata = 0; int runtimewarn; /* 300 = default TASKSLEEP setting */ int servicedumponly = 0; int pingrunning = 0; int usebackfeedqueue = 0; if (init_ldap_library() != 0) { errprintf("Failed to initialize ldap library\n"); return 1; } if (xgetenv("CONNTEST") && (strcmp(xgetenv("CONNTEST"), "FALSE") == 0)) pingcolumn = NULL; runtimewarn = (xgetenv("TASKSLEEP") ? atol(xgetenv("TASKSLEEP")) : 300); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--timeout=")) { char *p = strchr(argv[argi], '='); p++; timeout = atoi(p); } else if (argnmatch(argv[argi], "--conntimeout=")) { int newtimeout; char *p = strchr(argv[argi], '='); p++; newtimeout = atoi(p); if (newtimeout > timeout) timeout = newtimeout; errprintf("Deprecated option '--conntimeout' should not be used\n"); } else if (argnmatch(argv[argi], "--cmdtimeout=")) { char *p = strchr(argv[argi], '='); p++; extcmdtimeout = atoi(p); } else if (argnmatch(argv[argi], "--concurrency=")) { char *p = strchr(argv[argi], '='); p++; concurrency = atoi(p); } else if (argnmatch(argv[argi], "--dns-timeout=") || argnmatch(argv[argi], "--dns-max-all=")) { char *p = strchr(argv[argi], '='); p++; dnstimeout = atoi(p); } else if (argnmatch(argv[argi], "--dns=")) { char *p = strchr(argv[argi], '='); p++; if (strcmp(p, "only") == 0) dnsmethod = DNS_ONLY; else if (strcmp(p, "ip") == 0) dnsmethod = IP_ONLY; else dnsmethod = DNS_THEN_IP; } else if (strcmp(argv[argi], "--no-ares") == 0) { use_ares_lookup = 0; } else if (argnmatch(argv[argi], "--maxdnsqueue=")) { char *p = strchr(argv[argi], '='); max_dns_per_run = atoi(p+1); } else if (argnmatch(argv[argi], "--dnslog=")) { char *fn = strchr(argv[argi], '='); dnsfaillog = fopen(fn+1, "w"); } else if (argnmatch(argv[argi], "--report=") || (strcmp(argv[argi], "--report") == 0)) { char *p = strchr(argv[argi], '='); if (p) { egocolumn = strdup(p+1); } else egocolumn = "xymonnet"; timing = 1; } else if (strcmp(argv[argi], "--test-untagged") == 0) { testuntagged = 1; } else if (argnmatch(argv[argi], "--frequenttestlimit=")) { char *p = strchr(argv[argi], '='); p++; frequenttestlimit = atoi(p); } else if (argnmatch(argv[argi], "--timelimit=")) { char *p = strchr(argv[argi], '='); p++; runtimewarn = atol(p); } else if (argnmatch(argv[argi], "--huge=")) { char *p = strchr(argv[argi], '='); p++; warnbytesread = atoi(p); } else if (strcmp(argv[argi], "--loadhostsfromxymond") == 0) { loadhostsfromxymond = 1; } /* Options for TCP tests */ else if (strcmp(argv[argi], "--checkresponse") == 0) { checktcpresponse = 1; } else if (argnmatch(argv[argi], "--checkresponse=")) { char *p = strchr(argv[argi], '='); checktcpresponse = 1; respcheck_color = parse_color(p+1); if (respcheck_color == -1) { errprintf("Invalid colorname in '%s' - using yellow\n", argv[argi]); respcheck_color = COL_YELLOW; } } else if (strcmp(argv[argi], "--no-flags") == 0) { dosendflags = 0; } else if (strcmp(argv[argi], "--shuffle") == 0) { shuffletests = 1; } else if (argnmatch(argv[argi], "--source-ip=")) { char *p = strchr(argv[argi], '='); struct in_addr aa; p++; if (inet_aton(p, &aa)) defaultsourceip = strdup(p); else errprintf("Invalid source ip address '%s'\n", argv[argi]); } /* Options for PING tests */ else if (argnmatch(argv[argi], "--ping-tasks=")) { /* Note: must check for this before checking "--ping" option */ char *p = strchr(argv[argi], '='); pingchildcount = atoi(p+1); } else if (argnmatch(argv[argi], "--ping")) { char *p = strchr(argv[argi], '='); if (p) { p++; pingcolumn = p; } else pingcolumn = ""; } else if (strcmp(argv[argi], "--noping") == 0) { pingcolumn = NULL; } else if (strcmp(argv[argi], "--trace") == 0) { dotraceroute = 1; } else if (strcmp(argv[argi], "--notrace") == 0) { dotraceroute = 0; } /* Options for HTTP tests */ else if (argnmatch(argv[argi], "--content=")) { char *p = strchr(argv[argi], '='); contenttestname = strdup(p+1); } else if (strcmp(argv[argi], "--bb-proxy-syntax") == 0) { /* Obey the Big Brother format for http proxy listed as part of the URL */ obeybbproxysyntax = 1; } /* Options for SSL certificates */ else if (argnmatch(argv[argi], "--ssl=")) { char *p = strchr(argv[argi], '='); ssltestname = strdup(p+1); } else if (strcmp(argv[argi], "--no-ssl") == 0) { ssltestname = NULL; } else if (argnmatch(argv[argi], "--sslwarn=")) { char *p = strchr(argv[argi], '='); p++; sslwarndays = atoi(p); } else if (argnmatch(argv[argi], "--sslalarm=")) { char *p = strchr(argv[argi], '='); p++; sslalarmdays = atoi(p); } else if (argnmatch(argv[argi], "--sslbits=")) { char *p = strchr(argv[argi], '='); p++; mincipherbits = atoi(p); } else if (argnmatch(argv[argi], "--validity=")) { char *p = strchr(argv[argi], '='); p++; validity = atoi(p); } else if (argnmatch(argv[argi], "--sslkeysize=")) { char *p = strchr(argv[argi], '='); p++; sslminkeysize = atoi(p); } else if (argnmatch(argv[argi], "--sni=")) { char *p = strchr(argv[argi], '='); p++; snienabled = ( (strcasecmp(p, "yes") == 0) || (strcasecmp(p, "on") == 0) || (strcasecmp(p, "enabled") == 0) || (strcasecmp(p, "true") == 0) || (strcasecmp(p, "1") == 0) ); } else if (strcmp(argv[argi], "--no-cipherlist") == 0) { sslincludecipherlist = 0; } else if (strcmp(argv[argi], "--showallciphers") == 0) { sslshowallciphers = 1; } /* Debugging options */ else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--dump")) { char *p = strchr(argv[argi], '='); if (p) { if (strcmp(p, "=before") == 0) dumpdata = 1; else if (strcmp(p, "=after") == 0) dumpdata = 2; else dumpdata = 3; } else dumpdata = 2; debug = 1; } else if (strcmp(argv[argi], "--no-update") == 0) { dontsendmessages = 1; } else if (strcmp(argv[argi], "--timing") == 0) { timing = 1; } /* Informational options */ else if (strcmp(argv[argi], "--services") == 0) { servicedumponly = 1; } else if (strcmp(argv[argi], "--version") == 0) { printf("xymonnet version %s\n", VERSION); if (ssl_library_version) printf("SSL library : %s\n", ssl_library_version); if (ldap_library_version) printf("LDAP library: %s\n", ldap_library_version); printf("\n"); return 0; } else if ((strcmp(argv[argi], "--help") == 0) || (strcmp(argv[argi], "-?") == 0)) { printf("xymonnet version %s\n\n", VERSION); printf("Usage: %s [options] [host1 host2 host3 ...]\n", argv[0]); printf("General options:\n"); printf(" --timeout=N : Timeout (in seconds) for service tests\n"); printf(" --cmdtimeout=N : Timeout for external commands for testing NTP, RPC and traceroute\n"); printf(" --concurrency=N : Number of tests run in parallel\n"); printf(" --dns-timeout=N : DNS lookups timeout and fail after N seconds [30]\n"); printf(" --dns=[only|ip|standard] : How IP's are decided\n"); printf(" --no-ares : Use the system resolver library for hostname lookups\n"); printf(" --dnslog=FILENAME : Log failed hostname lookups to file FILENAME\n"); printf(" --report[=COLUMNNAME] : Send a status report about the running of xymonnet\n"); printf(" --test-untagged : Include hosts without a NET: tag in the test\n"); printf(" --frequenttestlimit=N : Seconds after detecting failures in which we poll frequently\n"); printf(" --timelimit=N : Warns if the complete test run takes longer than N seconds [TASKSLEEP]\n"); printf("\nOptions for simple TCP service tests:\n"); printf(" --checkresponse : Check response from known services\n"); printf(" --no-flags : Don't send extra xymonnet test flags\n"); printf("\nOptions for PING (connectivity) tests:\n"); printf(" --ping[=COLUMNNAME] : Enable ping checking, default columname is \"conn\"\n"); printf(" --noping : Disable ping checking\n"); printf(" --trace : Run traceroute on all hosts where ping fails\n"); printf(" --notrace : Disable traceroute when ping fails (default)\n"); printf(" --ping-tasks=N : Run N ping tasks in parallel (default N=1)\n"); printf("\nOptions for HTTP/HTTPS (Web) tests:\n"); printf(" --content=COLUMNNAME : Define default columnname for CONTENT checks (content)\n"); printf("\nOptions for SSL certificate tests:\n"); printf(" --ssl=COLUMNNAME : Define columnname for SSL certificate checks (sslcert)\n"); printf(" --no-ssl : Disable SSL certificate check\n"); printf(" --sslwarn=N : Go yellow if certificate expires in less than N days (default:30)\n"); printf(" --sslalarm=N : Go red if certificate expires in less than N days (default:10)\n"); printf(" --no-cipherlist : Do not display SSL cipher data in the SSL certificate check\n"); printf(" --showallciphers : List all available ciphers supported by the local SSL library\n"); printf("\nDebugging options:\n"); printf(" --no-update : Send status messages to stdout instead of to Xymon\n"); printf(" --timing : Trace the amount of time spent on each series of tests\n"); printf(" --debug : Output debugging information\n"); printf(" --dump[=before|=after|=all] : Dump internal memory structures before/after tests run\n"); printf(" --maxdnsqueue=N : Only queue N DNS lookups at a time\n"); printf("\nInformational options:\n"); printf(" --services : Dump list of known services and exit\n"); printf(" --version : Show program version and exit\n"); printf(" --help : Show help text and exit\n"); return 0; } else if (strncmp(argv[argi], "-", 1) == 0) { errprintf("Unknown option %s - try --help\n", argv[argi]); } else { /* Must be a hostname */ if (selectedcount == 0) selectedhosts = (char **) malloc(argc*sizeof(char *)); selectedhosts[selectedcount++] = strdup(argv[argi]); } } svctree = xtreeNew(strcasecmp); testhosttree = xtreeNew(strcasecmp); cookietree = xtreeNew(strcmp); init_timestamp(); envcheck(reqenv); fqdn = get_fqdn(); /* Setup SEGV handler */ setup_signalhandler(egocolumn ? egocolumn : "xymonnet"); if (xgetenv("XYMONNETWORK") && (strlen(xgetenv("XYMONNETWORK")) > 0)) location = strdup(xgetenv("XYMONNETWORK")); else if (xgetenv("BBLOCATION") && (strlen(xgetenv("BBLOCATION")) > 0)) location = strdup(xgetenv("BBLOCATION")); if (pingcolumn && (strlen(pingcolumn) == 0)) pingcolumn = xgetenv("PINGCOLUMN"); if (pingcolumn && xgetenv("IPTEST_2_CLEAR_ON_FAILED_CONN")) { failgoesclear = (strcmp(xgetenv("IPTEST_2_CLEAR_ON_FAILED_CONN"), "TRUE") == 0); } if (xgetenv("NETFAILTEXT")) failtext = strdup(xgetenv("NETFAILTEXT")); if (debug) { int i; printf("Command: xymonnet"); for (i=1; (i 0); load_tests(); add_timestamp(use_ares_lookup ? "Tests loaded" : "Tests loaded, hostname lookups done"); flush_dnsqueue(); if (use_ares_lookup) add_timestamp("DNS lookups completed"); if (dumpdata & 1) { dump_hostlist(); dump_testitems(); } /* Ping checks first */ if (pingtest && pingtest->items) pingrunning = (start_ping_service(pingtest) == 0); /* Load current status files */ for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); if (s != pingtest) load_test_status(s); } /* First run the TCP/IP and HTTP tests */ for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); if ((s->items) && (s->toolid == TOOL_CONTEST)) { char tname[128]; for (t = s->items; (t); t = t->next) { if (!t->host->dnserror) { strncpy(tname, s->testname, sizeof(tname)); if (s->namelen) tname[s->namelen] = '\0'; t->privdata = (void *)add_tcp_test(ip_to_test(t->host), s->portnum, tname, NULL, t->srcip, NULL, t->silenttest, NULL, NULL, NULL, NULL); } } } } for (t = httptest->items; (t); t = t->next) add_http_test(t); add_timestamp("Test engine setup completed"); do_tcp_tests(timeout, concurrency); add_timestamp("TCP tests completed"); if (pingrunning) { char msg[512]; finish_ping_service(pingtest); snprintf(msg, sizeof(msg), "PING test completed (%d hosts)", pingcount); add_timestamp(msg); if (usebackfeedqueue) combo_start_local(); else combo_start(); send_results(pingtest, failgoesclear); if (selectedhosts == 0) save_ping_status(); combo_end(); add_timestamp("PING test results sent"); } if (debug) { show_tcp_test_results(); show_http_test_results(httptest); } for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); if ((s->items) && (s->toolid == TOOL_CONTEST)) { for (t = s->items; (t); t = t->next) { /* * If the test fails due to DNS error, t->privdata is NULL */ if (t->privdata) { char *p; int i; tcptest_t *testresult = (tcptest_t *)t->privdata; t->open = testresult->open; t->banner = dupstrbuffer(testresult->banner); t->certinfo = testresult->certinfo; t->certissuer = testresult->certissuer; t->certexpires = testresult->certexpires; t->certkeysz = testresult->certkeysz; t->mincipherbits = testresult->mincipherbits; t->duration.tv_sec = testresult->duration.tv_sec; t->duration.tv_nsec = testresult->duration.tv_nsec; /* Binary data in banner ... */ for (i=0, p=STRBUF(t->banner); (i < STRBUFLEN(t->banner)); i++, p++) { if (!isprint((int)*p) && !isspace((int)*p)) *p = '.'; } } } } } for (t = httptest->items; (t); t = t->next) { if (t->privdata) { http_data_t *testresult = (http_data_t *)t->privdata; t->certinfo = testresult->tcptest->certinfo; t->certissuer = testresult->tcptest->certissuer; t->certexpires = testresult->tcptest->certexpires; t->certkeysz = testresult->tcptest->certkeysz; t->mincipherbits = testresult->tcptest->mincipherbits; } } add_timestamp("Test result collection completed"); /* Run the ldap tests */ for (t = ldaptest->items; (t); t = t->next) add_ldap_test(t); add_timestamp("LDAP test engine setup completed"); run_ldap_tests(ldaptest, (ssltestname != NULL), timeout); add_timestamp("LDAP tests executed"); if (debug) show_ldap_test_results(ldaptest); for (t = ldaptest->items; (t); t = t->next) { if (t->privdata) { ldap_data_t *testresult = (ldap_data_t *)t->privdata; t->certinfo = testresult->certinfo; t->certissuer = testresult->certissuer; t->mincipherbits = testresult->mincipherbits; t->certexpires = testresult->certexpires; t->certkeysz = testresult->certkeysz; } } add_timestamp("LDAP tests result collection completed"); /* dns, ntp tests */ for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); if (s->items) { switch(s->toolid) { case TOOL_DNS: run_nslookup_service(s); add_timestamp("DNS tests executed"); break; case TOOL_NTP: run_ntp_service(s); add_timestamp("NTP tests executed"); break; case TOOL_RPCINFO: run_rpcinfo_service(s); add_timestamp("RPC tests executed"); break; default: break; } } } if (usebackfeedqueue) combo_start_local(); else combo_start(); for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); switch (s->toolid) { case TOOL_CONTEST: case TOOL_DNS: case TOOL_NTP: send_results(s, failgoesclear); break; case TOOL_FPING: case TOOL_HTTP: case TOOL_LDAP: /* These handle result-transmission internally */ break; case TOOL_RPCINFO: send_rpcinfo_results(s, failgoesclear); break; } } for (handle = xtreeFirst(testhosttree); (handle != xtreeEnd(testhosttree)); handle = xtreeNext(testhosttree, handle)) { h = (testedhost_t *)xtreeData(testhosttree, handle); send_http_results(httptest, h, h->firsthttp, nonetpage, failgoesclear, usebackfeedqueue); send_content_results(httptest, h, nonetpage, contenttestname, failgoesclear); send_ldap_results(ldaptest, h, nonetpage, failgoesclear); if (ssltestname && !h->nosslcert) send_sslcert_status(h); } combo_end(); add_timestamp("Test results transmitted"); /* * The list of hosts to test frequently because of a failure must * be saved - it is then picked up by the frequent-test ext script * that runs xymonnet again with the frequent-test hosts as * parameter. * * Should the retest itself update the frequent-test file ? It * would allow us to kick hosts from the frequent-test file sooner. * However, it is simpler (no races) if we just let the normal * test-engine be alone in updating the file. * At the worst, we'll re-test a host going up a couple of times * too much. * * So for now update the list only if we ran with no host-parameters. */ if (selectedcount == 0) { /* Save current status files */ for (handle = xtreeFirst(svctree); handle != xtreeEnd(svctree); handle = xtreeNext(svctree, handle)) { s = (service_t *)xtreeData(svctree, handle); if (s != pingtest) save_test_status(s); } /* Save frequent-test list */ save_frequenttestlist(argc, argv); } /* Save session cookies - every time */ save_session_cookies(); shutdown_ldap_library(); add_timestamp("xymonnet completed"); if (dumpdata & 2) { dump_hostlist(); dump_testitems(); } /* Tell about us */ if (egocolumn) { char msgline[4096]; char *timestamps; int color; /* Go yellow if it runs for too long */ if ((runtimewarn > 0) && (total_runtime() > runtimewarn)) { errprintf("WARNING: Runtime %ld longer than time limit (%ld)\n", total_runtime(), runtimewarn); } color = (errbuf ? COL_YELLOW : COL_GREEN); if (bigfailure) color = COL_RED; if (usebackfeedqueue) combo_start_local(); else combo_start(); init_status(color); snprintf(msgline, sizeof(msgline), "status+%d %s.%s %s %s\n\n", validity, xgetenv("MACHINE"), egocolumn, colorname(color), timestamp); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "xymonnet version %s\n", VERSION); addtostatus(msgline); if (ssl_library_version) { snprintf(msgline, sizeof(msgline), "SSL library : %s\n", ssl_library_version); addtostatus(msgline); } if (ldap_library_version) { snprintf(msgline, sizeof(msgline), "LDAP library: %s\n", ldap_library_version); addtostatus(msgline); } snprintf(msgline, sizeof(msgline), "\nStatistics:\n Hosts total : %8d\n Hosts with no tests : %8d\n Total test count : %8d\n Status messages : %8d\n Alert status msgs : %8d\n Transmissions : %8d\n", hostcount, notesthostcount, testcount, xymonstatuscount, xymonnocombocount, xymonmsgcount); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "\nDNS statistics:\n # hostnames resolved : %8d\n # successful : %8d\n # failed : %8d\n # calls to dnsresolve : %8d\n", dns_stats_total, dns_stats_success, dns_stats_failed, dns_stats_lookups); addtostatus(msgline); snprintf(msgline, sizeof(msgline), "\nTCP test statistics:\n # TCP tests total : %8d\n # HTTP tests : %8d\n # Simple TCP tests : %8d\n # Connection attempts : %8d\n # bytes written : %8ld\n # bytes read : %8ld\n", tcp_stats_total, tcp_stats_http, tcp_stats_plain, tcp_stats_connects, tcp_stats_written, tcp_stats_read); addtostatus(msgline); if (errbuf) { addtostatus("\n\nError output:\n"); addtostatus(prehtmlquoted(errbuf)); } if (warnbuf) { addtostatus("\n\nWarning output:\n"); addtostatus(prehtmlquoted(warnbuf)); } show_timestamps(×tamps); addtostatus(timestamps); finish_status(); combo_end(); } else show_timestamps(NULL); if (dnsfaillog) fclose(dnsfaillog); if (usebackfeedqueue) sendmessage_finish_local(); return 0; } xymon-4.3.30/Changes0000664000076400007640000052123413534024770014512 0ustar rpmbuildrpmbuildChanges from 4.3.29 -> 4.3.30 (05 Sep 2019) =========================================== * rev 8010 * Fix reports with dashes or underscores not visible in history logs (Thanks, Tom Schmidt) * Really fix do_temperature.c report parsing for parentheses (Thanks, Tom Schmidt) * Fix truncation on exec strings causing missing custom RRD titles (Thanks, Tom Schmidt) * RPC buffer calculation on snprintf taking improper sizeof (Thanks, Tom Schmidt) * Don't crash on a missing allevents file * Fix assorted crashes with xymongen report generation after string changes * Add guards around GCC diagnostics pragma to allow for building on older vers * xymonclient-linux: Provide wide/untrimmed IP support in netstat port list * Fix problems with meta-combostatuses (Thanks, Dominique Delporte) Changes from 4.3.28 -> 4.3.29 (23 Jul 2019) =========================================== * rev 8070 * Security Fixes: A number of potential buffer overflows have been resolved CVE-2019-13451, CVE-2019-13452, CVE-2019-13455, CVE-2019-13473, CVE-2019-13474, CVE-2019-13484, CVE-2019-13485, CVE-2019-13486 * Deal with Set-Cookie deprecation on normal pages (Thanks, Erik Schminke) * Support glibc->tirpc migration on newer distributions * Fix certain flags not being set on GCC 8/9 * Fix wrong doc for --merge-clientlocal option (Thanks, Thomas Eckert) * Fix CSP errors on trends pages (Thanks, John Thurston) * Accept minimum libcares version >= 1.5.1; update bundled to 1.15.0 * Fix RRD parsing for recent netstat (net-tools) on Linux * Ensure Content-Type always set in HTML headers (Thanks, Christoph Berg) * Ignore additional common tmpfs partitions on recent Linux * Fix NONETPAGE parsing (Thanks, John Horne) * Increase hard max xymon message size from 10MB to 64MB to match 4.4-alpha * Fix line-off-by-one error in logfetch retrieval when triggers are used (Thanks, Toshimitsu FUJIWARA) * Fixes to do_temperature parsing (Thanks, Michael Pins) * Add support for GNU Hurd and GNU/kFreeBSD * Don't require apache authz_groupfile module by default when not needed * Add --no-cpu-listing option to xymond_client to block 'top' output in cpu test (Thanks, John Horne) * Double-quote the display name of host titles handed to RRD * Ensure NTP checks not hung for unreachable hosts (Thanks, Tom Schmidt) * Standardize xymonnet SMTP/s protocol conversation (Thanks, Tom Schmidt) * AIX: Report Actual Memory and Phys/Entitled CPU capacity (Thanks, Stef Coene) * snmp: Fix parsing error with SNMPv3 config parsing (Thanks, Jeremy Laidman) * RRD: Fix parsing error with DS files containing commas - http* only (Thanks, John Horne) Changes from 4.3.27 -> 4.3.28 (17 Jan 2017) =========================================== * rev 8005 * Catch addition possible errors during SSL handshake for standard TCP checks * Fix misparsing of --timelimit and --huge options in xymonnet (Reported by Foster Patch) * Fix memory leak when processing netapp test reports (Reported by Peter Welter) * The included version of c-ares has been bumped to version 1.12.0 * Fix for building on OpenSSL 1.1.0 (Thanks, Axel Beckert) * Add TLS variant specification to http checks, using newer funcs in OpenSSL 1.1.0 (From Henrik) * Fix overflow when skipping >2G pending data in logfetch (Reported by Sergey, a_s_y at sama.ru) * xymond_alert will no longer exit and be relaunched if started while there's no actual alertable condition. (Thanks, Franco G.) * Fix mis-parsing of PCRE regex's in client-local.cfg when char ranges are present (Reported by Erik D. Schminke) * The size limit of message data passed to SCRIPT alerts is configurable with the MAXMSG_ALERTSCRIPT variable. * Summary messages should work again (Thanks, Axel) * Many typos in comments and man pages have been corrected (Thanks, Axel et al. at Debian) * Change netstat RRD numbers to be slightly more human-readable (Thanks Roland Rosenfeld) Changes from 4.3.26 -> 4.3.27 (24 Mar 2016) =========================================== * rev 7957 * Don't treat empty (0 byte) directory size as invalid (Reported by Bert Willekens) * Fix looping redirect on criticaleditor.sh * Allow NK-critical acknowledgements from status pages * Fix redirect to criticalview.sh, which is just a regular CGI * Properly recognize https URLs as summary links (Thanks, David Steinn Geirsson) * Add compile-time check for SSLv3 support Changes from 4.3.25 -> 4.3.26 (19 Feb 2016) =========================================== * rev 7906 * Fix javascript failures on info/trends pages caused by CSP fixes * Fix incorrect HTTP refresh on rejected enadis.sh POSTs * Do not auto-refresh info or trends svcstatus pages * Revert default svcstatus page refresh interval from 30s back to 60s * Re-introduce XYMWEBREFRESH variable to control refresh interval * HTML encode most fields on info page * Restrict characters allowed for hostnames and testnames * HTML encode error log output on xymond/net/gen pages * HTML encode ghost hostnames output on xymond/ghostlist pages * logfetch: only evaluate the first config of a given type seen for the same file name * xymongen/reports: fix vague error message around missing history files and properly exclude clientlog statuses (Reported by Magdi Mahmoud) * Ensure configured CLASS overrides in hosts.cfg are always passed on to client workers, regardless of 'class' for that specific message (Reported by Steve Hill) Changes from 4.3.24 -> 4.3.25 (05 Feb 2016) =========================================== * rev 7890 * Resolve buffer overflow when handling "config" file requests (CVE-2016-2054) * Restrict "config" files to regular files inside the $XYMONHOME/etc/ directory (symlinks disallowed) (CVE-2016-2055). Also, require that the initial filename end in '.cfg' by default * Resolve shell command injection vulnerability in useradm and chpasswd CGIs (CVE-2016-2056) * Tighten permissions on the xymond BFQ used for message submission to restrict access to the xymon user and group. It is now 0620. (CVE-2016-2057) * Restrict javascript execution in current and historical status messages by the addition of appropriate Content-Security-Policy headers to prevent XSS attacks. (CVE-2016-2058) We would like to thank Markus Krell for reporting the above issues, and for working with us to resolve them. * Fix "TRENDS" entries in hosts.cfg improperly handling partial matches with other graph names (Reported by Jeremy Laidman) * A possible crash in when loading confreport.cgi has been fixed (Thanks, Axel Beckert) * Improve error handling slightly in the CGI wrapper * Fix missing network interface graph data on FreeBSD (Niko ) * In xymonnet, a rare SSL error state that could occur after a connection is opened will now be considered "service down" * Fix a crash in xymonnet when handling certain malformed SSL certificates (Reported by Thomas Leavitt, originally via Jeremy Laidman) * Add new trends_header and trends_footer for use on associated Trends pages * "Jump to page" redirect functionality fixed on findhost.sh (Reported by Francois Claire) * When a note is present for a host, the info page no longer has a spurious hostname on the text link * Add --noexec option to logfetch to ignore commands to dynamically list files, modifiable via new LOGFETCHOPTS variable in xymonclient.cfg (Suggested by Jeremy Laidman) * Add variables in xymonclient.cfg for overriding config files for xymond_client and logfetch when client is running in --local mode without editing xymonclient.sh * Add file globbing capabilities to logfetch to avoid need to fork commands to create dynamic lists (Suggested by Jeremy Laidman) * The "Valid Until" time for an acknowledgement is now displayed on the ack log report page (Thanks, Dominique Frise) * The xymon.sh and runclient.sh scripts are themselves now more LSB compliant (Thanks, Nikolai Lifanov) * Windows systems now have a better calculation of "Actual" memory usage (Thanks, John Rothlisberger) * A bug in xymond_alert that could cause pages about hosts.cfg not present at inital start to cause inconsistent alerting has been fixed * xymond_alert now reloads its hostlist at regular intervals Changes from 4.3.23 -> 4.3.24 (23 Nov 2015) =========================================== * rev 7774 * Fix occasional crash in xymond when handling group names (Thanks, Franco Gasperino) * Fix non-special HTTP <400 status codes red instead of yellow >.< Changes from 4.3.22 -> 4.3.23 (12 Nov 2015) =========================================== * rev 7740 * Fix broken 'TRACK' and 'OPTIONAL' identifiers in analysis.cfg * Prevent logfetch from segfaulting if a file we're tracking line matching deltacounts for wasn't found * Fix a type mismatch compiler warning in display group name alert matching Changes from 4.3.21 -> 4.3.22 (6 Nov 2015) =========================================== * rev 7723 * Ensure we don't leave xymond_hostdata or xymond_history zombies lying around after dropping host records (Reported by Scot Kreienkamp) * Fix up HTML list layout to reflect current standards (Thanks, hallik@calyc3.com) * Fix documentation incorrectly describing multigraph syntax as (e.g.) GRAPH_cpu. Should be GRAPHS_cpu (Thanks, Galen Johnson) * Supports scientific notation for NCV data (Thanks, Axel Beckert) * Increase resolution of xymonnet poll timing results (Thanks, Christoph Berg) * New clock skew RRD files will allow for negative delta values (Thanks, Axel Beckert) * Fix lots of typos! (Debian) * Don't skip over "mailq.rrd" (Roland Rosenfeld) * The signature algorithm used on an SSL-enabled TCP test run by xymonnet is now shown on the sslcert page. (Thanks, Ralph Mitchell) * The cipher list displayed in 'sslcert' tests will now be limited to the cipher that was actually used on the SSL connection. The --showallciphers option to xymonnet will restore the previous behavior. (From idea from Ralph Mitchell) * Provide configurable environment overrides in xymonserver.cfg for standard xymonnet options to fping/xymonping, ntpdate, and traceroute binaries. In regular installs, the intended default options to traceroute (-n -q 2 -w 2 -m 15) were not actually used. This may change in a future release, so it's suggested that users move any custom options to the new TRACEROUTEOPTS setting in xymonserver.cfg. (Orig. thanks, Axel Beckert, ntpdate issues pointed out by Matt Vander Werf) * Enable latent additional SHA digest strengths (sha256, sha512, sha224, sha384) * Don't crash generating wml cards for statuses w/ very long lines (Reported by Axel Beckert) * Flip SenderIP and Hostname columns on ghostlist pages to allow easier cutting and pasting to hosts files * Fix multiple disk volumes reported in on Darwin (OS X) clients. (Thanks, Axel Beckert) * Fix COMPACT parsing; update docs to match expected syntax (Thanks, Brian Scott) * Trailing slash no longer required for URL alias ("http://www.example.com/xymon" should work) * A new XYMONLOCALCLIENTOPTS variable in xymonclient.cfg allows options (e.g., --no-port-listing) to be given to xymond_client when running in local client mode. * Add a method to indicate lines which should be skipped by the NCV RRD processor or which mark the end of data-to-be-processed in the message. * Ensure that nostale is passed down during graph zooming (Thanks, Stef Coene) * Add missing XMH_DATA in loadhosts (Thanks, Jacek Tomasiak) * Search in more locations for default environment files when using xymoncmd * Add a "noflap" override to disable flap detection for any/all tests on a given host (Thanks, Martin Lenko) * Simplify default HTTP error code settings for xymonnet (2xx = green; 3xx = yellow; 4xx/5xx = red) * The protocol.cfg entry for RDP network tests has been updated and should work again (Thanks, Rob Steuer) * Add UDP ports to netstat output returned from darwin clients (Mac OS X) * Fixes to df/inode parsing on darwin clients (Mac OS X) (Thanks, Jason White et al.) * Add httphdr= tag to hosts.cfg to inject arbitrary headers into xymonnet HTTP tests for that host. * Turn memory test yellow if nonsensical numbers are found (>100% used for 'Actual' or Swap) * "optional include" and "optional directory" support actually added * xymongrep: load from the hosts.cfg file and error if unable, unless --loadhostsfromxymond is specified * Collect number of total cores in client data * combostatus: Fix parenthesis processing (Thanks, Andy Smith) * Add per-group anchors to generated pages when a group title is present (Thanks, Thomas Giordmaina) * xymongen: Display group tables even if group has no test results yet unless --no-showemptygroups given * Add chpasswd CGI for user-level htpasswd file updates. Requires Apache 2.4.5 or later (Thanks, Andy Smith) * Fix memory/display on multihost hostgraphs.cgi reports; remove multi-disk (which won't work as-is) * Add ACK_COOKIE_EXPIRATION for environment control of cookie validity duration (Noted by Thomas Giordmaina) * combostatus: fix core dumps on Solaris when dealing with erroneous config Changes from 4.3.20 -> 4.3.21 (22 May 2015) =========================================== * rev 7668 * RSS feeds should now display the short description of the event again. Changes from 4.3.19 -> 4.3.20 (15 May 2015) =========================================== * rev 7661 * Summaries should be properly displayed again, and will display on the nongreen.html page as well. * An icon for green acknowledged states is now included -- ironically, the original icon that the other checkmarks were based off of. * The various utilities in cgi-bin and cgi-secure are now hardlinked to cgiwrap at install time instead of softlink, to allow for FollowSymLinks-less apache configurations * The protocol section of URLs in hosts.cfg is now case-insensitive, and ftps URLs (FTP-over-SSL, not sftp) are recognized as a protocol. * hosts.cfg docs have been clarified to include delayyellow and delayred as allowable options (Reported by John Thurston) * 'optional include' and 'optional directory' syntax has been documented * pulldata directives in the hosts.cfg file now honor a given IP address and port XMH_FLAG_PULLDATA is now retired; XMH_PULLDATA must be used in its place * confreport.sh not displaying time-restricted alerts properly has been fixed (Reported by Gavin Stone-Tolcher) * Planned downtime settings are now applied to 'purple' statuses as well (Thanks, Torsten Richter) * Column documentation links should be working again (Reported by Andy Smith) * Fix missing null termination in certain logfetch situations (Reported by Johan Sjšberg) * New httphead tag to force an http request using HEAD instead of GET * Fix a memory leak introduced in parsing Windows SVCS test data * A divide-by-zero condition when systems erroneously report 0MB of physical memory has been corrected (Reported by John Thurston) * Parse either critical config or xymond-formatted acknowledgements on the report page, and add documentation for the --ack-log option in xymond (Thanks, Andy Smith) * The graphs to be displayed on a specific status page can be customized with environment variables - see xymonserver.cfg(5). From Werner Maier. * When clients are in "server" mode (sending raw data to the xymond server to be centrally processed), a 'clientlog' column will now be shown on xymon pages (similar to trends and info columns). This can be disabled on a per-host basis by adding a 'noclient' tag to the hosts.cfg line, or globally by adding that to the .default. host. * Add protocols.cfg entries for amqp(s), svn, ircd, and mail (submission). (Note that smtp testing here may suffer the same occasional issue as regular smtp conversations with regard to out-of-order commands.) * Fix a crash on non-glibc systems when testing xymond_alert configs with a host not in hosts.cfg (Reported by John Thurston) * On newer Linux kernels with recent procps-ng, use the "Available" memory reported by the kernel to give a more accurate reading for "Actual Used" in the client's memory status. (Reported by Dominique Frise) Changes from 4.3.18 -> 4.3.19 (30 Mar 2015) =========================================== * rev 7619 * Don't crash when receiving an AAAA DNS response (BSD, thanks Mark Felder) * xymonclient.sh running in --local mode was generating reports that were marked as duplicates (and thus being ignored). Reported by Guillaume Chane. * Building with old versions of libpcre not supporting PCRE_FIRSTLINE should once again work * Memory reporting on FreeBSD and OpenBSD has been fixed (Mark Felder) * The process list visible in the 'procs' test of Linux and FreeBSD clients is now generated in ASCII "forest" mode for increased legibility. * clientlog, hostinfo, and modify messages are now tracked in xymond stats * In environment config files (xymonserver.cfg, xymonclient.cfg, and cfgoptions.cfg) an initial "export " line (as if it were actually a shell script) will be ignored and the remainder of the line parsed as normal. * headermatch will now match the headers of an HTTP response even if the body is empty (eg, matching for a 302 Redirect) * --debug mode in most daemons should cause *much* less of a performance hit, and output will be timestamped in microseconds * xymondboard can now be used to PCRE-match against the raw message, and acknowledgement and disable comments. Inequalities can be specified against the lastchange, logtime, validtime, acktime, disabletime fields (in epoch timestamps). The existing net= and tag= filters have been documented. * The sample xymon.conf apache snippet now supports apache 2.4 syntax * Fix missing newline when returning upcoming 'schedule' commands. * EXTIME= syntax in analysis.cfg and alerts.cfg has been added. This is applied after any TIME= filter. Use (e.g.) to exclude Wednesday afternoons on a line which is already restricted to 9:00a to 5:00p on weekdays only. * The included version of c-ares has been bumped to version 1.10.0. * Support for older EGD (entropy gathering daemon) has been removed (Thanks, Bernard Spil) * A crash when xymond_rrd was run in --debug mode on non GNU/glibc systems has been fixed * The msgs and procs tests are now HTML-encoded to ensure that lines with brackets are properly displayed * An acknowledgements.sh log report has been added in (Submitted by Andy Smith) * A number of logfetch issues have been addressed: - --debug syntax is now supported. (If modifying the command line in xymonclient.sh, use --debug=stderr to prevent spurious lines being sent in the client report.) - Invalid POSIX regular expressions for ignore or trigger lines will now be reported but should not cause crashes - Null characters in a log file will no longer cause further processing to stop (Thanks, Franco Gasperino.) - All lines matching a 'trigger' regex will be reported back, even if the total size exceeds the "maxbytes" limit. (Up to the maximum compiled buffer size.) As much of the final section as can be fit in the space remaining will be included, similar to the previous behavior if maxbytes was exceeded but no trigger lines were given. (Thanks, Franco Gasperino.) - The current location (where the previous run left off) is now marked in the status report. - The '<...SKIPPED...>' and '<...CURRENT...>' texts can be overridden by specifying values for LOGFETCHSKIPTEXT and LOGFETCHCURRENTTEXT in xymonclient.cfg - The "scrollback" (number of positions in previous "runs" back) that logfetch starts at can now be specified with the LOGFETCHSCROLLBACK variable, from 0 - 6 (the default) * "deltacount" can be used to count the number of lines matching a specific regex in client-local.cfg, counting only since the last run. These will be shown on the trends page. NOTE: Unlike the "linecount:" option, deltacount is specified after a specific "log:" line. See the client-local.cfg file for details. * ifstat and netstat output from the new Windows PowerShell client is now graphed properly. * Hostnames beginning with a number (allowed by RFC1123) are now supported in combo.cfg * When a Windows service's status has been changed (ie, stopped or started), the relevant line in the 'svcs' test will now be updated to reflect this. (Reported by Gavin Stone-Tolcher and Neil Simmonds) * Various build issues, compiler fixes, and valgrind complaints have been fixed. Changes from 4.3.17 -> 4.3.18 (3 Feb 2015) =========================================== * rev 7494 * Fix CVE-2015-1430, a buffer overflow in the acknowledge.cgi script. Thank you to Mark Felder for noting the impact and Martin Lenko for the original patch. * Mitigate CVE-2014-6271 (bash 'Shell shock' vulnerability) by eliminating the shell script CGI wrappers * Don't crash in XML board output when there is no sender for status * Fix IP sender-address check for maintenance commands, when the target host is listed with IP 0.0.0.0 in hosts.cfg. * Linux client: - Generate 'raid' status from mdstat data - Include UDP listen ports in netstat data - Include full OS version data from SuSE clients * FreeBSD client: Handle 'actual' memory item, once the client starts reporting it. * Additional bugfixes: - xymond_capture: Fix exclude-test pattern handling - xymonlaunch: Guard against cron-times triggering twice in one minute - xymond_client: Fix DISPLAYGROUP handling in analysis.cfg rules - xymonnet: Handle AAAA records in dns checks - xymond_channel: Fix matching in --filter code - xymond: BFQ id may be zero - xymond: Fix bug in hostfilter matching code - xymond: Fix memory leak - xymond: Fix list manipulation for "modify" commands - xymond_rrd: Fix restart of external processor - Linux client: Set CPULOOP for correct top output - AIX client: vmstat behaves differently Changes from 4.3.16 -> 4.3.17 (23 Feb 2014) =========================================== * rev 7446 * Fix crash in xymond when using 'schedule' command * Configure/build/install fixes: - Allow specifying location of the PCRE include/library files for client-side configuration build. - Pass IDTOOL to client installation (for Solaris). - Fix broken configure+Makefiles for client-side configuration - C-ARES: Fix wrong call to Makefile.test-cares during configure - Dont error out if www-dir or man-dir is empty. Mostly an issue when building packages with non-standard layouts. * Fix wrong timestamp on a new status arriving with a non-green status while DOWNTIME was active. Such a status would appear to have been created on Jan 1st, 1970. * Fix hostgraphs so it obeys RRDWIDTH / RRDHEIGHT settings * Add upper limit to showgraph CGI when generating self-referring URI's From Werner Maier * Extra sanity check on extcombo message offsets. * The Enable/Disable webpage now permits filtering on CLASS value. From Galen Johnson Changes from 4.3.15 -> 4.3.16 (9 Feb 2014) ========================================== * rev 7394 * Fix xymonnet crash on sending http test results * Fix xymond crash if client-local.cfg contains empty sections * Fix RPM-based initscript for clients with explicit hostname * Fix misleading error-message when testing for C-ARES library * Fix client-local.cfg handling, so by default it will not merge sections together, i.e. behave like previous 4.x releases. NOTE: The new regexp matching can still be used. * Add "--merge-clientlocal" option for xymond, which causes it to merge all matching sections from client-local.cfg into one. * Use native POSIX binary-tree handling code Changes from 4.3.14 -> 4.3.15 (31 Jan 2014) =========================================== * rev 7384 * Fix xymond_alert crashes introduced in 4.3.14 * Fix missing C-ARES build files * client-local.cfg: Support expression matching of sections * acknowledge.cgi: Acks are enabled for all ALERTCOLORS, not just red and yellow Changes from 4.3.13 -> 4.3.14 (26 Jan 2014) =========================================== * rev 7377 * Fix critical ack not working for hosts where the display-name is set (via "NAME:" tag). From Any Smith. * SNI (Server Name Indication) causes some SSL connections to fail due to server-side buggy SSL implementations. Add "sni" and "nosni" flags to control SNI for specific hosts, and "--sni" option for xymonnet to control the default. Reported by Mark Felder. * Fix build process to fully obey any XYMONTOPDIR setting from the top-level Makefile. NOTE: Client-only builds no longer install the client in a "client/" subdirectory below XYMONHOME. * Fix showgraph so it silently ignores stale rrdctl files when trying to flush RRD data before showing a graph. * Fix xymond_alert crashing when trying to strip characters from the alert message. Bug introduced in 4.3.13. * Fix Solaris client to report memory even when no swap is configured. * Fix bug where alerts that were initially suppressed due to TIME restrictions are delayed until REPEAT interval expires. * Fix crash in xymonlaunch when trying to find tasks.cfg * Fix HTML generated by acknowledge.cgi (missing '>') * Fix Linux client reporting garbled client data if top output ends without a new-line (causes CPU load and other vmstat graphs to stop updating) * Fix Debian installation so it enables Apache mod_rewrite * Fix merge-lines utility crashing when first line was an include * Fix "make install" failing when server/www/help was a symlink * Document existing OPTIONAL setting in analysis.cfg for file-checks on files which may not exist. * Document existing CLASS setting in alerts.cfg * Add new INFOCOLUMNGIF and TRENDSCOLUMNGIF settings so the icons used for these pages are configurable. * Enhance Solaris client to correctly handle Solaris zones. * Add new search facilities to xymond to select hosts with the 'xymondboard' and 'hostinfo' commands. * New --ack-each-color option for xymondd changes ack behaviour so a yellow ack does not apply when status changed to red, but a red ack applies if status goes yellow * New "headermatch" tag for http tests so content checks can look at HTTP headers in addition to the HTML body. * Use system-wide c-ares library. The pre-built Debian packages now require the "libc-ares2" package. Changes from 4.3.12 -> 4.3.13 (08 Jan 2014) =========================================== * rev 7339 * Fixes to FreeBSD client code, from Mark Felder (FreeBSD maintainer) * Fix crash on "client" data sent via status channel when host is unknown * Strip carriage-return from text sent to mail alerts, to avoid mail programs treating the message as binary and putting it in an attachment * xymonnet network tester supports Server Name Indication (SNI) for SSL enabled virtual websites. * HTTP tests now use "Cache-control" header for HTTP/1.1 (default) and "Pragma" for HTTP/1.0, so it is protocol compliant. * netbios-ssn, snpp and lpd protocol.cfg entries (Tom Schmidt) * "temperature" status strips html tags from sensor names (Tom Schmidt) * Extra "total network I/O" line on ifstat graph (Tom Schmidt) * New "backfeed" queue for high-speed transmission of Xymon status updates between modules located on the same server as xymond. Note: This is disabled by default, see the README.backfeed file. * New "extcombo" message type allows for combo messages of all types (usually "status" and "data"). * Status webpage will return an HTTP error code for invalid requests instead of reporting an Ok status (some log analysis tools warn about attack attempts when an 'OK' status is reported). * New setting IMAGEFILETYPE removes hardcoded ".gif" on the various image-files in the "gifs" directory. Directory name is unchanged, though. * FreeBSD: Change from maintainer to enable building with CLANG. * New modifier for https tests for selecting only TLSv1 as protocol * CGI's now return a proper HTTP status code in case of errors (e.g. "404" when requesting a status for a non-existing host). * Fix problem with xymond_rrd dying if an external processors crashes (from J. Cleaver) * Fix configure/build problem with detecting POSIX realtime-clock functions. * Fix for FreeBSD 5+ vmstat reporting (from Jeremy Laidman) * Fix for "make install" not setting correct file/directory permissions * Re-add the "--hf-file" option for criticalview CGI (removed in 4.3.7) Changes from 4.3.11 -> 4.3.12 (24 Jul 2013) =========================================== * rev 7211 * Security fix: Guard against directory traversal via hostname in "drophost" commands * Fix crash in xymongen introduced in 4.3.11 * SCO client: Fix overflow in memory calculation when >2 GB memory * Fix so "include" and "directory" definitions in configuration files now handle after the keyword * Fix for the Xymon webpage menu on iPad's and Android (touch devices) * Fix "drophost" handling so the host data directory is also cleared * xymond_rrd now processes data from "clear" status messages * Xymon clients now report the version number in the client data * Linux clients now align "ps" output so it is more readable. * New "generic" client message handler allows log/file monitoring from systems that are not known to Xymon. * The Xymon client now works if invoked with a relative path to the runclient.sh script * Other minor / internal bugfixes Changes from 4.3.10 -> 4.3.11 (21 Apr 2013) =========================================== * rev 7188 * Fix wrong file permissions when installing * Linux client: Fix handling of root filesystem when mounted on "/dev/root" * trends webpage: Fix case where hostname disappears after zoom. * FreeBSD client: Memory patch for FreeBSD 8.0+ * xymond_alert: Fix problem with UNMATCHED rules triggering when there are actual recipients, but their alerts are suppressed due to a REPEAT setting not having expired. * xymond_rrd: Dont crash if called with an empty status/data message * xymond_channel: Report cause when channel-child exits/crashes * xymongen: Geneate an overview page with only reds (like non-green) * xymongen: Optionally define env. variable BOARDFILTER to select hosts/tests included in the generated pages * links: Add pdf, docx and odt as known document formats * Fix potential crashes after an alert cookie expired * Fix potential crash after deleting/renaming a host * Speedup loading of the hosts.cfg file, noticeable with very large hosts.cfg files (100.000+ hosts) Changes from 4.3.9 -> 4.3.10 (6 Aug 2012) ========================================= * rev 7164 * Fix build problems with "errno" * Fix build problems with OpenSSL in non-default locations * Fix build problems with certain LDAP configurations * Fix build problems with RRDtool on FreeBSD / OpenBSD * Fix problem with ifstat data from Fedora in graphs * "inode" check on FreeBSD, OpenBSD, OSX, Solaris, HP/UX, AIX in addition to existing support for Linux * Document building and installing Xymon on common platforms (Linux, FreeBSD, OpenBSD, Solaris) * Enhance xymoncfg so it can be used to import Xymon configuration settings into shell-scripts. Changes from 4.3.8 -> 4.3.9 (15 Jul 2012) ========================================= * rev 7120 * Fix crash when XYMSRV is undefined but XYMSERVERS is * Fix error in calculating combo-status messages with forward references * Fix error in disable-until-TIME or disable-until-OK code * Fix documentation of DURATION in alerts.cfg / xymond_alert so it is consistenly listed as being in "minutes". * Permit explicit use of ">" and ">=" in alerts.cfg * Permit building without the RRDtool libraries, e.g. for a network-tester build, but with trend-graphing disabled. * Full compiler-warning cleanup * Various configuration/build-script issues fixed. Changes from 4.3.7 -> 4.3.8 (15 Jul 2012) ========================================= * rev 7082 Bugfixes * Workaround for DNS timeout handling, now fixed at approximately 25 seconds. * "hostinfo" command for xymond documented * confreport only shows processes that are monitored * analysis.cfg parsing of COLOR for UP rules was broken * RRD handlers no longer crash after receiving 1 billion updates * Using .netrc for authentication could crash xymonnet * "directory" includes would report the wrong filename for missing directories. * useradm CGI would invoke htpassword twice * "include" and "directory" now ignores trailing whitespace * SSLv2 support disabled if SSL-library does not support it * Minor bugfixes and cleanups of compiler warnings. Enhancements * Service status on info page now links to the detailed status page. * Add RRDGRAPHOPTS setting to permit global user-specified RRD options, e.g. for font to showgraph CGI * Add check for the size of public keys used in SSL certificates (enabled via --sslkeysize=N option for xymonnet) * Optionally disable the display of SSL ciphers in the sslcert status (the --no-cipherlist option for xymonnet) * Improved build-scripts works on newer systems with libraries in new and surprising places * Reduce xymonnet memory usage and runtime for ping tests when there are multiple hosts.cfg entries with the same IP-address. * Add code for inode-monitoring on Linux. Does not currently work on any other client platform. * Added the ability to disable tests until a specific time, instead of for some interval. Disabling a test also now computes the expire time for the disable to happen at the next closest minute. Changes from 4.3.6 -> 4.3.7 (13 Dec 2011) ========================================= * rev 6803 * Fix acknowledge CGI (broken in 4.3.6) * Fix broken uptime calculation for systems reporting "1 day" * Workaround Solaris breakage in the LFS-support detection * Fix/add links to the HTML man-page index. * Fix "Stop after" value not being shown on the "info" page. * Fix broken alert texts when using FORMAT=SMS * Fix wrong description of xymondboard CRITERIA in xymon(1) * Fix missing columnname in analysis.cfg(5) DS example * Fix missing space in output from disk IGNORE rules in xymond_client --dump-config * Fix overwrite of xymon-apache.conf when upgrading * Fix installation so it does not remove include/directory lines from configuration files. * Add client/local/ directory for custom client script Changes from 4.3.5 -> 4.3.6 (5 Dec 2011) ======================================== * rev 6788 * Optionally choose the color for the "cpu" status when it goes non-green due to uptime or clock offset. * Allow for "include" and "directory" in combo.cfg and protocols.cfg * New INTERFACES definition in hosts.cfg to select which network interfaces are tracked in graphs. * New access control mechanism for some CGI scripts returning host-specific information. Access optionally checked against an Apache-style "group" file (see xymonwebaccess(5) CGI manpage). * New "vertical" page-definitions (vpage, vsubpage,vsubparent) for listing hosts across and tests down on a page. * Fix hostlist CGI crash when called with HTTP "HEAD" * Fix svcstatus CGI crash when called with non-existing hostname * Fix "ackinfo" updates being cleared when host hits a DOWNTIME period. * Fix compile-errors on Solaris due to network libraries not being included. * Fix "logrotate" messages not being sent to some channels. * Fix problem with loading the hosts.cfg file. * STATUSLIFETIME now provides the default time a status is valid (in xymond). * Critical systems view: Use priority 99 for un-categorised priorities (imported from NK tags) and show this as 'No priority' on the webpage. * useradm CGI: Sort usernames * New xymond module - xymond_distribute - can forward administrative commands (drop, rename, disable, enable) from one Xymon server to another. * New tool: appfeed CGI provides data for the Android "xymonQV" app by Darrik Mazey. Changes from 4.3.4 -> 4.3.5 (9 Sep 2011) ======================================== * rev 6754 * Fix crash in CGI generating the "info" status column. * Fix broken handling of IGNORE for log-file analysis. * Fix broken clean-up of obsolete cookies (no user impact). * Devmon RRD handler: Fix missing initialisation, which might cause crashes of the RRD handler. * Fix crashes in xymond caused by faulty new library for storing cookies and host-information. * Fix memory corruption/crash in xymond caused by logging of multi-source statuses. * New "delayred" and "delayyellow" definitions for a host can be used to delay change to a yellow/red status for any status column (replaces the network-specific "badFOO" definitions). * analysis.cfg and alerts.cfg: New DISPLAYGROUP setting to select hosts by the group/group-only/group-except text. * New HOSTDOCURL setting in xymonserver.cfg. Replaces the xymongen "--docurl" and "--doccgi" options, and is used by all tools. * xymond_history option to control location of PID file. * Critical Systems view: Optionally show eventlog for the hosts present on the CS view. * Critical Systems view: Multiple --config options can now be used, to display critical systems from multiple configurations on one page. * Detailed status display: Speedup by no longer having to load the hosts.cfg file. * xymongen and xymonnet: Optionally load the hosts.cfg from xymond instead of having to read the file. Changes from 4.3.3 -> 4.3.4 (1 Aug 2011) ======================================== * rev 6722 * Fix crashes and data corruption in Xymon worker modules (xymond_client, xymond_rrd etc) after handling large messages. * Fix xymond lock-up when renaming/deleting hosts * Fix xymond cookie lookup mechanism * Webpages: Add new HOSTPOPUP setting to control what values from hosts.cfg are displayed as a "comment" to the hostname (either in pop-up's or next to the hostname). * Fix xymond_client crash if analysis.cfg contains invalid configuration entries, e.g. expressions that do not compile. * Fix showgraph CGI crash when legends contain colon. * xymonnet: Include hostname when reporting erroneous test-spec * CGI utils: Multiple potential security fixes involving buffer- overruns when generating responses. * CGI utils: Fix crash when invoked with HTTP "HEAD" * CGI utils: Fix crashes on 64-bit platforms due to missing prototype of "basename()" function. * svcstatus CGI: Dont crash if history log is not a file. * Critical systems view CGI: Cross-site scripting fix * Fix recovery-messages for alerts sent to a GROUP * RRD "memory" status handler now recognizes the output from the bb-xsnmp.pl module (for Cisco routers). * Web templates modified so the menu CSS can override the default body CSS. * Acknowledge web page now allows selecting minutes/hours/days * Enable/Disable webpage enhanced, so when selecting multiple hosts the "Tests" column only lists the tests those hosts have. Changes from 4.3.2 -> 4.3.3 (6 May 2011) ======================================== * rev6684 * SECURITY FIX: Some CGI parameters were used to construct filenames of historical logfiles without being sanitized, so they could be abused to read files on the webserver. * SECURITY FIX: More cross-site scripting vulnerabilities. * Remove extra "," before "History" button on status-view * Critical view: Shring priority-column to 10% width * hosts.cfg loader: Check for valid IP spec (nibbles in 0-255 range). Large numbers in a nibble were accepted, triggering problems when trying to ping the host. * Alert macros no longer limited to 8kB Changes from 4.3.1 -> 4.3.2 (4 Apr 2011) ======================================== * rev6672 * Web UI: Fix bug introduced with the 4.3.1 XSS fixes. Changes from 4.3.0 -> 4.3.1 (3 Apr 2011) ======================================== * Web UI: SECURITY FIX - fix potential cross-site scripting vulnerabilities. Initial report by David Ferrest (email April 1st 2011). * Solaris Makefile: Drop guessing of what linker is being used, since we get it wrong too often. * configure: Add missing include to fix compile failure on some systems. * get_ostype(): Check that we have a valid OS identifier. Dont assume we can write to the string passed us. * xymond user messages: Improve error message for oversize messages. Document the MAXMSG_USER setting. * combostatus: Make the set of error-colors configurable. Change default set so BLUE and PURPLE are not considered errors (only RED is an error by default). * xymon(1) manpage: Add missing description of some fields available in the xymondboard command. * hosts.cfg manpage: Fix wrong NOPROP interpretation. From Thomas Brand. * Demotool: Change Hobbit->Xymon Changes from 4.3.0 RC 1 -> 4.3.0 (4 Mar 2011) ============================================= * Critical view and other webpages: Make the 'All systems OK' message configurable. Also allow the header/footer for the Critical Systems view to be configurable. Suggestion and preliminary patch from Buchan Milne. * xymonnet: Improve error report when HTTP tests get an empty response - 'HTTP error 0' sounds weird. * report / snapshot CGI's: Fix buffer overrun in the HTML delimiter generated in the "please wait..." message. Also, fix potential buffer overrun in report CGI if invoked with a large value for the "style" parameter. Reported by Rolf Biesbroek. * Graph definitions (graphs.cfg): Multi graphs cannot use a regex pattern. Problem report by Brian Majeska * Solaris interface statistics: Filter out "mac" and "wrsmd" devices at the client side. Update RRD handler to also filter "wrsmd" at the server side, like we already did for "mac" devices. Cf. http://www.xymon.com/archive/2009/06/msg00204.html * Documentation: Document the XMH_* fields available in xymondboard commands. * Documentation: Document SPLITNCV and "trends" methods of doing custom graphs. * RRD definitions: Allow override of --step/-s option for rrdcreate, from template supplied in rrddefinitions.cfg. Suggestion from Brian Majeska. * mailack: Remove restriction on how long a subjectline/message body can be. * Build procedure: Add notice about running upgrade script before installing the new version. * xymond_alert: Document --trace option * Alerts: For recovery messages, add information so you can tell whether the recovery was due to the service actually recovering, or if it was merely disabled. * xymond_alert: Fix missing element in array of alert status texts used for tracing. Spotted by Dominique Frise. * Add support for FreeBSD v8 modified ifstat output * Documentation: Update information about the Xymon mailing lists following move to Mailman and new archive URL. * HP/UX client: Use "swapinfo" to extract memory utilisation data, instead of the hpux-meminfo utility. By Earl Flack http://lists.xymon.com/pipermail/xymon/2010-December/030100.html Changes from 4.3.0 beta 3 -> 4.3.0 RC 1 (23 Jan 2011) ===================================================== * hosts.cfg badldap documentation: Document that for LDAP URL's you must use 'badldapurl'. Reported by Simo Hmami. * xymond flap detection: Make number of tracked status changes and the flap-check period configurable. Change the defaults to trigger flapping at more than 5 status changes in a 30 minute period. * sendmessage: Enhanced error reporting, to help track down communication problems. * xymond_client: Fix Windows SVC status handling to avoid coredumps, memory corruption and other nasties. Will now report the real name of the service, instead of the pattern used in the analysis.cfg file. NOTE: Slight change to status message format. * Client handler: Fix owner/user check parsing. Reported by Ian Marsh http://www.xymon.com/archive/2011/01/msg00133.html (also broken in 4.2.3). * xymongen: Fix broken --doc-window option handling. Reported by Tom Schmitt. * Xymongen: Fix documentation of the --doc-window/--no-doc-window options. * Webpage background: Use a CSS and a new set of gif's to implement a background that works on all displays, regardless of width. Uses a new xymonbody.css stylesheet which can also control some other aspects of the webpage. From Francois Claire. * Documentation: The xymon 'rename' command should be used AFTER renaming a host in hosts.cfg, not before. From Tom Georgoulias. * Memory status: Add some sanity checks for the memory utilisation reported by clients. Occasionally we get completely bogus data from clients, so only act on them if percentages do not exceed 100. * Critical systems view: Add "--tooltips" option so you can save screen space by hiding the host descriptions in a tooltip, like we do on the statically generated pages. Feature request from Chris Morris. * Solaris client: Report "swap -l" in addition to "swap -s" for swap usage. Backend prefers output from "swap -l" when determining swap utilisation. * Webpage menu: Use the CSS and GIF's by Malcolm Hunter - they are much nicer than the ones from Debian. Distribute both the blue and the grey version, and configure which one to use in xymonserver.cfg. * Graph zoom: Use float variables when calculating the upper/lower limits of the graph. Fixes vertical zoom. * xymond: Make sure we do not perform socket operations on invalid sockets (e.g. those from a scheduled task pseudo-connection) * Installation: Remove any existing old commands before creating symlinks * xymonproxy: Fix broken compatibility option '--bbdisplay' * Fix eventlog summary/count enums so they dont clash with Solaris predefined entities * History- and hostdata-modules: Dont save data if there is less than 5% free space on the filesystem. Also, dont save hostdata info more than 5 times per hour. * Historical statuslog display: Work-around for crash when status-log is empty * fping.sh configure sub-script: Fix syntax error in suggested 'sudoers' configuration, and point to the found fping binary. From Steff Coene. * namematch routine: Fix broken matching when doing simple matching against two strings where one was a subset of the other. http://www.xymon.com/archive/2010/11/msg00177.html . Reported by Elmar Heeb who also provided a patch, although I chose a different solution to this. * Xymon net: Fix broken compile when LDAP-checks are disabled. Reported by Roland Soderstrom, fix from Ralph Mitchell. * xymon(7) manpage: Drop notice that renaming in 4.3.0 is not complete * Installation: Setup links for the commonly used Hobbit binaries (bb, bbcmd, bbdigest, bbhostgrep, bbhostshow) * Upgrade script: Setup symlinks for the old names of the standard webpages * xymonserver.cfg.DIST: Missing end-quote in compatibility BBSERVERSECURECGIURL setting. From Ralph Mitchell * xymongrep: Fix broken commandline parsing resulting from trying to be backwards-compatible. Reported by Jason Chambers. Changes from 4.3.0 beta 2 -> 4.3.0 beta 3 (15 Nov 2010) ======================================================= * Reflect the renaming of the project at Sourceforge in documentation, links etc. * Any data going into graphs can now trigger a status to change color, if the value of the data is outside thresholds. This can be used to e.g. trigger an alert if the response-time of a network test is longer than expected, even though the service is responding. Also works for custom tests that feed data into graphs. (see analysis.cfg "DS" definition). This uses a new xymond command, "modify". * Clients can now use several modules to send "client" data to the Xymon server, all of which are passed to (specialised) client-data processors on the Xymon server. * All tools for the "Critical Systems View" now have a "--config=FILENAME" option for which file to load the configuration from. Configuration files: * Document the "directory" include syntax * Allow the "include" and "directory" definitions to be indented. xymongen: * New "--no-nongreen" option for bbgen disables generating the "All Non-green" page, since this is not useful on large installations. * If xymongen cannot load the current status from xymond, abort updating of the webpages instead of generating a 100% green set of webpages. xymonnet: * New "--source-ip=ADDRESS" option for xymonnet to set the default source IP used for network tests. * HTTP tests now use the source-IP. * New "--ping-tasks=N" option for xymonnet to split the ping-tests to multiple processes. Needed to speed up ping of large installations. * Disable support for the old Big Brother syntax for HTTP proxies in web checks. Necessary to allow testing of URL's beginning with "http". If necessary, the old Big Brother compatible behaviour is enabled with the new "--bb-proxy-syntax" option for xymonnet. xymonproxy: * Rename "--bbdisplay" option to "--server". * Drop support for sending data to Big Brother servers. This means that the Big Brother "page" messages will no longer be relayed by bbproxy, so the "--bbpager" and "--hobbitd" options have been removed. msgcache / xymonfetch: * Fix off-by-one bug when reading data. Could lead to data corruption, crashes and other nasty behaviour. * Remove port-numbers from the "Message received from..." line so these don't show up as multi-source. xymonlaunch: * Support for cron-style time specification, so tasks will run at specific times. xymon tool: * New "--response" option overrides auto-detection of whether to expect a response back from the server. * Support the new "usermsg" and "modify" commands. hosts.cfg configuration settings: * New "multihomed" option disables the multi-source detection for a host. xymond: * Support multiple client-collector modules for each host. * Detect when the same host receives updates from multiple source IP adresses. Usually indicates a misconfigured client reporting with the name of another server. May erroneously flag some multi-homed hosts, so this check can be disabled with the "multihomed" flag in bb-hosts. * Detect when a status is rapidly switching between to states. In that case, the most severe state is enforced until the flapping stops. Such flapping would lead to a huge number of status messages being stored as historical logs. * Fix rare bug where missing status-log data could crash xymond. * Fix small memory leak in processing "config" and "download" commands. xymond_capture: * New server-side tool to capture selected messages from a Xymon channel. xymond_channel: * New "--filter" option allows use of a regular expression to filter data being passed to the worker module based on the message summary line. xymond_client: * Fix bug where very large client messages could result in the next message processed being corrupted. Typically, this would cause semi-random disk graphs to appear, or bogus alerts triggering. * Test for filesystems running out of i-nodes. Currently only the Linux client reports data for this. * Test for any data going into graphs triggering a "modify" of a status if the value is outside limits. * Mangle filenames with a colon (i.e. Windows filenames) when passing them to other status-messages, e.g. xymond_rrd. * Detect/discard duplicated update-messages and discard them. xymond_history: * The SAVESTATUSLOG setting can now select which status-logs to save as historical logs. xymond_rootlogin.pl: * Sample serverside module in Perl. xymond_rrd: * Explicitly update access-times when updating RRD files on Linux, since the memory-mapped I/O on this platform does not modify timestamps, causing Xymon to consider all graphs stale. * Detect/discard duplicated update-messages and discard them. * New "--no-cache" option disables caching of RRD updates. * SPLITNCV bug fixed. * Support output from newer versions of the ntp.org "sntp" tool. Top-changing hosts/statuses: * Eventlog CGI application can now report the most changing hosts/statuses. perfdata CGI: * New "--page=REGEXP" option for selecting which hosts to include. BBWin client: * Fix clock offset calculation in cases where "epoch" time is reported without a decimal part. Linux client: * lsb_release may be installed in /usr/bin SCO Unixware client: * New client AIX client: * Fix wrong data collected in graphs (RRD files) for AIX memory/swap utilisation. Solaris client: * Ignore "mac" interfaces in interface-statistics. These are physical interfaces aggregated into a multi-link virtual interface - statistics are collected for the virtual interface. IBM MQ: * New collector module and sub-client. CGI applications: * New XYMONCGILOGDIR setting in xymonserver.cfg sets a directory where CGI debug output is stored. BEA/NetApp/Database add-on: * Server side updated to hobbit-perl-cl ver. 1.21. Among other things, this means that Tablespace utilisation is now graphed. Devmon add-on: * Server side updated to current version. Changes from 4.3.0 beta 1 -> 4.3.0 beta 2 (24 Apr 2009) ======================================================= * New "--shuffle" option for bbtest-net to run network tests in a random order. * Client startup script now exports important environment variables, so they are actually used in systems with a traditional shell. * hobbitlaunch no longer crashes if there are no tasks * Client configure script includes librt for clock_gettime() * New client support for mainframes: z/OS, z/VM, z/VSE * Enhanced eventlog and top-changing hosts webpages. * Revert debian package pathnames back to use "hobbit", so updates from 4.2.x will actually work. * Ghostlist options in hobbitcgi.cfg had no effect because of typo in setting name. * "data" messages could crash hobbitd. * Debug output from hobbitd_channel now logs only the relevant data instead of the full message. * trimhistory now informs the history module to re-open the "allevents" file after trimming it. * devmon template fix * New "rrdcachectl" utility included. * Fixed sorting routine (affected holiday list and others) * Fix generic crash in communications module between Xymon programs, where an empty response message would crash caller. Changes from 4.2.3 -> 4.3.0 beta 1 (09 Feb 2009) ================================================ Core changes: * New API's for loadhosts and sendmessage, in preparation for the full 5.0 changes. * Always use getcurrenttime() instead of time(). * Support for defining holidays as non-working days in alerts and SLA calculations. * Hosts which appear on multiple pages in the web display can use any page they are on in the alerting rules and elsewhere. * Worker modules (RRD, client-data parsers etc) can operate on remote hosts from the hobbitd daemon, for load-sharing. * Various bugfixes collected over time. Network test changes: * Merged new network tests from trunk: SOAP-over-HTTP, SSL minimum cipher strength * Changed network test code to always report a validity period for network tests, so it it possible to run network tests less often than every 30 minutes (e.g. once an hour). * Make the content-type setting in HTTP POST tests configurable. * Make the source-address used for TCP tests configurable. * Make the acceptable HTTP result codes configurable. * Use and save HTTP session cookies. Web changes * Support generic drop-down lists in templates. * "NOCOLUMNS" changed to work for all columns. * New "group-sorted" definition to auto-sort hosts in a group * Use browser tooltips for host comments * "Compact" status allows several statuses to appear as a single status on the overview webpages. * Trends page can select the time period to show. Buttons provided for the common selections. * Ghost list report now lists possible candidates for a ghost, based on IP-address or unqualified hostname. Report changes * Number of outages as SLA parameter Miscellaneous * hobbitlaunch support for running tasks only on certain hosts, and for a maximum time. * Alert script get a unique ID for each alert. Changes from 4.2.2 -> 4.2.3 (09 Feb 2008) ========================================= * Time-out code changed to use clock_gettime() with CLOCK_MONOTONIC * Bugfix for hobbitd/hobbitd_worker communication going out-of-sync resulting in "garbled data" being logged and worker modules stopping. * NCV module now works with negative numbers. * Several bugfixes in DNS lookup code - could lead to crashes when performing DNS tests. * Switch to C-ARES 1.6.0 - drop support for older versions. * Run more TCP tests in parallel by not waiting for very slow connections to complete before starting new ones. * Added "hostlist" web utility for spreadsheet-reporting of the hosts in Hobbit. Changes from 4.2.0 -> 4.2.2 (01 Dec 2008) ========================================= Changelog extracted from Subversion. ------------------------------------------------------------------------ r5935 | storner | 2008-11-26 12:57:11 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: A /branches/4.2.0 (from /trunk:5040) Create branch for maintenance of the 4.2.x release. ------------------------------------------------------------------------ r5936 | storner | 2008-11-26 13:13:50 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/common/bb-hosts.5 The ability to set a DOWNTIME for an individual test was mentioned in the Changes file, but not documented in the bb-hosts man-page. ------------------------------------------------------------------------ r5937 | storner | 2008-11-26 13:14:48 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/hobbitd/hobbitd_client.c The hobbitd_client program would crash when running in test-mode, i.e. launched with the --test option to test disk-, procs- and ports-settings. This only applies to running it in test-mode, normal operation is not affected. ------------------------------------------------------------------------ r5938 | storner | 2008-11-26 13:15:40 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/lib/headfoot.c M /branches/4.2.0/web/bb-datepage.c M /branches/4.2.0/web/bb-eventlog.c M /branches/4.2.0/web/bb-findhost.c M /branches/4.2.0/web/bb-rep.c M /branches/4.2.0/web/bb-snapshot.c M /branches/4.2.0/web/hobbit-enadis.c M /branches/4.2.0/web/hobbit-nkedit.c Some of the web page would generate an extra line with "Content-type: text/html" at the top of the webpage, although this would most often be hidden by the menubar. ------------------------------------------------------------------------ r5939 | storner | 2008-11-26 13:16:21 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/client/runclient.sh Using extra options with the client-side "runclient.sh" script when performing a restart command fails to pass the extra options to the final command. ------------------------------------------------------------------------ r5940 | storner | 2008-11-26 13:17:12 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/hobbitd/hobbitfetch.c hobbitfetch insisted that hosts must have a valid IP-adress in bb-hosts. This causes problems for hosts with dynamic IP-adresses. This patch causes hobbitfetch to lookup the IP-address at run-time if the IP is listed as "0.0.0.0". ------------------------------------------------------------------------ r5941 | storner | 2008-11-26 13:20:44 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/web/hobbit-confreport.c M /branches/4.2.0/web/hobbitsvc-info.c Hostname filtering on the info column page is broken, if you have multiple hosts with similar names, resulting in the same columns showing up multiple times in the disable section. A similar problem affects host filtering in the configuration report tool. ------------------------------------------------------------------------ r5942 | storner | 2008-11-26 13:21:27 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: M /branches/4.2.0/client/hobbitclient-sunos.sh The Solaris client would not collect the "top" process-listing data which is normally included in the data on the "cpu" column. ------------------------------------------------------------------------ r5943 | storner | 2008-11-26 13:25:28 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/build/bb-commands.sh M /branches/4.2.0/client/hobbitclient-sunos.sh The Solaris lofs (loopback filesystem) should not be included in the df output appearing on the Disk status. ------------------------------------------------------------------------ r5944 | storner | 2008-11-26 13:29:56 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/cgi.c M /branches/4.2.0/lib/cgi.h M /branches/4.2.0/web/bb-ack.c M /branches/4.2.0/web/bb-datepage.c M /branches/4.2.0/web/hobbit-confreport.c M /branches/4.2.0/web/hobbit-enadis.c M /branches/4.2.0/web/hobbit-hostgraphs.c M /branches/4.2.0/web/hobbit-statusreport.c Cookie handling does not always work. This results in hosts not showing up on the new acknowledgment page, or hosts missing from the Metrics report. ------------------------------------------------------------------------ r5945 | storner | 2008-11-26 13:30:31 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/bbdisplay/bbgen.h Hobbit 4.2.0 fails to build on some OS X releases due to a naming conflict between a system-defined datatype, and a different datatype defined in Hobbit. ------------------------------------------------------------------------ r5946 | storner | 2008-11-26 13:31:41 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/webfiles/zoom.js M /branches/4.2.0/lib/hobbitrrd.c M /branches/4.2.0/lib/hobbitrrd.h M /branches/4.2.0/lib/htmllog.c M /branches/4.2.0/web/hobbitgraph.c M /branches/4.2.0/web/hobbitsvc-trends.c When viewing detailed graphs linked from the detailed status page, the background color of the webpages would always show green, regardless of the actual color of the status it was linked from. This patch keeps the background color at what the status page shows. ------------------------------------------------------------------------ r5947 | storner | 2008-11-26 13:32:55 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/webfiles/confreport_front M /branches/4.2.0/hobbitd/wwwfiles/menu/menu_items.js.DIST M /branches/4.2.0/web/Makefile M /branches/4.2.0/web/hobbit-confreport.c M /branches/4.2.0/web/hobbit-confreport.cgi.1 The Configuration Report did not include information about what systems appears on the "Critical Systems" view. ------------------------------------------------------------------------ r5948 | storner | 2008-11-26 13:33:43 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/web/hobbitsvc-info.c The info-column page for hosts with an IP-address of 0.0.0.0 - i.e. a dynamic or unknown IP - often fails to work because of a buffer overflow when printing the real IP address of the host. ------------------------------------------------------------------------ r5949 | storner | 2008-11-26 13:34:23 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/do_alert.c M /branches/4.2.0/hobbitd/hobbitd_alert.c The hobbitd_alert module is leaking memory each time it sends out an alert, or whenever a status recovers and is removed from the list of active alerts. ------------------------------------------------------------------------ r5950 | storner | 2008-11-26 13:35:03 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/cgi.c Relaying of Hobbit status messages through HTTP via bbmessage.cgi was broken. ------------------------------------------------------------------------ r5951 | storner | 2008-11-26 13:37:00 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/webfiles/hobbitnk_footer M /branches/4.2.0/web/hobbit-nkview.c Let the Critical Systems view include Purple statuses as an option ------------------------------------------------------------------------ r5952 | storner | 2008-11-26 13:38:04 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/Makefile M /branches/4.2.0/lib/color.c M /branches/4.2.0/lib/timefunc.c Avoid use of strtok_r in client code, since this may not exist on all platforms ------------------------------------------------------------------------ r5953 | storner | 2008-11-26 13:39:35 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/rrd/do_ncv.c The NCV custom graphs module would mistakenly include text from lines with no data into the name of the next dataset. Apply this patch. Note that any existing RRD files affected by this bug must be deleted, since this changes the names of the datasets inside the RRD files. ------------------------------------------------------------------------ r5954 | storner | 2008-11-26 13:40:32 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/client/msgcache.c The msgcache utility used on some clients could lock up and/or crash if multiple connections to the program were active at the same time. Thanks to Rolf Masfelder for spotting it. ------------------------------------------------------------------------ r5955 | storner | 2008-11-26 13:41:13 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/client_config.c The hobbitd_client module handling status reports from Hobbit clients could crash while processing the disk status. ------------------------------------------------------------------------ r5956 | storner | 2008-11-26 13:42:04 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/hobbitd_client.c The logfile status display could be corrupted if the logs contained HTML tags. This patch wraps the logfile texts in a pre-formatted HTML sequence. ------------------------------------------------------------------------ r5957 | storner | 2008-11-26 13:42:49 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/bbdisplay/bbgen.h M /branches/4.2.0/bbdisplay/loadbbhosts.c M /branches/4.2.0/bbdisplay/loadbbhosts.h M /branches/4.2.0/bbdisplay/loaddata.c M /branches/4.2.0/bbdisplay/pagegen.c M /branches/4.2.0/bbnet/bbtest-net.c M /branches/4.2.0/bbnet/bbtest-net.h M /branches/4.2.0/hobbitd/hobbitd.c M /branches/4.2.0/lib/headfoot.c M /branches/4.2.0/lib/loadhosts.c M /branches/4.2.0/lib/loadhosts.h M /branches/4.2.0/lib/loadhosts_file.c The modembank-testing feature has been broken for a couple of releases. This patch removes this dead code. ------------------------------------------------------------------------ r5958 | storner | 2008-11-26 13:43:31 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/client/logfetch.c The client-side logfetch utility has been enhanced to support multiple ignore and trigger patterns. ------------------------------------------------------------------------ r5959 | storner | 2008-11-26 13:44:28 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/webfiles/info_header M /branches/4.2.0/web/hobbitsvc-info.c The info page disable function has been enhanced in two ways: A separate status summmary shows the current color of all statuses, and lets you easily pick all red/yellow/purple tests to disable them. Also, the status names in the disable listbox now shows the current color of the status. This enhancement was based on code from Michael Nagel. ------------------------------------------------------------------------ r5960 | storner | 2008-11-26 13:45:38 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/Makefile A /branches/4.2.0/hobbitd/convertnk.c A new convertnk utility has been added to convert the old NK tags in bb-hosts to the new Critical Systems view configuration file. ------------------------------------------------------------------------ r5961 | storner | 2008-11-26 13:46:32 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/configure.server The configuration script would allow you to enter a blank value for the webserver group-ID, causing installation to fail later. This patch changes the configuration script to require a value for this setting. ------------------------------------------------------------------------ r5962 | storner | 2008-11-26 13:47:38 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/client/hobbitclient-aix.sh M /branches/4.2.0/client/hobbitclient-darwin.sh AIX and Darwin clients: Show routing entries using IP-address, not hostnames ------------------------------------------------------------------------ r5963 | storner | 2008-11-26 13:49:04 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/timefunc.c M /branches/4.2.0/web/bb-ack.c The acknowledgment webpage requires you to enter the acknowledgment duration in minutes. This patch lets you enter the duration as "2d" or "4h30m" for an easier way of setting the duration. ------------------------------------------------------------------------ r5964 | storner | 2008-11-26 13:50:35 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/bbnet/httptest.c Include port-number in HTTP "Host" header if it is not standard ------------------------------------------------------------------------ r5965 | storner | 2008-11-26 13:51:57 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/stackio.c Do not crash if a configuration Include directory is empty ------------------------------------------------------------------------ r5966 | storner | 2008-11-26 13:52:58 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/bbdisplay/loadbbhosts.c The bbgen tool which creates the Hobbit webpages might crash if certain noprop settings were used. ------------------------------------------------------------------------ r5967 | storner | 2008-11-26 14:02:51 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: A /branches/4.2.0/web/hobbit-confreport-critical.sh.DIST Missed this file in previous commit. ------------------------------------------------------------------------ r5968 | storner | 2008-11-26 14:04:25 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: A /branches/4.2.0/hobbitd/webfiles/notify_footer A /branches/4.2.0/hobbitd/webfiles/notify_form A /branches/4.2.0/hobbitd/webfiles/notify_header M /branches/4.2.0/hobbitd/wwwfiles/menu/menu_items.js.DIST M /branches/4.2.0/include/libbbgen.h M /branches/4.2.0/lib/Makefile A /branches/4.2.0/lib/notifylog.c A /branches/4.2.0/lib/notifylog.h M /branches/4.2.0/web/Makefile A /branches/4.2.0/web/hobbit-notifylog.c A /branches/4.2.0/web/hobbit-notifylog.sh.DIST A utility for viewing the notifications log has been added. ------------------------------------------------------------------------ r5969 | storner | 2008-11-26 14:38:26 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/hobbitd.c M /branches/4.2.0/hobbitd/hobbitd_buffer.c M /branches/4.2.0/hobbitd/hobbitd_buffer.h M /branches/4.2.0/hobbitd/hobbitd_ipc.c The Hobbit daemon now has a "user channel" that may be used to send custom messages through Hobbit. ------------------------------------------------------------------------ r5970 | storner | 2008-11-26 14:45:50 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/lib/Makefile M /branches/4.2.0/web/Makefile Cleanup merge errors from allinone patch ------------------------------------------------------------------------ r5971 | storner | 2008-11-26 14:47:08 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/hobbitd.c Do not hang when reading from socket ------------------------------------------------------------------------ r5972 | storner | 2008-11-26 14:48:02 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/hobbitd/hobbitd.c Make sure there is space for Line-1 in message sent to workers ------------------------------------------------------------------------ r5973 | storner | 2008-11-26 14:48:45 +0100 (Wed, 26 Nov 2008) | 1 line Changed paths: M /branches/4.2.0/web/hobbitgraph.c Hostnames used in URL must be URL-encoded ------------------------------------------------------------------------ r5974 | storner | 2008-11-26 14:51:47 +0100 (Wed, 26 Nov 2008) | 3 lines Changed paths: A /branches/4.2.2 (from /branches/4.2.0:5973) New branch off the 4.2.0 + allinone patch for a 4.2.2 release. ------------------------------------------------------------------------ r5975 | storner | 2008-11-27 14:07:05 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/build/updmanver Adjusted to work with SVN ------------------------------------------------------------------------ r5976 | storner | 2008-11-27 14:12:12 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/CREDITS M /branches/4.2.2/README M /branches/4.2.2/README.CLIENT M /branches/4.2.2/bbdisplay/bbgen.1 M /branches/4.2.2/bbnet/bb-services.5 M /branches/4.2.2/bbnet/bbretest-net.sh.1 M /branches/4.2.2/bbnet/bbtest-net.1 M /branches/4.2.2/bbnet/hobbitping.1 M /branches/4.2.2/bbproxy/bbmessage.cgi.8 M /branches/4.2.2/bbproxy/bbproxy.8 M /branches/4.2.2/build/makedeb.sh M /branches/4.2.2/build/makehtml.sh M /branches/4.2.2/common/bb-hosts.5 M /branches/4.2.2/common/bb.1 M /branches/4.2.2/common/bbcmd.1 M /branches/4.2.2/common/bbdigest.1 M /branches/4.2.2/common/bbhostgrep.1 M /branches/4.2.2/common/bbhostshow.1 M /branches/4.2.2/common/clientlaunch.cfg.5 M /branches/4.2.2/common/clientupdate.1 M /branches/4.2.2/common/hobbit.7 M /branches/4.2.2/common/hobbitclient.cfg.5 M /branches/4.2.2/common/hobbitlaunch.8 M /branches/4.2.2/common/hobbitlaunch.cfg.5 M /branches/4.2.2/common/hobbitserver.cfg.5 M /branches/4.2.2/common/logfetch.1 M /branches/4.2.2/common/msgcache.8 M /branches/4.2.2/common/orcahobbit.1 M /branches/4.2.2/configure M /branches/4.2.2/configure.client M /branches/4.2.2/configure.server M /branches/4.2.2/debian/changelog M /branches/4.2.2/debian/control M /branches/4.2.2/debian/hobbit-client.init M /branches/4.2.2/debian/hobbit-client.postinst M /branches/4.2.2/debian/hobbit-client.preinst M /branches/4.2.2/debian/hobbit.conffiles M /branches/4.2.2/debian/hobbit.config M /branches/4.2.2/debian/hobbit.logrotate M /branches/4.2.2/debian/hobbit.postinst M /branches/4.2.2/debian/hobbit.preinst M /branches/4.2.2/debian/rules M /branches/4.2.2/docs/about.html M /branches/4.2.2/docs/bb-to-hobbit.html M /branches/4.2.2/docs/criticalsystems.html M /branches/4.2.2/docs/hobbit-alerts.html M /branches/4.2.2/docs/hobbit-config.html M /branches/4.2.2/docs/hobbit-mrtg.html M /branches/4.2.2/docs/howtograph.html M /branches/4.2.2/docs/install.html M /branches/4.2.2/docs/known-issues.html M /branches/4.2.2/docs/man-index.html M /branches/4.2.2/hobbitd/bbcombotest.1 M /branches/4.2.2/hobbitd/bbcombotest.cfg.5 M /branches/4.2.2/hobbitd/client-local.cfg.5 M /branches/4.2.2/hobbitd/etcfiles/bb-hosts.DIST M /branches/4.2.2/hobbitd/etcfiles/client-local.cfg M /branches/4.2.2/hobbitd/etcfiles/columndoc.csv M /branches/4.2.2/hobbitd/etcfiles/hobbit-apache-open.DIST M /branches/4.2.2/hobbitd/etcfiles/hobbit-apache-secure.DIST M /branches/4.2.2/hobbitd/etcfiles/hobbit-clients.cfg M /branches/4.2.2/hobbitd/etcfiles/hobbitcgi.cfg.DIST M /branches/4.2.2/hobbitd/etcfiles/hobbitlaunch.cfg.DIST M /branches/4.2.2/hobbitd/etcfiles/hobbitserver.cfg.DIST M /branches/4.2.2/hobbitd/hobbit-alerts.cfg.5 M /branches/4.2.2/hobbitd/hobbit-clients.cfg.5 M /branches/4.2.2/hobbitd/hobbit-mailack.8 M /branches/4.2.2/hobbitd/hobbitd.8 M /branches/4.2.2/hobbitd/hobbitd_alert.8 M /branches/4.2.2/hobbitd/hobbitd_channel.8 M /branches/4.2.2/hobbitd/hobbitd_client.8 M /branches/4.2.2/hobbitd/hobbitd_filestore.8 M /branches/4.2.2/hobbitd/hobbitd_history.8 M /branches/4.2.2/hobbitd/hobbitd_hostdata.8 M /branches/4.2.2/hobbitd/hobbitd_rrd.8 M /branches/4.2.2/hobbitd/hobbitd_sample.8 M /branches/4.2.2/hobbitd/hobbitfetch.8 M /branches/4.2.2/hobbitd/hobbitweb.5 M /branches/4.2.2/hobbitd/trimhistory.8 M /branches/4.2.2/hobbitd/webfiles/acknowledge_header M /branches/4.2.2/hobbitd/webfiles/bb2_header M /branches/4.2.2/hobbitd/webfiles/bb_footer M /branches/4.2.2/hobbitd/webfiles/bb_header M /branches/4.2.2/hobbitd/webfiles/bbnk_header M /branches/4.2.2/hobbitd/webfiles/bbrep_header M /branches/4.2.2/hobbitd/webfiles/bbsnap2_header M /branches/4.2.2/hobbitd/webfiles/bbsnap_header M /branches/4.2.2/hobbitd/webfiles/bbsnapnk_header M /branches/4.2.2/hobbitd/webfiles/columndoc_header M /branches/4.2.2/hobbitd/webfiles/confreport_front M /branches/4.2.2/hobbitd/webfiles/confreport_header M /branches/4.2.2/hobbitd/webfiles/event_header M /branches/4.2.2/hobbitd/webfiles/findhost_header M /branches/4.2.2/hobbitd/webfiles/ghosts_header M /branches/4.2.2/hobbitd/webfiles/graphs_header M /branches/4.2.2/hobbitd/webfiles/hist_header M /branches/4.2.2/hobbitd/webfiles/histlog_header M /branches/4.2.2/hobbitd/webfiles/hobbitnk_footer M /branches/4.2.2/hobbitd/webfiles/hobbitnk_header M /branches/4.2.2/hobbitd/webfiles/hostgraphs_header M /branches/4.2.2/hobbitd/webfiles/hostsvc_header M /branches/4.2.2/hobbitd/webfiles/info_header M /branches/4.2.2/hobbitd/webfiles/maint_header M /branches/4.2.2/hobbitd/webfiles/maintact_header M /branches/4.2.2/hobbitd/webfiles/nkedit_header M /branches/4.2.2/hobbitd/webfiles/notify_footer M /branches/4.2.2/hobbitd/webfiles/notify_header M /branches/4.2.2/hobbitd/webfiles/replog_header M /branches/4.2.2/hobbitd/webfiles/report_form M /branches/4.2.2/hobbitd/webfiles/report_form_daily M /branches/4.2.2/hobbitd/webfiles/report_form_monthly M /branches/4.2.2/hobbitd/webfiles/report_form_weekly M /branches/4.2.2/hobbitd/webfiles/report_header M /branches/4.2.2/hobbitd/webfiles/snapshot_form M /branches/4.2.2/hobbitd/webfiles/snapshot_header M /branches/4.2.2/hobbitd/webfiles/zoom.js M /branches/4.2.2/hobbitd/wwwfiles/menu/menu_items.js.DIST M /branches/4.2.2/rpm/hobbit.spec M /branches/4.2.2/web/bb-ack.cgi.1 M /branches/4.2.2/web/bb-csvinfo.cgi.1 M /branches/4.2.2/web/bb-datepage.cgi.1 M /branches/4.2.2/web/bb-eventlog.cgi.1 M /branches/4.2.2/web/bb-findhost.cgi.1 M /branches/4.2.2/web/bb-hist.cgi.1 M /branches/4.2.2/web/bb-rep.cgi.1 M /branches/4.2.2/web/bb-replog.cgi.1 M /branches/4.2.2/web/bb-snapshot.cgi.1 M /branches/4.2.2/web/bb-webpage.cgi.1 M /branches/4.2.2/web/hobbit-ackinfo.cgi.1 M /branches/4.2.2/web/hobbit-confreport.cgi.1 M /branches/4.2.2/web/hobbit-enadis.cgi.8 M /branches/4.2.2/web/hobbit-ghosts.cgi.1 M /branches/4.2.2/web/hobbit-hostgraphs.cgi.1 M /branches/4.2.2/web/hobbit-nkedit.cgi.1 M /branches/4.2.2/web/hobbit-nkview.cfg.5 M /branches/4.2.2/web/hobbit-nkview.cgi.1 M /branches/4.2.2/web/hobbit-statusreport.cgi.1 M /branches/4.2.2/web/hobbitcgi.cfg.5 M /branches/4.2.2/web/hobbitgraph.cfg.5 M /branches/4.2.2/web/hobbitgraph.cgi.1 M /branches/4.2.2/web/hobbitsvc.cgi.1 Documentation etc. updates for renaming project to Xymon. ------------------------------------------------------------------------ r5977 | storner | 2008-11-27 14:13:45 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/debian/hobbit.init Add standard stanza for daemon init scripts. ------------------------------------------------------------------------ r5978 | storner | 2008-11-27 14:23:39 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: A /branches/4.2.2/common/xymon.7 (from /branches/4.2.2/common/hobbit.7:5976) Rename "hobbit.7" to "xymon.7" as part of project rename ------------------------------------------------------------------------ r5979 | storner | 2008-11-27 14:24:24 +0100 (Thu, 27 Nov 2008) | 2 lines Changed paths: A /branches/4.2.2/hobbitd/client/bbwin.c M /branches/4.2.2/hobbitd/client_config.c M /branches/4.2.2/hobbitd/client_config.h M /branches/4.2.2/hobbitd/hobbitd_client.c M /branches/4.2.2/hobbitd/rrd/do_disk.c M /branches/4.2.2/hobbitd/rrd/do_ifstat.c M /branches/4.2.2/hobbitd/rrd/do_netstat.c M /branches/4.2.2/hobbitd/rrd/do_vmstat.c M /branches/4.2.2/lib/misc.c M /branches/4.2.2/lib/misc.h Add support for BBWin in centralized mode. ------------------------------------------------------------------------ r5980 | storner | 2008-11-27 14:25:03 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: D /branches/4.2.2/common/hobbit.7 Renamed to xymon.7 ------------------------------------------------------------------------ r5981 | storner | 2008-11-27 14:27:10 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/common/xymon.7 Actually updated the contents of the file for the Xymon rename. ------------------------------------------------------------------------ r5982 | storner | 2008-11-27 14:31:18 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/RELEASENOTES Modified notes for 4.2.2. ------------------------------------------------------------------------ r5983 | storner | 2008-11-27 15:07:06 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/hobbitd/do_rrd.c Drop the BEA and BIND statistics - they never really worked. ------------------------------------------------------------------------ r5984 | storner | 2008-11-27 15:10:26 +0100 (Thu, 27 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/bbdisplay/bbgen.1 M /branches/4.2.2/bbnet/bb-services.5 M /branches/4.2.2/bbnet/bbretest-net.sh.1 M /branches/4.2.2/bbnet/bbtest-net.1 M /branches/4.2.2/bbnet/hobbitping.1 M /branches/4.2.2/bbproxy/bbmessage.cgi.8 M /branches/4.2.2/bbproxy/bbproxy.8 M /branches/4.2.2/common/bb-hosts.5 M /branches/4.2.2/common/bb.1 M /branches/4.2.2/common/bbcmd.1 M /branches/4.2.2/common/bbdigest.1 M /branches/4.2.2/common/bbhostgrep.1 M /branches/4.2.2/common/bbhostshow.1 M /branches/4.2.2/common/clientlaunch.cfg.5 M /branches/4.2.2/common/clientupdate.1 M /branches/4.2.2/common/hobbitclient.cfg.5 M /branches/4.2.2/common/hobbitlaunch.8 M /branches/4.2.2/common/hobbitlaunch.cfg.5 M /branches/4.2.2/common/hobbitserver.cfg.5 M /branches/4.2.2/common/logfetch.1 M /branches/4.2.2/common/msgcache.8 M /branches/4.2.2/common/orcahobbit.1 M /branches/4.2.2/common/xymon.7 M /branches/4.2.2/debian/changelog M /branches/4.2.2/hobbitd/bbcombotest.1 M /branches/4.2.2/hobbitd/bbcombotest.cfg.5 M /branches/4.2.2/hobbitd/client-local.cfg.5 M /branches/4.2.2/hobbitd/hobbit-alerts.cfg.5 M /branches/4.2.2/hobbitd/hobbit-clients.cfg.5 M /branches/4.2.2/hobbitd/hobbit-mailack.8 M /branches/4.2.2/hobbitd/hobbitd.8 M /branches/4.2.2/hobbitd/hobbitd_alert.8 M /branches/4.2.2/hobbitd/hobbitd_channel.8 M /branches/4.2.2/hobbitd/hobbitd_client.8 M /branches/4.2.2/hobbitd/hobbitd_filestore.8 M /branches/4.2.2/hobbitd/hobbitd_history.8 M /branches/4.2.2/hobbitd/hobbitd_hostdata.8 M /branches/4.2.2/hobbitd/hobbitd_rrd.8 M /branches/4.2.2/hobbitd/hobbitd_sample.8 M /branches/4.2.2/hobbitd/hobbitfetch.8 M /branches/4.2.2/hobbitd/hobbitweb.5 M /branches/4.2.2/hobbitd/trimhistory.8 M /branches/4.2.2/include/version.h M /branches/4.2.2/web/bb-ack.cgi.1 M /branches/4.2.2/web/bb-csvinfo.cgi.1 M /branches/4.2.2/web/bb-datepage.cgi.1 M /branches/4.2.2/web/bb-eventlog.cgi.1 M /branches/4.2.2/web/bb-findhost.cgi.1 M /branches/4.2.2/web/bb-hist.cgi.1 M /branches/4.2.2/web/bb-rep.cgi.1 M /branches/4.2.2/web/bb-replog.cgi.1 M /branches/4.2.2/web/bb-snapshot.cgi.1 M /branches/4.2.2/web/bb-webpage.cgi.1 M /branches/4.2.2/web/hobbit-ackinfo.cgi.1 M /branches/4.2.2/web/hobbit-confreport.cgi.1 M /branches/4.2.2/web/hobbit-enadis.cgi.8 M /branches/4.2.2/web/hobbit-ghosts.cgi.1 M /branches/4.2.2/web/hobbit-hostgraphs.cgi.1 M /branches/4.2.2/web/hobbit-nkedit.cgi.1 M /branches/4.2.2/web/hobbit-nkview.cfg.5 M /branches/4.2.2/web/hobbit-nkview.cgi.1 M /branches/4.2.2/web/hobbit-statusreport.cgi.1 M /branches/4.2.2/web/hobbitcgi.cfg.5 M /branches/4.2.2/web/hobbitgraph.cfg.5 M /branches/4.2.2/web/hobbitgraph.cgi.1 M /branches/4.2.2/web/hobbitsvc.cgi.1 Bump version number to 4.2.2 ------------------------------------------------------------------------ r5985 | storner | 2008-11-27 15:34:16 +0100 (Thu, 27 Nov 2008) | 3 lines Changed paths: A /branches/4.2.2/debian/default debian/default had not been checked into SVN. ------------------------------------------------------------------------ r5987 | storner | 2008-11-27 22:40:08 +0100 (Thu, 27 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/build/Makefile.rules Dont try to clean the optional directories ------------------------------------------------------------------------ r5988 | storner | 2008-11-27 22:42:45 +0100 (Thu, 27 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/web/hobbit-confreport.c Fix Config Report (Critical) to work when hosts are in nkview.cfg but have no NK tags in bb-hosts. From Mandriva sources. ------------------------------------------------------------------------ r5989 | storner | 2008-11-27 22:59:07 +0100 (Thu, 27 Nov 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/do_rrd.c A /branches/4.2.2/hobbitd/rrd/do_trends.c "trends" RRD support from http://www.hswn.dk/hobbiton/2007/01/msg00236.html ------------------------------------------------------------------------ r5990 | storner | 2008-11-28 07:43:02 +0100 (Fri, 28 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/build/test-ldap.c Build properly with new OpenLDAP API by using deprecated functions. ------------------------------------------------------------------------ r5991 | storner | 2008-11-28 07:44:53 +0100 (Fri, 28 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/bbnet/contest.c Debian bug #503111: Dont crash on long-living SSL certs. ------------------------------------------------------------------------ r5992 | storner | 2008-11-28 07:47:24 +0100 (Fri, 28 Nov 2008) | 3 lines Changed paths: M /branches/4.2.2/lib/htmllog.c Old BB clients do not send in the "df" header line, so adjust linecount accordingly. From Debian patches for 4.2.0.dfsg-14lenny2. ------------------------------------------------------------------------ r5993 | storner | 2008-11-28 10:18:41 +0100 (Fri, 28 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/lib/url.c The BB proxy-syntax could not handle https target URLs. From Debian. ------------------------------------------------------------------------ r5995 | storner | 2008-11-28 10:27:42 +0100 (Fri, 28 Nov 2008) | 1 line Changed paths: M /branches/4.2.2/bbnet/ldaptest.h Build properly with new OpenLDAP API by using deprecated functions (missed ldaptest.h in previous commit) ------------------------------------------------------------------------ r5996 | storner | 2008-11-28 11:55:16 +0100 (Fri, 28 Nov 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/do_rrd.c M /branches/4.2.2/hobbitd/do_rrd.h M /branches/4.2.2/hobbitd/hobbitd_rrd.8 M /branches/4.2.2/hobbitd/hobbitd_rrd.c M /branches/4.2.2/hobbitd/rrd/do_ncv.c Split-NCV and TRACKMAX support from Charles Goyard (ref: http://www.hobbitmon.com/hobbiton/2007/03/msg00368.html). Taken from the Debian patchset. ------------------------------------------------------------------------ r5997 | storner | 2008-11-28 19:19:10 +0100 (Fri, 28 Nov 2008) | 2 lines Changed paths: M /branches/4.2.2/client/hobbitclient-linux.sh Fix for SuSE being ridiculous with their naming scheme. ------------------------------------------------------------------------ r5998 | storner | 2008-12-01 10:54:58 +0100 (Mon, 01 Dec 2008) | 3 lines Changed paths: M /branches/4.2.2/lib/htmllog.c Dont count lines if there is already a "linecount" HTML comment. ------------------------------------------------------------------------ r5999 | storner | 2008-12-01 10:58:09 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/hobbitd/do_rrd.c M /branches/4.2.2/hobbitd/etcfiles/hobbitgraph.cfg M /branches/4.2.2/hobbitd/etcfiles/hobbitserver.cfg.DIST M /branches/4.2.2/hobbitd/hobbitd_filestore.c A /branches/4.2.2/hobbitd/rrd/do_beastat.c A /branches/4.2.2/hobbitd/rrd/do_dbcheck.c M /branches/4.2.2/hobbitd/rrd/do_disk.c A /branches/4.2.2/hobbitd/rrd/do_fd_lib.c M /branches/4.2.2/hobbitd/rrd/do_la.c A /branches/4.2.2/hobbitd/rrd/do_netapp.c M /branches/4.2.2/lib/htmllog.c M /branches/4.2.2/web/hobbitsvc.c Merge hobbit-perl-client v1.15 server-side patches by Francesco Duranti ------------------------------------------------------------------------ r6000 | storner | 2008-12-01 11:53:35 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/hobbitd/do_rrd.c M /branches/4.2.2/hobbitd/etcfiles/hobbitserver.cfg.DIST M /branches/4.2.2/hobbitd/hobbitd_filestore.c A /branches/4.2.2/hobbitd/rrd/do_devmon.c M /branches/4.2.2/lib/hobbitrrd.c M /branches/4.2.2/lib/htmllog.c M /branches/4.2.2/web/hobbitsvc.c Merged server-side patch for Devmon 0.3.0 ------------------------------------------------------------------------ r6001 | storner | 2008-12-01 12:36:53 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/Changes M /branches/4.2.2/RELEASENOTES Updated to list changes from 4.2.0 to 4.2.2 ------------------------------------------------------------------------ r6002 | storner | 2008-12-01 12:53:04 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/hobbitd/rrd/do_devmon.c DEVMON: Updated with current TRUNK (r90) to fix segfault ------------------------------------------------------------------------ r6007 | storner | 2008-12-01 21:29:05 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/bbnet/hobbitping.c Dont loop indefinitely if we cannot send an ICMP message (backport r5641 from trunk) ------------------------------------------------------------------------ r6008 | storner | 2008-12-01 21:38:26 +0100 (Mon, 01 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/configure.client M /branches/4.2.2/configure.server User information on Darwin queried via dscl instead of nireport, for Leopard support ------------------------------------------------------------------------ r6011 | storner | 2008-12-01 22:10:40 +0100 (Mon, 01 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/do_alert.c Limit size of alert status-texts sent to a script to 4 KB. http://www.hswn.dk/hobbiton/2008/01/msg00015.html ------------------------------------------------------------------------ r6012 | storner | 2008-12-03 07:27:11 +0100 (Wed, 03 Dec 2008) | 4 lines Changed paths: M /branches/4.2.2/lib/acklog.c Alan Sparks noticed a 64-bit integer conversion problem resulting in strange data going into the acknowledgment logs. Patch from http://www.hobbitmon.com/hobbiton/2008/09/msg00038.html Backported from trunk r5815. ------------------------------------------------------------------------ r6013 | storner | 2008-12-03 07:39:43 +0100 (Wed, 03 Dec 2008) | 3 lines Changed paths: M /branches/4.2.2/bbnet/dns.c M /branches/4.2.2/bbnet/dns2.c Prepare bbtest-net for use of later versions of C-ARES. This way they can just be dropped in. Re-do the timeout code for DNS lookups so we'll always wait the full period for DNS timeouts to happen. ------------------------------------------------------------------------ r6014 | storner | 2008-12-04 12:50:05 +0100 (Thu, 04 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/rrd/do_disk.c Compiler warning fix ------------------------------------------------------------------------ r6015 | storner | 2008-12-04 12:54:11 +0100 (Thu, 04 Dec 2008) | 6 lines Changed paths: M /branches/4.2.2/hobbitd/rrd/do_ncv.c Several fixes from Graham Nayler: - Recognize signed numbers as values. - Dont index with -1 in dsname[outidx-1] (if DS name begins with non-alphanum) - Memory leak in split-NCV mode - Skip past any &COLOR text (backported from trunk) ------------------------------------------------------------------------ r6016 | storner | 2008-12-04 13:02:54 +0100 (Thu, 04 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/client/bbwin.c Fix parsing of [clock] section when the epoch reported does not contain a microsecond part. ------------------------------------------------------------------------ r6017 | storner | 2008-12-04 13:32:54 +0100 (Thu, 04 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/lib/loadalerts.c Fix broken handling of what duration to print on the alert-info webpage. ------------------------------------------------------------------------ r6019 | storner | 2008-12-04 13:45:03 +0100 (Thu, 04 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/lib/loadalerts.c Wrong initialization for maxdur ------------------------------------------------------------------------ r6021 | storner | 2008-12-05 12:58:37 +0100 (Fri, 05 Dec 2008) | 1 line Changed paths: A /branches/4.2.2/hobbitd/webfiles/acknowledge_footer A /branches/4.2.2/hobbitd/webfiles/bb2_footer A /branches/4.2.2/hobbitd/webfiles/bbnk_footer A /branches/4.2.2/hobbitd/webfiles/bbrep_footer A /branches/4.2.2/hobbitd/webfiles/bbsnap2_footer A /branches/4.2.2/hobbitd/webfiles/bbsnap_footer A /branches/4.2.2/hobbitd/webfiles/bbsnapnk_footer A /branches/4.2.2/hobbitd/webfiles/columndoc_footer A /branches/4.2.2/hobbitd/webfiles/event_footer A /branches/4.2.2/hobbitd/webfiles/findhost_footer A /branches/4.2.2/hobbitd/webfiles/ghosts_footer A /branches/4.2.2/hobbitd/webfiles/graphs_footer A /branches/4.2.2/hobbitd/webfiles/hist_footer A /branches/4.2.2/hobbitd/webfiles/histlog_footer A /branches/4.2.2/hobbitd/webfiles/hostgraphs_footer A /branches/4.2.2/hobbitd/webfiles/hostsvc_footer A /branches/4.2.2/hobbitd/webfiles/info_footer A /branches/4.2.2/hobbitd/webfiles/maint_footer A /branches/4.2.2/hobbitd/webfiles/maintact_footer A /branches/4.2.2/hobbitd/webfiles/nkedit_footer A /branches/4.2.2/hobbitd/webfiles/replog_footer A /branches/4.2.2/hobbitd/webfiles/report_footer A /branches/4.2.2/hobbitd/webfiles/snapshot_footer Added missing footer-file symlinks ------------------------------------------------------------------------ r6022 | storner | 2008-12-08 13:10:29 +0100 (Mon, 08 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/hobbitd/hobbitd_client.c In testmode, dont strip newlines from logfile input ------------------------------------------------------------------------ r6023 | storner | 2008-12-08 13:13:09 +0100 (Mon, 08 Dec 2008) | 3 lines Changed paths: M /branches/4.2.2/hobbitd/client_config.c Add more debugging to the log-matching code. Make the use/ignore test in the logmatching more intuitively correct. ------------------------------------------------------------------------ r6024 | storner | 2008-12-11 21:48:11 +0100 (Thu, 11 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/configure Make all shell-scripts used during the build be executable. ------------------------------------------------------------------------ r6025 | storner | 2008-12-12 10:46:46 +0100 (Fri, 12 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/configure.server Typo - xmon/xymon. Stef Coene noticed. ------------------------------------------------------------------------ r6026 | storner | 2008-12-15 13:57:54 +0100 (Mon, 15 Dec 2008) | 1 line Changed paths: M /branches/4.2.2/bbdisplay/bbgen.1 M /branches/4.2.2/bbnet/bb-services.5 M /branches/4.2.2/bbnet/bbretest-net.sh.1 M /branches/4.2.2/bbnet/bbtest-net.1 M /branches/4.2.2/bbnet/hobbitping.1 M /branches/4.2.2/bbproxy/bbmessage.cgi.8 M /branches/4.2.2/bbproxy/bbproxy.8 M /branches/4.2.2/common/bb-hosts.5 M /branches/4.2.2/common/bb.1 M /branches/4.2.2/common/bbcmd.1 M /branches/4.2.2/common/bbdigest.1 M /branches/4.2.2/common/bbhostgrep.1 M /branches/4.2.2/common/bbhostshow.1 M /branches/4.2.2/common/clientlaunch.cfg.5 M /branches/4.2.2/common/clientupdate.1 M /branches/4.2.2/common/hobbitclient.cfg.5 M /branches/4.2.2/common/hobbitlaunch.8 M /branches/4.2.2/common/hobbitlaunch.cfg.5 M /branches/4.2.2/common/hobbitserver.cfg.5 M /branches/4.2.2/common/logfetch.1 M /branches/4.2.2/common/msgcache.8 M /branches/4.2.2/common/orcahobbit.1 M /branches/4.2.2/common/xymon.7 A /branches/4.2.2/docs/manpages A /branches/4.2.2/docs/manpages/man1 A /branches/4.2.2/docs/manpages/man1/bb-ack.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-csvinfo.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-datepage.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-eventlog.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-findhost.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-hist.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-rep.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-replog.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-snapshot.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb-webpage.cgi.1.html A /branches/4.2.2/docs/manpages/man1/bb.1.html A /branches/4.2.2/docs/manpages/man1/bbcmd.1.html A /branches/4.2.2/docs/manpages/man1/bbcombotest.1.html A /branches/4.2.2/docs/manpages/man1/bbdigest.1.html A /branches/4.2.2/docs/manpages/man1/bbgen.1.html A /branches/4.2.2/docs/manpages/man1/bbhostgrep.1.html A /branches/4.2.2/docs/manpages/man1/bbhostshow.1.html A /branches/4.2.2/docs/manpages/man1/bbretest-net.sh.1.html A /branches/4.2.2/docs/manpages/man1/bbtest-net.1.html A /branches/4.2.2/docs/manpages/man1/clientupdate.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-ackinfo.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-confreport.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-ghosts.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-hostgraphs.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-nkedit.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-nkview.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbit-statusreport.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbitgraph.cgi.1.html A /branches/4.2.2/docs/manpages/man1/hobbitping.1.html A /branches/4.2.2/docs/manpages/man1/hobbitsvc.cgi.1.html A /branches/4.2.2/docs/manpages/man1/logfetch.1.html A /branches/4.2.2/docs/manpages/man1/orcahobbit.1.html A /branches/4.2.2/docs/manpages/man5 A /branches/4.2.2/docs/manpages/man5/bb-hosts.5.html A /branches/4.2.2/docs/manpages/man5/bb-services.5.html A /branches/4.2.2/docs/manpages/man5/bbcombotest.cfg.5.html A /branches/4.2.2/docs/manpages/man5/client-local.cfg.5.html A /branches/4.2.2/docs/manpages/man5/clientlaunch.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbit-alerts.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbit-clients.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbit-nkview.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitcgi.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitclient.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitgraph.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitlaunch.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitserver.cfg.5.html A /branches/4.2.2/docs/manpages/man5/hobbitweb.5.html A /branches/4.2.2/docs/manpages/man7 A /branches/4.2.2/docs/manpages/man7/xymon.7.html A /branches/4.2.2/docs/manpages/man8 A /branches/4.2.2/docs/manpages/man8/bbmessage.cgi.8.html A /branches/4.2.2/docs/manpages/man8/bbproxy.8.html A /branches/4.2.2/docs/manpages/man8/hobbit-enadis.cgi.8.html A /branches/4.2.2/docs/manpages/man8/hobbit-mailack.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_alert.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_channel.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_client.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_filestore.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_history.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_hostdata.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_rrd.8.html A /branches/4.2.2/docs/manpages/man8/hobbitd_sample.8.html A /branches/4.2.2/docs/manpages/man8/hobbitfetch.8.html A /branches/4.2.2/docs/manpages/man8/hobbitlaunch.8.html A /branches/4.2.2/docs/manpages/man8/msgcache.8.html A /branches/4.2.2/docs/manpages/man8/trimhistory.8.html M /branches/4.2.2/hobbitd/bbcombotest.1 M /branches/4.2.2/hobbitd/bbcombotest.cfg.5 M /branches/4.2.2/hobbitd/client-local.cfg.5 M /branches/4.2.2/hobbitd/hobbit-alerts.cfg.5 M /branches/4.2.2/hobbitd/hobbit-clients.cfg.5 M /branches/4.2.2/hobbitd/hobbit-mailack.8 M /branches/4.2.2/hobbitd/hobbitd.8 M /branches/4.2.2/hobbitd/hobbitd_alert.8 M /branches/4.2.2/hobbitd/hobbitd_channel.8 M /branches/4.2.2/hobbitd/hobbitd_client.8 M /branches/4.2.2/hobbitd/hobbitd_filestore.8 M /branches/4.2.2/hobbitd/hobbitd_history.8 M /branches/4.2.2/hobbitd/hobbitd_hostdata.8 M /branches/4.2.2/hobbitd/hobbitd_rrd.8 M /branches/4.2.2/hobbitd/hobbitd_sample.8 M /branches/4.2.2/hobbitd/hobbitfetch.8 M /branches/4.2.2/hobbitd/hobbitweb.5 M /branches/4.2.2/hobbitd/trimhistory.8 M /branches/4.2.2/web/bb-ack.cgi.1 M /branches/4.2.2/web/bb-csvinfo.cgi.1 M /branches/4.2.2/web/bb-datepage.cgi.1 M /branches/4.2.2/web/bb-eventlog.cgi.1 M /branches/4.2.2/web/bb-findhost.cgi.1 M /branches/4.2.2/web/bb-hist.cgi.1 M /branches/4.2.2/web/bb-rep.cgi.1 M /branches/4.2.2/web/bb-replog.cgi.1 M /branches/4.2.2/web/bb-snapshot.cgi.1 M /branches/4.2.2/web/bb-webpage.cgi.1 M /branches/4.2.2/web/hobbit-ackinfo.cgi.1 M /branches/4.2.2/web/hobbit-confreport.cgi.1 M /branches/4.2.2/web/hobbit-enadis.cgi.8 M /branches/4.2.2/web/hobbit-ghosts.cgi.1 M /branches/4.2.2/web/hobbit-hostgraphs.cgi.1 M /branches/4.2.2/web/hobbit-nkedit.cgi.1 M /branches/4.2.2/web/hobbit-nkview.cfg.5 M /branches/4.2.2/web/hobbit-nkview.cgi.1 M /branches/4.2.2/web/hobbit-statusreport.cgi.1 M /branches/4.2.2/web/hobbitcgi.cfg.5 M /branches/4.2.2/web/hobbitgraph.cfg.5 M /branches/4.2.2/web/hobbitgraph.cgi.1 M /branches/4.2.2/web/hobbitsvc.cgi.1 Update man-page version number and HTML versions of man-pages ------------------------------------------------------------------------ r6027 | storner | 2008-12-15 14:08:28 +0100 (Mon, 15 Dec 2008) | 2 lines Changed paths: M /branches/4.2.2/client/netbsd-meminfo.c Use 64-bit numbers for memory-info, so >2 GB systems are handled correctly. From Tracy Di Marco White. ------------------------------------------------------------------------ Changes from 4.1.2p1 -> 4.2 (10 Aug 2006) ----------------------------------------- New features: * A major overhaul of the "Critical Systems" (NK) webpage. A new hobbit-nkview CGI has been added, allowing much more flexible handling of the NK alerts. This allows the 24x7 monitoring staff to group alerts by priority, filter out acknowledged alerts that have been delegated to resolver groups, to permanently enable or disable a status to appear on their monitoring console when a system goes into or is taken out of production, and also provides direct access to special instructions for the monitoring staff. To accomodate all of these new configuration items, a separate "Critical Systems Configuration" file is introduced, which is separate from the bb-hosts file. A web-based configuration tool - the "hobbit-nkedit" CGI - is also provided, allowing the monitoring operations staff to control what systems appear and how their monitoring is setup. Since hobbit-nkview is a CGI script, the Critical Systems page will now always show a completely up-to-date version of the Hobbit systems status. * The Hobbit client will now report logfile data as part of the client data. Which logfiles to monitor and how much data to send is configured centrally on the Hobbit server, and automatically transmitted to the client when it contacts the Hobbit server. See the logfetch(1) man-page for details. Apart from size limitations, the logfile data is not filtered by the client. * Two new tools - hobbitfetch and msgcache - can be used to implement a "pull" style of clients, which may be useful if you have systems that cannot make network connections to the Hobbit server to deliver their data. See the hobbitfetch(8) man-page for details. * Disabling a status can now be done until the status goes to an OK state. * A "bulletin_header" or "bulletin_footer" file can now be created in the ~hobbit/server/web/ direectory. This will automatically get added to the header or footer of all webpages. * All configuration files now support the use of "include" statements to split the configuration into several files. * All configuration files now support the statement "directory DIRNAME"; this causes all normal files in this directory and below to be included as part of the configuration file. Note that the sequence of files being included in this way is not controllable. * An acknowledgment sent to Hobbit is only deleted after the status has been OK for a while (12 minutes). This allows a status to be acknowledged, then briefly go OK but return to critical shortly after, without resetting the alert timers. * A new "files" status column uses data from the client to monitor file- and directory attributes and sizes. This can be fed into graphs, so you can track the sizes of individual files or directories. * A new "ports" status column uses data from the client to monitor network ports. This can be fed into graphs, so you can track the number of connections to a given service, from a specific IP-address, or in a particular state. This is based on code provided by Mirko Saam. * The Hobbit clients now report network interface statistics. This allows for Hobbit to track network utilisation, like MRTG does. Note that due to limitations in many client operating systems, and the fact that Hobbit only records network statistics every 5 minutes, this is currently limited to approximately 100 Mbit/sec interfaces (Fast Ethernet). Gigabit interfaces are not handled correctly and will show up with much smaller bandwidth usage than what they actually do use. * When a host status goes critical, any client data from the host is saved. This allows detailed analysis of the host status just prior to a critical event happening, which can be helpful for troubleshooting. Improvements: * All of the core programs have been profiled to identify performance bottlenecks. Several optimizations have been implemented; these are definitely noticable when Hobbit is used in large installations (more than 100 hosts). The most noticable effects is a drop of 25-40% in hobbitd CPU utilisation, a 50% drop in CPU utilisation of the hobbitd_client module, and a huge speedup in the hobbit-enadis CGI program. * DOWNTIME can now be applied to individual tests, and you can specify a text explaining why the service is down. The new format in the bb-hosts file is: DOWNTIME=columns:days:starttime:endtime:cause If you have more than one service that you want to set the downtime for, "column" can be "*" to match all services, or you can define multiple downtime-settings: "DOWNTIME=http,ftp:*:0300:0315:CMS update;*:0:0200:0210:Reboot" * Status changes that happen during DOWNTIME periods do not update the last-status-change timestamp in hobbitd. Hence a service that was red before the start of DOWNTIME and stays red during downtime will not appear to be changed recently - so it wont reappear on the NK view when using time-based filters. * A new hobbit-statusreport CGI has been added. This CGI can generate an HTML report of all hosts with a given status column, e.g. all SSL certificates. By using filters, you can pick out those hosts where e.g. the status is non-green. A sample hobbit-certreport.sh script is included that uses this CGI to generate a report of all SSL certificates which are about to expire, i.e. have a red or yellow status. * When using alerts with FORMAT=SMS, the text will now clearly show when the status has RECOVERED. * The hobbitsvc CGI no longer needs to load the bb-hosts file to get information about the hosts' IP-address and display- name. Instead, it gets them from hobbitd as part of the normal request to get the current status. This avoids a lot of file I/O when looking at the detailed status page. * You can now explicitly choose which colors cause a status to appear on the BB2 page, via the "--bb2-colors=COLOR,COLOR" option to bbgen. * When zooming a graph, the legend now states the period that the graph covers. * bb-findhost now includes JavaScript code to make input focus go to the input field immediately. * SSH testing now sends an SSH version string. This should eliminate some logwarnings (note: requires updating of the bb-services file). * All BLUE status handling is now done by hobbitd. As a result, the detailed status shown while a status is BLUE will include the original status message color in the status text, even though the status will show up as blue. * bbhostgrep now support a "--no-down" option to omit hosts that are currently known to be down. This is determined by the current "conn" status. * The hobbit-mailack tool now recognizes ACK codes if given as a line "ack NUMBER" inside the mail body. Also, the duration of the acknowledge can be given through a "delay MINUTES" line in the message body. * The hobbitd client module can now run in a "local" mode, allowing for configurations to be maintained on individual servers. * Historical status logs generated by planned downtime settings now include a notice in the stored status log that the status was blue due to planned downtime. * For the NCV RRD handler, you can now set all datasets to a specific type by listing them as "NCV_foo=*:GAUGE". * The "bbdigest" utility no longer uses the OpenSSL library, and has been included in the client installation. * The "procs" (and "msgs" and "ports") status messages can now be configured to show an understandable legend for each of the checks, instead of the incomprehensible regular expression used to match the process listing. * Individual proces counts (matched through a PROC entry in hobbit-clients.cfg) can be tracked in a graph. * The event-log report can now select hosts based on the page they are on. Bugs: * The hobbitreports.sh script would calculate the wrong year and week-number for the end-of-year weekly reports. * hobbitd_client ignored qualifiers for individual rules. * The "query" command would return the wrong color for a disabled test. * The ncv handler would fail on input lines that had extra text after the value, e.g. "Temp: 23 degrees". * Memory reports from Mac OS X (Darwin) clients were ignored. Other: * The "NK" and "NKTIME" tags in the bb-hosts file have been deprecated with the introduction of the hobbit-nkview CGI. Similarly, the static NK webpage generated from these tags is now deprecated. They will continue to work for some time, but support for these will be removed in a future release of Hobbit. * The acknowledgment system has been redesigned, to allow for acks to happen at multiple levels of operation. E.g. the 24x7 monitoring staff may acknowledge an alert after raising a trouble-ticket, and a technician may acknowledge the same alert when responding to the ticket. This is currently used only by the new Critical Systems page, but a future release will use this for more advanced handling of alerts. * The HTML "Content-type" generated by the Hobbit CGI's can be configured through the HTMLCONTENTTYPE setting. This may be useful for sites where documentation embedded in the Hobbit webpages is in a different character-set, e.g. UTF-8 or Japanese. Changes from 4.1.2p1 -> 4.1.2p2 (02 Aug 2006) --------------------------------------------- Bugfixes: * [SECURITY] "config" commands would allow remote reading of any file accessible by the hobbit user. * Hosts were showing up twice on alternate pageset pages * Several programs would crash if a configuration file had a newline at exactly 4 KB offset into the file * Possible segfault in bbgen due to uninitialised variable. * Malformed history files could cause errors in reporting. * "query" of a disabled status would report the wrong color. Changes from 4.1.2 -> 4.1.2p1 (10 Nov 2005) ------------------------------------------- Bugfixes: * hobbitd could crash when processing a "combo" message, due to an incorrect test of the color of one message inside the combo-message before that color was actually deciphered. * hobbitd_alert would crash when attempting to save a checkpoint while cleaning up a "dead" alert. * Disk graphs would show up with all graphs in a single image, when the status message included any colored icons (typically, when the status was red or yellow). * The handling of alerts was counting the duration of an event based on when the color last changed. This meant that each time the color changed, any DURATION counters were reset. This would cause alerts to not go out if a status was changing between yellow and red faster than any DURATION setting. Changed this to count the event start as the *first* time the status went into an alert state (yellow or red, usually). * An idle hobbitd process would accumulate zombie processes. Improvements: * When a status goes yellow->red, the repeat-interval is now cleared for any alerts. This makes sure you get an alert immediately for the most severe state seen. This only affects the first such transition; if the status later changes between yellow/red, this normal REPEAT interval applies. Changes from 4.1.1 -> 4.1.2 (11 Oct 2005) ----------------------------------------- NOTE: If you are upgrading from 4.1.1, you MUST change the ~hobbit/server/etc/hobbit-clients.cfg file and add a line with the text "DEFAULT" before the default settings in the file. Post-RC1 fixes: * Linux client now runs ps with "-w" to get more of the command line. * Disk status reports from clients are now processed with sed to make sure each mounted filesystem appears on a single line. * A missing "req." text in the "procs" status report was fixed. * Web checks now recognize status "100" as OK. * All of the build scripts using "head -1" now use the POSIX'ly correct "head -n 1" instead. * Documentation update: We do have a client now; the hobbit-clients.cfg man-page was added. Bugfixes: * The hobbit module handling client reports had several bugs in the way it interpreted the hobbit-clients.cfg file. These were fixed, but this necessitated that the default settings are explicitly flagged with a "DEFAULT" line. * When multiple recipients of an alert had different minimum duration and/or repeat-settings, they would mostly use only the settings for the first recipient. * The alert module could continue sending alerts even though the rules in hobbit-alerts.cfg that triggered the alert had been modified. * The hobbitd daemon would leak memory when responding to a "query" request. In extreme circumstances, it could also crash. * The hobbitd_alert module could leak tiny amounts of memory. * The default timeouts on the server- and client-side have been increased to allow some more time to send in status messages. Because of Hobbit's more agressive use of "combo" messages and larger amounts of data, it could timeout prematurely on busy servers. * Hosts flagged with "nobb2" no longer appear in the acknowledge log on the BB2 page. * The size of the shared-memory buffers used to pass data between the core hobbit daemon and the hobbitd_* modules has been increased, allowing for larger messages. These are now also configurable, so you can change them without having to recompile Hobbit (see the MAXMSG_* settings in hobbitserver.cfg(5)). * bbproxy: When sending to multiple servers and the connection to one server fails, continue feeding a message to the other servers instead of dropping it completely. * bbproxy: Rotating the logs will now also rotate the logfile for any debugging output. * The RSS files now escape special characters, to make sure the file has a valid RSS XML syntax. * The "cpu" status from a Hobbit client with a critical load would include texts showing both that the load was "high" and "critical". Changed to include only the most severe condition. * The "ncv" (name-colon-value) data handler could easily read past end of input, and mis-interpret the input data. Fixed by Matti Klock. Build fixes: * An "autoconf" type of script is now used to check for some of the more common build problems. This should make the client build without problems on more platforms. * The "configure" script will now recognize the "hobbit" user on systems using NIS or NIS+. * "make install" would fail to set the proper permissions for the Hobbit client directories. * The pre-built Debian- and RPM-packages failed to flag the client configuration files as such, so they would be overwritten by an upgrade. Note that this fix only takes effect AFTER you have installed the new .deb or .rpm files. * The pre-built Debian- and RPM-packages failed to set permissions on the client logs/ and tmp/ directories. * A separate "hobbit-client" package is now generated in both .rpm and .deb format. * A bug in the "merge-sects" installation utility has been fixed. This could cause the installation to abort prematurely. Server improvements: * The acknowledge log on the BB 2 page now has a configurable max number and max time of the entries listed, via the --max-ackcount and --max-acktime options for bbgen. * The eventlog script now lets you filter out events based on the hostname, testname, color, and start/stop times. Thanks to Eric Schwimmer for contributing this. * The "netstat" statistics module has been upgraded to collect byte-counter statistics for HP-UX, AIX, OSF/1 and *BSD. This might only work with the Hobbit client, not the BB/LARRD bf-netstat module. * A "group-except" definition is now supported in the bb-hosts file, to show all tests EXCEPT certain ones for a group of hosts. * A "noclear" tag has been added. This is the equivalent of defining all network test with the '~' - "always report true status" - flag. * RPC tests now only run if the ping check of the server did not fail. * The default size of the RRD graphs can be defined via the RRDHEIGHT and RRDWIDTH settings in hobbitserver.cfg. * The hobbitgraph CGI can now generate comparison graphs with e.g. the load graphs from multiple hosts. However, a front-end tool for requsting these has not yet been created. * Stale RRD files (.rrd files that haven't been updated for more than 1 day) are no longer included when generating the graphs on the status pages. They still show up if you view the graphs on the "trends" status column. * The hobbit-confreport CGI is now installed correctly, including an item in the "Reports" menu. * The "info" column now include the "uname" data from the Hobbit client, allowing you to see what operating system is running on the host. Client improvements: * The "runclient.sh" script now accepts two command-line options: "--hostname=CLIENT.HOST.NAME" lets you override the default hostname that the client uses when it reports data to Hobbit; "--os=OSNAME" lets you override the operating system name for certain Linux systems. See the README.CLIENT file. * The client is now re-locatable. I.e. you can pack up the "client" directory and move it to another box or another location for easier deployment of the client on multiple boxes running the same operating system. * Client installations on NIS-based systems should now work. * AIX is now supported - has been tested with 4.3.3 and 5.x. * OSF/1 is now supported (4.x and 5.x) * HP-UX support should work * Darwin / Mac OS X is now supported. * {Free,Net,Open}BSD-based systems failed to build the meminfo tool, so memory reporting was broken. * Solaris clients now reports all types of filesystems (notably "vxfs" filesystems were omitted before). * The client configuration now lets you check for filesystems that MUST be mounted. * The clients now switch locale to use the POSIX locale - previously the system locale was used, which could result in status messages in languages that the backend did not expect. Other: * A new utility "demotool" can be used to simulate a number of servers to Hobbit. This may be useful when demonstrating Hobbit to new users. Note: This is not included in the default build - to build it, run "make demo-build". Changes from 4.1.0 -> 4.1.1 (25 Jul 2005) ----------------------------------------- Bugfixes: * The Hobbit client mis-interpreted the "df" output from filesystems with longer-than-usual device names (e.g. network-mounted filesystems, resulting in some rather incredible values for the disk utilisation. * hobbitsvc.cgi could crash if some of the input parameters from the URL were missing. This would only happen if you accessed it via a URL that was not created by Hobbit. * The hobbitlaunch.cfg file for the server was missing a line, causing it to run the local client much more often than intended. * A faulty initialisation when reloading the Hobbit daemon state could leave a broken pointer in a log-record. If this was then accessed by a "hobbitdxboard" or a "drop" command, hobbitd would crash. Build problems: * The "configure" script failed on certain systems with a "cannot shift" error. * Building the client on systems without the PCRE headers would fail. * Building Hobbit - client or server - would fail on a system if the PCRE headers were in a non-standard location. Changes from 4.0.4 -> 4.1.0 (24 Jul 2005) ----------------------------------------- A Hobbit client for Unix systems has been implemented, and this was found important enough to warrant bumping the version number to 4.1. The README.CLIENT file has the details on how to use it. The client is automatically installed as part of a server installation. Server bugfixes: * [SECURITY] The Hobbit daemon (hobbitd) could crash when processing certain types of messages. It is believed that this could only be used for a denial-of-service attack against Hobbit, although it cannot completely be ruled out that an attacker might be able to exploit it to run arbitrary code with the privileges of the hobbit user. Thanks to Vernon Everett and Stefan Loos for their efforts in helping me track down these bugs. * Workaround a bug in KHTML based browsers (KDE's Konqueror, Mac OS X Safari) when generating reports: They cannot handle "multipart/mixed" documents, but only offer to save the document instead of sending you off to the report URL. * Fix a build problem on OpenBSD: Apparently OpenBSD's linker does not recognize the --rpath option. * A memory leak in the Hobbit daemon has been fixed (it would leak memory upon each reload of the bb-hosts file, which is done every 5 minutes). * Status messages using "&green" or another color in the first line of the status message would display the "&green" text instead of the color GIF image. * bbtest-net's collection of DNS responses has been delayed until an actual test is queued. Previously, a host with a "testip" flag could end up with a DNS lookup which doesn't really make sense. * Handling of the "notrends" tag was broken. * The duration string should no longer be included in the webpage showing a disabled test. (Only applies to tests disabled after installing Hobbit 4.0.5). * bbtest-net now reports "Hobbit" in the User-Agent header of all web requests, instead of "BigBrother". * If an alert was configured to be sent only during certain periods of time, the recovery message would be suppressed if the recovery happened outside of the alerting period. Changed so that recovery messages ignore the time-based restrictions. * hobbit-mailack would generate ack's valid for 30 minutes, instead of the documented 60 minutes. Changed to use 60 minutes. * An off-by-one error in the routine generating the HTML document headers and footers was caught by Valgrind. * A number of minor documentation fixes. * Memory reports from Win32 clients using the Big Brother client could trigger an overflow when calculating the memory usage, resulting in memory utilization being reported as 0. Changed to use a larger internal representation for the memory sizes. Server improvements: * A new reporting tool, hobbit-confreport.cgi, provides a way of generating a printable report summarizing the Hobbit monitoring configuration for a single server or a group of servers. * If a "custom" directory exists, you can have custom Hobbit tools located there and have them built during the normal build proces. * A status handed off to the hobbitd_alert module, but for which there is no alert recipient configured, would be re-checked every minute causing a heavy spike in the CPU load if there were many such statuses. A small code change allows us to skip these until the configuration file changes. * The code handling lookups of data from the bb-hosts file was changed to access the data via a tree-based search instead of a linear search. On large systems this provides a much more efficient retrieval of these data, reducing the overall load of Hobbit. * The internal representation of status-data inside the hobbitd daemon now uses a more efficient tree-structure instead of a simple linked list. * The NETFAILTEXT environment variable can be used to change the "not OK" text added to status messages of failed network tests. * External commands used in network testing (ntpdate, rpcinfo, traceroute) now have max. 30 seconds to complete. This is to avoid a broken ntpdate or similar to lock up the network tests. The "--cmdtimeout=N" option controls the length of the timeout. * hobbitlaunch no longer logs every task started to the hobbitlaunch.log file - this could result in the log file growing to huge proportions. The "--verbose" option for hobbitlaunch will restore the old behaviour, if needed. * A number of arbitrary limits on the size of various buffers, messages, queries and responses have been removed. Hobbit will now handle status-messages of practically any size, except that the interface between the main daemon and the worker modules (handling history, RRD files and alerts) is limited to 100 KB message size. Configuration files (bb-hosts, hobbit-alerts.cfg, hobbitserver.cfg, hobbitlaunch.cfg) can have lines of any length. Continuation lines are now supported in all configuration files. * The moverrd.sh is now included in the default installation. * OpenBSD vmstat output now supported. LARRD / Hobbit cleanup: Upon request from Craig Cook, the code and docs were changed to clarify that Hobbit and LARRD are not related. I therefore decided to remove references to "LARRD" in the configuration files, resulting in these changes: * LARRDCOLUMN renamed to TRENDSCOLUMN, and LARRDS renamed to TEST2RRD in hobbitserver.cfg (handled automatically by "make install"). * The bb-hosts "LARRD:" tag was renamed to "TRENDS:". Existing bb-hosts files using the old tag still work, though. * The hobbitd_larrd program were renamed to hobbitd_rrd. The default hobbitlaunch.cfg file was also changed to reflect this, and the names of the logfiles from the two RRD update tasks were changed as well. All of this should happen automatically when running "make install", but if you have added extra options - e.g. for custom graphs - then you may need to re-do those modifications in hobbitlaunch.cfg. Changes from 4.0.3 -> 4.0.4 (29 May 2005) ----------------------------------------- Bugfixes: * "nodisp" tag re-implemented for hosts that should not appear on the Hobbit webpages. * Enabling the "apache" data collection could crash bbtest-net if the /server-status page returned was larger than 32 KB. * The "bbcmd" tool would not pass a --debug option to the command it was running. * Nested macros in hobbit-alerts.cfg were not working. * Using TAB's in hobbit-alerts.cfg could confuse the alert module. * hobbitd_alert's --test option now determines the page-name for a host automatically. It will also now accept a time-parameter to simulate how alerts are processed at specific time-of-day. * Status messages from "dialup" hosts should not go purple. * The "mailq" RRD handler would pick up the first number from the "requests" line, which might not be the right number. * Scheduling a "disable" did not work. * The startup-script was modified to correctly handle stale PID files left over from an unclean shutdown of Hobbit. These are now removed, and startup will proceed normally. Improvements: * CGI tools now log error-output to dedicated logs in /var/log/hobbit/ * The "bea-snmpstats.sh" script has been removed, and replaced with an enhanced tool "beastat". This collects statistics via SNMP from BEA Weblogic servers, and reports these via "data" messages to Hobbit. The data collected are run-time data for the JRockIT JVM and thread/memory utilization data from each Weblogic server instance. * The "ntpstat" RRD handler now accepts the raw output from "ntpq -c rv" * The heartbeat-timeout for hobbitd has been increased to 60 seconds. Changes from 4.0.2 -> 4.0.3 (22 May 2005) ----------------------------------------- Bugfixes (general): * The bb-datepage and bbmessage CGI tools were reading the POST data in an incorrect way; it worked on most systems, but did not adhere to the CGI specification. Bugfixes (alerting): * Acknowledgments were broken in 4.0.2. * Using PAGE=... in hobbit-alerts.cfg to pick out hosts on the front-page was not possible. The front page is now recognized with the name "/", so PAGE=/ will find them. * The hobbitd_alert --test option would not pick up the correct page-path settings from the bb-hosts file. * The BBALPHAMSG text passed to scripts as a default alert message now includes the URL link to the statuslog. Bugfixes (graphs and trends): * hobbitgraph.cgi could show "@RRDPARAM@" on graphs if it was matched by a NULL string (would happen for mailq graphs). * RRD files were not being updated while a status was blue (disabled), even though status messages were received. Changed so that blue logs are passed off to the RRD * The "disk1" graph definition failed to take into account that the numbers logged were already in KB of data. So the axis-label was wrong. parser - we might as well track data when it's there. * The "mailq" RRD handler now finds the queue-length regardless of whether it is before or after the "requests" keyword in the "mailq" or "nmailq" status message. * If the "apache" data collection was specified for a host, but the host had no "http" tests, a bogus http status report was being generated. * Network statistics used a conversion that would overflow on 32-bit systems. Bugfixes (web pages): * Some header/footer files for the snapshot report were missing. * The "info_header" and "info_footer" files were not being used for the "info" column pages. Bugfixes (installation): * Fix file-descriptor leak in the "setup-newfiles" tool used during installation. This could cause "make install" to abort while installing new files, on systems with a low setting for the max. number of simultaneous open files. * Some systems keep libraries in a /lib64 directory - this was not being searched by the configure script. * If Hobbit was built without SSL support and an SSL network test is configured, it will now always fail with a meaningful error message. * If the configure script found SSL- or LDAP-libraries, but these could not link, the build would not disable SSL- and LDAP-support and therefore it failed. If the libraries do not work, disable the support. * The SSL test would link without required network support libraries on some platforms. * The options for overriding SSL- and LDAP-include files did not match the documented name. * AIX systems built with gcc were missing the OSDEF compile- flags. Improvements: * All remnants of Big Brother compatibility have been removed. If you want to stick with the old Big Brother tool, use bbgen. This allowed for some much needed cleaning up of the bbgen code that loaded the status data, especially for the handling of purple status logs. Also, the sending of messages has dropped all support for the Big Brother method of sending "page" messages when a status-message is sent with an alert-color, so the BBPAGE and BBPAGERS settings are no longer used. * The maint.pl script has been removed. A new tool, hobbit-enadis.cgi, replaces this with a native Hobbit tool. If you are upgrading, you should change the ~/server/www/menu/menu_items.js file to point link to "hobbit-enadis.sh" instead of "maint.pl". * The "info" column page now includes a form to disable and enable tests for a single host. If you prefer not to have this on the info page, add the option "--no-disable" to the hobbit-cgi/bb-hostsvc.sh wrapper. * Some logfiles have been moved to the normal log-file directory - /var/log/hobbit: - nkstatus.log (from ~hobbit/server/) - notifications.log (from ~hobbit/data/acks/) - acklog (from ~hobbit/data/acks), also renamed to acknowledge.log * The hobbit-mailack CGI will now find a "delay=DURATION" line in the mail message, and use that as the duration of the acknowledgment. Reports show that there are some types of mail/SMS systems where you cannot modify the message subject. * Paul D. Backer contributed "favicon" images generated from the Hobbit "recent" GIF files. These have been added and are now loaded from the Hobbit web/*_header files, so that browsers supporting this (Mozilla, Firefox) will display a favicon-image in the titlebar or on the page-tab holding the Hobbit webpage. * Two new settings in hobbitserver.cfg can be used to restrict which filesystems are being tracked by Hobbit. The NORRDDISKS / RRDDISKS settings are regular-expressions that the filesystem names are matched against. See the hobbitserver.cfg(5) man-page. * Hobbit now works with RRDtool 1.2.x. Due to a bug in the first 1.2.x releases of RRDtool, you must use at least version 1.2.2 with Hobbit. * A new report-output option lets you save a CSV (comma- separated values) file with the availability data for each host+test in Hobbit. This allows for further processing of the availability data eg. importing it into a spreadsheet. This can be selected from the report request webpage. * It is now possible to define different values for an environment setting in hobbitserver.cfg, depending on a new "--area=..." command-line option for all tools. See hobbitserver.cfg. * Apache 1.x performance data are now graphed correctly, by mapping the "BusyServers/IdleServers" data into the BusyWorkers/IdleWorkers datasets used by Apache 2.0 RRD graphs. * sendmail RRD's for sendmail 8.13+ now tracks the number of "quarantined" messages also. You must delete any existing sendmail.rrd files for this new data item to be tracked. * All RRD-updates now use the RRDtool "--template" option to map values to RRD datasets. This should keep us from updating datasets with wrong values. * Graphs can now get their title from a script, instead of using a static string in hobbitgraph.cfg. This lets you e.g. pick up the graphtitle from the mrtg.cfg. * All CGI's now pick up command-line options from a new configuration file, hobbitcgi.cfg. This is to ease packaging and make sure the CGI's can be updated without losing local configurations. * The debian- and rpm-specific packaging files are now included in the distribution tarfile. * A historical status-log now includes a "Full History" button to go to the history overview. * "irix" is now recognized as operating system. A preliminary vmstat RRD will be generated, but this may change in a future version. "netstat" reports are not yet handled. Changes from 4.0 -> 4.0.2 (10 Apr 2005) --------------------------------------- Bugfixes: * "meta" reports could crash hobbitd. * Parsing of HTTP responses could crash bbtest-net. * Eventlog entries from hosts not in bb-hosts would crash the eventlog CGI reporting tool. * bbgen would crash when FQDN was set to FALSE (not default) and a host was in bb-hosts with the fully-qualified name. * The external rrd-module might launch more than one script simultaneously, which resulted in the status message being lost. * AS/400 disk reports were not handled correctly by the RRD module, since the format was different from what was expected. * bbtest-net would do DNS lookups of hostnames when run with the "--dns=ip" option, causing a severe slowdown. * When viewing historical disk reports from Unix systems, the "Status unchanged in ..." message might be included in the last line of the disk status report, instead of being on a line by itself at the bottom of the page. * "badconn" tags were not being recognized. Eric Schwimmer found the problem and even provided a patch. * On Solaris, the HOME environment variable may not be defined if Hobbit is started from a bootup-script. This caused network tests to stop running. * Historical logs that are saved when a host is disabled or goes purple would not reflect the blue/purple color, but the color of the status before it was disabled or went purple. * A spelling error in the hobbitgraph.cfg file caused the hobbitgraph CGI to crash when trying to generate mailq graphs. * Some BSD systems do not have an atoll() routine, which broke compilation of the hobbitd_larrd module. Switched to use Hobbit's own atoll() for this platform. * Duration-times could be mis-reported on the "info" page, due to some bad math done when building this page. Improvements: * In bb-hosts you can now define a host called ".default." - the tags set for this host will be the default tag settings for the following hosts (until a new .default. host appears). * Merged the bb-infocolumn and bb-larrdcolumn functionality into the service-display CGI, and make bb-hostsvc into a Hobbit-only CGI called hobbitsvc.cgi. The bb-infocolumn and bb-larrdcolumn binaries have been removed. * --alertcolors, --okcolors and --repeat options for hobbitd, hobbitd_alert and bb-infocolumn were moved to settings in hobbitserver.cfg (ALERTCOLORS, OKCOLORS and ALERTREPEAT respectively). * A new generic RRD handler was added for name-colon-value reports. This can be used to handle RRD tracking of reports where the data is in lines of the form "Name: Value". * New "notrends" tag for bb-hosts entries drops the "trends" tag for a host (similar to the "noinfo" tag). * New "DOC:" tag for bb-hosts entries lets you set a documentation URL for each host, or as a default using the ".default." hostname. The --docurl option on bb-infocolumn (which no longer exists) has been dropped. * Included the "hobbitreports.sh" script to show how reports can be pre-generated by a cron-job. * New "bb-datepage.cgi" CGI makes it easy to select daily/weekly/monthly pre-generated reports. * The hobbitgraph CGI now allows you to show weekday- and month-names in your local language, instead of forcing it to english. Note that the fonts used may not include all non-ASCII characters. * CPU-reports from the bb-xsnmp.pl script should now be handled correctly by the RRD module. * CPU-reports for z/VM should now be handled correctly by the RRD module. * CPU-, disk- and memory-reports from the nwstats2bb script are now handled by the RRD module. Changes from 4.0 -> 4.0.1 (31 Mar 2005) --------------------------------------- Bugfixes: * Compiling Hobbit on some platforms would fail due to a couple of missing standard include files not being pulled in. Changes from RC-6 -> 4.0 (30 Mar 2005) -------------------------------------- Bugfixes: * DOWNTIME handling was broken in some cases. While fixing this, it was also enhanced to allow multiple day-specifications in a single time-specification, e.g. "60:2200:2330" is now valid way of defining downtime between 10 PM and 11:30 PM on Saturday and Sunday. * If bbtest-net was run with "--dns=ip" option to disable DNS lookups, a DHCP host could not be tested. Changed so that hosts with a "0.0.0.0" IP-address always do a DNS lookup to determine the IP-address for network tests. * Links in the RSS file were missing a trailing slash. * Disk- and CPU-reports from AS/400 based systems were not handled properly by the RRD parser. Note that this change means the PCRE library is now needed for the hobbitd_larrd module. * The default hobbitlaunch.cfg had the environment path for the bbcombotest task hard-coded, instead of picking up the configuration value. * Back out the cookie-based filtering of hosts in the Enable/Disable (maint.pl) script - it breaks in too many places. Need further investigation. * Alert rules with the STOP and UNMATCHED keywords now flag this on the info-page alert table. * If a host was removed from the bb-hosts file, and hobbitd reloaded the file before a "drop" command was sent, then it was impossible to get rid of the internal state stored for the host without restarting Hobbit. * Disabled status-logs could go purple while still being disabled, this would show up as the status alternating between blue and purple. Improvements: * If invoking fping failed, the error message was lost and only a "failed with exit code 99" error was reported. Changed so that the real cause of the error is reported in the bbtest-net log. * An "mrtg" definition was added to hobbitgraph.cfg, to handle MRTG generated RRD files. If MRTG is configured to save RRD files directly to the Hobbit rrd-directory, these graphs can be handled as if they were native Hobbit graphs. Wrote up hobbit-mrtg.html to describe this setup. * When hosts are removed from the bb-hosts file, all in-memory data stored about the host is dropped automatically, so e.g. alerts will no longer be sent out. Data stored on disk is unaffected; this only gets removed when a "drop" command is issued. * Time-specifications now accept multiple week-days, e.g. you can define a host that is down Sunday and Monday 20:00->23:00 with "DOWNTIME=01:2000:2300". This applies globally, so also applies to alert-specifications and other time-related settings using the NKTIME syntax. It will also complain rather loudly in the logfile is an invalid time-specification is found in one of the configuration files. * hobbit-mailack added to the HTML man-page index and to the overview description in hobbit(7). * A new "trimhistory" tool was added, allowing you to trim the size of history logs and historical status-log collections. Changes from RC-5 -> RC-6 ------------------------- Bugfixes: * Recovery messages were sent to all recipients, regardless of any color-restrictions on the alerts they received. Changed this so that recipients only get recovery messages for the alerts they received. * The "NOALERT" option was not applied when multiple recipients were listed in one rule. * bbtest-net now performs a syntax check on all URL's before adding them to the test queue. This should stop it from crashing in case you happen to enter a syntactically invalid URL in your bb-hosts file. * The acknowledgment log on the BB2 page could mix up data from different entries in the log. * The default mail-utility used to send out e-mail alerts is now defined per OS. Solaris and HP-UX use "mailx", others use "mail". * Client tests no longer go purple when a host has been disabled. * bb-larrdcolumn no longer dumps core if there are no RRD files. * With the right input, bb-larrdcolumn could use massive amounts of memory and eventually terminate with an out-of-memory error. * A memory leak in hobbitd_larrd handling of "disk" reports was fixed. * bb-infocolumn now accepts a "--repeat=N" setting to inform it of the default alert-repeat interval. If you use --repeat with hobbitd_alert, you should copy that option to bb-infocolumn to make it generate correct info-column pages. * If bbgen cannot create output files or directories, the underlying error is now reported in the error message. * The "merge-lines" and "merge-sects" tools used during installation could crash due to a missing initialization of a pointer. Improvements: * It is now possible to make Hobbit re-open all logfiles, e.g. after a log rotate. Use "server/hobbit.sh rotate". * The hobbit-mailack tool now recognizes the BB format of alert message responses, i.e. putting "delay" and "msg" in the subject line will work. * bbcmd defaults to running /bin/sh if no command is given * hobbitd_larrd now logs the sender IP of a message that results in an error. * A network test definition for SpamAssassin's spamd daemon was added. * The default web/*header files now refer to a HOBBITLOGO setting for the HTML used in the upper-left corner of all pages. The default is just the text "Hobbit", but you can easily replace this with e.g. a company logo by changing this setting in hobbitserver.cfg. * The Hobbit daemon's "hobbitdboard", "hobbitdxboard" and "hobbitdlist" commands now support a set of primitive filtering techniques to limit the number of hosts returned. * maint.pl uses the new Hobbit daemon filtering and a cookie defined by the header in webpages to show only the hosts found on the page where it was called from, or just a single host. * Hobbit should now compile on Mac OS X (Darwin). * The info- and graph-column names are now defined globally as environment variables "INFOCOLUMN" and "LARRDCOLUMN", respectively. This eliminates the need to have them listed as options for multiple commands. Consequently, the --larrd and --info options have been dropped. * Systems with the necessary libraries (RRDtool, PCRE, OpenSSL etc) in unusual locations can now specify the location of these as parameters to the configure script, overriding the auto-detect routine. See "./configure --help" for details. * A definition for the "disk1" graph in LARRD was added, this shows the actual use of filesystems instead of the normal percentage. Changes from RC-4 -> RC-5 ------------------------- Bugfixes: * Very large status- or data-messages could overflow the shared memory segment used for communication between hobbitd and the worker modules. This would cause hobbitd to crash. Such messages are now truncated before being passed off to worker modules. * hobbitd_alert no longer crashes when trying to send a message. * Recovery messages were sent, even when no alert message had been sent. This caused unexpected "green" messages. * The router dependency "route" tag handling was broken. Improvements: * The "starthobbit.sh" script now refuses to start Hobbit if it is already running. * The "starthobbit.sh" script was renamed to just "hobbit.sh". It now also supports a "reload" command that causes hobbitd to reload the bb-hosts file. * The bb-hist CGI now supports the NAME tag for naming hosts. * The history CGI's showed the Host- and service-names twice when in Hobbit mode. Once is enough. * A "NOALERT" setting in hobbit-alerts.cfg was implemented, so it is easier to define recipients who only get notice-messages and not alerts. * The input parameter check for CGI scripts was relaxed, so that special characters are permitted - e.g. when passing a custom hostname to a CGI. Since we do not use any shell scripts in CGI handling, this should not cause any security problem. Building Hobbit: * The /opt/sfw directory is now searched for libraries (Solaris). * The order of libssl and libcrypto has been swapped, to avoid linker problems on some platforms. Changes from RC-3 -> RC-4 ------------------------- Bugfixes: * Loading the bb-services file no longer causes bbtest-net, hobbitd_larrd et al to crash. * The alert configuration loader was fixed, so that recipient criteria are applied correctly. * hobbitd_alert handling of "recovered" status messages was slightly broken. This was probably the cause of the unexpected "green" alerts that some have reported. * SCRIPT recipients can now have a "@" in their names without being silently treated as MAIL recipients. * An acknowledge message is now cleared when the status changes to an OK color (defined by the --okcolors option). Previously it would have to go "green" before the ack was cleared. * Acked and disabled statuses can not go purple while the acknowledge or disable is valid. This was causing brief flickers of purple for tests that were disabled for more than 30 minutes. * maint.pl "combo" message support was dropped. This was causing runtime warnings, and it has never been possible to send enable or disable messages inside combo's (neither with Hobbit nor BB). Building Hobbit: * bb-infocolumn should build without problems again. * The "configure" script now also looks in /opt/csw for tools and libraries (for Solaris/x86) * An OpenBSD Makefile was contributed. * The gcc option "-Wl,--rpath" is now used when linking the tools on Linux and *BSD. This should resolve a lot of the issues with runtime libraries that cannot be found. * "configure" now looks for your perl utility, and adjusts the maint.pl script accordingly. * HP-UX does not have an atoll() routine. So a simple implementation of this routine was added. Configuration file changes: * hobbitlaunch.cfg now supports a DISABLED keyword to shut off unwanted tasks. This permits upgrading without having to re-disable stuff. * All commands in hobbitserver.cfg are now quoted, so it can be sourced by the CGI scripts without causing errors. Note that this is NOT automatically changed in an existing configuration file. Improvements: * The detailed status display now lets you define what graphs should be split onto multiple graph images (the "--multigraphs" option for bb-hostsvc.cgi and hobbitd_filestore). Currently the "disk", "inode" and "qtree" graphs are handled this way. * The detailed status display now includes a line showing how long an acknowledgment is valid. This is configurable via the ACKUNTILMSG setting in hobbitserver.cfg. * A new "notify" message is supported as part of the Hobbit protocol. This takes a normal hostname+testname paramater, plus a text message; this is sent out as an informational message using the hobbit-alerts.cfg rules to determine recipients. This replaces the BB "notify-admin" recipient with a more fine-grained and configurable system. Currently used by maint.pl when enabling and disabling tests. * Alert scripts now receive a CFID environment variable with the linenumber of the hobbit-alerts.cfg file that caused this alert to go out. * A new tool - hobbit-mailack - was added. If setup to run from e.g. the Hobbit users' .procmailrc file, you can acknowledge alerts by responding to an alert email. * Temperature reports now accept additional text in parenthesis without being confused. Changes from RC-2 -> RC-3 ------------------------- Configuration file changes: * The bb-services file format was changed slightly. Instead of "service foo" to define a service, it is now "[foo]". Existing files will be converted automatically by "make install". * The name of the "conn" column (for ping-tests) is used throughout Hobbit, and had to be set in multiple locations. Changed all of them to use the setting from the PINGCOLUMN environment variable, and added this to hobbitserver.cfg. * The --purple-conn option was dropped from hobbitd. It should be removed from hobbitlaunch.cfg. * The --ping=COLUMNNAME option for bbtest-net should not be used any more. "--ping" enables the ping tests, the name of the column is taken from the PINGCOLUMN variable. * The GRAPHS setting in hobbitserver.cfg no longer needs to have the simple TCP tests defined. These are automatically picked up from the bb-services file. Bugfixes: * hobbitd no longer crashes, if the MACHINE name from hobbitserver.cfg is not listed in bb-hosts. Thanks to Stephen Beaudry for helping me track down this bug. * If hobbitd crashed, then hobbitlaunch would attempt to restart it immediately. Added a 5 second delay, so that there's time for the OS to clean up any open sockets, files etc that might prevent a restart from working. * The "disk" RRD handler could be confused by reports from a Unix server, and mistake it for a report from a Windows server. This caused the report to try and store data in an RRD file with an invalid filename, so no graph-data was being stored. * The "cpu" and "disk" RRD handlers were enhanced to support reports from the "filerstats2bb" script for monitoring NetApp systems. The disk-handler also supports the "inode" and "qtree" reports from the same script. * bb-services was overwritten by a "make install". This wiped out custom network test definitions. * bbnet would crash if you happened to define a "http" or "https" test instead of using a full URL. * bbnet was mis-calculating the size of the URL used for th apache-test. This could cause it to overflow a buffer and crash. * hobbitd would ignore the BBPORT setting and always default to using port 1984. * Portability problems on HP-UX 11 should be resolved. From reports it appears that building RRDtool on HP-UX 11 is somewhat of a challenge; however, the core library is all that Hobbit needs, so build-problems with the Perl modules can be ignored as far as Hobbit is concerned. * hobbitd_alert could not handle multiple recipients for scripts, and mistakenly assumed all recipients with a "@" were for e-mail recipients. * Alert messages no longer include the " * bb-xsnmp.pl Version: 1.78 */ p = strstr(msg, "CPU Usage="); if (p) { p += strlen("CPU Usage="); gotload = 1; load = atoi(p); } goto done_parsing; } else if (strstr(msg, "z/VM") || strstr(msg, "VSE/ESA") || strstr(msg, "z/VSE") || strstr(msg, "z/OS")) { /* z/VM cpu message. Looks like this, from Rich Smrcina (client config mode): * green 5 Apr 2005 20:07:34 CPU Utilization 7% z/VM Version 4 Release 4.0, service level 0402 (32-bit) AVGPROC-007% 01 * VSE/ESA or z/VSE cpu message. * VSE/ESA 2.7.2 cr IPLed on ... * or * z/VSE 3.1.1 cr IPLed on ... * In server (centralized) config mode or for z/OS (which is centralized config only) * the operating system name is part of the message (as in the tests above). */ int ovector[30]; char w[100]; int res; if (zVM_exp == NULL) { const char *errmsg = NULL; int errofs = 0; zVM_exp = pcre_compile(".* CPU Utilization *([0-9]+)%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(zVM_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } goto done_parsing; } eoln = strchr(msg, '\n'); if (eoln) *eoln = '\0'; p = strstr(msg, "up: "); if (!p) p = strstr(msg, "Uptime:"); /* Netapp filerstats2bb script */ if (!p) p = strstr(msg, "uptime:"); if (p) { /* First line of cpu report, contains "up: 159 days, 1 users, 169 procs, load=21" */ p = strchr(p, ','); if (p) { gotusers = (sscanf(p, ", %d users", &users) == 1); p = strchr(p+1, ','); } if (p) { gotprocs = (sscanf(p, ", %d procs", &procs) == 1); p = strchr(p+1, ','); } /* * Load can be either * - "load=xx%" (Windows) * - "load=xx.xx" (Unix, DISPREALLOADAVG=TRUE) * - "load=xx" (Unix, DISPREALLOADAVG=FALSE) * * We want the load in percent (Windows), or LA*100 (Unix). */ p = strstr(msg, "load="); if (p) { p += 5; if (strchr(p, '%')) { gotload = 1; load = atoi(p); } else if (strchr(p, '.')) { gotload = 1; load = 100*atoi(p); /* Find the decimal part, and cut off at 2 decimals */ p = strchr(p, '.'); if (strlen(p) > 3) *(p+3) = '\0'; load += atoi(p+1); } else { gotload = 1; load = atoi(p); } } } else { /* * No "uptime" in message - could be from an AS/400. They look like this: * green March 21, 2005 12:33:24 PM EST deltacdc 108 users 45525 jobs(126 batch,0 waiting for message), load=26% */ int ovector[30]; char w[100]; int res; if (as400_exp == NULL) { const char *errmsg = NULL; int errofs = 0; as400_exp = pcre_compile(".* ([0-9]+) users ([0-9]+) jobs.* load=([0-9]+)\\%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(as400_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the AS/400 data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { users = atoi(w); gotusers = 1; } *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 3, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } } done_parsing: if (eoln) *eoln = '\n'; p = strstr(msg, "System clock is "); if (p) { if (sscanf(p, "System clock is %d seconds off", &clockdiff) == 1) gotclock = 1; } if (!gotload) { /* See if it's a report from the ciscocpu.pl script. */ p = strstr(msg, "
CPU 5 min average:"); if (p) { /* It reports in % cpu utilization */ p = strchr(p, ':'); load = atoi(p+1); gotload = 1; } } if (gotload) { setupfn("%s.rrd", "la"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, load); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotprocs) { setupfn("%s.rrd", "procs"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, procs); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotusers) { setupfn("%s.rrd", "users"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, users); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotclock) { setupfn("%s.rrd", "clock"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, clockdiff); create_and_update_rrd(hostname, testname, classname, pagepaths, clock_params, clock_tpl); } /* * If we have run for less than 6 minutes, drop the memory updates here. * We want to be sure not to use memory statistics from the CPU report * if there is a memory add-on sending a separate memory statistics */ if ((now - starttime) < 360) return 0; if (!memhosts_init || (xtreeFind(memhosts, hostname) == xtreeEnd(memhosts))) { /* Pick up memory statistics */ int found, overflow, realuse, swapuse; long long phystotal, physavail, pagetotal, pageavail; found = overflow = realuse = swapuse = 0; phystotal = physavail = pagetotal = pageavail = 0; p = strstr(msg, "Total Physical memory:"); if (p) { phystotal = str2ll(strchr(p, ':') + 1, NULL); if (phystotal != LONG_MAX) found++; else overflow++; } if (found == 1) { p = strstr(msg, "Available Physical memory:"); if (p) { physavail = str2ll(strchr(p, ':') + 1, NULL); if (physavail != LONG_MAX) found++; else overflow++; } } if (found == 2) { p = strstr(msg, "Total PageFile size:"); if (p) { pagetotal = str2ll(strchr(p, ':') + 1, NULL); if (pagetotal != LONG_MAX) found++; else overflow++; } } if (found == 3) { p = strstr(msg, "Available PageFile size:"); if (p) { pageavail = str2ll(strchr(p, ':') + 1, NULL); if (pageavail != LONG_MAX) found++; else overflow++; } } if (found == 4) { if (!phystotal || !pagetotal) { errprintf("Host %s cpu report had 0 total physical/pagefile memory listed\n", hostname); return 0; } phystotal = phystotal / 100; pagetotal = pagetotal / 100; realuse = 100 - (physavail / phystotal); swapuse = 100 - (pageavail / pagetotal); do_memory_rrd_update(tstamp, hostname, testname, classname, pagepaths, realuse, swapuse, -1); } else if (overflow) { errprintf("Host %s cpu report overflows in memory usage calculation\n", hostname); } } return 0; } xymon-4.3.30/xymond/rrd/do_external.c0000664000076400007640000001127512000025440017751 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2009 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char external_rcsid[] = "$Id: do_external.c 7026 2012-07-13 14:05:20Z storner $"; int do_external_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { pid_t childpid; dbgprintf("-> do_external(%s, %s)\n", hostname, testname); childpid = fork(); if (childpid == 0) { FILE *fd; char fn[PATH_MAX]; enum { R_DEFS, R_FN, R_DATA, R_NEXT } pstate; FILE *extfd; char extcmd[2*PATH_MAX]; strbuffer_t *inbuf; char *p; char **params = NULL; int paridx = 0; pid_t mypid = getpid(); MEMDEFINE(fn); MEMDEFINE(extcmd); snprintf(fn, sizeof(fn), "%s/rrd_msg_%d", xgetenv("XYMONTMP"), (int) getpid()); dbgprintf("%09d : Saving msg to file %s\n", (int)mypid, fn); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot create temp file %s\n", fn); exit(1); } if (fwrite(msg, strlen(msg), 1, fd) != 1) { errprintf("Error writing to file %s: %s\n", fn, strerror(errno)); exit(1) ; } if (fclose(fd)) errprintf("Error closing file %s: %s\n", fn, strerror(errno)); /* * Disable the RRD update cache. * We cannot use the cache, because this child * process terminates without flushing the cache, * and it cannot feed the update-data back to the * parent process which owns the cache. So using * an external handler means the updates will be * sync'ed to disk immediately. * * NB: It is OK to do this now and not re-enable it, * since we're running in the external helper * child process - so this only affects the current * update. * * Thanks to Graham Nayler for the analysis. */ use_rrd_cache = 0; inbuf = newstrbuffer(0); /* Now call the external helper */ snprintf(extcmd, sizeof(extcmd), "%s %s %s %s", exthandler, hostname, testname, fn); dbgprintf("%09d : Calling helper script %s\n", (int)mypid, extcmd); extfd = popen(extcmd, "r"); if (extfd) { pstate = R_DEFS; initfgets(extfd); while (unlimfgets(inbuf, extfd)) { p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; dbgprintf("%09d : Helper input '%s'\n", (int)mypid, STRBUF(inbuf)); if (STRBUFLEN(inbuf) == 0) continue; if (pstate == R_NEXT) { /* After doing one set of data, allow script to re-use the same DS defs */ if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* New DS definitions, scratch the old ones */ if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); params = NULL; } pstate = R_DEFS; } else pstate = R_FN; } switch (pstate) { case R_DEFS: if (params == NULL) { params = (char **)calloc(1, sizeof(char *)); paridx = 0; } if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* Dataset definition */ params[paridx] = strdup(STRBUF(inbuf)); paridx++; params = (char **)realloc(params, (1 + paridx)*sizeof(char *)); params[paridx] = NULL; break; } else { /* No more DS defs */ pstate = R_FN; } /* Fall through */ case R_FN: setupfn("%s", STRBUF(inbuf)); pstate = R_DATA; break; case R_DATA: snprintf(rrdvalues, sizeof(rrdvalues)-1, "%d:%s", (int)tstamp, STRBUF(inbuf)); rrdvalues[sizeof(rrdvalues)-1] = '\0'; create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); pstate = R_NEXT; break; case R_NEXT: /* Should not happen */ break; } } pclose(extfd); } else { errprintf("Pipe open of RRD handler failed: %s\n", strerror(errno)); } if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); } dbgprintf("%09d : Unlinking temp file\n", (int)mypid); unlink(fn); freestrbuffer(inbuf); exit(0); } else if (childpid > 0) { /* Parent continues */ } else { errprintf("Fork failed in RRD handler: %s\n", strerror(errno)); } dbgprintf("<- do_external(%s, %s)\n", hostname, testname); return 0; } xymon-4.3.30/xymond/rrd/do_fd_lib.c0000664000076400007640000001127111535424634017366 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2006 Francesco Duranti */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ /* Some function used by do_netapp.pl do_beastat.pl and do_dbcheck.pl */ static char fd_lib_rcs[] = "$Id: do_fd_lib.c 6648 2011-03-08 13:05:32Z storner $"; unsigned long get_kb_data(char *msg,char *search) { char *p,*r,*eoln; unsigned long value=0; /* go to the start of the message */ p = strstr(msg, search); if (p) { /* set the endofline */ eoln = strchr(p, '\n'); if (eoln) *eoln = '\0'; /* search for a ":" or "=" */ if ((r = strchr(p,':')) == NULL) r=strchr(p,'='); // dbgprintf("1getdata %s\n",p); // dbgprintf("2getdata %s\n",r); if (r) { r++; value=atol(r); /* Convert to KB if there's a modifier after the numbers */ r += strspn(r, "0123456789. "); if (*r == 'M') value *= 1024; else if (*r == 'G') value *= (1024*1024); else if (*r == 'T') value *= (1024*1024*1024); } /* reset the endofline */ if (eoln) *eoln = '\n'; } return value; } unsigned long get_long_data(char *msg,char *search) { char *p,*r,*eoln; unsigned long value=0; /* go to the start of the message */ p = strstr(msg, search); if (p) { /* set the endofline */ eoln = strchr(p, '\n'); if (eoln) *eoln = '\0'; /* search for a ":" or "=" */ if ((r = strchr(p, ':')) == NULL) r=strchr(p, '='); // dbgprintf("1getdata %s\n",p); // dbgprintf("2getdata %s\n",r); if (r) { value=atol(++r); } /* reset the endofline */ if (eoln) *eoln = '\n'; } return value; } double get_double_data(char *msg,char *search) { char *p,*r,*eoln; double value=0; /* go to the start of the message */ p = strstr(msg, search); if (p) { /* set the endofline */ eoln = strchr(p, '\n'); if (eoln) *eoln = '\0'; /* search for a ":" or "=" */ if ((r = strchr(p,':')) == NULL) r=strchr(p,'='); // dbgprintf("1getdata %s\n",p); // dbgprintf("2getdata %s\n",r); if (r) value=atof(++r); /* reset the endofline */ if (eoln) *eoln = '\n'; } return value; } int get_int_data(char *msg,char *search) { char *p,*r,*eoln; int value=0; /* go to the start of the message */ p = strstr(msg, search); if (p) { /* set the endofline */ eoln = strchr(p, '\n'); if (eoln) *eoln = '\0'; /* search for a ":" or "=" */ if ((r = strchr(p,':')) == NULL) r=strchr(p,'='); // dbgprintf("\n1getdata\n%s\n",p); // dbgprintf("\n2getdata\n%s\n",r); if (r) value=atoi(++r); /* reset the endofline */ if (eoln) *eoln = '\n'; } return value; } typedef struct sectlist_t { char *sname; char *sdata; struct sectlist_t *next; } sectlist_t; sectlist_t *sections = NULL; void splitmsg(char *clientdata) { char *cursection, *nextsection; char *sectname, *sectdata; /* Free the old list */ if (sections) { sectlist_t *swalk, *stmp; swalk = sections; while (swalk) { stmp = swalk; swalk = swalk->next; xfree(stmp); } sections = NULL; } if (clientdata == NULL) { errprintf("Got a NULL client data message\n"); return; } /* Find the start of the first section */ if (*clientdata == '[') cursection = clientdata; else { cursection = strstr(clientdata, "\n["); if (cursection) cursection++; } while (cursection) { sectlist_t *newsect = (sectlist_t *)malloc(sizeof(sectlist_t)); /* Find end of this section (i.e. start of the next section, if any) */ nextsection = strstr(cursection, "\n["); if (nextsection) { *nextsection = '\0'; nextsection++; } /* Pick out the section name and data */ sectname = cursection+1; sectdata = sectname + strcspn(sectname, "]\n"); *sectdata = '\0'; sectdata++; if (*sectdata == '\n') sectdata++; /* Save the pointers in the list */ newsect->sname = sectname; newsect->sdata = sectdata; newsect->next = sections; sections = newsect; /* Next section, please */ cursection = nextsection; } } char *getdata(char *sectionname) { sectlist_t *swalk; for (swalk = sections; (swalk && strcmp(swalk->sname, sectionname)); swalk = swalk->next) ; if (swalk) return swalk->sdata; return NULL; } xymon-4.3.30/xymond/rrd/do_paging.c0000664000076400007640000000556612000025440017402 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles "paging" messages. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* Copyright (C) 2007-2008 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char paging_rcsid[] = "$Id: do_paging.c 7026 2012-07-13 14:05:20Z storner $"; static char *paging_params[] = { "DS:rate:GAUGE:600:0:U", NULL }; static void *paging_tpl = NULL; int do_paging_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *pr; char *fn = NULL; int pagerate, xstore, migrate; if (paging_tpl == NULL) paging_tpl = setup_template(paging_params); pr=(strstr(msg, "Rate")); if (pr) { pr += 5; sscanf(pr, "%d per", &pagerate); setupfn("paging.pagerate.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, pagerate); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); if (strstr(msg, "z/VM")) { /* Additional handling for z/VM */ pr=strstr(msg,"XSTORE-"); if (pr) { /* Extract values if we find XSTORE in results of 'IND' command */ pr += 7; /* Add 7 to get past literal (XSTORE). */ sscanf(pr, "%d/SEC", &xstore); pr=strstr(msg,"MIGRATE-"); pr += 8; /* Add 8 to get past literal (MIGRATE). */ sscanf(pr, "%d/SEC", &migrate); setupfn("paging.xstore.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, xstore); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); setupfn("paging.migrate.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, migrate); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); } } } return 0; } xymon-4.3.30/xymond/rrd/do_iishealth.c0000664000076400007640000000457012000025440020101 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char iishealth_rcsid[] = "$Id: do_iishealth.c 7026 2012-07-13 14:05:20Z storner $"; int do_iishealth_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *iishealth_params[] = { "DS:realmempct:GAUGE:600:0:U", NULL }; static void *iishealth_tpl = NULL; char *bol, *eoln, *tok; if (iishealth_tpl == NULL) iishealth_tpl = setup_template(iishealth_params); bol = strchr(msg, '\n'); if (bol) bol++; else return 0; while (bol && *bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; tok = strtok(bol, " \t\r\n"); /* Get color marker */ if (tok) tok = strtok(NULL, " \t\r\n"); /* Get keyword */ if (tok) { int havedata = 0; if (strcmp(tok, "Connections:") == 0) { tok = strtok(NULL, " \t\r\n"); if (tok == NULL) continue; setupfn2("%s.%s.rrd", "iishealth", "connections"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu", (int)tstamp, atol(tok)); havedata = 1; } else if (strcmp(tok, "RequestsQueued:") == 0) { tok = strtok(NULL, " \t\r\n"); if (tok == NULL) continue; setupfn2("%s.%s.rrd", "iishealth", "requestqueued"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu", (int)tstamp, atol(tok)); havedata = 1; } else if (strcmp(tok, "Sessions:") == 0) { tok = strtok(NULL, " \t\r\n"); if (tok == NULL) continue; setupfn2("%s.%s.rrd", "iishealth", "sessions"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu", (int)tstamp, atol(tok)); havedata = 1; } if (havedata) create_and_update_rrd(hostname, testname, classname, pagepaths, iishealth_params, iishealth_tpl); } bol = (eoln ? eoln+1 : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_counts.c0000664000076400007640000000504512000025440017440 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles various "counts" messages. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char counts_rcsid[] = "$Id: do_counts.c 7026 2012-07-13 14:05:20Z storner $"; static int do_one_counts_rrd(char *counttype, char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp, char *params[], char *tpl) { char *boln, *eoln; boln = strchr(msg, '\n'); if (boln) boln++; while (boln && *boln) { char *fn, *countstr = NULL; eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; fn = strtok(boln, ":"); if (fn) countstr = strtok(NULL, ":"); if (fn && countstr) { char *p; for (p=strchr(fn, '/'); (p); p = strchr(p, '/')) *p = ','; setupfn2("%s.%s.rrd", counttype, fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s", (int)tstamp, countstr); create_and_update_rrd(hostname, testname, classname, pagepaths, params, tpl); } boln = (eoln ? eoln+1 : NULL); } return 0; } static char *counts_params[] = { "DS:count:GAUGE:600:0:U", NULL }; static void *counts_tpl = NULL; static char *derive_params[] = { "DS:count:DERIVE:600:0:U", NULL }; static void *derive_tpl = NULL; int do_counts_rrd(char *counttype, char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { if (counts_tpl == NULL) counts_tpl = setup_template(counts_params); return do_one_counts_rrd(counttype, hostname, testname, classname, pagepaths, msg, tstamp, counts_params, counts_tpl); } int do_derives_rrd(char *counttype, char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { if (derive_tpl == NULL) derive_tpl = setup_template(derive_params); return do_one_counts_rrd(counttype, hostname, testname, classname, pagepaths, msg, tstamp, derive_params, derive_tpl); } xymon-4.3.30/xymond/rrd/do_xymonnet.c0000664000076400007640000000305412000025440020004 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char xymonnet_rcsid[] = "$Id: do_xymonnet.c 7026 2012-07-13 14:05:20Z storner $"; int do_xymonnet_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymonnet_params[] = { "DS:runtime:GAUGE:600:0:U", NULL }; static void *xymonnet_tpl = NULL; char *p; float runtime; if (xymonnet_tpl == NULL) xymonnet_tpl = setup_template(xymonnet_params); p = strstr(msg, "TIME TOTAL"); if (p && (sscanf(p, "TIME TOTAL %f", &runtime) == 1)) { if (strcmp("xymonnet", testname) != 0) { setupfn2("%s.%s.rrd", "xymonnet", testname); } else { setupfn("%s.rrd", "xymonnet"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int) tstamp, runtime); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_snmpmib.c0000664000076400007640000001623412003234710017601 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char snmpmib_rcsid[] = "$Id: do_snmpmib.c 7105 2012-07-23 11:47:20Z storner $"; static time_t snmp_nextreload = 0; typedef struct snmpmib_param_t { char *name; char **valnames; char **dsdefs; rrdtpldata_t *tpl; int valcount; } snmpmib_param_t; static void * snmpmib_paramtree; int is_snmpmib_rrd(char *testname) { time_t now = getcurrenttime(NULL); xtreePos_t handle; mibdef_t *mib; oidset_t *swalk; int i; if (now > snmp_nextreload) { int updated = readmibs(NULL, 0); if (updated) { if (snmp_nextreload > 0) { /* Flush the old params and templates */ snmpmib_param_t *walk; int i; for (handle = xtreeFirst(snmpmib_paramtree); (handle != xtreeEnd(snmpmib_paramtree)); handle = xtreeNext(snmpmib_paramtree, handle)) { walk = (snmpmib_param_t *)xtreeData(snmpmib_paramtree, handle); if (walk->valnames) xfree(walk->valnames); for (i=0; (i < walk->valcount); i++) xfree(walk->dsdefs[i]); if (walk->dsdefs) xfree(walk->dsdefs); /* * We don't free the "tpl" data here. We cannot do it, because * there are probably cached RRD updates waiting to use this * template - so freeing it would cause all sorts of bad behaviour. * It DOES cause a memory leak ... */ xfree(walk); } xtreeDestroy(snmpmib_paramtree); } snmpmib_paramtree = xtreeNew(strcasecmp); } snmp_nextreload = now + 600; } mib = find_mib(testname); if (!mib) return 0; handle = xtreeFind(snmpmib_paramtree, mib->mibname); if (handle == xtreeEnd(snmpmib_paramtree)) { snmpmib_param_t *newitem = (snmpmib_param_t *)calloc(1, sizeof(snmpmib_param_t)); int totalvars; newitem->name = mib->mibname; for (swalk = mib->oidlisthead, totalvars = 1; (swalk); swalk = swalk->next) totalvars += swalk->oidcount; newitem->valnames = (char **)calloc(totalvars, sizeof(char *)); newitem->dsdefs = (char **)calloc(totalvars, sizeof(char *)); for (swalk = mib->oidlisthead, newitem->valcount = 0; (swalk); swalk = swalk->next) { for (i=0; (i <= swalk->oidcount); i++) { char *datatypestr = NULL, *minimumstr = NULL; if (swalk->oids[i].rrdtype == RRD_NOTRACK) continue; switch (swalk->oids[i].rrdtype) { case RRD_TRACK_GAUGE: datatypestr = "GAUGE"; minimumstr = "U"; break; case RRD_TRACK_ABSOLUTE: datatypestr = "ABSOLUTE"; minimumstr = "U"; break; case RRD_TRACK_COUNTER: datatypestr = "COUNTER"; minimumstr = "0"; break; case RRD_TRACK_DERIVE: datatypestr = "DERIVE"; minimumstr = "0"; break; case RRD_NOTRACK: break; } if (!datatypestr || !minimumstr) continue; newitem->valnames[newitem->valcount] = swalk->oids[i].dsname; newitem->dsdefs[newitem->valcount] = (char *)malloc(strlen(swalk->oids[i].dsname) + 20); sprintf(newitem->dsdefs[newitem->valcount], "DS:%s:%s:600:%s:U", swalk->oids[i].dsname, datatypestr, minimumstr); newitem->valcount++; } } newitem->valnames[newitem->valcount] = NULL; newitem->dsdefs[newitem->valcount] = NULL; newitem->tpl = setup_template(newitem->dsdefs); xtreeAdd(snmpmib_paramtree, newitem->name, newitem); } return 1; } static void do_simple_snmpmib(char *hostname, char *testname, char *classname, char *pagepaths, char *fnkey, char *msg, time_t tstamp, snmpmib_param_t *params, int *pollinterval) { char *bol, *eoln; char **values; int valcount = 0; values = (char **)calloc(params->valcount, sizeof(char *)); bol = msg; while (bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; bol += strspn(bol, " \t"); if (*bol == '\0') { /* Nothing */ } else if (strncmp(bol, "Interval=", 9) == 0) { *pollinterval = atoi(bol+9); } else if (strncmp(bol, "ActiveIP=", 9) == 0) { /* Nothing */ } else { char *valnam, *valstr = NULL; valnam = strtok(bol, " ="); if (valnam) valstr = strtok(NULL, " ="); if (valnam && valstr) { int validx; for (validx = 0; (params->valnames[validx] && strcmp(params->valnames[validx], valnam)); validx++) ; /* Note: There may be items which are not RRD data (eg text strings) */ if (params->valnames[validx]) { values[validx] = (isdigit(*valstr) ? valstr : "U"); valcount++; } } } bol = (eoln ? eoln+1 : NULL); } if (valcount == params->valcount) { int i; char *ptr; if (fnkey) setupfn2("%s.%s.rrd", testname, fnkey); else setupfn("%s.rrd", testname); setupinterval(*pollinterval); ptr = rrdvalues + snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); for (i = 0; (i < valcount); i++) { ptr += snprintf(ptr, sizeof(rrdvalues)-(ptr-rrdvalues), ":%s", values[i]); } create_and_update_rrd(hostname, testname, classname, pagepaths, params->dsdefs, params->tpl); } xfree(values); } static void do_tabular_snmpmib(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp, snmpmib_param_t *params) { char *fnkey; int pollinterval = 0; char *boset, *eoset, *intvl; boset = strstr(msg, "\n["); if (!boset) return; /* See if there's a poll interval value */ *boset = '\0'; boset++; intvl = strstr(msg, "Interval="); if (intvl) pollinterval = atoi(intvl+9); while (boset) { fnkey = boset+1; boset = boset + strcspn(boset, "]\n"); *boset = '\0'; boset++; eoset = strstr(boset, "\n["); if (eoset) *eoset = '\0'; do_simple_snmpmib(hostname, testname, classname, pagepaths, fnkey, boset, tstamp, params, &pollinterval); boset = (eoset ? eoset+1 : NULL); } } int do_snmpmib_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { time_t now = getcurrenttime(NULL); mibdef_t *mib; xtreePos_t handle; snmpmib_param_t *params; int pollinterval = 0; char *datapart = msg; if (now > snmp_nextreload) readmibs(NULL, 0); mib = find_mib(testname); if (!mib) return 0; handle = xtreeFind(snmpmib_paramtree, mib->mibname); if (handle == xtreeEnd(snmpmib_paramtree)) return 0; params = (snmpmib_param_t *)xtreeData(snmpmib_paramtree, handle); if (params->valcount == 0) return 0; if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Skip the first line of full status- and data-messages. */ datapart = strchr(msg, '\n'); if (datapart) datapart++; else datapart = msg; } if (mib->tabular) do_tabular_snmpmib(hostname, testname, classname, pagepaths, datapart, tstamp, params); else do_simple_snmpmib(hostname, testname, classname, pagepaths, NULL, datapart, tstamp, params, &pollinterval); return 0; } xymon-4.3.30/xymond/rrd/do_beastat.c0000664000076400007640000003031513033575046017571 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2006 Francesco Duranti */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char beastat_rcsid[] = "$Id: do_beastat.c 7999 2017-01-06 02:00:06Z jccleaver $"; int do_beastat_jta_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jta_params[] = { "DS:ActiveTrans:GAUGE:600:0:U", "DS:SecondsActive:DERIVE:600:0:U", "DS:TransAbandoned:DERIVE:600:0:U", "DS:TransCommitted:DERIVE:600:0:U", "DS:TransHeuristics:DERIVE:600:0:U", "DS:TransRBackApp:DERIVE:600:0:U", "DS:TransRBackResource:DERIVE:600:0:U", "DS:TransRBackSystem:DERIVE:600:0:U", "DS:TransRBackTimeout:DERIVE:600:0:U", "DS:TransRBack:DERIVE:600:0:U", "DS:TransTotCount:DERIVE:600:0:U", NULL }; static void *beastat_jta_tpl = NULL; unsigned long heapfree=0, heapsize=0; unsigned long acttrans=0, secact=0, trab=0, trcomm=0, trheur=0, totot=0; unsigned long trrbapp=0, trrbres=0, trrbsys=0, trrbto=0, trrb=0, trtot=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jta_tpl == NULL) beastat_jta_tpl = setup_template(beastat_jta_params); acttrans=get_long_data(msg,"ActiveTransactionsTotalCount"); secact=get_long_data(msg,"SecondsActiveTotalCount"); trab=get_long_data(msg,"TransactionAbandonedTotalCount"); trcomm=get_long_data(msg,"TransactionCommittedTotalCount"); trheur=get_long_data(msg,"TransactionHeuristicsTotalCount"); trrbapp=get_long_data(msg,"TransactionRolledBackAppTotalCount"); trrbres=get_long_data(msg,"TransactionRolledBackResourceTotalCount"); trrbsys=get_long_data(msg,"TransactionRolledBackSystemTotalCount"); trrbto=get_long_data(msg,"TransactionRolledBackTimeoutTotalCount"); trrb=get_long_data(msg,"TransactionRolledBackTotalCount"); trtot=get_long_data(msg,"TransactionTotalCount"); dbgprintf("beastat: host %s test %s acttrans %ld secact %ld\n", hostname, testname, acttrans, secact); dbgprintf("beastat: host %s test %s TRANS: aband %ld comm %ld heur %ld total\n", hostname, testname, trab, trcomm, trheur, trtot); dbgprintf("beastat: host %s test %s RB: app %ld res %ld sys %ld timeout %ld total %ld\n", hostname, testname, trrbapp, trrbres, trrbsys, trrbto, trrb); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, acttrans, secact, trab, trcomm, trheur, trrbapp, trrbres, trrbsys, trrbto, trrb, trtot); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jta_params, beastat_jta_tpl); } return 0; } int do_beastat_jvm_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jvm_params[] = { "DS:HeapFreeCurrent:GAUGE:600:0:U", "DS:HeapSizeCurrent:GAUGE:600:0:U", NULL }; static void *beastat_jvm_tpl = NULL; unsigned long heapfree=0, heapsize=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jvm_tpl == NULL) beastat_jvm_tpl = setup_template(beastat_jvm_params); heapfree=get_long_data(msg, "HeapFreeCurrent"); heapsize=get_long_data(msg,"HeapSizeCurrent"); dbgprintf("beastat: host %s test %s heapfree %ld heapsize %ld\n", hostname, testname, heapfree, heapsize); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld", (int) tstamp, heapfree, heapsize); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jvm_params, beastat_jvm_tpl); } return 0; } int do_beastat_jms_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jms_params[] = { "DS:CurrConn:GAUGE:600:0:U", "DS:HighConn:GAUGE:600:0:U", "DS:TotalConn:DERIVE:600:0:U", "DS:CurrJMSSrv:GAUGE:600:0:U", "DS:HighJMSSrv:GAUGE:600:0:U", "DS:TotalJMSSrv:DERIVE:600:0:U", NULL }; static void *beastat_jms_tpl = NULL; unsigned long conncurr=0, connhigh=0, conntotal=0, jmscurr=0, jmshigh=0, jmstotal=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jms_tpl == NULL) beastat_jms_tpl = setup_template(beastat_jms_params); conncurr=get_long_data(msg, "ConnectionsCurrentCount"); connhigh=get_long_data(msg,"ConnectionsHighCount"); conntotal=get_long_data(msg,"ConnectionsTotalCount"); jmscurr=get_long_data(msg,"JMSServersCurrentCount"); jmshigh=get_long_data(msg,"JMSServersHighCount"); jmstotal=get_long_data(msg,"JMSServersTotalCount"); dbgprintf("beastat: host %s test %s conncurr %ld connhigh %ld conntotal %ld\n", hostname, testname, conncurr, connhigh, conntotal); dbgprintf("beastat: host %s test %s jmscurr %ld jmshigh %ld jmstotal %ld\n", hostname, testname, jmscurr, jmshigh,jmstotal); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, conncurr, connhigh, conntotal, jmscurr, jmshigh, jmstotal); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jms_params, beastat_jms_tpl); } return 0; } int do_beastat_exec_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_exec_params[] = { "DS:ExecThrCurrIdleCnt:GAUGE:600:0:U", "DS:ExecThrTotalCnt:GAUGE:600:0:U", "DS:PendReqCurrCnt:GAUGE:600:0:U", "DS:ServReqTotalCnt:DERIVE:600:0:U", NULL }; static void *beastat_exec_tpl = NULL; static char *checktest = "Type=ExecuteQueueRuntime"; char *curline; char *eoln; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { if (beastat_exec_tpl == NULL) beastat_exec_tpl = setup_template(beastat_exec_params); /* ---- Full Status Report ---- Type=ExecuteQueueRuntime - Location=admin - Name=weblogic.kernel.System */ curline=strstr(msg, "---- Full Status Report ----"); if (curline) { eoln = strchr(curline, '\n'); curline = (eoln ? (eoln+1) : NULL); } while (curline) { unsigned long currthr=0, totthr=0,currprq=0,totservrq=0; char *start=NULL, *execname=NULL, *nameptr=NULL; if ((start = strstr(curline,checktest))==NULL) break; if ((eoln = strchr(start, '\n')) == NULL) break; *eoln = '\0'; if ((nameptr=strstr(start,"Name=")) == NULL ) { dbgprintf("do_beastat.c: No name found in host %s test %s line %s\n", hostname,testname,start); goto nextline; } execname=xstrdup(nameptr+5); *eoln = '\n'; start=eoln+1; if ((eoln = strstr(start,checktest))==NULL) eoln=strstr(start,"dbcheck.pl"); if (eoln) *(--eoln)='\0'; setupfn2("%s,%s.rrd",testname,execname); currthr=get_long_data(start, "ExecuteThreadCurrentIdleCount"); totthr=get_long_data(start,"ExecuteThreadTotalCount"); currprq=get_long_data(start,"PendingRequestCurrentCount"); totservrq=get_long_data(start,"ServicedRequestTotalCount"); dbgprintf("beastat: host %s test %s name %s currthr %ld totthr %ld currprq %ld totservrq %ld\n", hostname, testname, execname, currthr, totthr, currprq, totservrq); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld", (int) tstamp, currthr, totthr, currprq, totservrq); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_exec_params, beastat_exec_tpl); if (execname) { xfree(execname); execname = NULL; } nextline: if (eoln) *(eoln)='\n'; curline = (eoln ? (eoln+1) : NULL); } } return 0; } int do_beastat_jdbc_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jdbc_params[] = { "DS:ActConnAvgCnt:GAUGE:600:0:U", "DS:ActConnCurrCnt:GAUGE:600:0:U", "DS:ActConnHighCnt:GAUGE:600:0:U", "DS:WtForConnCurrCnt:GAUGE:600:0:U", "DS:ConnDelayTime:GAUGE:600:0:U", "DS:ConnLeakProfileCnt:GAUGE:600:0:U", "DS:LeakedConnCnt:GAUGE:600:0:U", "DS:MaxCapacity:GAUGE:600:0:U", "DS:NumAvailable:GAUGE:600:0:U", "DS:NumUnavailable:GAUGE:600:0:U", "DS:HighNumAvailable:GAUGE:600:0:U", "DS:HighNumUnavailable:GAUGE:600:0:U", "DS:WaitSecHighCnt:GAUGE:600:0:U", "DS:ConnTotalCnt:DERIVE:600:0:U", "DS:FailToReconnCnt:DERIVE:600:0:U", "DS:WaitForConnHighCnt:GAUGE:600:0:U", NULL }; static void *beastat_jdbc_tpl = NULL; static char *checktest = "Type=JDBCConnectionPoolRuntime"; char *curline; char *eoln; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { if (beastat_jdbc_tpl == NULL) beastat_jdbc_tpl = setup_template(beastat_jdbc_params); /* ---- Full Status Report ---- Type=ExecuteQueueRuntime - Location=admin - Name=weblogic.kernel.System */ curline=strstr(msg, "---- Full Status Report ----"); if (curline) { eoln = strchr(curline, '\n'); curline = (eoln ? (eoln+1) : NULL); } while (curline) { unsigned long acac=0, accc=0, achc=0, wfccc=0, cdt=0, clpc=0, lcc=0; unsigned long mc=0, na=0, nu=0, hna=0, hnu=0, wshc=0, ctc=0, ftrc=0, wfchc=0; char *start=NULL, *execname=NULL, *nameptr=NULL; if ((start = strstr(curline,checktest))==NULL) break; if ((eoln = strchr(start, '\n')) == NULL) break; *eoln = '\0'; if ((nameptr=strstr(start,"Name=")) == NULL ) { dbgprintf("do_beastat.c: No name found in host %s test %s line %s\n", hostname,testname,start); goto nextline; } execname=xstrdup(nameptr+5); *eoln = '\n'; start=eoln+1; if ((eoln = strstr(start,checktest))==NULL) eoln=strstr(start,"dbcheck.pl"); if (eoln) *(--eoln)='\0'; setupfn2("%s,%s.rrd",testname,execname); acac=get_long_data(start,"ActiveConnectionsAverageCount"); accc=get_long_data(start,"ActiveConnectionsCurrentCount"); achc=get_long_data(start,"ActiveConnectionsHighCount"); wfccc=get_long_data(start,"WaitingForConnectionCurrentCount"); cdt=get_long_data(start,"ConnectionDelayTime"); clpc=get_long_data(start,"ConnectionLeakProfileCount"); lcc=get_long_data(start,"LeakedConnectionCount"); mc=get_long_data(start,"MaxCapacity"); na=get_long_data(start,"NumAvailable"); nu=get_long_data(start,"NumUnavailable"); hna=get_long_data(start,"HighestNumAvailable"); hnu=get_long_data(start,"HighestNumUnavailable"); wshc=get_long_data(start,"WaitSecondsHighCount"); ctc=get_long_data(start,"ConnectionsTotalCount"); ftrc=get_long_data(start,"FailuresToReconnectCount"); wfchc=get_long_data(start,"WaitingForConnectionHighCount"); dbgprintf("beastat: host %s test %s name %s acac %ld accc %ld achc %ld wfccc %ld cdt %ld clpc %ld lcc %ld\n", hostname, testname, execname, acac, accc, achc, wfccc, cdt, clpc, lcc); dbgprintf("beastat: host %s test %s name %s mc %ld na %ld nu %ld hna %ld hnu %ld wshc %ld ctc %ld ftrc %ld wfchc %ld\n",hostname, testname, execname, mc, na, nu, hna, hnu, wshc, ctc, ftrc, wfchc); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, acac, accc, achc, wfccc, cdt, clpc, lcc, mc, na, nu, hna, hnu, wshc, ctc, ftrc, wfchc); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jdbc_params, beastat_jdbc_tpl); if (execname) { xfree(execname); execname = NULL; } nextline: if (eoln) *(eoln)='\n'; curline = (eoln ? (eoln+1) : NULL); } } return 0; } xymon-4.3.30/xymond/rrd/do_xymonproxy.c0000664000076400007640000000314512000025440020400 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char xymonproxy_rcsid[] = "$Id: do_xymonproxy.c 7026 2012-07-13 14:05:20Z storner $"; int do_xymonproxy_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymonproxy_params[] = { "DS:runtime:GAUGE:600:0:U", NULL }; static void *xymonproxy_tpl = NULL; char *p; float runtime; if (xymonproxy_tpl == NULL) xymonproxy_tpl = setup_template(xymonproxy_params); p = strstr(msg, "Average queue time"); if (p && (sscanf(p, "Average queue time : %f", &runtime) == 1)) { if (strcmp("xymonproxy", testname) != 0) { setupfn2("%s.%s.rrd", "xymonproxy", testname); } else { setupfn("%s.rrd", "xymonproxy"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int) tstamp, runtime); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonproxy_params, xymonproxy_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_xymongen.c0000664000076400007640000001246212173472453020017 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char xymon_rcsid[] = "$Id: do_xymongen.c 7204 2013-07-23 12:20:59Z storner $"; int do_xymongen_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymon_params[] = { "DS:runtime:GAUGE:600:0:U", NULL }; static void *xymon_tpl = NULL; static char *xymon2_params[] = { "DS:hostcount:GAUGE:600:0:U", "DS:statuscount:GAUGE:600:0:U", NULL }; static void *xymon2_tpl = NULL; static char *xymon3_params[] = { "DS:redcount:GAUGE:600:0:U", "DS:rednopropcount:GAUGE:600:0:U", "DS:yellowcount:GAUGE:600:0:U", "DS:yellownopropcount:GAUGE:600:0:U", "DS:greencount:GAUGE:600:0:U", "DS:purplecount:GAUGE:600:0:U", "DS:clearcount:GAUGE:600:0:U", "DS:bluecount:GAUGE:600:0:U", "DS:redpct:GAUGE:600:0:100", "DS:rednoproppct:GAUGE:600:0:100", "DS:yellowpct:GAUGE:600:0:100", "DS:yellownoproppct:GAUGE:600:0:100", "DS:greenpct:GAUGE:600:0:100", "DS:purplepct:GAUGE:600:0:100", "DS:clearpct:GAUGE:600:0:100", "DS:bluepct:GAUGE:600:0:100", NULL }; static void *xymon3_tpl = NULL; char *p, *bol, *eoln; float runtime; int hostcount, statuscount; int redcount, rednopropcount, yellowcount, yellownopropcount, greencount, purplecount, clearcount, bluecount; double pctredcount, pctrednopropcount, pctyellowcount, pctyellownopropcount, pctgreencount, pctpurplecount, pctclearcount, pctbluecount; if (xymon_tpl == NULL) xymon_tpl = setup_template(xymon_params); if (xymon2_tpl == NULL) xymon2_tpl = setup_template(xymon2_params); if (xymon3_tpl == NULL) xymon3_tpl = setup_template(xymon3_params); runtime = 0.0; hostcount = statuscount = 0; redcount = rednopropcount = yellowcount = yellownopropcount = 0; greencount = purplecount = clearcount = bluecount = 0; pctredcount = pctrednopropcount = pctyellowcount = pctyellownopropcount = 0.0; pctgreencount = pctpurplecount = pctclearcount = pctbluecount = 0.0; bol = msg; do { int *valptr = NULL; double *pctvalptr = NULL; eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; p = bol + strspn(bol, " \t"); if (strncmp(p, "TIME TOTAL", 10) == 0) sscanf(p, "TIME TOTAL %f", &runtime); else if (strncmp(p, "Hosts", 5) == 0) valptr = &hostcount; else if (strncmp(p, "Status messages", 15) == 0) valptr = &statuscount; else if (strncmp(p, "- Red (non-propagating)", 23) == 0) { valptr = &rednopropcount; pctvalptr = &pctrednopropcount; } else if (strncmp(p, "- Red", 5) == 0) { valptr = &redcount; pctvalptr = &pctredcount; } else if (strncmp(p, "- Yellow (non-propagating)", 26) == 0) { valptr = &yellownopropcount; pctvalptr = &pctyellownopropcount; } else if (strncmp(p, "- Yellow", 8) == 0) { valptr = &yellowcount; pctvalptr = &pctyellowcount; } else if (strncmp(p, "- Green", 7) == 0) { valptr = &greencount; pctvalptr = &pctgreencount; } else if (strncmp(p, "- Purple", 8) == 0) { valptr = &purplecount; pctvalptr = &pctpurplecount; } else if (strncmp(p, "- Clear", 7) == 0) { valptr = &clearcount; pctvalptr = &pctclearcount; } else if (strncmp(p, "- Blue", 6) == 0) { valptr = &bluecount; pctvalptr = &pctbluecount; } if (valptr) { p = strchr(bol, ':'); if (p) { *valptr = atoi(p+1); if (pctvalptr) { p = strchr(p, '('); if (p) *pctvalptr = atof(p+1); } } } bol = (eoln ? eoln+1 : NULL); } while (bol); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymongen", testname); } else { setupfn("%s.rrd", "xymongen"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int)tstamp, runtime); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon_params, xymon_tpl); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymon", testname); } else { setupfn("%s.rrd", "xymon"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d", (int)tstamp, hostcount, statuscount); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon2_params, xymon2_tpl); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymon2", testname); } else { setupfn("%s.rrd", "xymon2"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d:%d:%d:%d:%d:%d:%d:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f", (int)tstamp, redcount, rednopropcount, yellowcount, yellownopropcount, greencount, purplecount, clearcount, bluecount, pctredcount, pctrednopropcount, pctyellowcount, pctyellownopropcount, pctgreencount, pctpurplecount, pctclearcount, pctbluecount); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon3_params, xymon3_tpl); return 0; } xymon-4.3.30/xymond/rrd/do_dbcheck.c0000664000076400007640000004113412000317413017513 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2006 Francesco Duranti */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char dbcheck_rcsid[] = "$Id: do_dbcheck.c 7060 2012-07-14 16:32:11Z storner $"; int do_dbcheck_memreq_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *dbcheck_memreq_params[] = { "DS:ResFree:GAUGE:600:0:U", "DS:ResAvgFree:GAUGE:600:0:U", "DS:ResUsed:GAUGE:600:0:U", "DS:ResAvgUsed:GAUGE:600:0:U", "DS:ReqFail:DERIVE:600:0:U", "DS:FailSize:GAUGE:600:0:U", NULL }; static void *dbcheck_memreq_tpl = NULL; unsigned long free=0,used=0,reqf=0,fsz=0; double avfr=0,avus=0; char *start,*end; dbgprintf("dbcheck: host %s test %s\n",hostname, testname); if (strstr(msg, "dbcheck.pl")) { if (dbcheck_memreq_tpl == NULL) dbcheck_memreq_tpl = setup_template(dbcheck_memreq_params); if ((start=strstr(msg, ""))==NULL) return 0; *end='\0'; free=get_long_data(start,"ResFree"); avfr=get_double_data(start,"ResAvgFree"); used=get_long_data(start,"ResUsed"); avus=get_double_data(start,"ResAvgUsed"); reqf=get_long_data(start,"ReqFail"); fsz=get_long_data(start,"FailSize"); *end='-'; dbgprintf("dbcheck: host %s test %s free %ld avgfree %f\n", hostname, testname, free, avfr); dbgprintf("dbcheck: host %s test %s used %ld avgused %f\n", hostname, testname, used, avus); dbgprintf("dbcheck: host %s test %s reqfail %ld failsize %ld\n", hostname, testname, reqf, fsz); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%f:%ld:%f:%ld:%ld", (int) tstamp, free, avfr, used, avus, reqf,fsz); setupfn("%s.rrd",testname); create_and_update_rrd(hostname, testname, classname, pagepaths, dbcheck_memreq_params, dbcheck_memreq_tpl); } return 0; } int do_dbcheck_hitcache_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *dbcheck_hitcache_params[] = { "DS:PinSQLArea:GAUGE:600:0:100", "DS:PinTblProc:GAUGE:600:0:100", "DS:PinBody:GAUGE:600:0:100", "DS:PinTrigger:GAUGE:600:0:100", "DS:HitSQLArea:GAUGE:600:0:100", "DS:HitTblProc:GAUGE:600:0:100", "DS:HitBody:GAUGE:600:0:100", "DS:HitTrigger:GAUGE:600:0:100", "DS:BlBuffHit:GAUGE:600:0:100", "DS:RowCache:GAUGE:600:0:100", NULL }; static void *dbcheck_hitcache_tpl = NULL; double pinsql=0, pintbl=0, pinbody=0, pintrig=0, hitsql=0, hittbl=0, hitbody=0, hittrig=0, blbuff=0, rowchache=0; dbgprintf("dbcheck: host %s test %s\n",hostname, testname); if (strstr(msg, "dbcheck.pl")) { setupfn("%s.rrd",testname); if (dbcheck_hitcache_tpl == NULL) dbcheck_hitcache_tpl = setup_template(dbcheck_hitcache_params); pinsql=get_double_data(msg,"PinSQLArea"); pintbl=get_double_data(msg,"PinTblProc"); pinbody=get_double_data(msg,"PinBody"); pintrig=get_double_data(msg,"PinTrigger"); hitsql=get_double_data(msg,"HitSQLArea"); hittbl=get_double_data(msg,"HitTblProc"); hitbody=get_double_data(msg,"HitBody"); hittrig=get_double_data(msg,"HitTrigger"); blbuff=get_double_data(msg,"BlBuffHit"); rowchache=get_double_data(msg,"RowCache"); dbgprintf("dbcheck: host %s test %s pinsql %5.2f pintbl %5.2f pinbody %5.2f pintrig %5.2f\n", hostname, testname, pinsql, pintbl, pinbody, pintrig); dbgprintf("dbcheck: host %s test %s hitsql %5.2f hittbl %5.2f hitbody %5.2f hittrig %5.2f\n", hostname, testname, hitsql, hittbl, hitbody, hittrig); dbgprintf("dbcheck: host %s test %s blbuff %5.2f rowchache %5.2f\n", hostname, testname, blbuff, rowchache); sprintf(rrdvalues, "%d:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f:%05.2f", (int) tstamp, pinsql, pintbl, pinbody, pintrig, hitsql, hittbl, hitbody, hittrig, blbuff, rowchache); create_and_update_rrd(hostname, testname, classname, pagepaths, dbcheck_hitcache_params, dbcheck_hitcache_tpl); } return 0; } int do_dbcheck_session_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *dbcheck_session_params[] = { "DS:MaxSession:GAUGE:600:0:U", "DS:CurrSession:GAUGE:600:0:U", "DS:SessUsedPct:GAUGE:600:0:100", "DS:MaxProcs:GAUGE:600:0:U", "DS:CurrProcs:GAUGE:600:0:U", "DS:ProcsUsedPct:GAUGE:600:0:100", NULL }; static void *dbcheck_session_tpl = NULL; unsigned long maxsess=0, currsess=0, maxproc=0, currproc=0 ; double pctsess=0, pctproc=0; dbgprintf("dbcheck: host %s test %s\n",hostname, testname); if (strstr(msg, "dbcheck.pl")) { setupfn("%s.rrd",testname); if (dbcheck_session_tpl == NULL) dbcheck_session_tpl = setup_template(dbcheck_session_params); maxsess=get_long_data(msg, "MaxSession"); currsess=get_long_data(msg,"CurrSession"); pctsess=get_double_data(msg,"SessUsedPct"); maxproc=get_long_data(msg,"MaxProcs"); currproc=get_long_data(msg,"CurrProcs"); pctproc=get_double_data(msg,"ProcsUsedPct"); dbgprintf("dbcheck: host %s test %s maxsess %ld currsess %ld pctsess %5.2f\n", hostname, testname, maxsess, currsess, pctsess); dbgprintf("dbcheck: host %s test %s maxproc %ld currproc %ld pctproc %5.2f\n", hostname, testname, maxproc, currproc, pctproc); sprintf(rrdvalues, "%d:%ld:%ld:%05.2f:%ld:%ld:%05.2f", (int) tstamp, maxsess, currsess, pctsess, maxproc, currproc, pctproc); create_and_update_rrd(hostname, testname, classname, pagepaths, dbcheck_session_params, dbcheck_session_tpl); } return 0; } int do_dbcheck_rb_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { /* This check can be done in slow mode so put a long heartbeat */ static char *dbcheck_rb_params[] = { "DS:pct:GAUGE:28800:0:100", NULL }; static void *dbcheck_rb_tpl = NULL; char *curline; char *eoln; dbgprintf("dbcheck: host %s test %s\n",hostname, testname); if (strstr(msg, "dbcheck.pl")) { if (dbcheck_rb_tpl == NULL) dbcheck_rb_tpl = setup_template(dbcheck_rb_params); curline=strstr(msg, "Rollback Checking"); if (curline) { eoln = strchr(curline, '\n'); curline = (eoln ? (eoln+1) : NULL); } while (curline) { float pct=0; char *execname=NULL; char *start; if ((start = strstr(curline,"ROLLBACK")) == NULL) break; if ((eoln = strchr(start, '\n')) == NULL) break; *eoln = '\0'; dbgprintf("dbcheck: host %s test %s line %s\n", hostname, testname, start); execname=xmalloc(strlen(start)); if ( sscanf(start,"ROLLBACK percentage for %s is %f",execname,&pct) !=2) goto nextline; setupfn2("%s,%s.rrd",testname,execname); dbgprintf("dbcheck: host %s test %s name %s pct %5.2f\n", hostname, testname, execname, pct); sprintf(rrdvalues, "%d:%05.2f", (int) tstamp, pct); create_and_update_rrd(hostname, testname, classname, pagepaths, dbcheck_rb_params, dbcheck_rb_tpl); nextline: if (execname) { xfree(execname); execname = NULL; } if (eoln) *(eoln)='\n'; curline = (eoln ? (eoln+1) : NULL); } } return 0; } int do_dbcheck_invobj_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { /* This check can be done in slow mode so put a long heartbeat */ static char *dbcheck_invobj_params[] = { "DS:red:GAUGE:28800:0:U", "DS:yellow:GAUGE:28800:0:U", "DS:green:GAUGE:28800:0:U", NULL }; static void *dbcheck_invobj_tpl = NULL; char *curline; char *eoln; unsigned long yellow=0,red=0,green=0; dbgprintf("dbcheck: host %s test %s\n",hostname, testname); if (strstr(msg, "dbcheck.pl")) { if (dbcheck_invobj_tpl == NULL) dbcheck_invobj_tpl = setup_template(dbcheck_invobj_params); curline=strstr(msg, "Invalid Object Checking"); if (curline) { eoln = strchr(curline, '\n'); curline = (eoln ? (eoln+1) : NULL); } while (curline) { if ( *curline == '\n') { curline++; continue; } if ((eoln = strchr(curline, '\n')) == NULL) break; *eoln = '\0'; if ( *curline =='&' ) curline++; if ( strstr(curline,"red") == curline) red++; if ( strstr(curline,"yellow") == curline) yellow++; if ( strstr(curline,"green") == curline) green++; if (eoln) *(eoln)='\n'; curline = (eoln ? (eoln+1) : NULL); } setupfn("%s.rrd",testname); dbgprintf("dbcheck: host %s test %s red %ld yellow %ld green %ld\n", hostname, testname, red,yellow,green); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld", (int) tstamp, red,yellow,green); create_and_update_rrd(hostname, testname, classname, pagepaths, dbcheck_invobj_params, dbcheck_invobj_tpl); } return 0; } int do_dbcheck_tablespace_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *tablespace_params[] = { "DS:pct:GAUGE:600:0:U", "DS:used:GAUGE:600:0:U", NULL }; static rrdtpldata_t *tablespace_tpl = NULL; char *eoln, *curline; static int ptnsetup = 0; static pcre *inclpattern = NULL; static pcre *exclpattern = NULL; if (tablespace_tpl == NULL) tablespace_tpl = setup_template(tablespace_params); if (!ptnsetup) { const char *errmsg; int errofs; char *ptn; ptnsetup = 1; ptn = getenv("RRDDISKS"); if (ptn && strlen(ptn)) { inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } ptn = getenv("NORRDDISKS"); if (ptn && strlen(ptn)) { exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } } /* * Francesco Duranti noticed that if we use the "/group" option * when sending the status message, this tricks the parser to * create an extra filesystem called "/group". So skip the first * line - we never have any disk reports there anyway. */ curline = strchr(msg, '\n'); if (curline) curline++; /* FD: For dbcheck.pl move after the Header */ curline=strstr(curline, "TableSpace/DBSpace"); if (curline) { eoln = strchr(curline, '\n'); curline = (eoln ? (eoln+1) : NULL); } while (curline) { char *fsline, *p; char *columns[20]; int columncount; char *diskname = NULL; int pused = -1; int wanteddisk = 1; long long aused = 0; /* FD: Using double instead of long long because we can have decimal on Netapp and DbCheck */ double dused = 0; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; /* FD: Exit if doing DBCHECK and the end of the tablespaces are reached */ if (strstr(eoln+1, "dbcheck.pl") == (eoln+1)) break; /* red/yellow filesystems show up twice */ if (*curline == '&') goto nextline; if ((strstr(curline, " red ") || strstr(curline, " yellow "))) goto nextline; for (columncount=0; (columncount<20); columncount++) columns[columncount] = ""; fsline = xstrdup(curline); columncount = 0; p = strtok(fsline, " "); while (p && (columncount < 20)) { columns[columncount++] = p; p = strtok(NULL, " "); } /* FD: Check TableSpace from dbcheck.pl */ /* FD: Add an initial "/" to TblSpace Name so they're reported in the trends column */ diskname=xmalloc(strlen(columns[0])+2); sprintf(diskname,"/%s",columns[0]); p = strchr(columns[4], '%'); if (p) *p = ' '; pused = atoi(columns[4]); p = columns[2] + strspn(columns[2], "0123456789."); /* FD: Using double instead of long long because we can have decimal */ dused = str2ll(columns[2], NULL); /* FD: dbspace report contains M/G/T Convert to KB if there's a modifier after the numbers */ if (*p == 'M') dused *= 1024; else if (*p == 'G') dused *= (1024*1024); else if (*p == 'T') dused *= (1024*1024*1024); aused=(long long)dused; /* Check include/exclude patterns */ wanteddisk = 1; if (exclpattern) { int ovector[30]; int result; result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result < 0); } if (wanteddisk && inclpattern) { int ovector[30]; int result; result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result >= 0); } if (wanteddisk && diskname && (pused != -1)) { p = diskname; while ((p = strchr(p, '/')) != NULL) { *p = ','; } if (strcmp(diskname, ",") == 0) { diskname = xrealloc(diskname, 6); strcpy(diskname, ",root"); } /* * Use testname here. * The disk-handler also gets data from NetAPP inode- and qtree-messages, * that are virtually identical to the disk-messages. So lets just handle * all of it by using the testname as part of the filename. */ setupfn2("%s%s.rrd", testname,diskname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%lld", (int)tstamp, pused, aused); create_and_update_rrd(hostname, testname, classname, pagepaths, tablespace_params, tablespace_tpl); } if (diskname) { xfree(diskname); diskname = NULL; } if (eoln) *eoln = '\n'; xfree(fsline); nextline: curline = (eoln ? (eoln+1) : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_disk.c0000664000076400007640000001702612000025440017061 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char disk_rcsid[] = "$Id: do_disk.c 7026 2012-07-13 14:05:20Z storner $"; int do_disk_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *disk_params[] = { "DS:pct:GAUGE:600:0:100", "DS:used:GAUGE:600:0:U", NULL }; static void *disk_tpl = NULL; enum { DT_IRIX, DT_AS400, DT_NT, DT_UNIX, DT_NETAPP, DT_NETWARE, DT_BBWIN } dsystype; char *eoln, *curline; static int ptnsetup = 0; static pcre *inclpattern = NULL; static pcre *exclpattern = NULL; if (strstr(msg, "netapp.pl")) return do_netapp_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); if (strstr(msg, "dbcheck.pl")) return do_dbcheck_tablespace_rrd(hostname, testname, classname, pagepaths, msg, tstamp); if (disk_tpl == NULL) disk_tpl = setup_template(disk_params); if (!ptnsetup) { const char *errmsg; int errofs; char *ptn; ptnsetup = 1; ptn = getenv("RRDDISKS"); if (ptn && strlen(ptn)) { inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } ptn = getenv("NORRDDISKS"); if (ptn && strlen(ptn)) { exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } } if (strstr(msg, " xfs ") || strstr(msg, " efs ") || strstr(msg, " cxfs ")) dsystype = DT_IRIX; else if (strstr(msg, "DASD")) dsystype = DT_AS400; else if (strstr(msg, "NetWare Volumes")) dsystype = DT_NETWARE; else if (strstr(msg, "NetAPP")) dsystype = DT_NETAPP; else if (strstr(msg, "Summary")) dsystype = DT_BBWIN; /* BBWin > 0.10 is almost like Windows/NT */ else if (strstr(msg, "Filesystem")) dsystype = DT_NT; else dsystype = DT_UNIX; if (dsystype == DT_NT) { /* * The MrBig client includes HTML tables with the configured disk thresholds. * We simply cut off that part of the message before doing any trend analysis. */ char *mrbigstuff = strstr(msg, "Limits:"); if (mrbigstuff) *mrbigstuff = '\0'; } /* * Francesco Duranti noticed that if we use the "/group" option * when sending the status message, this tricks the parser to * create an extra filesystem called "/group". So skip the first * line - we never have any disk reports there anyway. */ curline = strchr(msg, '\n'); if (curline) curline++; while (curline) { char *fsline, *p; char *columns[20]; int columncount; char *diskname = NULL; int pused = -1; int wanteddisk = 1; long long aused = 0; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; /* AS/400 reports must contain the word DASD */ if ((dsystype == DT_AS400) && (strstr(curline, "DASD") == NULL)) goto nextline; /* All clients except AS/400 report the mount-point with slashes - ALSO Win32 clients. */ if ((dsystype != DT_AS400) && (strchr(curline, '/') == NULL)) goto nextline; /* red/yellow filesystems show up twice */ if ((dsystype != DT_NETAPP) && (dsystype != DT_NETWARE) && (dsystype != DT_AS400)) { if (*curline == '&') goto nextline; if ((strstr(curline, " red ") || strstr(curline, " yellow "))) goto nextline; } for (columncount=0; (columncount<20); columncount++) columns[columncount] = ""; fsline = xstrdup(curline); columncount = 0; p = strtok(fsline, " "); while (p && (columncount < 20)) { columns[columncount++] = p; p = strtok(NULL, " "); } /* * Some Unix filesystem reports contain the word "Filesystem". * So check if there's a slash in the NT filesystem letter - if yes, * then it's really a Unix system after all. */ if ( (dsystype == DT_NT) && (*(columns[5])) && (strchr(columns[0], '/')) ) dsystype = DT_UNIX; switch (dsystype) { case DT_IRIX: diskname = xstrdup(columns[6]); p = strchr(columns[5], '%'); if (p) *p = ' '; pused = atoi(columns[5]); aused = str2ll(columns[3], NULL); break; case DT_AS400: diskname = xstrdup("/DASD"); p = strchr(columns[columncount-1], '%'); if (p) *p = ' '; /* * Yikes ... the format of this line varies depending on the color. * Red: * March 23, 2005 12:32:54 PM EST DASD on deltacdc at panic level at 90.4967% * Yellow: * April 4, 2005 9:20:26 AM EST DASD on deltacdc at warning level at 81.8919% * Green: * April 3, 2005 7:53:53 PM EST DASD on deltacdc OK at 79.6986% * * So we'll just pick out the number from the last column. */ pused = atoi(columns[columncount-1]); aused = 0; /* Not available */ break; case DT_NT: case DT_BBWIN: diskname = xmalloc(strlen(columns[0])+2); sprintf(diskname, "/%s", columns[0]); p = strchr(columns[4], '%'); if (p) *p = ' '; pused = atoi(columns[4]); aused = str2ll(columns[2], NULL); break; case DT_UNIX: diskname = xstrdup(columns[5]); p = strchr(columns[4], '%'); if (p) *p = ' '; pused = atoi(columns[4]); aused = str2ll(columns[2], NULL); break; case DT_NETAPP: diskname = xstrdup(columns[1]); pused = atoi(columns[5]); p = columns[3] + strspn(columns[3], "0123456789"); aused = str2ll(columns[3], NULL); /* Convert to KB if there's a modifier after the numbers */ if (*p == 'M') aused *= 1024; else if (*p == 'G') aused *= (1024*1024); else if (*p == 'T') aused *= (1024*1024*1024); break; case DT_NETWARE: diskname = xstrdup(columns[1]); aused = str2ll(columns[3], NULL); pused = atoi(columns[7]); break; } /* Check include/exclude patterns */ wanteddisk = 1; if (exclpattern) { int ovector[30]; int result; result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result < 0); } if (wanteddisk && inclpattern) { int ovector[30]; int result; result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result >= 0); } if (wanteddisk && diskname && (pused != -1)) { p = diskname; while ((p = strchr(p, '/')) != NULL) { *p = ','; } if (strcmp(diskname, ",") == 0) { diskname = xrealloc(diskname, 6); strcpy(diskname, ",root"); } /* * Use testname here. * The disk-handler also gets data from NetAPP inode- and qtree-messages, * that are virtually identical to the disk-messages. So lets just handle * all of it by using the testname as part of the filename. */ setupfn2("%s%s.rrd", testname, diskname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%lld", (int)tstamp, pused, aused); create_and_update_rrd(hostname, testname, classname, pagepaths, disk_params, disk_tpl); } if (diskname) { xfree(diskname); diskname = NULL; } if (eoln) *eoln = '\n'; xfree(fsline); nextline: curline = (eoln ? (eoln+1) : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_asid.c0000664000076400007640000000566112000025440017051 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles combined z/OS and z/VSE ASID and NPARTS messages. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* Copyright (C) 2007-2009 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char asid_rcsid[] = "$Id: do_asid.c 6585 2010-11-14 15:12:56Z storner $"; static char *asid_params[] = { "DS:util:GAUGE:600:0:100", NULL }; static char *asid_tpl = NULL; int do_asid_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *p; p=(strstr(msg, "Maxuser")); if (p) { long maxuser, maxufree, maxuused, rsvtstrt, rsvtfree, rsvtused, rsvnonr, rsvnfree, rsvnused; float maxupct, rsvtpct, rsvnpct; sscanf(p, "Maxuser: %ld Free: %ld Used: %ld %f", &maxuser, &maxufree, &maxuused, &maxupct); p=(strstr(p, "RSVTSTRT")); sscanf(p, "RSVTSTRT: %ld Free: %ld Used: %ld %f", &rsvtstrt, &rsvtfree, &rsvtused, &rsvtpct); p=(strstr(p, "RSVNONR")); sscanf(p, "RSVNONR: %ld Free: %ld Used: %ld %f", &rsvnonr, &rsvnfree, &rsvnused, &rsvnpct); setupfn2("%s.%s.rrd", "maxuser", "maxuser"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, (int)maxupct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); setupfn2("%s.%s.rrd", "maxuser", "rsvtstrt"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, (int)rsvtpct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); setupfn2("%s.%s.rrd", "maxuser", "rsvnonr"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, (int)rsvnpct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); } p=(strstr(msg, "Nparts")); if (p) { char *fn = NULL; long nparts, partfree, partused; float partupct; sscanf(p, "Nparts: %ld Free: %ld Used: %ld %f", &nparts, &partfree, &partused, &partupct); setupfn("nparts.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, (int)partupct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_trends.c0000664000076400007640000000711312000025440017422 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles custom "trends" data. */ /* */ /* Copyright (C) 2007-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char trends_rcsid[] = "$Id: do_trends.c 7026 2012-07-13 14:05:20Z storner $"; /* * This module was inspired by a mail from Stef Coene: * * --------------------------------------------------------------------------- * Date: Wed, 17 Jan 2007 14:04:29 +0100 * From: Stef Coene * Subject: Re: [xymon] xymon monitoring * * Just wondering, how hard would it be to create an extra channel for trending? * So you can use the xymon client to send "numbers" to the xymon server together * with some extra control information. * * xymon trends * * ----------------------------------------------------------------------------- * * Instead of a dedicated Xymon channel for this, I decided to use the * existing "data" message type. To use this, send a "data" message to * xymon formatted like this: * * data $MACHINE.trends * [filename.rrd] * DS-definition1 VALUE2 * DS-definition2 VALUE2 * * E.g. to create/update a custom RRD file "weather.rrd" with two * GAUGE datasets "temp" and "wind", with current values "21" and * "8" respectively, send this message: * * [weather.rrd] * DS:temp:GAUGE:600:0:U 21 * DS:wind:GAUGE:600:0:U 8 */ static int do_trends_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *boln, *eoln, *p; int dscount; char **creparams; creparams = (char **)calloc(1, sizeof(char *)); dscount = 0; boln = strchr(msg, '\n'); if (boln) boln++; while (boln && *boln) { eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; if (*boln == '[') { /* Flush the current RRD file */ if (creparams[0]) create_and_update_rrd(hostname, testname, classname, pagepaths, creparams, NULL); creparams = (char **)realloc(creparams, 1*sizeof(char *)); creparams[0] = NULL; dscount = 0; /* Get the RRD filename */ p = strchr(boln+1, ']'); if (p) *p = '\0'; setupfn("%s", boln+1); /* And setup the initial rrdvalues string */ snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); } else if (strncmp(boln, "DS:", 3) == 0) { char *valptr = boln + strcspn(boln, " \t"); if ((*valptr == ' ') || (*valptr == '\t')) { *valptr = '\0'; valptr += 1 + strspn(valptr+1, " \t"); creparams[dscount] = boln; dscount++; creparams = (char **)realloc(creparams, (1+dscount)*sizeof(char **)); creparams[dscount] = NULL; snprintf(rrdvalues+strlen(rrdvalues), sizeof(rrdvalues)-strlen(rrdvalues), ":%s", valptr); } } boln = (eoln ? eoln+1 : NULL); } /* Do the last RRD set */ if (creparams[0]) create_and_update_rrd(hostname, testname, classname, pagepaths, creparams, NULL); xfree(creparams); return 0; } xymon-4.3.30/xymond/rrd/do_xymond.c0000664000076400007640000000710312000025440017440 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char xymond_rcsid[] = "$Id: do_xymond.c 7026 2012-07-13 14:05:20Z storner $"; int do_xymond_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymond_params[] = { "DS:inmessages:DERIVE:600:0:U", "DS:statusmessages:DERIVE:600:0:U", "DS:combomessages:DERIVE:600:0:U", "DS:pagemessages:DERIVE:600:0:U", "DS:summarymessages:DERIVE:600:0:U", "DS:datamessages:DERIVE:600:0:U", "DS:notesmessages:DERIVE:600:0:U", "DS:enablemessages:DERIVE:600:0:U", "DS:disablemessages:DERIVE:600:0:U", "DS:ackmessages:DERIVE:600:0:U", "DS:configmessages:DERIVE:600:0:U", "DS:querymessages:DERIVE:600:0:U", "DS:boardmessages:DERIVE:600:0:U", "DS:listmessages:DERIVE:600:0:U", "DS:logmessages:DERIVE:600:0:U", "DS:dropmessages:DERIVE:600:0:U", "DS:renamemessages:DERIVE:600:0:U", "DS:statuschmsgs:DERIVE:600:0:U", "DS:stachgchmsgs:DERIVE:600:0:U", "DS:pagechmsgs:DERIVE:600:0:U", "DS:datachmsgs:DERIVE:600:0:U", "DS:noteschmsgs:DERIVE:600:0:U", "DS:enadischmsgs:DERIVE:600:0:U", NULL }; static void *xymond_tpl = NULL; struct { char *marker; unsigned long val; } xymond_data[] = { { "\nIncoming messages", 0 }, { "\n- status", 0 }, { "\n- combo", 0 }, { "\n- page", 0 }, { "\n- summary", 0 }, { "\n- data", 0 }, { "\n- notes", 0 }, { "\n- enable", 0 }, { "\n- disable", 0 }, { "\n- ack", 0 }, { "\n- config", 0 }, { "\n- query", 0 }, { "\n- xymondboard", 0 }, { "\n- xymondlist", 0 }, { "\n- xymondlog", 0 }, { "\n- drop", 0 }, { "\n- rename", 0 }, { "\nstatus channel messages", 0 }, { "\nstachg channel messages", 0 }, { "\npage channel messages", 0 }, { "\ndata channel messages", 0 }, { "\nnotes channel messages", 0 }, { "\nenadis channel messages", 0 }, { NULL, 0 } }; int i, gotany = 0; char *p; char valstr[50]; MEMDEFINE(valstr); if (xymond_tpl == NULL) xymond_tpl = setup_template(xymond_params); snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); i = 0; while (xymond_data[i].marker) { p = strstr(msg, xymond_data[i].marker); if (p) { if (*p == '\n') p++; p += strcspn(p, ":\r\n"); if (*p == ':') { xymond_data[i].val = strtoul(p+1, NULL, 10); gotany++; snprintf(valstr, sizeof(valstr), ":%lu", xymond_data[i].val); strncat(rrdvalues, valstr, sizeof(rrdvalues)-strlen(rrdvalues)-1); } else strcat(rrdvalues, ":U"); } else strcat(rrdvalues, ":U"); i++; } if (gotany) { if (strcmp("xymond", testname) != 0) { setupfn2("%s.%s.rrd", "xymond", testname); } else { setupfn("%s.rrd", "xymond"); } MEMUNDEFINE(valstr); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymond_params, xymond_tpl); } MEMUNDEFINE(valstr); return 0; } xymon-4.3.30/xymond/rrd/do_apache.c0000664000076400007640000000424212000025440017344 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char apache_rcsid[] = "$Id: do_apache.c 7026 2012-07-13 14:05:20Z storner $"; int do_apache_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *apache_params[] = { "DS:TA:DERIVE:600:0:U", "DS:TKB:DERIVE:600:0:U", "DS:BW:GAUGE:600:1:U", "DS:IW:GAUGE:600:1:U", "DS:CPU:GAUGE:600:0:U", "DS:REQPERSEC:GAUGE:600:0:U", NULL }; static void *apache_tpl = NULL; char *markers[] = { "Total Accesses:", "Total kBytes:", "BusyWorkers:", "IdleWorkers:", "CPULoad:", "ReqPerSec:", NULL }; int i; char *p, *eoln; if (apache_tpl == NULL) apache_tpl = setup_template(apache_params); /* Apache 1.x uses BusyServers/IdleServers. Convert the status to Apache 2.0 format */ if ((p = strstr(msg, "BusyServers:")) != NULL) memcpy(p, "BusyWorkers:", strlen("BusyWorkers:")); if ((p = strstr(msg, "IdleServers:")) != NULL) memcpy(p, "IdleWorkers:", strlen("IdleWorkers:")); setupfn("%s.rrd", "apache"); snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); i = 0; while (markers[i]) { strcat(rrdvalues, ":"); p = strstr(msg, markers[i]); if (p) { eoln = strchr(p, '\n'); if (eoln) *eoln = '\0'; p = strchr(p, ':')+1; p += strspn(p, " "); strcat(rrdvalues, p); if (eoln) *eoln = '\n'; } else { strcat(rrdvalues, "U"); } i++; } return create_and_update_rrd(hostname, testname, classname, pagepaths, apache_params, apache_tpl); } xymon-4.3.30/xymond/rrd/do_ntpstat.c0000664000076400007640000000336412000025440017624 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char ntpstat_rcsid[] = "$Id: do_ntpstat.c 7026 2012-07-13 14:05:20Z storner $"; int do_ntpstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *ntpstat_params[] = { "DS:offsetms:GAUGE:600:U:U", NULL }; static void *ntpstat_tpl = NULL; char *p; float offset; int gotdata = 0; if (ntpstat_tpl == NULL) ntpstat_tpl = setup_template(ntpstat_params); /* First check for the old LARRD ntpstat BF script */ p = strstr(msg, "\nOffset:"); gotdata = (p && (sscanf(p+1, "Offset: %f", &offset) == 1)); /* Or maybe it's just the "ntpq -c rv" output */ if (!gotdata) { p = strstr(msg, "offset="); if (p && (isspace((int)*(p-1)) || (*(p-1) == ','))) { gotdata = (p && (sscanf(p, "offset=%f", &offset) == 1)); } } if (gotdata) { setupfn("%s.rrd", "ntpstat"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.6f", (int)tstamp, offset); return create_and_update_rrd(hostname, testname, classname, pagepaths, ntpstat_params, ntpstat_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_ncv.c0000664000076400007640000001726112615577600016744 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles any message with data in the form */ /* NAME: VALUE */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* split-ncv added by Charles Goyard November 2006 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char ncv_rcsid[] = "$Id: do_ncv.c 7711 2015-11-02 06:15:28Z jccleaver $"; int do_ncv_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char **params = NULL; int paridx; char dsdef[1024]; /* destination DS syntax for rrd engine */ char *l, *name, *val; char *envnam; char *dstypes = NULL; /* contain NCV_testname value */ int split_ncv = 0; int skipblock = 0; int dslen; snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); params = (char **)calloc(1, sizeof(char *)); paridx = 0; /* Get the NCV_* or SPLITNCV_* environment setting */ envnam = (char *)malloc(9 + strlen(testname) + 1); sprintf(envnam, "SPLITNCV_%s", testname); l = getenv(envnam); if (l) { split_ncv = 1; dslen = 200; } else { split_ncv = 0; dslen = 19; setupfn("%s.rrd", testname); sprintf(envnam, "NCV_%s", testname); l = getenv(envnam); } if (l) { dstypes = (char *)malloc(strlen(l)+3); sprintf(dstypes, ",%s,", l); } xfree(envnam); l = strchr(msg, '\n'); if (l) l++; while (l && *l && strncmp(l, "@@\n", 3)) { name = val = NULL; l += strspn(l, " \t\n"); if (*l) { /* Look for a sign to alter processing */ if (strncmp(l, "", 8) == 0) { /* skip the entire line */ l += strcspn(l, "\n"); l++; continue; } else if (strncmp(l, "skipstart -->", 13) == 0) { /* begin ignoring lines until told to stop */ skipblock = 1; } else if (strncmp(l, "skipend -->", 11) == 0) { /* we're done skipping, */ skipblock = 0; l += 11; continue; } else if (strncmp(l, "ignore -->", 10) == 0) { /* allowed syntax: assorted text without html label : value */ l += 10; l += strcspn(l, ">\n"); /* search for closing '>' or the eol */ /* See if it's the expected end marker '', and repeat until we find it (or eol) */ while ((*l != '\n') && (strncmp((l-4), "", 5) != 0) ) { l++; l += strcspn(l, ">\n"); } /* Did we hit the end? Move on. If not, skip any (now) leading whitespace and continue on */ if (*l == '\n') { l++; continue; } else { l++; l += strspn(l, " \t\n"); } } else if (strncmp(l, "end -->", 7) == 0) break; /* abort */ else { dbgprintf("Unexpected NCV directive found\n"); /* skip past directive */ l += strcspn(l, ">"); l++; l += strspn(l, " \t\n"); } } if (skipblock) { l += strcspn(l, "\n"); l++; continue; } /* We're still in a comment block */ /* See if this line contains a '=' or ':' sign */ name = l; l += strcspn(l, ":=\n"); if (*l) { if (( *l == '=') || (*l == ':')) { *l = '\0'; l++; } else { /* No marker, so skip this line */ name = NULL; } } else break; /* We've hit the end of the message */ } /* Skip any color marker "&COLOR " in front of the ds name */ if (name && (*name == '&')) { name++; name += strspn(name, "abcdefghijklmnopqrstuvwxyz"); name += strspn(name, " \t"); if (*name == '\0') name = NULL; } if (name) { val = l + strspn(l, " \t"); /* Find the end of the value string */ l = val; if ((*l == '-') || (*l == '+')) l++; /* Pass leading sign */ l += strspn(l, "0123456789.+-eE"); /* and the numbers. */ if( *val ) { int iseol = (*l == '\n'); *l = '\0'; if (!iseol) { /* If extra data after the value, skip to end of line */ l = strchr(l+1, '\n'); if (l) l++; } else { l++; } } else break; /* No value data */ } if (name && val && *val) { char *endptr; double dummy; dummy = strtod(val, &endptr); /* Dont care - we're only interested in endptr */ if (isspace((int)*endptr) || (*endptr == '\0')) { char dsname[250]; /* name of ncv in status message (with space and all) */ char dskey[252]; /* name of final DS key (stripped) */ char *dstype = NULL; /* type of final DS */ char *inp; int outidx = 0; /* val contains a valid number */ /* rrdcreate(1) says: ds must be in the set [a-zA-Z0-9_] ... */ for (inp=name,outidx=0; (*inp && (outidx < dslen)); inp++) { if ( ((*inp >= 'A') && (*inp <= 'Z')) || ((*inp >= 'a') && (*inp <= 'z')) || ((*inp >= '0') && (*inp <= '9')) ) { dsname[outidx++] = *inp; } /* ... however, for split ncv, we replace anything else */ /* with an underscore, compacting successive invalid */ /* characters into a single one */ else if (split_ncv && ((outidx == 0) || (dsname[outidx - 1] != '_'))) { dsname[outidx++] = '_'; } } if ((outidx > 0) && (dsname[outidx-1] == '_')) { dsname[outidx-1] = '\0'; } else { dsname[outidx] = '\0'; } snprintf(dskey, sizeof(dskey), ",%s:", dsname); if (split_ncv) setupfn2("%s,%s.rrd", testname, dsname); if (dstypes) { dstype = strstr(dstypes, dskey); if (!dstype) { strcpy(dskey, ",*:"); dstype = strstr(dstypes, dskey); } } if (dstype) { /* if ds type is forced */ char *p; dstype += strlen(dskey); p = strchr(dstype, ','); if (p) *p = '\0'; if(split_ncv) { snprintf(dsdef, sizeof(dsdef), "DS:lambda:%s:600:U:U", dstype); } else { snprintf(dsdef, sizeof(dsdef), "DS:%s:%s:600:U:U", dsname, dstype); } if (p) *p = ','; } else { /* nothing specified in the environnement, and no '*:' default */ if(split_ncv) { strcpy(dsdef, "DS:lambda:DERIVE:600:U:U"); } else { snprintf(dsdef, sizeof(dsdef), "DS:%s:DERIVE:600:U:U", dsname); } } if (!dstype || (strncasecmp(dstype, "NONE", 4) != 0)) { /* if we have something */ params[paridx] = strdup(dsdef); paridx++; params = (char **)realloc(params, (1 + paridx)*sizeof(char *)); params[paridx] = NULL; snprintf(rrdvalues+strlen(rrdvalues), sizeof(rrdvalues)-strlen(rrdvalues), ":%s", val); } } if (split_ncv && (paridx > 0)) { create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); /* We've created one RRD, so reset the params for the next one */ for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); paridx = 0; params[0] = NULL; snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); } } } /* end of while */ if (!split_ncv && params[0]) create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); if (dstypes) xfree(dstypes); return 0; } xymon-4.3.30/xymond/rrd/do_net.c0000664000076400007640000001226712603142505016732 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char do_net_rcsid[] = "$Id: do_net.c 7676 2015-10-01 05:31:49Z jccleaver $"; int do_net_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymonnet_params[] = { "DS:sec:GAUGE:600:0:U", NULL }; static void *xymonnet_tpl = NULL; char *p; float seconds = 0.0; int do_default = 1; if (xymonnet_tpl == NULL) xymonnet_tpl = setup_template(xymonnet_params); if (strcmp(testname, "http") == 0) { char *line1, *url = NULL, *eoln; do_default = 0; line1 = msg; while ((line1 = strchr(line1, '\n')) != NULL) { line1++; /* Skip the newline */ eoln = strchr(line1, '\n'); if (eoln) *eoln = '\0'; if ( (strncmp(line1, "&green", 6) == 0) || (strncmp(line1, "&yellow", 7) == 0) || (strncmp(line1, "&red", 4) == 0) ) { p = strstr(line1, "http"); if (p) { url = xstrdup(p); p = strchr(url, ' '); if (p) *p = '\0'; } } else if (url && ((p = strstr(line1, "Seconds:")) != NULL) && (sscanf(p, "Seconds: %f", &seconds) == 1)) { char *urlfn = url; if (strncmp(urlfn, "http://", 7) == 0) urlfn += 7; p = urlfn; while ((p = strchr(p, '/')) != NULL) *p = ','; setupfn3("%s.%s.%s.rrd", "tcp", "http", urlfn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int)tstamp, seconds); create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl); xfree(url); url = NULL; } if (eoln) *eoln = '\n'; } if (url) xfree(url); } else if (strcmp(testname, xgetenv("PINGCOLUMN")) == 0) { /* * Ping-tests, possibly using fping. */ char *tmod = "ms"; do_default = 0; if ((p = strstr(msg, "time=")) != NULL) { /* Standard ping, reports ".... time=0.2 ms" */ seconds = atof(p+5); tmod = p + 5; tmod += strspn(tmod, "0123456789. "); } else if ((p = strstr(msg, "alive")) != NULL) { /* fping, reports ".... alive (0.43 ms)" */ seconds = atof(p+7); tmod = p + 7; tmod += strspn(tmod, "0123456789. "); } if (strncmp(tmod, "ms", 2) == 0) seconds = seconds / 1000.0; else if (strncmp(tmod, "usec", 4) == 0) seconds = seconds / 1000000.0; setupfn2("%s.%s.rrd", "tcp", testname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.6f", (int)tstamp, seconds); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl); } else if (strcmp(testname, "ntp") == 0) { /* * sntp output: * 2009 Nov 13 11:29:10.000313 + 0.038766 +/- 0.052900 secs * ntpdate output: * server 172.16.10.2, stratum 3, offset -0.040324, delay 0.02568 * 13 Nov 11:29:06 ntpdate[7038]: adjust time server 172.16.10.2 offset -0.040324 sec */ char dataforntpstat[100]; char *offsetval = NULL; char offsetbuf[40]; char *msgcopy = strdup(msg); if (strstr(msgcopy, "ntpdate") != NULL) { /* Old-style "ntpdate" output */ char *p; p = strstr(msgcopy, "offset "); if (p) { p += 7; offsetval = strtok(p, " \r\n\t"); } } else if (strstr(msgcopy, " secs") != NULL) { /* Probably new "sntp" output */ char *year, *tm, *offsetdirection, *offset, *plusminus, *errorbound, *secs; tm = offsetdirection = plusminus = errorbound = secs = NULL; year = strtok(msgcopy, " "); tm = year ? strtok(NULL, " ") : NULL; offsetdirection = tm ? strtok(NULL, " ") : NULL; offset = offsetdirection ? strtok(NULL, " ") : NULL; plusminus = offset ? strtok(NULL, " ") : NULL; errorbound = plusminus ? strtok(NULL, " ") : NULL; secs = errorbound ? strtok(NULL, " ") : NULL; if ( offsetdirection && ((strcmp(offsetdirection, "+") == 0) || (strcmp(offsetdirection, "-") == 0)) && plusminus && (strcmp(plusminus, "+/-") == 0) && secs && (strcmp(secs, "secs") == 0) ) { /* Looks sane */ snprintf(offsetbuf, sizeof(offsetbuf), "%s%s", offsetdirection, offset); offsetval = offsetbuf; } } if (offsetval) { snprintf(dataforntpstat, sizeof(dataforntpstat), "offset=%s", offsetval); do_ntpstat_rrd(hostname, testname, classname, pagepaths, dataforntpstat, tstamp); } xfree(msgcopy); } if (do_default) { /* * Normal network tests - pick up the "Seconds:" value */ p = strstr(msg, "\nSeconds:"); if (p && (sscanf(p+1, "Seconds: %f", &seconds) == 1)) { setupfn2("%s.%s.rrd", "tcp", testname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%f", (int)tstamp, seconds); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl); } } return 0; } xymon-4.3.30/xymond/rrd/do_vmstat.c0000664000076400007640000002753313463141670017473 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char vmstat_rcsid[] = "$Id: do_vmstat.c 8066 2019-05-03 22:42:00Z jccleaver $"; typedef struct vmstat_layout_t { int index; char *name; } vmstat_layout_t; /* This one matches the vmstat output from Solaris 8, possibly earlier ones as well */ /* LARRD 0.43c compatible. */ static vmstat_layout_t vmstat_solaris_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_swap" }, { 4, "mem_free" }, { 5, "mem_re" }, { 6, "mem_mf" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 11, "sr" }, { 16, "cpu_int" }, { 17, "cpu_syc" }, { 18, "cpu_csw" }, { 19, "cpu_usr" }, { 20, "cpu_sys" }, { 21, "cpu_idl" }, { -1, NULL } }; /* This one for OSF */ /* LARRD 0.43c compatible */ static vmstat_layout_t vmstat_osf_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 4, "mem_free" }, { 6, "mem_mf" }, { 10, "mem_pi" }, { 11, "mem_po" }, { 12, "cpu_int" }, { 13, "cpu_syc" }, { 14, "cpu_csw" }, { 15, "cpu_usr" }, { 16, "cpu_sys" }, { 17, "cpu_idl" }, { -1, NULL } }; /* This one for AIX */ /* LARRD 0.43c compatible */ static vmstat_layout_t vmstat_aix_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "mem_avm" }, { 3, "mem_free" }, { 4, "mem_re" }, { 5, "mem_pi" }, { 6, "mem_po" }, { 7, "mem_fr" }, { 8, "sr" }, { 9, "mem_cy" }, { 10, "cpu_int" }, { 11, "cpu_syc" }, { 12, "cpu_csw" }, { 13, "cpu_usr" }, { 14, "cpu_sys" }, { 15, "cpu_idl" }, { 16, "cpu_wait" }, { 17, "cpu_pc" }, { 18, "cpu_ec" }, { -1, NULL } }; /* This is for AIX running on Power5 cpu's. */ static vmstat_layout_t vmstat_aix_power5_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "mem_avm" }, { 3, "mem_free" }, { 4, "mem_re" }, { 5, "mem_pi" }, { 6, "mem_po" }, { 7, "mem_fr" }, { 8, "sr" }, { 9, "mem_cy" }, { 10, "cpu_int" }, { 11, "cpu_syc" }, { 12, "cpu_csw" }, { 13, "cpu_usr" }, { 14, "cpu_sys" }, { 15, "cpu_idl" }, { 16, "cpu_wait" }, { 17, "cpu_pc" }, { 18, "cpu_ec" }, { -1, NULL } }; /* This one for Christian Perrier's hacked IRIX "vmstat" done with sar */ static vmstat_layout_t vmstat_irix_layout[] = { { 1, "cpu_usr" }, { 2, "cpu_sys" }, { 3, "cpu_int" }, { 4, "cpu_wait" }, { 5, "cpu_idl" }, { -1, "cpu_csw" }, /* Not available, but having it in the RRD makes vmstat3 graph (int+csw) work */ { -1, NULL } }; /* This one matches FreeBSD 4.10 */ /* LARRD 0.43c compatible */ static vmstat_layout_t vmstat_freebsd4_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_avm" }, { 4, "mem_free" }, { 5, "mem_flt" }, { 6, "mem_re" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 9, "mem_fr" }, { 10, "sr" }, { 11, "dsk_da0" }, { 12, "dsk_fd0" }, { 13, "cpu_int" }, { 15, "cpu_csw" }, { 16, "cpu_sys" }, { 17, "cpu_usr" }, { 18, "cpu_idl" }, { -1, NULL } }; /* FreeBSD v6 and later, possibly v5 also */ static vmstat_layout_t vmstat_freebsd_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_avm" }, { 4, "mem_free" }, { 5, "mem_flt" }, { 6, "mem_re" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 9, "mem_fr" }, { 10, "sr" }, { 11, "dsk_da0" }, { 12, "dsk_pa0" }, { 13, "cpu_int" }, { 14, "cpu_syc" }, { 15, "cpu_csw" }, { 16, "cpu_usr" }, { 17, "cpu_sys" }, { 18, "cpu_idl" }, { -1, NULL } }; /* This one matches NetBSD 2.0 */ /* LARRD 0.43c does not support NetBSD */ static vmstat_layout_t vmstat_netbsd_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_avm" }, { 4, "mem_free" }, { 5, "mem_flt" }, { 6, "mem_re" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 9, "mem_fr" }, { 10, "sr" }, { 11, "dsk_f0" }, { 12, "dsk_m0" }, { 13, "dsk_w0" }, { 14, "cpu_int" }, { 15, "cpu_syc" }, { 16, "cpu_csw" }, { 17, "cpu_usr" }, { 18, "cpu_sys" }, { 19, "cpu_idl" }, { -1, NULL } }; static vmstat_layout_t vmstat_openbsd_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_avm" }, { 4, "mem_free" }, { 5, "mem_flt" }, { 6, "mem_re" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 9, "mem_fr" }, { 10, "sr" }, { 11, "dsk_wd0" }, { 12, "dsk_cd0" }, { 13, "cpu_int" }, { 14, "cpu_syc" }, { 15, "cpu_csw" }, { 16, "cpu_usr" }, { 17, "cpu_sys" }, { 18, "cpu_idl" }, { -1, NULL } }; /* This one for HP/UX */ /* LARRD 0.43c does not support HP-UX */ static vmstat_layout_t vmstat_hpux_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_avm" }, { 4, "mem_free" }, { 5, "mem_re" }, { 6, "mem_flt" }, { 7, "mem_pi" }, { 8, "mem_po" }, { 9, "mem_fr" }, { 11, "sr" }, { 12, "cpu_int" }, { 14, "cpu_csw" }, { 15, "cpu_usr" }, { 16, "cpu_sys" }, { 17, "cpu_idl" }, { -1, NULL } }; /* This one is all newer Linux procps versions, with kernel 2.4+ */ /* NOT compatible with LARRD 0.43c */ static vmstat_layout_t vmstat_linux_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { -1, "cpu_w" }, /* Not present for 2.4+ kernels, so log as "Undefined" */ { 2, "mem_swpd" }, { 3, "mem_free" }, { 4, "mem_buff" }, { 5, "mem_cach" }, { 6, "mem_si" }, { 7, "mem_so" }, { 8, "dsk_bi" }, { 9, "dsk_bo" }, { 10, "cpu_int" }, { 11, "cpu_csw" }, { 12, "cpu_usr" }, { 13, "cpu_sys" }, { 14, "cpu_idl" }, { 15, "cpu_wait" }, /* Requires kernel 2.6, but may not be present */ { -1, NULL } }; /* * This one is for Red Hat Enterprise Linux 3. Identical to the "linux" layout, * except Red Hat for some reason decided to swap the cpu_wait and cpu_idle columns. */ /* NOT compatible with LARRD 0.43c */ static vmstat_layout_t vmstat_rhel3_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { -1, "cpu_w" }, { 2, "mem_swpd" }, { 3, "mem_free" }, { 4, "mem_buff" }, { 5, "mem_cach" }, { 6, "mem_si" }, { 7, "mem_so" }, { 8, "dsk_bi" }, { 9, "dsk_bo" }, { 10, "cpu_int" }, { 11, "cpu_csw" }, { 12, "cpu_usr" }, { 13, "cpu_sys" }, { 14, "cpu_wait" }, { 15, "cpu_idl" }, { -1, NULL } }; /* This one is for Debian 3.0 (Woody), and possibly others with a Linux 2.2 kernel */ /* NOT compatible with LARRD 0.43c */ static vmstat_layout_t vmstat_linux22_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_swpd" }, { 4, "mem_free" }, { 5, "mem_buff" }, { 6, "mem_cach" }, { 7, "mem_si" }, { 8, "mem_so" }, { 9, "dsk_bi" }, { 10, "dsk_bo" }, { 11, "cpu_int" }, { 12, "cpu_csw" }, { 13, "cpu_usr" }, { 14, "cpu_sys" }, { 15, "cpu_idl" }, { -1, "cpu_wait" }, { -1, NULL } }; /*This one is for sco_sv */ /* NOT compatible with LARRD 0.43c */ static vmstat_layout_t vmstat_sco_sv_layout[] = { { 0, "cpu_r" }, { 1, "cpu_b" }, { 2, "cpu_w" }, { 3, "mem_free" }, { 4, "mem_dmd" }, { 5, "mem_swpd" }, { 6, "mem_cach" }, { 7, "mem_fil" }, { 8, "mem_flt" }, { 9, "mem_frd" }, { 10, "mem_pos" }, { 11, "mem_pif" }, { 12, "mem_pis" }, { 13, "mem_so" }, { 14, "mem_si" }, { 15, "sys_calls" }, { 16, "cpu_csw" }, { 17, "cpu_usr" }, { 18, "cpu_sys" }, { 19, "cpu_idl" }, /* { -1, "cpu_wait" }, */ { -1, NULL } }; #define MAX_VMSTAT_VALUES 30 int do_vmstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { enum ostype_t ostype; vmstat_layout_t *layout = NULL; char *datapart = msg; int values[MAX_VMSTAT_VALUES]; int defcount, defidx, datacount, result; char *p; char **creparams; if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Full message, including "status" or "data" line - so skip the first line. */ datapart = strchr(msg, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines (only 1) in vmstat report from %s\n", hostname); return -1; } } ostype = get_ostype(datapart); datapart = strchr(datapart, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines (only 1 or 2) in vmstat report from %s\n", hostname); return -1; } /* Pick up the values in the datapart line. Stop at newline. */ p = strchr(datapart, '\n'); if (p) *p = '\0'; p = strtok(datapart, " "); datacount = 0; while (p && (datacount < MAX_VMSTAT_VALUES)) { /* Removing . and , from the numbers */ char *p1; while ( (p1 = strchr(p,'.')) != NULL ) { strcpy (p1, p1+1) ; } char *p2; while ( (p2 = strchr(p,',')) != NULL ) { strcpy (p2, p2+1) ; } values[datacount++] = atoi(p); p = strtok(NULL, " "); } /* Must do this now, to check on the layout of any existing file */ setupfn("%s.rrd", "vmstat"); switch (ostype) { case OS_SOLARIS: layout = vmstat_solaris_layout; break; case OS_OSF: layout = vmstat_osf_layout; break; case OS_AIX: /* Special, because there are two layouts for AIX */ { char **dsnames = NULL; int dscount, i; dscount = rrddatasets(hostname, &dsnames); layout = ((dscount == 17) ? vmstat_aix_layout : vmstat_aix_power5_layout); if ((dscount > 0) && dsnames) { /* Free the dsnames list */ for (i=0; (i 0) && dsnames) { /* Free the dsnames list */ for (i=0; (i= datacount) || (dataidx == -1)) { p += snprintf(p, sizeof(rrdvalues)-(p-rrdvalues), ":U"); } else { p += snprintf(p, sizeof(rrdvalues)-(p-rrdvalues), ":%d", values[layout[defidx].index]); } } result = create_and_update_rrd(hostname, testname, classname, pagepaths, creparams, NULL); for (defidx=0; (defidx < defcount); defidx++) xfree(creparams[defidx]); xfree(creparams); return result; } xymon-4.3.30/xymond/rrd/do_devmon.c0000664000076400007640000000770213033575046017442 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module for Devmon */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* Copyright (C) 2008 Buchan Milne */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char devmon_rcsid[] = "$Id $"; int do_devmon_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { #define MAXCOLS 20 char *devmon_params[MAXCOLS+7] = { NULL, }; char *eoln, *curline; static int ptnsetup = 0; static pcre *inclpattern = NULL; static pcre *exclpattern = NULL; int in_devmon = 1; int numds = 0; char *rrdbasename; int lineno = 0; rrdbasename = NULL; curline = msg; while (curline) { char *fsline = NULL; char *p; char *columns[MAXCOLS]; int columncount; char *ifname = NULL; int pused = -1; int wanteddisk = 1; long long aused = 0; char *dsval; int i; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; lineno++; if(!strncmp(curline, "",3)) { in_devmon = 1; goto nextline; } if (in_devmon != 0 ) goto nextline; for (columncount=0; (columncount 2) { dbgprintf("Skipping line %d, found %d (max 2) columns in devmon rrd data, space in repeater name?\n",lineno,columncount); goto nextline; } /* Now we should be on to values: * eth0.0 4678222:9966777 */ ifname = xstrdup(columns[0]); dsval = strtok(columns[1],":"); if (dsval == NULL) { dbgprintf("Skipping line %d, line is malformed\n",lineno); goto nextline; } snprintf(rrdvalues, sizeof(rrdvalues), "%d:", (int)tstamp); strcat(rrdvalues,dsval); for (i=1;i < numds;i++) { dsval = strtok(NULL,":"); if (dsval == NULL) { dbgprintf("Skipping line %d, %d tokens present, expecting %d\n",lineno,i,numds); goto nextline; } strcat(rrdvalues,":"); strcat(rrdvalues,dsval); } /* File names in the format if_load.eth0.0.rrd */ setupfn2("%s.%s.rrd", rrdbasename, ifname); dbgprintf("Sending from devmon to RRD for %s %s: %s\n",rrdbasename,ifname,rrdvalues); create_and_update_rrd(hostname, testname, classname, pagepaths, devmon_params, NULL); if (ifname) { xfree(ifname); ifname = NULL; } if (eoln) *eoln = '\n'; nextline: if (fsline) { xfree(fsline); fsline = NULL; } curline = (eoln ? (eoln+1) : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_memory.c0000664000076400007640000002336213463141670017461 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char memory_rcsid[] = "$Id: do_memory.c 8066 2019-05-03 22:42:00Z jccleaver $"; static char *memory_params[] = { "DS:realmempct:GAUGE:600:0:U", NULL }; static void *memory_tpl = NULL; /* * Use the R/B tree to hold names of the hosts * that we receive "memory" status from. When handling * "cpu" reports, those hosts that are in the tree do * NOT take memory data from the cpu data. */ void * memhosts; int memhosts_init = 0; static int get_mem_percent(char *l) { char *p; p = strchr(l, '%'); if (p == NULL) return 0; p--; while ( (p > l) && (isdigit((int) *p) || (*p == '.')) ) p--; return atoi(p+1); } void do_memory_rrd_update(time_t tstamp, char *hostname, char *testname, char *classname, char *pagepaths, int physval, int swapval, int actval) { if (memory_tpl == NULL) memory_tpl = setup_template(memory_params); setupfn2("%s.%s.rrd", "memory", "real"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, physval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); setupfn2("%s.%s.rrd", "memory", "swap"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, swapval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); if (actval >= 0) { setupfn2("%s.%s.rrd", "memory", "actual"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, actval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } } /* bb-xsnmp.pl memory update - Marco Avvisano */ void do_memory_rrd_update_router(time_t tstamp, char *hostname, char *testname, char *classname, char *pagepaths, int procval, int ioval, int fastval) { if (memory_tpl == NULL) memory_tpl = setup_template(memory_params); if ((procval >= 0) && (procval <= 100)) { setupfn2("%s.%s.rrd", "memory", "processor"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, procval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } if ((ioval >= 0) && (ioval <= 100)) { setupfn2("%s.%s.rrd", "memory", "io"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, ioval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } if ((fastval >= 0) && (fastval <= 100)) { setupfn2("%s.%s.rrd", "memory", "fast"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, fastval); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } } int do_memory_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *phys = NULL; char *swap = NULL; char *actual = NULL; xtreePos_t hwalk; /* Log this hostname in the list of hosts we get true "memory" reports from. */ if (!memhosts_init) { memhosts = xtreeNew(strcmp); memhosts_init = 1; } hwalk = xtreeFind(memhosts, hostname); if (hwalk == xtreeEnd(memhosts)) { char *keyp = xstrdup(hostname); if (xtreeAdd(memhosts, keyp, NULL)) { errprintf("Insert into memhosts failed\n"); } } if (strstr(msg, "z/OS Memory Map")) { long j1, j2, j3; int csautil, ecsautil, sqautil, esqautil; char *p; /* z/OS Memory Utilization: Area Alloc Used HWM Util CSA 3524 3034 3436 86.1 ECSA 20172 19979 20014 99.0 SQA 1540 222 399 14.4 ESQA 13988 4436 4726 31.7 */ p = strstr(msg, "CSA ") + 4; if (p) { sscanf(p, "%ld %ld %ld %d", &j1, &j2, &j3, &csautil); } p = strstr(msg, "ECSA ") + 5; if (p) { sscanf(p, "%ld %ld %ld %d", &j1, &j2, &j3, &ecsautil); } p = strstr(msg, "SQA ") + 4; if (p) { sscanf(p, "%ld %ld %ld %d", &j1, &j2, &j3, &sqautil); } p = strstr(msg, "ESQA ") + 5; if (p) { sscanf(p, "%ld %ld %ld %d", &j1, &j2, &j3, &esqautil); } if (memory_tpl == NULL) memory_tpl = setup_template(memory_params); setupfn2("%s.%s.rrd", "memory", "CSA"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, csautil); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); setupfn2("%s.%s.rrd", "memory", "ECSA"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, ecsautil); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); setupfn2("%s.%s.rrd", "memory", "SQA"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, sqautil); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); setupfn2("%s.%s.rrd", "memory", "ESQA"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, esqautil); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); return 0; } if (strstr(msg, "z/VSE VSIZE Utilization")) { char *p; float pctused; p = strstr(msg, "Utilization ") + 12; if (p) { sscanf(p, "%f%%", &pctused); } if (memory_tpl == NULL) memory_tpl = setup_template(memory_params); setupfn2("%s.%s.rrd", "memory", "vsize"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, (int)pctused); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); return 0; } if (strstr(msg, "bb-xsnmp.pl")) { /* bb-xsnmp.pl memory update - Marco Avissano */ /* Cisco Routers memory report. * Aug 22 10:52:17 2006 * Memory Used Total Percentage * green Processor 2710556 13032864 20.80% * green I/O 1664400 4194304 39.68% * green Fast 1987024 8388608 23.69% */ char *proc, *io, *fast; proc = strstr(msg, "Processor"); if (proc == NULL) proc = strstr(msg, "Processor"); io = strstr(msg, "I/O"); if (io == NULL) io = strstr(msg, "I/O"); fast = strstr(msg, "Fast"); if (fast == NULL) fast = strstr(msg, "Fast"); if (proc) { char *eoln; int procval = -1, ioval = -1, fastval = -1; eoln = strchr(proc, '\n'); if (eoln) *eoln = '\0'; procval = get_mem_percent(proc); if (eoln) *eoln = '\n'; if (io) { eoln = strchr(io, '\n'); if (eoln) *eoln = '\0'; ioval = get_mem_percent(io); if (eoln) *eoln = '\n'; } if (fast) { eoln = strchr(fast, '\n'); if (eoln) *eoln = '\0'; fastval = get_mem_percent(fast); if (eoln) *eoln = '\n'; } do_memory_rrd_update_router(tstamp, hostname, testname, classname, pagepaths, procval, ioval, fastval); } return 0; } if (strstr(msg, "Total Cache Buffers")) { /* Netware nwstat2bb memory report. * * some.host.com|memory|green||1111681798|1111681982|1111699982|0|0|127.0.0.1|-1|| * green Thu Mar 24 17:33:02 CET 2005 - Memory OK * &green Original Cache Buffers : 326622 * &green Total Cache Buffers : 56% * &green Dirty Cache Buffers : 0% * &green Long Term Cache Hit Percentage : 0% * &green Least Recently Used (LRU) sitting time : 3 weeks, 2 days, 4 hours, 25 minutes, 36 seconds */ char *p; int val; p = strstr(msg, "Total Cache Buffers"); if (p) { p = strchr(p, ':'); if (p) { val = atoi(p+1); setupfn2("%s.%s.rrd", "memory", "tcb"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, val); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } } p = strstr(msg, "Dirty Cache Buffers"); if (p) { p = strchr(p, ':'); if (p) { val = atoi(p+1); setupfn2("%s.%s.rrd", "memory", "dcb"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, val); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } } p = strstr(msg, "Long Term Cache Hit Percentage"); if (p) { p = strchr(p, ':'); if (p) { val = atoi(p+1); setupfn2("%s.%s.rrd", "memory", "ltch"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, val); create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl); } } return 0; } else { phys = strstr(msg, "Physical"); if (phys == NULL) phys = strstr(msg, "Real"); swap = strstr(msg, "Swap"); if (swap == NULL) swap = strstr(msg, "Page"); actual = strstr(msg, "Actual"); if (actual == NULL) actual = strstr(msg, "Virtual"); if (phys) { char *eoln; int physval = -1, swapval = -1, actval = -1; eoln = strchr(phys, '\n'); if (eoln) *eoln = '\0'; physval = get_mem_percent(phys); if (eoln) *eoln = '\n'; if (swap) { eoln = strchr(swap, '\n'); if (eoln) *eoln = '\0'; swapval = get_mem_percent(swap); if (eoln) *eoln = '\n'; } if (actual) { eoln = strchr(actual, '\n'); if (eoln) *eoln = '\0'; actval = get_mem_percent(actual); if (eoln) *eoln = '\n'; } do_memory_rrd_update(tstamp, hostname, testname, classname, pagepaths, physval, swapval, actval); } } return 0; } xymon-4.3.30/xymond/rrd/do_cics.c0000664000076400007640000000433612000304667017063 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles "cics" messages. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* Copyright (C) 2008 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char cics_rcsid[] = "$Id: do_cics.c 6585 2010-11-14 15:12:56Z storner $"; static char *cicsntrans_params[] = { "DS:numtrans:GAUGE:600:0:U", NULL }; static char *cicsdsa_params[] = { "DS:dsa:GAUGE:600:0:100", "DS:edsa:GAUGE:600:0:100", NULL }; static char *cics_tpl = NULL; int do_cics_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *pr; char *fn = NULL; int numtrans; float dsapct, edsapct; char cicsappl[9], rrdfn[20]; pr=(strstr(msg, "Appl")); if (!pr) { return 0; } pr=(strstr(pr, "\n")); if (pr) { pr += 1; pr = strtok(pr, "\n"); while (pr != NULL) { sscanf(pr, "%s %d %f %f", cicsappl, &numtrans, &dsapct, &edsapct); snprintf(rrdfn, sizeof(rrdfn), "cics.%-s.rrd", cicsappl); setupfn(rrdfn, fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, numtrans); create_and_update_rrd(hostname, testname, classname, pagepaths, cicsntrans_params, cics_tpl); snprintf(rrdfn, sizeof(rrdfn), "dsa.%-s.rrd", cicsappl); setupfn(rrdfn, fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d", (int)tstamp, (int)dsapct, (int)edsapct); create_and_update_rrd(hostname, testname, classname, pagepaths, cicsdsa_params, cics_tpl); pr = strtok(NULL, "\n"); } } return 0; } xymon-4.3.30/xymond/rrd/do_ifstat.c0000664000076400007640000003145612634277577017465 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char ifstat_rcsid[] = "$Id: do_ifstat.c 7847 2015-12-16 15:13:03Z jccleaver $"; static char *ifstat_params[] = { "DS:bytesSent:DERIVE:600:0:U", "DS:bytesReceived:DERIVE:600:0:U", NULL }; static void *ifstat_tpl = NULL; /* eth0 Link encap: */ /* RX bytes: 1829192 (265.8 MiB) TX bytes: 1827320 (187.7 MiB */ static const char *ifstat_linux_exprs[] = { "^([a-z0-9]+(_[0-9]+)?:*|lo:?)\\s", "^\\s+RX bytes:([0-9]+) .*TX bytes.([0-9]+) ", "^\\s+RX packets\\s+[0-9]+\\s+bytes\\s+([0-9]+) ", "^\\s+TX packets\\s+[0-9]+\\s+bytes\\s+([0-9]+) " }; /* Name Mtu Network Address Ipkts Ierrs Idrop Ibytes Opkts Oerrs Obytes Coll */ /* em0 1500 14:da:e9:d2:10:b8 505128976 54 0 610016288902 294395839 14 290951791879 0 */ /* tun0 1500 tun0 0 0 0 0 5 0 436 0 */ /* Note: FreeBSD 9 and 10 have a blank column for "Address" when the interface doesn't have a MAC address */ static const char *ifstat_freebsd_exprs[] = { "^([a-z0-9]+)\\s+\\d+\\s+\\s+.*\\s+\\d+\\s+[0-9-]+\\s+[0-9-]+\\s+(\\d+)\\s+\\d+\\s+[0-9-]+\\s+(\\d+)\\s+[0-9-]+" }; /* Name Mtu Network Address Ipkts Ierrs Idrop Ibytes Opkts Oerrs Obytes Coll */ /* bge0 1500 192.168.X.X 192.168.X.X 29292829 - - 1130285651 26543376 - 2832025203 - */ static const char *ifstat_freebsdV8_exprs[] = { "^([a-z0-9]+)\\s+\\d+\\s+[0-9.\\/]+\\s+[0-9.]+\\s+\\d+\\s+[0-9-]+\\s+[0-9-]+\\s+(\\d+)\\s+\\d+\\s+[0-9-]+\\s+(\\d+)\\s+[0-9-]+" }; /* Name MTU Network IP Ibytes Obytes */ /* lnc0 1500 172.16.10.0/24 172.16.10.151 1818 1802 */ static const char *ifstat_openbsd_exprs[] = { "^([a-z0-9]+)\\s+\\d+\\s+[0-9.\\/]+\\s+[0-9.]+\\s+(\\d+)\\s+(\\d+)" }; /* Name MTU Network IP Ibytes Obytes */ /* lnc0 1500 172.16.10.0/24 172.16.10.151 1818 1802 */ static const char *ifstat_netbsd_exprs[] = { "^([a-z0-9]+)\\s+\\d+\\s+[0-9.\\/]+\\s+[0-9.]+\\s+(\\d+)\\s+(\\d+)" }; /* Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll en0 1500 fe80::20d:9 fe80::20d:93ff:fe 2013711826 - 2131205566781 331648829 - 41815551289 - en0 1500 130.223.20/24 130.223.20.20 2013711826 - 2131205566781 331648829 - 41815551289 - */ static const char *ifstat_darwin_exprs[] = { "^([a-z0-9]+)\\s+\\d+\\s+[0-9.\\/]+\\s+[0-9.]+\\s+\\d+\\s+[0-9-]+\\s+(\\d+)\\s+\\d+\\s+[0-9-]+\\s+(\\d+)\\s+[0-9-]+" }; /* dmfe:0:dmfe0:obytes64 107901705585 */ /* dmfe:0:dmfe0:rbytes64 1224808818952 */ /* dmfe:1:dmfe1:obytes64 0 */ /* dmfe:1:dmfe1:rbytes64 0 */ static const char *ifstat_solaris_exprs[] = { "^[a-z0-9]+:\\d+:([a-z0-9]+):obytes64\\s+(\\d+)", "^[a-z0-9]+:\\d+:([a-z0-9]+):rbytes64\\s+(\\d+)" }; /* ETHERNET STATISTICS (ent0) : Device Type: 2-Port 10/100/1000 Base-TX PCI-X Adapter (14108902) Hardware Address: 00:11:25:e6:0d:36 Elapsed Time: 45 days 20 hours 18 minutes 41 seconds Transmit Statistics: Receive Statistics: -------------------- ------------------- Packets: 1652404 Packets: 768800 Bytes: 1966314449 Bytes: 78793615 */ static const char *ifstat_aix_exprs[] = { "^ETHERNET STATISTICS \\(([a-z0-9]+)\\) :", "^Bytes:\\s+(\\d+)\\s+Bytes:\\s+(\\d+)" }; /* (lines dropped) PPA Number = 0 Description = lan0 Hewlett-Packard LAN Interface Hw Rev 0 Type (value) = ethernet-csmacd(6) MTU Size = 1500 Operation Status (value) = up(1) Inbound Octets = 3111235429 Outbound Octets = 3892111463 */ static const char *ifstat_hpux_exprs[] = { "^PPA Number\\s+= (\\d+)", "^Inbound Octets\\s+= (\\d+)", "^Outbound Octets\\s+= (\\d+)", }; /* Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll net0 1500 195.75.9 10.1.1.2 13096313 0 12257642 0 0 lo0 8232 127 127.0.0.1 26191 0 26191 0 0 Attention, theses numbers are packets, not bytes ! */ static const char *ifstat_sco_sv_exprs[] = { "^([a-z]+[0-9]+)\\s+[0-9]+\\s+[0-9.]+\\s+[0-9.]+\\s+([0-9]+)\\s+[0-9]+\\s+([0-9]+)\\s+" }; /* IP Ibytes Obytes */ /* 192.168.0.1 1818 1802 */ static const char *ifstat_bbwin_exprs[] = { "^([a-zA-Z0-9.:]+)\\s+([0-9]+)\\s+([0-9]+)" }; int do_ifstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static int pcres_compiled = 0; static pcre **ifstat_linux_pcres = NULL; static pcre **ifstat_freebsd_pcres = NULL; static pcre **ifstat_freebsdV8_pcres = NULL; static pcre **ifstat_openbsd_pcres = NULL; static pcre **ifstat_netbsd_pcres = NULL; static pcre **ifstat_darwin_pcres = NULL; static pcre **ifstat_solaris_pcres = NULL; static pcre **ifstat_aix_pcres = NULL; static pcre **ifstat_hpux_pcres = NULL; static pcre **ifstat_sco_sv_pcres = NULL; static pcre **ifstat_bbwin_pcres = NULL; enum ostype_t ostype; char *datapart = msg; char *bol, *eoln, *ifname, *rxstr, *txstr, *dummy; int dmatch; void *xmh; pcre *ifname_filter_pcre = NULL; xmh = hostinfo(hostname); if (xmh) { char *ifname_filter_expr = xmh_item(xmh, XMH_INTERFACES); if (ifname_filter_expr && *ifname_filter_expr) ifname_filter_pcre = compileregex(ifname_filter_expr); } if (pcres_compiled == 0) { pcres_compiled = 1; ifstat_linux_pcres = compile_exprs("LINUX", ifstat_linux_exprs, (sizeof(ifstat_linux_exprs) / sizeof(ifstat_linux_exprs[0]))); ifstat_freebsd_pcres = compile_exprs("FREEBSD", ifstat_freebsd_exprs, (sizeof(ifstat_freebsd_exprs) / sizeof(ifstat_freebsd_exprs[0]))); ifstat_freebsdV8_pcres = compile_exprs("FREEBSD", ifstat_freebsdV8_exprs, (sizeof(ifstat_freebsdV8_exprs) / sizeof(ifstat_freebsdV8_exprs[0]))); ifstat_openbsd_pcres = compile_exprs("OPENBSD", ifstat_openbsd_exprs, (sizeof(ifstat_openbsd_exprs) / sizeof(ifstat_openbsd_exprs[0]))); ifstat_netbsd_pcres = compile_exprs("NETBSD", ifstat_netbsd_exprs, (sizeof(ifstat_netbsd_exprs) / sizeof(ifstat_netbsd_exprs[0]))); ifstat_darwin_pcres = compile_exprs("DARWIN", ifstat_darwin_exprs, (sizeof(ifstat_darwin_exprs) / sizeof(ifstat_darwin_exprs[0]))); ifstat_solaris_pcres = compile_exprs("SOLARIS", ifstat_solaris_exprs, (sizeof(ifstat_solaris_exprs) / sizeof(ifstat_solaris_exprs[0]))); ifstat_aix_pcres = compile_exprs("AIX", ifstat_aix_exprs, (sizeof(ifstat_aix_exprs) / sizeof(ifstat_aix_exprs[0]))); ifstat_hpux_pcres = compile_exprs("HPUX", ifstat_hpux_exprs, (sizeof(ifstat_hpux_exprs) / sizeof(ifstat_hpux_exprs[0]))); ifstat_sco_sv_pcres = compile_exprs("SCO_SV", ifstat_sco_sv_exprs, (sizeof(ifstat_sco_sv_exprs) / sizeof(ifstat_sco_sv_exprs[0]))); ifstat_bbwin_pcres = compile_exprs("BBWIN", ifstat_bbwin_exprs, (sizeof(ifstat_bbwin_exprs) / sizeof(ifstat_bbwin_exprs[0]))); } if (ifstat_tpl == NULL) ifstat_tpl = setup_template(ifstat_params); if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Skip the first line of full status- and data-messages. */ datapart = strchr(msg, '\n'); if (datapart) datapart++; else datapart = msg; } ostype = get_ostype(datapart); datapart = strchr(datapart, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines in ifstat report from %s\n", hostname); return -1; } dmatch = 0; ifname = rxstr = txstr = dummy = NULL; bol = datapart; while (bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; switch (ostype) { case OS_LINUX22: case OS_LINUX: case OS_RHEL3: case OS_ZVM: case OS_ZVSE: case OS_ZOS: if (pickdata(bol, ifstat_linux_pcres[0], 1, &ifname)) { /* * Linux' netif aliases mess up things. * Clear everything when we see an interface name. * But we don't want to track the "lo" interface. */ /* Strip off the last character if it is a colon (:) */ if (ifname[strlen(ifname)-1] == ':') ifname[strlen(ifname)-1] = '\0'; if (strcmp(ifname, "lo") == 0) { xfree(ifname); ifname = NULL; } else { dmatch = 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } } else if (pickdata(bol, ifstat_linux_pcres[1], 1, &rxstr, &txstr)) dmatch |= 6; else if (pickdata(bol, ifstat_linux_pcres[2], 1, &rxstr)) dmatch |= 2; else if (pickdata(bol, ifstat_linux_pcres[3], 1, &txstr)) dmatch |= 4; break; case OS_FREEBSD: /* * FreeBSD 8 added an "Idrop" counter in the middle of the data. * See if we match this expression, and if not then fall back to * the old regex without that field. */ if (pickdata(bol, ifstat_freebsdV8_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; else if (pickdata(bol, ifstat_freebsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_OPENBSD: if (pickdata(bol, ifstat_openbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_NETBSD: if (pickdata(bol, ifstat_netbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_SOLARIS: if (pickdata(bol, ifstat_solaris_pcres[0], 0, &ifname, &txstr)) dmatch |= 1; else if (pickdata(bol, ifstat_solaris_pcres[1], 0, &dummy, &rxstr)) dmatch |= 6; if (ifname && dummy && (strcmp(ifname, dummy) != 0)) { /* They must match, drop the data */ errprintf("Host %s has weird ifstat data - device name mismatch %s:%s\n", hostname, ifname, dummy); xfree(ifname); xfree(txstr); xfree(rxstr); xfree(dummy); dmatch = 0; } /* Ignore "mac" and "wrsmd" entries - these are for sub-devices for multiple nic's aggregated into one */ /* See http://www.xymon.com/archive/2009/06/msg00204.html for more info */ if (ifname && ((strcmp(ifname, "mac") == 0) || (strcmp(ifname, "wrsmd") == 0)) ) { xfree(ifname); xfree(txstr); dmatch = 0; } if (dummy && ((strcmp(dummy, "mac") == 0) || (strcmp(dummy, "wrsmd") == 0)) ) { xfree(dummy); xfree(rxstr); dmatch = 0; } break; case OS_AIX: if (pickdata(bol, ifstat_aix_pcres[0], 1, &ifname)) { /* Interface names comes first, so any rx/tx data is discarded */ dmatch |= 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } else if (pickdata(bol, ifstat_aix_pcres[1], 1, &txstr, &rxstr)) dmatch |= 6; break; case OS_HPUX: if (pickdata(bol, ifstat_hpux_pcres[0], 1, &ifname)) { /* Interface names comes first, so any rx/tx data is discarded */ dmatch |= 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } else if (pickdata(bol, ifstat_hpux_pcres[1], 1, &rxstr)) dmatch |= 2; else if (pickdata(bol, ifstat_hpux_pcres[2], 1, &txstr)) dmatch |= 4; break; case OS_DARWIN: if (pickdata(bol, ifstat_darwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_SCO_SV: if (pickdata(bol, ifstat_sco_sv_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_WIN32_BBWIN: case OS_WIN_POWERSHELL: if (pickdata(bol, ifstat_bbwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; default: break; } if ((dmatch == 7) && ifname && rxstr && txstr) { if (!ifname_filter_pcre || matchregex(ifname, ifname_filter_pcre)) { setupfn2("%s.%s.rrd", "ifstat", ifname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s:%s", (int)tstamp, txstr, rxstr); create_and_update_rrd(hostname, testname, classname, pagepaths, ifstat_params, ifstat_tpl); } xfree(ifname); xfree(rxstr); xfree(txstr); if (dummy) xfree(dummy); ifname = rxstr = txstr = dummy = NULL; dmatch = 0; } if (eoln) { *eoln = '\n'; bol = eoln+1; if (*bol == '\0') bol = NULL; } else { bol = NULL; } } if (ifname_filter_pcre) freeregex(ifname_filter_pcre); if (ifname) xfree(ifname); if (rxstr) xfree(rxstr); if (txstr) xfree(txstr); if (dummy) xfree(dummy); return 0; } xymon-4.3.30/xymond/rrd/do_iostat.c0000664000076400007640000001642212000304667017444 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char iostat_rcsid[] = "$Id: do_iostat.c 7058 2012-07-14 15:01:11Z storner $"; static char *iostat_params[] = { "DS:rs:GAUGE:600:1:U", "DS:ws:GAUGE:600:1:U", "DS:krs:GAUGE:600:1:U", "DS:kws:GAUGE:600:1:U", "DS:wait:GAUGE:600:1:U", "DS:actv:GAUGE:600:1:U", "DS:wsvc_t:GAUGE:600:1:U", "DS:asvc_t:GAUGE:600:1:U", "DS:w:GAUGE:600:1:U", "DS:b:GAUGE:600:1:U", "DS:sw:GAUGE:600:1:U", "DS:hw:GAUGE:600:1:U", "DS:trn:GAUGE:600:1:U", "DS:tot:GAUGE:600:1:U", NULL }; static void *iostat_tpl = NULL; int do_iostatdisk_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *dataline; /* * This format is reported in the "iostatdisk" section: * * data HOSTNAME.iostatdisk * solaris * extended device statistics * device,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b, * dad0,a,0.0,0.7,0.0,5.8,0.0,0.0,4.3,0,0 * dad0,b,0.0,0.0,0.0,0.0,0.0,0.0,27.9,0,0 * dad0,c,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * dad0,e,0.0,0.6,0.0,4.1,0.0,0.0,3.7,0,0 * dad0,f,0.0,17.2,0.0,89.7,0.0,0.0,0.2,0,0 * dad0,h,0.0,0.5,0.0,2.7,0.0,0.0,2.2,0,0 * dad1,c,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * dad1,h,0.0,0.0,0.0,0.0,0.0,0.0,27.1,0,0 * nfs1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * extended device statistics * device,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b, * dad0,a,0.0,0.6,0.0,5.1,0.0,0.0,4.2,0,0 * dad0,b,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * dad0,c,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * dad0,e,0.0,0.5,0.0,3.4,0.0,0.0,3.2,0,0 * dad0,f,0.0,12.6,0.0,65.6,0.0,0.0,0.2,0,0 * dad0,h,0.0,0.4,0.0,2.4,0.0,0.0,1.8,0,0 * dad1,c,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * dad1,h,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * nfs1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0 * * There are two chunks of data: Like vmstat, we first get a * summary at the start of data collection, and then another * with the 5-minute average. So we must skip the first chunk. * * Note that real disks are identified by "dad0,a" whereas * NFS mounts show up as "nfs1" (no comma!). */ if (iostat_tpl == NULL) iostat_tpl = setup_template(iostat_params); dataline = strstr(msg, "\ndevice,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b,"); if (!dataline) return -1; dataline = strstr(dataline+1, "\ndevice,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b,"); if (!dataline) return -1; dataline++; while (dataline && *dataline) { char *elems[12]; char *eoln, *p, *id = ""; int i, valofs; eoln = strchr(dataline, '\n'); if (eoln) *eoln = '\0'; memset(elems, 0, sizeof(elems)); p = elems[0] = dataline; i=0; do { p = strchr(p+1, ','); i++; if (p) { *p = '\0'; elems[i] = p+1; } } while (p); if (elems[9] == NULL) goto nextline; else if (elems[10] == NULL) { /* NFS "disk" */ id = elems[0]; valofs = 1; } else { /* Normal disk - re-instate the "," between elems[0] and elems[1] */ *(elems[1]-1) = ','; /* Hack! */ valofs = 2; } setupfn2("%s.%s.rrd", "iostat", id); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s", (int) tstamp, elems[valofs], /* r/s */ elems[valofs+1], /* w/s */ elems[valofs+2], /* kr/s */ elems[valofs+3], /* kw/s */ elems[valofs+4], /* wait */ elems[valofs+5], /* actv */ elems[valofs+6], /* wsvc_t - we use svc_t here */ "U", /* asvc_t not in this format */ elems[valofs+7], /* %w */ elems[valofs+8], /* %b */ "U", "U", "U", "U" /* sw, hw, trn, tot not in this format */ ); nextline: dataline = (eoln ? eoln+1 : NULL); } return 0; } int do_iostat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { /* * BEGINKEY * d0 / * d5 /var * d6 /export * ENDKEY * BEGINDATA * r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b s/w h/w trn tot device * 0.9 2.8 7.3 1.8 0.0 0.0 2.7 9.3 1 2 0 0 0 0 d0 * 0.1 0.3 0.8 0.5 0.0 0.0 5.2 11.0 0 0 0 0 0 0 d5 * 0.1 0.2 1.0 1.1 0.0 0.0 6.9 12.9 0 0 0 0 0 0 d6 * ENDDATA */ typedef struct iostatkey_t { char *key; char *value; struct iostatkey_t *next; } iostatkey_t; enum { S_NONE, S_KEYS, S_DATA } state; iostatkey_t *keyhead = NULL; iostatkey_t *newkey; char *eoln, *curline; char *buf, *p; float v[14]; char marker[MAX_LINE_LEN]; MEMDEFINE(marker); if (iostat_tpl == NULL) iostat_tpl = setup_template(iostat_params); curline = msg; state = S_NONE; while (curline) { eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; if (strncmp(curline, "BEGINKEY", 8) == 0) { state = S_KEYS; } else if (strncmp(curline, "ENDKEY", 6) == 0) { state = S_NONE; } else if (strncmp(curline, "BEGINDATA", 9) == 0) { state = S_DATA; } else if (strncmp(curline, "ENDDATA", 7) == 0) { state = S_NONE; } else { switch (state) { case S_NONE: break; case S_KEYS: buf = xstrdup(curline); newkey = (iostatkey_t *)xcalloc(1, sizeof(iostatkey_t)); p = strtok(buf, " "); if (p) newkey->key = xstrdup(p); p = strtok(NULL, " "); if (p) { if (strcmp(p, "/") == 0) newkey->value = xstrdup(",root"); else { newkey->value = xstrdup(p); p = newkey->value; while ((p = strchr(p, '/')) != NULL) *p = ','; } } xfree(buf); if (newkey->key && newkey->value) { newkey->next = keyhead; keyhead = newkey; } else { if (newkey->key) xfree(newkey->key); if (newkey->value) xfree(newkey->value); xfree(newkey); } break; case S_DATA: buf = xstrdup(curline); if (sscanf(buf, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %s", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], &v[9], &v[10], &v[11], &v[12], &v[13], marker) == 15) { /* Find the disk name */ for (newkey = keyhead; (newkey && strcmp(newkey->key, marker)); newkey = newkey->next) ; if (newkey) { setupfn2("%s.%s.rrd", "iostat", newkey->value); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f", (int) tstamp, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12], v[13]); create_and_update_rrd(hostname, testname, classname, pagepaths, iostat_params, iostat_tpl); } } xfree(buf); break; } } if (eoln) { *eoln = '\n'; curline = eoln + 1; } else { curline = NULL; } } /* Free the keylist */ while (keyhead) { newkey = keyhead; keyhead = keyhead->next; if (newkey->key) xfree(newkey->key); if (newkey->value) xfree(newkey->value); xfree(newkey); } MEMUNDEFINE(marker); return 0; } xymon-4.3.30/xymond/rrd/do_mdc.c0000664000076400007640000000374712000025440016677 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles z/VM "mdc" data messages */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* Copyright (C) 2007 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char mdc_rcsid[] = "$Id: do_mdc.c 6585 2010-11-14 15:12:56Z storner $"; static char *mdc_params[] = { "DS:reads:GAUGE:600:0:U", "DS:writes:GAUGE:600:0:U", NULL }; static char *mdcpct_params[] = { "DS:hitpct:GAUGE:600:0:100", NULL }; static char *mdc_tpl = NULL; int do_mdc_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *pr; char *fn = NULL; int mdcreads, mdcwrites, mdchitpct; pr=(strstr(msg, "\n")); pr++; pr=(strstr(pr, "\n")); /* There are two of them... */ if (pr) { pr++; sscanf(pr, "%d:%d:%d", &mdcreads, &mdcwrites, &mdchitpct); setupfn("mdc.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d", (int)tstamp, mdcreads, mdcwrites); create_and_update_rrd(hostname, testname, classname, pagepaths, mdc_params, mdc_tpl); setupfn("mdchitpct.rrd", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, mdchitpct); create_and_update_rrd(hostname, testname, classname, pagepaths, mdcpct_params, mdc_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_sendmail.c0000664000076400007640000001320012000025440017711 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char sendmail_rcsid[] = "$Id: do_sendmail.c 7026 2012-07-13 14:05:20Z storner $"; int do_sendmail_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *sendmail_params_1[] = { "DS:msgsfr:DERIVE:600:0:U", "DS:bytes_from:DERIVE:600:0:U", "DS:msgsto:DERIVE:600:0:U", "DS:bytes_to:DERIVE:600:0:U", "DS:msgsrej:DERIVE:600:0:U", "DS:msgsdis:DERIVE:600:0:U", NULL }; static void *sendmail_tpl_1 = NULL; static char *sendmail_params_2[] = { "DS:msgsfr:DERIVE:600:0:U", "DS:bytes_from:DERIVE:600:0:U", "DS:msgsto:DERIVE:600:0:U", "DS:bytes_to:DERIVE:600:0:U", "DS:msgsrej:DERIVE:600:0:U", "DS:msgsdis:DERIVE:600:0:U", "DS:msgsqur:DERIVE:600:0:U", NULL }; static void *sendmail_tpl_2 = NULL; /* * The data we process is the output from the "mailstats" command. * * Statistics from Mon Apr 25 16:29:41 2005 * M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis msgsqur Mailer * 3 183435 215701K 0 0K 0 0 0 local * 5 0 0K 183435 215544K 0 0 0 esmtp * ===================================================================== * T 183435 215701K 183435 215544K 0 0 0 * C 183435 183435 0 * * We pick up those lines that come before the "============" line, and * create one RRD per "Mailer", with the counters. * * The output of the mailstats command will depend on the version of sendmail * used. This example is from sendmail 8.13.x which added the msgsqur column. * Sendmail versions prior to 8.10.0 did not have the mgsdis and msgsrej * columns. * */ char *bofdata, *eofdata, *eoln = NULL; int done, found; unsigned long msgsfr, bytesfr, msgsto, bytesto, msgsrej, msgsdis, msgsqur; if (sendmail_tpl_1 == NULL) sendmail_tpl_1 = setup_template(sendmail_params_1); if (sendmail_tpl_2 == NULL) sendmail_tpl_2 = setup_template(sendmail_params_2); /* Find the line that begins with "=====" and NULL the message there */ eofdata = strstr(msg, "\n=="); if (eofdata) *(eofdata+1) = '\0'; else return -1; /* Find the start of the Statistics part. */ bofdata = strstr(msg, "\nStatistics "); if (!bofdata) return -1; /* Skip the "Statistics from.... " line */ bofdata = strchr(bofdata+1, '\n'); if (!bofdata) return -1; /* Skip the header line */ bofdata = strchr(bofdata+1, '\n'); if (bofdata) bofdata++; else return -1; done = (bofdata == NULL); while (!done) { char mailer[1024]; MEMDEFINE(mailer); *rrdvalues = '\0'; eoln = strchr(bofdata, '\n'); if (eoln) { *eoln = '\0'; /* First try for sendmail 8.13.x format */ found = sscanf(bofdata, "%*s %lu %luK %lu %luK %lu %lu %lu %s", &msgsfr, &bytesfr, &msgsto, &bytesto, &msgsrej, &msgsdis, &msgsqur, mailer); if (found == 8) { snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu:%lu:%lu:%lu:%lu:%lu:%lu", (int)tstamp, msgsfr, bytesfr*1024, msgsto, bytesto*1024, msgsrej, msgsdis, msgsqur); goto gotdata; } /* Next sendmail 8.10.x - without msgsqur */ found = sscanf(bofdata, "%*s %lu %luK %lu %luK %lu %lu %s", &msgsfr, &bytesfr, &msgsto, &bytesto, &msgsrej, &msgsdis, mailer); if (found == 7) { snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu:%lu:%lu:%lu:%lu:%lu:U", (int)tstamp, msgsfr, bytesfr*1024, msgsto, bytesto*1024, msgsrej, msgsdis); goto gotdata; } /* Last resort: Sendmail prior to 8.10 - without msgsrej, msgsdis, msgsqur */ found = sscanf(bofdata, "%*s %lu %luK %lu %luK %s", &msgsfr, &bytesfr, &msgsto, &bytesto, mailer); if (found == 5) { snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lu:%lu:%lu:%lu:U:U:U", (int)tstamp, msgsfr, bytesfr*1024, msgsto, bytesto*1024); goto gotdata; } gotdata: if (*rrdvalues) { int dscount, i; char **dsnames = NULL; setupfn2("%s.%s.rrd", "sendmail", mailer); /* Get the RRD-file dataset count, so we can decide what to do */ dscount = rrddatasets(hostname, &dsnames); if ((dscount > 0) && dsnames) { /* Free the dsnames list */ for (i=0; (i */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char netapp_rcsid[] = "$Id: do_netapp.c 7969 2016-10-21 23:26:36Z jccleaver $"; int do_netapp_stats_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_stats_params[] = { "DS:NETread:GAUGE:600:0:U", "DS:NETwrite:GAUGE:600:0:U", "DS:DISKread:GAUGE:600:0:U", "DS:DISKwrite:GAUGE:600:0:U", "DS:TAPEread:GAUGE:600:0:U", "DS:TAPEwrite:GAUGE:600:0:U", "DS:FCPin:GAUGE:600:0:U", "DS:FCPout:GAUGE:600:0:U", NULL }; static void *netapp_stats_tpl = NULL; unsigned long netread=0, netwrite=0, diskread=0, diskwrite=0, taperead=0, tapewrite=0, fcpin=0, fcpout=0; dbgprintf("netapp: host %s test %s\n",hostname, testname); if (strstr(msg, "netapp.pl")) { setupfn("%s.rrd", testname); if (netapp_stats_tpl == NULL) netapp_stats_tpl = setup_template(netapp_stats_params); netread=get_kb_data(msg, "NET_read"); netwrite=get_kb_data(msg,"NET_write"); diskread=get_kb_data(msg,"DISK_read"); diskwrite=get_kb_data(msg,"DISK_write"); taperead=get_kb_data(msg,"TAPE_read"); tapewrite=get_kb_data(msg,"TAPE_write"); fcpin=get_kb_data(msg,"FCP_in"); fcpout=get_kb_data(msg,"FCP_out"); dbgprintf("netapp: host %s test %s netread %ld netwrite %ld\n", hostname, testname, netread,netwrite); dbgprintf("netapp: host %s test %s diskread %ld diskwrite %ld\n", hostname, testname, diskread,diskwrite); dbgprintf("netapp: host %s test %s taperead %ld tapewrite %ld\n", hostname, testname, taperead,tapewrite); dbgprintf("netapp: host %s test %s fcpin %ld fcpout %ld\n", hostname, testname, fcpin,fcpout); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, netread, netwrite, diskread, diskwrite, taperead, tapewrite, fcpin, fcpout); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_stats_params, netapp_stats_tpl); } return 0; } int do_netapp_cifs_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_cifs_params[] = { "DS:sessions:GAUGE:600:0:U", "DS:openshares:GAUGE:600:0:U", "DS:openfiles:GAUGE:600:0:U", "DS:locks:GAUGE:600:0:U", "DS:credentials:GAUGE:600:0:U", "DS:opendirectories:GAUGE:600:0:U", "DS:ChangeNotifies:GAUGE:600:0:U", "DS:sessionsusingsecuri:GAUGE:600:0:U", NULL }; static void *netapp_cifs_tpl = NULL; unsigned long sess=0, share=0, file=0, lock=0, cred=0, dir=0, change=0, secsess=0; dbgprintf("netapp: host %s test %s\n",hostname, testname); if (strstr(msg, "netapp.pl")) { setupfn("%s.rrd", testname); if (netapp_cifs_tpl == NULL) netapp_cifs_tpl = setup_template(netapp_cifs_params); sess=get_long_data(msg, "sessions"); share=get_long_data(msg,"open_shares"); file=get_long_data(msg,"open_files"); lock=get_long_data(msg,"locks"); cred=get_long_data(msg,"credentials"); dir=get_long_data(msg,"open_directories"); change=get_long_data(msg,"ChangeNotifies"); secsess=get_long_data(msg,"sessions_using_security_signatures"); dbgprintf("netapp: host %s test %s Session %ld OpenShare %ld\n", hostname, testname, sess, share); dbgprintf("netapp: host %s test %s OpenFile %ld Locks %ld\n", hostname, testname, file, lock); dbgprintf("netapp: host %s test %s Cred %ld OpenDir %ld\n", hostname, testname, cred, dir); dbgprintf("netapp: host %s test %s ChangeNotif %ld SecureSess %ld\n", hostname, testname, change, secsess); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, sess, share, file, lock, cred, dir, change,secsess); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_cifs_params, netapp_cifs_tpl); } return 0; } int do_netapp_ops_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_ops_params[] = { "DS:NFSops:GAUGE:600:0:U", "DS:CIFSops:GAUGE:600:0:U", "DS:iSCSIops:GAUGE:600:0:U", "DS:HTTPops:GAUGE:600:0:U", "DS:FCPops:GAUGE:600:0:U", "DS:Totalops:GAUGE:600:0:U", NULL }; static void *netapp_ops_tpl = NULL; unsigned long nfsops=0, cifsops=0, httpops=0, iscsiops=0, fcpops=0, totalops=0; dbgprintf("netapp: host %s test %s\n",hostname, testname); if (strstr(msg, "netapp.pl")) { setupfn("%s.rrd",testname); if (netapp_ops_tpl == NULL) netapp_ops_tpl = setup_template(netapp_ops_params); nfsops=get_long_data(msg, "NFS_ops"); cifsops=get_long_data(msg,"CIFS_ops"); httpops=get_long_data(msg,"HTTP_ops"); fcpops=get_long_data(msg,"FCP_ops"); iscsiops=get_long_data(msg,"iSCSI_ops"); totalops=get_long_data(msg,"Total_ops"); dbgprintf("netapp: host %s test %s nfsops %ld cifsops %ld\n", hostname, testname, nfsops, cifsops); dbgprintf("netapp: host %s test %s httpops %ld fcpops %ld\n", hostname, testname, httpops, fcpops); dbgprintf("netapp: host %s test %s iscsiops %ld totalops %ld\n", hostname, testname, iscsiops, totalops); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, nfsops, cifsops, httpops, fcpops, iscsiops, totalops); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_ops_params, netapp_ops_tpl); } return 0; } int do_netapp_snapmirror_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_snapmirror_params[] = { "DS:size:GAUGE:600:0:U", NULL }; static void *netapp_snapmirror_tpl = NULL; char *eoln, *curline, *start, *end; dbgprintf("netapp: host %s test %s\n",hostname, testname); if (strstr(msg, "netapp.pl")) { if (netapp_snapmirror_tpl == NULL) netapp_snapmirror_tpl = setup_template(netapp_snapmirror_params); if ((start=strstr(msg, ""))==NULL) return 0; *end='\0'; eoln = strchr(start, '\n'); curline = (eoln ? (eoln+1) : NULL); while (curline && (*curline)) { char *equalsign; long long size; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; equalsign=strchr(curline,'='); if (equalsign) { *(equalsign++)= '\0'; size=str2ll(equalsign,NULL); dbgprintf("netapp: host %s test %s SNAPMIRROR %s size %lld\n", hostname, testname, curline, size); setupfn2("%s,%s.rrd", testname, curline); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lld", (int)tstamp, size); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_snapmirror_params, netapp_snapmirror_tpl); *(--equalsign)='='; } if (eoln) *eoln = '\n'; curline = (eoln ? (eoln+1) : NULL); } *end='-'; } return 0; } int do_netapp_snaplist_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_snaplist_params[] = { "DS:youngsize:GAUGE:600:0:U", "DS:oldsize:GAUGE:600:0:U", NULL }; static void *netapp_snaplist_tpl = NULL; char *eoln, *curline, *start, *end; dbgprintf("netapp: host %s test %s\n",hostname, testname); if (strstr(msg, "netapp.pl")) { if (netapp_snaplist_tpl == NULL) netapp_snaplist_tpl = setup_template(netapp_snaplist_params); if ((start=strstr(msg, ""))==NULL) return 0; *end='\0'; eoln = strchr(start, '\n'); curline = (eoln ? (eoln+1) : NULL); while (curline && (*curline)) { char *fsline, *p; char *columns[5]; int columncount; char *volname = NULL; long long young,old; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; for (columncount=0; (columncount<5); columncount++) columns[columncount] = ""; fsline = xstrdup(curline); columncount = 0; p = strtok(fsline, "="); while (p && (columncount < 5)) { columns[columncount++] = p; p = strtok(NULL, ":"); } volname = xstrdup(columns[0]); young=str2ll(columns[1],NULL); old=str2ll(columns[2],NULL); dbgprintf("netapp: host %s test %s vol %s young %lld old %lld\n", hostname, testname, volname, young, old); setupfn2("%s,%s.rrd", testname, volname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%lld:%lld", (int)tstamp, young, old); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_snaplist_params, netapp_snaplist_tpl); if (volname) { xfree(volname); volname = NULL; } if (eoln) *eoln = '\n'; xfree(fsline); curline = (eoln ? (eoln+1) : NULL); } *end='-'; } return 0; } int do_netapp_extratest_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp, char *params[], rrdtpldata_t **tpl, char *varlist[]) { static rrdtpldata_t *netapp_tpl = NULL; char *outp; char *eoln,*curline; char *rrdp; /* Setup the update string */ if (tpl == NULL) netapp_tpl = setup_template(params); else { if ((*tpl) == NULL) *tpl = setup_template(params); netapp_tpl = *tpl; } curline = msg; dbgprintf("MESSAGE=%s\n",msg); rrdp = rrdvalues + snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); while (curline && (*curline)) { char *fsline, *p, *sep, *fname=NULL; char *columns[30]; int columncount; char *volname = NULL; int i,flag,l,first,totnum; char *val; outp=rrdp; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; if ((eoln == curline) || (strstr(curline,"netapp.pl"))) { dbgprintf("SKIP LINE=\n",curline); goto nextline; } fsline = xstrdup(curline); dbgprintf("LINE=%s\n",fsline); for (columncount=0; (columncount<30); columncount++) columns[columncount] = NULL; for (totnum=0; varlist[totnum]; totnum++) ; columncount = 0; p = strtok(fsline, ";"); first=0; while (p) { if (first==0) { fname=p; first=1; } else { sep=strchr(p,':'); if (sep) { l=sep-p; sep++; dbgprintf("Checking %s len=%d\n",p,l); flag=0; i = 0; while ((flag==0) && (varlist[i])) { dbgprintf("with %s\n",varlist[i]); if (strncmp(varlist[i], p, l) == 0) { columns[i]=sep; flag=1; } i++; } } } p = strtok(NULL, ";"); } volname = xstrdup(fname); p = volname; while ((p = strchr(p, '/')) != NULL) { *p = ','; } dbgprintf("netapp: host %s test %s name %s \n", hostname, testname, volname); setupfn2("%s,%s.rrd", testname, volname); for (i=0; varlist[i]; i++) { val=columns[i]; if (val) { outp += snprintf(outp, sizeof(rrdvalues)-(outp-rrdvalues), ":%s",val); dbgprintf("var %s value %s \n", varlist[i], columns[i]); } else { outp += snprintf(outp, sizeof(rrdvalues)-(outp-rrdvalues), ":%s","U"); } } create_and_update_rrd(hostname, testname, classname, pagepaths, params, netapp_tpl); if (volname) { xfree(volname); volname = NULL; } if (eoln) *eoln = '\n'; xfree(fsline); nextline: curline = (eoln ? (eoln+1) : NULL); } return 0; } int do_netapp_extrastats_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_qtree_params[] = { "DS:nfs_ops:GAUGE:600:0:U", "DS:cifs_ops:GAUGE:600:0:U", NULL }; static char *netapp_aggregate_params[] = { "DS:total_transfers:GAUGE:600:0:U", "DS:user_reads:GAUGE:600:0:U", "DS:user_writes:GAUGE:600:0:U", "DS:cp_reads:GAUGE:600:0:U", "DS:user_read_blocks:GAUGE:600:0:U", "DS:user_write_blocks:GAUGE:600:0:U", "DS:cp_read_blocks:GAUGE:600:0:U", NULL }; static char *netapp_iscsi_params[] = { "DS:iscsi_ops:GAUGE:600:0:U", "DS:iscsi_write_data:GAUGE:600:0:U", "DS:iscsi_read_data:GAUGE:600:0:U", NULL }; static char *netapp_fcp_params[] = { "DS:fcp_ops:GAUGE:600:0:U", "DS:fcp_write_data:GAUGE:600:0:U", "DS:fcp_read_data:GAUGE:600:0:U", NULL }; static char *netapp_cifs_params[] = { "DS:cifs_ops:GAUGE:600:0:U", "DS:cifs_latency:GAUGE:600:0:U", NULL }; static char *netapp_volume_params[] = { "DS:avg_latency:GAUGE:600:0:U", "DS:total_ops:GAUGE:600:0:U", "DS:read_data:GAUGE:600:0:U", "DS:read_latency:GAUGE:600:0:U", "DS:read_ops:GAUGE:600:0:U", "DS:write_data:GAUGE:600:0:U", "DS:write_latency:GAUGE:600:0:U", "DS:write_ops:GAUGE:600:0:U", "DS:other_latency:GAUGE:600:0:U", "DS:other_ops:GAUGE:600:0:U", NULL }; static char *netapp_lun_params[] = { "DS:read_ops:GAUGE:600:0:U", "DS:write_ops:GAUGE:600:0:U", "DS:other_ops:GAUGE:600:0:U", "DS:read_data:GAUGE:600:0:U", "DS:write_data:GAUGE:600:0:U", "DS:queue_full:GAUGE:600:0:U", "DS:avg_latency:GAUGE:600:0:U", "DS:total_ops:GAUGE:600:0:U", NULL }; static char *netapp_nfsv3_params[] = { "DS:ops:GAUGE:600:0:U", "DS:read_latency:GAUGE:600:0:U", "DS:read_ops:GAUGE:600:0:U", "DS:write_latency:GAUGE:600:0:U", "DS:write_ops:GAUGE:600:0:U", NULL }; static char *netapp_ifnet_params[] = { "DS:recv_packets:GAUGE:600:0:U", "DS:recv_errors:GAUGE:600:0:U", "DS:send_packets:GAUGE:600:0:U", "DS:send_errors:GAUGE:600:0:U", "DS:collisions:GAUGE:600:0:U", "DS:recv_data:GAUGE:600:0:U", "DS:send_data:GAUGE:600:0:U", "DS:recv_mcasts:GAUGE:600:0:U", "DS:send_mcasts:GAUGE:600:0:U", "DS:recv_drop_packets:GAUGE:600:0:U", NULL }; static char *netapp_processor_params[] = { "DS:proc_busy:GAUGE:600:0:U", NULL }; static char *netapp_disk_params[] = { "DS:total_transfers:GAUGE:600:0:U", "DS:user_read_chain:GAUGE:600:0:U", "DS:user_reads:GAUGE:600:0:U", "DS:user_write_chain:GAUGE:600:0:U", "DS:user_writes:GAUGE:600:0:U", "DS:cp_read_chain:GAUGE:600:0:U", "DS:cp_reads:GAUGE:600:0:U", "DS:gar_read_chain:GAUGE:600:0:U", "DS:gar_reads:GAUGE:600:0:U", "DS:gar_write_chain:GAUGE:600:0:U", "DS:gar_writes:GAUGE:600:0:U", "DS:user_read_latency:GAUGE:600:0:U", "DS:user_read_blocks:GAUGE:600:0:U", "DS:user_write_latency:GAUGE:600:0:U", "DS:user_write_blocks:GAUGE:600:0:U", "DS:cp_read_latency:GAUGE:600:0:U", "DS:cp_read_blocks:GAUGE:600:0:U", "DS:gar_read_latency:GAUGE:600:0:U", "DS:gar_read_blocks:GAUGE:600:0:U", "DS:gar_write_latency:GAUGE:600:0:U", "DS:gar_write_blocks:GAUGE:600:0:U", "DS:disk_busy:GAUGE:600:0:U", NULL }; static char *netapp_system_params[] = { "DS:nfs_ops:GAUGE:600:0:U", "DS:cifs_ops:GAUGE:600:0:U", "DS:http_ops:GAUGE:600:0:U", "DS:dafs_ops:GAUGE:600:0:U", "DS:fcp_ops:GAUGE:600:0:U", "DS:iscsi_ops:GAUGE:600:0:U", "DS:net_data_recv:GAUGE:600:0:U", "DS:net_data_sent:GAUGE:600:0:U", "DS:disk_data_read:GAUGE:600:0:U", "DS:disk_data_written:GAUGE:600:0:U", "DS:cpu_busy:GAUGE:600:0:U", "DS:avg_proc_busy:GAUGE:600:0:U", "DS:total_proc_busy:GAUGE:600:0:U", "DS:num_proc:GAUGE:600:0:U", "DS:time:GAUGE:600:0:U", "DS:uptime:GAUGE:600:0:U", NULL }; static char *qtree_test[] = { "nfs_ops", "cifs_ops" ,NULL }; static char *aggregate_test[] = { "total_transfers", "user_reads", "user_writes", "cp_reads", "user_read_blocks", "user_write_blocks", "cp_read_blocks" ,NULL }; static char *iscsi_test[] = { "iscsi_ops", "iscsi_write_data", "iscsi_read_data" ,NULL }; static char *fcp_test[] = { "fcp_ops", "fcp_write_data", "fcp_read_data" ,NULL }; static char *cifs_test[] = { "cifs_ops", "cifs_latency" ,NULL }; static char *volume_test[] = { "avg_latency", "total_ops", "read_data", "read_latency", "read_ops", "write_data", "write_latency", "write_ops", "other_latency", "other_ops" ,NULL }; static char *lun_test[] = { "read_ops", "write_ops", "other_ops", "read_data", "write_data", "queue_full", "avg_latency", "total_ops" ,NULL }; static char *nfsv3_test[] = { "nfsv3_ops", "nfsv3_read_latency", "nfsv3_read_ops", "nfsv3_write_latency", "nfsv3_write_ops" ,NULL }; static char *ifnet_test[] = { "recv_packets", "recv_errors", "send_packets", "send_errors", "collisions", "recv_data", "send_data", "recv_mcasts", "send_mcasts", "recv_drop_packets" ,NULL }; static char *processor_test[] = { "processor_busy" ,NULL }; static char *disk_test[] = { "total_transfers", "user_read_chain", "user_reads", "user_write_chain", "user_writes", "cp_read_chain", "cp_reads", "guarenteed_read_chain", "guaranteed_reads", "guarenteed_write_chain", "guaranteed_writes", "user_read_latency", "user_read_blocks", "user_write_latency", "user_write_blocks", "cp_read_latency", "cp_read_blocks", "guarenteed_read_latency", "guarenteed_read_blocks", "guarenteed_write_latency", "guarenteed_write_blocks", "disk_busy" ,NULL }; static char *system_test[] = { "nfs_ops", "cifs_ops", "http_ops", "dafs_ops", "fcp_ops", "iscsi_ops", "net_data_recv", "net_data_sent", "disk_data_read", "disk_data_written", "cpu_busy", "avg_processor_busy", "total_processor_busy", "num_processors", "time", "uptime" ,NULL }; static rrdtpldata_t *qtree_tpl = NULL; static rrdtpldata_t *aggregate_tpl = NULL; static rrdtpldata_t *iscsi_tpl = NULL; static rrdtpldata_t *fcp_tpl = NULL; static rrdtpldata_t *cifs_tpl = NULL; static rrdtpldata_t *volume_tpl = NULL; static rrdtpldata_t *lun_tpl = NULL; static rrdtpldata_t *nfsv3_tpl = NULL; static rrdtpldata_t *ifnet_tpl = NULL; static rrdtpldata_t *processor_tpl = NULL; static rrdtpldata_t *disk_tpl = NULL; static rrdtpldata_t *system_tpl = NULL; char *ifnetstr; char *qtreestr; char *aggregatestr; char *volumestr; char *lunstr; char *diskstr; splitmsg(msg); ifnetstr = getdata("ifnet"); qtreestr = getdata("qtree"); aggregatestr = getdata("aggregate"); volumestr = getdata("volume"); lunstr = getdata("lun"); diskstr = getdata("disk"); if (ifnet_tpl == NULL) ifnet_tpl = setup_template(netapp_ifnet_params); if (qtree_tpl == NULL) qtree_tpl = setup_template(netapp_qtree_params); if (aggregate_tpl == NULL) aggregate_tpl = setup_template(netapp_aggregate_params); if (volume_tpl == NULL) volume_tpl = setup_template(netapp_volume_params); if (lun_tpl == NULL) lun_tpl = setup_template(netapp_lun_params); if (disk_tpl == NULL) disk_tpl = setup_template(netapp_disk_params); do_netapp_extratest_rrd(hostname,"xstatifnet",classname,pagepaths,ifnetstr,tstamp,netapp_ifnet_params,&ifnet_tpl,ifnet_test); do_netapp_extratest_rrd(hostname,"xstatqtree",classname,pagepaths,qtreestr,tstamp,netapp_qtree_params,&qtree_tpl,qtree_test); do_netapp_extratest_rrd(hostname,"xstataggregate",classname,pagepaths,aggregatestr,tstamp,netapp_aggregate_params,&aggregate_tpl,aggregate_test); do_netapp_extratest_rrd(hostname,"xstatvolume",classname,pagepaths,volumestr,tstamp,netapp_volume_params,&volume_tpl,volume_test); do_netapp_extratest_rrd(hostname,"xstatlun",classname,pagepaths,lunstr,tstamp,netapp_lun_params,&lun_tpl,lun_test); do_netapp_extratest_rrd(hostname,"xstatdisk",classname,pagepaths,diskstr,tstamp,netapp_disk_params,&disk_tpl,disk_test); return 0; } int do_netapp_disk_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *netapp_disk_params[] = { "DS:pct:GAUGE:600:0:U", "DS:used:GAUGE:600:0:U", NULL }; static rrdtpldata_t *netapp_disk_tpl = NULL; char *eoln, *curline; static int ptnsetup = 0; static pcre *inclpattern = NULL; static pcre *exclpattern = NULL; int newdfreport; newdfreport = (strstr(msg,"netappnewdf") != NULL); if (netapp_disk_tpl == NULL) netapp_disk_tpl = setup_template(netapp_disk_params); if (!ptnsetup) { const char *errmsg; int errofs; char *ptn; ptnsetup = 1; ptn = getenv("RRDDISKS"); if (ptn && strlen(ptn)) { inclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!inclpattern) errprintf("PCRE compile of RRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } ptn = getenv("NORRDDISKS"); if (ptn && strlen(ptn)) { exclpattern = pcre_compile(ptn, PCRE_CASELESS, &errmsg, &errofs, NULL); if (!exclpattern) errprintf("PCRE compile of NORRDDISKS='%s' failed, error %s, offset %d\n", ptn, errmsg, errofs); } } /* * Francesco Duranti noticed that if we use the "/group" option * when sending the status message, this tricks the parser to * create an extra filesystem called "/group". So skip the first * line - we never have any disk reports there anyway. */ curline = strchr(msg, '\n'); if (curline) curline++; while (curline) { char *fsline, *p; char *columns[20]; int columncount; char *diskname = NULL; int pused = -1; int wanteddisk = 1; long long aused = 0; /* FD: Using double instead of long long because we can have decimal on Netapp and DbCheck */ double dused = 0; /* FD: used to add a column if the filesystem is named "snap reserve" for netapp.pl */ int snapreserve=0; eoln = strchr(curline, '\n'); if (eoln) *eoln = '\0'; /* FD: netapp.pl snapshot line that start with "snap reserve" need a +1 */ if (strstr(curline, "snap reserve")) snapreserve=1; /* All clients except AS/400 and DBCHECK report the mount-point with slashes - ALSO Win32 clients. */ if (strchr(curline, '/') == NULL) goto nextline; /* red/yellow filesystems show up twice */ if (*curline == '&') goto nextline; if ((strstr(curline, " red ") || strstr(curline, " yellow "))) goto nextline; for (columncount=0; (columncount<20); columncount++) columns[columncount] = ""; fsline = xstrdup(curline); columncount = 0; p = strtok(fsline, " "); while (p && (columncount < 20)) { columns[columncount++] = p; p = strtok(NULL, " "); } /* FD: Name column can contain "spaces" so it could be split in multiple columns, create a unique string from columns[5] that point to the complete disk name */ while (columncount-- > 6+snapreserve) { p = strchr(columns[columncount-1],0); if (p) *p = '_'; } /* FD: Add an initial "/" to qtree and quotas */ if (newdfreport) { diskname = xstrdup(columns[0]); } else if (*columns[5+snapreserve] != '/') { diskname=xmalloc(strlen(columns[5+snapreserve])+2); sprintf(diskname,"/%s",columns[5+snapreserve]); } else { diskname = xstrdup(columns[5+snapreserve]); } p = strchr(columns[4+snapreserve], '%'); if (p) *p = ' '; pused = atoi(columns[4+snapreserve]); p = columns[2+snapreserve] + strspn(columns[2+snapreserve], "0123456789."); /* Using double instead of long long because we can have decimal */ dused = str2ll(columns[2+snapreserve], NULL); /* snapshot and qtree contains M/G/T Convert to KB if there's a modifier after the numbers */ if (*p == 'M') dused *= 1024; else if (*p == 'G') dused *= (1024*1024); else if (*p == 'T') dused *= (1024*1024*1024); aused=(long long) dused; /* Check include/exclude patterns */ wanteddisk = 1; if (exclpattern) { int ovector[30]; int result; result = pcre_exec(exclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result < 0); } if (wanteddisk && inclpattern) { int ovector[30]; int result; result = pcre_exec(inclpattern, NULL, diskname, strlen(diskname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); wanteddisk = (result >= 0); } if (wanteddisk && diskname && (pused != -1)) { p = diskname; while ((p = strchr(p, '/')) != NULL) { *p = ','; } if (strcmp(diskname, ",") == 0) { diskname = xrealloc(diskname, 6); strcpy(diskname, ",root"); } /* * Use testname here. * The disk-handler also gets data from NetAPP inode- and qtree-messages, * that are virtually identical to the disk-messages. So lets just handle * all of it by using the testname as part of the filename. */ setupfn2("%s%s.rrd", testname, diskname); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%lld", (int)tstamp, pused, aused); create_and_update_rrd(hostname, testname, classname, pagepaths, netapp_disk_params, netapp_disk_tpl); } if (diskname) { xfree(diskname); diskname = NULL; } if (eoln) *eoln = '\n'; xfree(fsline); nextline: curline = (eoln ? (eoln+1) : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_citrix.c0000664000076400007640000000272612000025440017432 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char citrix_rcsid[] = "$Id: do_citrix.c 7026 2012-07-13 14:05:20Z storner $"; int do_citrix_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *citrix_params[] = { "DS:users:GAUGE:600:0:U", NULL }; static void *citrix_tpl = NULL; char *p; int users; if (citrix_tpl == NULL) citrix_tpl = setup_template(citrix_params); p = strstr(msg, " users active\n"); while (p && (p > msg) && (*p != '\n')) p--; if (p && (sscanf(p+1, "\n%d users active\n", &users) == 1)) { setupfn("%s.rrd", "citrix"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, users); return create_and_update_rrd(hostname, testname, classname, pagepaths, citrix_params, citrix_tpl); } return 0; } xymon-4.3.30/xymond/rrd/do_filesizes.c0000664000076400007640000000353512000025440020124 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* This module handles "filesizes" messages. */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char filesize_rcsid[] = "$Id: do_filesizes.c 7026 2012-07-13 14:05:20Z storner $"; static char *filesize_params[] = { "DS:size:GAUGE:600:0:U", NULL }; static void *filesize_tpl = NULL; int do_filesizes_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *boln, *eoln; if (filesize_tpl == NULL) filesize_tpl = setup_template(filesize_params); boln = strchr(msg, '\n'); if (boln) boln++; while (boln && *boln) { char *fn, *szstr = NULL; eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; fn = strtok(boln, ":"); if (fn) szstr = strtok(NULL, ":"); if (fn && szstr) { char *p; for (p=strchr(fn, '/'); (p); p = strchr(p, '/')) *p = ','; setupfn2("%s.%s.rrd", "filesizes", fn); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s", (int)tstamp, szstr); create_and_update_rrd(hostname, testname, classname, pagepaths, filesize_params, filesize_tpl); } boln = (eoln ? eoln+1 : NULL); } return 0; } xymon-4.3.30/xymond/rrd/do_ifmib.c0000664000076400007640000001343412000025440017214 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon RRD handler module. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char ifmib_rcsid[] = "$Id: do_ifmib.c 7026 2012-07-13 14:05:20Z storner $"; static char *ifmib_params[] = { "DS:ifInNUcastPkts:COUNTER:600:0:U", "DS:ifInDiscards:COUNTER:600:0:U", "DS:ifInErrors:COUNTER:600:0:U", "DS:ifInUnknownProtos:COUNTER:600:0:U", "DS:ifOutNUcastPkts:COUNTER:600:0:U", "DS:ifOutDiscards:COUNTER:600:0:U", "DS:ifOutErrors:COUNTER:600:0:U", "DS:ifOutQLen:GAUGE:600:0:U", "DS:ifInMcastPkts:COUNTER:600:0:U", "DS:ifInBcastPkts:COUNTER:600:0:U", "DS:ifOutMcastPkts:COUNTER:600:0:U", "DS:ifOutBcastPkts:COUNTER:600:0:U", "DS:ifHCInMcastPkts:COUNTER:600:0:U", "DS:ifHCInBcastPkts:COUNTER:600:0:U", "DS:ifHCOutMcastPkts:COUNTER:600:0:U", "DS:ifHCOutBcastPkts:COUNTER:600:0:U", "DS:InOctets:COUNTER:600:0:U", "DS:OutOctets:COUNTER:600:0:U", "DS:InUcastPkts:COUNTER:600:0:U", "DS:OutUcastPkts:COUNTER:600:0:U", NULL }; static void *ifmib_tpl = NULL; static char *ifmib_valnames[] = { /* These are in the standard interface MIB */ "ifInNUcastPkts", /* 0 */ "ifInDiscards", "ifInErrors", "ifInUnknownProtos", "ifOutNUcastPkts", /* 4 */ "ifOutDiscards", "ifOutErrors", "ifOutQLen", /* The following are the 64-bit counters in the extended MIB */ "ifInMulticastPkts", /* 8 */ "ifInBroadcastPkts", "ifOutMulticastPkts", "ifOutBroadcastPkts", "ifHCInMulticastPkts", /* 12 */ "ifHCInBroadcastPkts", "ifHCOutMulticastPkts", "ifHCOutBroadcastPkts", /* The following counters may be in both 32- (standard) and 64-bit (extended) versions. */ "ifInOctets", /* 16 */ "ifHCInOctets", "ifOutOctets", "ifHCOutOctets", "ifInUcastPkts", /* 20 */ "ifHCInUcastPkts", "ifOutUcastPkts", "ifHCOutUcastPkts", NULL }; static void ifmib_flush_data(int ifmibinterval, char *devname, time_t tstamp, char *hostname, char *testname, char *classname, char *pagepaths, char **values, int inidx, int outidx, int inUcastidx, int outUcastidx) { setupfn2("%s.%s.rrd", "ifmib", devname); setupinterval(ifmibinterval); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s", (int)tstamp, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10], values[11], values[12], values[13], values[14], values[15], values[inidx], values[outidx], values[inUcastidx], values[outUcastidx]); create_and_update_rrd(hostname, testname, classname, pagepaths, ifmib_params, ifmib_tpl); } int do_ifmib_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *datapart = msg; char *bol, *eoln; char *devname = NULL; char *values[sizeof(ifmib_valnames)/sizeof(ifmib_valnames[0])]; int valcount = 0; int incountidx = 16, outcountidx = 18, inUcastidx = 20, outUcastidx = 22; int pollinterval = 0; if (ifmib_tpl == NULL) ifmib_tpl = setup_template(ifmib_params); if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Skip the first line of full status- and data-messages. */ datapart = strchr(msg, '\n'); if (datapart) datapart++; else datapart = msg; } memset(values, 0, sizeof(values)); valcount = 0; devname = NULL; bol = datapart; while (bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; bol += strspn(bol, " \t"); if (*bol == '\0') { /* Nothing */ } else if (strncmp(bol, "Interval=", 9) == 0) { pollinterval = atoi(bol+9); } else if (*bol == '[') { /* New interface data begins */ if (devname && (valcount == 24)) { ifmib_flush_data(pollinterval, devname, tstamp, hostname, testname, classname, pagepaths, values, incountidx, outcountidx, inUcastidx, outUcastidx); memset(values, 0, sizeof(values)); valcount = 0; devname = NULL; incountidx = 16; outcountidx = 18; inUcastidx = 20; outUcastidx = 22; } devname = bol+1; bol = strchr(bol, ']'); if (bol) *bol = '\0'; } else { char *valnam, *valstr = NULL; valnam = strtok(bol, " ="); if (valnam) valstr = strtok(NULL, " ="); if (valnam && valstr) { int validx; for (validx = 0; (ifmib_valnames[validx] && strcmp(ifmib_valnames[validx], valnam)); validx++) ; if (ifmib_valnames[validx]) { values[validx] = (isdigit(*valstr) ? valstr : "U"); valcount++; /* See if this is one of the high-speed in/out counts */ if (*values[validx] != 'U') { if (validx == 17) incountidx = validx; if (validx == 19) outcountidx = validx; if (validx == 21) inUcastidx = validx; if (validx == 23) outUcastidx = validx; } } } } bol = (eoln ? eoln+1 : NULL); } /* Flush the last device */ if (devname && (valcount == 24)) { ifmib_flush_data(pollinterval, devname, tstamp, hostname, testname, classname, pagepaths, values, incountidx, outcountidx, inUcastidx, outUcastidx); valcount = 0; } return 0; } xymon-4.3.30/xymond/xymond_rrd.80000664000076400007640000004071013534041733017004 0ustar rpmbuildrpmbuild.TH XYMOND_RRD 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_rrd \- xymond worker module for updating Xymon RRD files .SH SYNOPSIS .B "xymond_channel \-\-channel=status xymond_rrd [options]" .br .B "xymond_channel \-\-channel=data xymond_rrd [options]" .SH DESCRIPTION xymond_rrd is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives "status" and "data" messages from xymond via stdin, and updates the RRD databases used to generate trend-graphs. Clients can send data to Xymon using both status- and data- messages. So you will normally run two instances of this module, once for the "status" channel and once for the "data" channel. xymond_rrd understands data sent by the LARRD 0.43c client-side scripts (the so-called "bottom-feeder" scripts). So you still want to install the LARRD bottom-feeders on the clients you monitor. Note: For certain types of data, the RRD files used by Xymon are imcompatible with those generated by the Big Brother LARRD add-on. See the COMPATIBILITY section below. .SH OPTIONS .IP "\-\-debug" Enable debugging output. .IP "\-\-rrddir=DIRECTORY" Defines the directory where the RRD-files are stored. xymond_rrd will use the location pointed to by the XYMONRRDS environment if this option is not present. .IP "\-\-no\-cache" xymond_rrd by default caches updates to the RRD files, to reduce the disk I/O needed for storing the RRD data. Data is collected for a 30 minute period before being committed to disk in one update. This option disables caching of the data, so that data is stored on disk immediately. .IP "\-\-processor=FILENAME" xymond_rrd can send a parallel copy of all RRD updates to a single external process as a stream on its STDIN. The data will be in a format similar to that used by rrdupdate(1): ts: host If the process exits, xymond_rrd will re-launch it. .IP "\-\-extra\-script=FILENAME" Defines the script that is run to get the RRD data for tests that are not built into xymond_rrd. You must also specify which tests are handled by the external script in the \fB\-\-extra\-tests\fR option. This option can only be given once, so the script must handle all of the external test-data. See the CUSTOM RRD DATA section below. Note that this is NOT needed if your custom graphs are generated by the NCV (Name Colon Value) module described below, it is only required for data where you have a custom script to parse the status message and extract the data that is put into the graph. .IP "\-\-extra\-tests=TEST[,TEST]" List of testnames that are handled by the external script. See the CUSTOM RRD DATA section below. Note that NCV graphs should NOT be listed here, but in the TEST2RRD environment variable - see below. .IP "\-\-no\-rrd" Disable the actual writing of RRD files. This is only really useful if you send all of the data destined for the RRD files to an external processor (the \-\-extra\-script or \-\-processor options). .SH ENVIRONMENT .IP TEST2RRD Defines the mapping between a status-log columnname and the corresponding RRD database format. This is normally defined in the .I xymonserver.cfg(5) file. .IP XYMONRRDS Default directory where RRD files are stored. .IP NCV_testname Defines the types of data collected by the "ncv" module in xymond_rrd. See below for more information. .IP SPLITNCV_testname The same as NCV_testname, but keeps the data into separate files. That is, it creates one rrd file per "NAME : value" line found in the status message. It is useful when the list of NCV lines is varying. .IP TRACKMAX Comma-separated list of columnname for which you want to keep the maximum values along with the default average values. This only works for the NCV backend. .SH COLLECTED DATA The following RRD-file datasets are generated by xymond_rrd: .IP la Records the CPU load average. Data is collected from the "cpu" status report. Requires that a Xymon client is running on the monitored server. .IP disk Records the disk utilization. Data is collected from the "disk" status report. Requires that a Xymon-compatible client is running on the monitored server. .IP memory Records memory- and swap-utilization. Data is collected from the "memory" status report. If no "memory" status is reported, it will use the data from the Win32 client "cpu" status report to generate this dataset. Requires that a Xymon-compatible client is running on the monitored server. .IP netstat Records TCP and UDP statistics. Data is collected from the "netstat" status report; however, this data is often sent via the Xymon "data" protocol, so there need not be a "netstat" column visible on the Xymon display. To get these data, the LARRD netstat bottom-feeder script must be running on the monitored server. .IP vmstat Records system performance metrics from the "vmstat" command. Data is collected from the "vmstat" status report; however, this data is often sent via the Xymon "data" protocol, so there need not be a "vmstat" column visible on the Xymon display. To get these data, the LARRD vmstat bottom-feeder script must be running on the monitored server. .IP tcp Response-time metrics from all of the Xymon network tests are recorded in the "tcp" RRD. .IP apache Apache server performance metrics, taken from the "apache" data report. See the description of the \fBapache\fR keyword in .I hosts.cfg(5) for details. .IP sendmail Sendmail server performance metrics, taken from the "mailstats" output. To get these data, the LARRD sendmail bottom-feeder script must be running on the monitored server. .IP mailq Mail queue size. To get these data, the LARRD nmailq bottom-feeder script must be running on the monitored server. .IP bea BEA Weblogic performance data. This is an experimental set of data collected from BEA Weblogic servers via SNMP, by the "beastats" tool included with Xymon. .IP iishealth IIS webserver performance data, collected by the "iishealth" script. This script is a client-side add-on available from the www.deadcat.net archive. .IP temperature Temperature data, collected with the temperature script from www.deadcat.net. To get these data, the temperature script must be running on the monitored server. .IP ntpstat Tracks the deviation between the local system time and an NTP server, using the output from the "ntpq \-c rv" command. A simple script to collect these data is included in the Xymon contrib/ directory. .IP citrix Tracks the number of active sessions on a Citrix server using the "query session" command. An extension for the BBNT client that generates data for this graph is in the Xymon contrib/ directory. .SH CUSTOM RRD DATA IN NAME-COLON-VALUE (NCV) FORMAT Many data-collection scripts report data in the form "NAME : value" or "NAME = value". So a generic module in xymond_rrd allows for easy tracking of this type of data. The "ncv" module will automatically detect all occurrences of a "NAME : value" or "NAME = value" string in a status message, and generate an RRD file holding all of the name/value data found in the message (unless you use SPLITNCV, see above). The colon- or equal-sign must be present - if there is only whitespace, this module will fail. Only the valid letters (A-Z, a-z) and digits (0-9) are used in the dataset names; whitespace and other characters are stripped off automatically. Only the first 19 characters of a dataset name are used (this is an RRD limitation). Underscore '_' is not allowed, even though RRDtool permits this, and will be stripped from the name. When using the alternative SPLITNCV_testname, the dataset name is not limited in length, and non-valid characters are changed to underscores instead of being stripped off. The dataset inside the resulting rrd file is always "lambda". Note that each "NAME : value" must be on a line by itself. If you have a custom script generating the status- or data-message that is fed into the NCV handler, make sure it inserts a newline before each of the data-items you want to track. Any lines in the status message prepended with a "" will be skipped by the module. This can be used to prevent unneeded RRD files from an existing dataset from being created. A line prepended with a "" will be ignored, along with all subsequent lines until a line starting with "" is found, at which point processing will resume. This can be used to ignore explanatory or other text with a mostly-ncv message. "" can be used to ignore certain text at the beginning of a line, up until a closing '' tag on the same line, at which point the line will continue to be processed as usual. Wrapping is not supported; but skipstart/skipend can be used to handle multiple lines. A bare "" on its own line will stop further NCV processing of that message. All of these ncv_ terms are case-sensitive. Note that if you have full control over your NCV output, it is most efficient to have NCV data near the top of your message and use "" once your data is complete. To enable the ncv module for a status, add a "COLUMNNAME=ncv" to the TEST2RRD setting and the COLUMNNAME to the GRAPHS setting in .I xymonserver.cfg(5) , then restart Xymon. Xymon will now send all status-messages for the column COLUMNNAME through the xymond_rrd ncv-handler. The name of the RRD file will be COLUMNNAME.rrd. When using SPLITNCV, the name of the RRD file will be COLUMNAME,DATASETNAME.rrd. By default, all of the datasets are generated as the RRD type "DERIVE" which works for all types of monotonically increasing counters. If you have data that are of the type GAUGE, you can override the default via an environment variable NCV_COLUMNNAME (or SPLITNCV_COLUMNAME). E.g. if you are using the bb-mysqlstatus script from www.deadcat.net to collect data about your MySQL server, it generates a report in the column called "mysql". One data item is the average number of queries/second, which must be logged in the RRD file as type "GAUGE". To do that, add the following to xymonserver.cfg: .br NCV_mysql="Queriespersecondavg:GAUGE" .br If you have multiple datasets that you myst define, add them to the environment variable separated by commas, e.g. .br NCV_mysql="Uptime:NONE,Queriespersecondavg:GAUGE" .br The dataset type "NONE" used above causes xymond_rrd to ignore this data, it is not included in the RRD file. You can use "*" as the dataset name to match all datasets not listed. E.g. .br NCV_weather="Rain:DERIVE,*:GAUGE" .br will cause the "Rainfall" dataset to be of type DERIVE, and all others of type GAUGE. If you want to track only a few of the variables in your data, you can use "*:NONE" to drop any dataset not explicitly listed. For a more detailed "how to" description, see the on-line HTML documentation of "How to create graph custom data" available in the Help menu section on your Xymon server. .SH SENDING METRIC DATA TO AN ADDITIONAL PROCESS xymond_rrd provides a mechanism to send a copy of isolated metric data to a single external processor for further processing. This can be used to inject metric data that xymond_rrd has prepared into other storage systems, such as OpenTSDB, graphite, etc. The data is printed in a format nearly suitable for injection using .I rrdupdate(1) and easily transformable to other formats. If the process exits, xymond_rrd will re-launch it automatically. .SH CUSTOM RRD DATA VIA SCRIPTS xymond_rrd provides a simple mechanism for adding custom graphs to the set of data collected on your Xymon server. By adding the "\-\-extra\-script" and "\-\-extra\-tests" options, data reported to Xymon from selected tests are passed to an external script, which can define the RRD data-sets to store in an RRD file. \fBNOTE:\fR For performance reasons, you should not use this mechanism for large amounts of data. The overhead involved in storing the received message to disk and launching the script is significantly larger than the normal xymond_rrd overhead. So if you have a large number of reports for a given test, you should consider implementing it in C and including it in the xymond_rrd tool or writing a separate stream listener that injects appropriate "trends" data messages back to xymond. Apart from writing the script, You must also add a section to .I graphs.cfg(5) so that .I showgraph.cgi(1) knows how to generate the graph from the data stored in the RRD file. To make the graphs actually show up on the status-page and/or the "trends" page, add the name of the new graph to the TEST2RRD and/or GRAPHS setting in .I xymonserver.cfg(5). The script is invoked for each message that arrives, where the test-name matches one of the testnames given in the "\-\-extra\-tests" option. The script receives three command-line parameters: .TP .BI "Hostname" The name of the host reporting the data. .TP .BI "Testname" The name of the test being reported. .TP .BI "Filename" File containing the data that was reported. This file is generated for you by xymond_rrd, and is also deleted automatically after your script is finished with it. .LP The script must process the data that is reported, and generate the following output: .TP .BI "RRD data-set definitions" For each dataset that the RRD file holds, a line beginning with "DS:" must be output. If multiple data-sets are used, print one line for each dataset. .br Data-set definitions are described in the .I rrdcreate(1) documentation, but a common definition for e.g. tracking the number of users logged on would be "DS:users:GAUGE:600:0:U". "users" is the name of the dataset, "GAUGE" is the datatype, "600" is the longest time allowed between updates for the data to be valid, "0" is the minimum value, and "U" is the maximum value (a "U" means "unknown"). .TP .BI "RRD filename" The name of the RRD file where the data is stored. Note that Xymon stores all RRD files in host-specific directories, so unlike LARRD you should not include the hostname in the name of the RRD file. .TP .BI "RRD values" One line, with all of the data values collected by the script. Data-items are colon-delimited and must appear in the same sequence as your data-set definitions, e.g. if your RRD has two datasets with the values "5" and "0.4" respectively, then the script must output "5:0.4" as the RRD values. .br In some cases it may be useful to define a dataset even though you will not always have data for it. In that case, use "U" (unknown) for the value. If you want to store the data in multiple RRD files, the script can just print out more sequences of data-set definitions, RRD filenames and RRD values. If the data-set definitions are identical to the previous definition, you need not print the data-set definitions again - just print a new RRD filename and value. .LP The following sample script for tracking weather data shows how to use this mechanism. It assumes the status message include lines like these: .IP .nf green Weather in Copenhagen is FAIR Temperature: 21 degrees Celsius Wind: 4 m/s Humidity: 72 % Rainfall: 5 mm since 6:00 AM .fi .LP A shell-script to track all of these variables could be written like this: .IP .nf #!/bin/sh # Input parameters: Hostname, testname (column), and messagefile HOSTNAME="$1" TESTNAME="$2" FNAME="$3" if [ "$TESTNAME" = "weather" ] then # Analyze the message we got TEMP=`grep "^Temperature:" $FNAME | awk '{print $2}'` WIND=`grep "^Wind:" $FNAME | awk '{print $2}'` HMTY=`grep "^Humidity:" $FNAME | awk '{print $2}'` RAIN=`grep "^Rainfall:" $FNAME | awk '{print $2}'` # The RRD dataset definitions echo "DS:temperature:GAUGE:600:\-30:50" echo "DS:wind:GAUGE:600:0:U" echo "DS:humidity:GAUGE:600:0:100" echo "DS:rainfall:DERIVE:600:0:100" # The filename echo "weather.rrd" # The data echo "$TEMP:$WIND:$HMTY:$RAIN" fi exit 0 .fi .SH COMPATIBILITY Some of the RRD files generated by xymond_rrd are incompatible with the files generated by the Big Brother LARRD add-on: .IP vmstat The vmstat files with data from Linux based systems are incompatible due to the addition of a number of new data-items that LARRD 0.43 do not collect, but xymond_rrd does. This is due to changes in the output from the Linux vmstat command, and changes in the way e.g. system load metrics are reported. .IP netstat All netstat files from LARRD 0.43 are incompatible with xymond_rrd. The netstat data collected by LARRD is quite confusing: For some types of systems LARRD collects packet-counts, for others it collects byte- counts. xymond_rrd uses a different RRD file-format with separate counters for packets and bytes and tracks whatever data the system is reporting. .SH "SEE ALSO" xymond_channel(8), xymond(8), xymonserver.cfg(5), xymon(7) xymon-4.3.30/xymond/client_config.c0000664000076400007640000035536113515616677017526 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module */ /* This file has routines that load the xymond_client configuration and */ /* finds the rules relevant for a particular test when applied. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* "PORT" handling (C) Mirko Saam */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: client_config.c 8068 2019-07-23 14:46:23Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "client_config.h" typedef struct exprlist_t { char *pattern; pcre *exp; struct exprlist_t *next; } exprlist_t; typedef struct c_load_t { float warnlevel, paniclevel; } c_load_t; typedef struct c_uptime_t { int recentlimit, ancientlimit, color; } c_uptime_t; typedef struct c_clock_t { int maxdiff, color; } c_clock_t; typedef struct c_disk_t { exprlist_t *fsexp; long warnlevel, paniclevel; int abswarn, abspanic; int dmin, dmax, dcount; int color; int ignored; } c_disk_t; typedef struct c_inode_t { exprlist_t *fsexp; long warnlevel, paniclevel; int abswarn, abspanic; int imin, imax, icount; int color; int ignored; } c_inode_t; typedef struct c_mem_t { enum { C_MEM_PHYS, C_MEM_SWAP, C_MEM_ACT } memtype; int warnlevel, paniclevel; } c_mem_t; typedef struct c_zos_mem_t { enum { C_MEM_CSA, C_MEM_ECSA, C_MEM_SQA, C_MEM_ESQA } zos_memtype; int warnlevel, paniclevel; } c_zos_mem_t; typedef struct c_zvse_vsize_t { int warnlevel, paniclevel; } c_zvse_vsize_t; typedef struct c_zvse_getvis_t { exprlist_t *partid; int warnlevel, paniclevel; int anywarnlevel, anypaniclevel; } c_zvse_getvis_t; typedef struct c_cics_t { exprlist_t *applid; /* CICS Application Identifier */ int dsawarnlevel, dsapaniclevel; int edsawarnlevel, edsapaniclevel; } c_cics_t; typedef struct c_asid_t { enum { C_ASID_MAXUSER, C_ASID_NPARTS } asidtype; int warnlevel, paniclevel; } c_asid_t; typedef struct c_proc_t { exprlist_t *procexp; int pmin, pmax, pcount; int color; } c_proc_t; typedef struct c_log_t { exprlist_t *logfile; exprlist_t *matchexp, *matchone, *ignoreexp; int color; } c_log_t; typedef struct c_paging_t { int warnlevel, paniclevel; } c_paging_t; #define FCHK_NOEXIST (1 << 0) #define FCHK_TYPE (1 << 1) #define FCHK_MODE (1 << 2) #define FCHK_MINLINKS (1 << 3) #define FCHK_MAXLINKS (1 << 4) #define FCHK_EQLLINKS (1 << 5) #define FCHK_MINSIZE (1 << 6) #define FCHK_MAXSIZE (1 << 7) #define FCHK_EQLSIZE (1 << 8) #define FCHK_OWNERID (1 << 10) #define FCHK_OWNERSTR (1 << 11) #define FCHK_GROUPID (1 << 12) #define FCHK_GROUPSTR (1 << 13) #define FCHK_CTIMEMIN (1 << 16) #define FCHK_CTIMEMAX (1 << 17) #define FCHK_CTIMEEQL (1 << 18) #define FCHK_MTIMEMIN (1 << 19) #define FCHK_MTIMEMAX (1 << 20) #define FCHK_MTIMEEQL (1 << 21) #define FCHK_ATIMEMIN (1 << 22) #define FCHK_ATIMEMAX (1 << 23) #define FCHK_ATIMEEQL (1 << 24) #define FCHK_MD5 (1 << 25) #define FCHK_SHA1 (1 << 26) #define FCHK_SHA256 (1 << 27) #define FCHK_SHA512 (1 << 28) #define FCHK_SHA224 (1 << 29) #define FCHK_SHA384 (1 << 30) #define FCHK_RMD160 (1 << 31) #define CHK_OPTIONAL (1 << 0) #define CHK_TRACKIT (1 << 1) typedef struct c_file_t { exprlist_t *filename; int color; int ftype; off_t minsize, maxsize, eqlsize; unsigned int minlinks, maxlinks, eqllinks; unsigned int fmode; int ownerid, groupid; char *ownerstr, *groupstr; unsigned int minctimedif, maxctimedif, ctimeeql; unsigned int minmtimedif, maxmtimedif, mtimeeql; unsigned int minatimedif, maxatimedif, atimeeql; char *md5hash, *sha1hash, *sha256hash, *sha512hash, *sha224hash, *sha384hash, *rmd160hash; } c_file_t; typedef struct c_dir_t { exprlist_t *filename; int color; unsigned long maxsize, minsize; } c_dir_t; typedef struct c_port_t { exprlist_t *localexp; exprlist_t *exlocalexp; exprlist_t *remoteexp; exprlist_t *exremoteexp; exprlist_t *stateexp; exprlist_t *exstateexp; int pmin, pmax, pcount; int color; } c_port_t; typedef struct c_svc_t { exprlist_t *svcexp; exprlist_t *stateexp; exprlist_t *startupexp; char *svcname, *startup, *state; int scount; int color; } c_svc_t; #define MIBCHK_MINVALUE (1 << 0) #define MIBCHK_MAXVALUE (1 << 1) #define MIBCHK_MATCH (1 << 2) typedef struct c_mibval_t { exprlist_t *mibvalexp; /* Key composed of the mib name and the value name */ exprlist_t *keyexp; /* Match pattern for the mib table key */ int color; long minval, maxval; exprlist_t *matchexp; /* * For optimization, we build a tree of c_rule_t pointers, indexed by a key * which is combined from the mib-, key- and value-names. This tree is updated * and/or used whenever an actual lookup happens for the thresholds. * So when doing a lookup, we first check to see if the combination is in the * tree; if not, then we scan the list by matching against the keyexp pattern * and update the tree with the result. */ int havetree; void * valdeftree; } c_mibval_t; #define RRDDSCHK_GT (1 << 0) #define RRDDSCHK_GE (1 << 1) #define RRDDSCHK_LT (1 << 2) #define RRDDSCHK_LE (1 << 3) #define RRDDSCHK_EQ (1 << 4) #define RRDDSCHK_INTVL (1 << 29) typedef struct c_rrdds_t { exprlist_t *rrdkey; /* Pattern match for filename of the RRD file */ char *rrdds; /* DS name */ char *column; /* Status column modified by this check */ int color; /* For absolute min/max values of the data item */ double limitval, limitval2; } c_rrdds_t; typedef struct c_mq_queue_t { exprlist_t *qmgrname, *qname; int warnlen, critlen; int warnage, critage; } c_mq_queue_t; typedef struct c_mq_channel_t { exprlist_t *qmgrname, *chnname, *warnstates, *alertstates; } c_mq_channel_t; typedef enum { C_LOAD, C_UPTIME, C_CLOCK, C_DISK, C_INODE, C_MEM, C_PROC, C_LOG, C_FILE, C_DIR, C_PORT, C_SVC, C_CICS, C_PAGING, C_MEM_GETVIS, C_MEM_VSIZE, C_ASID, C_RRDDS, C_MQ_QUEUE, C_MQ_CHANNEL, C_MIBVAL } ruletype_t; typedef struct c_rule_t { exprlist_t *hostexp; exprlist_t *exhostexp; exprlist_t *pageexp; exprlist_t *expageexp; exprlist_t *dgexp; exprlist_t *exdgexp; exprlist_t *classexp; exprlist_t *exclassexp; char *timespec, *extimespec, *statustext, *rrdidstr, *groups; ruletype_t ruletype; int cfid; uint32_t flags; uint32_t chkflags; struct c_rule_t *next; union { c_load_t load; c_uptime_t uptime; c_clock_t clock; c_disk_t disk; c_inode_t inode; c_mem_t mem; c_zos_mem_t zos_mem; c_zvse_vsize_t zvse_vsize; c_zvse_getvis_t zvse_getvis; c_cics_t cics; c_asid_t asid; c_proc_t proc; c_log_t log; c_file_t fcheck; c_dir_t dcheck; c_port_t port; c_svc_t svc; c_paging_t paging; c_mibval_t mibval; c_rrdds_t rrdds; c_mq_queue_t mqqueue; c_mq_channel_t mqchannel; } rule; } c_rule_t; static c_rule_t *rulehead = NULL; static c_rule_t *ruletail = NULL; static exprlist_t *exprhead = NULL; /* ruletree is a tree indexed by hostname of the rules. */ typedef struct ruleset_t { c_rule_t *rule; struct ruleset_t *next; } ruleset_t; static int havetree = 0; static void * ruletree; static off_t filesize_value(char *s) { /* s is the size in BYTES */ char *modifier; off_t result; modifier = (s + strspn(s, " 0123456789")); #ifdef _LARGEFILE_SOURCE result = (off_t) str2ll(s, NULL); #else result = (off_t) atol(s); #endif switch (*modifier) { case 'K': case 'k': result = (result << 10); break; case 'M': case 'm': result = (result << 20); break; case 'G': case 'g': result = (result << 30); break; case 'T': case 't': result = (result << 40); break; default: break; } return result; } static ruleset_t *ruleset(char *hostname, char *pagename, char *classname) { /* * This routine manages a list of rules that apply to a particular host. * * We maintain a tree indexed by hostname. Each node in the tree contains * a list of c_rule_t records, which point to individual rules in the full * list of rules. So instead of walking the entire list of rules for all hosts, * we can just go through those rules that are relevant for a given host. * This should speed up client-rule matching tremendously, since all of * the expensive pagename/hostname matches are only performed initially * when the list of rules for the host is decided. */ xtreePos_t handle; c_rule_t *rwalk; ruleset_t *head, *tail, *itm; char *pagenamecopy, *pgtok; int pgmatchres, pgexclres; handle = xtreeFind(ruletree, hostname); if (handle != xtreeEnd(ruletree)) { /* We have the tree for this host */ return (ruleset_t *)xtreeData(ruletree, handle); } pagenamecopy = strdup(pagename); /* We must build the list of rules for this host */ head = tail = NULL; for (rwalk = rulehead; (rwalk); rwalk = rwalk->next) { if (rwalk->exclassexp && namematch(classname, rwalk->exclassexp->pattern, rwalk->exclassexp->exp)) continue; if (rwalk->classexp && !namematch(classname, rwalk->classexp->pattern, rwalk->classexp->exp)) continue; if (rwalk->exhostexp && namematch(hostname, rwalk->exhostexp->pattern, rwalk->exhostexp->exp)) continue; if (rwalk->hostexp && !namematch(hostname, rwalk->hostexp->pattern, rwalk->hostexp->exp)) continue; if (rwalk->exdgexp && namematch(hostname, rwalk->exdgexp->pattern, rwalk->exdgexp->exp)) continue; if (rwalk->dgexp && !namematch(hostname, rwalk->dgexp->pattern, rwalk->dgexp->exp)) continue; pgmatchres = pgexclres = -1; pgtok = strtok(pagenamecopy, ","); while (pgtok) { if (rwalk->pageexp && (pgmatchres != 1)) pgmatchres = (namematch(pgtok, rwalk->pageexp->pattern, rwalk->pageexp->exp) ? 1 : 0); if (rwalk->expageexp && (pgexclres != 1)) pgexclres = (namematch(pgtok, rwalk->expageexp->pattern, rwalk->expageexp->exp) ? 1 : 0); pgtok = strtok(NULL, ","); } if (pgexclres == 1) continue; if (pgmatchres == 0) continue; /* All criteria match - add this rule to the list of rules for this host */ itm = (ruleset_t *)calloc(1, sizeof(ruleset_t)); itm->rule = rwalk; itm->next = NULL; if (head == NULL) { head = tail = itm; } else { tail->next = itm; tail = itm; } } /* Add the list to the tree */ xtreeAdd(ruletree, strdup(hostname), head); xfree(pagenamecopy); return head; } static exprlist_t *setup_expr(char *ptn, int multiline) { exprlist_t *newitem = (exprlist_t *)calloc(1, sizeof(exprlist_t)); newitem->pattern = strdup(ptn); if (*ptn == '%') { if (multiline) newitem->exp = multilineregex(ptn+1); else newitem->exp = compileregex(ptn+1); } newitem->next = exprhead; exprhead = newitem; return newitem; } static c_rule_t *setup_rule(ruletype_t ruletype, exprlist_t *curhost, exprlist_t *curexhost, exprlist_t *curpage, exprlist_t *curexpage, exprlist_t *curdg, exprlist_t *curexdg, exprlist_t *curclass, exprlist_t *curexclass, char *curtime, char *curextime, char *curtext, char *curgroup, int cfid) { c_rule_t *newitem = (c_rule_t *)calloc(1, sizeof(c_rule_t)); if (ruletail) { ruletail->next = newitem; ruletail = newitem; } else rulehead = ruletail = newitem; newitem->ruletype = ruletype; newitem->hostexp = curhost; newitem->exhostexp = curexhost; newitem->pageexp = curpage; newitem->expageexp = curexpage; newitem->dgexp = curdg; newitem->exdgexp = curexdg; newitem->classexp = curclass; newitem->exclassexp = curexclass; if (curtime) newitem->timespec = strdup(curtime); if (curextime) newitem->extimespec = strdup(curextime); if (curtext) newitem->statustext = strdup(curtext); if (curgroup) newitem->groups = strdup(curgroup); newitem->cfid = cfid; return newitem; } static int isqual(char *token) { if (!token) return 1; if ( (strncasecmp(token, "HOST=", 5) == 0) || (strncasecmp(token, "EXHOST=", 7) == 0) || (strncasecmp(token, "PAGE=", 5) == 0) || (strncasecmp(token, "EXPAGE=", 7) == 0) || (strncasecmp(token, "DISPLAYGROUP=", 13) == 0) || (strncasecmp(token, "EXDISPLAYGROUP=", 15) == 0) || (strncasecmp(token, "CLASS=", 6) == 0) || (strncasecmp(token, "EXCLASS=", 8) == 0) || (strncasecmp(token, "TEXT=", 5) == 0) || (strncasecmp(token, "GROUP=", 6) == 0) || (strncasecmp(token, "TIME=", 5) == 0) || (strncasecmp(token, "EXTIME=", 7) == 0) ) return 1; return 0; } static char *ftypestr(unsigned int ftype) { if (ftype == S_IFSOCK) return "socket"; else if (ftype == S_IFREG) return "file"; else if (ftype == S_IFBLK) return "block"; else if (ftype == S_IFCHR) return "char"; else if (ftype == S_IFDIR) return "dir"; else if (ftype == S_IFIFO) return "fifo"; else if (ftype == S_IFLNK) return "symlink"; return ""; } static char *grouplist = NULL; void clearalertgroups(void) { if (grouplist) xfree(grouplist); } char *getalertgroups(void) { if (grouplist) { *(grouplist + strlen(grouplist) - 1) = '\0'; return grouplist+1; } else return NULL; } void addalertgroup(char *group) { char *key; int curlen; if (group == NULL) return; key = (char *)malloc(strlen(group)+3); sprintf(key, ",%s,", group); if (!grouplist) { grouplist = key; return; } if (strstr(grouplist, key)) { xfree(key); return; } curlen = strlen(grouplist); grouplist = (char *)realloc(grouplist, curlen + strlen(key) + 2); sprintf(grouplist + curlen, "%s,", key); } int load_client_config(char *configfn) { /* (Re)load the configuration file without leaking memory */ static void *configfiles = NULL; char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf; char *tok; exprlist_t *curhost, *curpage, *curclass, *curexhost, *curexpage, *curexclass, *curdg, *curexdg; char *curtime, *curextime, *curtext, *curgroup; c_rule_t *currule = NULL; int cfid = 0; MEMDEFINE(fn); if (configfn) strcpy(fn, configfn); else sprintf(fn, "%s/etc/analysis.cfg", xgetenv("XYMONHOME")); /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", fn); return 0; } else { stackfclist(&configfiles); configfiles = NULL; } } fd = stackfopen(fn, "r", &configfiles); if (!fd) { errprintf("Cannot load config file %s: %s\n", fn, strerror(errno)); MEMUNDEFINE(fn); return 0; } /* First free the old list, if any */ while (rulehead) { c_rule_t *tmp = rulehead; rulehead = rulehead->next; if (tmp->groups) xfree(tmp->groups); if (tmp->timespec) xfree(tmp->timespec); if (tmp->extimespec) xfree(tmp->extimespec); if (tmp->statustext) xfree(tmp->statustext); if (tmp->rrdidstr) xfree(tmp->rrdidstr); switch (tmp->ruletype) { case C_MIBVAL: if (tmp->rule.mibval.havetree) xtreeDestroy(tmp->rule.mibval.valdeftree); break; case C_RRDDS: if (tmp->rule.rrdds.rrdds) xfree(tmp->rule.rrdds.rrdds); if (tmp->rule.rrdds.column) xfree(tmp->rule.rrdds.column); break; default: break; } xfree(tmp); } rulehead = ruletail = NULL; while (exprhead) { exprlist_t *tmp = exprhead; exprhead = exprhead->next; if (tmp->pattern) xfree(tmp->pattern); if (tmp->exp) pcre_free(tmp->exp); xfree(tmp); } exprhead = NULL; if (havetree) { xtreePos_t handle; char *key; ruleset_t *head, *itm; handle = xtreeFirst(ruletree); while (handle != xtreeEnd(ruletree)) { key = (char *)xtreeKey(ruletree, handle); head = (ruleset_t *)xtreeData(ruletree, handle); xfree(key); while (head) { itm = head; head = head->next; xfree(itm); } handle = xtreeNext(ruletree, handle); } xtreeDestroy(ruletree); havetree = 0; } #define NEWRULE(X) (setup_rule(X, curhost, curexhost, curpage, curexpage, curdg, curexdg, curclass, curexclass, curtime, curextime, curtext, curgroup, cfid)); curhost = curpage = curclass = curexhost = curexpage = curexclass = curdg = curexdg = NULL; curtime = curextime = curtext = curgroup = NULL; inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { exprlist_t *newhost, *newpage, *newexhost, *newexpage, *newclass, *newexclass, *newdg, *newexdg; char *newtime, *newextime, *newtext, *newgroup; int unknowntok = 0; cfid++; sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; newhost = newpage = newexhost = newexpage = newclass = newexclass = newdg = newexdg = NULL; newtime = newextime = newtext = newgroup = NULL; currule = NULL; tok = wstok(STRBUF(inbuf)); while (tok) { if (strncasecmp(tok, "HOST=", 5) == 0) { char *p = strchr(tok, '='); newhost = setup_expr(p+1, 0); if (currule) currule->hostexp = newhost; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "EXHOST=", 7) == 0) { char *p = strchr(tok, '='); newexhost = setup_expr(p+1, 0); if (currule) currule->exhostexp = newexhost; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "PAGE=", 5) == 0) { char *p = strchr(tok, '='); newpage = setup_expr(p+1, 0); if (currule) currule->pageexp = newpage; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "EXPAGE=", 7) == 0) { char *p = strchr(tok, '='); newexpage = setup_expr(p+1, 0); if (currule) currule->expageexp = newexpage; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "DISPLAYGROUP=", 13) == 0) { char *p = strchr(tok, '='); newdg = setup_expr(p+1, 0); if (currule) currule->dgexp = newdg; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "EXDISPLAYGROUP=", 15) == 0) { char *p = strchr(tok, '='); newexdg = setup_expr(p+1, 0); if (currule) currule->exdgexp = newexdg; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "CLASS=", 6) == 0) { char *p = strchr(tok, '='); newclass = setup_expr(p+1, 0); if (currule) currule->classexp = newclass; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "EXCLASS=", 8) == 0) { char *p = strchr(tok, '='); newexclass = setup_expr(p+1, 0); if (currule) currule->exclassexp = newexclass; tok = wstok(NULL); continue; } else if (strncasecmp(tok, "TIME=", 5) == 0) { char *p = strchr(tok, '='); if (currule) currule->timespec = strdup(p+1); else newtime = strdup(p+1); tok = wstok(NULL); continue; } else if (strncasecmp(tok, "EXTIME=", 7) == 0) { char *p = strchr(tok, '='); if (currule) currule->extimespec = strdup(p+1); else newextime = strdup(p+1); tok = wstok(NULL); continue; } else if (strncasecmp(tok, "TEXT=", 5) == 0) { char *p = strchr(tok, '='); if (currule) currule->statustext = strdup(p+1); else newtext = strdup(p+1); tok = wstok(NULL); continue; } else if (strncasecmp(tok, "GROUP=", 6) == 0) { char *p = strchr(tok, '='); if (currule) currule->groups = strdup(p+1); else newgroup = strdup(p+1); tok = wstok(NULL); continue; } else if (strncasecmp(tok, "DEFAULT", 6) == 0) { currule = NULL; } else if (strcasecmp(tok, "UP") == 0) { currule = NEWRULE(C_UPTIME) currule->rule.uptime.recentlimit = 3600; currule->rule.uptime.ancientlimit = -1; currule->rule.uptime.color = COL_YELLOW; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.uptime.recentlimit = 60*durationvalue(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.uptime.ancientlimit = 60*durationvalue(tok); tok = wstok(NULL); if (isqual(tok)) continue; if (tok) currule->rule.uptime.color = parse_color(tok); } else if (strcasecmp(tok, "CLOCK") == 0) { currule = NEWRULE(C_CLOCK); currule->rule.clock.maxdiff = 60; currule->rule.clock.color = COL_YELLOW; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.clock.maxdiff = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; if (tok) currule->rule.clock.color = parse_color(tok); } else if (strcasecmp(tok, "LOAD") == 0) { currule = NEWRULE(C_LOAD); currule->rule.load.warnlevel = 5.0; currule->rule.load.paniclevel = atof(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.load.warnlevel = atof(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.load.paniclevel = atof(tok); } else if (strcasecmp(tok, "DISK") == 0) { currule = NEWRULE(C_DISK); currule->rule.disk.abswarn = 0; currule->rule.disk.warnlevel = 90; currule->rule.disk.abspanic = 0; currule->rule.disk.paniclevel = 95; currule->rule.disk.dmin = 0; currule->rule.disk.dmax = -1; currule->rule.disk.color = COL_RED; currule->rule.disk.ignored = 0; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.disk.fsexp = setup_expr(tok, 0); tok = wstok(NULL); if (isqual(tok)) continue; if (strcasecmp(tok, "ignore") == 0) { currule->rule.disk.ignored = 1; tok = wstok(NULL); continue; } currule->rule.disk.warnlevel = atol(tok); switch (*(tok + strspn(tok, "0123456789"))) { case 'U': case 'u': currule->rule.disk.abswarn = 1; break; case '%': currule->rule.disk.abswarn = 0; break; default : currule->rule.disk.abswarn = (currule->rule.disk.warnlevel > 200 ? 1 : 0); break; } tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.disk.paniclevel = atol(tok); switch (*(tok + strspn(tok, "0123456789"))) { case 'U': case 'u': currule->rule.disk.abspanic = 1; break; case '%': currule->rule.disk.abspanic = 0; break; default : currule->rule.disk.abspanic = (currule->rule.disk.paniclevel > 200 ? 1 : 0); break; } tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.disk.dmin = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.disk.dmax = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.disk.color = parse_color(tok); } else if (strcasecmp(tok, "INODE") == 0) { currule = NEWRULE(C_INODE); currule->rule.inode.abswarn = 0; currule->rule.inode.warnlevel = 70; currule->rule.inode.abspanic = 0; currule->rule.inode.paniclevel = 90; currule->rule.inode.imin = 0; currule->rule.inode.imax = -1; currule->rule.inode.color = COL_RED; currule->rule.inode.ignored = 0; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.inode.fsexp = setup_expr(tok, 0); tok = wstok(NULL); if (isqual(tok)) continue; if (strcasecmp(tok, "ignore") == 0) { currule->rule.inode.ignored = 1; tok = wstok(NULL); continue; } currule->rule.inode.warnlevel = atol(tok); switch (*(tok + strspn(tok, "0123456789"))) { case 'U': case 'u': currule->rule.inode.abswarn = 1; break; case '%': currule->rule.inode.abswarn = 0; break; default : currule->rule.inode.abswarn = (currule->rule.inode.warnlevel > 200 ? 1 : 0); break; } tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.inode.paniclevel = atol(tok); switch (*(tok + strspn(tok, "0123456789"))) { case 'U': case 'u': currule->rule.inode.abspanic = 1; break; case '%': currule->rule.inode.abspanic = 0; break; default : currule->rule.inode.abspanic = (currule->rule.inode.paniclevel > 200 ? 1 : 0); break; } tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.inode.imin = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.inode.imax = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.inode.color = parse_color(tok); } else if ((strcasecmp(tok, "MEMREAL") == 0) || (strcasecmp(tok, "MEMPHYS") == 0) || (strcasecmp(tok, "PHYS") == 0)) { currule = NEWRULE(C_MEM); currule->rule.mem.memtype = C_MEM_PHYS; currule->rule.mem.warnlevel = 100; currule->rule.mem.paniclevel = 101; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.paniclevel = atoi(tok); } else if ((strcasecmp(tok, "MEMSWAP") == 0) || (strcasecmp(tok, "SWAP") == 0)) { currule = NEWRULE(C_MEM); currule->rule.mem.memtype = C_MEM_SWAP; currule->rule.mem.warnlevel = 50; currule->rule.mem.paniclevel = 80; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.paniclevel = atoi(tok); } else if ((strcasecmp(tok, "MEMACT") == 0) || (strcasecmp(tok, "ACTUAL") == 0) || (strcasecmp(tok, "ACT") == 0)) { currule = NEWRULE(C_MEM); currule->rule.mem.memtype = C_MEM_ACT; currule->rule.mem.warnlevel = 90; currule->rule.mem.paniclevel = 97; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.mem.paniclevel = atoi(tok); } else if (strcasecmp(tok, "MEMCSA") == 0) { currule = NEWRULE(C_MEM); currule->rule.zos_mem.zos_memtype = C_MEM_CSA; currule->rule.zos_mem.warnlevel = 90; currule->rule.zos_mem.paniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.paniclevel = atoi(tok); } else if (strcasecmp(tok, "MEMECSA") == 0) { currule = NEWRULE(C_MEM); currule->rule.zos_mem.zos_memtype = C_MEM_ECSA; currule->rule.zos_mem.warnlevel = 90; currule->rule.zos_mem.paniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.paniclevel = atoi(tok); } else if (strcasecmp(tok, "MEMSQA") == 0) { currule = NEWRULE(C_MEM); currule->rule.zos_mem.zos_memtype = C_MEM_SQA; currule->rule.zos_mem.warnlevel = 90; currule->rule.zos_mem.paniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.paniclevel = atoi(tok); } else if (strcasecmp(tok, "MEMESQA") == 0) { currule = NEWRULE(C_MEM); currule->rule.zos_mem.zos_memtype = C_MEM_ESQA; currule->rule.zos_mem.warnlevel = 90; currule->rule.zos_mem.paniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zos_mem.paniclevel = atoi(tok); } else if (strcasecmp(tok, "CICS") == 0) { currule = NEWRULE(C_CICS); currule->rule.cics.dsawarnlevel = 90; currule->rule.cics.dsapaniclevel = 95; currule->rule.cics.edsawarnlevel = 90; currule->rule.cics.edsapaniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.applid = setup_expr(tok, 0); tok = wstok(NULL); if (isqual(tok)) continue; if (strcasecmp(tok, "DSA") == 0) { tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.dsawarnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.dsapaniclevel = atoi(tok); } else if (strcasecmp(tok, "EDSA") == 0) { tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.edsawarnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.edsapaniclevel = atoi(tok); } tok = wstok(NULL); if (isqual(tok)) continue; if (strcasecmp(tok, "DSA") == 0) { tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.dsawarnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.dsapaniclevel = atoi(tok); } else if (strcasecmp(tok, "EDSA") == 0) { tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.edsawarnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.cics.edsapaniclevel = atoi(tok); } } else if (strcasecmp(tok, "PROC") == 0) { int idx = 0; tok = wstok(NULL); if (tok == NULL) { errprintf("Syntax error line %d: PROC with no definition\n", cfid); unknowntok = 1; break; } currule = NEWRULE(C_PROC); currule->rule.proc.pmin = 1; currule->rule.proc.pmax = -1; currule->rule.proc.color = COL_RED; currule->rule.proc.procexp = setup_expr(tok, 0); do { tok = wstok(NULL); if (!tok || isqual(tok)) { idx = -1; continue; } if (strncasecmp(tok, "min=", 4) == 0) { currule->rule.proc.pmin = atoi(tok+4); } else if (strncasecmp(tok, "max=", 4) == 0) { currule->rule.proc.pmax = atoi(tok+4); /* When we have an explicit max, minimum should not be higher */ if (currule->rule.proc.pmax < currule->rule.proc.pmin) { currule->rule.proc.pmin = currule->rule.proc.pmax; } } else if (strncasecmp(tok, "color=", 6) == 0) { currule->rule.proc.color = parse_color(tok+6); } else if (strncasecmp(tok, "track", 5) == 0) { currule->chkflags |= CHK_TRACKIT; if (*(tok+5) == '=') currule->rrdidstr = strdup(tok+6); } else if (idx == 0) { currule->rule.proc.pmin = atoi(tok); idx++; } else if (idx == 1) { currule->rule.proc.pmax = atoi(tok); idx++; } else if (idx == 2) { currule->rule.proc.color = parse_color(tok); idx++; } } while (tok && (!isqual(tok))); /* It's easy to set max=0 when you only want to define a minimum */ if (currule->rule.proc.pmin && (currule->rule.proc.pmax == 0)) { currule->rule.proc.pmax = -1; } } else if (strcasecmp(tok, "LOG") == 0) { int idx = 0; currule = NEWRULE(C_LOG); currule->rule.log.logfile = NULL; currule->rule.log.matchexp = NULL; currule->rule.log.matchone = NULL; currule->rule.log.ignoreexp = NULL; currule->rule.log.color = COL_RED; do { tok = wstok(NULL); if (!tok || isqual(tok)) { idx = -1; continue; } if (strncasecmp(tok, "file=", 5) == 0) { currule->rule.log.logfile = setup_expr(tok+5, 0); } else if (strncasecmp(tok, "match=", 6) == 0) { currule->rule.log.matchexp = setup_expr(tok+6, 1); currule->rule.log.matchone = setup_expr(tok+6, 0); } else if (strncasecmp(tok, "ignore=", 7) == 0) { currule->rule.log.ignoreexp = setup_expr(tok+7, 1); } else if (strncasecmp(tok, "color=", 6) == 0) { currule->rule.log.color = parse_color(tok+6); } else if (strcasecmp(tok, "optional") == 0) { currule->chkflags |= CHK_OPTIONAL; } else if (idx == 0) { currule->rule.log.logfile = setup_expr(tok, 0); idx++; } else if (idx == 1) { currule->rule.log.matchexp = setup_expr(tok, 1); currule->rule.log.matchone = setup_expr(tok, 0); idx++; } else if (idx == 2) { currule->rule.log.color = parse_color(tok); idx++; } else if (idx == 3) { currule->rule.log.ignoreexp = setup_expr(tok, 1); idx++; } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "FILE") == 0) { currule = NEWRULE(C_FILE); currule->rule.fcheck.filename = NULL; currule->rule.fcheck.color = COL_RED; tok = wstok(NULL); currule->rule.fcheck.filename = setup_expr(tok, 0); do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strcasecmp(tok, "noexist") == 0) { currule->flags |= FCHK_NOEXIST; } else if (strncasecmp(tok, "type=", 5) == 0) { currule->flags |= FCHK_TYPE; if (strcasecmp(tok+5, "socket") == 0) currule->rule.fcheck.ftype = S_IFSOCK; else if (strcasecmp(tok+5, "file") == 0) currule->rule.fcheck.ftype = S_IFREG; else if (strcasecmp(tok+5, "block") == 0) currule->rule.fcheck.ftype = S_IFBLK; else if (strcasecmp(tok+5, "char") == 0) currule->rule.fcheck.ftype = S_IFCHR; else if (strcasecmp(tok+5, "dir") == 0) currule->rule.fcheck.ftype = S_IFDIR; else if (strcasecmp(tok+5, "fifo") == 0) currule->rule.fcheck.ftype = S_IFIFO; else if (strcasecmp(tok+5, "symlink") == 0) currule->rule.fcheck.ftype = S_IFLNK; } else if (strncasecmp(tok, "size>", 5) == 0) { currule->flags |= FCHK_MINSIZE; currule->rule.fcheck.minsize = filesize_value(tok+5); } else if (strncasecmp(tok, "size<", 5) == 0) { currule->flags |= FCHK_MAXSIZE; currule->rule.fcheck.maxsize = filesize_value(tok+5); } else if (strncasecmp(tok, "size=", 5) == 0) { currule->flags |= FCHK_EQLSIZE; currule->rule.fcheck.eqlsize = filesize_value(tok+5); } else if (strncasecmp(tok, "links>", 6) == 0) { currule->flags |= FCHK_MINLINKS; currule->rule.fcheck.minlinks = atol(tok+6); } else if (strncasecmp(tok, "links<", 6) == 0) { currule->flags |= FCHK_MAXLINKS; currule->rule.fcheck.maxlinks = atol(tok+6); } else if (strncasecmp(tok, "links=", 6) == 0) { currule->flags |= FCHK_EQLLINKS; currule->rule.fcheck.eqllinks = atol(tok+6); } else if (strncasecmp(tok, "mode=", 5) == 0) { currule->flags |= FCHK_MODE; currule->rule.fcheck.fmode = strtol(tok+5, NULL, 8); } else if ((strncasecmp(tok, "owner=", 6) == 0) || (strncasecmp(tok, "ownerid=", 8) == 0)) { char *p, *eptr; int uid; p = strchr(tok, '='); uid = strtol(p+1, &eptr, 10); if (*eptr == '\0') { /* All numeric */ currule->flags |= FCHK_OWNERID; currule->rule.fcheck.ownerid = uid; } else { currule->flags |= FCHK_OWNERSTR; currule->rule.fcheck.ownerstr = strdup(p+1); } } else if (strncasecmp(tok, "groupid=", 8) == 0) { /* Cannot use "group" because that is reserved */ char *p, *eptr; int uid; p = strchr(tok, '='); uid = strtol(p+1, &eptr, 10); if (*eptr == '\0') { /* All numeric */ currule->flags |= FCHK_GROUPID; currule->rule.fcheck.groupid = uid; } else { currule->flags |= FCHK_GROUPSTR; currule->rule.fcheck.groupstr = strdup(p+1); } } else if (strncasecmp(tok, "mtime>", 6) == 0) { currule->flags |= FCHK_MTIMEMIN; currule->rule.fcheck.minmtimedif = atol(tok+6); } else if (strncasecmp(tok, "mtime<", 6) == 0) { currule->flags |= FCHK_MTIMEMAX; currule->rule.fcheck.maxmtimedif = atol(tok+6); } else if (strncasecmp(tok, "mtime=", 6) == 0) { currule->flags |= FCHK_MTIMEEQL; currule->rule.fcheck.mtimeeql = atol(tok+6); } else if (strncasecmp(tok, "ctime>", 6) == 0) { currule->flags |= FCHK_CTIMEMIN; currule->rule.fcheck.minctimedif = atol(tok+6); } else if (strncasecmp(tok, "ctime<", 6) == 0) { currule->flags |= FCHK_CTIMEMAX; currule->rule.fcheck.maxctimedif = atol(tok+6); } else if (strncasecmp(tok, "ctime=", 6) == 0) { currule->flags |= FCHK_CTIMEEQL; currule->rule.fcheck.ctimeeql = atol(tok+6); } else if (strncasecmp(tok, "atime>", 6) == 0) { currule->flags |= FCHK_ATIMEMIN; currule->rule.fcheck.minatimedif = atol(tok+6); } else if (strncasecmp(tok, "atime<", 6) == 0) { currule->flags |= FCHK_ATIMEMAX; currule->rule.fcheck.maxatimedif = atol(tok+6); } else if (strncasecmp(tok, "atime=", 6) == 0) { currule->flags |= FCHK_ATIMEEQL; currule->rule.fcheck.atimeeql = atol(tok+6); } else if (strncasecmp(tok, "md5=", 4) == 0) { currule->flags |= FCHK_MD5; currule->rule.fcheck.md5hash = strdup(tok+4); } else if (strncasecmp(tok, "sha1=", 5) == 0) { currule->flags |= FCHK_SHA1; currule->rule.fcheck.sha1hash = strdup(tok+5); } else if (strncasecmp(tok, "sha256=", 7) == 0) { currule->flags |= FCHK_SHA256; currule->rule.fcheck.sha256hash = strdup(tok+7); } else if (strncasecmp(tok, "sha512=", 7) == 0) { currule->flags |= FCHK_SHA512; currule->rule.fcheck.sha512hash = strdup(tok+7); } else if (strncasecmp(tok, "sha224=", 7) == 0) { currule->flags |= FCHK_SHA224; currule->rule.fcheck.sha224hash = strdup(tok+7); } else if (strncasecmp(tok, "sha384=", 7) == 0) { currule->flags |= FCHK_SHA384; currule->rule.fcheck.sha384hash = strdup(tok+7); } else if (strncasecmp(tok, "rmd160=", 7) == 0) { currule->flags |= FCHK_RMD160; currule->rule.fcheck.rmd160hash = strdup(tok+7); } else if (strncasecmp(tok, "track", 5) == 0) { currule->chkflags |= CHK_TRACKIT; if (*(tok+5) == '=') currule->rrdidstr = strdup(tok+6); } else if (strcasecmp(tok, "optional") == 0) { currule->chkflags |= CHK_OPTIONAL; } else { int col = parse_color(tok); if (col != -1) currule->rule.fcheck.color = col; } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "DIR") == 0) { currule = NEWRULE(C_DIR); currule->rule.dcheck.filename = NULL; currule->rule.dcheck.color = COL_RED; tok = wstok(NULL); currule->rule.dcheck.filename = setup_expr(tok, 0); do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "size<", 5) == 0) { currule->flags |= FCHK_MAXSIZE; currule->rule.dcheck.maxsize = atol(tok+5); } else if (strncasecmp(tok, "size>", 5) == 0) { currule->flags |= FCHK_MINSIZE; currule->rule.dcheck.minsize = atol(tok+5); } else if (strncasecmp(tok, "track", 5) == 0) { currule->chkflags |= CHK_TRACKIT; if (*(tok+5) == '=') currule->rrdidstr = strdup(tok+6); } else { int col = parse_color(tok); if (col != -1) currule->rule.dcheck.color = col; } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "PORT") == 0) { currule = NEWRULE(C_PORT); currule->rule.port.localexp = NULL; currule->rule.port.exlocalexp = NULL; currule->rule.port.remoteexp = NULL; currule->rule.port.exremoteexp = NULL; currule->rule.port.stateexp = NULL; currule->rule.port.exstateexp = NULL; currule->rule.port.pmin = 1; currule->rule.port.pmax = -1; currule->rule.port.color = COL_RED; /* parse syntax [local=ADDR] [remote=ADDR] [state=STATE] [min=mincount] [max=maxcount] [col=color] */ do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "local=", 6) == 0) { currule->rule.port.localexp = setup_expr(tok+6, 0); } else if (strncasecmp(tok, "exlocal=", 8) == 0) { currule->rule.port.exlocalexp = setup_expr(tok+8, 0); } else if (strncasecmp(tok, "remote=", 7) == 0) { currule->rule.port.remoteexp = setup_expr(tok+7, 0); } else if (strncasecmp(tok, "exremote=", 9) == 0) { currule->rule.port.exremoteexp = setup_expr(tok+9, 0); } else if (strncasecmp(tok, "state=", 6) == 0) { currule->rule.port.stateexp = setup_expr(tok+6, 0); } else if (strncasecmp(tok, "exstate=", 8) == 0) { currule->rule.port.exstateexp = setup_expr(tok+8, 0); } else if (strncasecmp(tok, "min=", 4) == 0) { currule->rule.port.pmin = atoi(tok+4); } else if (strncasecmp(tok, "max=", 4) == 0) { currule->rule.port.pmax = atoi(tok+4); /* When we have an explicit max, minimum should not be higher */ if (currule->rule.port.pmax < currule->rule.port.pmin) { currule->rule.port.pmin = currule->rule.port.pmax; } } else if (strncasecmp(tok, "col=", 4) == 0) { currule->rule.port.color = parse_color(tok+4); } else if (strncasecmp(tok, "color=", 6) == 0) { currule->rule.port.color = parse_color(tok+6); } else if (strncasecmp(tok, "track", 5) == 0) { currule->chkflags |= CHK_TRACKIT; if (*(tok+5) == '=') currule->rrdidstr = strdup(tok+6); } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "PAGING") == 0) { currule = NEWRULE(C_PAGING); currule->rule.paging.warnlevel = 5; currule->rule.paging.paniclevel = 10; tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.paging.warnlevel = atoi(tok); tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.paging.paniclevel = atoi(tok); } else if (strcasecmp(tok, "GETVIS") == 0) { currule = NEWRULE(C_MEM_GETVIS); currule->rule.zvse_getvis.warnlevel = 90; currule->rule.zvse_getvis.paniclevel = 95; currule->rule.zvse_getvis.anywarnlevel = 90; currule->rule.zvse_getvis.anypaniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_getvis.partid = setup_expr(tok, 0); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_getvis.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_getvis.paniclevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_getvis.anywarnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_getvis.anypaniclevel = atoi(tok); } else if (strcasecmp(tok, "VSIZE") == 0) { currule = NEWRULE(C_MEM_VSIZE); currule->rule.zvse_vsize.warnlevel = 90; currule->rule.zvse_vsize.paniclevel = 95; tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_vsize.warnlevel = atoi(tok); tok = wstok(NULL); if (isqual(tok)) continue; currule->rule.zvse_vsize.paniclevel = atoi(tok); } else if (strcasecmp(tok, "MAXUSER") == 0) { currule = NEWRULE(C_ASID); currule->rule.asid.asidtype = C_ASID_MAXUSER; currule->rule.asid.warnlevel = 101; currule->rule.asid.paniclevel = 101; tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.asid.warnlevel = atoi(tok); tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.asid.paniclevel = atoi(tok); } else if (strcasecmp(tok, "NPARTS") == 0) { currule = NEWRULE(C_ASID); currule->rule.asid.asidtype = C_ASID_NPARTS; currule->rule.asid.warnlevel = 101; currule->rule.asid.paniclevel = 101; tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.asid.warnlevel = atoi(tok); tok = wstok(NULL); if (!tok || isqual(tok)) continue; currule->rule.asid.paniclevel = atoi(tok); } else if (strcasecmp(tok, "SVC") == 0) { tok = wstok(NULL); /* See if there is any service definition at all */ if (tok) { currule = NEWRULE(C_SVC); currule->rule.svc.svcexp = setup_expr(tok, 0); currule->rule.svc.startupexp = NULL; currule->rule.svc.stateexp = NULL; currule->rule.svc.state = NULL; currule->rule.svc.startup = NULL; currule->rule.svc.color = COL_RED; do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "startup=", 8) == 0) { currule->rule.svc.startupexp = setup_expr(tok+8, 0); } else if (strncasecmp(tok, "status=", 7) == 0) { currule->rule.svc.stateexp = setup_expr(tok+7, 0); } else if (strncasecmp(tok, "col=", 4) == 0) { currule->rule.svc.color = parse_color(tok+4); } else if (strncasecmp(tok, "color=", 6) == 0) { currule->rule.svc.color = parse_color(tok+6); } } while (tok && (!isqual(tok))); if (!currule->rule.svc.stateexp && !currule->rule.svc.startupexp) { /* No criteria defined, so we'll assume they just want to check that the service is running */ currule->rule.svc.stateexp = setup_expr("started", 0); } } } else if (strcasecmp(tok, "MIB") == 0) { currule = NEWRULE(C_MIBVAL); currule->rule.mibval.mibvalexp = NULL; currule->rule.mibval.keyexp = NULL; currule->rule.mibval.color = COL_RED; currule->rule.mibval.minval = -1; currule->rule.mibval.maxval = -1; currule->rule.mibval.matchexp = NULL; tok = wstok(NULL); currule->rule.mibval.mibvalexp = setup_expr(tok, 0); do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "key=", 4) == 0) { currule->rule.mibval.keyexp = setup_expr(tok+4, 0); } else if (strncasecmp(tok, "max=", 4) == 0) { currule->flags |= MIBCHK_MAXVALUE; currule->rule.mibval.maxval = atol(tok+4); } else if (strncasecmp(tok, "min=", 4) == 0) { currule->flags |= MIBCHK_MINVALUE; currule->rule.mibval.minval = atol(tok+4); } else if (strncasecmp(tok, "match=", 6) == 0) { currule->flags |= MIBCHK_MATCH; currule->rule.mibval.matchexp = setup_expr(tok+6, 0); } else if (strncasecmp(tok, "color=", 6) == 0) { int col = parse_color(tok+6); if (col != -1) currule->rule.mibval.color = col; } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "DS") == 0) { char *key, *ds, *column; currule = NEWRULE(C_RRDDS); currule->rule.rrdds.color = COL_RED; tok = wstok(NULL); column = tok; tok = wstok(NULL); key = tok; ds = (tok ? strrchr(tok, ':') : NULL); if (ds) { *ds = '\0'; ds++; } if (!column || !key || !ds) { errprintf("Invalid DS definition at line %d (missing column, key and/or dataset)\n", cfid); continue; } currule->rule.rrdds.rrdkey = setup_expr(key, 0); currule->rule.rrdds.rrdds = strdup(ds); currule->rule.rrdds.column = strdup(column); do { int getnumber = 0; tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, ">=", 2) == 0) { if (currule->flags) currule->flags |= RRDDSCHK_INTVL; currule->flags |= RRDDSCHK_GE; getnumber = 2; } else if (strncasecmp(tok, "<=", 2) == 0) { if (currule->flags) currule->flags |= RRDDSCHK_INTVL; currule->flags |= RRDDSCHK_LE; getnumber = 2; } else if (strncasecmp(tok, ">", 1) == 0) { if (currule->flags) currule->flags |= RRDDSCHK_INTVL; currule->flags |= RRDDSCHK_GT; getnumber = 1; } else if (strncasecmp(tok, "<", 1) == 0) { if (currule->flags) currule->flags |= RRDDSCHK_INTVL; currule->flags |= RRDDSCHK_LT; getnumber = 1; } else if (strncasecmp(tok, "color=", 6) == 0) { int col = parse_color(tok+6); if (col != -1) currule->rule.rrdds.color = col; } if (getnumber) { if (currule->flags & RRDDSCHK_INTVL) currule->rule.rrdds.limitval2 = atof(tok+getnumber); else currule->rule.rrdds.limitval = atof(tok+getnumber); if ((currule->flags & RRDDSCHK_INTVL) && (currule->rule.rrdds.limitval > currule->rule.rrdds.limitval2)) { /* Swap the two values, so we always have limitval as the lower bound, and limitval2 as the upper */ double tmp; tmp=currule->rule.rrdds.limitval; currule->rule.rrdds.limitval = currule->rule.rrdds.limitval2; currule->rule.rrdds.limitval2 = tmp; } } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "MQ_QUEUE") == 0) { char *p; currule = NEWRULE(C_MQ_QUEUE); currule->rule.mqqueue.qmgrname = NULL; currule->rule.mqqueue.qname = NULL; currule->rule.mqqueue.warnlen = -1; currule->rule.mqqueue.critlen = -1; currule->rule.mqqueue.warnage = -1; currule->rule.mqqueue.critage = -1; tok = wstok(NULL); p = strchr(tok, ':'); if (p) { *p = '\0'; p++; currule->rule.mqqueue.qmgrname = setup_expr(tok, 0); currule->rule.mqqueue.qname = setup_expr(p, 0); } else { currule->rule.mqqueue.qmgrname = setup_expr("*", 0); currule->rule.mqqueue.qname = setup_expr(tok, 0); }; do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "depth-warning=", 14) == 0) { currule->rule.mqqueue.warnlen = atol(tok+14); } else if (strncasecmp(tok, "depth-critical=", 15) == 0) { currule->rule.mqqueue.critlen = atol(tok+15); } else if (strncasecmp(tok, "age-warning=", 12) == 0) { currule->rule.mqqueue.warnage = atol(tok+12); } else if (strncasecmp(tok, "age-critical=", 13) == 0) { currule->rule.mqqueue.critage = atol(tok+13); } else if (strncasecmp(tok, "track", 5) == 0) { currule->chkflags |= CHK_TRACKIT; if (*(tok+5) == '=') currule->rrdidstr = strdup(tok+6); } } while (tok && (!isqual(tok))); } else if (strcasecmp(tok, "MQ_CHANNEL") == 0) { char *p; currule = NEWRULE(C_MQ_CHANNEL); currule->rule.mqchannel.qmgrname = NULL; currule->rule.mqchannel.chnname = NULL; currule->rule.mqchannel.warnstates = NULL; currule->rule.mqchannel.alertstates = NULL; tok = wstok(NULL); p = strchr(tok, ':'); if (p) { *p = '\0'; p++; currule->rule.mqchannel.qmgrname = setup_expr(tok, 0); currule->rule.mqchannel.chnname = setup_expr(p, 0); } else { currule->rule.mqchannel.qmgrname = setup_expr("*", 0); currule->rule.mqchannel.chnname = setup_expr(tok, 0); }; do { tok = wstok(NULL); if (!tok || isqual(tok)) continue; if (strncasecmp(tok, "warning=", 8) == 0) { currule->rule.mqchannel.warnstates = setup_expr(tok+8, 0); } else if (strncasecmp(tok, "alert=", 6) == 0) { currule->rule.mqchannel.alertstates = setup_expr(tok+6, 0); } } while (tok && (!isqual(tok))); if ((currule->rule.mqchannel.warnstates == NULL) && (currule->rule.mqchannel.alertstates == NULL)) { /* Default: Alert on channel in BIND or RETRYING state */ currule->rule.mqchannel.alertstates = setup_expr("%BIND|RETRYING", 0); } } else { errprintf("Unknown token '%s' ignored at line %d\n", tok, cfid); unknowntok = 1; tok = NULL; continue; } if (tok && !isqual(tok)) tok = wstok(NULL); } if (!currule && !unknowntok) { /* No rules on this line - its the new set of criteria */ curhost = newhost; curpage = newpage; curclass = newclass; curexhost = newexhost; curexpage = newexpage; curexclass = newexclass; if (curtime) xfree(curtime); curtime = newtime; if (curextime) xfree(curextime); curextime = newextime; if (curtext) xfree(curtext); curtext = newtext; if (curgroup) xfree(curgroup); curgroup = newgroup; } } stackfclose(fd); freestrbuffer(inbuf); if (curtime) xfree(curtime); if (curextime) xfree(curextime); if (curtext) xfree(curtext); /* Create the ruletree, but leave it empty - it will be filled as clients report */ ruletree = xtreeNew(strcasecmp); havetree = 1; MEMUNDEFINE(fn); return 1; } void dump_client_config(void) { c_rule_t *rwalk; for (rwalk = rulehead; (rwalk); rwalk = rwalk->next) { switch (rwalk->ruletype) { case C_UPTIME: printf("UP %d %d", rwalk->rule.uptime.recentlimit, rwalk->rule.uptime.ancientlimit); break; case C_CLOCK: printf("CLOCK %d", rwalk->rule.clock.maxdiff); break; case C_LOAD: printf("LOAD %.2f %.2f", rwalk->rule.load.warnlevel, rwalk->rule.load.paniclevel); break; case C_DISK: if (!rwalk->rule.disk.fsexp) break; printf("DISK %s", rwalk->rule.disk.fsexp->pattern); if (rwalk->rule.disk.ignored) printf(" IGNORE"); else { printf(" %lu%c", rwalk->rule.disk.warnlevel, (rwalk->rule.disk.abswarn ? 'U' : '%')); printf(" %lu%c", rwalk->rule.disk.paniclevel, (rwalk->rule.disk.abspanic ? 'U' : '%')); printf(" %d %d %s", rwalk->rule.disk.dmin, rwalk->rule.disk.dmax, colorname(rwalk->rule.disk.color)); } break; case C_INODE: if (!rwalk->rule.inode.fsexp) break; printf("INODE %s", rwalk->rule.inode.fsexp->pattern); if (rwalk->rule.inode.ignored) printf(" IGNORE"); else { printf(" %lu%c", rwalk->rule.inode.warnlevel, (rwalk->rule.inode.abswarn ? 'U' : '%')); printf(" %lu%c", rwalk->rule.inode.paniclevel, (rwalk->rule.inode.abspanic ? 'U' : '%')); printf(" %d %d %s", rwalk->rule.inode.imin, rwalk->rule.inode.imax, colorname(rwalk->rule.inode.color)); } break; case C_MEM: switch (rwalk->rule.mem.memtype) { case C_MEM_PHYS: printf("MEMREAL"); break; case C_MEM_SWAP: printf("MEMSWAP"); break; case C_MEM_ACT: printf("MEMACT"); break; } printf(" %d %d", rwalk->rule.mem.warnlevel, rwalk->rule.mem.paniclevel); break; case C_ASID: switch (rwalk->rule.asid.asidtype) { case C_ASID_MAXUSER: printf("MAXUSER: "); break; case C_ASID_NPARTS: printf(" NPARTS: "); break; } printf(" %d %d", rwalk->rule.asid.warnlevel, rwalk->rule.asid.paniclevel); break; case C_PROC: if (!rwalk->rule.proc.procexp) break; if (strchr(rwalk->rule.proc.procexp->pattern, ' ') || strchr(rwalk->rule.proc.procexp->pattern, '\t')) { printf("PROC \"%s\" %d %d %s", rwalk->rule.proc.procexp->pattern, rwalk->rule.proc.pmin, rwalk->rule.proc.pmax, colorname(rwalk->rule.proc.color)); } else { printf("PROC %s %d %d %s", rwalk->rule.proc.procexp->pattern, rwalk->rule.proc.pmin, rwalk->rule.proc.pmax, colorname(rwalk->rule.proc.color)); } break; case C_LOG: if (!rwalk->rule.log.logfile || !rwalk->rule.log.matchexp) break; printf("LOG %s MATCH=%s COLOR=%s", rwalk->rule.log.logfile->pattern, rwalk->rule.log.matchexp->pattern, colorname(rwalk->rule.log.color)); if (rwalk->rule.log.ignoreexp) printf(" IGNORE=%s", rwalk->rule.log.ignoreexp->pattern); break; case C_FILE: if (!rwalk->rule.fcheck.filename) break; printf("FILE %s %s", rwalk->rule.fcheck.filename->pattern, colorname(rwalk->rule.fcheck.color)); if (rwalk->flags & FCHK_NOEXIST) printf(" noexist"); if (rwalk->flags & FCHK_TYPE) printf(" type=%s", ftypestr(rwalk->rule.fcheck.ftype)); if (rwalk->flags & FCHK_MODE) printf(" mode=%o", rwalk->rule.fcheck.fmode); #ifdef _LARGEFILE_SOURCE if (rwalk->flags & FCHK_MINSIZE) printf(" size>%lld", (long long int)rwalk->rule.fcheck.minsize); if (rwalk->flags & FCHK_MAXSIZE) printf(" size<%lld", (long long int)rwalk->rule.fcheck.maxsize); if (rwalk->flags & FCHK_EQLSIZE) printf(" size=%lld", (long long int)rwalk->rule.fcheck.eqlsize); #else if (rwalk->flags & FCHK_MINSIZE) printf(" size>%ld", rwalk->rule.fcheck.minsize); if (rwalk->flags & FCHK_MAXSIZE) printf(" size<%ld", rwalk->rule.fcheck.maxsize); if (rwalk->flags & FCHK_EQLSIZE) printf(" size=%ld", rwalk->rule.fcheck.eqlsize); #endif if (rwalk->flags & FCHK_MINLINKS) printf(" links>%u", rwalk->rule.fcheck.minlinks); if (rwalk->flags & FCHK_MAXLINKS) printf(" links<%u", rwalk->rule.fcheck.maxlinks); if (rwalk->flags & FCHK_EQLLINKS) printf(" links=%u", rwalk->rule.fcheck.eqllinks); if (rwalk->flags & FCHK_OWNERID) printf(" owner=%u", rwalk->rule.fcheck.ownerid); if (rwalk->flags & FCHK_OWNERSTR) printf(" owner=%s", rwalk->rule.fcheck.ownerstr); if (rwalk->flags & FCHK_GROUPID) printf(" group=%u", rwalk->rule.fcheck.groupid); if (rwalk->flags & FCHK_GROUPSTR) printf(" group=%s", rwalk->rule.fcheck.groupstr); if (rwalk->flags & FCHK_CTIMEMIN) printf(" ctime>%u", rwalk->rule.fcheck.minctimedif); if (rwalk->flags & FCHK_CTIMEMAX) printf(" ctime<%u", rwalk->rule.fcheck.maxctimedif); if (rwalk->flags & FCHK_CTIMEEQL) printf(" ctime=%u", rwalk->rule.fcheck.ctimeeql); if (rwalk->flags & FCHK_MTIMEMIN) printf(" mtime>%u", rwalk->rule.fcheck.minmtimedif); if (rwalk->flags & FCHK_MTIMEMAX) printf(" mtime<%u", rwalk->rule.fcheck.maxmtimedif); if (rwalk->flags & FCHK_MTIMEEQL) printf(" mtime=%u", rwalk->rule.fcheck.mtimeeql); if (rwalk->flags & FCHK_ATIMEMIN) printf(" atime>%u", rwalk->rule.fcheck.minatimedif); if (rwalk->flags & FCHK_ATIMEMAX) printf(" atime<%u", rwalk->rule.fcheck.maxatimedif); if (rwalk->flags & FCHK_ATIMEEQL) printf(" atime=%u", rwalk->rule.fcheck.atimeeql); if (rwalk->flags & FCHK_MD5) printf(" md5=%s", rwalk->rule.fcheck.md5hash); if (rwalk->flags & FCHK_SHA1) printf(" sha1=%s", rwalk->rule.fcheck.sha1hash); if (rwalk->flags & FCHK_SHA256) printf(" sha256=%s", rwalk->rule.fcheck.sha256hash); if (rwalk->flags & FCHK_SHA512) printf(" sha512=%s", rwalk->rule.fcheck.sha512hash); if (rwalk->flags & FCHK_SHA224) printf(" sha224=%s", rwalk->rule.fcheck.sha224hash); if (rwalk->flags & FCHK_SHA384) printf(" sha384=%s", rwalk->rule.fcheck.sha384hash); if (rwalk->flags & FCHK_RMD160) printf(" rmd160=%s", rwalk->rule.fcheck.rmd160hash); break; case C_DIR: if (!rwalk->rule.dcheck.filename) break; printf("DIR %s %s", rwalk->rule.dcheck.filename->pattern, colorname(rwalk->rule.dcheck.color)); if (rwalk->flags & FCHK_MINSIZE) printf(" size>%lu", rwalk->rule.dcheck.minsize); if (rwalk->flags & FCHK_MAXSIZE) printf(" size<%lu", rwalk->rule.dcheck.maxsize); break; case C_PORT: printf("PORT"); if (rwalk->rule.port.localexp) printf(" local=%s", rwalk->rule.port.localexp->pattern); if (rwalk->rule.port.exlocalexp) printf(" exlocal=%s", rwalk->rule.port.exlocalexp->pattern); if (rwalk->rule.port.remoteexp) printf(" remote=%s", rwalk->rule.port.remoteexp->pattern); if (rwalk->rule.port.exremoteexp) printf(" exremote=%s", rwalk->rule.port.exremoteexp->pattern); if (rwalk->rule.port.stateexp) printf(" state=%s", rwalk->rule.port.stateexp->pattern); if (rwalk->rule.port.exstateexp) printf(" exstate=%s", rwalk->rule.port.exstateexp->pattern); if (rwalk->rule.port.pmin != -1) printf(" min=%d", rwalk->rule.port.pmin); if (rwalk->rule.port.pmax != -1) printf(" max=%d", rwalk->rule.port.pmax); printf(" color=%s", colorname(rwalk->rule.port.color)); break; case C_PAGING: printf("PAGING %d %d", rwalk->rule.paging.warnlevel, rwalk->rule.paging.paniclevel); break; case C_MEM_VSIZE: printf("z/VSE VSIZE %d %d", rwalk->rule.zvse_vsize.warnlevel, rwalk->rule.zvse_vsize.paniclevel); break; case C_MEM_GETVIS: break; case C_CICS: if (!rwalk->rule.cics.applid) break; printf("CICS: Appid:%s, DSA warning:%d, DSA panic:%d, EDSA warning%d, EDSA panic:%d", rwalk->rule.cics.applid->pattern, rwalk->rule.cics.dsawarnlevel, rwalk->rule.cics.dsapaniclevel, rwalk->rule.cics.edsawarnlevel, rwalk->rule.cics.edsapaniclevel); break; case C_SVC: if (!rwalk->rule.svc.svcexp) break; printf("SVC %s", rwalk->rule.svc.svcexp->pattern); if (rwalk->rule.svc.stateexp) printf(" status=%s", rwalk->rule.svc.stateexp->pattern); if (rwalk->rule.svc.startupexp) printf(" startup=%s", rwalk->rule.svc.startupexp->pattern); printf(" color=%s", colorname(rwalk->rule.svc.color)); break; case C_MIBVAL: printf("MIB"); if (rwalk->rule.mibval.mibvalexp) printf(" %s", rwalk->rule.mibval.mibvalexp->pattern); if (rwalk->rule.mibval.keyexp) printf(" key=%s", rwalk->rule.mibval.keyexp->pattern); if (rwalk->flags & MIBCHK_MINVALUE) printf(" min=%ld", rwalk->rule.mibval.minval); if (rwalk->flags & MIBCHK_MAXVALUE) printf(" max=%ld", rwalk->rule.mibval.maxval); if (rwalk->flags & MIBCHK_MATCH) printf(" match=%s", rwalk->rule.mibval.matchexp->pattern); printf(" color=%s", colorname(rwalk->rule.mibval.color)); break; case C_RRDDS: if (!rwalk->rule.rrdds.rrdkey) break; printf("DS %s %s:%s", rwalk->rule.rrdds.column, rwalk->rule.rrdds.rrdkey->pattern, rwalk->rule.rrdds.rrdds); if (rwalk->flags & RRDDSCHK_GT) printf(" >%.2f", rwalk->rule.rrdds.limitval); if (rwalk->flags & RRDDSCHK_GE) printf(" >=%.2f", rwalk->rule.rrdds.limitval); if (rwalk->flags & RRDDSCHK_INTVL) { if (rwalk->flags & RRDDSCHK_LT) printf(" <%.2f", rwalk->rule.rrdds.limitval2); if (rwalk->flags & RRDDSCHK_LE) printf(" <=%.2f", rwalk->rule.rrdds.limitval2); } else { if (rwalk->flags & RRDDSCHK_LT) printf(" <%.2f", rwalk->rule.rrdds.limitval); if (rwalk->flags & RRDDSCHK_LE) printf(" <=%.2f", rwalk->rule.rrdds.limitval); } printf(" color=%s", colorname(rwalk->rule.rrdds.color)); break; case C_MQ_QUEUE: if (!rwalk->rule.mqqueue.qmgrname || !rwalk->rule.mqqueue.qname) break; printf("MQ_QUEUE %s:%s", rwalk->rule.mqqueue.qmgrname->pattern, rwalk->rule.mqqueue.qname->pattern); if (rwalk->rule.mqqueue.warnlen != -1) printf(" depth-warn=%d", rwalk->rule.mqqueue.warnlen); if (rwalk->rule.mqqueue.critlen != -1) printf(" depth-critical=%d", rwalk->rule.mqqueue.critlen); if (rwalk->rule.mqqueue.warnage != -1) printf(" age-warn=%d", rwalk->rule.mqqueue.warnage); if (rwalk->rule.mqqueue.critage != -1) printf(" age-critical=%d", rwalk->rule.mqqueue.critage); break; case C_MQ_CHANNEL: if (!rwalk->rule.mqchannel.qmgrname || !rwalk->rule.mqchannel.chnname) break; printf("MQ_CHANNEL %s:%s",rwalk->rule.mqchannel.qmgrname->pattern , rwalk->rule.mqchannel.chnname->pattern); if (rwalk->rule.mqchannel.warnstates) printf(" warning=%s", rwalk->rule.mqchannel.warnstates->pattern); if (rwalk->rule.mqchannel.alertstates) printf(" alert=%s", rwalk->rule.mqchannel.alertstates->pattern); break; } if (rwalk->chkflags & CHK_TRACKIT) { printf(" TRACK"); if (rwalk->rrdidstr) printf("=%s", rwalk->rrdidstr); } if (rwalk->chkflags & CHK_OPTIONAL) printf(" OPTIONAL"); if (rwalk->timespec) printf(" TIME=%s", rwalk->timespec); if (rwalk->extimespec) printf(" EXTIME=%s", rwalk->extimespec); if (rwalk->hostexp) printf(" HOST=%s", rwalk->hostexp->pattern); if (rwalk->exhostexp) printf(" EXHOST=%s", rwalk->exhostexp->pattern); if (rwalk->dgexp) printf(" DISPLAYGROUP=%s", rwalk->dgexp->pattern); if (rwalk->exdgexp) printf(" EXDISPLAYGROUP=%s", rwalk->exdgexp->pattern); if (rwalk->pageexp) printf(" PAGE=%s", rwalk->pageexp->pattern); if (rwalk->expageexp) printf(" EXPAGE=%s", rwalk->expageexp->pattern); if (rwalk->classexp) printf(" CLASS=%s", rwalk->classexp->pattern); if (rwalk->exclassexp) printf(" EXCLASS=%s", rwalk->exclassexp->pattern); if (rwalk->statustext) printf(" TEXT=%s", rwalk->statustext); printf(" (line: %d)\n", rwalk->cfid); } } static c_rule_t *getrule(char *hostname, char *pagename, char *classname, void *hinfo, ruletype_t ruletype) { static ruleset_t *rwalk = NULL; char *holidayset; if (hostname || pagename) { rwalk = ruleset(hostname, pagename, classname); } else { if (rwalk) rwalk = rwalk->next; } holidayset = (hinfo ? xmh_item(hinfo, XMH_HOLIDAYS) : NULL); for (; (rwalk); rwalk = rwalk->next) { if (rwalk->rule->ruletype != ruletype) continue; if (rwalk->rule->timespec && !timematch(holidayset, rwalk->rule->timespec)) continue; if (rwalk->rule->extimespec && timematch(holidayset, rwalk->rule->extimespec)) continue; /* If we get here, then we have something that matches */ return rwalk->rule; } return NULL; } int get_cpu_thresholds(void *hinfo, char *classname, float *loadyellow, float *loadred, int *recentlimit, int *ancientlimit, int *uptimecolor, int *maxclockdiff, int *clockdiffcolor) { int result = 0; char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *loadyellow = 5.0; *loadred = 10.0; *uptimecolor = *clockdiffcolor = COL_YELLOW; rule = getrule(hostname, pagename, classname, hinfo, C_LOAD); if (rule) { *loadyellow = rule->rule.load.warnlevel; *loadred = rule->rule.load.paniclevel; result = rule->cfid; } *recentlimit = 3600; *ancientlimit = -1; rule = getrule(hostname, pagename, classname, hinfo, C_UPTIME); if (rule) { *recentlimit = rule->rule.uptime.recentlimit; *ancientlimit = rule->rule.uptime.ancientlimit; *uptimecolor = rule->rule.uptime.color; result = rule->cfid; } *maxclockdiff = -1; rule = getrule(hostname, pagename, classname, hinfo, C_CLOCK); if (rule) { *maxclockdiff = rule->rule.clock.maxdiff; *clockdiffcolor = rule->rule.clock.color; } return result; } int get_disk_thresholds(void *hinfo, char *classname, char *fsname, long *warnlevel, long *paniclevel, int *abswarn, int *abspanic, int *ignored, char **group) { char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *warnlevel = 90; *paniclevel = 95; *abswarn = 0; *abspanic = 0; *ignored = 0; *group = NULL; rule = getrule(hostname, pagename, classname, hinfo, C_DISK); while (rule && (!rule->rule.disk.fsexp || !namematch(fsname, rule->rule.disk.fsexp->pattern, rule->rule.disk.fsexp->exp))) { rule = getrule(NULL, NULL, NULL, hinfo, C_DISK); } if (rule) { *warnlevel = rule->rule.disk.warnlevel; *abswarn = rule->rule.disk.abswarn; *paniclevel = rule->rule.disk.paniclevel; *abspanic = rule->rule.disk.abspanic; *ignored = rule->rule.disk.ignored; *group = rule->groups; return rule->cfid; } return 0; } int get_inode_thresholds(void *hinfo, char *classname, char *fsname, long *warnlevel, long *paniclevel, int *abswarn, int *abspanic, int *ignored, char **group) { char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); *warnlevel = 70; *paniclevel = 90; *abswarn = 0; *abspanic = 0; *ignored = 0; *group = NULL; rule = getrule(hostname, pagename, classname, hinfo, C_INODE); while (rule && (!rule->rule.inode.fsexp || !namematch(fsname, rule->rule.inode.fsexp->pattern, rule->rule.inode.fsexp->exp))) { rule = getrule(NULL, NULL, NULL, hinfo, C_INODE); } if (rule) { *warnlevel = rule->rule.inode.warnlevel; *abswarn = rule->rule.inode.abswarn; *paniclevel = rule->rule.inode.paniclevel; *abspanic = rule->rule.inode.abspanic; *ignored = rule->rule.inode.ignored; *group = rule->groups; return rule->cfid; } return 0; } void get_cics_thresholds(void *hinfo, char *classname, char *appid, int *dsayel, int *dsared, int *edsayel, int *edsared) { char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); *dsayel = 90; *dsared = 95; *edsayel = 90; *edsared = 95; /* Get thresholds for CICS DSA */ rule = getrule(hostname, pagename, classname, hinfo, C_CICS); /* This is sort of cheating, because the while statement that follows should catch it but it doesn't. So if there is a way to solve the problem I welcome some tips... */ if (!rule) { return; } while (rule && (!rule->rule.cics.applid || !namematch(appid, rule->rule.cics.applid->pattern, rule->rule.cics.applid->exp))) { rule = getrule(NULL, NULL, NULL, hinfo, C_CICS); } if (rule) { *dsayel = rule->rule.cics.dsawarnlevel; *dsared = rule->rule.cics.dsapaniclevel; *edsayel = rule->rule.cics.edsawarnlevel; *edsared = rule->rule.cics.edsapaniclevel; } } void get_zvsevsize_thresholds(void *hinfo, char *classname, int *usedyel, int *usedred) { char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); *usedyel = 90; *usedred = 95; /* Get thresholds for z/VSE System Memory */ rule = getrule(hostname, pagename, classname, hinfo, C_MEM_VSIZE); if (rule) { *usedyel = rule->rule.zvse_vsize.warnlevel; *usedred = rule->rule.zvse_vsize.paniclevel; } } void get_zvsegetvis_thresholds(void *hinfo, char *classname, char *pid, int *gv24yel, int *gv24red, int *gvanyyel, int *gvanyred) { char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); *gv24yel = 90; *gv24red = 95; *gvanyyel = 90; *gvanyred = 95; /* Get thresholds for z/VSE Partition Getvis */ rule = getrule(hostname, pagename, classname, hinfo, C_MEM_GETVIS); /* This is sort of cheating, because the while statement that follows should catch it but it doesn't. So if there is a way to solve the problem I welcome some tips... */ if (!rule) { return; } while (rule && (!rule->rule.zvse_getvis.partid || !namematch(pid, rule->rule.zvse_getvis.partid->pattern, rule->rule.zvse_getvis.partid->exp))) { rule = getrule(NULL, NULL, NULL, hinfo, C_MEM_GETVIS); } if (rule) { *gv24yel = rule->rule.zvse_getvis.warnlevel; *gv24red = rule->rule.zvse_getvis.paniclevel; *gvanyyel = rule->rule.zvse_getvis.anywarnlevel; *gvanyred = rule->rule.zvse_getvis.anypaniclevel; } } void get_memory_thresholds(void *hinfo, char *classname, int *physyellow, int *physred, int *swapyellow, int *swapred, int *actyellow, int *actred) { char *hostname, *pagename; c_rule_t *rule; int gotphys = 0, gotswap = 0, gotact = 0; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *physyellow = 100; *physred = 101; *swapyellow = 50; *swapred = 80; *actyellow = 90; *actred = 97; rule = getrule(hostname, pagename, classname, hinfo, C_MEM); while (rule) { switch (rule->rule.mem.memtype) { case C_MEM_PHYS: if (!gotphys) { *physyellow = rule->rule.mem.warnlevel; *physred = rule->rule.mem.paniclevel; gotphys = 1; } break; case C_MEM_ACT: if (!gotact) { *actyellow = rule->rule.mem.warnlevel; *actred = rule->rule.mem.paniclevel; gotact = 1; } break; case C_MEM_SWAP: if (!gotswap) { *swapyellow = rule->rule.mem.warnlevel; *swapred = rule->rule.mem.paniclevel; gotswap = 1; } break; } rule = getrule(NULL, NULL, NULL, hinfo, C_MEM); } } void get_zos_memory_thresholds(void *hinfo, char *classname, int *csayellow, int *csared, int *ecsayellow, int *ecsared, int *sqayellow, int *sqared, int *esqayellow, int *esqared) { char *hostname, *pagename; c_rule_t *rule; int gotcsa = 0, gotecsa = 0, gotsqa = 0, gotesqa = 0; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *csayellow = 90; *csared = 95; *ecsayellow = 90; *ecsared = 95; *sqayellow = 90; *sqared = 95; *esqayellow = 90; *esqared = 95; rule = getrule(hostname, pagename, classname, hinfo, C_MEM); while (rule) { switch (rule->rule.zos_mem.zos_memtype) { case C_MEM_CSA: if (!gotcsa) { *csayellow = rule->rule.zos_mem.warnlevel; *csared = rule->rule.zos_mem.paniclevel; gotcsa = 1; } break; case C_MEM_ECSA: if (!gotecsa) { *ecsayellow = rule->rule.zos_mem.warnlevel; *ecsared = rule->rule.zos_mem.paniclevel; gotecsa = 1; } break; case C_MEM_SQA: if (!gotsqa) { *sqayellow = rule->rule.zos_mem.warnlevel; *sqared = rule->rule.zos_mem.paniclevel; gotsqa = 1; } break; case C_MEM_ESQA: if (!gotesqa) { *esqayellow = rule->rule.zos_mem.warnlevel; *esqared = rule->rule.zos_mem.paniclevel; gotesqa = 1; } break; } rule = getrule(NULL, NULL, NULL, hinfo, C_MEM); } } /* This routine doubles to get threshold values for z/OS Maxuser and z/VSE Nparts. */ void get_asid_thresholds(void *hinfo, char *classname, int *maxyellow, int *maxred) { int gotmaxuser = 0, gotnparts = 0; char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *maxyellow = 101; *maxred = 101; rule = getrule(hostname, pagename, classname, hinfo, C_ASID); while (rule) { switch (rule->rule.asid.asidtype) { case C_ASID_MAXUSER: if (!gotmaxuser) { *maxyellow = rule->rule.asid.warnlevel; *maxred = rule->rule.asid.paniclevel; gotmaxuser = 1; } break; case C_ASID_NPARTS: if (!gotnparts) { *maxyellow = rule->rule.asid.warnlevel; *maxred = rule->rule.asid.paniclevel; gotnparts = 1; } break; } rule = getrule(NULL, NULL, NULL, hinfo, C_ASID); } } int get_paging_thresholds(void *hinfo, char *classname, int *pagingyellow, int *pagingred) { int result = 0; char *hostname, *pagename; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); *pagingyellow = 5; *pagingred = 10; rule = getrule(hostname, pagename, classname, hinfo, C_PAGING); if (rule) { *pagingyellow = rule->rule.paging.warnlevel; *pagingred = rule->rule.paging.paniclevel; result = rule->cfid; } return result; } int get_mibval_thresholds(void *hinfo, char *classname, char *mibname, char *keyname, char *valname, long *minval, long *maxval, void **matchexp, int *color, char **group) { static void * mibnametree; static int have_mibnametree = 0; char *hostname, *pagename, *mibkeyval_id; c_rule_t *rule; xtreePos_t namhandle, valdefhandle; void * valdeftree; if (!have_mibnametree) { mibnametree = xtreeNew(strcasecmp); have_mibnametree = 1; } hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_PAGEPATH); /* Any potential rules at all ? */ rule = getrule(hostname, pagename, classname, hinfo, C_MIBVAL); if (!rule) return -1; *minval = LONG_MIN; *maxval = LONG_MAX; *matchexp = NULL; *color = COL_GREEN; *group = NULL; /* * Configuration rules are indexed by three items: * - the MIB Name * - the MIB Key * - the Value Name * * The MIB- and Value-names are static, so we combine these into * a single key which is referenced directly in the configuration. * This is the pattern listed as the first MIB criteria in the config, * stored in the "mibvalexp" field. * For the MIB Keys we want to use a regex (so the config can refer to * all "eth.*" interfaces), so when searching for a rule we must walk * the list of potential rules for this MIB+Value name, and match the * actual key value against the pattern. * * So all in all rules are keyed with the MIB+Key+Name strings as * a unique key. Hence, to speed things up we gradually build a tree * with this key, which points directly to the rule for this item. * This is the "valdeftree" tree. * * TODO: A further optimization would be to somehow keep * track of how many single MIB variables have a configuration rule, * to avoid scanning for a configuration for variables when all config * items have been used in a message. I cannot tell right away if this * is possible - perhaps by counting the number of configuration cache * hits while processing a message, and for the next message from the * same source then only process data until this count has been done? * * Finally, for optimising memory usage, the MIB+Key+Name strings * are not duplicated for each key; instead we have a separate token- * tree (mibnametree) which holds these. */ /* Setup the key and find/insert it into the mibnametree */ mibkeyval_id = (char *)malloc(strlen(mibname) + (keyname ? strlen(keyname) : 0) + strlen(valname) + 3); sprintf(mibkeyval_id, "%s!%s!%s", mibname, (keyname ? keyname : ""), valname); namhandle = xtreeFind(mibnametree, mibkeyval_id); if (namhandle == xtreeEnd(mibnametree)) { xtreeAdd(mibnametree, mibkeyval_id, mibkeyval_id); } else { xfree(mibkeyval_id); /* Discard our copy - we now use the tree value */ mibkeyval_id = (char *)xtreeData(mibnametree, namhandle); } /* Create the rule tree (if it does not exist); look up the ruleset */ if (!rule->rule.mibval.havetree) { rule->rule.mibval.havetree = 1; valdeftree = rule->rule.mibval.valdeftree = xtreeNew(strcasecmp); valdefhandle = xtreeEnd(rule->rule.mibval.valdeftree); } else { valdeftree = rule->rule.mibval.valdeftree; valdefhandle = xtreeFind(valdeftree, mibkeyval_id); } if (valdefhandle == xtreeEnd(valdeftree)) { /* * Ruleset not in the tree. * Scan the configuration set for a rule matching this * MIB+Value name, and where the keyname matches. * Then insert the result into the tree (even if there is no * rule matching at all - we also cache the negative lookups! */ int found = 0; char *mibval_id = (char *)malloc(strlen(mibname) + strlen(valname) + 2); sprintf(mibval_id, "%s:%s", mibname, valname); while (rule && !found) { found = (rule->rule.mibval.mibvalexp && namematch(mibval_id, rule->rule.mibval.mibvalexp->pattern, rule->rule.mibval.mibvalexp->exp)); if (found && keyname && rule->rule.mibval.keyexp) found = namematch(keyname, rule->rule.mibval.keyexp->pattern, rule->rule.mibval.keyexp->exp); if (!found) rule = getrule(NULL, NULL, NULL, hinfo, C_MIBVAL); } xtreeAdd(valdeftree, mibkeyval_id, rule); xfree(mibval_id); } else { /* Found the rule */ rule = (c_rule_t *)xtreeData(valdeftree, valdefhandle); } if (rule) { *color = rule->rule.mibval.color; *group = rule->groups; if (rule->flags & MIBCHK_MINVALUE) *minval = rule->rule.mibval.minval; if (rule->flags & MIBCHK_MAXVALUE) *maxval = rule->rule.mibval.maxval; if (rule->flags & MIBCHK_MATCH) *matchexp = rule->rule.mibval.matchexp; } return (rule ? rule->cfid : 0); } int check_mibvals(void *hinfo, char *classname, char *mibname, char *keyname, char *mibdata, strbuffer_t *summarybuf, int *anyrules) { char *bol, *eoln, *dnam, *dval, *delimp, delim; long minval, maxval, actval; void *matchexp; int rulecolor, color = COL_GREEN; char msgline[MAX_LINE_LEN]; char *group; /* * Scan a single section of MIB data - without the [key] line - * and check all values against the configured limits. */ *anyrules = 1; bol = mibdata; while (bol && *anyrules) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; dnam = bol + strspn(bol, " \t"); delimp = dnam + strcspn(dnam, " ="); delim = *delimp; *delimp = '\0'; dval = delimp + 1; dval += strspn(dval, " ="); actval = atol(dval); switch (get_mibval_thresholds(hinfo, classname, mibname, keyname, dnam, &minval, &maxval, &matchexp, &rulecolor, &group)) { case -1: /* This means: No rules at all for this host. So just drop all further processing */ *anyrules = 0; break; case 0: /* No rules for this key/value, but there might be for others */ break; default: if (actval < minval) { if (keyname) sprintf(msgline, "&%s %s:%s %ld (minimum: %ld)\n", colorname(rulecolor), keyname, dnam, actval, minval); else sprintf(msgline, "&%s %s %ld (minimum: %ld)\n", colorname(rulecolor), dnam, actval, minval); addtobuffer(summarybuf, msgline); if (rulecolor > color) color = rulecolor; if (group) addalertgroup(group); } if (actval > maxval) { if (keyname) sprintf(msgline, "&%s %s:%s %ld (maximum: %ld)\n", colorname(rulecolor), keyname, dnam, actval, maxval); else sprintf(msgline, "&%s %s %ld (maximum: %ld)\n", colorname(rulecolor), dnam, actval, maxval); addtobuffer(summarybuf, msgline); if (rulecolor > color) color = rulecolor; if (group) addalertgroup(group); } if (matchexp) { if (!namematch(dval, ((exprlist_t *)matchexp)->pattern, ((exprlist_t *)matchexp)->exp)) { if (rulecolor > color) color = rulecolor; if (group) addalertgroup(group); if (keyname) sprintf(msgline, "&%s %s:%s %s (expected: %s)\n", colorname(rulecolor), keyname, dnam, dval, ((exprlist_t *)matchexp)->pattern); else sprintf(msgline, "&%s %s %s (expected: %s)\n", colorname(rulecolor), dnam, dval, ((exprlist_t *)matchexp)->pattern); } else { if (keyname) sprintf(msgline, "&green %s:%s %s\n", keyname, dnam, dval); else sprintf(msgline, "&green %s %s\n", dnam, dval); } addtobuffer(summarybuf, msgline); } break; } *delimp = delim; if (eoln) { *eoln = '\n'; bol = eoln + 1; } else { bol = NULL; } } return color; } int scan_log(void *hinfo, char *classname, char *logname, char *logdata, char *section, strbuffer_t *summarybuf) { int result = COL_GREEN; char *hostname, *pagename; c_rule_t *rule; int nofile = 0; char *boln, *eoln; char msgline[PATH_MAX]; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); nofile = (strncmp(logdata, "Cannot open logfile ", 20) == 0); for (rule = getrule(hostname, pagename, classname, hinfo, C_LOG); (rule); rule = getrule(NULL, NULL, NULL, hinfo, C_LOG)) { int anylines = 0; /* First, check if the filename matches */ if (!rule->rule.log.logfile || !namematch(logname, rule->rule.log.logfile->pattern, rule->rule.log.logfile->exp)) continue; if (nofile) { if (!(rule->chkflags & CHK_OPTIONAL)) { if (COL_YELLOW > result) result = COL_YELLOW; addalertgroup(rule->groups); addtobuffer(summarybuf, "&yellow Logfile not accessible \n"); } continue; } /* Next, check for a match anywhere in the data*/ if (!(rule->rule.log.matchexp && patternmatch(logdata, rule->rule.log.matchexp->pattern, rule->rule.log.matchexp->exp))) continue; /* Some data in there matches what we want. Look at each line. */ boln = logdata; while (boln) { eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; if (patternmatch(boln, rule->rule.log.matchone->pattern, rule->rule.log.matchone->exp)) { dbgprintf("Line '%s' matches\n", boln); /* It matches. But maybe we'll ignore it ? */ if (rule->rule.log.ignoreexp && patternmatch(boln, rule->rule.log.ignoreexp->pattern, rule->rule.log.ignoreexp->exp)) { /* Ignore it */ } else { /* We wants it ... */ dbgprintf("FOUND match in line '%s'\n", boln); anylines++; sprintf(msgline, "&%s ", colorname(rule->rule.log.color)); addtobuffer(summarybuf, msgline); addtobuffer(summarybuf, prehtmlquoted(boln)); addtobuffer(summarybuf, "\n"); } } if (eoln) { *eoln = '\n'; boln = eoln+1; } else boln = NULL; } /* We have a match */ if (anylines) { dbgprintf("Log rule at line %d matched\n", rule->cfid); if (rule->rule.log.color != COL_GREEN) addalertgroup(rule->groups); if (rule->rule.log.color > result) result = rule->rule.log.color; } } return result; } int check_file(void *hinfo, char *classname, char *filename, char *filedata, char *section, strbuffer_t *summarybuf, off_t *filesize, char **id, int *trackit, int *anyrules) { int result = COL_GREEN; char *hostname, *pagename; c_rule_t *rwalk; char *boln, *eoln; char msgline[PATH_MAX]; int exists = 1, ftype = 0, islink = 0; off_t fsize = 0; unsigned int fmode = 0, linkcount = 0; int ownerid = -1, groupid = -1; char *ownerstr = NULL, *groupstr = NULL; unsigned int ctime = 0, mtime = 0, atime = 0, clock = 0; unsigned int ctimedif, mtimedif, atimedif; char *md5hash = NULL, *sha1hash = NULL, *sha256hash = NULL, *sha512hash = NULL, *sha224hash = NULL, *sha384hash = NULL, *rmd160hash = NULL; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *trackit = *anyrules = 0; boln = filedata; while (boln && *boln) { eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; if (strncmp(boln, "ERROR:", 6) == 0) { exists = 0; } else if (strncmp(boln, "type:", 5) == 0) { char *tstr; tstr = strchr(boln, '('); if (tstr) { if (strncmp(tstr, "(file", 5) == 0) ftype = S_IFREG; else if (strncmp(tstr, "(directory", 10) == 0) ftype = S_IFDIR; else if (strncmp(tstr, "(char-device", 12) == 0) ftype = S_IFCHR; else if (strncmp(tstr, "(block-device", 13) == 0) ftype = S_IFBLK; else if (strncmp(tstr, "(FIFO", 5) == 0) ftype = S_IFIFO; else if (strncmp(tstr, "(socket", 7) == 0) ftype = S_IFSOCK; else if (strstr(tstr, ", symlink -> ") == 0) islink = 1; } } else if (strncmp(boln, "mode:", 5) == 0) { fmode = strtol(boln+5, NULL, 8); } else if (strncmp(boln, "linkcount:", 10) == 0) { linkcount = atoi(boln+6); } else if (strncmp(boln, "owner:", 6) == 0) { ownerid = atoi(boln+6); ownerstr = strchr(boln, '('); if (ownerstr) { char *estr; ownerstr++; estr = strchr(ownerstr, ')'); if (estr) *estr = '\0'; } } else if (strncmp(boln, "group:", 6) == 0) { groupid = atoi(boln+6); groupstr = strchr(boln, '('); if (groupstr) { char *estr; groupstr++; estr = strchr(groupstr, ')'); if (estr) *estr = '\0'; } } else if (strncmp(boln, "size:", 5) == 0) { fsize = filesize_value(boln+5); } else if (strncmp(boln, "clock:", 6) == 0) { clock = atoi(boln+6); } else if (strncmp(boln, "atime:", 6) == 0) { atime = atoi(boln+6); } else if (strncmp(boln, "ctime:", 6) == 0) { ctime = atoi(boln+6); } else if (strncmp(boln, "mtime:", 6) == 0) { mtime = atoi(boln+6); } else if (strncmp(boln, "md5:", 4) == 0) { md5hash = boln+4; } else if (strncmp(boln, "sha1:", 5) == 0) { sha1hash = boln+5; } else if (strncmp(boln, "sha256:", 7) == 0) { sha256hash = boln+7; } else if (strncmp(boln, "sha512:", 7) == 0) { sha512hash = boln+7; } else if (strncmp(boln, "sha224:", 7) == 0) { sha224hash = boln+7; } else if (strncmp(boln, "sha384:", 7) == 0) { sha384hash = boln+7; } else if (strncmp(boln, "rmd160:", 7) == 0) { rmd160hash = boln+7; } if (eoln) { boln = eoln+1; } else boln = NULL; } *filesize = fsize; if (clock == 0) clock = getcurrenttime(NULL); ctimedif = clock - ctime; atimedif = clock - atime; mtimedif = clock - mtime; for (rwalk = getrule(hostname, pagename, classname, hinfo, C_FILE); (rwalk); rwalk = getrule(NULL, NULL, NULL, hinfo, C_FILE)) { int rulecolor = COL_GREEN; /* First, check if the filename matches */ if (!rwalk->rule.fcheck.filename || !namematch(filename, rwalk->rule.fcheck.filename->pattern, rwalk->rule.fcheck.filename->exp)) continue; *anyrules = 1; if (!exists) { if (rwalk->chkflags & CHK_OPTIONAL) goto nextcheck; if (!(rwalk->flags & FCHK_NOEXIST)) { /* Required file does not exist */ rulecolor = rwalk->rule.fcheck.color; addtobuffer(summarybuf, "File is missing\n"); } goto nextcheck; } if (rwalk->flags & FCHK_NOEXIST) { /* File exists, but it shouldn't */ rulecolor = rwalk->rule.fcheck.color; addtobuffer(summarybuf, "File exists\n"); goto nextcheck; } if (rwalk->flags & FCHK_TYPE) { if ( ((rwalk->rule.fcheck.ftype == S_IFLNK) && !islink) || (rwalk->rule.fcheck.ftype != ftype) ) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is a %s - should be %s\n", ftypestr(ftype), ftypestr(rwalk->rule.fcheck.ftype)); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MODE) { if (rwalk->rule.fcheck.fmode != fmode) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is mode %03o - should be %03o\n", fmode, rwalk->rule.fcheck.fmode); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MINSIZE) { if (fsize < rwalk->rule.fcheck.minsize) { rulecolor = rwalk->rule.fcheck.color; #ifdef _LARGEFILE_SOURCE sprintf(msgline, "File has size %lld - should be >%lld\n", (long long int)fsize, (long long int)rwalk->rule.fcheck.minsize); #else sprintf(msgline, "File has size %ld - should be >%ld\n", (long int)fsize, (long int)rwalk->rule.fcheck.minsize); #endif addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MAXSIZE) { if (fsize > rwalk->rule.fcheck.maxsize) { rulecolor = rwalk->rule.fcheck.color; #ifdef _LARGEFILE_SOURCE sprintf(msgline, "File has size %lld - should be <%lld\n", (long long int)fsize, (long long int)rwalk->rule.fcheck.maxsize); #else sprintf(msgline, "File has size %ld - should be <%ld\n", (long int)fsize, (long int)rwalk->rule.fcheck.maxsize); #endif addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_EQLSIZE) { if (fsize != rwalk->rule.fcheck.eqlsize) { rulecolor = rwalk->rule.fcheck.color; #ifdef _LARGEFILE_SOURCE sprintf(msgline, "File has size %lld - should be %lld\n", (long long int)fsize, (long long int)rwalk->rule.fcheck.eqlsize); #else sprintf(msgline, "File has size %ld - should be %ld\n", (long int)fsize, (long int)rwalk->rule.fcheck.eqlsize); #endif addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MINLINKS) { if (linkcount < rwalk->rule.fcheck.minlinks) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has linkcount %u - should be >%u\n", linkcount, rwalk->rule.fcheck.minlinks); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MAXLINKS) { if (linkcount > rwalk->rule.fcheck.maxlinks) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has linkcount %u - should be <%u\n", linkcount, rwalk->rule.fcheck.maxlinks); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_OWNERID) { if (ownerid != rwalk->rule.fcheck.ownerid) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is owned by user %u - should be %u\n", ownerid, rwalk->rule.fcheck.ownerid); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_OWNERSTR) { if (!ownerstr) ownerstr = "(No owner data)"; if (strcmp(ownerstr, rwalk->rule.fcheck.ownerstr) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is owned by user %s - should be %s\n", ownerstr, rwalk->rule.fcheck.ownerstr); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_GROUPID) { if (groupid != rwalk->rule.fcheck.groupid) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is owned by group %u - should be %u\n", groupid, rwalk->rule.fcheck.groupid); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_GROUPSTR) { if (!groupstr) groupstr = "(No group data)"; if (strcmp(groupstr, rwalk->rule.fcheck.groupstr) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File is owned by group %s - should be %s\n", groupstr, rwalk->rule.fcheck.groupstr); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_CTIMEMIN) { if (ctimedif < rwalk->rule.fcheck.minctimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File status changed %u seconds ago - should be >%u\n", ctimedif, rwalk->rule.fcheck.minctimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_CTIMEMAX) { if (ctimedif > rwalk->rule.fcheck.maxctimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File status changed %u seconds ago - should be <%u\n", ctimedif, rwalk->rule.fcheck.maxctimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MTIMEMIN) { if (mtimedif < rwalk->rule.fcheck.minmtimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File was modified %u seconds ago - should be >%u\n", mtimedif, rwalk->rule.fcheck.minmtimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MTIMEMAX) { if (mtimedif > rwalk->rule.fcheck.maxmtimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File was modified %u seconds ago - should be <%u\n", mtimedif, rwalk->rule.fcheck.maxmtimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_ATIMEMIN) { if (atimedif < rwalk->rule.fcheck.minatimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File was accessed %u seconds ago - should be >%u\n", atimedif, rwalk->rule.fcheck.minatimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_ATIMEMAX) { if (atimedif > rwalk->rule.fcheck.maxatimedif) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File was accessed %u seconds ago - should be <%u\n", atimedif, rwalk->rule.fcheck.maxatimedif); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_MD5) { if (!md5hash) md5hash = "(No MD5 data)"; if (strcmp(md5hash, rwalk->rule.fcheck.md5hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has MD5 hash %s - should be %s\n", md5hash, rwalk->rule.fcheck.md5hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_SHA1) { if (!sha1hash) sha1hash = "(No SHA1 data)"; if (strcmp(sha1hash, rwalk->rule.fcheck.sha1hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has SHA1 hash %s - should be %s\n", sha1hash, rwalk->rule.fcheck.sha1hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_SHA256) { if (!sha256hash) sha256hash = "(No SHA256 data)"; if (strcmp(sha256hash, rwalk->rule.fcheck.sha256hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has SHA256 hash %s - should be %s\n", sha256hash, rwalk->rule.fcheck.sha256hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_SHA512) { if (!sha512hash) sha512hash = "(No SHA256 data)"; if (strcmp(sha512hash, rwalk->rule.fcheck.sha512hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has SHA512 hash %s - should be %s\n", sha512hash, rwalk->rule.fcheck.sha512hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_SHA224) { if (!sha224hash) sha224hash = "(No SHA224 data)"; if (strcmp(sha224hash, rwalk->rule.fcheck.sha224hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has SHA224 hash %s - should be %s\n", sha224hash, rwalk->rule.fcheck.sha224hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_SHA384) { if (!sha384hash) sha384hash = "(No SHA384 data)"; if (strcmp(sha384hash, rwalk->rule.fcheck.sha384hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has SHA384 hash %s - should be %s\n", sha384hash, rwalk->rule.fcheck.sha384hash); addtobuffer(summarybuf, msgline); } } if (rwalk->flags & FCHK_RMD160) { if (!rmd160hash) rmd160hash = "(No RMD160 data)"; if (strcmp(rmd160hash, rwalk->rule.fcheck.rmd160hash) != 0) { rulecolor = rwalk->rule.fcheck.color; sprintf(msgline, "File has RMD160 hash %s - should be %s\n", rmd160hash, rwalk->rule.fcheck.rmd160hash); addtobuffer(summarybuf, msgline); } } if (rwalk->chkflags & CHK_TRACKIT) { *trackit = (trackit || (ftype == S_IFREG)); *id = rwalk->rrdidstr; } nextcheck: if (rulecolor != COL_GREEN) addalertgroup(rwalk->groups); if (rulecolor > result) result = rulecolor; } return result; } int check_dir(void *hinfo, char *classname, char *filename, char *filedata, char *section, strbuffer_t *summarybuf, unsigned long *dirsize, char **id, int *trackit) { int result = COL_GREEN; int gotsize = 0; char *hostname, *pagename; c_rule_t *rwalk; char *boln, *eoln; char msgline[PATH_MAX]; unsigned long dsize = 0; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); *trackit = 0; boln = filedata; while (boln && *boln) { unsigned long sz; char *p; eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; /* * We need to check the directory name on each line, to * find the line that gives us the exact directory we want. * NB: Assumes the output is in the form * 12345 /foo/bar/baz */ sz = atol(boln); p = boln + strcspn(boln, " \t"); if (isspace((int)*p)) p += strspn(p, " \t"); if (strcmp(p, filename) == 0) { gotsize = 1; dsize = sz; } if (eoln) { *eoln = '\0'; boln = eoln+1; } else boln = NULL; } *dirsize = dsize; /* Got the data? */ if (!gotsize) { sprintf(msgline, "Could not determine size of directory %s\n", filename); addtobuffer(summarybuf, msgline); return COL_YELLOW; } for (rwalk = getrule(hostname, pagename, classname, hinfo, C_DIR); (rwalk); rwalk = getrule(NULL, NULL, NULL, hinfo, C_DIR)) { int rulecolor = COL_GREEN; /* First, check if the filename matches */ if (!rwalk->rule.fcheck.filename || !namematch(filename, rwalk->rule.fcheck.filename->pattern, rwalk->rule.fcheck.filename->exp)) continue; if (rwalk->flags & FCHK_MAXSIZE) { if (dsize > rwalk->rule.dcheck.maxsize) { rulecolor = rwalk->rule.dcheck.color; sprintf(msgline, "Directory has size %lu - should be <%lu\n", dsize, rwalk->rule.dcheck.maxsize); addtobuffer(summarybuf, msgline); } } else if (rwalk->flags & FCHK_MINSIZE) { if (dsize < rwalk->rule.dcheck.minsize) { rulecolor = rwalk->rule.dcheck.color; sprintf(msgline, "Directory has size %lu - should be >%lu\n", dsize, rwalk->rule.dcheck.minsize); addtobuffer(summarybuf, msgline); } } if (rwalk->chkflags & CHK_TRACKIT) { *trackit = 1; *id = rwalk->rrdidstr; } if (rulecolor != COL_GREEN) addalertgroup(rwalk->groups); if (rulecolor > result) result = rulecolor; } return result; } strbuffer_t *check_rrdds_thresholds(char *hostname, char *classname, char *pagepaths, char *rrdkey, void * valnames, char *vals) { static strbuffer_t *resbuf = NULL; char msgline[1024]; c_rule_t *rule; char *valscopy = NULL; char **vallist = NULL; xtreePos_t handle; rrdtplnames_t *tpl; double val; void *hinfo; if (!resbuf) resbuf = newstrbuffer(0); clearstrbuffer(resbuf); hinfo = hostinfo(hostname); rule = getrule(hostname, pagepaths, classname, hinfo, C_RRDDS); while (rule) { int rulematch = 0; if (strcmp(rule->rule.rrdds.column, "http") == 0) { if (!rule->rule.rrdds.rrdkey || !patternmatch(rrdkey, rule->rule.rrdds.rrdkey->pattern, rule->rule.rrdds.rrdkey->exp)) goto nextrule; } else { if (!rule->rule.rrdds.rrdkey || !namematch(rrdkey, rule->rule.rrdds.rrdkey->pattern, rule->rule.rrdds.rrdkey->exp)) goto nextrule; } handle = xtreeFind(valnames, rule->rule.rrdds.rrdds); if (handle == xtreeEnd(valnames)) goto nextrule; tpl = (rrdtplnames_t *)xtreeData(valnames, handle); /* Split the value-string into individual numbers that we can index */ if (!vallist) { char *p; int idx = 0; valscopy = strdup(vals); vallist = calloc(128, sizeof(char *)); vallist[0] = valscopy; for (p = strchr(valscopy, ':'); (p); p = strchr(p+1, ':')) { vallist[++idx] = p+1; *p = '\0'; } } if (vallist[tpl->idx] == NULL) goto nextrule; val = atof(vallist[tpl->idx]); /* Do the checks */ if (rule->flags & RRDDSCHK_INTVL) { rulematch = ( ( ((rule->flags & RRDDSCHK_GT) && (val > rule->rule.rrdds.limitval)) || ((rule->flags & RRDDSCHK_GE) && (val >= rule->rule.rrdds.limitval)) ) && ( ((rule->flags & RRDDSCHK_LT) && (val < rule->rule.rrdds.limitval2)) || ((rule->flags & RRDDSCHK_LE) && (val <= rule->rule.rrdds.limitval2)) ) ); if (!rule->statustext) { char fmt[100]; strcpy(fmt, "&N=&V ("); if (rule->flags & RRDDSCHK_GT) strcat(fmt, " > &L"); else if (rule->flags & RRDDSCHK_GE) strcat(fmt, " >= &L"); strcat(fmt, " and"); if (rule->flags & RRDDSCHK_LT) strcat(fmt, " < &U)"); else if (rule->flags & RRDDSCHK_LE) strcat(fmt, " <= &U)"); rule->statustext = strdup(fmt); } } else { rulematch = ( ((rule->flags & RRDDSCHK_GT) && (val > rule->rule.rrdds.limitval)) || ((rule->flags & RRDDSCHK_GE) && (val >= rule->rule.rrdds.limitval)) || ((rule->flags & RRDDSCHK_LT) && (val < rule->rule.rrdds.limitval)) || ((rule->flags & RRDDSCHK_LE) && (val <= rule->rule.rrdds.limitval)) ); if (!rule->statustext) { char *fmt = ""; if (rule->flags & RRDDSCHK_GT) fmt = "&N=&V (> &L)"; else if (rule->flags & RRDDSCHK_GE) fmt = "&N=&V (>= &L)"; else if (rule->flags & RRDDSCHK_LT) fmt = "&N=&V (< &L)"; else if (rule->flags & RRDDSCHK_LE) fmt = "&N=&V (<= &L)"; rule->statustext = strdup(fmt); } } if (rulematch) { char *bot, *marker; sprintf(msgline, "modify %s.%s %s rrdds ", hostname, rule->rule.rrdds.column, colorname(rule->rule.rrdds.color)); addtobuffer(resbuf, msgline); /* Format and add the status text */ bot = rule->statustext; do { marker = strchr(bot, '&'); if (marker) { *marker = '\0'; addtobuffer(resbuf, bot); *marker = '&'; switch (*(marker+1)) { case 'N': addtobuffer(resbuf, rule->rule.rrdds.rrdds); bot = marker+2; break; case 'V': addtobuffer(resbuf, vallist[tpl->idx]); bot = marker+2; break; case 'L': sprintf(msgline, "%.2f", rule->rule.rrdds.limitval); addtobuffer(resbuf, msgline); bot = marker+2; break; case 'U': sprintf(msgline, "%.2f", (rule->flags & RRDDSCHK_INTVL) ? rule->rule.rrdds.limitval2 : rule->rule.rrdds.limitval); addtobuffer(resbuf, msgline); bot = marker+2; break; default: addtobuffer(resbuf, "&"); bot = marker+1; break; } } else { addtobuffer(resbuf, bot); bot = NULL; } } while (bot); addtobuffer(resbuf, "\n\n"); } nextrule: rule = getrule(NULL, NULL, NULL, hinfo, C_RRDDS); } if (valscopy) xfree(valscopy); if (vallist) xfree(vallist); return (STRBUFLEN(resbuf) > 0) ? resbuf : NULL; } void get_mqqueue_thresholds(void *hinfo, char *classname, char *qmgrname, char *qname, int *warnlen, int *critlen, int *warnage, int *critage, char **trackit) { char *hostname, *pagepaths; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagepaths = xmh_item(hinfo, XMH_ALLPAGEPATHS); *warnlen = *critlen = *warnage = *critage = -1; *trackit = NULL; rule = getrule(hostname, pagepaths, classname, hinfo, C_MQ_QUEUE); while (rule) { if (rule->rule.mqqueue.qname && rule->rule.mqqueue.qmgrname && namematch(qname, rule->rule.mqqueue.qname->pattern, rule->rule.mqqueue.qname->exp) && namematch(qmgrname, rule->rule.mqqueue.qmgrname->pattern, rule->rule.mqqueue.qmgrname->exp)) { *warnlen = rule->rule.mqqueue.warnlen; *critlen = rule->rule.mqqueue.critlen; *warnage = rule->rule.mqqueue.warnage; *critage = rule->rule.mqqueue.critage; if (rule->chkflags & CHK_TRACKIT) *trackit = (rule->rrdidstr ? rule->rrdidstr : ""); return; } rule = getrule(NULL, NULL, NULL, hinfo, C_MQ_QUEUE); } } int get_mqchannel_params(void *hinfo, char *classname, char *qmgrname, char *chnname, char *chnstatus, int *color) { char *hostname, *pagepaths; c_rule_t *rule; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagepaths = xmh_item(hinfo, XMH_ALLPAGEPATHS); rule = getrule(hostname, pagepaths, classname, hinfo, C_MQ_CHANNEL); while (rule) { if (rule->rule.mqchannel.chnname && rule->rule.mqchannel.qmgrname && namematch(chnname, rule->rule.mqchannel.chnname->pattern, rule->rule.mqchannel.chnname->exp) && namematch(qmgrname, rule->rule.mqchannel.qmgrname->pattern, rule->rule.mqchannel.qmgrname->exp)) { if (rule->rule.mqchannel.alertstates && namematch(chnstatus, rule->rule.mqchannel.alertstates->pattern, rule->rule.mqchannel.alertstates->exp)) { *color = COL_RED; } else if (rule->rule.mqchannel.warnstates && namematch(chnstatus, rule->rule.mqchannel.warnstates->pattern, rule->rule.mqchannel.warnstates->exp)) { *color = COL_YELLOW; } else { *color = COL_GREEN; } return 1; } rule = getrule(NULL, NULL, NULL, hinfo, C_MQ_CHANNEL); } return 0; } typedef struct mon_proc_t { c_rule_t *rule; struct mon_proc_t *next; } mon_proc_t; static int clear_counts(void *hinfo, char *classname, ruletype_t ruletype, mon_proc_t **head, mon_proc_t **tail, mon_proc_t **walk) { char *hostname, *pagename; c_rule_t *rule; int count = 0; while (*head) { mon_proc_t *tmp = *head; *head = (*head)->next; xfree(tmp); } *head = *tail = *walk = NULL; hostname = xmh_item(hinfo, XMH_HOSTNAME); pagename = xmh_item(hinfo, XMH_ALLPAGEPATHS); rule = getrule(hostname, pagename, classname, hinfo, ruletype); while (rule) { mon_proc_t *newitem = (mon_proc_t *)calloc(1, sizeof(mon_proc_t)); newitem->rule = rule; newitem->next = NULL; if (*tail) { (*tail)->next = newitem; *tail = newitem; } else { *head = *tail = newitem; } count++; switch (rule->ruletype) { case C_DISK : rule->rule.disk.dcount = 0; break; case C_INODE: rule->rule.inode.icount = 0; break; case C_PROC : rule->rule.proc.pcount = 0; break; case C_PORT : rule->rule.port.pcount = 0; break; case C_SVC : rule->rule.svc.scount = 0; break; default: break; } rule = getrule(NULL, NULL, NULL, hinfo, ruletype); } *walk = *head; return count; } static void add_count(char *pname, mon_proc_t *head) { mon_proc_t *pwalk; if (!pname) return; for (pwalk = head; (pwalk); pwalk = pwalk->next) { switch (pwalk->rule->ruletype) { case C_PROC: if (!pwalk->rule->rule.proc.procexp->exp) { /* * No pattern, just see if the token in the config file is * present in the string we got from "ps". So you can setup * the config to look for "cron" and it will actually find "/usr/sbin/cron". */ if (strstr(pname, pwalk->rule->rule.proc.procexp->pattern)) pwalk->rule->rule.proc.pcount++; } else { /* * Strip the initial spaces, pipes and so forth seen if an ASCII forest was generated * This allows PCRE regexes using a '^' to remain useful. */ pname += strspn(pname, " |\\_"); if (!pname) break; if (namematch(pname, pwalk->rule->rule.proc.procexp->pattern, pwalk->rule->rule.proc.procexp->exp)) pwalk->rule->rule.proc.pcount++; } break; case C_DISK: if (!pwalk->rule->rule.disk.fsexp->exp) { if (strstr(pname, pwalk->rule->rule.disk.fsexp->pattern)) pwalk->rule->rule.disk.dcount++; } else { if (namematch(pname, pwalk->rule->rule.disk.fsexp->pattern, pwalk->rule->rule.disk.fsexp->exp)) pwalk->rule->rule.disk.dcount++; } break; case C_INODE: if (!pwalk->rule->rule.inode.fsexp->exp) { if (strstr(pname, pwalk->rule->rule.inode.fsexp->pattern)) pwalk->rule->rule.inode.icount++; } else { if (namematch(pname, pwalk->rule->rule.inode.fsexp->pattern, pwalk->rule->rule.inode.fsexp->exp)) pwalk->rule->rule.inode.icount++; } default: break; } } } static int check_expr_match(char *s, exprlist_t *inclexp, exprlist_t *exclexp) { int inclmatch = 0; int exclmatch = 0; if (inclexp) { if (namematch(s, inclexp->pattern, inclexp->exp)) inclmatch = 1; } else inclmatch = 1; /* If rejected by include spec, no need to check excludes */ if (inclmatch == 0) return 0; if (exclexp) { if (namematch(s, exclexp->pattern, exclexp->exp)) exclmatch = 1; } /* If the exclude matched, then the whole thing does not match */ if (exclmatch) return 0; /* Include- and exclude-patterns match OK, we have a match */ return 1; } static void add_count3(char *pname0, char *pname1, char *pname2 , mon_proc_t *head) { mon_proc_t *pwalk; int mymatch; if (!pname0) return; if (!pname1) return; if (!pname2) return; for (pwalk = head; (pwalk); pwalk = pwalk->next) { switch (pwalk->rule->ruletype) { case C_PORT: mymatch = 0; if (check_expr_match(pname0, pwalk->rule->rule.port.localexp, pwalk->rule->rule.port.exlocalexp)) mymatch++; if (check_expr_match(pname1, pwalk->rule->rule.port.remoteexp, pwalk->rule->rule.port.exremoteexp)) mymatch++; if (check_expr_match(pname2, pwalk->rule->rule.port.stateexp, pwalk->rule->rule.port.exstateexp)) mymatch++; if (mymatch == 3) {pwalk->rule->rule.port.pcount++;} break; case C_SVC: mymatch = 0; if (check_expr_match(pname0, pwalk->rule->rule.svc.svcexp, NULL)) { mymatch++; /* Save the actual startup-method and state for later display in the status message */ pwalk->rule->rule.svc.svcname = strdup(pname0); pwalk->rule->rule.svc.startup = strdup(pname1); pwalk->rule->rule.svc.state = strdup(pname2); /* Startupexp and stateexp are optional - if no criteria defined, then they do match */ if (!pwalk->rule->rule.svc.startupexp || check_expr_match(pname1, pwalk->rule->rule.svc.startupexp, NULL)) mymatch++; if (!pwalk->rule->rule.svc.stateexp || check_expr_match(pname2, pwalk->rule->rule.svc.stateexp, NULL)) mymatch++; } if (mymatch == 3) {pwalk->rule->rule.svc.scount++;} break; default: break; } } } static char *check_count(int *count, ruletype_t ruletype, int *lowlim, int *uplim, int *color, mon_proc_t **walk, char **id, int *trackit, char **group) { char *result = NULL; *color = COL_GREEN; *count = 0; if (*walk == NULL) return NULL; switch (ruletype) { case C_PROC: result = (*walk)->rule->statustext; if (!result) result = (*walk)->rule->rule.proc.procexp->pattern; *count = (*walk)->rule->rule.proc.pcount; *lowlim = (*walk)->rule->rule.proc.pmin; *uplim = (*walk)->rule->rule.proc.pmax; if ((*lowlim != 0) && (*count < *lowlim)) *color = (*walk)->rule->rule.proc.color; if ((*uplim != -1) && (*count > *uplim)) *color = (*walk)->rule->rule.proc.color; *trackit = ((*walk)->rule->chkflags & CHK_TRACKIT); *id = (*walk)->rule->rrdidstr; if (group) *group = (*walk)->rule->groups; break; case C_DISK: result = (*walk)->rule->rule.disk.fsexp->pattern; *count = (*walk)->rule->rule.disk.dcount; *lowlim = (*walk)->rule->rule.disk.dmin; *uplim = (*walk)->rule->rule.disk.dmax; if ((*lowlim != 0) && (*count < *lowlim)) *color = (*walk)->rule->rule.disk.color; if ((*uplim != -1) && (*count > *uplim)) *color = (*walk)->rule->rule.disk.color; if (group) *group = (*walk)->rule->groups; break; case C_INODE: result = (*walk)->rule->rule.inode.fsexp->pattern; *count = (*walk)->rule->rule.inode.icount; *lowlim = (*walk)->rule->rule.inode.imin; *uplim = (*walk)->rule->rule.inode.imax; *color = COL_GREEN; if ((*lowlim != 0) && (*count < *lowlim)) *color = (*walk)->rule->rule.inode.color; if ((*uplim != -1) && (*count > *uplim)) *color = (*walk)->rule->rule.inode.color; if (group) *group = (*walk)->rule->groups; break; case C_PORT: result = (*walk)->rule->statustext; if (!result) { int sz = 1024; char *p; if ((*walk)->rule->rule.port.localexp) sz += strlen((*walk)->rule->rule.port.localexp->pattern) + 10; if ((*walk)->rule->rule.port.exlocalexp) sz += strlen((*walk)->rule->rule.port.exlocalexp->pattern) + 10; if ((*walk)->rule->rule.port.remoteexp) sz += strlen((*walk)->rule->rule.port.remoteexp->pattern) + 10; if ((*walk)->rule->rule.port.exremoteexp) sz += strlen((*walk)->rule->rule.port.exremoteexp->pattern) + 10; if ((*walk)->rule->rule.port.stateexp) sz += strlen((*walk)->rule->rule.port.stateexp->pattern) + 10; if ((*walk)->rule->rule.port.exstateexp) sz += strlen((*walk)->rule->rule.port.exstateexp->pattern) + 10; (*walk)->rule->statustext = (char *)malloc(sz + 1); p = (*walk)->rule->statustext; if ((*walk)->rule->rule.port.localexp) p += sprintf(p, "local=%s ", (*walk)->rule->rule.port.localexp->pattern); if ((*walk)->rule->rule.port.exlocalexp) p += sprintf(p, "exlocal=%s ", (*walk)->rule->rule.port.exlocalexp->pattern); if ((*walk)->rule->rule.port.remoteexp) p += sprintf(p, "remote=%s ", (*walk)->rule->rule.port.remoteexp->pattern); if ((*walk)->rule->rule.port.exremoteexp) p += sprintf(p, "exremote=%s ", (*walk)->rule->rule.port.exremoteexp->pattern); if ((*walk)->rule->rule.port.stateexp) p += sprintf(p, "state=%s ", (*walk)->rule->rule.port.stateexp->pattern); if ((*walk)->rule->rule.port.exstateexp) p += sprintf(p, "exstate=%s ", (*walk)->rule->rule.port.exstateexp->pattern); *p = '\0'; strcat((*walk)->rule->statustext, ":"); result = (*walk)->rule->statustext; } *count = (*walk)->rule->rule.port.pcount; *lowlim = (*walk)->rule->rule.port.pmin; *uplim = (*walk)->rule->rule.port.pmax; if ((*lowlim != 0) && (*count < *lowlim)) *color = (*walk)->rule->rule.port.color; if ((*uplim != -1) && (*count > *uplim)) *color = (*walk)->rule->rule.port.color; *trackit = ((*walk)->rule->chkflags & CHK_TRACKIT); *id = (*walk)->rule->rrdidstr; if (group) *group = (*walk)->rule->groups; break; case C_SVC: /* Have to clear this each time since it contains current state */ // result = (*walk)->rule->statustext; if (!result) { int sz = 1024; char *p; /* Current state */ if ((*walk)->rule->rule.svc.svcname) sz += strlen((*walk)->rule->rule.svc.svcname) + 10; if ((*walk)->rule->rule.svc.startup) sz += strlen((*walk)->rule->rule.svc.startup) + 10; if ((*walk)->rule->rule.svc.state) sz += strlen((*walk)->rule->rule.svc.state) + 10; if ((*walk)->rule->rule.svc.startupexp) sz += strlen((*walk)->rule->rule.svc.startupexp->pattern) + 10; if ((*walk)->rule->rule.svc.stateexp) sz += strlen((*walk)->rule->rule.svc.stateexp->pattern) + 10; if ((*walk)->rule->statustext != NULL) xfree((*walk)->rule->statustext); (*walk)->rule->statustext = (char *)malloc(sz + 1); p = (*walk)->rule->statustext; if ((*walk)->rule->rule.svc.svcname) { p += sprintf(p, "%s is %s/%s", (*walk)->rule->rule.svc.svcname, ((*walk)->rule->rule.svc.state ? (*walk)->rule->rule.svc.state : "Unknown"), ((*walk)->rule->rule.svc.startup ? (*walk)->rule->rule.svc.startup : "Unknown")); } else { /* Did not find the service matching our wanted criteria */ p += sprintf(p, "%s: No matching service", (*walk)->rule->rule.svc.svcexp->pattern); } p += sprintf(p, " - want %s/%s", ((*walk)->rule->rule.svc.stateexp ? (*walk)->rule->rule.svc.stateexp->pattern : "Any"), ((*walk)->rule->rule.svc.startupexp ? (*walk)->rule->rule.svc.startupexp->pattern : "Any")); *p = '\0'; result = (*walk)->rule->statustext; /* We free the extra buffers */ if ((*walk)->rule->rule.svc.svcname) xfree((*walk)->rule->rule.svc.svcname); if ((*walk)->rule->rule.svc.state) xfree((*walk)->rule->rule.svc.state); if ((*walk)->rule->rule.svc.startup) xfree((*walk)->rule->rule.svc.startup); } *count = (*walk)->rule->rule.svc.scount; if (*count == 0) *color = (*walk)->rule->rule.svc.color; if (group) *group = (*walk)->rule->groups; break; default: break; } *walk = (*walk)->next; return result; } static mon_proc_t *phead = NULL, *ptail = NULL, *pmonwalk = NULL; static mon_proc_t *dhead = NULL, *dtail = NULL, *dmonwalk = NULL; static mon_proc_t *ihead = NULL, *itail = NULL, *imonwalk = NULL; static mon_proc_t *porthead = NULL, *porttail = NULL, *portmonwalk = NULL; static mon_proc_t *svchead = NULL, *svctail = NULL, *svcmonwalk = NULL; int clear_process_counts(void *hinfo, char *classname) { return clear_counts(hinfo, classname, C_PROC, &phead, &ptail, &pmonwalk); } int clear_disk_counts(void *hinfo, char *classname) { return clear_counts(hinfo, classname, C_DISK, &dhead, &dtail, &dmonwalk); } int clear_inode_counts(void *hinfo, char *classname) { return clear_counts(hinfo, classname, C_INODE, &ihead, &itail, &imonwalk); } int clear_port_counts(void *hinfo, char *classname) { return clear_counts(hinfo, classname, C_PORT, &porthead, &porttail, &portmonwalk); } int clear_svc_counts(void *hinfo, char *classname) { return clear_counts(hinfo, classname, C_SVC, &svchead, &svctail, &svcmonwalk); } void add_process_count(char *pname) { add_count(pname, phead); } void add_disk_count(char *dname) { add_count(dname, dhead); } void add_inode_count(char *iname) { add_count(iname, ihead); } void add_port_count(char *localstr, char *foreignstr, char *stname) { add_count3(localstr, foreignstr, stname, porthead); } void add_svc_count(char *localstr, char *foreignstr, char *stname) { add_count3(localstr, foreignstr, stname, svchead); } char *check_process_count(int *count, int *lowlim, int *uplim, int *color, char **id, int *trackit, char **group) { return check_count(count, C_PROC, lowlim, uplim, color, &pmonwalk, id, trackit, group); } char *check_disk_count(int *count, int *lowlim, int *uplim, int *color, char **group) { return check_count(count, C_DISK, lowlim, uplim, color, &dmonwalk, NULL, NULL, group); } char *check_inode_count(int *count, int *lowlim, int *uplim, int *color, char **group) { return check_count(count, C_INODE, lowlim, uplim, color, &imonwalk, NULL, NULL, group); } char *check_port_count(int *count, int *lowlim, int *uplim, int *color, char **id, int *trackit, char **group) { return check_count(count, C_PORT, lowlim, uplim, color, &portmonwalk, id, trackit, group); } char *check_svc_count(int *count, int *color, char **group) { return check_count(count, C_SVC, NULL, NULL, color, &svcmonwalk, NULL, NULL, group); } xymon-4.3.30/xymond/analysis.cfg.50000664000076400007640000006326413534041733017206 0ustar rpmbuildrpmbuild.TH ANALYSIS.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME analysis.cfg \- Configuration file for the xymond_client module .SH SYNOPSIS .B ~Xymon/server/etc/analysis.cfg .SH DESCRIPTION The analysis.cfg file controls what color is assigned to the status-messages that are generated from the Xymon client data - typically the cpu, disk, memory, procs- and msgs-columns. Color is decided on the basis of some \fBsettings\fR defined in this file; settings apply to specific hosts through a set of \fBrules\fR. Note: This file is only used on the Xymon server - it is not used by the Xymon client, so there is no need to distribute it to your client systems. .SH FILE FORMAT Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. .SH CPU STATUS COLUMN SETTINGS .sp .BR "LOAD warnlevel paniclevel" .sp If the system load exceeds "warnlevel" or "paniclevel", the "cpu" status will go yellow or red, respectively. These are decimal numbers. .sp Defaults: warnlevel=5.0, paniclevel=10.0 .sp .BR "UP bootlimit toolonglimit [color]" .sp The cpu status goes yellow/red if the system has been up for less than "bootlimit" time, or longer than "toolonglimit". The time is in minutes, or you can add h/d/w for hours/days/weeks - eg. "2h" for two hours, or "4w" for 4 weeks. .sp Defaults: bootlimit=1h, toolonglimit=\-1 (infinite), color=yellow. .sp .sp .BR "CLOCK max.offset [color]" .sp The cpu status goes yellow/red if the system clock on the client differs more than "max.offset" seconds from that of the Xymon server. Note that this is not a particularly accurate test, since it is affected by network delays between the client and the server, and the load on both systems. You should therefore not rely on this being accurate to more than +/\- 5 seconds, but it will let you catch a client clock that goes completely wrong. The default is NOT to check the system clock. .br \fBNOTE:\fR Correct operation of this test obviously requires that the system clock of the Xymon server is correct. You should therefore make sure that the Xymon server is synchronized to the real clock, e.g. by using NTP. .sp Example: Go yellow if the load average exceeds 5, and red if it exceeds 10. Also, go yellow for 10 minutes after a reboot, and after 4 weeks uptime. Finally, check that the system clock is at most 15 seconds offset from the clock of the Xymon system and go red if that is exceeded. .IP .nf LOAD 5 10 UP 10m 4w yellow CLOCK 15 red .fi .LP .SH DISK STATUS COLUMN SETTINGS .sp .BR "DISK filesystem warnlevel paniclevel" .br .BR "DISK filesystem IGNORE" .br .BR "INODE filesystem warnlevel paniclevel" .br .BR "INODE filesystem IGNORE" .sp If the utilization of "filesystem" is reported to exceed "warnlevel" or "paniclevel", the "disk" status will go yellow or red, respectively. "warnlevel" and "paniclevel" are either the percentage used, or the space available as reported by the local "df" command on the host. For the latter type of check, the "warnlevel" must be followed by the letter "U", e.g. "1024U". The special keyword "IGNORE" causes this filesystem to be ignored completely, i.e. it will not appear in the "disk" status column and it will not be tracked in a graph. This is useful for e.g. removable devices, backup-disks and similar hardware. "filesystem" is the mount-point where the filesystem is mounted, e.g. "/usr" or "/home". A filesystem-name that begins with "%" is interpreted as a Perl-compatible regular expression; e.g. "%^/oracle.*/" will match any filesystem whose mountpoint begins with "/oracle". "INODE" works identical to "DISK", but uses the count of i-nodes in the filesystem instead of the amount of disk space. .sp Defaults DISK: warnlevel=90%, paniclevel=95% .BR Defaults INODE: warnlevel=70%, paniclevel=90% .SH MEMORY STATUS COLUMN SETTINGS .sp .BR "MEMPHYS warnlevel paniclevel" .br .BR "MEMACT warnlevel paniclevel" .br .BR "MEMSWAP warnlevel paniclevel" .sp If the memory utilization exceeds the "warnlevel" or "paniclevel", the "memory" status will change to yellow or red, respectively. Note: The words "PHYS", "ACT" and "SWAP" are also recognized. .sp Example: Go yellow if more than 20% swap is used, and red if more than 40% swap is used or the actual memory utilisation exceeds 90%. Don't alert on physical memory usage. .IP .nf MEMSWAP 20 40 MEMACT 90 90 MEMPHYS 101 101 .fi .LP Defaults: .IP .nf MEMPHYS warnlevel=100 paniclevel=101 (i.e. it will never go red). MEMSWAP warnlevel=50 paniclevel=80 MEMACT warnlevel=90 paniclevel=97 .fi .LP .SH PROCS STATUS COLUMN SETTINGS .sp .BR "PROC processname minimumcount maximumcount color [TRACK=id] [TEXT=text]" .sp The "ps" listing sent by the client will be scanned for how many processes containing "processname" are running, and this is then matched against the min/max settings defined here. If the running count is outside the thresholds, the color of the "procs" status changes to "color". .sp To check for a process that must NOT be running: Set minimum and maximum to 0. .sp "processname" can be a simple string, in which case this string must show up in the "ps" listing as a command. The scanner will find a ps-listing of e.g. "/usr/sbin/cron" if you only specify "processname" as "cron". "processname" can also be a Perl-compatiable regular expression, e.g. "%java.*inst[0123]" can be used to find entries in the ps-listing for "java \-Xmx512m inst2" and "java \-Xmx256 inst3". In that case, "processname" must begin with "%" followed by the regular expression. Note that Xymon defaults to case-insensitive pattern matching; if that is not what you want, put "(?\-i)" between the "%" and the regular expression to turn this off. E.g. "%(?\-i)HTTPD" will match the word HTTPD only when it is upper-case. .br If "processname" contains whitespace (blanks or TAB), you must enclose the full string in double quotes - including the "%" if you use regular expression matching. E.g. .sp PROC "%xymond_channel \-\-channel=data.*xymond_rrd" 1 1 yellow .sp or .sp PROC "java \-DCLASSPATH=/opt/java/lib" 2 5 .sp You can have multiple "PROC" entries for the same host, all of the checks are merged into the "procs" status and the most severe check defines the color of the status. .sp The optional \fBTRACK=id\fR setting causes Xymon to track the number of processes found in an RRD file, and put this into a graph which is shown on the "procs" status display. The \fBid\fR setting is a simple text string which will be used as the legend for the graph, and also as part of the RRD filename. It is recommended that you use only letters and digits for the ID. .br Note that the process counts which are tracked are only performed once when the client does a poll cycle - i.e. the counts represent snapshots of the system state, not an average value over the client poll cycle. Therefore there may be peaks or dips in the actual process counts which will not show up in the graphs, because they happen while the Xymon client is not doing any polling. .sp The optional \fBTEXT=text\fR setting is used in the summary of the "procs" status. Normally, the summary will show the "processname" to identify the process and the related count and limits. But this may be a regular expression which is not easily recognizable, so if defined, the \fBtext\fR setting string will be used instead. This only affects the "procs" status display - it has no effect on how the rule counts or recognizes processes in the "ps" output. .sp Example: Check that "cron" is running: .br PROC cron .sp Example: Check that at least 5 "httpd" processes are running, but not more than 20: .br PROC httpd 5 20 .sp Defaults: .br mincount=1, maxcount=\-1 (unlimited), color="red". .br Note that no processes are checked by default. .SH MSGS STATUS COLUMN SETTINGS .sp .BR "LOG logfilename pattern [COLOR=color] [IGNORE=excludepattern] [OPTIONAL]" .sp The Xymon client extracts interesting lines from one or more logfiles - see the .I client-local.cfg(5) man-page for information about how to configure which logs a client should look at. .sp The \fBLOG\fR setting determine how these extracts of log entries are processed, and what warnings or alerts trigger as a result. .sp "logfilename" is the name of the logfile. Only logentries from this filename will be matched against this rule. Note that "logfilename" can be a regular expression (if prefixed with a '%' character). .sp "pattern" is a string or regular expression. If the logfile data matches "pattern", it will trigger the "msgs" column to change color. If no "color" parameter is present, the default is to go "red" when the pattern is matched. To match against a regular expression, "pattern" must begin with a '%' sign - e.g "%WARNING|NOTICE" will match any lines containing either of these two words. Note that Xymon defaults to case-insensitive pattern matching; if that is not what you want, put "(?\-i)" between the "%" and the regular expression to turn this off. E.g. "%(?\-i)WARNING" will match the word WARNING only when it is upper-case. .sp "excludepattern" is a string or regular expression that can be used to filter out any unwanted strings that happen to match "pattern". .sp The \fBOPTIONAL\fR keyword causes the check to be skipped if the logfile does not exist. .sp Example: Trigger a red alert when the string "ERROR" appears in the "/var/adm/syslog" file: .br LOG /var/adm/syslog ERROR .sp Example: Trigger a yellow warning on all occurrences of the word "WARNING" or "NOTICE" in the "daemon.log" file, except those from the "lpr" system: .br LOG /var/log/daemon.log %WARNING|NOTICE COLOR=yellow IGNORE=lpr .sp Defaults: .br color="red", no "excludepattern". .sp Note that no logfiles are checked by default. Any log data reported by a client will just show up on the "msgs" column with status OK (green). .SH FILES STATUS COLUMN SETTINGS .sp .BR "FILE filename [color] [things to check] [OPTIONAL] [TRACK]" .sp .BR "DIR directoryname [color] [sizeMINSIZE] [TRACK]" .sp These entries control the status of the "files" column. They allow you to check on various data for files and directories. \fBfilename\fR and \fBdirectoryname\fR are names of files or directories, with a full path. You can use a regular expression to match the names of files and directories reported by the client, if you prefix the expression with a '%' character. \fBcolor\fR is the color that triggers when one or more of the checks fail. The \fBOPTIONAL\fR keyword causes this check to be skipped if the file does not exist. E.g. you can use this to check if files that should be temporary are not deleted, by checking that they are not older than the max time you would expect them to stick around, and then using OPTIONAL to ignore the state where no files exist. The \fBTRACK\fR keyword causes the size of the file or directory to be tracked in an RRD file, and presented in a graph on the "files" status display. For files, you can check one or more of the following: .IP "noexist" triggers a warning if the file exists. By default, a warning is triggered for files that have a FILE entry, but which do not exist. .IP "type=TYPE" where TYPE is one of "file", "dir", "char", "block", "fifo", or "socket". Triggers warning if the file is not of the specified type. .IP "ownerid=OWNER" triggers a warning if the owner does not match what is listed here. OWNER is specified either with the numeric uid, or the user name. .IP "groupid=GROUP" triggers a warning if the group does not match what is listed here. GROUP is specified either with the numeric gid, or the group name. .IP "mode=MODE" triggers a warning if the file permissions are not as listed. MODE is written in the standard octal notation, e.g. "644" for the rw\-r\-\-r\-\- permissions. .IP "sizeMIN.SIZE" triggers a warning it the file size is greater than MAX.SIZE or less than MIN.SIZE, respectively. For filesizes, you can use the letters "K", "M", "G" or "T" to indicate that the filesize is in Kilobytes, Megabytes, Gigabytes or Terabytes, respectively. If there is no such modifier, Kilobytes is assumed. E.g. to warn if a file grows larger than 1MB, use \fBsize<1024M\fR. .IP "mtime>MIN.MTIME mtime86400\fR. .IP "mtime=TIMESTAMP" checks if a file was last modified at TIMESTAMP. TIMESTAMP is a unix epoch time (seconds since midnight Jan 1 1970 UTC). .IP "ctime>MIN.CTIME, ctimeMIN.SIZE" triggers a warning it the directory size is greater than MAX.SIZE or less than MIN.SIZE, respectively. Directory sizes are reported in whatever unit the \fBdu\fR command on the client uses - often KB or diskblocks - so MAX.SIZE and MIN.SIZE must be given in the same unit. .LP Experience shows that it can be difficult to get these rules right. Especially when defining minimum/maximum values for file sizes, when they were last modified etc. The one thing you must remember when setting up these checks is that the rules describe criteria that must be met - only when they are met will the status be green. So "mtime<600" means "the difference between current time and the mtime of the file must be less than 600 seconds - if not, the file status will go red". .SH PORTS STATUS COLUMN SETTINGS .sp .BR "PORT criteria [MIN=mincount] [MAX=maxcount] [COLOR=color] [TRACK=id] [TEXT=displaytext]" .sp The "netstat" listing sent by the client will be scanned for how many sockets match the \fBcriteria\fR listed. The criteria you can use are: .IP "LOCAL=addr" "addr" is a (partial) local address specification in the format used on the output from netstat. .IP "EXLOCAL=addr" Exclude certain local addresses from the rule. .IP "REMOTE=addr" "addr" is a (partial) remote address specification in the format used on the output from netstat. .IP "EXREMOTE=addr" Exclude certain remote addresses from the rule. .IP "STATE=state" Causes only the sockets in the specified state to be included, "state" is usually LISTEN or ESTABLISHED but can be any socket state reported by the clients "netstat" command. .IP "EXSTATE=state" Exclude certain states from the rule. .LP "addr" is typically "10.0.0.1:80" for the IP 10.0.0.1, port 80. Or "*:80" for any local address, port 80. Note that the Xymon clients normally report only the numeric data for IP-addresses and port-numbers, so you must specify the port number (e.g. "80") instead of the service name ("www"). .br "addr" and "state" can also be a Perl-compatiable regular expression, e.g. "LOCAL=%[.:](80|443)" can be used to find entries in the netstat local port for both http (port 80) and https (port 443). In that case, portname or state must begin with "%" followed by the reg.expression. .sp The socket count found is then matched against the min/max settings defined here. If the count is outside the thresholds, the color of the "ports" status changes to "color". To check for a socket that must NOT exist: Set minimum and maximum to 0. .sp The optional \fBTRACK=id\fR setting causes Xymon to track the number of sockets found in an RRD file, and put this into a graph which is shown on the "ports" status display. The \fBid\fR setting is a simple text string which will be used as the legend for the graph, and also as part of the RRD filename. It is recommended that you use only letters and digits for the ID. .br Note that the sockets counts which are tracked are only performed once when the client does a poll cycle - i.e. the counts represent snapshots of the system state, not an average value over the client poll cycle. Therefore there may be peaks or dips in the actual sockets counts which will not show up in the graphs, because they happen while the Xymon client is not doing any polling. .sp The \fBTEXT=displaytext\fR option affects how the port appears on the "ports" status page. By default, the port is listed with the local/remote/state rules as identification, but this may be somewhat difficult to understand. You can then use e.g. "TEXT=Secure Shell" to make these ports appear with the name "Secure Shell" instead. .sp Defaults: mincount=1, maxcount=\-1 (unlimited), color="red". Note: No ports are checked by default. .sp Example: Check that the SSH daemon is listening on port 22. Track the number of active SSH connections, and warn if there are more than 5. .br PORT LOCAL=%[.:]22$ STATE=LISTEN "TEXT=SSH listener" .br PORT LOCAL=%[.:]22$ STATE=ESTABLISHED MAX=5 TRACK=ssh TEXT=SSH .sp .sp .SH SVCS status (Microsoft Windows clients) .sp .BR "SVC servicename status=(started|stopped) [startup=automatic|disabled|manual]" .sp .SH DS - RRD based status override .sp .BR "DS column filename:dataset rules COLOR=colorname TEXT=explanation" .sp "column" is the statuscolumn that will be modified. "filename" is the name of the RRD file holding the data you use for comparison. "dataset" is the name of the dataset in the RRD file - the "rrdtool info" command is useful when determining these. "rules" determine when to apply the override. You can use ">", ">=", "<" or "<=" to compare the current measurement value against one or more thresholds. "explanation" is a text that will be shown to explain the override - you can use some placeholders in the text: "&N" is replaced with the name of the dataset, "&V" is replaced with the current value, "&L" is replaced by the low threshold, "&U" is replaced with the upper threshold. .sp NOTE: This rule uses the \fbraw\fR data value from a client to examine the rules. So this type of test is only really suitable for datasets that are of the "GAUGE" type. It cannot be used meaningfully for datasets that use "COUNTER" or "DERIVE" - e.g. the datasets that are used to capture network packet traffic - because the data stored in the RRD for COUNTER-based datasets undergo a transformation (calculation) when going into the RRD. Xymon does not have direct access to the calculated data. .sp Example: Flag "conn" status a yellow if responsetime exceeds 100 msec. .br DS conn tcp.conn.rrd:sec >0.1 COLOR=yellow TEXT="Response time &V exceeds &U seconds" .sp .SH MQ Series SETTINGS .sp .BR "MQ_QUEUE queuename [age\-warning=N] [age\-critical=N] [depth\-warning=N] [depth\-critical=N]" .br .BR "MQ_CHANNEL channelname [warning=PATTERN] [alert=PATTERN]" .sp This is a set of checks for checking the health of IBM MQ message-queues. It requires the "mq.sh" or similar collector module to run on a node with access to the MQ "Queue Manager" so it can report the status of queues and channels. .sp The MQ_QUEUE setting checks the health of a single queue: You can warn (yellow) or alert (red) based on the depth of the queue, and/or the age of the oldest entry in the queue. These values are taken directly from the output generated by the "runmqsc" utility. .sp The MQ_CHANNEL setting checks the health of a single MQ channel: You can warn or alert based on the reported status of the channel. The PATTERN is a normal pattern, i.e. either a list of status keywords, or a regular expression pattern. .sp .SH CHANGING THE DEFAULT SETTINGS If you would like to use different defaults for the settings described above, then you can define the new defaults after a DEFAULT line. E.g. this would explicitly define all of the default settings: .IP .nf DEFAULT UP 1h LOAD 5.0 10.0 DISK * 90 95 MEMPHYS 100 101 MEMSWAP 50 80 MEMACT 90 97 .fi .LP .SH RULES TO SELECT HOSTS All of the settings can be applied to a group of hosts, by preceding them with rules. A rule defines of one of more filters using these keywords (note that this is identical to the rule definitions used in the .I alerts.cfg(5) file). .BR "PAGE=targetstring" Rule matching an alert by the name of the page in Xymon. "targetstring" is the path of the page as defined in the hosts.cfg file. E.g. if you have this setup: .IP .nf page servers All Servers subpage web Webservers 10.0.0.1 www1.foo.com subpage db Database servers 10.0.0.2 db1.foo.com .fi .LP Then the "All servers" page is found with \fBPAGE=servers\fR, the "Webservers" page is \fBPAGE=servers/web\fR and the "Database servers" page is \fBPAGE=servers/db\fR. Note that you can also use regular expressions to specify the page name, e.g. \fBPAGE=%.*/db\fR would find the "Database servers" page regardless of where this page was placed in the hierarchy. The top-level page has a the fixed name \fB/\fR, e.g. \fBPAGE=/\fR would match all hosts on the Xymon frontpage. If you need it in a regular expression, use \fBPAGE=%^/\fR to avoid matching the forward-slash present in subpage-names. .BR "EXPAGE=targetstring" Rule excluding a host if the pagename matches. .BR "HOST=targetstring" Rule matching a host by the hostname. "targetstring" is either a comma-separated list of hostnames (from the hosts.cfg file), "*" to indicate "all hosts", or a Perl-compatible regular expression. E.g. "HOST=dns.foo.com,www.foo.com" identifies two specific hosts; "HOST=%www.*.foo.com EXHOST=www\-test.foo.com" matches all hosts with a name beginning with "www", except the "www\-test" host. .BR "EXHOST=targetstring" Rule excluding a host by matching the hostname. .BR "CLASS=classname" Rule match by the client class-name. You specify the class-name for a host when starting the client through the "\-\-class=NAME" option to the runclient.sh script. If no class is specified, the host by default goes into a class named by the operating system. .BR "EXCLASS=classname" Exclude all hosts belonging to "classname" from this rule. .BR "DISPLAYGROUP=groupstring" Rule matching an alert by the text of the display-group (text following the group, group-only, group-except heading) in the hosts.cfg file. "groupstring" is the text for the group, stripped of any HTML tags. E.g. if you have this setup: .IP .nf group Web 10.0.0.1 www1.foo.com 10.0.0.2 www2.foo.com group Production databases 10.0.1.1 db1.foo.com .fi .LP Then the hosts in the Web-group can be matched with \fBDISPLAYGROUP=Web\fR, and the database servers can be matched with \fBDISPLAYGROUP="Production databases"\fR. Note that you can also use regular expressions, e.g. \fBDISPLAYGROUP=%database\fR. If there is no group-setting for the host, use "DISPLAYGROUP=NONE". .BR "EXDISPLAYGROUP=groupstring" Rule excluding a group by matching the display-group string. .BR "TIME=timespecification" Rule matching by the time-of-day. This is specified as the DOWNTIME time specification in the hosts.cfg file. E.g. "TIME=W:0800:2200" applied to a rule will make this rule active only on week-days between 8AM and 10PM. .BR "EXTIME=timespecification" Rule excluding by the time-of-day. This is also specified as the DOWNTIME time specification in the hosts.cfg file. E.g. "TIME=W:0400:0600" applied to a rule will make this rule exclude on week-days between 4AM and 6AM. This applies on top of any TIME= specification, so both must match. .SH DIRECTING ALERTS TO GROUPS For some tests - e.g. "procs" or "msgs" - the right group of people to alert in case of a failure may be different, depending on which of the client rules actually detected a problem. E.g. if you have PROCS rules for a host checking both "httpd" and "sshd" processes, then the Web admins should handle httpd-failures, whereas "sshd" failures are handled by the Unix admins. To handle this, all rules can have a "GROUP=groupname" setting. When a rule with this setting triggers a yellow or red status, the groupname is passed on to the Xymon alerts module, so you can use it in the alert rule definitions in .I alerts.cfg(5) to direct alerts to the correct group of people. .SH RULES: APPLYING SETTINGS TO SELECTED HOSTS Rules must be placed after the settings, e.g. .IP .nf LOAD 8.0 12.0 HOST=db.foo.com TIME=*:0800:1600 .fi .LP If you have multiple settings that you want to apply the same rules to, you can write the rules *only* on one line, followed by the settings. E.g. .IP .nf HOST=%db.*.foo.com TIME=W:0800:1600 LOAD 8.0 12.0 DISK /db 98 100 PROC mysqld 1 .fi .LP will apply the three settings to all of the "db" hosts on week-days between 8AM and 4PM. This can be combined with per-settings rule, in which case the per-settings rule overrides the general rule; e.g. .IP .nf HOST=%.*.foo.com LOAD 7.0 12.0 HOST=bax.foo.com LOAD 3.0 8.0 .fi .LP will result in the load-limits being 7.0/12.0 for the "bax.foo.com" host, and 3.0/8.0 for all other foo.com hosts. The entire file is evaluated from the top to bottom, and the first match found is used. So you should put the specific settings first, and the generic ones last. .SH NOTES For the LOG, FILE and DIR checks, it is necessary also to configure the actual file- and directory-names in the .I client\-local.cfg(5) file. If the filenames are not listed there, the clients will not collect any data about these files/directories, and the settings in the analysis.cfg file will be silently ignored. The ability to compute file checksums with MD5, SHA1 or RMD160 should not be used for general-purpose file integrity checking, since the overhead of calculating these on a large number of files can be significant. If you need this, look at tools designed for this purpose - e.g. Tripwire or AIDE. At the time of writing (april 2006), the SHA-1 and RMD160 algorithms are considered cryptographically safe. The MD5 algorithm has been shown to have some weaknesses, and is not considered strong enough when a high level of security is required. .SH "SEE ALSO" xymond_client(8), client\-local.cfg(5), xymond(8), xymon(7) xymon-4.3.30/xymond/xymond_filestore.80000664000076400007640000000620713534041733020214 0ustar rpmbuildrpmbuild.TH XYMOND_FILESTORE 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_filestore \- xymond worker module for storing Xymon data .SH SYNOPSIS .B "xymond_channel \-\-channel=status xymond_filestore \-\-status [options]" .br .B "xymond_channel \-\-channel=data xymond_filestore \-\-data [options]" .br .B "xymond_channel \-\-channel=notes xymond_filestore \-\-notes [options]" .br .B "xymond_channel \-\-channel=enadis xymond_filestore \-\-enadis [options]" .SH DESCRIPTION xymond_filestore is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives xymond messages from a xymond channel via stdin, and stores these in the filesystem in a manner that is compatible with the Big Brother daemon, bbd. This program can be started multiple times, if you want to store messages for more than one channel. .SH OPTIONS .IP "\-\-status" Incoming messages are "status" messages, they will be stored in the $XYMONRAWSTATUSDIR/ directory. If you are using .I xymon(7) throughout your Xymon server, you will not need to run this module to save status messages, unless you have a third-party add-on that reads the status-logs directly. This module is NOT needed to get trend graphs, you should run the .I xymond_rrd(8) module instead. .IP "\-\-data" Incoming messages are "data" messages, they will be stored in the $XYMONDATADIR directory. This module is not needed, unless you have a third-party module that processes the data-files. This module is NOT needed to get trend graphs, you should run the .I xymond_rrd(8) module instead. .IP "\-\-notes" Incoming messages are "notes" messages, they will be stored in the $XYMONNOTESDIR directory. This modules is only needed if you want to allow people to remotely update the notes-files available on the Xymon webpages. .IP "\-\-enadis" Incoming messages are enable/disable messages, they will update files in the $XYMONDISABLEDDIR directory. This is only needed if you have third-party add-ons that use these files. .IP "\-\-dir=DIRECTORY" Overrides the default output directory. .IP "\-\-html" Used together with "\-\-status". Tells xymond_filestore to also save an HTML version of the status-log. Should not be used unless you must run with "XYMONLOGSTATUS=static". .IP "\-\-htmldir=DIRECTORY" The directory where HTML-versions of the status logs are stored. Default: $XYMONHTMLSTATUSDIR .IP "\-\-htmlext=.EXT" Set the filename extension for generated HTML files. By default, HTML files are saved with a ".html" extension. .IP "\-\-multigraphs=TEST1[,TEST2]" This causes xymond_filestore to generate HTML status pages with links to service graphs that are split up into multiple images, with at most 5 graphs per image. If not specified, only the "disk" status is split up this way. .IP "\-\-only=test[,test,test]" Save status messages only for the listed set of tests. This can be useful if you have an external script that needs to parse some of the status logs, but you do not want to save all status logs. .IP "\-\-debug" Enable debugging output. .SH FILES This module does not rely on any configuration files. .SH "SEE ALSO" xymond_channel(8), xymond_rrd(8), xymond(8), xymon(7) xymon-4.3.30/xymond/do_rrd.c0000664000076400007640000006417412503303630016145 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: do_rrd.c 7608 2015-03-21 15:00:40Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_rrd.h" #include "do_rrd.h" #include "client_config.h" #ifndef NAME_MAX #define NAME_MAX 255 /* Solaris doesn't define NAME_MAX, but ufs limit is 255 */ #endif extern int seq; /* from xymond_rrd.c */ char *rrddir = NULL; int use_rrd_cache = 1; /* Use the cache by default */ int no_rrd = 0; /* Write to rrd by default */ static int processorfd = 0; static FILE *processorstream = NULL; static char *exthandler = NULL; static char **extids = NULL; static char rrdvalues[MAX_LINE_LEN]; static char *senderip = NULL; static char rrdfn[PATH_MAX]; /* Base filename without directories, from setupfn() */ static char filedir[PATH_MAX]; /* Full path filename */ static char *fnparams[4] = { NULL, }; /* Saved parameters passed to setupfn() */ /* How often do we feed data into the RRD file */ #define DEFAULT_RRD_INTERVAL 300 static int rrdinterval = DEFAULT_RRD_INTERVAL; #define CACHESZ 12 /* # of updates that can be cached - updates are usually 5 minutes apart */ static int updcache_keyofs = -1; static void * updcache; typedef struct updcacheitem_t { char *key; rrdtpldata_t *tpl; int valcount; char *vals[CACHESZ]; int updseq[CACHESZ]; time_t updtime[CACHESZ]; } updcacheitem_t; static void * flushtree; static int have_flushtree = 0; typedef struct flushtree_t { char *hostname; time_t flushtime; } flushtree_t; void setup_exthandler(char *handlerpath, char *ids) { char *p; int idcount = 0; MEMDEFINE(rrdvalues); exthandler = strdup(handlerpath); idcount=1; p = ids; while ((p = strchr(p, ',')) != NULL) { p++; idcount++; } extids = (char **)malloc((idcount+1)*(sizeof(char *))); idcount = 0; p = strtok(ids, ","); while (p) { extids[idcount++] = strdup(p); p = strtok(NULL, ","); } extids[idcount] = NULL; MEMUNDEFINE(rrdvalues); } void setup_extprocessor(char *cmd) { int n; int pfd[2]; pid_t childpid; if (!cmd) return; processorfd = 0; n = pipe(pfd); if (n == -1) { errprintf("Could not get a pipe: %s\n", strerror(errno)); } else { childpid = fork(); if (childpid == -1) { errprintf("Could not fork channel handler: %s\n", strerror(errno)); } else if (childpid == 0) { /* The channel handler child */ char *argv[2]; argv[0] = strdup(cmd); argv[1] = NULL; n = dup2(pfd[0], STDIN_FILENO); close(pfd[0]); close(pfd[1]); n = execvp(cmd, argv); /* We should never go here */ errprintf("exec() failed for child command %s: %s\n", cmd, strerror(errno)); exit(1); } else { /* Parent process continues */ close(pfd[0]); processorfd = pfd[1]; processorstream = fdopen(processorfd, "w"); errprintf("External processor '%s' started\n", cmd); } } } void shutdown_extprocessor(void) { if (!processorfd) return; close(processorfd); processorfd = 0; processorstream = NULL; errprintf("External processor stopped\n"); } static void setupfn(char *format, char *param) { char *p; memset(fnparams, 0, sizeof(fnparams)); fnparams[0] = param; snprintf(rrdfn, sizeof(rrdfn)-1, format, param); rrdfn[sizeof(rrdfn)-1] = '\0'; while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_'; } static void setupfn2(char *format, char *param1, char *param2) { char *p; while ((p = strchr(param2, '/')) != NULL) *p = ','; memset(fnparams, 0, sizeof(fnparams)); fnparams[0] = param1; fnparams[1] = param2; snprintf(rrdfn, sizeof(rrdfn)-1, format, param1, param2); rrdfn[sizeof(rrdfn)-1] = '\0'; while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_'; } static void setupfn3(char *format, char *param1, char *param2, char *param3) { char *p; memset(fnparams, 0, sizeof(fnparams)); fnparams[0] = param1; fnparams[1] = param2; fnparams[2] = param3; snprintf(rrdfn, sizeof(rrdfn)-1, format, param1, param2, param3); rrdfn[sizeof(rrdfn)-1] = '\0'; while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_'; if (strlen(rrdfn) >= (NAME_MAX - 50)) { /* * Filename is too long. Limit filename length * by replacing the last part of the filename * with an MD5 hash. */ char *hash = md5hash(rrdfn+(NAME_MAX-50)); sprintf(rrdfn+(NAME_MAX-50), "_%s.rrd", hash); } } static void setupinterval(int intvl) { rrdinterval = (intvl ? intvl : DEFAULT_RRD_INTERVAL); } static int flush_cached_updates(updcacheitem_t *cacheitem, char *newdata) { /* Flush any updates we've cached */ char *updparams[5+CACHESZ+1] = { "rrdupdate", filedir, "-t", NULL, NULL, NULL, }; int i, pcount, result; dbgprintf("Flushing '%s' with %d updates pending, template '%s'\n", cacheitem->key, (newdata ? 1 : 0) + cacheitem->valcount, cacheitem->tpl->template); /* ISO C90: parameters cannot be used as initializers */ updparams[3] = cacheitem->tpl->template; /* Setup the parameter list with all of the cached and new readings */ for (i=0; (i < cacheitem->valcount); i++) updparams[4+i] = cacheitem->vals[i]; if (newdata) { updparams[4+cacheitem->valcount] = newdata; updparams[4+cacheitem->valcount+1] = NULL; } else { /* No new data - happens when flushing the cache */ updparams[4+cacheitem->valcount] = NULL; } for (pcount = 0; (updparams[pcount]); pcount++); optind = opterr = 0; rrd_clear_error(); result = rrd_update(pcount, updparams); #if defined(LINUX) && defined(RRDTOOL12) /* * RRDtool 1.2+ uses mmap'ed I/O, but the Linux kernel does not update timestamps when * doing file I/O on mmap'ed files. This breaks our check for stale/nostale RRD's. * So do an explicit timestamp update on the file here. */ utimes(filedir, NULL); #endif /* Clear the cached data */ for (i=0; (i < cacheitem->valcount); i++) { cacheitem->updseq[i] = 0; cacheitem->updtime[i] = 0; if (cacheitem->vals[i]) xfree(cacheitem->vals[i]); } cacheitem->valcount = 0; return result; } static int create_and_update_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *creparams[], void *template) { static int callcounter = 0; struct stat st; int pcount, result; char *updcachekey; xtreePos_t handle; updcacheitem_t *cacheitem = NULL; int pollinterval; strbuffer_t *modifymsg; time_t updtime = 0; /* Reset the RRD poll interval */ pollinterval = rrdinterval; rrdinterval = DEFAULT_RRD_INTERVAL; if ((rrdfn == NULL) || (strlen(rrdfn) == 0)) { errprintf("RRD update for no file\n"); return -1; } MEMDEFINE(rrdvalues); MEMDEFINE(filedir); sprintf(filedir, "%s/%s", rrddir, hostname); if (stat(filedir, &st) == -1) { if (mkdir(filedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == -1) { errprintf("Cannot create rrd directory %s : %s\n", filedir, strerror(errno)); MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return -1; } } /* Watch out here - "rrdfn" may be very large. */ snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn); filedir[sizeof(filedir)-1] = '\0'; /* Make sure it is null terminated */ /* * Prepare to cache the update. Create the cache tree, and find/create a cache record. * Note: Cache records are persistent, once created they remain in place forever. * Only the update-data is flushed from time to time. */ if (updcache_keyofs == -1) { updcache = xtreeNew(strcasecmp); updcache_keyofs = strlen(rrddir); } updcachekey = filedir + updcache_keyofs; handle = xtreeFind(updcache, updcachekey); if (handle == xtreeEnd(updcache)) { if (!template) template = setup_template(creparams); if (!template) { errprintf("BUG: setup_template() returns NULL! host=%s,test=%s,cp[0]=%s, cp[1]=%s\n", hostname, testname, (creparams[0] ? creparams[0] : "NULL"), (creparams[1] ? creparams[1] : "NULL")); return -1; } cacheitem = (updcacheitem_t *)calloc(1, sizeof(updcacheitem_t)); cacheitem->key = strdup(updcachekey); cacheitem->tpl = template; xtreeAdd(updcache, cacheitem->key, cacheitem); } else { cacheitem = (updcacheitem_t *)xtreeData(updcache, handle); if (!template) template = cacheitem->tpl; } /* If the RRD file doesn't exist, create it immediately */ if (stat(filedir, &st) == -1) { char **rrdcreate_params, **rrddefinitions; int rrddefcount, i; char *rrakey = NULL; char stepsetting[10]; int havestepsetting = 0, fixcount = 2; dbgprintf("Creating rrd %s\n", filedir); /* How many parameters did we get? */ for (pcount = 0; (creparams[pcount]); pcount++); /* Add the RRA definitions to the create parameter set */ if (pollinterval != DEFAULT_RRD_INTERVAL) { rrakey = (char *)malloc(strlen(testname) + 10); sprintf(rrakey, "%s/%d", testname, pollinterval); } sprintf(stepsetting, "%d", pollinterval); rrddefinitions = get_rrd_definition((rrakey ? rrakey : testname), &rrddefcount); rrdcreate_params = (char **)calloc(4 + pcount + rrddefcount + 1, sizeof(char *)); rrdcreate_params[0] = "rrdcreate"; rrdcreate_params[1] = filedir; /* Is there already a step-setting in the rrddefinitions? */ for (i=0; (!havestepsetting && (i < rrddefcount)); i++) havestepsetting = ((strcmp(rrddefinitions[i], "-s") == 0) || (strcmp(rrddefinitions[i], "--step") == 0)); if (!havestepsetting) { rrdcreate_params[2] = "-s"; rrdcreate_params[3] = stepsetting; fixcount = 4; } for (i=0; (i < pcount); i++) rrdcreate_params[fixcount+i] = creparams[i]; for (i=0; (i < rrddefcount); i++, pcount++) rrdcreate_params[fixcount+pcount] = rrddefinitions[i]; if (debug) { for (i = 0; (rrdcreate_params[i]); i++) { dbgprintf("RRD create param %02d: '%s'\n", i, rrdcreate_params[i]); } } /* * Ugly! RRDtool uses getopt() for parameter parsing, so * we MUST reset this before every call. */ optind = opterr = 0; rrd_clear_error(); result = rrd_create(4+pcount, rrdcreate_params); xfree(rrdcreate_params); if (rrakey) xfree(rrakey); if (result != 0) { errprintf("RRD error creating %s: %s\n", filedir, rrd_get_error()); MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 1; } } updtime = atoi(rrdvalues); if (cacheitem->valcount > 0) { /* Check for duplicate updates */ if (cacheitem->updseq[cacheitem->valcount-1] == seq) { /* * This is usually caused by a configuration error, * e.g. two PORT settings in analysis.cfg that * use the same TRACK string. * Can also be two web checks using the same URL, but * with different POST data. */ dbgprintf("%s/%s: Error - ignored duplicate update for message sequence %d\n", hostname, rrdfn, seq); MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 0; } else if (cacheitem->updtime[cacheitem->valcount-1] > updtime) { dbgprintf("%s/%s: Error - RRD time goes backwards: Now=%d, previous=%d\n", hostname, rrdfn, (int) updtime, (int)cacheitem->updtime[cacheitem->valcount-1]); MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 0; } else if (cacheitem->updtime[cacheitem->valcount-1] == updtime) { int identical = (strcmp(rrdvalues, cacheitem->vals[cacheitem->valcount-1]) == 0); if (!identical) { int i; errprintf("%s/%s: Bug - duplicate RRD data with same timestamp %d, different data\n", hostname, rrdfn, (int) updtime); for (i=0; (i < cacheitem->valcount); i++) dbgprintf("Val %d: Seq %d: %s\n", i, cacheitem->updseq[i], cacheitem->vals[i]); dbgprintf("NewVal: Seq %d: %s\n", seq, rrdvalues); } else { dbgprintf("%s/%s: Ignored duplicate (and identical) update timestamped %d\n", hostname, rrdfn, (int) updtime); } MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 0; } } /* * Match the RRD data against any DS client-configuration modifiers. */ modifymsg = check_rrdds_thresholds(hostname, classname, pagepaths, rrdfn, ((rrdtpldata_t *)template)->dsnames, rrdvalues); if (modifymsg) combo_add(modifymsg); /* * See if we want the data to go to an external handler. */ if (processorstream) { int i, n; n = fprintf(processorstream, "%s %s %s", ((rrdtpldata_t *)template)->template, rrdvalues, hostname); for (i=0; ((n >= 0) && fnparams[i]); i++) n = fprintf(processorstream, " %s", fnparams[i]); if (n >= 0) n = fprintf(processorstream, "\n"); if (n >= 0) fflush(processorstream); if (n == -1) { errprintf("Ext-processor write failed: %s\n", strerror(errno)); shutdown_extprocessor(); } } /* Are we actually handling the writing of RRD files? */ if (no_rrd) return 0; /* * We cannot just cache data every time because then after CACHESZ updates * of each RRD, we will flush all of the data at once (all of the caches * fill at the same speed); this would result in huge load-spikes every * rrdinterval*CACHESZ seconds. * * So to smooth the load, we force the update through for every CACHESZ * updates, regardless of how much is in the cache. This gives us a steady * (although slightly higher) load. */ if (use_rrd_cache && (++callcounter < CACHESZ)) { if (cacheitem && (cacheitem->valcount < CACHESZ)) { cacheitem->updseq[cacheitem->valcount] = seq; cacheitem->updtime[cacheitem->valcount] = updtime; cacheitem->vals[cacheitem->valcount] = strdup(rrdvalues); cacheitem->valcount += 1; MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 0; } } else callcounter = 0; /* At this point, we will commit the update to disk */ result = flush_cached_updates(cacheitem, rrdvalues); if (result != 0) { char *msg = rrd_get_error(); if (strstr(msg, "(minimum one second step)") != NULL) { dbgprintf("RRD error updating %s from %s: %s\n", filedir, (senderip ? senderip : "unknown"), msg); } else { errprintf("RRD error updating %s from %s: %s\n", filedir, (senderip ? senderip : "unknown"), msg); } MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 2; } MEMUNDEFINE(filedir); MEMUNDEFINE(rrdvalues); return 0; } void rrdcacheflushall(void) { xtreePos_t handle; updcacheitem_t *cacheitem; if (updcache_keyofs == -1) return; /* No cache */ for (handle = xtreeFirst(updcache); (handle != xtreeEnd(updcache)); handle = xtreeNext(updcache, handle)) { cacheitem = (updcacheitem_t *) xtreeData(updcache, handle); if (cacheitem->valcount > 0) { sprintf(filedir, "%s%s", rrddir, cacheitem->key); flush_cached_updates(cacheitem, NULL); } } } void rrdcacheflushhost(char *hostname) { xtreePos_t handle; updcacheitem_t *cacheitem; flushtree_t *flushitem; int keylen; time_t now = gettimer(); if (updcache_keyofs == -1) return; /* If we get a full path for the key, skip the leading rrddir */ if (strncmp(hostname, rrddir, updcache_keyofs) == 0) hostname += updcache_keyofs; keylen = strlen(hostname); if (!have_flushtree) { flushtree = xtreeNew(strcasecmp); have_flushtree = 1; } handle = xtreeFind(flushtree, hostname); if (handle == xtreeEnd(flushtree)) { flushitem = (flushtree_t *)calloc(1, sizeof(flushtree_t)); flushitem->hostname = strdup(hostname); flushitem->flushtime = 0; xtreeAdd(flushtree, flushitem->hostname, flushitem); } else { flushitem = (flushtree_t *) xtreeData(flushtree, handle); } if ((flushitem->flushtime + 60) >= now) { dbgprintf("Flush of '%s' skipped, too soon\n", hostname); return; } flushitem->flushtime = now; handle = xtreeFirst(updcache); while (handle != xtreeEnd(updcache)) { cacheitem = (updcacheitem_t *) xtreeData(updcache, handle); switch (strncasecmp(cacheitem->key, hostname, keylen)) { case 1 : handle = xtreeEnd(updcache); break; case 0: if (cacheitem->valcount > 0) { dbgprintf("Flushing cache '%s'\n", cacheitem->key); sprintf(filedir, "%s%s", rrddir, cacheitem->key); flush_cached_updates(cacheitem, NULL); } /* Fall through */ default: handle = xtreeNext(updcache, handle); break; } } } static int rrddatasets(char *hostname, char ***dsnames) { struct stat st; int result; char *fetch_params[] = { "rrdfetch", filedir, "AVERAGE", "-s", "-30m", NULL }; time_t starttime, endtime; unsigned long steptime, dscount; rrd_value_t *rrddata; snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn); filedir[sizeof(filedir)-1] = '\0'; if (stat(filedir, &st) == -1) return 0; optind = opterr = 0; rrd_clear_error(); result = rrd_fetch(5, fetch_params, &starttime, &endtime, &steptime, &dscount, dsnames, &rrddata); if (result == -1) { errprintf("Error while retrieving RRD dataset names from %s: %s\n", filedir, rrd_get_error()); return 0; } free(rrddata); /* No use for the actual data */ return dscount; } /* Include all of the sub-modules. */ #include "rrd/do_xymongen.c" #include "rrd/do_xymonnet.c" #include "rrd/do_xymonproxy.c" #include "rrd/do_xymond.c" #include "rrd/do_citrix.c" #include "rrd/do_ntpstat.c" #include "rrd/do_memory.c" /* Must go before do_la.c */ #include "rrd/do_la.c" /* * From hobbit-perl-client http://sourceforge.net/projects/hobbit-perl-cl/ * version 1.15 Oct. 17 2006 (downloaded on 2008-12-01). * * Include file for netapp.pl dbcheck.pl and beastat.pl scripts * do_fd_lib.c contains some function used by the other library * * Must go before "do_disk.c" */ #include "rrd/do_fd_lib.c" #include "rrd/do_netapp.c" #include "rrd/do_beastat.c" #include "rrd/do_dbcheck.c" #include "rrd/do_disk.c" #include "rrd/do_netstat.c" #include "rrd/do_vmstat.c" #include "rrd/do_iostat.c" #include "rrd/do_ifstat.c" #include "rrd/do_apache.c" #include "rrd/do_sendmail.c" #include "rrd/do_mailq.c" #include "rrd/do_iishealth.c" #include "rrd/do_temperature.c" #include "rrd/do_net.c" #include "rrd/do_ncv.c" #include "rrd/do_external.c" #include "rrd/do_filesizes.c" #include "rrd/do_counts.c" #include "rrd/do_trends.c" #include "rrd/do_ifmib.c" #include "rrd/do_snmpmib.c" /* z/OS, z/VM, z/VME stuff */ #include "rrd/do_paging.c" #include "rrd/do_mdc.c" #include "rrd/do_cics.c" #include "rrd/do_getvis.c" #include "rrd/do_asid.c" /* * From devmon http://sourceforge.net/projects/devmon/ * version 0.3.0 (downloaded on 2008-12-01). */ #include "rrd/do_devmon.c" void update_rrd(char *hostname, char *testname, char *msg, time_t tstamp, char *sender, xymonrrd_t *ldef, char *classname, char *pagepaths) { char *id; MEMDEFINE(rrdvalues); if (ldef) id = ldef->xymonrrdname; else id = testname; senderip = sender; if (strcmp(id, "bbgen") == 0) do_xymongen_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "xymongen") == 0) do_xymongen_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "bbtest") == 0) do_xymonnet_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "xymonnet") == 0) do_xymonnet_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "bbproxy") == 0) do_xymonproxy_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "xymonproxy") == 0) do_xymonproxy_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "hobbitd") == 0) do_xymond_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "xymond") == 0) do_xymond_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "citrix") == 0) do_citrix_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ntpstat") == 0) do_ntpstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "la") == 0) do_la_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "disk") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "memory") == 0) do_memory_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "netstat") == 0) do_netstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "vmstat") == 0) do_vmstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "iostat") == 0) do_iostat_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ifstat") == 0) do_ifstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp); /* These two come from the filerstats2bb.pl script. The reports are in disk-format */ else if (strcmp(id, "inode") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "qtree") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "apache") == 0) do_apache_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "sendmail") == 0) do_sendmail_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "mailq") == 0) do_mailq_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "iishealth") == 0) do_iishealth_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "temperature") == 0) do_temperature_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ncv") == 0) do_ncv_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "tcp") == 0) do_net_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "filesizes") == 0) do_filesizes_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "proccounts") == 0) do_counts_rrd("processes", hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "portcounts") == 0) do_counts_rrd("ports", hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "linecounts") == 0) do_derives_rrd("lines", hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "deltacounts") == 0) do_counts_rrd("deltalines", hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "trends") == 0) do_trends_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ifmib") == 0) do_ifmib_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (is_snmpmib_rrd(id)) do_snmpmib_rrd(hostname, testname, classname, pagepaths, msg, tstamp); /* z/OS, z/VSE, z/VM from Rich Smrcina */ else if (strcmp(id, "paging") == 0) do_paging_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "mdc") == 0) do_mdc_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "cics") == 0) do_cics_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "getvis") == 0) do_getvis_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "maxuser") == 0) do_asid_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "nparts") == 0) do_asid_rrd(hostname, testname, classname, pagepaths, msg, tstamp); /* * These are from the hobbit-perl-client * NetApp check for netapp.pl, dbcheck.pl and beastat.pl scripts */ else if (strcmp(id, "xtstats") == 0) do_netapp_extrastats_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "quotas") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "snapshot") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "TblSpace") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "stats") == 0) do_netapp_stats_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ops") == 0) do_netapp_ops_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "cifs") == 0) do_netapp_cifs_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "snaplist") == 0) do_netapp_snaplist_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "snapmirr") == 0) do_netapp_snapmirror_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "HitCache") == 0) do_dbcheck_hitcache_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "Session") == 0) do_dbcheck_session_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "RollBack") == 0) do_dbcheck_rb_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "InvObj") == 0) do_dbcheck_invobj_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "MemReq") == 0) do_dbcheck_memreq_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "JVM") == 0) do_beastat_jvm_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "JMS") == 0) do_beastat_jms_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "JTA") == 0) do_beastat_jta_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "ExecQueue") == 0) do_beastat_exec_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (strcmp(id, "JDBCConn") == 0) do_beastat_jdbc_rrd(hostname, testname, classname, pagepaths, msg, tstamp); /* * This is from the devmon SNMP collector */ else if (strcmp(id, "devmon") == 0) do_devmon_rrd(hostname, testname, classname, pagepaths, msg, tstamp); else if (extids && exthandler) { int i; for (i=0; (extids[i] && strcmp(extids[i], id)); i++) ; if (extids[i]) do_external_rrd(hostname, testname, classname, pagepaths, msg, tstamp); } senderip = NULL; MEMUNDEFINE(rrdvalues); } xymon-4.3.30/xymond/xymond.c0000664000076400007640000053732613453011125016216 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This is the master daemon, xymond. */ /* */ /* This is a daemon that implements the Big Brother network protocol, with */ /* additional protocol items implemented for Xymon. */ /* */ /* This daemon maintains the full state of the Xymon system in memory, */ /* eliminating the need for file-based storage of e.g. status logs. The web */ /* frontend programs (xymongen, combostatus, hostsvc.cgi etc) can retrieve */ /* current statuslogs from this daemon to build the Xymon webpages. However, */ /* a "plugin" mechanism is also implemented to allow "worker modules" to */ /* pickup various types of events that occur in the system. This allows */ /* such modules to e.g. maintain the standard Xymon file-based storage, or */ /* implement history logging or RRD database updates. This plugin mechanism */ /* uses System V IPC mechanisms for a high-performance/low-latency communi- */ /* cation between xymond and the worker modules - under no circumstances */ /* should the daemon be tasked with storing data to a low-bandwidth channel. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond.c 8045 2019-04-09 03:32:37Z jccleaver $"; #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include /* Someday I'll move to GNU Autoconf for this ... */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #define DISABLED_UNTIL_OK -1 /* * The absolute maximum size we'll grow our buffers to accommodate an incoming message. * This is really just an upper bound to squash the bad guys trying to data-flood us. */ #define MAX_XYMON_INBUFSZ (64*1024*1024) /* 64 MB */ /* The initial size of an input buffer. Make this large enough for most traffic. */ #define XYMON_INBUF_INITIAL (128*1024) /* How much the input buffer grows per re-allocation */ #define XYMON_INBUF_INCREMENT (32*1024) /* How long to keep an ack after the status has recovered */ #define ACKCLEARDELAY 720 /* 12 minutes */ /* How long messages are good for (by default) before going purple - minutes */ #define DEFAULT_VALIDITY 30 #define DEFAULT_PURPLE_INTERVAL 60 int purplecheckinterval = DEFAULT_PURPLE_INTERVAL; /* Seconds - check for purples every 60s */ #define DEFAULT_STATS_INTERVAL (5*60) int statsinterval = DEFAULT_STATS_INTERVAL; /* Seconds - report xymond status every 5m */ /* How long are sub-client messages valid */ #define MAX_SUBCLIENT_LIFETIME 960 /* 15 minutes + a bit */ #define DEFAULT_FLAPCOUNT 5 int flapcount = DEFAULT_FLAPCOUNT; int flapthreshold = (DEFAULT_FLAPCOUNT+1)*5*60; /* Seconds - if more than flapcount changes during this period, it's flapping */ htnames_t *metanames = NULL; typedef struct xymond_meta_t { htnames_t *metaname; char *value; struct xymond_meta_t *next; } xymond_meta_t; typedef struct ackinfo_t { int level; time_t received, validuntil, cleartime; char *ackedby; char *msg; struct ackinfo_t *next; } ackinfo_t; typedef struct testinfo_t { char *name; int clientsave; } testinfo_t; typedef struct modifier_t { char *source, *cause; int color, valid; struct modifier_t *next; } modifier_t; /* This holds all information about a single status */ typedef struct xymond_log_t { struct xymond_hostlist_t *host; testinfo_t *test; char *origin; int color, oldcolor, activealert, histsynced, downtimeactive, flapping, oldflapcolor, currflapcolor; char *testflags; char *grouplist; /* For extended status reports (e.g. from xymond_client) */ char sender[IP_ADDR_STRLEN]; time_t *lastchange; /* Table of times when the currently logged status began */ time_t logtime; /* time when last update was received */ time_t validtime; /* time when status is no longer valid */ time_t enabletime; /* time when test auto-enables after a disable */ time_t acktime; /* time when test acknowledgement expires */ time_t redstart, yellowstart; int maxackedcolor; /* The most severe color that has been acked */ unsigned char *message; int msgsz; unsigned char *dismsg, *ackmsg; char *cookie; time_t cookieexpires; struct xymond_meta_t *metas; struct modifier_t *modifiers; ackinfo_t *acklist; /* Holds list of acks */ unsigned long statuschangecount; struct xymond_log_t *next; } xymond_log_t; typedef struct clientmsg_list_t { char *collectorid; time_t timestamp; char *msg; struct clientmsg_list_t *next; } clientmsg_list_t; /* This is a list of the hosts we have seen reports for, and links to their status logs */ typedef struct xymond_hostlist_t { char *hostname; char ip[IP_ADDR_STRLEN]; enum { H_NORMAL, H_SUMMARY } hosttype; xymond_log_t *logs; xymond_log_t *pinglog; /* Points to entry in logs list, but we need it often */ clientmsg_list_t *clientmsgs; time_t clientmsgtstamp; } xymond_hostlist_t; typedef struct filecache_t { char *fn; long len; unsigned char *fdata; } filecache_t; typedef struct senderstats_t { char *senderip; unsigned long msgcount; } senderstats_t; void *rbhosts; /* The hosts we have reports from */ void *rbtests; /* The tests (columns) we have seen */ void *rborigins; /* The origins we have seen */ void *rbcookies; /* The cookies we use */ void *rbfilecache; void *rbsenders; sender_t *maintsenders = NULL; sender_t *statussenders = NULL; sender_t *adminsenders = NULL; sender_t *wwwsenders = NULL; sender_t *tracelist = NULL; int traceall = 0; int ignoretraced = 0; int clientsavemem = 1; /* In memory */ int clientsavedisk = 0; /* On disk via the CLICHG channel */ int allow_downloads = 1; int defaultvalidity = 30; /* Minutes */ int ackeachcolor = 0; int defaultcookietime = 86400; /* 1 day */ #define NOTALK 0 #define RECEIVING 1 #define RESPONDING 2 /* This struct describes an active connection with a Xymon client */ typedef struct conn_t { int sock; /* Communications socket */ struct sockaddr_in addr; /* Client source address */ unsigned char *buf, *bufp; /* Message buffer and pointer */ size_t buflen, bufsz; /* Active and maximum length of buffer */ int doingwhat; /* Communications state (NOTALK, READING, RESPONDING) */ time_t timeout; /* When the timeout for this connection happens */ struct conn_t *next; } conn_t; enum droprencmd_t { CMD_DROPHOST, CMD_DROPTEST, CMD_RENAMEHOST, CMD_RENAMETEST, CMD_DROPSTATE }; static volatile int running = 1; static volatile int reloadconfig = 0; static volatile time_t nextcheckpoint = 0; static volatile int dologswitch = 0; static volatile int gotalarm = 0; /* Our channels to worker modules */ xymond_channel_t *statuschn = NULL; /* Receives full "status" messages */ xymond_channel_t *stachgchn = NULL; /* Receives brief message about a status change */ xymond_channel_t *pagechn = NULL; /* Receives alert messages (triggered from status changes) */ xymond_channel_t *datachn = NULL; /* Receives raw "data" messages */ xymond_channel_t *noteschn = NULL; /* Receives raw "notes" messages */ xymond_channel_t *enadischn = NULL; /* Receives "enable" and "disable" messages */ xymond_channel_t *clientchn = NULL; /* Receives "client" messages */ xymond_channel_t *clichgchn = NULL; /* Receives "clichg" messages */ xymond_channel_t *userchn = NULL; /* Receives "usermsg" messages */ static int backfeedqueue = -1; static unsigned long backfeedcount = 0; static char *bf_buf = NULL; static int bf_bufsz = 0; #define NO_COLOR (COL_COUNT) static char *colnames[COL_COUNT+1]; int alertcolors, okcolors; enum alertstate_t { A_OK, A_ALERT, A_UNDECIDED }; typedef struct ghostlist_t { char *name; char *sender; time_t tstamp, matchtime; } ghostlist_t; void *rbghosts; typedef struct multisrclist_t { char *id; char *senders[2]; time_t tstamp; } multisrclist_t; void *rbmultisrc; enum ghosthandling_t ghosthandling = GH_LOG; char *checkpointfn = NULL; FILE *dbgfd = NULL; char *dbghost = NULL; time_t boottimer = 0; int hostcount = 0; char *ackinfologfn = NULL; FILE *ackinfologfd = NULL; char *defaultreddelay = NULL, *defaultyellowdelay = NULL; typedef struct xymond_statistics_t { char *cmd; unsigned long count; } xymond_statistics_t; xymond_statistics_t xymond_stats[] = { { "status", 0 }, { "combo", 0 }, { "extcombo", 0 }, { "page", 0 }, { "summary", 0 }, { "data", 0 }, { "clientlog", 0 }, { "client", 0 }, { "notes", 0 }, { "enable", 0 }, { "disable", 0 }, { "modify", 0 }, { "ack", 0 }, { "config", 0 }, { "query", 0 }, { "xymondboard", 0 }, { "xymondlog", 0 }, { "hostinfo", 0 }, { "drop", 0 }, { "rename", 0 }, { "dummy", 0 }, { "ping", 0 }, { "notify", 0 }, { "schedule", 0 }, { "download", 0 }, { NULL, 0 } }; enum boardfield_t { F_NONE, F_IP, F_HOSTNAME, F_TESTNAME, F_MATCHEDTAG, F_COLOR, F_FLAGS, F_LASTCHANGE, F_LOGTIME, F_VALIDTIME, F_ACKTIME, F_DISABLETIME, F_SENDER, F_COOKIE, F_LINE1, F_ACKMSG, F_DISMSG, F_MSG, F_CLIENT, F_CLIENTTSTAMP, F_ACKLIST, F_HOSTINFO, F_FLAPINFO, F_STATS, F_MODIFIERS, F_LAST }; typedef struct boardfieldnames_t { char *name; enum boardfield_t id; } boardfieldnames_t; boardfieldnames_t boardfieldnames[] = { { "ip", F_IP }, { "hostname", F_HOSTNAME }, { "matchedtag", F_MATCHEDTAG }, { "matchedtags", F_MATCHEDTAG }, { "testname", F_TESTNAME }, { "color", F_COLOR }, { "flags", F_FLAGS }, { "lastchange", F_LASTCHANGE }, { "logtime", F_LOGTIME }, { "validtime", F_VALIDTIME }, { "acktime", F_ACKTIME }, { "disabletime", F_DISABLETIME }, { "sender", F_SENDER }, { "cookie", F_COOKIE }, { "line1", F_LINE1 }, { "ackmsg", F_ACKMSG }, { "dismsg", F_DISMSG }, { "msg", F_MSG }, { "client", F_CLIENT }, { "clntstamp", F_CLIENTTSTAMP }, { "acklist", F_ACKLIST }, { "XMH_", F_HOSTINFO }, { "flapinfo", F_FLAPINFO }, { "stats", F_STATS }, { "modifiers", F_MODIFIERS }, { NULL, F_LAST }, }; typedef struct boardfields_t { enum boardfield_t field; enum xmh_item_t xmhfield; /* Only for field == F_HOSTINFO */ } boardfield_t; enum filtertype_t { FILTER_XMH, FILTER_PAGEPATH, FILTER_TEST, FILTER_FIELD, FILTER_FIELDTIME, FILTER_TAG, FILTER_COLOR, FILTER_ACKLEVEL, FILTER_NOTDOWN, FILTER_DOWN }; /* Filtration comparison flags */ #define COMPARE_GT (1 << 0) #define COMPARE_GE (1 << 1) #define COMPARE_LT (1 << 2) #define COMPARE_LE (1 << 3) #define COMPARE_EQ (1 << 4) #define COMPARE_NE (1 << 5) #define COMPARE_INTVL (1 << 29) typedef struct hostfilter_rec_t { enum filtertype_t filtertype; pcre *wantedptn; int wantedvalue; struct hostfilter_rec_t *next; enum xmh_item_t field; /* Only for filtertype == FILTER_XMH */ enum boardfield_t boardfield; /* Only for filtertype == FILTER_FIELD(TIME) */ unsigned int flags; /* Private filter flags */ xtreePos_t handle; } hostfilter_rec_t; /* Statistics counters */ unsigned long msgs_total = 0; unsigned long msgs_total_last = 0; time_t last_stats_time = 0; /* List of scheduled (future) tasks */ typedef struct scheduletask_t { int id; time_t executiontime; char *command; char *sender; struct scheduletask_t *next; } scheduletask_t; scheduletask_t *schedulehead = NULL; int nextschedid = 1; void update_statistics(char *cmd) { int i; dbgprintf("-> update_statistics\n"); if (!cmd) { dbgprintf("No command for update_statistics\n"); return; } msgs_total++; i = 0; while (xymond_stats[i].cmd && strncmp(xymond_stats[i].cmd, cmd, strlen(xymond_stats[i].cmd))) { i++; } xymond_stats[i].count++; dbgprintf("<- update_statistics\n"); } char *generate_stats(void) { static strbuffer_t *statsbuf = NULL; time_t now = getcurrenttime(NULL); time_t nowtimer = gettimer(); int i, clients; char bootuptxt[40]; char uptimetxt[40]; xtreePos_t ghandle; time_t uptime = (nowtimer - boottimer); time_t boottstamp = (now - uptime); char msgline[2048]; dbgprintf("-> generate_stats\n"); MEMDEFINE(bootuptxt); MEMDEFINE(uptimetxt); if (statsbuf == NULL) { statsbuf = newstrbuffer(8192); } else { clearstrbuffer(statsbuf); } strftime(bootuptxt, sizeof(bootuptxt), "%d-%b-%Y %T", localtime(&boottstamp)); sprintf(uptimetxt, "%d days, %02d:%02d:%02d", (int)(uptime / 86400), (int)(uptime % 86400)/3600, (int)(uptime % 3600)/60, (int)(uptime % 60)); sprintf(msgline, "status %s.xymond %s\nStatistics for Xymon daemon\nVersion: %s\nUp since %s (%s)\n\n", xgetenv("MACHINE"), colorname(errbuf ? COL_YELLOW : COL_GREEN), VERSION, bootuptxt, uptimetxt); addtobuffer(statsbuf, msgline); sprintf(msgline, "Incoming messages : %10ld\n", msgs_total); addtobuffer(statsbuf, msgline); i = 0; while (xymond_stats[i].cmd) { sprintf(msgline, "- %-20s : %10ld\n", xymond_stats[i].cmd, xymond_stats[i].count); addtobuffer(statsbuf, msgline); i++; } sprintf(msgline, "- %-20s : %10ld\n", "Bogus/Timeouts ", xymond_stats[i].count); addtobuffer(statsbuf, msgline); if ((now > last_stats_time) && (last_stats_time > 0)) { sprintf(msgline, "Incoming messages/sec : %10ld (average last %d seconds)\n", ((msgs_total - msgs_total_last) / (now - last_stats_time)), (int)(now - last_stats_time)); addtobuffer(statsbuf, msgline); } msgs_total_last = msgs_total; addtobuffer(statsbuf, "\n"); clients = semctl(statuschn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "status channel messages: %10ld (%d readers)\n", statuschn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(stachgchn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "stachg channel messages: %10ld (%d readers)\n", stachgchn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(pagechn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "page channel messages: %10ld (%d readers)\n", pagechn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(datachn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "data channel messages: %10ld (%d readers)\n", datachn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(noteschn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "notes channel messages: %10ld (%d readers)\n", noteschn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(enadischn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "enadis channel messages: %10ld (%d readers)\n", enadischn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(clientchn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "client channel messages: %10ld (%d readers)\n", clientchn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(clichgchn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "clichg channel messages: %10ld (%d readers)\n", clichgchn->msgcount, clients); addtobuffer(statsbuf, msgline); clients = semctl(userchn->semid, CLIENTCOUNT, GETVAL); sprintf(msgline, "user channel messages: %10ld (%d readers)\n", userchn->msgcount, clients); addtobuffer(statsbuf, msgline); sprintf(msgline, "backfeed messages : %10ld\n", backfeedcount); addtobuffer(statsbuf, msgline); ghandle = xtreeFirst(rbghosts); if (ghandle != xtreeEnd(rbghosts)) addtobuffer(statsbuf, "\n\nGhost reports:\n"); for (; (ghandle != xtreeEnd(rbghosts)); ghandle = xtreeNext(rbghosts, ghandle)) { ghostlist_t *gwalk = (ghostlist_t *)xtreeData(rbghosts, ghandle); /* Skip records older than 10 minutes */ if (gwalk->tstamp < (nowtimer - 600)) continue; sprintf(msgline, " %-15s reported host %s\n", gwalk->sender, htmlquoted(gwalk->name)); addtobuffer(statsbuf, msgline); } ghandle = xtreeFirst(rbmultisrc); if (ghandle != xtreeEnd(rbmultisrc)) addtobuffer(statsbuf, "\n\nMulti-source statuses\n"); for (; (ghandle != xtreeEnd(rbmultisrc)); ghandle = xtreeNext(rbmultisrc, ghandle)) { multisrclist_t *mwalk = (multisrclist_t *)xtreeData(rbmultisrc, ghandle); /* Skip records older than 10 minutes */ if (mwalk->tstamp < (nowtimer - 600)) continue; sprintf(msgline, " %-25s reported by %s and %s\n", mwalk->id, mwalk->senders[0], mwalk->senders[1]); addtobuffer(statsbuf, msgline); } if (errbuf) { addtobuffer(statsbuf, "\n\nLatest error messages:\n"); addtobuffer(statsbuf, prehtmlquoted(errbuf)); addtobuffer(statsbuf, "\n"); } MEMUNDEFINE(bootuptxt); MEMUNDEFINE(uptimetxt); dbgprintf("<- generate_stats\n"); return STRBUF(statsbuf); } char *totalclientmsg(clientmsg_list_t *msglist) { static strbuffer_t *result = NULL; clientmsg_list_t *mwalk; time_t nowtimer = gettimer(); if (!result) result = newstrbuffer(10240); clearstrbuffer(result); for (mwalk = msglist; (mwalk); mwalk = mwalk->next) { if ((mwalk->timestamp + MAX_SUBCLIENT_LIFETIME) < nowtimer) continue; /* Expired data */ addtobuffer_many(result, "\n[collector:", mwalk->collectorid, "]\n", mwalk->msg, NULL); } return STRBUF(result); } enum alertstate_t decide_alertstate(int color) { if ((okcolors & (1 << color)) != 0) return A_OK; else if ((alertcolors & (1 << color)) != 0) return A_ALERT; else return A_UNDECIDED; } char *check_downtime(char *hostname, char *testname) { void *hinfo = hostinfo(hostname); char *dtag; char *holkey; if (hinfo == NULL) return NULL; dtag = xmh_item(hinfo, XMH_DOWNTIME); holkey = xmh_item(hinfo, XMH_HOLIDAYS); if (dtag && *dtag) { static char *downtag = NULL; static unsigned char *cause = NULL; static int causelen = 0; char *s1, *s2, *s3, *s4, *s5, *p; char timetxt[30]; if (downtag) xfree(downtag); if (cause) xfree(cause); p = downtag = strdup(dtag); do { /* Its either DAYS:START:END or SERVICE:DAYS:START:END:CAUSE */ s1 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s2 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s3 = p; p += strcspn(p, ":;,"); if ((*p == ',') || (*p == ';') || (*p == '\0')) { if (*p != '\0') { *p = '\0'; p++; } snprintf(timetxt, sizeof(timetxt), "%s:%s:%s", s1, s2, s3); cause = strdup("Planned downtime"); s1 = "*"; } else if (*p == ':') { *p = '\0'; p++; s4 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s5 = p; p += strcspn(p, ",;"); if (*p != '\0') { *p = '\0'; p++; } snprintf(timetxt, sizeof(timetxt), "%s:%s:%s", s2, s3, s4); getescapestring(s5, &cause, &causelen); } if (within_sla(holkey, timetxt, 0)) { char *onesvc, *buf; if (strcmp(s1, "*") == 0) return cause; onesvc = strtok_r(s1, ",", &buf); while (onesvc) { if (strcmp(onesvc, testname) == 0) return cause; onesvc = strtok_r(NULL, ",", &buf); } /* If we didn't use the "cause" we just created, it must be freed */ if (cause) xfree(cause); } } while (*p); } return NULL; } xymond_hostlist_t *create_hostlist_t(char *hostname, char *ip) { xymond_hostlist_t *hitem; hitem = (xymond_hostlist_t *) calloc(1, sizeof(xymond_hostlist_t)); hitem->hostname = strdup(hostname); strcpy(hitem->ip, ip); if (strcmp(hostname, "summary") == 0) hitem->hosttype = H_SUMMARY; else hitem->hosttype = H_NORMAL; xtreeAdd(rbhosts, hitem->hostname, hitem); return hitem; } testinfo_t *create_testinfo(char *name) { testinfo_t *newrec; newrec = (testinfo_t *)calloc(1, sizeof(testinfo_t)); newrec->name = strdup(name); newrec->clientsave = clientsavedisk; xtreeAdd(rbtests, newrec->name, newrec); return newrec; } void posttochannel(xymond_channel_t *channel, char *channelmarker, char *msg, char *sender, char *hostname, xymond_log_t *log, char *readymsg) { struct sembuf s; int clients; int n; struct timeval tstamp; struct timezone tz; int semerr = 0; unsigned int bufsz = 1024*shbufsz(channel->channelid); void *hi; char *pagepath, *classname, *osname; time_t timeroffset = (getcurrenttime(NULL) - gettimer()); dbgprintf("-> posttochannel\n"); /* First see how many users are on this channel */ clients = semctl(channel->semid, CLIENTCOUNT, GETVAL); if (clients == 0) { dbgprintf("Dropping message - no readers\n"); return; } /* * Wait for BOARDBUSY to go low. * We need a loop here, because if we catch a signal * while waiting on the semaphore, then we need to * re-start the semaphore wait. Otherwise we may * end up with semaphores that are out of sync * (GOCLIENT goes up while a worker waits for it * to go to 0). */ gotalarm = 0; alarm(5); do { s.sem_num = BOARDBUSY; s.sem_op = 0; s.sem_flg = 0; n = semop(channel->semid, &s, 1); if (n == -1) { semerr = errno; if (semerr != EINTR) errprintf("semop failed, %s\n", strerror(errno)); } } while ((n == -1) && (semerr == EINTR) && running && !gotalarm); alarm(0); if (!running) return; /* Check if the alarm fired */ if (gotalarm) { errprintf("BOARDBUSY locked at %d, GETNCNT is %d, GETPID is %d, %d clients\n", semctl(channel->semid, BOARDBUSY, GETVAL), semctl(channel->semid, BOARDBUSY, GETNCNT), semctl(channel->semid, BOARDBUSY, GETPID), semctl(channel->semid, CLIENTCOUNT, GETVAL)); return; } /* Check if we failed to grab the semaphore */ if (n == -1) { errprintf("Dropping message due to semaphore error\n"); return; } /* All clear, post the message */ if (channel->seq == 999999) channel->seq = 0; channel->seq++; channel->msgcount++; gettimeofday(&tstamp, &tz); if (readymsg) { n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s", channelmarker, channel->seq, (hostname ? hostname : "*"), (int) tstamp.tv_sec, (int) tstamp.tv_usec, sender, readymsg); if (n > (bufsz-5)) { char *p, *overmsg = readymsg; *(overmsg+100) = '\0'; p = strchr(overmsg, '\n'); if (p) *p = '\0'; errprintf("Oversize data/client msg from %s truncated (n=%d, limit %d)\nFirst line: %s\n", sender, n, bufsz, overmsg); } *(channel->channelbuf + bufsz - 5) = '\0'; } else { switch(channel->channelid) { case C_STATUS: hi = hostinfo(hostname); pagepath = (hi ? xmh_item(hi, XMH_ALLPAGEPATHS) : ""); classname = (hi ? xmh_item(hi, XMH_CLASS) : ""); if (!classname) classname = ""; n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%s|%s|%d|%s|%s|%s|%d", channelmarker, channel->seq, hostname, /* 0 */ (int) tstamp.tv_sec, (int) tstamp.tv_usec, /* 1 */ sender, /* 2 */ log->origin, /* 3 */ hostname, /* 4 */ log->test->name, /* 5 */ (int) log->validtime, /* 6 */ colnames[log->color], /* 7 */ (log->testflags ? log->testflags : ""), /* 8 */ colnames[log->oldcolor], /* 9 */ (int) log->lastchange[0]); /* 10 */ if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d|%s", /* 11+12 */ (int)log->acktime, nlencode(log->ackmsg)); } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d|%s", /* 13+14 */ (int)log->enabletime, nlencode(log->dismsg)); } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d", /* 15 */ (int)(log->host->clientmsgtstamp + timeroffset)); } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%s", classname); /* 16 */ } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%s", pagepath); /* 17 */ } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d", /* 18 */ (int)log->flapping); } if (n < (bufsz-5)) { modifier_t *mwalk; n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|"); mwalk = log->modifiers; /* 19 */ while ((n < (bufsz-5)) && mwalk) { if (mwalk->valid > 0) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "%s", nlencode(mwalk->cause)); } mwalk = mwalk->next; } } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "\n%s", msg); } if (n > (bufsz-5)) { errprintf("Oversize status msg from %s for %s:%s truncated (n=%d, limit=%d)\n", sender, hostname, log->test->name, n, bufsz); } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_STACHG: n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%s|%s|%d|%s|%s|%d", channelmarker, channel->seq, hostname, /* 0 */ (int) tstamp.tv_sec, (int) tstamp.tv_usec, /* 1 */ sender, /* 2 */ log->origin, /* 3 */ hostname, /* 4 */ log->test->name, /* 5 */ (int) log->validtime, /* 6 */ colnames[log->color], /* 7 */ colnames[log->oldcolor], /* 8 */ (int) log->lastchange[0]) /* 9 */; if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d|%s", /* 10+11 */ (int)log->enabletime, nlencode(log->dismsg)); } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d", /* 12 */ log->downtimeactive); } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|%d", /* 13 */ (int) (log->host->clientmsgtstamp + timeroffset)); } if (n < (bufsz-5)) { modifier_t *mwalk; n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|"); mwalk = log->modifiers; /* 14 */ while ((n < (bufsz-5)) && mwalk) { if (mwalk->valid > 0) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "%s", nlencode(mwalk->cause)); } mwalk = mwalk->next; } } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "\n%s", msg); } if (n > (bufsz-5)) { errprintf("Oversize stachg msg from %s for %s:%s truncated (n=%d, limit=%d)\n", sender, hostname, log->test->name, n, bufsz); } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_CLICHG: n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%d\n%s", channelmarker, channel->seq, hostname, (int) tstamp.tv_sec, (int) tstamp.tv_usec, sender, hostname, (int) (log->host->clientmsgtstamp + timeroffset), totalclientmsg(log->host->clientmsgs)); if (n > (bufsz-5)) { errprintf("Oversize clichg msg from %s for %s truncated (n=%d, limit=%d)\n", sender, hostname, n, bufsz); } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_PAGE: if (strcmp(channelmarker, "ack") == 0) { n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%s|%s|%d\n%s", channelmarker, channel->seq, hostname, (int) tstamp.tv_sec, (int) tstamp.tv_usec, sender, hostname, log->test->name, log->host->ip, (int) log->acktime, msg); } else { hi = hostinfo(hostname); pagepath = (hi ? xmh_item(hi, XMH_ALLPAGEPATHS) : ""); classname = (hi ? xmh_item(hi, XMH_CLASS) : ""); osname = (hi ? xmh_item(hi, XMH_OS) : ""); if (!classname) classname = ""; if (!osname) osname = ""; n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%s|%s|%d|%s|%s|%d|%s|%s|%s|%s|%s", channelmarker, channel->seq, hostname, (int) tstamp.tv_sec, (int) tstamp.tv_usec, sender, hostname, log->test->name, log->host->ip, (int) log->validtime, colnames[log->color], colnames[log->oldcolor], (int) log->lastchange[0], pagepath, (log->cookie ? log->cookie : ""), osname, classname, (log->grouplist ? log->grouplist : "")); if (n < (bufsz-5)) { modifier_t *mwalk; n += snprintf(channel->channelbuf+n, (bufsz-n-5), "|"); mwalk = log->modifiers; while ((n < (bufsz-5)) && mwalk) { if (mwalk->valid > 0) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "%s", nlencode(mwalk->cause)); } mwalk = mwalk->next; } } if (n < (bufsz-5)) { n += snprintf(channel->channelbuf+n, (bufsz-n-5), "\n%s", msg); } } if (n > (bufsz-5)) { errprintf("Oversize page/ack/notify msg from %s for %s:%s truncated (n=%d, limit=%d)\n", sender, hostname, (log->test->name ? log->test->name : ""), n, bufsz); } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_DATA: case C_CLIENT: /* Data channel messages are pre-formatted so we never go here */ break; case C_NOTES: case C_USER: n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s\n%s", channelmarker, channel->seq, hostname, (int) tstamp.tv_sec, (int) tstamp.tv_usec, sender, hostname, msg); if (n > (bufsz-5)) { errprintf("Oversize %s msg from %s for %s truncated (n=%d, limit=%d)\n", ((channel->channelid == C_NOTES) ? "notes" : "user"), sender, hostname, n, bufsz); } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_ENADIS: { char *dism = ""; if (log->dismsg) dism = nlencode(log->dismsg); n = snprintf(channel->channelbuf, (bufsz-5), "@@%s#%u/%s|%d.%06d|%s|%s|%s|%d|%s", channelmarker, channel->seq, hostname, (int) tstamp.tv_sec, (int)tstamp.tv_usec, sender, hostname, log->test->name, (int) log->enabletime, dism); if (n > (bufsz-5)) { errprintf("Oversize enadis msg from %s for %s:%s truncated (n=%d, limit=%d)\n", sender, hostname, log->test->name, n, bufsz); } } *(channel->channelbuf + bufsz - 5) = '\0'; break; case C_FEEDBACK_QUEUE: case C_LAST: break; } } /* Terminate the message */ strncat(channel->channelbuf, "\n@@\n", (bufsz-1)); /* Let the readers know it is there. */ clients = semctl(channel->semid, CLIENTCOUNT, GETVAL); /* Get it again, maybe changed since last check */ dbgprintf("Posting message %u to %d readers\n", channel->seq, clients); /* Up BOARDBUSY */ s.sem_num = BOARDBUSY; s.sem_op = (clients - semctl(channel->semid, BOARDBUSY, GETVAL)); if (s.sem_op <= 0) { errprintf("How did this happen? clients=%d, s.sem_op=%d\n", clients, s.sem_op); s.sem_op = clients; } s.sem_flg = 0; n = semop(channel->semid, &s, 1); /* Make sure GOCLIENT is 0 */ n = semctl(channel->semid, GOCLIENT, GETVAL); if (n > 0) { errprintf("Oops ... GOCLIENT is high (%d)\n", n); } s.sem_num = GOCLIENT; s.sem_op = clients; s.sem_flg = 0; /* Up GOCLIENT */ n = semop(channel->semid, &s, 1); dbgprintf("<- posttochannel\n"); return; } void posttoall(char *msg) { posttochannel(statuschn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(stachgchn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(pagechn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(datachn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(noteschn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(enadischn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(clientchn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(clichgchn, msg, NULL, "xymond", NULL, NULL, ""); posttochannel(userchn, msg, NULL, "xymond", NULL, NULL, ""); } char *log_ghost(char *hostname, char *sender, char *msg) { xtreePos_t ghandle; ghostlist_t *gwalk; char *result = NULL; time_t nowtimer = gettimer(); dbgprintf("-> log_ghost\n"); /* If debugging, log the full request */ if (dbgfd) { fprintf(dbgfd, "\n---- combo message from %s ----\n%s---- end message ----\n", sender, msg); fflush(dbgfd); } if ((hostname == NULL) || (sender == NULL)) return NULL; ghandle = xtreeFind(rbghosts, hostname); gwalk = (ghandle != xtreeEnd(rbghosts)) ? (ghostlist_t *)xtreeData(rbghosts, ghandle) : NULL; /* Disallow weird test names - Note: a future version may restrict these to valid hostname + DNS labels and not preserve case */ if (!gwalk && (strlen(hostname) != strspn(hostname, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:,._-")) ) { errprintf("Bogus message from %s: Invalid new hostname '%s'\n", sender, hostname); return NULL; } if ((gwalk == NULL) || ((gwalk->matchtime + 600) < nowtimer)) { int found = 0; if (ghosthandling == GH_MATCH) { /* See if we can find this host just by ignoring domains */ char *hostnodom, *p; void *hrec; hostnodom = strdup(hostname); p = strchr(hostnodom, '.'); if (p) *p = '\0'; for (hrec = first_host(); (hrec && !found); hrec = next_host(hrec, 0)) { char *candname; candname = xmh_item(hrec, XMH_HOSTNAME); p = strchr(candname, '.'); if (p) *p = '\0'; found = (strcasecmp(hostnodom, candname) == 0); if (p) *p = '.'; if (found) { result = candname; xmh_set_item(hrec, XMH_CLIENTALIAS, hostname); errprintf("Matched ghost '%s' to host '%s'\n", hostname, result); } } } if (!found) { if (gwalk == NULL) { gwalk = (ghostlist_t *)calloc(1, sizeof(ghostlist_t)); gwalk->name = strdup(hostname); gwalk->sender = strdup(sender); gwalk->tstamp = gwalk->matchtime = nowtimer; xtreeAdd(rbghosts, gwalk->name, gwalk); } else { if (gwalk->sender) xfree(gwalk->sender); gwalk->sender = strdup(sender); gwalk->tstamp = gwalk->matchtime = nowtimer; } } } else { if (gwalk->sender) xfree(gwalk->sender); gwalk->sender = strdup(sender); gwalk->tstamp = nowtimer; } dbgprintf("<- log_ghost\n"); return result; } void log_multisrc(xymond_log_t *log, char *newsender) { xtreePos_t ghandle; multisrclist_t *gwalk; char id[1024]; dbgprintf("-> log_multisrc\n"); snprintf(id, sizeof(id), "%s:%s", log->host->hostname, log->test->name); ghandle = xtreeFind(rbmultisrc, id); if (ghandle == xtreeEnd(rbmultisrc)) { gwalk = (multisrclist_t *)calloc(1, sizeof(multisrclist_t)); gwalk->id = strdup(id); gwalk->senders[0] = strdup(log->sender); gwalk->senders[1] = strdup(newsender); gwalk->tstamp = gettimer(); xtreeAdd(rbmultisrc, gwalk->id, gwalk); } else { gwalk = (multisrclist_t *)xtreeData(rbmultisrc, ghandle); xfree(gwalk->senders[0]); gwalk->senders[0] = strdup(log->sender); xfree(gwalk->senders[1]); gwalk->senders[1] = strdup(newsender); gwalk->tstamp = gettimer(); } dbgprintf("<- log_multisrc\n"); } xymond_log_t *find_log(hostfilter_rec_t *filter, xymond_hostlist_t **host) { hostfilter_rec_t *fwalk; xymond_hostlist_t *hrec = NULL; testinfo_t *trec = NULL; xymond_log_t *lwalk; *host = NULL; if (!filter) return NULL; for (fwalk = filter; (fwalk); fwalk = fwalk->next) { switch(fwalk->filtertype) { case FILTER_XMH: if ((fwalk->field == XMH_HOSTNAME) && (fwalk->handle != xtreeEnd(rbhosts))) *host = hrec = xtreeData(rbhosts, fwalk->handle); break; case FILTER_TEST: if (fwalk->handle != xtreeEnd(rbtests)) trec = xtreeData(rbtests, fwalk->handle); break; default: break; } } if (!hrec || !trec) return NULL; for (lwalk = hrec->logs; (lwalk && (lwalk->test != trec)); lwalk = lwalk->next); return lwalk; } int accept_test(void *hrec, char *testname) { char *accept = xmh_item(hrec, XMH_ACCEPT_ONLY); char *p, *endp; if (!accept || !testname || !(*testname)) return 1; p = strstr(accept, testname); if (p) { int testlength = strlen(testname); while (p) { /* * p points to where the testname is in the accept string. Must check that it * points to a full word. * * Check : * - if p points at (beginning of accept string, or there is a ',' right before p) AND * - (p+strlen(testname) hits end of accept string, or it hits a ',') */ endp = p + testlength; if (((*endp == '\0') || (*endp == ',')) && ((p == accept) || (*(p-1) == ','))) return 1; /* no match, keep looking */ p = strstr(endp, testname); } } return 0; } void get_hts(char *msg, char *sender, char *origin, xymond_hostlist_t **host, testinfo_t **test, char **grouplist, xymond_log_t **log, int *color, char **downcause, int *alltests, int createhost, int createlog) { /* * This routine takes care of finding existing status log records, or * (if they don't exist) creating new ones for an incoming status. * * "msg" contains an incoming message. First list is of the form "KEYWORD host,domain.test COLOR" */ char *firstline, *p; char *hosttest, *hostname, *testname, *colstr, *grp; char hostip[IP_ADDR_STRLEN]; xtreePos_t hosthandle, testhandle, originhandle; xymond_hostlist_t *hwalk = NULL; testinfo_t *twalk = NULL; int is_summary = 0; char *owalk = NULL; xymond_log_t *lwalk = NULL; dbgprintf("-> get_hts\n"); MEMDEFINE(hostip); *hostip = '\0'; *host = NULL; *test = NULL; *log = NULL; *color = -1; if (grouplist) *grouplist = NULL; if (downcause) *downcause = NULL; if (alltests) *alltests = 0; hosttest = hostname = testname = colstr = grp = NULL; p = strchr(msg, '\n'); if (p == NULL) { firstline = strdup(msg); } else { *p = '\0'; firstline = strdup(msg); *p = '\n'; } p = strtok(firstline, " \t"); /* Keyword ... */ if (p) { /* There might be a group-list */ grp = strstr(p, "/group:"); if (grp) grp += 7; } if (p) hosttest = strtok(NULL, " \t"); /* ... HOST.TEST combo ... */ if (hosttest == NULL) goto done; colstr = strtok(NULL, " \t"); /* ... and the color (if any) */ if (colstr) { *color = parse_color(colstr); /* Don't create log-entries if we get a bad color spec. */ if (*color == -1) createlog = 0; } else createlog = 0; if (strncmp(msg, "summary", 7) == 0) { /* Summary messages are handled specially */ hostname = hosttest; /* This will always be "summary" */ testname = strchr(hosttest, '.'); if (testname) { *testname = '\0'; testname++; } is_summary = 1; } else { char *knownname; hostname = hosttest; testname = strrchr(hosttest, '.'); if (testname) { *testname = '\0'; testname++; } uncommafy(hostname); /* For BB agent compatibility */ knownname = knownhost(hostname, hostip, ghosthandling); if (knownname == NULL) { knownname = log_ghost(hostname, sender, msg); if (knownname == NULL) goto done; } hostname = knownname; } hosthandle = xtreeFind(rbhosts, hostname); if (hosthandle == xtreeEnd(rbhosts)) hwalk = NULL; else hwalk = xtreeData(rbhosts, hosthandle); if (createhost && (hosthandle == xtreeEnd(rbhosts))) { hwalk = create_hostlist_t(hostname, hostip); hostcount++; } if (testname && *testname) { if (alltests && (*testname == '*')) { *alltests = 1; return; } testhandle = xtreeFind(rbtests, testname); if (testhandle != xtreeEnd(rbtests)) twalk = xtreeData(rbtests, testhandle); /* Disallow new, weird test names - Note: a future version of Xymon may restrict this further and not preserve case */ /* NB: Summary messages are stored under the pseudo-host 'summary' but have invalid test names unpacked by xymongen */ if (!twalk && !is_summary && (strlen(testname) != strspn(testname, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:\\/_-")) ) { errprintf("Bogus message from %s: Invalid new testname '%s'\n", sender, testname); return; } if (createlog && (twalk == NULL)) twalk = create_testinfo(testname); } else { if (createlog) errprintf("Bogus message from %s: No testname '%s'\n", sender, msg); } if (origin) { originhandle = xtreeFind(rborigins, origin); if (originhandle != xtreeEnd(rborigins)) owalk = xtreeData(rborigins, originhandle); if (createlog && (owalk == NULL)) { owalk = strdup(origin); xtreeAdd(rborigins, owalk, owalk); } } if (hwalk && twalk && owalk) { for (lwalk = hwalk->logs; (lwalk && ((lwalk->test != twalk) || (lwalk->origin != owalk))); lwalk = lwalk->next); if (createlog && (lwalk == NULL)) { lwalk = (xymond_log_t *)calloc(1, sizeof(xymond_log_t)); lwalk->lastchange = (time_t *)calloc((flapcount > 0) ? flapcount : 1, sizeof(time_t)); lwalk->lastchange[0] = getcurrenttime(NULL); lwalk->color = lwalk->oldcolor = NO_COLOR; lwalk->host = hwalk; lwalk->test = twalk; lwalk->origin = owalk; lwalk->next = hwalk->logs; hwalk->logs = lwalk; if (strcmp(testname, xgetenv("PINGCOLUMN")) == 0) hwalk->pinglog = lwalk; } } done: if (colstr) { if ((*color == COL_RED) || (*color == COL_YELLOW) || (*color == COL_PURPLE)) { char *cause; cause = check_downtime(hostname, testname); if (lwalk) lwalk->downtimeactive = (cause != NULL); if (cause) *color = COL_BLUE; if (downcause) *downcause = cause; } else { if (lwalk) lwalk->downtimeactive = 0; } } if (grouplist && grp) *grouplist = strdup(grp); xfree(firstline); *host = hwalk; *test = twalk; *log = lwalk; MEMUNDEFINE(hostip); dbgprintf("<- get_hts\n"); } void clear_cookie(xymond_log_t *log) { if (!log->cookie) return; xtreeDelete(rbcookies, log->cookie); xfree(log->cookie); log->cookie = NULL; log->cookieexpires = 0; } xymond_log_t *find_cookie(char *cookie) { /* * Find a cookie we have issued. */ xymond_log_t *result = NULL; xtreePos_t cookiehandle; dbgprintf("-> find_cookie\n"); cookiehandle = xtreeFind(rbcookies, cookie); if (cookiehandle != xtreeEnd(rbcookies)) { result = xtreeData(rbcookies, cookiehandle); if (result->cookieexpires <= getcurrenttime(NULL)) { clear_cookie(result); result = NULL; } } dbgprintf("<- find_cookie\n"); return result; } static int changedelay(void *hinfo, int newcolor, char *testname, int currcolor) { char *key, *tok, *dstr = NULL; int keylen, result = 0; /* Ignore any delays when we start with a purple status */ if (currcolor == COL_PURPLE) return 0; switch (newcolor) { case COL_RED: dstr = xmh_item(hinfo, XMH_DELAYRED); if (!dstr) dstr = defaultreddelay; break; case COL_YELLOW: dstr = xmh_item(hinfo, XMH_DELAYYELLOW); if (!dstr) dstr = defaultyellowdelay; break; default: break; } if (!dstr) return result; /* Check "DELAYRED=cpu:10,disk:30,ssh:20" - number is in minutes */ keylen = strlen(testname) + 1; key = (char *)malloc(keylen + 1); sprintf(key, "%s:", testname); dstr = strdup(dstr); tok = strtok(dstr, ","); while (tok && (strncmp(key, tok, keylen) != 0)) tok = strtok(NULL, ","); if (tok) result = 60*atoi(tok+keylen); /* Convert to seconds */ xfree(key); xfree(dstr); return result; } static int isset_noflap(void *hinfo, char *testname, char *hostname) { char *tok, *dstr; int keylen; dstr = xmh_item(hinfo, XMH_NOFLAP); if (!dstr) return 0; /* no 'noflap' set */ /* Check bare noflap (disable for host) vs "noflap=test1,test2" */ /* A bare noflap will be set equal to the key itself (usually NOFLAP) like a flag */ if (strcmp(dstr, "NOFLAP") == 0) return 1; /* if not 'NOFLAP', we should receive "=test1,test2". Skip the = */ if (*dstr == '=') dstr++; keylen = strlen(testname); tok = strtok(dstr, ","); while (tok && (strncmp(testname, tok, keylen) != 0)) tok = strtok(NULL, ","); if (!tok) return 0; /* specifies noflap, but this test is not in the list */ /* do not use flapping for the test */ dbgprintf("Ignoring flapping for %s:%s due to noflap set.\n", hostname, testname); return 1; } void handle_status(unsigned char *msg, char *sender, char *hostname, char *testname, char *grouplist, xymond_log_t *log, int newcolor, char *downcause, int modifyonly) { int validity = defaultvalidity; time_t now = getcurrenttime(NULL); int msglen, issummary; enum alertstate_t oldalertstatus, newalertstatus; int delayval = 0; void *hinfo = hostinfo(hostname); dbgprintf("->handle_status\n"); if (msg == NULL) { errprintf("handle_status got a NULL message for %s.%s, sender %s, color %s\n", textornull(hostname), textornull(testname), textornull(sender), colorname(newcolor)); return; } msglen = strlen(msg); if (msglen == 0) { errprintf("Bogus status message for %s.%s contains no data: Sent from %s\n", textornull(hostname), textornull(testname), textornull(sender)); return; } if (msg_data(msg, 0) == (char *)msg, 0) { errprintf("Bogus status message: msg_data finds no host.test. Sent from: '%s', data:'%s'\n", sender, msg); return; } /* XXX: TODO: Needs revisiting; get_hts() has already run, so * we're leaving test record debris around */ /* Check if disallowed, but let internally-generated messages through */ /* Otherwise existing tests never go purple */ // if ((strcmp(sender, "xymond") != 0) && !accept_test(hinfo, testname)) { // dbgprintf("Rejected status message for %s.%s sent from %s\n", // textornull(hostname), textornull(testname), textornull(sender)); // return; // } issummary = (log->host->hosttype == H_SUMMARY); if (strncmp(msg, "status+", 7) == 0) { validity = durationvalue(msg+7); } if (!modifyonly && log->modifiers) { /* * Original status message - check if there is an active modifier for the color. * We don't do this for status changes triggered by a "modify" command. */ modifier_t *mwalk; modifier_t *mlast; int mcolor = -1; mlast = NULL; mwalk = log->modifiers; while (mwalk) { mwalk->valid--; if (mwalk->valid <= 0) { modifier_t *zombie; /* Modifier no longer valid */ zombie = mwalk; if (zombie->source) xfree(zombie->source); if (zombie->cause) xfree(zombie->cause); /* Remove this modifier from the list. Make sure log->modifiers is updated */ if (mwalk == log->modifiers) log->modifiers = mwalk->next; /* ... link the previous entry to the next, since we're about to free the current record */ if (mlast) mlast->next = mwalk->next; mwalk = mwalk->next; xfree(zombie); } else { if (mwalk->color > mcolor) mcolor = mwalk->color; mlast = mwalk; mwalk = mwalk->next; } } /* If there was an active modifier, this overrides the current "newcolor" status value */ if ((mcolor != -1) && (mcolor != newcolor)) newcolor = mcolor; } /* * Flap check. * * We check if more than flapcount changes have occurred * within "flapthreshold" seconds. If yes, and the newcolor * is less serious than the old color, then we ignore the * color change and keep the status at the more serious level. */ if (modifyonly || issummary) { /* Nothing */ } else if ((flapcount > 0) && ((now - log->lastchange[flapcount-1]) < flapthreshold) && (!isset_noflap(hinfo, testname, hostname))) { if (!log->flapping) { errprintf("Flapping detected for %s:%s - %d changes in %d seconds\n", hostname, testname, flapcount, (now - log->lastchange[flapcount-1])); log->flapping = 1; log->oldflapcolor = log->color; log->currflapcolor = newcolor; } else { log->oldflapcolor = log->currflapcolor; log->currflapcolor = newcolor; } /* Make sure we maintain the most critical level reported by the flapping unit */ if (newcolor < log->color) newcolor = log->color; /* * If the status is actually changing, but we've detected it's a * flap and therefore suppress atatus change events, then we must * update the lastchange-times here because it won't be done in * the status-change handler. */ if ((log->oldflapcolor != log->currflapcolor) && (newcolor == log->color)) { int i; for (i=flapcount-1; (i > 0); i--) log->lastchange[i] = log->lastchange[i-1]; log->lastchange[0] = now; } } else { log->flapping = 0; } if (log->enabletime == DISABLED_UNTIL_OK) { /* The test is disabled until we get an OK status */ if ((newcolor != COL_BLUE) && (decide_alertstate(newcolor) == A_OK)) { /* It's OK now - clear the disable status */ log->enabletime = 0; if (log->dismsg) { xfree(log->dismsg); log->dismsg = NULL; } posttochannel(enadischn, channelnames[C_ENADIS], msg, sender, log->host->hostname, log, NULL); } else { /* Still not OK - keep it BLUE */ newcolor = COL_BLUE; } } else if (log->enabletime > now) { /* The test is currently disabled. */ newcolor = COL_BLUE; } else if (log->enabletime) { /* A disable has expired. Clear the timestamp and the message buffer */ log->enabletime = 0; if (log->dismsg) { xfree(log->dismsg); log->dismsg = NULL; } posttochannel(enadischn, channelnames[C_ENADIS], msg, sender, log->host->hostname, log, NULL); } else { /* If we got a downcause, and the status is not disabled, use downcause as the disable text */ if (log->dismsg) { xfree(log->dismsg); log->dismsg = NULL; } if (downcause && (newcolor == COL_BLUE)) log->dismsg = strdup(downcause); } if (log->acktime) { /* Handling of ack'ed tests */ if (decide_alertstate(newcolor) == A_OK) { /* The test recovered. Clear the ack. */ log->acktime = 0; log->maxackedcolor = 0; } if (ackeachcolor && (log->maxackedcolor < newcolor)) { /* Severity has increased above the one that was acked. Clear the current ack */ log->acktime = 0; } if (log->acktime > now) { /* Don't need to do anything about an acked test */ } else { /* The acknowledge has expired. Clear the timestamp and the message buffer */ log->acktime = 0; log->maxackedcolor = 0; if (log->ackmsg) { xfree(log->ackmsg); log->ackmsg = NULL; } } } if (!modifyonly) { log->logtime = now; /* * Decide how long this status is valid. * * Normally we'll just set the valid time according * to the validity of the status report. * * If the status is acknowledged, make it valid for the longest period * of the acknowledgment and the normal validity (so an acknowledged status * does not go purple because it is not being updated due to the host being down). * * Same tweak must be done for disabled tests. */ log->validtime = now + validity*60; if (log->acktime && (log->acktime > log->validtime)) log->validtime = log->acktime; if (log->enabletime) { if (log->enabletime == DISABLED_UNTIL_OK) log->validtime = INT_MAX; else if (log->enabletime > log->validtime) log->validtime = log->enabletime; } else if ((newcolor == COL_PURPLE) && (xmh_item(hinfo, XMH_DOWNTIME) != NULL) ) { /* * If DOWNTIME is configured, we don't want to wait the default amount of time * to re-scan for validity. */ log->validtime = now + 60; } /* * If we have an existing status, check if the sender has changed. * This could be an indication of a mis-configured host reporting with * the wrong hostname. */ if (*(log->sender) && (strcmp(log->sender, sender) != 0)) { /* * There are a few exceptions: * - if sender is "xymond", then this is an internal update, e.g. a status going purple. * - if the host has "pulldata" enabled, then the sender shows up as the host doing the * data collection, so it does not make sense to check it (thanks to Cade Robinson). * - some multi-homed hosts use a random IP for sending us data. */ if ( (strcmp(log->sender, "xymond") != 0) && (strcmp(sender, "xymond") != 0) && (strcmp(sender, "0.0.0.0") != 0)) { if ((xmh_item(hinfo, XMH_PULLDATA) == NULL) && (xmh_item(hinfo, XMH_FLAG_MULTIHOMED) == NULL)) { log_multisrc(log, sender); } } } strncpy(log->sender, sender, sizeof(log->sender)-1); *(log->sender + sizeof(log->sender) - 1) = '\0'; } /* Handle delayed red/yellow */ switch (newcolor) { case COL_RED: if (log->redstart == 0) log->redstart = now; /* * Do NOT clear yellowstart. If we changed green->red, then it is already clear. * When changing yellow->red, we may drop down to yellow again later and then we * want to count the red time as part of the yellow status. * But do set yellowstart if it is 0. If we go green->red now, and then later * red->yellow, we do want it to look as if the yellow began when the red status * happened. */ if (log->yellowstart == 0) log->yellowstart = now; break; case COL_YELLOW: if (log->yellowstart == 0) log->yellowstart = now; log->redstart = 0; /* Clear it here, so brief red's from a yellow state does not trigger red */ break; default: log->yellowstart = log->redstart = 0; break; } if ((newcolor == COL_RED) && ((delayval = changedelay(hinfo, COL_RED, testname, log->color)) > 0)) { if ((now - log->redstart) >= delayval) { /* Time's up - we will go red */ } else { delayval = changedelay(hinfo, COL_YELLOW, testname, log->color); if ((now - log->redstart) >= delayval) { /* The yellow delay has been passed, so go yellow */ newcolor = COL_YELLOW; } else { /* Neither yellow nor red delay passed - keep current color */ newcolor = log->color; } } } else if ((newcolor == COL_YELLOW) && ((delayval = changedelay(hinfo, COL_YELLOW, testname, log->color)) > 0)) { if ((now - log->yellowstart) < delayval) newcolor = log->color; /* Keep current color */ } log->oldcolor = log->color; log->color = newcolor; oldalertstatus = decide_alertstate(log->oldcolor); newalertstatus = decide_alertstate(newcolor); /* grouplist and log->grouplist can point to the same address.. */ if (log->grouplist && log->grouplist != grouplist) xfree(log->grouplist); if (grouplist && !log->grouplist) log->grouplist = strdup(grouplist); if (log->acklist) { ackinfo_t *awalk; if ((oldalertstatus != A_OK) && (newalertstatus == A_OK)) { /* The status recovered. Set the "clearack" timer, unless it is just because we are in a DOWNTIME period */ if (!log->downtimeactive) { time_t cleartime = now + ACKCLEARDELAY; for (awalk = log->acklist; (awalk); awalk = awalk->next) awalk->cleartime = cleartime; } } else if ((oldalertstatus == A_OK) && (newalertstatus != A_OK)) { /* The status went into a failure-mode. Any acks are revived */ for (awalk = log->acklist; (awalk); awalk = awalk->next) awalk->cleartime = awalk->validuntil; } } if (msg != log->message) { /* They can be the same when called from handle_enadis() or check_purple_status() */ char *p; /* * Note here: * - log->msgsz is the buffer size INCLUDING the final \0. * - msglen is the message length WITHOUT the final \0. */ if ((log->message == NULL) || (log->msgsz == 0)) { /* No buffer - get one */ log->message = (unsigned char *)malloc(msglen+1); memcpy(log->message, msg, msglen+1); log->msgsz = msglen+1; } else if (log->msgsz > msglen) { /* Message - including \0 - fits into the existing buffer. */ memcpy(log->message, msg, msglen+1); } else { /* Message does not fit into existing buffer. Grow it. */ log->message = (unsigned char *)realloc(log->message, msglen+1); memcpy(log->message, msg, msglen+1); log->msgsz = msglen+1; } /* Get at the test flags. They are immediately after the color */ p = msg_data(msg, 0); p += strlen(colorname(newcolor)); if (strncmp(p, " End-of-file */ ioerror = 1; dbgprintf("get_xymond_message: Returning NULL due to EOF\n"); return NULL; } else { /* * Got data - null-terminate it, and update fillpos */ dbgprintf("Got %d bytes\n", res); *(fillpos+res) = '\0'; fillpos += res; /* Did we get an end-of-message marker ? Then we're done. */ endpos = strstr(endsrch, "\n@@\n"); needmoredata = (endpos == NULL); /* * If not done, update endsrch. We need to look at the * last 3 bytes of input we got - they could be "\n@@" so * all that is missing is the final "\n". */ if (needmoredata && (res >= 3)) endsrch = fillpos-3; } } } } /* We have a complete message between startpos and endpos */ result = startpos; *endpos = '\0'; if (truncated) { startpos = fillpos = buf; endpos = NULL; } else { startpos = endpos+4; /* +4 because we skip the "\n@@\n" end-marker from the previous message */ endpos = strstr(startpos, "\n@@\n"); /* To see if we already have a full message loaded */ /* fillpos stays where it is */ } /* Check that it really is a message, and not just some garbled data */ if (strncmp(result, "@@", 2) != 0) { errprintf("Dropping (more) garbled data\n"); goto startagain; } { /* * Get and check the message sequence number. * We don't do this for network based workers, since the * sequence number is globally generated (by xymond) * but a network-based worker may only see some of the * messages (those that are not handled by other network-based * worker modules). */ char *p = result + strcspn(result, "#/|\n"); if (*p == '#') { *seq = atoi(p+1); if (debug) { p = strchr(result, '\n'); if (p) *p = '\0'; dbgprintf("%s: Got message %u %s\n", id, *seq, result); if (p) *p = '\n'; } if ((seqnum == 0) || (*seq == (seqnum + 1))) { /* First message, or the correct sequence # */ seqnum = *seq; } else if (*seq == seqnum) { /* Duplicate message - drop it */ errprintf("%s: Duplicate message %d dropped\n", id, *seq); goto startagain; } else { /* * Out-of-sequence message. Cant do much except accept it. * Since xymond_channel filters out some messages, messages * may be missing. We really could do without the sequence * numbers now, I think. */ seqnum = *seq; } if (seqnum == 999999) seqnum = 0; } } /* Verify checksum - except for truncated messages, where it won't match since we overwrite bytes with the end-marker */ if (result && !truncated) { static struct digestctx_t *ctx = NULL; char *hashstr; if (!ctx) { ctx = (digestctx_t *) malloc(sizeof(digestctx_t)); ctx->digestname = strdup("md5"); ctx->digesttype = D_MD5; ctx->mdctx = (void *)malloc(myMD5_Size()); } hashstr = result + strcspn(result, ":#/|\n"); if (*hashstr == ':') { unsigned char md_value[16]; char md_string[2*16+1]; int i; char *p; myMD5_Init(ctx->mdctx); myMD5_Update(ctx->mdctx, result, (hashstr - result)); myMD5_Update(ctx->mdctx, hashstr + 33, strlen(hashstr + 33)); myMD5_Update(ctx->mdctx, "\n@@\n", 4); /* Stripped earlier */ myMD5_Final(md_value, ctx->mdctx); for(i = 0, p = md_string; (i < sizeof(md_value)); i++) p += sprintf(p, "%02x", md_value[i]); *p = '\0'; if (memcmp(hashstr+1, md_string, 32) != 0) { p = strchr(result, '\n'); if (p) *(p+1) = '\0'; errprintf("get_xymond_message: Invalid checksum, skipping message '%s'\n", result); result = NULL; goto startagain; } } } dbgprintf("startpos %ld, fillpos %ld, endpos %ld\n", (startpos-buf), (fillpos-buf), (endpos ? (endpos-buf) : -1)); return result; } xymon-4.3.30/xymond/do_rrd.h0000664000076400007640000000241712173472453016157 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DO_RRD_H__ #define __DO_RRD_H__ #include #include "libxymon.h" extern char *rrddir; extern char *trackmax; extern int use_rrd_cache; extern int no_rrd; extern void setup_exthandler(char *handlerpath, char *ids); extern void update_rrd(char *hostname, char *testname, char *restofmsg, time_t tstamp, char *sender, xymonrrd_t *ldef, char *classname, char *pagepaths); extern void rrdcacheflushall(void); extern void rrdcacheflushhost(char *hostname); extern void setup_extprocessor(char *cmd); extern void shutdown_extprocessor(void); #endif xymon-4.3.30/xymond/combostatus.c0000664000076400007640000003063713533557517017257 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon combination test tool. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: combostatus.c 8106 2019-09-03 21:46:55Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "version.h" #include "libxymon.h" typedef struct value_t { char *symbol; int color; struct value_t *next; } value_t; typedef struct testspec_t { char *reshostname; char *restestname; char *expression; char *comment; char *resultexpr; value_t *valuelist; long result; char *errbuf; struct testspec_t *next; } testspec_t; static testspec_t *testhead = NULL; static int testcount = 0; static int errorcolors = (1 << COL_RED); static char *gethname(char *spec) { static char *result = NULL; char *p; if (result) xfree(result); /* grab the hostname part from a "www.xxx.com.testname" string */ p = strrchr(spec, '.'); if (!p) { errprintf("Item '%s' has no testname part\n", spec); return NULL; } *p = '\0'; result = strdup(spec); *p = '.'; return result; } static char *gettname(char *spec) { static char *result = NULL; char *p; if (result) xfree(result); /* grab the testname part from a "www.xxx.com.testname" string */ p = strrchr(spec, '.'); if (!p) { errprintf("Item '%s' has no testname part\n", spec); return NULL; } result = strdup(p+1); return result; } static void flush_valuelist(value_t *head) { value_t *walk, *zombie; walk = head; while (walk) { zombie = walk; walk = walk->next; xfree(zombie->symbol); xfree(zombie); } } static void flush_testlist(void) { testspec_t *walk, *zombie; walk = testhead; while (walk) { zombie = walk; walk = walk->next; if (zombie->reshostname) xfree(zombie->reshostname); if (zombie->restestname) xfree(zombie->restestname); if (zombie->expression) xfree(zombie->expression); if (zombie->comment) xfree(zombie->comment); if (zombie->resultexpr) xfree(zombie->resultexpr); if (zombie->errbuf) xfree(zombie->errbuf); flush_valuelist(zombie->valuelist); xfree(zombie); } testhead = NULL; testcount = 0; } static void loadtests(void) { static time_t lastupdate = 0; static char *fn = NULL; struct stat st; FILE *fd; strbuffer_t *inbuf; if (!fn) { fn = (char *)malloc(1024 + strlen(xgetenv("XYMONHOME"))); *fn = '\0'; } sprintf(fn, "%s/etc/combo.cfg", xgetenv("XYMONHOME")); if ((stat(fn, &st) == 0) && (st.st_mtime == lastupdate)) return; lastupdate = st.st_mtime; fd = stackfopen(fn, "r", NULL); if (fd == NULL) { errprintf("Cannot open %s/combo.cfg\n", xgetenv("XYMONHOME")); *fn = '\0'; return; } flush_testlist(); inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *p, *comment; char *inp, *outp; p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; /* Strip whitespace */ for (inp=outp=STRBUF(inbuf); ((*inp >= ' ') && (*inp != '#')); inp++) { if (isspace((int)*inp)) { } else { *outp = *inp; outp++; } } *outp = '\0'; if (strlen(inp)) memmove(outp, inp, strlen(inp)+1); strbufferrecalc(inbuf); if (STRBUFLEN(inbuf) && (*STRBUF(inbuf) != '#') && (p = strchr(STRBUF(inbuf), '=')) ) { testspec_t *newtest; char *hname, *tname; hname = gethname(STRBUF(inbuf)); tname = gettname(STRBUF(inbuf)); if (hname && tname) { *p = '\0'; comment = strchr(p+1, '#'); if (comment) *comment = '\0'; newtest = (testspec_t *) malloc(sizeof(testspec_t)); newtest->reshostname = strdup(gethname(STRBUF(inbuf))); newtest->restestname = strdup(gettname(STRBUF(inbuf))); newtest->expression = strdup(p+1); newtest->comment = (comment ? strdup(comment+1) : NULL); newtest->resultexpr = NULL; newtest->valuelist = NULL; newtest->result = -1; newtest->errbuf = NULL; newtest->next = testhead; testhead = newtest; testcount++; } else { errprintf("Invalid combo test %s - missing host/test names. Perhaps you need to escape dashes?\n", STRBUF(inbuf)); } } } stackfclose(fd); freestrbuffer(inbuf); } static int getxymondvalue(char *hostname, char *testname, char **errptr) { static char *board = NULL; int xymondresult; int result = COL_CLEAR; char *pattern, *found, *colstr; if (board == NULL) { sendreturn_t *sres = newsendreturnbuf(1, NULL); xymondresult = sendmessage("xymondboard fields=hostname,testname,color", NULL, XYMON_TIMEOUT, sres); board = getsendreturnstr(sres, 1); if ((xymondresult != XYMONSEND_OK) || (board == NULL)) { board = ""; *errptr += sprintf(*errptr, "Could not access xymond board, error %d\n", xymondresult); return COL_CLEAR; } freesendreturnbuf(sres); } pattern = (char *)malloc(1 + strlen(hostname) + 1 + strlen(testname) + 1 + 1); sprintf(pattern, "\n%s|%s|", hostname, testname); if (strncmp(board, pattern+1, strlen(pattern+1)) == 0) { /* The first entry in the board doesn't have the "\n" */ found = board; } else { found = strstr(board, pattern); } if (found) { /* hostname|testname|color */ colstr = found + strlen(pattern); result = parse_color(colstr); } xfree(pattern); return result; } static long getvalue(char *hostname, char *testname, int *color, char **errbuf) { testspec_t *walk; char errtext[1024]; char *errptr; *color = -1; errptr = errtext; *errptr = '\0'; /* First check if it is one of our own tests */ for (walk = testhead; (walk && ( (strcmp(walk->reshostname, hostname) != 0) || (strcmp(walk->restestname, testname) != 0) ) ); walk = walk->next); if (walk != NULL) { /* It is a combo test they want the result of. */ *color = (walk->result ? COL_GREEN : COL_RED); return walk->result; } *color = getxymondvalue(hostname, testname, &errptr); /* Save error messages */ if (strlen(errtext) > 0) { if (*errbuf == NULL) *errbuf = strdup(errtext); else { *errbuf = (char *)realloc(*errbuf, strlen(*errbuf)+strlen(errtext)+1); strcat(*errbuf, errtext); } } if (*color == -1) return -1; else return (((1 << *color) & errorcolors) == 0); } static long evaluate(char *symbolicexpr, char **resultexpr, value_t **valuelist, char **errbuf) { char expr[MAX_LINE_LEN]; char *inp, *outp, *symp; char symbol[MAX_LINE_LEN]; int done; int insymbol = 0; int result, error; long oneval; int onecolor; value_t *valhead = NULL, *valtail = NULL; value_t *newval; char errtext[1024]; done = 0; inp=symbolicexpr; outp=expr; symp = NULL; while (!done) { if (isalpha((int)*inp) || (isdigit((int)*inp) && insymbol && *(inp+1) && (*(inp+1) > ' ') && *(inp+2) && (*(inp+2) > ' ')) ) { /* puke */ if (!insymbol) { insymbol = 1; symp = symbol; } *symp = *inp; symp++; } else if (insymbol && (isdigit((int) *inp) || (*inp == '.'))) { *symp = *inp; symp++; } else if (insymbol && ((*inp == '\\') && (*(inp+1) > ' '))) { *symp = *(inp+1); symp++; inp++; } else { if (insymbol) { /* Symbol finished - evaluate the symbol */ char *hname, *tname; *symp = '\0'; insymbol = 0; hname = gethname(symbol); tname = gettname(symbol); if (hname && tname) { oneval = getvalue(gethname(symbol), gettname(symbol), &onecolor, errbuf); if (oneval == -1) { dbgprintf("Forward lookup of '%s.%s' pending for '%s'\n", hname, tname, symbolicexpr); return -1; } } else { errprintf("Invalid data for symbol calculation - missing host/testname: %s\n", symbol); oneval = 0; onecolor = COL_CLEAR; } sprintf(outp, "%ld", oneval); outp += strlen(outp); newval = (value_t *) malloc(sizeof(value_t)); newval->symbol = strdup(symbol); newval->color = onecolor; newval->next = NULL; if (valhead == NULL) { valtail = valhead = newval; } else { valtail->next = newval; valtail = newval; } } *outp = *inp; outp++; symp = NULL; } if (*inp == '\0') done = 1; else inp++; } *outp = '\0'; if (resultexpr) *resultexpr = strdup(expr); dbgprintf("Symbolic '%s' converted to '%s'\n", symbolicexpr, expr); error = 0; result = compute(expr, &error); if (error) { sprintf(errtext, "compute(%s) returned error %d\n", expr, error); if (*errbuf == NULL) { *errbuf = strdup(errtext); } else { *errbuf = (char *)realloc(*errbuf, strlen(*errbuf)+strlen(errtext)+1); strcat(*errbuf, errtext); } } *valuelist = valhead; return result; } static char *printify(char *exp, int cleanexpr) { static char result[MAX_LINE_LEN]; char *inp, *outp; size_t n; if (!cleanexpr) { return exp; } inp = exp; outp = result; while (*inp) { n = strcspn(inp, "|&"); memcpy(outp, inp, n); inp += n; outp += n; if (*inp == '|') { inp++; if (*inp == '|') { inp++; strcpy(outp, " OR "); outp += 4; } else { strcpy(outp, " bOR "); outp += 5; } } else if (*inp == '&') { inp++; if (*inp == '&') { inp++; strcpy(outp, " AND "); outp += 5; } else { strcpy(outp, " bAND "); outp += 6; } } } *outp = '\0'; return result; } int update_combotests(int showeval, int cleanexpr) { testspec_t *t; int pending; int remaining = 0; init_timestamp(); loadtests(); /* * Loop over the tests to allow us "forward refs" in expressions. * We continue for as long as progress is being made. */ remaining = testcount; do { pending = remaining; for (t=testhead; (t); t = t->next) { if (t->result == -1) { t->result = evaluate(t->expression, &t->resultexpr, &t->valuelist, &t->errbuf); if (t->result != -1) remaining--; } } } while (pending != remaining); combo_start(); for (t=testhead; (t); t = t->next) { char msgline[MAX_LINE_LEN]; int color; value_t *vwalk; color = (t->result ? COL_GREEN : COL_RED); init_status(color); sprintf(msgline, "status %s.%s %s %s\n\n", commafy(t->reshostname), ( t->restestname ? t->restestname : "combostatuserror" ), colorname(color), timestamp); addtostatus(msgline); if (t->comment) { addtostatus(t->comment); addtostatus("\n\n"); } if (showeval) { addtostatus(printify(t->expression, cleanexpr)); addtostatus(" = "); addtostatus(printify(t->resultexpr, cleanexpr)); addtostatus(" = "); sprintf(msgline, "%ld\n", t->result); addtostatus(msgline); for (vwalk = t->valuelist; (vwalk); vwalk = vwalk->next) { sprintf(msgline, "&%s %s\n", colorname(vwalk->color), xgetenv("CGIBINURL"), textornull(gethname(vwalk->symbol)), textornull(gettname(vwalk->symbol)), textornull(vwalk->symbol)); addtostatus(msgline); } if (t->errbuf) { addtostatus("\nErrors occurred during evaluation:\n"); addtostatus(t->errbuf); } } finish_status(); } combo_end(); return 0; } int main(int argc, char *argv[]) { int argi; int showeval = 1; int cleanexpr = 0; setup_signalhandler(argv[0]); for (argi = 1; (argi < argc); argi++) { if ((strcmp(argv[argi], "--help") == 0)) { printf("%s version %s\n\n", argv[0], VERSION); printf("Usage:\n%s [--quiet] [--clean] [--debug] [--no-update]\n", argv[0]); exit(0); } else if ((strcmp(argv[argi], "--version") == 0)) { printf("%s version %s\n", argv[0], VERSION); exit(0); } else if ((strcmp(argv[argi], "--debug") == 0)) { debug = 1; } else if ((strcmp(argv[argi], "--no-update") == 0)) { dontsendmessages = 1; } else if ((strcmp(argv[argi], "--quiet") == 0)) { showeval = 0; } else if ((strcmp(argv[argi], "--clean") == 0)) { cleanexpr = 1; } else if ((strncmp(argv[argi], "--error-colors=", 15) == 0)) { char *tok; int newerrorcolors = 0; tok = strtok(strchr(argv[argi], '=')+1, ","); while (tok) { int col = parse_color(tok); if ((col >= 0) && (col <= COL_RED)) newerrorcolors |= (1 << parse_color(tok)); tok = strtok(NULL, ","); } if (newerrorcolors) errorcolors = newerrorcolors; } } return update_combotests(showeval, cleanexpr); } xymon-4.3.30/xymond/convertnk.c0000664000076400007640000000316111615341300016671 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon utility to convert the deprecated NK tags to a critical.cfg */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: convertnk.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { void *walk; load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); for (walk = first_host(); (walk); walk=next_host(walk, 0)) { char *nk, *nktime, *tok; nk = xmh_item(walk, XMH_NK); if (!nk) continue; nktime = xmh_item(walk, XMH_NKTIME); nk = strdup(nk); tok = strtok(nk, ","); while (tok) { char *hostname = xmh_item(walk, XMH_HOSTNAME); char *startstr = "", *endstr = "", *ttgroup = "", *ttextra = "", *updinfo = "Migrated"; int priority = 2; fprintf(stdout, "%s|%s|%s|%s|%s|%d|%s|%s|%s\n", hostname, tok, startstr, endstr, (nktime ? nktime : ""), priority, ttgroup, ttextra, updinfo); tok = strtok(NULL, ","); } xfree(nk); } return 0; } xymon-4.3.30/xymond/client/0000775000076400007640000000000013534041775016010 5ustar rpmbuildrpmbuildxymon-4.3.30/xymond/client/hpux.c0000664000076400007640000000752012654207223017136 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for HP-UX */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char hpux_rcsid[] = "$Id: hpux.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_hpux_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *memorystr; char *swapinfostr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *p; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); memorystr = getdata("memory"); swapinfostr = getdata("swapinfo"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "ifree", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (memorystr && swapinfostr) { unsigned long memphystotal, memphysfree, memphysused; unsigned long memswaptotal, memswapfree, memswapused; int found = 0; memphystotal = memphysfree = memphysused = 0; memswaptotal = memswapfree = memswapused = 0; p = strstr(memorystr, "Total:"); if (p) { memphystotal = atol(p+6); found++; } p = strstr(memorystr, "Free:"); if (p) { memphysfree = atol(p+5); found++; } memphysused = memphystotal - memphysfree; p = strstr(swapinfostr, "\ntotal"); if (p && (sscanf(p, "\ntotal %lu %lu %lu", &memswaptotal, &memswapused, &memswapfree) >= 2)) { found++; } if (found == 3) { unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, -1, -1, memswaptotal, memswapused); } } splitmsg_done(); } xymon-4.3.30/xymond/client/netbsd.c0000664000076400007640000000725312654207223017434 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for NetBSD */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char netbsd_rcsid[] = "$Id: netbsd.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_netbsd_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *meminfostr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *p; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); meminfostr = getdata("meminfo"); msgsstr = getdata("msgsstr"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Avail", "Capacity", "Mounted", dfstr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (meminfostr) { unsigned long memphystotal, memphysfree, memphysused; unsigned long memswaptotal, memswapfree, memswapused; int found = 0; memphystotal = memphysfree = memphysused = 0; memswaptotal = memswapfree = memswapused = 0; p = strstr(meminfostr, "Total:"); if (p) { memphystotal = atol(p+6); found++; } p = strstr(meminfostr, "Free:"); if (p) { memphysfree = atol(p+5); found++; } memphysused = memphystotal - memphysfree; p = strstr(meminfostr, "Swaptotal:"); if (p) { memswaptotal = atol(p+10); found++; } p = strstr(meminfostr, "Swapused:"); if (p) { memswapused = atol(p+9); found++; } memswapfree = memswaptotal - memswapused; if (found == 4) { unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, -1, -1, memswaptotal, memswapused); } } splitmsg_done(); } xymon-4.3.30/xymond/client/darwin.c0000664000076400007640000001024312654207223017432 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for Darwin / Mac OS X */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char darwin_rcsid[] = "$Id: darwin.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_darwin_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *meminfostr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); meminfostr = getdata("meminfo"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Avail", "Capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "ifree", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); /* No vmstat on Darwin */ if (meminfostr) { unsigned long pagesfree, pagesactive, pagesinactive, pageswireddown, pgsize; char *p; pagesfree = pagesactive = pagesinactive = pageswireddown = pgsize = -1; p = strstr(meminfostr, "page size of"); if (p && (sscanf(p, "page size of %lu bytes", &pgsize) == 1)) pgsize /= 1024; if (pgsize != -1) { p = strstr(meminfostr, "\nPages free:"); if (p) p = strchr(p, ':'); if (p) pagesfree = atol(p+1); p = strstr(meminfostr, "\nPages active:"); if (p) p = strchr(p, ':'); if (p) pagesactive = atol(p+1); p = strstr(meminfostr, "\nPages inactive:"); if (p) p = strchr(p, ':'); if (p) pagesinactive = atol(p+1); p = strstr(meminfostr, "\nPages wired down:"); if (p) p = strchr(p, ':'); if (p) pageswireddown = atol(p+1); if ((pagesfree >= 0) && (pagesactive >= 0) && (pagesinactive >= 0) && (pageswireddown >= 0)) { unsigned long memphystotal, memphysused; memphystotal = (pagesfree+pagesactive+pagesinactive+pageswireddown); memphystotal = memphystotal * pgsize / 1024; memphysused = (pagesactive+pagesinactive+pageswireddown); memphysused = memphysused * pgsize / 1024; unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, -1, -1, -1, -1); } } } splitmsg_done(); } xymon-4.3.30/xymond/client/bbwin.c0000664000076400007640000004357112654207223017261 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for BBWin/Windoes client */ /* */ /* Copyright (C) 2006-2011 Henrik Storner */ /* Copyright (C) 2007-2008 Francois Lacroix */ /* Copyright (C) 2007-2008 Etienne Grignon */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char bbwin_rcsid[] = "$Id: bbwin.c 7886 2016-02-02 20:16:19Z jccleaver $"; static void bbwin_uptime_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *uptimestr) { char *p, *myuptimestr = NULL; float loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; long uptimesecs = -1; int upcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!uptimestr) return; dbgprintf("Uptime check host %s\n", hostname); uptimesecs = 0; /* Parse to check data */ p = strstr(uptimestr, "sec:"); if (p) { p += strcspn(p, "0123456789\r\n"); uptimesecs = atol(p); dbgprintf("uptimestr [%d]\n", uptimesecs); /* DEBUG TODO REMOVE */ } /* Parse to show a nice msg */ myuptimestr = strchr(uptimestr, '\n'); if (myuptimestr) { ++myuptimestr; } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); dbgprintf("DEBUG recentlimit: [%d] ancienlimit: [%d]\n", recentlimit, ancientlimit); /* DEBUG TODO REMOVE */ upmsg = newstrbuffer(0); if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { if (upcolor != COL_RED) upcolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(upmsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { if (upcolor != COL_RED) upcolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(upmsg, msgline); } init_status(upcolor); sprintf(msgline, "status %s.uptime %s %s %s\n", commafy(hostname), colorname(upcolor), (timestr ? timestr : ""), ((upcolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info if pb */ if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } /* And add the msg we recevied */ if (myuptimestr) { addtostatus(myuptimestr); addtostatus("\n"); } dbgprintf("msgline %s", msgline); /* DEBUG TODO REMOVE */ if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void bbwin_cpu_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr) { char *p, *topstr; float load1, loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; int cpucolor = COL_GREEN; char msgline[4096]; strbuffer_t *cpumsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!cpuutilstr) return; dbgprintf("CPU check host %s\n", hostname); load1 = 0; p = strstr(cpuutilstr, "load="); if (p) { p += strcspn(p, "0123456789%\r\n"); load1 = atol(p); dbgprintf("load1 [%d]\n", load1); /* DEBUG TODO REMOVE */ } topstr = strstr(cpuutilstr, "CPU states"); if (topstr) { *(topstr - 1) = '\0'; } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); dbgprintf("loadyellow: %d, loadred: %d\n", loadyellow, loadred); cpumsg = newstrbuffer(0); if (load1 > loadred) { cpucolor = COL_RED; addtobuffer(cpumsg, "&red Load is CRITICAL\n"); } else if (load1 > loadyellow) { cpucolor = COL_YELLOW; addtobuffer(cpumsg, "&yellow Load is HIGH\n"); } init_status(cpucolor); sprintf(msgline, "status %s.cpu %s %s %s", commafy(hostname), colorname(cpucolor), (timestr ? timestr : ""), cpuutilstr); addtostatus(msgline); /* And add the info if pb */ if (STRBUFLEN(cpumsg)) { addtostrstatus(cpumsg); addtostatus("\n"); } /* And add the msg we recevied */ if (topstr) { addtostatus(topstr); addtostatus("\n"); } dbgprintf("msgline %s", msgline); /* DEBUG TODO REMOVE */ if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(cpumsg); } static void bbwin_clock_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *clockstr, char *msgcachestr) { char *myclockstr; int clockcolor = COL_GREEN; float loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; char msgline[4096]; strbuffer_t *clockmsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!clockstr) return; dbgprintf("Clock check host %s\n", hostname); clockmsg = newstrbuffer(0); myclockstr = strstr(clockstr, "local"); if (myclockstr) { *(myclockstr - 1) = '\0'; } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); if (clockstr) { char *p; struct timeval clockval; p = strstr(clockstr, "epoch:"); if (!p) { /* No epoch reported */ } else { struct timeval clockdiff; struct timezone tz; int cachedelay = 0; /* The clock may be reported with a decimal part. But not always */ p += 6; /* Skip "epoch:" */ clockval.tv_sec = atol(p); /* See if there's a decimal part */ p += strspn(p, "0123456789"); if (*p == '.') { p++; clockval.tv_usec = atol(p); } else { clockval.tv_usec = 0; } if (msgcachestr) { /* Message passed through msgcache, so adjust for the cache delay */ p = strstr(msgcachestr, "Cachedelay:"); if (p) cachedelay = atoi(p+11); } gettimeofday(&clockdiff, &tz); clockdiff.tv_sec -= (clockval.tv_sec + cachedelay); clockdiff.tv_usec -= clockval.tv_usec; if (clockdiff.tv_usec < 0) { clockdiff.tv_usec += 1000000; clockdiff.tv_sec -= 1; } if ((maxclockdiff > 0) && (abs(clockdiff.tv_sec) > maxclockdiff)) { if (clockcolor != COL_RED) clockcolor = clockdiffcolor; sprintf(msgline, "&%s System clock is %ld seconds off (max %ld)\n", colorname(clockdiffcolor), (long) clockdiff.tv_sec, (long) maxclockdiff); addtobuffer(clockmsg, msgline); } else { sprintf(msgline, "System clock is %ld seconds off\n", (long) clockdiff.tv_sec); addtobuffer(clockmsg, msgline); } } } init_status(clockcolor); sprintf(msgline, "status %s.timediff %s %s %s\n", commafy(hostname), colorname(clockcolor), (timestr ? timestr : ""), ((clockcolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info if pb */ if (STRBUFLEN(clockmsg)) { addtostrstatus(clockmsg); addtostatus("\n"); } /* And add the msg we recevied */ if (myclockstr) { addtostatus(myclockstr); addtostatus("\n"); } dbgprintf("msgline %s", msgline); /* DEBUG TODO REMOVE */ if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(clockmsg); } void bbwin_who_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *whostr) { int whocolor = COL_GREEN; char msgline[4096]; strbuffer_t *whomsg; if (!want_msgtype(hinfo, MSG_WHO)) return; if (!whostr) return; dbgprintf("Who check host %s\n", hostname); whomsg = newstrbuffer(0); init_status(whocolor); sprintf(msgline, "status %s.who %s %s %s\n", commafy(hostname), colorname(whocolor), (timestr ? timestr : ""), ((whocolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info if pb */ if (STRBUFLEN(whomsg)) { addtostrstatus(whomsg); addtostatus("\n"); } /* And add the msg we recevied */ if (whostr) { addtostatus(whostr); addtostatus("\n"); } dbgprintf("msgline %s", msgline); /* DEBUG TODO REMOVE */ if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(whomsg); } void bbwin_svcs_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, int namecol, int startupcol, int statecol, char *svcstr, char *svcauto) { int svccolor = -1; int schecks; char msgline[4096]; static strbuffer_t *monmsg = NULL; char *group; if (!want_msgtype(hinfo, MSG_SVCS)) return; if (!svcstr) return; if (!monmsg) monmsg = newstrbuffer(0); dbgprintf("Services check host %s\n", hostname); clearalertgroups(); schecks = clear_svc_counts(hinfo, clientclass); dbgprintf("schecks: [%d]\n", schecks); /* DEBUG TODO REMOVE */ if (schecks > 0) { /* Count how many instances of each monitored condition are found */ char *sname, *bol, *nl; int scount, scolor; char *namestr, *startupstr, *statestr; bol = svcstr; while (bol) { char *p; nl = strchr(bol, '\n'); if (nl) *nl = '\0'; /* Data lines */ p = strdup(bol); namestr = getcolumn(p, namecol); strcpy(p, bol); startupstr = getcolumn(p, startupcol); strcpy(p, bol); statestr = getcolumn(p, statecol); add_svc_count(namestr, startupstr, statestr); xfree(p); if (nl) { *nl = '\n'; bol = nl+1; } else bol = NULL; } /* Check the status and state found for each monitored svc */ while ((sname = check_svc_count(&scount, &scolor, &group)) != NULL) { if (scolor > svccolor) svccolor = scolor; if (scolor == COL_GREEN) { sprintf(msgline, "&green %s\n", sname); addtobuffer(monmsg, msgline); } else { sprintf(msgline, "&%s %s\n", colorname(scolor), sname); addtobuffer(monmsg, msgline); addalertgroup(group); } } } if ((svccolor == -1) && sendclearsvcs) { /* Nothing to check */ addtobuffer(monmsg, "No Services checks defined\n"); svccolor = noreportcolor; } if (svccolor != -1) { if (svcauto && strlen(svcauto) > 1 && (svccolor == COL_GREEN || svccolor == noreportcolor)) svccolor = COL_YELLOW; /* Now we know the result, so generate a status message */ init_status(svccolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.svcs %s %s - Services %s\n", commafy(hostname), colorname(svccolor), (timestr ? timestr : ""), ((svccolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info about what's wrong */ addtostrstatus(monmsg); addtostatus("\n"); clearstrbuffer(monmsg); /* Add AutoRestart status */ if (svcauto && strlen(svcauto) > 1) { addtostatus(svcauto); addtostatus("\n\n"); } /* And the full svc output for those who want it */ if (svclistinsvcs) addtostatus(svcstr); if (fromline) addtostatus(fromline); finish_status(); } else { clearstrbuffer(monmsg); } } void handle_win32_bbwin_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *cpuutilstr; char *uptimestr; char *clockstr; char *msgcachestr; char *diskstr; char *procsstr; char *msgsstr; char *portsstr; char *memorystr; char *netstatstr; char *ifstatstr; char *svcstr; char *svcauto; char *whostr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); /* Get all data by section timestr is the date time for all status */ timestr = getdata("date"); if (!timestr) return; uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); /* TODO check when it is usefull */ cpuutilstr = getdata("cpu"); procsstr = getdata("procs"); diskstr = getdata("disk"); portsstr = getdata("ports"); memorystr = getdata("memory"); msgsstr = getdata("msg"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); svcstr = getdata("svcs"); svcauto = getdata("svcautorestart"); whostr = getdata("who"); bbwin_uptime_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr); bbwin_clock_report(hostname, clienttype, os, hinfo, fromline, timestr, clockstr, msgcachestr); bbwin_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "Name", NULL, procsstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 1, 2, 3, portsstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Avail", "Capacity", "Filesystem", diskstr); bbwin_svcs_report(hostname, clienttype, os, hinfo, fromline, timestr, 0, 1, 2, svcstr, svcauto); bbwin_who_report(hostname, clienttype, os, hinfo, fromline, timestr, whostr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); /* Data status */ unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); if (memorystr) { char *p; long memphystotal, memphysused, memactused, memacttotal, memswaptotal, memswapused; memphystotal = memswaptotal = memphysused = memswapused = memactused = memacttotal = -1; p = strstr(memorystr, "\nphysical:"); if (p) sscanf(p, "\nphysical: %ld %ld", &memphystotal, &memphysused); p = strstr(memorystr, "\npage:"); if (p) sscanf(p, "\npage: %ld %ld", &memswaptotal, &memswapused); p = strstr(memorystr, "\nvirtual:"); if (p) sscanf(p, "\nvirtual: %ld %ld", &memacttotal, &memactused); dbgprintf("DEBUG Memory %ld %ld %ld %ld %ld %ld\n", memphystotal, memphysused, memacttotal, memactused, memswaptotal, memswapused); /* DEBUG TODO Remove*/ unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, memacttotal, memactused, memswaptotal, memswapused); } splitmsg_done(); } xymon-4.3.30/xymond/client/linux.c0000664000076400007640000002042312654207223017306 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for Linux */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char linux_rcsid[] = "$Id: linux.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_linux_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *freestr; char *msgsstr; char *netstatstr; char *vmstatstr; char *ifstatstr; char *portsstr; char *mdstatstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); freestr = getdata("free"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); vmstatstr = getdata("vmstat"); portsstr = getdata("ports"); mdstatstr = getdata("mdstat"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "IFree", "IUse%", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "CMD", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); /* * Sigh. Recent kernels + procps-ng change things up a bit. If 'available' is present * (roughly, 3.14+ and 2.6.27+, but depends on the vendor), then we'll use the inverse of that: * (Physical - Available = ACTUALUSED) * Otherwise, it's: * (Physical Used - (buffers + cached) = ACTUALUSED) * * See discussions at http://lists.xymon.com/pipermail/xymon/2015-April/041628.html * If the legacy meminfo display is NOT used, we should get the old format still * */ if (freestr) { char *p; long memphystotal, memphysused, memphysfree, memacttotal, memactused, memactfree, memswaptotal, memswapused, memswapfree; memphystotal = memswaptotal = memphysused = memswapused = memacttotal = memactused = memactfree = -1; /* check for old style */ p = strstr(freestr, "\n-/+ buffers/cache:"); if (p) { p = strstr(freestr, "\nMem:"); if (p && (sscanf(p, "\nMem: %ld %ld %ld", &memphystotal, &memphysused, &memphysfree) == 3)) { memphystotal /= 1024; memphysused /= 1024; memphysfree /= 1024; } p = strstr(freestr, "\n-/+ buffers/cache:"); if (sscanf(p, "\n-/+ buffers/cache: %ld %ld", &memactused, &memactfree) == 2) { memacttotal = memphystotal; memactused /= 1024; memactfree /= 1024; } } /* check for new style */ else if (strstr(freestr, "available\n")) { long shared, buffcache; p = strstr(freestr, "\nMem:"); if (p && (sscanf(p, "\nMem: %ld %ld %ld %ld %ld %ld", &memphystotal, &memphysused, &memphysfree, &shared, &buffcache, &memactfree) == 6)) { memphystotal /= 1024; memphysused /= 1024; memphysfree /= 1024; /* Provide a Physical Used value that's compatible with previous thresholds. However, use the */ /* new 'Available' line as the basis for "Actual Used", since it'll be more accurate. */ memacttotal = memphystotal; memactfree /= 1024; memactused = memacttotal - memactfree; if (memactused < 0) memactused = 0; memphysused += (buffcache / 1024); } } else errprintf(" -> No readable memory data for %s in freestr\n", hostname); /* There's always a swap line */ p = strstr(freestr, "\nSwap:"); if (p && (sscanf(p, "\nSwap: %ld %ld %ld", &memswaptotal, &memswapused, &memswapfree) == 3)) { memswaptotal /= 1024; memswapused /= 1024; memswapfree /= 1024; } unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, memacttotal, memactused, memswaptotal, memswapused); } if (mdstatstr) { char *statcopy, *bol, *eol; int color = COL_GREEN; char *mdname = NULL, *mdstatus = NULL; int mddevices = 0, mdactive = 0, recovering = 0; strbuffer_t *alerttext = newstrbuffer(0); char msgline[1024]; char *summary = NULL; int arraycount = 0; statcopy = (char *)malloc(strlen(mdstatstr) + 10); sprintf(statcopy, "%s\nmd999\n", mdstatstr); bol = statcopy; while (bol) { eol = strchr(bol, '\n'); if (eol) *eol = '\0'; if ((strncmp(bol, "md", 2) == 0) && (isdigit(*(bol+2)))) { char *tok; if (mdname && (mddevices >= 0) && (mdactive >= 0)) { int onecolor = COL_GREEN; /* Got a full md device status, flush it before we start on the next one */ arraycount++; if (mddevices != mdactive) { if (!recovering) { onecolor = COL_RED; snprintf(msgline, sizeof(msgline), "&red %s : Disk failure in array : %d devices of %d active\n", mdname, mdactive, mddevices); addtobuffer(alerttext, msgline); summary = "failure"; } else { onecolor = COL_YELLOW; snprintf(msgline, sizeof(msgline), "&yellow %s status %s : %d devices of %d active\n", mdname, mdstatus, mdactive, mddevices); addtobuffer(alerttext, msgline); if (!summary) summary = "recovering"; } } else { snprintf(msgline, sizeof(msgline), "&green %s : %d devices of %d active\n", mdname, mdactive, mddevices); addtobuffer(alerttext, msgline); } if (onecolor > color) { color = onecolor; } } /* First line, holds the name of the array and the active/inactive status */ mddevices = mdactive = -1; recovering = 0; mdname = strtok(bol, " "); tok = strtok(NULL, " "); // Skip the ':' mdstatus = strtok(NULL, " "); } if (mdname && ((mddevices == -1) && (mdactive == -1)) && (strchr(bol, '/'))) { char *p = strchr(bol, '/'); /* Second line: Holds the number of configured/active devices */ mdactive = atoi(p+1); while ((p > bol) && (isdigit(*(p-1)))) p--; mddevices = atoi(p); } if (mdname && (mddevices != mdactive) && strstr(bol, "recovery = ")) { /* Third line: Only present during recovery */ mdstatus = "recovery in progress"; recovering = 1; } bol = (eol ? eol+1 : NULL); } if (arraycount > 0) { init_status(color); sprintf(msgline, "status %s.raid %s %s - RAID %s\n\n", commafy(hostname), colorname(color), (timestr ? timestr : ""), (summary ? summary : "OK")); addtostatus(msgline); if (STRBUFLEN(alerttext) > 0) { addtostrstatus(alerttext); addtostatus("\n\n"); } addtostatus("============================ /proc/mdstat ===========================\n\n"); addtostatus(mdstatstr); finish_status(); } xfree(statcopy); freestrbuffer(alerttext); } splitmsg_done(); } xymon-4.3.30/xymond/client/freebsd.c0000664000076400007640000001111712654207223017561 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for FreeBSD */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char freebsd_rcsid[] = "$Id: freebsd.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_freebsd_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *meminfostr; char *swapinfostr; char *vmtotalstr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *p; char fromline[1024]; unsigned long memphystotal = 0, memphysfree = 0, memphysused = 0, memphysactual = -1; unsigned long memswaptotal = 0, memswapfree = 0, memswapused = 0; int found = 0; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); meminfostr = getdata("meminfo"); swapinfostr = getdata("swapinfo"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); vmtotalstr = getdata("vmtotal"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Avail", "Capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "ifree", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (meminfostr) { p = strstr(meminfostr, "Total:"); if (p) { memphystotal = atol(p+6); found++; } p = strstr(meminfostr, "Actual:"); if (p) memphysactual = atol(p+7); } if (vmtotalstr) { p = strstr(vmtotalstr, "\nFree Memory Pages:"); if (p) { memphysfree = atol(p + 19)/1024; memphysused = memphystotal - memphysfree; found++; } else { p = strstr(vmtotalstr, "\nFree Memory:"); if (p) { memphysfree = atol(p + 13)/1024; memphysused = memphystotal - memphysfree; found++; } } } if ((found == 1) && meminfostr) { p = strstr(meminfostr, "Free:"); if (p) { memphysfree = atol(p+5); found++; } memphysused = memphystotal - memphysfree; } if (swapinfostr) { found++; p = strchr(swapinfostr, '\n'); /* Skip the header line */ while (p) { long stot, sused, sfree; char *bol; bol = p+1; p = strchr(bol, '\n'); if (p) *p = '\0'; if (sscanf(bol, "%*s %ld %ld %ld", &stot, &sused, &sfree) == 3) { memswaptotal += stot; memswapused += sused; memswapfree += sfree; } if (p) *p = '\n'; } memswaptotal /= 1024; memswapused /= 1024; memswapfree /= 1024; } if (found >= 2) { unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, memphystotal, memphysactual, memswaptotal, memswapused); } splitmsg_done(); } xymon-4.3.30/xymond/client/powershell.c0000664000076400007640000000245611615341300020330 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for the Windows Powershell client */ /* */ /* Copyright (C) 2010-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char powershell_rcsid[] = "$Id: powershell.c 6712 2011-07-31 21:01:52Z storner $"; void handle_powershell_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { /* At the moment, the Powershell client just uses the same handling as the BBWin client */ handle_win32_bbwin_client(hostname, clienttype, os, hinfo, sender, timestamp, clientdata); } xymon-4.3.30/xymond/client/zos.c0000664000076400007640000006075312503303630016764 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for z/VSE, VSE/ESA and z/OS */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* Copyright (C) 2006-2009 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char zos_rcsid[] = "$Id: zos.c 7608 2015-03-21 15:00:40Z jccleaver $"; void zos_cpu_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr, char *uptimestr) { char *p; float load1, loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; int uphour, upmin; char loadresult[100]; char myupstr[100]; long uptimesecs = -1; long upday; int cpucolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!uptimestr) return; if (!cpuutilstr) return; uptimesecs = 0; /* * z/OS: "Uptime: 1 Days, 13 Hours, 38 Minutes" */ sscanf(uptimestr,"Uptime: %ld Days, %d Hours, %d Minutes", &upday, &uphour, &upmin); uptimesecs = upday * 86400; uptimesecs += 60*(60*uphour + upmin); sprintf(myupstr, "%s\n", uptimestr); /* * Looking for average CPU Utilization in CPU message * CPU Utilization=000% */ *loadresult = '\0'; p = strstr(cpuutilstr, "CPU Utilization ") + 16 ; if (p) { if (sscanf(p, "%f%%", &load1) == 1) { sprintf(loadresult, "z/OS CPU Utilization %3.0f%%\n", load1); } } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); upmsg = newstrbuffer(0); if (load1 > loadred) { cpucolor = COL_RED; addtobuffer(upmsg, "&red Load is CRITICAL\n"); } else if (load1 > loadyellow) { cpucolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Load is HIGH\n"); } if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(upmsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(upmsg, msgline); } init_status(cpucolor); sprintf(msgline, "status %s.cpu %s %s %s %s %s\n", commafy(hostname), colorname(cpucolor), (timestr ? timestr : ""), loadresult, myupstr, cpuutilstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } void zos_paging_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *pagingstr) { char *p; int ipagerate, pagingyellow, pagingred; float fpagerate=0.0; char pagingresult[100]; int pagingcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!pagingstr) return; /* * Looking for Paging rate in message * Paging Rate=0 */ *pagingresult = '\0'; ipagerate=0; p = strstr(pagingstr, "Paging Rate ") + 12; if (p) { if (sscanf(p, "%f", &fpagerate) == 1) { ipagerate=fpagerate + 0.5; /* Rounding up */ sprintf(pagingresult, "z/OS Paging Rate %d per second\n", ipagerate); } } else sprintf(pagingresult, "Can not find page rate value in:\n%s\n", pagingstr); get_paging_thresholds(hinfo, clientclass, &pagingyellow, &pagingred); upmsg = newstrbuffer(0); if (ipagerate > pagingred) { pagingcolor = COL_RED; addtobuffer(upmsg, "&red Paging Rate is CRITICAL\n"); } else if (ipagerate > pagingyellow) { pagingcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Paging Rate is HIGH\n"); } init_status(pagingcolor); sprintf(msgline, "status %s.paging %s %s %s %s\n", commafy(hostname), colorname(pagingcolor), (timestr ? timestr : ""), pagingresult, pagingstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } void zos_memory_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *memstr) { char *p; char headstr[100], csastr[100], ecsastr[100], sqastr[100], esqastr[100]; long csaalloc, csaused, csahwm, ecsaalloc, ecsaused, ecsahwm; long sqaalloc, sqaused, sqahwm, esqaalloc, esqaused, esqahwm; float csautil, ecsautil, sqautil, esqautil; int csayellow, csared, ecsayellow, ecsared, sqayellow, sqared, esqayellow, esqared; int memcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!memstr) return; /* * Looking for memory eyecatchers in message */ p = strstr(memstr, "CSA ") + 4; if (p) { sscanf(p, "%ld %ld %ld", &csaalloc, &csaused, &csahwm); } p = strstr(memstr, "ECSA ") + 5; if (p) { sscanf(p, "%ld %ld %ld", &ecsaalloc, &ecsaused, &ecsahwm); } p = strstr(memstr, "SQA ") + 4; if (p) { sscanf(p, "%ld %ld %ld", &sqaalloc, &sqaused, &sqahwm); } p = strstr(memstr, "ESQA ") + 5; if (p) { sscanf(p, "%ld %ld %ld", &esqaalloc, &esqaused, &esqahwm); } csautil = ((float)csaused / (float)csaalloc) * 100; ecsautil = ((float)ecsaused / (float)ecsaalloc) * 100; sqautil = ((float)sqaused / (float)sqaalloc) * 100; esqautil = ((float)esqaused / (float)esqaalloc) * 100; get_zos_memory_thresholds(hinfo, clientclass, &csayellow, &csared, &ecsayellow, &ecsared, &sqayellow, &sqared, &esqayellow, &esqared); upmsg = newstrbuffer(0); if (csautil > csared) { if (memcolor < COL_RED) memcolor = COL_RED; addtobuffer(upmsg, "&red CSA Utilization is CRITICAL\n"); } else if (csautil > csayellow) { if (memcolor < COL_YELLOW) memcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow CSA Utilization is HIGH\n"); } if (ecsautil > ecsared) { if (memcolor < COL_RED) memcolor = COL_RED; addtobuffer(upmsg, "&red ECSA Utilization is CRITICAL\n"); } else if (ecsautil > ecsayellow) { if (memcolor < COL_YELLOW) memcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow ECSA Utilization is HIGH\n"); } if (sqautil > sqared) { if (memcolor < COL_RED) memcolor = COL_RED; addtobuffer(upmsg, "&red SQA Utilization is CRITICAL\n"); } else if (sqautil > sqayellow) { if (memcolor < COL_YELLOW) memcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow SQA Utilization is HIGH\n"); } if (esqautil > esqared) { if (memcolor < COL_RED) memcolor = COL_RED; addtobuffer(upmsg, "&red ESQA Utilization is CRITICAL\n"); } else if (esqautil > esqayellow) { if (memcolor < COL_YELLOW) memcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow ESQA Utilization is HIGH\n"); } *headstr = '\0'; *csastr = '\0'; *ecsastr = '\0'; *sqastr = '\0'; *esqastr = '\0'; strcpy(headstr, "z/OS Memory Map\n Area Alloc Used HWM Util%\n"); sprintf(csastr, "CSA %8ld %8ld %8ld %3.1f\n", csaalloc, csaused, csahwm, csautil); sprintf(ecsastr, "ECSA %8ld %8ld %8ld %3.1f\n", ecsaalloc, ecsaused, ecsahwm, ecsautil); sprintf(sqastr, "SQA %8ld %8ld %8ld %3.1f\n", sqaalloc, sqaused, sqahwm, sqautil); sprintf(esqastr, "ESQA %8ld %8ld %8ld %3.1f\n", esqaalloc, esqaused, esqahwm, esqautil); init_status(memcolor); sprintf(msgline, "status %s.memory %s %s\n%s %s %s %s %s", commafy(hostname), colorname(memcolor), (timestr ? timestr : ""), headstr, csastr, ecsastr, sqastr, esqastr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zos_cics_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cicsstr) { char cicsappl[9], cicsdate[11], cicstime[9]; int numtrans=0, cicsok=1; float dsapct=0.0; float edsapct=0.0; char cicsresult[100]; char tempresult[100]; char *cicsentry = NULL; int cicscolor = COL_GREEN; int dsayel, dsared, edsayel, edsared; char msgline[4096]; char cicsokmsg[]="All CICS Systems OK"; char cicsnotokmsg[]="One or more CICS Systems not OK"; strbuffer_t *headline; strbuffer_t *upmsg; strbuffer_t *cicsmsg; if (!cicsstr) return; cicsmsg = newstrbuffer(0); upmsg = newstrbuffer(0); headline= newstrbuffer(0); addtobuffer(headline, "Appl ID Trans DSA Pct EDSA Pct\n"); /* * * Each CICS system reporting uses one line in the message, the format is: * applid date time numtrans dsapct edsapct * applid is the CICS application id * date and time are the date and time of the report * numtrans is the number of transactions that were executed in CICS since the last report * dsapct is the DSA utilization percentage * edsapct is the EDSA utilization percentage * */ if (cicsstr) { cicsentry=strtok(cicsstr, "\n"); while (cicsentry != NULL) { sscanf(cicsentry, "%8s %10s %8s %d %f %f", cicsappl, cicsdate, cicstime, &numtrans, &dsapct, &edsapct); sprintf(cicsresult,"%-8s %6d %3.1f %3.1f\n", cicsappl, numtrans, dsapct, edsapct); addtobuffer(cicsmsg, cicsresult); if (numtrans == -1 ) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow CICS system %s not responding, removed\n", cicsappl); addtobuffer(upmsg, tempresult); } /* Get CICS thresholds for this application ID. */ get_cics_thresholds(hinfo, clientclass, cicsappl, &dsayel, &dsared, &edsayel, &edsared); /* The threshold of the DSA values for each CICS must be checked in this loop. */ if (dsapct > dsared) { if (cicscolor < COL_RED) cicscolor = COL_RED; cicsok=0; sprintf(tempresult,"&red %s DSA Utilization is CRITICAL\n", cicsappl); addtobuffer(upmsg, tempresult); } else if (dsapct > dsayel) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow %s DSA Utilization is HIGH\n", cicsappl); addtobuffer(upmsg, tempresult); } if (edsapct > edsared) { if (cicscolor < COL_RED) cicscolor = COL_RED; cicsok=0; sprintf(tempresult,"&red %s EDSA Utilization is CRITICAL\n", cicsappl); addtobuffer(upmsg, tempresult); } else if (edsapct > edsayel) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow %s EDSA Utilization is HIGH\n", cicsappl); addtobuffer(upmsg, tempresult); } init_status(cicscolor); cicsentry=strtok(NULL, "\n"); } } sprintf(msgline, "status %s.cics %s %s %s\n", commafy(hostname), colorname(cicscolor), (timestr ? timestr : ""), ( (cicsok==1) ? cicsokmsg : cicsnotokmsg) ); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); } if (STRBUFLEN(cicsmsg)) { addtostrstatus(headline); addtostrstatus(cicsmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(headline); freestrbuffer(upmsg); freestrbuffer(cicsmsg); } void zos_jobs_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *psstr) { int pscolor = COL_GREEN; int pchecks; int cmdofs = -1; char msgline[4096]; strbuffer_t *monmsg; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PROCS)) return; if (!psstr) return; if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); monmsg = newstrbuffer(0); sprintf(msgline, "data %s.proccounts\n", commafy(hostname)); addtobuffer(countdata, msgline); cmdofs = 0; /* Command offset for z/OS isn't necessary */ pchecks = clear_process_counts(hinfo, clientclass); if (pchecks == 0) { /* Nothing to check */ sprintf(msgline, "&%s No process checks defined\n", colorname(noreportcolor)); addtobuffer(monmsg, msgline); pscolor = noreportcolor; } else if (cmdofs >= 0) { /* Count how many instances of each monitored process is running */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; bol = psstr; while (bol) { nl = strchr(bol, '\n'); /* Take care - the ps output line may be shorter than what we look at */ if (nl) { *nl = '\0'; if ((nl-bol) > cmdofs) add_process_count(bol+cmdofs); *nl = '\n'; bol = nl+1; } else { if (strlen(bol) > cmdofs) add_process_count(bol+cmdofs); bol = NULL; } } /* Check the number found for each monitored process */ while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { if (pcolor > pscolor) pscolor = pcolor; sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the count data for later DATA message to track process counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } else { pscolor = COL_YELLOW; sprintf(msgline, "&yellow Expected string not found in ps output header\n"); addtobuffer(monmsg, msgline); } /* Now we know the result, so generate a status message */ init_status(pscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.procs %s %s - Processes %s\n", commafy(hostname), colorname(pscolor), (timestr ? timestr : ""), ((pscolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full list of jobs for those who want it */ if (pslistinprocs) { /* * Format the list of virtual machines into four per line, * this list could be fairly long. */ char *tmpstr, *tok; /* Make a copy of psstr, strtok() will be changing it */ tmpstr = strdup(psstr); /* Use strtok() to split string into pieces delimited by newline */ tok = strtok(tmpstr, "\n"); while (tok) { sprintf(msgline, "%s\n", tok); addtostatus(msgline); tok = strtok(NULL, "\n"); } free(tmpstr); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); if (anycountdata) combo_add(countdata); clearstrbuffer(countdata); } void zos_maxuser_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *maxuserstr) { char *p; char maxustr[256]; long maxusers, maxufree, maxuused, rsvtstrt, rsvtfree, rsvtused, rsvnonr, rsvnfree, rsvnused; int maxyellow, maxred; float maxutil, rsvtutil, rsvnutil; int maxcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!maxuserstr) return; /* * Looking for eyecatchers in message */ p = strstr(maxuserstr, "Maxusers: ") + 9; if (p) { sscanf(p, "%ld Free: %ld", &maxusers, &maxufree); } p = strstr(maxuserstr, "RSVTSTRT: ") + 9; if (p) { sscanf(p, "%ld Free: %ld", &rsvtstrt, &rsvtfree); } p = strstr(maxuserstr, "RSVNONR: ") + 8; if (p) { sscanf(p, "%ld Free: %ld", &rsvnonr, &rsvnfree); } maxuused = maxusers - maxufree; rsvtused = rsvtstrt - rsvtfree; rsvnused = rsvnonr - rsvnfree; if ( maxuused == 0.0 ) maxutil = 0; else maxutil = ((float)maxuused / (float)maxusers) * 100; if ( rsvtused == 0.0 ) rsvtutil = 0; else rsvtutil = ((float)rsvtused / (float)rsvtstrt) * 100; if ( rsvnused == 0.0 ) rsvnutil = 0; else rsvnutil = ((float)rsvnused / (float)rsvnonr) * 100; get_asid_thresholds(hinfo, clientclass, &maxyellow, &maxred); upmsg = newstrbuffer(0); if ((int)maxutil > maxred) { if (maxcolor < COL_RED) maxcolor = COL_RED; addtobuffer(upmsg, "&red ASID (Maxuser) Utilization is CRITICAL\n"); } else if ((int)maxutil > maxyellow) { if (maxcolor < COL_YELLOW) maxcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow ASID (Maxuser) Utilization is HIGH\n"); } *maxustr = '\0'; sprintf(maxustr, " Maxuser: %8ld Free: %8ld Used: %8ld %3.1f\nRSVTSTRT: %8ld Free: %8ld Used: %8ld %3.1f\n RSVNONR: %8ld Free: %8ld Used: %8ld %3.1f\n",maxusers,maxufree,maxuused,maxutil,rsvtstrt,rsvtfree,rsvtused,rsvtutil,rsvnonr,rsvnfree,rsvnused,rsvnutil); init_status(maxcolor); sprintf(msgline, "status %s.maxuser %s %s\n%s", commafy(hostname), colorname(maxcolor), (timestr ? timestr : ""), maxustr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } void handle_zos_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *cpuutilstr; char *pagingstr; char *uptimestr; char *dfstr; char *cicsstr; /* z/OS CICS Information */ char *jobsstr; /* z/OS Running jobs */ char *memstr; /* z/OS Memory Utilization */ char *maxuserstr; /* z/OS Maxuser */ char *portsstr; char *ifstatstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); cpuutilstr = getdata("cpu"); pagingstr = getdata("paging"); dfstr = getdata("df"); cicsstr = getdata("cics"); jobsstr = getdata("jobs"); memstr = getdata("memory"); maxuserstr = getdata("maxuser"); portsstr = getdata("ports"); ifstatstr = getdata("ifstat"); zos_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr, uptimestr); zos_paging_report(hostname, clienttype, os, hinfo, fromline, timestr, pagingstr); zos_cics_report(hostname, clienttype, os, hinfo, fromline, timestr, cicsstr); zos_jobs_report(hostname, clienttype, os, hinfo, fromline, timestr, jobsstr); zos_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memstr); zos_maxuser_report(hostname, clienttype, os, hinfo, fromline, timestr, maxuserstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Cap", "Mounted", dfstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); splitmsg_done(); } xymon-4.3.30/xymond/client/zvm.c0000664000076400007640000003420512503303630016756 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for z/VM */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* Copyright (C) 2006-2008 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char zvm_rcsid[] = "$Id: zvm.c 7608 2015-03-21 15:00:40Z jccleaver $"; static void zvm_cpu_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr, char *uptimestr) { char *p; float load1, loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; int uphour, upmin; char loadresult[100]; char myupstr[100]; long uptimesecs = -1; long upday; int cpucolor = COL_GREEN; char msgline[1024]; strbuffer_t *upmsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!cpuutilstr) return; if (!uptimestr) return; uptimesecs = 0; /* * z/VM: "Uptime: 1 Days, 13 Hours, 38 Minutes" */ sscanf(uptimestr,"Uptime: %ld Days, %d Hours, %d Minutes", &upday, &uphour, &upmin); uptimesecs = upday * 86400; uptimesecs += 60*(60*uphour + upmin); sprintf(myupstr, "%s\n", uptimestr); /* * Looking for average CPU Utilization in 'IND' command response * AVGPROC-000% */ *loadresult = '\0'; p = strstr(cpuutilstr, "AVGPROC-") + 8 ; if (p) { if (sscanf(p, "%f%%", &load1) == 1) { sprintf(loadresult, "z/VM CPU Utilization %3.0f%%\n", load1); } } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); upmsg = newstrbuffer(0); if (load1 > loadred) { cpucolor = COL_RED; addtobuffer(upmsg, "&red Load is CRITICAL\n"); } else if (load1 > loadyellow) { cpucolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Load is HIGH\n"); } if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(upmsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(upmsg, msgline); } init_status(cpucolor); sprintf(msgline, "status %s.cpu %s %s %s %s %s\n", commafy(hostname), colorname(cpucolor), (timestr ? timestr : ""), loadresult, myupstr, cpuutilstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zvm_paging_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr) { char *p; int pagerate, pagingyellow, pagingred; char pagingresult[100]; int pagingcolor = COL_GREEN; char msgline[256]; strbuffer_t *upmsg; if (!cpuutilstr) return; /* * Looking for Paging rate info in 'IND' command response * PAGING-0000/SEC */ *pagingresult = '\0'; /* Skip past three newlines in message to the PAGING text */ p=strstr(cpuutilstr,"PAGING-") + 7; if (sscanf(p, "%d/SEC", &pagerate) == 1) { sprintf(pagingresult, "z/VM Paging Rate %d per second\n", pagerate); } get_paging_thresholds(hinfo, clientclass, &pagingyellow, &pagingred); upmsg = newstrbuffer(0); if (pagerate > pagingred) { pagingcolor = COL_RED; addtobuffer(upmsg, "&red Paging Rate is CRITICAL\n"); } else if (pagerate > pagingyellow) { pagingcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Paging Rate is HIGH\n"); } init_status(pagingcolor); sprintf(msgline, "status %s.paging %s %s %s %s\n", commafy(hostname), colorname(pagingcolor), (timestr ? timestr : ""), pagingresult, cpuutilstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zvm_mdc_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr) { char *p; int mdcreads, mdcwrites, mdchitpct; char mdcresult[100]; char msgline[256]; strbuffer_t *msg; if (!cpuutilstr) return; msg = newstrbuffer(0); /* * Looking for MDC info in 'IND' command response * MDC READS-000001/SEC WRITES-000001/SEC HIT RATIO-098% */ *mdcresult = '\0'; /* Skip past three newlines in message to the PAGING text */ p=strstr(cpuutilstr,"READS-"); if (p) { p += 6; sscanf(p, "%d/SEC", &mdcreads); p=strstr(cpuutilstr,"WRITES-") + 7; sscanf(p, "%d/SEC", &mdcwrites); p=strstr(cpuutilstr,"RATIO-") + 6; sscanf(p, "%d", &mdchitpct); sprintf(msgline, "data %s.mdc\n%s\n%d:%d:%d\n", commafy(hostname), osname(os), mdcreads, mdcwrites, mdchitpct); addtobuffer(msg, msgline); combo_add(msg); } freestrbuffer(msg); } static void zvm_users_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *psstr) { int pscolor = COL_GREEN; int pchecks; int cmdofs = -1; char msgline[4096]; strbuffer_t *monmsg; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PROCS)) return; if (!psstr) return; if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); monmsg = newstrbuffer(0); sprintf(msgline, "data %s.proccounts\n", commafy(hostname)); addtobuffer(countdata, msgline); cmdofs = 0; /* Command offset for z/VM isn't necessary */ pchecks = clear_process_counts(hinfo, clientclass); if (pchecks == 0) { /* Nothing to check */ sprintf(msgline, "&%s No process checks defined\n", colorname(noreportcolor)); addtobuffer(monmsg, msgline); pscolor = noreportcolor; } else if (cmdofs >= 0) { /* Count how many instances of each monitored process is running */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; bol = psstr; while (bol) { nl = strchr(bol, '\n'); /* Take care - the ps output line may be shorter than what we look at */ if (nl) { *nl = '\0'; if ((nl-bol) > cmdofs) add_process_count(bol+cmdofs); *nl = '\n'; bol = nl+1; } else { if (strlen(bol) > cmdofs) add_process_count(bol+cmdofs); bol = NULL; } } /* Check the number found for each monitored process */ while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { if (pcolor > pscolor) pscolor = pcolor; sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the count data for later DATA message to track process counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } else { pscolor = COL_YELLOW; sprintf(msgline, "&yellow Expected string not found in ps output header\n"); addtobuffer(monmsg, msgline); } /* Now we know the result, so generate a status message */ init_status(pscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.procs %s %s - Processes %s\n", commafy(hostname), colorname(pscolor), (timestr ? timestr : ""), ((pscolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full virtual machine names output for those who want it */ if (pslistinprocs) { /* * Format the list of virtual machines into four per line, * this list could be fairly long. */ char *tmpstr, *tok, *nm[4]; int nmidx = 0; /* Make a copy of psstr, strtok() will be changing it */ tmpstr = strdup(psstr); /* Use strtok() to split string into pieces delimited by newline */ tok = strtok(tmpstr, "\n"); while (tok) { nm[nmidx++] = tok; if (nmidx == 4) { sprintf(msgline, "%-8s %-8s %-8s %-8s\n", nm[0], nm[1], nm[2], nm[3]); addtostatus(msgline); nmidx = 0; nm[0] = nm[1] = nm[2] = nm[3] = " "; } tok = strtok(NULL, "\n"); } /* Print any remaining names */ if (nmidx > 0) { sprintf(msgline, "%-8s %-8s %-8s %-8s\n", nm[0], nm[1], nm[2], nm[3]); addtostatus(msgline); } free(tmpstr); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); if (anycountdata) combo_add(countdata); clearstrbuffer(countdata); } void handle_zvm_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *cpuutilstr; char *uptimestr; char *dfstr; char *usersstr; /* Logged on z/VM Users */ char *msgsstr; char *ifstatstr; char *portsstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); cpuutilstr = getdata("cpu"); dfstr = getdata("df"); usersstr = getdata("UserID"); msgsstr = getdata("msgs"); portsstr = getdata("ports"); ifstatstr = getdata("ifstat"); zvm_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr, uptimestr); zvm_paging_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr); zvm_mdc_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr); zvm_users_report(hostname, clienttype, os, hinfo, fromline, timestr, usersstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); splitmsg_done(); } xymon-4.3.30/xymond/client/osf.c0000664000076400007640000001067112654207223016742 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for OSF */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char osf_rcsid[] = "$Id: osf.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_osf_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *memorystr; char *swapstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); memorystr = getdata("memory"); swapstr = getdata("swap"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "CMD", "COMMAND", psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (memorystr && swapstr) { char *p, *bol; long phystotal, physfree, swaptotal, swapfree, pagecnt, pagesize; /* * Total Physical Memory = 5120.00 M * = 655360 pages * * ... * * Managed Pages Break Down: * * free pages = 499488 * */ phystotal = physfree = swaptotal = swapfree = -1; pagesize = 8; /* Default - appears to be the OSF/1 standard */ bol = strstr(memorystr, "\nTotal Physical Memory ="); if (bol) { p = strchr(bol, '='); phystotal = atol(p+1); bol = strchr(p, '\n'); if (bol) { bol++; bol += strspn(bol, " \t"); if (*bol == '=') { pagecnt = atol(bol+1); pagesize = (phystotal * 1024) / pagecnt; } } } bol = strstr(memorystr, "\nManaged Pages Break Down:"); if (bol) { bol = strstr(bol, "free pages ="); if (bol) { p = strchr(bol, '='); physfree = atol(p+1) * pagesize / 1024; } } bol = strstr(swapstr, "\nTotal swap allocation:"); if (bol) { unsigned long swappages, freepages; int n1, n2; n1 = n2 = 0; p = strstr(bol, "Allocated space:"); if (p) n1 = sscanf(p, "Allocated space: %lu pages", &swappages); p = strstr(bol, "Available space:"); if (p) n2 = sscanf(p, "Available space: %lu pages", &freepages); if ((n1 == 1) && (n2 == 1)) { swaptotal = swappages * pagesize / 1024; swapfree = freepages * pagesize / 1024; } } unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, phystotal, (phystotal - physfree), -1, -1, swaptotal, (swaptotal - swapfree)); } splitmsg_done(); } xymon-4.3.30/xymond/client/openbsd.c0000664000076400007640000000753212654207223017607 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for OpenBSD */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char openbsd_rcsid[] = "$Id: openbsd.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_openbsd_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *meminfostr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *p; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); meminfostr = getdata("meminfo"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Avail", "Capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "ifree", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (meminfostr) { unsigned long memphystotal, memphysfree, memphysused; unsigned long memswaptotal, memswapfree, memswapused; int found = 0; memphystotal = memphysfree = memphysused = 0; memswaptotal = memswapfree = memswapused = 0; p = strstr(meminfostr, "Total:"); if (p) { memphystotal = atol(p+6); found++; } p = strstr(meminfostr, "Free:"); if (p) { memphysfree = atol(p+5); found++; } memphysused = memphystotal - memphysfree; p = strstr(meminfostr, "Swaptotal:"); if (p) { memswaptotal = atol(p+10); found++; } p = strstr(meminfostr, "Swapused:"); if (p) { memswapused = atol(p+9); found++; } memswapfree = memswaptotal - memswapused; if (found == 4) { unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, -1, -1, memswaptotal, memswapused); } } splitmsg_done(); } xymon-4.3.30/xymond/client/solaris.c0000664000076400007640000001302612654207223017624 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for Solaris */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char solaris_rcsid[] = "$Id: solaris.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_solaris_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *prtconfstr; char *memorystr; char *swapstr; char *swapliststr; char *dfstr; char *inodestr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *iostatdiskstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); prtconfstr = getdata("prtconf"); memorystr = getdata("memory"); swapstr = getdata("swap"); swapliststr = getdata("swaplist"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); iostatdiskstr = getdata("iostatdisk"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "avail", "capacity", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "ifree", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "CMD", "COMMAND", psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 0, 1, 6, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (prtconfstr && memorystr && (swapstr || swapliststr)) { long memphystotal, memphysfree, memswapused, memswapfree; char *p; memphystotal = memphysfree = memswapfree = memswapused = -1; p = strstr(prtconfstr, "\nMemory size:"); if (p && (sscanf(p, "\nMemory size: %ld Megabytes", &memphystotal) == 1)) ; if (sscanf(memorystr, "%*d %*d %*d %*d %ld", &memphysfree) == 1) memphysfree /= 1024; if (!swapliststr) { /* * No "swap -l" output, so use what "swap -s" reports. * Xymon clients prior to 2010-Dec-14 (roughly 4.3.0 release) does not report "swap -l". */ p = strchr(swapstr, '='); if (p && sscanf(p, "= %ldk used, %ldk available", &memswapused, &memswapfree) == 2) { memswapused /= 1024; memswapfree /= 1024; } } else { /* We prefer using "swap -l" output since it matches what other system tools report */ char *bol; long blktotal, blkfree; blktotal = blkfree = 0; bol = swapliststr; while (bol) { char *nl, *tmpline; nl = strchr(bol, '\n'); if (nl) *nl = '\0'; tmpline = strdup(bol); /* According to the Solaris man-page for versions 8 thru 10, the "swap -l" output is always 5 columns */ /* Note: getcolumn() is zero-based (thanks, Dominique Frise) */ p = getcolumn(tmpline, 3); if (p) blktotal += atol(p); strcpy(tmpline, bol); p = getcolumn(tmpline, 4); if (p) blkfree += atol(p); xfree(tmpline); if (nl) { *nl = '\n'; bol = nl+1; } else { bol = NULL; } } if ((blktotal >= 0) && (blkfree >= 0)) { /* Values from swap -l are numbers of 512-byte blocks. Convert to MB = N*512/(1024*1024) = N/2048 */ memswapused = (blktotal - blkfree) / 2048; memswapfree = blkfree / 2048; } } if ((memphystotal>=0) && (memphysfree>=0) && (memswapused>=0) && (memswapfree>=0)) { unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, (memphystotal - memphysfree), -1, -1, (memswapused + memswapfree), memswapused); } } if (iostatdiskstr) { char msgline[1024]; strbuffer_t *msg = newstrbuffer(0); char *p; p = strchr(iostatdiskstr, '\n'); if (p) { p++; sprintf(msgline, "data %s.iostatdisk\n%s\n", commafy(hostname), osname(os)); addtobuffer(msg, msgline); addtobuffer(msg, p); combo_add(msg); } freestrbuffer(msg); } splitmsg_done(); } xymon-4.3.30/xymond/client/snmpcollect.c0000664000076400007640000000671112603243142020470 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for SNMP collector */ /* */ /* Copyright (C) 2009-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char snmpcollect_rcsid[] = "$Id: snmpcollect.c 7678 2015-10-01 14:42:42Z jccleaver $"; /* * Split the snmpcollect client-message into individual mib-datasets. * Run each dataset through the mib-value configuration module, and * generate a status-message for each dataset. */ void handle_snmpcollect_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { void *ns1var, *ns1sects; char *onemib; char *mibname; char fromline[1024], msgline[1024]; strbuffer_t *summary = newstrbuffer(0); sprintf(fromline, "\nStatus message received from %s\n", sender); onemib = nextsection_r(clientdata, &mibname, &ns1var, &ns1sects); while (onemib) { char *bmark, *emark; char *oneds, *dskey; void *ns2var, *ns2sects; int color, rulecolor, anyrules; char *groups; if (strcmp(mibname, "proxy") == 0) { /* * Data was forwarded through a proxy - skip this section. * We don't want a "proxy" status for all SNMP-enabled hosts. */ goto sectiondone; } /* Convert the "" markers to "[NNN]" */ bmark = onemib; while ((bmark = strstr(bmark, "\n<")) != NULL) { emark = strchr(bmark, '>'); *(bmark+1) = '['; if (emark) *emark = ']'; bmark += 2; } /* Match the mib data against the configuration */ anyrules = 1; color = COL_GREEN; clearalertgroups(); clearstrbuffer(summary); oneds = nextsection_r(onemib, &dskey, &ns2var, &ns2sects); if (oneds) { /* Tabular MIB data. Handle each of the rows in the table. */ while (oneds && anyrules) { rulecolor = check_mibvals(hinfo, clienttype, mibname, dskey, oneds, summary, &anyrules); if (rulecolor > color) color = rulecolor; oneds = nextsection_r(NULL, &dskey, &ns2var, &ns2sects); } nextsection_r_done(ns2sects); } else { /* Non-tabular MIB data - no key */ rulecolor = check_mibvals(hinfo, clienttype, mibname, NULL, onemib, summary, &anyrules); if (rulecolor > color) color = rulecolor; } /* Generate the status message */ groups = getalertgroups(); init_status(color); if (groups) sprintf(msgline, "status/group:%s ", groups); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.%s %s %s\n", hostname, mibname, colorname(color), ctime(×tamp)); addtostatus(msgline); if (STRBUFLEN(summary) > 0) { addtostrstatus(summary); addtostatus("\n"); } addtostatus(onemib); addtostatus(fromline); finish_status(); sectiondone: onemib = nextsection_r(NULL, &mibname, &ns1var, &ns1sects); } nextsection_r_done(ns1sects); freestrbuffer(summary); } xymon-4.3.30/xymond/client/aix.c0000664000076400007640000000762013463141670016736 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for AIX */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char aix_rcsid[] = "$Id: aix.c 8066 2019-05-03 22:42:00Z jccleaver $"; void handle_aix_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *inodestr; char *msgsstr; char *netstatstr; char *ifstatstr; char *portsstr; char *vmstatstr; char *realmemstr; char *freememstr; char *swapmemstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); inodestr = getdata("inode"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); portsstr = getdata("ports"); vmstatstr = getdata("vmstat"); realmemstr = getdata("realmem"); freememstr = getdata("freemem"); swapmemstr = getdata("swap"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Free", "%Used", "Mounted", dfstr); unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "avail", "%iused", "Mounted", inodestr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", "CMD", psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if (realmemstr && freememstr && swapmemstr) { long memphystotal = 0, memphysfree = 0, memswaptotal = 0, memswappct = 0; long memacttotal = 0, memactused = 0; char *p; if (strncmp(realmemstr, "realmem ", 8) == 0) memphystotal = atol(realmemstr+8) / 1024L; if (sscanf(freememstr, "%*d %*d %*d %ld", &memphysfree) == 1) memphysfree /= 256L; if (sscanf(freememstr, "%*d %*d %ld", &memactused) == 1) memactused /= 256; p = strchr(swapmemstr, '\n'); if (p) p++; if (p && (sscanf(p, " %ldMB %ld%%", &memswaptotal, &memswappct) != 2)) { memswaptotal = memswappct = -1L; } memacttotal = memphystotal; unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, (memphystotal - memphysfree), memacttotal, memactused, memswaptotal, ((memswaptotal * memswappct) / 100L)); } splitmsg_done(); } xymon-4.3.30/xymond/client/mqcollect.c0000664000076400007640000001722112000317413020120 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for MQ collector */ /* */ /* Copyright (C) 2009-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char mqcollect_rcsid[] = "$Id: mqcollect.c 7060 2012-07-14 16:32:11Z storner $"; void mqcollect_flush_status(int color, char *fromline, time_t timestamp, char *hostname, char *qmid, strbuffer_t *redsummary, strbuffer_t *yellowsummary, strbuffer_t *greensummary, char *clienttext) { char *groups; char msgline[1024]; /* Generate the status message */ groups = getalertgroups(); init_status(color); if (groups) sprintf(msgline, "status/group:%s ", groups); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.mq %s %s\n", hostname, colorname(color), ctime(×tamp)); addtostatus(msgline); if (STRBUFLEN(redsummary) > 0) { addtostrstatus(redsummary); addtostatus("\n"); } if (STRBUFLEN(yellowsummary) > 0) { addtostrstatus(yellowsummary); addtostatus("\n"); } if (STRBUFLEN(greensummary) > 0) { addtostrstatus(greensummary); addtostatus("\n"); } addtostatus(clienttext); addtostatus("\n"); addtostatus(fromline); finish_status(); } void handle_mqcollect_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *qmline = "Starting MQSC for queue manager "; strbuffer_t *redsummary = newstrbuffer(0); strbuffer_t *yellowsummary = newstrbuffer(0); strbuffer_t *greensummary = newstrbuffer(0); char *bol, *eoln, *clienttext; int color = COL_GREEN; char fromline[1024], msgline[1024]; char *qmid = NULL, *qnam = NULL; int qlen = -1, qage = -1; char *chnnam = NULL, *chnstatus = NULL; enum { PARSING_QL, PARSING_QS, PARSING_CHS, PARSER_FLOAT } pstate = PARSER_FLOAT; int lastline = 0; sprintf(fromline, "\nStatus message received from %s\n", sender); bol = strchr(clientdata, '\n'); if (bol) bol++; clienttext = bol; while (bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; else lastline = 1; bol += strspn(bol, " \t"); if (strncmp(bol, qmline, strlen(qmline)) == 0) { char *p; if (qmid) xfree(qmid); qmid = strdup(bol+strlen(qmline)); p = strrchr(qmid, '.'); if (p) *p = '\0'; } else if ( (strncmp(bol, "AMQ8409:", 8) == 0) || /* "ql" command - Queue details, incl. depth */ (strncmp(bol, "AMQ8450:", 8) == 0) || /* "qs" command - Queue status */ (strncmp(bol, "AMQ8417:", 8) == 0) || /* "chs" command - Channel status */ lastline ) { if ( ((pstate == PARSING_QL) || (pstate == PARSING_QS)) && qmid && qnam && (qlen >= 0)) { /* Got a full queue depth status */ int warnlen, critlen, warnage, critage; char *trackid; get_mqqueue_thresholds(hinfo, clienttype, qmid, qnam, &warnlen, &critlen, &warnage, &critage, &trackid); if ((critlen != -1) && (qlen >= critlen)) { color = COL_RED; sprintf(msgline, "&red Queue %s:%s has depth %d (critical: %d, warn: %d)\n", qmid, qnam, qlen, critlen, warnlen); addtobuffer(redsummary, msgline); } else if ((warnlen != -1) && (qlen >= warnlen)) { if (color < COL_YELLOW) color = COL_YELLOW; sprintf(msgline, "&yellow Queue %s:%s has depth %d (warn: %d, critical: %d)\n", qmid, qnam, qlen, warnlen, critlen); addtobuffer(yellowsummary, msgline); } else if ((warnlen != -1) || (critlen != -1)) { sprintf(msgline, "&green Queue %s:%s has depth %d (warn: %d, critical: %d)\n", qmid, qnam, qlen, warnlen, critlen); addtobuffer(greensummary, msgline); } if ((pstate == PARSING_QS) && (qage >= 0)) { if ((critage != -1) && (qage >= critage)) { color = COL_RED; sprintf(msgline, "&red Queue %s:%s has age %d (critical: %d, warn: %d)\n", qmid, qnam, qage, critage, warnage); addtobuffer(redsummary, msgline); } else if ((warnage != -1) && (qage >= warnage)) { if (color < COL_YELLOW) color = COL_YELLOW; sprintf(msgline, "&yellow Queue %s:%s has age %d (warn: %d, critical: %d)\n", qmid, qnam, qage, warnage, critage); addtobuffer(yellowsummary, msgline); } else if ((warnage != -1) || (critage != -1)) { sprintf(msgline, "&green Queue %s:%s has age %d (warn: %d, critical: %d)\n", qmid, qnam, qage, warnage, critage); addtobuffer(greensummary, msgline); } } if (trackid) { /* FIXME: Send "data" message for creating queue-length RRD */ } pstate = PARSER_FLOAT; } if ((pstate == PARSING_CHS) && qmid && chnnam && chnstatus) { /* Got a full channel status */ int chncolor; if (get_mqchannel_params(hinfo, clienttype, qmid, chnnam, chnstatus, &chncolor)) { if (chncolor > color) color = chncolor; switch (chncolor) { case COL_RED: sprintf(msgline, "&red Channel %s:%s has status %s\n", qmid, chnnam, chnstatus); addtobuffer(redsummary, msgline); break; case COL_YELLOW: sprintf(msgline, "&yellow Channel %s:%s has status %s\n", qmid, chnnam, chnstatus); addtobuffer(yellowsummary, msgline); break; case COL_GREEN: sprintf(msgline, "&green Channel %s:%s has status %s\n", qmid, chnnam, chnstatus); addtobuffer(greensummary, msgline); break; } } pstate = PARSER_FLOAT; } if (qnam) xfree(qnam); qlen = qage = -1; if (chnnam) xfree(chnnam); if (chnstatus) xfree(chnstatus); if (strncmp(bol, "AMQ8409:", 8) == 0) pstate = PARSING_QL; else if (strncmp(bol, "AMQ8450:", 8) == 0) pstate = PARSING_QS; else if (strncmp(bol, "AMQ8417:", 8) == 0) pstate = PARSING_CHS; else pstate = PARSER_FLOAT; } else if ((pstate == PARSING_QL) || (pstate == PARSING_QS)) { char *bdup = strdup(bol); char *tok = strtok(bdup, " \t"); while (tok) { if (strncmp(tok, "QUEUE(", 6) == 0) { char *p; qnam = strdup(tok+6); p = strchr(qnam, ')'); if (p) *p = '\0'; } else if (strncmp(tok, "CURDEPTH(", 9) == 0) { qlen = atoi(tok+9); } else if (strncmp(tok, "MSGAGE(", 7) == 0) { if (isdigit(*(tok+7))) qage = atoi(tok+7); } tok = strtok(NULL, " \t"); } xfree(bdup); } else if (pstate == PARSING_CHS) { char *bdup = strdup(bol); char *tok = strtok(bdup, " \t"); while (tok) { if (strncmp(tok, "CHANNEL(", 8) == 0) { char *p; chnnam = strdup(tok+8); p = strchr(chnnam, ')'); if (p) *p = '\0'; } else if (strncmp(tok, "STATUS(", 7) == 0) { char *p; chnstatus = strdup(tok+7); p = strchr(chnstatus, ')'); if (p) *p = '\0'; } tok = strtok(NULL, " \t"); } xfree(bdup); } if (eoln) { *eoln = '\n'; bol = eoln+1; } else bol = NULL; } mqcollect_flush_status(color, fromline, timestamp, hostname, qmid, redsummary, yellowsummary, greensummary, clienttext); if (qmid) xfree(qmid); freestrbuffer(greensummary); freestrbuffer(yellowsummary); freestrbuffer(redsummary); } xymon-4.3.30/xymond/client/generic.c0000664000076400007640000000315112503303630017552 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for generic unknown client */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char generic_rcsid[] = "$Id: generic.c 7059 2012-07-14 15:18:14Z storner $"; void handle_generic_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *msgsstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); msgsstr = getdata("msgs"); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); splitmsg_done(); } xymon-4.3.30/xymond/client/zvse.c0000664000076400007640000006555412503303630017144 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for z/VSE or VSE/ESA */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* Copyright (C) 2006-2008 Rich Smrcina */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char zvse_rcsid[] = "$Id: zvse.c 7608 2015-03-21 15:00:40Z jccleaver $"; static void zvse_cpu_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cpuutilstr, char *uptimestr) { char *p; float load1, loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor, maxclockdiff, clockdiffcolor; int uphour, upmin; char loadresult[100]; char myupstr[100]; long uptimesecs = -1; long upday; int cpucolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!uptimestr) return; if (!cpuutilstr) return; uptimesecs = 0; /* * z/VSE: "Uptime: 1 Days, 13 Hours, 38 Minutes" */ sscanf(uptimestr,"Uptime: %ld Days, %d Hours, %d Minutes", &upday, &uphour, &upmin); uptimesecs = upday * 86400; uptimesecs += 60*(60*uphour + upmin); sprintf(myupstr, "%s\n", uptimestr); /* * Looking for average CPU Utilization in CPU message * Avg CPU=000% */ *loadresult = '\0'; p = strstr(cpuutilstr, "Avg CPU=") + 8 ; if (p) { if (sscanf(p, "%f%%", &load1) == 1) { sprintf(loadresult, "z/VSE CPU Utilization %3.0f%%\n", load1); } } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); upmsg = newstrbuffer(0); if (load1 > loadred) { cpucolor = COL_RED; addtobuffer(upmsg, "&red Load is CRITICAL\n"); } else if (load1 > loadyellow) { cpucolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Load is HIGH\n"); } if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(upmsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(upmsg, msgline); } init_status(cpucolor); sprintf(msgline, "status %s.cpu %s %s %s %s %s\n", commafy(hostname), colorname(cpucolor), (timestr ? timestr : ""), loadresult, myupstr, cpuutilstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zvse_paging_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *pagingstr) { char *p; int ipagerate, pagingyellow, pagingred; float fpagerate=0.0; char pagingresult[100]; int pagingcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!pagingstr) return; /* * Looking for Paging rate in message * Page Rate=0.00 /sec */ *pagingresult = '\0'; ipagerate=0; p = strstr(pagingstr, "Page Rate=") + 10; if (p) { if (sscanf(p, "%f", &fpagerate) == 1) { ipagerate=fpagerate + 0.5; /* Rounding up */ sprintf(pagingresult, "z/VSE Paging Rate %d per second\n", ipagerate); } } else sprintf(pagingresult, "Can not find page rate value in:\n%s\n", pagingstr); get_paging_thresholds(hinfo, clientclass, &pagingyellow, &pagingred); upmsg = newstrbuffer(0); if (ipagerate > pagingred) { pagingcolor = COL_RED; addtobuffer(upmsg, "&red Paging Rate is CRITICAL\n"); } else if (ipagerate > pagingyellow) { pagingcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow Paging Rate is HIGH\n"); } init_status(pagingcolor); sprintf(msgline, "status %s.paging %s %s %s %s\n", commafy(hostname), colorname(pagingcolor), (timestr ? timestr : ""), pagingresult, pagingstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zvse_cics_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cicsstr) { char cicsappl[9], cicsdate[11], cicstime[9]; int numtrans=0, cicsok=1; float dsapct=0.0; float edsapct=0.0; char cicsresult[100]; char tempresult[100]; char *cicsentry = NULL; int cicscolor = COL_GREEN; int dsayel, dsared, edsayel, edsared; char msgline[4096]; char cicsokmsg[]="All CICS Systems OK"; char cicsnotokmsg[]="One or more CICS Systems not OK"; strbuffer_t *headline; strbuffer_t *upmsg; strbuffer_t *cicsmsg; if (!cicsstr) return; cicsmsg = newstrbuffer(0); upmsg = newstrbuffer(0); headline= newstrbuffer(0); addtobuffer(headline, "Appl ID Trans DSA Pct EDSA Pct\n"); /* * * Each CICS system reporting uses one line in the message, the format is: * applid date time numtrans dsapct edsapct * applid is the CICS application id * date and time are the date and time of the report * numtrans is the number of transactions that were executed in CICS since the last report * dsapct is the DSA utilization percentage * edsapct is the EDSA utilization percentage * */ if (cicsstr) { cicsentry=strtok(cicsstr, "\n"); while (cicsentry != NULL) { sscanf(cicsentry, "%8s %10s %8s %d %f %f", cicsappl, cicsdate, cicstime, &numtrans, &dsapct, &edsapct); sprintf(cicsresult,"%-8s %6d %3.1f %3.1f\n", cicsappl, numtrans, dsapct, edsapct); addtobuffer(cicsmsg, cicsresult); if (numtrans == -1 ) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow CICS system %s not responding, removed\n", cicsappl); addtobuffer(upmsg, tempresult); } /* Get CICS thresholds for this application ID. */ get_cics_thresholds(hinfo, clientclass, cicsappl, &dsayel, &dsared, &edsayel, &edsared); /* The threshold of the DSA values for each CICS must be checked in this loop. */ if (dsapct > dsared) { if (cicscolor < COL_RED) cicscolor = COL_RED; cicsok=0; sprintf(tempresult,"&red %s DSA Utilization is CRITICAL\n", cicsappl); addtobuffer(upmsg, tempresult); } else if (dsapct > dsayel) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow %s DSA Utilization is HIGH\n", cicsappl); addtobuffer(upmsg, tempresult); } if (edsapct > edsared) { if (cicscolor < COL_RED) cicscolor = COL_RED; cicsok=0; sprintf(tempresult,"&red %s EDSA Utilization is CRITICAL\n", cicsappl); addtobuffer(upmsg, tempresult); } else if (edsapct > edsayel) { if (cicscolor < COL_YELLOW) cicscolor = COL_YELLOW; cicsok=0; sprintf(tempresult,"&yellow %s EDSA Utilization is HIGH\n", cicsappl); addtobuffer(upmsg, tempresult); } init_status(cicscolor); cicsentry=strtok(NULL, "\n"); } } sprintf(msgline, "status %s.cics %s %s %s\n", commafy(hostname), colorname(cicscolor), (timestr ? timestr : ""), ( (cicsok==1) ? cicsokmsg : cicsnotokmsg) ); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); } if (STRBUFLEN(cicsmsg)) { addtostrstatus(headline); addtostrstatus(cicsmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(headline); freestrbuffer(upmsg); freestrbuffer(cicsmsg); } static void zvse_jobs_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *psstr) { int pscolor = COL_GREEN; int pchecks; int cmdofs = -1; char msgline[4096]; strbuffer_t *monmsg; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PROCS)) return; if (!psstr) return; if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); monmsg = newstrbuffer(0); sprintf(msgline, "data %s.proccounts\n", commafy(hostname)); addtobuffer(countdata, msgline); cmdofs = 0; /* Command offset for z/VSE isn't necessary */ pchecks = clear_process_counts(hinfo, clientclass); if (pchecks == 0) { /* Nothing to check */ sprintf(msgline, "&%s No process checks defined\n", colorname(noreportcolor)); addtobuffer(monmsg, msgline); pscolor = noreportcolor; } else if (cmdofs >= 0) { /* Count how many instances of each monitored process is running */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; bol = psstr; while (bol) { nl = strchr(bol, '\n'); /* Take care - the ps output line may be shorter than what we look at */ if (nl) { *nl = '\0'; if ((nl-bol) > cmdofs) add_process_count(bol+cmdofs); *nl = '\n'; bol = nl+1; } else { if (strlen(bol) > cmdofs) add_process_count(bol+cmdofs); bol = NULL; } } /* Check the number found for each monitored process */ while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { if (pcolor > pscolor) pscolor = pcolor; sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the count data for later DATA message to track process counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } else { pscolor = COL_YELLOW; sprintf(msgline, "&yellow Expected string not found in ps output header\n"); addtobuffer(monmsg, msgline); } /* Now we know the result, so generate a status message */ init_status(pscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.procs %s %s - Processes %s\n", commafy(hostname), colorname(pscolor), (timestr ? timestr : ""), ((pscolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full list of jobs for those who want it */ if (pslistinprocs) { /* * Format the list of virtual machines into four per line, * this list could be fairly long. */ char *tmpstr, *tok; /* Make a copy of psstr, strtok() will be changing it */ tmpstr = strdup(psstr); /* Use strtok() to split string into pieces delimited by newline */ tok = strtok(tmpstr, "\n"); while (tok) { sprintf(msgline, "%s\n", tok); addtostatus(msgline); tok = strtok(NULL, "\n"); } free(tmpstr); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); if (anycountdata) combo_add(countdata); clearstrbuffer(countdata); } static void zvse_memory_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *memstr) { int usedyellow, usedred; /* Thresholds for total used system memory */ int sysmemok=1; long totmem, availmem; float pctavail, pctused; char memorystr[1024]; int memorycolor = COL_GREEN; char memokmsg[]="Memory OK"; char memnotokmsg[]="Memory Not OK"; char msgline[4096]; strbuffer_t *upmsg; if (!memstr) return; upmsg = newstrbuffer(0); /* * The message is just two values, the total system memory and * the available memory; both values are in K. * tttttt aaaaaa */ sscanf(memstr, "%ld %ld", &totmem, &availmem); pctavail = ((float)availmem / (float)totmem) * 100; pctused = 100 - pctavail; sprintf(memorystr, "z/VSE VSIZE Utilization %3.1f%%\nMemory Allocated %ldK, Memory Available %ldK\n", pctused, totmem, availmem); get_zvsevsize_thresholds(hinfo, clientclass, &usedyellow, &usedred); if (pctused > (float)usedred) { memorycolor = COL_RED; sysmemok=0; addtobuffer(upmsg, "&red VSIZE Utilization is CRITICAL\n"); } else if (pctused > (float)usedyellow) { memorycolor = COL_YELLOW; sysmemok=0; addtobuffer(upmsg, "&yellow VSIZE Utilization is HIGH\n"); } init_status(memorycolor); sprintf(msgline, "status %s.memory %s %s %s\n%s", commafy(hostname), colorname(memorycolor), (timestr ? timestr : ""), ( (sysmemok==1) ? memokmsg : memnotokmsg ), memorystr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } static void zvse_getvis_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *gvstr) { char *q; int gv24yel, gv24red, gvanyyel, gvanyred; /* Thresholds for getvis */ int getvisok=1; float used24p, usedanyp; char jinfo[11], pid[4], jobname[9]; int size24, used24, free24, sizeany, usedany, freeany; char *getvisentry = NULL; char tempresult[128]; char getvisresult[128]; char msgline[4096]; int memorycolor = COL_GREEN; char getvisokmsg[]="Getvis OK"; char getvisnotokmsg[]="Getvis Not OK"; strbuffer_t *getvismsg; strbuffer_t *upmsg; strbuffer_t *headline; if (!gvstr) return; getvismsg = newstrbuffer(0); upmsg = newstrbuffer(0); headline = newstrbuffer(0); /* * The getvis message is a table if the partitions requested including the SVA. * The format of the table is: * * Partition Used/24 Free/24 Used/Any Free/Any * SVA 748 1500 2056 5604 * F1 824 264 824 264 * Z1-CICSICCF 7160 3844 27516 4992 * O1-CICS1 5912 5092 31584 19352 */ addtobuffer(headline, "z/VSE Getvis Map\nPID Jobname Size24 Used24 Free24 SizeAny UsedAny FreeAny Used24% UsedAny%\n"); getvisentry=strtok(gvstr, "\n"); getvisentry=strtok(NULL, "\n"); /* Skip heading line */ while (getvisentry != NULL) { sscanf(getvisentry, "%s %d %d %d %d", jinfo, &used24, &free24, &usedany, &freeany); q = strchr(jinfo, '-'); /* Check if jobname passed */ if (q) { strncpy(pid, jinfo, 2); /* Copy partition ID */ q++; /* Increment pointer */ strcpy(jobname,q); /* Copy jobname */ } else { strcpy(pid,jinfo); /* Just copy jinfo into partition ID */ strcpy(jobname, "- "); /* Jobname placeholder */ } size24 = used24 + free24; sizeany = usedany + freeany; used24p = ( (float)used24 / (float)size24 ) * 100; usedanyp = ( (float)usedany / (float)sizeany ) * 100; sprintf(getvisresult,"%-3s %-8s %6d %6d %6d %6d %6d %6d %3.0f %3.0f\n", pid, jobname, size24, used24, free24, sizeany, usedany, freeany, used24p, usedanyp); get_zvsegetvis_thresholds(hinfo, clientclass, pid, &gv24yel, &gv24red, &gvanyyel, &gvanyred); if (used24p > (float)gv24red) { memorycolor = COL_RED; getvisok=0; sprintf(tempresult,"&red 24-bit Getvis utilization for %s is CRITICAL\n", pid); addtobuffer(upmsg, tempresult); } else if (used24p > (float)gv24yel) { memorycolor = COL_YELLOW; getvisok=0; sprintf(tempresult,"&yellow 24-bit Getvis utilization for %s is HIGH\n", pid); addtobuffer(upmsg, tempresult); } if (usedanyp > (float)gvanyred) { memorycolor = COL_RED; getvisok=0; sprintf(tempresult,"&red Any Getvis utilization for %s is CRITICAL\n", pid); addtobuffer(upmsg, tempresult); } else if (usedanyp > (float)gvanyyel) { memorycolor = COL_YELLOW; getvisok=0; sprintf(tempresult,"&yellow Any Getvis utilization for %s is HIGH\n", pid); addtobuffer(upmsg, tempresult); } addtobuffer(getvismsg, getvisresult); getvisentry=strtok(NULL, "\n"); } init_status(memorycolor); sprintf(msgline, "status %s.getvis %s %s %s\n", commafy(hostname), colorname(memorycolor), (timestr ? timestr : ""), ( (getvisok==1) ? getvisokmsg : getvisnotokmsg ) ); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (STRBUFLEN(getvismsg)) { addtostrstatus(headline); addtostrstatus(getvismsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(headline); freestrbuffer(upmsg); freestrbuffer(getvismsg); } void zvse_nparts_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *npartstr) { char npdispstr[256]; long nparts, runparts, partsavail; int npartsyellow, npartsred; float partutil; int npartcolor = COL_GREEN; char msgline[4096]; strbuffer_t *upmsg; if (!npartstr) return; sscanf(npartstr, "%ld %ld", &nparts, &runparts); /* * The nparts message is two values that indicate the maximum number of partitions * configured in the system (based on the NPARTS value in the IPL proc) and * the number of partitions currently running jobs: * The format of the data is: * * nnnnnnn mmmmmmm * */ partsavail = nparts - runparts; partutil = ((float)runparts / (float)nparts) * 100; get_asid_thresholds(hinfo, clientclass, &npartsyellow, &npartsred); upmsg = newstrbuffer(0); if ((int)partutil > npartsred) { if (npartcolor < COL_RED) npartcolor = COL_RED; addtobuffer(upmsg, "&red NPARTS Utilization is CRITICAL\n"); } else if ((int)partutil > npartsyellow) { if (npartcolor < COL_YELLOW) npartcolor = COL_YELLOW; addtobuffer(upmsg, "&yellow NPARTS Utilization is HIGH\n"); } *npdispstr = '\0'; sprintf(npdispstr, "Nparts: %8ld Free: %8ld Used: %8ld %3.1f\n",nparts,partsavail,runparts,partutil); init_status(npartcolor); sprintf(msgline, "status %s.nparts %s %s\n%s", commafy(hostname), colorname(npartcolor), (timestr ? timestr : ""), npdispstr); addtostatus(msgline); if (STRBUFLEN(upmsg)) { addtostrstatus(upmsg); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(upmsg); } void handle_zvse_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *cpuutilstr; char *pagingstr; char *cicsstr; char *uptimestr; char *dfstr; char *jobsstr; /* z/VSE Running jobs */ char *portsstr; char *memstr; /* System Memory data */ char *gvstr; /* GETVIS data */ char *npartstr; /* Num Parts */ char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); cpuutilstr = getdata("cpu"); pagingstr = getdata("paging"); cicsstr = getdata("cics"); dfstr = getdata("df"); jobsstr = getdata("jobs"); portsstr = getdata("ports"); memstr = getdata("memory"); gvstr = getdata("getvis"); npartstr = getdata("nparts"); zvse_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, cpuutilstr, uptimestr); zvse_paging_report(hostname, clienttype, os, hinfo, fromline, timestr, pagingstr); zvse_cics_report(hostname, clienttype, os, hinfo, fromline, timestr, cicsstr); zvse_jobs_report(hostname, clienttype, os, hinfo, fromline, timestr, jobsstr); zvse_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memstr); zvse_getvis_report(hostname, clienttype, os, hinfo, fromline, timestr, gvstr); zvse_nparts_report(hostname, clienttype, os, hinfo, fromline, timestr, npartstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Cap", "Mounted", dfstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); splitmsg_done(); } xymon-4.3.30/xymond/client/sco_sv.c0000664000076400007640000001106212654207223017442 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for SCO_SV */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* Copyright (C) 2006-2008 Charles Goyard */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char sco_sv_rcsid[] = "$Id: sco_sv.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_sco_sv_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *freememstr; char *memsizestr; char *swapstr; char *msgsstr; char *netstatstr; char *vmstatstr; char *ifstatstr; char *portsstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); memsizestr = getdata("memsize"); freememstr = getdata("freemem"); swapstr = getdata("swap"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); vmstatstr = getdata("vmstat"); portsstr = getdata("ports"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); unix_vmstat_report(hostname, clienttype, os, hinfo, fromline, timestr, vmstatstr); if(freememstr && memsizestr && swapstr) { long memphystotal, memphysfree, memswaptotal, memswapfree; char *p; memphystotal = memphysfree = 0; memphystotal = (atol(memsizestr) / 1048576); if(sscanf(freememstr, "%*s %ld %ld %*d %*d", &memphysfree, &memswapfree) == 2) memphysfree /= 256; /* comes in 4kb pages */ else memphysfree = -1; memswaptotal = memswapfree = 0; if (swapstr) { p = strchr(swapstr, '\n'); /* Skip the header line */ while (p) { long stot, sfree; char *bol; bol = p+1; p = strchr(bol, '\n'); if (p) *p = '\0'; if (sscanf(bol, "%*s %*s %*d %ld %ld", &stot, &sfree) == 2) { memswaptotal += stot; memswapfree += sfree; } if (p) *p = '\n'; } memswaptotal /= 2048 ; memswapfree /= 2048; } unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, (memphystotal - memphysfree), -1, -1, memswaptotal, (memswaptotal - memswapfree)); } splitmsg_done(); } xymon-4.3.30/xymond/client/irix.c0000664000076400007640000001052712654207223017126 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module for IRIX */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char irix_rcsid[] = "$Id: irix.c 7886 2016-02-02 20:16:19Z jccleaver $"; void handle_irix_client(char *hostname, char *clienttype, enum ostype_t os, void *hinfo, char *sender, time_t timestamp, char *clientdata) { static pcre *memptn = NULL; char *timestr; char *uptimestr; char *clockstr; char *msgcachestr; char *whostr; char *psstr; char *topstr; char *dfstr; char *msgsstr; char *netstatstr; // char *sarstr; char *ifstatstr; char *portsstr; char fromline[1024]; sprintf(fromline, "\nStatus message received from %s\n", sender); splitmsg(clientdata); timestr = getdata("date"); uptimestr = getdata("uptime"); clockstr = getdata("clock"); msgcachestr = getdata("msgcache"); whostr = getdata("who"); psstr = getdata("ps"); topstr = getdata("top"); dfstr = getdata("df"); msgsstr = getdata("msgs"); netstatstr = getdata("netstat"); ifstatstr = getdata("ifstat"); // sarstr = getdata("sar"); portsstr = getdata("ports"); unix_cpu_report(hostname, clienttype, os, hinfo, fromline, timestr, uptimestr, clockstr, msgcachestr, whostr, 0, psstr, 0, topstr); unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr); unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "COMMAND", NULL, psstr); unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr); msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr); file_report(hostname, clienttype, os, hinfo, fromline, timestr); linecount_report(hostname, clienttype, os, hinfo, fromline, timestr); deltacount_report(hostname, clienttype, os, hinfo, fromline, timestr); unix_netstat_report(hostname, clienttype, os, hinfo, fromline, timestr, netstatstr); unix_ifstat_report(hostname, clienttype, os, hinfo, fromline, timestr, ifstatstr); /* unix_sar_report(hostname, clienttype, os, hinfo, fromline, timestr, sarstr); */ if (topstr) { char *memline, *eoln = NULL; int res; int ovector[20]; char w[20]; long memphystotal = -1, memphysused = -1, memphysfree = 0, memacttotal = -1, memactused = -1, memactfree = -1, memswaptotal = -1, memswapused = -1, memswapfree = 0; if (!memptn) { memptn = compileregex("^Memory: (\\d+)M max, (\\d+)M avail, (\\d+)M free, (\\d+)M swap, (\\d+)M free swap"); } memline = strstr(topstr, "\nMemory:"); if (memline) { memline++; eoln = strchr(memline, '\n'); if (eoln) *eoln = '\0'; res = pcre_exec(memptn, NULL, memline, strlen(memline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); } else res = -1; if (res > 1) { pcre_copy_substring(memline, ovector, res, 1, w, sizeof(w)); memphystotal = atol(w); } if (res > 2) { pcre_copy_substring(memline, ovector, res, 2, w, sizeof(w)); memactfree = atol(w); memacttotal = memphystotal; memactused = memphystotal - memactfree; } if (res > 3) { pcre_copy_substring(memline, ovector, res, 3, w, sizeof(w)); memphysfree = atol(w); memphysused = memphystotal - memphysfree; } if (res > 4) { pcre_copy_substring(memline, ovector, res, 4, w, sizeof(w)); memswaptotal = atol(w); } if (res > 5) { pcre_copy_substring(memline, ovector, res, 5, w, sizeof(w)); memswapfree = atol(w); } memswapused = memswaptotal - memswapfree; if (eoln) *eoln = '\n'; unix_memory_report(hostname, clienttype, os, hinfo, fromline, timestr, memphystotal, memphysused, memacttotal, memactused, memswaptotal, memswapused); } splitmsg_done(); } xymon-4.3.30/xymond/xymond_hostdata.c0000664000076400007640000002020712536407005020075 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This Xymon worker module saves the client messages that arrive on the */ /* CLICHG channel, for use when looking at problems with a host. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_hostdata.c 7669 2015-06-11 22:39:01Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_worker.h" #include #define MAX_META 20 /* The maximum number of meta-data items in a message */ typedef struct savetimes_t { char *hostname; time_t tstamp[12]; } savetimes_t; void * savetimes; static char *clientlogdir = NULL; int nextfscheck = 0; void sig_handler(int signum) { /* * Why this? Because we must have our own signal handler installed to call wait() */ switch (signum) { case SIGCHLD: break; case SIGHUP: nextfscheck = 0; break; } } void update_locator_hostdata(char *id) { DIR *fd; struct dirent *d; fd = opendir(clientlogdir); if (fd == NULL) { errprintf("Cannot scan directory %s\n", clientlogdir); return; } while ((d = readdir(fd)) != NULL) { if (*(d->d_name) == '.') continue; locator_register_host(d->d_name, ST_HOSTDATA, id); } closedir(fd); } int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; int recentperiod = 3600; int maxrecentcount = 5; int logdirfull = 0; int minlogspace = 5; struct sigaction sa; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--logdir=")) { clientlogdir = strchr(argv[argi], '=')+1; } else if (argnmatch(argv[argi], "--recent-period=")) { char *p = strchr(argv[argi], '='); recentperiod = 60*atoi(p+1); } else if (argnmatch(argv[argi], "--recent-count=")) { char *p = strchr(argv[argi], '='); maxrecentcount = atoi(p+1); } else if (argnmatch(argv[argi], "--minimum-free=")) { minlogspace = atoi(strchr(argv[argi], '=')+1); } else if (strcmp(argv[argi], "--debug") == 0) { /* * A global "debug" variable is available. If * it is set, then "dbgprintf()" outputs debug messages. */ debug = 1; } else if (net_worker_option(argv[argi])) { /* Handled in the subroutine */ } } if (clientlogdir == NULL) clientlogdir = xgetenv("CLIENTLOGS"); if (clientlogdir == NULL) { clientlogdir = (char *)malloc(strlen(xgetenv("XYMONVAR")) + 10); sprintf(clientlogdir, "%s/hostdata", xgetenv("XYMONVAR")); } save_errbuf = 0; /* Do the network stuff if needed */ net_worker_run(ST_HOSTDATA, LOC_STICKY, update_locator_hostdata); setup_signalhandler("xymond_hostdata"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; signal(SIGCHLD, SIG_IGN); sigaction(SIGHUP, &sa, NULL); signal(SIGPIPE, SIG_DFL); savetimes = xtreeNew(strcasecmp); running = 1; while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; msg = get_xymond_message(C_CLICHG, "xymond_hostdata", &seq, NULL); if (msg == NULL) { /* * get_xymond_message will return NULL if xymond_channel closes * the input pipe. We should shutdown when that happens. */ running = 0; continue; } if (nextfscheck < gettimer()) { logdirfull = (chkfreespace(clientlogdir, minlogspace, minlogspace) != 0); if (logdirfull) errprintf("Hostdata directory %s has less than %d%% free space - disabling save of data for 5 minutes\n", clientlogdir, minlogspace); nextfscheck = gettimer() + 300; } /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; if (strncmp(metadata[0], "@@clichg", 8) == 0) { xtreePos_t handle; savetimes_t *itm; int i, recentcount; time_t now = gettimer(); char hostdir[PATH_MAX]; char fn[PATH_MAX]; FILE *fd; /* metadata[3] is the hostname */ handle = xtreeFind(savetimes, metadata[3]); if (handle != xtreeEnd(savetimes)) { itm = (savetimes_t *)xtreeData(savetimes, handle); } else { itm = (savetimes_t *)calloc(1, sizeof(savetimes_t)); itm->hostname = strdup(metadata[3]); xtreeAdd(savetimes, itm->hostname, itm); } /* See how many times we've saved the hostdata recently (within the past 'recentperiod' seconds) */ for (i=0, recentcount=0; ((i < 12) && (itm->tstamp[i] > (now - recentperiod))); i++) recentcount++; /* If it's been saved less than 'maxrecentcount' times, then save it. Otherwise just drop it */ if (!logdirfull && (recentcount < maxrecentcount)) { int written, closestatus, ok = 1; for (i = 10; (i > 0); i--) itm->tstamp[i+1] = itm->tstamp[i]; itm->tstamp[0] = now; sprintf(hostdir, "%s/%s", clientlogdir, metadata[3]); mkdir(hostdir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); sprintf(fn, "%s/%s", hostdir, metadata[4]); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot create file %s: %s\n", fn, strerror(errno)); continue; } written = fwrite(restofmsg, 1, strlen(restofmsg), fd); if (written != strlen(restofmsg)) { errprintf("Cannot write hostdata file %s: %s\n", fn, strerror(errno)); closestatus = fclose(fd); /* Ignore any close errors */ ok = 0; } else { closestatus = fclose(fd); if (closestatus != 0) { errprintf("Cannot write hostdata file %s: %s\n", fn, strerror(errno)); ok = 0; } } if (!ok) remove(fn); } } /* * A "shutdown" message is sent when the master daemon * terminates. The child workers should shutdown also. */ else if (strncmp(metadata[0], "@@shutdown", 10) == 0) { running = 0; continue; } else if (strncmp(metadata[0], "@@idle", 6) == 0) { /* Ignored */ continue; } /* * A "logrotate" message is sent when the Xymon logs are * rotated. The child workers must re-open their logfiles, * typically stdin and stderr - the filename is always * provided in the XYMONCHANNEL_LOGFILENAME environment. */ else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); } continue; } else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) { /* @@drophost|timestamp|sender|hostname */ char hostdir[PATH_MAX]; snprintf(hostdir, sizeof(hostdir), "%s/%s", clientlogdir, basename(metadata[3])); dropdirectory(hostdir, 1); } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { /* @@renamehost|timestamp|sender|hostname|newhostname */ char oldhostdir[PATH_MAX], newhostdir[PATH_MAX]; snprintf(oldhostdir, sizeof(oldhostdir), "%s/%s", clientlogdir, basename(metadata[3])); snprintf(newhostdir, sizeof(newhostdir), "%s/%s", clientlogdir, basename(metadata[4])); rename(oldhostdir, newhostdir); if (net_worker_locatorbased()) locator_rename_host(metadata[3], metadata[4], ST_HOSTDATA); } else if (strncmp(metadata[0], "@@reload", 8) == 0) { /* Do nothing */ } } return 0; } xymon-4.3.30/xymond/xymond_capture.c0000664000076400007640000002547712603243142017742 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* xymond worker module, to capture status messages for a particulr host */ /* or test, or data type. This is fed from the status- or data-channel, and */ /* simply logs the data received to a file. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_capture.c 7678 2015-10-01 14:42:42Z jccleaver $"; #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_worker.h" #define MAX_META 20 /* The maximum number of meta-data items in a message */ int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; struct timespec *timeout = NULL; pcre *hostexp = NULL; pcre *exhostexp = NULL; pcre *testexp = NULL; pcre *extestexp = NULL; pcre *colorexp = NULL; const char *errmsg = NULL; int errofs = 0; FILE *logfd = stdout; int batchtimeout = 30; char *batchcmd = NULL; strbuffer_t *batchbuf = NULL; time_t lastmsgtime = 0; int hostnameitem = 4, testnameitem = 5, coloritem = 7; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { /* * A global "debug" variable is available. If * it is set, then "dbgprintf()" outputs debug messages. */ debug = 1; } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { /* * You can have a timeout when waiting for new * messages. If it happens, you will get a "@@idle\n" * message with sequence number 0. * If you don't want a timeout, just pass a NULL for the timeout parameter. */ timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = (atoi(argv[argi]+10)); timeout->tv_nsec = 0; } else if (strcmp(argv[argi], "--client") == 0) { hostnameitem = 3; testnameitem = 4; errprintf("Expecting to be fed from 'client' channel\n"); } else if (argnmatch(argv[argi], "--hosts=")) { char *exp = strchr(argv[argi], '=') + 1; hostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--exhosts=")) { char *exp = strchr(argv[argi], '=') + 1; exhostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--tests=")) { char *exp = strchr(argv[argi], '=') + 1; testexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--extests=")) { char *exp = strchr(argv[argi], '=') + 1; extestexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--colors=")) { char *exp = strchr(argv[argi], '=') + 1; colorexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colorexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--outfile=")) { char *fn = strchr(argv[argi], '=') + 1; logfd = fopen(fn, "a"); if (logfd == NULL) { printf("Cannot open logfile %s: %s\n", fn, strerror(errno)); logfd = stdout; } } else if (argnmatch(argv[argi], "--batch-timeout=")) { char *p = strchr(argv[argi], '='); batchtimeout = atoi(p+1); timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = batchtimeout; timeout->tv_nsec = 0; } else if (argnmatch(argv[argi], "--batch-command=")) { char *p = strchr(argv[argi], '='); batchcmd = strdup(p+1); batchbuf = newstrbuffer(0); } else { printf("Unknown option %s\n", argv[argi]); printf("Usage: %s [--hosts=EXP] [--tests=EXP] [--exhosts=EXP] [--extests=EXP] [--color=EXP] [--outfile=FILENAME] [--batch-timeout=N] [--batch-command=COMMAND]\n", argv[0]); return 0; } } signal(SIGCHLD, SIG_IGN); running = 1; while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; msg = get_xymond_message(C_LAST, argv[0], &seq, timeout); if (msg == NULL) { /* * get_xymond_message will return NULL if xymond_channel closes * the input pipe. We should shutdown when that happens. */ running = 0; continue; } /* * Now we have a message. So do something with it. * * The first line of the message is always a '|' separated * list of meta-data about the message. After the first * line, the content varies by channel. */ /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } /* * Now parse the meta-data into elements. * We use our own "gettok()" routine which works * like strtok(), but can handle empty elements. */ metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; /* * A "shutdown" message is sent when the master daemon * terminates. The child workers should shutdown also. */ if (strncmp(metadata[0], "@@shutdown", 10) == 0) { printf("Shutting down\n"); running = 0; continue; } /* * A "logrotate" message is sent when the Xymon logs are * rotated. The child workers must re-open their logfiles, * typically stdin and stderr - the filename is always * provided in the XYMONDHANNEL_LOGFILENAME environment. */ else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); } continue; } /* * A "reload" means the hosts.cfg file has changed. */ else if (strncmp(metadata[0], "@@reload", 8) == 0) { /* Nothing ... right now */ } /* * An "idle" message appears when get_xymond_message() * exceeds the timeout setting (ie. you passed a timeout * value). This allows your worker module to perform * some internal processing even though no messages arrive. */ else if (strncmp(metadata[0], "@@idle", 6) == 0) { dbgprintf("Got an 'idle' message\n"); } /* * The "drophost", "droptest", "renamehost" and "renametst" * indicates that a host/test was deleted or renamed. If the * worker module maintains some internal storage (in memory * or persistent file-storage), it should act on these * messages to maintain data consistency. */ else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) { dbgprintf("Got a 'drophost' message for host '%s'\n", metadata[3]); } else if ((metacount > 3) && (strncmp(metadata[0], "@@dropstate", 11) == 0)) { dbgprintf("Got a 'dropstate' message for host '%s'\n", metadata[3]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) { dbgprintf("Got a 'droptest' message for host '%s' test '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { dbgprintf("Got a 'renamehost' message for host '%s' -> '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { dbgprintf("Got a 'renametest' message for host '%s' test '%s' -> '%s'\n", metadata[3], metadata[4], metadata[5]); } /* * Process this message. */ else { int ovector[30]; int match, i; char *hostname = metadata[hostnameitem]; char *testname = metadata[testnameitem]; char *color = metadata[coloritem]; /* See if we should handle the batched messages we've got */ if (batchcmd && ((lastmsgtime + batchtimeout) < gettimer()) && (STRBUFLEN(batchbuf) > 0)) { pid_t childpid = fork(); int childres = 0; if (childpid < 0) { /* Fork failed! */ errprintf("Fork failed: %s\n", strerror(errno)); } else if (childpid == 0) { /* Child */ FILE *cmdpipe = popen(batchcmd, "w"); if (cmdpipe) { /* Write the data to the batch command pipe */ int n, bytesleft = STRBUFLEN(batchbuf); char *outp = STRBUF(batchbuf); while (bytesleft) { n = fwrite(outp, 1, bytesleft, cmdpipe); if (n >= 0) { bytesleft -= n; outp += n; } else { errprintf("Error while writing data to batch command\n"); bytesleft = 0; } } childres = pclose(cmdpipe); } else { errprintf("Could not open pipe to batch command '%s'\n", batchcmd); childres = 127; } exit(childres); } else if (childpid > 0) { /* Parent continues */ } clearstrbuffer(batchbuf); } if (hostexp) { match = (pcre_exec(hostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(exhostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (testexp) { match = (pcre_exec(testexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (extestexp) { match = (pcre_exec(extestexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (colorexp) { match = (pcre_exec(colorexp, NULL, color, strlen(color), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } lastmsgtime = gettimer(); if (batchcmd) { addtobuffer(batchbuf, "## "); for (i=0; (i < metacount); i++) { addtobuffer(batchbuf, metadata[i]); addtobuffer(batchbuf, " "); } addtobuffer(batchbuf, "\n"); addtobuffer(batchbuf, restofmsg); addtobuffer(batchbuf, "\n"); } else { fprintf(logfd, "## "); for (i=0; (i < metacount); i++) fprintf(logfd, "%s ", metadata[i]); fprintf(logfd, "\n"); fprintf(logfd, "%s\n", restofmsg); } } } return 0; } xymon-4.3.30/xymond/xymond.80000664000076400007640000003464713534041733016151 0ustar rpmbuildrpmbuild.TH XYMOND 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond \- Master network daemon for a Xymon server .SH SYNOPSIS .B "xymond [options]" .SH DESCRIPTION xymond is the core daemon in the Xymon Monitor. It is designed to handle monitoring of a large number of hosts, with a strong focus on being a high-speed, low-overhead implementation of a Big Brother compatible server. To achieve this, xymond stores all information about the state of the monitored systems in memory, instead of storing it in the host filesystem. A number of plug-ins can be enabled to enhance the basic operation; e.g. a set of plugins are provided to implement persistent storage in a way that is compatible with the Big Brother daemon. However, even with these plugins enabled, xymond still performs much faster than the standard bbd daemon. xymond is normally started and controlled by the .I xymonlaunch(8) tool, and the command used to invoke xymond should therefore be in the tasks.cfg file. .SH OPTIONS .IP "\-\-hosts=FILENAME" Specifies the path to the Xymon hosts.cfg file. This is used to check if incoming status messages refer to known hosts; depending on the "\-\-ghosts" option, messages for unknown hosts may be dropped. If this option is omitted, the default path used is set by the HOSTSCFG environment variable. .IP "\-\-checkpoint\-file=FILENAME" With regular intervals, xymond will dump all of its internal state to this check-point file. It is also dumped when xymond terminates, or when it receives a SIGUSR1 signal. .IP "\-\-checkpoint\-interval=N" Specifies the interval (in seconds) between dumps to the check-point file. The default is 900 seconds (15 minutes). .IP "\-\-restart=FILENAME" Specifies an existing file containing a previously generated xymond checkpoint. When starting up, xymond will restore its internal state from the information in this file. You can use the same filename for "\-\-checkpoint\-file" and "\-\-restart". .IP "\-\-ghosts={allow|drop|log|match}" How to handle status messages from unknown hosts. The "allow" setting accepts all status messages, regardless of whether the host is known in the hosts.cfg file or not. "drop" silently ignores reports from unknown hosts. "log" works like drop, but logs the event in the xymond output file. "match" will try to match the name of the unknown host reporting with the known names by ignoring any domain-names - if a match is found, then a temporary client alias is automatically generated. The default is "log". .IP "\-\-no\-purple" Prevent status messages from going purple when they are no longer valid. Unlike the standard bbd daemon, purple-handling is done by xymond. .IP "\-\-merge\-clientlocal" The .I client-local.cfg(5) file contains client-configuration which can be found matching a client against its hostname, its classname, or the name of the OS the client is running. By default xymond will return one entry from the file to the client, looking for a hostname, classname or OS match (in that order). This option causes xymond to merge all matching entries together into one and return all of it to the client. .IP "\-\-listen=IP[:PORT]" Specifies the IP-address and port where xymond will listen for incoming connections. By default, xymond listens on IP 0.0.0.0 (i.e. all IP- addresses available on the host) and port 1984. .IP "\-\-lqueue=NUMBER" Specifies the listen-queue for incoming connections. You don't need to tune this unless you have a very busy xymond daemon. .IP "\-\-no\-bfq" Tells xymond to NOT use the local messagequeue interface for receiving status- updates from xymond_client and xymonnet. .IP "\-\-daemon" xymond is normally started by \fIxymonlaunch(8)\fR. If you do not want to use xymonlaunch, you can start xymond with this option; it will then detach from the terminal and continue running as a background task. .IP "\-\-timeout=N" Set the timeout used for incoming connections. If a status has not been received more than N seconds after the connection was accepted, then the connection is dropped and any status message is discarded. Default: 10 seconds. .IP "\-\-flap\-count=N" Track the N latest status-changes for flap-detection. See the \fB\-\-flap\-seconds\fR option also. To disable flap-checks globally, set N to zero. To disable for a specific host, you must use the "noflap" option in \fIhosts.cfg(5)\fR. Default: 5 .IP "\-\-flap\-seconds=N" If a status changes more than \fBflap\-count\fR times in N seconds or less, then it is considered to be flapping. In that case, the status is locked at the most severe level until the flapping stops. The history information is not updated after the flapping is detected. \fBNOTE:\fR If this is set higher than the default value, you should also use the \fB\-\-flap\-count\fR option to ensure that enough status-changes are stored for flap detection to work. The flap\-count setting should be at least (N/300)\-1, e.g. if you set flap\-seconds to 3600 (1 hour), then flap\-count should be at least (3600/300)\-1, i.e. 11. Default: 1800 seconds (30 minutes). .IP "\-\-delay\-red=N" .IP "\-\-delay\-yellow=N" Sets the delay before a red/yellow status causes a change in the web page display. Is usually controlled on a per-host basis via the \fBdelayred\fR and \fBdelayyellow\fR settings in .I hosts.cfg(5) but these options allow you to set a default value for the delays. The value N is in minutes. Default: 0 minutes (no delay). Note: Since most tests only execute once every 5 minutes, it will usually not make sense to set N to anything but a multiple of 5. .IP "\-\-env=FILENAME" Loads the content of FILENAME as environment settings before starting xymond. This is mostly used when running as a stand-alone daemon; if xymond is started by xymonlaunch, the environment settings are controlled by the xymonlaunch tasks.cfg file. .IP "\-\-pidfile=FILENAME" xymond writes the process-ID it is running with to this file. This is for use in automated startup scripts. The default file is $XYMONSERVERLOGS/xymond.pid. .IP "\-\-log=FILENAME" Redirect all output from xymond to FILENAME. .IP "\-\-store\-clientlogs[=[!]COLUMN]" Determines which status columns can cause a client message to be broadcast to the CLICHG channel. By default, no client messages are pushed to the CLICHG channel. If this option is specified with no parameter list, all status columns that go into an alert state will trigger the client data to be sent to the CLICHG channel. If a parameter list is added to this option, only those status columns listed in the list will cause the client data to be sent to the CLICHG channel. Several column names can be listed, separated by commas. If all columns are given as "!COLUMNNAME", then all status columns except those listed will cause the client data to be sent. .IP "\-\-status\-senders=IP[/MASK][,IP/MASK]" Controls which hosts may send "status", "combo", "config" and "query" commands to xymond. By default, any host can send status-updates. If this option is used, then status-updates are accepted only if they are sent by one of the IP-addresses listed here, or if they are sent from the IP-address of the host that the updates pertains to (this is to allow Xymon clients to send in their own status updates, without having to list all clients here). So typically you will need to list your servers running network tests here. The format of this option is a list of IP-addresses, optionally with a network mask in the form of the number of bits. E.g. if you want to accept status-updates from the host 172.16.10.2, you would use .br \-\-status\-senders=172.16.10.2 .br whereas if you want to accept status updates from both 172.16.10.2 and from all of the hosts on the 10.0.2.* network (a 24-bit IP network), you would use .br \-\-status\-senders=172.16.10.2,10.0.2.0/24 .IP "\-\-maint\-senders=IP[/MASK][,IP/MASK]" Controls which hosts may send maintenance commands to xymond. Maintenance commands are the "enable", "disable", "ack" and "notes" commands. Format of this option is as for the \-\-status\-senders option. It is strongly recommended that you use this to restrict access to these commands, so that monitoring of a host cannot be disabled by a rogue user - e.g. to hide a system compromise from the monitoring system. \fBNote:\fR If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses. .IP "\-\-www\-senders=IP[/MASK][,IP/MASK]" Controls which hosts may send commands to retrieve the state of xymond. These are the "xymondlog", "xymondboard" and "xymondxboard" commands, which are used by .I xymongen(1) and .I combostatus(1) to retrieve the state of the Xymon system so they can generate the Xymon webpages. \fBNote:\fR If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses. .IP "\-\-admin\-senders=IP[/MASK][,IP/MASK]" Controls which hosts may send administrative commands to xymond. These commands are the "drop" and "rename" commands. Access to these should be restricted, since they provide an un-authenticated means of completely disabling monitoring of a host, and can be used to remove all traces of e.g. a system compromise from the Xymon monitor. \fBNote:\fR If messages are sent through a proxy, the IP-address restrictions are of little use, since the messages will appear to originate from the proxy server address. It is therefore strongly recommended that you do NOT include the address of a server running xymonproxy in the list of allowed addresses. .IP "\-\-no\-download" Disable the "download" command which can be used by clients to pull files from the Xymon server. The use of these may be seen as a security risk since they allow file downloads. .IP "\-\-ack\-each\-color" By default, sending an ACK for a yellow status stops alerts from being sent while the status remains yellow or red. A status change from yellow to red will not re-enable alerts - the ACK covers all non-green statuses. With this option, an ACK is valid only for the color of the status when the ACK was sent. So an ACK for a yellow status is ignored if the status later changes to red, but an ACK for a red status covers both yellow and red. .br Note: An ACK for a red status will clear any existing yellow acks. This means that a long-lived ack for yellow is lost when you send a short-lived ack for red. Hence alerts will restart when the red ack expires, even if the status by then has changed to yellow. .IP "\-\-ack\-log=FILENAME" Log acknowledgements created on the Critical Systems page to FILENAME. NB, acknowledgements created by the Acknowledge Alert CGI are automatically written to acknowledge.log in the Xymon server log directory. Alerts from the Critical Systems page can be directed to the same log. .IP "\-\-debug" Enable debugging output. .IP "\-\-dbghost=HOSTNAME" For troubleshooting problems with a specific host, it may be useful to track the exact communications from a single host. This option causes xymond to dump all traffic from a single host to the file "/tmp/xymond.dbg". .SH HOW ALERTS TRIGGER When a status arrives, xymond matches the old and new color against the "alert" colors (from the "ALERTCOLORS" setting) and the "OK" colors (from the "OKCOLORS" setting). The old and new color falls into one of three categories: .sp .BR OK: The color is one of the "OK" colors (e.g. "green"). .sp .BR ALERT: The color is one of the "alert" colors (e.g. "red"). .sp .BR UNDECIDED: The color is neither an "alert" color nor an "OK" color (e.g. "yellow"). If the new status shows an ALERT state, then a message to the .I xymond_alert(8) module is triggered. This may be a repeat of a previous alert, but .I xymond_alert(8) will handle that internally, and only send alert messages with the interval configured in .I alerts.cfg(5). If the status goes from a not-OK state (ALERT or UNDECIDED) to OK, and there is a record of having been in a ALERT state previously, then a recovery message is triggered. The use of the OK, ALERT and UNDECIDED states make it possible to avoid being flooded with alerts when a status flip-flops between e.g yellow and red, or green and yellow. .SH CHANNELS A lot of functionality in the Xymon server is delegated to "worker modules" that are fed various events from xymond via a "channel". Programs access a channel using IPC mechanisms - specifically, shared memory and semaphores - or by using an instance of the .I xymond_channel(8) intermediate program. xymond_channel enables access to a channel via a simple file I/O interface. A skeleton program for hooking into a xymond channel is provided as part of Xymon in the .I xymond_sample(8) program. The following channels are provided by xymond: .sp .BR status This channel is fed the contents of all incoming "status" and "summary" messages. .sp .BR stachg This channel is fed information about tests that change status, i.e. the color of the status-log changes. .sp .BR page This channel is fed information about tests where the color changes between an alert color and a non-alert color. It also receives information about "ack" messages. .sp .BR data This channel is fed information about all "data" messages. .sp .BR notes This channel is fed information about all "notes" messages. .sp .BR enadis This channel is fed information about hosts or tests that are being disabled or enabled. .sp .BR client This channel is fed the contents of the client messages sent by Xymon clients installed on the monitored servers. .sp .BR clichg This channel is fed the contents of a host client messages, whenever a status for that host goes red, yellow or purple. Information about the data stream passed on these channels is in the Xymon source-tree, see the "xymond/new\-daemon.txt" file. .SH SIGNALS .IP SIGHUP Re-read the hosts.cfg configuration file. .IP SIGUSR1 Force an immediate dump of the checkpoint file. .SH BUGS Timeout of incoming connections are not strictly enforced. The check for a timeout only triggers during the normal network handling loop, so a connection that should timeout after N seconds may persist until some activity happens on another (unrelated) connection. .SH FILES If ghost-handling is enabled via the "\-\-ghosts" option, the hosts.cfg file is read to determine the names of all known hosts. .SH "SEE ALSO" xymon(7), xymonserver.cfg(5). xymon-4.3.30/xymond/xymond_worker.h0000664000076400007640000000221512174246230017602 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __XYMOND_WORKER_H__ #define __XYMOND_WORKER_H__ #include typedef void (update_fn_t)(char *); extern int net_worker_option(char *arg); extern int net_worker_locatorbased(void); extern void net_worker_run(enum locator_servicetype_t svc, enum locator_sticky_t sticky, update_fn_t *updfunc); extern unsigned char *get_xymond_message(enum msgchannels_t chnid, char *id, int *seq, struct timespec *timeout); #endif xymon-4.3.30/xymond/combo.cfg.50000664000076400007640000000616713534041733016461 0ustar rpmbuildrpmbuild.TH COMBO.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME combo.cfg \- Configuration of combostatus tool .SH SYNOPSIS .B $XYMONHOME/etc/combo.cfg .SH DESCRIPTION .I combostatus(1) uses it's own configuration file, $XYMONHOME/etc/combo.cfg Each line in this file defines a combined test. .SH FILE FORMAT Each line of the file defines a new combined test. Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. .sp The configuration file uses the hostnames and testnames that are already used in your Xymon hosts.cfg file. These are then combined using normal logical operators - "||" for "or", "&&" for "and" etc. A simple test - e.g. "Web1.http" - results in the value "1" if the "http" test for server "Web1" is green, yellow or clear. It yields the value "0" if it is red, purple or blue. Apart from the logical operations, you can also do integer arithmetic and comparisons. E.g. the following is valid: WebCluster.http = (Web1.http + Web2.http + Web3.http) >= 2 This test is green if two or more of the http tests for Web1, Web2 and Web3 are green. The full range of operators are: + Add - Subtract * Multiply / Divide % Modulo | Bit-wise "or" & Bit-wise "and" || Logical "or" && Logical "and" > Greater than < Less than >= Greater than or equal <= Less than or equal == Equal There is currently no support for a "not" operator. If you need it, use the transcription "(host.test == 0)" instead of "!host.test". NB: All operators have EQUAL PRECEDENCE. If you need something evaluated in a specific order, use parentheses to group the expressions together. If the expression comes out as "0", the combined test goes red. If it comes out as non-zero, the combined test is green. Note: If the expression involves hostnames with a character that is also an operator - e.g. if you have a host "t1-router-newyork.foo.com" with a dash in the hostname - then the operator-character must be escaped with a backslash '\\' in the expression, or it will be interpreted as an operator. E.g. like this: nyc.conn = (t1\\-router\\-nyc.conn || backup\\-router\\-nyc.conn) .SH EXAMPLE WebCluster.http = (Web1.http || Web2.http) .br AppSrvCluster.procs = (AppSrv1.conn && AppSrv1.procs) || (AppSrv2.conn && AppSrv2.procs) .br Customer.cluster = WebCluster.http && AppSrvCluster.procs .br The first line defines a new test, with hostname "WebCluster" and the columnname "http". It will be green if the http test on either the "Web1" or the "Web2" server is green. The second line defines a "procs" test for the "AppSrvCluster" host. Each of the AppSrv1 and AppSrv2 hosts is checked for "conn" (ping) and their "procs" test. On each host, both of these must be green, but the combined test is green if that condition is fulfilled on just one of the hosts. The third line uses the two first tests to build a "double combined" test, defining a test that shows the overall health of the system. .SH FILES .BR "$XYMONHOME/etc/combo.cfg" .SH "SEE ALSO" combostatus(1) xymon-4.3.30/xymond/xymond_client.c0000664000076400007640000020443113463141670017552 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Client backend module */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* "PORT" handling (C) Mirko Saam */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_client.c 8066 2019-05-03 22:42:00Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_worker.h" #include "client_config.h" #define MAX_META 20 /* The maximum number of meta-data items in a message */ enum msgtype_t { MSG_CPU, MSG_DISK, MSG_INODE, MSG_FILES, MSG_MEMORY, MSG_MSGS, MSG_PORTS, MSG_PROCS, MSG_SVCS, MSG_WHO, MSG_LAST }; typedef struct sectlist_t { char *sname; char *sdata; char *nextsectionrestoreptr, *sectdatarestoreptr; char nextsectionrestoreval, sectdatarestoreval; struct sectlist_t *next; } sectlist_t; static sectlist_t *defsecthead = NULL; int cpulistincpu = 1; int pslistinprocs = 1; int portlistinports = 1; int svclistinsvcs = 1; int sendclearmsgs = 1; int sendclearfiles = 1; int sendclearports = 1; int sendclearsvcs = 1; int localmode = 0; int unknownclientosok = 0; int noreportcolor = COL_CLEAR; int separate_uptime_status = 0; int usebackfeedqueue = 0; typedef struct updinfo_t { char *hostname; time_t updtime; int updseq; } updinfo_t; static void * updinfotree; int add_updateinfo(char *hostname, int seq, time_t tstamp) { xtreePos_t handle; updinfo_t *itm; handle = xtreeFind(updinfotree, hostname); if (handle == xtreeEnd(updinfotree)) { itm = (updinfo_t *)calloc(1, sizeof(updinfo_t)); itm->hostname = strdup(hostname); xtreeAdd(updinfotree, itm->hostname, itm); } else { itm = (updinfo_t *)xtreeData(updinfotree, handle); } if (itm->updtime == tstamp) { dbgprintf("%s: Duplicate client message at time %d, seq %d, lastseq %d\n", hostname, (int) tstamp, seq, itm->updseq); return 1; } itm->updtime = tstamp; itm->updseq = seq; return 0; } void nextsection_r_done(void *secthead) { /* Free the old list */ sectlist_t *swalk, *stmp; swalk = (sectlist_t *)secthead; while (swalk) { if (swalk->nextsectionrestoreptr) *swalk->nextsectionrestoreptr = swalk->nextsectionrestoreval; if (swalk->sectdatarestoreptr) *swalk->sectdatarestoreptr = swalk->sectdatarestoreval; stmp = swalk; swalk = swalk->next; xfree(stmp); } } void splitmsg_r(char *clientdata, sectlist_t **secthead) { char *cursection, *nextsection; char *sectname, *sectdata; if (clientdata == NULL) { errprintf("Got a NULL client data message\n"); return; } if (secthead == NULL) { errprintf("BUG: splitmsg_r called with NULL secthead\n"); return; } if (*secthead) { errprintf("BUG: splitmsg_r called with non-empty secthead\n"); nextsection_r_done(*secthead); *secthead = NULL; } /* Find the start of the first section */ if (*clientdata == '[') cursection = clientdata; else { cursection = strstr(clientdata, "\n["); if (cursection) cursection++; } while (cursection) { sectlist_t *newsect = (sectlist_t *)calloc(1, sizeof(sectlist_t)); /* Find end of this section (i.e. start of the next section, if any) */ nextsection = strstr(cursection, "\n["); if (nextsection) { newsect->nextsectionrestoreptr = nextsection; newsect->nextsectionrestoreval = *nextsection; *nextsection = '\0'; nextsection++; } /* Pick out the section name and data */ sectname = cursection+1; sectdata = sectname + strcspn(sectname, "]\n"); newsect->sectdatarestoreptr = sectdata; newsect->sectdatarestoreval = *sectdata; *sectdata = '\0'; sectdata++; if (*sectdata == '\n') sectdata++; /* Save the pointers in the list */ newsect->sname = sectname; newsect->sdata = sectdata; newsect->next = *secthead; *secthead = newsect; /* Next section, please */ cursection = nextsection; } } void splitmsg_done(void) { /* * NOTE: This MUST be called when we're doing using a message, * and BEFORE the next message is read. If called after the * next message is read, the restore-pointers in the "defsecthead" * list will point to data inside the NEW message, and * if the buffer-usage happens to be setup correctly, then * this will write semi-random data over the new message. */ if (defsecthead) { /* Clean up after the previous message */ nextsection_r_done(defsecthead); defsecthead = NULL; } } void splitmsg(char *clientdata) { if (defsecthead) { errprintf("BUG: splitmsg_done() was not called on previous message - data corruption possible.\n"); splitmsg_done(); } splitmsg_r(clientdata, &defsecthead); } char *nextsection_r(char *clientdata, char **name, void **current, void **secthead) { if (clientdata) { *secthead = NULL; splitmsg_r(clientdata, (sectlist_t **)secthead); *current = *secthead; } else { *current = (*current ? ((sectlist_t *)*current)->next : NULL); } if (*current) { *name = ((sectlist_t *)*current)->sname; return ((sectlist_t *)*current)->sdata; } return NULL; } char *nextsection(char *clientdata, char **name) { static void *current = NULL; if (clientdata && defsecthead) { nextsection_r_done(defsecthead); defsecthead = NULL; } return nextsection_r(clientdata, name, ¤t, (void *)defsecthead); } char *getdata(char *sectionname) { sectlist_t *swalk; for (swalk = defsecthead; (swalk && strcmp(swalk->sname, sectionname)); swalk = swalk->next) ; if (swalk) return swalk->sdata; return NULL; } int linecount(char *msg) { int result = 0; char *nl; if (!msg) return 0; nl = msg - 1; while (nl) { nl++; if (*nl >= ' ') result++; nl = strchr(nl, '\n'); } return result; } int want_msgtype(void *hinfo, enum msgtype_t msg) { static void *currhost = NULL; static unsigned long currset = 0; if (currhost != hinfo) { char *val, *tok; currhost = hinfo; currset = 0; val = xmh_item(currhost, XMH_NOCOLUMNS); if (val) { val = strdup(val); tok = strtok(val, ","); while (tok) { if (strcmp(tok, "cpu") == 0) currset |= (1 << MSG_CPU); else if (strcmp(tok, "disk") == 0) currset |= (1 << MSG_DISK); else if (strcmp(tok, "inode") == 0) currset |= (1 << MSG_INODE); else if (strcmp(tok, "files") == 0) currset |= (1 << MSG_FILES); else if (strcmp(tok, "memory") == 0) currset |= (1 << MSG_MEMORY); else if (strcmp(tok, "msgs") == 0) currset |= (1 << MSG_MSGS); else if (strcmp(tok, "ports") == 0) currset |= (1 << MSG_PORTS); else if (strcmp(tok, "procs") == 0) currset |= (1 << MSG_PROCS); else if (strcmp(tok, "svcs") == 0) currset |= (1 << MSG_SVCS); else if (strcmp(tok, "who") == 0) currset |= (1 << MSG_WHO); tok = strtok(NULL, ","); } xfree(val); } } return ((currset & (1 << msg)) == 0); } char *nocolon(char *txt) { static char *result = NULL; char *p; /* * This function changes all colons in "txt" to semi-colons. * This is needed because some of the data messages we use * for reporting things like file- and directory-sizes, or * linecounts in files, use a colon-delimited string that * is sent to the RRD module, and this breaks for the Windows * Powershell client where filenames may contain a colon. */ if (result) xfree(result); result = strdup(txt); p = result; while ((p = strchr(p, ':')) != NULL) *p = ';'; return result; } void unix_cpu_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *uptimestr, char *clockstr, char *msgcachestr, char *whostr, int usercount, char *psstr, int pscount, char *topstr) { char *p; float load1, load5, load15; float loadyellow, loadred; int recentlimit, ancientlimit, maxclockdiff, uptimecolor, clockdiffcolor; char loadresult[100]; long uptimesecs = -1; char myupstr[100]; int cpucolor = COL_GREEN, upstatuscolor = COL_GREEN; char msgline[4096]; strbuffer_t *cpumsg, *upmsg = NULL; if (!want_msgtype(hinfo, MSG_CPU)) return; if (!uptimestr) return; p = strstr(uptimestr, " up "); if (p) { char *uptimeresult; char *daymark; char *hourmark; long uphour, upmin, upsecs; uptimesecs = 0; uptimeresult = strdup(p+3); /* * Linux: " up 178 days, 9:15," * BSD: "" * Solaris: " up 21 days 20:58," */ daymark = strstr(uptimeresult, " day"); dbgprintf("CPU check host %s: daymark '%s'\n", hostname, daymark); if (daymark) { uptimesecs = atoi(uptimeresult) * 86400; if (strncmp(daymark, " days ", 6) == 0) { hourmark = daymark + 6; } else if (strncmp(daymark, " day ", 5) == 0) { hourmark = daymark + 5; } else { hourmark = strchr(daymark, ','); if (hourmark) hourmark++; else hourmark = ""; } } else { hourmark = uptimeresult; } hourmark += strspn(hourmark, " "); dbgprintf("CPU check host %s: hourmark '%s'\n", hostname, hourmark); if (sscanf(hourmark, "%ld:%ld", &uphour, &upmin) == 2) { uptimesecs += 60*(60*uphour + upmin); } else if (sscanf(hourmark, "%ld hours %ld mins", &uphour, &upmin) == 2) { uptimesecs += 60*(60*uphour + upmin); } else if (strstr(hourmark, " secs") && (sscanf(hourmark, "%ld secs", &upsecs) == 1)) { uptimesecs += upsecs; } else if (strstr(hourmark, "min") && (sscanf(hourmark, "%ld min", &upmin) == 1)) { uptimesecs += 60*upmin; } else if (strncmp(hourmark, "1 hr", 4) == 0) { uptimesecs = 3600; } else { uptimesecs = -1; } xfree(uptimeresult); } if (uptimesecs != -1) { int days = (uptimesecs / 86400); int hours = (uptimesecs % 86400) / 3600; int mins = (uptimesecs % 3600) / 60; if (days) sprintf(myupstr, "up: %d days", days); else sprintf(myupstr, "up: %02d:%02d", hours, mins); } else *myupstr = '\0'; load5 = 0.0; *loadresult = '\0'; p = strstr(uptimestr, "load average: "); if (!p) p = strstr(uptimestr, "load averages: "); /* Many BSD's */ if (p) { p = strchr(p, ':') + 1; p += strspn(p, " "); if ((sscanf(p, "%f, %f, %f", &load1, &load5, &load15) == 3) || (sscanf(p, "%f %f %f", &load1, &load5, &load15) == 3)) { sprintf(loadresult, "%.2f", load5); } } else { p = strstr(uptimestr, " load="); if (p) { char *lstart = p+6; char savech; p = lstart + strspn(lstart, "0123456789."); savech = *p; *p = '\0'; load5 = atof(loadresult); strcpy(loadresult, lstart); *p = savech; if (savech == '%') strcat(loadresult, "%"); } } get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); cpumsg = newstrbuffer(0); if (load5 > loadred) { cpucolor = COL_RED; addtobuffer(cpumsg, "&red Load is CRITICAL\n"); } else if (load5 > loadyellow) { cpucolor = COL_YELLOW; addtobuffer(cpumsg, "&yellow Load is HIGH\n"); } if (separate_uptime_status) { upmsg = newstrbuffer(0); if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { upstatuscolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(upmsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { upstatuscolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(upmsg, msgline); } } else { if ((uptimesecs != -1) && (recentlimit != -1) && (uptimesecs < recentlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine recently rebooted\n", colorname(uptimecolor)); addtobuffer(cpumsg, msgline); } if ((uptimesecs != -1) && (ancientlimit != -1) && (uptimesecs > ancientlimit)) { if (cpucolor != COL_RED) cpucolor = uptimecolor; sprintf(msgline, "&%s Machine has been up more than %d days\n", colorname(uptimecolor), (ancientlimit / 86400)); addtobuffer(cpumsg, msgline); } } if (clockstr) { char *p; struct timeval clockval; p = strstr(clockstr, "epoch:"); if (p && (sscanf(p, "epoch: %ld.%ld", (long int *)&clockval.tv_sec, (long int *)&clockval.tv_usec) == 2)) { struct timeval clockdiff; struct timezone tz; int cachedelay = 0; if (msgcachestr) { /* Message passed through msgcache, so adjust for the cache delay */ p = strstr(msgcachestr, "Cachedelay:"); if (p) cachedelay = atoi(p+11); } gettimeofday(&clockdiff, &tz); clockdiff.tv_sec -= (clockval.tv_sec + cachedelay); clockdiff.tv_usec -= clockval.tv_usec; if (clockdiff.tv_usec < 0) { clockdiff.tv_usec += 1000000; clockdiff.tv_sec -= 1; } if ((maxclockdiff > 0) && (abs(clockdiff.tv_sec) > maxclockdiff)) { if (cpucolor != COL_RED) cpucolor = clockdiffcolor; sprintf(msgline, "&%s System clock is %ld seconds off (max %ld)\n", colorname(clockdiffcolor), (long) clockdiff.tv_sec, (long) maxclockdiff); addtobuffer(cpumsg, msgline); } else { sprintf(msgline, "System clock is %ld seconds off\n", (long) clockdiff.tv_sec); addtobuffer(cpumsg, msgline); } } } init_status(cpucolor); sprintf(msgline, "status %s.cpu %s %s %s, %d users, %d procs, load=%s\n", commafy(hostname), colorname(cpucolor), (timestr ? timestr : ""), myupstr, (whostr ? linecount(whostr) : usercount), (psstr ? linecount(psstr)-1 : pscount), loadresult); addtostatus(msgline); if (STRBUFLEN(cpumsg)) { addtostrstatus(cpumsg); addtostatus("\n"); } if (topstr && cpulistincpu == 1) { addtostatus("\n"); addtostatus(topstr); } if (fromline && !localmode) addtostatus(fromline); finish_status(); if (separate_uptime_status) { init_status(upstatuscolor); sprintf(msgline, "status %s.uptime %s %s Uptime %s\n", commafy(hostname), colorname(upstatuscolor), (timestr ? timestr : ""), ((upstatuscolor == COL_GREEN) ? "OK" : "Not OK")); addtostatus(msgline); sprintf(msgline, "\nSystem has been %s\n", myupstr); addtostatus(msgline); if (fromline && !localmode) addtostatus(fromline); finish_status(); } freestrbuffer(cpumsg); if (upmsg) freestrbuffer(upmsg); } void unix_disk_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *freehdr, char *capahdr, char *mnthdr, char *dfstr) { int diskcolor = COL_GREEN; int freecol = -1; int capacol = -1; int mntcol = -1; char *p, *bol, *nl; char msgline[4096]; strbuffer_t *monmsg, *dfstr_filtered; char *dname; int dmin, dmax, dcount, dcolor; char *group; if (!want_msgtype(hinfo, MSG_DISK)) return; if (!dfstr) return; dbgprintf("Disk check host %s\n", hostname); monmsg = newstrbuffer(0); dfstr_filtered = newstrbuffer(0); clear_disk_counts(hinfo, clientclass); clearalertgroups(); bol = dfstr; /* Must do this always, to at least grab the column-numbers we need */ while (bol) { int ignored = 0; nl = strchr(bol, '\n'); if (nl) *nl = '\0'; if ((capacol == -1) && (mntcol == -1) && (freecol == -1)) { /* First line: Check the header and find the columns we want */ p = strdup(bol); freecol = selectcolumn(p, freehdr); strcpy(p, bol); capacol = selectcolumn(p, capahdr); strcpy(p, bol); mntcol = selectcolumn(p, mnthdr); xfree(p); dbgprintf("Disk check: header '%s', columns %d and %d\n", bol, freecol, capacol, mntcol); } else { char *fsname = NULL, *levelstr = NULL; int abswarn, abspanic; long levelpct = -1, levelabs = -1, warnlevel, paniclevel; p = strdup(bol); fsname = getcolumn(p, mntcol); if (fsname) { char *msgp = msgline; add_disk_count(fsname); get_disk_thresholds(hinfo, clientclass, fsname, &warnlevel, &paniclevel, &abswarn, &abspanic, &ignored, &group); strcpy(p, bol); levelstr = getcolumn(p, freecol); if (levelstr) levelabs = atol(levelstr); strcpy(p, bol); levelstr = getcolumn(p, capacol); if (levelstr) levelpct = atol(levelstr); dbgprintf("Disk check: FS='%s' level %ld%%/%ldU (thresholds: %lu/%lu, abs: %d/%d)\n", fsname, levelpct, levelabs, warnlevel, paniclevel, abswarn, abspanic); if (ignored) { /* Forget about this one */ } else if ( (abspanic && (levelabs <= paniclevel)) || (!abspanic && (levelpct >= paniclevel)) ) { if (diskcolor < COL_RED) diskcolor = COL_RED; msgp += sprintf(msgp, "&red %s ", fsname); if (abspanic) msgp += sprintf(msgp, "(%lu units free)", levelabs); else msgp += sprintf(msgp, "(%lu%% used)", levelpct); msgp += sprintf(msgp, " has reached the PANIC level "); if (abspanic) msgp += sprintf(msgp, "(%lu units)\n", paniclevel); else msgp += sprintf(msgp, "(%lu%%)\n", paniclevel); addtobuffer(monmsg, msgline); addalertgroup(group); } else if ( (abswarn && (levelabs <= warnlevel)) || (!abswarn && (levelpct >= warnlevel)) ) { if (diskcolor < COL_YELLOW) diskcolor = COL_YELLOW; msgp += sprintf(msgp, "&yellow %s ", fsname); if (abswarn) msgp += sprintf(msgp, "(%lu units free)", levelabs); else msgp += sprintf(msgp, "(%lu%% used)", levelpct); msgp += sprintf(msgp, " has reached the WARNING level "); if (abswarn) msgp += sprintf(msgp, "(%lu units)\n", warnlevel); else msgp += sprintf(msgp, "(%lu%%)\n", warnlevel); addtobuffer(monmsg, msgline); addalertgroup(group); } } xfree(p); } if (!ignored) { addtobuffer(dfstr_filtered, bol); addtobuffer(dfstr_filtered, "\n"); } if (nl) { *nl = '\n'; bol = nl+1; } else bol = NULL; } if ((capacol == -1) && (mntcol == -1)) { /* If this happens, we havent found our headers so no filesystems have been processed */ diskcolor = COL_YELLOW; sprintf(msgline, "&red Expected strings (%s and %s) not found in df output\n", capahdr, mnthdr); addtobuffer(monmsg, msgline); errprintf("Host %s (%s) sent incomprehensible disk report - missing columnheaders '%s' and '%s'\n", hostname, osname(os), capahdr, mnthdr); } /* Check for filesystems that must (not) exist */ while ((dname = check_disk_count(&dcount, &dmin, &dmax, &dcolor, &group)) != NULL) { char limtxt[1024]; *limtxt = '\0'; if (dmax == -1) { if (dmin > 0) sprintf(limtxt, "%d or more", dmin); else if (dmin == 0) sprintf(limtxt, "none"); } else { if (dmin > 0) sprintf(limtxt, "between %d and %d", dmin, dmax); else if (dmin == 0) sprintf(limtxt, "at most %d", dmax); } if (dcolor != COL_GREEN) { if (dcolor > diskcolor) diskcolor = dcolor; sprintf(msgline, "&%s Filesystem %s (found %d, req. %s)\n", colorname(dcolor), dname, dcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } } /* Now we know the result, so generate a status message */ init_status(diskcolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.disk %s %s - Filesystems %s\n", commafy(hostname), colorname(diskcolor), (timestr ? timestr : ""), (((diskcolor == COL_RED) || (diskcolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full df output */ addtostrstatus(dfstr_filtered); if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); freestrbuffer(dfstr_filtered); } void unix_inode_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *freehdr, char *capahdr, char *mnthdr, char *dfstr) { int inodecolor = COL_GREEN; int freecol = -1; int capacol = -1; int mntcol = -1; char *p, *bol, *nl; char msgline[4096]; strbuffer_t *monmsg, *dfstr_filtered; char *iname; int imin, imax, icount, icolor; char *group; if (!want_msgtype(hinfo, MSG_INODE)) return; if (!dfstr) return; dbgprintf("Inode check host %s\n", hostname); monmsg = newstrbuffer(0); dfstr_filtered = newstrbuffer(0); clear_inode_counts(hinfo, clientclass); clearalertgroups(); bol = dfstr; /* Must do this always, to at least grab the column-numbers we need */ while (bol) { int ignored = 0; nl = strchr(bol, '\n'); if (nl) *nl = '\0'; if ((capacol == -1) && (mntcol == -1) && (freecol == -1)) { /* First line: Check the header and find the columns we want */ p = strdup(bol); freecol = selectcolumn(p, freehdr); strcpy(p, bol); capacol = selectcolumn(p, capahdr); strcpy(p, bol); mntcol = selectcolumn(p, mnthdr); xfree(p); dbgprintf("Inode check: header '%s', columns %d and %d\n", bol, freecol, capacol, mntcol); } else { char *fsname = NULL, *levelstr = NULL; int abswarn, abspanic; long levelpct = -1, levelabs = -1, warnlevel, paniclevel; p = strdup(bol); fsname = getcolumn(p, mntcol); if (fsname) { char *msgp = msgline; add_inode_count(fsname); get_inode_thresholds(hinfo, clientclass, fsname, &warnlevel, &paniclevel, &abswarn, &abspanic, &ignored, &group); strcpy(p, bol); levelstr = getcolumn(p, freecol); if (levelstr) levelabs = atol(levelstr); strcpy(p, bol); levelstr = getcolumn(p, capacol); if (levelstr) levelpct = atol(levelstr); dbgprintf("Inode check: FS='%s' level %ld%%/%ldU (thresholds: %lu/%lu, abs: %d/%d)\n", fsname, levelpct, levelabs, warnlevel, paniclevel, abswarn, abspanic); if (ignored) { /* Forget about this one */ } else if ( (abspanic && (levelabs <= paniclevel)) || (!abspanic && (levelpct >= paniclevel)) ) { if (inodecolor < COL_RED) inodecolor = COL_RED; msgp += sprintf(msgp, "&red %s ", fsname, fsname); if (abspanic) msgp += sprintf(msgp, "(%lu units free)", levelabs); else msgp += sprintf(msgp, "(%lu%% used)", levelpct); msgp += sprintf(msgp, " has reached the PANIC level "); if (abspanic) msgp += sprintf(msgp, "(%lu units)\n", paniclevel); else msgp += sprintf(msgp, "(%lu%%)\n", paniclevel); addtobuffer(monmsg, msgline); addalertgroup(group); } else if ( (abswarn && (levelabs <= warnlevel)) || (!abswarn && (levelpct >= warnlevel)) ) { if (inodecolor < COL_YELLOW) inodecolor = COL_YELLOW; msgp += sprintf(msgp, "&yellow %s ", fsname, fsname); if (abswarn) msgp += sprintf(msgp, "(%lu units free)", levelabs); else msgp += sprintf(msgp, "(%lu%% used)", levelpct); msgp += sprintf(msgp, " has reached the WARNING level "); if (abswarn) msgp += sprintf(msgp, "(%lu units)\n", warnlevel); else msgp += sprintf(msgp, "(%lu%%)\n", warnlevel); addtobuffer(monmsg, msgline); addalertgroup(group); } } xfree(p); } if (!ignored) { addtobuffer(dfstr_filtered, bol); addtobuffer(dfstr_filtered, "\n"); } if (nl) { *nl = '\n'; bol = nl+1; } else bol = NULL; } if ((capacol == -1) && (mntcol == -1)) { if (strlen(dfstr) == 0) { /* Empty inode report, happens on Solaris when all filesystems are ZFS */ inodecolor = COL_GREEN; sprintf(msgline, "&green No filesystems reporting inode data\n"); addtobuffer(monmsg, msgline); } else { /* If this happens, we havent found our headers so no filesystems have been processed */ inodecolor = COL_YELLOW; sprintf(msgline, "&red Expected strings (%s and %s) not found in df output\n", capahdr, mnthdr); addtobuffer(monmsg, msgline); errprintf("Host %s (%s) sent incomprehensible inode report - missing columnheaders '%s' and '%s'\n%s\n", hostname, osname(os), capahdr, mnthdr, dfstr); } } /* Check for filesystems that must (not) exist */ while ((iname = check_inode_count(&icount, &imin, &imax, &icolor, &group)) != NULL) { char limtxt[1024]; *limtxt = '\0'; if (imax == -1) { if (imin > 0) sprintf(limtxt, "%d or more", imin); else if (imin == 0) sprintf(limtxt, "none"); } else { if (imin > 0) sprintf(limtxt, "between %d and %d", imin, imax); else if (imin == 0) sprintf(limtxt, "at most %d", imax); } if (icolor != COL_GREEN) { if (icolor > inodecolor) inodecolor = icolor; sprintf(msgline, "&%s Filesystem %s (found %d, req. %s)\n", colorname(icolor), iname, iname, icount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } } /* Now we know the result, so generate a status message */ init_status(inodecolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.inode %s %s - Filesystems %s\n", commafy(hostname), colorname(inodecolor), (timestr ? timestr : ""), (((inodecolor == COL_RED) || (inodecolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full df output */ addtostrstatus(dfstr_filtered); if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); freestrbuffer(dfstr_filtered); } void unix_memory_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, long memphystotal, long memphysused, long memacttotal, long memactused, long memswaptotal, long memswapused) { long memphyspct = 0, memswappct = 0, memactpct = 0; int physyellow, physred, swapyellow, swapred, actyellow, actred; int invaliddata = 0; int memorycolor = COL_GREEN, physcolor = COL_GREEN, swapcolor = COL_GREEN, actcolor = COL_GREEN; char *memorysummary = "OK"; char msgline[4096]; if (!want_msgtype(hinfo, MSG_MEMORY)) return; if (memphystotal == -1) return; if (memphysused == -1) return; get_memory_thresholds(hinfo, clientclass, &physyellow, &physred, &swapyellow, &swapred, &actyellow, &actred); memphyspct = (memphystotal > 0) ? ((100 * memphysused) / memphystotal) : 0; if (memphyspct <= 100) { if (memphyspct > physyellow) physcolor = COL_YELLOW; if (memphyspct > physred) physcolor = COL_RED; } if (memswapused != -1) memswappct = (memswaptotal > 0) ? ((100 * memswapused) / memswaptotal) : 0; if (memswappct <= 100) { if (memswappct > swapyellow) swapcolor = COL_YELLOW; if (memswappct > swapred) swapcolor = COL_RED; } else invaliddata = 1; if (memactused != -1) memactpct = (memacttotal > 0) ? ((100 * memactused) / memacttotal) : 0; /* Actual percentage can be above 100 */ if (memactpct > actyellow) actcolor = COL_YELLOW; if (memactpct > actred) actcolor = COL_RED; if ((physcolor == COL_RED) || (swapcolor == COL_RED) || (actcolor == COL_RED)) { memorycolor = COL_RED; memorysummary = "CRITICAL"; } else if ((physcolor == COL_YELLOW) || (swapcolor == COL_YELLOW) || (actcolor == COL_YELLOW)) { memorycolor = COL_YELLOW; memorysummary = "low"; } if ((memphystotal == 0) && (memorycolor == COL_GREEN)) { memorycolor = COL_YELLOW; memorysummary = "detection FAILED"; } else if (invaliddata) { if (memorycolor != COL_RED) memorycolor = COL_YELLOW; memorysummary = "invalid data when parsing"; } init_status(memorycolor); sprintf(msgline, "status %s.memory %s %s - Memory %s\n", commafy(hostname), colorname(memorycolor), (timestr ? timestr : ""), memorysummary); addtostatus(msgline); sprintf(msgline, " %-16s%12s%12s%12s\n", "Memory", "Used", "Total", "Percentage"); addtostatus(msgline); sprintf(msgline, "&%s %-16s%11ldM%11ldM%11ld%%\n", colorname(physcolor), "Real/Physical", memphysused, memphystotal, memphyspct); addtostatus(msgline); if (memactused != -1) { sprintf(msgline, "&%s %-16s%11ldM%11ldM%11ld%%\n", colorname(actcolor), "Actual/Virtual", memactused, memacttotal, memactpct); addtostatus(msgline); } if (memswapused != -1) { if (memswappct <= 100) sprintf(msgline, "&%s %-16s%11ldM%11ldM%11ld%%\n", colorname(swapcolor), "Swap/Page", memswapused, memswaptotal, memswappct); else sprintf(msgline, "&%s %-16s%11ldM%11ldM%11ld%% - invalid data\n", colorname(COL_YELLOW), "Swap/Page", memswapused, memswaptotal, 0L); addtostatus(msgline); } if (fromline && !localmode) addtostatus(fromline); finish_status(); } void unix_procs_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *cmdhdr, char *altcmdhdr, char *psstr) { int pscolor = COL_GREEN; int pchecks; int cmdofs = -1; char *p, *eol; char msgline[4096]; strbuffer_t *monmsg; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PROCS)) return; if (!psstr) return; if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); monmsg = newstrbuffer(0); sprintf(msgline, "data %s.proccounts\n", commafy(hostname)); addtobuffer(countdata, msgline); /* * Find where the command is located. We look for the header for the command, * and calculate the offset from the beginning of the line. * * NOTE: The header strings could show up in the normal "ps" output. So * we look for it only in the first line of output. */ eol = strchr(psstr, '\n'); if (eol) *eol = '\0'; dbgprintf("Host %s need heading %s or %s - ps header line reads '%s'\n", hostname, cmdhdr, (altcmdhdr ? altcmdhdr : ""), psstr); /* Look for the primary key */ p = strstr(psstr, cmdhdr); if (p) { cmdofs = (p - psstr); dbgprintf("Host %s: Found pri. heading '%s' at offset %d\n", hostname, cmdhdr, cmdofs); } /* If there's a secondary key, look for that also */ if (altcmdhdr) { p = strstr(psstr, altcmdhdr); if (p) { dbgprintf("Host %s: Found sec. heading '%s' at offset %d\n", hostname, altcmdhdr, (p - psstr)); if ((cmdofs == -1) || ((p - psstr) < cmdofs)) { /* We'll use the secondary key */ cmdofs = (p - psstr); } } } if (eol) *eol = '\n'; if (cmdofs >= 0) { dbgprintf("Host %s: Found ps command line at offset %d\n", hostname, cmdofs); } else { dbgprintf("Host %s: None of the headings found\n", hostname); } pchecks = clear_process_counts(hinfo, clientclass); if (pchecks == 0) { /* Nothing to check */ sprintf(msgline, "&%s No process checks defined\n", colorname(noreportcolor)); addtobuffer(monmsg, msgline); pscolor = noreportcolor; } else if (cmdofs >= 0) { /* Count how many instances of each monitored process is running */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; bol = psstr; while (bol) { nl = strchr(bol, '\n'); /* Take care - the ps output line may be shorter than what we look at */ if (nl) { *nl = '\0'; if ((nl-bol) > cmdofs) add_process_count(bol+cmdofs); *nl = '\n'; bol = nl+1; } else { if (strlen(bol) > cmdofs) add_process_count(bol+cmdofs); bol = NULL; } } /* Check the number found for each monitored process */ while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { if (pcolor > pscolor) pscolor = pcolor; sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the count data for later DATA message to track process counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } else { pscolor = COL_YELLOW; sprintf(msgline, "&yellow Expected string %s not found in ps output header\n", cmdhdr); addtobuffer(monmsg, msgline); } /* Now we know the result, so generate a status message */ init_status(pscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.procs %s %s - Processes %s\n", commafy(hostname), colorname(pscolor), (timestr ? timestr : ""), (((pscolor == COL_RED) || (pscolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full ps output for those who want it */ if (pslistinprocs) addtostatus(prehtmlquoted(psstr)); if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); if (anycountdata) combo_add(countdata); clearstrbuffer(countdata); } static void old_msgs_report(char *hostname, void *hinfo, char *fromline, char *timestr, char *msgsstr) { int msgscolor = COL_GREEN; char msgline[4096]; char *summary = "All logs OK"; if (msgsstr) { if (strstr(msgsstr, "&clear ")) { msgscolor = COL_CLEAR; summary = "No log data available"; } if (strstr(msgsstr, "&yellow ")) { msgscolor = COL_YELLOW; summary = "WARNING"; } if (strstr(msgsstr, "&red ")) { msgscolor = COL_RED; summary = "CRITICAL"; } } else if (sendclearmsgs) { msgscolor = noreportcolor; summary = "No log data available"; } else return; init_status(msgscolor); sprintf(msgline, "status %s.msgs %s System logs at %s : %s\n", commafy(hostname), colorname(msgscolor), (timestr ? timestr : ""), summary); addtostatus(msgline); if (msgsstr) addtostatus(msgsstr); else addtostatus("The client did not report any logfile data\n"); if (fromline && !localmode) addtostatus(fromline); finish_status(); } void msgs_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *msgsstr) { static strbuffer_t *greendata = NULL; static strbuffer_t *yellowdata = NULL; static strbuffer_t *reddata = NULL; sectlist_t *swalk; strbuffer_t *logsummary; int msgscolor = COL_GREEN; char msgline[PATH_MAX]; char *group; if (!want_msgtype(hinfo, MSG_MSGS)) return; for (swalk = defsecthead; (swalk && strncmp(swalk->sname, "msgs:", 5)); swalk = swalk->next) ; if (!swalk) { old_msgs_report(hostname, hinfo, fromline, timestr, msgsstr); return; } if (!greendata) greendata = newstrbuffer(0); if (!yellowdata) yellowdata = newstrbuffer(0); if (!reddata) reddata = newstrbuffer(0); clearalertgroups(); logsummary = newstrbuffer(0); while (swalk) { int logcolor; clearstrbuffer(logsummary); logcolor = scan_log(hinfo, clientclass, swalk->sname+5, swalk->sdata, swalk->sname, logsummary); if (logcolor > msgscolor) msgscolor = logcolor; switch (logcolor) { case COL_GREEN: if (!localmode) { sprintf(msgline, "\nNo entries in %s\n", hostsvcclienturl(hostname, swalk->sname), swalk->sname+5); } else { sprintf(msgline, "\nNo entries in %s\n", swalk->sname+5); } addtobuffer(greendata, msgline); break; case COL_YELLOW: if (!localmode) { sprintf(msgline, "\n&yellow Warnings in %s\n", hostsvcclienturl(hostname, swalk->sname), swalk->sname+5); } else { sprintf(msgline, "\n&yellow Warnings in %s\n", swalk->sname+5); } addtobuffer(yellowdata, msgline); addtostrbuffer(yellowdata, logsummary); break; case COL_RED: if (!localmode) { sprintf(msgline, "\n&red Critical entries in %s\n", hostsvcclienturl(hostname, swalk->sname), swalk->sname+5); } else { sprintf(msgline, "\n&red Critical entries in %s\n", swalk->sname+5); } addtobuffer(reddata, msgline); addtostrbuffer(reddata, logsummary); break; } do { swalk=swalk->next; } while (swalk && strncmp(swalk->sname, "msgs:", 5)); } freestrbuffer(logsummary); init_status(msgscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.msgs %s %s - System logs %s\n", commafy(hostname), colorname(msgscolor), (timestr ? timestr : ""), (((msgscolor == COL_RED) || (msgscolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); if (STRBUFLEN(reddata)) { addtostrstatus(reddata); clearstrbuffer(reddata); addtostatus("\n"); } if (STRBUFLEN(yellowdata)) { addtostrstatus(yellowdata); clearstrbuffer(yellowdata); addtostatus("\n"); } if (STRBUFLEN(greendata)) { addtostrstatus(greendata); clearstrbuffer(greendata); addtostatus("\n"); } /* * Add the full log message data from each logfile. * It's probably faster to re-walk the section list than * stuffing the full messages into a temporary buffer. */ for (swalk = defsecthead; (swalk && strncmp(swalk->sname, "msgs:", 5)); swalk = swalk->next) ; while (swalk) { if (!localmode) { sprintf(msgline, "\nFull log %s\n", hostsvcclienturl(hostname, swalk->sname), swalk->sname+5); } else { sprintf(msgline, "\nFull log %s\n", swalk->sname+5); } addtostatus(msgline); addtostatus(prehtmlquoted(swalk->sdata)); do { swalk=swalk->next; } while (swalk && strncmp(swalk->sname, "msgs:", 5)); } if (fromline && !localmode) addtostatus(fromline); finish_status(); } void file_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr) { static strbuffer_t *greendata = NULL; static strbuffer_t *yellowdata = NULL; static strbuffer_t *reddata = NULL; static strbuffer_t *sizedata = NULL; sectlist_t *swalk; strbuffer_t *filesummary; int filecolor = -1, onecolor; char msgline[PATH_MAX]; char sectionname[PATH_MAX]; int anyszdata = 0; char *group; if (!want_msgtype(hinfo, MSG_FILES)) return; if (!greendata) greendata = newstrbuffer(0); if (!yellowdata) yellowdata = newstrbuffer(0); if (!reddata) reddata = newstrbuffer(0); if (!sizedata) sizedata = newstrbuffer(0); filesummary = newstrbuffer(0); clearalertgroups(); sprintf(msgline, "data %s.filesizes\n", commafy(hostname)); addtobuffer(sizedata, msgline); for (swalk = defsecthead; (swalk); swalk = swalk->next) { int trackit, anyrules; char *sfn = NULL; char *id = NULL; if (strncmp(swalk->sname, "file:", 5) == 0) { off_t sz; sfn = swalk->sname+5; sprintf(sectionname, "file:%s", sfn); onecolor = check_file(hinfo, clientclass, sfn, swalk->sdata, sectionname, filesummary, &sz, &id, &trackit, &anyrules); if (trackit) { /* Save the size data for later DATA message to track file sizes */ if (id == NULL) id = sfn; #ifdef _LARGEFILE_SOURCE sprintf(msgline, "%s:%lld\n", nocolon(id), (long long int)sz); #else sprintf(msgline, "%s:%ld\n", nocolon(id), (long int)sz); #endif addtobuffer(sizedata, msgline); anyszdata = 1; } } else if (strncmp(swalk->sname, "logfile:", 8) == 0) { off_t sz; sfn = swalk->sname+8; sprintf(sectionname, "logfile:%s", sfn); onecolor = check_file(hinfo, clientclass, sfn, swalk->sdata, sectionname, filesummary, &sz, &id, &trackit, &anyrules); if (trackit) { /* Save the size data for later DATA message to track file sizes */ if (id == NULL) id = sfn; #ifdef _LARGEFILE_SOURCE sprintf(msgline, "%s:%lld\n", nocolon(id), (long long int)sz); #else sprintf(msgline, "%s:%ld\n", nocolon(id), (long int)sz); #endif addtobuffer(sizedata, msgline); anyszdata = 1; } if (!anyrules) { /* Don't clutter the display with logfiles unless they have rules */ continue; } } else if (strncmp(swalk->sname, "dir:", 4) == 0) { unsigned long sz; sfn = swalk->sname+4; sprintf(sectionname, "dir:%s", sfn); onecolor = check_dir(hinfo, clientclass, sfn, swalk->sdata, sectionname, filesummary, &sz, &id, &trackit); if (trackit) { /* Save the size data for later DATA message to track directory sizes */ if (id == NULL) id = sfn; sprintf(msgline, "%s:%lu\n", nocolon(id), sz); addtobuffer(sizedata, msgline); anyszdata = 1; } } else continue; if (onecolor > filecolor) filecolor = onecolor; switch (onecolor) { case COL_GREEN: if (!localmode) { sprintf(msgline, "\n&green %s\n", hostsvcclienturl(hostname, sectionname), sfn); } else { sprintf(msgline, "\n&green %s\n", sfn); } addtobuffer(greendata, msgline); break; case COL_YELLOW: if (!localmode) { sprintf(msgline, "\n&yellow %s\n", hostsvcclienturl(hostname, sectionname), sfn); } else { sprintf(msgline, "\n&yellow %s\n", sfn); } addtobuffer(yellowdata, msgline); addtostrbuffer(yellowdata, filesummary); break; case COL_RED: if (!localmode) { sprintf(msgline, "\n&red %s\n", hostsvcclienturl(hostname, sectionname), sfn); } else { sprintf(msgline, "\n&red %s\n", sfn); } addtobuffer(reddata, msgline); addtostrbuffer(reddata, filesummary); break; } clearstrbuffer(filesummary); } freestrbuffer(filesummary); if ((filecolor == -1) && sendclearfiles) { filecolor = noreportcolor; addtobuffer(greendata, "No files checked\n"); } if (filecolor != -1) { init_status(filecolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.files %s %s - Files %s\n", commafy(hostname), colorname(filecolor), (timestr ? timestr : ""), (((filecolor == COL_RED) || (filecolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); if (STRBUFLEN(reddata)) { addtostrstatus(reddata); clearstrbuffer(reddata); addtostatus("\n"); } if (STRBUFLEN(yellowdata)) { addtostrstatus(yellowdata); clearstrbuffer(yellowdata); addtostatus("\n"); } if (STRBUFLEN(greendata)) { addtostrstatus(greendata); clearstrbuffer(greendata); addtostatus("\n"); } if (fromline && !localmode) addtostatus(fromline); finish_status(); } else { clearstrbuffer(reddata); clearstrbuffer(yellowdata); clearstrbuffer(greendata); } if (anyszdata) combo_add(sizedata); clearstrbuffer(sizedata); } void linecount_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr) { static strbuffer_t *countdata = NULL; sectlist_t *swalk; char msgline[PATH_MAX]; int anydata = 0; if (!countdata) countdata = newstrbuffer(0); sprintf(msgline, "data %s.linecounts\n", commafy(hostname)); addtobuffer(countdata, msgline); for (swalk = defsecthead; (swalk); swalk = swalk->next) { if (strncmp(swalk->sname, "linecount:", 10) == 0) { char *fn, *boln, *eoln, *id, *countstr; anydata = 1; fn = strchr(swalk->sname, ':'); fn += 1 + strspn(fn+1, "\t "); boln = swalk->sdata; while (boln) { eoln = strchr(boln, '\n'); id = strtok(boln, ":"); countstr = (id ? strtok(NULL, "\n") : NULL); if (id && countstr) { countstr += strspn(countstr, "\t "); snprintf(msgline, sizeof(msgline), "%s#%s:%s\n", nocolon(fn), id, countstr); addtobuffer(countdata, msgline); } boln = (eoln ? eoln + 1 : NULL); } } } if (anydata) combo_add(countdata); clearstrbuffer(countdata); } void deltacount_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr) { static strbuffer_t *countdata = NULL; sectlist_t *swalk; char msgline[PATH_MAX]; int anydata = 0; if (!countdata) countdata = newstrbuffer(0); sprintf(msgline, "data %s.deltacounts\n", commafy(hostname)); addtobuffer(countdata, msgline); for (swalk = defsecthead; (swalk); swalk = swalk->next) { if (strncmp(swalk->sname, "deltacount:", 10) == 0) { char *fn, *boln, *eoln, *id, *countstr; anydata = 1; fn = strchr(swalk->sname, ':'); fn += 1 + strspn(fn+1, "\t "); boln = swalk->sdata; while (boln) { eoln = strchr(boln, '\n'); id = strtok(boln, ":"); countstr = (id ? strtok(NULL, "\n") : NULL); if (id && countstr) { countstr += strspn(countstr, "\t "); snprintf(msgline, sizeof(msgline), "%s#%s:%s\n", nocolon(fn), id, countstr); addtobuffer(countdata, msgline); } boln = (eoln ? eoln + 1 : NULL); } } } if (anydata) combo_add(countdata); clearstrbuffer(countdata); } void unix_netstat_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *netstatstr) { strbuffer_t *msg; char msgline[4096]; if (!netstatstr) return; msg = newstrbuffer(0); sprintf(msgline, "data %s.netstat\n%s\n", commafy(hostname), osname(os)); addtobuffer(msg, msgline); addtobuffer(msg, netstatstr); combo_add(msg); freestrbuffer(msg); } void unix_ifstat_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *ifstatstr) { strbuffer_t *msg; char msgline[4096]; if (!ifstatstr) return; msg = newstrbuffer(0); sprintf(msgline, "data %s.ifstat\n%s\n", commafy(hostname), osname(os)); addtobuffer(msg, msgline); addtobuffer(msg, ifstatstr); combo_add(msg); freestrbuffer(msg); } void unix_vmstat_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *vmstatstr) { strbuffer_t *msg; char msgline[4096]; char *p; if (!vmstatstr) return; p = strrchr(vmstatstr, '\n'); if (!p) return; /* No NL in vmstat output ? Unlikely. */ if (strlen(p) == 1) { /* Go back to the previous line */ do { p--; } while ((p > vmstatstr) && (*p != '\n')); } if (strcmp(p+1,"Terminated") == 0) return; /* vmstat process was killed early - ignore data */ msg = newstrbuffer(0); sprintf(msgline, "data %s.vmstat\n%s\n", commafy(hostname), osname(os)); addtobuffer(msg, msgline); addtobuffer(msg, p+1); combo_add(msg); freestrbuffer(msg); } void unix_ports_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, int localcol, int remotecol, int statecol, char *portstr) { int portcolor = -1; int pchecks; char msgline[4096]; static strbuffer_t *monmsg = NULL; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PORTS)) return; if (!portstr) return; if (!monmsg) monmsg = newstrbuffer(0); if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); pchecks = clear_port_counts(hinfo, clientclass); sprintf(msgline, "data %s.portcounts\n", commafy(hostname)); addtobuffer(countdata, msgline); if (pchecks > 0) { /* Count how many instances of each monitored condition are found */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; char *localstr, *remotestr, *statestr; bol = portstr; while (bol) { char *p; nl = strchr(bol, '\n'); if (nl) *nl = '\0'; /* Data lines */ p = strdup(bol); localstr = getcolumn(p, localcol); strcpy(p, bol); remotestr = getcolumn(p, remotecol); strcpy(p, bol); statestr = getcolumn(p, statecol); add_port_count(localstr, remotestr, statestr); xfree(p); if (nl) { *nl = '\n'; bol = nl+1; } else bol = NULL; } /* Check the number found for each monitored port */ while ((pname = check_port_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; *limtxt = '\0'; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor > portcolor) portcolor = pcolor; if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the size data for later DATA message to track port counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } if ((portcolor == -1) && sendclearports) { /* Nothing to check */ addtobuffer(monmsg, "No port checks defined\n"); portcolor = noreportcolor; } if (portcolor != -1) { /* Now we know the result, so generate a status message */ init_status(portcolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.ports %s %s - Ports %s\n", commafy(hostname), colorname(portcolor), (timestr ? timestr : ""), (((portcolor == COL_RED) || (portcolor == COL_YELLOW)) ? "NOT ok" : "ok")); addtostatus(msgline); /* And add the info about what's wrong */ addtostrstatus(monmsg); addtostatus("\n"); clearstrbuffer(monmsg); /* And the full port output for those who want it */ if (portlistinports) addtostatus(portstr); if (fromline) addtostatus(fromline); finish_status(); } else { clearstrbuffer(monmsg); } if (anycountdata) combo_add(countdata); clearstrbuffer(countdata); } #include "client/linux.c" #include "client/freebsd.c" #include "client/netbsd.c" #include "client/openbsd.c" #include "client/solaris.c" #include "client/hpux.c" #include "client/osf.c" #include "client/aix.c" #include "client/darwin.c" #include "client/irix.c" #include "client/sco_sv.c" #include "client/bbwin.c" #include "client/powershell.c" /* Must go after client/bbwin.c */ #include "client/zvm.c" #include "client/zvse.c" #include "client/zos.c" #include "client/mqcollect.c" #include "client/snmpcollect.c" #include "client/generic.c" static volatile int reloadconfig = 0; void sig_handler(int signum) { switch (signum) { case SIGHUP: reloadconfig = 1; break; default: break; } } void clean_instr(char *s) { char *p; p = s + strcspn(s, "\r\n"); *p = '\0'; } void testmode(char *configfn) { void *hinfo, *oldhinfo = NULL; char hostname[1024], clientclass[1024]; char s[4096]; load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_client_config(configfn); *hostname = '\0'; *clientclass = '\0'; while (1) { hinfo = NULL; while (!hinfo) { printf("Hostname (.=end, ?=dump, !=reload) [%s]: ", hostname); fflush(stdout); if (!fgets(hostname, sizeof(hostname), stdin)) return; clean_instr(hostname); if (strlen(hostname) == 0) { hinfo = oldhinfo; if (hinfo) strcpy(hostname, xmh_item(hinfo, XMH_HOSTNAME)); } else if (strcmp(hostname, ".") == 0) { exit(0); } else if (strcmp(hostname, "!") == 0) { load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_client_config(configfn); *hostname = '\0'; } else if (strcmp(hostname, "?") == 0) { dump_client_config(); if (oldhinfo) strcpy(hostname, xmh_item(oldhinfo, XMH_HOSTNAME)); } else { hinfo = hostinfo(hostname); if (!hinfo) printf("Unknown host\n"); printf("Hosttype [%s]: ", clientclass); fflush(stdout); if (!fgets(clientclass, sizeof(clientclass), stdin)) return; clean_instr(clientclass); } } oldhinfo = hinfo; printf("Test (cpu, mem, disk, proc, log, port): "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); if (strcmp(s, "cpu") == 0) { float loadyellow, loadred; int recentlimit, ancientlimit, uptimecolor; int maxclockdiff, clockdiffcolor; get_cpu_thresholds(hinfo, clientclass, &loadyellow, &loadred, &recentlimit, &ancientlimit, &uptimecolor, &maxclockdiff, &clockdiffcolor); printf("Load: Yellow at %.2f, red at %.2f\n", loadyellow, loadred); printf("Uptime: %s from boot until %s,", colorname(uptimecolor), durationstring(recentlimit)); printf("and after %s uptime\n", durationstring(ancientlimit)); if (maxclockdiff > 0) printf("Max clock diff: %d (%s)\n", maxclockdiff, colorname(clockdiffcolor)); } else if (strcmp(s, "mem") == 0) { int physyellow, physred, swapyellow, swapred, actyellow, actred; get_memory_thresholds(hinfo, clientclass, &physyellow, &physred, &swapyellow, &swapred, &actyellow, &actred); printf("Phys: Yellow at %d, red at %d\n", physyellow, physred); printf("Swap: Yellow at %d, red at %d\n", swapyellow, swapred); printf("Act.: Yellow at %d, red at %d\n", actyellow, actred); } else if (strcmp(s, "disk") == 0) { unsigned long warnlevel, paniclevel; int abswarn, abspanic, ignored; char *groups; printf("Filesystem: "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); get_disk_thresholds(hinfo, clientclass, s, &warnlevel, &paniclevel, &abswarn, &abspanic, &ignored, &groups); if (ignored) printf("Ignored\n"); else printf("Yellow at %lu%c, red at %lu%c\n", warnlevel, (abswarn ? 'U' : '%'), paniclevel, (abspanic ? 'U' : '%')); } else if (strcmp(s, "proc") == 0) { int pchecks = clear_process_counts(hinfo, clientclass); char *pname, *pid; int pcount, pmin, pmax, pcolor, ptrack; char *groups; FILE *fd; if (pchecks == 0) { printf("No process checks for this host\n"); continue; } printf("To read 'ps' data from a file, enter '@FILENAME' at the prompt\n"); do { printf("ps command string: "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); if (*s == '@') { fd = fopen(s+1, "r"); while (fd && fgets(s, sizeof(s), fd)) { clean_instr(s); if (*s) add_process_count(s); } fclose(fd); } else { if (*s) add_process_count(s); } } while (*s); while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &groups)) != NULL) { printf("Process %s color %s: Count=%d, min=%d, max=%d\n", pname, colorname(pcolor), pcount, pmin, pmax); } } else if (strcmp(s, "log") == 0) { FILE *fd; char *sectname; strbuffer_t *logdata, *logsummary; int logcolor; printf("log filename: "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); sectname = (char *)malloc(strlen(s) + 20); sprintf(sectname, "msgs:%s", s); logdata = newstrbuffer(0); logsummary = newstrbuffer(0); printf("To read log data from a file, enter '@FILENAME' at the prompt\n"); do { printf("log line: "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); if (*s == '@') { fd = fopen(s+1, "r"); while (fd && fgets(s, sizeof(s), fd)) { if (*s) addtobuffer(logdata, s); } fclose(fd); } else { if (*s) addtobuffer(logdata, s); } } while (*s); clearstrbuffer(logsummary); logcolor = scan_log(hinfo, clientclass, sectname+5, STRBUF(logdata), sectname, logsummary); printf("Log status is %s\n\n", colorname(logcolor)); if (STRBUFLEN(logsummary)) printf("%s\n", STRBUF(logsummary)); freestrbuffer(logsummary); freestrbuffer(logdata); } else if (strcmp(s, "port") == 0) { char *localstr, *remotestr, *statestr, *p, *pname, *pid; int pcount, pmin, pmax, pcolor, pchecks, ptrack; char *groups; int localcol = 4, remotecol = 5, statecol = 6, portcolor = COL_GREEN; pchecks = clear_port_counts(hinfo, clientclass); if (pchecks == 0) { printf("No PORT checks for this host\n"); continue; } printf("Need to know netstat columns for 'Local address', 'Remote address' and 'State'\n"); printf("Enter columns [%d %d %d]: ", localcol, remotecol, statecol); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); if (*s) sscanf(s, "%d %d %d", &localcol, &remotecol, &statecol); printf("To read 'netstat' data from a file, enter '@FILENAME' at the prompt\n"); do { printf("netstat line: "); fflush(stdout); if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s); if (*s == '@') { FILE *fd; fd = fopen(s+1, "r"); while (fd && fgets(s, sizeof(s), fd)) { clean_instr(s); if (*s) { p = strdup(s); localstr = getcolumn(p, localcol-1); strcpy(p, s); remotestr = getcolumn(p, remotecol-1); strcpy(p, s); statestr = getcolumn(p, statecol-1); add_port_count(localstr, remotestr, statestr); xfree(p); } } fclose(fd); } else if (*s) { p = strdup(s); localstr = getcolumn(p, localcol-1); strcpy(p, s); remotestr = getcolumn(p, remotecol-1); strcpy(p, s); statestr = getcolumn(p, statecol-1); add_port_count(localstr, remotestr, statestr); xfree(p); } } while (*s); /* Check the number found for each monitored port */ while ((pname = check_port_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &groups)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { printf("&green %s (found %d, req. %s)\n", pname, pcount, limtxt); } else { if (pcolor > portcolor) portcolor = pcolor; printf("&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); } } } } exit(0); } int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; struct sigaction sa; time_t nextconfigload = 0; char *configfn = NULL; char **collectors = NULL; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--no-update") == 0) { dontsendmessages = 1; } else if (strcmp(argv[argi], "--no-ps-listing") == 0) { pslistinprocs = 0; } else if (strcmp(argv[argi], "--no-port-listing") == 0) { portlistinports = 0; } else if (strcmp(argv[argi], "--no-cpu-listing") == 0) { cpulistincpu = 0; } else if (strcmp(argv[argi], "--no-clear-msgs") == 0) { sendclearmsgs = 0; } else if (strcmp(argv[argi], "--no-clear-files") == 0) { sendclearfiles = 0; } else if (strcmp(argv[argi], "--no-clear-ports") == 0) { sendclearports = 0; } else if (strncmp(argv[argi], "--clear-color=", 14) == 0) { char *p = strchr(argv[argi], '='); noreportcolor = parse_color(p+1); } else if (strcmp(argv[argi], "--uptime-status") == 0) { separate_uptime_status = 1; } else if (argnmatch(argv[argi], "--config=")) { char *lp = strchr(argv[argi], '='); configfn = strdup(lp+1); } else if (argnmatch(argv[argi], "--collectors=")) { char *lp = strdup(strchr(argv[argi], '=')+1); char *tok; int i; tok = strtok(lp, ","); i = 0; collectors = (char **)calloc(1, sizeof(char *)); while (tok) { collectors = (char **)realloc(collectors, (i+2)*sizeof(char *)); if (strcasecmp(tok, "default") == 0) tok = ""; collectors[i++] = tok; collectors[i] = NULL; tok = strtok(NULL, ","); } } else if (strcmp(argv[argi], "--unknownclientosok") == 0) { unknownclientosok = 1; } else if (argnmatch(argv[argi], "--dump-config")) { load_client_config(configfn); dump_client_config(); return 0; } else if (strcmp(argv[argi], "--local") == 0) { localmode = 1; } else if (strcmp(argv[argi], "--test") == 0) { testmode(configfn); } else if (net_worker_option(argv[argi])) { /* Handled in the subroutine */ } } save_errbuf = 0; if (collectors == NULL) { /* Setup the default collectors */ collectors = (char **)calloc(2, sizeof(char *)); collectors[0] = ""; collectors[1] = NULL; } /* Do the network stuff if needed */ net_worker_run(ST_CLIENT, LOC_ROAMING, NULL); /* Signals */ setup_signalhandler("xymond_client"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; sigaction(SIGHUP, &sa, NULL); signal(SIGCHLD, SIG_IGN); updinfotree = xtreeNew(strcasecmp); running = 1; usebackfeedqueue = (sendmessage_init_local() > 0); while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; time_t nowtimer = gettimer(); msg = get_xymond_message(C_CLIENT, argv[0], &seq, NULL); if (msg == NULL) { if (!localmode) errprintf("Failed to get a message, terminating\n"); running = 0; continue; } if (reloadconfig || (nowtimer >= nextconfigload)) { nextconfigload = nowtimer + 600; reloadconfig = 0; if (!localmode) load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_client_config(configfn); } /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; if ((metacount > 4) && (strncmp(metadata[0], "@@client", 8) == 0)) { int cnum, havecollector; time_t timestamp = atoi(metadata[1]); char *sender = metadata[2]; char *hostname = metadata[3]; char *clientos = metadata[4]; char *clientclass = metadata[5]; char *collectorid = metadata[6]; enum ostype_t os; void *hinfo = NULL; dbgprintf("Client report from host %s\n", (hostname ? hostname : "")); /* Check if we are running a collector module for this type of client */ if (!collectorid) collectorid = ""; for (cnum = 0, havecollector = 0; (collectors[cnum] && !havecollector); cnum++) havecollector = (strcmp(collectorid, collectors[cnum]) == 0); if (!havecollector) continue; hinfo = (localmode ? localhostinfo(hostname) : hostinfo(hostname)); if (!hinfo) continue; os = get_ostype(clientos); /* Default clientclass to the OS name */ if (!clientclass || (*clientclass == '\0')) clientclass = clientos; /* Check for duplicates */ if (add_updateinfo(hostname, seq, timestamp) != 0) continue; if (usebackfeedqueue) combo_start_local(); else combo_start(); switch (os) { case OS_FREEBSD: handle_freebsd_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_NETBSD: handle_netbsd_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_OPENBSD: handle_openbsd_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_LINUX22: case OS_LINUX: case OS_RHEL3: handle_linux_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_DARWIN: handle_darwin_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_SOLARIS: handle_solaris_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_HPUX: handle_hpux_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_OSF: handle_osf_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_AIX: handle_aix_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_IRIX: handle_irix_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_SCO_SV: handle_sco_sv_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_WIN32_BBWIN: handle_win32_bbwin_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_WIN_POWERSHELL: handle_powershell_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_ZVM: handle_zvm_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_ZVSE: handle_zvse_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_ZOS: handle_zos_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_SNMPCOLLECT: handle_snmpcollect_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; case OS_MQCOLLECT: handle_mqcollect_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); break; default: if (unknownclientosok) { dbgprintf("No client backend for OS '%s' sent by %s; using generic\n", clientos, sender); handle_generic_client(hostname, clientclass, os, hinfo, sender, timestamp, restofmsg); } else errprintf("No client backend for OS '%s' sent by %s\n", clientos, sender); break; } combo_end(); } else if (strncmp(metadata[0], "@@shutdown", 10) == 0) { printf("Shutting down\n"); running = 0; continue; } else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); } continue; } else if (strncmp(metadata[0], "@@reload", 8) == 0) { reloadconfig = 1; } else { /* Unknown message - ignore it */ } } if (usebackfeedqueue) sendmessage_finish_local(); return 0; } xymon-4.3.30/xymond/xymond_client.80000664000076400007640000000765113534041733017502 0ustar rpmbuildrpmbuild.TH XYMOND_CLIENT 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_client \- xymond worker module for client data .SH SYNOPSIS .B "xymond_channel \-\-channel=client xymond_client [options]" .SH DESCRIPTION xymond_client is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives xymond client messages sent from systems that have the the Xymon client installed, and use the client data to generate the Xymon status messages for the cpu-, disk-, memory- and procs-columns. It also feeds Xymon data messages with the netstat- and vmstat-data collected by the client. When generating these status messages from the client data, xymond_client will use the configuration rules defined in the .I analysis.cfg(5) file to determine the color of each status message. .SH OPTIONS .IP "\-\-clear\-color=COLOR" Define the color used when sending "msgs", "files" or "ports" reports and there are no rules to check for these statuses. The default is to show a "clear" status, but some people prefer to have it "green". If you would rather prefer not to see these status columns at all, then you can use the "\-\-no\-clear\-msgs", "\-\-no\-clear\-files" and "\-\-no\-clear\-ports" options instead. .IP "\-\-no\-clear\-msgs" If there are no logfile checks, the "msgs" column will show a "clear" status. If you would rather avoid having a "msgs" column, this option causes xymond_client to not send in a clear "msgs" status. .IP "\-\-no\-clear\-files" If there are no file checks, the "files" column will show a "clear" status. If you would rather avoid having a "files" column, this option causes xymond_client to not send in a clear "files" status. .IP "\-\-no\-clear\-ports" If there are no port checks, the "ports" column will show a "clear" status. If you would rather avoid having a "ports" column, this option causes xymond_client to not send in a clear "ports" status. .IP "\-\-no\-ps\-listing" Normally the "procs" status message includes the full process-listing received from the client. If you prefer to just have the monitored processes shown, this option will turn off the full ps-listing. .IP "\-\-no\-port\-listing" Normally the "ports" status message includes the full netstat-listing received from the client. If you prefer to just have the monitored ports shown, this option will turn off the full netstat-listing. .IP "\-\-no\-cpu\-listing" Normally the "cpu" status message includes the full cpu-listing received from the client. If you prefer to just have the monitored cpu load shown, this option will turn off the full cpu-listing. .IP "\-\-uptime\-status" Generate a separate "uptime" status column. The uptime is normally just reported in the "cpu" status column, but if you would like a separate status column for the uptime, you can use this option. It is useful if you want to generate an alert in case of a reboot, without having this alert mixed in with the cpu load alerts. .IP "\-\-config=FILENAME" Sets the filename for the .I analysis.cfg file. The default value is "etc/analysis.cfg" below the Xymon server directory. .IP "\-\-unknownclientosok" Expect and attempt to parse clients with unknown CLIENTOS types. Useful if you're submitting custom host responses with file or msgs data that you'd like to parse. .IP "\-\-dump\-config" Dumps the configuration after parsing it. May be useful to track down problems with configuration file errors. .IP "\-\-test" Starts an interactive session where you can test the analysis.cfg configuration. .IP "\-\-collectors=COLLECTOR1[,COLLECTOR2,...] Limit the set of collector modules that xymond_client will handle. This is not normally used except for running experimental versions of the program. .IP "\-\-debug" Enable debugging output. .SH FILES .IP "~xymon/server/etc/analysis.cfg" .SH BUGS The "disk" status cannot handle filesystems containing whitespace in the filesystem (device) name. .SH "SEE ALSO" analysis.cfg(5), xymond(8), xymond_channel(8), xymon(7) xymon-4.3.30/xymond/xymond_history.80000664000076400007640000000537713534041733017730 0ustar rpmbuildrpmbuild.TH XYMOND_HISTORY 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_history \- xymond worker module for logging status changes .SH SYNOPSIS .B "xymond_channel \-\-channel=stachg xymond_history [options]" .SH DESCRIPTION xymond_history is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives xymond status-change messages from the "stachg" channel via stdin, and uses these to update the history logfiles in a manner that is compatible with the standard Big Brother daemon, bbd. .SH OPTIONS .IP "\-\-histdir=DIRECTORY" The directory for the history files. If not specified, the directory given by the XYMONHISTDIR environment is used. .IP "\-\-histlogdir=DIRECTORY" The directory for the historical status-logs. If not specified, the directory given by the XYMONHISTLOGS environment is used. .IP "\-\-minimum\-free=N" Sets the minimum percentage of free filesystem space on the $XYMONHISTLOGS directory. If there is less than N% free space, xymond_history will not save the detailed status-logs. Default: 5 .IP "\-\-pidfile=FILENAME" xymond_history writes the process-ID it is running with to this file. This is for use in automated startup scripts. The default file is $XYMONSERVERLOGS/xymond_history.pid. .IP "\-\-debug" Enable debugging output. .SH ENVIRONMENT .IP XYMONALLHISTLOG This environment variable controls if the $XYMONHISTDIR/allevents logfile is updated. This file is used by the event-log display on the nongreen html page and the eventlog-webpage, among other things. You can disable it by setting XYMONALLHISTLOGS=FALSE, but this is not recommended. .IP XYMONHOSTHISTLOG This environment variable controls if the $XYMONHISTDIR/HOSTNAME logfile is updated. This file holds a list of all status changes seen for a single host, but is not used by any of the standard Xymon tools. If you do not want to save this, you can disable it by setting XYMONHOSTHISTLOG=FALSE. .IP SAVESTATUSLOG This environment variable controls if the historical status-logs are saved whenever a status change occurs. These logfiles are stored in the $XYMONHISTLOGS directory, and are used for the detailed log-display of a status from the Xymon "History" page. If you do not want to save these, you can disable it by setting SAVESTATUSLOG=FALSE. If you want to save all except some specific logs, use SAVESTATUSLOG=TRUE,!TEST1[,!TEST2...] If you want to save none except some specific logs, use SAVESTATUSLOG=FALSE,TEST1[,TEST2...] .br NOTE: Status logs will not be saved if there is less than 5% free space on the filesystem hosting the $XYMONHISTLOGS directory. The threshold can be tuned via the "\-\-minimum\-free" option. .SH FILES This module does not rely on any configuration files. .SH "SEE ALSO" xymond_channel(8), xymond(8), xymon(7) xymon-4.3.30/xymond/combostatus.10000664000076400007640000000353113534041733017153 0ustar rpmbuildrpmbuild.TH COMBOSTATUS 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME combostatus \- Xymon combination test tool .SH SYNOPSIS .B "combostatus \-\-help" .br .B "combostatus \-\-version" .br .B "combostatus [\-\-debug] [\-\-quiet]" .SH DESCRIPTION \fBcombostatus\fR is a Xymon extension script that runs on the Xymon server. It combines the results of one or more of the normal Xymon test results into a combined test result, using standard arithmetic og logical operators. The resulting tests are sent to the Xymon display server as any normal test - so all of the standard Xymon functions (history, statistics etc.) are available for the combined tests. The tool was born from the need to monitor systems with built-in redundancy and automatic failover - e.g. load-balanced web servers. But other uses are possible. .SH OPTIONS .IP "\-\-error\-colors=COLOR[,COLOR]" Specify which colors trigger an error status. By default only a "red" status counts as an error color - all other colors, including yellow, will count as "green" when evaluating the combined status. COLOR is "red", "yellow", "blue", "purple" or "clear". .IP "\-\-quiet" Normally, the test status sent by combostatus includes information about the underlying test results used to determine the current value of the combined test. "\-\-quiet" eliminates this information from the test status page. .IP "\-\-debug" Provide debugging output for use in troubleshooting problems with combostatus. .IP "\-\-no\-update" Don't send any status messages - instead, the result of the combotests is simply dumped to stdout. Useful for debugging. .SH FILES .IP $XYMONHOME/etc/combo.cfg Configuration file for combostatus, where the combined tests are defined .IP $XYMONHOME/etc/tasks.cfg Configuration file controlling when combostatus is run. .SH "SEE ALSO" combo.cfg(5), hosts.cfg(5), xymonserver.cfg(5), tasks.cfg(5) xymon-4.3.30/xymond/xymonweb.50000664000076400007640000001144413534041733016466 0ustar rpmbuildrpmbuild.TH XYMONWEB 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME Xymon-Web-Templates \- web page headers, footers and forms. .SH DESCRIPTION The Xymon webpages are somewhat customizable, by modifying the header- and footer-templates found in the ~xymon/server/web/ directory. There are usually two or more files for a webpage: A \fBtemplate_header\fR file which is the header for this webpage, and a \fBtemplate_footer\fR file which is the footer. Webpages where entry forms are used have a \fBtemplate_form\fR file which is the data-entry form. With the exception of the \fBbulletin\fR files, the header files are inserted into the HTML code at the very beginning and the footer files are inserted at the bottom. The following templates are available: .IP bulletin A \fBbulletin_header\fR and \fBbulletin_footer\fR is not shipped with Xymon, but if they exist then the content of these files will be inserted in all HTML documents generated by Xymon. The "bulletin_header" contents will appear after the normal header for the webpage, and the "bulletin_footer" will appear just before the normal footer for the webpage. These files can be used to post important information about the Xymon system, e.g. to notify users of current operational or monitoring problems. .IP acknowledge Header, footer and form template for the Xymon \fBacknowledge alert\fR webpage generated by .I acknowledge.cgi(1) .IP stdnormal Header and footer for the Xymon \fBMain view\fR webpages, generated by .I xymongen(1) .IP stdnongreen Header and footer for the Xymon \fBAll non-green view\fR webpage, generated by .I xymongen(1) .IP "stdcritical (DEPRECATED)" Header and footer for the now deprecated \fBold critical\fR webpage, generated by xymongen. You should use the newer .I criticalview.cgi(1) utility instead, which uses the \fBcritical\fR templates. .IP repnormal Header and footer for the Xymon \fBMain view\fR availability report webpages, generated by .I xymongen(1) when running in availability report mode. .IP snapnormal Header and footer for the Xymon \fBMain view\fR snapshot webpages, generated by .I xymongen(1) when running in snapshot report mode. .IP snapnongreen Header and footer for the Xymon \fBAll non-green view\fR snapshot webpage, generated by .I xymongen(1) when running in snapshot report mode. .IP columndoc Header and footer for the Xymon \fBColumn documentation\fR webpages, generated by the .I csvinfo.cgi(1) utility in the default Xymon configuration. .IP confreport Header and footer for the Xymon \fBConfiguration report\fR webpage, generated by the .I confreport.cgi(1) utility. Note that there are also "confreport_front" and "confreport_back" templates, these are inserted into the generated report before the hostlist, and before the column documentation, respectively. .IP event Header, footer and form for the Xymon \fBEventlog report\fR, generated by .I eventlog.cgi(1) .IP findhost Header, footer and form for the Xymon \fBFind host\fR webpage, generated by .I findhost.cgi(1) .IP graphs Header and footer for the Xymon \fBGraph details\fR webpages, generated by .I showgraph.cgi(1) .IP hist Header and footer for the Xymon \fBHistory\fR webpage, generated by .I history.cgi(1) .IP histlog Header and footer for the Xymon \fBHistorical status-log\fR webpage, generated by .I svcstatus.cgi(1) utility when used to show a historical (non-current) status log. .IP critical Header and footer for the Xymon \fBCritical Systems view\fR webpage, generated by .I criticalview.cgi(1) .IP hostsvc Header and footer for the Xymon \fBStatus-log\fR webpage, generated by .I svcstatus.cgi(1) utility when used to show a current status log. .IP info Header and footer for the Xymon \fBInfo column\fR webpage, generated by .I svcstatus.cgi(1) utility when used to show the host configuration page. .IP maintact Header and footer for the Xymon \fB\fR webpage, generated by .I enadis.cgi(1) utility when using the Enable/Disable "preview" mode. .IP maint Header, footer and form for the Xymon \fBEnable/disable\fR webpage, generated by .I enadis.cgi(1) .IP critack Form show on the \fBstatus-log\fR webpage when viewed from the "Critical Systems" overview. This form is used to acknowledge a critical status by the operators monitoring the Critical Systems view. .IP critedit Header, footer and form for the \fBCritical Systems Editor\fR, the .I criticaleditor.cgi(1) utility. .IP replog Header and footer for the Xymon \fBReport status-log\fR webpage, generated by .I svcstatus.cgi(1) utility when used to show a status log for an availability report. .IP report Header, footer and forms for selecting a pre-generated \fBAvailability Report\fR. Handled by the .I datepage.cgi(1) utility. .IP snapshot Header and footer for the Xymon \fBSnapshot report\fR selection webpage, generated by .I snapshot.cgi(1) .SH "SEE ALSO" xymongen(1), svcstatus.cgi(1), xymon(7) xymon-4.3.30/xymond/xymond_history.c0000664000076400007640000005413513527262615020005 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This is a xymond worker module for the "stachg" channel. */ /* This module implements the file-based history logging, and keeps the */ /* historical logfiles in $XYMONVAR/hist/ and $XYMONVAR/histlogs/ updated */ /* to keep track of the status changes. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymond_history.c 8080 2019-08-21 15:38:53Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_worker.h" int rotatefiles = 0; time_t nextfscheck = 0; void sig_handler(int signum) { /* * Why this? Because we must have our own signal handler installed to call wait() */ switch (signum) { case SIGCHLD: break; case SIGHUP: rotatefiles = 1; nextfscheck = 0; break; } } typedef struct columndef_t { char *name; int saveit; } columndef_t; void * columndefs; int main(int argc, char *argv[]) { time_t starttime = gettimer(); char *histdir = NULL; char *histlogdir = NULL; char *msg; int argi, seq; int save_allevents = 1; int save_hostevents = 1; int save_statusevents = 1; int save_histlogs = 1, defaultsaveop = 1; FILE *alleventsfd = NULL; int running = 1; struct sigaction sa; char newcol2[3]; char oldcol2[3]; char alleventsfn[PATH_MAX]; char pidfn[PATH_MAX]; int logdirfull = 0; int minlogspace = 5; MEMDEFINE(pidfn); MEMDEFINE(alleventsfn); MEMDEFINE(newcol2); MEMDEFINE(oldcol2); /* Don't save the error buffer */ save_errbuf = 0; sprintf(pidfn, "%s/xymond_history.pid", xgetenv("XYMONSERVERLOGS")); if (xgetenv("XYMONALLHISTLOG")) save_allevents = (strcmp(xgetenv("XYMONALLHISTLOG"), "TRUE") == 0); if (xgetenv("XYMONHOSTHISTLOG")) save_hostevents = (strcmp(xgetenv("XYMONHOSTHISTLOG"), "TRUE") == 0); if (xgetenv("SAVESTATUSLOG")) save_histlogs = (strncmp(xgetenv("SAVESTATUSLOG"), "FALSE", 5) != 0); for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--histdir=")) { histdir = strchr(argv[argi], '=')+1; } else if (argnmatch(argv[argi], "--histlogdir=")) { histlogdir = strchr(argv[argi], '=')+1; } else if (argnmatch(argv[argi], "--pidfile=")) { strcpy(pidfn, strchr(argv[argi], '=')+1); } else if (argnmatch(argv[argi], "--minimum-free=")) { minlogspace = atoi(strchr(argv[argi], '=')+1); } else if (argnmatch(argv[argi], "--debug")) { debug = 1; } } if (xgetenv("XYMONHISTDIR") && (histdir == NULL)) { histdir = strdup(xgetenv("XYMONHISTDIR")); } if (histdir == NULL) { errprintf("No history directory given, aborting\n"); return 1; } if (save_histlogs && (histlogdir == NULL) && xgetenv("XYMONHISTLOGS")) { histlogdir = strdup(xgetenv("XYMONHISTLOGS")); } if (save_histlogs && (histlogdir == NULL)) { errprintf("No history-log directory given, aborting\n"); return 1; } columndefs = xtreeNew(strcmp); { char *defaultsave, *tok; char *savelist; columndef_t *newrec; savelist = strdup(xgetenv("SAVESTATUSLOG")); defaultsave = strtok(savelist, ","); /* * TRUE: Save everything by default; may list some that are not saved. * ONLY: Save nothing by default; may list some that are saved. * FALSE: Save nothing. */ defaultsaveop = (strcasecmp(defaultsave, "TRUE") == 0); tok = strtok(NULL, ","); while (tok) { newrec = (columndef_t *)malloc(sizeof(columndef_t)); if (*tok == '!') { newrec->saveit = 0; newrec->name = strdup(tok+1); } else { newrec->saveit = 1; newrec->name = strdup(tok); } xtreeAdd(columndefs, newrec->name, newrec); tok = strtok(NULL, ","); } xfree(savelist); } { FILE *pidfd = fopen(pidfn, "w"); if (pidfd) { fprintf(pidfd, "%lu\n", (unsigned long)getpid()); fclose(pidfd); } } sprintf(alleventsfn, "%s/allevents", histdir); if (save_allevents) { alleventsfd = fopen(alleventsfn, "a"); if (alleventsfd == NULL) { errprintf("Cannot open the all-events file '%s'\n", alleventsfn); return 1; } else { setvbuf(alleventsfd, (char *)NULL, _IOLBF, 0); } } /* For picking up lost children */ setup_signalhandler("xymond_history"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; signal(SIGCHLD, SIG_IGN); sigaction(SIGHUP, &sa, NULL); signal(SIGPIPE, SIG_DFL); while (running) { char *metadata[20] = { NULL, }; int metacount; char *p; char *statusdata = ""; char *hostname, *hostnamecommas, *testname, *dismsg, *modifiers; time_t tstamp, lastchg, disabletime, clienttstamp; int tstamp_i, lastchg_i; int newcolor, oldcolor; int downtimeactive; struct tm tstamptm; int trend; int childstat; if (rotatefiles && alleventsfd) { fclose(alleventsfd); alleventsfd = fopen(alleventsfn, "a"); if (alleventsfd == NULL) { errprintf("Cannot re-open the all-events file '%s'\n", alleventsfn); } else { setvbuf(alleventsfd, (char *)NULL, _IOLBF, 0); } } msg = get_xymond_message(C_STACHG, "xymond_history", &seq, NULL); if (msg == NULL) { running = 0; continue; } if (nextfscheck < gettimer()) { logdirfull = (chkfreespace(histlogdir, minlogspace, minlogspace) != 0); if (logdirfull) errprintf("Historylog directory %s has less than %d%% free space - disabling save of data for 5 minutes\n", histlogdir, minlogspace); nextfscheck = gettimer() + 300; } p = strchr(msg, '\n'); if (p) { *p = '\0'; statusdata = msg_data(p+1, 0); } metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < 20)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } if ((metacount > 9) && (strncmp(metadata[0], "@@stachg", 8) == 0)) { xtreePos_t handle; columndef_t *saveit = NULL; /* @@stachg#seq|timestamp|sender|origin|hostname|testname|expiretime|color|prevcolor|changetime|disabletime|disablemsg|downtimeactive|clienttstamp|modifiers */ sscanf(metadata[1], "%d.%*d", &tstamp_i); tstamp = tstamp_i; hostname = metadata[4]; testname = metadata[5]; newcolor = parse_color(metadata[7]); oldcolor = parse_color(metadata[8]); lastchg = atoi(metadata[9]); disabletime = atoi(metadata[10]); dismsg = metadata[11]; downtimeactive = (atoi(metadata[12]) > 0); clienttstamp = atoi(metadata[13]); modifiers = metadata[14]; if (newcolor == -1) { errprintf("Bad message: newcolor is unknown '%s'\n", metadata[7]); continue; } p = hostnamecommas = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = ','; handle = xtreeFind(columndefs, testname); if (handle == xtreeEnd(columndefs)) { saveit = (columndef_t *)malloc(sizeof(columndef_t)); saveit->name = strdup(testname); saveit->saveit = defaultsaveop; xtreeAdd(columndefs, saveit->name, saveit); } else { saveit = (columndef_t *) xtreeData(columndefs, handle); } if (save_statusevents) { char statuslogfn[PATH_MAX]; int logexists; FILE *statuslogfd; char oldcol[100]; char timestamp[40]; struct stat st; MEMDEFINE(statuslogfn); MEMDEFINE(oldcol); MEMDEFINE(timestamp); sprintf(statuslogfn, "%s/%s.%s", histdir, hostnamecommas, testname); stat(statuslogfn, &st); statuslogfd = fopen(statuslogfn, "r+"); logexists = (statuslogfd != NULL); *oldcol = '\0'; if (logexists) { /* * There is a fair chance xymond has not been * running all the time while this system was monitored. * So get the time of the latest status change from the file, * instead of relying on the "lastchange" value we get * from xymond. This is also needed when migrating from * standard bbd to xymond. */ off_t pos = -1; char l[1024]; int gotit; MEMDEFINE(l); fseeko(statuslogfd, 0, SEEK_END); if (ftello(statuslogfd) > 512) { /* Go back 512 from EOF, and skip to start of a line */ fseeko(statuslogfd, -512, SEEK_END); gotit = (fgets(l, sizeof(l)-1, statuslogfd) == NULL); } else { /* Read from beginning of file */ fseeko(statuslogfd, 0, SEEK_SET); gotit = 0; } while (!gotit) { off_t tmppos = ftello(statuslogfd); int dur_i; if (fgets(l, sizeof(l)-1, statuslogfd)) { /* Sun Oct 10 06:49:42 2004 red 1097383782 602 */ if ((strlen(l) > 24) && (sscanf(l+24, " %s %d %d", oldcol, &lastchg_i, &dur_i) == 2) && (parse_color(oldcol) != -1)) { /* * Record the start location of the line */ pos = tmppos; lastchg = lastchg_i; } } else { gotit = 1; } } if (pos == -1) { /* * Couldnt find anything in the log. * Take lastchg from the timestamp of the logfile, * and just append the data. */ lastchg = st.st_mtime; fseeko(statuslogfd, 0, SEEK_END); } else { /* * lastchg was updated above. * Seek to where the last line starts. */ fseeko(statuslogfd, pos, SEEK_SET); } MEMUNDEFINE(l); } else { /* * Logfile does not exist. */ lastchg = tstamp; statuslogfd = fopen(statuslogfn, "a"); if (statuslogfd == NULL) { errprintf("Cannot open status historyfile '%s' : %s\n", statuslogfn, strerror(errno)); } } if (strcmp(oldcol, colorname(newcolor)) == 0) { /* We wont update history unless the color did change. */ if ((gettimer() - starttime) > 300) { errprintf("Will not update %s - color unchanged (%s)\n", statuslogfn, oldcol); } if (hostnamecommas) xfree(hostnamecommas); if (statuslogfd) fclose(statuslogfd); MEMUNDEFINE(statuslogfn); MEMUNDEFINE(oldcol); MEMUNDEFINE(timestamp); continue; } if (statuslogfd) { if (logexists) { struct tm oldtm; /* Re-print the old record, now with the final duration */ memcpy(&oldtm, localtime(&lastchg), sizeof(oldtm)); strftime(timestamp, sizeof(timestamp), "%a %b %e %H:%M:%S %Y", &oldtm); fprintf(statuslogfd, "%s %s %d %d\n", timestamp, oldcol, (int)lastchg, (int)(tstamp - lastchg)); } /* And the new record. */ memcpy(&tstamptm, localtime(&tstamp), sizeof(tstamptm)); strftime(timestamp, sizeof(timestamp), "%a %b %e %H:%M:%S %Y", &tstamptm); fprintf(statuslogfd, "%s %s %d", timestamp, colorname(newcolor), (int)tstamp); fclose(statuslogfd); } MEMUNDEFINE(statuslogfn); MEMUNDEFINE(oldcol); MEMUNDEFINE(timestamp); } if (save_histlogs && saveit->saveit && !logdirfull) { char *hostdash; char fname[PATH_MAX]; FILE *histlogfd; MEMDEFINE(fname); p = hostdash = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; sprintf(fname, "%s/%s", histlogdir, hostdash); mkdir(fname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); p = fname + sprintf(fname, "%s/%s/%s", histlogdir, hostdash, testname); mkdir(fname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); p += sprintf(p, "/%s", histlogtime(tstamp)); histlogfd = fopen(fname, "w"); if (histlogfd) { /* * When a host gets disabled or goes purple, the status * message data is not changed - so it will include a * wrong color as the first word of the message. * Therefore we need to fixup this so it matches the * newcolor value. */ int txtcolor = parse_color(statusdata); char *origstatus = statusdata; char *eoln, *restofdata; int written, closestatus, ok = 1; if (txtcolor != -1) { fprintf(histlogfd, "%s", colorname(newcolor)); statusdata += strlen(colorname(txtcolor)); } if (dismsg && *dismsg) nldecode(dismsg); if (disabletime > 0) { fprintf(histlogfd, " Disabled until %s\n%s\n\n", ctime(&disabletime), (dismsg ? dismsg : "")); fprintf(histlogfd, "Status message when disabled follows:\n\n"); statusdata = origstatus; } else if (dismsg && *dismsg) { fprintf(histlogfd, " Planned downtime: %s\n\n", dismsg); fprintf(histlogfd, "Original status message follows:\n\n"); statusdata = origstatus; } restofdata = statusdata; if (modifiers && *modifiers) { char *modtxt; /* We must finish writing the first line before putting in the modifiers */ eoln = strchr(restofdata, '\n'); if (eoln) { restofdata = eoln+1; *eoln = '\0'; fprintf(histlogfd, "%s\n", statusdata); } nldecode(modifiers); modtxt = strtok(modifiers, "\n"); while (modtxt) { fprintf(histlogfd, "%s\n", modtxt); modtxt = strtok(NULL, "\n"); } } written = fwrite(restofdata, 1, strlen(restofdata), histlogfd); if (written != strlen(restofdata)) { ok = 0; errprintf("Error writing to file %s: %s\n", fname, strerror(errno)); closestatus = fclose(histlogfd); /* Ignore any errors on close */ } else { fprintf(histlogfd, "Status unchanged in 0.00 minutes\n"); fprintf(histlogfd, "Message received from %s\n", metadata[2]); if (clienttstamp) fprintf(histlogfd, "Client data ID %d\n", (int) clienttstamp); closestatus = fclose(histlogfd); if (closestatus != 0) { ok = 0; errprintf("Error writing to file %s: %s\n", fname, strerror(errno)); } } if (!ok) remove(fname); } else { errprintf("Cannot create histlog file '%s' : %s\n", fname, strerror(errno)); } xfree(hostdash); MEMUNDEFINE(fname); } strncpy(oldcol2, ((oldcolor >= 0) ? colorname(oldcolor) : "-"), 2); strncpy(newcol2, colorname(newcolor), 2); newcol2[2] = oldcol2[2] = '\0'; if (oldcolor == -1) trend = -1; /* we don't know how bad it was */ else if (newcolor > oldcolor) trend = 2; /* It's getting worse */ else if (newcolor < oldcolor) trend = 1; /* It's getting better */ else trend = 0; /* Shouldn't happen ... */ if (save_hostevents) { char hostlogfn[PATH_MAX]; FILE *hostlogfd; MEMDEFINE(hostlogfn); sprintf(hostlogfn, "%s/%s", histdir, hostname); hostlogfd = fopen(hostlogfn, "a"); if (hostlogfd) { fprintf(hostlogfd, "%s %d %d %d %s %s %d\n", testname, (int)tstamp, (int)lastchg, (int)(tstamp - lastchg), newcol2, oldcol2, trend); fclose(hostlogfd); } else { errprintf("Cannot open host logfile '%s' : %s\n", hostlogfn, strerror(errno)); } MEMUNDEFINE(hostlogfn); } if (save_allevents) { fprintf(alleventsfd, "%s %s %d %d %d %s %s %d\n", hostname, testname, (int)tstamp, (int)lastchg, (int)(tstamp - lastchg), newcol2, oldcol2, trend); fflush(alleventsfd); } xfree(hostnamecommas); } else if ((metacount > 3) && ((strncmp(metadata[0], "@@drophost", 10) == 0))) { /* @@drophost|timestamp|sender|hostname */ hostname = metadata[3]; if (save_histlogs) { char *hostdash; char testdir[PATH_MAX]; MEMDEFINE(testdir); /* Remove all directories below the host-specific histlog dir */ p = hostdash = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; sprintf(testdir, "%s/%s", histlogdir, hostdash); dropdirectory(testdir, 1); xfree(hostdash); MEMUNDEFINE(testdir); } if (save_hostevents) { char hostlogfn[PATH_MAX]; struct stat st; MEMDEFINE(hostlogfn); sprintf(hostlogfn, "%s/%s", histdir, hostname); if ((stat(hostlogfn, &st) == 0) && S_ISREG(st.st_mode)) { unlink(hostlogfn); } MEMUNDEFINE(hostlogfn); } if (save_statusevents) { DIR *dirfd; struct dirent *de; char *hostlead; char statuslogfn[PATH_MAX]; struct stat st; MEMDEFINE(statuslogfn); /* Remove $XYMONVAR/hist/host,name.* */ p = hostnamecommas = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = ','; hostlead = malloc(strlen(hostname) + 2); strcpy(hostlead, hostnamecommas); strcat(hostlead, "."); dirfd = opendir(histdir); if (dirfd) { while ((de = readdir(dirfd)) != NULL) { if (strncmp(de->d_name, hostlead, strlen(hostlead)) == 0) { sprintf(statuslogfn, "%s/%s", histdir, de->d_name); if ((stat(statuslogfn, &st) == 0) && S_ISREG(st.st_mode)) { unlink(statuslogfn); } } } closedir(dirfd); } xfree(hostlead); xfree(hostnamecommas); MEMUNDEFINE(statuslogfn); } } else if ((metacount > 4) && ((strncmp(metadata[0], "@@droptest", 10) == 0))) { /* @@droptest|timestamp|sender|hostname|testname */ hostname = metadata[3]; testname = metadata[4]; if (save_histlogs) { char *hostdash; char testdir[PATH_MAX]; MEMDEFINE(testdir); p = hostdash = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; sprintf(testdir, "%s/%s/%s", histlogdir, hostdash, testname); dropdirectory(testdir, 1); xfree(hostdash); MEMUNDEFINE(testdir); } if (save_statusevents) { char *hostnamecommas; char statuslogfn[PATH_MAX]; struct stat st; MEMDEFINE(statuslogfn); p = hostnamecommas = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = ','; sprintf(statuslogfn, "%s/%s.%s", histdir, hostnamecommas, testname); if ((stat(statuslogfn, &st) == 0) && S_ISREG(st.st_mode)) unlink(statuslogfn); xfree(hostnamecommas); MEMUNDEFINE(statuslogfn); } } else if ((metacount > 4) && ((strncmp(metadata[0], "@@renamehost", 12) == 0))) { /* @@renamehost|timestamp|sender|hostname|newhostname */ char *newhostname; hostname = metadata[3]; newhostname = metadata[4]; if (save_histlogs) { char *hostdash; char *newhostdash; char olddir[PATH_MAX]; char newdir[PATH_MAX]; MEMDEFINE(olddir); MEMDEFINE(newdir); p = hostdash = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; p = newhostdash = strdup(newhostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; sprintf(olddir, "%s/%s", histlogdir, hostdash); sprintf(newdir, "%s/%s", histlogdir, newhostdash); rename(olddir, newdir); xfree(newhostdash); xfree(hostdash); MEMUNDEFINE(newdir); MEMUNDEFINE(olddir); } if (save_hostevents) { char hostlogfn[PATH_MAX]; char newhostlogfn[PATH_MAX]; MEMDEFINE(hostlogfn); MEMDEFINE(newhostlogfn); sprintf(hostlogfn, "%s/%s", histdir, hostname); sprintf(newhostlogfn, "%s/%s", histdir, newhostname); rename(hostlogfn, newhostlogfn); MEMUNDEFINE(hostlogfn); MEMUNDEFINE(newhostlogfn); } if (save_statusevents) { DIR *dirfd; struct dirent *de; char *hostlead; char *newhostnamecommas; char statuslogfn[PATH_MAX]; char newlogfn[PATH_MAX]; MEMDEFINE(statuslogfn); MEMDEFINE(newlogfn); p = hostnamecommas = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = ','; hostlead = malloc(strlen(hostname) + 2); strcpy(hostlead, hostnamecommas); strcat(hostlead, "."); p = newhostnamecommas = strdup(newhostname); while ((p = strchr(p, '.')) != NULL) *p = ','; dirfd = opendir(histdir); if (dirfd) { while ((de = readdir(dirfd)) != NULL) { if (strncmp(de->d_name, hostlead, strlen(hostlead)) == 0) { char *testname = strchr(de->d_name, '.'); sprintf(statuslogfn, "%s/%s", histdir, de->d_name); sprintf(newlogfn, "%s/%s%s", histdir, newhostnamecommas, testname); rename(statuslogfn, newlogfn); } } closedir(dirfd); } xfree(newhostnamecommas); xfree(hostlead); xfree(hostnamecommas); MEMUNDEFINE(statuslogfn); MEMUNDEFINE(newlogfn); } } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { /* @@renametest|timestamp|sender|hostname|oldtestname|newtestname */ char *newtestname; hostname = metadata[3]; testname = metadata[4]; newtestname = metadata[5]; if (save_histlogs) { char *hostdash; char olddir[PATH_MAX]; char newdir[PATH_MAX]; MEMDEFINE(olddir); MEMDEFINE(newdir); p = hostdash = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = '_'; sprintf(olddir, "%s/%s/%s", histlogdir, hostdash, testname); sprintf(newdir, "%s/%s/%s", histlogdir, hostdash, newtestname); rename(olddir, newdir); xfree(hostdash); MEMUNDEFINE(newdir); MEMUNDEFINE(olddir); } if (save_statusevents) { char *hostnamecommas; char statuslogfn[PATH_MAX]; char newstatuslogfn[PATH_MAX]; MEMDEFINE(statuslogfn); MEMDEFINE(newstatuslogfn); p = hostnamecommas = strdup(hostname); while ((p = strchr(p, '.')) != NULL) *p = ','; sprintf(statuslogfn, "%s/%s.%s", histdir, hostnamecommas, testname); sprintf(newstatuslogfn, "%s/%s.%s", histdir, hostnamecommas, newtestname); rename(statuslogfn, newstatuslogfn); xfree(hostnamecommas); MEMUNDEFINE(newstatuslogfn); MEMUNDEFINE(statuslogfn); } } else if (strncmp(metadata[0], "@@idle", 6) == 0) { /* Nothing */ } else if (strncmp(metadata[0], "@@shutdown", 10) == 0) { running = 0; } else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); } continue; } else if (strncmp(metadata[0], "@@reload", 8) == 0) { /* Do nothing */ } } MEMUNDEFINE(newcol2); MEMUNDEFINE(oldcol2); MEMUNDEFINE(alleventsfn); MEMUNDEFINE(pidfn); fclose(alleventsfd); unlink(pidfn); return 0; } xymon-4.3.30/xymond/wwwfiles/0000775000076400007640000000000013534041775016401 5ustar rpmbuildrpmbuildxymon-4.3.30/xymond/wwwfiles/menu/0000775000076400007640000000000013534041775017345 5ustar rpmbuildrpmbuildxymon-4.3.30/xymond/wwwfiles/menu/t2b-grey.gif0000775000076400007640000000151611535424634021473 0ustar rpmbuildrpmbuildGIF89açB  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ!þCreated with GIMP,õÜ™‡3c¾pÁR%Š%Hˆé¡ÃÆ ,;xymon-4.3.30/xymond/wwwfiles/menu/b2t-blue.gif0000775000076400007640000000147111535424634021454 0ustar rpmbuildrpmbuildGIF89a÷4X4W5Y6Y8[ :\=^=]AbAaDcEdGfGe!Jg!Ki%Mi&Nj*Pj*Ql.Tn/Tm/Uo3Vo3Wq5[u6[t7^y8^x9`:`~9b:b~9d;dƒ;eƒhˆ>jˆ>kˆ@kŒ@mŒAm‹@nŒAn‘@oŒAp‘BpCpCq‘Dq”BrEq“Ds”Dt–Du”Gu™FwšGw™FyšIxGy™HyžIzJzœH{žI|I|ŸJ|¢H}žK|¡J~¢K£J€¢K€¡K€©L‚¨M‚§K„©M„§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,(` "H p!Ã$N¨QC‡$N;xymon-4.3.30/xymond/wwwfiles/menu/xymonmenu-blue.css0000775000076400007640000000357611535424634023057 0ustar rpmbuildrpmbuild#menue { position:absolute; top: 0px; left: 0; padding-bottom: 2px; z-index: 200; } .outer { float: left; display: block; overflow: hidden; padding-top: 2px; padding-left: 4px; height: 1.6em; text-align: left; font: 14px Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif; width: 10em; /* Menu element width 0.05em wider than inner-1 width (see below) */ border: 1px solid #345678; /* Menu button border (button up) */ background: url(t2b-blue.gif); /* Menu button image (button up) */ color: #ffffff; /* Menu button text colour (button up) */ } .outer:hover { height: auto; padding-top: 4px; border: 1px solid #345678; /* Menu button border (button down) */ background: url(b2t-blue.gif); /* Menu button image (button down) */ color: #ebeb77; /* Menu button text colour (button down) */ } a.inner-1 { margin-top: 4px; margin-left: -4px; } a.inner, a.inner-1 { margin-left: -4px; display: block; padding: 2px 0; padding-left: 4px; text-decoration: none; width: 9.95em; /* Menu element width 0.05em narrower than outer width (see above) */ border-top: 1px solid #345678; /* Menu item top border colour */ border-right: 1px solid #345678; /* Menu item right border colour */ color: #eeeeee; /* Unvisited menu item text colour */ background: #456789; /* Unvisited menu item background colour */ } a:visited.inner, a:visited.inner-1 { color: #eeeeee; /* Visited menu item text colour (usually same as unvisited) */ background: #456789; /* Visited menu item background colour (usually same as unvisited) */ } a:hover.inner, a:hover.inner-1 { color: #333333; /* Selected menu item text colour */ background: #00bbbb; /* Selected menu item background colour */ } span.menutag { display: block; cursor: default; } span.invis { display: none; } xymon-4.3.30/xymond/wwwfiles/menu/t2b-blue.gif0000775000076400007640000000147111535424634021454 0ustar rpmbuildrpmbuildGIF89a÷4X4W5Y6Y8[ :\=^=]AbAaDcEdGfGe!Jg!Ki%Mi&Nj*Pj*Ql.Tn/Tm/Uo3Vo3Wq5[u6[t7^y8^x9`:`~9b:b~9d;dƒ;eƒhˆ>jˆ>kˆ@kŒ@mŒAm‹@nŒAn‘@oŒAp‘BpCpCq‘Dq”BrEq“Ds”Dt–Du”Gu™FwšGw™FyšIxGy™HyžIzJzœH{žI|I|ŸJ|¢H}žK|¡J~¢K£J€¢K€¡K€©L‚¨M‚§K„©M„§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,$¢£† 'H€Øá 0PÀ@;xymon-4.3.30/xymond/wwwfiles/menu/b2t-grey.gif0000775000076400007640000000151611535424634021473 0ustar rpmbuildrpmbuildGIF89aç   !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~€€€‚‚‚ƒƒƒ„„„………†††‡‡‡ˆˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŒŽŽŽ‘‘‘’’’“““”””•••–––———˜˜˜™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¼¼¼½½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßßàààáááâââãããäääåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ!þCreated with GIMP,YÀ˜aCG D(q¥ ._ƘQÃΜ;z;xymon-4.3.30/xymond/wwwfiles/menu/xymonmenu-grey.css0000775000076400007640000000357611535424634023076 0ustar rpmbuildrpmbuild#menue { position:absolute; top: 0px; left: 0; padding-bottom: 2px; z-index: 200; } .outer { float: left; display: block; overflow: hidden; padding-top: 2px; padding-left: 4px; height: 1.6em; text-align: left; font: 14px Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif; width: 10em; /* Menu element width 0.05em wider than inner-1 width (see below) */ border: 1px solid #444444; /* Menu button border (button up) */ background: url(t2b-grey.gif); /* Menu button image (button up) */ color: #dddddd; /* Menu button text colour (button up) */ } .outer:hover { height: auto; padding-top: 4px; border: 1px solid #444444; /* Menu button border (button down) */ background: url(b2t-grey.gif); /* Menu button image (button down) */ color: #ffffff; /* Menu button text colour (button down) */ } a.inner-1 { margin-top: 4px; margin-left: -4px; } a.inner, a.inner-1 { margin-left: -4px; display: block; padding: 2px 0; padding-left: 4px; text-decoration: none; width: 9.95em; /* Menu element width 0.05em narrower than outer width (see above) */ border-top: 1px solid #444444; /* Menu item top border colour */ border-right: 1px solid #444444; /* Menu item right border colour */ color: #eeeeee; /* Unvisited menu item text colour */ background: #666666; /* Unvisited menu item background colour */ } a:visited.inner, a:visited.inner-1 { color: #eeeeee; /* Visited menu item text colour (usually same as unvisited) */ background: #666666; /* Visited menu item background colour (usually same as unvisited) */ } a:hover.inner, a:hover.inner-1 { color: #444444; /* Selected menu item text colour */ background: #bbbbbb; /* Selected menu item background colour */ } span.menutag { display: block; cursor: default; } span.invis { display: none; } xymon-4.3.30/xymond/wwwfiles/gifs/0000775000076400007640000000000013534041775017331 5ustar rpmbuildrpmbuildxymon-4.3.30/xymond/wwwfiles/gifs/clear.gif0000664000076400007640000000156411070452713021103 0ustar rpmbuildrpmbuildGIF89a÷€€€€€€€€€ÀÀÀÀÜÀ¤Èðÿ¥ïÿŒÖÿ1{ÿ!cÿZÿRÿRÿRÿJïBçBÞB¿¿¿ÖBÖBÎc„Îc{ÎBkÎJÎ9ƽ½Æ{”Æ{ŒÆ9½9½1µ1­1œJcœ)”)Œ1J„1„)s1s!k!cZ!ZJJw3f™Ì3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿ3ÿfÿ™3333f3™3Ì3ÿ3333333f33™33Ì33ÿ3f3f33ff3f™3fÌ3fÿ3™3™33™f3™™3™Ì3™ÿ3Ì3Ì33Ìf3Ì™3ÌÌ3ÌÿÿÌ3ÿ3ÿ33ÿf3ÿ™3ÿÌff3fff™fÌfÿf3f33f3ff3™f3Ìf3ÿffff3fffff™ffÌffÿf™f™3f™ff™™f™Ìf™ÿfÌfÌ3fÌffÌ™fÌÌfÌÿ3ÿÿfÿfÿ3fÿffÿ™fÿÌ™™3™f™™™Ì™ÿ™3™33™3f™3™™3Ì™3ÿ™f™f3™ff™f™™fÌ™fÿ™™™™3™™f™™™™™Ì™™ÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™Ìÿfÿÿ™ÿ™ÿ3™ÿf™ÿ™™ÿÌÌÌ3ÌfÌ™ÌÌÌÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌfÌf3Ìff™ÿÿÌf™ÌfÌÌfÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÿ3ÿfÿ™ÿÌÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿfÿf3ÿffÿf™ÿfÌÿfÿÿ™ÿûð  ¤€€€ÿÿÿÿÿÿÿÿÿÿÿÿ!ù,QH° Áƒ»)\¨ð`7|#BìVð!>3b¤8ð!Æñqh±`Æ‘<^$8‘`I–]jd)R¦Æ›(U‚ÄXӦĖ2DH´(Ñ€;xymon-4.3.30/xymond/wwwfiles/gifs/yellow.gif0000664000076400007640000000504611070452713021327 0ustar rpmbuildrpmbuildGIF89a…       !%!!%,%/,#/%8"8#3(8+8-B/K-B5K4 €¦…Æwªˆ±³Ù‚¿™ÇŸõ“Ò¨ÿ™!ÿ NETSCAPE2.0!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,[@€P(XD" Áp) LB¥Rh`!”J… )¬ÂFi»-5À1YeF«Émð»|–áu+VËõ¢PRTh„€QSU`{[]_‘Y“~`‚`EGILA!ù ,}@€@9‘ÈÂ1¢„B†(s •J¡KFÄ€$¤M¥R¡B’Ä ö”Êå’GÍ&¹á*9Ú~Ãõk|v~qsB}x€ubdfh{QSUWY[]P^RTVXZ\Œcegi‡_a®±¦“©–¬PDFHJLNBA!ù ,…@2J‘ÈBQCT9LB¥Rhr¨ˆQ I¢¡T*TH!–„Ç]j´ß’ø\U¿Úzs}cxtv„pr‚ˆnŠdfhjl‰SUWY[]_QQ—VXZ\^`egik~m¶“¹–T¯š²BDFHJLNPA!ù ,‹Àe”‘ÈBHŒ(…‡¨2LB¥RhTD IP„P**¤HH1¹QJ§K 7\ ÛUxzqc}uvoƒs†wy‰|~‡Ž{„fhjl‚RTVXZ\^`  ›UWY[]_a•gikm»—¾šS´ž·¡BDFHJLNPA!ù ,‡@Ì(‘ÈBPLŒ0§Ê˜„J¥Ð$TN)IQB©T¨¢(I…‹Òù\j°Ýb@|®ªßßzrs~m€{ƒv…xp‚tІydfhjwQSUWY[]_EE˜TVXZ\^`’egik‹€“¸–‹®š±´BDFHJLNA!þ‹FILE IDENTITY Created or modified by Created by Alchemy Mindworks' GIF Construction Set Professional http://www.mindworkshop.com!þêUNREGISTERED SHAREWARE Assembled with GIF Construction Set: Alchemy Mindworks Inc. Box 500 Beeton, ON L0G 1A0 CANADA. http://www.mindworkshop.com This comment will not appear in files created with a registered version.!ÿ GIFCONtb1.0     ;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-clear.ico0000664000076400007640000000706611070452713022536 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿ«««ÊÊÊää丸¸õõõÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿ€€€@@@ÀÀÀ    ```àààÐÐа°°PPPððð111ooo‘‘‘èèèØØØ(((ˆˆˆwwwøøøÉÉɹ¹¹WWW§§§ggg™™™ ôôôììì$$$äää,,,ÜÜÜÔÔÔLLLÅÅÅ[[[µµµ¬¬¬kkk{{{•••üüüÍÍÍCCC¼¼¼SSSddd¤¤¤œœœttt‹‹‹ƒƒƒ úúúöööòòòîîî"""êêê&&&æææâââ...ÞÞÞ333ÚÚÚÖÖÖÒÒÒËËËNNNÇÇÇÃÃÃUUUYYY]]]···³³³®®®iiimmm¢¢¢žžžyyy}}}———……… þþþýýýûûûùùù÷÷÷õõõñññïïïííí!!!###ëëëééé'''ççç)))ååå+++ããã---áááßßß222ÝÝÝÛÛÛÙÙÙ×××ÕÕÕAAAÓÓÓÑÑÑÏÏÏÎÎÎÌÌÌQQQTTTÄÄÄVVVÂÂÂÁÁÁZZZ¿¿¿\\\»»»^^^ººº___aaaeeefff±±±hhh¯¯¯jjj­­­lllnnn¦¦¦¥¥¥£££uuuvvv¡¡¡xxxŸŸŸzzz|||ššš~~~˜˜˜–––‚‚‚†††=ccccbHŽ6—))•—Ozc oU ¡¡ VSo=bJ•YZ„D} 2 ˆ‘°£›Oz1‹‘4˜–P&…Lˆ‹P”4®jœ¤n«“ S[lq}ƒ„K„.J)Ÿ†ƒB„_r"9‚&%FGKˆ‹®OaPDGw%¤¢Y—š• ,¡Bds„M„˜•`oY(DyF#ƒL\xuE¨‘‰Œ‰‚£œ¦ˆ{Fs>B+,X•™),ž8‰FN°Sc*FFF#{yD!‚L€QªEtz³&vˆ‘°b €s#####}G{s>B+—œ¥ƒ{ˆˆV™ ­{!}#}{ywy{FDvwLMMƒGƒ Tg]FvG}GFq qFGGyiB#…ŠŠW•g-#s#{{}ƒLƒG{{{}I%wD#Š‹W)g¬} ws„©±„BDB„©±K F„ŠŠW•g¯DvDn X$Š@q@ X$ „Š T?>nFwl2Re5Œipi2Re52hw ˆV—?-ƒ@B{v‹S/2p‹S/‹>D%‹’^b±4y 0‹Ž=5Œipi2R=520B#²S´Ddf‰| @q@ X~ž‰ls‘,kªn„[©„sDs„Z;7ƒvGG–)`<L>hsIƒG{#{Gƒ„€{‰°O'­fA#{qlnDI‘ŽC±I!BllBv!vs vQ°/‡9:¥¢š'g?C³‚!vy#{{€*›m<3§±¯­]­ª•g??????gcÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/purple-ack.gif0000664000076400007640000000151211070452713022051 0ustar rpmbuildrpmbuildGIF89a ç3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿf3f33f3ff3™f3Ìf3ÿ™3™33™3f™3™™3Ì™3ÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿff3fff™fÌfÿ3f3f33ff3f™3fÌ3fÿffff3fffff™ffÌffÿ™f™f3™ff™f™™fÌ™fÿÌfÌf3ÌffÌf™ÌfÌÌfÿÿfÿf3ÿffÿf™ÿfÌÿfÿ™™3™f™™™Ì™ÿ3™3™33™f3™™3™Ì3™ÿf™f™3f™ff™™f™Ìf™ÿ™™™™3™™f™™™™™Ì™™ÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÌÌ3ÌfÌ™ÌÌÌÿ3Ì3Ì33Ìf3Ì™3ÌÌ3ÌÿfÌfÌ3fÌffÌ™fÌÌfÌÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™ÌÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùÿ, 'ÿ H° Á#G D¨paC FtH‘`ĉ&”ˆ±`LJ;xymon-4.3.30/xymond/wwwfiles/gifs/bkg-red.gif0000664000076400007640000000104011535462534021325 0ustar rpmbuildrpmbuildGIF89a}Æu     "#$%'()*+-/0134578:;=>?ABDFGIJL N P R T U X Z \ ] ` b d f i k m o q t v xz|„…ˆŒ‰Ž’—•›™Ÿ¢¤¨§«°­´¶º½ÂÆÎÜûõ ï(è/â3ß6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€t‚srqponmlkjihgefdbca`_^\]Z[YWXUVTSQRPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/clear-recent.gif0000664000076400007640000000335111070452713022355 0ustar rpmbuildrpmbuildGIF89a³ÿÿÿÿøøøõõõòòòäääÊÊʸ¸¸«««ÀÀÀ!ù ,S0ɉjXV„(W†paÅ`ˆœpºjœ7:xª‰VÉæ+V-˜u —&#²­üvT\®¢pm9”ŒÅ-—"„amPÍ2ËNÏD;>;à,àOE ‡²–±H9ê”ͧŽçT‰Å#û«n¹ÓTÓ Mæ´8!ù ,B %ŠBYŽ(U:C[œ¨P°më8Â(Ðuÿ’4AMØÊí†ÈÁm•‹ÏžÔyœJKVêPÅÓnUè2Ì’ubXJe:‹B!ù ,< %ŠDYŽ(Ulqœ(q´ô;Êtn«-Ñ÷ªË7¤­~Å1Ç, ™ÆeîX ð¢F’²yƒSÔ¡5E2G!!ù ,= %ŠFYŽ(U쑜¨‘$mûŽF­»I9V¨ª ‡/YëhîšÏÝê9%:Î^Qx%’¢^Ü–R™´£!ù ,B %ŠHYŽ(UBI (²°­ûŽ]ï BÒˆZ°åË ÈËHD‡»èS'B£%¡ŠšÕª¬ÑÛ¯šðÅ®ËÎd…!ù ,; %ŠJYŽ(U.ìÒœ¨Ò´ô;*tî*ä¼à,àOE ²–±xÔ)›Ndt$2‹¤§Ž—¦¨ÏÔÍÄ…!ù ,: %ŠLYŽ(0MÛ2A¸ô;²u«.Þø Šï×£ÁŒÅÞ0§dæJN¨m)µ ›º›ó—ª¾‚)’ < !ù ,D %Š…c:cJ…äºÅ¡Ñcßv1¶8“›ã6|HtŠOœ©G:«Bho*\mµ( ”ËÔ‘°OÙªÚ£!ù ,C %ŠKcJ-K京ºLo=Ac[ïÓB¾‰D¸ª ]ÇÈM‡ÖL»(’)&w ²h¼â(ÉSÔ÷«~Gb#Yµ:¡R!!ù ,@ %ŠÑ#cJEÑ京Qo½Žm­ßë+ù¾Ðõs­rÄ¡ëñÐ9‰È§¯è<£kBÕÖf$iVå]‚U+*!ù ,B %ŠKcJ-K京ºPoMAc[ï+ù&/HpUºŒ‘›î¬™vÐã2úCî À#±hÅÝ‚VXŽñŽN×™ŠtB¥B!ù ,D %Š…c:cJ…äºÅ¡Ñcßv1¶8“›ã6|HtŠOœ©G:«Bho*\mµ( ”ËÔ‘°OÙªÚ£!ù ,: %ŠLYŽ(0MÛ2A¸ô;²u«.Þø Šï×£ÁŒÅÞ0§dæJN¨m)µ ›º›ó—ª¾‚)’ < !ù ,9 %ŠJYŽ(U.ì¢*)ÜÎê¨Ì¸ ×ìÝ·0ßoØ“…‹U.§\Κ¸f0ŠÜ ¡=›3C&w©—)!ù ,B %ŠHYŽ(UBI (²°­ûŽ]ï BÒˆZ°åË ÈËHD‡»èS'B£%¡ŠšÕª¬ÑÛ¯šðÅ®ËÎd…!ù ,= %ŠFYŽ(U쑜¨‘$mûŽF­»I9V¨ª ‡/YëhîšÏÝê9%:Î^Qx%’¢^Ü–R™´£!ù ,< %ŠDYŽ(Ulqœ(q´ô;Êtn«-Ñ÷ªË7¤­~Å1Ç, ™ÆeîX ð¢F’²yƒSÔ¡5E2G!!ù ,B %ŠBYŽ(U:C[œ¨P°më8Â(Ðuÿ’4AMØÊí†ÈÁm•‹ÏžÔyœJKVêPÅÓnUè2Ì’ubXJe:‹B!ù_,; %Š@YŽ(Ul0œ(0´ô;tîäà,àOE ²–±xÔ)›Ndt$2‹¤§Ž—¦¨ÏÔÍÄ…!ù_, !ù_, ;xymon-4.3.30/xymond/wwwfiles/gifs/arrow.gif0000664000076400007640000000033711070452713021144 0ustar rpmbuildrpmbuildGIF89aÄÿÀÀÀêêÝÜÎÎÍÍÀ³³²²¤¤££–•Љ!ù,@\` ŽdiGbr ëz¤ð5x®çÔD§ È&,^€%£ÁX0ʆùX0Å‘`@Ìz¿,xT±ˆG$ýx@"I{Á*îø¼O¼øÿ€]`†c'!;xymon-4.3.30/xymond/wwwfiles/gifs/bkg-green.gif0000664000076400007640000000104011535462534021653 0ustar rpmbuildrpmbuildGIF89a}Æu              "#$%'()*+-/0134578:;=>?ABDFGIJL!N"P#R"T#U%X&Z'\&])`)b*d)f,i-k.m-o0q1t2v1x3z4|568„8…9ˆ:‰;Œ<Ž?=’?•B—@™D›EEŸG¢H¤I§I¨K«L­P°R´R¶TºV½XÂZÆ]ÎdÜ[ß_âdèmïpõ sûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€o‚pqrstnmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/blue.gif0000664000076400007640000000164011070452713020737 0ustar rpmbuildrpmbuildGIF89a÷3f™Ìÿ333f3™3Ì3ÿÈàéV1]óLêVôAZA\ôVf¨ÉÿˆšAêVêV ¸ðAp²ÙæêVn¢ö¿‡´ö¿@ôAðAôVÛò@ôAZò ðüôAú[óôA i€ iˆôXÀFC:\FDB\BBTEST\BBTEST_FILES\BLUE.GIF*@È"ù¿¾ìVôVÿÿÿçܨ°hî@ôVÈ>½ÿÿÿçܨ°´û¿ÿÿÿÿ¯¹ö¿ ¾ÁÚíVÔ¨°ÔùVTëV‡·¾p °û¿ÒëV¬¦GƒÿÿÿÿpëVܸö¿ÏAö¿ã€„ëVܸö¿ÏAö¿´û¿÷¸ö¿´û¿ã€œëV‰¹ö¿‡·ÏAö¿´û¿¯¹ö¿p²ÙæÌëVE1ø¿ã€+õõVèëVÀŒõìV<ìVhìVìVeŒõ Ä7ƒìV<ìVoŒõõVlìV®‹õìV<ìVhìVõVW€õV€ iW€õV$õVLìVDìVÀ~A˜ôVy‹õLAìV!ù,}H° @TãâÎñ¢:ˆª¡Å‹îÄÈ1£Àx ˆ)’a<BÆ[Ér¡»>Œ×¬f3…2ŽRÙ áM—£tòô‰Ó]P2!Úü™@Ê™,Wº„ äC’#Mnt(¤«W† ìhQ£Ø„.UJ4È–`@;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-red.ico0000664000076400007640000000706611070452713022222 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿÿzzÿÀÀÀUÅXXÿ§éÈ                       ÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿ>=ÿ_a_މˆìAE è:;¥$&O’’¨Vabã=:0Ã-w:NQ~k8:Y"åÎÿ††»PQìŽ)+yHI¾AC‹v/13’E//ÿ=opÜxWY@6NLÿIK¦؇ˆÿBDdO£ uuíggûÅQQÌò_aN&&ë A .YXöjkíFFìEFz€ã ï;;ñ y€ [÷79fÃMM‹ÿÛ68€ -&)AZZè \23¥SS× jHJ›n wH‹‹ª ‚=?€€ÿ76ÿIJà2PPâBBÂpqÉIHù crröBBô]`A/1€ «þ—&à 5 !IK„rggáEopäÓÌÃ]\ïÂ::ùbeT;=†ADt]=@@ <@ ÿg‡ð cBD|9;mVUã ùÿZ]N_aX‘u'l‡‡ùIHÿVñøâë¾xwÿ)HJ‹  úGJÿllò &Íbd@cOQˆ@Aƒh`_çLs~!± ceß@@ø46e!&ó11ÿ ëÐ Ìjö2¨Ÿƒ”û ó×)z &Yw h <>ƒOOÿ !@kšŠ [[í óìÞ$$ê 1ÈTºi즦¦¦¦ìõåþ¾¾¾¾¾æñ›ì¦›_}<ôô}—;Õiõ×_ÓeØTÙ_ÃÃÃ_ÛÿIö&&JD¼3!¦i\¸kYYyP¨ ŸŸŸŸéééߦÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/yellow-ack.gif0000664000076400007640000000151211070452713022055 0ustar rpmbuildrpmbuildGIF89a ç3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿf3f33f3ff3™f3Ìf3ÿ™3™33™3f™3™™3Ì™3ÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿff3fff™fÌfÿ3f3f33ff3f™3fÌ3fÿffff3fffff™ffÌffÿ™f™f3™ff™f™™fÌ™fÿÌfÌf3ÌffÌf™ÌfÌÌfÿÿfÿf3ÿffÿf™ÿfÌÿfÿ™™3™f™™™Ì™ÿ3™3™33™f3™™3™Ì3™ÿf™f™3f™ff™™f™Ìf™ÿ™™™™3™™f™™™™™Ì™™ÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÌÌ3ÌfÌ™ÌÌÌÿ3Ì3Ì33Ìf3Ì™3ÌÌ3ÌÿfÌfÌ3fÌffÌ™fÌÌfÌÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™ÌÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùÿ, 'ÿ H° ÁW¯ D¨paC FtH‘`ĉ&”ˆ±`LJ;xymon-4.3.30/xymond/wwwfiles/gifs/unknown-recent.gif0000664000076400007640000000110411070452713022760 0ustar rpmbuildrpmbuild‰PNG  IHDR(-SØPLTE33f½¥BýÐîߦÿìžok}ŸŸŸõîÓýÜYÏĦ„ƒ{^Ynÿñ»îÂųxÿøÜ”Œmeavÿ×9ÝÔ¸ÿåÿî¬ÏÌÊýËÿýóõ奭¬»ÔÄa\s‘Œ•üÒ,‚|…©¡–þálˆ…xÿõÌ·°¥ÿûíšgcb†þÚKÿèÿð²ûÌóå±ÖÊ¥DCnÀ¦?ÿí¥ys¤žŸýôÑ………\Z}ÿóÄôÆ Å¶†ÿúåcaÿÚGåâÝÿæ„ÿð²üÌ ÿþùÿê•ÔÆa^}ûÓ3ÿãtž’bRÚ÷ºHtRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœìò`ÓIDATxœ-ëRÂ0F·X FJëÑZŠoц–ˆ™Xmíû¿› ߯=gfg÷ƒÎ]üÔC›rFÖ ë¤(yƒ^ ø¹yÚn¿/rQ9aõÕ÷¥~B_ûÞ¦yî6–𮛘„Ôšøî¯k#ð'IQü½òpÝ œÖY–×µIgÈ£²^OˆÛ¨+º"7›ßé|G¼Ç€6RÞÎÏÆÄ¶bþÓ…1míŸñ_ù.6BÌzX{Ñ1•¦Žm)lÅ”òÓt+ðÙÛ„IEND®B`‚xymon-4.3.30/xymond/wwwfiles/gifs/yellow-recent.gif0000664000076400007640000000056611070452713022607 0ustar rpmbuildrpmbuildGIF89aÃÿÿÿÿû¥ÿû9ÿ¾ÿãÿŠÿÛÿÿ÷ÿ¶ïÿ¢ÿšµÿÛÿ×!ÿ NETSCAPE2.0!ù_,gÐÉ jXÖ Æ WVacp´/J ãñ’/¨ ÈÜ?AôH‰Z’ HM‡Äâ'6DÁTáL'aKÞ2ÎÖÐÛ¶·: aœVÒªyC8Ç‹ (j…†Š!ù ,¸y¦­D!ù ,¸Ié±5ƒ!ù ,ð¸I+=!ùP,ð¸I«½3E!ù ,ÐI¦½³Î!ù ,ÐI¦¬3;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-purple.ico0000664000076400007640000000706611070452713022757 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿÈÆµšÿþaýÿüš˜ï¶ÿÿÛÿ®¬ïíÖÔ                              ÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿÁÀ€ša`ôbóÄÊÂ;P;ÿÿ‰A‰ž‡ÙЦþ/ 4‘ÏFÎMNsnqní1ëãÍãM+Mà Ý«ˆ°k0k*Æ™ÞVnVHGwz©§ÌËŠ‰ÿBÿâQát[Xpÿ!ÿVKYœ<œ´Æ;0=îíy#yÕ«Û$?#Ý9Ýgm…sŒsÒÐ##`U~ ›zo~ÚÀ×îëJÓ  ‚ i#ilglrrvu 8 ËÉñ ïwyw~OM,-}áIà9 8®­ŒŠûùHKm:H9E@..gf  t7tàÝ»¸[Zñ5ñmfy55¤¡’& &²ŠÄÅÃXWi*iîëÕÓÒ¬ÿêèï+í98;‚‹vtóñõ0óú÷!%$dcˆ2ˆ4 9”’''Šƒ~ }…„ÿôÿ   ŒÙ764 4_YonàÐà! !vun3n…7…%%+ +×=Ö›šzy×Ä×ÿÿÿÿÿ;ÿÿ1ÿED ¸¶¬ªJHp ÄÎÄ ãáÍËv3väIãNNQQqeojiŒŠhh‰#ˆá.á(+ÑIв°ut€ƒr3rîëÄÀ¾¼_^“õóÝÛ**88WVŽxwÇÅñï#"ÕÒ2133GFWNZpoù÷;;;;;;;;¬îuéð@ððððÄ÷;ç¸éRH{ÈÈÈÈ ð¸æ¬‡ßx0Íí\\\ííqŒ½‚Äg¸Ô{{{HÇÇHHÇÇÇHÞ|uçıÇ0Ô‡ÒÒÒÒÒÒÒÒ@‡Ô¼H¦uî¬èõ•ª®>¹¹¹ggg¹¹¹>®ªq0¦Äþ¿‚•ÀÍ{ª½½½½±Ô±½½½½ªHÍõ臿ìß0}ëíôäääôøíøôäääô…ë}α¡£ÍÀ}µ›››¨øÀ•ª›››Bä}À•¦Ò;éHUœë•h‹wwÜ¥êqcQwwÜ à0—0Ç|¬æòUÀõÞ©ajs5DÉ#^eÓs5D~PŒ‘0ð;µœÀÍCw¾+d 8=M6+d­b°Ç\Èð;µëÀíÒv«² 3FI²–.1€HíÈð;µœÀ̓/Ëš™"STNš™"'‰ŸuH\Èð;xœÀ—kÚ,Z¢%(v,Z¢ü_W‡†\Èð;æh œ½çpÙm;öÅÊŠpÙm;öÅpæ†\Èð;Ì×Ã$`½Øû££@Oóoãû££@Oó†\Èð;ÌAÐE”ýÈøôHªùæÑ{øôHªO‡Çq ¬¤…Cç:$`—†Äåi$`—†æ‡ÇðŽ4ÕzVYŒÒºáÝVYŒÒßHµ¸Æž<“Ö’ð@£´*¶i’ð@‡½{ÞþÊÏyˆ7JïŽgãùñ‘¯³g÷½èô Äþ·f»Glýýx‘)èý£Ô±òÈôRÒ>2]!KXÛârrÿ}õÍÍíÎÇÞ Ò9„ &- [ÁÀÀÀÀ‘ª‚ĸÌm§¤!?˜”)œõ‘±gæ¬9„LntµµµxúÌö;ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/green-ack.gif0000664000076400007640000000151212511454274021647 0ustar rpmbuildrpmbuildGIF89a ÷3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿf3f33f3ff3™f3Ìf3ÿ™3™33™3f™3™™3Ì™3ÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿff3fff™fÌfÿ3f3f33ff3f™3fÌ3fÿffff3fffff™ffÌffÿ™f™f3™ff™f™™fÌ™fÿÌfÌf3ÌffÌf™ÌfÌÌfÿÿfÿf3ÿffÿf™ÿfÌÿfÿ™™3™f™™™Ì™ÿ3™3™33™f3™™3™Ì3™ÿf™f™3f™ff™™f™Ìf™ÿ™™™™3™™f™™™™™Ì™™ÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÌÌ3ÌfÌ™ÌÌÌÿ3Ì3Ì33Ìf3Ì™3ÌÌ3ÌÿfÌfÌ3fÌffÌ™fÌÌfÌÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™ÌÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿ3ÿfÿ™ÿÌÿÿ3ÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿfÿfÿ3fÿffÿ™fÿÌfÿÿ™ÿ™ÿ3™ÿf™ÿ™™ÿÌ™ÿÿÌÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÿÿÿÿ3ÿÿfÿÿ™ÿÿÌÿÿÿ!ù¬, @'Y H ­ƒ´ *xp¡Á„ :lèp!E‹/2„¨ñ!ÄŠ ;xymon-4.3.30/xymond/wwwfiles/gifs/purple-recent.gif0000664000076400007640000000064011070452713022574 0ustar rpmbuildrpmbuildGIF89aÃýaþüÿÔÖíÆÈ¬®ÿÿÿÿ¶ïÿÛÿÿšµ!ÿ NETSCAPE2.0!ù_ ,_É jXÖ„Wpa€‚EX¨ªµaŒ6j`§?_ŠðXŽÃAU|! À3ªd ^ŠÄÝV‰“Ëe¦´z§€:³ÆF§Ë)€ƒþ’e4G‚ƒ!ù_ ,E!ù_ ,E!ù( ,E!ù , ÐH k¡æ‚Í#!ù , ÐH k¡æ‚Í#!ù2 ,1#§1Å–!ù ,±"'¸ì‚!ù , И$8«´À^;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-blue.ico0000664000076400007640000000706611070452713022377 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿÿHþžWœ,ý{Ì:ýŒ8ýe(°1½5þ˜M                        ÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿÿo tM,Á1ðSQ¾v0†(ïC" À] O6ÿ‡2§EápG݉IþS©eÿ§=k ÿj&¡.×=6ŠR#éX õ} ÿSw4ÿ–Hí†5A,X5¼< ±2õ“/]%È{;ÿEÿ_ # öœ?ónÿ'x$êw"“+?í—H€L ä@Ë9‰Y.F ÿ…€Q,æK\ÿs!ÿŠ'êOƒ? x?íaÿ”2óZ *ÿ]õ’E¹8ÿž:ÿ{÷Hÿb ÿV ìrî}'ÞEÿf÷‡5©0~5ÿ—@ek'éE#ãŠHÿLš, ÿ¦D` rr9¶.Å7/W-}F<ÿXïz J)Ý?õC yP-* ÿ‚"~N(Ï=þZôI}B ¾6éBÈw7DUÿRûIp#†S,¹4µ8  üúBósÓ;îui#ÿ‡*ÿi øFê^ÿpfÿ^t"~%éI’&A ²-µ4ñ†5ÿP¥.ëy%íF ;ÿ~ÿ~^ÿIm‰V,Ï;œ/Â5¬.ƒ%ët ÿ}'XbÿVm!ìCæA–+È8 " ,2Gþyÿf&öFãCà?Û>+ÿ <ý™@A.iv!ž-»5! ùI÷Dq"sK-~E # ÿ¦?ÿ˜Iÿ™AÞˆGÿj$ÿ\ÿMÿJ`ýIdûGípóEñEïFéDz%„'Ø<Œ(}DÒ<Í:Á7³2  4ÿ”0Xÿ_[ÿRÿKëti ô‡‡‡‡‡‡‡£¿á=µµµµµÁ+Ö±ù`%V     í³Ö£§ã턼­­­­ññ%ȸ¶Á¾ö”%¼ÏÏg¼gggggggg{œÈ¤§¬ð| ºÆpÆÆÆÆÆpÆÇŒ«{1µ÷] g«5äâäääää䑯6¼6¼Î£ûñº5 ¨ý¨¨¨¨¨¨¨ý¨çp66ì{á󳸼‘¨¨¨¨¨¨¨¨¨¨¨¨¨ýâ5Œìñ¸³Y®5ýŸŸßßßßßßßßßßߟŸýÄ5go‡cI¢äæ|ºººººººººººººººÆŒñòín£½úàœ–ÌÌÿÿÿÿÿÿÿÿÿÿÿ–»„ðVµ‡rz-Ñ™ÀØ+++++++++++++ØhÓœŒVµ‡rŠÑfÍÓ»ÏðVµ‡rÕQ“€Ò ¹|||¹ ¹|¹ ¹|||¹¹g­ µ‡rj0¥TlŸßßߟüŸŸŸüŸßßߟļ­V=‡²4žøÂE牨ßýä瑨‘çäýßý¹ïg6òá‡PªÚÙ—›¨ýœëœ5œë%¨ýœêë„Ç­”õPs^,mš2dì<Ç–~È1~Ó<Ç/káòïV=‡ƒRB'YŽ”§/…Å…ê§”Ž””/¬ÏãÐU&AF¾t¯Çyypë¿Ø¿p輸³v : eZd)ý¨ß¨­–©–„Ĩ6§9ÜÊ?ˆ’˜‘ý_àààL[é|5pïVù£ ;(ÛbJu•*x··ÞGN_q«`§¤ ;H u¦K>ÝÃM@wg á³"Ô#7}XÉD.´´>Þ$‚Yh†† ;3!¡°þåCS\aOôËi4îzzšW–8PP²rrrr׋ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/bkg-clear.gif0000664000076400007640000000104011535462534021641 0ustar rpmbuildrpmbuildGIF89a}Æu  """###$$$%%%'''((()))***+++---///000111333444555777888:::;;;===>>>???AAABBBDDDFFFGGGIIIJJJLLLNNNPPPRRRTTTUUUXXXZZZ\\\]]]```bbbdddfffiiikkkmmmoooqqqtttvvvxxxzzz|||„„„………ˆˆˆ‰‰‰ŒŒŒŽŽŽ’’’•••———™™™›››ŸŸŸ¢¢¢¤¤¤§§§¨¨¨«««­­­°°°´´´¶¶¶ººº½½½ÂÂÂÆÆÆÎÎÎÜÜÜßßßâââèèèïïïõõõûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€o‚pqrstnmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/zoom.gif0000664000076400007640000000174711070452713021004 0ustar rpmbuildrpmbuildGIF89a÷þþþÎýýÖýýÐþý÷ñë”§óïìÃþþÉþý˜æûšæûþØtÎÎÖ‚ÑùƒÒûØ‚Ñþý¾ýýýýþ¼þýÂþýÌýý¿ÂÏÒþþ«îü’®Êqo…{ÌùÑÑÚÞüÎÏØÜøyÌý¢‰y©‹x—oU}¥Ò§u  "Ã( 2:Ñs#cš"@¸“$J•!k2ÆÁd@ …xLÀá(#ÐPiQ¡I€ J2®ØÑ£F^(T £|¡ à3S2¾q2ãK0YéÂ!ã#:*–9p$†B{ŒÈÈ€M"XÜx@R ‹:n3!2ç ‰êP³eœER"3ÑÈÇ¡š^ áE Ð ýÈ£! ;xymon-4.3.30/xymond/wwwfiles/gifs/red-ack.gif0000664000076400007640000000151211070452713021314 0ustar rpmbuildrpmbuildGIF89a ç3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿf3f33f3ff3™f3Ìf3ÿ™3™33™3f™3™™3Ì™3ÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿff3fff™fÌfÿ3f3f33ff3f™3fÌ3fÿffff3fffff™ffÌffÿ™f™f3™ff™f™™fÌ™fÿÌfÌf3ÌffÌf™ÌfÌÌfÿÿfÿf3ÿffÿf™ÿfÌÿfÿ™™3™f™™™Ì™ÿ3™3™33™f3™™3™Ì3™ÿf™f™3f™ff™™f™Ìf™ÿ™™™™3™™f™™™™™Ì™™ÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÌÌ3ÌfÌ™ÌÌÌÿ3Ì3Ì33Ìf3Ì™3ÌÌ3ÌÿfÌfÌ3fÌffÌ™fÌÌfÌÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™ÌÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùÿ, 'ÿ H° Á!C D¨paC FtH‘`ĉ&”ˆ±`LJ;xymon-4.3.30/xymond/wwwfiles/gifs/green-recent.gif0000664000076400007640000000025111070452713022363 0ustar rpmbuildrpmbuildGIF89a³ÀÀÀöɹœ†t`!ù,VÈ™jXÖ„0W–paH‚¥é¢ª& AÛ5¨Ãíç)@b€+Þ ÕÐt`:‘J¢kzJ T*LƒM¦ ƒŽÛµ„·±Z%ðC*–јëø|;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-yellow.ico0000664000076400007640000000706611070452713022763 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿŠÿ9ûÿµšÿ¥ûÿ×ÿï¶ÿÿÛÿ÷ÿ¾ÿ¢ÿãÿÛÿ               ÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿ˜ÿ£xlnlÿÿÁÄÂýÿQ;jC”—%NiÁ¥€ÔÇÂ{ÅÉÕ¡ú>.+4ØàkphçÓç’¢?yÍþ9kw‚•—"šÌ`—_Šˆn¼fàä)JjzJk=õúÄ•ÕIQJi— 8<ÿÜÿܹÕ~ßMNNÚâAÈÉŽÙÙc’’}‹È¦¿©´!ÿÿÊÖÖÀÜ-RJ€Z{)1æöè±èðéë]lcYkS†‰†ÀnJ2^˜‹˜(]>9@W÷÷.œŸ’íðOi®íM‹u o€YwyC[\³Ê“â<†‡ÒÚŒky&&'ÊÙ%àäÑáâŹä1q¦ÏãNøRQ¤ü-všš>•P‰†CåÀ$yÈBXeeXŠXX%¯rðÃÓ° NZ†-*Ø™váx3+0|¢ BŒuuš4.{£tiYLžžø†e¤/U¥©J|—ŒŒŒÓÓÃÃÃÃÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/blue-recent.gif0000664000076400007640000000112111070452713022207 0ustar rpmbuildrpmbuildGIF89aÔ Wžþ8Œý{ý:Ì(eý,œM˜þHÿ5½1°ÿŠ„ÿ$ÿÿ‚{ÿMJ!ÿ NETSCAPE2.0!ù_,Z $Ž@YލXÂ0 g ‡[ÜD ³‹üÀÜNÕ*„aðc2a ÐZÑàuµ&Ú—i\új ]¯A‰N'’¤h÷ æå¢xÂ:5(þ kC|}&„‡|!!ù_, !ù_, !ù_, !ù_, !ù_, !ù ,  Š!!ù ,  °0$@@šB!!ù ,  °,Íò"£2‚¾I!ù ,  $>Ð"–ÍB Ó0 4 …!ù ,  $6Ð#BLÊ@ຠ”Ì3!ù ,  1$!@š"'â²!!ù ,  Œ#!( …;xymon-4.3.30/xymond/wwwfiles/gifs/blue-ack.gif0000664000076400007640000000070511070452713021474 0ustar rpmbuildrpmbuildGIF89a Æ3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿf3f33f3ff3™f3Ìf3ÿ™3™33™3f™3™™3Ì™3ÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÿ3ÿ33ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù, "€‚ƒ„…††ƒˆŠ‹‚Œ‘Ž”„‘“–ˆ‰’˜……;xymon-4.3.30/xymond/wwwfiles/gifs/xymonbody.css0000664000076400007640000000103011535424634022063 0ustar rpmbuildrpmbuild/* body classes definitions */ body { color: #D8D8BF; background-color: black; background-repeat: repeat-y; } a:link { color: #00FFAA; text-decoration: underline; } a:visited { color: #FFFF44; text-decoration: underline; } .green { background-image: url(bkg-green.gif); } .yellow { background-image: url(bkg-yellow.gif); } .red { background-image: url(bkg-red.gif); } .purple { background-image: url(bkg-purple.gif); } .blue { background-image: url(bkg-blue.gif); } .clear { background-image: url(bkg-clear.gif); } xymon-4.3.30/xymond/wwwfiles/gifs/favicon-green.ico0000664000076400007640000000706611070452713022550 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿöt¹œ`†É ÿÿüðàÀÀ€€€€€ÀÀàðü( @€ÿÿÿÿ¿?ŸÞ^î/nÏO®÷'æ7G¶f—v‡×ÈV§ ó+3Ä;»CK£Z›b“j‹rƒzëá"Ò̳«R ñ äÜÙ$Õ)Ê5Â9=½A¹E±M©¥X¡\`™d•‘lp‰t…x|þø í ÝÖÑÎ !ËÉÅ*Ã,Á.¼2º4¸68µ:<>¬@ªB¨D¦F¤H¢J LžPœQš˜U–W”Y’[]ŽŒaŠˆ†„ik€mq{syuwn@nnnnnlz‹(MŽƒw@ot’15d»3½3b­Knl:Nœž1±¦ª¬¬0¬_4œ‘%w8*2e¼¼5555555¹À- qI*`®>½P”º^¥h§ "l‘d°_¦¤Dwwwww!!yÀ±´5«ƒ6µ,®1Ž‘R˜**š+”K‘¯¶0¿ŽjœµU_¢”5ª_ °°¬¥4G*¹.gr–`®™··¥“>•UU>SŸb¢/2.´[&@P¾¦Z£^_¨ZŸŸXXXŸX¬^¥^cÀW…m#§¡=,.ZV•™¡.£¡¡£¥ZV>U¡0c4¸nB •Š,\.¡ŸZ..££££.£¡XX£0cµ MnB[O,\¦^0¨.Z\^0¨.Z\^ª¦¥ªcµ nB •Q›¡\4dg\V¥4dg\V¥4¿4¨¨³µ nB­VVU1R ¨1R ¨1š²_.±µ nr]=“V§D”0‚•D”0‚•z˜±aµ Mnt¾u)O Tr¬J“¬J“s³Xa¶¸8f}‚'  0“¢tŽ0“¢8‘±,a©…m•';—R‰¬€“Tq‹¬€“TBM°U2 ‰dCS*0LUW~*ª'•«: 4Rr»9†´1d^>-º¦S›5Yº ¦j#3{ F<„SXZ¡¦¬ª¥¡.^®´fW%6?hL$E—••V¡\¦Z™—¾?‡"hxp7E;<ˆ>››,Z¬¶dW #d4³)AikLLŒ¥ºšƒwtv:¼H7}OQV¼”slPd4¹½1·­’|8vvtssq@ÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿàÿÿþ?üøððððÀÀÀÀÀÀÀÀÀððððøüþ?ÿÿàÿÿðÿxymon-4.3.30/xymond/wwwfiles/gifs/unknown.gif0000664000076400007640000000110411070452713021502 0ustar rpmbuildrpmbuild‰PNG  IHDR(-SØPLTE33f½¥BýÐîߦÿìžok}ŸŸŸõîÓýÜYÏĦ„ƒ{^Ynÿñ»îÂųxÿøÜ”Œmeavÿ×9ÝÔ¸ÿåÿî¬ÏÌÊýËÿýóõ奭¬»ÔÄa\s‘Œ•üÒ,‚|…©¡–þálˆ…xÿõÌ·°¥ÿûíšgcb†þÚKÿèÿð²ûÌóå±ÖÊ¥DCnÀ¦?ÿí¥ys¤žŸýôÑ………\Z}ÿóÄôÆ Å¶†ÿúåcaÿÚGåâÝÿæ„ÿð²üÌ ÿþùÿê•ÔÆa^}ûÓ3ÿãtž’bRÚ÷ºHtRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœìò`ÓIDATxœ-ëRÂ0F·X FJëÑZŠoц–ˆ™Xmíû¿› ߯=gfg÷ƒÎ]üÔC›rFÖ ë¤(yƒ^ ø¹yÚn¿/rQ9aõÕ÷¥~B_ûÞ¦yî6–𮛘„Ôšøî¯k#ð'IQü½òpÝ œÖY–×µIgÈ£²^OˆÛ¨+º"7›ßé|G¼Ç€6RÞÎÏÆÄ¶bþÓ…1míŸñ_ù.6BÌzX{Ñ1•¦Žm)lÅ”òÓt+ðÙÛ„IEND®B`‚xymon-4.3.30/xymond/wwwfiles/gifs/red-recent.gif0000664000076400007640000000056611070452713022046 0ustar rpmbuildrpmbuildGIF89aà ÿzzÿXXÈÿéUŧÀÀÀz˜Îÿ!ÿ NETSCAPE2.0!ù_,`ðÉ jXÖ„(WpQœC`cœ0®Z@Tñ;У ‡ð…P=z'®P\KX`ø,X@ó8H*_ÑÀë>K%íŽ20‡e2«½« â45Á'ç3GX€ƒ„!ù ,p­·X!ù ,±Ç"!ù ,°µ'#!ù ,й'#!ù ,°µ'#!ù ,±'#!ù ,p­·";xymon-4.3.30/xymond/wwwfiles/gifs/bkg-yellow.gif0000664000076400007640000000104011535462534022066 0ustar rpmbuildrpmbuildGIF89a}Æu          "#$%'()*+- /!0!1#3$4%5%7'8':)=*;+?+>,A-B/D0F0G2I2J4L6N7P7R8T<U<X>Z?\?]A`BbEdFfIiJkKmKoNqNtPvQxTzV|WY[„[…[‰^ˆ`Œ``Ža—e•f’g›hi™k¢lŸm¤n§p«r¨s°s­t´u¶z½{º|Â~ÆΊÜû¤â«ï¨õ§ ß°è¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€s‚ptqronmlkijhgefcdba_`]\^YZ[WXVTUSRQPONMLKJIHGFEDCBA@?>=<;:987654321/0-.,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/bkg-purple.gif0000664000076400007640000000104011535462534022062 0ustar rpmbuildrpmbuildGIF89a}Æu     "#$ %"'#($)%*%+(-)/)0+1-3.4.517183:5;5=6?7>8A:B<D<F>I?G@JCLENEPFRJTKUNXNZN\Q]S`WbWdZf]i]k_mbobqetfvhxlzl|nrq…s„w‰xˆyŒxyŽ•’—„›…™†‡¢ŠŸŒ¤Ž§¨«“­“°“´›¶›º›½Ÿ¢ƯδÜÎûÒ õÎïÑâÖèÕßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€t‚rsqponmlkjihgfedcba_`^\][YZWXVTURSQPONMLKJIHGFEDCBA@?>=<;:987564321/0.-,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/favicon-unknown.ico0000664000076400007640000000706611070452713023147 0ustar rpmbuildrpmbuildh& ¨Ž( @ÿÿÿËýsyåÿf33»¬­B¥½¸Ô݆¶ÅGÚÿÌõÿgšnY^•Œ‘¥íÿÝâå–¡©ÆÔ,Òü†bcåúÿnCD¥°·x…ˆÊÌÏÂî¦ßîláþYÜý»ñÿ•êÿÐýx³Å9×ÿÓîõ…|‚}Z\ŸŸŸ±åóvaeÄÔ}koÌûóýÿ¦ÄÏ……… Æô¥åõÜøÿ¥ÊÖ²ðÿmŒ”tãÿÄóÿèÿ3Óûacžìÿb’žs\aíûÿ¬îÿùþÿÑôý{ƒ„ Ìü„æÿŸž¤?¦À}^aKÚþA A..A./8GG" /;.CC5 +;.8)< !5 B/AB33(< C5 .662C5 . >C"A>11@@F->:75G41@$0CG===1@:78B,#D*CBEG?%%9&'/G=1@6>8B>>:BBüðàÀ€€€€Ààø?( @€ÿÿÿÌý–uwÒçc,,Õ¼º5©ÇCóÿ’¥¯¹ôÿuSV[•¤ÜÝàyûÿ¬ÑÜ+Àæ‹‘ªj­¾bßþ áþÜùþ”ºÈtrz–êÿµ¼¿Áªªm@B7×þÁìËËÎB¼ÚcdËéòrœ¦M°É©¬²òæå}äþ«åôÄÛÝ“„ˆ Ÿ ]óÿ¡üÿÎü•ÐàiŒ•}©¸‹– ßíñ/µÖ´ ¡ÊþÿžÅÓIàÿ ÜþÞÒÒoagíøû·ÆÍqÚõ ÙéµÝè‡}‚uÉàÆï1ðÿŒmomëÿw²Å(ÕÿD¨À›µ¿¦ðÿÐòú†ºË€mrQîÿ“áôa¬Œ–i54»ãc¥¶ÏÕÙŠèÿs¦³œ–›,¬ÍrJK;³Ñ ‹Ž Æô-äþpŠ;èÿÊ··’ÂÒ­ÁÇ|\^Ë¿À¡ãõ}Ûô´ìúƒ……Wàþ~íÿ‘îñòŸ¿Ê­÷ÿ¢Òàž¬´Æôÿ ÒÿÜþ—óÿkáþµÎ×Öÿ€v|¾ÕÜ«Úè­œŸ‰×ëãóøÖêïëàáAÞÿ ëüãÿÿÖÿÿ–‘yÔì`çÿxek¾ýÿÖýÌâé~£±÷ýÿX¯Å‰prsäÿÈöÇìõ‘Õè5Ûÿ¨±¸™¨±¤ÎÛ¿òþìÿIîÿÂêwˆ‹‘•<¹Øb”¡ËüÖÿ=¬ÈrNP'´×Ÿòÿ+Üÿtõÿ’ ¨D²ÍÐøÿƒhkމ‰›£a''uŸ¯Âä“‚µñÿRÜÿk;<Ùðð†¶ÅÂîAÚþ¥Þêw—¥‘©³åúÿÌü#Üÿ8ñÿ~‰Œ©ž¡o™¢ÒäìÇÇÊŠÍíôFöÿ¦öÿjÝú«¨¬çúž¡¦—²¼|_aëüÿyêÿe11HÛÿ‹Ž2²Ò¬ëûiçÿšÔà´úÿUíÿ¥âòw\_ÜÿÖ÷þ.¸Û¦ç÷'ãþËõÿ;Þÿ­ñÿ„åþ³ÁÈÔùÝþÿd™¶èõVçÿßø›¹Å€swÑþ“¸ÄnQUt…‘\àÿtWZ‡km Õú›îÿxÙò¬ßîlGI{kqèòöŒzŽ‚‡§™œ`àé`RjZ£ Ÿ\ª$ø’’¾¾¾¾’œßI `Ôj±œyÝÝyyy¢¢t¡^T4$Xž­^ö¢H•‚888‚•Hᄀ¡¸\Qžjç¢áã´ó×FF׈kÓHytÕUž­¡u•ó‘ååìhø>>Êk´¹H¾^ÕQžj‹¢a×W÷Ì”M»°GB>w´¹Ht\Xjuãw÷äKgcm‰ñ;òG‡‘wó´¹Ht¸$`¡D׳ äÛƤSú1'‘w´¹Ht¡4 .Ú÷³ ³(72ûô‰·~ål‘wó´¹y¡TI#jѳ♠³i|o ® ð/PWW'‘w´H¾^ßÁ¡ák™âs™™ êooqÛƒƒWå'‘wkÁ¡ÀÑÖs«âsss@rR©˜ÖäÉ÷WW'‘ÓHt’$¾›š™â«««ââxþ¤Ü®˜äpK÷Wå'w´•¢¾ª`¾O¦âÞÞ«««{*µÒ‰—ùÙpÉ÷W'wó¹¢¾\0¾Ú¦«ÞÞ…"%¬¤AJ|ÖK¦Wå‘Óy¾Ÿé¾ÚKÞ½½½èÞ)%ýe NRíºK¦W'wÓy¾ 0¾O¦«½Ð½½½½è"æ†e[ AÎ?ƒšåwÓy¾\0¡šs½ŽÐÐÐЄ„èÇ=Y¬[ z¼ØÌ÷Ww¹Ý^¡_׳ЎŽÐÐн„„èL{Íϵzð̦šݸ¹¦ÐŽ<ü33½ÐÐè"–!¯Ü¼gÉš´Hy¥ï¨«Žn ÅV€¶Œ=YϵîJà¦Ñ‚ïC¡Èv½&f}]]ÿÂY*!!A—Öšóát¸ÝëɽbEEEõ²+d@i÷וu^‹¿,KÄ:5}ÂÂÂË{“ ¦‘a¢t¡k÷â333€€€"“™ ¦‘ãu¡‹ÝÈ-Š…è„è…6 vl,ÀÝ‹9y¹FvÉpÉÉvlóy9¡¾§OÚÚO›À¿¾¡9t¾¾¾t9¡ÿÿÿÿÿðÿÿàÿÿþ?üøðàÀÀÀÀÀÀÀÀà?ðøÿüÿÿ€ÿÿÀÿxymon-4.3.30/xymond/wwwfiles/gifs/green.gif0000664000076400007640000000016611070452713021112 0ustar rpmbuildrpmbuildGIF89a¢ÿÿÿÀÀÀIøI«5>€&>Y'8ÿ!ù,@;ºÜz$ÊBëiGèÁ¯{å}0Œ˜¦r,@“E>î|ÔNfž¤¾µŒŒa8dABE”‹p ÈsF]$;xymon-4.3.30/xymond/wwwfiles/gifs/purple.gif0000664000076400007640000001025411070452713021320 0ustar rpmbuildrpmbuildGIF89a€€éÿÿpÿ€€!ÿ NETSCAPE2.0!ù ,!ŒiÀí¾ždq¾jÎ`go“(‘WÀAhJ­¬!°B!ù ,"ŒiÀí¾ždq¾jÎ`go“(‘WÀAhJÛ¹oªÔH!ù ,#ŒiÀí¾ždq¾jÎ`go“(‘WÀAR+›Â+öQ!ù ,#ŒiÀí¾ždq¾jÎ`go“(‘W pšª†»lü)öQ!ù ,$ŒiÀí¾ždq¾jÎ`go“(§‰šk«®lËŸ‚!ù ,%ŒiÀí¾ždq¾jÎ`go“!pZ ”&™®hª†/üÍô¨äG!ù ,&ŒiÀí¾ždq¾jÎ`go§ÂHŠgjžhغ_,Oª»JÊŽ!ù ,(ŒiÀí¾ždq¾jÎ`g#pZ „"XždiZ(û­l{ÉóôÎ4¥ôG!ù ,(ŒiÀí¾ždq¾jÎÀ®Âzc)ޤeªYëNp|¥*Þz­ôF!ù ,)ŒiÀí¾ždq¾j›ÁuÀŠd™è¤®×Æá+ËRk{uí)¾Q!ù ,+ŒiÀí¾ždq>#ì "kÊu€užUšZªNl»™òÙ¼r<ßuä:© !ù ,.ŒiÀí¾ždFLYímYïîM`øŒ$êz¦Š¥,[Êó ÀMSú΃¹ÄC!ù ,-ŒiÀínÄ›,J ƒØ¸YÞ} %ŽOizÚÆ¦ÊžkÛfM« ^¿AË)†ˆ!ù ,-ŒiíïƒTNƒØÛ5èiWžgeªd殣bÐÔ¤áè ßÓ)†ˆ!ù ,-Œi"àÝb±NZßÅyóè}ZÀ”¥Eš&˜ªç¸«8òk<7•ë{ï“)†ˆ!ù ,,ŒiÂàÁb"ÆIíÃYó~ÔX…ähž *h8oÃ>sÛs®«|OR!ù ,.ŒiÂãj.Ê@™…3oÐyV(rXF]š>ÆÃ6nÅÚ[ÛxÎî|æû5DD!ù ,+Œi áj.Ê@›}3‹ÝyV(^€G™'Zë¸/,ÏhmgxÞì¼ " !ù ,-Œi ßj.Ê@©33ÛyBdbÅÏù¥;–/+ÏbmgxÞì¼àã)†ˆ!ù ,,ŒiÂ-#X®IH+»Y¿hž…иM扪*„ï(ÏZm;xÎ켟S!ù ,+ŒiÂÍãr.ÂI›5 ×@žpâ(”a„ &;¾p&ÏNm3x¾Ûý¬" !ù ,,ŒiÂÝár4h•jÇE߃‰£Pš_ªRlÛ¼0ÚY–[Û­lǹnR!ù ,&ŒiÂí®Š8©m0ë}yß&ŽUi6h*¬©k£üÑšM):R!ù ,-Œi íâb¯Êiu`Æýx(ˆãfž!–µ(ÛfUê:t]Âq}Çùì(†‡!ù ,&ŒiâÙb° 0©}YïîU`ÈÌyZc ­¬ã¾1;§õyKÊ~!ù ,(ŒiÀâÁbZ1é}YïîY`ÈÔÙ@㩚(Z¾¯³Îõ{£ù©ôH!ù ,&ŒiÀ ãj.Ê@™…3oÑyV(rXF]hI®O뫌ҙM):R!ù ,&ŒiÀ,áj.Ê@›}3ƒÝyV(^^fž‡©+éª|Òž):R!ù ,'ŒiÀ-ßj.Ê@©33Ûy@ŠPir˜˜©¬‡²±8ÃëÛÔ™Â#!ù ,&ŒiÀ £X®IH+»Y¿Øy`àUY:š6aú–±7kuu;ÊŽ!ù ,#ŒiÀÍãr.ÂI›ÅùÝÐQ_(r$`’i¸vmöR±37Ê!ù ,$ŒiÀÝár4ŠI]ÄùÝÐe_˜q$`’i¸vm žÍKÑŽ‚#!ù ,#ŒiÀíÅrÄYŸ ¹î^a #Ž%xvi¶†ÜØ´”ì(6R!ù ,#ŒiÀí âzTŠÅÄoóæ}@ø‘œ‰¡”Ú]"è¾cü*6R!ù ,"ŒiÀí,ÄzÈPëÌnsæ}!7f¥†}ÍI±Û¥* ÔH!ù , ŒiÀí-Ö›LÒgoËpý]!5N%tι¦jå¾ÊŒ!ù , ŒiÀí¾ždq¾jÎ`go“(‘WÀAhJ­¬©*²Q!þ‹FILE IDENTITY Created or modified by Created by Alchemy Mindworks' GIF Construction Set Professional http://www.mindworkshop.com!þêUNREGISTERED SHAREWARE Assembled with GIF Construction Set: Alchemy Mindworks Inc. Box 500 Beeton, ON L0G 1A0 CANADA. http://www.mindworkshop.com This comment will not appear in files created with a registered version.!ÿ GIFCONtb1.0%C:\FDB\bbtest\purple1.gifC:\FDB\bbtest\purple2.gifC:\FDB\bbtest\purple3.gifC:\FDB\bbtest\purple4.gifC:\FDB\bbtest\purple5.gifC:\FDB\bbtest\purple6.gifC:\FDB\bbtest\purple7.gifC:\FDB\bbtest\purple8.gif C:\FDB\bbtest\purple9.gif C:\FDB\bbtest\purple9a.gif C:\FDB\bbtest\purple9b.gif C:\FDB\bbtest\purple9c.gif C:\FDB\bbtest\purple9d.gifC:\FDB\bbtest\purple9e.gifC:\FDB\bbtest\purple9f.gifC:\FDB\bbtest\purple9g.gifC:\FDB\bbtest\purple9h.gifC:\FDB\bbtest\purple9i.gifC:\FDB\bbtest\purple9j.gifC:\FDB\bbtest\purple9k.gifC:\FDB\bbtest\purple9l.gifC:\FDB\bbtest\purple9m.gifC:\FDB\bbtest\purple9n.gifC:\FDB\bbtest\purple9o.gifC:\FDB\bbtest\purple9p.gifC:\FDB\bbtest\purple9q.gifC:\FDB\bbtest\purple9r.gifC:\FDB\bbtest\purple9u.gifC:\FDB\bbtest\purple9v.gifC:\FDB\bbtest\purple9w.gifC:\FDB\bbtest\purple9x.gif C:\FDB\bbtest\purple9y.gif!C:\FDB\bbtest\purple9z.gif"C:\FDB\bbtest\purple9zz.gif#C:\FDB\bbtest\purple9zzz.gif$C:\FDB\bbtest\purple9zzzz.gif%C:\FDB\bbtest\purple9zzzzz.gif;xymon-4.3.30/xymond/wwwfiles/gifs/red.gif0000664000076400007640000000305311070452713020562 0ustar rpmbuildrpmbuildGIF89aƒ€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿ!ÿ NETSCAPE2.0!ù ,<ÈI«LI†ÍoXÆuáTˆU¥¹N›ú(@†kg×ò·k<¬vêb-¥åñ5m)&m$ó© ‹¶!ù ,;ÈI« 8[ÈZGu^ ™d•N뉊œˆ¹/YΟ)َǰ ˜ÒWEÝ.TÉNMÖ Û€~›ì$!ù ,7ÈI« 8[šõN H#há„r¥ ¬£p,Ž=Ùö»Ê²–Î3sÕ(¿œ µ6·4è™Z#!ù ,:ÈI« 8Û™{ØŽÕ—$Ô)r¦ œ(&i0,Ê÷T³søÚ½^k§Ém¸•K¢òÍž«hÉ“¼x6XK!ù ,8ÈI« 8Û™{Øð‰âÈ…•&¡I"µë¨µ´«¢@}ƓΗŸì6‚å\¥“I™úÈ’.ÚÙX-!ù ,2ÈI« 8Û™{ØR£¨™ØužI› æä¾1J3÷ÙwÎï%Ýí·CH•çXYnž–!ù ,+ÈI« 8Û™{ØžW…!×Q"pŽšÚ&‰´®°Ü®è»-Ob¬ˆ´±íŠÈ!ù ,(ÈI« 8Û™{ØžW…!G–€hjiG©ª»+&Ÿ1ÎÖèHn7p(‰!ù ,$ÈI« 8Û™{ØžW…!G–À‰ªbÊjîûůɎ*HnÊÿ’!ù ,=$@«¥3iºÇ›6yŸX™'m–y²\ê¢)PŠÛg×+ÜÅ/_í†Û e,Z Ö» T®&égrMkÕ‹Vˆ!þ‹FILE IDENTITY Created or modified by Created by Alchemy Mindworks' GIF Construction Set Professional http://www.mindworkshop.com!þêUNREGISTERED SHAREWARE Assembled with GIF Construction Set: Alchemy Mindworks Inc. Box 500 Beeton, ON L0G 1A0 CANADA. http://www.mindworkshop.com This comment will not appear in files created with a registered version.!ÿ GIFCONtb1.0 C:\FDB\bbtest\1a.gifC:\FDB\bbtest\2a.gifC:\FDB\bbtest\3a.gifC:\FDB\bbtest\4a.gifC:\FDB\bbtest\5a.gifC:\FDB\bbtest\6a.gifC:\FDB\bbtest\7a.gifC:\FDB\bbtest\8a.gif C:\FDB\bbtest\9a.gif C:\FDB\bbtest\red.gif;xymon-4.3.30/xymond/wwwfiles/gifs/bkg-blue.gif0000664000076400007640000000104011535462534021502 0ustar rpmbuildrpmbuildGIF89a}Æu     "#$'%()*+-/0134578:;?=>ABDFGIJLNPRTUZX\]`bdfikmq ov t x z |  „ … ˆ ‰ Œ Ž ’— • › ™ Ÿ¤ ¢¨ §«­°´¶º½ÂÆÎÜ û õï'è+â.ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,}}€t‚srqponmlkjihgfedbc`a_^\]Z[YWXVUTSRQPONMKLIJHGFEDCBA@>?=<;:987654321.0/-,+*)('&%$##"!  û;xymon-4.3.30/xymond/wwwfiles/gifs/README0000664000076400007640000000206511070452713020203 0ustar rpmbuildrpmbuildThese GIF's were collected from various GPL- and public-domain archives around the Internet. To the best of my knowledge, all of them can be distributed freely. The source of these files are as follows: arrow.gif: From the "dots" collection on www.deadcat.net. (GPL) bkg-*.gif: From the Big Sister "skins/bigbro13/ collection. (No copyright/author notice, assumed public domain) green.gif: From the Big Sister "skins/bigbro13/ collection. (No copyright/author notice, assumed public domain) red,yellow,blue,purple,clear: From the deadcat "animated-bb-icons" collection (GPL) {red,yellow,purple,blue}-ack.gif: From the deadcat altset02 "green.gif" modified with colors. (GPL) {red,yellow,purple,green,blue,clear}-recent.gif: From the deadcat "smile" set. (GPL) unknown.gif, unknown-recent.gif: From http://www.brindilles.net/lune/themes/default/smilies/question.png zoom.gif: From Cacti 0.8.6c favicon*.gif: By "Paul D. Backer" 21. apr.2005, based on the *-recent.gif files. Henrik Storner 2005-01-04 - 2005-02-24 - 2005-04-24 xymon-4.3.30/xymond/xymond_sample.80000664000076400007640000000152413534041733017476 0ustar rpmbuildrpmbuild.TH XYMOND_SAMPLE 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_sample \- example of a xymond worker module .SH SYNOPSIS .B "xymond_channel --channel=status xymond_sample [options]" .SH DESCRIPTION xymond_sample is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives messages from xymond via stdin, and simply displays these on stdout. It can be used with all types of xymond channels. xymond_sample is not designed to actually run, except as a demonstration. The purpose of this tool is to show how xymond worker modules can be implemented to handle different tasks that need to hook into the xymond processing. .SH OPTIONS .IP "--timeout=N" Read messages with a timeout of N seconds. .IP "--debug" Enable debugging output. .SH "SEE ALSO" xymond_channel(8), xymond(8), xymon(7) xymon-4.3.30/xymond/xymond_alert.80000664000076400007640000001216013534041733017322 0ustar rpmbuildrpmbuild.TH XYMOND_ALERT 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_alert \- xymond worker module for sending out alerts .SH SYNOPSIS .B "xymond_channel \-\-channel=page xymond_alert [options]" .SH DESCRIPTION xymond_alert is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. It receives xymond page- and ack-messages from the "page" channel via stdin, and uses these to send out alerts about failed and recovered hosts and services. The operation of this module is controlled by the .I alerts.cfg(5) file. This file holds the definition of rules and recipients, that determine who gets alerts, how often, for what servers etc. .SH OPTIONS .IP "\-\-config=FILENAME" Sets the filename for the .I alerts.cfg file. The default value is "etc/alerts.cfg" below the Xymon server directory. .IP "\-\-dump\-config" Dumps the configuration after parsing it. May be useful to track down problems with configuration file errors. .IP "\-\-checkpoint\-file=FILENAME" File where the current state of the xymond_alert module is saved. When starting up, xymond_alert will also read this file to restore the previous state. .IP "\-\-checkpoint\-interval=N" Defines how often (in seconds) the checkpoint-file is saved. .IP "\-\-cfid" If this option is present, alert messages will include a line with "cfid:N" where N is the linenumber in the alerts.cfg file that caused this message to be sent. This can be useful to track down problems with duplicate alerts. .IP "\-\-test HOST SERVICE [options] Shows which alert rules matches the given HOST/SERVICE combination. Useful to debug configuration problems, and see what rules are used for an alert. The possible options are: .br .BI "\-\-color=COLORNAME" The COLORNAME parameter is the color of the alert: red, yellow or purple. .br .BI "\-\-duration=MINUTES" The MINUTES parameter is the duration of the alert in minutes. .br .BI "\-\-group=GROUPNAME" The GROUPNAME parameter is a groupid string from the analysis.cfg file. .br .BI "\-\-time=TIMESTRING" The TIMESTRING parameter is the time-of-day for the alert, expressed as an absolute time in the epoch format (seconds since Jan 1 1970). This is easily obtained with the GNU date utility using the "+%s" output format. .IP "\-\-trace=FILENAME" Send trace output to FILENAME, This allows for more detailed analysis of how alerts trigger, without having the full debugging enabled. .IP "\-\-debug" Enable debugging output. .SH HOW XYMON DECIDES WHEN TO SEND ALERTS The xymond_alert module is responsible for sending out all alerts. When a status first goes to one of the ALERTCOLORS, xymond_alert is notified of this change. It notes that the status is now in an alert state, and records the \fBtimestamp\fR when this event started, and adds the alert to the list statuses that may potentially trigger one or more alert messages. This list is then matched against the alerts.cfg configuration. This happens at least once a minute, but may happen more often. E.g. when status first goes into an alert state, this will always trigger the matching to happen. When scanning the configuration, xymond_alert looks at all of the configuration rules. It also checks the DURATION setting against how long time has elapsed since the event started - i.e. against the timestamp logged when xymond_alert first heard of this event. When an alert recipient is found, the alert is sent and it is recorded when this recipient is due for his next alert message, based on the REPEAT setting defined for this recipient. The next time xymond_alert scans the configuration for what alerts to send, it will still find this recipient because all of the configuration rules are fulfilled, but an alert message will not be generated until the repeat interval has elapsed. It can happen that a status first goes yellow and triggers an alert, and later it goes red - e.g. a disk filling up. In that case, xymond_alert clears the internal timer for when the next (repeat) alert is due for all recipients. You generally want to be told when something that has been in a warning state becomes critical, so in that case the REPEAT setting is ignored and the alert is sent. This only happens the first time such a change occurs - if the status switches between yellow and red multiple times, only the first transition from yellow->red causes this override. When an status recovers, a recovery message may be sent - depending on the configuration - and then xymond_alert forgets everything about this status. So the next time it goes into an alert state, the entire process starts all over again. .SH ENVIRONMENT .IP MAIL The first part of a command line used to send out an e-mail with a subject, typically set to "/usr/bin/mail \-s" . xymond_alert will add the subject and the mail recipients to form the command line used for sending out email alerts. .IP MAILC The first part of a command line used to send out an e-mail without a subject. Typically this will be "/usr/bin/mail". xymond_alert will add the mail recipients to form the command line used for sending out email alerts. .SH FILES .IP "~xymon/server/etc/alerts.cfg" .SH "SEE ALSO" alerts.cfg(5), xymond(8), xymond_channel(8), xymon(7) xymon-4.3.30/xymond/trimhistory.80000664000076400007640000000612113534041733017212 0ustar rpmbuildrpmbuild.TH TRIMHISTORY 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME trimhistory \- Remove old Xymon history-log entries .SH SYNOPSIS .B "trimhistory \-\-cutoff=TIME [options]" .SH DESCRIPTION The \fBtrimhistory\fR tool is used to purge old entries from the Xymon history logs. These logfiles accumulate information about all status changes that have occurred for any given service, host, or the entire Xymon system, and is used to generate the event- and history-log webpages. Purging old entries can be done while Xymon is running, since the tool takes care not to commit updates to a file if it changes mid-way through the operation. In that case, the update is aborted and the existing logfile is left untouched. Optionally, this tool will also remove logfiles from hosts that are no longer defined in the Xymon .I hosts.cfg(5) file. As an extension, even logfiles from services can be removed, if the service no longer has a valid status-report logged in the current Xymon status. .SH OPTIONS .IP "\-\-cutoff=TIME" This defines the cutoff-time when processing the history logs. Entries dated before this time are discarded. TIME is specified as the number of seconds since the beginning of the Epoch. This is easily generated by the GNU .I date(1) utility, e.g. the following command will trim history logs of all entries prior to Oct. 1st 2004: .br .sp trimhistory \-\-cutoff=`date +%s \-\-date="1 Oct 2004"` .IP "\-\-outdir=DIRECTORY" Normally, files in the XYMONHISTDIR directory are replaced. This option causes trimhistory to save the shortened history logfiles to another directory, so you can verify that the operation works as intended. The output directory must exist. .IP \-\-drop Causes trimhistory to delete files from hosts that are not listed in the .I hosts.cfg(5) file. .IP \-\-dropsvcs Causes trimhistory to delete files from services that are not currently tracked by Xymon. Normally these files would be left untouched if only the host exists. .IP \-\-droplogs Process the XYMONHISTLOGS directory also, and delete status-logs from events prior to the cut-off time. Note that this can dramatically increase the processing time, since there are often lots and lots of files to process. .IP "\-\-progress[=N]" This will cause trimhistory to output a status line for every N history logs or status-log collections it processes, to indicate how far it has progressed. The default setting for N is 100. .IP "\-\-env=FILENAME" Loads the environment from FILENAME before executing trimhistory. .IP \-\-debug Enable debugging output. .SH FILES .IP "$XYMONHISTDIR/allevents" The eventlog of all events that have happened in Xymon. .IP "$XYMONHISTDIR/HOSTNAME" The per-host eventlogs. .IP "$XYMONHISTDIR/HOSTNAME.SERVICE" The per-service eventlogs. .IP "$XYMONHISTLOGS/*/*" The historical status-logs. .SH "ENVIRONMENT VARIABLES" .IP XYMONHISTDIR The directory holding all history logs. .IP XYMONHISTLOGS The top-level directory for the historical status-log collections. .IP HOSTSCFG The location of the hosts.cfg file, holding the list of currently known hosts in Xymon. .SH "SEE ALSO" xymon(7), hosts.cfg(5) xymon-4.3.30/xymond/do_alert.h0000664000076400007640000000234111615341300016455 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DO_ALERT_H__ #define __DO_ALERT_H__ #include #include extern int include_configid; extern int testonly; extern time_t next_alert(activealerts_t *alert); extern void cleanup_alert(activealerts_t *alert); extern void clear_interval(activealerts_t *alert); extern void start_alerts(void); extern void send_alert(activealerts_t *alert, FILE *logfd); extern void finish_alerts(void); extern void load_state(char *filename, char *statusbuf); extern void save_state(char *filename); #endif xymon-4.3.30/xymond/do_alert.c0000664000076400007640000006120613033575046016471 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This is part of the xymond_alert worker module. */ /* This module implements the standard xymond alerting function. It loads */ /* the alert configuration from alerts.cfg, and incoming alerts are */ /* then sent according to the rules defined. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: do_alert.c 7999 2017-01-06 02:00:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" /* * This is the dynamic info stored to keep track of active alerts. We * need to keep track of when the next alert is due for each recipient, * and this goes on a host+test+recipient basis. */ typedef struct repeat_t { char *recipid; /* Essentially hostname|testname|method|address */ time_t nextalert; struct repeat_t *next; } repeat_t; static repeat_t *rpthead = NULL; int include_configid = 0; /* Whether to include the configuration file linenumber in alerts */ int testonly = 0; /* Test mode, don't actually send out alerts */ int max_alertmsg_scripts = 0; /* Max message size to pass to SCRIPT via env variable */ /* * This generates a unique ID for an event. * The ID is an MD5 hash of the hostname, testname and the * event start-time. */ static char *make_alertid(char *hostname, char *testname, time_t eventstart) { static char result[33]; unsigned char id[16]; char *key; void *md5handle; int i, j; key = (char *)malloc(strlen(hostname)+strlen(testname)+15); sprintf(key, "%s|%s|%d", hostname, testname, (int)eventstart); md5handle = (void *)malloc(myMD5_Size()); myMD5_Init(md5handle); myMD5_Update(md5handle, key, strlen(key)); myMD5_Final(id, md5handle); for (i=0, j=0; (i < 16); i++, j+=2) sprintf(result+j, "%02x", id[i]); result[32] = '\0'; return result; } static int servicecode(char *testname) { /* * The SVCCODES environment is a list of servicecodes: * SVCCODES="disk:100,cpu:200,procs:300,msgs:400,conn:500,http:600,dns:800,smtp:725,telnet:721" * This routine returns the number associated with the service. */ static char *svccodes = NULL; char *tname; char *p; if (svccodes == NULL) { p = xgetenv("SVCCODES"); if (p == NULL) p = "none"; svccodes = (char *)malloc(strlen(p)+2); sprintf(svccodes, ",%s", p); } tname = (char *)malloc(strlen(testname)+3); sprintf(tname, ",%s:", testname); p = strstr(svccodes, tname); xfree(tname); if (p) { p = strchr(p, ':'); return atoi(p+1); } return 0; } void start_alerts(void) { /* No special pre-alert setup needed */ return; } static repeat_t *find_repeatinfo(activealerts_t *alert, recip_t *recip, int create) { char *id, *method = "unknown"; repeat_t *walk; if (recip->method == M_IGNORE) return NULL; switch (recip->method) { case M_MAIL: method = "mail"; break; case M_SCRIPT: method = "script"; break; case M_IGNORE: method = "ignore"; break; } id = (char *) malloc(strlen(alert->hostname) + strlen(alert->testname) + strlen(method) + strlen(recip->recipient) + 4); sprintf(id, "%s|%s|%s|%s", alert->hostname, alert->testname, method, recip->recipient); for (walk = rpthead; (walk && strcmp(walk->recipid, id)); walk = walk->next); if ((walk == NULL) && create) { walk = (repeat_t *)malloc(sizeof(repeat_t)); walk->recipid = id; walk->nextalert = 0; walk->next = rpthead; rpthead = walk; } else xfree(id); return walk; } static char *message_recipient(char *reciptext, char *hostname, char *svcname, char *colorname) { static char *result = NULL; char *inpos, *p; if (result) xfree(result); result = (char *)malloc(strlen(reciptext) + strlen(hostname) + strlen(svcname) + strlen(colorname) + 1); *result = '\0'; inpos = reciptext; do { p = strchr(inpos, '&'); if (p) { *p = '\0'; strcat(result, inpos); *p = '&'; p++; if (strncasecmp(p, "HOST&", 5) == 0) { strcat(result, hostname); inpos = p + 5; } else if (strncasecmp(p, "SERVICE&", 8) == 0) { strcat(result, svcname); inpos = p + 8; } else if (strncasecmp(p, "COLOR&", 6) == 0) { strcat(result, colorname); inpos = p + 6; } else { strcat(result, "&"); inpos = p; } } else { strcat(result, inpos); inpos = NULL; } } while (inpos && *inpos); return result; } static char *message_subject(activealerts_t *alert, recip_t *recip) { static char subj[250]; static char *sevtxt[COL_COUNT] = { "is GREEN", "has no data (CLEAR)", "is disabled (BLUE)", "stopped reporting (PURPLE)", "warning (YELLOW)", "CRITICAL (RED)" }; char *sev = ""; char *subjfmt = NULL; /* Only subjects on ALERTFORM_TEXT and ALERTFORM_PLAIN messages */ if ((recip->format != ALERTFORM_TEXT) && (recip->format != ALERTFORM_PLAIN)) return NULL; MEMDEFINE(subj); if ((alert->color >= 0) && (alert->color < COL_COUNT)) sev = sevtxt[alert->color]; switch (alert->state) { case A_PAGING: case A_ACKED: subjfmt = (include_configid ? "Xymon [%d] %s:%s %s [cfid:%d]" : "Xymon [%d] %s:%s %s"); snprintf(subj, sizeof(subj), subjfmt, alert->cookie, alert->hostname, alert->testname, sev, recip->cfid); break; case A_NOTIFY: subjfmt = (include_configid ? "Xymon %s:%s NOTICE [cfid:%d]" : "Xymon %s:%s NOTICE"); snprintf(subj, sizeof(subj), subjfmt, alert->hostname, alert->testname, recip->cfid); break; case A_RECOVERED: subjfmt = (include_configid ? "Xymon %s:%s recovered [cfid:%d]" : "Xymon %s:%s recovered"); snprintf(subj, sizeof(subj), subjfmt, alert->hostname, alert->testname, recip->cfid); break; case A_DISABLED: subjfmt = (include_configid ? "Xymon %s:%s disabled [cfid:%d]" : "Xymon %s:%s disabled"); snprintf(subj, sizeof(subj), subjfmt, alert->hostname, alert->testname, recip->cfid); break; case A_NORECIP: case A_DEAD: /* Cannot happen */ break; } *(subj + sizeof(subj) - 1) = '\0'; MEMUNDEFINE(subj); return subj; } static char *message_text(activealerts_t *alert, recip_t *recip) { static strbuffer_t *buf = NULL; char *eoln, *bom, *p; char info[4096]; MEMDEFINE(info); if (!buf) buf = newstrbuffer(0); else clearstrbuffer(buf); if (alert->state == A_NOTIFY) { sprintf(info, "%s:%s INFO\n", alert->hostname, alert->testname); addtobuffer(buf, info); addtobuffer(buf, alert->pagemessage); MEMUNDEFINE(info); return STRBUF(buf); } switch (recip->format) { case ALERTFORM_TEXT: case ALERTFORM_PLAIN: bom = msg_data(alert->pagemessage, 1); eoln = strchr(bom, '\n'); if (eoln) *eoln = '\0'; /* If there's a "<-- flags:.... -->" then remove it from the message */ if ((p = strstr(bom, ""); if (p) addtobuffer(buf, p+3); /* And if there is more than line 1, add it as well */ if (eoln) { *eoln = '\n'; addtobuffer(buf, eoln); } } else { if (eoln) *eoln = '\n'; addtobuffer(buf, bom); } addtobuffer(buf, "\n"); if (recip->format == ALERTFORM_TEXT) { sprintf(info, "See %s%s\n", xgetenv("XYMONWEBHOST"), hostsvcurl(alert->hostname, alert->testname, 0)); addtobuffer(buf, info); } MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_SMS: /* * Send a report containing a brief alert * and any lines that begin with a "&COLOR" */ switch (alert->state) { case A_PAGING: case A_ACKED: sprintf(info, "%s:%s %s [%d]", alert->hostname, alert->testname, colorname(alert->color), alert->cookie); break; case A_RECOVERED: sprintf(info, "%s:%s RECOVERED", alert->hostname, alert->testname); break; case A_DISABLED: sprintf(info, "%s:%s DISABLED", alert->hostname, alert->testname); break; case A_NOTIFY: sprintf(info, "%s:%s NOTICE", alert->hostname, alert->testname); break; case A_NORECIP: case A_DEAD: break; } addtobuffer(buf, info); bom = msg_data(alert->pagemessage, 1); eoln = strchr(bom, '\n'); if (eoln) { bom = eoln; while ((bom = strstr(bom, "\n&")) != NULL) { eoln = strchr(bom+1, '\n'); if (eoln) *eoln = '\0'; if ((strncmp(bom+1, "&red", 4) == 0) || (strncmp(bom+1, "&yellow", 7) == 0)) addtobuffer(buf, bom); if (eoln) *eoln = '\n'; bom = (eoln ? eoln+1 : ""); } } MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_SCRIPT: sprintf(info, "%s:%s %s [%d]\n", alert->hostname, alert->testname, colorname(alert->color), alert->cookie); addtobuffer(buf, info); addtobuffer(buf, msg_data(alert->pagemessage, 0)); addtobuffer(buf, "\n"); sprintf(info, "See %s%s\n", xgetenv("XYMONWEBHOST"), hostsvcurl(alert->hostname, alert->testname, 0)); addtobuffer(buf, info); MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_PAGER: case ALERTFORM_NONE: MEMUNDEFINE(info); return ""; } MEMUNDEFINE(info); return alert->pagemessage; } void send_alert(activealerts_t *alert, FILE *logfd) { recip_t *recip; static char *bbalphamsg; int first = 1; int alertcount = 0; time_t now = getcurrenttime(NULL); /* A_PAGING, A_NORECIP, A_ACKED, A_RECOVERED, A_DISABLED, A_NOTIFY, A_DEAD */ char *alerttxt[A_DEAD+1] = { "Paging", "Norecip", "Acked", "Recovered", "Disabled", "Notify", "Dead" }; dbgprintf("send_alert %s:%s state %d\n", alert->hostname, alert->testname, (int)alert->state); traceprintf("send_alert %s:%s state %s\n", alert->hostname, alert->testname, alerttxt[alert->state]); if (bbalphamsg == NULL) { int len; len = strlen("BBALPHAMSG="); max_alertmsg_scripts = atoi(xgetenv("MAXMSG_ALERTSCRIPT")) + len; bbalphamsg = (char *)calloc(1, max_alertmsg_scripts + 1); } stoprulefound = 0; while (!stoprulefound && ((recip = next_recipient(alert, &first, NULL, NULL)) != NULL)) { /* If this is an "UNMATCHED" rule, ignore it if we have already sent out some alert */ if (recip->unmatchedonly && (alertcount != 0)) { traceprintf("Recipient '%s' dropped, not unmatched (count=%d)\n", recip->recipient, alertcount); continue; } if (recip->noalerts && ((alert->state == A_PAGING) || (alert->state == A_RECOVERED) || (alert->state == A_DISABLED))) { traceprintf("Recipient '%s' dropped (NOALERT)\n", recip->recipient); continue; } if (recip->method == M_IGNORE) { traceprintf("IGNORE rule found\n"); continue; } if (alert->state == A_PAGING) { repeat_t *rpt = NULL; /* * This runs in a child-process context, so the record we * might create here is NOT used later on. */ rpt = find_repeatinfo(alert, recip, 1); if (!rpt) continue; /* Happens for e.g. M_IGNORE recipients */ /* * Update alertcount here, because we don't want to hit an UNMATCHED * rule when there is actually an alert active - it is just suppressed * for this run due to the REPEAT setting. */ alertcount++; dbgprintf(" repeat %s at %d\n", rpt->recipid, rpt->nextalert); if (rpt->nextalert > now) { traceprintf("Recipient '%s' dropped, next alert due at %ld > %ld\n", rpt->recipid, (long)rpt->nextalert, (long)now); continue; } } else if ((alert->state == A_RECOVERED) || (alert->state == A_DISABLED)) { /* RECOVERED messages require that we've sent out an alert before */ repeat_t *rpt = NULL; rpt = find_repeatinfo(alert, recip, 0); if (!rpt) continue; alertcount++; } dbgprintf(" Alert for %s:%s to %s\n", alert->hostname, alert->testname, recip->recipient); switch (recip->method) { case M_IGNORE: break; case M_MAIL: { char cmd[32768]; char *mailsubj; char *mailrecip; FILE *mailpipe; MEMDEFINE(cmd); mailsubj = message_subject(alert, recip); mailrecip = message_recipient(recip->recipient, alert->hostname, alert->testname, colorname(alert->color)); if (mailsubj) { if (xgetenv("MAIL")) sprintf(cmd, "%s \"%s\" ", xgetenv("MAIL"), mailsubj); else if (xgetenv("MAILC")) sprintf(cmd, "%s -s \"%s\" ", xgetenv("MAILC"), mailsubj); else sprintf(cmd, "mail -s \"%s\" ", mailsubj); } else { if (xgetenv("MAILC")) sprintf(cmd, "%s ", xgetenv("MAILC")); else sprintf(cmd, "mail "); } strcat(cmd, mailrecip); traceprintf("Mail alert with command '%s'\n", cmd); if (testonly) { MEMUNDEFINE(cmd); break; } mailpipe = popen(cmd, "w"); if (mailpipe) { fprintf(mailpipe, "%s", message_text(alert, recip)); pclose(mailpipe); if (logfd) { init_timestamp(); fprintf(logfd, "%s %s.%s (%s) %s[%d] %ld %d", timestamp, alert->hostname, alert->testname, alert->ip, mailrecip, recip->cfid, (long)now, servicecode(alert->testname)); if ((alert->state == A_RECOVERED) || (alert->state == A_DISABLED)) { fprintf(logfd, " %ld\n", (long)(now - alert->eventstart)); } else { fprintf(logfd, "\n"); } fflush(logfd); } } else { errprintf("ERROR: Cannot open command pipe for '%s' - alert lost!\n", cmd); traceprintf("Mail pipe failed - alert lost\n"); } MEMUNDEFINE(cmd); } break; case M_SCRIPT: { pid_t scriptpid; char *scriptrecip; traceprintf("Script alert with command '%s' and recipient %s\n", recip->scriptname, recip->recipient); if (testonly) break; scriptrecip = message_recipient(recip->recipient, alert->hostname, alert->testname, colorname(alert->color)); scriptpid = fork(); if (scriptpid == 0) { /* Setup all of the environment for a paging script */ void *hinfo; char *p; int ip1=0, ip2=0, ip3=0, ip4=0; char *ackcode, *rcpt, *bbhostname, *bbhostsvc, *bbhostsvccommas, *bbnumeric, *machip, *bbsvcname, *bbsvcnum, *bbcolorlevel, *recovered, *downsecs, *eventtstamp, *downsecsmsg, *cfidtxt; char *alertid, *alertidenv; int msglen; cfidtxt = (char *)malloc(strlen("CFID=") + 10); sprintf(cfidtxt, "CFID=%d", recip->cfid); putenv(cfidtxt); p = message_text(alert, recip); if (debug) { msglen = strlen(p); if (msglen > (max_alertmsg_scripts - strlen("BBALPHAMSG="))) { errprintf("Truncated large alert message from %d bytes; consider increasing MAXMSG_ALERTSCRIPT above %d\n", msglen, atoi(xgetenv("MAXMSG_ALERTSCRIPT"))); } } snprintf(bbalphamsg, max_alertmsg_scripts, "BBALPHAMSG=%s", p); putenv(bbalphamsg); ackcode = (char *)malloc(strlen("ACKCODE=") + 10); sprintf(ackcode, "ACKCODE=%d", alert->cookie); putenv(ackcode); rcpt = (char *)malloc(strlen("RCPT=") + strlen(scriptrecip) + 1); sprintf(rcpt, "RCPT=%s", scriptrecip); putenv(rcpt); bbhostname = (char *)malloc(strlen("BBHOSTNAME=") + strlen(alert->hostname) + 1); sprintf(bbhostname, "BBHOSTNAME=%s", alert->hostname); putenv(bbhostname); bbhostsvc = (char *)malloc(strlen("BBHOSTSVC=") + strlen(alert->hostname) + 1 + strlen(alert->testname) + 1); sprintf(bbhostsvc, "BBHOSTSVC=%s.%s", alert->hostname, alert->testname); putenv(bbhostsvc); bbhostsvccommas = (char *)malloc(strlen("BBHOSTSVCCOMMAS=") + strlen(alert->hostname) + 1 + strlen(alert->testname) + 1); sprintf(bbhostsvccommas, "BBHOSTSVCCOMMAS=%s.%s", commafy(alert->hostname), alert->testname); putenv(bbhostsvccommas); bbnumeric = (char *)malloc(strlen("BBNUMERIC=") + 22 + 1); p = bbnumeric; p += sprintf(p, "BBNUMERIC="); p += sprintf(p, "%03d", servicecode(alert->testname)); sscanf(alert->ip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4); p += sprintf(p, "%03d%03d%03d%03d", ip1, ip2, ip3, ip4); p += sprintf(p, "%d", alert->cookie); putenv(bbnumeric); machip = (char *)malloc(strlen("MACHIP=") + 13); sprintf(machip, "MACHIP=%03d%03d%03d%03d", ip1, ip2, ip3, ip4); putenv(machip); bbsvcname = (char *)malloc(strlen("BBSVCNAME=") + strlen(alert->testname) + 1); sprintf(bbsvcname, "BBSVCNAME=%s", alert->testname); putenv(bbsvcname); bbsvcnum = (char *)malloc(strlen("BBSVCNUM=") + 10); sprintf(bbsvcnum, "BBSVCNUM=%d", servicecode(alert->testname)); putenv(bbsvcnum); bbcolorlevel = (char *)malloc(strlen("BBCOLORLEVEL=") + strlen(colorname(alert->color)) + 1); sprintf(bbcolorlevel, "BBCOLORLEVEL=%s", colorname(alert->color)); putenv(bbcolorlevel); recovered = (char *)malloc(strlen("RECOVERED=") + 2); switch (alert->state) { case A_RECOVERED: strcpy(recovered, "RECOVERED=1"); break; case A_DISABLED: strcpy(recovered, "RECOVERED=2"); break; default: strcpy(recovered, "RECOVERED=0"); break; } putenv(recovered); downsecs = (char *)malloc(strlen("DOWNSECS=") + 20); sprintf(downsecs, "DOWNSECS=%ld", (long)(getcurrenttime(NULL) - alert->eventstart)); putenv(downsecs); eventtstamp = (char *)malloc(strlen("EVENTSTART=") + 20); sprintf(eventtstamp, "EVENTSTART=%ld", (long)alert->eventstart); putenv(eventtstamp); if ((alert->state == A_RECOVERED) || (alert->state == A_DISABLED)) { downsecsmsg = (char *)malloc(strlen("DOWNSECSMSG=Event duration :") + 20); sprintf(downsecsmsg, "DOWNSECSMSG=Event duration : %ld", (long)(getcurrenttime(NULL) - alert->eventstart)); } else { downsecsmsg = strdup("DOWNSECSMSG="); } putenv(downsecsmsg); alertid = make_alertid(alert->hostname, alert->testname, alert->eventstart); alertidenv = (char *)malloc(strlen("ALERTID=") + strlen(alertid) + 10); sprintf(alertidenv, "ALERTID=%s", alertid); putenv(alertidenv); hinfo = hostinfo(alert->hostname); if (hinfo) { enum xmh_item_t walk; char *itm, *id, *bbhenv; for (walk = 0; (walk < XMH_LAST); walk++) { itm = xmh_item(hinfo, walk); id = xmh_item_id(walk); if (itm && id) { bbhenv = (char *)malloc(strlen(id) + strlen(itm) + 2); sprintf(bbhenv, "%s=%s", id, itm); putenv(bbhenv); } } } /* The child starts the script */ execlp(recip->scriptname, recip->scriptname, NULL); errprintf("Could not launch paging script %s: %s\n", recip->scriptname, strerror(errno)); exit(0); } else if (scriptpid > 0) { /* Parent waits for child to complete */ int childstat; wait(&childstat); if (WIFEXITED(childstat) && (WEXITSTATUS(childstat) != 0)) { errprintf("Paging script %s terminated with status %d\n", recip->scriptname, WEXITSTATUS(childstat)); } else if (WIFSIGNALED(childstat)) { errprintf("Paging script %s terminated by signal %d\n", recip->scriptname, WTERMSIG(childstat)); } if (logfd) { init_timestamp(); fprintf(logfd, "%s %s.%s (%s) %s %ld %d", timestamp, alert->hostname, alert->testname, alert->ip, scriptrecip, (long)now, servicecode(alert->testname)); if ((alert->state == A_RECOVERED) || (alert->state == A_DISABLED)) { fprintf(logfd, " %ld\n", (long)(now - alert->eventstart)); } else { fprintf(logfd, "\n"); } fflush(logfd); } } else { errprintf("ERROR: Fork failed to launch script '%s' - alert lost\n", recip->scriptname); traceprintf("Script fork failed - alert lost\n"); } } break; } } } void finish_alerts(void) { /* No special post-alert setup needed */ return; } time_t next_alert(activealerts_t *alert) { time_t now = getcurrenttime(NULL); int first = 1; int found = 0; time_t nexttime = now+(30*86400); /* 30 days from now */ recip_t *recip; repeat_t *rpt; time_t r_next = -1; void *hinfo = hostinfo(alert->hostname); stoprulefound = 0; while (!stoprulefound && ((recip = next_recipient(alert, &first, NULL, &r_next)) != NULL)) { found = 1; if (recip->criteria && recip->criteria->timespec && !timematch(xmh_item(hinfo, XMH_HOLIDAYS), recip->criteria->timespec)) { /* Recipient not active due to time-restrictions. */ if ((r_next != -1) && (r_next < nexttime)) nexttime = r_next; } else { /* * This runs in the parent xymond_alert process, so we must create * a repeat-record here - or all alerts will get repeated every minute. * * NB: Even though we say "create", find_repeatinfo() will return NULL * for ignored alerts. */ rpt = find_repeatinfo(alert, recip, 1); if (rpt) { if (rpt->nextalert <= now) rpt->nextalert = (now + recip->interval); if (rpt->nextalert < nexttime) nexttime = rpt->nextalert; } else if (r_next != -1) { if (r_next < nexttime) nexttime = r_next; } else { /* * This can happen, e.g. if we get an alert, but the minimum * DURATION has not been met. * This simply means we dropped the alert -for now - for some * reason, so it should be retried again right away. Put in a * 1 minute delay to prevent run-away alerts from flooding us. */ if ((now + 60) < nexttime) nexttime = now + 60; } } } if (r_next != -1) { /* * Waiting for a minimum duration to trigger */ if (r_next < nexttime) nexttime = r_next; } else if (!found) { /* * There IS a potential recipient (or we would not be here). * And it's not a DURATION waiting to happen. * Probably waiting for a TIME restriction to trigger, so try * again soon. */ nexttime = now + 60; } return nexttime; } void cleanup_alert(activealerts_t *alert) { /* * A status has recovered and gone green, or it has been deleted. * So we clear out all info we have about this alert and it's recipients. */ char *id; repeat_t *rptwalk, *rptprev; dbgprintf("cleanup_alert called for host %s, test %s\n", alert->hostname, alert->testname); id = (char *)malloc(strlen(alert->hostname)+strlen(alert->testname)+3); sprintf(id, "%s|%s|", alert->hostname, alert->testname); rptwalk = rpthead; rptprev = NULL; while (rptwalk) { if (strncmp(rptwalk->recipid, id, strlen(id)) == 0) { repeat_t *tmp = rptwalk; dbgprintf("cleanup_alert found recipient %s\n", rptwalk->recipid); if (rptwalk == rpthead) { rptwalk = rpthead = rpthead->next; } else { if (rptprev) rptprev->next = rptwalk->next; rptwalk = rptwalk->next; } xfree(tmp->recipid); xfree(tmp); } else { rptprev = rptwalk; rptwalk = rptwalk->next; } } xfree(id); } void clear_interval(activealerts_t *alert) { int first = 1; recip_t *recip; repeat_t *rpt; alert->nextalerttime = 0; stoprulefound = 0; while (!stoprulefound && ((recip = next_recipient(alert, &first, NULL, NULL)) != NULL)) { rpt = find_repeatinfo(alert, recip, 0); if (rpt) { dbgprintf("Cleared repeat interval for %s\n", rpt->recipid); rpt->nextalert = 0; } } } void save_state(char *filename) { FILE *fd = fopen(filename, "w"); repeat_t *walk; if (fd == NULL) return; for (walk = rpthead; (walk); walk = walk->next) { fprintf(fd, "%ld|%s\n", (long) walk->nextalert, walk->recipid); } fclose(fd); } void load_state(char *filename, char *statusbuf) { FILE *fd = fopen(filename, "r"); strbuffer_t *inbuf; char *p; if (fd == NULL) return; initfgets(fd); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, fd)) { sanitize_input(inbuf, 0, 0); p = strchr(STRBUF(inbuf), '|'); if (p) { repeat_t *newrpt; *p = '\0'; if (atoi(STRBUF(inbuf)) > getcurrenttime(NULL)) { char *found = NULL; if (statusbuf) { char *htend; /* statusbuf contains lines with "HOSTNAME|TESTNAME|COLOR" */ htend = strchr(p+1, '|'); if (htend) htend = strchr(htend+1, '|'); if (htend) { *htend = '\0'; *p = '\n'; found = strstr(statusbuf, p); if (!found && (strncmp(statusbuf, p+1, strlen(p+1)) == 0)) found = statusbuf; *htend = '|'; } } if (!found) continue; newrpt = (repeat_t *)malloc(sizeof(repeat_t)); newrpt->recipid = strdup(p+1); newrpt->nextalert = atoi(STRBUF(inbuf)); newrpt->next = rpthead; rpthead = newrpt; } } } fclose(fd); freestrbuffer(inbuf); } xymon-4.3.30/xymond/xymon-mailack.c0000664000076400007640000001376612603243142017450 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon mail-acknowledgment filter. */ /* */ /* This program runs from the Xymon users' .procmailrc file, and processes */ /* incoming e-mails that are responses to alert mails that Xymon has sent */ /* out. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymon-mailack.c 7678 2015-10-01 14:42:42Z jccleaver $"; #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { strbuffer_t *inbuf; char *ackbuf; char *subjectline = NULL; char *returnpathline = NULL; char *fromline = NULL; char *firsttxtline = NULL; int inheaders = 1; char *p; pcre *subjexp; const char *errmsg; int errofs, result; int ovector[30]; char cookie[10]; int duration = 0; int argi; char *envarea = NULL; for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } } initfgets(stdin); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, stdin)) { sanitize_input(inbuf, 0, 0); if (!inheaders) { /* We're in the message body. Look for a "delay=N" line here. */ if ((strncasecmp(STRBUF(inbuf), "delay=", 6) == 0) || (strncasecmp(STRBUF(inbuf), "delay ", 6) == 0)) { duration = durationvalue(STRBUF(inbuf)+6); continue; } else if ((strncasecmp(STRBUF(inbuf), "ack=", 4) == 0) || (strncasecmp(STRBUF(inbuf), "ack ", 4) == 0)) { /* Some systems cannot generate a subject. Allow them to ack * via text in the message body. */ subjectline = (char *)malloc(STRBUFLEN(inbuf) + 1024); sprintf(subjectline, "Subject: Xymon [%s]", STRBUF(inbuf)+4); } else if (*STRBUF(inbuf) && !firsttxtline) { /* Save the first line of the message body, but ignore blank lines */ firsttxtline = strdup(STRBUF(inbuf)); } continue; /* We don't care about the rest of the message body */ } /* See if we're at the end of the mail headers */ if (inheaders && (STRBUFLEN(inbuf) == 0)) { inheaders = 0; continue; } /* Is it one of those we want to keep ? */ if (strncasecmp(STRBUF(inbuf), "return-path:", 12) == 0) returnpathline = strdup(skipwhitespace(STRBUF(inbuf)+12)); else if (strncasecmp(STRBUF(inbuf), "from:", 5) == 0) fromline = strdup(skipwhitespace(STRBUF(inbuf)+5)); else if (strncasecmp(STRBUF(inbuf), "subject:", 8) == 0) subjectline = strdup(skipwhitespace(STRBUF(inbuf)+8)); } freestrbuffer(inbuf); /* No subject ? No deal */ if (subjectline == NULL) { dbgprintf("Subject-line not found\n"); return 1; } /* Get the alert cookie */ subjexp = pcre_compile(".*(Xymon|Hobbit|BB)[ -]* \\[*(-*[0-9]+)[\\]!]*", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 1\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) { dbgprintf("Subject line did not match pattern\n"); return 3; /* Subject did not match what we expected */ } if (pcre_copy_substring(subjectline, ovector, result, 2, cookie, sizeof(cookie)) <= 0) { dbgprintf("Could not find cookie value\n"); return 4; /* No cookie */ } pcre_free(subjexp); /* See if there's a "DELAY=" delay-value also */ subjexp = pcre_compile(".*DELAY[ =]+([0-9]+[mhdw]*)", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 2\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result >= 0) { char delaytxt[4096]; if (pcre_copy_substring(subjectline, ovector, result, 1, delaytxt, sizeof(delaytxt)) > 0) { duration = durationvalue(delaytxt); } } pcre_free(subjexp); /* See if there's a "msg" text also */ subjexp = pcre_compile(".*MSG[ =]+(.*)", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 3\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result >= 0) { char msgtxt[4096]; if (pcre_copy_substring(subjectline, ovector, result, 1, msgtxt, sizeof(msgtxt)) > 0) { firsttxtline = strdup(msgtxt); } } pcre_free(subjexp); /* Use the "return-path:" header if we didn't see a From: line */ if ((fromline == NULL) && returnpathline) fromline = returnpathline; if (fromline) { /* Remove '<' and '>' from the fromline - they mess up HTML */ while ((p = strchr(fromline, '<')) != NULL) *p = ' '; while ((p = strchr(fromline, '>')) != NULL) *p = ' '; } /* Setup the acknowledge message */ if (duration == 0) duration = 60; /* Default: Ack for 60 minutes */ if (firsttxtline == NULL) firsttxtline = ""; ackbuf = (char *)malloc(4096 + strlen(firsttxtline) + (fromline ? strlen(fromline) : 0)); p = ackbuf; p += sprintf(p, "xymondack %s %d %s", cookie, duration, firsttxtline); if (fromline) { p += sprintf(p, "\nAcked by: %s", fromline); } if (debug) { printf("%s\n", ackbuf); return 0; } sendmessage(ackbuf, NULL, XYMON_TIMEOUT, NULL); return 0; } xymon-4.3.30/xymond/xymond_hostdata.80000664000076400007640000000247413534041733020031 0ustar rpmbuildrpmbuild.TH XYMOND_HOSTDATA 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_hostdata \- xymond worker module for storing historical client data .SH SYNOPSIS .B "xymond_channel \-\-channel=clichg xymond_hostdata" .SH DESCRIPTION xymond_hostdata is a worker module for xymond, and as such it is normally run via the .I xymond_channel(8) program. Whenever a status column in Xymon changes to an alert state (usually red, yellow or purple), this module receives a copy of the latest Xymon client data sent by the host, and stores it on disk. This allows you to review all of the data collected by the Xymon client on the server around the time that a problem occurred. This can make troubleshooting incidents easier by providing a snapshot of the host status shortly before a problem became apparent. Note: This module requires that .I xymond(8) is launched with the "\-\-store\-clientlogs" option enabled. .SH OPTIONS .IP "\-\-minimum\-free=N" Sets the minimum percentage of free filesystem space on the $CLIENTLOGS directory. If there is less than N% free space, xymond_hostdata will not save the data. Default: 5 .IP "\-\-debug" Enable debugging output. .SH FILES All of the host data are stored in the $CLIENTLOGS directory, by default this is the $XYMONVAR/hostdata/ directory. .SH "SEE ALSO" xymond(8), xymond_channel(8), xymon(7) xymon-4.3.30/xymond/Makefile0000664000076400007640000002715112500500212016152 0ustar rpmbuildrpmbuildXYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(ZLIBLIBS) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) PROGRAMS = xymon.sh xymond xymond_channel xymond_locator xymond_filestore xymond_history xymond_alert xymond_sample xymond_client xymond_hostdata xymond_capture xymond_distribute xymonfetch xymon-mailack trimhistory combostatus xymonreports.sh moverrd.sh convertnk rrdcachectl CLIENTPROGRAMS = ../client/xymond_client ifeq ($(DORRD),yes) PROGRAMS += xymond_rrd endif XYMONDOBJS = xymond.o CHANNELOBJS = xymond_channel.o LOCATOROBJS = xymond_locator.o SAMPLEOBJS = xymond_sample.o xymond_worker.o FILESTOREOBJS = xymond_filestore.o xymond_worker.o HISTORYOBJS = xymond_history.o xymond_worker.o ALERTOBJS = xymond_alert.o xymond_worker.o do_alert.o RRDOBJS = xymond_rrd.o xymond_worker.o do_rrd.o client_config.o HOSTDATAOBJS = xymond_hostdata.o xymond_worker.o CAPTUREOBJS = xymond_capture.o xymond_worker.o CLIENTOBJS = xymond_client.o xymond_worker.o client_config.o DISTRIBUTEOBJS= xymond_distribute.o xymond_worker.o COMBOTESTOBJS = combostatus.o MAILACKOBJS = xymon-mailack.o TRIMHISTOBJS = trimhistory.o FETCHOBJS = xymonfetch.o CONVERTNKOBJS = convertnk.o RRDCACHECTLOBJS = rrdcachectl.o IDTOOL := $(shell if test `uname -s` = "SunOS"; then echo /usr/xpg4/bin/id; else echo id; fi) all: $(PROGRAMS) cfgfiles # Need NETLIBS on Solaris for getservbyname(), called by parse_url() client: $(CLIENTPROGRAMS) xymond: $(XYMONDOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(XYMONDOBJS) $(XYMONCOMMLIBS) $(XYMONTIMELIBS) $(PCRELIBS) xymond_channel: $(CHANNELOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(CHANNELOBJS) $(XYMONCOMMLIBS) $(XYMONTIMELIBS) $(PCRELIBS) xymond_locator: $(LOCATOROBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(LOCATOROBJS) $(XYMONCOMMLIBS) xymond_filestore: $(FILESTOREOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(FILESTOREOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) xymond_history: $(HISTORYOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(HISTORYOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) xymond_alert: $(ALERTOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(ALERTOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) xymond_rrd: $(RRDOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(RRDOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(RRDLIBS) $(PCRELIBS) xymond.o: xymond.c $(CC) $(CFLAGS) $(SSLFLAGS) -c -o $@ xymond.c do_alert.o: do_alert.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ do_alert.c do_rrd.o: do_rrd.c do_rrd.h rrd/*.c $(CC) $(CFLAGS) $(RRDINCDIR) $(PCREINCDIR) $(RRDDEF) -c -o $@ do_rrd.c xymond_capture.o: xymond_capture.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ xymond_capture.c xymond_sample: $(SAMPLEOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(SAMPLEOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) xymond_capture: $(CAPTUREOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(CAPTUREOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) xymond_distribute: $(DISTRIBUTEOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(DISTRIBUTEOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) xymond_hostdata: $(HOSTDATAOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(HOSTDATAOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) xymond_client: $(CLIENTOBJS) $(XYMONCOMMLIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(CLIENTOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) ../client/xymond_client: $(CLIENTOBJS) ../lib/libxymonclientcomm.a ../lib/libxymontime.a ../lib/libxymonclient.a $(CC) -o $@ $(RPATHOPT) $(CLIENTOBJS) ../lib/libxymonclientcomm.a ../lib/libxymontime.a ../lib/libxymonclient.a $(PCRELIBS) $(NETLIBS) $(LIBRTDEF) xymond_client.o: xymond_client.c client/*.c $(CC) $(CFLAGS) -c -o $@ xymond_client.c combostatus.o: combostatus.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ $< combostatus: $(COMBOTESTOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(LDFLAGS) -o $@ $(RPATHOPT) $(COMBOTESTOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) xymon-mailack.o: xymon-mailack.c $(CC) $(CFLAGS) $(PCREINCDIR) -c -o $@ xymon-mailack.c xymon-mailack: $(MAILACKOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(MAILACKOBJS) $(XYMONCOMMLIBS) $(PCRELIBS) trimhistory: $(TRIMHISTOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(TRIMHISTOBJS) $(XYMONCOMMLIBS) xymonfetch: $(FETCHOBJS) $(XYMONCOMMLIB) $(XYMONTIMELIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(FETCHOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) convertnk: $(CONVERTNKOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(CONVERTNKOBJS) $(XYMONCOMMLIBS) rrdcachectl: $(RRDCACHECTLOBJS) $(XYMONCOMMLIB) $(CC) $(CFLAGS) -o $@ $(RPATHOPT) $(RRDCACHECTLOBJS) $(XYMONCOMMLIBS) xymon.sh: xymon.sh.DIST cat $< | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@XYMONLOGDIR@!$(XYMONLOGDIR)!g' | sed -e 's!@XYMONUSER@!$(XYMONUSER)!g' | sed -e 's!@RUNTIMEDEFS@!$(RUNTIMEDEFS)!g' >$@ chmod 755 $@ xymonreports.sh: xymonreports.sh.DIST cat $< | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' >$@ chmod 755 $@ moverrd.sh: moverrd.sh.DIST cat $< | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@XYMONVAR@!$(XYMONVAR)!g' >$@ chmod 755 $@ ifeq ($(XYMONCGIURL),$(SECUREXYMONCGIURL)) APACHECONF = etcfiles/xymon-apache-open.DIST else APACHECONF = etcfiles/xymon-apache-secure.DIST endif cfgfiles: cat $(APACHECONF) | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@INSTALLETCDIR@!$(INSTALLETCDIR)!g' | sed -e 's!@INSTALLWWWDIR@!$(INSTALLWWWDIR)!g' | sed -e 's!@CGIDIR@!$(CGIDIR)!g' | sed -e 's!@SECURECGIDIR@!$(SECURECGIDIR)!g' | sed -e 's!@XYMONHOSTURL@!$(XYMONHOSTURL)!g' | sed -e 's!@XYMONCGIURL@!$(XYMONCGIURL)!g' | sed -e 's!@SECUREXYMONCGIURL@!$(SECUREXYMONCGIURL)!g' >etcfiles/xymon-apache.conf cat etcfiles/xymonserver.cfg.DIST | sed -e 's!@XYMONTOPDIR@!$(XYMONTOPDIR)!g'| sed -e 's!@XYMONLOGDIR@!$(XYMONLOGDIR)!g'| sed -e 's!@XYMONHOSTNAME@!$(XYMONHOSTNAME)!g'| sed -e 's!@XYMONHOSTIP@!$(XYMONHOSTIP)!g'| sed -e 's!@XYMONHOSTOS@!$(XYMONHOSTOS)!g' | sed -e 's!@XYMONHOSTURL@!$(XYMONHOSTURL)!g' | sed -e 's!@XYMONCGIURL@!$(XYMONCGIURL)!g' | sed -e 's!@SECUREXYMONCGIURL@!$(SECUREXYMONCGIURL)!g' | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@XYMONVAR@!$(XYMONVAR)!g' | sed -e 's!@FPING@!$(FPING)!g' | sed -e 's!@MAILPROGRAM@!$(MAILPROGRAM)!g' | sed -e 's!@RUNTIMEDEFS@!$(RUNTIMEDEFS)!g' >etcfiles/xymonserver.cfg ../build/bb-commands.sh >>etcfiles/xymonserver.cfg cat etcfiles/hosts.cfg.DIST | sed -e 's!@XYMONHOSTNAME@!$(XYMONHOSTNAME)!g' | sed -e 's!@XYMONHOSTIP@!$(XYMONHOSTIP)!g' >etcfiles/hosts.cfg cat etcfiles/alerts.cfg.DIST | sed -e 's!@XYMONHOSTNAME@!$(XYMONHOSTNAME)!g' | sed -e 's!@XYMONHOSTIP@!$(XYMONHOSTIP)!g' >etcfiles/alerts.cfg cat etcfiles/tasks.cfg.DIST | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' | sed -e 's!@XYMONTOPDIR@!$(XYMONTOPDIR)!g' >etcfiles/tasks.cfg cat etcfiles/cgioptions.cfg.DIST | sed -e 's!@XYMONHOME@!$(XYMONHOME)!g' >etcfiles/cgioptions.cfg %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(PROGRAMS) *.o *~ client/*~ rrd/*~ rm -f etcfiles/xymon-apache.conf etcfiles/xymonserver.cfg etcfiles/hosts.cfg etcfiles/alerts.cfg etcfiles/tasks.cfg etcfiles/cgioptions.cfg (find etcfiles/ -name "*~"; find wwwfiles/ -name "*~"; find webfiles/ -name "*~") | xargs rm -f install: install-bin install-man install-cfg install-bin: ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ install-man: ifndef PKGBUILD chown $(XYMONUSER) *.1 *.5 *.8 chgrp `$(IDTOOL) -g $(XYMONUSER)` *.1 *.5 *.8 chmod 644 *.1 *.5 *.8 endif mkdir -p $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 chmod 755 $(INSTALLROOT)$(MANROOT) $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man8 endif cp -fp *.1 $(INSTALLROOT)$(MANROOT)/man1/ cp -fp *.5 $(INSTALLROOT)$(MANROOT)/man5/ cp -fp *.8 $(INSTALLROOT)$(MANROOT)/man8/ install-cfg: cd etcfiles; ../../build/merge-lines xymonserver.cfg $(INSTALLROOT)$(INSTALLETCDIR)/xymonserver.cfg LARRDCOLUMN=TRENDSCOLUMN LARRDS=TEST2RRD cd etcfiles; ../../build/merge-lines cgioptions.cfg $(INSTALLROOT)$(INSTALLETCDIR)/cgioptions.cfg cd etcfiles; ../../build/merge-sects tasks.cfg $(INSTALLROOT)$(INSTALLETCDIR)/tasks.cfg larrdstatus=rrdstatus larrddata=rrddata cd etcfiles; ../../build/merge-sects client-local.cfg $(INSTALLROOT)$(INSTALLETCDIR)/client-local.cfg cd etcfiles; ../../build/merge-sects graphs.cfg $(INSTALLROOT)$(INSTALLETCDIR)/graphs.cfg cd etcfiles; ../../build/merge-lines columndoc.csv $(INSTALLROOT)$(INSTALLETCDIR)/columndoc.csv cd etcfiles; (echo "hosts.cfg"; echo "alerts.cfg"; echo "analysis.cfg"; echo "combo.cfg"; echo "client-local.cfg"; echo "holidays.cfg"; echo "rrddefinitions.cfg"; echo snmpmibs.cfg; echo xymonmenu.cfg; echo xymon-apache.conf) | ../../build/setup-newfiles $(INSTALLROOT)$(INSTALLETCDIR)/ cd $(INSTALLROOT)$(XYMONHOME); rm -f xymon.sh; ln -sf bin/xymon.sh . cd wwwfiles; find . | grep -v RCS | grep -v ".svn" | grep -v DIST | ../../build/setup-newfiles $(INSTALLROOT)$(INSTALLWWWDIR)/ ../../build/md5.dat cd webfiles; find . | grep -v RCS | grep -v ".svn" | grep -v DIST | ../../build/setup-newfiles $(INSTALLROOT)$(INSTALLWEBDIR)/ ../../build/md5.dat touch $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg.bak chmod 664 $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg.bak mkdir -p $(INSTALLROOT)$(XYMONLOGDIR); chmod 755 $(INSTALLROOT)$(XYMONLOGDIR) mkdir -p $(INSTALLROOT)$(INSTALLETCDIR)/tasks.d; chmod 755 $(INSTALLROOT)$(INSTALLETCDIR)/tasks.d ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONLOGDIR) $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/* $(INSTALLROOT)$(INSTALLBINDIR)/* $(INSTALLROOT)$(INSTALLETCDIR)/* $(INSTALLROOT)$(INSTALLEXTDIR)/* $(INSTALLROOT)$(INSTALLWEBDIR)/* $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/gifs/* $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/menu/* $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/wml $(INSTALLROOT)$(XYMONVAR) $(INSTALLROOT)$(XYMONVAR)/* chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONLOGDIR) $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/* $(INSTALLROOT)$(INSTALLBINDIR)/* $(INSTALLROOT)$(INSTALLETCDIR)/* $(INSTALLROOT)$(INSTALLEXTDIR)/* $(INSTALLROOT)$(INSTALLWEBDIR)/* $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/gifs/* $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/menu/* $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/wml $(INSTALLROOT)$(XYMONVAR) $(INSTALLROOT)$(XYMONVAR)/* chgrp $(HTTPDGID) $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg.bak chmod 664 $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg $(INSTALLROOT)$(INSTALLETCDIR)/critical.cfg.bak chown root $(INSTALLROOT)$(INSTALLBINDIR)/xymonping || echo "Could not make xymonping owned by root, continuing" chmod 4755 $(INSTALLROOT)$(INSTALLBINDIR)/xymonping || echo "Could not make xymonping suid-root, continuing" endif xymon-4.3.30/xymond/client_config.h0000664000076400007640000001142312206407300017470 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CLIENT_CONFIG_H__ #define __CLIENT_CONFIG_H__ #include "libxymon.h" extern int load_client_config(char *configfn); extern void dump_client_config(void); extern void clearalertgroups(void); extern char *getalertgroups(void); extern void addalertgroup(char *group); extern int get_cpu_thresholds(void *hinfo, char *classname, float *loadyellow, float *loadred, int *recentlimit, int *ancientlimit, int *uptimecolor, int *maxclockdiff, int *clockdiffcolor); extern int get_disk_thresholds(void *hinfo, char *classname, char *fsname, long *warnlevel, long *paniclevel, int *abswarn, int *abspanic, int *ignored, char **group); extern int get_inode_thresholds(void *hinfo, char *classname, char *fsname, long *warnlevel, long *paniclevel, int *abswarn, int *abspanic, int *ignored, char **group); extern void get_memory_thresholds(void *hhinfo, char *classname, int *physyellow, int *physred, int *swapyellow, int *swapred, int *actyellow, int *actred); extern void get_zos_memory_thresholds(void *hinfo, char *classname, int *csayellow, int *csared, int *ecsayellow, int *ecsared, int *sqayellow, int *sqared, int *esqayellow, int *esqared); extern void get_cics_thresholds(void *hinfo, char *classname, char *appid, int *dsayel, int *dsared, int *edsayel, int *edsared); extern void get_zvsevsize_thresholds(void *hinfo, char *classname, int *availyel, int *availred); extern void get_zvsegetvis_thresholds(void *hinfo, char *classname, char *pid, int *gv24yel, int *gv24red, int *gvanyyel, int *gvanyred); extern void get_asid_thresholds(void *hinfo, char *classname, int *maxyellow, int *maxred); extern int get_paging_thresholds(void *hinfo, char *classname, int *pagingyellow, int *pagingred); extern int check_mibvals(void *hinfo, char *classname, char *mibname, char *keyname, char *mibdata, strbuffer_t *summarybuf, int *anyrules); extern strbuffer_t *check_rrdds_thresholds(char *hostname, char *classname, char *pagepaths, char *rrdkey, void *valnames, char *vals); extern int scan_log(void *hinfo, char *classname, char *logname, char *logdata, char *section, strbuffer_t *summarybuf); extern int check_file(void *hinfo, char *classname, char *filename, char *filedata, char *section, strbuffer_t *summarybuf, off_t *sz, char **id, int *trackit, int *anyrules); extern int check_dir(void *hinfo, char *classname, char *filename, char *filedata, char *section, strbuffer_t *summarybuf, unsigned long *sz, char **id, int *trackit); extern int clear_process_counts(void *hinfo, char *classname); extern void add_process_count(char *pname); extern char *check_process_count(int *pcount, int *lowlim, int *uplim, int *pcolor, char **id, int *trackit, char **group); extern int clear_disk_counts(void *hinfo, char *classname); extern void add_disk_count(char *dname); extern char *check_disk_count(int *dcount, int *lowlim, int *uplim, int *dcolor, char **group); extern int clear_inode_counts(void *hinfo, char *classname); extern void add_inode_count(char *iname); extern char *check_inode_count(int *icount, int *lowlim, int *uplim, int *icolor, char **group); extern int clear_port_counts(void *hinfo, char *classname); extern void add_port_count(char *spname, char *tpname, char *stname); extern char *check_port_count(int *pcount, int *lowlim, int *uplim, int *pcolor, char **id, int *trackit, char **group); extern int clear_svc_counts(void *hinfo, char *classname); extern void add_svc_count(char *spname, char *tpname, char *stname); extern char *check_svc_count(int *pcount, int *pcolor, char **group); extern void get_mqqueue_thresholds(void *hinfo, char *classname, char *qmgrname, char *qname, int *warnlen, int *critlen, int *warnage, int *critage, char **trackit); extern int get_mqchannel_params(void *hinfo, char *classname, char *qmgrname, char *chnname, char *chnstatus, int *color); #endif xymon-4.3.30/xymond/client-local.cfg.50000664000076400007640000001757413534041733017734 0ustar rpmbuildrpmbuild.TH CLIENT\-LOCAL.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME client\-local.cfg \- Local configuration settings for Xymon clients .SH SYNOPSIS .B ~xymon/server/etc/client\-local.cfg .SH DESCRIPTION The client\-local.cfg file contains settings that are used by each Xymon client when it runs on a monitored host. It provides a convenient way of configuring clients from a central location without having to setup special configuration maintenance tools on all clients. The client\-local.cfg file is currently used to configure what logfiles the client should fetch data from, to be used as the basis for the "msgs" status column; and to configure which files and directories are being monitored in the "files" status column. Note that there is a dependency between the client\-local.cfg file and the .I analysis.cfg(5) file. When monitoring e.g. a logfile, you must first enter it into the client\-local.cfg file, to trigger the Xymon client into reporting any data about the logfile. Next, you must configure analysis.cfg so the Xymon server knows what to look for in the file data sent by the client. So: client\-local.cfg defines what raw data is collected by the client, and analysis.cfg defines how to analyze them. .SH PROPAGATION TO CLIENTS The client\-local.cfg file resides on the Xymon server. When clients connect to the Xymon server to send in their client data, they will receive part of this file back from the Xymon server. The configuration received by the client is then used the next time the client runs. This method of propagating the configuration means that there is a delay of up to two poll cycles (i.e. 5-10 minutes) from a configuration change is entered into the client\-local.cfg file, and until you see the result in the status messages reported by the client. By default, xymond will look for a matching entry by matching the client hostname, classname or operating system name against the section expressions. Hostname matches are used first, then classname matches, then OS matches. The first match found is the one that is returned to the client. If xymond is started with the "--merge-clientlocal" option, then xymond will instead merge all of the matching sections into one, and return all of this data to the client. So you can have host-specific entries, and then supplement them with class- or os-generic entries. Note that the merging does not remove entries, so if you have e.g. a "log" entry defined in both a hostname- and an osname-matching section, then both entries will be sent back to the client. .SH FILE FORMAT The file is divided into sections, delimited by "[name]" lines. A section name can be either an operating system identifier - linux, solaris, hp-ux, aix, freebsd, openbsd, netbsd, darwin - a class, or a hostname. When deciding which section to send to a client, Xymon will first look for a section named after the hostname of the client; if such a section does not exist, it will look for a section named by the operating system of the client. So you can configure special configurations for individual hosts, and have a default configuration for all other hosts of a certain type. It will often be practical to use regular expressions for hostnames. To do this you must use .sp [host=] .sp where is a Perl-compatible regular expression. The same kind of matching can be done on operating system or host class, using .sp [os=] .br [class=] Apart from the section delimiter, the file format is free-form, or rather it is defined by the tools that make use of the configuration. .SH LOGFILE CONFIGURATION ENTRIES A logfile configuration entry looks like this: .sp log:/var/log/messages:10240 .br ignore MARK .br trigger Oops .sp The \fBlog:FILENAME:SIZE\fR line defines the filename of the log, and the maximum amount of data (in bytes) to send to the Xymon server. FILENAME is usually an explicit full-path filename on the client. If it is enclosed in backticks, it is a command which the Xymon client runs and each line of output from this command is then used as a filename. This allows scripting which files to monitor, e.g. if you have logfiles that are named with some sort of timestamp. If FILENAME is enclosed in angle brackets it is treated as a glob and passed through the local glob(3) function first. .sp The \fBignore PATTERN\fR line (optional) defines lines in the logfile which are ignored entirely, i.e. they are stripped from the logfile data before sending it to the Xymon server. It is used to remove completely unwanted "noise" entries from the logdata processed by Xymon. "PATTERN" is a regular expression. .sp The \fBtrigger PATTERN\fR line (optional) is used only when there is more data in the log than the maximum size set in the "log:FILENAME:SIZE" line. The "trigger" pattern is then used to find particularly interesting lines in the logfile - these will always be sent to the Xymon server. After picking out the "trigger" lines, any remaining space up to the maximum size is filled in with the most recent entries from the logfile. "PATTERN" is a regular expression. .SH COUNTING LOGENTRIES A special type of log-handling is possible, where the number of lines matching a regular expressions are merely counted. This is \fBlinecount:FILENAME\fR, followed by a number of lines of the form \fBID:PATTERN\fR. E.g. .sp linecount:/var/log/messages .br diskerrors:I/O error.*device.*hd .br badlogins:Failed login .sp .SH FILE CONFIGURATION ENTRIES A file monitoring entry is used to watch the meta-data of a file: Owner, group, size, permissions, checksum etc. It looks like this: .sp file:/var/log/messages[:HASH] .sp The \fBfile:FILENAME\fR line defines the filename of the file to monitor. As with the "log:" entries, a filename enclosed in backticks means a command which will generate the filenames dynamically. The optional [:HASH] setting defines what type of hash to compute for the file: \fBmd5\fR, \fBrmd160\fR, \fBsha1\fR, or \fBsha256, \fBsha512\fR, \fBsha224\fR, or \fBsha384\fR. By default, no hash is calculated. .br \fBNOTE:\fR If you want to check multiple files using a wildcard, you \fBmust\fR use a command to generate the filenames. Putting wildcards directly into the \fBfile:\fR entry will not work. .SH DIRECTORY CONFIGURATION ENTRIES A directory monitoring entry is used to watch the size of a directory and any sub-directories. It looks like this: .sp dir:DIRECTORYNAME .sp The \fBdir:DIRECTORYNAME\fR line defines the filename of the file to monitor. As with the "log:" entries, a filename enclosed in backticks means a command which will generate the filenames dynamically and a filename enclosed in angle brackets will be treated as a fileglob. The Xymon client will run the .I du(1) command with the directoryname as parameter, and send the output back to the Xymon server. .br \fBNOTE:\fR If you want to check multiple directories using a wildcard, you \fBmust\fR use a command or glob to generate the directory names. Putting wildcards directly into the \fBdir:\fR entry will not work. E.g. use something like .br dir:`find /var/log \-maxdepth 1 \-type d` The "du" command used can be configured through the \fBDU\fR environment variable in the xymonclient.cfg file if needed. If not specified, \fBdu \-k\fR is used, as on some systems by default \fBdu\fR reports data in disk blocks instead of KB (e.g. Solaris). .SH NOTES The ability of the Xymon client to calculate file hashes and monitor those can be used for file integrity validation on a small scale. However, there is a significant processing overhead in calculating these every time the Xymon client runs, so this should not be considered a replacement for host-based intrusion detection systems such as Tripwire or AIDE. Use of the directory monitoring on directory structures with a large number of files and/or sub-directories can be quite ressource-intensive. .SH "SEE ALSO" analysis.cfg(5), xymond_client(8), xymond(8), xymon(7) xymon-4.3.30/xymond/xymond_alert.c0000664000076400007640000007333613007426256017413 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon message daemon. */ /* */ /* This is the main alert module for xymond. It receives alert messages, */ /* keeps track of active alerts, enable/disable, acks etc., and triggers */ /* outgoing alerts by calling send_alert(). */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ /* * Information from the Xymon docs about "page" modules: * * page * ---- * @@page|timestamp|sender|hostname|testname|expiretime|color|prevcolor|changetime|location * * @@ * * @@ack|timestamp|sender|hostname|testname|expiretime * * @@ * * @@notify|timestamp|sender|hostname|testname|pagepath * * @@ * * Note that "page" modules get messages whenever the alert-state of a test * changes. I.e. a message is generated whenever a test goes from a color * that is non-alerting to a color that is alerting, or vice versa. * * How does the pager know when a test is disabled ? It will get a "page" * message with color=blue, if the old color of the test was in an alert * state. (If it wasn't, the pager module does not need to know that the * test has been disabled). It should then clear any stored info about * active alerts for this host.test combination. */ static char rcsid[] = "$Id: xymond_alert.c 7982 2016-11-05 19:02:06Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include "xymond_worker.h" #include "do_alert.h" #define DEFAULT_RELOAD_INTERVAL 300 int reloadinterval = DEFAULT_RELOAD_INTERVAL; /* Seconds - how often to check hosts.cfg for changes (which can be expensive) */ int loadhostsfromxymond = 0; static int reloadconfig = 0; static int running = 1; static time_t nextcheckpoint = 0; static int termsig = -1; void * hostnames; void * testnames; void * locations; typedef struct alertanchor_t { activealerts_t *head; } alertanchor_t; activealerts_t *ahead = NULL; char *statename[] = { /* A_PAGING, A_NORECIP, A_ACKED, A_RECOVERED, A_DISABLED, A_NOTIFY, A_DEAD */ "paging", "norecip", "acked", "recovered", "disabled", "notify", "dead" }; char *find_name(void * tree, char *name) { char *result; xtreePos_t handle; handle = xtreeFind(tree, name); if (handle == xtreeEnd(tree)) { result = strdup(name); if (tree == hostnames) { alertanchor_t *anchor = malloc(sizeof(alertanchor_t)); anchor->head = NULL; xtreeAdd(tree, result, anchor); } else { xtreeAdd(tree, result, result); } } else { result = (char *)xtreeKey(tree, handle); } return result; } void add_active(char *hostname, activealerts_t *rec) { xtreePos_t handle; alertanchor_t *anchor; handle = xtreeFind(hostnames, hostname); if (handle == xtreeEnd(hostnames)) return; anchor = (alertanchor_t *)xtreeData(hostnames, handle); rec->next = anchor->head; anchor->head = rec; } void clean_active(alertanchor_t *anchor) { activealerts_t *newhead = NULL, *tmp, *curr; curr = anchor->head; while (curr) { tmp = curr; curr = curr->next; if (tmp->state == A_DEAD) { if (tmp->osname) xfree(tmp->osname); if (tmp->classname) xfree(tmp->classname); if (tmp->groups) xfree(tmp->groups); if (tmp->pagemessage) xfree(tmp->pagemessage); if (tmp->ackmessage) xfree(tmp->ackmessage); xfree(tmp); } else { tmp->next = newhead; newhead = tmp; } } anchor->head = newhead; } void clean_all_active(void) { xtreePos_t handle; for (handle = xtreeFirst(hostnames); handle != xtreeEnd(hostnames); handle = xtreeNext(hostnames, handle)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle); clean_active(anchor); } } activealerts_t *find_active(char *hostname, char *testname) { xtreePos_t handle; alertanchor_t *anchor; char *twalk; activealerts_t *awalk; handle = xtreeFind(hostnames, hostname); if (handle == xtreeEnd(hostnames)) return NULL; anchor = (alertanchor_t *)xtreeData(hostnames, handle); handle = xtreeFind(testnames, testname); if (handle == xtreeEnd(testnames)) return NULL; twalk = (char *)xtreeData(testnames, handle); for (awalk = anchor->head; (awalk && (awalk->testname != twalk)); awalk=awalk->next) ; return awalk; } static xtreePos_t alisthandle; static activealerts_t *alistwalk; activealerts_t *alistBegin(void) { alisthandle = xtreeFirst(hostnames); alistwalk = NULL; while ((alisthandle != xtreeEnd(hostnames)) && (alistwalk == NULL)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, alisthandle); alistwalk = anchor->head; if (alistwalk == NULL) alisthandle = xtreeNext(hostnames, alisthandle); } return alistwalk; } activealerts_t *alistNext(void) { if (!alistwalk) return NULL; alistwalk = alistwalk->next; if (alistwalk) return alistwalk; alisthandle = xtreeNext(hostnames, alisthandle); alistwalk = NULL; while ((alisthandle != xtreeEnd(hostnames)) && (alistwalk == NULL)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, alisthandle); alistwalk = anchor->head; if (alistwalk == NULL) alisthandle = xtreeNext(hostnames, alisthandle); } return alistwalk; } void sig_handler(int signum) { switch (signum) { case SIGCHLD: /* Pickup any finished child processes to avoid zombies */ while (waitpid(-1, NULL, WNOHANG) > 0) ; break; case SIGHUP: reloadconfig = 1; break; case SIGUSR1: nextcheckpoint = 0; break; default: running = 0; termsig = signum; break; } } void save_checkpoint(char *filename) { char *subfn; FILE *fd = fopen(filename, "w"); activealerts_t *awalk; unsigned char *pgmsg, *ackmsg; if (fd == NULL) return; for (awalk = alistBegin(); (awalk); awalk = alistNext()) { if (awalk->state == A_DEAD) continue; pgmsg = ackmsg = ""; fprintf(fd, "%s|%s|%s|%s|%s|%d|%d|%s|", awalk->hostname, awalk->testname, awalk->location, awalk->ip, colorname(awalk->maxcolor), (int) awalk->eventstart, (int) awalk->nextalerttime, statename[awalk->state]); if (awalk->pagemessage) pgmsg = nlencode(awalk->pagemessage); fprintf(fd, "%s|", pgmsg); if (awalk->ackmessage) ackmsg = nlencode(awalk->ackmessage); fprintf(fd, "%s\n", ackmsg); } fclose(fd); subfn = (char *)malloc(strlen(filename)+5); sprintf(subfn, "%s.sub", filename); save_state(subfn); xfree(subfn); } int load_checkpoint(char *filename) { char *subfn; FILE *fd; strbuffer_t *inbuf; char statuscmd[1024]; char *statusbuf = NULL; sendreturn_t *sres; int xymondresult; sprintf(statuscmd, "xymondboard fields=hostname,testname,color"); sres = newsendreturnbuf(1, NULL); xymondresult = sendmessage(statuscmd, NULL, XYMON_TIMEOUT, sres); statusbuf = getsendreturnstr(sres, 1); freesendreturnbuf(sres); if ((xymondresult != XYMONSEND_OK) || (statusbuf == NULL) || (*statusbuf == '\0')) { /* * If no data returned for any hosts, chances are xymond is not fully up. * To prevent alerts clearing and spuriously re-firing, bail out here. xymonlaunch * will restart us soon. */ errprintf("xymond_alert: xymond not available or had empty response; error: %d\n", xymondresult); running = 0; return -1; } fd = fopen(filename, "r"); if (fd == NULL) { errprintf("xymond_alert: Couldn't open checkpoint file '%s', but continuing: %s\n", filename, strerror(errno)); return 0; } initfgets(fd); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, fd)) { char *item[20], *p; int i; sanitize_input(inbuf, 0, 0); i = 0; p = gettok(STRBUF(inbuf), "|"); while (p && (i < 20)) { item[i++] = p; p = gettok(NULL, "|"); } if (i == 9) { /* There was no ack message */ item[i++] = ""; } if (i > 9) { char *valid = NULL; activealerts_t *newalert = (activealerts_t *)calloc(1, sizeof(activealerts_t)); newalert->hostname = find_name(hostnames, item[0]); newalert->testname = find_name(testnames, item[1]); newalert->location = find_name(locations, item[2]); strcpy(newalert->ip, item[3]); newalert->color = newalert->maxcolor = parse_color(item[4]); newalert->eventstart = (time_t) atoi(item[5]); newalert->nextalerttime = (time_t) atoi(item[6]); newalert->state = A_PAGING; if (statusbuf) { char *key; key = (char *)malloc(strlen(newalert->hostname) + strlen(newalert->testname) + 100); sprintf(key, "\n%s|%s|%s\n", newalert->hostname, newalert->testname, colorname(newalert->color)); valid = strstr(statusbuf, key); if (!valid && (strncmp(statusbuf, key+1, strlen(key+1)) == 0)) valid = statusbuf; xfree(key); } if (!valid) { errprintf("Stale alert for %s:%s dropped\n", newalert->hostname, newalert->testname); xfree(newalert); continue; } while (strcmp(item[7], statename[newalert->state]) && (newalert->state < A_DEAD)) newalert->state++; /* Config might have changed while we were down */ if (newalert->state == A_NORECIP) newalert->state = A_PAGING; newalert->pagemessage = newalert->ackmessage = NULL; if (strlen(item[8])) { nldecode(item[8]); newalert->pagemessage = strdup(item[8]); } if (strlen(item[9])) { nldecode(item[9]); newalert->ackmessage = strdup(item[9]); } add_active(newalert->hostname, newalert); } } fclose(fd); freestrbuffer(inbuf); subfn = (char *)malloc(strlen(filename)+5); sprintf(subfn, "%s.sub", filename); load_state(subfn, statusbuf); xfree(subfn); if (statusbuf) xfree(statusbuf); return 0; } int main(int argc, char *argv[]) { char *msg; int seq; int argi; int alertcolors, alertinterval; char *configfn = NULL; char *checkfn = NULL; int loadresult; int reloadconfigtime = 0; int checkpointinterval = 900; char acklogfn[PATH_MAX]; FILE *acklogfd = NULL; char notiflogfn[PATH_MAX]; FILE *notiflogfd = NULL; char *tracefn = NULL; struct sigaction sa; int configchanged; time_t lastxmit = 0; MEMDEFINE(acklogfn); MEMDEFINE(notiflogfn); /* Don't save the error buffer */ save_errbuf = 0; /* Load alert config */ alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE))); alertinterval = 60*atoi(xgetenv("ALERTREPEAT")); /* Create our loookup-trees */ hostnames = xtreeNew(strcasecmp); testnames = xtreeNew(strcasecmp); locations = xtreeNew(strcasecmp); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--debug")) { debug = 1; } else if (argnmatch(argv[argi], "--config=")) { configfn = strdup(strchr(argv[argi], '=')+1); } else if (argnmatch(argv[argi], "--checkpoint-file=")) { checkfn = strdup(strchr(argv[argi], '=')+1); } else if (argnmatch(argv[argi], "--checkpoint-interval=")) { char *p = strchr(argv[argi], '=') + 1; checkpointinterval = atoi(p); } else if (argnmatch(argv[argi], "--reload-interval=")) { char *p = strchr(argv[argi], '=') + 1; reloadinterval = atoi(p); } else if (argnmatch(argv[argi], "--loadhostsfromxymond")) { loadhostsfromxymond = 1; } else if (argnmatch(argv[argi], "--dump-config")) { load_alertconfig(configfn, alertcolors, alertinterval); dump_alertconfig(1); return 0; } else if (argnmatch(argv[argi], "--cfid")) { include_configid = 1; } else if (argnmatch(argv[argi], "--test")) { char *testhost = NULL, *testservice = NULL, *testpage = NULL, *testcolor = "red", *testgroups = NULL; void *hinfo; int testdur = 0; FILE *logfd = NULL; activealerts_t *awalk = NULL; int paramno = 0; set_localalertmode(1); /* create a dummy hostinfo record to try to match against */ argi++; if (argi < argc) testhost = argv[argi]; argi++; if (argi < argc) testservice = argv[argi]; argi++; while (argi < argc) { if (strncasecmp(argv[argi], "--duration=", 11) == 0) { testdur = durationvalue(strchr(argv[argi], '=')+1); } else if (strncasecmp(argv[argi], "--color=", 8) == 0) { testcolor = strchr(argv[argi], '=')+1; } else if (strncasecmp(argv[argi], "--group=", 8) == 0) { testgroups = strchr(argv[argi], '=')+1; } else if (strncasecmp(argv[argi], "--time=", 7) == 0) { fakestarttime = (time_t)atoi(strchr(argv[argi], '=')+1); } else { paramno++; if (paramno == 1) testdur = atoi(argv[argi]); else if (paramno == 2) testcolor = argv[argi]; else if (paramno == 3) fakestarttime = (time_t) atoi(argv[argi]); } argi++; } if ((testhost == NULL) || (testservice == NULL)) { printf("Usage: xymond_alert --test HOST SERVICE [options]\n"); printf("Possible options:\n\t[--duration=MINUTES]\n\t[--color=COLOR]\n\t[--group=GROUPNAME]\n\t[--time=TIMESPEC]\n"); return 1; } load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); hinfo = hostinfo(testhost); if (hinfo) { testpage = strdup(xmh_item(hinfo, XMH_ALLPAGEPATHS)); } else { errprintf("Host not found in hosts.cfg - assuming it is on the top page\n"); testpage = ""; } awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t)); awalk->hostname = find_name(hostnames, testhost); awalk->testname = find_name(testnames, testservice); awalk->location = find_name(locations, testpage); strcpy(awalk->ip, "127.0.0.1"); awalk->color = awalk->maxcolor = parse_color(testcolor); awalk->pagemessage = "Test of the alert configuration"; awalk->eventstart = getcurrenttime(NULL) - testdur*60; awalk->groups = (testgroups ? strdup(testgroups) : NULL); awalk->state = A_PAGING; awalk->cookie = 12345; awalk->next = NULL; logfd = fopen("/dev/null", "w"); starttrace(NULL); testonly = 1; load_alertconfig(configfn, alertcolors, alertinterval); load_holidays(0); send_alert(awalk, logfd); return 0; } else if (argnmatch(argv[argi], "--trace=")) { tracefn = strdup(strchr(argv[argi], '=')+1); starttrace(tracefn); } else if (net_worker_option(argv[argi])) { /* Handled in the subroutine */ } else { errprintf("Unknown option '%s'\n", argv[argi]); } } /* Do the network stuff if needed */ net_worker_run(ST_ALERT, LOC_SINGLESERVER, NULL); /* Load our hostnames */ loadresult = load_hostnames( (loadhostsfromxymond ? "@" : xgetenv("HOSTSCFG")) , NULL, get_fqdn() ); if (loadresult != 0) { errprintf("Cannot load host configuration from %s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG"))); running = 0; return -1; } else { reloadconfig = 0; reloadconfigtime = getcurrenttime(NULL) + reloadinterval; } if (checkfn) { if ( load_checkpoint(checkfn) != 0 ) { errprintf("xymond_alert: cannot load checkpoint file or current state; aborting\n"); return -1; } nextcheckpoint = gettimer() + checkpointinterval; dbgprintf("Next checkpoint at %d, interval %d\n", (int) nextcheckpoint, checkpointinterval); } setup_signalhandler("xymond_alert"); /* Need to handle these ourselves, so we can shutdown and save state-info */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; sigaction(SIGPIPE, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGHUP, &sa, NULL); if (xgetenv("XYMONSERVERLOGS")) { sprintf(acklogfn, "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS")); acklogfd = fopen(acklogfn, "a"); sprintf(notiflogfn, "%s/notifications.log", xgetenv("XYMONSERVERLOGS")); notiflogfd = fopen(notiflogfn, "a"); } /* * The general idea here is that this loop handles receiving of alert- * and ack-messages from the master daemon, and maintains a list of * host+test combinations that may have alerts going out. * * This module does not deal with any specific alert-configuration, * it just picks up the alert messages, maintains the list of * known tests that are in some sort of critical condition, and * periodically pushes alerts to the do_alert.c module for handling. * * The only modification of alerts that happen here is the handling * of when the next alert is due. It calls into the next_alert() * routine to learn when an alert should be repeated, and also * deals with Acknowledgments that stop alerts from going out for * a period of time. */ while (running) { char *eoln, *restofmsg; char *metadata[20]; char *p; int metacount; char *hostname = NULL, *testname = NULL; struct timespec timeout; time_t now, nowtimer; int anytogo; activealerts_t *awalk; int childstat; nowtimer = gettimer(); if (checkfn && (nowtimer > nextcheckpoint)) { dbgprintf("Saving checkpoint\n"); nextcheckpoint = nowtimer + checkpointinterval; save_checkpoint(checkfn); if (acklogfd) acklogfd = freopen(acklogfn, "a", acklogfd); if (notiflogfd) notiflogfd = freopen(notiflogfn, "a", notiflogfd); } if (reloadconfig || (nowtimer > reloadconfigtime)) { dbgprintf("Reloading hostnames\n"); reloadconfig = 0; loadresult = load_hostnames( (loadhostsfromxymond ? "@" : xgetenv("HOSTSCFG")) , NULL, get_fqdn() ); if (loadresult == -1) { errprintf("Cannot load host configuration from %s; postponing for 90s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG"))); reloadconfigtime = nowtimer + 90; } else reloadconfigtime = nowtimer + reloadinterval; } timeout.tv_sec = 60; timeout.tv_nsec = 0; msg = get_xymond_message(C_PAGE, "xymond_alert", &seq, &timeout); if (msg == NULL) { running = 0; continue; } /* See what time it is - must happen AFTER the timeout */ now = getcurrenttime(NULL); /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } /* * Now parse the meta-data into elements. * We use our own "gettok()" routine which works * like strtok(), but can handle empty elements. */ metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < 19)) { metadata[metacount] = p; metacount++; p = gettok(NULL, "|"); } metadata[metacount] = NULL; if (metacount > 3) hostname = metadata[3]; if (metacount > 4) testname = metadata[4]; if ((metacount > 10) && (strncmp(metadata[0], "@@page", 6) == 0)) { /* @@page|timestamp|sender|hostname|testname|hostip|expiretime|color|prevcolor|changetime|location|cookie|osname|classname|grouplist|modifiers */ int newcolor, newalertstatus, oldalertstatus; dbgprintf("Got page message from %s:%s\n", hostname, testname); traceprintf("@@page %s:%s:%s=%s\n", hostname, testname, metadata[10], metadata[7]); awalk = find_active(hostname, testname); if (awalk == NULL) { char *hwalk = find_name(hostnames, hostname); char *twalk = find_name(testnames, testname); char *pwalk = find_name(locations, metadata[10]); awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t)); awalk->hostname = hwalk; awalk->testname = twalk; awalk->location = pwalk; awalk->cookie = -1; awalk->state = A_DEAD; /* * Use changetime here, if we restart the alert module then * this gets the duration values more right than using "now". * Also, define this only when a new alert arrives - we should * NOT clear this when a status goes yellow->red, or if it * flaps between yellow and red. */ awalk->eventstart = atoi(metadata[9]); add_active(awalk->hostname, awalk); traceprintf("New record\n"); } newcolor = parse_color(metadata[7]); oldalertstatus = ((alertcolors & (1 << awalk->color)) != 0); newalertstatus = ((alertcolors & (1 << newcolor)) != 0); traceprintf("state %d->%d\n", oldalertstatus, newalertstatus); if (newalertstatus) { /* It's in an alert state. */ awalk->color = newcolor; awalk->state = A_PAGING; if (newcolor > awalk->maxcolor) { if (awalk->maxcolor != 0) { /* * Severity has increased (yellow -> red). * Clear the repeat-interval, and set maxcolor to * the new color. If it drops to yellow again, * maxcolor stays at red, so a test that flaps * between yellow and red will only alert on red * the first time, and then follow the repeat * interval. */ dbgprintf("Severity increased, cleared repeat interval: %s/%s %s->%s\n", awalk->hostname, awalk->testname, colorname(awalk->maxcolor), colorname(newcolor)); clear_interval(awalk); } awalk->maxcolor = newcolor; } } else { /* * Send one "recovered" message out now, then go to A_DEAD. * Don't update the color here - we want recoveries to go out * only if the alert color triggered an alert */ awalk->state = (newcolor == COL_BLUE) ? A_DISABLED : A_RECOVERED; } if (oldalertstatus != newalertstatus) { dbgprintf("Alert status changed from %d to %d\n", oldalertstatus, newalertstatus); clear_interval(awalk); } strcpy(awalk->ip, metadata[5]); awalk->cookie = atoi(metadata[11]); if (awalk->osname) xfree(awalk->osname); awalk->osname = (metadata[12] ? strdup(metadata[12]) : NULL); if (awalk->classname) xfree(awalk->classname); awalk->classname = (metadata[13] ? strdup(metadata[13]) : NULL); if (awalk->groups) xfree(awalk->groups); awalk->groups = (metadata[14] ? strdup(metadata[14]) : NULL); if (awalk->pagemessage) xfree(awalk->pagemessage); if (metadata[15]) { /* Modifiers are more interesting than the message itself */ awalk->pagemessage = (char *)malloc(strlen(awalk->hostname) + strlen(awalk->testname) + strlen(colorname(awalk->color)) + strlen(metadata[15]) + strlen(restofmsg) + 10); sprintf(awalk->pagemessage, "%s:%s %s\n%s\n%s", awalk->hostname, awalk->testname, colorname(awalk->color), metadata[15], restofmsg); } else { awalk->pagemessage = strdup(restofmsg); } } else if ((metacount > 5) && (strncmp(metadata[0], "@@ack", 5) == 0)) { /* @@ack|timestamp|sender|hostname|testname|hostip|expiretime */ /* * An ack is handled simply by setting the next * alert-time to when the ack expires. */ time_t nextalert = atoi(metadata[6]); dbgprintf("Got ack message from %s:%s\n", hostname, testname); traceprintf("@@ack: %s:%s now=%d, ackeduntil %d\n", hostname, testname, (int)now, (int)nextalert); awalk = find_active(hostname, testname); if (acklogfd) { int cookie = (awalk ? awalk->cookie : -1); int color = (awalk ? awalk->color : 0); fprintf(acklogfd, "%d\t%d\t%d\t%d\t%s\t%s.%s\t%s\t%s\n", (int)now, cookie, (int)((nextalert - now) / 60), cookie, "np_filename_not_used", hostname, testname, colorname(color), nlencode(restofmsg)); fflush(acklogfd); } if (awalk && (awalk->state == A_PAGING)) { traceprintf("Record updated\n"); awalk->state = A_ACKED; awalk->nextalerttime = nextalert; if (awalk->ackmessage) xfree(awalk->ackmessage); awalk->ackmessage = strdup(restofmsg); } else { traceprintf("No record\n"); } } else if ((metacount > 4) && (strncmp(metadata[0], "@@notify", 5) == 0)) { /* @@notify|timestamp|sender|hostname|testname|pagepath */ char *hwalk = find_name(hostnames, hostname); char *twalk = find_name(testnames, testname); char *pwalk = find_name(locations, (metadata[5] ? metadata[5] : "")); awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t)); awalk->hostname = hwalk; awalk->testname = twalk; awalk->location = pwalk; awalk->cookie = -1; awalk->pagemessage = strdup(restofmsg); awalk->eventstart = getcurrenttime(NULL); awalk->state = A_NOTIFY; add_active(awalk->hostname, awalk); } else if ((metacount > 3) && ((strncmp(metadata[0], "@@drophost", 10) == 0) || (strncmp(metadata[0], "@@dropstate", 11) == 0))) { /* @@drophost|timestamp|sender|hostname */ /* @@dropstate|timestamp|sender|hostname */ xtreePos_t handle; handle = xtreeFind(hostnames, hostname); if (handle != xtreeEnd(hostnames)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle); for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD; } } else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) { /* @@droptest|timestamp|sender|hostname|testname */ awalk = find_active(hostname, testname); if (awalk) awalk->state = A_DEAD; } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { /* @@renamehost|timestamp|sender|hostname|newhostname */ /* * We handle rename's simply by dropping the alert. If there is still an * active alert for the host, it will have to be dealt with when the next * status update arrives. */ xtreePos_t handle; handle = xtreeFind(hostnames, hostname); if (handle != xtreeEnd(hostnames)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle); for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD; } } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { /* @@renametest|timestamp|sender|hostname|oldtestname|newtestname */ /* * We handle rename's simply by dropping the alert. If there is still an * active alert for the host, it will have to be dealt with when the next * status update arrives. */ awalk = find_active(hostname, testname); if (awalk) awalk->state = A_DEAD; } else if (strncmp(metadata[0], "@@shutdown", 10) == 0) { running = 0; errprintf("Got a shutdown message\n"); continue; } else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); if (tracefn) { stoptrace(); starttrace(tracefn); } } continue; } else if (strncmp(metadata[0], "@@reload", 8) == 0) { logprintf("Received reload request\n"); reloadconfig = 1; /* Nothing ... right now */ } else if (strncmp(metadata[0], "@@idle", 6) == 0) { /* Timeout */ } /* * When a burst of alerts happen, we get lots of alert messages * coming in quickly. So lets handle them in bunches and only * do the full alert handling once every 10 secs - that lets us * combine a bunch of alerts into one transmission process. */ if (nowtimer < (lastxmit+10)) continue; lastxmit = nowtimer; /* * Loop through the activealerts list and see if anything is pending. * This is an optimization, we could just as well just fork off the * notification child and let it handle all of it. But there is no * reason to fork a child process unless it is going to do something. */ configchanged = load_alertconfig(configfn, alertcolors, alertinterval); configchanged += load_holidays(0); if (configchanged) reloadconfig = 1; anytogo = 0; for (awalk = alistBegin(); (awalk); awalk = alistNext()) { int anymatch = 0; switch (awalk->state) { case A_NORECIP: if (!configchanged) break; /* The configuration has changed - switch NORECIP -> PAGING */ awalk->state = A_PAGING; clear_interval(awalk); /* Fall through */ case A_PAGING: if (have_recipient(awalk, &anymatch)) { if (awalk->nextalerttime <= now) anytogo++; } else { if (!anymatch) { awalk->state = A_NORECIP; cleanup_alert(awalk); } } break; case A_ACKED: if (awalk->nextalerttime <= now) { /* An ack has expired, so drop the ack message and switch to A_PAGING */ anytogo++; if (awalk->ackmessage) xfree(awalk->ackmessage); awalk->state = A_PAGING; } break; case A_RECOVERED: case A_DISABLED: case A_NOTIFY: anytogo++; break; case A_DEAD: break; } } dbgprintf("%d alerts to go\n", anytogo); if (anytogo) { pid_t childpid; childpid = fork(); if (childpid == 0) { /* The child */ start_alerts(); for (awalk = alistBegin(); (awalk); awalk = alistNext()) { switch (awalk->state) { case A_PAGING: if (awalk->nextalerttime <= now) { send_alert(awalk, notiflogfd); } break; case A_ACKED: /* Cannot be A_ACKED unless the ack is still valid, so no alert. */ break; case A_RECOVERED: case A_DISABLED: case A_NOTIFY: send_alert(awalk, notiflogfd); break; case A_NORECIP: case A_DEAD: break; } } finish_alerts(); /* Child does not continue */ exit(0); } else if (childpid < 0) { errprintf("Fork failed, cannot send alerts: %s\n", strerror(errno)); } } /* Update the state flag and the next-alert timestamp */ for (awalk = alistBegin(); (awalk); awalk = alistNext()) { switch (awalk->state) { case A_PAGING: if (awalk->nextalerttime <= now) awalk->nextalerttime = next_alert(awalk); break; case A_NORECIP: break; case A_ACKED: /* Still cannot get here except if ack is still valid */ break; case A_RECOVERED: case A_DISABLED: case A_NOTIFY: awalk->state = A_DEAD; /* Fall through */ case A_DEAD: cleanup_alert(awalk); break; } } clean_all_active(); } if (checkfn) save_checkpoint(checkfn); if (acklogfd) fclose(acklogfd); if (notiflogfd) fclose(notiflogfd); stoptrace(); MEMUNDEFINE(notiflogfn); MEMUNDEFINE(acklogfn); if (termsig >= 0) { errprintf("Terminated by signal %d\n", termsig); } return 0; } xymon-4.3.30/xymond/webfiles/0000775000076400007640000000000013534041775016332 5ustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hostgraphs_header0000664000076400007640000000216013446110526021737 0ustar rpmbuildrpmbuild Xymon - Metrics Report &XYMONBODYHEADER
 
&XYMONLOGO
Metrics Report
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/graphs_header0000664000076400007640000000220113446110526021035 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Graphs
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/histlog_header0000664000076400007640000000247313446110526021235 0ustar rpmbuildrpmbuild Xymon Historical Status: &XYMWEBHOST - &XYMWEBSVC @ &LOGTIME &XYMONBODYHEADER
 
&XYMONLOGO
Historical Status
&XYMWEBHOST - &XYMWEBSVC
Log time
&LOGTIME


xymon-4.3.30/xymond/webfiles/notify_footer0000777000076400007640000000000013534041775024442 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/confreport_front0000664000076400007640000000477511415724561021660 0ustar rpmbuildrpmbuild


Explanation of Terms
Basics
AliasesNames for this host other than the primary name, e.g. a hostname used by a client installed on the server
Monitoring locationThe location of this host on the Xymon webpages
Comment
Description
Explanatory text about the host
Planned downtimeTime of day/week when the host monitoring is disabled
SLA Reporting PeriodTime of day/week where the status impacts the SLA availability calculation
Network tests
ServiceCorresponds to the column-name on the Xymon webpage
CriticalWhether this test appears on the Critical Systems view
C/Y/R limitsIf set, this is the number of failures that must happen before the status changes to Clear/Yellow/Red
SpecificsDetails about how this status is monitored
Local tests
ServiceCorresponds to the column-name on the Xymon webpage
CriticalWhether this test appears on the Critical view
C/Y/R limitsIf set, this is the number of failures that must happen before the status changes to Clear/Yellow/Red
ConfigurationDetails about how this status is monitored. NOTE: The exact thresholds for each test are configured on the client, and may differ from that listed here.
xymon-4.3.30/xymond/webfiles/histlog_footer0000777000076400007640000000000013534041775024603 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/repnormal_header0000664000076400007640000000240613446110526021557 0ustar rpmbuildrpmbuild Xymon Availability Report : &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Availability Report
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/maint_footer0000777000076400007640000000000013534041775024242 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/report_header0000664000076400007640000000217213446110526021073 0ustar rpmbuildrpmbuild Xymon - Availability Report &XYMONBODYHEADER
 
&XYMONLOGO
Availability Report
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/maintact_footer0000777000076400007640000000000013534041775024732 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/maintact_header0000664000076400007640000000215213446110526021356 0ustar rpmbuildrpmbuild Xymon - Maintenance &XYMONBODYHEADER
 
&XYMONLOGO
Maintenance
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/report_form_weekly0000664000076400007640000000144211415724561022171 0ustar rpmbuildrpmbuild

Xymon Weekly Availability Report






xymon-4.3.30/xymond/webfiles/acknowledge_form0000664000076400007640000000212211070452713021547 0ustar rpmbuildrpmbuild
Estimated time to resolve issue: minutes
Explanation/Cause of problem:
Acknowledgment Code:


xymon-4.3.30/xymond/webfiles/zoom.js0000664000076400007640000005473412610344744017665 0ustar rpmbuildrpmbuild xymon-4.3.30/xymond/webfiles/critical_header0000664000076400007640000000241413446110526021351 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Current Critical Systems
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/columndoc_footer0000777000076400007640000000000013534041775025115 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/event_form0000664000076400007640000001364611535462534020432 0ustar rpmbuildrpmbuild
Starting minutes ago ( Default 1440 )
 - OR - 
From: (ccyy/mm/dd@hh:mm:ss)
To: (ccyy/mm/dd@hh:mm:ss)


Max # of events   ( Default 100 )
Hosts to match   ( ex: ^host.*$ )
Hosts to skip   ( ex: ^host.*$ )
Pages to match  
Pages to skip   ( ex: ^webservers/.*$ )
Tests to match   ( ex: cpu|vmstat )
Tests to skip   ( ex: cpu|vmstat )
Colors to match   ( ex: red|green )
Ignore dialup hosts    


xymon-4.3.30/xymond/webfiles/perfdata_form0000664000076400007640000000776211535424634021100 0ustar rpmbuildrpmbuild
Hosts to match   ( ex: ^host.*$ )
Hosts to skip   ( ex: ^host.*$ )
Pages to match  
Pages to skip   ( ex: ^webservers/.*$ )
Start time   ( ex: 2009/01/15 )
End time   ( ex: 2009/02/01 )
 
Format    
Custom RRD filename    
Custom dataset    


xymon-4.3.30/xymond/webfiles/snapnormal_header0000664000076400007640000000237613446110526021740 0ustar rpmbuildrpmbuild Xymon Snapshot Report : &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Snapshot Report
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/acknowledge_footer0000777000076400007640000000000013534041775025415 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/maint_form0000664000076400007640000001440712277125340020410 0ustar rpmbuildrpmbuild
Current StatusSelect what to Disable
&DISABLELIST
Currently disabled tests
 
&SCHEDULELIST
Scheduled actions
HostsTests 
 
Filter hostlist
Hostname pattern
Pagename pattern
IP address pattern
Class pattern
 
Cause: 
Disable for   
Disable until
    - OR - until OK:
 
Disable now
Schedule disable at
 
   Preview
xymon-4.3.30/xymond/webfiles/report_form_daily0000664000076400007640000000155111415724561021774 0ustar rpmbuildrpmbuild
Xymon Daily Availability Report






xymon-4.3.30/xymond/webfiles/snapnongreen_header0000664000076400007640000000221713446110526022255 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Snapshot &XYMONBODYHEADER
 
&XYMONLOGO
Snapshot - All non-green Systems
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/stdnormal_footer0000664000076400007640000000143313441565171021635 0ustar rpmbuildrpmbuild


Xymon &XYMONDREL
&XYMONBODYFOOTER xymon-4.3.30/xymond/webfiles/replog_footer0000777000076400007640000000000013534041775024422 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/confreport_footer0000664000076400007640000000002111070452713021774 0ustar rpmbuildrpmbuild xymon-4.3.30/xymond/webfiles/critedit_form0000664000076400007640000000775311535462534021122 0ustar rpmbuildrpmbuild
Edit Critical Systems

Host:  Test: 
Last update by: &CRITEDITUPDINFO

Priority: 
 
Monitoring time:   from     to  
Start monitoring    
Stop monitoring    
 
Resolver group: 
Instruction: 
 
 
   Even if it has clones:

Clones of this host: Clone this host to:



xymon-4.3.30/xymond/webfiles/snapnongreen_footer0000777000076400007640000000000013534041775025627 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/graphs_footer0000777000076400007640000000000013534041775024416 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/ghosts_footer0000777000076400007640000000000013534041775024441 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/trends_form0000664000076400007640000001633212050700657020575 0ustar rpmbuildrpmbuild
Trends period

Days:  Hours:  Minutes:  Seconds: 
 - OR - 
From: (ccyy/mm/dd@hh:mm:ss)
To: (ccyy/mm/dd@hh:mm:ss)
Show last
Show last
Show this

xymon-4.3.30/xymond/webfiles/hostlist_form0000664000076400007640000000360111535462534021150 0ustar rpmbuildrpmbuild
Page

Select
 Hosts w/ client  Hosts w/ ping  All hosts

Include
Page path
Comment
Downtime
NK columns
NK time
SLA period
SLA level
Network

 
xymon-4.3.30/xymond/webfiles/info_header0000664000076400007640000000574113446110526020520 0ustar rpmbuildrpmbuild Xymon - &XYMWEBHOST Host Information &XYMONBODYHEADER
 
&XYMONLOGO
&XYMWEBHOST - Information
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/trends_header0000664000076400007640000000237413446110526021063 0ustar rpmbuildrpmbuild Xymon - &XYMWEBHOST Host Trends &XYMONBODYHEADER
 
&XYMONLOGO
&XYMWEBHOST - Trends
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/critmulti_header0000664000076400007640000000274013446110526021575 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Current Critical Systems
&XYMWEBDATE

 
&DIVIDERTEXT
 
xymon-4.3.30/xymond/webfiles/chpasswd_footer0000777000076400007640000000000013534041775024746 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/divider_footer0000664000076400007640000000001311630352060021236 0ustar rpmbuildrpmbuild

xymon-4.3.30/xymond/webfiles/useradm_header0000664000076400007640000000215413446110526021220 0ustar rpmbuildrpmbuild Xymon - Manage Users &XYMONBODYHEADER
 
&XYMONLOGO
Manage Users
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/useradm_footer0000777000076400007640000000000013534041775024572 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hostsvc_header0000664000076400007640000000265413446110526021256 0ustar rpmbuildrpmbuild &XYMWEBCOLOR : Xymon - &XYMWEBSVC status for &XYMWEBHOST (&XYMWEBIP) @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
&XYMWEBHOST - &XYMWEBSVC
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/info_footer0000777000076400007640000000000013534041775024065 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/confreport_header0000664000076400007640000000030413446110526021734 0ustar rpmbuildrpmbuild Xymon configuration Report xymon-4.3.30/xymond/webfiles/findhost_footer0000777000076400007640000000000013534041775024750 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hist_footer0000777000076400007640000000000013534041775024101 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/snapnormal_footer0000777000076400007640000000000013534041775025304 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/perfdata_header0000664000076400007640000000233113446110526021343 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Performance data @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Performance data
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/snapcritical_header0000664000076400007640000000223013446110526022227 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Snapshot @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Snapshot - Critical Systems
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/findhost_header0000664000076400007640000000246713446110526021405 0ustar rpmbuildrpmbuild Xymon - Find Host &XYMONBODYHEADER
 
&XYMONLOGO
Find Host
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/report_footer0000777000076400007640000000000013534041775024445 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/perfdata_footer0000777000076400007640000000000013534041775024720 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/critedit_footer0000777000076400007640000000000013534041775024741 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/replog_header0000664000076400007640000000226313446110526021051 0ustar rpmbuildrpmbuild Xymon Availability Report : &XYMWEBHOST - &XYMWEBSVC &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Availability
&XYMWEBHOST - &XYMWEBSVC
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/acknowledge_header0000664000076400007640000000216613446110526022046 0ustar rpmbuildrpmbuild Xymon - Acknowledge Alert &XYMONBODYHEADER
 
&XYMONLOGO
Acknowledge Alert
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/event_footer0000777000076400007640000000000013534041775024253 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/chpasswd_header0000664000076400007640000000216113446110526021372 0ustar rpmbuildrpmbuild Xymon - Change Password &XYMONBODYHEADER
 
&XYMONLOGO
Change Password
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/useradm_form0000664000076400007640000000155211074633713020737 0ustar rpmbuildrpmbuild
Username: Password:

 
xymon-4.3.30/xymond/webfiles/hostgraphs_footer0000777000076400007640000000000013534041775025314 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/stdnongreen_header0000664000076400007640000000241513446110526022106 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Current non-green Systems
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/maint_header0000664000076400007640000001113013446110526020662 0ustar rpmbuildrpmbuild Xymon - Maintenance &XYMONBODYHEADER
 
&XYMONLOGO
Maintenance
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/stdcritical_header0000664000076400007640000000241413446110526022064 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Current Critical Systems
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/acknowledgements_form0000664000076400007640000001373212503132277022631 0ustar rpmbuildrpmbuild
Starting minutes ago ( Default 1440 )
 - OR - 
From: (ccyy/mm/dd@hh:mm:ss)
To: (ccyy/mm/dd@hh:mm:ss)


Max # of acknowledgements   ( Default 100 )
Hosts to match   ( ex: ^host.*$ )
Hosts to skip   ( ex: ^host.*$ )
Pages to match  
Pages to skip   ( ex: ^webservers/.*$ )
Tests to match   ( ex: cpu|vmstat )
Tests to skip   ( ex: cpu|vmstat )
Operators to match   ( ex: admin@test.com )
Operators to skip   ( ex: admin@test.com )


xymon-4.3.30/xymond/webfiles/snapshot_header0000664000076400007640000000216213446110526021416 0ustar rpmbuildrpmbuild Xymon - Snapshot Report &XYMONBODYHEADER
 
&XYMONLOGO
Snapshot Report
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/ghosts_header0000664000076400007640000000215613446110526021071 0ustar rpmbuildrpmbuild Xymon - Ghost Clients &XYMONBODYHEADER
 
&XYMONLOGO
Ghost Clients
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/notify_header0000664000076400007640000000233113446110526021065 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Notification Log @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Notification Log
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/topchanges_header0000664000076400007640000000234413446110526021714 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Top Changes @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Most changing hosts and services
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/topchanges_footer0000777000076400007640000000000013534041775025265 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hostsvc_footer0000777000076400007640000000000013534041775024623 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/notify_form0000664000076400007640000001372311535462534020615 0ustar rpmbuildrpmbuild
Starting minutes ago ( Default 1440 )
 - OR - 
From: (ccyy/mm/dd@hh:mm:ss)
To: (ccyy/mm/dd@hh:mm:ss)


Max # of notifications   ( Default 100 )
Hosts to match   ( ex: ^host.*$ )
Hosts to skip   ( ex: ^host.*$ )
Pages to match  
Pages to skip   ( ex: ^webservers/.*$ )
Tests to match   ( ex: cpu|vmstat )
Tests to skip   ( ex: cpu|vmstat )
Recipients to match   ( ex: admin@test.com )
Recipients to skip   ( ex: admin@test.com )


xymon-4.3.30/xymond/webfiles/snapcritical_footer0000777000076400007640000000000013534041775025606 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/trends_footer0000777000076400007640000000000013534041775024431 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/findhost_form0000664000076400007640000000161311070452713021106 0ustar rpmbuildrpmbuild

Pattern to look for

Case Sensitive        Jump to page       
xymon-4.3.30/xymond/webfiles/stdnongreen_footer0000777000076400007640000000000013534041775025460 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/report_form0000664000076400007640000000275511415724561020621 0ustar rpmbuildrpmbuild
Xymon Availability Report

- to -




xymon-4.3.30/xymond/webfiles/snapshot_footer0000777000076400007640000000000013534041775024771 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/acknowledgements_footer0000777000076400007640000000000013534041775026464 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/critack_form0000664000076400007640000000323212263613340020707 0ustar rpmbuildrpmbuild
Priority Resolver group Documentation
&CRITACKTTPRIO &CRITACKTTGROUP Host info
Host docs
&CRITACKTTEXTRA
  Host-ack   
xymon-4.3.30/xymond/webfiles/critedit_header0000664000076400007640000000220213446110526021361 0ustar rpmbuildrpmbuild Xymon - Critical Systems editor &XYMONBODYHEADER
 
&XYMONLOGO
Critical Systems editor
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/divider_header0000664000076400007640000000041011630352060021171 0ustar rpmbuildrpmbuild
 
&DIVIDERTEXT
 
xymon-4.3.30/xymond/webfiles/acknowledgements_header0000664000076400007640000000233713446110526023115 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Acknowledgement Log @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Acknowledgement Log
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/snapshot_form0000664000076400007640000000177711415724561021150 0ustar rpmbuildrpmbuild
Xymon Snapshot Report






xymon-4.3.30/xymond/webfiles/confreport_back0000664000076400007640000000000011070452713021373 0ustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/report_form_monthly0000664000076400007640000000144411415724561022365 0ustar rpmbuildrpmbuild
Xymon Monthly Availability Report






xymon-4.3.30/xymond/webfiles/chpasswd_form0000664000076400007640000000217012615453444021113 0ustar rpmbuildrpmbuild
Current Username:
Existing Password:
New Password:
Repeat New Password:
xymon-4.3.30/xymond/webfiles/stdcritical_footer0000777000076400007640000000000013534041775025437 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/event_header0000664000076400007640000000231113446110526020674 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Eventlog @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Eventlog
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/stdnormal_header0000664000076400007640000000260313446110526021562 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Status @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
Current Status
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/hostlist_header0000664000076400007640000000215613446110526021433 0ustar rpmbuildrpmbuild Xymon - List of Hosts &XYMONBODYHEADER
 
&XYMONLOGO
List of Hosts
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/columndoc_header0000664000076400007640000000217713446110526021550 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - Documentation &XYMONBODYHEADER
 
&XYMONLOGO
Column Info
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/hist_header0000664000076400007640000000243513446110526020531 0ustar rpmbuildrpmbuild &XYMWEBBACKGROUND : Xymon - History @ &XYMWEBDATE &XYMONBODYHEADER
 
&XYMONLOGO
History
&XYMWEBHOST - &XYMWEBSVC
&XYMWEBDATE


xymon-4.3.30/xymond/webfiles/repnormal_footer0000777000076400007640000000000013534041775025131 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hostlist_footer0000777000076400007640000000000013534041775025003 2stdnormal_footerustar rpmbuildrpmbuildxymon-4.3.30/xymond/webfiles/hostgraphs_form0000664000076400007640000000371012615641657021467 0ustar rpmbuildrpmbuild
Metrics Report

- to -






xymon-4.3.30/xymond/webfiles/topchanges_form0000664000076400007640000001473111535462534021440 0ustar rpmbuildrpmbuild
From: (ccyy/mm/dd@hh:mm:ss)
To: (ccyy/mm/dd@hh:mm:ss)


Hosts to match   ( ex: ^host.*$ )
Hosts to skip   ( ex: ^host.*$ )
Pages to match  
Pages to skip   ( ex: ^webservers/.*$ )
Tests to match   ( ex: cpu|vmstat )
Tests to skip   ( ex: cpu|vmstat )
Colors to match   ( ex: red|green )
Only Critical systems     Ignore dialup hosts    
Rank by    
Show top    


xymon-4.3.30/xymond/webfiles/critical_footer0000664000076400007640000000456411623437505021433 0ustar rpmbuildrpmbuild
Priority Color Age Acked Eventlog  



Xymon &XYMONDREL
&XYMONBODYFOOTER xymon-4.3.30/xymond/xymond_channel.80000664000076400007640000000673113534041733017632 0ustar rpmbuildrpmbuild.TH XYMOND_CHANNEL 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymond_channel \- Feed a xymond channel to a worker module .SH SYNOPSIS .B "xymond_channel --channel=CHANNEL [options] workerprogram [worker-options]" .SH DESCRIPTION xymond_channel hooks into one of the .I xymond(8) channels that provide information about events occurring in the Xymon system. It retrieves messages from the xymond daemon, and passes them on to the \fBworkerprogram\fR on the STDIN (file descripter 1) of the worker program. Worker programs can then handle messages as they like. A number of worker programs are shipped with xymond, e.g. .I xymond_filestore(8) .I xymond_history(8) .I xymond_alert(8) .I xymond_rrd(8) If you want to write your own worker module, a sample worker module is provided as part of the xymond distribution in the xymond_sample.c file. This illustrates how to easily fetch and parse messages. .SH OPTIONS xymond_channel accepts a few options. .IP "--channel=CHANNELNAME" Specifies the channel to receive messages from, only one channel can be used. This option is required. The following channels are available: .br "status" receives all Xymon status- and summary-messages .br "stachg" receives information about status changes .br "page" receives information about statuses triggering alerts .br "data" receives all Xymon "data" messages .br "notes" receives all Xymon "notes" messages .br "enadis" receives information about hosts being disabled or enabled. .IP "--filter=EXPRESSION" EXPRESSION is a Perl-compatible regular expression. xymond_channel will match the first line of each message against this expression, and silently drops any message that does not match the expression. Especially useful for custom worker modules and during testing, to limit the amount of data that the module must process. .br Note that messages for "logrotate", "shutdown", "drophost", "renamehost", "droptest" and "renametest" are always forwarded by xymond_channel, whether they match the filter or not. .IP "--msgtimeout=TIMEOUT" Modify the default timeout (30 seconds) for the worker module to handle a message. If a message is not handled within this time, it is considered lost. You normally do not have to modify this unless you have an extremely busy server. .IP "--daemon" xymond_channel is normally started by .I xymonlaunch(8) as a task defined in the .I tasks.cfg(5) file. If you are not using xymonlaunch, then starting xymond_channel with this option causes it to run as a stand-alone background task. .IP "--pidfile=FILENAME" If running as a stand-alone daemon, xymond_channel will save the process-ID of the daemon in FILENAME. This is useful for automated startup- and shutdown- scripts. .IP "--env=FILENAME" Loads the environment variables defined in FILENAME before starting xymond_channel. This is normally used only when running as a stand-alone daemon; if xymond_channel is started by xymonlaunch, then the environment is controlled by the task definition in the .I tasks.cfg(5) file. .IP "--log=FILENAME" Redirect output to this log-file. .IP "--md5 / --no-md5" Enable/disable checksumming of messages passed from xymond_channel to the worker module. This may be useful if you suspect that data may be corrupted, e.g. when sent to a remote worker module. Note that enabling this may break communication with old versions of Xymon worker modules. Default: Disabled. .IP "--debug" Enable debugging output. .SH FILES This program does not use any configuration files. .SH "SEE ALSO" xymond(8), xymon(7) xymon-4.3.30/CREDITS0000664000076400007640000000331713461631306014232 0ustar rpmbuildrpmbuildThe following people have contributed to the development of Xymon, Hobbit, bbgen and the bbtest tools, by helping me with testing, suggesting new features or improvements, pointing out bugs, or even coming up with patches. I am very grateful for their help. Marco Avvisano Paul Backer Axel Beckert Olivier Beau Adamets Bluejay Brian Buchanan Massimo Carnevali Japheth Cleaver Stef Coene Craig Cook Douwe Dijkstra Francesco Duranti Lars Ebeling Mark Felder David Ferrest Franco Gasperino Tom Georgoulias Laurent Grilli Kevin Hanrahan John Horne Malcolm Hunter Knud Højgaard Asif Iqbal Charles Jones Thomas J Jones Uwe Kirbach Joshua Krause Jeremy Laidman Patrick Lin Brian Lynch Werner Maier Thomas Mattsson Daniel J McDonald Werner Michels Christian Perrier Jure Peternel William Richardson Torsten Richter Chris Ricker Tim Rotunda Thomas Rucker Mirko Saam Thomas Schäfer Tom Schmidt Eric Schwimmer Bill Simaz Andy Smith Bernard Spil Gavin Stone-Tolcher Jeff Stoner David Stuffle Christian Thibodeau John Thurston Rick Waegner Rob Watson Several others have contributed bug reports and helped with testing the beta releases - Xymon would not be as good as it is without their efforts. It would have been hard to implement Xymon without the existing libraries for lots of stuff: libCURL (although this is no longer used, it was quite important while it was in use) http://curl.haxx.se/ Daniel Steenberg and others libCARES Based on the ARES library by Greg Hudson of MIT, C-ARES provides asynchronous parallel DNS lookups. http://c-ares.haxx.se/ Greg Hudson, Daniel Steenberg and others RRDtool http://oss.oetiker.ch/rrdtool/ OpenSSL http://www.openssl.org/ OpenLDAP http://www.openldap.org/ PCRE http://www.pcre.org/ xymon-4.3.30/build/0000775000076400007640000000000013534041774014312 5ustar rpmbuildrpmbuildxymon-4.3.30/build/Makefile.test-ssl30000664000076400007640000000034412674126516017615 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(OSSLINC) -o test-ssl3.o -c test-ssl3.c test-link: @$(CC) $(CFLAGS) $(OSSLLIB) -o test-ssl3 test-ssl3.o -lssl -lcrypto $(NETLIBS) clean: @rm -f test-ssl3.o test-ssl3 xymon-4.3.30/build/bb-commands.sh0000775000076400007640000000243611535462534017040 0ustar rpmbuildrpmbuild#!/bin/sh # $Id: bb-commands.sh 6650 2011-03-08 17:20:28Z storner $ # Script to pick up most of the commands used by BB extension scripts. # This is used during installation, to build a xymonserver.cfg that # includes these commands so that extension scripts can run from # xymonserver.cfg without having to do special setups. findbin() { MYP="`echo ${PATH} | sed -e 's/:/ /g'`" for D in $MYP do if test -x $D/$1; then echo "${D}/${1}" fi done } echo "" echo "# The following defines a bunch of commands that BB extensions expect to be present." echo "# Xymon does not use them, but they are provided here so if you use BB extension" echo "# scripts, then they will hopefully run without having to do a lot of tweaking." echo "" for CMD in uptime awk cat cp cut date egrep expr find grep head id ln ls mv rm sed sort tail top touch tr uniq who do ENVNAME=`echo $CMD | tr "[a-z]" "[A-Z]"` PGM=`findbin $CMD | head -n 1` echo "${ENVNAME}=\"${PGM}\"" done # WC is special PGM=`findbin wc | head -n 1` echo "WC=\"${PGM} -l\"" echo "WCC=\"${PGM}\"" # DFCMD is an alias for DF PGM=`findbin df | head -n 1` echo "# DF,DFCMD and PS are for compatibility only, NOT USED by the Xymon client" echo "DF=\"${PGM} -Pk\"" echo "DFCMD=\"${PGM} -Pk\"" echo "PS=\"ps ax\"" echo "" echo "MAXLINE=\"32768\"" xymon-4.3.30/build/test-uname.c0000664000076400007640000000040712523024624016531 0ustar rpmbuildrpmbuild#include #include #include int main(int argc, char *argv[]) { struct utsname u_name; if (uname(&u_name) == -1) return -1; printf("system name is: %s, node name is %s\n", u_name.sysname, u_name.nodename); return 0; } xymon-4.3.30/build/test-sysselecth.c0000664000076400007640000000023711070452713017613 0ustar rpmbuildrpmbuild#include #include #include #include #include int main(int argc, char *argv[]) { return 0; } xymon-4.3.30/build/Makefile.NetBSD0000664000076400007640000000161212006166517017024 0ustar rpmbuildrpmbuild# Xymon compile-time settings for NetBSD systems # From Emmanuel Dreyfus. # OSDEF = -DBSD # NETLIBS: None needed NETLIBS = # # Compile flags for normal build PKGDIR?=/usr/pkg CC= gcc GCCVER := $(shell gcc -dumpversion|cut -d. -f1) ifeq ($(GCCVER),4) CFLAGS = -g -O2 -Wall -Wno-unused -Wno-pointer-sign -D_REENTRANT $(LFSDEF) $(OSDEF) \ -I${PKGDIR}/include -L${PKGDIR}/lib, -Wl,--rpath=${PKGDIR}/lib else CFLAGS = -g -O2 -Wall -Wno-unused -D_REENTRANT $(LFSDEF) $(OSDEF) \ -I${PKGDIR}/include -L${PKGDIR}/lib, -Wl,--rpath=${PKGDIR}/lib endif RPATH = "-Wl,--rpath," # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) \ -I${PKGDIR}/include -L${PKGDIR}/lib, -Wl,--rpath=${PKGDIR}/lib # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/dorelease.sh0000775000076400007640000000034312277655770016626 0ustar rpmbuildrpmbuild#!/bin/sh VERSION="$1" if [ "$VERSION" = "" ] then echo "$0 VERSION" exit 1 fi ./build/generate-md5.sh >build/md5.dat.new mv build/md5.dat.new build/md5.dat ./build/updmanver $VERSION ./build/makehtml.sh $VERSION exit 0 xymon-4.3.30/build/convert-bbservices0000775000076400007640000000070611535462534020050 0ustar rpmbuildrpmbuild#!/bin/sh # Script to convert a bbgen v3 protocols.cfg file to the # [NAME] section delimited format used in Xymon v4 (starting with RC3). FN="$1" if test ! -r "${FN}"; then exit 0; fi sed -e 's/^service \(.*\)/\[\1\]/' < "${FN}" >"${FN}.converted" cmp -s "${FN}" "${FN}.converted" if test $? -eq 0; then rm -f "${FN}.converted"; exit 0; fi if test -f "${FN}.v3"; then rm -f "${FN}.v3"; fi mv "${FN}" "${FN}.v3" mv "${FN}.converted" "${FN}" exit 0 xymon-4.3.30/build/Makefile.GNU0000664000076400007640000000156213460440436016402 0ustar rpmbuildrpmbuild# Xymon compile-time settings for GNU (Hurd) systems OSDEF = -DLINUX # NETLIBS: None needed NETLIBS = # Compile flags for normal build CC = gcc CFLAGS += -g -O2 -Wall -Wno-unused -D_REENTRANT $(LFSDEF) $(OSDEF) ifndef PKGBUILD RPATH = -Wl,--rpath, endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # For profiling # CFLAGS = -g -pg -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Note: Do 'export GMON_OUT_PREFIX=/var/tmp/FILENAME' to save profiling output in /var/tmp # Use gprof to analyse # By default, Xymon uses a static library for common code. # To save some diskspace and run-time memory, you can use a # shared library by un-commenting this. # XYMONLIBRARY=libxymon.so # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/Makefile.GNU_kFreeBSD0000664000076400007640000000155513457402722020053 0ustar rpmbuildrpmbuild# Xymon compile-time settings for GNU/kFreeBSD systems OSDEF = # NETLIBS: None needed NETLIBS = # Compile flags for normal build CC = gcc CFLAGS += -g -O2 -Wall -Wno-unused -D_REENTRANT $(LFSDEF) $(OSDEF) ifndef PKGBUILD RPATH = -Wl,--rpath, endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # For profiling # CFLAGS = -g -pg -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Note: Do 'export GMON_OUT_PREFIX=/var/tmp/FILENAME' to save profiling output in /var/tmp # Use gprof to analyse # By default, Xymon uses a static library for common code. # To save some diskspace and run-time memory, you can use a # shared library by un-commenting this. # XYMONLIBRARY=libxymon.so # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/Makefile.SCO_SV0000664000076400007640000000122512006166517017001 0ustar rpmbuildrpmbuild# Xymon compile-time settings for SCO_SV (tested on SCO_SV 5.0.5 i386) OSDEF = -DSCO_SV # SCO_SV need this NETLIBS = -lsocket -lnsl # Compile flags for normal build CC = gcc GCCVER := $(shell gcc -dumpversion|cut -d. -f1) ifeq ($(GCCVER),4) CFLAGS = -g -O2 -Wall -Wno-unused -Wno-pointer-sign -D_REENTRANT $(LFSDEF) $(OSDEF) else CFLAGS = -g -O2 -Wall -Wno-unused -D_REENTRANT $(LFSDEF) $(OSDEF) endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mailx" xymon-4.3.30/build/test-ssl2.c0000664000076400007640000000064012000050736016277 0ustar rpmbuildrpmbuild#include #include #include #include #include #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x00905000L) #error SSL-protocol testing requires OpenSSL version 0.9.5 or later #endif int main(int argc, char *argv[]) { SSL_CTX *ctx; SSL_library_init(); ctx = SSL_CTX_new(SSLv2_client_method()); return 0; } xymon-4.3.30/build/test-vsnprintf.c0000664000076400007640000000067511070452713017464 0ustar rpmbuildrpmbuild#include #include #include #include #include #include #include #include void errprintf(const char *fmt, ...) { char msg[4096]; va_list args; va_start(args, fmt); vsnprintf(msg, sizeof(msg), fmt, args); va_end(args); } int main(int argc, char *argv[]) { errprintf("testing ... %d %d %d\n", 1, 2, 3); return 0; } xymon-4.3.30/build/clock-gettime-librt.sh0000775000076400007640000000120712003325253020475 0ustar rpmbuildrpmbuild echo "Checking for clock_gettime() requiring librt ..." LIBRTDEF="" cd build OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-clockgettime-librt clean OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-clockgettime-librt test-link 1>/dev/null 2>&1 if [ $? -ne 0 ]; then OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-clockgettime-librt test-link-rt 1>/dev/null 2>&1 if [ $? -eq 0 ]; then echo "clock_gettime() requires librt" LIBRTDEF="-lrt" else echo "clock_gettime() not present, but this should be OK" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-clockgettime-librt clean fi cd .. xymon-4.3.30/build/test-rrd.c0000664000076400007640000000124611535462534016225 0ustar rpmbuildrpmbuild#include #include int main(int argc, char *argv[]) { char *rrdargs[] = { "rrdgraph", "xymongen.png", "-s", "e - 48d", "--title", "xymongen runtime last 48 days", "-w576", "-v", "Seconds", "-a", "PNG", "DEF:rt=xymongen.rrd:runtime:AVERAGE", "AREA:rt#00CCCC:Run Time", "COMMENT: Timestamp", NULL }; char **calcpr=NULL; int pcount, result, xsize, ysize; double ymin, ymax; for (pcount = 0; (rrdargs[pcount]); pcount++); rrd_clear_error(); #ifdef RRDTOOL12 result = rrd_graph(pcount, rrdargs, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax); #else result = rrd_graph(pcount, rrdargs, &calcpr, &xsize, &ysize); #endif return 0; } xymon-4.3.30/build/snmp.sh0000775000076400007640000000050111070452713015612 0ustar rpmbuildrpmbuild echo "Checking for Net-SNMP ..." SNMPINC="" SNMPLIB="" VERSION=`net-snmp-config --version` if test $? -eq 0 then echo "Found Net-SNMP version $VERSION" DOSNMP=yes else sleep 3 echo "Could not find Net-SNMP (net-snmp-config command fails)" echo "Continuing with SNMP support disabled." DOSNMP=no fi xymon-4.3.30/build/md5.dat0000664000076400007640000006657513515623702015510 0ustar rpmbuildrpmbuildmd5:2aef75abd6973d322c5ab1b1d52d2a4f webfiles/acknowledge_form md5:a76f9c67d39286495adf558ba7f4a412 webfiles/acknowledge_form md5:c763137d2728671f4e34af9b213cfd63 webfiles/acknowledge_form md5:205e90ad0bd8da45eaf60af92af3671c webfiles/acknowledge_header md5:43351eb1cf5732e0d03fdc79fd35c8b4 webfiles/acknowledge_header md5:497b4840642f76ac9c79ec8cde7683e3 webfiles/acknowledge_header md5:5c8e8c31770e200a2874a3065bac7b69 webfiles/acknowledge_header md5:6d850290b2b67c67d93ab11dbd33ed40 webfiles/acknowledge_header md5:8a9daf4a620fd82b40f375823a1dd4a8 webfiles/acknowledge_header md5:ad88b18efcc32c2cfcb9b3b7835b5aaf webfiles/acknowledge_header md5:d79fb47e79f7d29d51a7325a9d243a7a webfiles/acknowledge_header md5:db9a4cba68249970f061f3d96ecd3eb9 webfiles/acknowledge_header md5:e81bf64853683dc48ac1daa8be2dc4c8 webfiles/acknowledge_header md5:f5fff2638b80aa0b05f7dc6f53551e44 webfiles/acknowledge_header md5:373e21f4981ec788d84bebb524879ecb webfiles/acknowledgements_form md5:4d6fc228e6d1357da31860c81ed221cf webfiles/acknowledgements_header md5:c92c811a597b27efe580877008e847a4 webfiles/acknowledgements_header md5:0a6a33b186d06ea3b1ce20dd2da0e28e webfiles/bb2_header md5:493c4d72368efb374e5f3009097eb922 webfiles/bb2_header md5:4dedb331a60d9c8e253e3db341722812 webfiles/bb2_header md5:57ce6cc343e9de8a42e4ad34ac348ea8 webfiles/bb2_header md5:64c4e1eff77b5d76eccf58a90fdde99e webfiles/bb2_header md5:c7dd652fac52bae36584391f66e06346 webfiles/bb2_header md5:f012d6c2991d25ca65df1cfd2dbbc920 webfiles/bb2_header md5:679ecf0460d9ee066b53703edfb45bf5 webfiles/bb_footer md5:b927ca734b83973f47762278b1015d32 webfiles/bb_footer md5:c8564c73cec7da1e297ba94ed56f693a webfiles/bb_footer md5:d507ae62602354e576423a7216e875fa webfiles/bb_footer md5:dab9ebea0665fc43eb5beb70d4a02756 webfiles/bb_footer md5:474bc71541cb592df74511a22863cc86 webfiles/bb_header md5:4ac5d2b7f12e01ac6d474a9a3ebd19ce webfiles/bb_header md5:55546fa53e7cef87d5161132376a4dd5 webfiles/bb_header md5:b4faefac3b7b3bf2687ff86b567c616f webfiles/bb_header md5:c9fc71f108007688f15b583aa36fda39 webfiles/bb_header md5:d53ac4c4d96c82c0a03e77cc0d3ae99e webfiles/bb_header md5:e39355b7be74b49b49f8cf0650f43284 webfiles/bb_header md5:1d9e995b3778cf2c40529b47a7af8739 webfiles/bbnk_header md5:5035b17fa863349fdf2ed10524f1e753 webfiles/bbnk_header md5:9094360854ab61a4d2f035a4108ae8c9 webfiles/bbnk_header md5:a3f93fea81ac47b1d78706f6dd0689fc webfiles/bbnk_header md5:b33729d38c73e2ce04514c30a0058f20 webfiles/bbnk_header md5:eb11ca199fb132916136d85ea2237068 webfiles/bbnk_header md5:ebefec59449af568839fd4c3b99c944a webfiles/bbnk_header md5:2fae67a97ac7d2dd1d029416dff48389 webfiles/bbrep_header md5:6a896754a4a7980674c15d42e1f10ba7 webfiles/bbrep_header md5:811f9be38e8554d21d368b1a1097e923 webfiles/bbrep_header md5:9ba890901af2d23bd9344f7a720a43b9 webfiles/bbrep_header md5:d03f2266e60ad6f88e5df878492133bd webfiles/bbrep_header md5:eb6fefe16aade1408f3956ef2c918d9e webfiles/bbrep_header md5:fe409202eed8f8f3f2fffbe35d14820b webfiles/bbrep_header md5:6a801ecc0819d2d5c505945f367b670c webfiles/bbsnap2_header md5:6cecb03deb4f505479e1f2cf582c3bf4 webfiles/bbsnap2_header md5:90f22e6c2933c95417a1d4a060194386 webfiles/bbsnap2_header md5:059a4404abd26025c43111e1f2d83baf webfiles/bbsnap_header md5:77ff5d11d89b6e4b125289e2de15efc6 webfiles/bbsnap_header md5:801e80f099c190002847b20def4a0ec8 webfiles/bbsnap_header md5:8174f9bc6eb7d8c4019331c356b7c83b webfiles/bbsnap_header md5:83c5980f3af0548d7aed029711a67f9d webfiles/bbsnap_header md5:abd6b4accb9cb39e3e4491a8c0905623 webfiles/bbsnap_header md5:4accea67f8fb44aeea4c58c2e70ec6a0 webfiles/bbsnapnk_header md5:d5fd55e8fd8caa675dc2bda3f2d886a6 webfiles/bbsnapnk_header md5:fe3e7e17ff71f189bf5bae2bf924fd16 webfiles/bbsnapnk_header md5:9cc913e3c6403b67cadd2add56e168e3 webfiles/chpasswd_form md5:a724ea2aed2b04a17e57b5c4deaa027a webfiles/chpasswd_header md5:d4efd5ffc214b3719e384f2a6e112b70 webfiles/chpasswd_header md5:023a7ee2e6267b8bb5f84951ff2e14ef webfiles/columndoc_header md5:40c8ae5d3477449c630110677964ac3d webfiles/columndoc_header md5:488cdd7334c3eb9c193862abb37e7d3e webfiles/columndoc_header md5:4db0e94127a7a106bb9b0a7d868b0b48 webfiles/columndoc_header md5:78891f699ad3f376f67b0e61b0682ebb webfiles/columndoc_header md5:7e183c7cb5b8ce1b05733f9c5f60ecee webfiles/columndoc_header md5:800a70147c90c0f8657969d2536d8fc2 webfiles/columndoc_header md5:b404bcecd8e569afa285a20062d94e6b webfiles/columndoc_header md5:de754f14cc93e6e1fa3bc29e32b12244 webfiles/columndoc_header md5:e8abaa53a14b000359bd8efca5efeb29 webfiles/columndoc_header md5:f087d77977baf65f2045407186460693 webfiles/columndoc_header md5:d41d8cd98f00b204e9800998ecf8427e webfiles/confreport_back md5:d921357393ccb03ffaef687bfc2e761f webfiles/confreport_footer md5:24b77246484e86b6518ab935e951f77e webfiles/confreport_front md5:49d391762e953602e903ea6dcb795c79 webfiles/confreport_front md5:704d7803ae223200faf7d88f775addac webfiles/confreport_front md5:1665c44475fe1d35876e5469a2ecaffc webfiles/confreport_header md5:ba20d150c6e40573658a06f42f0594dc webfiles/confreport_header md5:d212a7ad882942aa236e85ef4ed615a9 webfiles/confreport_header md5:179df9ba60e00a47c2bcfce43fe692a3 webfiles/critack_form md5:578c97c324eab20dc9037ed1b5427468 webfiles/critack_form md5:06b49128133a91498bd2e49429ceda25 webfiles/critedit_form md5:49b1da0ac9a006a928a5469d481d1206 webfiles/critedit_header md5:6dd58e48fe7d18233d4cafaf7d3004f4 webfiles/critedit_header md5:c17946f11c129c5cde57fb9620ea1450 webfiles/critedit_header md5:f353bd6812cbe0b401589936a2c3bdd2 webfiles/critedit_header md5:14358551b0e66d351e44fb6b47f11b35 webfiles/critical_footer md5:21db9961013bc43684c4069beda7462b webfiles/critical_footer md5:73ee8e0ee307e0c7647d9cc62811f79d webfiles/critical_footer md5:0a222fda13f6e3f7b4744cb9de2da149 webfiles/critical_header md5:2bd621622835d6184cca9a1296149aaf webfiles/critical_header md5:3b2143d0c4d641504561cb19707d652c webfiles/critical_header md5:c8ea8cc52599e94282ede20509846819 webfiles/critical_header md5:d34d8b055b39a084bebb37cdd93b8651 webfiles/critical_header md5:1a6a567318c13f01ea02e71f2219ec6b webfiles/critmulti_header md5:315a623c40c5938b5c5e747ee633fe38 webfiles/critmulti_header md5:e5b489c2a327657a4a00d5a92d0dcdce webfiles/critmulti_header md5:fe7222ba18aa2f55e71867d310a9c58e webfiles/divider_footer md5:a02584f3d7501468489b2c73b11747ae webfiles/divider_header md5:2b21da4cdd5544a1efd1cb6dbbc12597 webfiles/event_form md5:2cad1811e9d8e08d6677cec8cb7a7578 webfiles/event_form md5:49006fc8f40cac94eca246b2fe5faa97 webfiles/event_form md5:5c7b30b4ab4332c421d674df90ffc4dd webfiles/event_form md5:e48b4c57298510d191d4e25cac276186 webfiles/event_form md5:49c01f3cefeec8d33f3233c216955b0e webfiles/event_header md5:569b0d510a38e0cdc2b711ffbf16266e webfiles/event_header md5:61bde058b46eaed4d9bb394092982953 webfiles/event_header md5:65e553d7a63b1636e857f0901987220a webfiles/event_header md5:79a6d29ab45c7c50ea508c802718ea18 webfiles/event_header md5:7f28375fa8ded2bb7921f5e061d338cc webfiles/event_header md5:982e40879bfcbcc034dc85a9012291e6 webfiles/event_header md5:ba1f75db90350d0435a3456ca346a8cd webfiles/event_header md5:d663673082a6a047c2389e87345e8554 webfiles/event_header md5:fbe38443ac25e9fc8c8d0185a5d8012a webfiles/event_header md5:1ba14ae777f497982d377a8c8bcb4757 webfiles/findhost_form md5:b6a0e5dbd16655e0381987e3273f15a6 webfiles/findhost_form md5:d5bfa8db22b85ffae86b53bff405ba54 webfiles/findhost_form md5:dc043069fbc9d6fbd366118030b999ec webfiles/findhost_form md5:014520c12bad9d3b6813af8caadd72d5 webfiles/findhost_header md5:196ea4f94210b930f963d60e3a9a2413 webfiles/findhost_header md5:290c890f5ea1d83531d1f5d57ca6087b webfiles/findhost_header md5:4d1a15c83fb36c9d08af51c08bf45a40 webfiles/findhost_header md5:5fd00142761f5a35bf551f7a76da4918 webfiles/findhost_header md5:75e229b43ad1ffce9cb82ada92010f4b webfiles/findhost_header md5:7b6271f002bd76509a828d1a1de0fbb5 webfiles/findhost_header md5:882d30d43808e3c3f565dda72b4f7379 webfiles/findhost_header md5:9d332c0401798845e73df7cf623ec4bd webfiles/findhost_header md5:b44092ed93b418463cd3a70de72a4719 webfiles/findhost_header md5:d9264b516ba58f25cd468e24830a28f4 webfiles/findhost_header md5:e6b1dc37b53a84c59f9a4db8740b1faa webfiles/findhost_header md5:1753f139f26a56434563cff9b82ab0c2 webfiles/ghosts_header md5:2a418ce8601d6556975508e06aeee5c4 webfiles/ghosts_header md5:4f5c88a6a3bfb41e57b9801b53ad9c29 webfiles/ghosts_header md5:6c0636a026583b2b1b7f7a188a4316e7 webfiles/ghosts_header md5:6ec27117c57776b55330713fc46f69d0 webfiles/ghosts_header md5:7385028893b6dd65014960bda8587c26 webfiles/ghosts_header md5:c77887553449ea8852989b5af0e43c09 webfiles/ghosts_header md5:13335f1bd9efe02d4fbcc6afcd679a1e webfiles/graphs_header md5:4c95fdb687ff65202afb2d52ba2852e5 webfiles/graphs_header md5:6dc264cc490b1ae66f5277638bf6428f webfiles/graphs_header md5:7475d6cd57634b07d9644a23dd1b0809 webfiles/graphs_header md5:7799acee834dcdf087475295d5ca8620 webfiles/graphs_header md5:86e44561be6cd5f1034261f636ee0260 webfiles/graphs_header md5:8e096f4b332b860bcc6676ab0b324e9a webfiles/graphs_header md5:a800f27856ac7cbab9dc18a2b5a70dc8 webfiles/graphs_header md5:ad27fb97f7a3699fdcd6e0bb1c566d23 webfiles/graphs_header md5:c0556131f57a929ddba5b6534b46c05f webfiles/graphs_header md5:df9f3d1bddb0c235fd5c79f166c64fa7 webfiles/graphs_header md5:01627dccc3a51003b39c8d8186597782 webfiles/hist_header md5:01d77cfe8ce9e630bce443c1f84b67ba webfiles/hist_header md5:0fb000cfe04a0c9e9d256cb1c46a7908 webfiles/hist_header md5:153b0f20cb7955900f9dbce9a8e96806 webfiles/hist_header md5:21633df466936d9127646e294c2da585 webfiles/hist_header md5:297866f9c07f55f6b7428388877734a4 webfiles/hist_header md5:3ef3eeeb8911b8b7f549ebf9914f853b webfiles/hist_header md5:44681e656173a378615b2d92b117215e webfiles/hist_header md5:4e9a8d280a2fe22bdc300ccf099da3ed webfiles/hist_header md5:60134cfc5286371c1f1d3b31b8c6ee25 webfiles/hist_header md5:e3f6247196a3b8d81c96c45849adb955 webfiles/hist_header md5:0743068fd065363cc4f012999fa295c6 webfiles/histlog_header md5:2644ceb1fe529efcdef0f768a66d04fe webfiles/histlog_header md5:4310d90bd4b437a315dc3bf11ea3f086 webfiles/histlog_header md5:492374a6e3ad22db61a1adc85df30b1f webfiles/histlog_header md5:5ace7ed2cb41587f9ad9a96093d6cb8b webfiles/histlog_header md5:5bd4e7b3bf41f1f38d5d209157c1dbf8 webfiles/histlog_header md5:8850587715fcd0a1a7b9ed1c7a7f6f59 webfiles/histlog_header md5:9fbcf8fd18f69b0ac7fb2993d2dd5142 webfiles/histlog_header md5:c2bbba732ce2e66e56bd4f722607e9d6 webfiles/histlog_header md5:d75ab4808d7492c974f7db6765649ec0 webfiles/histlog_header md5:e3aee3404892a5117f79b0c8802a55b3 webfiles/histlog_header md5:43b22c9b2bbe4d19e6f1be5047dcd013 webfiles/hobbitnk_footer md5:834b0816b8ba716e35bed8bab1462a09 webfiles/hobbitnk_footer md5:c37a4c5f3fe8d412cc8002b235126f21 webfiles/hobbitnk_footer md5:d20c72f46d33284ac2006960369f9401 webfiles/hobbitnk_footer md5:1d9e995b3778cf2c40529b47a7af8739 webfiles/hobbitnk_header md5:9094360854ab61a4d2f035a4108ae8c9 webfiles/hobbitnk_header md5:eb11ca199fb132916136d85ea2237068 webfiles/hobbitnk_header md5:04370521e21a8f5e8a7f5a4bd90be710 webfiles/hostgraphs_form md5:12a5a143d0176995da2393c5d921a730 webfiles/hostgraphs_form md5:1a89274a84bcb504ec795efe38790a29 webfiles/hostgraphs_form md5:0b93340f61b0ab8a9679ed63f8fdaf1f webfiles/hostgraphs_header md5:6fbce8b850a2b6f6c11eae3de1780a53 webfiles/hostgraphs_header md5:aedd2c25005ee3967fbcfe3d786919bb webfiles/hostgraphs_header md5:c5bb29b190d16c6ca742989e9a1de086 webfiles/hostgraphs_header md5:dcf906c6360cf53462d068b9ce23f0bd webfiles/hostgraphs_header md5:f40ffcfb250ba6cc7d2c6070bf23e8c0 webfiles/hostgraphs_header md5:fbe1a74ef3ec0dec42087e764ed807f8 webfiles/hostgraphs_header md5:742b6877f8ce89c7f10c99d28ada808b webfiles/hostlist_form md5:9f0b363a4c8519411e99e44726083b59 webfiles/hostlist_form md5:0070575ad3c0e4e3290b8b84aefd7de8 webfiles/hostlist_header md5:2cae7e396594a66894f134432bd83cc7 webfiles/hostlist_header md5:598bbbc38bfc7ba88543850eacf98fdb webfiles/hostlist_header md5:93b82bc3ea9af5e11c59fd8a466558c0 webfiles/hostlist_header md5:a6e156a339770dfaa002cf3ff62d9247 webfiles/hostlist_header md5:cb6a2759593b4ad6e242cfaae5a31dfa webfiles/hostlist_header md5:02e7fc8ea569046453deeb97b5acddc6 webfiles/hostsvc_header md5:1b7a69a900b93d30ef3416360bdd4d7f webfiles/hostsvc_header md5:21f51fbc2b68080bd0c9c2b2b8591fde webfiles/hostsvc_header md5:24c42b758752dd05c889ca4990990712 webfiles/hostsvc_header md5:299af865e1b0cbbf6e74da2d7e383d9e webfiles/hostsvc_header md5:3eae7096b99bdfe104651be21998a56a webfiles/hostsvc_header md5:560cf8fe8dc232a240cd4af8fb4b75fb webfiles/hostsvc_header md5:6dffec4e8d9b920e0635a181969871ea webfiles/hostsvc_header md5:716bff33489a38a2b56ca08b328701a7 webfiles/hostsvc_header md5:b302577baf5e5523e39653fc20224789 webfiles/hostsvc_header md5:c515695830039843ed2eab2ba71b37ac webfiles/hostsvc_header md5:cd6cdc0faa7e7c927893556dfafddc90 webfiles/hostsvc_header md5:04dfb1ba775e198224440bae14ef5d04 webfiles/info_header md5:0fa7f284384cf650788a85f9fd67e80a webfiles/info_header md5:100b94781cee0834b87f920ef9715245 webfiles/info_header md5:2338498e9800f77363e6452fe6ee08a5 webfiles/info_header md5:2afb7ea168587710bcf3a154eab5846c webfiles/info_header md5:2c9fd562e7db17cfc3efe32b4a223059 webfiles/info_header md5:4d6bae7894fa3474ff3b89f89bc4705b webfiles/info_header md5:553d801c12f0ecef0f41192d416ad883 webfiles/info_header md5:60b96f5f65206e650dac7727fc676f66 webfiles/info_header md5:6492e8e810dbfb46e5e7c967fddb892c webfiles/info_header md5:68b104dae211825808194a32f3ad3a05 webfiles/info_header md5:c198e90bc92ccc93c88653b8f11499f2 webfiles/info_header md5:d33a2f0bbdaef3aaa9d9f4a5757978b5 webfiles/info_header md5:02c12f6ad41ac910227d69b73b28e189 webfiles/maintact_header md5:2c243255e690fe983785ba200c28616f webfiles/maintact_header md5:64bc22c385336eaacfd7a6791e330643 webfiles/maintact_header md5:66e68f3b400fd3208713b7a1c7ef1882 webfiles/maintact_header md5:75777a63aa42d7497e3e54f7c27b1af0 webfiles/maintact_header md5:97eac84720003897d2fdeb7471f20805 webfiles/maintact_header md5:c367d4fee01483db265e8e085ad0cb1f webfiles/maintact_header md5:1a5ad876e1e60e8ff8b20f14d18adf33 webfiles/maint_form md5:2228bd803ecddda0c872a55b9bcce38c webfiles/maint_form md5:352b4de71f8e5459322ffb6e84d76e4a webfiles/maint_form md5:a8a0c6187685fdb81d98e46a75751a56 webfiles/maint_form md5:b8ccc42a08ccc98a21323320986a1b8f webfiles/maint_form md5:03b90a406ad8188e0b14d01ac536f3fe webfiles/maint_header md5:31c57123b77c406f0d870eae82ccabb0 webfiles/maint_header md5:379921dfcc1a337ec2077436cebad9f0 webfiles/maint_header md5:3a6e92a359c93e3dda812f23bb56cbed webfiles/maint_header md5:8cf55c31b18c79bea6c19ca10fbe6af7 webfiles/maint_header md5:966b865bbb9c67f71b26aa5dddb87d32 webfiles/maint_header md5:b6d4b7d210f57ce85aef99acab48f84d webfiles/maint_header md5:c242f7f162979c7c9a4cb56ca4c2f687 webfiles/maint_header md5:c412630b335d35f136cf81b5b93d282e webfiles/maint_header md5:c77acb7ab0ed935efbbf52974ae02262 webfiles/maint_header md5:fa4fcc8c6c4eb71ea4e76be8b0ddb881 webfiles/maint_header md5:fad36d4b7d04a94c4bb44ea9adedce9b webfiles/maint_header md5:78a9cd70a37dfa793423ffe5be770434 webfiles/nkack_form md5:f4ad6dfcfc96d8588e8a09b3ef59c90a webfiles/nkack_form md5:1df6c9d0e2a5b8253af64ee4d809ddf9 webfiles/nkedit_form md5:233b4a8fbf6cc513143001267be0adbf webfiles/nkedit_form md5:84c18fac4a57fcce6e5815c30844a86f webfiles/nkedit_form md5:bd794af473b37866b09b4ca590f4e6ed webfiles/nkedit_form md5:448fb5f498b13b7e5f89360003266127 webfiles/nkedit_header md5:a54004eaacf0575e1f7f829d45c406ee webfiles/nkedit_header md5:d2e696ae9cc8243c00e30772d67a92d2 webfiles/nkedit_header md5:ee95fdd7461d7518a41f448b51f0c85d webfiles/nkedit_header md5:679ecf0460d9ee066b53703edfb45bf5 webfiles/notify_footer md5:b927ca734b83973f47762278b1015d32 webfiles/notify_footer md5:660d6e4ae0578496e35178f5dd0382c1 webfiles/notify_form md5:c4e7cd276c4a88a9970594f102d78b18 webfiles/notify_form md5:029d369f57ca69d5fb3397a5a05dd4bc webfiles/notify_header md5:4b531c44a8d1b4d26080917ceb27bf5f webfiles/notify_header md5:64c7882aa785d49c13f77c2146ff2809 webfiles/notify_header md5:ae4db871545396b32f3b1ded6d7199d8 webfiles/notify_header md5:c1df159a27547efaa9587c6252fcef5f webfiles/notify_header md5:c61a13654bf5ad0041e572f50d909af0 webfiles/notify_header md5:e8712f523109b9e24ff46c405c1c1f2c webfiles/notify_header md5:62daa40456f23e6b67469018fd6851d6 webfiles/perfdata_form md5:0fc17291c4a0473908ee696df0c252fd webfiles/perfdata_header md5:88f0b2d8558257191776c7448e7d1b0d webfiles/perfdata_header md5:94f05352f7c2942833ecc1d3a70f312e webfiles/perfdata_header md5:bf74bde923d7f179d57b697b7e2d1d69 webfiles/perfdata_header md5:d59620f735b856fe3419ab49fde0f984 webfiles/perfdata_header md5:1f56f01a99daca0e70434f77d8a0c661 webfiles/replog_header md5:5a5fad279887ab62368651d01f5fa930 webfiles/replog_header md5:a3c57748c6384747d331eecf50f6cb67 webfiles/replog_header md5:b870b82a721d97f8e454d87f206931cb webfiles/replog_header md5:c67be08b9e26df6ff1c497f4148ad812 webfiles/replog_header md5:cec633be45f2dab91210dcfdd6244ebd webfiles/replog_header md5:d930c2e8041d1aa34c2e9a9c58e48666 webfiles/replog_header md5:dda39e97fe87ed5d5487c071d99707a7 webfiles/replog_header md5:de60aa05e19471556c17039bff9013b6 webfiles/replog_header md5:deb80a076dcce05567290f0e13f1aa0f webfiles/replog_header md5:f333ce96b7ba5aa8f1a8382d9b0f44da webfiles/replog_header md5:4bd1e8ef2ffe23017d65e46e746a1d83 webfiles/repnormal_header md5:5469e970c51cdd6417f6230ca1397c24 webfiles/repnormal_header md5:5fbb435afe6127f9d8c32a2679feee9b webfiles/repnormal_header md5:b1c85b082fc7ac1f49e851d3f42626ab webfiles/repnormal_header md5:1600c0858a63f2ea16e31d68c23c1c8d webfiles/report_form md5:1ec8e1e00b792c9d4b893616600c3625 webfiles/report_form md5:22cb2a34475ef16c6ea2d70f74edf448 webfiles/report_form md5:99b1dd3b0e281a3a22a2c5821aaaa0a6 webfiles/report_form md5:c45479931e8863f29071733e267440c3 webfiles/report_form md5:08cd5e23cc5b091fbd54dd99ab970eb9 webfiles/report_form_daily md5:3c2bab1a60aeef54ff6106cabc1fd242 webfiles/report_form_daily md5:e69ae5138ab9134422b3cc96993f5ca2 webfiles/report_form_daily md5:6a91b8d2036878883e8779af9b45244c webfiles/report_form_monthly md5:c6fef48851d5cb736ba8ff4b51317464 webfiles/report_form_monthly md5:f86629e4566ad17fab4559919bd34291 webfiles/report_form_monthly md5:3af281e115975b6f139f3f79899b691d webfiles/report_form_weekly md5:7aa455d83886d52a83d7b24d5993c65d webfiles/report_form_weekly md5:f78dd68561c6d8bcc15f919db08fc1dc webfiles/report_form_weekly md5:0a2e9a98428077f2d653841917394976 webfiles/report_header md5:28cb27832f238da19fea4ce263d49e45 webfiles/report_header md5:4782ff0c687a882a293f2742f70a75ac webfiles/report_header md5:5373ce8c0780516f53c496a6b571fc68 webfiles/report_header md5:57af05fcb91d32eb5725cf4fcdbc4595 webfiles/report_header md5:8df11e75679f001591ad99069edf176f webfiles/report_header md5:9f3e0a09a8ae034ef1ae1087e4798bdd webfiles/report_header md5:a429189b343613487385804066e52b86 webfiles/report_header md5:b162c38cdc039f78b627c389a2016e5e webfiles/report_header md5:b5f3411b293ba8d116881b59fc3a75ce webfiles/report_header md5:ba52c5aa47f656a4994bef126caf3d10 webfiles/report_header md5:007ab114780bd1339332a09c94f08607 webfiles/snapcritical_header md5:493b820db94c7db9bcfab47bf0c5a5b4 webfiles/snapcritical_header md5:774921d90c4531dbd8665852e1e55ddf webfiles/snapcritical_header md5:cfa74bc7d493f007db5237983ba378c4 webfiles/snapcritical_header md5:18a7b1258bb1f074d4e53d7baf456338 webfiles/snapnongreen_header md5:95f8dec43e100107c85c408acad0125f webfiles/snapnongreen_header md5:c6dac37646074d840904d89bf958e533 webfiles/snapnongreen_header md5:d54b7e479d838d28a0bc01d9f7c72038 webfiles/snapnongreen_header md5:0121bc271e6dcb1127e21ffd37daa280 webfiles/snapnormal_header md5:463b2ae634fdee79b455dadd265a346a webfiles/snapnormal_header md5:472e23dada587d022290079ab981d240 webfiles/snapnormal_header md5:4aef4af069e68e41392e782504e4a453 webfiles/snapnormal_header md5:178fccce4e579115d29413721f7f920d webfiles/snapshot_form md5:51a077e0abe5299f4e96c4e67961efc1 webfiles/snapshot_form md5:817527af6850157b1471f34fb77d1a54 webfiles/snapshot_form md5:d069271f0256f14dfa2ba5d97effe217 webfiles/snapshot_form md5:07d4847d28ff996ec6a635b79fe727ca webfiles/snapshot_header md5:1afb45714ed5911dd448dcf2771ab72f webfiles/snapshot_header md5:367fc4351b0e18d432b81946332dfeaf webfiles/snapshot_header md5:68363d5ffc97b36221e898bf4e100e2a webfiles/snapshot_header md5:760a1b470f3dfcbc36e453c4c6801405 webfiles/snapshot_header md5:a331684b00910024e9887ee3ce902b8c webfiles/snapshot_header md5:b871efbc9b0a04b269dafb62c6d2286f webfiles/snapshot_header md5:d29cd0949b0a88dec8e3b41b407253b5 webfiles/snapshot_header md5:e8c64a75e30ff1d201534e57da0eebb2 webfiles/snapshot_header md5:f088c56cb6da8894fd9cc6d61da06066 webfiles/snapshot_header md5:0a222fda13f6e3f7b4744cb9de2da149 webfiles/stdcritical_header md5:2bd621622835d6184cca9a1296149aaf webfiles/stdcritical_header md5:3b2143d0c4d641504561cb19707d652c webfiles/stdcritical_header md5:c8ea8cc52599e94282ede20509846819 webfiles/stdcritical_header md5:d34d8b055b39a084bebb37cdd93b8651 webfiles/stdcritical_header md5:624e3d52c93db2c6f3601d8e24203267 webfiles/stdnongreen_header md5:989cbd44eec10ef96643ed5ce0445c5a webfiles/stdnongreen_header md5:c682264443af81b4e2dcc02006ca69f9 webfiles/stdnongreen_header md5:c9e6ab9dd10a6437d78bee82c14b3529 webfiles/stdnongreen_header md5:fe55695a2cdb46f7caa2ece116a03eb2 webfiles/stdnongreen_header md5:d57bec4b9fe9dc8dd8f74b590d059ba3 webfiles/stdnormal_footer md5:f8dbf09d682924a6fae1339d4ba3d831 webfiles/stdnormal_footer md5:14395d6a02ce1007374141f691be7e04 webfiles/stdnormal_header md5:16e4ba34e9489dbad700f02e119c142a webfiles/stdnormal_header md5:725cbb67bf038f584356dcc4978ff946 webfiles/stdnormal_header md5:a9b0db3159a06da8a054912d6f5834a1 webfiles/stdnormal_header md5:ef6cb4583f0a98485cc0f090098e14b1 webfiles/stdnormal_header md5:d41bb6227216667076f8e90c75512fa0 webfiles/topchanges_form md5:4e88e5fec96e1c3e927cf262456cf82c webfiles/topchanges_header md5:5c2f9b555c9306fccb6d7b62a2f7a791 webfiles/topchanges_header md5:b7edf3431851324fb2ebdd71552c3afa webfiles/topchanges_header md5:daa843834a2a8e709b1248d78ba93693 webfiles/topchanges_header md5:e7d6bc63b04dd13aa55ff126f3a3f29e webfiles/topchanges_header md5:77a26d505caa295c0124663d50bd6dc3 webfiles/trends_form md5:78765fbe54edc0ee84dc07b3ba829152 webfiles/trends_form md5:a4d1bb01beeb18453a0312ca15ceabb7 webfiles/trends_form md5:40f697302df4fcf21b1eb586dde422da webfiles/trends_header md5:ace5ab7a9ab648e14751005c70287189 webfiles/trends_header md5:b97f9484757a782160ae65f7578452e5 webfiles/useradm_form md5:63a9ec53f2034b71c0bd2ca30da5005a webfiles/useradm_header md5:64acc7c5c91cae0052a9abe95a75a0b1 webfiles/useradm_header md5:8ed0452ebc8934e7a8c5f78d2f37efbb webfiles/useradm_header md5:b20204911a14cf4360e0e02bed6aa1a3 webfiles/useradm_header md5:eb7962eedea531ac0437cd7ba99b2f6b webfiles/useradm_header md5:152758a0a0a028353ea10fb1824e39c1 webfiles/zoom.js md5:1781c28a551f54aba99821a0f70065ad webfiles/zoom.js md5:2e55ae03b1e9deebd4d98f1bdc7fc9fc webfiles/zoom.js md5:36717ff2352222b96514de2fed9003e0 webfiles/zoom.js md5:4cdb87332f200d1d6b1cf1cd37fcd5ff webfiles/zoom.js md5:4d2d2cd984c9046d2332d5e59c527a59 webfiles/zoom.js md5:5bf16eb30301d49011406f71f839c58b webfiles/zoom.js md5:92552cb1b50d3dccd67a7988d08dbf81 webfiles/zoom.js md5:0f7a1e430bd5f3bf75b6876dbb31346a wwwfiles/gifs/arrow.gif md5:15f209b4350be229473a5a17d9f47043 wwwfiles/gifs/bkg-blue.gif md5:550d2867f08912e067ac51dee5552003 wwwfiles/gifs/bkg-blue.gif md5:36b45d8e64a84350099f7fb06c26da0b wwwfiles/gifs/bkg-clear.gif md5:c58f1de41747454ea0beda3ac8cfc4e9 wwwfiles/gifs/bkg-clear.gif md5:30f0bc11f679d95e108da969080c5fc6 wwwfiles/gifs/bkg-green.gif md5:e414d855710fb2c8f4fb50be63b1f52d wwwfiles/gifs/bkg-green.gif md5:339f2319ad364d4ed36ddc0c06f2efc9 wwwfiles/gifs/bkg-purple.gif md5:fffed8a62895572e03fe00ebb7d4d650 wwwfiles/gifs/bkg-purple.gif md5:50920dcb02ff2ac3c317edb8dbdfe047 wwwfiles/gifs/bkg-red.gif md5:7d3c891e2c8d16a9e7529c8a41f2c6be wwwfiles/gifs/bkg-red.gif md5:09f9232bb6d3dba27604e80bacea6caa wwwfiles/gifs/bkg-yellow.gif md5:6e2d929901ca1297a6518129c40dfbf3 wwwfiles/gifs/bkg-yellow.gif md5:6edab754e263eca78cd14414e9c598eb wwwfiles/gifs/blue-ack.gif md5:db01e36f1f4f7623f730525d5a1785a9 wwwfiles/gifs/blue.gif md5:1f7e0d09d3bdcc785556e927031443e6 wwwfiles/gifs/blue-recent.gif md5:7dbeb09959873840f4e2aeddfb2c76a1 wwwfiles/gifs/clear.gif md5:9537b303a8ca9006f7132cd7d10caa74 wwwfiles/gifs/clear-recent.gif md5:b7e7717acc440e90f480fae1e2ca750c wwwfiles/gifs/favicon-blue.ico md5:40a4a21ce27ed5a127dc3182f8e6f761 wwwfiles/gifs/favicon-clear.ico md5:081a360ef5d509a41251308c2592b929 wwwfiles/gifs/favicon-green.ico md5:3a0f210c04cf0ca8112ebdb5acf6931a wwwfiles/gifs/favicon-purple.ico md5:6030caa1c3efb1f78d3371db897d4c1f wwwfiles/gifs/favicon-red.ico md5:f8096714c7bf4ba1de5bb121f37e5843 wwwfiles/gifs/favicon-unknown.ico md5:ec30822e46c1d23bcddf50e901f0841a wwwfiles/gifs/favicon-yellow.ico md5:a1bfa97274f4905d26ff44eb3ddd5376 wwwfiles/gifs/green-ack.gif md5:fcd9f31b34edc95c424654eacd2ce3df wwwfiles/gifs/green.gif md5:720ee80877f25d10e18a2435df8e5515 wwwfiles/gifs/green-recent.gif md5:974f3c1e72b6cec1ff089cbcc0874340 wwwfiles/gifs/purple-ack.gif md5:69f79b571c3dc10be10c6321b37f8480 wwwfiles/gifs/purple.gif md5:59be91136046b6ce6078ff5e51b92f1f wwwfiles/gifs/purple-recent.gif md5:2900d3a7ce74c31df2c3e29081e89ec7 wwwfiles/gifs/README md5:4785eef9a563e895a949ab6fbd43f24c wwwfiles/gifs/README md5:54c9e6c5cf9f3af55c9987f126afe70c wwwfiles/gifs/README md5:71f2e080cfad6a23e2d0f241f071c5e6 wwwfiles/gifs/README md5:771a69c81b193f84a9bbf951b9533d7b wwwfiles/gifs/README md5:569c22387f3e0eae9e167a4e723c4dad wwwfiles/gifs/red-ack.gif md5:cd27207c6975c5fd95acb3edc05a663f wwwfiles/gifs/red.gif md5:3fcb4f34b6579377b91e5aac1125609b wwwfiles/gifs/red-recent.gif md5:cc7def940d5512b3db198bd4198da72f wwwfiles/gifs/unknown.gif md5:cc7def940d5512b3db198bd4198da72f wwwfiles/gifs/unknown-recent.gif md5:9d2ba1a166533c4e7275c8baeee09328 wwwfiles/gifs/xymonbody.css md5:9817d961c3a96a4b4e61f3be2eb0b5f0 wwwfiles/gifs/yellow-ack.gif md5:be7f9a896dad98a28e7fc621fc05934e wwwfiles/gifs/yellow.gif md5:c48ee1c1706fb25f84241d78c2320561 wwwfiles/gifs/yellow-recent.gif md5:2676442ce3bb26c96aa0173d462148d5 wwwfiles/gifs/zoom.gif md5:db3101fb3b347e6fd3f8fbda67e2e390 wwwfiles/menu/b2t-blue.gif md5:bfba2b5ee74c7be23107f580cbfe7d65 wwwfiles/menu/b2t-grey.gif md5:cb0fd3f28fcedcca636d9017e7cf3909 wwwfiles/menu/menu.css md5:fa0d4c587d093e953db4b21e7bacd2f8 wwwfiles/menu/menu_items.js md5:157744fbdd343c55f2866220370277a8 wwwfiles/menu/menu_items.js.DIST md5:2471b1a55835ca094a767ef84a8c923b wwwfiles/menu/menu_items.js.DIST md5:25501f4c319c14cc894fd485d1371c67 wwwfiles/menu/menu_items.js.DIST md5:33222e87f8e5ea46d187383c8ba8ee76 wwwfiles/menu/menu_items.js.DIST md5:42fc35954fb111e39fc7b13a44e0229b wwwfiles/menu/menu_items.js.DIST md5:4698934d41c97abbf79e31f2b254db24 wwwfiles/menu/menu_items.js.DIST md5:676bc52bb8183124b87c90f69afd47a2 wwwfiles/menu/menu_items.js.DIST md5:8a77e51d1da3920af481f96d8aad05ea wwwfiles/menu/menu_items.js.DIST md5:ae61aa6ecb9332a1cb7c4dc1778503e1 wwwfiles/menu/menu_items.js.DIST md5:cdfb74f05ab5f885925666a88973bfaf wwwfiles/menu/menu_items.js.DIST md5:dd15fed90607a93eeec4250c626e4f1f wwwfiles/menu/menu_items.js.DIST md5:feda8f1f05273c80b5048c43f8c38e39 wwwfiles/menu/menu_items.js.DIST md5:47fd53051fb48237501e3cc9d9410cf6 wwwfiles/menu/menu.js md5:7f1a456f123866f518220fad3d1f0137 wwwfiles/menu/menu_tpl.js md5:bc7f251fc00a431f452b9b29042cb5e7 wwwfiles/menu/menu_tpl.js md5:2420fb3d074c15362b4a6380a08e0980 wwwfiles/menu/README md5:a1a37fb8d0abfc5e48b5d00ae5a36f80 wwwfiles/menu/README md5:948d61a485df74b79f75af9406fa3be6 wwwfiles/menu/t2b-blue.gif md5:693c1595105e325af62ad73f5c766041 wwwfiles/menu/t2b-grey.gif md5:52145f5f7f3c5ca6946f18e081ee811a wwwfiles/menu/xymonmenu-blue.css md5:1b68e91383dac5118cfe9c0c9675f0c4 wwwfiles/menu/xymonmenu.css md5:2ec844f6efeaac8fdb5da8badccc3c4f wwwfiles/menu/xymonmenu-grey.css xymon-4.3.30/build/Makefile.test-cares0000664000076400007640000000042413443010711020005 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) include Makefile.rules test-compile: @$(CC) $(CFLAGS) $(CARESINC) -o test-cares.o -c test-cares.c test-link: @$(CC) $(CFLAGS) $(CARESLIB) -o test-cares test-cares.o -lcares && ./test-cares $(MINARESVER) ares-clean: @rm -f test-cares.o test-cares xymon-4.3.30/build/Makefile.test-ssl20000664000076400007640000000034412000050736017573 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(OSSLINC) -o test-ssl2.o -c test-ssl2.c test-link: @$(CC) $(CFLAGS) $(OSSLLIB) -o test-ssl2 test-ssl2.o -lssl -lcrypto $(NETLIBS) clean: @rm -f test-ssl2.o test-ssl2 xymon-4.3.30/build/test-ldap.c0000664000076400007640000000177612000050736016347 0ustar rpmbuildrpmbuild#include #include #include #include #include int main(int argc, char *argv[]) { LDAP *ld; if ((argc >= 1) && (strcmp(argv[1], "vendor") == 0)) { printf("%s\n", LDAP_VENDOR_NAME); } else if ((argc >= 1) && (strcmp(argv[1], "version") == 0)) { printf("%d\n", LDAP_VENDOR_VERSION); } else if ((argc >= 1) && (strcmp(argv[1], "flags") == 0)) { if ((strcasecmp(LDAP_VENDOR_NAME, "OpenLDAP") == 0) && (LDAP_VENDOR_VERSION >= 20400)) { printf("-DLDAP_DEPRECATED=1\n"); } } else { LDAPURLDesc ludp; int protocol, rc; struct timeval nettimeout; protocol = LDAP_VERSION3; nettimeout.tv_sec = 1; nettimeout.tv_usec = 0; rc = ldap_url_parse("ldap://ldap.example.com/cn=xymon,ou=development,o=xymon", &ludp); ld = ldap_init(ludp.lud_host, ludp.lud_port); rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); rc = ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &nettimeout); rc = ldap_start_tls_s(ld, NULL, NULL); } return 0; } xymon-4.3.30/build/test-clockgettime-librt.c0000664000076400007640000000026512262773452021224 0ustar rpmbuildrpmbuild#include #include #include #include int main () { struct timespec ts; (void)clock_gettime(CLOCK_MONOTONIC, &ts); return 0; } xymon-4.3.30/build/Makefile.test-pcre0000664000076400007640000000032111070452713017643 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(PCREINC) -o test-pcre.o -c test-pcre.c test-link: @$(CC) $(CFLAGS) $(PCRELIB) -o test-pcre test-pcre.o -lpcre clean: @rm -f test-pcre.o test-pcre xymon-4.3.30/build/makerpm.sh0000775000076400007640000000316111535462534016306 0ustar rpmbuildrpmbuild#!/bin/sh REL=$1 if [ "$REL" = "" ]; then echo "Error - missing release number" exit 1 fi BASEDIR=`pwd` cd $BASEDIR rm -rf rpmbuild # Setup a temp. rpm build directory. mkdir -p rpmbuild/RPMS rpmbuild/RPMS/i386 rpmbuild/BUILD rpmbuild/SPECS rpmbuild/SRPMS rpmbuild/SOURCES cat >rpmbuild/.rpmmacros <rpmbuild/.rpmrc <rpmbuild/SPECS/xymon.spec cp rpm/xymon-init.d rpmbuild/SOURCES/ cp rpm/xymon.logrotate rpmbuild/SOURCES/ cp rpm/xymon-client.init rpmbuild/SOURCES/ cp rpm/xymon-client.default rpmbuild/SOURCES/ mkdir -p rpmbuild/xymon-$REL for f in xymongen xymonnet bbpatches xymonproxy build common contrib docs xymond web include lib client demotool do find $f/ | egrep -v "RCS|.svn" | cpio -pdvmu $BASEDIR/rpmbuild/xymon-$REL/ done cp -p Changes configure configure.server configure.client COPYING CREDITS README README.CLIENT RELEASENOTES $BASEDIR/rpmbuild/xymon-$REL/ find $BASEDIR/rpmbuild/xymon-$REL -type d|xargs chmod 755 cd rpmbuild #pushd xymon-$REL #make -f $HOME/xymon/Makefile.home distclean #popd tar zcf SOURCES/xymon-$REL.tar.gz xymon-$REL rm -rf xymon-$REL HOME=`pwd` rpmbuild -ba --clean SPECS/xymon.spec #rpm --addsign RPMS/i?86/xymon-$REL-*.i?86.rpm RPMS/i386/xymon-client-$REL-*.i?86.rpm SRPMS/xymon-$REL-*.src.rpm # mv RPMS/i?86/xymon-$REL-*.i?86.rpm RPMS/i?86/xymon-client-$REL-*.i?86.rpm SRPMS/xymon-$REL-*.src.rpm ../rpm/pkg/ xymon-4.3.30/build/Makefile.Linux0000664000076400007640000000215113441566225017047 0ustar rpmbuildrpmbuild# Xymon compile-time settings for LINUX systems OSDEF = -DLINUX # NETLIBS: Use replacement rpc NETLIBS = -ltirpc # Compile flags for normal build CC = gcc GCCVER := $(shell test 0`gcc -dumpversion|cut -d. -f1` -ge 4 && echo yes) ifeq ($(GCCVER),yes) CFLAGS = -g -O2 -Wall -Wno-unused -I/usr/include/tirpc -Wno-pointer-sign -D_REENTRANT $(LFSDEF) $(OSDEF) else CFLAGS = -g -O2 -Wall -Wno-unused -I/usr/include/tirpc -D_REENTRANT $(LFSDEF) $(OSDEF) endif ifndef PKGBUILD RPATH = -Wl,--rpath, endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # For profiling # CFLAGS = -g -pg -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Note: Do 'export GMON_OUT_PREFIX=/var/tmp/FILENAME' to save profiling output in /var/tmp # Use gprof to analyse # By default, Xymon uses a static library for common code. # To save some diskspace and run-time memory, you can use a # shared library by un-commenting this. # XYMONLIBRARY=libxymon.so # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/test-lfs.c0000664000076400007640000000065711544715637016234 0ustar rpmbuildrpmbuild#include #include #include #include #include int main(int argc, char *argv[]) { off_t fileofs; int minsize = atoi(argv[1]); memset(&fileofs, 0, sizeof(fileofs)); #ifdef _LARGEFILE_SOURCE printf("%d:%d:%lld\n", sizeof(off_t), (sizeof(off_t) >= minsize), fileofs); #else printf("%d:%d:%ld\n", sizeof(off_t), (sizeof(off_t) >= minsize), fileofs); #endif return 0; } xymon-4.3.30/build/Makefile.test-ssl0000664000076400007640000000033611070452713017521 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(OSSLINC) -o test-ssl.o -c test-ssl.c test-link: @$(CC) $(CFLAGS) $(OSSLLIB) -o test-ssl test-ssl.o -lssl -lcrypto $(NETLIBS) clean: @rm -f test-ssl.o test-ssl xymon-4.3.30/build/test-shutdown.c0000664000076400007640000000051311070452713017275 0ustar rpmbuildrpmbuild#include #include #include #include #include int main(int argc, char *argv[]) { #ifndef SHUT_RD printf("#define SHUT_RD 0\n"); #endif #ifndef SHUT_WR printf("#define SHUT_WR 1\n"); #endif #ifndef SHUT_RDWR printf("#define SHUT_RDWR 2\n"); #endif return 0; } xymon-4.3.30/build/renamevars.c0000664000076400007640000000107411546253217016621 0ustar rpmbuildrpmbuild#include #include #include #include int main(int argc, char **argv) { char buf[1024]; char *newnam, *oldnam, *oldval, *p; while (fgets(buf, sizeof(buf), stdin)) { p = strchr(buf, '\n'); if (p) *p = '\0'; newnam = buf; oldnam = strchr(buf, '='); if (!oldnam) continue; *oldnam = '\0'; oldnam++; oldval = getenv(oldnam); if (oldval) { printf("%s=\"", newnam); for (p = oldval; (*p); p++) { if (*p == '"') printf("\\\""); else printf("%c", *p); } printf("\"\n"); } } return 0; } xymon-4.3.30/build/lfs.sh0000775000076400007640000000163512003230207015417 0ustar rpmbuildrpmbuild echo "Checking for Large File Support ..." # Solaris is br0ken when it comes to LFS tests. # See http://lists.xymon.com/archive/2011-November/033216.html if test "`uname -s`" = "SunOS"; then echo "Large File Support assumed OK on Solaris" exit 0 fi cd build OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-lfs clean OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-lfs 2>/dev/null if test $? -ne 0; then echo "ERROR: Compiler doesnt recognize the off_t C type." exit 1 fi STDRES="`./test-lfs-std 4`" if test "$STDRES" != "4:1:0" -a "$STDRES" != "8:1:0"; then echo "ERROR: LFS support check failed for standard file support" exit 1 fi LFSRES="`./test-lfs-lfs 8`" if test "$LFSRES" != "8:1:0"; then echo "ERROR: LFS support check failed for large file support" exit 1 fi echo "Large File Support OK" OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-lfs clean cd .. xymon-4.3.30/build/Makefile.test-lfs0000664000076400007640000000037311070452713017505 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) all: test-lfs-std test-lfs-lfs test-lfs-std: @$(CC) -o test-lfs-std test-lfs.c test-lfs-lfs: @$(CC) $(CFLAGS) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -o test-lfs-lfs test-lfs.c clean: @rm -f test-lfs-std test-lfs-lfs xymon-4.3.30/build/Makefile.test-rrd0000664000076400007640000000036311535462534017517 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(RRDDEF) $(RRDINC) -o test-rrd.o -c test-rrd.c test-link: @$(CC) $(CFLAGS) $(RRDDEF) $(RRDLIB) -o test-rrd test-rrd.o -lrrd $(PNGLIB) clean: @rm -f test-rrd.o test-rrd xymongen.png xymon-4.3.30/build/fping.sh0000775000076400007640000000413711535462534015761 0ustar rpmbuildrpmbuild#!/bin/sh echo "Checking for fping ..." for DIR in / /usr /usr/local /opt /usr/pkg /opt/csw do if test "$DIR" = "/"; then DIR=""; fi if test -x $DIR/bin/fping then FPING=$DIR/bin/fping elif test -x $DIR/sbin/fping then FPING=$DIR/sbin/fping fi done if test "$USERFPING" != "" then FPING="$USERFPING" fi if test "$USEXYMONPING" = "" then echo "Xymon has a built-in ping utility (xymonping)" echo "However, it is not yet fully stable and therefore it" echo "may be best to use the external fping utility instead." if test "$FPING" = "" then echo "I could not find fping on your system" echo "Do you want to use xymonping [Y/n] ?" read USEXYMONPING if test "$USEXYMONPING" = "n" then echo "What command should Xymon use to run fping ?" read FPING else USEXYMONPING="y" echo "OK, I will use xymonping." FPING="xymonping" fi else echo "I found fping in $FPING" echo "Do you want to use it [Y/n] ?" read USEFPING if test "$USEFPING" = "n" then USEXYMONPING="y" echo "OK, I will use xymonping instead." FPING="xymonping" fi fi elif test "$USEXYMONPING" = "n" then echo "OK, will use '$FPING' for ping tests" else FPING="xymonping" USEXYMONPING="y" fi if test "$USEXYMONPING" = "y" -o "$USERFPING" != "" then NOTOK=0 else NOTOK=1 fi while test $NOTOK -eq 1 do echo "Checking to see if '$FPING 127.0.0.1' works ..." $FPING 127.0.0.1 RC=$? if test $RC -eq 0; then echo "OK, will use '$FPING' for ping tests" echo "NOTE: If you are using an suid-root wrapper, make sure the 'xymond'" echo " user is also allowed to run fping without having to enter passwords." echo " For 'sudo', add something like this to your 'sudoers' file:" echo " xymon ALL=(ALL) NOPASSWD: $FPING" echo "" NOTOK=0 else echo "" echo "Failed to run fping." echo "If fping is not suid-root, you may want to use an suid-root wrapper" echo "like 'sudo' to run fping." echo "" echo "Xymon needs the fping utility. What command should it use to run fping ?" read FPING fi done xymon-4.3.30/build/ldap.sh0000775000076400007640000000570212003230207015552 0ustar rpmbuildrpmbuild echo "Checking for LDAP ..." LDAPINC="" LDAPLIB="" for DIR in /opt/openldap* /opt/ldap* /usr/local/openldap* /usr/local/ldap* /usr/local /usr/pkg /opt/csw /opt/sfw do if test -f $DIR/include/ldap.h then LDAPINC=$DIR/include fi if test -f $DIR/lib/libldap.so then LDAPLIB=$DIR/lib fi if test -f $DIR/lib/libldap.a then LDAPLIB=$DIR/lib fi if test -f $DIR/lib64/libldap.so then LDAPLIB=$DIR/lib64 fi if test -f $DIR/lib64/libldap.a then LDAPLIB=$DIR/lib64 fi done if test "$USERLDAPINC" != ""; then LDAPINC="$USERLDAPINC" fi if test "$USERLDAPLIB" != ""; then LDAPLIB="$USERLDAPLIB" fi # See if it builds LDAPOK="YES" if test "$LDAPINC" != ""; then INCOPT="-I$LDAPINC"; fi if test "$LDAPLIB" != ""; then LIBOPT="-L$LDAPLIB"; fi cd build OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ldap clean OS=`uname -s | sed -e's@/@_@g'` LDAPINC="$INCOPT" $MAKE -f Makefile.test-ldap test-compile 2>/dev/null if test $? -eq 0; then echo "Compiling with LDAP works OK" else echo "WARNING: Cannot compile with LDAP" LDAPOK="NO" fi if test "$LDAPOK" = "YES" then OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-lber clean OS=`uname -s | sed -e's@/@_@g'` LDAPINC="$INCOPT" $MAKE -f Makefile.test-lber test-compile 2>/dev/null if test $? -eq 0; then OS=`uname -s | sed -e's@/@_@g'` LDAPLIB="$LIBOPT" $MAKE -f Makefile.test-lber test-link 2>/dev/null if test $? -eq 0; then echo "LBER library not needed" LDAPLBER="" else OS=`uname -s | sed -e's@/@_@g'` LDAPLIB="$LIBOPT" LDAPLBER="-llber" $MAKE -f Makefile.test-lber test-link 2>/dev/null if test $? -eq 0; then echo "LDAP requires the LBER library" LDAPLBER="-llber" else echo "LBER library not found, disabling LDAP support" LDAPOK="NO" fi fi else echo "WARNING: Cannot compile with LBER, disabling LDAP support" LDAPOK="NO" fi fi OS=`uname -s | sed -e's@/@_@g'` LDAPLIB="$LIBOPT" LDAPLBER="$LDAPLBER" $MAKE -f Makefile.test-ldap test-link 2>/dev/null if test $? -eq 0; then echo "Linking with LDAP works OK" LDAPVENDOR=`./test-ldap vendor` LDAPVERSION=`./test-ldap version` LDAPCOMPILEFLAGS=`./test-ldap flags` # echo "LDAP vendor is $LDAPVENDOR, version $LDAPVERSION" else echo "WARNING: Cannot link with LDAP" LDAPOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ldap clean OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-lber clean cd .. if test "$LDAPOK" = "NO"; then echo "(Open)LDAP include- or library-files not found." echo "If you want to perform detailed LDAP tests (queries), you need" echo "to install an LDAP client library that Xymon can use." echo "OpenLDAP can be found at http://www.openldap.org/" echo "" echo "If you have OpenLDAP installed, use the \"--ldapinclude DIR\" and \"--ldaplib DIR\"" echo "options to configure to specify where they are." echo "" sleep 3 echo "Continuing with LDAP support disabled." fi xymon-4.3.30/build/merge-sects.c0000664000076400007640000000730512263072434016674 0ustar rpmbuildrpmbuild/* * Merge the current "[...]" sectioned file with a new template. New entries are added, * and existing ones are copied over from the current setup. */ #include #include #include #include #include #include typedef struct entry_t { char *name; char *val; int copied; struct entry_t *next; } entry_t; typedef struct newname_t { char *oldname, *newname; struct newname_t *next; } newname_t; entry_t *head = NULL; entry_t *tail = NULL; newname_t *newnames = NULL; int main(int argc, char *argv[]) { char *curfn, *curbckfn, *srcfn; FILE *curfd, *curbckfd, *srcfd; struct stat st; char l[32768]; entry_t *ewalk; entry_t *newent = NULL; int adding = 0; int showit = 1; if (argc < 3) { printf("Usage: %s DESTINATIONFILE TEMPLATEFILE\n", argv[0]); return 1; } srcfn = strdup(argv[1]); curfn = strdup(argv[2]); if (argc > 3) { int i; char *p; for (i=3; (i < argc); i++) { p = strchr(argv[i], '='); if (p) { newname_t *newitem = (newname_t *)malloc(sizeof(newname_t)); *p = '\0'; newitem->oldname = strdup(argv[i]); newitem->newname = strdup(p+1); newitem->next = newnames; newnames = newitem; } } } curbckfn = (char *)malloc(strlen(curfn) + 5); sprintf(curbckfn, "%s.bak", curfn); if (stat(curfn, &st) == -1) { showit = 0; goto nooriginal; } curfd = fopen(curfn, "r"); unlink(curbckfn); curbckfd = fopen(curbckfn, "w"); if (curfd == NULL) { printf("Cannot open configuration file %s\n", curfn); return 1; } if (curbckfd == NULL) { printf("Cannot open backup file %s\n", curbckfn); return 1; } while (fgets(l, sizeof(l), curfd)) { char *bol, *p; newname_t *nwalk; fprintf(curbckfd, "%s", l); bol = l + strspn(l, " \t\r\n"); if ((*bol == '#') || (*bol == '\0')) continue; if ((*bol == '[') && strchr(bol, ']')) { newent = (entry_t *)malloc(sizeof(entry_t)); p = strchr(bol, ']'); *p = '\0'; for (nwalk = newnames; (nwalk && strcmp(nwalk->oldname, bol+1)); nwalk = nwalk->next); if (nwalk) { newent->name = strdup(nwalk->newname); newent->val = (char *)malloc(strlen(nwalk->newname) + 4); sprintf(newent->val, "[%s]\n", nwalk->newname); } else { newent->name = strdup(bol+1); *p = ']'; newent->val = strdup(l); } newent->copied = 0; newent->next = NULL; if (tail == NULL) { tail = head = newent; } else { tail->next = newent; tail = newent; } } else if (newent) { newent->val = (char *)realloc(newent->val, strlen(newent->val) + strlen(l) + 1); strcat(newent->val, l); } } fclose(curfd); fclose(curbckfd); nooriginal: srcfd = fopen(srcfn, "r"); unlink(curfn); curfd = fopen(curfn, "w"); if (srcfd == NULL) { printf("Cannot open template file %s\n", srcfn); return 1; } if (curfd == NULL) { printf("Cannot open config file %s\n", curfn); return 1; } fchmod(fileno(curfd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); while (fgets(l, sizeof(l), srcfd)) { char *bol, *p; bol = l + strspn(l, " \t\r\n"); if ((*bol == '[') && strchr(bol, ']')) { p = strchr(bol, ']'); *p = '\0'; for (ewalk = head; (ewalk && strcmp(ewalk->name, bol+1)); ewalk = ewalk->next) ; *p = ']'; if (ewalk) { fprintf(curfd, "%s", ewalk->val); ewalk->copied = 1; adding = 0; } else { if (showit) printf("Adding new entry to %s: %s", curfn, l); fprintf(curfd, "%s", l); adding = 1; } } else if (adding || (*bol == '#') || (*bol == '\0')) { fprintf(curfd, "%s", l); } } /* Copy over any local settings that have been added */ for (ewalk = head; (ewalk); ewalk = ewalk->next) { if (!ewalk->copied) { fprintf(curfd, "%s", ewalk->val); } } fclose(curfd); fclose(srcfd); return 0; } xymon-4.3.30/build/Makefile.test-clockgettime-librt0000664000076400007640000000067611070452713022513 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-clockgettime-librt.o: test-clockgettime-librt.c @$(CC) $(CFLAGS) -o test-clockgettime-librt.o -c test-clockgettime-librt.c test-link: test-clockgettime-librt.o @$(CC) $(CFLAGS) -o test-clockgettime-librt test-clockgettime-librt.o test-link-rt: test-clockgettime-librt.o @$(CC) $(CFLAGS) -o test-clockgettime-librt test-clockgettime-librt.o -lrt clean: @rm -f test-clockgettime-librt.o test-clockgettime-librt xymon-4.3.30/build/test-pcre.c0000664000076400007640000000030011535462534016355 0ustar rpmbuildrpmbuild#include int main(int argc, char *argv[]) { pcre *result; const char *errmsg; int errofs; result = pcre_compile("xymon.*", PCRE_CASELESS, &errmsg, &errofs, NULL); return 0; } xymon-4.3.30/build/Makefile.OpenBSD0000664000076400007640000000146012005761247017200 0ustar rpmbuildrpmbuild# Xymon compile-time settings for OpenBSD systems OSDEF = -DBSD # NETLIBS: None needed NETLIBS = # Compile flags for normal build CC = gcc GCCVER := $(shell gcc -dumpversion|cut -d. -f1) ifeq ($(GCCVER),4) CFLAGS = -g -O2 -Wall -Wno-unused -Wno-pointer-sign -D_REENTRANT -I/usr/local/include -L/usr/local/lib $(LFSDEF) $(OSDEF) else CFLAGS = -g -O2 -Wall -Wno-unused -D_REENTRANT -I/usr/local/include -L/usr/local/lib $(LFSDEF) $(OSDEF) endif # # According to reports, this does not work on OpenBSD # RPATH = "-Wl,--rpath," # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT -I/usr/local/include -L/usr/local/lib $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/Makefile.Darwin0000664000076400007640000000160212006166517017170 0ustar rpmbuildrpmbuild# Xymon compile-time settings for Darwin (Mac OS X) # OSDEF = -DDarwin # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = # Compile flags for normal build CC = gcc GCCVER := $(shell gcc -dumpversion|cut -d. -f1) ifeq ($(GCCVER),4) CFLAGS = -g -O -Wall -Wno-unused -Wno-pointer-sign -D_REENTRANT -DBIND_8_COMPAT=1 $(LFSDEF) $(OSDEF) else CFLAGS = -g -O -Wall -Wno-unused -D_REENTRANT -DBIND_8_COMPAT=1 $(LFSDEF) $(OSDEF) endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT -DBIND_8_COMPAT=1 $(LFSDEF) $(OSDEF) # Extra environment settings for runtime stuff. # E.g. RUNTIMEDEFS="LD_LIBRARY_PATH=\"/opt/lib\"" to use # runtime libraries located in /opt/lib RUNTIMEDEFS = # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/test-socklent.c0000664000076400007640000000057311070452713017252 0ustar rpmbuildrpmbuild#include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int connres; socklen_t connressize = sizeof(connres); int res, sockfd = 0; res = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &connres, &connressize); return 0; } xymon-4.3.30/build/Makefile.OSF10000664000076400007640000000071411535462534016463 0ustar rpmbuildrpmbuild# Xymon compile-time settings for a OSF/1 system # OSDEF = -DOSF # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = # Compile flags for normal build CC = cc CFLAGS = -g -O -D_REENTRANT $(OSDEF) # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/c-ares.sh0000775000076400007640000000326112275770001016016 0ustar rpmbuildrpmbuild echo "Checking for C-ARES library ..." CARESINC="" CARESLIB="" for DIR in /opt/c*ares* /usr/local/c*ares* /usr/local /usr/pkg /opt/csw /opt/sfw do if test -f $DIR/include/ares.h then CARESINC=$DIR/include fi if test -f $DIR/include/ares/ares.h then CARESINC=$DIR/include/ares fi if test -f $DIR/lib/libcares.so then CARESLIB=$DIR/lib fi if test -f $DIR/lib/libcares.a then CARESLIB=$DIR/lib fi if test -f $DIR/lib64/libcares.so then CARESLIB=$DIR/lib64 fi if test -f $DIR/lib64/libcares.a then CARESLIB=$DIR/lib64 fi done if test "$USERCARESINC" != ""; then CARESINC="$USERCARESINC" fi if test "$USERCARESLIB" != ""; then CARESLIB="$USERCARESLIB" fi # Lets see if it can build CARESOK="YES" cd build if test "$CARESINC" != ""; then INCOPT="-I$CARESINC"; fi if test "$CARESLIB" != ""; then LIBOPT="-L$CARESLIB"; fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-cares ares-clean OS=`uname -s | sed -e's@/@_@g'` CARESINC="$INCOPT" $MAKE -f Makefile.test-cares test-compile if test $? -eq 0; then echo "Compiling with c-ares library works OK" else echo "ERROR: Cannot compile using c-ares library." CARESOK="NO" fi if test "$CARESOK" = "YES" then OS=`uname -s | sed -e's@/@_@g'` CARESLIB="$LIBOPT" $MAKE -f Makefile.test-cares test-link if test $? -eq 0; then echo "Linking with c-ares library works OK" else echo "ERROR: Cannot link with c-ares library." CARESOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-cares ares-clean fi cd .. if test "$CARESOK" = "NO"; then echo "The system C-ARES library is missing or not usable. I will use the version shipped with Xymon" fi xymon-4.3.30/build/Makefile.test-lber0000664000076400007640000000033512001246456017643 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(LDAPINC) -o test-lber.o -c test-lber.c test-link: @$(CC) $(CFLAGS) $(LDAPLIB) -o test-lber test-lber.o -lldap $(LDAPLBER) clean: @rm -f test-lber.o test-lber xymon-4.3.30/build/Makefile.AIX0000664000076400007640000000115011535462534016367 0ustar rpmbuildrpmbuild# Xymon compile-time settings for a AIX system # OSDEF = -DAIX # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = # Compile flags for normal build with gcc # CC = gcc # CFLAGS = -O -D_REENTRANT $(OSDEF) # Compile flags for normal build with IBM compiler CC = cc CFLAGS = -g -O3 -qstrict -qcpluscmt -D_REENTRANT $(LFSDEF) $(OSDEF) # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/updmanver0000775000076400007640000000106212411274461016232 0ustar rpmbuildrpmbuild#!/bin/bash export LANG=C DATE=`date +"%e %b %Y"` VERSION=$1 if [ "$VERSION" = "" ] then echo "Usage: $0 VERSION" exit 1 fi # cd $HOME/xymon || exit 1 for DIR in xymongen xymonnet xymonproxy common xymond web do pushd $DIR # co -l RCS/*.[1-9],v for f in *.[1-9] do NAME=`head -n 1 $f | awk '{print $2}'`; SECTION=`head -n 1 $f | awk '{print $3}'`; (echo ".TH $NAME $SECTION \"Version $VERSION: $DATE\" \"Xymon\""; tail -n +2 $f) >$f.new mv -f $f.new $f # ci -u -m"Version update" -q -f $f done popd done xymon-4.3.30/build/merge-lines.c0000664000076400007640000001460212271162643016664 0ustar rpmbuildrpmbuild/* * Merge the current xymonserver.cfg file with a new template. New entries are added, * and existing ones are copied over from the current setup. */ #include #include #include #include #include #include typedef struct entry_t { char *name; char *val; int copied; struct entry_t *next; int extracount; char **extralines; } entry_t; typedef struct newname_t { char *oldname, *newname; struct newname_t *next; } newname_t; entry_t *head = NULL; entry_t *tail = NULL; newname_t *newnames = NULL; char *lastblankandcomment = NULL; int main(int argc, char *argv[]) { char *curfn, *curbckfn, *srcfn; FILE *curfd, *curbckfd, *srcfd; char delim = '='; char alldelims[10]; char l[32768]; entry_t *ewalk; struct stat st; int showit = 1; srcfn = strdup(argv[1]); curfn = strdup(argv[2]); if (argc > 3) { int i; char *p; for (i=3; (i < argc); i++) { p = strchr(argv[i], '='); if (p) { newname_t *newitem = (newname_t *)malloc(sizeof(newname_t)); *p = '\0'; newitem->oldname = strdup(argv[i]); newitem->newname = strdup(p+1); newitem->next = newnames; newnames = newitem; } } } curbckfn = (char *)malloc(strlen(curfn) + 5); sprintf(curbckfn, "%s.bak", curfn); if (strstr(srcfn, ".csv")) { delim = ';'; strcpy(alldelims, ";"); } else { sprintf(alldelims, "%c+-", delim); } if (stat(curfn, &st) == -1) { showit = 0; goto nooriginal; } curfd = fopen(curfn, "r"); unlink(curbckfn); curbckfd = fopen(curbckfn, "w"); if (curfd == NULL) { printf("Cannot open config file %s\n", curfn); return 1; } if (curbckfd == NULL) { printf("Cannot create backup file %s\n", curbckfn); return 1; } while (fgets(l, sizeof(l), curfd)) { char *bol, *p; fprintf(curbckfd, "%s", l); bol = l + strspn(l, " \t\r\n"); if ((*bol == '#') || (*bol == '\0')) { if (!lastblankandcomment) lastblankandcomment = strdup(bol); else { lastblankandcomment = (char *)realloc(lastblankandcomment, strlen(lastblankandcomment) + strlen(bol) + 1); strcat(lastblankandcomment, bol); } continue; } if (tail && ((strncmp(bol, "include ", 8) == 0) || (strncmp(bol, "directory ", 10) == 0))) { if (!tail->extralines) { tail->extracount = 1; tail->extralines = (char **)malloc(sizeof(char *)); } else { tail->extracount++; tail->extralines = (char **)realloc(tail->extralines, (tail->extracount*sizeof(char *))); } if (!lastblankandcomment) tail->extralines[tail->extracount-1] = strdup(bol); else { tail->extralines[tail->extracount-1] = (char *)malloc(1 + strlen(bol) + strlen(lastblankandcomment)); sprintf(tail->extralines[tail->extracount-1], "%s%s", lastblankandcomment, bol); } if (lastblankandcomment) { free(lastblankandcomment); lastblankandcomment = NULL; } continue; } p = bol + strcspn(bol, alldelims); if (*p) { entry_t *newent; if (*p == delim) { *p = '\0'; newent = (entry_t *)calloc(1, sizeof(entry_t)); newent->name = strdup(bol); *p = delim; newent->val = strdup(l); if (tail == NULL) { tail = head = newent; } else { tail->next = newent; tail = newent; } } else if (*(p+1) == delim) { char sav = *p; entry_t *walk; *p = '\0'; for (walk = head; (walk && (strcmp(walk->name, bol) != 0)); walk = walk->next) ; *p = sav; if (walk) { if (!walk->extralines) { walk->extracount = 1; walk->extralines = (char **)malloc(sizeof(char *)); } else { walk->extracount++; walk->extralines = (char **)realloc(walk->extralines, (walk->extracount*sizeof(char *))); } if (!lastblankandcomment) walk->extralines[walk->extracount-1] = strdup(bol); else { walk->extralines[walk->extracount-1] = (char *)malloc(1 + strlen(bol) + strlen(lastblankandcomment)); sprintf(walk->extralines[walk->extracount-1], "%s%s", lastblankandcomment, bol); } } } if (lastblankandcomment) { free(lastblankandcomment); lastblankandcomment = NULL; } } } fclose(curfd); fclose(curbckfd); if (lastblankandcomment) { /* Add this to the last entry */ if (!tail->extralines) { tail->extracount = 1; tail->extralines = (char **)malloc(sizeof(char *)); } else { tail->extracount++; tail->extralines = (char **)realloc(tail->extralines, (tail->extracount*sizeof(char *))); } tail->extralines[tail->extracount-1] = strdup(lastblankandcomment); } nooriginal: srcfd = fopen(srcfn, "r"); unlink(curfn); curfd = fopen(curfn, "w"); if (srcfd == NULL) { printf("Cannot open template file %s\n", srcfn); return 1; } if (curfd == NULL) { printf("Cannot create config file %s\n", curfn); return 1; } fchmod(fileno(curfd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); while (fgets(l, sizeof(l), srcfd)) { char *bol, *p; bol = l + strspn(l, " \t\r\n"); if ((*bol == '#') || (*bol == '\0') || (strncmp(bol, "include ", 8) == 0) || (strncmp(bol, "directory ", 10) == 0)) { fprintf(curfd, "%s", l); continue; } p = strchr(bol, delim); if (p) { /* Find the old value */ *p = '\0'; for (ewalk = head; (ewalk && strcmp(ewalk->name, bol)); ewalk = ewalk->next) ; if (!ewalk) { /* See if it's been renamed */ newname_t *nwalk; for (nwalk = newnames; (nwalk && strcmp(nwalk->newname, bol)); nwalk = nwalk->next) ; if (nwalk) { /* It has - find the value of the old setting */ for (ewalk = head; (ewalk && strcmp(ewalk->name, nwalk->oldname)); ewalk = ewalk->next) ; if (ewalk) { /* Merge it with the new name */ char *newval; char *oval = strchr(ewalk->val, delim); newval = (char *)malloc(strlen(nwalk->newname) + strlen(oval) + 1); sprintf(newval, "%s%s", nwalk->newname, oval); ewalk->val = newval; } } } *p = delim; if (ewalk) { fprintf(curfd, "%s", ewalk->val); if (ewalk->extralines) { int i; for (i = 0; (i < ewalk->extracount); i++) fprintf(curfd, "%s", ewalk->extralines[i]); } ewalk->copied = 1; } else { if (showit) printf("Adding new entry to %s: %s", curfn, l); fprintf(curfd, "%s", l); } } else { fprintf(curfd, "%s", l); } } /* Copy over any local settings that have been added */ for (ewalk = head; (ewalk); ewalk = ewalk->next) { if (!ewalk->copied) { fprintf(curfd, "%s", ewalk->val); } } fclose(curfd); fclose(srcfd); return 0; } xymon-4.3.30/build/generate-md5.sh0000775000076400007640000000052212277655770017137 0ustar rpmbuildrpmbuild#!/bin/sh # cd ~/xymon/trunk WEBLIST=`(cd xymond; find webfiles -type f) | egrep -v "RCS|\.svn" | xargs echo` WWWLIST=`(cd xymond; find wwwfiles -type f) | egrep -v "RCS|\.svn" | xargs echo` (cat build/md5.dat; for F in $WEBLIST $WWWLIST; do echo "md5:`openssl dgst -md5 xymond/${F} | awk '{print $2}'` ${F}"; done) | sort -k2 | uniq xymon-4.3.30/build/test-lber.c0000664000076400007640000000022112004462124016335 0ustar rpmbuildrpmbuild#include int main(int argc, char **argv) { BerElement *dummy; char *foo = "bar"; dummy = ber_init(ber_bvstrdup(foo)); return 0; } xymon-4.3.30/build/Makefile.IRIX0000664000076400007640000000121311535462534016521 0ustar rpmbuildrpmbuild# Xymon compile-time settings for a IRIX system # OSDEF = -DIRIX # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = # Compile flags for normal build CC = cc CFLAGS = -g -O -D_REENTRANT $(OSDEF) $(LFSDEF) # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT $(OSDEF) $(LFSDEF) # Extra environment settings for runtime stuff. # E.g. RUNTIMEDEFS="LD_LIBRARY_PATH=\"/opt/lib\"" to use # runtime libraries located in /opt/lib RUNTIMEDEFS = # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/renametasks.c0000664000076400007640000001053511535424634016776 0ustar rpmbuildrpmbuild#include #include #include #include int main(int argc, char **argv) { char buf[10240]; while (fgets(buf, sizeof(buf), stdin)) { char *dlim; dlim = (*buf == '[') ? strchr(buf, ']') : NULL; if (dlim != NULL) { *dlim = '\0'; if (strcmp(buf+1, "hobbitd") == 0) printf("[xymond]%s", dlim+1); else if (strcmp(buf+1, "bbstatus") == 0) printf("[storestatus]%s", dlim+1); else if (strcmp(buf+1, "bbhistory") == 0) printf("[history]%s", dlim+1); else if (strcmp(buf+1, "hostdata") == 0) printf("[hostdata]%s", dlim+1); else if (strcmp(buf+1, "bbdata") == 0) printf("[storedata]%s", dlim+1); else if (strcmp(buf+1, "bbnotes") == 0) printf("[storenotes]%s", dlim+1); else if (strcmp(buf+1, "bbenadis") == 0) printf("[storeenadis]%s", dlim+1); else if (strcmp(buf+1, "bbpage") == 0) printf("[alert]%s", dlim+1); else if (strcmp(buf+1, "rrdstatus") == 0) printf("[rrdstatus]%s", dlim+1); else if (strcmp(buf+1, "larrdstatus") == 0) printf("[rrdstatus]%s", dlim+1); else if (strcmp(buf+1, "rrddata") == 0) printf("[rrddata]%s", dlim+1); else if (strcmp(buf+1, "larrddata") == 0) printf("[rrddata]%s", dlim+1); else if (strcmp(buf+1, "clientdata") == 0) printf("[clientdata]%s", dlim+1); else if (strcmp(buf+1, "bbproxy") == 0) printf("[xymonproxy]%s", dlim+1); else if (strcmp(buf+1, "hobbitfetch") == 0) printf("[xymonfetch]%s", dlim+1); else if (strcmp(buf+1, "bbdisplay") == 0) printf("[xymongen]%s", dlim+1); else if (strcmp(buf+1, "bbcombotest") == 0) printf("[combostatus]%s", dlim+1); else if (strcmp(buf+1, "bbnet") == 0) printf("[xymonnet]%s", dlim+1); else if (strcmp(buf+1, "bbretest") == 0) printf("[xymonnetagain]%s", dlim+1); else if (strcmp(buf+1, "hobbitclient") == 0) printf("[xymonclient]%s", dlim+1); else { *dlim = ']'; printf("%s", buf); } continue; } dlim = buf + strspn(buf, " \t"); if (strncasecmp(dlim, "NEEDS", 5) == 0) { char *nam; char savchar; nam = dlim + 5; nam += strspn(nam, " \t"); dlim = nam + strspn(nam, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefhijklmnopqrstuvwxyz"); savchar = *dlim; *dlim = '\0'; if (strcmp(nam, "hobbitd") == 0) { *nam = '\0'; printf("%sxymond%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbstatus") == 0) { *nam = '\0'; printf("%sstorestatus%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbhistory") == 0) { *nam = '\0'; printf("%shistory%c%s", buf, savchar, dlim); } else if (strcmp(nam, "hostdata") == 0) { *nam = '\0'; printf("%shostdata%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbdata") == 0) { *nam = '\0'; printf("%sstoredata%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbnotes") == 0) { *nam = '\0'; printf("%sstorenotes%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbenadis") == 0) { *nam = '\0'; printf("%sstoreenadis%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbpage") == 0) { *nam = '\0'; printf("%salert%c%s", buf, savchar, dlim); } else if (strcmp(nam, "rrdstatus") == 0) { *nam = '\0'; printf("%srrdstatus%c%s", buf, savchar, dlim); } else if (strcmp(nam, "larrdstatus") == 0) { *nam = '\0'; printf("%srrdstatus%c%s", buf, savchar, dlim); } else if (strcmp(nam, "rrddata") == 0) { *nam = '\0'; printf("%srrddata%c%s", buf, savchar, dlim); } else if (strcmp(nam, "larrddata") == 0) { *nam = '\0'; printf("%srrddata%c%s", buf, savchar, dlim); } else if (strcmp(nam, "clientdata") == 0) { *nam = '\0'; printf("%sclientdata%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbproxy") == 0) { *nam = '\0'; printf("%sxymonproxy%c%s", buf, savchar, dlim); } else if (strcmp(nam, "hobbitfetch") == 0) { *nam = '\0'; printf("%sxymonfetch%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbdisplay") == 0) { *nam = '\0'; printf("%sxymongen%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbcombotest") == 0) { *nam = '\0'; printf("%scombostatus%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbnet") == 0) { *nam = '\0'; printf("%sxymonnet%c%s", buf, savchar, dlim); } else if (strcmp(nam, "bbretest") == 0) { *nam = '\0'; printf("%sxymonnetagain%c%s", buf, savchar, dlim); } else if (strcmp(nam, "hobbitclient") == 0) { *nam = '\0'; printf("%sxymonclient%c%s", buf, savchar, dlim); } else { *dlim = savchar; printf("%s", buf); } continue; } printf("%s", buf); } return 0; } xymon-4.3.30/build/revlog.c0000664000076400007640000000233011070452713015742 0ustar rpmbuildrpmbuild#include int main(int argc, char *argv[]) { char *date = argv[1]; char *fn = argv[2]; FILE *logfd; char cmd[4096]; char buf[4096]; int gotrevmarker = 0; int gotlocksline = 0; int fileislocked = 0; sprintf(cmd, "rlog \"-d>%s\" %s 2>/dev/null", date, fn); logfd = popen(cmd, "r"); while (fgets(buf, sizeof(buf), logfd)) { if (gotlocksline == 0) { if (strncmp(buf, "locks:", 6) == 0) gotlocksline = 1; } else if (gotlocksline == 1) { if (isspace(*buf)) fileislocked = 1; gotlocksline = 2; } if (!gotrevmarker) { gotrevmarker = (strcmp(buf, "----------------------------\n") == 0); if (gotrevmarker) { fprintf(stdout, "%s", fn); if (fileislocked) fprintf(stdout, " (is being edited)"); fprintf(stdout, "\n"); fileislocked = 0; } } if (gotrevmarker) fprintf(stdout, "%s", buf); } pclose(logfd); if (fileislocked) { /* Locked file, but we haven't shown anything yet */ fprintf(stdout, "%s", fn); if (fileislocked) fprintf(stdout, " (is being edited)"); fprintf(stdout, "\n"); fprintf(stdout, "%s\n", "============================================================================="); } if (gotrevmarker || fileislocked) fprintf(stdout, "\n"); return 0; } xymon-4.3.30/build/test-bintree.c0000664000076400007640000000147012275523176017067 0ustar rpmbuildrpmbuild#include #include #include #include void *root = NULL; int compare(const void *pa, const void *pb) { if (*(int *) pa < *(int *) pb) return -1; if (*(int *) pa > *(int *) pb) return 1; return 0; } void action(const void *nodep, const VISIT which, const int depth) { int *datap; switch (which) { case preorder: case endorder: break; case postorder: case leaf: datap = *(int **) nodep; printf("%6d\n", *datap); break; } } int main(void) { int i, *ptr; void *val; srand(time(NULL)); for (i = 0; i < 12; i++) { ptr = malloc(sizeof(int)); *ptr = rand() & 0xff; val = tsearch((void *) ptr, &root, compare); if (val == NULL) exit(EXIT_FAILURE); else if ((*(int **) val) != ptr) free(ptr); } twalk(root, action); exit(EXIT_SUCCESS); } xymon-4.3.30/build/genconfig.sh0000775000076400007640000000654612520566040016613 0ustar rpmbuildrpmbuild#!/bin/sh # Simpler than autoconf, but it does what we need it to do right now. echo "/* This file is auto-generated */" >include/config.h echo "#ifndef __CONFIG_H__" >>include/config.h echo "#define __CONFIG_H__ 1" >>include/config.h echo "Checking for socklen_t" $CC -c -o build/testfile.o $CFLAGS build/test-socklent.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_SOCKLEN_T 1" >>include/config.h else echo "#undef HAVE_SOCKLEN_T" >>include/config.h fi echo "Checking for snprintf" $CC -c -o build/testfile.o $CFLAGS build/test-snprintf.c 1>/dev/null 2>&1 if test $? -eq 0; then $CC -o build/testfile $CFLAGS build/testfile.o 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_SNPRINTF 1" >>include/config.h else echo "#undef HAVE_SNPRINTF" >>include/config.h fi else echo "#undef HAVE_SNPRINTF" >>include/config.h fi echo "Checking for vsnprintf" $CC -c -o build/testfile.o $CFLAGS build/test-vsnprintf.c 1>/dev/null 2>&1 if test $? -eq 0; then $CC -o build/testfile $CFLAGS build/testfile.o 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_VSNPRINTF 1" >>include/config.h else echo "#undef HAVE_VSNPRINTF" >>include/config.h fi else echo "#undef HAVE_VSNPRINTF" >>include/config.h fi echo "Checking for rpc/rpcent.h" $CC -c -o build/testfile.o $CFLAGS build/test-rpcenth.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_RPCENT_H 1" >>include/config.h else echo "#undef HAVE_RPCENT_H" >>include/config.h fi echo "Checking for sys/select.h" $CC -c -o build/testfile.o $CFLAGS build/test-sysselecth.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_SYS_SELECT_H 1" >>include/config.h else echo "#undef HAVE_SYS_SELECT_H" >>include/config.h fi echo "Checking for u_int32_t typedef" $CC -c -o build/testfile.o $CFLAGS build/test-uint.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_UINT32_TYPEDEF 1" >>include/config.h else echo "#undef HAVE_UINT32_TYPEDEF" >>include/config.h fi echo "Checking for PATH_MAX definition" $CC -o build/testfile $CFLAGS build/test-pathmax.c 1>/dev/null 2>&1 if test -x build/testfile; then ./build/testfile >>include/config.h; fi echo "Checking for SHUT_RD/WR/RDWR definitions" $CC -o build/testfile $CFLAGS build/test-shutdown.c 1>/dev/null 2>&1 if test -x build/testfile; then ./build/testfile >>include/config.h; fi echo "Checking for strtoll()" $CC -c -o build/testfile.o $CFLAGS build/test-strtoll.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_STRTOLL_H 1" >>include/config.h else echo "#undef HAVE_STRTOLL_H" >>include/config.h fi echo "Checking for uname" $CC -c -o build/testfile.o $CFLAGS build/test-uname.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_UNAME 1" >>include/config.h else echo "#undef HAVE_UNAME" >>include/config.h fi echo "Checking for setenv" $CC -c -o build/testfile.o $CFLAGS build/test-setenv.c 1>/dev/null 2>&1 if test $? -eq 0; then echo "#define HAVE_SETENV 1" >>include/config.h else echo "#undef HAVE_SETENV" >>include/config.h fi # This is experimental for 4.3.x #echo "Checking for POSIX binary tree functions" #$CC -c -o build/testfile.o $CFLAGS build/test-bintree.c 1>/dev/null 2>&1 #if test $? -eq 0; then # echo "#define HAVE_BINARY_TREE 1" >>include/config.h #else echo "#undef HAVE_BINARY_TREE" >>include/config.h #fi echo "#endif" >>include/config.h echo "config.h created" rm -f testfile.o testfile exit 0 xymon-4.3.30/build/pcre.sh0000775000076400007640000000337112003230207015563 0ustar rpmbuildrpmbuild echo "Checking for PCRE ..." PCREINC="" PCRELIB="" for DIR in /opt/pcre* /usr/local/pcre* /usr/local /usr/pkg /opt/csw /opt/sfw do if test -f $DIR/include/pcre.h then PCREINC=$DIR/include fi if test -f $DIR/include/pcre/pcre.h then PCREINC=$DIR/include/pcre fi if test -f $DIR/lib/libpcre.so then PCRELIB=$DIR/lib fi if test -f $DIR/lib/libpcre.a then PCRELIB=$DIR/lib fi if test -f $DIR/lib64/libpcre.so then PCRELIB=$DIR/lib64 fi if test -f $DIR/lib64/libpcre.a then PCRELIB=$DIR/lib64 fi done if test "$USERPCREINC" != ""; then PCREINC="$USERPCREINC" fi if test "$USERPCRELIB" != ""; then PCRELIB="$USERPCRELIB" fi # Lets see if it can build PCREOK="YES" cd build if test "$PCREINC" != ""; then INCOPT="-I$PCREINC"; fi if test "$PCRELIB" != ""; then LIBOPT="-L$PCRELIB"; fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-pcre clean OS=`uname -s | sed -e's@/@_@g'` PCREINC="$INCOPT" $MAKE -f Makefile.test-pcre test-compile if test $? -eq 0; then echo "Compiling with PCRE library works OK" else echo "ERROR: Cannot compile using PCRE library." PCREOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` PCRELIB="$LIBOPT" $MAKE -f Makefile.test-pcre test-link if test $? -eq 0; then echo "Linking with PCRE library works OK" else echo "ERROR: Cannot link with PCRE library." PCREOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-pcre clean cd .. if test "$PCREOK" = "NO"; then echo "Missing PCRE include- or library-files. These are REQUIRED for xymond" echo "PCRE can be found at http://www.pcre.org/" echo "If you have PCRE installed, use the \"--pcreinclude DIR\" and \"--pcrelib DIR\"" echo "options to configure to specify where they are." exit 1 fi xymon-4.3.30/build/upgrade430.sh0000775000076400007640000003243511535424634016535 0ustar rpmbuildrpmbuild#!/bin/sh renameandlink() { if test -f $1 then mv $1 $2 ln -s $2 $1 fi } if test "$BBHOME" = "" then echo "ERROR: This must be invoked using the bbcmd utility" echo " bbcmd $0" exit 1 fi # Get directory where we are running from SDIR=`dirname $0` # Could be a relative path SDIRFULL=`(cd $SDIR; pwd)` if test ! -f $SDIRFULL/renamevars then echo "ERROR: You must run 'make' first to build the 4.3.0 tools" exit 1 fi cd $BBHOME/etc || (echo "Cannot cd to etc directory"; exit 1) if test ! -w .; then echo "Cannot write to etc directory"; exit 1; fi renameandlink bb-hosts hosts.cfg renameandlink bbcombotest.cfg combo.cfg renameandlink hobbit-alerts.cfg alerts.cfg renameandlink hobbit-nkview.cfg critical.cfg renameandlink hobbit-nkview.cfg.bak critical.cfg.bak renameandlink hobbit-rrddefinitions.cfg rrddefinitions.cfg renameandlink hobbitgraph.cfg graphs.cfg renameandlink hobbit-holidays.cfg holidays.cfg renameandlink hobbit-clients.cfg analysis.cfg renameandlink hobbit-snmpmibs.cfg snmpmibs.cfg renameandlink hobbit-apache.conf xymon-apache.conf renameandlink bb-services protocols.cfg renameandlink hobbitcgi.cfg cgioptions.cfg if test -f hobbitlaunch.cfg then mv hobbitlaunch.cfg tasks.old $SDIRFULL/renametasks tasks.cfg ln -s tasks.cfg hobbitlaunch.cfg fi if test -f hobbitserver.cfg then mv hobbitserver.cfg xymonserver.old $SDIRFULL/renamevars >xymonserver.cfg <xymonclient.cfg <&1|head -1|cut -d' ' -f1) #ifeq ($(LDTYPE),GNU) # RPATH=-Wl,--rpath, #else # RPATH=-Wl,-R #endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mailx" xymon-4.3.30/build/test-pathmax.c0000664000076400007640000000037213460440436017073 0ustar rpmbuildrpmbuild#include #include #include int main(int argc, char *argv[]) { long res; #ifndef PATH_MAX res = pathconf("/", _PC_PATH_MAX); if (res == -1) res = 4096; printf("#define PATH_MAX %ld\n", res); #endif return 0; } xymon-4.3.30/build/test-rpcenth.c0000664000076400007640000000011211070452713017060 0ustar rpmbuildrpmbuild#include int main(int argc, char *argv[]) { return 0; } xymon-4.3.30/build/test-ssl.c0000664000076400007640000000054511070452713016230 0ustar rpmbuildrpmbuild#include #include #include #include #include #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x00905000L) #error SSL-protocol testing requires OpenSSL version 0.9.5 or later #endif int main(int argc, char *argv[]) { SSL_library_init(); return 0; } xymon-4.3.30/build/test-strtoll.c0000664000076400007640000000025611070452713017131 0ustar rpmbuildrpmbuild#include #include int main(int argc, char **argv) { long long l; l = strtoll("1234567890123456789x", NULL, 10); printf("%lld\n", l); return 0; } xymon-4.3.30/build/ssl.sh0000775000076400007640000000732512674126516015463 0ustar rpmbuildrpmbuild echo "Checking for OpenSSL ..." OSSLINC="" OSSLLIB="" for DIR in /opt/openssl* /opt/ssl* /usr/local/openssl* /usr/local/ssl* /usr/local /usr/pkg /opt/csw /opt/sfw/*ssl* /usr/sfw /usr/sfw/*ssl* do if test -d $DIR/include/openssl then OSSLINC=$DIR/include fi if test -f $DIR/lib/libcrypto.so then OSSLLIB=$DIR/lib fi if test -f $DIR/lib/libcrypto.a then OSSLLIB=$DIR/lib fi if test -f $DIR/lib64/libcrypto.so then OSSLLIB=$DIR/lib64 fi if test -f $DIR/lib64/libcrypto.a then OSSLLIB=$DIR/lib64 fi done if test "$USEROSSLINC" != ""; then OSSLINC="$USEROSSLINC" fi if test "$USEROSSLLIB" != ""; then OSSLLIB="$USEROSSLLIB" fi # Red Hat in their wisdom ships an openssl that depends on Kerberos, # and then puts the Kerberos includes where they are not found automatically. if test "`uname -s`" = "Linux" -a -d /usr/kerberos/include then OSSLINC="$OSSLINC -I/usr/kerberos/include" fi # Lets see if it builds SSLOK="YES" cd build if test "$OSSLINC" != ""; then INCOPT="-I$OSSLINC"; fi if test "$OSSLLIB" != ""; then LIBOPT="-L$OSSLLIB"; fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ssl clean OS=`uname -s | sed -e's@/@_@g'` OSSLINC="$INCOPT" $MAKE -f Makefile.test-ssl test-compile if test $? -eq 0; then echo "Compiling with SSL library works OK" else echo "Warning: Cannot compile with SSL library" SSLOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` OSSLLIB="$LIBOPT" $MAKE -f Makefile.test-ssl test-link if test $? -eq 0; then echo "Linking with SSL library works OK" else echo "Warning: Cannot link with SSL library" SSLOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ssl clean cd .. if test "$SSLOK" = "YES"; then SSLFLAGS="-DHAVE_OPENSSL" cd build echo "Checking if your SSL library has SSLv2 enabled" OS=`uname -s | sed -e's@/@_@g'` OSSLINC="$INCOPT" OSSLLIB="$LIBOPT" $MAKE -f Makefile.test-ssl2 test-compile 2>/dev/null CSTAT=$?; LSTAT=$? if test $CSTAT -eq 0; then OS=`uname -s | sed -e's@/@_@g'` OSSLINC="$INCOPT" OSSLLIB="$LIBOPT" $MAKE -f Makefile.test-ssl2 test-link 2>/dev/null LSTAT=$? fi if test $CSTAT -ne 0 -o $LSTAT -ne 0; then echo "SSLv2 support disabled (dont worry, all systems should use SSLv1 or TLS)" OSSL2OK="N" else echo "Will support SSLv2 when testing SSL-enabled network services" OSSL2OK="Y" SSLFLAGS="$SSLFLAGS -DHAVE_SSLV2_SUPPORT" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ssl2 clean echo "Checking if your SSL library has SSLv3 enabled" OS=`uname -s | sed -e's@/@_@g'` OSSLINC="$INCOPT" OSSLLIB="$LIBOPT" $MAKE -f Makefile.test-ssl3 test-compile 2>/dev/null CSTAT=$?; LSTAT=$? if test $CSTAT -eq 0; then OS=`uname -s | sed -e's@/@_@g'` OSSLINC="$INCOPT" OSSLLIB="$LIBOPT" $MAKE -f Makefile.test-ssl3 test-link 2>/dev/null LSTAT=$? fi if test $CSTAT -ne 0 -o $LSTAT -ne 0; then echo "SSLv3 support disabled (dont worry, all systems should use SSLv1 or TLS)" OSSL3OK="N" else echo "Will support SSLv3 when testing SSL-enabled network services" OSSL3OK="Y" SSLFLAGS="$SSLFLAGS -DHAVE_SSLV3_SUPPORT" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-ssl3 clean cd .. fi if test "$SSLOK" = "NO"; then echo "OpenSSL include- or library-files not found." echo "Although you can use Xymon without OpenSSL, you will not" echo "be able to run network tests of SSL-enabled services, e.g. https." echo "So installing OpenSSL is recommended." echo "OpenSSL can be found at http://www.openssl.org/" echo "" echo "If you have OpenSSL installed, use the \"--sslinclude DIR\" and \"--ssllib DIR\"" echo "options to configure to specify where they are." echo "" sleep 3 echo "Continuing with SSL support disabled." fi xymon-4.3.30/build/Makefile.HP-UX0000664000076400007640000000254312006166517016612 0ustar rpmbuildrpmbuild# Xymon compile-time settings for a HP-UX system OSDEF = -DHPUX # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = -lnsl # Compile flags for normal build # NOTE: HP-UX built-in compiler is horribly broken and will not compile Xymon. # So you should use the GNU compiler, gcc. CC = gcc # NOTE: Some HP-UX 11i systems have a severely broken set of include files. This # will typically show up when compiling the "xymonnet/xymonnet.c" where it bombs with # xymonnet.c: In function 'send_rpcinfo_results': # xymonnet.c:1794: warning: assignment makes pointer from integer without a cast # xymonnet.c:1801: error: dereferencing pointer to incomplete type # xymonnet.c:1813: error: dereferencing pointer to incomplete type # xymonnet.c:1818: error: dereferencing pointer to incomplete type # If that happens, try adding -DBROKEN_HPUX_NETDB at the end of the CFLAGS line below. GCCVER := $(shell gcc -dumpversion|cut -d. -f1) ifeq ($(GCCVER),4) CFLAGS = -Wno-unused -Wno-pointer-sign -g -O -D_REENTRANT $(LFSDEF) $(OSDEF) else CFLAGS = -g -O -D_REENTRANT $(LFSDEF) $(OSDEF) endif # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mailx" xymon-4.3.30/build/setup-newfiles.c0000664000076400007640000000722312603243142017421 0ustar rpmbuildrpmbuild#include #include #include #include #include #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { char srcfn[PATH_MAX]; char destfn[PATH_MAX]; char *p; struct stat st; unsigned char *sumbuf = NULL; if (argc > 2) { if (stat(argv[2], &st) == 0) { FILE *sumfd; printf("Loading md5-data ... "); sumfd = fopen(argv[2], "r"); if (sumfd) { sumbuf = (char *)malloc(st.st_size + 1); if (fread(sumbuf, 1, st.st_size, sumfd) == st.st_size) { printf("OK\n"); } else { printf("failed\n"); free(sumbuf); sumbuf = NULL; } fclose(sumfd); } else { printf("failed\n"); } } } while (fgets(srcfn, sizeof(srcfn), stdin)) { FILE *fd; unsigned char buf[8192]; size_t buflen; digestctx_t *ctx; char srcmd5[40]; char *md5sum; p = strchr(srcfn, '\n'); if (p) *p = '\0'; strcpy(destfn, argv[1]); p = srcfn; if (strcmp(srcfn, ".") == 0) p = ""; else if (strncmp(p, "./", 2) == 0) p += 2; strcat(destfn, p); *srcmd5 = '\0'; if (((fd = fopen(srcfn, "r")) != NULL) && ((ctx = digest_init("md5")) != NULL)) { while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen); strcpy(srcmd5, digest_done(ctx)); fclose(fd); } if (stat(destfn, &st) == 0) { /* Destination file exists, see if it's a previous version */ if (sumbuf == NULL) continue; /* No md5-data, don't overwrite an existing file */ if (!S_ISREG(st.st_mode)) continue; fd = fopen(destfn, "r"); if (fd == NULL) continue; if ((ctx = digest_init("md5")) == NULL) continue; while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen); md5sum = digest_done(ctx); fclose(fd); if (strstr(sumbuf, md5sum) == NULL) continue; /* Not one of our known versions */ if (strcmp(srcmd5, md5sum) == 0) continue; /* Already installed */ /* We now know the destination that exists is just one of our old files */ printf("Updating old standard file %s\n", destfn); unlink(destfn); } else { printf("Installing new file %s\n", destfn); } if (lstat(srcfn, &st) != 0) { printf("Error - cannot lstat() %s\n", srcfn); return 1; } if (S_ISREG(st.st_mode)) { FILE *infd, *outfd; char buf[16384]; int n; infd = fopen(srcfn, "r"); if (infd == NULL) { /* Don't know how this can happen, but .. */ fprintf(stderr, "Cannot open input file %s: %s\n", srcfn, strerror(errno)); return 1; } outfd = fopen(destfn, "w"); if (outfd == NULL) { /* Don't know how this can happen, but .. */ fprintf(stderr, "Cannot create output file %s: %s\n", destfn, strerror(errno)); return 1; } fchmod(fileno(outfd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); while ( (n = fread(buf, 1, sizeof(buf), infd)) > 0) fwrite(buf, 1, n, outfd); fclose(infd); fclose(outfd); } else if (S_ISDIR(st.st_mode)) { struct stat tmpst; /* Create upper-lying directories */ if (*destfn == '/') p = strchr(destfn+1, '/'); else p = strchr(destfn, '/'); while (p) { *p = '\0'; if ((stat(destfn, &tmpst) == 0) || (mkdir(destfn, st.st_mode) == 0)) { *p = '/'; p = strchr(p+1, '/'); } else p = NULL; } /* Create the directory itself */ if (stat(destfn, &tmpst) == -1) mkdir(destfn, st.st_mode); chmod(destfn, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); } else if (S_ISLNK(st.st_mode)) { char ldest[PATH_MAX + 1]; memset(ldest, 0, sizeof(ldest)); if ((readlink(srcfn, ldest, sizeof(ldest)-1) != -1) && (symlink(ldest, destfn) == 0)) {}; } } return 0; } xymon-4.3.30/build/Makefile.OSX0000664000076400007640000000074511535462534016430 0ustar rpmbuildrpmbuild# Xymon compile-time settings for Darwin systems # Contributed by "Marc" # NETLIBS: None needed NETLIBS = # Compile flags for normal build CC = cc CFLAGS = -g -O2 -Wall -Wno-unused -D_REENTRANT -D_BSD_SOCKLEN_T_=int $(LFSDEF) $(OSDEF) # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/makehtml.sh0000775000076400007640000000153712007210740016442 0ustar rpmbuildrpmbuild#!/bin/bash export LANG=C DATE=`date +"%e %b %Y"` VERSION="$1" if [ "$VERSION" = "" ] then echo "Usage: $0 VERSION" exit 1 fi # cd ~/xymon/trunk rm -f docs/*~ docs/manpages/index.html* docs/manpages/man1/* docs/manpages/man5/* docs/manpages/man7/* docs/manpages/man8/* for DIR in xymongen xymonnet xymonproxy common xymond web do for SECT in 1 5 7 8 do for FILE in $DIR/*.$SECT do if [ -r $FILE ] then NAME=`head -n 1 $FILE | awk '{print $2}'`; SECTION=`head -n 1 $FILE | awk '{print $3}'`; (echo ".TH $NAME $SECTION \"Version $VERSION: $DATE\" \"Xymon\""; tail -n +2 $FILE) | \ man2html -r - | tail -n +2 >docs/manpages/man$SECT/`basename $FILE`.html fi done done done # Sourceforge update # cd ~/xymon/trunk/docs && rsync -av --rsh=ssh --exclude=RCS ./ storner@shell.sourceforge.net:/home/groups/x/xy/xymon/htdocs/docs/ xymon-4.3.30/build/Makefile.test-ldap0000664000076400007640000000033511070452713017637 0ustar rpmbuildrpmbuildinclude Makefile.$(OS) test-compile: @$(CC) $(CFLAGS) $(LDAPINC) -o test-ldap.o -c test-ldap.c test-link: @$(CC) $(CFLAGS) $(LDAPLIB) -o test-ldap test-ldap.o -lldap $(LDAPLBER) clean: @rm -f test-ldap.o test-ldap xymon-4.3.30/build/test-uint.c0000664000076400007640000000022611070452713016402 0ustar rpmbuildrpmbuild#include #include int main(int argc, char *argv[]) { u_int32_t l; l = 1; printf("%u:%d\n", l, sizeof(l)); return 0; } xymon-4.3.30/build/test-snprintf.c0000664000076400007640000000036411070452713017271 0ustar rpmbuildrpmbuild#include #include #include #include #include #include int main(int argc, char *argv[]) { char l[100]; snprintf(l, sizeof(l), "testing ... %d %d %d\n", 1, 2, 3); return 0; } xymon-4.3.30/build/Makefile0000664000076400007640000000065012000050736015734 0ustar rpmbuildrpmbuildTOOLS = merge-lines merge-sects setup-newfiles renamevars renametasks all: $(TOOLS) merge-lines: merge-lines.c $(CC) -o $@ $(CFLAGS) $< merge-sects: merge-sects.c $(CC) -o $@ $(CFLAGS) $< setup-newfiles: setup-newfiles.c $(CC) -o $@ $(CFLAGS) $< ../lib/libxymonclient.a renamevars: renamevars.c $(CC) -o $@ $(CFLAGS) $< renametasks: renametasks.c $(CC) -o $@ $(CFLAGS) $< clean: rm -f $(TOOLS) testfile *.o *~ xymon-4.3.30/build/test-setenv.c0000664000076400007640000000014012523024624016722 0ustar rpmbuildrpmbuild#include int main(int argc, char *argv[]) { setenv("FOO", "BAR", 1); return 0; } xymon-4.3.30/build/test-cares.c0000664000076400007640000000346612274210064016527 0ustar rpmbuildrpmbuild#include #include #include #include #include #include int main(int argc, char *argv[]) { static ares_channel mychannel; struct ares_options options; int status, version, ver_maj, ver_min, ver_patch; int ver_maj_required, ver_min_required, ver_patch_required, failed = 0; const char *versionstr; char *version_required, *tok; version_required = strdup(argv[1]); tok = strtok(version_required, "."); ver_maj_required = atoi(tok); tok = strtok(NULL, "."); ver_min_required = atoi(tok); tok = strtok(NULL, "."); ver_patch_required = atoi(tok); versionstr = ares_version(&version); ver_maj = ((version >> 16) & 0xFF); ver_min = ((version >> 8) & 0xFF); ver_patch = (version & 0xFF); if (ver_maj > ver_maj_required) failed = 0; else if (ver_maj < ver_maj_required) failed = 1; else { /* Major version matches */ if (ver_min > ver_min_required) failed = 0; else if (ver_min < ver_min_required) failed = 1; else { /* Major and minor version matches */ if (ver_patch > ver_patch_required) failed = 0; else if (ver_patch < ver_patch_required) failed = 1; else { /* Major, minor and patch matches */ failed = 0; } } } printf("C-ARES version: Found %d.%d.%d - %s, require %d.%d.%d\n", ver_maj, ver_min, ver_patch, (failed ? "too old, will use included version" : "OK"), ver_maj_required, ver_min_required, ver_patch_required ); /* ARES timeout backported from Xymon trunk 20120411 - this should give us a ~23 second timeout */ options.timeout = 2000; options.tries = 4; status = ares_init_options(&mychannel, &options, (ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES)); if (status != ARES_SUCCESS) { printf("c-ares init failed\n"); return 1; } ares_destroy(mychannel); return (failed ? 1 : 0); } xymon-4.3.30/build/rrd.sh0000775000076400007640000000705312005761320015431 0ustar rpmbuildrpmbuild echo "Checking for RRDtool ..." RRDDEF="" RRDINC="" RRDLIB="" PNGLIB="" ZLIB="" for DIR in /opt/rrdtool* /usr/local/rrdtool* /usr/local /usr/pkg /opt/csw /opt/sfw /usr/sfw do if test -f $DIR/include/rrd.h then RRDINC=$DIR/include fi if test -f $DIR/lib/librrd.so then RRDLIB=$DIR/lib fi if test -f $DIR/lib/librrd.a then RRDLIB=$DIR/lib fi if test -f $DIR/lib64/librrd.so then RRDLIB=$DIR/lib64 fi if test -f $DIR/lib64/librrd.a then RRDLIB=$DIR/lib64 fi if test -f $DIR/lib/libpng.so then PNGLIB="-L$DIR/lib -lpng" fi if test -f $DIR/lib/libpng.a then PNGLIB="-L$DIR/lib -lpng" fi if test -f $DIR/lib64/libpng.so then PNGLIB="-L$DIR/lib64 -lpng" fi if test -f $DIR/lib64/libpng.a then PNGLIB="-L$DIR/lib64 -lpng" fi if test -f $DIR/lib/libz.so then ZLIB="-L$DIR/lib -lz" fi if test -f $DIR/lib/libz.a then ZLIB="-L$DIR/lib -lz" fi if test -f $DIR/lib64/libz.so then ZLIB="-L$DIR/lib64 -lz" fi if test -f $DIR/lib64/libz.a then ZLIB="-L$DIR/lib64 -lz" fi done if test "$USERRRDINC" != ""; then RRDINC="$USERRRDINC" fi if test "$USERRRDLIB" != ""; then RRDLIB="$USERRRDLIB" fi # See if it builds RRDOK="YES" if test "$RRDINC" != ""; then INCOPT="-I$RRDINC"; fi if test "$RRDLIB" != ""; then LIBOPT="-L$RRDLIB"; fi cd build OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-rrd clean OS=`uname -s | sed -e's@/@_@g'` RRDDEF="$RRDDEF" RRDINC="$INCOPT" $MAKE -f Makefile.test-rrd test-compile 2>/dev/null if test $? -ne 0; then # See if it's the new RRDtool 1.2.x echo "Not RRDtool 1.0.x, checking for 1.2.x" RRDDEF="-DRRDTOOL12" OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-rrd clean OS=`uname -s | sed -e's@/@_@g'` RRDDEF="$RRDDEF" RRDINC="$INCOPT" $MAKE -f Makefile.test-rrd test-compile fi if test $? -eq 0; then echo "Compiling with RRDtool works OK" else echo "ERROR: Cannot compile with RRDtool." RRDOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` RRDLIB="$LIBOPT" PNGLIB="$PNGLIB" $MAKE -f Makefile.test-rrd test-link 2>/dev/null if test $? -ne 0; then # Could be that we need -lz for RRD PNGLIB="$PNGLIB $ZLIB" fi OS=`uname -s | sed -e's@/@_@g'` RRDLIB="$LIBOPT" PNGLIB="$PNGLIB" $MAKE -f Makefile.test-rrd test-link 2>/dev/null if test $? -ne 0; then # Could be that we need -lm for RRD PNGLIB="$PNGLIB -lm" fi OS=`uname -s | sed -e's@/@_@g'` RRDLIB="$LIBOPT" PNGLIB="$PNGLIB" $MAKE -f Makefile.test-rrd test-link 2>/dev/null if test $? -ne 0; then # Could be that we need -L/usr/X11R6/lib (OpenBSD) LIBOPT="$LIBOPT -L/usr/X11R6/lib" RRDLIB="$RRDLIB -L/usr/X11R6/lib" fi OS=`uname -s | sed -e's@/@_@g'` RRDLIB="$LIBOPT" PNGLIB="$PNGLIB" $MAKE -f Makefile.test-rrd test-link 2>/dev/null if test $? -eq 0; then echo "Linking with RRDtool works OK" if test "$PNGLIB" != ""; then echo "Linking RRD needs extra library: $PNGLIB" fi else echo "ERROR: Linking with RRDtool fails" RRDOK="NO" fi OS=`uname -s | sed -e's@/@_@g'` $MAKE -f Makefile.test-rrd clean cd .. if test "$RRDOK" = "NO"; then echo "RRDtool include- or library-files not found." echo "These are REQUIRED for trend-graph support in Xymon, but Xymon can" echo "be built without them (e.g. for a network-probe only installation." echo "" echo "RRDtool can be found at http://oss.oetiker.ch/rrdtool/" echo "If you have RRDtool installed, use the \"--rrdinclude DIR\" and \"--rrdlib DIR\"" echo "options to configure to specify where they are." echo "" echo "Continuing with all trend-graph support DISABLED" sleep 3 fi xymon-4.3.30/build/makedeb.sh0000775000076400007640000000157012463723221016236 0ustar rpmbuildrpmbuild#!/bin/bash REL=$1 if [ "$REL" = "" ]; then echo "Error - missing release number" exit 1 fi BASEDIR=`pwd` cd $BASEDIR rm -rf debbuild mkdir -p $BASEDIR/debbuild/xymon-$REL for f in xymongen xymonnet bbpatches xymonproxy build common contrib docs xymond web include lib client demotool do find $f/ | egrep -v "RCS|\.svn" | cpio -pdvmu $BASEDIR/debbuild/xymon-$REL/ done cp -p Changes configure configure.server configure.client COPYING CREDITS README README.CLIENT RELEASENOTES $BASEDIR/debbuild/xymon-$REL/ find $BASEDIR/debbuild/xymon-$REL -type d|xargs chmod 755 cd debbuild pushd xymon-$REL make -f ../../Makefile distclean popd tar zcf xymon-$REL.tar.gz xymon-$REL cd $BASEDIR find debian | egrep -v "RCS|pkg|\.svn" | cpio -pdvmu $BASEDIR/debbuild/xymon-$REL/ cd debbuild/xymon-$REL dpkg-buildpackage -rfakeroot #mv ../xymon*$REL*.{deb,dsc,changes} ../../debian/pkg/ xymon-4.3.30/build/Makefile.rules0000664000076400007640000005527313443010711017101 0ustar rpmbuildrpmbuild# Xymon main Makefile # # This file is included from the Makefile created by the "configure" script ##################### # Build targets ##################### CFLAGS += -I$(BUILDTOPDIR)/include ifeq ($(CLIENTONLY),yes) BUILDTARGETS = client CFLAGS += -DCLIENTONLY=1 XYMONCLIENTHOME = $(XYMONTOPDIR) XYMONHOME = $(XYMONTOPDIR) ifeq ($(LOCALCLIENT),yes) CLIENTTARGETS = lib-client common-client build-build xymond-client INSTALLTARGETS = install-client install-localclient install-clientmsg CFLAGS += -DLOCALCLIENT=1 $(PCREINCDIR) else CLIENTTARGETS = lib-client common-client build-build INSTALLTARGETS = install-client install-clientmsg endif else BUILDTARGETS = lib-build common-build xymongen-build xymonnet-build xymonproxy-build docs-build build-build xymond-build web-build client CLIENTTARGETS = lib-client common-client build-build INSTALLTARGETS = install-xymongen install-xymonnet install-xymonproxy install-xymond install-web install-docs install-client install-servermsg CFLAGS += $(PCREINCDIR) XYMONCLIENTHOME = $(XYMONTOPDIR)/client XYMONHOME = $(XYMONTOPDIR)/server endif ifndef INSTALLBINDIR INSTALLBINDIR = $(XYMONHOME)/bin endif ifndef INSTALLETCDIR INSTALLETCDIR = $(XYMONHOME)/etc endif ifndef INSTALLEXTDIR INSTALLEXTDIR = $(XYMONHOME)/ext endif ifndef INSTALLTMPDIR INSTALLTMPDIR = $(XYMONHOME)/tmp endif ifndef INSTALLWEBDIR INSTALLWEBDIR = $(XYMONHOME)/web endif ifndef INSTALLWWWDIR INSTALLWWWDIR = $(XYMONHOME)/www endif MINARESVER = 1.5.1 ARESVER = 1.15.0 FPINGVER = 3.0 IDTOOL := $(shell if test `uname -s` = "SunOS"; then echo /usr/xpg4/bin/id; else echo id; fi) ifdef RPATH RPATHOPT := $(RPATH)$(shell echo $(RPATHVAL) | sed -e 's/ / $(RPATH)/g') endif all: include/config.h $(BUILDTARGETS) @echo "" @echo "Build complete." @echo "" @echo "#####################################################################" @echo "IMPORTANT: If upgrading from 4.2.x, see the docs/upgrade-to-430.txt" @echo " file for instructions. You must run build/upgrade430.sh" @echo " before installing the new version." @echo "#####################################################################" @echo "" @echo "Now run '${MAKE} install' as root" @echo "" client: include/config.h $(CLIENTTARGETS) CC="$(CC)" CFLAGS="$(CFLAGS)" XYMONHOME="$(XYMONCLIENTHOME)" XYMONHOSTIP="$(XYMONHOSTIP)" LOCALCLIENT="$(LOCALCLIENT)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" $(MAKE) -C client all include/config.h: MAKE="$(MAKE)" CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" $(BUILDTOPDIR)/build/genconfig.sh build-build: CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONHOME)" $(MAKE) -C build all lib-build: include/config.h CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" OSDEF="$(OSDEF)" RPATHOPT="$(RPATHOPT)" PCREINCDIR="$(PCREINCDIR)" ZLIBINCDIR="$(ZLIBINCDIR)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONCLIENTHOME=$(XYMONCLIENTHOME) XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" $(MAKE) -C lib all lib-client: CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" OSDEF="$(OSDEF)" RPATHOPT="$(RPATHOPT)" PCREINCDIR="$(PCREINCDIR)" ZLIBINCDIR="$(ZLIBINCDIR)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONCLIENTHOME)" XYMONCLIENTHOME=$(XYMONCLIENTHOME) XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" LOCALCLIENT="$(LOCALCLIENT)" $(MAKE) -C lib client common-build: lib-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" ZLIBLIBS="$(ZLIBLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONHOME)" $(MAKE) -C common all common-client: lib-client CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" ZLIBLIBS="$(ZLIBLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONCLIENTHOME)" $(MAKE) -C common client xymongen-build: lib-build common-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" HISTGRAPHDEF="$(HISTGRAPHDEF)" RUNTIMEDEFS="$(RUNTIMEDEFS)" PCREINCDIR="$(PCREINCDIR)" PCRELIBS="$(PCRELIBS)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" $(MAKE) -C xymongen all xymonnet-build: lib-build common-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" DOLDAP="$(DOLDAP)" LDAPFLAGS="$(LDAPFLAGS)" LDAPINCDIR="$(LDAPINCDIR)" LDAPLIBS="$(LDAPLIBS)" DOSNMP="$(DOSNMP)" NETLIBS="$(NETLIBS)" XYMONHOME="$(XYMONHOME)" ARESVER="$(ARESVER)" FPINGVER="$(FPINGVER)" RUNTIMEDEFS="$(RUNTIMEDEFS)" PCREINCDIR="$(PCREINCDIR)" PCRELIBS="$(PCRELIBS)" SYSTEMCARES="$(SYSTEMCARES)" CARESINCDIR="$(CARESINCDIR)" CARESLIBS="$(CARESLIBS)" SQLITELIBS="$(SQLITELIBS)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" LIBRTDEF="$(LIBRTDEF)" $(MAKE) -C xymonnet all xymonproxy-build: lib-build common-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONHOME)" $(MAKE) -C xymonproxy all xymond-build: lib-build build-build common-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" DORRD="$(DORRD)" RRDDEF="$(RRDDEF)" RRDINCDIR="$(RRDINCDIR)" PCREINCDIR="$(PCREINCDIR)" SSLFLAGS="$(SSLFLAGS)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" RRDLIBS="$(RRDLIBS)" PCRELIBS="$(PCRELIBS)" SQLITELIBS="$(SQLITELIBS)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" XYMONUSER="$(XYMONUSER)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONHOSTURL="$(XYMONHOSTURL)" XYMONCGIURL="$(XYMONCGIURL)" SECUREXYMONCGIURL="$(SECUREXYMONCGIURL)" MAILPROGRAM="$(MAILPROGRAM)" RUNTIMEDEFS="$(RUNTIMEDEFS)" INSTALLWWWDIR="$(INSTALLWWWDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" FPING="$(FPING)" $(MAKE) -C xymond all web-build: lib-build build-build common-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" DORRD="$(DORRD)" RRDDEF="$(RRDDEF)" RRDINCDIR="$(RRDINCDIR)" PCREINCDIR="$(PCREINCDIR)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" RRDLIBS="$(RRDLIBS)" PCRELIBS="$(PCRELIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" XYMONUSER="$(XYMONUSER)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONHOSTURL="$(XYMONHOSTURL)" XYMONCGIURL="$(XYMONCGIURL)" SECUREXYMONCGIURL="$(SECUREXYMONCGIURL)" MAILPROGRAM="$(MAILPROGRAM)" RUNTIMEDEFS="$(RUNTIMEDEFS)" INSTALLWWWDIR="$(INSTALLWWWDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" $(MAKE) -C web all xymond-client: lib-client build-build common-client CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" LIBRTDEF="$(LIBRTDEF)" RRDDEF="$(RRDDEF)" RRDINCDIR="$(RRDINCDIR)" PCREINCDIR="$(PCREINCDIR)" NETLIBS="$(NETLIBS)" RRDLIBS="$(RRDLIBS)" PCRELIBS="$(PCRELIBS)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" XYMONUSER="$(XYMONUSER)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONHOSTURL="$(XYMONHOSTURL)" XYMONCGIURL="$(XYMONCGIURL)" SECUREXYMONCGIURL="$(SECUREXYMONCGIURL)" MAILPROGRAM="$(MAILPROGRAM)" RUNTIMEDEFS="$(RUNTIMEDEFS)" INSTALLWWWDIR="$(INSTALLWWWDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" $(MAKE) -C xymond client docs-build: XYMONHOSTURL="$(XYMONHOSTURL)" $(MAKE) -C docs all custom-build: lib-build CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" RRDDEF="$(RRDDEF)" RRDINCDIR="$(RRDINCDIR)" PCREINCDIR="$(PCREINCDIR)" NETLIBS="$(NETLIBS)" RRDLIBS="$(RRDLIBS)" PCRELIBS="$(PCRELIBS)" ZLIBINCDIR="$(ZLIBINCDIR)" ZLIBLIBS="$(ZLIBLIBS)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" XYMONUSER="$(XYMONUSER)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONHOSTURL="$(XYMONHOSTURL)" XYMONCGIURL="$(XYMONCGIURL)" SECUREXYMONCGIURL="$(SECUREXYMONCGIURL)" MAILPROGRAM="$(MAILPROGRAM)" RUNTIMEDEFS="$(RUNTIMEDEFS)" INSTALLWWWDIR="$(INSTALLWWWDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" $(MAKE) -C custom all || echo "Skipped custom modules" demo-build: CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" NETLIBS="$(NETLIBS)" $(MAKE) -C demotool all win32: include/config.h CC="$(CC)" CFLAGS="$(CFLAGS) -DXYMONWINCLIENT -DCLIENTONLY" LDFLAGS="$(LDFLAGS)" RPATHOPT="$(RPATHOPT)" SSLFLAGS="$(SSLFLAGS)" SSLINCDIR="$(SSLINCDIR)" SSLLIBS="$(SSLLIBS)" NETLIBS="$(NETLIBS)" LIBRTDEF="$(LIBRTDEF)" XYMONHOME="$(XYMONHOME)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONHOSTNAME="$(XYMONHOSTNAME)" XYMONHOSTIP="$(XYMONHOSTIP)" XYMONHOSTOS="$(XYMONHOSTOS)" $(MAKE) -C common xymon.exe ##################### # Cleanup targets ##################### distclean: allclean rm -f Makefile rm -rf xymonnet/c-ares rm -rf debbuild rpmbuild allclean: clean (cd xymonnet/c-ares 2>/dev/null && $(MAKE) clean) || true clean: $(MAKE) -C build clean $(MAKE) -C lib clean $(MAKE) -C common clean $(MAKE) -C xymongen clean $(MAKE) DOSNMP="$(DOSNMP)" DOLDAP="$(DOLDAP)" -C xymonnet clean $(MAKE) -C xymonproxy clean $(MAKE) DORRD="$(DORRD)" -C xymond clean $(MAKE) DORRD="$(DORRD)" -C web clean $(MAKE) -C docs clean $(MAKE) -C client clean # $(MAKE) -C demotool clean # $(MAKE) -C custom clean || echo "" rm -f ./*~ include/config.h include/*~ debian/*~ rpm/*~ contrib/*~ #################### # Install targets #################### install: $(INSTALLTARGETS) install-servermsg: @echo "" @echo "Installation complete." @echo "" @echo "You must configure your webserver for the Xymon webpages and CGI-scripts." @echo "A sample Apache configuration is in ${XYMONHOME}/etc/xymon-apache.conf" @echo "If you have your Administration CGI scripts in a separate directory," @echo "then you must also setup the password-file with the htpasswd command." @echo "" @echo "To start Xymon, as the $(XYMONUSER) user run '${XYMONHOME}/bin/xymon.sh start'" @echo "To view the Xymon webpages, go to http://${XYMONHOSTNAME}${XYMONHOSTURL}" install-dirs: mkdir -p $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/download $(INSTALLROOT)$(XYMONVAR) ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/download $(INSTALLROOT)$(XYMONVAR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/download $(INSTALLROOT)$(XYMONVAR) chmod 755 $(INSTALLROOT)$(XYMONHOME) $(INSTALLROOT)$(XYMONHOME)/download $(INSTALLROOT)$(XYMONVAR) endif mkdir -p $(INSTALLROOT)$(INSTALLBINDIR) ifneq ($(INSTALLBINDIR),$(XYMONHOME)/bin) rm -f $(INSTALLROOT)$(XYMONHOME)/bin || true ln -s $(INSTALLBINDIR) $(INSTALLROOT)$(XYMONHOME)/bin || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLBINDIR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLBINDIR) chmod 755 $(INSTALLROOT)$(INSTALLBINDIR) endif mkdir -p $(INSTALLROOT)$(INSTALLETCDIR) ifneq ($(INSTALLETCDIR),$(XYMONHOME)/etc) rm -f $(INSTALLROOT)$(XYMONHOME)/etc || true ln -s $(INSTALLETCDIR) $(INSTALLROOT)$(XYMONHOME)/etc || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLETCDIR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLETCDIR) chmod 755 $(INSTALLROOT)$(INSTALLETCDIR) endif mkdir -p $(INSTALLROOT)$(INSTALLEXTDIR) ifneq ($(INSTALLEXTDIR),$(XYMONHOME)/ext) rm -f $(INSTALLROOT)$(XYMONHOME)/ext || true ln -s $(INSTALLEXTDIR) $(INSTALLROOT)$(XYMONHOME)/ext || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLEXTDIR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLEXTDIR) chmod 755 $(INSTALLROOT)$(INSTALLEXTDIR) endif mkdir -p $(INSTALLROOT)$(INSTALLTMPDIR) ifneq ($(INSTALLTMPDIR),$(XYMONHOME)/tmp) rm -f $(INSTALLROOT)$(XYMONHOME)/tmp || true ln -s $(INSTALLTMPDIR) $(INSTALLROOT)$(XYMONHOME)/tmp || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLTMPDIR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLTMPDIR) chmod 755 $(INSTALLROOT)$(INSTALLTMPDIR) endif mkdir -p $(INSTALLROOT)$(INSTALLWEBDIR) ifneq ($(INSTALLWEBDIR),$(XYMONHOME)/web) rm -f $(INSTALLROOT)$(XYMONHOME)/web || true ln -s $(INSTALLWEBDIR) $(INSTALLROOT)$(XYMONHOME)/web || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLWEBDIR) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLWEBDIR) chmod 755 $(INSTALLROOT)$(INSTALLWEBDIR) endif mkdir -p $(INSTALLROOT)$(INSTALLWWWDIR) $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap $(INSTALLROOT)$(INSTALLWWWDIR)/wml ifneq ($(INSTALLWWWDIR),$(XYMONHOME)/www) rm -f $(INSTALLROOT)$(XYMONHOME)/www || true ln -s $(INSTALLWWWDIR) $(INSTALLROOT)$(XYMONHOME)/www || true endif ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(INSTALLWWWDIR) $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap $(INSTALLROOT)$(INSTALLWWWDIR)/wml chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(INSTALLWWWDIR) $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap $(INSTALLROOT)$(INSTALLWWWDIR)/wml chmod 755 $(INSTALLROOT)$(INSTALLWWWDIR) $(INSTALLROOT)$(INSTALLWWWDIR)/gifs $(INSTALLROOT)$(INSTALLWWWDIR)/help $(INSTALLROOT)$(INSTALLWWWDIR)/html $(INSTALLROOT)$(INSTALLWWWDIR)/menu $(INSTALLROOT)$(INSTALLWWWDIR)/notes $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap $(INSTALLROOT)$(INSTALLWWWDIR)/wml ifdef HTTPDGID # The www/rep and www/snap directories must be writable by the apache daemon chgrp $(HTTPDGID) $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap endif chmod g+w $(INSTALLROOT)$(INSTALLWWWDIR)/rep $(INSTALLROOT)$(INSTALLWWWDIR)/snap endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/acks ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/acks chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/acks chmod 755 $(INSTALLROOT)$(XYMONVAR)/acks endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/data ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/data chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/data chmod 755 $(INSTALLROOT)$(XYMONVAR)/data endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/disabled ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/disabled chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/disabled chmod 755 $(INSTALLROOT)$(XYMONVAR)/disabled endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/hist ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/hist chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/hist chmod 755 $(INSTALLROOT)$(XYMONVAR)/hist endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/histlogs ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/histlogs || echo "Warning: Could not set owner on the histlogs directory" chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/histlogs || echo "Warning: Could not set group on the histlogs directory" chmod 755 $(INSTALLROOT)$(XYMONVAR)/histlogs endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/hostdata ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/hostdata || echo "Warning: Could not set owner on the hostdata directory" chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/hostdata || echo "Warning: Could not set group on the hostdata directory" chmod 755 $(INSTALLROOT)$(XYMONVAR)/hostdata endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/logs ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/logs chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/logs chmod 755 $(INSTALLROOT)$(XYMONVAR)/logs endif mkdir -p $(INSTALLROOT)$(XYMONVAR)/rrd ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(XYMONVAR)/rrd chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(XYMONVAR)/rrd chmod 755 $(INSTALLROOT)$(XYMONVAR)/rrd endif install-common: install-dirs XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C common install install-xymongen: install-common XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C xymongen install install-xymongen-nocgi: install-common XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C xymongen install-nocgi install-xymonnet: install-common XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" ARESVER="$(ARESVER)" FPINGVER="$(FPINGVER)" DOSNMP="$(DOSNMP)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" PKGBUILD="$(PKGBUILD)" $(MAKE) -C xymonnet install install-xymonproxy: install-common XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C xymonproxy install install-xymond: install-common DORRD="$(DORRD)" MANROOT="$(MANROOT)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" HTTPDGID="$(HTTPDGID)" $(MAKE) -C xymond install install-web: install-common DORRD="$(DORRD)" MANROOT="$(MANROOT)" XYMONTOPDIR="$(XYMONTOPDIR)" XYMONHOME="$(XYMONHOME)" XYMONVAR="$(XYMONVAR)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" XYMONLOGDIR="$(XYMONLOGDIR)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C web install find $(INSTALLROOT)$(INSTALLWWWDIR) -type f -exec chmod 644 {} \; # NOTE: This one is normally not used - man-page install is done by the sub-Makefiles during "make install" install-man: XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C common install-man XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" CGIDIR="$(CGIDIR)" SECURECGIDIR="$(SECURECGIDIR)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C xymongen install-man XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C xymonnet install-man XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C xymonproxy install-man XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C xymond install-man XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" INSTALLROOT="$(INSTALLROOT)" $(MAKE) -C web install-man find $(INSTALLROOT)$(MANROOT) -type f -exec chmod 644 {} \; install-docs: XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C docs install install-custom: XYMONHOME="$(XYMONHOME)" MANROOT="$(MANROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" INSTALLROOT="$(INSTALLROOT)" INSTALLBINDIR="$(INSTALLBINDIR)" INSTALLETCDIR="$(INSTALLETCDIR)" INSTALLEXTDIR="$(INSTALLEXTDIR)" INSTALLTMPDIR="$(INSTALLTMPDIR)" INSTALLWEBDIR="$(INSTALLWEBDIR)" INSTALLWWWDIR="$(INSTALLWWWDIR)" $(MAKE) -C custom install || echo "Skipped custom modules" client-install: install-client install-client: client XYMONHOME="$(XYMONCLIENTHOME)" INSTALLROOT="$(INSTALLROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" PKGBUILD="$(PKGBUILD)" LOCALCLIENT="$(LOCALCLIENT)" $(MAKE) -C client install install-clientmsg: @echo "" @echo "Installation complete." @echo "" @echo "To start the Xymon client, as the $(XYMONUSER) user run '${XYMONHOME}/runclient.sh start'" install-localclient: XYMONHOME="$(XYMONCLIENTHOME)" INSTALLROOT="$(INSTALLROOT)" XYMONUSER="$(XYMONUSER)" IDTOOL="$(IDTOOL)" LOCALCLIENT="$(LOCALCLIENT)" $(MAKE) -C client install-localclient xymon-4.3.30/build/test-ssl3.c0000664000076400007640000000064012674126516016321 0ustar rpmbuildrpmbuild#include #include #include #include #include #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x00905000L) #error SSL-protocol testing requires OpenSSL version 0.9.5 or later #endif int main(int argc, char *argv[]) { SSL_CTX *ctx; SSL_library_init(); ctx = SSL_CTX_new(SSLv3_client_method()); return 0; } xymon-4.3.30/build/Makefile.generic0000664000076400007640000000117511535462534017371 0ustar rpmbuildrpmbuild# Xymon compile-time settings for a GENERIC system # OSDEF = -Dgeneric # NETLIBS: You may need to add -lresolv or similar to pick up network libraries NETLIBS = # Compile flags for normal build CC = cc CFLAGS = -g -O -D_REENTRANT $(OSDEF) # Compile flags for debugging # CFLAGS = -g -DDEBUG -D_REENTRANT $(OSDEF) # Extra environment settings for runtime stuff. # E.g. RUNTIMEDEFS="LD_LIBRARY_PATH=\"/opt/lib\"" to use # runtime libraries located in /opt/lib RUNTIMEDEFS = # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/build/Makefile.FreeBSD0000664000076400007640000000110012262737100017143 0ustar rpmbuildrpmbuild# Xymon compile-time settings for FreeBSD systems OSDEF = -DBSD # NETLIBS: None needed NETLIBS = # Compile flags for normal build CC ?= cc CFLAGS = -g -O2 -Wall -Wno-unused -Wno-pointer-sign -D_REENTRANT -I/usr/local/include -L/usr/local/lib $(LFSDEF) $(OSDEF) RPATH = "-Wl,--rpath," # Compile flags for debugging # CFLAGS = -g -DDEBUG -Wall -D_REENTRANT -I/usr/local/include -L/usr/local/lib $(LFSDEF) $(OSDEF) # Mail program: This must support "CMD -s SUBJECT ADDRESS" to send out a mail with a subject # Typically, this will be "mail" or "mailx" MAILPROGRAM="mail" xymon-4.3.30/xymongen/0000775000076400007640000000000013534041774015057 5ustar rpmbuildrpmbuildxymon-4.3.30/xymongen/rssgen.c0000664000076400007640000002103512603243142016512 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* This file contains code to generate RSS/RDF format output of alerts. */ /* It is heavily influenced by Jeff Stoner's bb_content-feed script. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: rssgen.c 7678 2015-10-01 14:42:42Z jccleaver $"; #include #include #include #include #include "xymongen.h" #include "util.h" #include "rssgen.h" char *rssversion = "0.91"; int rsscolorlimit = COL_RED; int nssidebarcolorlimit = COL_RED; char *rsstitle = "Xymon Critical Alerts"; #define RSS091 0 #define RSS092 1 #define RSS10 2 #define RSS20 3 static int rssver = 0; static int ttlvalue = 300; static int anyshown = 0; static void initial_rss_setup(void) { static int hasrun = 0; if (hasrun) return; if (xgetenv("XYMONRSSTITLE")) rsstitle = strdup(xgetenv("XYMONRSSTITLE")); if (strcmp(rssversion, "0.91") == 0) rssver = RSS091; else if (strcmp(rssversion, "0.92") == 0) rssver = RSS092; else if (strcmp(rssversion, "1.0") == 0) rssver = RSS10; else if (strcmp(rssversion, "2.0") == 0) rssver = RSS20; else { errprintf("Unknown RSS version requested (%s), using 0.91\n", rssversion); rssver = RSS091; } ttlvalue = (xgetenv("TASKSLEEP") ? (atoi(xgetenv("TASKSLEEP")) / 60) : 5); } void do_rss_header(FILE *fd) { if (fd == NULL) return; initial_rss_setup(); switch (rssver) { case RSS091: fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, " %s\n", rsstitle); fprintf(fd, " %s/\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " Last updated on %s\n", timestamp); break; case RSS092: fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, " %s\n", rsstitle); fprintf(fd, " %s/\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " Last updated on %s\n", timestamp); fprintf(fd, " \n"); fprintf(fd, " %s/gifs/bblogo.gif\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " Xymon\n"); fprintf(fd, " http://xymon.sourceforge.net/\n"); fprintf(fd, " \n"); break; case RSS10: fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, " \n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " %s\n", rsstitle); fprintf(fd, " %s/\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " Last updated on %s\n", timestamp); fprintf(fd, " \n"); break; case RSS20: fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, " \n"); fprintf(fd, " %s\n", rsstitle); fprintf(fd, " %s/\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " Last updated on %s\n", timestamp); fprintf(fd, " %d\n", ttlvalue); break; } anyshown = 0; } void do_rss_item(FILE *fd, host_t *h, entry_t *e) { if (fd == NULL) return; if (h->color < rsscolorlimit) return; if (e->color < rsscolorlimit) return; anyshown = 1; switch (rssver) { case RSS091: case RSS092: case RSS20: fprintf(fd, " \n"); break; case RSS10: fprintf(fd, " \n", xgetenv("XYMONWEBHOSTURL"), htmlextension); break; } fprintf(fd, " %s (%s)\n", h->hostname, e->column->name); fprintf(fd, " "); if (generate_static()) { /* * Don't use htmlextension here - the .html files are generated by bbd. */ fprintf(fd, "%s/html/%s.%s.html", xgetenv("XYMONWEBHOSTURL"), h->hostname, e->column->name); } else { fprintf(fd, "%s%s", xgetenv("XYMONWEBHOST"), hostsvcurl(h->hostname, e->column->name, 1)); } fprintf(fd, "\n"); if (e->shorttext) { char *inpos = e->shorttext; int len; char savech; fprintf(fd, ""); /* Must escape any '&', '<' and '>' -characters, or RSS readers will choke on them */ while (*inpos) { len = strcspn(inpos, "&<>"); savech = *(inpos+len); *(inpos+len) = '\0'; fprintf(fd, "%s", inpos); *(inpos+len) = savech; inpos += len; if (savech != '\0') { switch (savech) { case '&': fprintf(fd, "&"); break; case '>': fprintf(fd, ">"); break; case '<': fprintf(fd, "<"); break; } inpos++; /* Skip the escaped char we just output */ } } fprintf(fd, "\n"); } fprintf(fd, " \n"); } void do_rss_footer(FILE *fd) { if (fd == NULL) return; if (!anyshown) { fprintf(fd, " \n"); fprintf(fd, " No Critical Alerts\n"); fprintf(fd, " %s/\n", xgetenv("XYMONWEBHOSTURL")); fprintf(fd, " \n"); } switch (rssver) { case RSS091: case RSS092: case RSS20: fprintf(fd, " \n"); fprintf(fd, "\n"); break; case RSS10: fprintf(fd, "\n"); break; } } void do_netscape_sidebar(char *nssidebarfilename, host_t *hosts) { FILE *fd; char tmpfn[PATH_MAX]; char destfn[PATH_MAX]; int ttlvalue; host_t *h; int anyshown; if (nssidebarfilename == NULL) return; if (xgetenv("XYMONRSSTITLE")) rsstitle = strdup(xgetenv("XYMONRSSTITLE")); ttlvalue = (xgetenv("TASKSLEEP") ? atoi(xgetenv("TASKSLEEP")) : 300); if (*nssidebarfilename == '/') { sprintf(tmpfn, "%s.tmp", nssidebarfilename); sprintf(destfn, "%s", nssidebarfilename); } else { sprintf(tmpfn, "%s/www/%s.tmp", xgetenv("XYMONHOME"), nssidebarfilename); sprintf(destfn, "%s/www/%s", xgetenv("XYMONHOME"), nssidebarfilename); } fd = fopen(tmpfn, "w"); if (fd == NULL) { errprintf("Cannot create Netscape sidebar outputfile %s\n", tmpfn); return; } fprintf(fd, "\n"); fprintf(fd, "\n"); fprintf(fd, " \n"); fprintf(fd, " %s\n", rsstitle); fprintf(fd, " \n"); fprintf(fd, " \n", ttlvalue, xgetenv("XYMONWEBHOSTURL"), nssidebarfilename); fprintf(fd, " \n"); fprintf(fd, " \n"); fprintf(fd, " Last updated:
%s
\n", timestamp); fprintf(fd, " \n"); fprintf(fd, " \n"), fprintf(fd, "\n"); fclose(fd); if (rename(tmpfn, destfn) != 0) { errprintf("Cannot move file %s to destination %s\n", tmpfn, destfn); } return; } xymon-4.3.30/xymongen/process.h0000664000076400007640000000171211615341300016671 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __PROCESS_H_ #define __PROCESS_H_ extern void calc_hostcolors(char *nongreenignores); extern void calc_pagecolors(xymongen_page_t *phead); extern void delete_old_acks(void); extern void send_summaries(summary_t *sumhead); #endif xymon-4.3.30/xymongen/rssgen.h0000664000076400007640000000205311615341300016513 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon webpage generator tool. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __RSSGEN_H__ #define __RSSGEN_H__ extern char *rssversion; extern int rsscolorlimit; extern int nssidebarcolorlimit; extern void do_rss_header(FILE *fd); extern void do_rss_item(FILE *fd, host_t *h, entry_t *e); extern void do_rss_footer(FILE *fd); extern void do_netscape_sidebar(char *rssfilename, host_t *hosts); #endif xymon-4.3.30/xymongen/pagegen.h0000664000076400007640000000372112615432073016634 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __PAGEGEN_H_ #define __PAGEGEN_H_ extern int subpagecolumns; extern int hostsbeforepages; extern char *includecolumns; extern char *nongreenignorecolumns; extern int nongreencolors; extern int sort_grouponly_items; extern char *documentationurl; extern char *doctargetspec; extern char *rssextension; extern char *defaultpagetitle; extern char *eventignorecolumns; extern char *htaccess; extern char *xymonhtaccess; extern char *xymonpagehtaccess; extern char *xymonsubpagehtaccess; extern int pagetitlelinks; extern int pagetextheadings; extern int underlineheadings; extern int maxrowsbeforeheading; extern int showemptygroups; extern int nongreeneventlog; extern int nongreenacklog; extern int nongreeneventlogmaxcount; extern int nongreeneventlogmaxtime; extern int nongreennodialups; extern int nongreenacklogmaxcount; extern int nongreenacklogmaxtime; extern char *logcritstatus; extern int critonlyreds; extern int wantrss; extern void select_headers_and_footers(char *prefix); extern void do_one_page(xymongen_page_t *page, dispsummary_t *sums, int embedded); extern void do_page_with_subs(xymongen_page_t *curpage, dispsummary_t *sums); extern int do_nongreen_page(char *nssidebarfilename, int summarytype, char *filenamebase); #endif xymon-4.3.30/xymongen/xymongen.h0000664000076400007640000002003611664525562017101 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This file holds data-definitions and declarations used in xymongen. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef _XYMONGEN_H_ #define _XYMONGEN_H_ #include #include "libxymon.h" /* Structure defs for xymongen */ /* This "drawing" depicts the relations between the various data objects used by xymongen. Think of this as doing object-oriented programming in plain C. xymongen_page_t hostlist_t state_t +-> name hostentry --+ entry --+ | title next | next | | color | | | subpages +-----------+ +-------+ | groups -------> group_t | | | hosts ---+ title V | +--- parent | hosts ---------> host_t | oldage | onlycols hostname | next | next ip | ^ +------------------------> color | | oldage | | nongreencolor | | criticalcolor | +--------------------------------- parent | alerts | waps | anywaps | nopropyellowtests | nopropredtests | noproppurpletests | nopropacktests | rawentry V entries ---------> entry_t dialup column -------> xymongen_col_t reportwarnlevel color name comment age next next oldage acked alert onwap propagate reportinfo fileage next xymongen_page_t structure holds data about one Xymon page - the first record in this list represents the top-level xymon.html page. Other pages in the list are defined using the hosts.cfg "page" directive and access via the page->next link. subpages are stored in xymongen_page_t structures also. Accessible via the "subpages" link from a page. group_t structure holds the data from a "group" directive. groups belong to pages or subpages. Currently, all groups act as "group-compress" directive. host_t structure holds all data about a given host. "color" is calculated as the most critical color of the individual entries belonging to this host. Individual tests are connected to the host via the "entries" link. hostlist_t is a simple 1-dimensional list of all the hosts, for easier traversal of the host list. entry_t holds the data for a given test (basically, a file in $XYMONRAWSTATUSDIR). test-names are not stored directly, but in the linked "xymongen_col_t" list. "age" is the "Status unchanged in X" text from the logfile. "oldage" is a boolean indicating if "age" is more than 1 day. "alert" means this test belongs on the reduced summary (alerts) page. state_t is a simple 1-dimensional list of all tests (entry_t records). */ #define PAGE_NORMAL 0 #define PAGE_NONGREEN 1 #define PAGE_CRITICAL 2 /* Max number of purple messages in one run */ #define MAX_PURPLE_PER_RUN 30 /* Column definitions. */ /* Basically a list of all possible column */ /* names */ typedef struct xymongen_col_t { char *name; char *listname; /* The ",NAME," string used for searches */ struct xymongen_col_t *next; } xymongen_col_t; typedef struct col_list_t { struct xymongen_col_t *column; struct col_list_t *next; } col_list_t; /* Measurement entry definition */ /* This points to a column definition, and */ /* contains the actual color of a measurement */ /* Linked list. */ typedef struct entry_t { struct xymongen_col_t *column; int color; char age[20]; int oldage; time_t fileage; int acked; int alert; int onwap; int propagate; int compacted; char *sumurl; char *skin; char *testflags; struct reportinfo_t *repinfo; struct replog_t *causes; char *histlogname; char *shorttext; struct entry_t *next; } entry_t; /* Aux. list definition for loading state of all tests into one list */ typedef struct state_t { struct entry_t *entry; struct state_t *next; } state_t; /* OSX has a built-in "host_t" type. */ #define host_t xymongen_host_t typedef struct host_t { char *hostname; char *displayname; char *clientalias; char *comment; char *description; char ip[IP_ADDR_STRLEN]; int dialup; struct entry_t *entries; int color; /* Calculated */ int nongreencolor; /* Calculated */ int criticalcolor; /* Calculated */ int oldage; char *alerts; int nktime; int anywaps; int wapcolor; char *waps; char *nopropyellowtests; char *nopropredtests; char *noproppurpletests; char *nopropacktests; char *pretitle; struct xymongen_page_t *parent; double reportwarnlevel; int reportwarnstops; char *reporttime; int nonongreen; struct host_t *next; } host_t; /* Aux. list definition for quick access to host records */ typedef struct hostlist_t { struct host_t *hostentry; struct hostlist_t *clones; } hostlist_t; typedef struct group_t { char *title; char *onlycols; char *exceptcols; struct host_t *hosts; int sorthosts; char *pretitle; struct group_t *next; } group_t; typedef struct xymongen_page_t { char *name; char *title; int color; /* Calculated */ int oldage; char *pretitle; int vertical; struct xymongen_page_t *next; struct xymongen_page_t *subpages; struct xymongen_page_t *parent; struct group_t *groups; struct host_t *hosts; } xymongen_page_t; typedef struct summary_t { char *name; char *receiver; char *url; struct summary_t *next; } summary_t; typedef struct dispsummary_t { char *row; char *column; char *url; int color; struct dispsummary_t *next; } dispsummary_t; enum tooltipuse_t { TT_STDONLY, TT_ALWAYS, TT_NEVER}; extern enum tooltipuse_t tooltipuse; extern xymongen_page_t *pagehead; extern state_t *statehead; extern xymongen_col_t *colhead, null_column; extern summary_t *sumhead; extern dispsummary_t *dispsums; extern int xymon_color, nongreen_color, critical_color; extern time_t reportstart, reportend; extern double reportwarnlevel, reportgreenlevel; extern int reportwarnstops; extern int reportstyle; extern int dynamicreport; extern int fqdn; extern int loadhostsfromxymond; #endif xymon-4.3.30/xymongen/loaddata.c0000664000076400007640000004255312661666466017020 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This file contains code to load the current Xymon status data. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: loaddata.c 7904 2016-02-19 19:29:58Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "xymongen.h" #include "util.h" #include "loadlayout.h" #include "loaddata.h" int statuscount = 0; char *ignorecolumns = NULL; /* Columns that will be ignored totally */ char *dialupskin = NULL; /* XYMONSKIN used for dialup tests */ char *reverseskin = NULL; /* XYMONSKIN used for reverse tests */ time_t recentgif_limit = 86400; /* Limit for recent-gifs display, in seconds */ xymongen_col_t null_column = { "", NULL }; /* Null column */ char *purplelogfn = NULL; static FILE *purplelog = NULL; int colorcount[COL_COUNT] = { 0, }; int colorcount_noprop[COL_COUNT] = { 0, }; static time_t oldestentry; typedef struct compact_t { char *compactname; int color; time_t fileage; char *members; } compact_t; typedef struct logdata_t { /* hostname|testname|color|testflags|lastchange|logtime|validtime|acktime|disabletime|sender|cookie|1st line of message */ char *hostname; char *testname; int color; char *testflags; time_t lastchange; time_t logtime; time_t validtime; time_t acktime; time_t disabletime; char *sender; int cookie; char *msg; } logdata_t; char *parse_testflags(char *l) { char *result = NULL; char *flagstart = strstr(l, "[flags:"); if (flagstart) { char *flagend; flagstart += 7; flagend = strchr(flagstart, ']'); if (flagend) { *flagend = '\0'; result = strdup(flagstart); *flagend = ']'; } } return result; } int testflag_set(entry_t *e, char flag) { if (e->testflags) return (strchr(e->testflags, flag) != NULL); else return 0; } int unwantedcolumn(char *hostname, char *testname) { void *hinfo; char *nc, *tok; int result = 0; hinfo = hostinfo(hostname); if (!hinfo) return 1; nc = xmh_item(hinfo, XMH_NOCOLUMNS); if (!nc) return 0; nc = strdup(nc); tok = strtok(nc, ","); while (tok && (result == 0)) { if (strcmp(tok, testname) == 0) result = 1; tok = strtok(NULL, ","); } return result; } state_t *init_state(char *filename, logdata_t *log) { FILE *fd = NULL; char *p; char *hostname = NULL; char *testname = NULL; char *testnameidx; state_t *newstate; char fullfn[PATH_MAX]; host_t *host; struct stat log_st; time_t now = getcurrenttime(NULL); time_t histentry_start; int propagating, isacked; dbgprintf("init_state(%s, %d, ...)\n", textornull(filename)); /* Ignore summary files and dot-files (this catches "." and ".." also) */ if ( (strncmp(filename, "summary.", 8) == 0) || (filename[0] == '.')) { return NULL; } if (reportstart || snapshot) { /* Don't do reports for info- and trends-columns */ p = strrchr(filename, '.'); if (p == NULL) return NULL; p++; if (strcmp(p, xgetenv("INFOCOLUMN")) == 0) return NULL; if (strcmp(p, xgetenv("TRENDSCOLUMN")) == 0) return NULL; if (strcmp(p, xgetenv("CLIENTCOLUMN")) == 0) return NULL; /* * When doing reports, we are scanning the XYMONHISTDIR directory. It may * contain files that are named as a host only (no test-name). * Skip those. */ if (find_host(filename)) return NULL; } if (!reportstart && !snapshot) { if (log->hostname) hostname = strdup(log->hostname); if (log->testname) testname = strdup(log->testname); } else { sprintf(fullfn, "%s/%s", xgetenv("XYMONHISTDIR"), filename); /* Check that we can access this file */ if (stat(fullfn, &log_st) == -1) { errprintf("Error searching for '%s' history file: %s\n", filename, strerror(errno)); return NULL; } if (!S_ISREG(log_st.st_mode)) { errprintf("Weird file '%s' skipped\n", fullfn); return NULL; } if ((fd = fopen(fullfn, "r")) == NULL) { errprintf("Unable to read file '%s', skipped: %s\n", fullfn, strerror(errno)); return NULL; } /* Pick out host- and test-name */ hostname = strdup(filename); p = strrchr(hostname, '.'); /* Skip files that have no '.' in filename */ if (p) { /* Pick out the testname ... */ *p = '\0'; p++; testname = strdup(p); /* ... and change hostname back into normal form */ for (p=hostname; (*p); p++) { if (*p == ',') *p='.'; } } else { xfree(hostname); fclose(fd); return NULL; } } /* Must do these first to get the propagation value for the statistics */ host = find_host(hostname); isacked = (log->acktime > now); propagating = checkpropagation(host, testname, log->color, isacked); /* Count all of the real columns */ if ( (strcmp(testname, xgetenv("INFOCOLUMN")) != 0) && (strcmp(testname, xgetenv("TRENDSCOLUMN")) != 0) ) { statuscount++; switch (log->color) { case COL_RED: case COL_YELLOW: if (propagating) colorcount[log->color] += 1; else colorcount_noprop[log->color] += 1; break; default: colorcount[log->color] += 1; break; } } testnameidx = (char *)malloc(strlen(testname) + 3); sprintf(testnameidx, ",%s,", testname); if (unwantedcolumn(hostname, testname) || (ignorecolumns && strstr(ignorecolumns, testnameidx))) { xfree(hostname); xfree(testname); xfree(testnameidx); if (fd) fclose(fd); return NULL; /* Ignore this type of test */ } xfree(testnameidx); newstate = (state_t *) calloc(1, sizeof(state_t)); newstate->entry = (entry_t *) calloc(1, sizeof(entry_t)); newstate->next = NULL; newstate->entry->column = find_or_create_column(testname, 1); newstate->entry->color = -1; strcpy(newstate->entry->age, ""); newstate->entry->oldage = 0; newstate->entry->propagate = 1; newstate->entry->testflags = NULL; newstate->entry->skin = NULL; newstate->entry->repinfo = NULL; newstate->entry->causes = NULL; newstate->entry->histlogname = NULL; newstate->entry->shorttext = NULL; if (host) { newstate->entry->alert = checkalert(host->alerts, testname); /* If no WAP's specified, default all tests to be on WAP page */ newstate->entry->onwap = (host->waps ? checkalert(host->waps, testname) : 1); } else { dbgprintf(" hostname %s not found\n", hostname); newstate->entry->alert = newstate->entry->onwap = 0; } newstate->entry->sumurl = NULL; if (reportstart) { /* Determine "color" for this test from the historical data */ newstate->entry->repinfo = (reportinfo_t *) calloc(1, sizeof(reportinfo_t)); newstate->entry->color = parse_historyfile(fd, newstate->entry->repinfo, (dynamicreport ? NULL: hostname), (dynamicreport ? NULL : testname), reportstart, reportend, 0, (host ? host->reportwarnlevel : reportwarnlevel), reportgreenlevel, (host ? host->reportwarnstops : reportwarnstops), (host ? host->reporttime : NULL)); newstate->entry->causes = (dynamicreport ? NULL : save_replogs()); } else if (snapshot) { time_t fileage; newstate->entry->color = history_color(fd, snapshot, &histentry_start, &newstate->entry->histlogname); fileage = snapshot - histentry_start; newstate->entry->oldage = (fileage >= recentgif_limit); newstate->entry->fileage = fileage; strcpy(newstate->entry->age, agestring(fileage)); } else { time_t fileage = (now - log->lastchange); newstate->entry->color = log->color; newstate->entry->testflags = strdup(log->testflags ? log->testflags : ""); if (testflag_set(newstate->entry, 'D')) newstate->entry->skin = dialupskin; if (testflag_set(newstate->entry, 'R')) newstate->entry->skin = reverseskin; newstate->entry->shorttext = strdup(log->msg); newstate->entry->acked = isacked; newstate->entry->oldage = (fileage >= recentgif_limit); newstate->entry->fileage = (log->lastchange ? fileage : -1); if (log->lastchange == 0) strcpy(newstate->entry->age, ""); else strcpy(newstate->entry->age, agestring(fileage)); } if (purplelog && (newstate->entry->color == COL_PURPLE)) { fprintf(purplelog, "%s %s%s\n", hostname, testname, (host ? " (expired)" : " (unknown host)")); } newstate->entry->propagate = propagating; dbgprintf("init_state: hostname=%s, testname=%s, color=%d, acked=%d, age=%s, oldage=%d, propagate=%d, alert=%d\n", textornull(hostname), textornull(testname), newstate->entry->color, newstate->entry->acked, textornull(newstate->entry->age), newstate->entry->oldage, newstate->entry->propagate, newstate->entry->alert); if (host) { hostlist_t *l; /* Add this state entry to the host's list of state entries. */ newstate->entry->next = host->entries; host->entries = newstate->entry; /* There may be multiple host entries, if a host is * listed in several locations in hosts.cfg (for display purposes). * This is handled by updating ALL of the cloned host records. * Bug reported by Bluejay Adametz of Fuji. */ /* Cannot use "find_host()" here, as we need the hostlink record, not the host record */ l = find_hostlist(hostname); /* Walk through the clone-list and set the "entries" for all hosts */ for (l=l->clones; (l); l = l->clones) l->hostentry->entries = host->entries; } else { /* No host for this test - must be missing from hosts.cfg */ newstate->entry->next = NULL; } xfree(hostname); xfree(testname); if (fd) fclose(fd); return newstate; } dispsummary_t *init_displaysummary(char *fn, logdata_t *log) { char l[MAX_LINE_LEN]; dispsummary_t *newsum = NULL; time_t now = getcurrenttime(NULL); dbgprintf("init_displaysummary(%s)\n", textornull(fn)); if (log->validtime < now) return NULL; strcpy(l, log->msg); if (strlen(l)) { char *p; char *color = (char *) malloc(strlen(l)); newsum = (dispsummary_t *) calloc(1, sizeof(dispsummary_t)); newsum->url = (char *) malloc(strlen(l)); if (sscanf(l, "%s %s", color, newsum->url) == 2) { char *rowcol; newsum->color = parse_color(color); rowcol = (char *) malloc(strlen(fn) + 1); strcpy(rowcol, fn+8); p = strrchr(rowcol, '.'); if (p) *p = ' '; newsum->column = (char *) malloc(strlen(rowcol)+1); newsum->row = (char *) malloc(strlen(rowcol)+1); sscanf(rowcol, "%s %s", newsum->row, newsum->column); newsum->next = NULL; xfree(rowcol); } else { xfree(newsum->url); xfree(newsum); newsum = NULL; } xfree(color); } return newsum; } void generate_compactitems(state_t **topstate) { void *xmh; compact_t **complist = NULL; int complistsz = 0; hostlist_t *h; entry_t *e; char *compacted; char *tok1, *savep1, *savep2; compact_t *itm; int i; state_t *newstate; time_t now = getcurrenttime(NULL); for (h = hostlistBegin(); (h); h = hostlistNext()) { xmh = hostinfo(h->hostentry->hostname); compacted = xmh_item(xmh, XMH_COMPACT); if (!compacted) continue; tok1 = strtok_r(compacted, ",", &savep1); while (tok1) { char *members; itm = (compact_t *)calloc(1, sizeof(compact_t)); itm->compactname = strdup(strtok_r(tok1, "=", &savep2)); members = strtok_r(NULL, "\n", &savep2); itm->members = (char *)malloc(3 + (members ? strlen(members) : 0) ); sprintf(itm->members, "|%s|", (members ? members : "") ); if (complistsz == 0) { complist = (compact_t **)calloc(2, sizeof(compact_t *)); } else { complist = (compact_t **)realloc(complist, (complistsz+2)*sizeof(compact_t *)); } complist[complistsz++] = itm; complist[complistsz] = NULL; tok1 = strtok_r(NULL, ",", &savep1); } for (e = h->hostentry->entries; (e); e = e->next) { for (i = 0; (i < complistsz); i++) { if (wantedcolumn(e->column->name, complist[i]->members)) { e->compacted = 1; if (e->color > complist[i]->color) complist[i]->color = e->color; if (e->fileage > complist[i]->fileage) complist[i]->fileage = e->fileage; } } } for (i = 0; (i < complistsz); i++) { logdata_t log; char fn[PATH_MAX]; memset(&log, 0, sizeof(log)); sprintf(fn, "%s.%s", commafy(h->hostentry->hostname), complist[i]->compactname); log.hostname = h->hostentry->hostname; log.testname = complist[i]->compactname; log.color = complist[i]->color; log.testflags = ""; log.lastchange = now - complist[i]->fileage; log.logtime = getcurrenttime(NULL); log.validtime = log.logtime + 300; log.sender = ""; log.msg = ""; newstate = init_state(fn, &log); if (newstate) { newstate->next = *topstate; *topstate = newstate; } } } } state_t *load_state(dispsummary_t **sumhead) { int xymondresult; char fn[PATH_MAX]; state_t *newstate, *topstate; dispsummary_t *newsum, *topsum; char *board = NULL; char *nextline; int done; logdata_t log; sendreturn_t *sres; dbgprintf("load_state()\n"); sres = newsendreturnbuf(1, NULL); if (!reportstart && !snapshot) { char *dumpfn = getenv("BOARDDUMP"); char *filter = getenv("BOARDFILTER"); if (dumpfn) { /* Debugging - read data from a dump file */ struct stat st; FILE *fd; xymondresult = XYMONSEND_ETIMEOUT; if (stat(dumpfn, &st) == 0) { fd = fopen(dumpfn, "r"); if (fd) { board = (char *)malloc(st.st_size + 1); *board = '\0'; if (fread(board, 1, st.st_size, fd)) { fclose(fd); xymondresult = XYMONSEND_OK; } } } } else { char *bcmd; bcmd = (char *)malloc(1024 + (filter ? strlen(filter) : 0)); sprintf(bcmd, "xymondboard fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,line1,acklist %s", (filter ? filter: "")); xymondresult = sendmessage(bcmd, NULL, XYMON_TIMEOUT, sres); board = getsendreturnstr(sres, 1); xfree(bcmd); } } else { xymondresult = sendmessage("xymondboard fields=hostname,testname", NULL, XYMON_TIMEOUT, sres); board = getsendreturnstr(sres, 1); } freesendreturnbuf(sres); if ((xymondresult != XYMONSEND_OK) || (board == NULL) || (*board == '\0')) { errprintf("xymond status-board not available, code %d\n", xymondresult); return NULL; } if (reportstart || snapshot) { oldestentry = getcurrenttime(NULL); purplelog = NULL; purplelogfn = NULL; } else { if (purplelogfn) { purplelog = fopen(purplelogfn, "w"); if (purplelog == NULL) errprintf("Cannot open purplelog file %s\n", purplelogfn); else fprintf(purplelog, "Stale (purple) logfiles as of %s\n\n", timestamp); } } topstate = NULL; topsum = NULL; done = 0; nextline = board; while (!done) { char *bol = nextline; char *onelog, *acklist; char *p; int i; nextline = strchr(nextline, '\n'); if (nextline) { *nextline = '\0'; nextline++; } else done = 1; if (strlen(bol) == 0) { done = 1; continue; } memset(&log, 0, sizeof(log)); onelog = strdup(bol); acklist = NULL; p = gettok(onelog, "|"); i = 0; while (p) { switch (i) { /* hostname|testname|color|testflags|lastchange|logtime|validtime|acktime|disabletime|sender|cookie|1st line of message|acklist */ case 0: log.hostname = p; break; case 1: log.testname = p; break; case 2: log.color = parse_color(p); break; case 3: log.testflags = p; break; case 4: log.lastchange = atoi(p); break; case 5: log.logtime = atoi(p); break; case 6: log.validtime = atoi(p); break; case 7: log.acktime = atoi(p); break; case 8: log.disabletime = atoi(p); break; case 9: log.sender = p; break; case 10: log.cookie = atoi(p); break; case 11: log.msg = p; break; case 12: acklist = p; break; } p = gettok(NULL, "|"); i++; } if (!log.hostname || !log.testname) { errprintf("Found incomplete or corrupt log line (%s|%s); skipping\n", textornull(log.hostname), textornull(log.testname) ); xfree(onelog); continue; } if (!log.msg) log.msg = ""; sprintf(fn, "%s.%s", commafy(log.hostname), log.testname); /* Get the data */ if (strncmp(fn, "summary.", 8) == 0) { if (!reportstart && !snapshot) { newsum = init_displaysummary(fn, &log); if (newsum) { newsum->next = topsum; topsum = newsum; } } } else { if (acklist && *acklist) { /* * It's been acked. acklist looks like * 1149489234:1149510834:1:henrik:Joe promised to take care of this right after lunch\n * The "\n" is the delimiter between multiple acks. */ char *tok; tok = strtok(acklist, ":"); if (tok) tok = strtok(NULL, ":"); if (tok) log.acktime = atol(tok); } newstate = init_state(fn, &log); if (newstate) { newstate->next = topstate; topstate = newstate; if (reportstart && (newstate->entry->repinfo->reportstart < oldestentry)) { oldestentry = newstate->entry->repinfo->reportstart; } } } xfree(onelog); } generate_compactitems(&topstate); if (reportstart) sethostenv_report(oldestentry, reportend, reportwarnlevel, reportgreenlevel); if (purplelog) fclose(purplelog); *sumhead = topsum; return topstate; } xymon-4.3.30/xymongen/xymongen.10000664000076400007640000006672213534041732017014 0ustar rpmbuildrpmbuild.TH XYMONGEN 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymongen \- Xymon webpage generator .SH SYNOPSIS .B "xymongen \-?" .br .B "xymongen \-\-help" .br .B "xymongen \-\-version" .br .B "xymongen [options] [output-directory]" .br (See the OPTIONS section for a description of the available command-line options). .SH DESCRIPTION \fBxymongen\fR generates the overview webpages for the Xymon monitor. These are the webpages that show the overall status of your hosts, not the detailed status pages for each test. Note: The data for the webpages is retrieved from the .I xymond(8) daemon, and xymongen uses the values of the XYMSRV / XYMSERVERS environment variables to determine the network address where xymond can be reached. If you have more than one server listed in XYMSERVERS, make sure the first one is the local Xymon server - this is the one that xymongen will query for data. .SH OPTIONS xymongen has a large number of command-line options. The options can be used to change the behaviour of xymongen and affect the web pages generated by it. .SH GENERAL OPTIONS .sp .IP "\-\-help or \-?" Provide a summary of available command-line options. .sp .IP "\-\-version" Prints the version number of xymongen .sp .IP "\-\-docurl=URL" This option is deprecated, use the HOSTDOCURL setting in .I xymonserver.cfg(5) instead. .sp .IP "\-\-doccgi=URL" This option is deprecated, use the HOSTDOCURL setting in .I xymonserver.cfg(5) instead. .sp .IP "\-\-doc\-window" Causes links to documentation for hosts and services to open in a new window. The default is to show documentation in the same browser window as the Xymon status. .sp .IP "\-\-htmlextension=.EXTENSION" Sets the filename extension used for the webpages generated by xymongen. By default, an extension of ".html" is used. Note that you need to specify the "dot". .sp .IP "\-\-report[=COLUMNNAME]" With this option, xymongen will send a status message with details of how many hosts were processed, how many pages were generated, any errors that occurred during the run, and some timing statistics. The default columnname is "xymongen". .sp .IP "\-\-htaccess[=htaccess-filename]" Create .htaccess files when new web page directories are created. The content of the .htaccess files are determined by the XYMONHTACCESS environment variable (for the top-level directory with xymon.html and nongreen.html); by the XYMONPAGEHTACCESS variable (for the page-level directories); and by the XYMONSUBPAGEHTACCESS variable for subpage- and subparent-level directories. The filename of the .htaccess files default to ".htaccess" if no filename is given with this option. The XYMONHTACCESS variable is copied verbatim into the top-level .htaccess file. The XYMONPAGEHTACCESS variable may contain a "%s" where the name of the page is inserted. The XYMONSUBPAGEHTACCESS variable may contain two "%s" instances: The first is replaced with the pagename, the second with the subpagename. .sp .IP "\-\-max\-eventcount=N" Limit the eventlog on the "All non-green" page to only N events. Default: 100. .sp .IP "\-\-max\-eventtime=N" Limit the eventlog on the "All non-green" page to events that happened within the past N minutes. Default: 240. .sp .IP "\-\-no\-eventlog" Disable the eventlog normally displayed on the "All non-green" page .sp .IP "\-\-max\-ackcount=N" Limit the acknowledgment log on the "All non-green" page to only N events. Default: 25. .sp .IP "\-\-max\-acktime=N" Limit the acknowledgment log on the "All non-green" page to acks that happened within the past N minutes. Default: 240. .sp .IP "\-\-no\-acklog" Disable the acknowledgement log normally displayed on the "All non-green" page. .sp .IP "\-\-cricitcallog[=Critical log column]" This generates a text-based log of what is shown on the critical.html status page, and sends a status message for the Xymon server itself reflecting the color of the Critical status page. This allows you to track when problems have appeared on the critical status page. The logfile is stored in $XYMONSERVERLOGS/criticalstatus.log .sp .IP \-\-loadhostsfromxymond Instead of reading the hosts.cfg file, xymongen will load the hosts.cfg configuration from the xymond daemon. This eliminates the need for reading the hosts.cfg, and if you have xymond and xymongen running on different hosts, it also eliminates the need for copying the hosts.cfg file between systems. Note that the "dispinclude" option in hosts.cfg is ignored when this option is enabled. .SH PAGE LAYOUT OPTIONS These options affect how the webpages generated by xymongen appear in the browser. .sp .IP "\-\-pages\-last" Put page- and subpage-links after hosts. .IP "\-\-pages\-first" Put page- and subpage-links before hosts (default). .sp These two options decide whether a page with links to subpages and hosts have the hosts or the subpages first. .sp .IP "\-\-subpagecolumns=N" Determines the number of columns used for links to pages and subpages. The default is N=1. .sp .IP "\-\-maxrows=N" Column headings on a page are by default only shown at the beginning of a page, subpage or group of hosts. This options causes the column headings to repeat for every N hosts shown. .sp .IP "\-\-showemptygroups" .IP "\-\-no\-showemptygroups" When groups are hosts are made, display the table and host names even if there are no tests present for any of the hosts in question. Use \-\-no\-showemptygroups to hide. (Default: yes) .sp .IP "\-\-pagetitle\-links" Normally, only the colored "dots" next to a page or subpage act as links to the page itself. With this option, the page title will link to the page also. .sp .IP "\-\-pagetext\-headings" Use the description text from the "page" or "subpage" tags as a heading for the page, instead of the "Pages hosted locally" or other standard heading. .sp .IP "\-\-no\-underline\-headings" Normally, page headings are underlined using an HTML "horizontal ruler" tag. This option disables the underlining of headings. .sp .IP "\-\-recentgifs[=MINUTES]" Use images named COLOR\-recent.gif for tests, where the test status has changed within the past 24 hours. These GIF files need to be installed in the $XYMONHOME/www/gifs/ directory. By default, the threshold is set to 24 hours - if you want it differently, you can specify the time limit also. E.g. "\-\-recentgifs=3h" will show the recent GIFs for only 3 hours after a status change. .sp .IP "\-\-sort\-group\-only\-items" In a normal "group-only" directive, you can specify the order in which the tests are displayed, from left to right. If you prefer to have the tests listed in alphabetical order, use this option - the page will then generate "group-only" groups like it generates normal groups, and sort the tests alphabetically. .sp .IP "\-\-dialupskin=URL" If you want to visually show that a test is a dialup-test, you can use an alternate set of icons for the green/red/yellow>/etc. images by specifying this option. The URL parameter specified here overrides the normal setting from the XYMONSKIN environment variable, but only for dialup tests. .sp .IP "\-\-reverseskin=URL" Same as "\-\-dialupskin", but for reverse tests (tests with '!' in front). .sp .IP "\-\-tooltips=[always,never,main]" Determines which pages use tooltips to show the description of the host (from the COMMENT entry in the .I hosts.cfg(5) file). If set to \fBalways\fR, tooltips are used on all pages. If set to \fBnever\fR, tooltips are never used. If set to \fBmain\fR, tooltips are used on the main pages, but not on the "All non-green" or "Critical systems" pages. .SH COLUMN SELECTION OPTIONS These options affect which columns (tests) are included in the webpages generated by xymongen. .sp .IP "\-\-ignorecolumns=test[,test]" The given columns will be completely ignored by xymongen when generating webpages. Can be used to generate reports where you eliminate some of the more noisy tests, like "msgs". .sp .IP "\-\-critical\-reds\-only" Only red status columns will be included on the Critical page. By default, the Critical page will contain hosts with red, yellow and clear status. .sp .IP "\-\-nongreen\-colors=COLOR[,COLOR]" Defines which colors cause a test to appear on the "All non-green" status page. COLOR is red, yellow or purple. The default is to include all three. .sp .IP "\-\-nongreen\-ignorecolumns=test[,test]" Same as the \-\-ignorecolumns, but applies to hosts on the "All non-green" page only. .sp .IP "\-\-nongreen\-ignorepurples" Deprecated, use "\-\-nongreen\-colors" instead. .sp .IP "\-\-nongreen\-ignoredialups" Ignore all dialup hosts on the "All non-green" page, including the eventlog. .sp .IP "\-\-no\-pages" Do not generate the normal pages (normally used to generate only the non-green page). .sp .IP "\-\-no\-nongreen" Do not generate the "All non-green" page. .sp .IP "\-\-includecolumns=test[,test]" Always include these columns on "All non-green" page Will include certain columns on the nongreen.html page, regardless of its color. Normally, nongreen.html drops a test-column, if all tests are green. This can be used e.g. to always have a link to the trends column (with the RRD graphs) from your nongreen.html page. .sp .IP "\-\-eventignore=test[,test]" Ignore these tests in the "All non-green" event log display. .SH STATUS PROPAGATION OPTIONS These options suppress the normal propagation of a status upwards in the page hierarchy. Thus, you can have a test with status yellow or red, but still have the entire page green. It is useful for tests that need not cause an alarm, but where you still want to know the actual status. These options set global defaults for all hosts; you can use the NOPROPRED and NOPROPYELLOW tags in the .I hosts.cfg(5) file to apply similar limits on a per-host basis. .sp .IP "\-\-nopropyellow=test[,test] or \-\-noprop=test[,test] Disable upwards status propagation when YELLOW. The "\-\-noprop" option is deprecated and should not be used. .sp .IP "\-\-noproppurple=test[,test]" Disable upwards status propagation when PURPLE. .sp .IP "\-\-nopropred=test[,test]" Disable upwards status propagation when RED or YELLOW. .sp .IP "\-\-nopropack=test[,test]" Disable upwards status propagation when status has been acknowledged. If you want to disable all acked tests from being propageted, use "\-\-nopropack=*". .SH PURPLE STATUS OPTIONS Purple statuses occur when reporting of a test status stops. A test status is valid for a limited amount of time - normally 30 minutes - and after this time, the test becomes purple. .sp .IP "\-\-purplelog=FILENAME" Generate a logfile of all purple status messages. .SH ALTERNATE PAGESET OPTIONS .sp .IP "\-\-pageset=PAGESETNAME" Build webpages for an alternate pageset than the default. See the PAGESETS section below. .sp .IP "\-\-template=TEMPLATE" Use an alternate template for header and footer files. Typically used together the the "\-\-pageset" option; see the PAGESETS section below. .SH ALTERNATE OUTPUT FORMATS .sp .IP "\-\-wml[=test1,test2,...]" This option causes xymongen to generate a set of WML "card" files that can be accessed by a WAP device (cell phone, PDA etc.) The generated files contain the hosts that have a RED or YELLOW status on tests specified. This option can define the default tests to include - the defaults can be overridden or amended using the "WML:" or "NK:" tags in the .I hosts.cfg(5) file. If no tests are specified, all tests will be included. .sp .IP "\-\-nstab=FILENAME" Generate an HTML file suitable for a Netscape 6/Mozilla sidebar entry. To actually enable your users to obtain such a sidebar entry, you need this Javascript code in a webpage (e.g. you can include it in the $XYMONHOME/web/stdnormal_header file): .sp .sp and then you can include a "Add this to sidebar" link using this as a template: .sp Add to Sidebar .sp or if you prefer to have the standard Netscape "Add tab" button, you would do it with .sp .br [Add Sidebar] .br .sp The "add\-button.gif" is available from Netscape at http://developer.netscape.com/docs/manuals/browser/sidebar/add\-button.gif. If FILENAME does not begin with a slash, the Netscape sidebar file is placed in the $XYMONHOME/www/ directory. .IP "\-\-nslimit=COLOR" The minimum color to include in the Netscape Sidebar - default is "red", meaning only critical alerts are included. If you want to include warnings also, use "\-\-nslimit=yellow". .IP "\-\-rss" Generate RSS/RDF content delivery stream of your Xymon alerts. This output format can be dynamically embedded in other web pages, much like the live newsfeeds often seen on web sites. Two RSS files will be generated, one reflects the "All non-green" page, the other reflects the "Critical" page. They will be in the "nongreen.rss" and "critical.rss" files, respectively. In addition, an RSS file will be generated for each page and/or subpage listing the hosts present on that page or subpage. .br The FILENAME parameter previously allowed on the \-\-rss option is now obsolete. .br For more information about RSS/RDF content feeds, please see http://www.syndic8.com/. .sp .IP "\-\-rssextension=.EXTENSION" Sets the filename extension used for the RSS files generated by xymongen. By default, an extension of ".rss" is used. Note that you need to specify the "dot". .sp .IP "\-\-rssversion={0.91|0.92|1.0|2.0}" The desired output format of the RSS/RDF feed. Version 0.91 appears to be the most commonly used format, and is the default if this option is omitted. .sp .IP "\-\-rsslimit=COLOR" The minimum color to include in the RSS feed - default is "red", meaning only critical alerts are included. If you want to include warnings also, use "\-\-rsslimit=yellow". .SH OPTIONS USED BY CGI FRONT-ENDS .IP "\-\-reportopts=START:END:DYNAMIC:STYLE" Invoke xymongen in report-generation mode. This is normally used by the .I report.cgi(1) CGI script, but may also be used directly when pre-generating reports. The START parameter is the start-time for the report in Unix time_t format (seconds since Jan 1st 1970 00:00 UTC); END is the end-time for the report; DYNAMIC is 0 for a pre-built report and 1 for a dynamic (on-line) report; STYLE is "crit" to include only critical (red) events, "nongr" to include all non-green events, and "all" to include all events. .sp .IP "\-\-csv=FILENAME" Used together with \-\-reportopts, this causes xymongen to generate an availability report in the form of a comma-separated values (CSV) file. This format is commonly used for importing into spreadsheets for further processing. .br The CSV file includes Unix timestamps. To display these as human readable times in Excel, the formula \fB=C2/86400+DATEVALUE(1\-jan\-1970)\fR (if you have the Unix timestamp in the cell C2) can be used. The result cell should be formatted as a date/time field. Note that the timestamps are in UTC, so you may also need to handle local timezone and DST issues yourself. .sp .IP "\-\-csvdelim=DELIMITER" By default, a comma is used to delimit fields in the CSV output. Some non-english spreadsheets use a different delimiter, typically semi-colon. To generate a CSV file with the proper delimiter, you can use this option to set the character used as delimiter. E.g. "\-\-csvdelim=;" - note that this normally should be in double quotes, to prevent the Unix shell from interpreting the delimiter character as a command-line delimiter. .sp .IP "\-\-snapshot=TIME" Generate a snapshot of the Xymon pages, as they appeared at TIME. TIME is given as seconds since Jan 1st 1970 00:00 UTC. Normally used via the .I snapshot.cgi(1) CGI script. .SH DEBUGGING OPTIONS .sp .IP "\-\-debug" Causes xymongen to dump large amounts of debugging output to stdout, if it was compiled with the \-DDEBUG enabled. When reporting a problem with xymongen, please try to reproduce the problem and provide the output from running xymongen with this option. .sp .IP "\-\-timing" Dump information about the time spent by various parts of xymongen to stdout. This is useful to see what part of the processing is responsible for the run-time of xymongen. .br Note: This information is also provided in the output sent to the Xymon display when using the "\-\-report" option. .SH BUILDING ALTERNATE PAGESETS With version 1.4 of xymongen comes the possibility to generate multiple sets of pages from the same data. .br Suppose you have two groups of people looking at the Xymon webpages. Group A wants to have the hosts grouped by the client, they belong to. This is how you have Xymon set up - the default pageset. Now group B wants to have the hosts grouped by operating system - let us call it the "os" set. Then you would add the page layout to hosts.cfg like this: .sp ospage win Microsoft Windows .br ossubpage win\-nt4 MS Windows NT 4 .br osgroup NT4 File servers .br osgroup NT4 Mail servers .br ossubpage win\-xp MS Windows XP .br ospage unix Unix .br ossubpage unix\-sun Solaris .br ossubpage unix\-linux Linux .sp This defines a set of pages with one top-level page (the xymon.html page), two pages linked from xymon.html (win.html and unix.html), and from e.g. the win.html page there are subpages win\-nt4.html and win\-xp.html .br The syntax is identical to the normal "page" and "subpage" directives in hosts.cfg, but the directive is prefixed with the pageset name. Don't put any hosts in-between the page and subpage directives - just add all the directives at the top of the hosts.cfg file. .br How do you add hosts to the pages, then ? Simple - just put a tag "OS:win\-xp" on the host definition line. The "OS" must be the same as prefix used for the pageset names, but in uppercase. The "win\-xp" must match one of the pages or subpages defined within this pageset. E.g. .sp 207.46.249.190 www.microsoft.com # OS:win\-xp http://www.microsoft.com/ .br 64.124.140.181 www.sun.com # OS:unix\-sun http://www.sun.com/ .sp If you want the host to appear inside a group defined on that page, you must identify the group by number, starting at 1. E.g. to put a host inside the "NT4 Mail servers" group in the example above, use "OS:win\-nt4,2" (the second group on the "win\-nt4" page). .br If you want the host to show up on the frontpage instead of a subpage, use "OS:*" . .sp All of this just defines the layout of the new pageset. To generate it, you must run xymongen once for each pageset you define - i.e. create an extension script like this: .IP .nf #!/bin/sh XYMONWEB="/xymon/os" $XYMONHOME/bin/xymongen \\ \-\-pageset=os \-\-template=os \\ $XYMONHOME/www/os/ .fi .LP Save this to $XYMONHOME/ext/os\-display.sh, and set this up to run as a Xymon extension; this means addng an extra section to tasks.cfg to run it. This generates the pages. There are some important options used here: .br * XYMONWEB="/xymon/os" environment variable, and the "$XYMONHOME/www/os/" option work together, and places the new pageset HTML files in a subdirectory off the normal Xymon webroot. If you normally access the Xymon pages as "http://xymon.acme.com/xymon/", you will then access the new pageset as "http://xymon.acme.com/xymon/os/" NB: The directory given as XYMONWEB must contain a symbolic link to the $XYMONHOME/www/html/ directory, or links to individual status messages will not work. Similar links should be made for the gifs/, help/ and notes/ directories. .br * "\-\-pageset=os" tells xymongen to structure the webpages using the "os" layout, instead of the default layout. .br * "\-\-template=os" tells xymongen to use a different set of header- and footer-templates. Normally xymongen uses the standard template in $XYMONHOME/web/stdnormal_header and .../stdnormal_footer - with this option, it will instead use the files "os_header" and "os_footer" from the $XYMONHOME/web/ directory. This allows you to customize headers and footers for each pageset. If you just want to use the normal template, you can omit this option. .SH USING XYMONGEN FOR REPORTS xymongen reporting is implemented via drop-in replacements for the standard Xymon reporting scripts (report.sh and reportlog.sh) installed in your webservers cgi\-bin directory. These two shell script have been replaced with two very small shell-scripts, that merely setup the Xymon environment variables, and invoke the .I report.cgi(1) or .I reportlog.cgi(1) scripts in $XYMONHOME/bin/ You can use xymongen command-line options when generating reports, e.g. to exclude certain types of tests (e.g. "\-\-ignorecolumns=msgs") from the reports, to specify the name of the trends- and info- columns that should not be in the report, or to format the report differently (e.g. "\-\-subpagecolumns=2"). If you want certain options to be used when a report is generated from the web interface, put these options into your $XYMONHOME/etc/xymonserver.cfg file in the XYMONGENREPOPTS environment variable. The report files generated by xymongen are stored in individual directories (one per report) below the $XYMONHOME/www/rep/ directory. These should be automatically cleaned up - as new reports are generated, the old ones get removed. After installing, try generating a report. You will probably see that the links in the upper left corner (to ack.html, nongreen.html etc.) no longer works. To fix these, change your $XYMONHOME/web/repnormal_header file so these links do not refer to "&XYMONWEB" but to the normal URL prefix for your Xymon pages. .SH SLA REPORTING xymongen reporting allows for the generation of true SLA (Service Level Agreement) reports, also for service periods that are not 24x7. This is enabled by defining a "REPORTTIME:timespec" tag for the hosts to define the service period, and optionally a "WARNPCT:level" tag to define the agreed availability. Note: See .I hosts.cfg(5) for the exact syntax of these options. "REPORTTIME:timespec" specifies the time of day when the service is expected to be up and running. By default this is 24 hours a day, all days of the week. If your SLA only covers Mon-Fri 7am - 8pm, you define this as "REPORTTIME=W:0700:2000", and the report generator will then compute both the normal 24x7 availability but also a "SLA availability" which only takes the status of the host during the SLA period into account. The DOWNTIME:timespec parameter affects the SLA availability calculation. If an outage occurs during the time defined as possible "DOWNTIME", then the failure is reported with a status of "blue". (The same color is used if you "disable" then host using the Xymon "disable" function). The time when the test status is "blue" is not included in the SLA calculation, neither in the amount of time where the host is considered down, nor in the total amount of time that the report covers. So "blue" time is effectively ignored by the SLA availability calculation, allowing you to have planned downtime without affecting the reported SLA availability. Example: A host has "DOWNTIME:*:0700:0730 REPORTTIME=W:0600:2200" because it is rebooted every day between 7am and 7.30am, but the service must be available from 6am to 10pm. For the day of the report, it was down from 7:10am to 7:15am (the planned reboot), but also from 9:53pm to 10:15pm. So the events for the day are: 0700 : green for 10 minutes (600 seconds) 0710 : blue for 5 minutes (300 seconds) 0715 : green for 14 hours 38 minutes (52680 seconds) 2153 : red for 22 minutes (1320 seconds) 2215 : green The service is available for 600+52680 = 53280 seconds. It is down (red) for 420 seconds (the time from 21:53 until 22:00 when the SLA period ends). The total time included in the report is 15 hours (7am - 10pm) except the 5 minutes blue = 53700 seconds. So the SLA availability is 53280/53700 = 99,22% The "WARNPCT:level" tag is supported in the hosts.cfg file, to set the availability threshold on a host-by-host basis. This threshold determines whether a test is reported as green, yellow or red in the reports. A default value can be set for all hosts with the via the XYMONREPWARN environment variable, but overridden by this tag. The level is given as a percentage, e.g. "WARNPCT:98.5" .SH PRE-GENERATED REPORTS Normally, xymongen produce reports that link to dynamically generated webpages with the detailed status of a test (via the reportlog.sh CGI script). It is possible to have xymongen produce a report without these dynamic links, so the report can be exported to another server. It may also be useful to pre-generate the reports, to lower the load by having multiple users generate the same reports. To do this, you must run xymongen with the "\-\-reportopts" option to select the time interval that the report covers, the reporting style (critical, non-green, or all events), and to request that no dynamic pages are to be generated. The syntax is: xymongen \-\-reportopts=starttime:endtime:nodynamic:style "starttime" and "endtime" are specified as Unix time_t values, i.e. seconds since Jan 1st 1970 00:00 GMT. Fortunately, this can easily be computed with the GNU date utility if you use the "+%s" output option. If you don't have the GNU date utility, either pick that up from www.gnu.org; or you can use the "etime" utility for the same purpose, which is available from the archive at www.deadcat.net. "nodynamic" is either 0 (for dynamic pages, the default) or 1 (for no dynamic, i.e. pre-generated, pages). "style" is either "crit" (include critical i.e. red events only), "nongr" (include all non-green events), or "all" (include all events). Other xymongen options can be used, e.g. "\-\-ignorecolumns" if you want to exclude certain tests from the report. You will normally also need to specify the XYMONWEB environment variable (it must match the base URL for where the report will be made accessible from), and an output directory where the report files are saved. If you specify XYMONWEB, you should probably also define the XYMONHELPSKIN and XYMONNOTESSKIN environment variables. These should point to the URL where your Xymon help- and notes-files are located; if they are not defined, the links to help- and notes-files will point inside the report directory and will probably not work. So a typical invocation of xymongen for a static report would be: START=`date +%s \-\-date="22 Jun 2003 00:00:00"` END=`date +%s \-\-date="22 Jun 2003 23:59:59"` XYMONWEB=/reports/bigbrother/daily/2003/06/22 \\ XYMONHELPSKIN=/xymon/help \\ XYMONNOTESSKIN=/xymon/notes \\ xymongen \-\-reportopts=$START:$END:1:crit \\ \-\-subpagecolumns=2 \\ /var/www/docroot/reports/xymon/daily/2003/06/22 The "XYMONWEB" setting means that the report will be available with a URL of "http://www.server.com/reports/xymon/daily/2003/06/22". The report contains internal links that use this URL, so it cannot be easily moved to another location. The last parameter is the corresponding physical directory on your webserver matching the XYMONWEB URL. You can of course create the report files anywhere you like - perhaps on another machine - and then move them to the webserver later on. Note how the .I date(1) utility is used to calculate the start- and end-time parameters. .SH "ENVIRONMENT VARIABLES" .IP BOARDFILTER Filter used to select what hosts / tests are included in the webpages, by filtering the data retrieved from xymond vi the xymondboard command. See .I xymon(1) for details on the filter syntax. By default, no filtering is done. .SH "SEE ALSO" hosts.cfg(5), xymonserver.cfg(5), tasks.cfg(5), report.cgi(1), snapshot.cgi(1), xymon(7) xymon-4.3.30/xymongen/csvreport.c0000664000076400007640000000474511615341300017246 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #include #include #include #include "csvreport.h" #include "util.h" void csv_availability(char *fn, char csvdelim) { hostlist_t *hl; FILE *fd; char *header = "Hostname,Testname,Start,End,24x7 availability %,24x7 green %,24x7 green secs,24x7 clear %,24x7 clear secs,24x7 blue %,24x7 blue secs,24x7 purple %,24x7 purple secs,24x7 yellow %,24x7 yellow secs,24x7 red %,24x7 red secs,SLA availability %,SLA green %,SLA green secs,SLA clear %,SLA clear secs,SLA blue %,SLA blue secs,SLA purple %,SLA purple secs,SLA yellow %,SLA yellow secs,SLA red %,SLA red secs"; fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot open output file %s: %s\n", fn, strerror(errno)); return; } if (csvdelim != ',') { char *p, *newheader; newheader = strdup(header); p = newheader; while ((p = strchr(p, ',')) != NULL) *p = csvdelim; header = newheader; } fprintf(fd, "%s\n", header); for (hl = hostlistBegin(); (hl); hl = hostlistNext()) { host_t *hwalk = hl->hostentry; entry_t *ewalk; int i; for (ewalk = hwalk->entries; (ewalk); ewalk = ewalk->next) { fprintf(fd, "%s%c%s%c%ld%c%ld", hwalk->hostname, csvdelim, ewalk->column->name, csvdelim, ewalk->repinfo->reportstart, csvdelim, reportend); fprintf(fd, "%c%.2f", csvdelim, ewalk->repinfo->fullavailability); for (i=0; (irepinfo->fullpct[i], csvdelim, ewalk->repinfo->fullduration[i]); } fprintf(fd, "%c%.2f", csvdelim, ewalk->repinfo->reportavailability); for (i=0; (irepinfo->reportpct[i], csvdelim, ewalk->repinfo->reportduration[i]); } fprintf(fd, "\n"); } } fclose(fd); } xymon-4.3.30/xymongen/util.h0000664000076400007640000000250711615341300016173 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __UTIL_H_ #define __UTIL_H_ extern char *htmlextension; extern char *hostpage_link(host_t *host); extern char *hostpage_name(host_t *host); extern int checkpropagation(host_t *host, char *test, int color, int acked); extern host_t *find_host(char *hostname); extern int host_exists(char *hostname); extern hostlist_t *find_hostlist(char *hostname); extern hostlist_t *hostlistBegin(void); extern hostlist_t *hostlistNext(void); extern void add_to_hostlist(hostlist_t *rec); extern xymongen_col_t *find_or_create_column(char *testname, int create); extern int wantedcolumn(char *current, char *wanted); #endif xymon-4.3.30/xymongen/wmlgen.c0000664000076400007640000003070113442143206016504 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon WML generator. */ /* */ /* This file contains code to generate the WAP/WML documents showing the */ /* Xymon status. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: wmlgen.c 8031 2019-03-13 08:59:50Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "xymongen.h" #include "wmlgen.h" #include "util.h" int enable_wmlgen = 0; static char wmldir[PATH_MAX]; static void delete_old_cards(char *dirname) { DIR *xymoncards; struct dirent *d; struct stat st; time_t now = getcurrenttime(NULL); char fn[PATH_MAX]; xymoncards = opendir(dirname); if (!xymoncards) { errprintf("Cannot read directory %s\n", dirname); return; } if (chdir(dirname) == -1) { return; } while ((d = readdir(xymoncards))) { strcpy(fn, d->d_name); stat(fn, &st); if ((fn[0] != '.') && S_ISREG(st.st_mode) && (st.st_mtime < (now-3600))) { unlink(fn); } } closedir(xymoncards); } static char *wml_colorname(int color) { switch (color) { case COL_GREEN: return "GR"; break; case COL_RED: return "RE"; break; case COL_YELLOW: return "YE"; break; case COL_PURPLE: return "PU"; break; case COL_CLEAR: return "CL"; break; case COL_BLUE: return "BL"; break; } return ""; } static void wml_header(FILE *output, char *cardid, int idpart) { fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "\n", cardid, idpart); } static void generate_wml_statuscard(host_t *host, entry_t *entry) { char fn[PATH_MAX]; FILE *fd; char *msg = NULL, *logbuf = NULL; char l[MAX_LINE_LEN], lineout[MAX_LINE_LEN]; char *p, *outp, *nextline; char xymondreq[1024]; int xymondresult; sendreturn_t *sres; sres = newsendreturnbuf(1, NULL); sprintf(xymondreq, "xymondlog %s.%s", host->hostname, entry->column->name); xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres); logbuf = getsendreturnstr(sres, 1); freesendreturnbuf(sres); if ((xymondresult != XYMONSEND_OK) || (logbuf == NULL) || (strlen(logbuf) == 0)) { errprintf("WML: Status not available\n"); return; } msg = strchr(logbuf, '\n'); if (msg) { msg++; } else { errprintf("WML: Unable to parse log data\n"); xfree(logbuf); return; } nextline = msg; l[MAX_LINE_LEN - 1] = '\0'; sprintf(fn, "%s/%s.%s.wml", wmldir, host->hostname, entry->column->name); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot create file %s\n", fn); return; } wml_header(fd, "name", 1); fprintf(fd, "

\n"); fprintf(fd, "Host
\n", host->hostname); fprintf(fd, "%s

\n", timestamp); fprintf(fd, "

\n"); fprintf(fd, "%s.%s

\n", host->hostname, entry->column->name); /* * We need to parse the logfile a bit to get a decent WML * card that contains the logfile. bbd does this for * HTML, we need to do it ourselves for WML. * * Empty lines are removed. * DOCTYPE lines (if any) are removed. * "http://" is removed * "" tags are replaced with a newline. * All HTML tags are removed * "&COLOR" is replaced with the shortname color * "<", ">", "&", "\"" and "\'" are replaced with the coded name so they display correctly. */ while (nextline) { p = strchr(nextline, '\n'); if (p) *p = '\0'; strncpy(l, nextline, (MAX_LINE_LEN - 1)); if (p) nextline = p+1; else nextline = NULL; outp = lineout; for (p=l; (*p && isspace((int) *p)); p++) ; if (strlen(p) == 0) { /* Empty line - ignore */ } else if (strstr(l, "DOCTYPE")) { /* DOCTYPE - ignore */ } else { for (p=l; (*p); ) { if (strncmp(p, "http://", 7) == 0) { p += 7; } else if (strncasecmp(p, "", 4) == 0) { strcpy(outp, "
"); outp += 5; p += 4; } else if (*p == '<') { char *endtag, *newstarttag; /* * Possibilities: * - : Drop it * - < : Output the < equivalent * - <<< : Handle them one '<' at a time */ endtag = strchr(p+1, '>'); newstarttag = strchr(p+1, '<'); if ((endtag == NULL) || (newstarttag && (newstarttag < endtag))) { /* Single '<', or new starttag before the end */ strcpy(outp, "<"); outp += 4; p++; } else { /* Drop all html tags */ *outp = ' '; outp++; p = endtag+1; } } else if (*p == '>') { strcpy(outp, ">"); outp += 4; p++; } else if (strncmp(p, "&red", 4) == 0) { strcpy(outp, "red"); outp += 10; p += 4; } else if (strncmp(p, "&green", 6) == 0) { strcpy(outp, "green"); outp += 12; p += 6; } else if (strncmp(p, "&purple", 7) == 0) { strcpy(outp, "purple"); outp += 13; p += 7; } else if (strncmp(p, "&yellow", 7) == 0) { strcpy(outp, "yellow"); outp += 13; p += 7; } else if (strncmp(p, "&clear", 6) == 0) { strcpy(outp, "clear"); outp += 12; p += 6; } else if (strncmp(p, "&blue", 5) == 0) { strcpy(outp, "blue"); outp += 11; p += 5; } else if (*p == '&') { strcpy(outp, "&"); outp += 5; p++; } else if (*p == '\'') { strcpy(outp, "'"); outp += 6; p++; } else if (*p == '\"') { strcpy(outp, """); outp += 6; p++; } else { *outp = *p; outp++; p++; } } } *outp = '\0'; if (strlen(lineout)) fprintf(fd, "%s\n
\n", lineout); } fprintf(fd, "

\n"); fclose(fd); if (logbuf) xfree(logbuf); } void do_wml_cards(char *webdir) { FILE *nongreenfd, *hostfd; char nongreenfn[PATH_MAX], hostfn[PATH_MAX]; hostlist_t *h; entry_t *t; int nongreenwapcolor; long wmlmaxchars = 1500; int nongreenpart = 1; /* Determine where the WML files go */ sprintf(wmldir, "%s/wml", webdir); /* Make sure the WML directory exists */ if (chdir(wmldir) != 0) mkdir(wmldir, 0755); if (chdir(wmldir) != 0) { errprintf("Cannot access or create the WML output directory %s\n", wmldir); return; } /* Make sure this is set sensibly */ if (xgetenv("WMLMAXCHARS")) { wmlmaxchars = atol(xgetenv("WMLMAXCHARS")); } /* * Cleanup cards that are too old. */ delete_old_cards(wmldir); /* * Find all the test entries that belong on the WAP page, * and calculate the color for the nongreen wap page. * * We want only tests that have the "onwap" flag set, i.e. * tests given in the "WAP:test,..." for this host (of the * "NK:test,..." if no WAP list). * * At the same time, generate the WML card for the tests, * corresponding to the HTML file for the test logfile. */ nongreenwapcolor = COL_GREEN; for (h = hostlistBegin(); (h); h = hostlistNext()) { h->hostentry->wapcolor = COL_GREEN; for (t = h->hostentry->entries; (t); t = t->next) { if (t->onwap && ((t->color == COL_RED) || (t->color == COL_YELLOW))) { generate_wml_statuscard(h->hostentry, t); h->hostentry->anywaps = 1; } else { /* Clear the onwap flag - makes testing later a bit simpler */ t->onwap = 0; } if (t->onwap && (t->color > h->hostentry->wapcolor)) h->hostentry->wapcolor = t->color; } /* Update the nongreenwapcolor */ if ( (h->hostentry->wapcolor == COL_RED) || (h->hostentry->wapcolor == COL_YELLOW) ) { if (h->hostentry->wapcolor > nongreenwapcolor) nongreenwapcolor = h->hostentry->wapcolor; } } /* Start the non-green WML card */ sprintf(nongreenfn, "%s/nongreen.wml.tmp", wmldir); nongreenfd = fopen(nongreenfn, "w"); if (nongreenfd == NULL) { errprintf("Cannot open non-green WML file %s\n", nongreenfn); return; } /* Standard non-green wap header */ wml_header(nongreenfd, "card", nongreenpart); fprintf(nongreenfd, "

\n"); fprintf(nongreenfd, "%s

\n", timestamp); fprintf(nongreenfd, "

\n"); fprintf(nongreenfd, "Summary Status
%s

\n", colorname(nongreenwapcolor)); /* All green ? Just say so */ if (nongreenwapcolor == COL_GREEN) { fprintf(nongreenfd, "All is OK
\n"); } /* Now loop through the hostlist again, and generate the nongreen WAP links and host pages */ for (h = hostlistBegin(); (h); h = hostlistNext()) { if (h->hostentry->anywaps) { /* Create the host WAP card, with links to individual test results */ sprintf(hostfn, "%s/%s.wml", wmldir, h->hostentry->hostname); hostfd = fopen(hostfn, "w"); if (hostfd == NULL) { errprintf("Cannot create file %s\n", hostfn); return; } wml_header(hostfd, "name", 1); fprintf(hostfd, "

\n"); fprintf(hostfd, "Overall
\n"); fprintf(hostfd, "%s

\n", timestamp); fprintf(hostfd, "

\n"); fprintf(hostfd, "%s

\n", h->hostentry->hostname); for (t = h->hostentry->entries; (t); t = t->next) { if (t->onwap) { fprintf(hostfd, "%s%s %s
\n", t->column->name, wml_colorname(t->color), (t->acked ? "x" : ""), h->hostentry->hostname, t->column->name, t->column->name); } } fprintf(hostfd, "\n

\n"); fclose(hostfd); /* Create the link from the nongreen wap card to the host card */ fprintf(nongreenfd, "%s %s
\n", h->hostentry->hostname, wml_colorname(h->hostentry->wapcolor), h->hostentry->hostname, h->hostentry->hostname); /* * Gross hack. Some WAP phones cannot handle large cards. * So if the card grows larger than WMLMAXCHARS, split it into * multiple files and link from one file to the next. */ if (ftello(nongreenfd) >= wmlmaxchars) { char oldnongreenfn[PATH_MAX]; /* WML link is from the nongreenfd except leading wmldir+'/' */ strcpy(oldnongreenfn, nongreenfn+strlen(wmldir)+1); nongreenpart++; fprintf(nongreenfd, "
Next\n", nongreenpart); fprintf(nongreenfd, "

\n"); fclose(nongreenfd); /* Start a new Nongreen WML card */ sprintf(nongreenfn, "%s/nongreen-%d.wml", wmldir, nongreenpart); nongreenfd = fopen(nongreenfn, "w"); if (nongreenfd == NULL) { errprintf("Cannot open Nongreen WML file %s\n", nongreenfd); return; } wml_header(nongreenfd, "card", nongreenpart); fprintf(nongreenfd, "

\n"); fprintf(nongreenfd, "Previous
\n", oldnongreenfn); fprintf(nongreenfd, "%s

\n", timestamp); fprintf(nongreenfd, "

\n"); fprintf(nongreenfd, "Summary Status
%s

\n", colorname(nongreenwapcolor)); } } } fprintf(nongreenfd, "

\n"); fclose(nongreenfd); if (chdir(wmldir) == 0) { /* Rename the top-level file into place now */ rename("nongreen.wml.tmp", "nongreen.wml"); /* Make sure there is the index.wml file pointing to nongreen.wml */ if (!symlink("nongreen.wml", "index.wml")) { errprintf("symlink nongreen.xml->index.wml failed: %s\n", strerror(errno)); } } return; } xymon-4.3.30/xymongen/debug.h0000664000076400007640000000230411615341300016277 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __DEBUG_H_ #define __DEBUG_H_ extern int timing; extern void add_timestamp(const char *msg); extern void show_timestamps(char **buffer); extern long total_runtime(void); extern const char *textornull(const char *text); extern void dumphosts(host_t *head, char *prefix); extern void dumpgroups(group_t *head, char *prefix, char *hostprefix); extern void dumphostlist(hostlist_t *head); extern void dumpstatelist(state_t *head); extern void dumpall(xymongen_page_t *head); #endif xymon-4.3.30/xymongen/xymongen.c0000664000076400007640000006357112661417753017107 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This is the main program for generating Xymon overview webpages, showing */ /* the status of hosts in a Xymon system. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymongen.c 7902 2016-02-18 19:47:55Z jccleaver $"; #include #include #include #include #include #include #include #include "version.h" #include "xymongen.h" #include "util.h" #include "debug.h" #include "loadlayout.h" #include "loaddata.h" #include "process.h" #include "pagegen.h" #include "wmlgen.h" #include "rssgen.h" #include "csvreport.h" /* Global vars */ xymongen_page_t *pagehead = NULL; /* Head of page list */ state_t *statehead = NULL; /* Head of list of all state entries */ summary_t *sumhead = NULL; /* Summaries we send out */ dispsummary_t *dispsums = NULL; /* Summaries we received and display */ int xymon_color, nongreen_color, critical_color; /* Top-level page colors */ int fqdn = 1; /* Xymon FQDN setting */ int loadhostsfromxymond = 0; time_t reportstart = 0; time_t reportend = 0; double reportwarnlevel = 97.0; double reportgreenlevel = 99.995; int reportwarnstops = -1; int reportstyle = STYLE_CRIT; int dynamicreport = 1; enum tooltipuse_t tooltipuse = TT_STDONLY; char *reqenv[] = { "XYMONACKDIR", "XYMONHISTDIR", "XYMONHISTLOGS", "XYMONHOME", "HOSTSCFG", "XYMONRAWSTATUSDIR", "XYMONLOGSTATUS", "XYMONNOTESDIR", "XYMONREPDIR", "XYMONREPURL", "XYMONSKIN", "XYMONTMP", "XYMONVAR", "XYMONWEB", "XYMONWEBHOST", "XYMONWEBHOSTURL", "CGIBINURL", "DOTHEIGHT", "DOTWIDTH", "MACHINE", "MACHINEADDR", "XYMONPAGECOLFONT", "XYMONPAGELOCAL", "XYMONPAGESUBLOCAL", "XYMONPAGEREMOTE", "XYMONPAGEROWFONT", "XYMONPAGETITLE", "PURPLEDELAY", NULL }; int main(int argc, char *argv[]) { char *pagedir; xymongen_page_t *p; dispsummary_t *s; int i; char *pageset = NULL; char *nssidebarfilename = NULL; char *egocolumn = NULL; char *csvfile = NULL; char csvdelim = ','; int embedded = 0; char *envarea = NULL; int do_normal = 1; int do_nongreen = 1; /* Setup standard header+footer (might be modified by option pageset) */ select_headers_and_footers("std"); xymon_color = nongreen_color = critical_color = -1; pagedir = NULL; init_timestamp(); fqdn = get_fqdn(); /* Setup values from env. vars that may be overridden via command-line options */ if (xgetenv("XYMONPAGECOLREPEAT")) { int i = atoi(xgetenv("XYMONPAGECOLREPEAT")); if (i > 0) maxrowsbeforeheading = i; } for (i = 1; (i < argc); i++) { if ( (strcmp(argv[i], "--hobbitd") == 0) || (argnmatch(argv[i], "--purplelifetime=")) || (strcmp(argv[i], "--nopurple") == 0) ) { /* Deprecated */ } else if (argnmatch(argv[i], "--env=")) { char *lp = strchr(argv[i], '='); loadenv(lp+1, envarea); } else if (argnmatch(argv[i], "--area=")) { char *lp = strchr(argv[i], '='); envarea = strdup(lp+1); } else if (argnmatch(argv[i], "--ignorecolumns=")) { char *lp = strchr(argv[i], '='); ignorecolumns = (char *) malloc(strlen(lp)+2); sprintf(ignorecolumns, ",%s,", (lp+1)); } else if (strcmp(argv[i], "--showemptygroups") == 0) { showemptygroups = 1; } else if (strcmp(argv[i], "--no-showemptygroups") == 0) { showemptygroups = 0; } else if (argnmatch(argv[i], "--critical-reds-only") || argnmatch(argv[i], "--nk-reds-only")) { critonlyreds = 1; } else if (argnmatch(argv[i], "--nongreen-ignorecolumns=") || argnmatch(argv[i], "--bb2-ignorecolumns=")) { char *lp = strchr(argv[i], '='); nongreenignorecolumns = (char *) malloc(strlen(lp)+2); sprintf(nongreenignorecolumns, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--nongreen-colors=") || argnmatch(argv[i], "--bb2-colors=")) { char *lp = strchr(argv[i], '=') + 1; nongreencolors = colorset(lp, (1 << COL_GREEN)); } else if (argnmatch(argv[i], "--nongreen-ignorepurples") || argnmatch(argv[i], "--bb2-ignorepurples")) { nongreencolors = (nongreencolors & ~(1 << COL_PURPLE)); } else if (argnmatch(argv[i], "--nongreen-ignoredialups") || argnmatch(argv[i], "--bb2-ignoredialups")) { nongreennodialups = 1; } else if (argnmatch(argv[i], "--includecolumns=")) { char *lp = strchr(argv[i], '='); includecolumns = (char *) malloc(strlen(lp)+2); sprintf(includecolumns, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--eventignore=")) { char *lp = strchr(argv[i], '='); eventignorecolumns = (char *) malloc(strlen(lp)+2); sprintf(eventignorecolumns, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--doccgi=")) { char *lp = strchr(argv[i], '='); char *url = (char *)malloc(strlen(xgetenv("CGIBINURL"))+strlen(lp+1)+2); sprintf(url, "%s/%s", xgetenv("CGIBINURL"), lp+1); setdocurl(url); xfree(url); } else if (argnmatch(argv[i], "--docurl=")) { char *lp = strchr(argv[i], '='); setdocurl(lp+1); } else if (argnmatch(argv[i], "--no-doc-window")) { /* This is a no-op now */ } else if (argnmatch(argv[i], "--doc-window")) { setdoctarget("TARGET=\"_blank\""); } else if (argnmatch(argv[i], "--htmlextension=")) { char *lp = strchr(argv[i], '='); htmlextension = strdup(lp+1); } else if (argnmatch(argv[i], "--htaccess")) { char *lp = strchr(argv[i], '='); if (lp) htaccess = strdup(lp+1); else htaccess = ".htaccess"; } else if ((strcmp(argv[i], "--wml") == 0) || argnmatch(argv[i], "--wml=")) { char *lp = strchr(argv[i], '='); if (lp) { wapcolumns = (char *) malloc(strlen(lp)+2); sprintf(wapcolumns, ",%s,", (lp+1)); } enable_wmlgen = 1; } else if (argnmatch(argv[i], "--nstab=")) { char *lp = strchr(argv[i], '='); if (strlen(lp+1) > 0) { nssidebarfilename = strdup(lp+1); } else errprintf("--nstab requires a filename\n"); } else if (argnmatch(argv[i], "--nslimit=")) { char *lp = strchr(argv[i], '='); nssidebarcolorlimit = parse_color(lp+1); } else if (argnmatch(argv[i], "--rssversion=")) { char *lp = strchr(argv[i], '='); rssversion = strdup(lp+1); } else if (argnmatch(argv[i], "--rsslimit=")) { char *lp = strchr(argv[i], '='); rsscolorlimit = parse_color(lp+1); } else if (argnmatch(argv[i], "--rss")) { wantrss = 1; } else if (argnmatch(argv[i], "--rssextension=")) { char *lp = strchr(argv[i], '='); rssextension = strdup(lp+1); } else if (argnmatch(argv[i], "--reportopts=")) { char style[MAX_LINE_LEN]; unsigned int rstart, rend; int count = sscanf(argv[i], "--reportopts=%u:%u:%d:%s", &rstart, &rend, &dynamicreport, style); reportstart = rstart; reportend = rend; if (count < 2) { errprintf("Invalid --reportopts option: Must have start- and end-times\n"); return 1; } if (count < 3) dynamicreport = 1; if (count == 4) { if (strcmp(style, stylenames[STYLE_CRIT]) == 0) reportstyle = STYLE_CRIT; else if (strcmp(style, stylenames[STYLE_NONGR]) == 0) reportstyle = STYLE_NONGR; else reportstyle = STYLE_OTHER; } if (reportstart < 788918400) reportstart = 788918400; if (reportend > getcurrenttime(NULL)) reportend = getcurrenttime(NULL); if (xgetenv("XYMONREPWARN")) reportwarnlevel = atof(xgetenv("XYMONREPWARN")); if (xgetenv("XYMONREPGREEN")) reportgreenlevel = atof(xgetenv("XYMONREPGREEN")); if ((reportwarnlevel < 0.0) || (reportwarnlevel > 100.0)) reportwarnlevel = 97.0; if ((reportgreenlevel < 0.0) || (reportgreenlevel > 100.0)) reportgreenlevel = 99.995; select_headers_and_footers("rep"); sethostenv_report(reportstart, reportend, reportwarnlevel, reportgreenlevel); } else if (argnmatch(argv[i], "--csv=")) { char *lp = strchr(argv[i], '='); csvfile = strdup(lp+1); } else if (argnmatch(argv[i], "--csvdelim=")) { char *lp = strchr(argv[i], '='); csvdelim = *(lp+1); } else if (argnmatch(argv[i], "--snapshot=")) { char *lp = strchr(argv[i], '='); snapshot = atol(lp+1); select_headers_and_footers("snap"); sethostenv_snapshot(snapshot); } else if (strcmp(argv[i], "--pages-first") == 0) { hostsbeforepages = 0; } else if (strcmp(argv[i], "--pages-last") == 0) { hostsbeforepages = 1; } else if (argnmatch(argv[i], "--subpagecolumns=")) { char *lp = strchr(argv[i], '='); subpagecolumns = atoi(lp+1); if (subpagecolumns < 1) subpagecolumns=1; } else if (argnmatch(argv[i], "--maxrows=")) { char *lp = strchr(argv[i], '='); maxrowsbeforeheading = atoi(lp+1); if (maxrowsbeforeheading < 0) maxrowsbeforeheading=0; } else if (strcmp(argv[i], "--recentgifs") == 0) { use_recentgifs = 1; } else if (argnmatch(argv[i], "--recentgifs=")) { char *lp = strchr(argv[i], '='); use_recentgifs = 1; recentgif_limit = 60*durationvalue(lp+1); } else if (strcmp(argv[i], "--sort-group-only-items") == 0) { sort_grouponly_items = 1; } else if (argnmatch(argv[i], "--page-title=")) { char *lp = strchr(argv[i], '='); defaultpagetitle = strdup(lp+1); } else if (argnmatch(argv[i], "--dialupskin=")) { char *lp = strchr(argv[i], '='); dialupskin = strdup(lp+1); } else if (argnmatch(argv[i], "--reverseskin=")) { char *lp = strchr(argv[i], '='); reverseskin = strdup(lp+1); } else if (strcmp(argv[i], "--pagetitle-links") == 0) { pagetitlelinks = 1; } else if (strcmp(argv[i], "--pagetext-headings") == 0) { pagetextheadings = 1; } else if (strcmp(argv[i], "--underline-headings") == 0) { underlineheadings = 1; } else if (strcmp(argv[i], "--no-underline-headings") == 0) { underlineheadings = 0; } else if (strcmp(argv[i], "--no-eventlog") == 0) { nongreeneventlog = 0; } else if (argnmatch(argv[i], "--max-eventcount=")) { char *lp = strchr(argv[i], '='); nongreeneventlogmaxcount = atoi(lp+1); } else if (argnmatch(argv[i], "--max-eventtime=")) { char *lp = strchr(argv[i], '='); nongreeneventlogmaxtime = atoi(lp+1); } else if (argnmatch(argv[i], "--max-ackcount=")) { char *lp = strchr(argv[i], '='); nongreenacklogmaxcount = atoi(lp+1); } else if (argnmatch(argv[i], "--max-acktime=")) { char *lp = strchr(argv[i], '='); nongreenacklogmaxtime = atoi(lp+1); } else if (strcmp(argv[i], "--no-acklog") == 0) { nongreenacklog = 0; } else if (strcmp(argv[i], "--no-pages") == 0) { do_normal = 0; } else if ((strcmp(argv[i], "--no-nongreen") == 0) || (strcmp(argv[i], "--no-bb2") == 0)) { do_nongreen = 0; } else if (argnmatch(argv[i], "--noprop=")) { char *lp = strchr(argv[i], '='); nopropyellowdefault = (char *) malloc(strlen(lp)+2); sprintf(nopropyellowdefault, ",%s,", (lp+1)); errprintf("--noprop is deprecated - use --nopropyellow instead\n"); } else if (argnmatch(argv[i], "--nopropyellow=")) { char *lp = strchr(argv[i], '='); nopropyellowdefault = (char *) malloc(strlen(lp)+2); sprintf(nopropyellowdefault, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--nopropred=")) { char *lp = strchr(argv[i], '='); nopropreddefault = (char *) malloc(strlen(lp)+2); sprintf(nopropreddefault, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--noproppurple=")) { char *lp = strchr(argv[i], '='); noproppurpledefault = (char *) malloc(strlen(lp)+2); sprintf(noproppurpledefault, ",%s,", (lp+1)); } else if (argnmatch(argv[i], "--nopropack=")) { char *lp = strchr(argv[i], '='); nopropackdefault = (char *) malloc(strlen(lp)+2); sprintf(nopropackdefault, ",%s,", (lp+1)); } else if (strcmp(argv[i], "--bbpageONLY") == 0) { /* Deprecated */ errprintf("--bbpageONLY is deprecated - use --pageset=NAME to generate pagesets\n"); } else if (strcmp(argv[i], "--embedded") == 0) { embedded = 1; } else if (argnmatch(argv[i], "--pageset=")) { char *lp = strchr(argv[i], '='); pageset = strdup(lp+1); } else if (argnmatch(argv[i], "--template=")) { char *lp = strchr(argv[i], '='); lp++; select_headers_and_footers(lp); } else if (argnmatch(argv[i], "--tooltips=")) { char *lp = strchr(argv[i], '='); lp++; if (strcmp(lp, "always") == 0) tooltipuse = TT_ALWAYS; else if (strcmp(lp, "never") == 0) tooltipuse = TT_NEVER; else tooltipuse = TT_STDONLY; } else if (argnmatch(argv[i], "--purplelog=")) { char *lp = strchr(argv[i], '='); if (*(lp+1) == '/') purplelogfn = strdup(lp+1); else { purplelogfn = (char *) malloc(strlen(xgetenv("XYMONHOME"))+1+strlen(lp+1)+1); sprintf(purplelogfn, "%s/%s", xgetenv("XYMONHOME"), (lp+1)); } } else if (argnmatch(argv[i], "--report=") || (strcmp(argv[i], "--report") == 0)) { char *lp = strchr(argv[i], '='); if (lp) { egocolumn = strdup(lp+1); } else egocolumn = "xymongen"; timing = 1; } else if ( argnmatch(argv[i], "--criticallog=") || (strcmp(argv[i], "--criticallog") == 0) || argnmatch(argv[i], "--nklog=") || (strcmp(argv[i], "--nklog") == 0) ){ char *lp = strchr(argv[i], '='); if (lp) { logcritstatus = strdup(lp+1); } else logcritstatus = "critical"; } else if (strcmp(argv[i], "--timing") == 0) { timing = 1; } else if (strcmp(argv[i], "--debug") == 0) { debug = 1; } else if (strcmp(argv[i], "--no-update") == 0) { dontsendmessages = 1; } else if (strcmp(argv[i], "--loadhostsfromxymond") == 0) { loadhostsfromxymond = 1; } else if (strcmp(argv[i], "--version") == 0) { printf("xymongen version %s\n", VERSION); printf("\n"); exit(0); } else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-?") == 0)) { printf("xymongen for Xymon version %s\n\n", VERSION); printf("Usage: %s [options] [WebpageDirectory]\n", argv[0]); printf("Options:\n"); printf(" --ignorecolumns=test[,test] : Completely ignore these columns\n"); printf(" --critical-reds-only : Only show red statuses on the Critical page\n"); printf(" --nongreen-ignorecolumns=test[,test]: Ignore these columns for the non-green page\n"); printf(" --nongreen-ignorepurples : Ignore all-purple hosts on non-green page\n"); printf(" --includecolumns=test[,test]: Always include these columns on non-green page\n"); printf(" --max-eventcount=N : Max number of events to include in eventlog\n"); printf(" --max-eventtime=N : Show events that occurred within the last N minutes\n"); printf(" --eventignore=test[,test] : Columns to ignore in non-green event-log display\n"); printf(" --no-eventlog : Do not generate the non-green eventlog display\n"); printf(" --no-acklog : Do not generate the non-green ack-log display\n"); printf(" --no-pages : Generate only the nongreen and critical pages\n"); printf(" --docurl=documentation-URL : Hostnames link to a general (dynamic) web page for docs\n"); printf(" --doc-window : Open doc-links in a new browser window\n"); printf(" --htmlextension=.EXT : Sets filename extension for generated file (default: .html\n"); printf(" --report[=COLUMNNAME] : Send a status report about the running of xymongen\n"); printf(" --reportopts=ST:END:DYN:STL : Run in Xymon Reporting mode\n"); printf(" --csv=FILENAME : For Xymon Reporting, output CSV file\n"); printf(" --csvdelim=CHARACTER : Delimiter in CSV file output (default: comma)\n"); printf(" --snapshot=TIME : Snapshot mode\n"); printf("\nPage layout options:\n"); printf(" --pages-first : Put page- and subpage-links before hosts (default)\n"); printf(" --pages-last : Put page- and subpage-links after hosts\n"); printf(" --subpagecolumns=N : Number of columns for links to pages and subpages\n"); printf(" --maxrows=N : Repeat column headings for every N hosts shown\n"); printf(" --no-showemptygroups : Do not show groups without test results for the listed hosts\n"); printf(" --recentgifs : Use xxx-recent.gif icons for newly changed tests\n"); printf(" --sort-group-only-items : Display group-only items in alphabetical order\n"); printf(" --page-title=TITLE : Set a default page title for all pages\n"); printf(" --dialupskin=URL : Use a different icon skin for dialup tests\n"); printf(" --reverseskin=URL : Use a different icon skin for reverse tests\n"); printf(" --pagetitle-links : Make page- and subpage-titles act as links\n"); printf(" --pagetext-headings : Use page texts as headings\n"); printf(" --no-underline-headings : Do not underline the page headings\n"); printf("\nStatus propagation control options:\n"); printf(" --noprop=test[,test] : Disable upwards status propagation when YELLOW\n"); printf(" --nopropred=test[,test] : Disable upwards status propagation when RED or YELLOW\n"); printf(" --noproppurple=test[,test] : Disable upwards status propagation when PURPLE\n"); printf("\nAlternate pageset generation support:\n"); printf(" --pageset=SETNAME : Generate non-standard pageset with tag SETNAME\n"); printf(" --template=TEMPLATE : template for header and footer files\n"); printf("\nAlternate output formats:\n"); printf(" --wml[=test1,test2,...] : Generate a small (All nongreen-style) WML page\n"); printf(" --nstab=FILENAME : Generate a Netscape Sidebar feed\n"); printf(" --nslimit=COLOR : Minimum color to include on Netscape sidebar\n"); printf(" --rss : Generate a RSS/RDF feed of alerts\n"); printf(" --rssextension=.EXT : Sets filename extension for RSS files (default: .rss\n"); printf(" --rssversion={0.91|0.92|1.0|2.0} : Specify RSS/RDF version (default: 0.91)\n"); printf(" --rsslimit=COLOR : Minimum color to include on RSS feed\n"); printf("\nDebugging/troubleshooting options:\n"); printf(" --timing : Collect timing information\n"); printf(" --debug : Debugging information\n"); printf(" --version : Show version information\n"); printf(" --purplelog=FILENAME : Create a log of purple hosts and tests\n"); exit(0); } else if (argnmatch(argv[i], "-")) { errprintf("Unknown option : %s\n", argv[i]); } else { /* Last argument is pagedir */ pagedir = strdup(argv[i]); } } /* In case they changed the name of our column ... */ if (egocolumn) setup_signalhandler(egocolumn); if (debug) { int i; printf("Command: xymongen"); for (i=1; (inext) { if (p->color > pagehead->color) pagehead->color = p->color; } xymon_color = pagehead->color; if (xgetenv("SUMMARY_SET_BKG") && (strcmp(xgetenv("SUMMARY_SET_BKG"), "TRUE") == 0)) { /* * Displayed summaries affect the Xymon page only, * but should not go into the color we report to * others. */ for (s=dispsums; (s); s = s->next) { if (s->color > pagehead->color) pagehead->color = s->color; } } add_timestamp("Color calculation done"); if (debug) dumpall(pagehead); /* Generate pages */ if (chdir(pagedir) != 0) { errprintf("Cannot change to webpage directory %s\n", pagedir); exit(1); } if (embedded) { /* Just generate that one page */ do_one_page(pagehead, NULL, 1); return 0; } /* The main page - xymon.html and pages/subpages thereunder */ add_timestamp("Xymon pagegen start"); if (reportstart && csvfile) { csv_availability(csvfile, csvdelim); } if (do_normal) { do_page_with_subs(pagehead, dispsums); } add_timestamp("Xymon pagegen done"); if (reportstart) { /* Reports end here */ return 0; } /* The full summary page - nongreen.html */ if (do_nongreen) { nongreen_color = do_nongreen_page(nssidebarfilename, PAGE_NONGREEN, "nongreen"); nongreencolors = (nongreencolors & ~(1 << COL_YELLOW)); nongreencolors = (nongreencolors & ~(1 << COL_PURPLE)); nongreen_color = do_nongreen_page(nssidebarfilename, PAGE_NONGREEN, "red"); add_timestamp("Non-green page generation done"); } /* Reduced summary (alerts) page - critical.html */ critical_color = do_nongreen_page(NULL, PAGE_CRITICAL, "critical"); add_timestamp("Critical page generation done"); if (snapshot) { /* Snapshots end here */ return 0; } /* Send summary notices - only once, so not on pagesets */ if (pageset == NULL) { send_summaries(sumhead); add_timestamp("Summary transmission done"); } /* Generate WML cards */ if (enable_wmlgen) { do_wml_cards(pagedir); add_timestamp("WML generation done"); } /* Need to do this before sending in our report */ add_timestamp("Run completed"); /* Tell about us */ if (egocolumn) { char msgline[4096]; char *timestamps; long tasksleep = (xgetenv("TASKSLEEP") ? atol(xgetenv("TASKSLEEP")) : -1); int usebackfeedqueue, color; /* Go yellow if it runs for too long */ if ((tasksleep > 0) && (total_runtime() > tasksleep)) { errprintf("WARNING: Runtime %ld longer than TASKSLEEP (%ld)\n", total_runtime(), tasksleep); } color = (errbuf ? COL_YELLOW : COL_GREEN); usebackfeedqueue = (sendmessage_init_local() > 0); if (usebackfeedqueue) combo_start_local(); else combo_start(); init_status(color); sprintf(msgline, "status %s.%s %s %s\n\n", xgetenv("MACHINE"), egocolumn, colorname(color), timestamp); addtostatus(msgline); sprintf(msgline, "xymongen for Xymon version %s\n", VERSION); addtostatus(msgline); addtostatus("\nStatistics:\n"); sprintf(msgline, " Hosts : %5d\n", hostcount); addtostatus(msgline); sprintf(msgline, " Pages : %5d\n", pagecount); addtostatus(msgline); sprintf(msgline, " Status messages : %5d\n", statuscount); addtostatus(msgline); sprintf(msgline, " - Red : %5d (%5.2f %%)\n", colorcount[COL_RED], ((100.0 * colorcount[COL_RED]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Red (non-propagating) : %5d (%5.2f %%)\n", colorcount_noprop[COL_RED], ((100.0 * colorcount_noprop[COL_RED]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Yellow : %5d (%5.2f %%)\n", colorcount[COL_YELLOW], ((100.0 * colorcount[COL_YELLOW]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Yellow (non-propagating) : %5d (%5.2f %%)\n", colorcount_noprop[COL_YELLOW], ((100.0 * colorcount_noprop[COL_YELLOW]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Clear : %5d (%5.2f %%)\n", colorcount[COL_CLEAR], ((100.0 * colorcount[COL_CLEAR]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Green : %5d (%5.2f %%)\n", colorcount[COL_GREEN], ((100.0 * colorcount[COL_GREEN]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Purple : %5d (%5.2f %%)\n", colorcount[COL_PURPLE], ((100.0 * colorcount[COL_PURPLE]) / statuscount)); addtostatus(msgline); sprintf(msgline, " - Blue : %5d (%5.2f %%)\n", colorcount[COL_BLUE], ((100.0 * colorcount[COL_BLUE]) / statuscount)); addtostatus(msgline); if (errbuf) { addtostatus("\n\nError output:\n"); addtostatus(prehtmlquoted(errbuf)); } show_timestamps(×tamps); addtostatus(timestamps); finish_status(); combo_end(); if (usebackfeedqueue) sendmessage_finish_local(); } else show_timestamps(NULL); return 0; } xymon-4.3.30/xymongen/pagegen.c0000664000076400007640000012277512616226703016644 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This file contains code to generate the HTML for the Xymon overview */ /* webpages. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: pagegen.c 7719 2015-11-03 21:57:23Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include #include "xymongen.h" #include "util.h" #include "loadlayout.h" #include "rssgen.h" #include "pagegen.h" int subpagecolumns = 1; int hostsbeforepages = 0; char *includecolumns = NULL; char *nongreenignorecolumns = ""; int nongreennodialups = 0; int sort_grouponly_items = 0; /* Standard Xymon behaviour: Don't sort group-only items */ char *rssextension = ".rss"; /* Filename extension for generated RSS files */ char *defaultpagetitle = NULL; int pagetitlelinks = 0; int pagetextheadings = 0; int underlineheadings = 1; int maxrowsbeforeheading = 0; int showemptygroups = 1; int nongreeneventlog = 1; int nongreenacklog = 1; int nongreeneventlogmaxcount = 100; int nongreeneventlogmaxtime = 240; int nongreenacklogmaxcount = 25; int nongreenacklogmaxtime = 240; char *logcritstatus = NULL; int critonlyreds = 0; int wantrss = 0; int nongreencolors = ((1 << COL_RED) | (1 << COL_YELLOW) | (1 << COL_PURPLE)); /* Format strings for htaccess files */ char *htaccess = NULL; char *xymonhtaccess = NULL; char *xymonpagehtaccess = NULL; char *xymonsubpagehtaccess = NULL; char *hf_prefix[3]; /* header/footer prefixes for xymon, nongreen, critical pages*/ static int hostblkidx = 0; void select_headers_and_footers(char *prefix) { hf_prefix[PAGE_NORMAL] = (char *) malloc(strlen(prefix)+10); sprintf(hf_prefix[PAGE_NORMAL], "%snormal", prefix); hf_prefix[PAGE_NONGREEN] = (char *) malloc(strlen(prefix)+10); sprintf(hf_prefix[PAGE_NONGREEN], "%snongreen", prefix); hf_prefix[PAGE_CRITICAL] = (char *) malloc(strlen(prefix)+10); sprintf(hf_prefix[PAGE_CRITICAL], "%scritical", prefix); } int interesting_column(int pagetype, int color, int alert, xymongen_col_t *column, char *onlycols, char *exceptcols) { /* * Decides if a given column is to be included on a page. */ if (pagetype == PAGE_NORMAL) { /* Fast-path the Xymon page. */ int result = 1; if (onlycols) { /* onlycols explicitly list the columns to include (for xymon.html page only) */ char *search; /* loaddata::init_group guarantees that onlycols start and end with a '|' */ search = (char *) malloc(strlen(column->name)+3); sprintf(search, "|%s|", column->name); result = (strstr(onlycols, search) != NULL); xfree(search); } if (exceptcols) { /* exceptcols explicitly list the columns to exclude (for xymon.html page only) */ char *search; /* loaddata::init_group guarantees that exceptcols start and end with a '|' */ search = (char *) malloc(strlen(column->name)+3); sprintf(search, "|%s|", column->name); result = (strstr(exceptcols, search) == NULL); xfree(search); } /* This is final. */ return result; } /* pagetype is now known NOT to be PAGE_NORMAL */ /* CLIENT, TRENDS and INFO columns are always included on non-Xymon pages */ if (strcmp(column->name, xgetenv("INFOCOLUMN")) == 0) return 1; if (strcmp(column->name, xgetenv("TRENDSCOLUMN")) == 0) return 1; if (strcmp(column->name, xgetenv("CLIENTCOLUMN")) == 0) return 1; if (includecolumns) { int result; result = (strstr(includecolumns, column->listname) != NULL); /* If included, done here. Otherwise may be included further down. */ if (result) return result; } switch (pagetype) { case PAGE_NONGREEN: /* Include all non-green tests */ if (( (1 << color) & nongreencolors ) != 0) { return (strstr(nongreenignorecolumns, column->listname) == NULL); } else return 0; case PAGE_CRITICAL: /* Include only RED or YELLOW tests with "alert" property set. * Even then, the "conn" test is included only when RED. */ if (alert) { if (color == COL_RED) return 1; if (critonlyreds) return 0; if ( (color == COL_YELLOW) || (color == COL_CLEAR) ) { if (strcmp(column->name, xgetenv("PINGCOLUMN")) == 0) return 0; if (logcritstatus && (strcmp(column->name, logcritstatus) == 0)) return 0; return 1; } } break; } return 0; } col_list_t *gen_column_list(host_t *hostlist, int pagetype, char *onlycols, char *exceptcols) { /* * Build a list of all the columns that are in use by * any host in the hostlist passed as parameter. * The column list will be sorted by column name, except * when doing a "group-only" and the standard Xymon behaviour. */ col_list_t *head; host_t *h; entry_t *e; col_list_t *newlistitem, *collist_walk; /* Code de-obfuscation trick: Add a null record as the head item */ /* Simplifies handling since head != NULL and we never have to insert at head of list */ head = (col_list_t *) calloc(1, sizeof(col_list_t)); head->column = &null_column; head->next = NULL; if (!sort_grouponly_items && (onlycols != NULL)) { /* * This is the original handling of "group-only". * All items are included, whether there are any test data * for a column or not. The order given in the group-only * directive is maintained. * We simple convert the group-only directive to a * col_list_t linked list. */ char *p1 = onlycols; char *p2; xymongen_col_t *col; collist_walk = head; do { if (*p1 == '|') p1++; p2 = strchr(p1, '|'); if (p2) { *p2 = '\0'; col = find_or_create_column(p1, 0); if (col) { newlistitem = (col_list_t *) calloc(1, sizeof(col_list_t)); newlistitem->column = col; newlistitem->next = NULL; collist_walk->next = newlistitem; collist_walk = collist_walk->next; } *p2 = '|'; } p1 = p2; } while (p1 != NULL); /* Skip the dummy record */ collist_walk = head; head = head->next; xfree(collist_walk); /* We're done - don't even look at the actual test data. */ return (head); } for (h = hostlist; (h); h = h->next) { /* * This is for everything except "standard group-only" handled above. * So also for group-only with --sort-group-only-items. * Note that in a group-only here, items may be left out if there * are no test data for a column at all. */ for (e = h->entries; (e); e = e->next) { if (!e->compacted && interesting_column(pagetype, e->color, e->alert, e->column, onlycols, exceptcols)) { /* See where e->column should go in list */ collist_walk = head; while ( (collist_walk->next && strcmp(e->column->name, ((col_list_t *)(collist_walk->next))->column->name) > 0) ) { collist_walk = collist_walk->next; } if ((collist_walk->next == NULL) || ((col_list_t *)(collist_walk->next))->column != e->column) { /* collist_walk points to the entry before the new one */ newlistitem = (col_list_t *) calloc(1, sizeof(col_list_t)); newlistitem->column = e->column; newlistitem->next = collist_walk->next; collist_walk->next = newlistitem; } } } } /* Skip the dummy record */ collist_walk = head; head = head->next; xfree(collist_walk); return (head); } void setup_htaccess(const char *pagepath) { char htaccessfn[PATH_MAX]; char htaccesscontent[1024]; if (htaccess == NULL) return; htaccesscontent[0] = '\0'; if (strlen(pagepath) == 0) { sprintf(htaccessfn, "%s", htaccess); if (xymonhtaccess) strcpy(htaccesscontent, xymonhtaccess); } else { char *pagename, *subpagename, *p; char *path = strdup(pagepath); for (p = path + strlen(path) - 1; ((p > path) && (*p == '/')); p--) *p = '\0'; sprintf(htaccessfn, "%s/%s", path, htaccess); pagename = path; if (*pagename == '/') pagename++; p = strchr(pagename, '/'); if (p) { *p = '\0'; subpagename = p+1; p = strchr(subpagename, '/'); if (p) *p = '\0'; if (xymonsubpagehtaccess) sprintf(htaccesscontent, xymonsubpagehtaccess, pagename, subpagename); } else { if (xymonpagehtaccess) sprintf(htaccesscontent, xymonpagehtaccess, pagename); } xfree(path); } if (strlen(htaccesscontent)) { FILE *fd; struct stat st; if (stat(htaccessfn, &st) == 0) { dbgprintf("htaccess file %s exists, not overwritten\n", htaccessfn); return; } fd = fopen(htaccessfn, "w"); if (fd) { fprintf(fd, "%s\n", htaccesscontent); fclose(fd); } else { errprintf("Cannot create %s: %s\n", htaccessfn, strerror(errno)); } } } static int host_t_compare(const void *v1, const void *v2) { host_t **n1 = (host_t **)v1; host_t **n2 = (host_t **)v2; return strcmp((*n1)->hostname, (*n2)->hostname); } typedef struct vprec_t { char *testname; host_t **hosts; entry_t **entries; } vprec_t; void do_vertical(host_t *head, FILE *output, char *pagepath) { /* * This routine outputs the host part of a page or a group, * but with the hosts going across the page, and the test going down. * I.e. it generates buttons and links to all the hosts for * a test, and the host docs. */ host_t *h; entry_t *e; char *xymonskin; int hostcount = 0; int width; int hidx; void *vptree; xtreePos_t handle; if (head == NULL) return; vptree = xtreeNew(strcmp); xymonskin = strdup(xgetenv("XYMONSKIN")); width = atoi(xgetenv("DOTWIDTH")); if ((width < 0) || (width > 50)) width = 16; width += 4; /* Start the table ... */ fprintf(output, "
\n"); /* output column headings */ fprintf(output, ""); for (h = head, hostcount = 0; (h); h = h->next, hostcount++) { fprintf(output, " \n", hostsvcurl(h->hostname, xgetenv("INFOCOLUMN"), 1), xgetenv("XYMONPAGECOLFONT"), h->hostname); } fprintf(output, "\n"); fprintf(output, "\n\n", hostcount); /* Create a tree indexed by the testname, and holding the show/noshow status of each test */ for (h = head, hidx = 0; (h); h = h->next, hidx++) { for (e = h->entries; (e); e = e->next) { vprec_t *itm; handle = xtreeFind(vptree, e->column->name); if (handle == xtreeEnd(vptree)) { itm = (vprec_t *)malloc(sizeof(vprec_t)); itm->testname = e->column->name; itm->hosts = (host_t **)calloc(hostcount, sizeof(host_t *)); itm->entries = (entry_t **)calloc(hostcount, sizeof(entry_t *)); xtreeAdd(vptree, itm->testname, itm); } else { itm = xtreeData(vptree, handle); } (itm->hosts)[hidx] = h; (itm->entries)[hidx] = e; } } for (handle = xtreeFirst(vptree); (handle != xtreeEnd(vptree)); handle = xtreeNext(vptree, handle)) { vprec_t *itm = xtreeData(vptree, handle); fprintf(output, ""); fprintf(output, "", itm->testname); for (hidx = 0; (hidx < hostcount); hidx++) { char *skin, *htmlalttag; host_t *h = (itm->hosts)[hidx]; entry_t *e = (itm->entries)[hidx]; fprintf(output, ""); } fprintf(output, "\n"); } fprintf(output, "
 "); fprintf(output, " %s
 
%s"); if (e == NULL) { fprintf(output, "-"); } else { if (strcmp(e->column->name, xgetenv("INFOCOLUMN")) == 0) { /* show the host ip on the hint display of the "info" column */ htmlalttag = alttag(e->column->name, COL_GREEN, 0, 1, h->ip); } else { htmlalttag = alttag(e->column->name, e->color, e->acked, e->propagate, e->age); } skin = (e->skin ? e->skin : xymonskin); fprintf(output, "", hostsvcurl(h->hostname, e->column->name, 1)); fprintf(output, "\"%s\"", skin, dotgiffilename(e->color, e->acked, e->oldage), htmlalttag, htmlalttag, xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); } fprintf(output, "

\n"); xfree(xymonskin); } void do_hosts(host_t *head, int sorthosts, char *onlycols, char *exceptcols, FILE *output, FILE *rssoutput, char *grouptitle, int pagetype, char *pagepath) { /* * This routine outputs the host part of a page or a group. * I.e. it generates buttons and links to all the tests for * a host, and the host docs. */ host_t *h; entry_t *e; col_list_t *groupcols, *gc; int genstatic; int columncount; char *xymonskin, *infocolumngif, *trendscolumngif, *clientcolumngif; char *safegrouptitle; int rowcount = 0; int usetooltip = 0; if (head == NULL) return; xymonskin = strdup(xgetenv("XYMONSKIN")); infocolumngif = strdup(getenv("INFOCOLUMNGIF") ? getenv("INFOCOLUMNGIF") : dotgiffilename(COL_GREEN, 0, 1)); trendscolumngif = strdup(getenv("TRENDSCOLUMNGIF") ? getenv("TRENDSCOLUMNGIF") : dotgiffilename(COL_GREEN, 0, 1)); clientcolumngif = strdup(getenv("CLIENTCOLUMNGIF") ? getenv("CLIENTCOLUMNGIF") : dotgiffilename(COL_GREEN, 0, 1)); switch (tooltipuse) { case TT_STDONLY: usetooltip = (pagetype == PAGE_NORMAL); break; case TT_ALWAYS: usetooltip = 1; break; case TT_NEVER: usetooltip = 0; break; } /* Generate static or dynamic links (from XYMONLOGSTATUS) ? */ genstatic = generate_static(); if (hostblkidx == 0) fprintf(output, " \n\n"); else fprintf(output, " \n\n", hostblkidx); hostblkidx++; if (!grouptitle) grouptitle = ""; safegrouptitle = stripnonwords(grouptitle); if (*safegrouptitle != '\0') fprintf(output, "\n\n", safegrouptitle); groupcols = gen_column_list(head, pagetype, onlycols, exceptcols); for (columncount=0, gc=groupcols; (gc); gc = gc->next, columncount++) ; if (showemptygroups || groupcols) { int width; width = atoi(xgetenv("DOTWIDTH")); if ((width < 0) || (width > 50)) width = 16; width += 4; /* Start the table ... */ fprintf(output, "
\n", safegrouptitle); /* Generate the host rows */ if (sorthosts) { int i, hcount = 0; host_t **hlist; for (h=head; (h); h=h->next) hcount++; hlist = (host_t **) calloc((hcount+1), sizeof(host_t *)); for (h=head, i=0; (h); h=h->next, i++) hlist[i] = h; qsort(hlist, hcount, sizeof(host_t *), host_t_compare); for (h=head=hlist[0], i=1; (i <= hcount); i++) { h->next = hlist[i]; h = h->next; } xfree(hlist); } for (h = head; (h); h = h->next) { /* If there is a host pretitle, show it. */ dbgprintf("Host:%s, pretitle:%s\n", h->hostname, textornull(h->pretitle)); if (h->pretitle && (pagetype == PAGE_NORMAL)) { fprintf(output, "\n", columncount+1, xgetenv("XYMONPAGETITLE"), h->pretitle); rowcount = 0; } if (rowcount == 0) { /* output group title and column headings */ fprintf(output, ""); fprintf(output, "\n", xgetenv("XYMONPAGETITLE"), grouptitle); for (gc=groupcols; (gc); gc = gc->next) { fprintf(output, " \n", columnlink(gc->column->name), xgetenv("XYMONPAGECOLFONT"), gc->column->name); } if (columncount) fprintf(output, "\n\n\n", columncount); else fprintf(output, "\n\n\n"); } fprintf(output, "\n \n"); } fprintf(output, "\n\n"); } fprintf(output, "

%s
%s
\n"); fprintf(output, " %s

 \n", h->hostname); if (maxrowsbeforeheading) rowcount = (rowcount + 1) % maxrowsbeforeheading; else rowcount++; fprintf(output, "%s", hostnamehtml(h->hostname, ((pagetype != PAGE_NORMAL) ? hostpage_link(h) : NULL), usetooltip)); /* Then the columns. */ for (gc = groupcols; (gc); gc = gc->next) { char *htmlalttag; fprintf(output, ""); /* Any column entry for this host ? */ for (e = h->entries; (e && (e->column != gc->column)); e = e->next) ; if (e == NULL) { fprintf(output, "-"); } else if (e->histlogname) { /* Snapshot points to historical logfile */ htmlalttag = alttag(e->column->name, e->color, e->acked, e->propagate, e->age); fprintf(output, "", histlogurl(h->hostname, e->column->name, 0, e->histlogname)); fprintf(output, "\"%s\"", xymonskin, dotgiffilename(e->color, 0, 1), htmlalttag, htmlalttag, xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); } else if (reportstart == 0) { /* Standard webpage */ char *skin; char *img = dotgiffilename(e->color, e->acked, e->oldage); if (strcmp(e->column->name, xgetenv("INFOCOLUMN")) == 0) { /* Show the host IP on the hint display of the "info" column */ htmlalttag = alttag(e->column->name, COL_GREEN, 0, 1, h->ip); img = infocolumngif; } else if (strcmp(e->column->name, xgetenv("TRENDSCOLUMN")) == 0) { htmlalttag = alttag(e->column->name, COL_GREEN, 0, 1, h->ip); img = trendscolumngif; } else if (strcmp(e->column->name, xgetenv("CLIENTCOLUMN")) == 0) { htmlalttag = alttag(e->column->name, COL_GREEN, 0, 1, h->ip); img = clientcolumngif; } else { htmlalttag = alttag(e->column->name, e->color, e->acked, e->propagate, e->age); } skin = (e->skin ? e->skin : xymonskin); if (e->sumurl) { /* A summary host. */ fprintf(output, "", e->sumurl); } else if (genstatic && strcmp(e->column->name, xgetenv("INFOCOLUMN")) && strcmp(e->column->name, xgetenv("TRENDSCOLUMN")) && strcmp(e->column->name, xgetenv("CLIENTCOLUMN"))) { /* * Don't use htmlextension here - it's for the * pages generated dynamically. * We don't do static pages for the info- and trends-columns, because * they are always generated dynamically. */ fprintf(output, "", xgetenv("XYMONWEB"), h->hostname, e->column->name); do_rss_item(rssoutput, h, e); } else { fprintf(output, "", hostsvcurl(h->hostname, e->column->name, 1)); do_rss_item(rssoutput, h, e); } fprintf(output, "\"%s\"", skin, img, htmlalttag, htmlalttag, xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); } else { /* Report format output */ if ((e->color == COL_GREEN) || (e->color == COL_CLEAR)) { fprintf(output, "\"%s\"", xymonskin, dotgiffilename(e->color, 0, 1), colorname(e->color), colorname(e->color), xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH")); } else { if (dynamicreport) { fprintf(output, "", replogurl(h->hostname, e->column->name, e->color, stylenames[reportstyle], use_recentgifs, e->repinfo, h->reporttime, reportend, h->reportwarnlevel)); } else { FILE *htmlrep, *textrep; char htmlrepfn[PATH_MAX]; char textrepfn[PATH_MAX]; char textrepurl[PATH_MAX]; /* File names are relative - current directory is the output dir */ /* pagepath is either empty, or it ends with a '/' */ sprintf(htmlrepfn, "%s%s-%s%s", pagepath, h->hostname, e->column->name, htmlextension); sprintf(textrepfn, "%savail-%s-%s.txt", pagepath, h->hostname, e->column->name); sprintf(textrepurl, "%s/%s", xgetenv("XYMONWEB"), textrepfn); htmlrep = fopen(htmlrepfn, "w"); if (!htmlrep) { errprintf("Cannot create output file %s: %s\n", htmlrepfn, strerror(errno)); } textrep = fopen(textrepfn, "w"); if (!textrep) { errprintf("Cannot create output file %s: %s\n", textrepfn, strerror(errno)); } if (textrep && htmlrep) { /* Pre-build the test-specific report */ restore_replogs(e->causes); generate_replog(htmlrep, textrep, textrepurl, h->hostname, e->column->name, e->color, reportstyle, h->ip, h->displayname, reportstart, reportend, reportwarnlevel, reportgreenlevel, reportwarnstops, e->repinfo); fclose(textrep); fclose(htmlrep); } fprintf(output, "\n", h->hostname, e->column->name, htmlextension); } /* Only show #stops if we have this as an SLA parameter */ if (h->reportwarnstops >= 0) { fprintf(output, "%.2f (%d)\n", colorname(e->color), e->repinfo->reportavailability, e->repinfo->reportstops); } else { fprintf(output, "%.2f\n", colorname(e->color), e->repinfo->reportavailability); } } } fprintf(output, "

\n"); } /* Free the columnlist allocated by gen_column_list() */ while (groupcols) { gc = groupcols; groupcols = groupcols->next; xfree(gc); } xfree(xymonskin); xfree(infocolumngif); xfree(trendscolumngif); } void do_groups(group_t *head, FILE *output, FILE *rssoutput, char *pagepath) { /* * This routine generates all the groups on a given page. * It also triggers generating host output for hosts * within the groups. */ group_t *g; if (head == NULL) return; fprintf(output, "
\n\n \n"); for (g = head; (g); g = g->next) { if (g->hosts && g->pretitle) { fprintf(output, "
\n"); fprintf(output, " \n", xgetenv("XYMONPAGETITLE"), g->pretitle); if (underlineheadings) fprintf(output, " \n"); fprintf(output, "
%s

\n"); } do_hosts(g->hosts, g->sorthosts, g->onlycols, g->exceptcols, output, rssoutput, g->title, PAGE_NORMAL, pagepath); } fprintf(output, "\n
\n"); } void do_summaries(dispsummary_t *sums, FILE *output) { /* * Generates output for summary statuses received from others. */ dispsummary_t *s; host_t *sumhosts = NULL; host_t *walk; if (sums == NULL) { /* No summary items */ return; } for (s=sums; (s); s = s->next) { /* Generate host records out of all unique s->row values */ host_t *newhost; entry_t *newentry; dispsummary_t *s2; /* Do we already have it ? */ for (newhost = sumhosts; (newhost && (strcmp(s->row, newhost->hostname) != 0) ); newhost = newhost->next); if (newhost == NULL) { /* New summary "host" */ newhost = init_host(s->row, 1, NULL, NULL, NULL, NULL, 0,0,0,0, 0, 0.0, 0, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL); /* Insert into sorted host list */ if ((!sumhosts) || (strcmp(newhost->hostname, sumhosts->hostname) < 0)) { /* Empty list, or new entry goes before list head item */ newhost->next = sumhosts; sumhosts = newhost; } else { /* Walk list until we find element that goes after new item */ for (walk = sumhosts; (walk->next && (strcmp(newhost->hostname, ((host_t *)walk->next)->hostname) > 0)); walk = walk->next) ; /* "walk" points to element before the new item */ newhost->next = walk->next; walk->next = newhost; } /* Setup the "event" records from the column records */ for (s2 = sums; (s2); s2 = s2->next) { if (strcmp(s2->row, s->row) == 0) { newentry = (entry_t *) calloc(1, sizeof(entry_t)); newentry->column = find_or_create_column(s2->column, 1); newentry->color = s2->color; strcpy(newentry->age, ""); newentry->oldage = 1; /* Use standard gifs */ newentry->propagate = 1; newentry->sumurl = s2->url; newentry->next = newhost->entries; newhost->entries = newentry; } } } } fprintf(output, " \n"); fprintf(output, "
\n"); fprintf(output, "\n"); fprintf(output, "\n"); fprintf(output, "
\n"); do_hosts(sumhosts, 1, NULL, NULL, output, NULL, xgetenv("XYMONPAGEREMOTE"), 0, NULL); fprintf(output, "
\n"); fprintf(output, "
\n"); } void do_page_subpages(FILE *output, xymongen_page_t *subs, char *pagepath) { /* * This routine does NOT generate subpages! * Instead, it generates the LINKS to the subpages below any given page. */ xymongen_page_t *p; int currentcolumn; char pagelink[PATH_MAX]; char *linkurl; if (subs) { fprintf(output, " \n"); fprintf(output, "
\n
\n"); fprintf(output, "\n"); currentcolumn = 0; for (p = subs; (p); p = p->next) { if (p->pretitle) { /* * Output a page-link title text. */ if (currentcolumn != 0) { fprintf(output, "\n"); currentcolumn = 0; } fprintf(output, "\n"); fprintf(output, "\n"); } if (currentcolumn == 0) fprintf(output, "\n"); sprintf(pagelink, "%s/%s/%s/%s%s", xgetenv("XYMONWEB"), pagepath, p->name, p->name, htmlextension); linkurl = hostlink(p->name); fprintf(output, "\n"); fprintf(output, "\n"); if (currentcolumn == (subpagecolumns-1)) { fprintf(output, "\n"); currentcolumn = 0; } else { /* Need to have a little space between columns */ fprintf(output, "", xgetenv("DOTWIDTH")); currentcolumn++; } } if (currentcolumn != 0) fprintf(output, "\n"); fprintf(output, "
\n\n", (2*subpagecolumns + (subpagecolumns - 1)), xgetenv("XYMONPAGETITLE")); fprintf(output, "
%s\n", p->pretitle); fprintf(output, "
", (2*subpagecolumns + (subpagecolumns - 1))); if (underlineheadings) { fprintf(output, "
"); } else { fprintf(output, " "); } fprintf(output, "
", xgetenv("XYMONPAGEROWFONT")); if (linkurl) { fprintf(output, "%s", linkurl, p->title); } else if (pagetitlelinks) { fprintf(output, "%s", cleanurl(pagelink), p->title); } else { fprintf(output, "%s", p->title); } fprintf(output, "
", cleanurl(pagelink)); fprintf(output, "\"%s\"", xgetenv("XYMONSKIN"), dotgiffilename(p->color, 0, ((reportstart > 0) ? 1 : p->oldage)), xgetenv("DOTWIDTH"), xgetenv("DOTHEIGHT"), colorname(p->color), colorname(p->color)); fprintf(output, "
 

\n"); fprintf(output, "
\n"); } } void do_one_page(xymongen_page_t *page, dispsummary_t *sums, int embedded) { FILE *output = NULL; FILE *rssoutput = NULL; char pagepath[PATH_MAX]; char filename[PATH_MAX]; char tmpfilename[PATH_MAX]; char rssfilename[PATH_MAX]; char tmprssfilename[PATH_MAX]; char curdir[PATH_MAX]; char *dirdelim; char *localtext; if (!getcwd(curdir, sizeof(curdir))) { errprintf("Cannot get current directory: %s\n", strerror(errno)); return; } localtext = strdup(xgetenv((page->parent ? "XYMONPAGESUBLOCAL" : "XYMONPAGELOCAL"))); pagepath[0] = '\0'; if (embedded) { output = stdout; } else { if (page->parent == NULL) { char indexfilename[PATH_MAX]; /* top level page */ sprintf(filename, "xymon%s", htmlextension); sprintf(rssfilename, "xymon%s", rssextension); sprintf(indexfilename, "index%s", htmlextension); unlink(indexfilename); if (symlink(filename, indexfilename)) { dbgprintf("Symlinking %s -> %s\n", filename, indexfilename); } } else { char tmppath[PATH_MAX]; xymongen_page_t *pgwalk; for (pgwalk = page; (pgwalk); pgwalk = pgwalk->parent) { if (strlen(pgwalk->name)) { sprintf(tmppath, "%s/%s/", pgwalk->name, pagepath); strcpy(pagepath, tmppath); } } sprintf(filename, "%s/%s%s", pagepath, page->name, htmlextension); sprintf(rssfilename, "%s/%s%s", pagepath, page->name, rssextension); } sprintf(tmpfilename, "%s.tmp", filename); sprintf(tmprssfilename, "%s.tmp", rssfilename); /* Try creating the output file. If it fails, we may need to create the directories */ hostblkidx = 0; output = fopen(tmpfilename, "w"); if (output == NULL) { char indexfilename[PATH_MAX]; char pagebasename[PATH_MAX]; char *p; int res; /* Make sure the directories exist. */ dirdelim = tmpfilename; while ((dirdelim = strchr(dirdelim, '/')) != NULL) { *dirdelim = '\0'; if ((mkdir(tmpfilename, 0755) == -1) && (errno != EEXIST)) { errprintf("Cannot create directory %s (in %s): %s\n", tmpfilename, curdir, strerror(errno)); } *dirdelim = '/'; dirdelim++; } /* We've created the directories. Now retry creating the file. */ output = fopen(tmpfilename, "w"); if (output == NULL) { errprintf("Cannot create file %s (in %s): %s\n", tmpfilename, curdir, strerror(errno)); return; } /* * We had to create the directory. Set up an index.html file for * the directory where we created our new file. */ strcpy(indexfilename, filename); p = strrchr(indexfilename, '/'); if (p) p++; else p = indexfilename; sprintf(p, "index%s", htmlextension); sprintf(pagebasename, "%s%s", page->name, htmlextension); if ((symlink(pagebasename, indexfilename) == -1) && ((res = errno) != EEXIST)) { errprintf("Cannot create symlink %s->%s (in %s): %s\n", indexfilename, pagebasename, curdir, strerror(res)); } if (output == NULL) { return; } } if (wantrss) { /* Just create the RSS files - all the directory stuff is done */ rssoutput = fopen(tmprssfilename, "w"); if (rssoutput == NULL) { errprintf("Cannot open RSS file %s: %s\n", tmprssfilename, strerror(errno)); } } } setup_htaccess(pagepath); headfoot(output, hf_prefix[PAGE_NORMAL], pagepath, "header", page->color); do_rss_header(rssoutput); if (pagetextheadings && page->title && strlen(page->title)) { fprintf(output, "
\n"); fprintf(output, " \n", xgetenv("XYMONPAGETITLE"), page->title); if (underlineheadings) fprintf(output, " \n"); fprintf(output, "
%s

\n"); } else if (page->subpages) { /* If first page does not have a pretitle, use the default ones */ if (page->subpages->pretitle == NULL) { page->subpages->pretitle = (defaultpagetitle ? defaultpagetitle : localtext); } } if (!embedded && !hostsbeforepages && page->subpages) do_page_subpages(output, page->subpages, pagepath); if (page->vertical) { do_vertical(page->hosts, output, pagepath); } else { do_hosts(page->hosts, 0, NULL, NULL, output, rssoutput, "", PAGE_NORMAL, pagepath); do_groups(page->groups, output, rssoutput, pagepath); } if (!embedded && hostsbeforepages && page->subpages) do_page_subpages(output, page->subpages, pagepath); /* Summaries on main page only */ if (!embedded && (page->parent == NULL)) { do_summaries(dispsums, output); } /* Extension scripts */ do_extensions(output, "XYMONSTDEXT", "mkbb"); headfoot(output, hf_prefix[PAGE_NORMAL], pagepath, "footer", page->color); do_rss_footer(rssoutput); if (!embedded) { fclose(output); if (rename(tmpfilename, filename)) { errprintf("Cannot rename %s to %s - error %d\n", tmpfilename, filename, errno); } if (rssoutput) { fclose(rssoutput); if (rename(tmprssfilename, rssfilename)) { errprintf("Cannot rename %s to %s - error %d\n", tmprssfilename, rssfilename, errno); } } } xfree(localtext); } void do_page_with_subs(xymongen_page_t *curpage, dispsummary_t *sums) { xymongen_page_t *levelpage; for (levelpage = curpage; (levelpage); levelpage = levelpage->next) { do_one_page(levelpage, sums, 0); do_page_with_subs(levelpage->subpages, NULL); } } static void do_nongreenext(FILE *output, char *extenv, char *family) { /* * Do the non-green page extensions. Since we have built-in * support for eventlog.sh and acklog.sh, we cannot * use the standard do_extensions() routine. */ char *extensions, *p; FILE *inpipe; char extfn[PATH_MAX]; char buf[4096]; p = xgetenv(extenv); if (p == NULL) { /* No extension */ return; } extensions = strdup(p); p = strtok(extensions, "\t "); while (p) { /* Don't redo the eventlog or acklog things */ if (strcmp(p, "eventlog.sh") == 0) { if (nongreeneventlog && !havedoneeventlog) { do_eventlog(output, nongreeneventlogmaxcount, nongreeneventlogmaxtime, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, nongreennodialups, host_exists, NULL, NULL, NULL, XYMON_COUNT_NONE, XYMON_S_NONE, NULL); } } else if (strcmp(p, "acklog.sh") == 0) { if (nongreenacklog && !havedoneacklog) do_acklog(output, nongreenacklogmaxcount, nongreenacklogmaxtime); } else if (strcmp(p, "summaries") == 0) { do_summaries(dispsums, output); } else { sprintf(extfn, "%s/ext/%s/%s", xgetenv("XYMONHOME"), family, p); inpipe = popen(extfn, "r"); if (inpipe) { while (fgets(buf, sizeof(buf), inpipe)) fputs(buf, output); pclose(inpipe); } } p = strtok(NULL, "\t "); } xfree(extensions); } int do_nongreen_page(char *nssidebarfilename, int summarytype, char *filenamebase) { xymongen_page_t nongreenpage; FILE *output = NULL; FILE *rssoutput = NULL; char filename[PATH_MAX]; char tmpfilename[PATH_MAX]; char rssfilename[PATH_MAX]; char tmprssfilename[PATH_MAX]; hostlist_t *h; /* Build a "page" with the hosts that should be included in nongreen page */ nongreenpage.name = nongreenpage.title = ""; nongreenpage.color = COL_GREEN; nongreenpage.subpages = NULL; nongreenpage.groups = NULL; nongreenpage.hosts = NULL; nongreenpage.next = NULL; for (h=hostlistBegin(); (h); h=hostlistNext()) { entry_t *e; int useit = 0; /* * Why don't we use the interesting_column() routine here ? * * Well, because what we are interested in for now is * to determine if this HOST should be included on the page. * * We don't care if individual COLUMNS are included if the * host shows up - some columns are always included, e.g. * the info- and trends-columns, but we don't want that to * trigger a host being on the nongreen page! */ switch (summarytype) { case PAGE_NONGREEN: /* Normal non-green page */ if (h->hostentry->nonongreen || (nongreennodialups && h->hostentry->dialup)) useit = 0; else useit = (( (1 << h->hostentry->nongreencolor) & nongreencolors ) != 0); break; case PAGE_CRITICAL: /* The Critical page */ for (useit=0, e=h->hostentry->entries; (e && !useit); e=e->next) { if (e->alert && !e->acked) { if (e->color == COL_RED) { useit = 1; } else { if (!critonlyreds) { useit = ((e->color == COL_YELLOW) && (strcmp(e->column->name, xgetenv("PINGCOLUMN")) != 0)); } } } } break; } if (useit) { host_t *newhost, *walk; switch (summarytype) { case PAGE_NONGREEN: if (h->hostentry->nongreencolor > nongreenpage.color) nongreenpage.color = h->hostentry->nongreencolor; break; case PAGE_CRITICAL: if (h->hostentry->criticalcolor > nongreenpage.color) nongreenpage.color = h->hostentry->criticalcolor; break; } /* We need to create a copy of the original record, */ /* as we will diddle with the pointers */ newhost = (host_t *) calloc(1, sizeof(host_t)); memcpy(newhost, h->hostentry, sizeof(host_t)); newhost->next = NULL; /* Insert into sorted host list */ if ((!nongreenpage.hosts) || (strcmp(newhost->hostname, nongreenpage.hosts->hostname) < 0)) { /* Empty list, or new entry goes before list head item */ newhost->next = nongreenpage.hosts; nongreenpage.hosts = newhost; } else { /* Walk list until we find element that goes after new item */ for (walk = nongreenpage.hosts; (walk->next && (strcmp(newhost->hostname, ((host_t *)walk->next)->hostname) > 0)); walk = walk->next) ; /* "walk" points to element before the new item. * * Check for duplicate hosts. We can have a host on two normal Xymon * pages, but in the non-green page we want it only once. */ if (strcmp(walk->hostname, newhost->hostname) == 0) { /* Duplicate at start of list */ xfree(newhost); } else if (walk->next && (strcmp(((host_t *)walk->next)->hostname, newhost->hostname) == 0)) { /* Duplicate inside list */ xfree(newhost); } else { /* New host */ newhost->next = walk->next; walk->next = newhost; } } } } switch (summarytype) { case PAGE_NONGREEN: sprintf(filename, "%s%s", filenamebase, htmlextension); sprintf(rssfilename, "%s%s", filenamebase, rssextension); break; case PAGE_CRITICAL: sprintf(filename, "%s%s", filenamebase, htmlextension); sprintf(rssfilename, "%s%s", filenamebase, rssextension); break; } sprintf(tmpfilename, "%s.tmp", filename); output = fopen(tmpfilename, "w"); if (output == NULL) { errprintf("Cannot create file %s: %s\n", tmpfilename, strerror(errno)); return nongreenpage.color; } if (wantrss) { sprintf(tmprssfilename, "%s.tmp", rssfilename); rssoutput = fopen(tmprssfilename, "w"); if (rssoutput == NULL) { errprintf("Cannot create RSS file %s: %s\n", tmpfilename, strerror(errno)); return nongreenpage.color; } } headfoot(output, hf_prefix[summarytype], "", "header", nongreenpage.color); do_rss_header(rssoutput); fprintf(output, "
\n"); fprintf(output, "\n  \n \n"); if (nongreenpage.hosts) { do_hosts(nongreenpage.hosts, 0, NULL, NULL, output, rssoutput, "", summarytype, NULL); } else { /* All Monitored Systems OK */ fprintf(output, "%s", xgetenv("XYMONALLOKTEXT")); } /* Summaries on nongreenpage as well */ do_summaries(dispsums, output); if ((snapshot == 0) && (summarytype == PAGE_NONGREEN)) { do_nongreenext(output, "XYMONNONGREENEXT", "mkbb"); /* Don't redo the eventlog or acklog things */ if (nongreeneventlog && !havedoneeventlog) { do_eventlog(output, nongreeneventlogmaxcount, nongreeneventlogmaxtime, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, nongreennodialups, host_exists, NULL, NULL, NULL, XYMON_COUNT_NONE, XYMON_S_NONE, NULL); } if (nongreenacklog && !havedoneacklog) do_acklog(output, nongreenacklogmaxcount, nongreenacklogmaxtime); } fprintf(output, "
\n"); headfoot(output, hf_prefix[summarytype], "", "footer", nongreenpage.color); do_rss_footer(rssoutput); fclose(output); if (rename(tmpfilename, filename)) { errprintf("Cannot rename %s to %s - error %d\n", tmpfilename, filename, errno); } if (rssoutput) { fclose(rssoutput); if (rename(tmprssfilename, rssfilename)) { errprintf("Cannot rename %s to %s - error %d\n", tmprssfilename, rssfilename, errno); } } if (nssidebarfilename) do_netscape_sidebar(nssidebarfilename, nongreenpage.hosts); if (logcritstatus && (summarytype == PAGE_CRITICAL)) { host_t *hwalk; entry_t *ewalk; char *msgptr; char msgline[MAX_LINE_LEN]; FILE *nklog; char nklogfn[PATH_MAX]; char svcspace; sprintf(nklogfn, "%s/criticalstatus.log", xgetenv("XYMONSERVERLOGS")); nklog = fopen(nklogfn, "a"); if (nklog == NULL) { errprintf("Cannot log Critical status to %s: %s\n", nklogfn, strerror(errno)); } init_timestamp(); combo_start(); init_status(nongreenpage.color); sprintf(msgline, "status %s.%s %s %s Critical page %s\n\n", xgetenv("MACHINE"), logcritstatus, colorname(nongreenpage.color), timestamp, colorname(nongreenpage.color)); addtostatus(msgline); if (nklog) fprintf(nklog, "%u\t%s", (unsigned int)getcurrenttime(NULL), colorname(nongreenpage.color)); for (hwalk = nongreenpage.hosts; hwalk; hwalk = hwalk->next) { msgptr = msgline; msgptr += sprintf(msgline, "&%s %s :", colorname(hwalk->color), hwalk->hostname); if (nklog) fprintf(nklog, "\t%s ", hwalk->hostname); svcspace = '('; for (ewalk = hwalk->entries; (ewalk); ewalk = ewalk->next) { if ((summarytype == PAGE_NONGREEN) || (ewalk->alert)) { if ((ewalk->color == COL_RED) || (ewalk->color == COL_YELLOW)) { msgptr += sprintf(msgptr, "%s", ewalk->column->name); if (nklog) fprintf(nklog, "%c%s:%s", svcspace, ewalk->column->name, colorname(ewalk->color)); svcspace = ' '; } } } strcpy(msgptr, "\n"); addtostatus(msgline); if (nklog) fprintf(nklog, ")"); } finish_status(); combo_end(); if (nklog) { fprintf(nklog, "\n"); fclose(nklog); } } { /* Free temporary hostlist */ host_t *h1, *h2; h1 = nongreenpage.hosts; while (h1) { h2 = h1; h1 = h1->next; xfree(h2); } } return nongreenpage.color; } xymon-4.3.30/xymongen/util.c0000664000076400007640000001400311630612201016156 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Various utility functions specific to xymongen. Generally useful code is */ /* in the library. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: util.c 6746 2011-09-04 06:02:41Z storner $"; #include #include #include #include #include #include #include #include "xymongen.h" #include "util.h" char *htmlextension = ".html"; /* Filename extension for generated HTML files */ static void * hosttree; static int havehosttree = 0; static void * columntree; static int havecolumntree = 0; char *hostpage_link(host_t *host) { /* Provide a link to the page where this host lives, relative to XYMONWEB */ static char pagelink[PATH_MAX]; char tmppath[PATH_MAX]; xymongen_page_t *pgwalk; if (host->parent && (strlen(((xymongen_page_t *)host->parent)->name) > 0)) { sprintf(pagelink, "%s%s", ((xymongen_page_t *)host->parent)->name, htmlextension); for (pgwalk = host->parent; (pgwalk); pgwalk = pgwalk->parent) { if (strlen(pgwalk->name)) { sprintf(tmppath, "%s/%s", pgwalk->name, pagelink); strcpy(pagelink, tmppath); } } } else { sprintf(pagelink, "xymon%s", htmlextension); } return pagelink; } char *hostpage_name(host_t *host) { /* Provide a link to the page where this host lives */ static char pagename[PATH_MAX]; char tmpname[PATH_MAX]; xymongen_page_t *pgwalk; if (host->parent && (strlen(((xymongen_page_t *)host->parent)->name) > 0)) { pagename[0] = '\0'; for (pgwalk = host->parent; (pgwalk); pgwalk = pgwalk->parent) { if (strlen(pgwalk->name)) { strcpy(tmpname, pgwalk->title); if (strlen(pagename)) { strcat(tmpname, "/"); strcat(tmpname, pagename); } strcpy(pagename, tmpname); } } } else { sprintf(pagename, "Top page"); } return pagename; } static int checknopropagation(char *testname, char *noproptests) { if (noproptests == NULL) return 0; if (strcmp(noproptests, ",*,") == 0) return 1; if (strstr(noproptests, testname) != NULL) return 1; return 0; } int checkpropagation(host_t *host, char *test, int color, int acked) { /* NB: Default is to propagate test, i.e. return 1 */ char *testname; int result = 1; if (!host) return 1; testname = (char *) malloc(strlen(test)+3); sprintf(testname, ",%s,", test); if (acked) { if (checknopropagation(testname, host->nopropacktests)) result = 0; } if (result) { if (color == COL_RED) { if (checknopropagation(testname, host->nopropredtests)) result = 0; } else if (color == COL_YELLOW) { if (checknopropagation(testname, host->nopropyellowtests)) result = 0; if (checknopropagation(testname, host->nopropredtests)) result = 0; } else if (color == COL_PURPLE) { if (checknopropagation(testname, host->noproppurpletests)) result = 0; } } xfree(testname); return result; } host_t *find_host(char *hostname) { xtreePos_t handle; if (havehosttree == 0) return NULL; /* Search for the host */ handle = xtreeFind(hosttree, hostname); if (handle != xtreeEnd(hosttree)) { hostlist_t *entry = (hostlist_t *)xtreeData(hosttree, handle); return (entry ? entry->hostentry : NULL); } return NULL; } int host_exists(char *hostname) { return (find_host(hostname) != NULL); } hostlist_t *find_hostlist(char *hostname) { xtreePos_t handle; if (havehosttree == 0) return NULL; /* Search for the host */ handle = xtreeFind(hosttree, hostname); if (handle != xtreeEnd(hosttree)) { hostlist_t *entry = (hostlist_t *)xtreeData(hosttree, handle); return entry; } return NULL; } void add_to_hostlist(hostlist_t *rec) { if (havehosttree == 0) { hosttree = xtreeNew(strcasecmp); havehosttree = 1; } xtreeAdd(hosttree, rec->hostentry->hostname, rec); } static xtreePos_t hostlistwalk; hostlist_t *hostlistBegin(void) { if (havehosttree == 0) return NULL; hostlistwalk = xtreeFirst(hosttree); if (hostlistwalk != xtreeEnd(hosttree)) { return (hostlist_t *)xtreeData(hosttree, hostlistwalk); } else { return NULL; } } hostlist_t *hostlistNext(void) { if (havehosttree == 0) return NULL; if (hostlistwalk != xtreeEnd(hosttree)) hostlistwalk = xtreeNext(hosttree, hostlistwalk); if (hostlistwalk != xtreeEnd(hosttree)) { return (hostlist_t *)xtreeData(hosttree, hostlistwalk); } else { return NULL; } } xymongen_col_t *find_or_create_column(char *testname, int create) { xymongen_col_t *newcol = NULL; xtreePos_t handle; dbgprintf("find_or_create_column(%s)\n", textornull(testname)); if (havecolumntree == 0) { columntree = xtreeNew(strcasecmp); havecolumntree = 1; } handle = xtreeFind(columntree, testname); if (handle != xtreeEnd(columntree)) newcol = (xymongen_col_t *)xtreeData(columntree, handle); if (newcol == NULL) { if (!create) return NULL; newcol = (xymongen_col_t *) calloc(1, sizeof(xymongen_col_t)); newcol->name = strdup(testname); newcol->listname = (char *)malloc(strlen(testname)+1+2); sprintf(newcol->listname, ",%s,", testname); xtreeAdd(columntree, newcol->name, newcol); } return newcol; } int wantedcolumn(char *current, char *wanted) { char *tag; int result; tag = (char *) malloc(strlen(current)+3); sprintf(tag, "|%s|", current); result = (strstr(wanted, tag) != NULL); xfree(tag); return result; } xymon-4.3.30/xymongen/csvreport.h0000664000076400007640000000154211615341300017243 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __CSVREPORT_H__ #define __CSVREPORT_H__ #include "xymongen.h" extern void csv_availability(char *fn, char csvdelim); #endif xymon-4.3.30/xymongen/loaddata.h0000664000076400007640000000206111615341300016762 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOADDATA_H_ #define __LOADDATA_H_ extern int statuscount; extern char *ignorecolumns; extern char *dialupskin; extern char *reverseskin; extern time_t recentgif_limit; extern char *purplelogfn; extern int colorcount[]; extern int colorcount_noprop[]; extern state_t *load_state(dispsummary_t **sumhead); #endif xymon-4.3.30/xymongen/loadlayout.h0000664000076400007640000000273111615341300017372 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __LOADLAYOUT_H__ #define __LOADLAYOUT_H__ extern int hostcount; extern int pagecount; extern xymongen_page_t *load_layout(char *pgset); /* Needed by the summary handling */ extern host_t *init_host(char *hostname, int issummary, char *displayname, char *clientalias, char *comment, char *description, int ip1, int ip2, int ip3, int ip4, int dialup, double warnpct, int warnstops, char *reporttime, char *alerts, int crittime, char *waps, char *nopropyellowtests, char *nopropredtests, char *noproppurpletests, char *nopropacktests); extern char *nopropyellowdefault; extern char *nopropreddefault; extern char *noproppurpledefault; extern char *nopropackdefault; extern char *wapcolumns; extern time_t snapshot; #endif xymon-4.3.30/xymongen/process.c0000664000076400007640000002015412672550115016677 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This file contains to to calculate the "color" of hosts and pages, and */ /* handle summary transmission. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: process.c 7953 2016-03-17 15:42:05Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include #include "xymongen.h" #include "process.h" #include "util.h" void calc_hostcolors(char *nongreenignores) { int color, nongreencolor, criticalcolor, oldage; hostlist_t *h, *cwalk; entry_t *e; for (h = hostlistBegin(); (h); h = hostlistNext()) { color = nongreencolor = criticalcolor = 0; oldage = 1; for (e = h->hostentry->entries; (e); e = e->next) { if (e->propagate && (e->color > color)) color = e->color; oldage &= e->oldage; if (e->propagate && (e->color > nongreencolor) && (strstr(nongreenignores, e->column->listname) == NULL)) { nongreencolor = e->color; } if (e->propagate && e->alert && (e->color > criticalcolor)) { criticalcolor = e->color; } } /* Blue and clear is not propagated upwards */ if ((color == COL_CLEAR) || (color == COL_BLUE)) color = COL_GREEN; h->hostentry->color = color; h->hostentry->nongreencolor = nongreencolor; h->hostentry->criticalcolor = criticalcolor; h->hostentry->oldage = oldage; /* Need to update the clones also */ for (cwalk = h->clones; (cwalk); cwalk = cwalk->clones) { cwalk->hostentry->color = color; cwalk->hostentry->nongreencolor = nongreencolor; cwalk->hostentry->criticalcolor = criticalcolor; cwalk->hostentry->oldage = oldage; } } } void calc_pagecolors(xymongen_page_t *phead) { xymongen_page_t *p, *toppage; group_t *g; host_t *h; int color, oldage; for (toppage=phead; (toppage); toppage = toppage->next) { /* Start with the color of immediate hosts */ color = -1; oldage = 1; for (h = toppage->hosts; (h); h = h->next) { if (h->color > color) color = h->color; oldage &= h->oldage; } /* Then adjust with the color of hosts in immediate groups */ for (g = toppage->groups; (g); g = g->next) { for (h = g->hosts; (h); h = h->next) { if ((g->onlycols == NULL) && (g->exceptcols == NULL)) { /* No group-only or group-except directives - use host color */ if (h->color > color) color = h->color; oldage &= h->oldage; } else if (g->onlycols) { /* This is a group-only directive. Color must be * based on the tests included in the group-only * directive, NOT all tests present for the host. * So we need to re-calculate host color from only * the selected tests. */ entry_t *e; for (e = h->entries; (e); e = e->next) { if ( e->propagate && (e->color > color) && wantedcolumn(e->column->name, g->onlycols) ) color = e->color; oldage &= e->oldage; } /* Blue and clear is not propagated upwards */ if ((color == COL_CLEAR) || (color == COL_BLUE)) color = COL_GREEN; } else if (g->exceptcols) { /* This is a group-except directive. Color must be * based on the tests NOT included in the group-except * directive, NOT all tests present for the host. * So we need to re-calculate host color from only * the selected tests. */ entry_t *e; for (e = h->entries; (e); e = e->next) { if ( e->propagate && (e->color > color) && !wantedcolumn(e->column->name, g->exceptcols) ) color = e->color; oldage &= e->oldage; } /* Blue and clear is not propagated upwards */ if ((color == COL_CLEAR) || (color == COL_BLUE)) color = COL_GREEN; } } } /* Then adjust with the color of subpages, if any. */ /* These must be calculated first! */ if (toppage->subpages) { calc_pagecolors(toppage->subpages); } for (p = toppage->subpages; (p); p = p->next) { if (p->color > color) color = p->color; oldage &= p->oldage; } if (color == -1) { /* * If no hosts or subpages, all goes green. */ color = COL_GREEN; oldage = 1; } toppage->color = color; toppage->oldage = oldage; } } void delete_old_acks(void) { DIR *xymonacks; struct dirent *d; struct stat st; time_t now = getcurrenttime(NULL); char fn[PATH_MAX]; xymonacks = opendir(xgetenv("XYMONACKDIR")); if (!xymonacks) { errprintf("No XYMONACKDIR! Cannot cd to directory %s\n", xgetenv("XYMONACKDIR")); return; } if (chdir(xgetenv("XYMONACKDIR")) == -1) { errprintf("Cannot chdir to %s: %s\n", xgetenv("XYMONACKDIR"), strerror(errno)); return; } while ((d = readdir(xymonacks))) { strcpy(fn, d->d_name); if (strncmp(fn, "ack.", 4) == 0) { stat(fn, &st); if (S_ISREG(st.st_mode) && (st.st_mtime < now)) { unlink(fn); } } } closedir(xymonacks); } void send_summaries(summary_t *sumhead) { summary_t *s; for (s = sumhead; (s); s = s->next) { char *suburl; int summarycolor = -1; char *summsg; /* Decide which page to pick the color from for this summary. */ suburl = s->url; if (strncmp(suburl, "http://", 7) == 0) { char *p; /* Skip hostname part */ suburl += 7; /* Skip "http://" */ p = strchr(suburl, '/'); /* Find next '/' */ if (p) suburl = p; } else if(strncmp(suburl, "https://", 8) == 0) { char *p; /* Skip hostname part */ suburl += 8; /* Skip "https://" */ p = strchr(suburl, '/'); /* Find next '/' */ if (p) suburl = p; } if (strncmp(suburl, xgetenv("XYMONWEB"), strlen(xgetenv("XYMONWEB"))) == 0) suburl += strlen(xgetenv("XYMONWEB")); if (*suburl == '/') suburl++; dbgprintf("summ1: s->url=%s, suburl=%s\n", s->url, suburl); if (strcmp(suburl, "xymon.html") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "index.html") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "") == 0) summarycolor = xymon_color; else if (strcmp(suburl, "nongreen.html") == 0) summarycolor = nongreen_color; else if (strcmp(suburl, "critical.html") == 0) summarycolor = critical_color; else { /* * Specific page - find it in the page tree. */ char *p, *pg; xymongen_page_t *pgwalk; xymongen_page_t *sourcepg = NULL; char *urlcopy = strdup(suburl); /* * Walk the page tree */ pg = urlcopy; sourcepg = pagehead; do { p = strchr(pg, '/'); if (p) *p = '\0'; dbgprintf("Searching for page %s\n", pg); for (pgwalk = sourcepg->subpages; (pgwalk && (strcmp(pgwalk->name, pg) != 0)); pgwalk = pgwalk->next); if (pgwalk != NULL) { sourcepg = pgwalk; if (p) { *p = '/'; pg = p+1; } else pg = NULL; } else pg = NULL; } while (pg); dbgprintf("Summary search for %s found page %s (title:%s), color %d\n", suburl, sourcepg->name, sourcepg->title, sourcepg->color); summarycolor = sourcepg->color; xfree(urlcopy); } if (summarycolor == -1) { errprintf("Could not determine sourcepage for summary %s\n", s->url); summarycolor = pagehead->color; } /* Send the summary message */ summsg = (char *)malloc(1024 + strlen(s->name) + strlen(s->url) + strlen(timestamp)); sprintf(summsg, "summary summary.%s %s %s %s", s->name, colorname(summarycolor), s->url, timestamp); sendmessage(summsg, s->receiver, XYMON_TIMEOUT, NULL); xfree(summsg); } } xymon-4.3.30/xymongen/loadlayout.c0000664000076400007640000006005512003234710017366 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* This file holds code to load the page-structure from the hosts.cfg file. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: loadlayout.c 7105 2012-07-23 11:47:20Z storner $"; #include #include #include #include #include #include #include #include #include #include #include "xymongen.h" #include "util.h" #include "loadlayout.h" #define MAX_TARGETPAGES_PER_HOST 10 time_t snapshot = 0; /* Set if we are doing a snapshot */ char *null_text = ""; /* List definition to search for page records */ typedef struct xymonpagelist_t { struct xymongen_page_t *pageentry; struct xymonpagelist_t *next; } xymonpagelist_t; static xymonpagelist_t *pagelisthead = NULL; int pagecount = 0; int hostcount = 0; char *wapcolumns = NULL; /* Default columns included in WAP cards */ char *nopropyellowdefault = NULL; char *nopropreddefault = NULL; char *noproppurpledefault = NULL; char *nopropackdefault = NULL; void addtopagelist(xymongen_page_t *page) { xymonpagelist_t *newitem; newitem = (xymonpagelist_t *) calloc(1, sizeof(xymonpagelist_t)); newitem->pageentry = page; newitem->next = pagelisthead; pagelisthead = newitem; } char *build_noprop(char *defset, char *specset) { static char result[MAX_LINE_LEN]; char *set; char *item; char ibuf[MAX_LINE_LEN]; char op; char *p; /* It's guaranteed that specset is non-NULL. defset may be NULL */ if ((*specset != '+') && (*specset != '-')) { /* Old-style - specset is the full set of tests */ sprintf(result, ",%s,", specset); return result; } set = strdup(specset); strcpy(result, ((defset != NULL) ? defset : "")); item = strtok(set, ","); while (item) { if ((*item == '-') || (*item == '+')) { op = *item; sprintf(ibuf, ",%s,", item+1); } else { op = '+'; sprintf(ibuf, ",%s,", item); } p = strstr(result, ibuf); if (p && (op == '-')) { /* Remove this item */ memmove(p, (p+strlen(item)), strlen(p)); } else if ((p == NULL) && (op == '+')) { /* Add this item (it's not already included) */ if (strlen(result) == 0) { sprintf(result, ",%s,", item+1); } else { strcat(result, item+1); strcat(result, ","); } } item = strtok(NULL, ","); } xfree(set); return result; /* This may be an empty string */ } xymongen_page_t *init_page(char *name, char *title, int vertical) { xymongen_page_t *newpage = (xymongen_page_t *) calloc(1, sizeof(xymongen_page_t)); pagecount++; dbgprintf("init_page(%s, %s)\n", textornull(name), textornull(title)); if (name) { newpage->name = strdup(name); } else name = null_text; if (title) { newpage->title = strdup(title); }else title = null_text; newpage->color = -1; newpage->oldage = 1; newpage->vertical = vertical; newpage->pretitle = NULL; newpage->groups = NULL; newpage->hosts = NULL; newpage->parent = NULL; newpage->subpages = NULL; newpage->next = NULL; return newpage; } group_t *init_group(char *title, char *onlycols, char *exceptcols, int sorthosts) { group_t *newgroup = (group_t *) calloc(1, sizeof(group_t)); dbgprintf("init_group(%s, %s)\n", textornull(title), textornull(onlycols)); if (title) { newgroup->title = strdup(title); } else title = null_text; if (onlycols) { newgroup->onlycols = (char *) malloc(strlen(onlycols)+3); /* Add a '|' at start and end */ sprintf(newgroup->onlycols, "|%s|", onlycols); } else newgroup->onlycols = NULL; if (exceptcols) { newgroup->exceptcols = (char *) malloc(strlen(exceptcols)+3); /* Add a '|' at start and end */ sprintf(newgroup->exceptcols, "|%s|", exceptcols); } else newgroup->exceptcols = NULL; newgroup->pretitle = NULL; newgroup->hosts = NULL; newgroup->sorthosts = sorthosts; newgroup->next = NULL; return newgroup; } host_t *init_host(char *hostname, int issummary, char *displayname, char *clientalias, char *comment, char *description, int ip1, int ip2, int ip3, int ip4, int dialup, double warnpct, int warnstops, char *reporttime, char *alerts, int crittime, char *waps, char *nopropyellowtests, char *nopropredtests, char *noproppurpletests, char *nopropacktests) { host_t *newhost = (host_t *) calloc(1, sizeof(host_t)); hostlist_t *oldlist; hostcount++; dbgprintf("init_host(%s)\n", textornull(hostname)); newhost->hostname = newhost->displayname = strdup(hostname); if (displayname) newhost->displayname = strdup(displayname); newhost->clientalias = (clientalias ? strdup(clientalias) : NULL); newhost->comment = (comment ? strdup(comment) : NULL); newhost->description = (description ? strdup(description) : NULL); sprintf(newhost->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); newhost->pretitle = NULL; newhost->entries = NULL; newhost->color = -1; newhost->oldage = 1; newhost->dialup = dialup; newhost->reportwarnlevel = warnpct; newhost->reportwarnstops = warnstops; newhost->reporttime = (reporttime ? strdup(reporttime) : NULL); if (alerts && crittime) { newhost->alerts = strdup(alerts); } else { newhost->alerts = NULL; } newhost->anywaps = 0; newhost->wapcolor = -1; /* Wap set is : * - Specific WML: tag * - NK: tag * - --wap=COLUMN cmdline option * - NULL */ if (waps || alerts) { newhost->waps = strdup(waps ? waps : alerts); } else { newhost->waps = wapcolumns; } if (nopropyellowtests) { char *p; p = skipword(nopropyellowtests); if (*p) *p = '\0'; else p = NULL; newhost->nopropyellowtests = strdup(build_noprop(nopropyellowdefault, nopropyellowtests)); if (p) *p = ' '; } else { newhost->nopropyellowtests = nopropyellowdefault; } if (nopropredtests) { char *p; p = skipword(nopropredtests); if (*p) *p = '\0'; else p = NULL; newhost->nopropredtests = strdup(build_noprop(nopropreddefault, nopropredtests)); if (p) *p = ' '; } else { newhost->nopropredtests = nopropreddefault; } if (noproppurpletests) { char *p; p = skipword(noproppurpletests); if (*p) *p = '\0'; else p = NULL; newhost->noproppurpletests = strdup(build_noprop(noproppurpledefault, noproppurpletests)); if (p) *p = ' '; } else { newhost->noproppurpletests = noproppurpledefault; } if (nopropacktests) { char *p; p = skipword(nopropacktests); if (*p) *p = '\0'; else p = NULL; newhost->nopropacktests = strdup(build_noprop(nopropackdefault, nopropacktests)); if (p) *p = ' '; } else { newhost->nopropacktests = nopropackdefault; } newhost->parent = NULL; newhost->nonongreen = 0; newhost->next = NULL; /* Summary hosts don't go into the host list */ if (issummary) return newhost; /* * Add this host to the hostlist_t list of known hosts. * HOWEVER: It might be a duplicate! In that case, we need * to figure out which host record we want to use. */ oldlist = find_hostlist(hostname); if (oldlist == NULL) { hostlist_t *newlist; newlist = (hostlist_t *) calloc(1, sizeof(hostlist_t)); newlist->hostentry = newhost; newlist->clones = NULL; add_to_hostlist(newlist); } else { hostlist_t *clone = (hostlist_t *) calloc(1, sizeof(hostlist_t)); dbgprintf("Duplicate host definition for host '%s'\n", hostname); clone->hostentry = newhost; clone->clones = oldlist->clones; oldlist->clones = clone; } return newhost; } void getnamelink(char *l, char **name, char **link) { /* "page NAME title-or-link" splitup */ char *p; dbgprintf("getnamelink(%s, ...)\n", textornull(l)); *name = null_text; *link = null_text; /* Skip page/subpage keyword, and whitespace after that */ p = skipwhitespace(skipword(l)); *name = p; p = skipword(p); if (*p) { *p = '\0'; /* Null-terminate pagename */ p++; *link = skipwhitespace(p); } } void getparentnamelink(char *l, xymongen_page_t *toppage, xymongen_page_t **parent, char **name, char **link) { /* "subparent NAME PARENTNAME title-or-link" splitup */ char *p; char *parentname; xymonpagelist_t *walk; dbgprintf("getnamelink(%s, ...)\n", textornull(l)); *name = null_text; *link = null_text; /* Skip page/subpage keyword, and whitespace after that */ parentname = p = skipwhitespace(skipword(l)); p = skipword(p); if (*p) { *p = '\0'; /* Null-terminate pagename */ p++; *name = p = skipwhitespace(p); p = skipword(p); if (*p) { *p = '\0'; /* Null-terminate parentname */ p++; *link = skipwhitespace(p); } } for (walk = pagelisthead; (walk && (strcmp(walk->pageentry->name, parentname) != 0)); walk = walk->next) ; if (walk) { *parent = walk->pageentry; } else { errprintf("Cannot find parent page '%s'\n", parentname); *parent = NULL; } } void getgrouptitle(char *l, char *pageset, char **title, char **onlycols, char **exceptcols) { char grouponlytag[100], groupexcepttag[100], grouptag[100]; *title = null_text; *onlycols = NULL; *exceptcols = NULL; sprintf(grouponlytag, "%sgroup-only", pageset); sprintf(groupexcepttag, "%sgroup-except", pageset); sprintf(grouptag, "%sgroup", pageset); dbgprintf("getgrouptitle(%s, ...)\n", textornull(l)); if (strncmp(l, grouponlytag, strlen(grouponlytag)) == 0) { char *p; *onlycols = skipwhitespace(skipword(l)); p = skipword(*onlycols); if (*p) { *p = '\0'; p++; *title = skipwhitespace(p); } } else if (strncmp(l, groupexcepttag, strlen(groupexcepttag)) == 0) { char *p; *exceptcols = skipwhitespace(skipword(l)); p = skipword(*exceptcols); if (*p) { *p = '\0'; p++; *title = skipwhitespace(p); } } else if (strncmp(l, grouptag, strlen(grouptag)) == 0) { *title = skipwhitespace(skipword(l)); } } summary_t *init_summary(char *name, char *receiver, char *url) { summary_t *newsum; dbgprintf("init_summary(%s, %s, %s)\n", textornull(name), textornull(receiver), textornull(url)); /* Sanity check */ if ((name == NULL) || (receiver == NULL) || (url == NULL)) return NULL; newsum = (summary_t *) calloc(1, sizeof(summary_t)); newsum->name = strdup(name); newsum->receiver = strdup(receiver); newsum->url = strdup(url); newsum->next = NULL; return newsum; } xymongen_page_t *load_layout(char *pgset) { char pagetag[100], subpagetag[100], subparenttag[100], vpagetag[100], vsubpagetag[100], vsubparenttag[100], grouptag[100], summarytag[100], titletag[100], hosttag[100]; char *name, *link, *onlycols, *exceptcols; char hostname[MAX_LINE_LEN]; xymongen_page_t *toppage, *curpage, *cursubpage, *cursubparent; group_t *curgroup; host_t *curhost; char *curtitle; int ip1, ip2, ip3, ip4; char *p; int fqdn = get_fqdn(); char *cfgdata, *inbol, *ineol, insavchar = '\0'; if (loadhostsfromxymond) { if (load_hostnames("@", NULL, fqdn) != 0) { errprintf("Cannot load host configuration from xymond\n"); return NULL; } } else { if (load_hostnames(xgetenv("HOSTSCFG"), "dispinclude", fqdn) != 0) { errprintf("Cannot load host configuration from %s\n", xgetenv("HOSTSCFG")); return NULL; } } if (first_host() == NULL) { errprintf("Empty configuration from %s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG"))); return NULL; } dbgprintf("load_layout(pgset=%s)\n", textornull(pgset)); /* * load_hostnames() picks up the hostname definitions, but not the page * layout. So we will scan the file again, this time doing the layout. */ if (pgset == NULL) pgset = ""; sprintf(pagetag, "%spage", pgset); sprintf(subpagetag, "%ssubpage", pgset); sprintf(subparenttag, "%ssubparent", pgset); sprintf(vpagetag, "v%spage", pgset); sprintf(vsubpagetag, "v%ssubpage", pgset); sprintf(vsubparenttag, "v%ssubparent", pgset); sprintf(grouptag, "%sgroup", pgset); sprintf(summarytag, "%ssummary", pgset); sprintf(titletag, "%stitle", pgset); sprintf(hosttag, "%s:", pgset); for (p=hosttag; (*p); p++) *p = toupper((int)*p); toppage = init_page("", "", 0); addtopagelist(toppage); curpage = NULL; cursubpage = NULL; curgroup = NULL; curhost = NULL; cursubparent = NULL; curtitle = NULL; inbol = cfgdata = hostscfg_content(); while (inbol && *inbol) { inbol += strspn(inbol, " \t"); ineol = strchr(inbol, '\n'); if (ineol) { while ((ineol > inbol) && (isspace(*ineol) || (*ineol == '\n'))) ineol--; if (*ineol != '\n') ineol++; insavchar = *ineol; *ineol = '\0'; } dbgprintf("load_layout: -- got line '%s'\n", inbol); if ((strncmp(inbol, pagetag, strlen(pagetag)) == 0) || (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0)) { getnamelink(inbol, &name, &link); if (curpage == NULL) { /* First page - hook it on toppage as a subpage from there */ curpage = toppage->subpages = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0)); } else { curpage = curpage->next = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0)); } curpage->parent = toppage; if (curtitle) { curpage->pretitle = curtitle; curtitle = NULL; } cursubpage = NULL; cursubparent = NULL; curgroup = NULL; curhost = NULL; addtopagelist(curpage); } else if ( (strncmp(inbol, subpagetag, strlen(subpagetag)) == 0) || (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0) ) { if (curpage == NULL) { errprintf("'subpage' ignored, no preceding 'page' tag : %s\n", inbol); goto nextline; } getnamelink(inbol, &name, &link); if (cursubpage == NULL) { cursubpage = curpage->subpages = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0)); } else { cursubpage = cursubpage->next = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0)); } cursubpage->parent = curpage; if (curtitle) { cursubpage->pretitle = curtitle; curtitle = NULL; } cursubparent = NULL; curgroup = NULL; curhost = NULL; addtopagelist(cursubpage); } else if ( (strncmp(inbol, subparenttag, strlen(subparenttag)) == 0) || (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0) ) { xymongen_page_t *parentpage, *walk; getparentnamelink(inbol, toppage, &parentpage, &name, &link); if (parentpage == NULL) { errprintf("'subparent' ignored, unknown parent page: %s\n", inbol); goto nextline; } cursubparent = init_page(name, link, (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0)); if (parentpage->subpages == NULL) { parentpage->subpages = cursubparent; } else { for (walk = parentpage->subpages; (walk->next); (walk = walk->next)) ; walk->next = cursubparent; } if (curtitle) { cursubparent->pretitle = curtitle; curtitle = NULL; } cursubparent->parent = parentpage; curgroup = NULL; curhost = NULL; addtopagelist(cursubparent); } else if (strncmp(inbol, grouptag, strlen(grouptag)) == 0) { int sorthosts = (strstr(inbol, "group-sorted") != NULL); getgrouptitle(inbol, pgset, &link, &onlycols, &exceptcols); if (curgroup == NULL) { curgroup = init_group(link, onlycols, exceptcols, sorthosts); if (cursubparent != NULL) { cursubparent->groups = curgroup; } else if (cursubpage != NULL) { /* We're in a subpage */ cursubpage->groups = curgroup; } else if (curpage != NULL) { /* We're on a main page */ curpage->groups = curgroup; } else { /* We're on the top page */ toppage->groups = curgroup; } } else { curgroup->next = init_group(link, onlycols, exceptcols, sorthosts); curgroup = curgroup->next; } if (curtitle) { curgroup->pretitle = curtitle; curtitle = NULL; } curhost = NULL; } else if (sscanf(inbol, "%3d.%3d.%3d.%3d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { void *xymonhost = NULL; int dialup, nonongreen, crittime = 1; double warnpct = reportwarnlevel; int warnstops = reportwarnstops; char *displayname, *clientalias, *comment, *description; char *alertlist, *onwaplist, *reporttime; char *nopropyellowlist, *nopropredlist, *noproppurplelist, *nopropacklist; char *targetpagelist[MAX_TARGETPAGES_PER_HOST]; int targetpagecount; char *hval; /* Check for ".default." hosts - they are ignored. */ if (*hostname == '.') goto nextline; if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } /* Get the info */ xymonhost = hostinfo(hostname); if (xymonhost == NULL) { errprintf("Confused - hostname '%s' cannot be found. Ignored\n", hostname); goto nextline; } /* Check for no-display hosts - they are ignored. */ /* But only when we're building the default pageset */ if ((strlen(pgset) == 0) && (xmh_item(xymonhost, XMH_FLAG_NODISP) != NULL)) goto nextline; for (targetpagecount=0; (targetpagecount < MAX_TARGETPAGES_PER_HOST); targetpagecount++) targetpagelist[targetpagecount] = NULL; targetpagecount = 0; dialup = (xmh_item(xymonhost, XMH_FLAG_DIALUP) != NULL); nonongreen = (xmh_item(xymonhost, XMH_FLAG_NONONGREEN) != NULL); alertlist = xmh_item(xymonhost, XMH_NK); hval = xmh_item(xymonhost, XMH_NKTIME); if (hval) crittime = within_sla(xmh_item(xymonhost, XMH_HOLIDAYS), hval, 0); onwaplist = xmh_item(xymonhost, XMH_WML); nopropyellowlist = xmh_item(xymonhost, XMH_NOPROPYELLOW); if (nopropyellowlist == NULL) nopropyellowlist = xmh_item(xymonhost, XMH_NOPROP); nopropredlist = xmh_item(xymonhost, XMH_NOPROPRED); noproppurplelist = xmh_item(xymonhost, XMH_NOPROPPURPLE); nopropacklist = xmh_item(xymonhost, XMH_NOPROPACK); displayname = xmh_item(xymonhost, XMH_DISPLAYNAME); comment = xmh_item(xymonhost, XMH_COMMENT); description = xmh_item(xymonhost, XMH_DESCRIPTION); hval = xmh_item(xymonhost, XMH_WARNPCT); if (hval) warnpct = atof(hval); hval = xmh_item(xymonhost, XMH_WARNSTOPS); if (hval) warnstops = atof(hval); reporttime = xmh_item(xymonhost, XMH_REPORTTIME); clientalias = xmh_item(xymonhost, XMH_CLIENTALIAS); if (xymonhost && (strcmp(xmh_item(xymonhost, XMH_HOSTNAME), clientalias) == 0)) clientalias = NULL; if (xymonhost && (strlen(pgset) > 0)) { /* Walk the clone-list and pick up the target pages for this host */ void *cwalk = xymonhost; do { hval = xmh_item_walk(cwalk); while (hval) { if (strncasecmp(hval, hosttag, strlen(hosttag)) == 0) targetpagelist[targetpagecount++] = strdup(hval+strlen(hosttag)); hval = xmh_item_walk(NULL); } cwalk = next_host(cwalk, 1); } while (cwalk && (strcmp(xmh_item(cwalk, XMH_HOSTNAME), xmh_item(xymonhost, XMH_HOSTNAME)) == 0) && (targetpagecount < MAX_TARGETPAGES_PER_HOST) ); /* * HACK: Check if the pageset tag is present at all in the host * entry. If it isn't, then drop this incarnation of the host. * * Without this, the following hosts.cfg file will have the * www.hswn.dk host listed twice on the alternate pageset: * * adminpage nyc NYC * * 127.0.0.1 localhost # bbd http://localhost/ CLIENT:osiris * 172.16.10.2 www.xymon.com # http://www.xymon.com/ ADMIN:nyc ssh noinfo * * page superdome Superdome * 172.16.10.2 www.xymon.com # noconn * */ if (strstr(inbol, hosttag) == NULL) targetpagecount = 0; } if (strlen(pgset) == 0) { /* * Default pageset generated. Put the host into * whatever group or page is current. */ if (curhost == NULL) { curhost = init_host(hostname, 0, displayname, clientalias, comment, description, ip1, ip2, ip3, ip4, dialup, warnpct, warnstops, reporttime, alertlist, crittime, onwaplist, nopropyellowlist, nopropredlist, noproppurplelist, nopropacklist); if (curgroup != NULL) { curgroup->hosts = curhost; } else if (cursubparent != NULL) { cursubparent->hosts = curhost; } else if (cursubpage != NULL) { cursubpage->hosts = curhost; } else if (curpage != NULL) { curpage->hosts = curhost; } else { toppage->hosts = curhost; } } else { curhost = curhost->next = init_host(hostname, 0, displayname, clientalias, comment, description, ip1, ip2, ip3, ip4, dialup, warnpct, warnstops, reporttime, alertlist, crittime, onwaplist, nopropyellowlist,nopropredlist, noproppurplelist, nopropacklist); } curhost->parent = (cursubparent ? cursubparent : (cursubpage ? cursubpage : curpage)); if (curtitle) { curhost->pretitle = curtitle; curtitle = NULL; } curhost->nonongreen = nonongreen; } else if (targetpagecount) { int pgnum; for (pgnum=0; (pgnum < targetpagecount); pgnum++) { char *targetpagename = targetpagelist[pgnum]; char savechar; int wantedgroup = 0; xymonpagelist_t *targetpage = NULL; /* Put the host into the page specified by the PGSET: tag */ p = strchr(targetpagename, ','); if (p) { savechar = *p; *p = '\0'; wantedgroup = atoi(p+1); } else { savechar = '\0'; p = targetpagename + strlen(targetpagename); } /* Find the page */ if (strcmp(targetpagename, "*") == 0) { *targetpagename = '\0'; } for (targetpage = pagelisthead; (targetpage && (strcmp(targetpagename, targetpage->pageentry->name) != 0)); targetpage = targetpage->next) ; *p = savechar; if (targetpage == NULL) { errprintf("Warning: Cannot find any target page named '%s' in set '%s' - dropping host '%s'\n", targetpagename, pgset, hostname); } else { host_t *newhost = init_host(hostname, 0, displayname, clientalias, comment, description, ip1, ip2, ip3, ip4, dialup, warnpct, warnstops, reporttime, alertlist, crittime, onwaplist, nopropyellowlist,nopropredlist, noproppurplelist, nopropacklist); if (wantedgroup > 0) { group_t *gwalk; host_t *hwalk; int i; for (gwalk = targetpage->pageentry->groups, i=1; (gwalk && (i < wantedgroup)); i++,gwalk=gwalk->next) ; if (gwalk) { if (gwalk->hosts == NULL) gwalk->hosts = newhost; else { for (hwalk = gwalk->hosts; (hwalk->next); hwalk = hwalk->next) ; hwalk->next = newhost; } } else { errprintf("Warning: Cannot find group %d for host %s - dropping host\n", wantedgroup, hostname); } } else { /* Just put in on the page's hostlist */ host_t *walk; if (targetpage->pageentry->hosts == NULL) targetpage->pageentry->hosts = newhost; else { for (walk = targetpage->pageentry->hosts; (walk->next); walk = walk->next) ; walk->next = newhost; } } newhost->parent = targetpage->pageentry; if (curtitle) newhost->pretitle = curtitle; } curtitle = NULL; } } } else if (strncmp(inbol, summarytag, strlen(summarytag)) == 0) { /* summary row.column IP-ADDRESS-OF-PARENT http://xymon.com/ */ char sumname[MAX_LINE_LEN]; char receiver[MAX_LINE_LEN]; char url[MAX_LINE_LEN]; summary_t *newsum; if (sscanf(inbol, "summary %s %s %s", sumname, receiver, url) == 3) { newsum = init_summary(sumname, receiver, url); newsum->next = sumhead; sumhead = newsum; } } else if (strncmp(inbol, titletag, strlen(titletag)) == 0) { /* Save the title for the next entry */ curtitle = strdup(skipwhitespace(skipword(inbol))); } nextline: if (ineol) { *ineol = insavchar; if (*ineol != '\n') ineol = strchr(ineol, '\n'); inbol = (ineol ? ineol+1 : NULL); } else inbol = NULL; } xfree(cfgdata); return toppage; } xymon-4.3.30/xymongen/debug.c0000664000076400007640000000676411615341300016310 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon overview webpage generator tool. */ /* */ /* Debugging code for dumping various data in xymongen. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: debug.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include "xymongen.h" #include "util.h" void dumphosts(host_t *head, char *prefix) { host_t *h; entry_t *e; char format[512]; strcpy(format, prefix); strcat(format, "Host: %s, ip: %s, name: %s, color: %d, old: %d, anywaps: %d, wapcolor: %d, pretitle: '%s', noprop-y: %s, noprop-r: %s, noprop-p: %s, noprop-ack: %s, waps: %s\n"); for (h = head; (h); h = h->next) { printf(format, h->hostname, h->ip, textornull(h->displayname), h->color, h->oldage, h->anywaps, h->wapcolor, textornull(h->pretitle), textornull(h->nopropyellowtests), textornull(h->nopropredtests), textornull(h->noproppurpletests), textornull(h->nopropacktests), textornull(h->waps)); for (e = h->entries; (e); e = e->next) { printf("\t\t\t\t\tTest: %s, alert %d, propagate %d, state %d, age: %s, oldage: %d\n", e->column->name, e->alert, e->propagate, e->color, e->age, e->oldage); } } } void dumpgroups(group_t *head, char *prefix, char *hostprefix) { group_t *g; char format[512]; strcpy(format, prefix); strcat(format, "Group: %s, pretitle: '%s'\n"); for (g = head; (g); g = g->next) { printf(format, textornull(g->title), textornull(g->pretitle)); dumphosts(g->hosts, hostprefix); } } void dumphostlist(hostlist_t *head) { hostlist_t *h; for (h=hostlistBegin(); (h); h=hostlistNext()) { printf("Hostlist entry: Hostname %s\n", h->hostentry->hostname); } } void dumpstatelist(state_t *head) { state_t *s; for (s=head; (s); s=s->next) { printf("test:%s, state: %d, alert: %d, propagate: %d, oldage: %d, age: %s\n", s->entry->column->name, s->entry->color, s->entry->alert, s->entry->propagate, s->entry->oldage, s->entry->age); } } void dumponepagewithsubs(xymongen_page_t *curpage, char *indent) { xymongen_page_t *levelpage; char newindent[100]; char newindentextra[105]; strcpy(newindent, indent); strcat(newindent, "\t"); strcpy(newindentextra, newindent); strcat(newindentextra, " "); for (levelpage = curpage; (levelpage); levelpage = levelpage->next) { printf("%sPage: %s, color=%d, oldage=%d, title=%s, pretitle=%s\n", indent, levelpage->name, levelpage->color, levelpage->oldage, textornull(levelpage->title), textornull(levelpage->pretitle)); dumpgroups(levelpage->groups, newindent, newindentextra); dumphosts(levelpage->hosts, newindentextra); dumponepagewithsubs(levelpage->subpages, newindent); } } void dumpall(xymongen_page_t *head) { dumponepagewithsubs(head, ""); } xymon-4.3.30/xymongen/wmlgen.h0000664000076400007640000000152011615341300016501 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon WML generator. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ #ifndef __WMLGEN_H__ #define __WMLGEN_H__ extern int enable_wmlgen; extern void do_wml_cards(char *webdir); #endif xymon-4.3.30/xymongen/Makefile0000664000076400007640000000255412050700262016507 0ustar rpmbuildrpmbuild# Makefile for xymongen # PROGRAMS = xymongen GENOBJS = xymongen.o loadlayout.o loaddata.o pagegen.o process.o wmlgen.o rssgen.o util.o debug.o csvreport.o XYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(ZLIBLIBS) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) all: $(PROGRAMS) xymongen: $(GENOBJS) $(XYMONTIMELIB) $(XYMONCOMMLIB) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(GENOBJS) $(XYMONTIMELIBS) $(XYMONCOMMLIBS) $(PCRELIBS) ################################################ # Default compilation rules ################################################ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f *.o *.a *~ $(PROGRAMS) install: install-bin install-man install-bin: $(PROGRAMS) ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ install-man: ifndef PKGBUILD chown $(XYMONUSER) *.1 chgrp `$(IDTOOL) -g $(XYMONUSER)` *.1 chmod 644 *.1 endif mkdir -p $(INSTALLROOT)$(MANROOT)/man1 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man1 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man1 chmod 755 $(INSTALLROOT)$(MANROOT)/man1 endif cp -fp *.1 $(INSTALLROOT)$(MANROOT)/man1/ xymon-4.3.30/README.CLIENT0000664000076400007640000001164411535462534015056 0ustar rpmbuildrpmbuildUnix client for Xymon ====================== As of version 4.1, Xymon ships with a native client for most Unix-based systems. The Xymon client will generate status columns for: * cpu : CPU utilisation * disk : Filesystem (disk) utilisation * files : File- and directory attributes and sizes * memory : Memory and Swap utilisation * msgs : Log file messages * ports : TCP/IP Network connections * procs : Processes It will also feed data to generate some graphs: * ifstat : Raw traffic data for network interfaces * netstat: TCP/IP statistics * vmstat : Various performance counters (OS-specific) In the default setup, all configuration of disk thresholds, load limits, which processes to monitor etc. is done on the Xymon server, NOT on the client. This is to allow centralized configuration of the monitored systems. If you prefer to have the client configuration done locally on each of the systems you monitor, this is an option when building the client. It is possible to have a mix of systems, with some systems configured locally, and others that use the central configuration. Note: The locally-configured client requires the PCRE libraries to be installed on the client host. The Xymon client is released under the GNU GPL, version 2 or later. See the file COPYING for details. Installation ============ Building the client package requires a working C compiler and GNU make on the target platform. None of the extra libraries needed for building Xymon are used by the client - so a plain C compiler installation with GNU make is all that is needed. To build the client: - create a "xymon" userid on the system (not required, but recommended). - extract the Xymon source archive - cd to the xymon-X.X directory - run "./configure --client; make" - as root, run "make install" The client installation is kept entirely within the "xymon" users' home-directory. All client-related files are in the ~xymon/client/ directory. If convenient, this directory can be copied directly to other systems of the same type, so you need not build the client from source on all systems. Running it ========== To start the client, su to the "xymon" user, then run $HOME/client/runclient.sh start You should arrange for your boot-time scripts to run this command at startup. Client configuration ==================== All of the normal configuration is done on the Xymon SERVER. See the analysis.cfg(5) and client-local.cfg(5) man- pages on the Xymon server. Hostname detection ------------------ The client reports to Xymon using the hostname taken from the "uname -n" command output. Whether this provides a fully qualified DNS name (myserver.foo.com) or a simple hostname (myserver) varies a lot. If your client gets it wrong, you can override the default with the "--hostname=CLIENT.HOST.NAME" option to the runclient.sh startup command. OS detection on Linux systems ----------------------------- The client normally determines the operating system auto- matically from the "uname -s" output. This results in all Linux systems reporting as "Linux" - which causes the vmstat graphs to fail for certain types of systems: - Systems running Linux kernels 2.2.x (e.g. Debian Woody) Must report "linux22" instead. - Red Hat Enterprise Linux 2.1 Must report "linux22" instead. - Red Hat Enterprise Linux 3 update 1 The default is adequate - Red Hat Enterprise Linux 3 update 2 or later Must report "rhel3" instead. - Red Hat Enterprise Linux 4 update 2 and later The default is adequate To override the default, start the client using the "--os=OSNAME" option to the runclient.sh startup command. (Thanks to Thomas Seglard Enata for providing the about the various Red Hat versions). Extension scripts ----------------- The file client/etc/clientlaunch.cfg configures the "xymonlaunch" used to run the client scripts. If you need to run extension scripts for your client, you can add them to this file. The environment variables commonly used by Big Brother-based extensions are made available by xymonlaunch for the scripts, so in most cases extensions written for the Big Brother client will work without modifications on Xymon. Each script should have a separate section in the file, like the default one that runs the core client: [myextension] ENVFILE /usr/lib/xymon/client/etc/xymonclient.cfg CMD /usr/lib/xymon/client/ext/myscript.sh INTERVAL 5m LOGFILE /usr/lib/xymon/client/logs/myscript.log See the tasks.cfg(5) man-page for a full description of this file. Installing on multiple systems ============================== After building and installing the client on one system, you can copy the client installation to other systems. You need only copy the directory structure with the "client" directory. The client does not have any hardcoded file- or directory-paths embedded in it, so you can put the client files anywhere you like, as long as you preserve the directory structure below the "client" directory. Henrik Stoerner, 2006-Apr-23 xymon-4.3.30/README.backfeed0000664000076400007640000000655312174443430015621 0ustar rpmbuildrpmbuildEnabling the "backfeed" channel on the Xymon server =================================================== Background ---------- Traditionally, all communication between modules on the Xymon server uses a TCP connection to xymond. This is a simple standardized way of talking to the daemon, e.g. to send status updates from xymond_client or xymonnet into the xymond daemon. However, a TCP connection also carries quite a bit of overhead. On a server with a very high load of messages this can be a problem - empirical evidence shows that the limit appears to be around 3300 messages/second. Solution -------- To solve this, an alternative interface has been implemented using the standard SysV IPC "message queue" interface. This is a POSIX standard, and other parts of SysV IPC is already used by Xymon. Operating system configuration ------------------------------ Unfortunately, most systems have default settings for the message queue parameters MSGMNB (total # of bytes allowed in the queue) and MSGMAX (maximum size of a single mssage) settings. E.g. on Linux, defaults for these are 16 kB and 8 Kb, respectively. Since Xymon by default permits status messages of up to 256 kB in size, these settings are inadequate. On Linux, you change the settings via the "sysctl" utility. Most Linux systems have these settings defined in /etc/sysctl.conf, so you add these parameters: kernel.msgmax=262144 kernel.msgmnb=1048576 The "msgmax" setting should match your MAXMSG_STATUS setting in xymonserver.cfg, converted to bytes (MAXMSG_STATUS is in kB, so you must multiply it by 1024 for the kernel.msgmax value). "msgmnb" should be 4 times the msgmax setting. After setting these, either run "sysctl -f /etc/sysctl.conf" or reboot the server to enable the new settings. For other systems, please refer to your OS documentation. Enabling the backfeed queue --------------------------- The backfeed queue is disabled by default. To enable it, add the "--bfq" option to xymond (in your tasks.cfg) and restart Xymon. You can verify that this has been enabled by checking the output from "ipcs -q" - you should see a line with a message queue owned by the Xymon userid: ------ Message Queues -------- key msqid owner perms used-bytes messages 0x0a01205e 98305 xymon 666 0 0 Using the backfeed queue ------------------------ xymond_client and xymonnet will automatically use the backfeed queue, if available. If you have custom scripts or tools running on the Xymon server, then you can send messages into the queue using the standard "xymon" utility. To do so, set the recipient to "0". E.g. xymon 0 "status localhost.test green" will send a status update via the backfeed queue. NOTE: The backfeed queue is "one-way", so it can only be used for "status", "data", "drop" and "rename" messages - i.e., any message where xymond does not return a response. Checking if the queue is used ----------------------------- The "xymond" status page includes statistics on the kinds of messages received by xymond. If the backfeed queue is used, you should see the number reported in the "backfeed messages" line increase. You can also query xymond for "senderstats": This lists the number of connections to xymond from each IP-address. The backfeed queue shows up as IP "0.0.0.0": $ xymon 127.0.0.1 "senderstats" 0.0.0.0 1360796 127.0.0.1 1648 10.0.31.155 1397281 xymon-4.3.30/configure0000775000076400007640000000125312411753520015113 0ustar rpmbuildrpmbuild#!/bin/sh # Configuration script for Xymon. # $Id: configure 7474 2014-09-28 09:39:28Z storner $ BASEDIR="`dirname $0`" TARGET="$1" if test "$TARGET" != ""; then shift; fi # Make sure that all shell-scripts are executable. # Subversion has a habit of exporting without the # execute-bit set. chmod 755 $BASEDIR/configure* $BASEDIR/build/*.sh $BASEDIR/client/*.sh case "$TARGET" in "--client") exec $BASEDIR/configure.client $* ;; "--server"|"") exec $BASEDIR/configure.server $* ;; "--help") echo "To configure a Xymon server: $0 --server" echo "To configure a Xymon client: $0 --client" ;; *) echo "unrecognized $0 target $TARGET" exit 1 ;; esac exit 0 xymon-4.3.30/common/0000775000076400007640000000000013534041774014503 5ustar rpmbuildrpmbuildxymon-4.3.30/common/xymongrep.c0000664000076400007640000002055412611263210016667 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon hosts.cfg file grep'er */ /* */ /* This tool will pick out the hosts from a hosts.cfg file that has one of */ /* the tags given on the command line. This allows an extension script to */ /* deal with only the relevant parts of the hosts.cfg file, instead of */ /* having to parse the entire file. */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymongrep.c 7706 2015-10-19 21:54:16Z jccleaver $"; #include #include #include #include #include "version.h" #include "libxymon.h" static char *connstatus = NULL; static char *teststatus = NULL; static char *conncolumn = "conn"; static char *testcolumn = NULL; static void load_hoststatus() { int res; char msg[1024]; sendreturn_t *sres; sprintf(msg, "xymondboard fields=hostname,testname,color test=%s", conncolumn); sres = newsendreturnbuf(1, NULL); res = sendmessage(msg, NULL, XYMON_TIMEOUT, sres); if (res == XYMONSEND_OK) connstatus = getsendreturnstr(sres, 1); if ((res == XYMONSEND_OK) && testcolumn) { sprintf(msg, "xymondboard fields=hostname,testname,color test=%s", testcolumn); res = sendmessage(msg, NULL, XYMON_TIMEOUT, sres); if (res == XYMONSEND_OK) teststatus = getsendreturnstr(sres, 1); } if (res != XYMONSEND_OK) { errprintf("Cannot fetch Xymon status, ignoring --no-down\n"); connstatus = NULL; teststatus = NULL; } freesendreturnbuf(sres); } static int netok(char *netstring, char *curnet, int testuntagged) { return ( (netstring == NULL) || (curnet && netstring && (strcmp(curnet, netstring) == 0)) || (testuntagged && (curnet == NULL)) ); } static int downok(char *hostname, int nodownhosts) { char *mark, *colorstr; int color; if (!nodownhosts) return 1; /* Check if the host is down (i.e. "conn" test is non-green) */ if (!connstatus) return 1; mark = (char *)malloc(strlen(hostname) + strlen(conncolumn) + 4); sprintf(mark, "\n%s|%s|", hostname, conncolumn); colorstr = strstr(connstatus, mark); if (colorstr) { colorstr += strlen(mark); /* Skip to the color data */ } else if (strncmp(connstatus, mark+1, strlen(mark+1)) == 0) { colorstr = connstatus + strlen(mark+1); /* First entry we get */ } xfree(mark); color = (colorstr ? parse_color(colorstr) : COL_GREEN); if ((color == COL_RED) || (color == COL_BLUE)) return 0; /* Check if the test is currently disabled */ if (!teststatus) return 1; mark = (char *)malloc(strlen(hostname) + strlen(testcolumn) + 4); sprintf(mark, "\n%s|%s|", hostname, testcolumn); colorstr = strstr(teststatus, mark); if (colorstr) { colorstr += strlen(mark); /* Skip to the color data */ } else if (strncmp(teststatus, mark+1, strlen(mark+1)) == 0) { colorstr = teststatus + strlen(mark+1); /* First entry we get */ } xfree(mark); color = (colorstr ? parse_color(colorstr) : COL_GREEN); if ((color == COL_RED) || (color == COL_BLUE)) return 0; return 1; } int main(int argc, char *argv[]) { void *hwalk; char *hostsfn = NULL; char *netstring = NULL; char *include2 = NULL; int extras = 1; int testuntagged = 0; int nodownhosts = 0; int loadhostsfromxymond = 0; int onlypreferredentry = 0; char *p; char **lookv; int argi, lookc; strbuffer_t *wantedtags; lookv = (char **)malloc(argc*sizeof(char *)); lookc = 0; conncolumn = xgetenv("PINGCOLUMN"); for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { char *delim = strchr(argv[argi], '='); debug = 1; if (delim) set_debugfile(delim+1, 0); } else if (strcmp(argv[argi], "--help") == 0) { printf("Usage:\n%s [options] test1 [test2] [test3] ... \n", argv[0]); exit(1); } else if (strcmp(argv[argi], "--noextras") == 0) { extras = 0; } else if (strcmp(argv[argi], "--test-untagged") == 0) { testuntagged = 1; } else if (argnmatch(argv[argi], "--no-down")) { char *p; nodownhosts = 1; p = strchr(argv[argi], '='); if (p) testcolumn = strdup(p+1); } else if (strcmp(argv[argi], "--version") == 0) { printf("xymongrep version %s\n", VERSION); exit(0); } else if ((strcmp(argv[argi], "--net") == 0) || (strcmp(argv[argi], "--bbnet") == 0)) { include2 = "netinclude"; onlypreferredentry = 0; } else if ((strcmp(argv[argi], "--web") == 0) || (strcmp(argv[argi], "--bbdisp") == 0)) { include2 = "dispinclude"; onlypreferredentry = 1; } else if (argnmatch(argv[argi], "--hosts=")) { hostsfn = strchr(argv[argi], '=') + 1; } else if (strcmp(argv[argi], "--loadhostsfromxymond") == 0) { loadhostsfromxymond = 1; } else if ((*(argv[argi]) == '-') && (strlen(argv[argi]) > 1)) { fprintf(stderr, "Unknown option %s\n", argv[argi]); } else { lookv[lookc] = strdup(argv[argi]); lookc++; } } lookv[lookc] = NULL; if ((hostsfn == NULL) || (strlen(hostsfn) == 0)) { hostsfn = strdup(xgetenv("HOSTSCFG")); if (!loadhostsfromxymond) { /* The default in load_hostnames is to try xymond first when */ /* hostsfn = xgetenv("HOSTSCFG"), however we don't want that here */ /* unless we're told to explicitly. Thus, copy xymond logic here. */ hostsfn = (char *)realloc(hostsfn, strlen(hostsfn) + 2); memmove(hostsfn+1, hostsfn, strlen(hostsfn)+1); *hostsfn = '!'; } } dbgprintf("Loading host configuration from %s%s\n", (loadhostsfromxymond ? "xymond, failing back to " : ""), hostsfn); load_hostnames(hostsfn, include2, get_fqdn()); if (first_host() == NULL) { errprintf("Cannot load %s, or file is empty\n", hostsfn); exit(3); } /* If we must avoid downed or disabled hosts, let's find out what those are */ if (nodownhosts) load_hoststatus(); /* Each network test tagged with NET:locationname */ p = xgetenv("XYMONNETWORK"); if ((p == NULL) || (strlen(p) == 0)) p = xgetenv("BBLOCATION"); if (p && strlen(p)) netstring = strdup(p); hwalk = first_host(); wantedtags = newstrbuffer(0); while (hwalk) { char hostip[IP_ADDR_STRLEN]; char *curnet = xmh_item(hwalk, XMH_NET); char *curname = xmh_item(hwalk, XMH_HOSTNAME); /* * Only look at the hosts whose NET: definition matches the wanted one. * Must also check if the host is currently down (not responding to ping). * And if the host is OK with knownhost(), because it may be time-limited. */ if (netok(netstring, curnet, testuntagged) && downok(curname, nodownhosts) && knownhost(curname, hostip, GH_IGNORE)) { char *item; clearstrbuffer(wantedtags); for (item = xmh_item_walk(hwalk); (item); item = xmh_item_walk(NULL)) { int i; char *realitem = item + strspn(item, "!~?"); for (i=0; lookv[i]; i++) { char *outitem = NULL; if (lookv[i][strlen(lookv[i])-1] == '*') { if (strncasecmp(realitem, lookv[i], strlen(lookv[i])-1) == 0) { outitem = (extras ? item : realitem); } } else if (strcasecmp(realitem, lookv[i]) == 0) { outitem = (extras ? item : realitem); } if (outitem) { int needquotes = ((strchr(outitem, ' ') != NULL) || (strchr(outitem, '\t') != NULL)); addtobuffer(wantedtags, " "); if (needquotes) addtobuffer(wantedtags, "\""); addtobuffer(wantedtags, outitem); if (needquotes) addtobuffer(wantedtags, "\""); } } } if (STRBUF(wantedtags) && (*STRBUF(wantedtags) != '\0') && extras) { if (xmh_item(hwalk, XMH_FLAG_DIALUP)) addtobuffer(wantedtags, " dialup"); if (xmh_item(hwalk, XMH_FLAG_TESTIP)) addtobuffer(wantedtags, " testip"); } if (STRBUF(wantedtags) && *STRBUF(wantedtags)) { printf("%s %s #%s\n", xmh_item(hwalk, XMH_IP), xmh_item(hwalk, XMH_HOSTNAME), STRBUF(wantedtags)); } } do { hwalk = next_host(hwalk, 1); } while (hwalk && onlypreferredentry && (strcmp(curname, xmh_item(hwalk, XMH_HOSTNAME)) == 0)); } return 0; } xymon-4.3.30/common/xymonlaunch.80000664000076400007640000000552413534041733017142 0ustar rpmbuildrpmbuild.TH XYMONLAUNCH 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonlaunch \- Master program to launch other Xymon programs .SH SYNOPSIS .B "xymonlaunch [options]" .SH DESCRIPTION .I xymonlaunch(8) is the main program that controls the execution and scheduling of all of the components in the Xymon system. xymonlaunch allows the administrator to add, remove or change the set of Xymon applications and extensions without restarting Xymon - xymonlaunch will automatically notice any changes in the set of tasks, and change the scheduling of activities accordingly. xymonlaunch also allows the administrator to setup specific logfiles for each component of the Xymon system, instead of getting output from all components logged to a single file. .SH OPTIONS .IP "--env=FILENAME" Loads the environment from FILENAME before starting other tools. The environment defined by FILENAME is the default, it can be overridden by the ENVFILE option in .I tasks.cfg(5) .IP "--config=FILENAME" This option defines the file that xymonlaunch scans for tasks it must launch. A description of this file is in .I tasks.cfg(5) If not specified, files at /etc/tasks.cfg, /etc/xymon/tasks.cfg, and /etc/xymon-client/clientlaunch.cfg are searched for, as well as ~/server/etc/tasks.cfg. .IP "--log=FILENAME" Defines the logfile where xymonlaunch logs information about failures to launch tasks and other data about the operation of xymonlaunch. Logs from individual tasks are defined in the tasks.cfg file. By default this is logged to stdout. .IP "--pidfile=FILENAME" Filename which xymonlaunch saves its own process-ID to. Commonly used by automated start/stop scripts. .IP "--verbose" Logs the launch of all tasks to the logfile. Note that the logfile may become quite large if you enable this. .IP "--dump" Just dump the contents of the tasks.cfg file after parsing it. Used for debugging. .IP "--debug" Enable debugging output while running. .IP "--no-daemon" xymonlaunch normally detaches from the controlling tty and runs as a background task. This option keeps it running in the foreground. .SH STARTING TASKS xymonlaunch will read the configuration file and start all of the tasks listed there. If a task completes abnormally (i.e. terminated by a signal or with a non-zero exit status), then xymonlaunch will attempt to restart it 5 times. If it still will not run, then the task is disabled for 10 minutes. This will be logged to the xymonlaunch logfile. If the configuration file changes, xymonlaunch will re-read it and notice any changes. If a running task was removed from the configuration, then the task is stopped. If a new task was added, it will be started. If the command used for a task changed, or it was given a new environment definition file, or the logfile was changed, then the task is stopped and restarted with the new definition. .SH "SEE ALSO" tasks.cfg(5), xymon(7) xymon-4.3.30/common/xymondigest.10000664000076400007640000000232213534041733017131 0ustar rpmbuildrpmbuild.TH XYMONDIGEST 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymondigest \- calculate message digests .SH SYNOPSIS .B "xymondigest md5|sha1|sha256|sha512|sha224|sha384|rmd160 [filename]" .SH DESCRIPTION .I xymondigest(1) is a utility to calculate message digests for a file or document. It is used when defining HTTP- or FTP-based content checks, where .I xymonnet(1) checks that a URL returns a specific document; instead of having to compare the entire document, the comparison is done against a pre-computed message digest value using the MD5, RIPEMD160, SHA1 or any of the SHA2 (SHA-512, SHA-256, SHA-384, SHA-224) message digest algorithms. The optional \fBfilename\fR parameter is the input file whose message digest should be calculated; if no filename is given, the data is read from standard input. xymondigest outputs a string containing the digest algorithm and the computed message digest. This is in a format suitable for use in the .I hosts.cfg(5) definition of a content check. .SH EXAMPLE $ xymondigest md5 index.html md5:88b81b110a85c83db56a939caa2e2cf6 $ curl \-s http://www.foo.com/ | xymondigest sha1 sha1:e5c69784cb971680e2c7380138e04021a20a45a2 .SH "SEE ALSO" xymonnet(1), hosts.cfg(5) xymon-4.3.30/common/xymongrep.10000664000076400007640000001061613534041733016614 0ustar rpmbuildrpmbuild.TH XYMONGREP 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymongrep \- pick out lines in hosts.cfg .SH SYNOPSIS .B "xymongrep \-\-help" .br .B "xymongrep \-\-version" .br .B "xymongrep [\-\-noextras] [\-\-test\-untagged] [\-\-web] [\-\-net] [\-\-loadhostsfromxymond] TAG [TAG...]" .SH DESCRIPTION .I xymongrep(1) is for use by extension scripts that need to pick out the entries in a hosts.cfg file that are relevant to the script. The utility accepts test names as parameters, and will then parse the hosts.cfg file and print out the host entries that have at least one of the wanted tests specified. Tags may be given with a trailing asterisk '*', e.g. "xymongrep http*" is needed to find all http and https tags. The xymongrep utility supports the use of "include" directives inside the hosts.cfg file, and will find matching tags in all included files. If the DOWNTIME or SLA tags are used in the .I hosts.cfg(5) file, these are interpreted relative to the current time. xymongrep then outputs a "INSIDESLA" or "OUTSIDESLA" tag for easier use by scripts that want to check if the current time is inside or outside the expected uptime window. .SH OPTIONS .IP "\-\-noextras" Remove the "testip", "dialup", "INSIDESLA" and "OUTSIDESLA" tags from the output. .IP "\-\-test\-untagged" When using the XYMONNETWORK environment variable to test only hosts on a particular network segment, xymonnet will ignore hosts that do not have any "NET:x" tag. So only hosts that have a NET:$XYMONNETWORK tag will be tested. .br With this option, hosts with no NET: tag are included in the test, so that all hosts that either have a matching NET: tag, or no NET: tag at all are tested. .IP "\-\-no\-down[=TESTNAME]" xymongrep will query the Xymon server for the current status of the "conn" test, and if TESTNAME is specified also for the current state of the specified test. If the status of the "conn" test for a host is non-green, or the status of the TESTNAME test is disabled, then this host is ignored and will not be included in the output. This can be used to ignore hosts that are down, or hosts where the custom test is disabled. .IP "\-\-web" Search the hosts.cfg file following include statements as a Xymon web-server would. .IP "\-\-net" Search the hosts.cfg file following include statements as when running xymonnet. .IP "\-\-loadhostsfromxymond" xymongrep will normally attempt to load the HOSTSCFG file by itself when searching for lines to transmit. If the file is unreadable, it will exit out. With this option, it will query the xymond server (set via the XYMONSERVER environment) for the hosts file. This can be used if you're running this on a client or remote system and can't or don't want to have the hosts.cfg file synchronized across your servers. .SH EXAMPLE If your hosts.cfg file looks like this 192.168.1.1 www.test.com # ftp telnet !oracle 192.168.1.2 db1.test.com # oracle 192.168.1.3 mail.test.com # smtp and you have a custom Xymon extension script that performs the "oracle" test, then running "xymongrep oracle" would yield 192.168.1.1 www.test.com # !oracle 192.168.1.2 db1.test.com # oracle so the script can quickly find the hosts that are of interest. Note that the reverse-test modifier - "!oracle" - is included in the output; this also applies to the other test modifiers defined by Xymon (the dial-up and always-true modifiers). If your extension scripts use more than one tag, just list all of the interesting tags on the command line. xymongrep also supports the "NET:location" tag used by xymonnet, so if your script performs network checks then it will see only the hosts that are relevant for the test location that the script currently executes on. .SH USE IN EXTENSION SCRIPTS To integrate xymongrep into an existing script, look for the line in the script that grep's in the $HOSTSCFG file. Typically it will look somewhat like this: $GREP \-i "^[0\-9].*#.*TESTNAME" $HOSTSCFG | ... code to handle test Instead of the grep, we will use xymongrep. It then becomes $XYMONHOME/bin/xymongrep TESTNAME | ... code to handle test which is simpler, less error-prone and more efficient. .SH ENVIRONMENT VARIABLES .IP XYMONNETWORK If set, xymongrep outputs only lines from hosts.cfg that have a matching NET:$XYMONNETWORK setting. .sp .IP HOSTSCFG Filename for the Xymon .I hosts.cfg(5) file. .SH FILES .IP $HOSTSCFG The Xymon hosts.cfg file .SH "SEE ALSO" hosts.cfg(5), xymonserver.cfg(5) xymon-4.3.30/common/logfetch.10000664000076400007640000000563113534041732016357 0ustar rpmbuildrpmbuild.TH LOGFETCH 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME logfetch \- Xymon client data collector .SH SYNOPSIS .B "logfetch [options] CONFIGFILE STATUSFILE" .SH DESCRIPTION \fBlogfetch\fR is part of the Xymon client. It is responsible for collecting data from logfiles, and other file-related data, which is then sent to the Xymon server for analysis. logfetch uses a configuration file, which is automatically retrieved from the Xymon server. There is no configuration done locally. The configuration file is usually stored in the \fB$XYMONHOME/tmp/logfetch.cfg\fR file, but editing this file has no effect since it is re-written with data from the Xymon server each time the client runs. logfetch stores information about what parts of the monitored logfiles have been processed already in the \fB$XYMONHOME/tmp/logfetch.status\fR file. This file is an internal file used by logfetch, and should not be edited. If deleted, it will be re-created automatically. .SH OPTIONS .IP "\-\-debug[=stderr]" Enables debug mode. Note that when run by the xymonclient, debug output may be written into the client data report, which can cause false positives and other unintended side effects. Use '=stderr' to cause the output to be written to stderr instead. .IP "\-\-noexec" The client-local.cfg(5) section for this host, class, or OS is automatically retrieved from the server during client submission. Logfetch can be requested to execute arbitrary commands to generate a list of log files to examine dynamically, but this can present a security risk in some environments. Set this option to prevent logfetch from executing requested commands .SH SECURITY logfetch needs read access to the logfiles it should monitor. If you configure monitoring of files or directories through the "file:" and "dir:" entries in .I client\-local.cfg(5) then logfetch will require at least read-access to the directory where the file is located. If you request checksum calculation for a file, then it must be readable by the Xymon client user. Do \fBNOT\fR install logfetch as suid-root. There is no way that logfetch can check whether the configuration file it uses has been tampered with, so installing logfetch with suid-root privileges could allow an attacker to read any file on the system by using a hand-crafted configuration file. In fact, logfetch will attempt to remove its own suid-root setup if it detects that it has been installed suid-root. .SH "ENVIRONMENT VARIABLES" .IP DU Command used to collect information about the size of directories. By default, this is the command \fBdu \-k\fR. If the local du-command on the client does not recognize the "\-k" option, you should set the DU environment variable in the \fB$XYMONHOME/etc/xymonclient.cfg\fR file to a command that does report directory sizes in kilobytes. .SH FILES .IP $XYMONHOME/tmp/logfetch.cfg .IP $XYMONHOME/tmp/logfetch.status .SH "SEE ALSO" xymon(7), analysis.cfg(5), client-local.cfg(5) xymon-4.3.30/common/xymon-xmh.50000664000076400007640000001120213534041732016523 0ustar rpmbuildrpmbuild.TH XYMON-XMH 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME Xymon-XMH-variables \- Configuration items available online .SH DESCRIPTION The .I hosts.cfg(5) file is the most important configuration file for all of the Xymon programs. This file contains the full list of all the systems monitored by Xymon, including the set of tests and other configuration items stored for each host. Although the file is in text format and can be searched using tools like .I xymongrep(1) it can be difficult to pick out specific fields from the configuration due to quoting and other text parsing issues. So Xymon allows for querying this information directly from the .I xymond daemon via the "xymondboard" command. So the information can be provided together with the current status of a host and/or test. This is done by adding a "fields" definition to the "xymondboard" command. .SH XMH items Except where specified below, all items return the text of a particular setting from the hosts.cfg file, or an empty string if the setting has not been set for the host that is queried. .IP XMH_ALLPAGEPATHS List of all pages where the host is found, using the filename hierarchy page path. .IP XMH_BROWSER Value of the "browser" tag. .IP XMH_CLASS The host "class" (if reported by a Xymon client), or the value of the CLASS tag. .IP XMH_CLIENTALIAS Value of the CLIENT tag. .IP XMH_COMMENT Value of the COMMENT tag. .IP XMH_COMPACT Value of the COMPACT tag. .IP XMH_DEPENDS Value of the DEPENDS tag. .IP XMH_DESCRIPTION Value of the DESCR tag. .IP XMH_DGNAME The text string from the hosts.cfg "group" definition (group, group-only, group-except) in which the host is defined. .IP XMH_DISPLAYNAME Value of the NAME tag. .IP XMH_DOCURL Value of the DOC tag. .IP XMH_DOWNTIME Value of the DOWNTIME tag. .IP XMH_PULLDATA Value of the PULLDATA tag (including IP:PORT, if any) .IP XMH_FLAG_DIALUP Value of the "dialup" tag. .IP XMH_FLAG_HIDEHTTP Value of the HIDEHTTP tag. .IP XMH_FLAG_LDAPFAILYELLOW Value of the "ldapyellowfail" tag. .IP XMH_FLAG_MULTIHOMED Value of the MULTIHOMED tag. .IP XMH_FLAG_NOBB2 Value of the "nobb2" tag (deprecated, use NONONGREEN instead). .IP XMH_FLAG_NOCLEAR Value of the NOCLEAR tag. .IP XMH_FLAG_NOCLIENT Value of the "noclient" tag. .IP XMH_FLAG_NOCONN Value of the "noconn" tag. .IP XMH_FLAG_NODISP Value of the "nodisp" tag. .IP XMH_FLAG_NOINFO Value of the "noinfo" atg. .IP XMH_FLAG_NONONGREEN Value of the "nonongreen" tag. .IP XMH_FLAG_NOPING Value of the "noping" tag. .IP XMH_FLAG_NOSSLCERT Value of the "nosslcert" tag. .IP XMH_FLAG_NOTRACE Value of the "notrace" tag. .IP XMH_FLAG_NOTRENDS Value of the "notrends" tag. .IP XMH_FLAG_PREFER Value of the "prefer" tag. .IP XMH_FLAG_TESTIP Value of the "testip" tag. .IP XMH_FLAG_TRACE Value of the "trace" tag. .IP XMH_GROUPID Number of the group where the host is listed - first group is 0. If a host is present on multiple pages, this is the number of the group for the first page where the host is found. .IP XMH_HOLIDAYS Value of the "holidays" tag. .IP XMH_HOSTNAME The name of the host. .IP XMH_HTTPHEADERS Value of the "httphdr" tag. .IP XMH_IP The IP-address of the host (as specified in hosts.cfg). .IP XMH_LDAPLOGIN Value of the "ldaplogin" tag. .IP XMH_NET Value of the NET tag. .IP XMH_NK Value of the NK tag (deprecated). .IP XMH_NKTIME Value of the NKTIME tag (deprecated). .IP XMH_NOCOLUMNS Value of the NOCOLUMNS tag. .IP XMH_NOPROP Value of the NOPROP tag. .IP XMH_NOPROPACK Value of the NOPROPACK tag. .IP XMH_NOPROPPURPLE Value of the NOPROPPURPLE tag. .IP XMH_NOPROPRED Value of the NOPROPRED tag. .IP XMH_NOPROPYELLOW Value of the NOPROPYELLOW tag. .IP XMH_NOTAFTER Value of the NOTAFTER tag. .IP XMH_NOTBEFORE Value of the NOTBEFORE tag. .IP XMH_OS The host operating system (if reported by a Xymon client), or the value of the OS tag. .IP XMH_PAGEINDEX Index of the host on the page where it is shown, first host has index 0. .IP XMH_PAGENAME Name of the page where the host is shown (see also XMH_PAGEPATH). .IP XMH_PAGEPATH File path to the page where the host is shown. .IP XMH_PAGEPATHTITLE Title of the full path to the page where the host is shown. .IP XMH_PAGETITLE Title of the page where the host is shown. .IP XMH_RAW All configuration settings for the host. Settings are separated by a pipe-sign. .IP XMH_REPORTTIME Value of the REPORTTIME tag. .IP XMH_SSLDAYS Value of the "ssldays" tag. .IP XMH_SSLMINBITS Value of the "sslbits" tag. .IP XMH_TRENDS Value of the TRENDS tag. .IP XMH_WARNPCT Value of the WARNPCT tag. .IP XMH_WARNSTOPS Value of the WARNSTOPS tag. .IP XMH_WML Value of the WML tag. .SH "SEE ALSO" xymon(1), hosts.cfg(5), xymongrep(1) xymon-4.3.30/common/xymonserver.cfg.50000664000076400007640000006472213534041733017736 0ustar rpmbuildrpmbuild.TH XYMONSERVER.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonserver.cfg \- Xymon environment variables .SH DESCRIPTION Xymon programs use multiple environment variables beside the normal set of variables. The environment definitions are stored in the ~Xymon/server/etc/xymonserver.cfg file. Each line in this file is of the form \fBNAME=VALUE\fR and defines one environment variable NAME with the value VALUE. You can also append data to existing variables, using the syntax \fBNAME+=VALUE\fR. VALUE is then appended to the existing value of the NAME variable. If NAME has not been defined, then this acts as if it were a normal definition. .SH ENVIRONMENT AREAS In some cases it may be useful to have different values for an environment variable, depending on where it is used. This is possible by defining variables with an associated "area". Such definitions have the form \fBAREA/NAME=VALUE\fR. E.g. to define a special setup of the XYMSERVERS variable when it is used by an application in the "management" area, you would do this: .IP .nf XYMSERVERS="127.0.0.1" # Default definition management/XYMSERVERS="10.1.0.5" # Definition in the "management" area .fi .LP Areas are invoked by using the "\-\-area" option for all tools, or via the ENVAREA setting in the .I tasks.cfg(5) file. .SH GENERAL SETTINGS .IP XYMONSERVERHOSTNAME The fully-qualified hostname of the server that is running Xymon. .IP XYMONSERVERWWWNAME The hostname used to access this servers' web-pages, used to construct URL's in the Xymon webpages. Default is the XYMONSERVERHOSTNAME. .IP XYMONSERVERIP The public IP-address of the server that is running Xymon. .IP XYMONSERVEROS A name identifying the operating system of the Xymon server. The known names are currently "linux", "freebsd", "solaris", "hpux", "aix" and "osf". .IP FQDN If set to TRUE, Xymon will use fully-qualified hostnames throughout. If set to FALSE, hostnames are stripped of their domain-part before being processed. It is \fBhighly recommended\fR that you keep this set to TRUE. Default: TRUE. .IP XYMONLOGSTATUS Controls how the HTML page for a status log is generated. If set to DYNAMIC, the HTML logs are generated on-demand by the .I svcstatus.cgi(1) script. If set to STATIC, you must activate the .I xymond_filestore(8) module (through an entry in the .I tasks.cfg(5) file) to create and store the HTML logs whenever a status update is received. Setting "XYMONLOGSTATUS=STATIC" is \fBdiscouraged\fR since the I/O load on the Xymon server will increase significantly. .IP PINGCOLUMN Defines the name of the column for "ping" test status. The data from the "ping" test is used internally by Xymon, so it must be defined here so all of the Xymon tools know which column to watch for this data. The default setting is PINGCOLUMN=conn. .IP INFOCOLUMN Defines the name of the column for the "info" pages. .IP TRENDSCOLUMN Defines the name of the column for the RRD graph pages. .IP RRDHEIGHT The default height (in pixels) of the RRD graph images. Default: 120 pixels. .IP RRDWIDTH The default width (in pixels) of the RRD graph images. Default: 576 pixels. .IP RRDGRAPHOPTS Extra options for the RRD graph command. These are passed directly to the "rrdgraph" command used to generate graphs, see the .I rrdgraph(1) man-page for details of the options. .IP TRENDSECONDS The graphs on the "trends" page show data for the past TRENDSECONDS seconds. Default: 172800 seconds, i.e. 48 hours. .IP HTMLCONTENTTYPE The Content-type reported by the CGI scripts that generate web pages. By default, this it "text/html". If you have on-line help texts in character sets other than the ISO\-8859\-1 (western european) character set, it may be necessary to modify this to include a character set. E.g. .br HTMLCONTENTTYPE="text/html; charset=euc\-jp" .br for a Japanese character sets. Note: Some webservers will automatically add this, if configured to do so. .IP XYMWEBREFRESH The default HTTP page reload interval for many xymongen and status pages. Note that while this can be overridden in the header template files for regular pages, dynamically generated status logs displayed with svcstatus.cgi(1) use this value in the HTTP response header and for security reasons the value in hostsvc_header may be ignored on many modern browsers. (default [seconds]: 60) .IP HOLIDAYS Defines the default set of holidays used if there is no "holidays" tag for a host in the hosts.cfg file. Holiday sets are defined in the .I holidays.cfg(5) file. If not defined, only the default holidays (those defined outside a named holiday set) will be considered as holidays. .IP WEEKSTART Defines which day is the first day of the week. Set to "0" for Sunday, "1" for Monday. Default: 1 (Monday). .IP XYMONBODYHEADER Text that is included in the Xymon web pages at the location specified by ~xymon/server/web/*_header templates. If this is set to a value beginning with "file:", then the contents of the specified file is included. Default: "file:$XYMONHOME/etc/xymonmenu.cfg" .IP XYMONBODYFOOTER Text that is included in the Xymon web pages at the location specified by ~xymon/server/web/*_footer templates. If this is set to a value beginning with "file:", then the contents of the specified file is included. Default: Empty. .IP XYMONBODYMENUCSS URL for the Xymon menu CSS file. Default: "$XYMONMENUSKIN/xymonmenu.css" .IP HOSTPOPUP Determines what is used as the host comment on the webpages. The comment by default appears as a pop-up when the mouse hovers over the hostname, and is also shown on the "info" status page. This setting must be one or more of the letters "C" (COMMENT), "D" (DESCRIPTION) or "I" (IP-address). Including "C" uses the COMMENT setting for the host, including "D" uses the DESCR setting for the host, and "I" uses the IP-address of the host. If more than one of these is set, then COMMENT takes precedence over DESCR which again has precence over IP. Note that DESCR and IP only appear in pop-up windows (if enabled), whereas the COMMENT is always used - if pop-up's have been disabled, then the COMMENT value is displayed next to the hostname on the webpages. Default: CDI .IP STATUSLIFETIME The number of minutes that a status is considered valid after an update. After this time elapses, the status will go purple. Default: 30 minutes .SH DIRECTORIES .IP XYMONSERVERROOT The top-level directory for the Xymon installation. The default is the home-directory for the user running Xymon. .IP XYMONSERVERLOGS The directory for the Xymon's own logfiles (NOT the status-logs from the monitored hosts). .IP XYMONHOME The Xymon server directory, where programs and configurations are kept. Default: $XYMONSERVERROOT/server/ . .IP XYMONTMP Directory used for temporary files. Default: $XYMONHOME/tmp/ .IP XYMONWWWDIR Directory for Xymon webfiles. The $XYMONWEB URL must map to this directory. Default: $XYMONHOME/www/ .IP XYMONNOTESDIR Directory for Xymon notes-files. The $XYMONNOTESSKIN URL must map to this directory. Default: $XYMONHOME/www/notes/ .IP XYMONREPDIR Directory for Xymon availability reports. The $XYMONREPURL URL must map to this directory. Note also that your webserver must have write-access to this directory, if you want to use the .I report.cgi(1) CGI script to generate reports on-demand. Default: $XYMONHOME/www/rep/ .IP XYMONSNAPDIR Directory for Xymon snapshots. The $XYMONSNAPURL URL must map to this directory. Note also that your webserver must have write-access to this directory, if you want to use the .I snapshot.cgi(1) CGI script to generate snapshots on-demand. Default: $XYMONHOME/www/snap/ .IP XYMONVAR Directory for all data stored about the monitored items. Default: $XYMONSERVERROOT/data/ .IP XYMONRAWSTATUSDIR Directory for storing the raw status-logs. Not used unless "xymond_filestore \-\-status" is running, which is \fBdiscouraged\fR since it increases the load on the Xymon server significantly. Default: $XYMONVAR/logs/ .IP XYMONHTMLSTATUSDIR Directory for storing HTML status-logs. Not used unless "xymond_filestore \-\-status \-\-html" is running, which is \fBdiscouraged\fR since it increases the load on the Xymon server significantly. Default: $XYMONHOME/www/html/ .IP XYMONHISTDIR Directory for storing the history of monitored items. Default: $XYMONVAR/hist/ .IP XYMONHISTLOGS Directory for storing the detailed status-log of historical events. Default: $XYMONVAR/histlogs/ .IP XYMONACKDIR Directory for storing information about alerts that have been acknowledged. Default: $XYMONVAR/acks/ .IP XYMONDISABLEDDIR Directory for storing information about tests that have been disabled. Default: $XYMONVAR/disabled/ .IP XYMONDATADIR Directory for storing incoming "data" messages. Default: $XYMONVAR/data/ .IP XYMONRRDS Top-level directory for storing RRD files (the databases with trend-information used to generate graphs). Default: $XYMONVAR/rrd/ .IP CLIENTLOGS Directory for storing the data sent by a Xymon client around the time a status changes to a warning (yellow) or critical (red) state. Used by the .I xymond_hostdata(8) module. Default: $XYMONVAR/hostdata/ .IP XYMONCGILOGDIR Directory where debug output from CGI applications are stored. If not specified, it defaults to $XYMONSERVERLOGS, but this is often a directory that is not writable by the userid running the CGI applications. It is therefore recommended when using "\-\-debug" on CGI applications that you create a separate directory owned by the user running your webserver, and point XYMONCGILOGDIR to this directory. .SH SYSTEM FILES .IP HOSTSCFG Full path to the Xymon .I hosts.cfg(5) configuration file. Default: $XYMONHOME/etc/hosts.cfg. .IP XYMON Full path to the .I xymon(1) client program. Default: $XYMONHOME/bin/xymon. .IP XYMONGEN Full path to the .I xymongen(1) webpage generator program. Default: $XYMONHOME/bin/xymongen. .SH URLS .IP XYMONSERVERWWWURL The root URL for the Xymon webpages, without the hostname. This URL must be mapped to the ~/server/www/ directory in your webserver configuration. See the sample Apache configuration in ~/server/etc/xymon\-apache.conf. .IP XYMONSERVERCGIURL The root URL for the Xymon CGI-scripts, without the hostname. This directory must be mapped to the ~/cgi\-bin/ directory in your webserver configuration, and must be flagged as holding executable scripts. See the sample Apache configuration in ~/server/etc/xymon\-apache.conf. .IP XYMONWEBHOST Initial part of the Xymon URL, including just the protocol and the hostname, e.g. "http://www.foo.com" .IP XYMONWEBHOSTURL Prefix for all of the static Xymon webpages, e.g. "http://www.foo.com/xymon" .IP XYMONWEBHTMLLOGS URL prefix for the static HTML status-logs generated when XYMONLOGSTATUS=STATIC. Note that this setting is \fBdiscouraged\fR so this setting should not be used. .IP XYMONWEB URL prefix (without hostname) of the Xymon webpages. E.g. "/xymon". .IP XYMONSKIN URL prefix (without hostname) of the Xymon graphics. E.g. "/xymon/gifs". .IP XYMONHELPSKIN URL prefix (without hostname) of the Xymon on-line help files. E.g "/xymon/help". .IP XYMONMENUSKIN URL prefix (without hostname) of the Xymon menu files. E.g "/xymon/menu". .IP XYMONNOTESSKIN URL prefix (without hostname) of the Xymon on-line notes files. E.g "/xymon/notes". .IP XYMONREPURL URL prefix (without hostname) of the Xymon availability reports. E.g. "/xymon/rep". .IP XYMONSNAPURL URL prefix (without hostname) of the Xymon snapshots. E.g. "/xymon/snap". .IP XYMONWAP URL prefix (without hostname) of the Xymon WAP/WML files. E.g. "/xymon/wml". .IP CGIBINURL URL prefix (without hostname) of the Xymon CGI-scripts. Default: $XYMONSERVERCGIURL . .IP COLUMNDOCURL Format string used to build a link to the documentation for a column heading. Default: "$CGIBINURL/columndoc.sh?%s", which causes links to use the .I columndoc.sh(1) script to document a column. .IP HOSTDOCURL Format string used to build a link to the documentation for a host. If not set, then Xymon falls back to scanning the XYMONNOTES directory for files matching the hostname, or the hostname together with a common filename extension (.php, .html, .doc and so on). If set, this string becomes a formatting string for the documentation URL. E.g. for the host "myhost", a setting of HOSTDOCURL="/docs/%s.php" will generate a link to "/docs/myhost.php". Default: Not set, so host documentation will be retrieved from the XYMONNOTES directory. .SH SETTINGS FOR SENDING MESSAGES TO XYMON .IP XYMSRV The IP-address used to contact the .I xymond(8) service. Used by clients and the tools that perform network tests. Default: $XYMONSERVERIP .IP XYMSERVERS List of IP-addresses. Clients and network test tools will try to send status reports to a Xymon server running on each of these addresses. This setting is only used if XYMSRV=0.0.0.0. .IP XYMONDPORT The portnumber for used to contact the .I xymond(8) service. Used by clients and the tools that perform network tests. Default: 1984. .IP MAXMSGSPERCOMBO The maximum number of status messages to combine into one combo message. Default: 100. .IP SLEEPBETWEENMSGS Length of a pause introduced between each successive transmission of a combo-message by xymonnet, in microseconds. Default: 0 (send messages as quickly as possible). .SH XYMOND SETTINGS .IP ALERTCOLORS Comma-separated list of the colors that may trigger an alert-message. The default is "red,yellow,purple". Note that alerts may further be generated or suppresed based on the configuration in the .I alerts.cfg(5) file. .IP OKCOLORS Comma-separated list of the colors that may trigger a recovery-message. The default is "green,clear,blue". .IP ALERTREPEAT How often alerts get repeated while a status is in an alert state. This is the default setting, which may be changed in the .I alerts.cfg(5) file. .IP MAXMSG_STATUS The maximum size of a "status" message in kB, default: 256. Status messages are the ones that end up as columns on the web display. The default size should be adequate in most cases, but some extension scripts can generate very large status messages - close to 1024 kB. You should only change this if you see messages in the xymond log file about status messages being truncated. .IP MAXMSG_CLIENT The maximum size of a "client" message in kB, default: 512. "client" messages are generated by the Xymon client, and often include large process-listings. You should only change this if you see messages in the xymond log file about client messages being truncated. .IP MAXMSG_DATA The maximum size of a "data" message in kB, default: 256. "data" messages are typically used for client reports of e.g. netstat or vmstat data. You should only change this setting if you see messages in the xymond log file about data messages being truncated. .IP MAXMSG_NOTES The maximum size of a "notes" message in kB, default: 256. "notes" messages provide a way for uploading documentation about a host to Xymon; it is not enabled by default. If you want to upload large documents, you may need to change this setting. .IP MAXMSG_STACHG The maximum size of a "status change" message in kB, default: Current value of the MAXMSG_STATUS setting. Status-change messages occur when a status changes color. There is no reason to change this setting. .IP MAXMSG_PAGE The maximum size of a "page" message in kB, default: Current value of the MAXMSG_STATUS setting. "page" messages are alerts, and include the status message that triggers the alert. There is no reason to change this setting. .IP MAXMSG_ENADIS The maximum size of an "enadis" message in kB, default: 32. "enadis" are small messages used when enabling or disabling hosts and tests, so the default size should be adequate. .IP MAXMSG_CLICHG The maximum size of a "client change" message in kB, default: Current value of the MAXMSG_CLIENT setting. Client-change messages occur when a status changes color to one of the alert-colors, usually red, yellow and purple. There is no reason to change this setting. .IP MAXMSG_USER The maximum size of a "user" message in kB, default: 128. "user" messages are for communication between custom Xymon modules you have installed, it is not used directly by Xymon. .SH XYMOND_HISTORY SETTINGS .IP XYMONALLHISTLOG If set to TRUE, .I xymond_history(8) will update the $XYMONHISTDIR/allevents file logging all changes to a status. The allevents file is used by the .I eventlog.cgi(1) tool to show the list of recent events on the "All non-green" webpage. .IP XYMONHOSTHISTLOG If set to TRUE, .I xymond_history(8) will update the host-specific eventlog that keeps record of all status changes for a host. This logfile is not used by any Xymon tool. .IP SAVESTATUSLOG If set to TRUE, .I xymond_history(8) will save historical detailed status-logs to the $XYMONHISTLOGS directory. .SH XYMOND_ALERT SETTINGS .IP MAIL Command used to send alerts via e-mail, including a "Subject:" header in the mail. Default: "mail \-s" .IP MAILC Command used to send alerts via e-mail in a form that does not have a "Subject" in the mail. Default: "mail" .IP SVCCODES Maps status-columns to numeric service-codes. The numeric codes are used when sending an alert using a script, where the numeric code of the service is provided in the BBSVCNUM variable. .SH XYMOND_RRD SETTINGS .IP TEST2RRD List of "COLUMNNAME[=RRDSERVICE]" settings, that define which status- and data-messages have a corresponding RRD graph. You will normally not need to modify this, unless you have added a custom TCP-based test to the protocols.cfg file, and want to collect data about the response-time, OR if you are using the .I xymond_rrd(8) external script mechanism to collect data from custom tests. Note: All TCP tests are automatically added. .IP GRAPHS_ List of GRAPHs that should be displayed on the corresponding colmn page. Note this will override the default, so to add multiple graphs you should include the original one (e.g. GRAPHS_cpu="la,vmstat1"). These are used together by the .I svcstatus.cgi(1) script to determine if the detailed status view of a test should include a graph. .IP GRAPHS List of the RRD databases, that should be shown as a graph on the "trends" column. .IP NORRDDISKS This is used to disable the tracking of certain filesystems. By default all filesystems reported by a client are tracked. In some cases you may want to disable this for certain filesystems, e.g. database filesystems since they are always completely full. This setting is a regular expression that is matched against the filesystem name (the Unix mount-point, or the Windows disk-letter) - if the filesystem name matches this expression, then it will not be tracked by Xymon. .br Note: Setting this does not affect filesystems that are already being tracked by Xymon - to remove them, you must remove the RRD files for the unwanted filesystems from the ~xymon/data/rrd/HOSTNAME/ directory. .IP RRDDISKS This is used to enable tracking of only selected filesystems (see the NORRDDISKS setting above). By default all filesystems are being tracked, setting this changes that default so that only those filesystems that match this pattern will be tracked. .SH XYMONNET NETWORK TEST SETTINGS .IP XYMONNETWORK If this variable is defined, then only the hosts that have been tagged with "NET:$XYMONNETWORK" will be tested by the xymonnet tool. .IP CONNTEST If set to TRUE, the connectivity (ping) test will be performed. .IP IPTEST_2_CLEAR_ON_FAILED_CONN If set to TRUE, then failing network tests go CLEAR if the conn-test fails. .IP NONETPAGE List of network services (separated with ) that should go yellow upon failure instead of red. .IP XYMONROUTERTEXT When using the "router" or "depends" tags for a host, a failure status will include text that an "Intermediate router is down". With todays network topologies, the router could be a switch or another network device; if you define this environment variable the word "router" will be replaced with whatever you put into the variable. So to inform the users that an intermediate switch or router is down, use XYMONROUTERTEXT="switch or router". This can also be set on a per-host basis using the "DESCR:hosttype:description" tag in the .I hosts.cfg(5) file. .IP NETFAILTEXT When a network test fails, the status message reports "SERVICENAME not OK". The "not OK" message can be changed via this variable, e.g. you can change it to "FAILED" or customize it as you like. .IP FPING The command used to run the .I xymonping(1) tool for the connectivity test. (The name FPING is due to the fact that the "fping" utility was used until Xymon version 4.2). This may include suid-root wrappers and xymonping options. Default: "xymonping" .IP FPINGOPTS Options used for the .I fping(1) or .I xymonping(1) tool for the connectivity test. Note that xymonnet will still expect the output to match the default format. Default: "-Ae" .IP TRACEROUTE .IP TRACEROUTEOPTS Defines the location of the "traceroute" tool and any options needed to run it. traceroute is used by the connectivity test when the ping test fails; if requested via the "trace" tag, the TRACEROUTE command is executed to try to indicate the point in the network that is causing the problem. For backwards compatibility, with prior versions, if TRACEROUTEOPTS is unset, TRACEROUTE is assumed to have whatever options are desired and no addl options are used. Recommended defaults are: "\-n \-q 2 \-w 2 \-m 15" (no DNS lookup, max. 2 probes, wait 2 seconds per hop, max 15 hops). .sp If you have the .I mtr(8) tool installed - available from http://www.bitwizard.nl/mtr/ - I strongly recommend using this instead. The recommended TRACEROUTEOPTS for mtr are "\-c 2 \-n \-\-report" Note that mtr needs to be installed suid-root on most systems. .IP NTPDATE Defines the .I ntpdate(1) program used for the "ntp" test. Default: "ntpdate" .IP NTPDATEOPTS Options used for the .I ntpdate(1) program. Default: "\-u \-q \-p 1" .IP RPCINFO Defines the .I rpcinfo(8) program used for "rpc" tests. Default: "rpcinfo" .SH XYMONGEN WEBPAGE GENERATOR SETTINGS .IP XYMONLOGO HTML code that is inserted on all standard headers. The default is to add the text "Xymon" in the upper-left corner of the page, but you can easily replace this with e.g. a company logo. If you do, I suggest that you keep it at about 30-35 pixels high, and 100-150 pixels wide. .IP XYMONPAGELOCAL The string "Pages hosted locally" that appears above all of the pages linked from the main Xymon webpage. .IP XYMONPAGESUBLOCAL The string "Subpages hosted locally" that appears above all of the sub-pages linked from pages below the main Xymon webpage. .IP XYMONPAGEREMOTE The string "Remote status display" that appears about the summary statuses displayed on the min Xymon webpage. .IP XYMONPAGETITLE HTML tags designed to go in a tag, to choose the font for titles of the webpages. .IP XYMONPAGEROWFONT HTML tags designed to go in a tag, to choose the font for row headings (hostnames) on the webpages. .IP XYMONPAGECOLFONT HTML tags designed to go in a tag, to chose the font for column headings (test names) on the webpages. .IP XYMONPAGEACKFONT HTML tags designed to go in a tag, to chose the font for the acknowledgement text displayed on the status-log HTML page for an acknowledged status. .IP ACKUNTILMSG When displaying the detailed status of an acknowledged test, Xymon will include the time that the acknowledge expires using the print-format defined in this setting. You can define the timeformat using the controls in your systems .I strftime(3) routine, and add the text suitable for your setup. .IP ACK_COOKIE_EXPIRATION The valid length of an acknowledgement cookie. You want to set this large enough so that a late-answered acknowledgement for an alert is still processed properly. Default value: 86400 .IP XYMONDATEFORMAT On webpages generated by xymongen, the default header includes the current date and time. Normally this looks like "Tue Aug 24 21:59:47 2004". The XYMONDATEFORMAT controls the format of this timestamp - you can define the format using the controls in the .I strftime(3) routine. E.g. to have it show up as "2004\-08\-24 21:59:47 +0200" you would set XYMONDATEFORMAT="%Y\-%m\-%d %H:%M:%S %z" .IP HOLIDAYFORMAT How holiday dates are displayed. The default is "%d/%m" which show the day and month. American users may want to change this to "%m/%d" to suit their preferred date-display style. This is a formatting string for the system .I strftime(3) routine, so any controls available for this routine may be used. .IP XYMONPAGECOLREPEAT Inspired by Jeff Stoner's col_repeat_patch.tgz patch, this defines the maximum number of rows before repeating the column headings on a webpage. This sets the default value for the .I xymongen(1) "\-\-maxrows" option; if the command-line option is also specified, then it overrides this environment variable. Note that unlike Jeff's patch, xymongen implements this for both the "All non-green" page and all other pages (xymon.html, subpages, critical.html). .IP SUMMARY_SET_BKG If set to TRUE, then summaries will affect the color of the main Xymon webpage. Default: FALSE. .IP DOTHEIGHT The height (in pixels) of the icons showing the color of a status. Default: 16, which matches the default icons. .IP DOTWIDTH The width (in pixels) of the icons showing the color of a status. Default: 16, which matches the default icons. .IP CLIENTSVCS List of the status logs fed by data from the Xymon client. These status logs will - if there are Xymon client data available for the host - include a link to the raw data sent by the client. Default: cpu,disk,memory,procs,svcs. .IP XYMONRSSTITLE If defined, this is the title of the RSS/RDF documents generated when .I xymongen(1) is invoked with the "\-\-rss" option. The default value is "Xymon Alerts". .IP WMLMAXCHARS Maximum size of a WAP/WML output "card" when generating these. Default: 1500. .IP XYMONNONGREENEXT List of scripts to run as extensions to the "All non-green" page. Note that two scripts, "eventlog.sh" and "acklog.sh" are handled specially: They are handled internally by xymongen, but the script names must be listed in this variable for this function to be enabled. .IP XYMONHISTEXT List of scripts to run as extensions to a history page. .IP XYMONREPWARN Default threshold for listing the availability as "critical" (red) when generating the availability report. This can be set on a per-host basis with the WARNPCT setting in .I hosts.cfg(5). Default: 97 (percent) .IP XYMONGENREPOPTS Default xymongen options used for reports. This will typically include such options as "\-\-subpagecolumns", and also "\-\-ignorecolumns" if you wish to exclude certain tests from reports by default. .IP XYMONGENSNAPOPTS Default xymongen options used by snapshots. This should be identical to the options you normally used when building Xymon webpages. .SH FILES .BR "~xymon/server/etc/xymonserver.cfg" .SH "SEE ALSO" xymon(7) xymon-4.3.30/common/tasks.cfg.50000664000076400007640000001234613534041732016454 0ustar rpmbuildrpmbuild.TH TASKS.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME tasks.cfg \- Task definitions for the xymonlaunch utility .SH SYNOPSIS .B ~xymon/server/etc/tasks.cfg .SH DESCRIPTION The tasks.cfg file holds the list of tasks that xymonlaunch runs to perform all of the tasks needed by the Xymon monitor. .SH FILE FORMAT A task is defined by a \fBkey\fR, a \fBcommand\fR, and optionally also \fBinterval\fR, \fBenvironment\fR, and \fBlogfile\fR. Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. Long lines can be broken up by putting a backslash at the end of the line and continuing the entry on the next line. An entry looks like this: .sp [xymond] .br ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg .br CMD /usr/local/xymon/server/bin/xymond .sp [updateweb] .br ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg .br CMD /usr/local/xymon/server/bin/xymongen .br NEEDS xymond .br GROUP webupdates .br INTERVAL 5m .br ONHOST localhost .br MAXTIME 10m .br LOGFILE /var/log/xymon/updateweb.log .sp [monthlyreport] .br ENVFILE /usr/local/xymon/server/etc/xymonserver.cfg .br CMD /usr/local/xymon/server/ext/monthlyreport.sh .br CRONDATE 30 4 1 * * .sp The \fBkey\fR is enclosed in angle brackets, and must be unique for each task. You can choose your key-names as you like, they are only used internally in xymonlaunch to identify each task. The \fBcommand\fR is defined by the \fbCMD\fR keyword. This is the full command including any options you want to use for this task. This is required for all tasks. The \fBDISABLED\fR keyword means that this command is disabled. xymonlaunch will not start this task. It is recommended that you use this to disable standard tasks, instead of removing them or commenting them out. Upgrades to Xymon will add standard tasks back into the file, so unless you have them listed as DISABLED then tasks may re-appear unexpectedly after an upgrade. There is also a corresponding \fBENABLED\fR keyword, to explicitly enable a task. The \fBONHOST\fR keyword tells xymonlaunch that this task should only run on specific hosts. After the ONHOST keyword, you must provide a "regular expression"; if the hostname where xymonlaunch runs matches this expression, then the task will run. If it doesn't match, then the task is treated as if it were DISABLED. The \fBMAXTIME\fR keyword sets a maximum time that the task may run; if exceeded, xymonlaunch will kill the task. The time is in seconds by default, you can specify minutes, hours or days by adding an "m", "h" or "d" after the number. By default there is no upper limit on how long a taskmay run. The \fBNEEDS\fR instructs xymonlaunch not to run this task unless the task defined by the NEEDS keyword is already running. This is used e.g. to delay the start of some application until the needed daemons have been started. The task that must be running is defined by its \fBkey\fR. The \fBGROUP\fR keyword can be used to limit the number of tasks that may run simultaneously. E.g. if you are generating multiple pagesets of webpages, you don't want them to run at the same time. Putting them into a GROUP will cause xymonlaunch to delay the start of new tasks, so that only one task will run per group. You can change the limit by defining the group before the tasks, with a "GROUP groupname maxtasks" line. The \fBINTERVAL\fR keyword defines how often this command is executed. The example shows a command that runs every 5 minutes. If no interval is given, the task is only run once - this is useful for tasks that run continually as daemons - although if the task stops for some reason, then xymonlaunch will attempt to restart it. Intervals can be specified in seconds (if you just put a number there), or in minutes (5m), hours (2h), or days (1d). The \fBCRONDATE\fR keyword is used for tasks that must run at regular intervals or at a specific time. The time specification is identical to the one used by cron in .I crontab(5) entries, i.e. a sequence of numbers for minute, hour, day-of-month, month and day-of-week. Three-letter abbreviations in english can be used for the month and day-of-week fields. An asterisk is a wildcard. So in the example above, this job would run once a month, at 4:30 AM on the 1st day of the month. The \fBENVFILE\fR setting points to a file with definitions of environment variables. Before running the task, xymonlaunch will setup all of the environment variables listed in this file. Since this is a per-task setting, you can use the same xymonlaunch instance to run e.g. both the server- and client-side Xymon tasks. If this option is not present, then the environment defined to xymonlaunch is used. The \fBENVAREA\fR setting modifies which environment variables are loaded, by picking up the ones that are defined for this specific "area". See .I xymonserver.cfg(5) for information about environment areas. The \fBLOGFILE\fR setting defines a logfile for the task. xymonlaunch will start the task with stdout and stderr redirected to this file. If this option is not present, then the output goes to the same location as the xymonlaunch output. .SH "SEE ALSO" xymonlaunch(8), xymond(8), crontab(5), xymon(7) xymon-4.3.30/common/xymoncfg.c0000664000076400007640000000567412004254623016503 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon config file viewer */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymoncfg.c 7126 2012-07-26 14:52:03Z storner $"; #include #include #include #include #include "version.h" #include "libxymon.h" int main(int argc, char *argv[]) { FILE *cfgfile; char *fn = NULL; strbuffer_t *inbuf; int argi; char *include2 = NULL; enum { S_NONE, S_KSH, S_CSH } shelltype = S_NONE; char *p; for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--version") == 0) { printf("xymoncfg version %s\n", VERSION); exit(0); } else if (strcmp(argv[argi], "--help") == 0) { printf("Usage:\n%s [filename]\n", argv[0]); exit(0); } else if ((strcmp(argv[argi], "--net") == 0) || (strcmp(argv[argi], "--bbnet") == 0)) { include2 = "netinclude"; } else if ((strcmp(argv[argi], "--web") == 0) || (strcmp(argv[argi], "--bbdisp") == 0)) { include2 = "dispinclude"; } else if (strcmp(argv[argi], "-s") == 0) { shelltype = S_KSH; } else if (strcmp(argv[argi], "-c") == 0) { shelltype = S_CSH; } else if (*argv[argi] != '-') { fn = strdup(argv[argi]); } } if (!fn || (strlen(fn) == 0)) { fn = getenv("HOSTSCFG"); if (!fn) { errprintf("Environment variable HOSTSCFG is not set - aborting\n"); exit(2); } } cfgfile = stackfopen(fn, "r", NULL); if (cfgfile == NULL) { printf("Cannot open file '%s'\n", fn); exit(1); } inbuf = newstrbuffer(0); while (stackfgets(inbuf, include2)) { switch (shelltype) { case S_NONE: printf("%s", STRBUF(inbuf)); break; case S_KSH: sanitize_input(inbuf, 1, 0); p = STRBUF(inbuf) + strspn(STRBUF(inbuf), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); if (*p == '=') { char *val = p+1; *p = '\0'; p = val + strcspn(val, "\r\n"); *p = '\0'; printf("%s=%s;export %s\n", STRBUF(inbuf), val, STRBUF(inbuf)); } break; case S_CSH: sanitize_input(inbuf, 1, 0); p = STRBUF(inbuf) + strspn(STRBUF(inbuf), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); if (*p == '=') { char *val = p+1; *p = '\0'; p = val + strcspn(val, "\r\n"); *p = '\0'; printf("setenv %s %s\n", STRBUF(inbuf), val); } break; } } stackfclose(cfgfile); freestrbuffer(inbuf); return 0; } xymon-4.3.30/common/clientupdate.10000664000076400007640000001111413534041732017236 0ustar rpmbuildrpmbuild.TH CLIENTUPDATE 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME clientupdate \- Xymon client update utility .SH SYNOPSIS .B "clientupdate [options]" .SH DESCRIPTION \fBclientupdate\fR is part of the Xymon client. It is responsible for updating an existing client installation from a central repository of client packages stored on the Xymon server. When the Xymon client sends a normal client report to the Xymon server, the server responds with the section of the .I client\-local.cfg(5) file that is relevant to this client. Included in this may be a "clientversion" value. The clientversion received from the server is compared against the current clientversion installed on the client, as determined by the contents of the $XYMONHOME/etc/clientversion.cfg file. If the two versions are not identical, clientupdate is launched to update the client installation. .SH OPTIONS .IP "\-\-level" Report the current clientversion. .IP "\-\-update=NEWVERSION" Attempt to update the client to NEWVERSION by fetching this version of the client software from the Xymon server. .IP "\-\-reexec" Used internally during the update process, see \fBOPERATION\fR below. .IP "\-\-remove\-self" Used internally during the update process. This option causes the running clientupdate utility to delete itself - it is used during the update to purge a temporary copy of the clientupdate utility that is installed in $XYMONTMP. .SH USING CLIENTUPDATE IN XYMON To manage updating clients without having to logon to each server, you can use the clientupdate utility. This is how you setup the release of a new client version. .IP "Create the new client" Setup the new client $XYMONHOME directory, e.g. by copying an existing client installation to an empty directory and modifying it for your needs. It is a good idea to delete all files in the tmp/ and logs/ directories, since there is no need to copy these over to all of the clients. Pay attention to the etc/ files, and make sure that they are suitable for the systems where you want to deploy this new client. You can add files - e.g. extension scripts in the ext/ directory - but the clientupdate utility cannot delete or rename files. .IP "Package the client" When your new client software is ready, create a tar-file of the new client. All files in the tar archive must have file names relative to the clients' $XYMONHOME (usually, ~xymon/client/). Save the tar file on the Xymon server in ~xymon/server/download/somefile.tar. Don't compress it. It is recommended that you use some sort of operating-system and version-numbering scheme for the filename, but you can choose whatever filename suits you - the only requirement is that it must end with ".tar". The part of the filename preceding ".tar" is what Xymon will use as the "clientversion" ID. .IP "Configure which hosts receive the new client" In the .I client\-local.cfg(5) file, you must now setup a \fBclientversion:ID\fR line where the \fBID\fR matches the filename you used for the tar-file. So if you have packaged the new client into the file \fBlinux.v2.tar\fR, then the corresponding entry in client\-local.cfg would be \fBclientversion:linux.v2\fR. .IP "Wait for xymond to reload client\-local.cfg" xymond will automatically reload the client\-local.cfg file after at most 10 minutes. If you want to force an immediate reload, send a SIGHUP signal to the xymond process. .IP "Wait for the client to update" The next time the client contacts the Xymon server to send the client data, it will notice the new clientversion setting in client\-local.cfg, and will run \fBclientupdate\fR to install the new client software. So when the client runs the next time, it will use the new client software. .SH OPERATION \fBclientupdate\fR runs in two steps: .IP "Re-exec step" The first step is when clientupdate is first invoked from the xymonclient.sh script with the "\-\-re\-exec" option. This step copies the clientupdate program from $XYMONHOME/bin/ to a temporary file in the $XYMONTMP directory. This is to avoid conflicts when the update procedure installs a new version of the clientupdate utility itself. Upon completion of this step, the clientupdate utility automatically launches the next step by running the program from the file in $XYMONTMP. .IP "Update step" The second step downloads the new client software from the Xymon server. The new software must be packed into a tar file, which clientupdate then unpacks into the $XYMONHOME directory. .SH "ENVIRONMENT VARIABLES" clientupdate uses several of the standard Xymon environment variables, including \fBXYMONHOME\fR and \fBXYMONTMP\fR. .SH "SEE ALSO" xymon(7), xymon(1), client\-local.cfg(5) xymon-4.3.30/common/xymoncmd.c0000664000076400007640000001150412610564002016472 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon application launcher. */ /* */ /* This is used to launch a single Xymon application, with the environment */ /* that would normally be established by xymonlaunch. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymoncmd.c 7696 2015-10-18 00:29:54Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" #ifdef HAVE_UNAME #include #endif static void xymon_default_envs(char *envfn) { FILE *fd; char buf[1024]; char *evar; char *homedir, *p; int hasuname = 0; #ifdef HAVE_UNAME struct utsname u_name; #endif #ifdef HAVE_UNAME hasuname = (uname(&u_name) != -1); if (!hasuname) errprintf("uname() failed: %s\n", strerror(errno)); #endif if (getenv("MACHINEDOTS") == NULL) { if (getenv("HOSTNAME") != NULL) sprintf(buf, "%s", xgetenv("HOSTNAME")); #ifdef HAVE_UNAME else if (hasuname) sprintf(buf, "%s", u_name.nodename); #endif else { fd = popen("uname -n", "r"); if (fd && fgets(buf, sizeof(buf), fd)) { p = strchr(buf, '\n'); if (p) *p = '\0'; pclose(fd); } else strcpy(buf, "localhost"); } evar = (char *)malloc(strlen(buf) + 13); sprintf(evar, "MACHINEDOTS=%s", buf); putenv(evar); } xgetenv("MACHINE"); if (getenv("SERVEROSTYPE") == NULL) { #ifdef HAVE_UNAME if (hasuname) sprintf(buf, "%s", u_name.sysname); else { #else { #endif fd = popen("uname -s", "r"); if (fd && fgets(buf, sizeof(buf), fd)) { p = strchr(buf, '\n'); if (p) *p = '\0'; pclose(fd); } else strcpy(buf, "unix"); } for (p=buf; (*p); p++) *p = (char) tolower((int)*p); evar = (char *)malloc(strlen(buf) + 14); sprintf(evar, "SERVEROSTYPE=%s", buf); putenv(evar); } if (getenv("XYMONCLIENTHOME") == NULL) { homedir = strdup(envfn); p = strrchr(homedir, '/'); if (p) { *p = '\0'; if (strlen(homedir) > 4) { p = homedir + strlen(homedir) - 4; if (strcmp(p, "/etc") == 0) { *p = '\0'; evar = (char *)malloc(20 + strlen(homedir)); sprintf(evar, "XYMONCLIENTHOME=%s", homedir); putenv(evar); } } } } } int main(int argc, char *argv[]) { int argi; char *cmd = NULL; char **cmdargs = NULL; int argcount = 0; char *envfile = NULL; char *envarea = NULL; char envfn[PATH_MAX]; cmdargs = (char **) calloc(argc+2, sizeof(char *)); for (argi=1; (argi < argc); argi++) { if ((argcount == 0) && (strcmp(argv[argi], "--debug") == 0)) { debug = 1; } else if ((argcount == 0) && (argnmatch(argv[argi], "--env="))) { char *p = strchr(argv[argi], '='); envfile = strdup(p+1); } else if ((argcount == 0) && (argnmatch(argv[argi], "--area="))) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if ((argcount == 0) && (strcmp(argv[argi], "--version") == 0)) { fprintf(stdout, "Xymon version %s\n", VERSION); return 0; } else { if (argcount == 0) { cmdargs[0] = cmd = strdup(expand_env(argv[argi])); argcount = 1; } else cmdargs[argcount++] = strdup(expand_env(argv[argi])); } } if (!envfile) { struct stat st; sprintf(envfn, "%s/etc/xymonserver.cfg", xgetenv("XYMONHOME")); if (stat(envfn, &st) == -1) sprintf(envfn, "/etc/xymon/xymonserver.cfg"); if (stat(envfn, &st) == -1) sprintf(envfn, "%s/etc/xymonclient.cfg", xgetenv("XYMONHOME")); if (stat(envfn, &st) == -1) sprintf(envfn, "%s/etc/xymonclient.cfg", xgetenv("XYMONCLIENTHOME")); if (stat(envfn, &st) == -1) sprintf(envfn, "/etc/xymon-client/xymonclient.cfg"); if (stat(envfn, &st) == -1) sprintf(envfn, "xymonserver.cfg"); if (stat(envfn, &st) == -1) sprintf(envfn, "xymonclient.cfg"); envfile = (char *)envfn; dbgprintf("Using default environment file %s\n", envfile); } /* Make sure SERVEROSTYPE, MACHINEDOTS and MACHINE are setup for our child */ xymon_default_envs(envfile); loadenv(envfile, envarea); /* Go! */ if (cmd == NULL) cmd = cmdargs[0] = "/bin/sh"; execvp(cmd, cmdargs); /* Should never go here */ errprintf("execvp() failed: %s\n", strerror(errno)); return 0; } xymon-4.3.30/common/xymon.c0000664000076400007640000001356012475417664016036 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon communications tool. */ /* */ /* This is used to send a single message using the Xymon/BB protocol to the */ /* Xymon server. */ /* */ /* Copyright (C) 2002-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymon.c 7594 2015-03-03 20:55:16Z jccleaver $"; #include #include #include #include #include #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { int timeout = XYMON_TIMEOUT; int result = 1; int argi; int showhelp = 0; char *recipient = NULL; strbuffer_t *msg = newstrbuffer(0); FILE *respfd = stdout; char *envarea = NULL; sendreturn_t *sres; int wantresponse = 0, mergeinput = 0, usebackfeedqueue = 0; for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strncmp(argv[argi], "--proxy=", 8) == 0) { char *p = strchr(argv[argi], '='); setproxy(p+1); } else if (strcmp(argv[argi], "--help") == 0) { showhelp = 1; } else if (strcmp(argv[argi], "--version") == 0) { fprintf(stdout, "Xymon version %s\n", VERSION); return 0; } else if (strcmp(argv[argi], "--str") == 0) { respfd = NULL; } else if (strncmp(argv[argi], "--out=", 6) == 0) { char *fn = argv[argi]+6; respfd = fopen(fn, "wb"); } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { char *p = strchr(argv[argi], '='); timeout = atoi(p+1); } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--merge") == 0) { mergeinput = 1; } else if (strcmp(argv[argi], "--response") == 0) { wantresponse = 1; } else if (strcmp(argv[argi], "-?") == 0) { showhelp = 1; } else if ((*(argv[argi]) == '-') && (strlen(argv[argi]) > 1)) { fprintf(stderr, "Unknown option %s\n", argv[argi]); } else { /* No more options - pickup recipient and msg */ if (recipient == NULL) { recipient = argv[argi]; } else if (STRBUFLEN(msg) == 0) { msg = dupstrbuffer(argv[argi]); } else { showhelp=1; } } } if ((recipient == NULL) || (STRBUFLEN(msg) == 0) || showhelp) { fprintf(stderr, "Xymon version %s\n", VERSION); fprintf(stderr, "Usage: %s [--debug] [--merge] [--proxy=http://ip.of.the.proxy:port/] RECIPIENT DATA\n", argv[0]); fprintf(stderr, " RECIPIENT: IP-address, hostname or URL\n"); fprintf(stderr, " DATA: Message to send, or \"-\" to read from stdin\n"); return 1; } if (strcmp(STRBUF(msg), "-") == 0) { strbuffer_t *inpline = newstrbuffer(0); sres = newsendreturnbuf(0, NULL); initfgets(stdin); while (unlimfgets(inpline, stdin)) { result = sendmessage(STRBUF(inpline), recipient, timeout, sres); clearstrbuffer(inpline); } return result; } if (mergeinput || (strcmp(STRBUF(msg), "@") == 0)) { strbuffer_t *inpline = newstrbuffer(0); if (mergeinput) /* Must add a new-line before the rest of the message */ addtobuffer(msg, "\n"); else /* Clear input buffer, we'll read it all from stdin */ clearstrbuffer(msg); initfgets(stdin); while (unlimfgets(inpline, stdin)) addtostrbuffer(msg, inpline); freestrbuffer(inpline); } if (strncmp(STRBUF(msg), "query ", 6) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "client ", 7) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "config ", 7) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "download ", 9) == 0) wantresponse = 1; else if ((strncmp(STRBUF(msg), "xymondlog ", 10) == 0) || (strncmp(STRBUF(msg), "hobbitdlog ", 11) == 0)) wantresponse = 1; else if ((strncmp(STRBUF(msg), "xymondxlog ", 11) == 0) || (strncmp(STRBUF(msg), "hobbitdxlog ", 12) == 0)) wantresponse = 1; else if ((strncmp(STRBUF(msg), "xymondboard", 11) == 0) || (strncmp(STRBUF(msg), "hobbitdboard", 12) == 0)) wantresponse = 1; else if ((strncmp(STRBUF(msg), "xymondxboard", 12) == 0) || (strncmp(STRBUF(msg), "hobbitdxboard", 13) == 0)) wantresponse = 1; else if (strncmp(STRBUF(msg), "schedule ", 9) == 0) wantresponse = 0; else if (strncmp(STRBUF(msg), "schedule", 8) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "clientlog ", 10) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "hostinfo", 8) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "ping", 4) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "pullclient", 10) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "ghostlist", 9) == 0) wantresponse = 1; else if (strncmp(STRBUF(msg), "multisrclist", 12) == 0) wantresponse = 1; usebackfeedqueue = ((strcmp(recipient, "0") == 0) && !wantresponse); if (!usebackfeedqueue) { sres = newsendreturnbuf(wantresponse, respfd); result = sendmessage(STRBUF(msg), recipient, timeout, sres); if (sres->respstr) printf("Buffered response is '%s'\n", STRBUF(sres->respstr)); } else { dbgprintf("Using backfeed channel\n"); sendmessage_init_local(); sendmessage_local(STRBUF(msg)); sendmessage_finish_local(); result = 0; } return result; } xymon-4.3.30/common/clientlaunch.cfg.50000664000076400007640000000103413534041732017770 0ustar rpmbuildrpmbuild.TH CLIENTLAUNCH.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME clientlaunch.cfg \- Task definitions for the xymonlaunch utility .SH SYNOPSIS .B ~xymon/client/etc/clientlaunch.cfg .SH DESCRIPTION The clientlaunch.cfg file holds the list of tasks that xymonlaunch runs on a Xymon client. This is typically just the Xymon client itself, but you can add custom test scripts here and have them executed regularly by the Xymon scheduler. .SH "FILE FORMAT" See the .I tasks.cfg(5) description. .SH "SEE ALSO" xymonlaunch(8), xymon(7) xymon-4.3.30/common/xymoncmd.10000664000076400007640000000206413534041733016420 0ustar rpmbuildrpmbuild.TH XYMONCMD 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymoncmd \- Run a Xymon command with environment set .SH SYNOPSIS .B "xymoncmd [\-\-env=ENVFILE COMMAND|\-\-version|\-\-debug]" .SH DESCRIPTION .I xymoncmd(1) is a utility that can setup the Xymon environment variables as defined in a .I xymonlaunch(8) compatible environment definition file, and then execute a command with this environment in place. It is mostly used for testing extension scripts or in other situations where you need to run a single command with the environment in place. The "\-\-env=ENVFILE" option points xymoncmd to the file where the environment definitions are loaded from. COMMAND is the command to execute after setting up the environment. If you want to run multiple commands, it is often easiest to just use "sh" as the COMMAND - this gives you a sub-shell with the environment defined globally. The "\-\-debug" option print out more detail steps of xymoncmd execution. The "\-\-version" option print out version number of xymoncmd. .SH "SEE ALSO" xymonlaunch(8), xymon(7) xymon-4.3.30/common/xymon.70000664000076400007640000005313713534041732015750 0ustar rpmbuildrpmbuild.TH XYMON 7 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME Xymon \- Introduction to Xymon .SH OVERVIEW Xymon is a tool for monitoring the health of your networked servers and the applications running on them. It provides a simple, intuitive way of checking the health of your systems from a web browser, and can also alert you to any problems that arise through alarms sent as e-mail, SMS messages, via a pager or by other means. Xymon is Open Source software, licensed under the GNU GPL. This means that you are free to use Xymon as much as you like, and you are free to re-distribute it and change it to suit your specific needs. However, if you change it then you must make your changes available to others on the same terms that you received Xymon originally. See the file COPYING in the Xymon source-archive for details. Xymon was called "Hobbit" until November 2008, when it was renamed to Xymon. This was done because the name "Hobbit" is trademarked. Xymon initially began life as an enhancement to Big Brother called "bbgen". Over a period of 5 years, Xymon has evolved from a small add-on to a full-fledged monitoring system with capabilities far exceeding what was in the original Big Brother package. Xymon does still maintain some compatibility with Big Brother, so it is possible to migrate from Big Brother to Xymon without too much trouble. Migrating to Xymon will give you a significant performance boost, and provide you with much more advanced monitoring. The Xymon tools are designed for installations that need to monitor a large number of hosts, with very little overhead on the monitoring server. Monitoring of thousands of hosts with a single Xymon server is possible - it was developed to handle just this task. .SH FEATURES These are some of the core features in Xymon: .IP "Monitoring of hosts and networks" Xymon collects information about your systems in two ways: From querying network services (Web, LDAP, DNS, Mail etc.), or from scripts that run either on the Xymon server or on the systems you monitor. The Xymon package includes a \fbXymon client\fR which you can install on the servers you monitor; it collects data about the CPU-load, disk- and memory-utilization, log files, network ports in use, file- and directory-information and more. All of the information is stored inside Xymon, and you can define conditions that result in alerts, e.g. if a network service stops responding, or a disk fills up. .IP "Centralized configuration" All configuration of Xymon is done on the Xymon server. Even when monitoring hundreds or thousands of hosts, you can control their configuration centrally on the Xymon server - so there is no need for you to login to a system just to change e.g. which processes are monitored. .IP "Works on all major platforms" The Xymon server works on all Unix-like systems, including Linux, Solaris, FreeBSD, AIX, HP-UX and others. The Xymon client supports all major Unix platforms, and there are other Open Source projects - e.g. BBWin, see http://bbwin.sourceforge.net/ - providing support for Microsoft Windows based systems. .IP "A simple, intuitive web-based front-end" "Green is good, red is bad". Using the Xymon web pages is as simple as that. The hosts you monitor can be grouped together in a way that makes sense in your organisation and presented in a tree-structure. The web pages use many techniques to convey information about the monitored systems, e.g. different icons can be used for recently changed statuses; links to sub-pages can be listed in multiple columns; different icons can be used for dial-up-tests or reverse-tests; selected columns can be dropped or unconditionally included on the web pages to eliminate unwanted information, or always include certain information; user-friendly names can be shown for hosts regardless of their true hostname. You can also have automatic links to on-line documentation, so information about your critical systems is just a click away. .IP "Integrated trend analysis, historical data and SLA reporting" Xymon stores trend- and availability-information about everything it monitors. So if you need to look at how your systems behave over time, Xymon has all of the information you need: Whether it is response times of your web pages during peak hours, the CPU utilization over the past 4 weeks, or what the availability of a site was compared to the SLA - it's all there inside Xymon. All measurements are tracked and made available in time-based graphs. When you need to drill down into events that have occurred, Xymon provides a powerful tool for viewing the event history for each status log, with overviews of when problems have occurred during the past and easy-to-use zoom-in on the event. For SLA reporting, You can configure planned downtime, agreed service availability level, service availability time and have Xymon generate availability reports directly showing the actual availability measured against the agreed SLA. Such reports of service availability can be generated on-the-fly, or pre-generated e.g. for monthly reporting. .IP "Role-based views" You can have multiple different views of the same hosts for different parts of the organisation, e.g. one view for the hardware group, and another view for the webmasters - all of them fed by the same test tools. If you have a dedicated Network Operations Center, you can configure precisely which alerts will appear on their monitors - e.g. a simple anomaly in the system log file need not trigger a call to 3rd-level support at 2 AM, but if the on-line shop goes down you do want someone to respond immediately. So you put the web-check for the on-line shop on the NOC monitor page, and leave out the log-file check. .IP "Also for the techies" The Xymon user-interface is simple, but engineers will also find lots of relevant information. E.g. the data that clients report to Xymon contain the raw output from a number of system commands. That information is available directly in Xymon, so an administrator no longer needs to login to a server to get an overview of how it is behaving - the very commands they would normally run have already been performed, and the results are on-line in Xymon. .IP "Easy to adapt to your needs" Xymon includes a lot of tests in the core package, but there will always be something specific to your setup that you would like to watch. Xymon allows you to write test scripts in your favorite scripting language and have the results show up as regular status columns in Xymon. You can trigger alerts from these, and even track trends in graphs just by a simple configuration setting. .IP "Real network service tests" The network test tool knows how to test most commonly used protocols, including HTTP, SMTP (e-mail), DNS, LDAP (directory services), and many more. When checking websites, it is possible to not only check that the web server is responding, but also that the response looks correct by matching the response against a pre-defined pattern or a check-sum. So you can test that a network service is really working and supplying the data you expect - not just that the service is running. Protocols that use SSL encryption such as https web sites are fully supported, and while checking such services the network tester will automatically run a check of the validity of the SSL server certificate, and warn about certificates that are about to expire. .IP "Highly configurable alerts" You want to know when something breaks. But you don't want to get flooded with alerts all the time. Xymon lets you define several criteria for when to send out an alert, so you only get alerts when there is really something that needs your attention right away. While you are handling an incident, you can tell Xymon about it so it stops sending more alerts, and so that everyone else can check with Xymon and know that the problem is being taken care of. .IP "Combined super-tests and test inter-dependencies" If a single test is not enough, combination tests can be defined that combine the result of several tests to a single status-report. So if you need to monitor that at least 3 out of 5 servers are running at any time, Xymon can do that for you and generate the necessary availability report. Tests can also be configured to depend on each other, so that when a critical router goes down you will get alerts only for the router - and not from the 200 hosts behind the router. .SH SECURITY All of the Xymon server tools run under an unprivileged user account. A single program - the .I xymonping(1) network connectivity tester - must be installed setuid-root, but has been written so that it drops all root privileges immediately after performing the operation that requires root privileges. It is recommended that you setup a dedicated account for Xymon. Communications between the Xymon server and Xymon clients use the Big Brother TCP port 1984. If the Xymon server is located behind a firewall, it must allow for inbound connections to the Xymon server on tcp port 1984. Normally, Xymon clients - i.e. the servers you are monitoring - must be permitted to connect to the Xymon server on this port. However, if that is not possible due to firewall policies, then Xymon includes the .I xymonfetch(8) and .I msgcache(8) tools to allows for a pull-style way of collecting data, where it is the Xymon server that initiates connections to the clients. The Xymon web pages are dynamically generated through CGI programs. Access to the Xymon web pages is controlled through your web server access controls, e.g. you can require a login through some form of HTTP authentication. .SH DEMONSTRATION SITE A site running this software can be seen at http://www.xymon.com/ .SH PREREQUISITES AND INSTALLATION You will need a Unix-like system (Linux, Solaris, HP-UX, AIX, FreeBSD, Mac OS X or similar) with a web server installed. You will also need a C compiler and some additional libraries, but many systems come with the required development tools and libraries pre-installed. The required libraries are: .sp .BR RRDtool This library is used to store and present trend-data. It is required. .sp .BR libpcre This library is used for advanced pattern-matching of text strings in configuration files. This library is required. .sp .BR OpenSSL This library is used for communication with SSL-enabled network services. Although optional, it is recommended that you install this for Xymon since many network tests do use SSL. .sp .BR OpenLDAP This library is used for testing LDAP servers. Use of this is optional. For more detailed information about Xymon system requirements and how to install Xymon, refer to the on-line documentation "Installing Xymon" available from the Xymon web server (via the "Help" menu), or from the "docs/install.html" file in the Xymon source archive. .SH "SUPPORT and MAILING LISTS" xymon@xymon.com is an open mailing list for discussions about Xymon. If you would like to participate, send an e-mail to \fBxymon-subscribe@xymon.com\fR to join the list, or visit http://lists.xymon.com/mailman/listinfo/xymon . An archive of the mailing list is available at http://lists.xymon.com/archive/ If you just want to be notified of new releases of Xymon, please subscribe to the xymon-announce mailing list. This is a moderated list, used only for announcing new Xymon releases. To be added to the list, send an e-mail to \fBxymon-announce-subscribe@xymon.com\fR or visit http://lists.xymon.com/mailman/listinfo/xymon-announce . .SH XYMON SERVER TOOLS These tools implement the core functionality of the Xymon server: .I xymond(8) is the core daemon that collects all reports about the status of your hosts. It uses a number of helper modules to implement certain tasks such as updating log files and sending out alerts: xymond_client, xymond_history, xymond_alert and xymond_rrd. There is also a xymond_filestore module for compatibility with Big Brother. .I xymond_channel(8) Implements the communication between the Xymon daemon and the other Xymon server modules. .I xymond_history(8) Stores historical data about the things that Xymon monitors. .I xymond_rrd(8) Stores trend data, which is used to generate graphs of the data monitored by Xymon. .I xymond_alert(8) handles alerts. When a status changes to a critical state, this module decides if an alert should be sent out, and to whom. .I xymond_client(8) handles data collected by the Xymon clients, analyzes the data and feeds back several status updates to Xymon to build the view of the client status. .I xymond_hostdata(8) stores historical client data when something breaks. E.g. when a web page stops responding xymond_hostdata will save the latest client data, so that you can use this to view a snapshot of how the system state was just prior to it failing. .SH XYMON NETWORK TEST TOOLS These tools are used on servers that execute tests of network services. .I xymonping(1) performs network connectivity (ping) tests. .I xymonnet(1) runs the network service tests. .I xymonnet-again.sh(1) is an extension script for re-doing failed network tests with a higher frequency than the normal network tests. This allows Xymon to pick up the recovery of a network service as soon as it happens, resulting in less downtime being recorded. .SH XYMON TOOLS HANDLING THE WEB USER-INTERFACE These tools take care of generating and updating the various Xymon web-pages. .I xymongen(1) takes care of updating the Xymon web pages. .I svcstatus.cgi(1) This CGI program generates an HTML view of a single status log. It is used to present the Xymon status-logs. .I showgraph.cgi(1) This CGI program generates graphs of the trend-data collected by Xymon. .I hostgraphs.cgi(1) When you want to combine multiple graphs into one, this CGI lets you combine graphs so you can e.g. compare the load on all of the nodes in your server farm. .I criticalview.cgi(1) Generates the Critical Systems view, based on the currently critical systems and the configuration of what systems and services you want to monitor when. .I history.cgi(1) This CGI program generates a web page with the most recent history of a particular host+service combination. .I eventlog.cgi(1) This CGI lets you view a log of events that have happened over a period of time, for a single host or test, or for multiple systems. .I ack.cgi(1) This CGI program allows a user to acknowledge an alert he received from Xymon about a host that is in a critical state. Acknowledging an alert serves two purposes: First, it stops more alerts from being sent so the technicians are not bothered wit more alerts, and secondly it provides feedback to those looking at the Xymon web pages that the problem is being handled. .I xymon-mailack(8) is a tool for processing acknowledgments sent via e-mail, e.g. as a response to an e-mail alert. .I enadis.cgi(8) is a CGI program to disable or re-enable hosts or individual tests. When disabling a host or test, you stop alarms from being sent and also any outages do not affect the SLA calculations. So this tool is useful when systems are being brought down for maintenance. .I findhost.cgi(1) is a CGI program that finds a given host in the Xymon web pages. As your Xymon installation grows, it can become difficult to remember exactly which page a host is on; this CGI script lets you find hosts easily. .I report.cgi(1) This CGI program triggers the generation of Xymon availability reports, using .I xymongen(1) as the reporting back-end engine. .I reportlog.cgi(1) This CGI program generates the detailed availability report for a particular host+service combination. .I snapshot.cgi(1) is a CGI program to build the Xymon web pages in a "snapshot" mode, showing the look of the web pages at a particular point in time. It uses .I xymongen(1) as the back-end engine. .I statusreport.cgi(1) is a CGI program reporting test results for a single status but for several hosts. It is used to e.g. see which SSL certificates are about to expire, across all of the Xymon web pages. .I csvinfo.cgi(1) is a CGI program to present information about a host. The information is pulled from a CSV (Comma Separated Values) file, which is easily exported from any spreadsheet or database program. .SH CLIENT-SIDE TOOLS .I logfetch(1) is a utility used by the Xymon Unix client to collect information from log files on the client. It can also monitor various other file-related data, e.g. file meta-data or directory sizes. .I clientupdate(1) Is used on Xymon clients, to automatically update the client software with new versions. Through this tool, updates of the client software can happen without an administrator having to logon to the server. .I msgcache(8) This tool acts as a mini Xymon server to the client. It stores client data internally, so that the .I xymonfetch(8) utility can pick it up later and send it to the Xymon server. It is typically used on hosts that cannot contact the Xymon server directly due to network- or firewall-restrictions. .SH XYMON COMMUNICATION TOOLS These tools are used for communications between the Xymon server and the Xymon clients. If there are no firewalls then they are not needed, but it may be necessary due to network or firewall issues to make use of them. .I xymonproxy(8) is a proxy-server that forwards Xymon messages between clients and the Xymon server. The clients must be able to talk to the proxy, and the proxy must be able to talk to the Xymon server. .I xymonfetch(8) is used when the client is not able to make outbound connections to neither xymonproxy nor the Xymon server (typically, for clients located in a DMZ network zone). Together with the .I msgcache(8) utility running on the client, the Xymon server can contact the clients and pick up their data. .SH OTHER TOOLS .I xymonlaunch(8) is a program scheduler for Xymon. It acts as a master program for running all of the Xymon tools on a system. On the Xymon server, it controls running all of the server tasks. On a Xymon client, it periodically launches the client to collect data and send them to the Xymon server. .I xymon(1) is the tool used to communicate with the Xymon server. It is used to send status reports to the Xymon server, through the custom Xymon/BB protocol, or via HTTP. It can be used to query the state of tests on the central Xymon server and retrieve Xymon configuration files. The server-side script .I xymoncgimsg.cgi(1) used to receive messages sent via HTTP is also included. .I xymoncmd(1) is a wrapper for the other Xymon tools which sets up all of the environment variables used by Xymon tools. .I xymongrep(1) is a utility for use by Xymon extension scripts. It allows an extension script to easily pick out the hosts that are relevant to a script, so it need not parse a huge hosts.cfg file with lots of unwanted test-specifications. .I xymoncfg(1) is a utility to dump the full .I hosts.cfg(5) file following any "include" statements. .I xymondigest(1) is a utility to compute message digest values for use in content checks that use digests. .I combostatus(1) is an extension script for the Xymon server, allowing you to build complicated tests from simpler Xymon test results. E.g. you can define a test that uses the results from testing your web server, database server and router to have a single test showing the availability of your enterprise web application. .I trimhistory(8) is a tool to trim the Xymon history logs. It will remove all log entries and optionally also the individual status-logs for events that happened before a given time. .SH VERSIONS Version 1 of bbgen was released in November 2002, and optimized the web page generation on Big Brother servers. Version 2 of bbgen was released in April 2003, and added a tool for performing network tests. Version 3 of bbgen was released in September 2004, and eliminated the use of several external libraries for network tests, resulting in a significant performance improvement. With version 4.0 released on March 30 2005, the project was de-coupled from Big Brother, and the name changed to Hobbit. This version was the first full implementation of the Hobbit server, but it still used the data collected by Big Brother clients for monitoring host metrics. Version 4.1 was released in July 2005 included a simple client for Unix. Log file monitoring was not implemented. Version 4.2 was released in July 2006, and includes a fully functional client for Unix. Version 4.3 was released in November 2010, and implemented the renaming of the project to Xymon. This name was already introduced in 2008 with a patch version of 4.2, but with version 4.3.0 this change of names was fully implemented. .SH COPYRIGHT Xymon is .br Copyright (C) 2002-2011 Henrik Storner .br Parts of the Xymon sources are from public-domain or other freely available sources. These are the the Red-Black tree implementation, and the MD5-, SHA1- and RIPEMD160-implementations. Details of the license for these is in the README file included with the Xymon sources. All other files are released under the GNU General Public License version 2, with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. See the file COPYING for details. .SH "SEE ALSO" xymond(8), xymond_channel(8), xymond_history(8), xymond_rrd(8), xymond_alert(8), xymond_client(8), xymond_hostdata(8), xymonping(1), xymonnet(1), xymonnet-again.sh(1), xymongen(1), svcstatus.cgi(1), showgraph.cgi(1), hostgraphs.cgi(1), criticalview.cgi(1), history.cgi(1), eventlog.cgi(1), ack.cgi(1), xymon-mailack(8), enadis.cgi(8), findhost.cgi(1), report.cgi(1), reportlog.cgi(1), snapshot.cgi(1), statusreport.cgi(1), csvinfo.cgi(1), logfetch(1), clientupdate(1), msgcache(8), xymonproxy(8), xymonfetch(8), xymonlaunch(8), xymon(1), xymoncgimsg.cgi(1), xymoncmd(1), xymongrep(1), xymoncfg(1), xymondigest(1), combostatus(1), trimhistory(8), hosts.cfg(5), tasks.cfg(5), xymonserver.cfg(5), alerts.cfg(5), analysis.cfg(5), client-local.cfg(5) xymon-4.3.30/common/xymondigest.c0000664000076400007640000000337012605347542017224 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon monitor message digest tool. */ /* */ /* This is used to implement message digest functions (MD5, SHA1 etc.) */ /* */ /* Copyright (C) 2003-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymondigest.c 7683 2015-10-08 02:05:22Z jccleaver $"; #include #include #include #include #include "libxymon.h" int main(int argc, char *argv[]) { FILE *fd; char buf[8192]; int buflen; digestctx_t *ctx; if (argc < 2) { printf("Usage: %s digestmethod [filename]\n", argv[0]); printf("\"digestmethod\" is \"md5\", \"sha1\", \"sha256\", \"sha512\", \"sha224\", \"sha384\", or \"rmd160\"\n"); return 1; } if ((ctx = digest_init(argv[1])) == NULL) { printf("Unknown message digest method %s\n", argv[1]); return 1; } if (argc > 2) fd = fopen(argv[2], "r"); else fd = stdin; if (fd == NULL) { printf("Cannot open file %s\n", argv[2]); return 1; } while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) { digest_data(ctx, buf, buflen); } printf("%s\n", digest_done(ctx)); return 0; } xymon-4.3.30/common/hosts.cfg.50000664000076400007640000016365413534041732016500 0ustar rpmbuildrpmbuild.TH HOSTS.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME hosts.cfg \- Main Xymon configuration file .SH SYNOPSIS .IP hosts.cfg .SH DESCRIPTION The .I hosts.cfg(5) file is the most important configuration file for all of the Xymon programs. This file contains the full list of all the systems monitored by Xymon, including the set of tests and other configuration items stored for each host. .SH FILE FORMAT Each line of the file defines a host. Blank lines and lines starting with a hash mark (#) are treated as comments and ignored. Long lines can be broken up by putting a backslash at the end of the line and continuing the entry on the next line. .sp The format of an entry in the hosts.cfg file is as follows: .br IP-address hostname # tag1 tag2 ... .sp The IP-address and hostname are mandatory; all of the tags are optional. Listing a host with only IP-address and hostname will cause a network test to be executed for the host - the connectivity test is enabled by default, but no other tests. The optional tags are then used to define which tests are relevant for the host, and also to set e.g. the time-interval used for availability reporting by .I xymongen(1) An example of setting up the hosts.cfg file is in the Xymon on-line documentation (from the Help menu, choose "Configuring Monitoring"). The following describes the possible settings in a hosts.cfg file supported by Xymon. .SH TAGS RECOGNIZED BY ALL TOOLS .IP "include filename" This tag is used to include another file into the hosts.cfg file at run-time, allowing for a large hosts.cfg file to be split up into more manageable pieces. The "filename" argument should point to a file that uses the same syntax as hosts.cfg. The filename can be an absolute filename (if it begins with a '/'), or a relative filename - relative file names are prefixed with the directory where the main hosts.cfg file is located (usually $XYMONHOME/etc/). You can nest include tags, i.e. a file that is included from the main hosts.cfg file can itself include other files. .IP "dispinclude filename" Acts like the "include" tag, but only for the xymongen tool. Can be used e.g. to put a group of hosts on multiple sub-pages, without having to repeat the host definitions. .IP "netinclude filename" Acts like the "include" tag, but only for the xymonnet tool. .IP "directory directoryname" This tag is used to include all files in the named directory. Files are included in alphabetical order. If there are sub- directories, these are recursively included also. The following files are ignored: Files that begin with a dot, files that end with a tilde, RCS files that end with ",v", RPM package manager files ending in ".rpmsave" or ".rpmnew", DPKG package manager files ending in ".dpkg\-new" or ".dpkg\-orig", and all special files (devices, sockets, pipes etc). .IP "optional include/directory" Both "include" and "directory" can be prefixed with the tag "optional", which will preven an error message being logged if the file or directory is not present on a system. .SH GENERAL PER-HOST OPTIONS .IP noclear Controls whether stale status messages go purple or clear when a host is down. Normally, when a host is down the client statuses ("cpu", "disk", "memory" etc) will stop updating - this would usually make them go "purple" which can trigger alerts. To avoid that, Xymon checks if the "conn" test has failed, and if that is true then the other tests will go "clear" instead of purple so you only get alerts for the "conn" test. If you do want the stale statuses to go purple, you can use the "noclear" tag to override this behaviour. Note that "noclear" also affects the behaviour of network tests; see below. .IP prefer When a single host is defined multiple time in the hosts.cfg file, xymongen tries to guess which definition is the best to use for the information used on the "info" column, or for the NOPROPRED and other xymongen-specific settings. Host definitions that have a "noconn" tag or an IP of 0.0.0.0 get lower priority. By using the "prefer" tag you tell xymongen that this host definition should be used. Note: This only applies to hosts that are defined multiple times in the hosts.cfg file, although it will not hurt to add it on other hosts as well. .IP multihomed Tell Xymon that data from the host can arrive from multiple IP-addresses. By default, Xymon will warn if it sees data for one host coming from different IP-addresses, because this usually indicates a mis-configuration of the hostname on at least one of the servers involved. Some hosts with multiple IP-addresses may use different IP's for sending data to Xymon, however. This tag disables the check of source IP when receiving data. .IP delayred=STATUSCOLUMN:DELAY[,STATUSCOLUMN:DELAY...] Usually, status changes happen immediately. This tag is used to defer an update to red for the STATUSCOLUMN status for DELAY minutes. E.g. with \fBdelayred=disk:10,cpu:30\fR, a red disk-status will not appear on the Xymon webpages until it has been red for at least 10 minutes. Note: Since most tests only execute once every 5 minutes, it will usually not make sense to set N to anything but a multiple of 5. The exception is network tests, since .I xymonnet\-again.sh(1) will re-run failed network tests once a minute for up to 30 minutes. .IP delayyellow=STATUSCOLUMN:DELAY[,STATUSCOLUMN:DELAY...] Same as \fBdelayred\fR, but defers the change to a yellow status. .SH XYMONGEN DISPLAY OPTIONS These tags are processed by the .I xymongen(1) tool when generating the Xymon webpages or reports. .IP "page NAME [Page-title]" This defines a page at the level below the entry page. All hosts following the "page" directive appear on this page, until a new "page", "subpage" or "subparent" line is found. .IP "subpage NAME [Page-title]" This defines a sub-page in the second level below the entry page. You must have a previous "page" line to hook this sub-page to. .IP "subparent parentpage newpage [Page-title]" This is used to define sub-pages in whatever levels you may wish. Just like the standard "subpage" tag, "subparent" defines a new Xymon web page; however with "subparent" you explicitly list which page it should go as a sub-page to. You can pick any page as the parent - pages, sub-pages or even other subparent pages. So this allows you to define any tree structure of pages that you like. E.g. with this in hosts.cfg: page USA United States subpage NY New York subparent NY manhattan Manhattan data centers subparent manhattan wallstreet Wall Street center you get this hierarchy of pages: USA (United States) NY (New York) manhattan (Manhattan data centers) wallstreet (Wall Street center) Note: The parent page must be defined before you define the subparent. If not, the page will not be generated, and you get a message in the log file. Note: xymongen is case-sensitive, when trying to match the name of the parent page. The inspiration for this came from Craig Cook's mkbb.pl script, and I am grateful to Craig for suggesting that I implement it in xymongen. The idea to explicitly list the parent page in the "subparent" tag was what made it easy to implement. .IP "vpage" .IP "vsubpage" .IP "vsubparent" These are page-definitions similar to the "page", "subpage" and "subparent" definitions. However, on these pages the rows are the tests, and the columns are the hosts (normal pages have it the other way around). This is useful if you have a very large number of tests for a few hosts, and prefer to have them listed on a page that can be scrolled vertically. .br Note that the "group" directives have no effect on these types of pages. .IP "group [group-title]" .IP "group\-compress [group-title]" Defines a group of hosts, that appear together on the web page, with a single header-line listing all of the columns. Hosts following the "group" line appear inside the group, until a new "group" or page-line is found. The two group-directives are handled identically by Xymon and xymongen, but both forms are allowed for backwards compatibility. .IP "group\-sorted [group-title]" Same as the "group" line, but will sort the hosts inside the group so they appear in strict lexicographic order. .IP "group\-only COLUMN1|COLUMN2|COLUMN3 [group-title]" Same as the "group" and "group\-compress" lines, but includes only the columns explicitly listed in the group. Any columns not listed will be ignored for these hosts. .IP "group\-except COLUMN1|COLUMN2|COLUMN3 [group-title]" Same as the "group\-only" lines, but includes all columns EXCEPT those explicitly listed in the group. Any columns listed will be ignored for these hosts - all other columns are shown. .IP "title Page, group or host title text" The "title" tag is used to put custom headings into the pages generated by xymongen, in front of page/subpage links, groups or hosts. The title tag operates on the next item in the hosts.cfg file following the title tag. If a title tag precedes a host entry, the title is shown just before the host is listed on the status page. The column headings present for the host will be repeated just after the heading. If a title tag precedes a group entry, the title is show just before the group on the status page. If a title tag precedes a page/subpage/subparent entry, the title text replaces the normal "Pages hosted locally" heading normally inserted by Xymon. This appears on the page that links to the sub-pages, not on the sub-page itself. To get a custom heading on the sub-page, you may want to use the "\-\-pagetext\-heading" when running .I xymongen(1) .IP NAME:hostname Overrides the default hostname used on the overview web pages. If "hostname" contains spaces, it must be enclosed in double quotes, e.g. NAME:"R&D Oracle Server" .IP CLIENT:hostname Defines an alias for a host, which will be used when identifying status messages. This is typically used to accommodate a local client that sends in status reports with a different hostname, e.g. if you use hostnames with domains in your Xymon configuration, but the client is a silly Window box that does not include the hostname. Or vice-versa. Whatever the reason, this can be used to match status reports with the hosts you define in your hosts.cfg file. It causes incoming status reports with the specified hostname to be filed using the hostname defined in hosts.cfg. .IP NOCOLUMNS:column[,column] Used to drop certain of the status columns generated by the Xymon client. \fBcolumn\fR is one of \fBcpu\fR, \fBdisk\fR, \fBfiles\fR, \fBmemory\fR, \fBmsgs\fR, \fBports\fR, \fBprocs\fR. This setting stops these columns from being updated for the host. Note: If the columns already exist, you must use the .I xymon(1) utility to \fBdrop\fR them, or they will go purple. .IP "COMMENT:Host comment" Adds a small text after the hostname on the web page. This can be used to describe the host, without completely changing its display-name as the NAME: tag does. If the comment includes whitespace, it must be in double-quotes, e.g. COMMENT:"Sun web server" .IP "DESCR:Hosttype:Description" Define some informational text about the host. The "Hosttype" is a text describing the type of this device - "router", "switch", "hub", "server" etc. The "Description" is an informational text that will be shown on the "Info" column page; this can e.g. be used to store information about the physical location of the device, contact persons etc. If the text contain whitespace, you must enclose it in double-quotes, e.g. DESCR:"switch:4th floor Marketing switch" .IP "CLASS:Classname" Force the host to belong to a specific class. Class-names are used when configuring log-file monitoring (they can be used as references in .I client\-local.cfg(5), .I analysis.cfg(5) and .I alerts.cfg(5) to group log file checks or alerts). Normally, class-names are controlled on the client by starting the Xymon client with the "\-\-class=Classname" option. If you specify it in the hosts.cfg file on the Xymon server, it overrides any class name that the client reports. If not set, then the host belongs to a class named by the operating system the Xymon client is running on. .IP dialup The keyword "dialup" for a host means that it is OK for it to be off-line - this should not trigger an alert. All network tests will go "clear" upon failure, and any missing reports from e.g. cpu- and disk-status will not go purple when they are not updated. .IP nonongreen Ignore this host on the "All non-green" page. Even if it has an active alert, it will not be included in the "All non-green" page. This also removes the host from the event-log display. .IP nodisp Ignore this host completely when generating the Xymon webpages. Can be useful for monitoring a host without having it show up on the webpages, e.g. because it is not yet in production use. Or for hiding a host that is shown only on a second pageset. .IP TRENDS:[*,][![graph,...]] Defines the RRD graphs to include in the "trends" column generated by xymongen. This option syntax is complex. .br If this option is not present, xymongen provides graphs matching the standard set of RRD files: la, disk, memory, users, vmstat, iostat, netstat, tcp, bind, apache, sendmail .br * If this option is specified, the list of graphs to include start out as being empty (no graphs). .br * To include all default graphs, use an asterisk. E.g. "TRENDS:*" .br * To exclude a certain graph, specify it prefixed with '!'. E.g. to see all graphs except users: "TRENDS:*,!users" .br * The netstat, vmstat and tcp graphs have many "subgraphs". Which of these are shown can be specified like this: "TRENDS:*,netstat:netstat2|netstat3,tcp:http|smtp|conn" This will show all graphs, but instead of the normal netstat graph, there will be two: The netstat2 and netstat3 graphs. Instead of the combined tcp graphs showing all services, there will be three: One for each of the http, conn and smtp services. .br .IP "COMPACT:COLUMN=COLUMN1|COLUMN2|COLUMN3[,ditto]" Collapses a series of statuses into a single column on the overview web page. .br .IP "INTERFACES:REGEXP" On systems with multiple network interfaces, the operating system may report a number of network interface where the statistics are of no interest. By default Xymon tracks and graphs the traffic on all network interfaces. This option defines a regular expression, and only those interfaces whose name matches the expression are tracked. .SH XYMON TAGS FOR THE CRITICAL SYSTEMS OVERVIEW PAGE \fBNOTE:\fR The "NK" set of tags is deprecated. They will be supported for Xymon 4.x, but will be dropped in version 5. It is recommended that you move your critical systems view to the .I criticalview.cgi(1) viewer, which has a separate configuration tool, .I criticaleditor.cgi(1) with more facilities than the NK tags in hosts.cfg. xymongen will create three sets of pages: The main page xymon.html, the all-non-green-statuses page (nongreen.html), and a specially reduced version of nongreen.html with only selected tests (critical.html). This page includes selected tests that currently have a red or yellow status. .IP NK:testname[,testname] NOTE: This has been deprecated, you should use .I criticalview.cgi(1) instead of the NK tag. Define the tests that you want included on the critical page. E.g. if you have a host where you only want to see the http tests on critical.html, you specify it as 12.34.56.78 www.acme.com # http://www.acme.com/ NK:http If you want multiple tests for a host to show up on the critical.html page, specify all the tests separated by commas. The test names correspond to the column names (e.g. https tests are covered by an "NK:http" tag). .IP NKTIME=day:starttime:endtime[,day:starttime:endtime] This tag limits the time when an active alert is presented on the NK web page. By default, tests with a red or yellow status that are listed in the "NK:testname" tag will appear on the NK page. However, you may not want the test to be shown outside of normal working hours - if, for example, the host is not being serviced during week-ends. You can then use the NKTIME tag to define the time periods where the alert will show up on the NK page. The time specification consists of .sp .BR day-of-week: \fBW\fR means Mon-Fri ("weekdays"), \fB*\fR means all days, \fB0\fR .. \fB6\fR = Sunday .. Saturday. Listing multiple days is possible, e.g. "60" is valid meaning "Saturday and Sunday". .sp .BR starttime: Time to start showing errors, must be in 24-hour clock format as HHMM hours/minutes. E.g. for 8 am enter "0800", for 9.30 pm enter "2130" .sp .BR endtime: Time to stop showing errors. If necessary, multiple periods can be specified. E.g. to monitor a site 24x7, except between noon and 1 pm, use NKTIME=*:0000:1159,*:1300:2359 The interval between start time and end time may cross midnight, e.g. \fB*:2330:0200\fR would be valid and have the same effect as \fB*:2330:2400,*:0000:0200\fR. .SH XYMON TAGS FOR THE WML (WAP) CARDS If xymongen is run with the "\-\-wml" option, it will generate a set of WAP-format output "cards" that can be viewed with a WAP-capable device, e.g. a PDA or cell-phone. .IP WML:[+|\-]testname[,[+|\-]testname] This tag determines which tests for this hosts are included in the WML (WAP) page. Syntax is identical to the NK: tag. The default set of WML tests are taken from the \-\-wml command line option. If no "WML:" tag is specified, the "NK:" tag is used if present. .SH XYMON STATUS PROPAGATION OPTIONS These tags affect how a status propagates upwards from a single test to the page and higher. This can also be done with the command-line options \-\-nopropyellow and \-\-nopropred, but the tags apply to individual hosts, whereas the command line options are global. .IP NOPROPRED:[+|\-]testname[,[+|\-]testname] This tag is used to inhibit a yellow or red status from propagating upwards - i.e. from a test status color to the (sub)page status color, and further on to xymon.html or nongreen.html If a host-specific tag begins with a '\-' or a '+', the host-specific tags are removed/added to the default setting from the command-line option. If the host-specific tag does not begin with a '+' or a '\-', the default setting is ignored for this host and the NOPROPRED applies to the tests given with this tag. E.g.: xymongen runs with "\-\-nopropred=ftp,smtp". "NOPROPRED:+dns,\-smtp" gives a NOPROPRED setting of "ftp,dns" (dns is added to the default, smtp is removed). "NOPROPRED:dns" gives a setting of "dns" only (the default is ignored). Note: If you set use the "\-\-nopropred=*" command line option to disable propagation of all alerts, you cannot use the "+" and "\-" methods to add or remove from the wildcard setting. In that case, do not use the "+" or "\-" setting, but simply list the required tests that you want to keep from propagating. .IP NOPROPYELLOW:[+|\-]testname[,[+|\-]testname] Similar to NOPROPRED: tag, but applies to propagating a yellow status upwards. .IP NOPROPPURPLE:[+|\-]testname[,[+|\-]testname] Similar to NOPROPRED: tag, but applies to propagating a purple status upwards. .IP NOPROPACK:[+|\-]testname[,[+|\-]testname] Similar to NOPROPRED: tag, but applies to propagating an acknowledged status upwards. .SH XYMON AVAILABILITY REPORT OPTIONS These options affect the way the Xymon availability reports are processed (see .I report.cgi(1) for details about availability reports). .IP REPORTTIME=day:starttime:endtime[,day:starttime:endtime] This tag defines the time interval where you measure uptime of a service for reporting purposes. When xymongen generates a report, it computes the availability of each service - i.e. the percentage of time that the service is reported as available (meaning: not red). By default, this calculation is done on a 24x7 basis, so no matter when an outage occurs, it counts as downtime. The REPORTTIME tag allows you to specify a period of time other than 24x7 for the service availability calculation. If you have systems where you only guarantee availability from e.g. 7 AM to 8 PM on weekdays, you can use .br REPORTTIME=W:0700:2000 .br and the availability calculation will only be performed for the service with measurements from this time interval. The syntax for REPORTTIME is the same as the one used by the NKTIME parameter. When REPORTTIME is specified, the availability calculation happens like this: * Only measurements done during the given time period is used for the calculation. .br * "blue" time reduces the length of the report interval, so if you are generating a report for a 10-hour period and there are 20 minutes of "blue" time, then the availability calculation will consider the reporting period to be 580 minutes (10 hours minus 20 minutes). This allows you to have scheduled downtime during the REPORTTIME interval without hurting your availability; this is (I believe) the whole idea of the downtime being "planned". .br * "red" and "clear" status counts as downtime; "yellow" and "green" count as uptime. "purple" time is ignored. The availability calculation correctly handles status changes that cross into/out of a REPORTTIME interval. If no REPORTTIME is given, the standard 24x7 calculation is used. .IP WARNPCT:percentage Xymon's reporting facility uses a computed availability threshold to color services green (100% available), yellow (above threshold, but less than 100%), or red (below threshold) in the reports. This option allows you to set the threshold value on a host-by-host basis, instead of using a global setting for all hosts. The threshold is defined as the percentage of the time that the host must be available, e.g. "WARNPCT:98.5" if you want the threshold to be at 98.5% .IP "noflap[=test1,test2,...]" Disable flap detection for this host, or for specific tests on this host. Flap detection is globally controlled by options given to xymond on the command line, but, if enabled, it can be disabled using this option. .SH NETWORK TEST SETTINGS .IP testip By default, Xymon will perform a name lookup of the hostname to get the IP address it will use for network tests. This tag causes Xymon to use the IP listed in the hosts.cfg file. .IP NET:location This tag defines the host as being tested from a specific location. If xymonnet sees that the environment variable XYMONNETWORK is set, it will only test the hosts that have a matching "NET:location" tag in the hosts.cfg file. So this tag is useful if you have more than one system running network tests, but you still want to keep a consolidated hosts.cfg file for all your systems. Note: The "\-\-test\-untagged" option modifies this behaviour, see .I xymonnet(1) .IP noclear Some network tests depend on others. E.g. if the host does not respond to ping, then there's a good chance that the entire host is down and all network tests will fail. Or if the http server is down, then any web content checks are also likely to fail. To avoid floods of alerts, the default behaviour is for xymonnet to change the status of these tests that fail because of another problem to "clear" instead of "red". The "noclear" tag disables this behaviour and causes all failing tests to be reported with their true color. This behaviour can also be implemented on a per-test basis by putting the "~" flag on any network test. Note that "noclear" also affects whether stale status messages from e.g. a client on the host go purple or clear when the host is down; see the "noclear" description in the "GENERAL PER-HOST OPTIONS" section above. .IP nosslcert Disables the standard check of any SSL certificates for this host. By default, if an SSL-enabled service is tested, a second test result is generated with information about the SSL certificate - this tag disables the SSL certificate checks for the host. .IP "ssldays=WARNDAYS:ALARMDAYS" Define the number of days before an SSL certificate expires, in which the sslcert status shows a warning (yellow) or alarm (red) status. These default to the values from the "\-\-sslwarn" and "\-\-sslalarm" options for the .I xymonnet(1) tool; the values specified in the "ssldays" tag overrides the default. .IP "sslbits=MINIMUMKEYBITS" Enable checking of the encryption strength of the SSL protocol offered by the server. If the server offers encryption using a key with fewer than MINIMUMKEYBITS bits, the "sslcert" test will go red. E.g. to check that your server only uses strong encryption (128 bits or better), use "sslbits=128". .IP sni .IP nosni Enables or disables use of SNI (Server Name Indication) for SSL tests. Some SSL implementations cannot handle SSL handshakes with SNI data, so Xymon by default does not use SNI. This default can be changed with the "--sni" option for .I xymonnet(1) but can also be managed per host with these tags. SNI support was added in Xymon 4.3.13, where the default was to use SNI. This was changed in 4.3.14 so SNI support is disabled by default, and the "sni" and "nosni" tags were introduced together with the "--sni" option for xymonnet. .IP DOWNTIME=day:starttime:endtime[,day:starttime:endtime] .IP DOWNTIME=columns:day:starttime:endtime:cause[,columns:day:starttime:endtime:cause] This tag can be used to ignore failed checks during specific times of the day - e.g. if you run services that are only monitored e.g. Mon-Fri 8am-5pm, or you always reboot a server every Monday between 5 and 6 pm. What happens is that if a test fails during the specified time, it is reported with status BLUE instead of red, yellow, or purple. Thus you can still see when the service was unavailable, but alarms will not be triggered and the downtime is not counted in the availability calculations generated by the Xymon reports. The "columns" and "cause" settings are optional, but both or neither must be specified. "columns" may be a comma-separated list of status columns to which DOWNTIME will apply. The "cause" string will be displayed on the status web page to explain why the system is down. The syntax for DOWNTIME is the same as the one used by the NKTIME parameter. .IP SLA=day:starttime:endtime[,day:starttime:endtime] This tag is now deprecated. Use the DOWNTIME tag instead. This tag works the opposite of the DOWNTIME tag - you use it to specify the periods of the day that the service should be green. Failures OUTSIDE the SLA interval are reported as blue. .IP depends=(testA:host1/test1,host2/test2),(testB:host3/test3),[...] This tag allows you to define dependencies between tests. If "testA" for the current host depends on "test1" for host "host1" and test "test2" for "host2", this can be defined with depends=(testA:host1/test1,host2/test2) When deciding the color to report for testA, if either host1/test1 failed or host2/test2 failed, if testA has failed also then the color of testA will be "clear" instead of red or yellow. Since all tests are actually run before the dependencies are evaluated, you can use any host/test in the dependency - regardless of the actual sequence that the hosts are listed, or the tests run. It is also valid to use tests from the same host that the dependency is for. E.g. 1.2.3.4 foo # http://foo/ webmin depends=(webmin:foo/http) is valid; if both the http and the webmin tests fail, then webmin will be reported as clear. Note: The "depends" tag is evaluated by xymonnet while running the network tests. It can therefore only refer to other network tests that are handled by the same server - there is currently no way to use the e.g. the status of locally run tests (disk, cpu, msgs) or network tests from other servers in a dependency definition. Such dependencies are silently ignored. .IP badTEST[\-weekdays\-starttime\-endtime]:x:y:z NOTE: This has been deprecated, use the \fBdelayred\fR and \fBdelayyellow\fR settings instead. Normally when a network test fails, the status changes to red immediately. With a "badTEST:x:y:z" tag this behaviour changes: .br * While "z" or more successive tests fail, the column goes RED. .br * While "y" or more successive tests fail, but fewer than "z", the column goes YELLOW. .br * While "x" or more successive tests fail, but fewer than "y", the column goes CLEAR. .br * While fewer than "x" successive tests fail, the column stays GREEN. The optional time specification can be used to limit this "badTEST" setting to a particular time of day, e.g. to require a longer period of downtime before raising an alarm during out-of-office hours. The time-specification uses: .br * Weekdays: The weekdays this badTEST tag applies, from 0 (Sunday) through 6 (Saturday). Putting "W" here counts as "12345", i.e. all working days. Putting "*" here counts as all days of the week, equivalent to "0123456". .br * start time and end time are specified using 24-hour clocks, e.g. "badTEST\-W\-0900\-2000" is valid for working days between 9 AM (09:00) and 8 PM (20:00). When using multiple badTEST tags, the LAST one specified with a matching time-spec is used. Note: The "TEST" is replaced by the name of the test, e.g. 12.34.56.78 www.foo.com # http://www.foo.com/ badhttp:1:2:4 defines a http test that goes "clear" after the first failure, "yellow" after two successive failures, and "red" after four successive failures. For LDAP tests using URL's, use the option "badldapurl". For the other network tests, use "badftp", "badssh" etc. .SH CONNECTIVITY (PING) TEST These tags affect the behaviour of the xymonnet connectivity test. .IP noping Disables the ping-test, but will keep the "conn" column on the web display with a notice that it has been disabled. .IP noconn Disables the ping-test, and does not put a "conn" column on the web display. .IP conn The "conn" test (which does a ping of the host) is enabled for all hosts by default, and normally you just want to disable it using "noconn" or "noping". However, on the rare occasion where you may want to check that a host is NOT up, you can specify it as an explicit test, and use the normal test modifiers, e.g. "!conn" will be green when the host is NOT up, and red if it does appear on the network. The actual name of the tag - "conn" by default - depends on the "\-\-ping=TESTNAME" option for xymonnet, as that decides the testname for the connectivity test. .IP "conn={best,|worst,}IP1[,IP2...]" This adds additional IP-addresses that are pinged during the normal "conn" test. So the normal "conn" test must be enabled (the default) before this tag has any effect. The IP-addresses listed here are pinged in addition to the main IP-address. When multiple IP's are pinged, you can choose if ALL IP's must respond (the "worst" method), or AT LEAST one IP must respond (the "best" setting). All of the IP's are reported in a single "conn" status, whose color is determined from the result of pinging the IP's and the best/worst setting. The default method is "best" - so it will report green if just one of the IP's respond to ping. .IP badconn[\-weekdays\-starttime\-endtime]:x:y:z This is taken directly from the "fping.sh" connectivity- testing script, and is used by xymonnet when it runs with ping testing enabled (the default). See the description of the "badTEST" tag. .IP route:router1,router2,.... This tag is taken from the "fping.sh" script, and is used by xymonnet when run with the "\-\-ping" option to enable ping testing. The router1,router2,... is a comma-separated list of hosts elsewhere in the hosts.cfg file. You cannot have any spaces in the list - separate hosts with commas. This tag changes the color reported for a ping check that fails, when one or more of the hosts in the "route" list is also down. A "red" status becomes "yellow" - other colors are unchanged. The status message will include information about the hosts in the router-list that are down, to aid tracking down which router is the root cause of the problem. Note: Internally, the ping test will still be handled as "failed", and therefore any other tests run for this host will report a status of "clear". .IP route_LOCATION:router1,router2,... If the XYMONNETWORK environment variable is defined, a tag of "route_XYMONNETWORK:" is recognized by xymonnet with the same effect as the normal "route:" tag (see above). This allows you to have different route: tags for each server running xymonnet. The actual text for the tag then must match the value you have for the XYMONNETWORK setting. E.g. with XYMONNETWORK=dmz, the tag becomes "route_dmz:" .IP "trace" If the connectivity test fails, run a "traceroute" and include the output from this in the status message from the failed connectivity test. Note: For this to work, you may have to define the TRACEROUTE environment variable, see .I xymonserver.cfg(5) .IP "notrace" Similar to the "trace" option, this disables the running of a traceroute for the host after a failed connectivity test. It is only used if running traceroute is made the default via the \-\-trace option. .SH SIMPLE NETWORK TESTS These tests perform a simple network test of a service by connecting to the port and possibly checking that a banner is shown by the server. How these tests operate are configured in the .I protocols.cfg(5) configuration file, which controls which port to use for the service, whether to send any data to the service, whether to check for a response from the service etc. You can modify the behaviour of these tests on a per-test basis by adding one or more modifiers to the test: \fB:NUMBER\fR changes the port number from the default to the one you specify for this test. E.g. to test ssh running on port 8022, specify the test as \fBssh:8022\fR. \fB:s\fR makes the test silent, i.e. it does not send any data to the service. E.g. to do a silent test of an smtp server, enter \fBsmtp:s\fR. You can combine these two: \fBftp:8021:s\fR is valid. If you must test a service from a multi-homed host (i.e. using a specific source IP-address instead of the one your operating system provides), you can use the modifier "@IPADDRESS" at the end of the test specification, \fBafter\fR any other modifiers or port number. "IPADDRESS" must be a valid dotted IP-address (not hostname) which is assigned to the host running the network tests. The name of the test also determines the column name that the test result will appear with in the Xymon webpages. By prefixing a test with "!" it becomes a reverse test: Xymon will expect the service NOT to be available, and send a green status if it does NOT respond. If a connection to the service succeeds, the status will go red. By prefixing a test with "?" errors will be reported with a "clear" status instead of red. This is known as a test for a "dialup" service, and allows you to run tests of hosts that are not always online, without getting alarms while they are off-line. .IP "ftp ssh telnet smtp pop3 imap nntp rsync clamd oratns qmtp qmqp" These tags are for testing services offering the FTP, Secure Shell (ssh), SMTP, POP3, IMAP, NNTP, rsync, CLAM anti-virus daemon (clamd), Oracle TNS listener (oratns), qmail QMTP and QMQP protocols. .IP "ftps telnets smtps pop3s imaps nntps" These tags are for testing of the SSL-tunneled versions of the standard ftp, telnet, smtp, pop3, imap and nntp protocols. If Xymon was configured with support for SSL, you can test these services like any other network service - xymonnet will setup an SSL-encrypted session while testing the service. The server certificate is validated and information about it sent in the "sslcert" column. Note that smtps does not have a standard port number assignment, so you will need to enter this into the protocols.cfg file or your /etc/services file. .IP bbd Test that a Big Brother compatible daemon is running. This check works both for the Xymon .I xymond(8) daemon, and the original Big Brother bbd daemon. .SH DNS SERVER TESTS These tags are used to setup monitoring of DNS servers. .IP dns Simple DNS test. It will attempt to lookup the A record for the hostname of the DNS server. .IP dig This is an alias for the "dns" test. In xymonnet, the "dns" and "dig" tests are handled identically, so all of the facilities for testing described for the "dns" test are also available for the "dig" test. .IP "dns=hostname" .IP "dns=TYPE:lookup[,TYPE:lookup...] The default DNS tests will attempt a DNS lookup of the DNS' servers own hostname. You can specify the hostname to lookup on a DNS server by listing it on each test. The second form of the test allows you to perform multiple queries of the DNS server, requesting different types of DNS records. The TYPE defines the type of DNS data: A (IP-address), MX (Mail eXchanger), PTR (reverse), CNAME (alias), SOA (Start-Of-Authority), NS (Name Server) are among the more common ones used. The "lookup" is the query. E.g. to lookup the MX records for the "foo.com" domain, you would use "dns=mx:foo.com". Or to lookup the nameservers for the "bar.org" domain, "dns=ns:bar.org". You can list multiple lookups, separated by commas. For the test to end up with a green status, all lookups must succeed. .SH OTHER NETWORK TESTS .IP ntp Check for a running NTP (Network Time Protocol) server on this host. This test uses the "ntpdate" utility to check for a NTP server - you should either have ntpdate in your PATH, or set the location of the ntpdate program in $XYMONHOME/etc/xymonserver.cfg .IP rpc[=rpcservice1,rpcservice2,...] Check for one or more available RPC services. This check is indirect in that it only queries the RPC Portmapper on the host, not the actual service. If only "rpc" is given, the test only verifies that the port mapper is available on the remote host. If you want to check that one or more RPC services are registered with the port mapper, list the names of the desired RPC services after the equals-sign. E.g. for a working NFS server the "mount", "nlockmgr" and "nfs" services must be available; this can be checked with "rpc=mount,nlockmgr,nfs". This test uses the rpcinfo tool for the actual test; if this tool is not available in the PATH of xymonnet, you must define the RPCINFO environment variable to point at this tool. See .I xymonserver.cfg(5) .SH HTTP TESTS Simple testing of a http URL is done simply by putting the URL into the hosts.cfg file. Note that this only applies to URL's that begin with "http:" or "https:". The following items describe more advanced forms of http URL's. .IP "Basic Authentication with username/password" If the URL requires authentication in the form of a username and password, it is most likely using the HTTP "Basic" authentication. xymonnet support this, and you can provide the username and password either by embedding them in the URL e.g. .br http://USERNAME:PASSWORD@www.sample.com/ .br or by putting the username and password into the ~/.netrc file (see .I ftp(1) for details). .IP "Authentication with SSL client certificates" An SSL client certificate can be used for authentication. To use this, the client certificate must be stored in a PEM-formatted file together with the client certificate key, in the $XYMONHOME/certs/ directory. The URL is then given as .br http://CERT:FILENAME@www.sample.com/ .br The "CERT:" part is literal - i.e. you write C-E-R-T-colon and then the filename of the PEM-formatted certificate. .br A PEM-formatted certificate file can be generated based on certificates stored in Microsoft Internet Explorer and OpenSSL. Do as follows: .br From the MSIE Tools-Options menu, pick the Content tab, click on Certificates, choose the Personal tab, select the certificate and click Export. Make sure you export the private key also. In the Export File Format, choose PKCS 12 (.PFX), check the "Include all certificates" checkbox and uncheck the "Enable strong protection". Provide a temporary password for the exported file, and select a filename for the PFX-file. .br Now run "openssl pkcs12 \-in file.pfx \-out file.pem". When prompted for the "Import Password", provide the temporary password you gave when exporting the certificate. Then provide a "PEM pass phrase" (twice) when prompted for one. .br The file.pem file is the one you should use in the FILENAME field in the URL - this file must be kept in $XYMONHOME/certs/. The PEM pass phrase must be put into a file named the same as the certificate, but with extension ".pass". E.g. if you have the PEM certificate in $XYMONHOME/certs/client.pem, you must put the pass phrase into the $XYMONHOME/certs/client.pass file. Make sure to protect this file with Unix permissions, so that only the user running Xymon can read it. .IP "Forcing an HTTP or SSL version" Some SSL sites will only allow you to connect, if you use specific "dialects" of HTTP or SSL. Normally this is auto-negotiated, but experience shows that this fails on some systems. xymonnet can be told to use specific dialects, by adding one or more "dialect names" to the URL scheme, i.e. the "http" or "https" in the URL: * "2", e.g. https2://www.sample.com/ : use only SSLv2 .br * "3", e.g. https3://www.sample.com/ : use only SSLv3 .br * "t", e.g. httpst://www.sample.com/ : use only TLSv1.0 .br * "a", e.g. httpsa://www.sample.com/ : use only TLSv1.0 .br * "b", e.g. httpsb://www.sample.com/ : use only TLSv1.1 .br * "c", e.g. httpsc://www.sample.com/ : use only TLSv1.2 .br * "m", e.g. httpsm://www.sample.com/ : use only 128-bit ciphers .br * "h", e.g. httpsh://www.sample.com/ : use only >128-bit ciphers .br * "10", e.g. http10://www.sample.com/ : use HTTP 1.0 .br * "11", e.g. http11://www.sample.com/ : use HTTP 1.1 These can be combined where it makes sense, e.g to force TLS1.2 and HTTP 1.0 you would use "httpsc10". Note that SSLv2 support is disabled in all current OpenSSL releases. TLS version-specific scheme testing requires OpenSSL 1.0.1 or higher. .IP "Testing sites by IP-address" xymonnet ignores the "testip" tag normally used to force a test to use the IP-address from the hosts.cfg file instead of the hostname, when it performs http and https tests. The reason for this is that it interacts badly with virtual hosts, especially if these are IP-based as is common with https-websites. Instead the IP-address to connect to can be overridden by specifying it as: http://www.sample.com=1.2.3.4/index.html The "=1.2.3.4" will case xymonnet to run the test against the IP-address "1.2.3.4", but still trying to access a virtual website with the name "www.sample.com". The "=ip.address.of.host" must be the last part of the hostname, so if you need to combine this with e.g. an explicit port number, it should be done as http://www.sample.com:3128=1.2.3.4/index.html .IP "HTTP Testing via proxy" \fBNOTE:\fR This is not enabled by default. You must add the "\-\-bb\-proxy\-syntax" option when running .I xymonnet(1) if you want to use this. xymonnet supports the Big Brother syntax for specifying an HTTP proxy to use when performing http tests. This syntax just joins the proxy- and the target-URL into one, e.g. .br http://webproxy.sample.com:3128/http://www.foo.com/ .br would be the syntax for testing the www.foo.com website via the proxy running on "webproxy.sample.com" port 3128. If the proxy port number is not specified, the default HTTP port number (80) is used. If your proxy requires authentication, you can specify the username and password inside the proxy-part of the URL, e.g. .br http://fred:Wilma1@webproxy.sample.com:3128/http://www.foo.com/ .br will authenticate to the proxy using a username of "fred" and a password of "Wilma1", before requesting the proxy to fetch the www.foo.com homepage. Note that it is not possible to test https-sites via a proxy, nor is it possible to use https for connecting to the proxy itself. .IP cont[=COLUMN];URL;[expected_data_regexp|#digesttype:digest] This tag is used to specify a http/https check, where it is also checked that specific content is present in the server response. If the URL itself includes a semi-colon, this must be escaped as '%3B' to avoid confusion over which semicolon is part of the URL, and which semicolon acts as a delimiter. The data that must be returned can be specified either as a regular expression (except that is not allowed) or as a message digest (typically using an MD5 sum or SHA-1 hash). The regex is pre-processed for backslash "\\" escape sequences. So you can really put any character in this string by escaping it first: .br \\n Newline (LF, ASCII 10 decimal) .br \\r Carriage return (CR, ASCII 13 decimal) .br \\t TAB (ASCII 8 decimal) .br \\\\ Backslash (ASCII 92 decimal) .br \\XX The character with ASCII hex-value XX .br If you must have whitespace in the regex, use the [[:space:]] syntax, e.g. if you want to test for the string "All is OK", use "All[[:space:]]is[[:space:]]OK". Note that this may depend on your particular implementation of the regex functions found in your C library. Thanks to Charles Goyard for this tip. Note: If you are migrating from the "cont2.sh" script, you must change the '_' used as wildcards by cont2.sh into '.' which is the regular-expression wildcard character. Message digests can use whatever digest algorithms your libcrypto implementation (usually OpenSSL) supports. Common message digests are "md5", "sha1", "sha256" or "sha512". The digest is calculated on the data portion of the response from the server, i.e. HTTP headers are not included in the digest (as they change from one request to the next). The expected digest value can be computed with the .I xymondigest(1) utility. "cont" tags in hosts.cfg result in two status reports: One status with the "http" check, and another with the "content" check. As with normal URL's, the extended syntax described above can be used e.g. when testing SSL sites that require the use of SSLv2 or strong ciphers. The column name for the result of the content check is by default called "content" - you can change the default with the "\-\-content=NAME" option to xymonnet. See .I xymonnet(1) for a description of this option. If more than one content check is present for a host, the first content check is reported in the column "content", the second is reported in the column "content1", the third in "content2" etc. You can also specify the column name directly in the test specification, by writing it as "cont=COLUMN;http://...". Column-names cannot include whitespace or semi-colon. The content-check status by default includes the full URL that was requested, and the HTML data returned by the server. You can hide the HTML data on a per-host (not per-test) basis by adding the \fBHIDEHTTP\fR tag to the host entry. .IP content=URL This syntax is deprecated. You should use the "cont" tag instead, see above. .IP post[=COLUMN];URL;form\-data;[expected_data_regexp|#digesttype:digest] This tag can be used to test web pages, that use an input form. Data can be posted to the form by specifying them in the form-data field, and the result can be checked as if it was a normal content check (see above for a description of the cont-tag and the restrictions on how the URL must be written). The form-data field must be entered in "application/x\-www\-form\-urlencoded" format, which is the most commonly used format for web forms. E.g. if you have a web form defined like this:
.br

Given name

.br

Surname

.br .br
and you want to post the value "John" to the first field and "Doe Jr." to the second field, then the form data field would be givenname=John&surname=Doe+Jr. Note that any spaces in the input value is replaced with '+'. If your form-data requires a different content-type, you can specify it by beginning the form-data with \fB(content\-type=TYPE)\fR, e.g. "(content\-type=text/xml)" followed by the POST data. Note that as with normal forms, the POST data should be specified using escape-sequences for reserved characters: "space" should be entered as "\\x20", double quote as "\\x22", newline as "\\n", carriage-return as "\\r", TAB as "\\t", backslash as "\\\\". Any byte value can be entered using "\\xNN" with NN being the hexadecimal value, e.g. "\\x20" is the space character. The [expected_data_regexp|#digesttype:digest] is the expected data returned from the server in response to the POST. See the "cont;" tag above for details. If you are only interested in knowing if it is possible to submit the form (but don't care about the data), this can be an empty string - but the ';' at the end is required. .IP nocont[=COLUMN];URL;forbidden_data_regexp This tag works just like "cont" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message. .IP nopost[=COLUMN];URL;form\-data;expected_data_regexp This tag works just like "post" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message. .IP type[=COLUMN];URL;expected_content_type This is a variant of the content check - instead of checking the content data, it checks the type of the data as given by the HTTP Content\-Type: header. This can used to check if a URL returns e.g. a PDF file, regardless of what is inside the PDF file. .IP soap[=COLUMN];URL;SOAPMESSAGE;[expected_data_regexp|#digesttype:digest] Send SOAP message over HTTP. This is identical to the "cont" test, except that the request sent to the server uses a Content\-type of "application/soap+xml", and it also sends a "SOAPAction" header with the URL. SOAPMESSAGE is the SOAP message sent to the server. Since SOAP messages are usually XML documents, you can store this in a separate file by specifying "file:FILENAME" as the SOAPMESSAGE parameter. E.g. a test specification of soap=echo;http://soap.foo.bar/baz?wsdl;file:/home/foo/msg.xml;. will read the SOAP message from the file /home/foo/msg.xml and post it to the URL http://soap.foo.bar/bas?wsdl Note that SOAP XML documents usually must begin with the XML version line, \fB\fR .IP nosoap[=COLUMN];URL;SOAPMESSAGE;[forbidden_data_regexp|#digesttype:digest] This tag works just like "soap" tag, but reverses the test. It is green when the "forbidden_data_regexp" is NOT found in the response, and red when it IS found. So it can be used to watch for data that should NOT be present in the response, e.g. a server error message. .IP httphead[=COLUMN];URL This is used to perform an HTTP HEAD request instead of a GET. .IP httpstatus[=COLUMN];URL;okstatusexpr;notokstatusexpr This is used to explicitly test for certain HTTP statuscodes returned when the URL is requested. The \fBokstatusexpr\fR and \fBnokokstatusexpr\fR expressions are Perl-compatible regular expressions, e.g. "2..|302" will match all OK codes and the redirect (302) status code. If the URL cannot be retrieved, the status is "999". .IP HIDEHTTP The status display for HTTP checks usually includes the URL, and for content checks also the actual data from the web page. If you would like to hide these from view, then the HIDEHTTP tag will keep this information from showing up on the status webpages. .IP headermatch Content checks by default only search the HTML body returned by the webserver. This option causes it to also search the HTTP headers for the string that must / must not be present. .IP browser=BROWSERNAME By default, Xymon sends an HTTP "User\-Agent" header identifying it a "Xymon". Some websites require that you use a specific browser, typically Internet Explorer. To cater for testing of such sites, this tag can be used to modify the data sent in the User\-Agent header. .br E.g. to perform an HTTP test with Xymon masquerading as an Internet Explorer 6.0 browser, use \fBbrowser="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"\fR. If you do not know what the User\-Agent header should be, open up the browser that works with this particular site, and open the URL "javascript:document.writeln(navigator.userAgent)" (just copy this into the "Open URL" dialog. The text that shows up is what the browser sends as the User\-Agent header. .IP httphdr=STRING Xymon can be send additional headers when performing HTTP checks, to allow for validation of any custom configurations needed for your site. Note that this is a host-wide configuration. The string will be added directly to the headers for all URLs on that host. There is currently no way to have this occur only for specific URLs checked. .br The string should be encased in quotes, like \fBhttphdr="X-Requested-With: XMLHttpRequest"\fR. Newlines can be included, however the string MUST NOT end with a newline as that may cause premature ending of the headers sent. .SH LDAP (DIRECTORY SERVER) TESTS .IP ldap .IP ldaps Simple check for an LDAP service. This check merely looks for any service running on the ldap/ldaps service port, but does not perform any actual LDAP transaction. .IP ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] Check for an LDAP service by performing an LDAP request. This tag is in the form of an LDAP URI (cf. RFC 2255). This type of LDAP test requires that .I xymonnet(1) was built with support for LDAP, e.g. via the OpenLDAP library. The components of the LDAP URI are: .nf \fIhostport\fP is a host name with an optional ":portnumber" \fIdn\fP is the search base \fIattrs\fP is a comma separated list of attributes to request \fIscope\fP is one of these three strings: base one sub (default=base) \fIfilter\fP is filter \fIexts\fP are recognized set of LDAP and/or API extensions. .fi .IP ldaps://hostport/dn[?attrs[?scope[?filter[?exts]]]] LDAP service check using LDAPv3 and STARTTLS for talking to an LDAP server that requires TLS encryption. See .I xymonnet(1) for a discussion of the different ways of running LDAP servers with SSL/TLS, and which of these are supported by xymonnet. .IP ldaplogin=username:password Define a username and password to use when binding to the LDAP server for ldap URI tests. If not specified, xymonnet will attempt an anonymous bind. .IP ldapyellowfail Used with an LDAP URL test. If the LDAP query fails during the search of the directory, the ldap status is normally reported as "red" (alarm). This tag reduces a search failure to a "yellow" (warning) status. .SH PERFORMANCE MONITORING TESTS .IP apache[=URL] If you are running an Apache web server, adding this tag makes .I xymonnet(1) collect performance statistics from the Apache web server by querying the URL \fBhttp://IP.ADDRESS.OF.HOST/server\-status?auto\fR. The response is sent as a data-report and processed by the Xymon xymond_rrd module into an RRD file and an "apache" graph. If your web server requires e.g. authentication, or runs on a different URL for the server-status, you can provide the full URL needed to fetch the server-status page, e.g. \fBapache=http://LOGIN:PASSWORD@10.0.0.1/server\-status?auto\fR for a password protected server\-status page, or \fBapache=http://10.0.0.1:8080/apache/server\-status?auto\fR for a server listening on port 8080 and with a different path to the server-status page. Note that you need to enable the server-status URL in your Apache configuration. The following configuration is needed: .sp .br SetHandler server\-status .br Order deny,allow .br Deny from all .br allow from 127.0.0.1 .br .br ExtendedStatus On .sp Change "127.0.0.1" to the IP-address of the server that runs your network tests. .SH DEFAULT HOST If you have certain tags that you want to apply to all hosts, you can define a host name ".default." and put the tags on that host. Note that per-host definitions will override the default ones. To apply to all hosts this should be listed FIRST in your file. \fBNOTE:\fR The ".default." host entry will only accept the following tags - others are silently ignored: delayyellow, delayred, NOCOLUMNS, COMMENT, DESCR, CLASS, dialup, testip, nonongreen, nodisp, noinfo, notrends, noclient, TRENDS, NOPROPRED, NOPROPYELLOW, NOPROPPURPLE, NOPROPACK, REPORTTIME, WARNPCT, NET, noclear, nosslcert, ssldays, DOWNTIME, depends, noping, noconn, trace, notrace, HIDEHTTP, browser, pulldata. Specifically, note that network tests, "badTEST" settings, and alternate pageset relations cannot be listed on the ".default." host. .SH SENDING SUMMARIES TO REMOTE XYMON SERVERS .IP "summary ROW.COLUMN IP URL" If you have multiple Xymon servers, the "summary" directive lets you form a hierarchy of servers by sending the overall status of this server to a remote Xymon server, which then displays this in a special summary section. E.g. if your offices are spread over three locations, you can have a Xymon server at each office. These branch-office Xymon have a "summary" definition in their hosts.cfg file that makes them report the overall status of their branch Xymon to the central Xymon server you maintain at the corporate headquarters. Multiple "summary" definitions are allowed. The ROW.COLUMN setting defines how this summary is presented on the server that receives the summary. The ROW text will be used as the heading for a summary line, and the COLUMN defines the name of the column where this summary is shown - like the hostname and testname used in the normal displays. The IP is the IP-address of the \fBremote\fR (upstream) Xymon server, where this summary is sent). The URL is the URL of your \fBlocal\fR Xymon server. The URL need not be that of your Xymon server's main page - it could be the URL of a sub-page on the local Xymon server. Xymon will report the summary using the color of the page found at the URL you specify. E.g. on your corporate Xymon server you want a summary from the Las Vegas office - but you would like to know both what the overall status is, and what is the status of the servers on the critical Sales department back-office servers in Las Vegas. So you configure the Las Vegas Xymon server to send \fBtwo\fR summaries: .sp summary Vegas.All 10.0.1.1 http://vegas.foo.com/xymon/ .br summary Vegas.Sales 10.0.1.1 http://vegas.foo.com/xymon/sales/ .sp This gives you one summary line for Baltimore, with two columns: An "All" column showing the overall status, and a "Sales" column showing the status of the "sales" page on the Baltimore Xymon server. Note: Pages defined using alternate pageset definitions cannot be used, the URL must point to a web page from the default set of Xymon webpages. .SH OTHER TAGS .IP pulldata[=[IP][:port]] This option is recognized by the .I xymonfetch(8) utility, and causes it to poll the host for client data. The optional IP-address and port-number can be used if the client-side .I msgcache(8) daemon is listening on a non-standard IP-address or port-number. .SH FILES .BR ~xymon/server/etc/hosts.cfg .SH "SEE ALSO" xymongen(1), xymonnet(1), xymondigest(1), xymonserver.cfg(5), xymon(7) xymon-4.3.30/common/msgcache.80000664000076400007640000000533513534041732016346 0ustar rpmbuildrpmbuild.TH MSGCACHE 8 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME msgcache \- Cache client messages for later pickup by xymonfetch .SH SYNOPSIS .B "msgcache [options]" .SH DESCRIPTION \fBmsgcache\fR implements a Xymon message cache. It is intended for use with clients which cannot deliver their data to the Xymon server in the normal way. Instead of having the client tools connect to the Xymon server, msgcache runs locally and the client tools then deliver their data to the msgcache daemon. The msgcache daemon is then polled regularly by the .I xymonfetch(8) utility, which collects the client messages stored by msgcache and forwards them to the Xymon server. \fBNOTE:\fR When using msgcache, the \fBXYMSRV\fR setting for the clients should be \fBXYMSRV=127.0.0.1\fR instead of pointing at the real Xymon server. .SH RESTRICTIONS Clients delivering their data to msgcache instead of the real Xymon server will in general not notice this. Specifically, the client configuration data provided by the Xymon server when a client delivers its data is forwarded through the xymonfetch / msgcache chain, so the normal centralized client configuration works. However, other commands which rely on clients communicating directly with the Xymon server will not work. This includes the \fBconfig\fR and \fBquery\fR commands which clients may use to fetch configuration files and query the Xymon server for a current status. The \fBdownload\fR command also does not work with msgcache. This means that the automatic client update facility will not work for clients communicating via msgcache. .SH OPTIONS .IP "--listen=IPADDRESS[:PORT]" Defines the IP-address and portnumber where msgcache listens for incoming connections. By default, msgcache listens for connections on all network interfaces, port 1984. .IP "--server=IPADDRESS[,IPADDRESS]" Restricts which servers are allowed to pick up the cached messages. By default anyone can contact the msgcache utility and request all of the cached messages. This option allows only the listed servers to request the cached messages. .IP "--max-age=N" Defines how long cached messages are kept. If the message has not been picked up with N seconds after being delivered to msgcache, it is silently discarded. Default: N=600 seconds (10 minutes). .IP "--daemon" Run as a daemon, i.e. msgcache will detach from the terminal and run as a background task .IP "--no-daemon" Run as a foreground task. This option must be used when msgcache is started by .I xymonlaunch(8) which is the normal way of running msgcache. .IP "--pidfile=FILENAME" Store the process ID of the msgcache task in FILENAME. .IP "--logfile=FILENAME" Log msgcache output to FILENAME. .IP "--debug" Enable debugging output. .SH "SEE ALSO" xymonfetch(8), xymon(7) xymon-4.3.30/common/xymonclient.cfg.50000664000076400007640000000373613534041733017704 0ustar rpmbuildrpmbuild.TH XYMONCLIENT.CFG 5 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymonclient.cfg \- Xymon client environment variables .SH DESCRIPTION Xymon programs use multiple environment variables beside the normal set of variables. For the Xymon client, the environment definitions are stored in the ~xymon/client/etc/xymonclient.cfg file. Each line in this file is of the form \fBNAME=VALUE\fR and defines one environment variable NAME with the value VALUE. .SH SETTINGS .IP XYMSRV The IP-address used to contact the Xymon server. Default: Chosen when the Xymon client was compiled. .IP XYMSERVERS List of IP-addresses of Xymon servers. Data will be sent to all of the servers listed here. This setting is only used if XYMSRV=0.0.0.0. .IP XYMONDPORT The port number for used to contact the Xymon server. Default: 1984. .IP XYMONHOME The Xymon client top-level directory. Default: The $XYMONCLIENTHOME setting inherited from the "runclient.sh" script which starts the Xymon client. .IP XYMONCLIENTLOGS The directory for the Xymon clients' own log files. Default: $XYMONHOME/logs .IP XYMONTMP Directory used for temporary files. Default: $XYMONHOME/tmp/ .IP XYMON Full path to the .I xymon(1) client program. Default: $XYMONHOME/bin/xymon. .IP Commands Many extension scripts expect a series of environment variables to point at various system utilities. These are included in the file when the client is built. .SH INHERITED SETTINGS Some environment variables are inherited from the "runclient.sh" script which launches the Xymon client: .IP MACHINEDOTS The hostname of the local system. Default: Taken from "uname \-n". .IP MACHINE The hostname of the local system, with dots replaced by commas. For compatibility with Big Brother extension scripts. .IP SERVEROSTYPE The operating system of the local system, in lowercase. Default: taken from "uname \-s". .IP XYMONCLIENTHOME The top-level directory for the Xymon client. Default: The location of the "runclient.sh" script. .SH "SEE ALSO" xymon(7) xymon-4.3.30/common/orcaxymon.10000664000076400007640000000226713534041732016605 0ustar rpmbuildrpmbuild.TH ORCAXYMON 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME orcaxymon \- Xymon client utility to grab data from ORCA .SH SYNOPSIS .B "orcaxymon --orca=PREFIX [options]" .SH NOTICE This utility is included in the client distribution for Xymon 4.2. However, the backend module to parse the data it sends it \fBNOT\fR included in Xymon 4.2. It is possible to use the generic Xymon NCV data handler in .I xymond_rrd(8) to process ORCA data, if you have an urgent need to do so. .SH DESCRIPTION \fBorcaxymon\fR is an add-on tool for the Xymon client. It is used to grab data collected by the ORCA data collection tool (orcallator.se), and send it to the Xymon server in NCV format. orcaxymon should run from the client .I xymonlaunch(8) utility, i.e. there must be an entry in the .I clientlaunch.cfg(5) file for orcaxymon. .SH OPTIONS .IP "--orca=PREFIX" The filename prefix for the ORCA data log. Typically this is the directory for the ORCA logs, followed by "orcallator". The actual filename for the ORCA logs include a timestamp and sequence number, e.g. "orcallator-2006-06-20-000". This option is required. .IP "--debug" Enable debugging output. .SH "SEE ALSO" xymon(7), clientlaunch.cfg(5) xymon-4.3.30/common/xymon.10000664000076400007640000005004413534041732015734 0ustar rpmbuildrpmbuild.TH XYMON 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymon \- Xymon client communication program .SH SYNOPSIS .B "xymon [options] RECIPIENT message" .SH DESCRIPTION .I xymon(1) is the client program used to communicate with a Xymon server. It is frequently used by Xymon client systems to send in status messages and pager alerts on local tests. In Xymon, the xymon program is also used for administrative purposes, e.g. to rename or delete hosts, or to disable hosts that are down for longer periods of time. .SH OPTIONS AND PARAMETERS .IP "\-\-debug" Enable debugging. This prints out details about how the connection to the Xymon server is being established. .IP "\-\-proxy=http://PROXYSERVER:PROXYPORT/" When sending the status messages via HTTP, use this server as an HTTP proxy instead of connecting directly to the Xymon server. .IP "\-\-timeout=N" Specifies the timeout for connecting to the Xymon server, in seconds. The default is 5 seconds. .IP "\-\-response" The xymon utility normally knows when to expect a response from the server, so this option is not required. However, it will cause any response from the server to be displayed. .IP "\-\-merge" Merge the command line message text with the data provided on standard input, and send the result to the Xymon server. The message text provided on the command line becomes the first line of the merged message. .IP "RECIPIENT" The \fBRECIPIENT\fR parameter defines which server receives the message. If RECIPIENT is given as "0.0.0.0", then the message is sent to all of the servers listed in the XYMSERVERS environment variable. Usually, a client will use "$XYMSRV" for the \fBRECIPIENT\fR parameter, as this is defined for the client scripts to automatically contain the correct value. The \fBRECIPIENT\fR parameter may be a URL for a webserver that has the xymoncgimsg.cgi or similar script installed. This tunnels the Xymon messages to the Xymon server using standard HTTP protocol. The .I xymoncgimsg.cgi(8) CGI tool (included in Xymon) must be installed on the webserver for the HTTP transport to work. .br .IP MESSAGE The \fBmessage\fR parameter is the message to be sent across to the Xymon server. Messages must be enclosed in quotes, but by doing so they can span multiple lines. The maximum size of a message is defined by the maximum allowed length of your shell\(aqs command-line, and is typically 8-32 KB. If you need to send longer status messages, you can specify "@" as the message: xymon will then read the status message from its stdin. .SH XYMON MESSAGE SYNTAX This section lists the most commonly used messages in the Xymon protocol. Each message must begin with one of the Xymon commands. Where a HOSTNAME is specified, it must have any dots in the hostname changed to commas if the Xymon FQDN setting is enabled (which is the default). So the host "www.foo.com", for example, would report as "www,foo,com". .IP "status[+LIFETIME][/group:GROUP] HOSTNAME.TESTNAME COLOR " This sends in a status message for a single test (column) on a single host. TESTNAME is the name of the column where this test will show up; any name is valid except that using dots in the testname will not work. COLOR must be one of the valid colors: "green", "yellow", "red" or "clear". The colors "blue" and "purple" - although valid colors - should not be sent in a status message, as these are handled specially by the Xymon server. As a special case (for supporting older clients), "client" can be used as the name of the color. This causes the status message to be handled by Xymon as a "client" data message, and the TESTNAME parameter is used as the "collector id". .br The "additional text" normally includes a local timestamp and a summary of the test result on the first line. Any lines following the first one are free-form, and can include any information that may be useful to diagnose the problem being reported. .br The LIFETIME defines how long this status is valid after being received by the Xymon server. The default is 30 minutes, but you can set any period you like. E.g. for a custom test that runs once an hour, you will want to set this to at least 60 minutes - otherwise the status will go purple after 30 minutes. It is a good idea to set the LIFETIME to slightly longer than the interval between your tests, to allow for variations in the time it takes your test to complete. The LIFETIME is in minutes, unless you add an "h" (hours), "d" (days) or "w" (weeks) immediately after the number, e.g. "status+5h" for a status that is valid for 5 hours. .br The GROUP option is used to direct alerts from the status to a specific group. It is currently used for status generated from the Xymon clients\(aq data, e.g. to direct alerts for a "procs" status to different people, depending on exactly which process is down. .IP "notify HOSTNAME.TESTNAME " This triggers an informational message to be sent to those who receive alerts for this HOSTNAME+TESTNAME combination, according to the rules defined in .I alerts.cfg(5) This is used by the .I enadis.cgi(1) tool to notify people about hosts being disabled or enabled, but can also serve as a general way of notifying server administrators. .IP "data HOSTNAME.DATANAME" The "data" message allows tools to send data about a host, without it appearing as a column on the Xymon webpages. This is used, for example, to report statistics about a host, e.g. vmstat data, which does not in itself represent something that has a red, yellow or green identity. It is used by RRD bottom-feeder modules, among others. In Xymon, data messages are by default processed only by the .I xymond_rrd(8) module. If you want to handle data-messages using an external application, you may want to enable the .I xymond_filestore(8) module for data-messages, to store data-messages in a format compatible with how the Big Brother daemon does. .IP "disable HOSTNAME.TESTNAME DURATION " Disables a specific test for DURATION minutes. This will cause the status of this test to be listed as "blue" on the Xymon server, and no alerts for this host/test will be generated. If DURATION is given as a number followed by s/m/h/d, it is interpreted as being in seconds/minutes/hours/days respectively. .BR To disable a test until it becomes OK, use "\-1" as the DURATION. .BR To disable all tests for a host, use an asterisk "*" for TESTNAME. .IP "enable HOSTNAME.TESTNAME" Re-enables a test that had been disabled. .IP "query HOSTNAME.TESTNAME" Query the Xymon server for the latest status reported for this particular test. If the host/test status is known, the response is the first line of the status report - the current color will be the first word on the line. Additional lines of text that might be present on the status message cannot be retrieved. .br This allows any Xymon client to determine the status of a particular test, whether it is one pertaining to the host where the client is running, some other host, or perhaps the result of a combined test from multiple hosts managed by .I combostatus(1) This will typically be useful to Xymon client extension scripts, that need to determine the status of other hosts, for example, to decide if an automatic recovery action should be initiated. .IP "config FILENAME" Retrieve one of the Xymon configuration files from the server. This command allows a client to pull files from the $XYMONHOME/etc/ directory on the server, allowing for semi-automatic updates of the client configuration. Since the configuration files are designed to have a common file for the configuration of all hosts in the system - and this is in fact the recommended way of configuring your clients - this makes it easier to keep the configuration files synchronized. .IP "drop HOSTNAME" Removes all data stored about the host HOSTNAME. It is assumed that you have already deleted the host from the hosts.cfg configuration file. .IP "drop HOSTNAME TESTNAME" Remove data about a single test (column). .IP "rename OLDHOSTNAME NEWHOSTNAME" Rename all data for a host that has had its name changed. You should do this after changing the hostname in the hosts.cfg configuration file. .IP "rename HOSTNAME OLDTESTNAME NEWTESTNAME" Rename data about a single test (column). .IP "xymondlog HOSTNAME.TESTNAME" Retrieve the Xymon status-log for a single test. The first line of the response contains a series of fields separated by a pipe-sign: .sp .BR hostname The name of the host .sp .BR testname The name of the test .sp .BR color Status color (green, yellow, red, blue, clear, purple) .sp .BR testflags For network tests, the flags indicating details about the test (used by xymongen). .sp .BR lastchange Unix timestamp when the status color last changed. .sp .BR logtime Unix timestamp when the log message was received. .sp .BR validtime Unix timestamp when the log message is no longer valid (it goes purple at this time). .sp .BR acktime Either \-1 or Unix timestamp when an active acknowledgement expires. .sp .BR disabletime Either \-1 or Unix timestamp when the status is no longer disabled. .sp .BR sender IP address where the status was received from. .sp .BR cookie Either \-1 or the cookie value used to acknowledge an alert. .sp .BR ackmsg Empty or the acknowledgment message sent when the status was acknowledged. Newline, pipe-signs and backslashes are escaped with a backslash, C-style. .sp .BR dismsg Empty or the message sent when the status was disabled. Newline, pipe-signs and backslashes are escaped with a backslash, C-style. .sp After the first line comes the full status log in plain text format. .IP "xymondxlog HOSTNAME.TESTNAME" Retrieves an XML string containing the status log as with the "xymondlog" command. .IP "xymondboard [CRITERIA] [fields=FIELDLIST]" Retrieves a summary of the status of all known tests available to the Xymon daemon. By default - if no CRITERIA is provided - it returns one line for all status messages that are found in Xymon. You can filter the response by selection specific page, host, test, color or various other fields. The PAGEPATH, NETWORK, HOSTNAME, TESTNAME, and *MSG parameters are interpreted perl-compatible regular expressions; the COLOR parameter accepts multiple colors separated by commas; the *TIME values accept unix epoch timestamps. Other variables identified in xymon-xmh(5) may also be used. Because host filtration is done before test filtration, it's more efficient (with very large data sets) to use PAGEPATH, HOSTNAME, NETWORK, and other XMH_ filters when possible, before globally filtering with COLOR, *MSG, *TIME, or TESTNAME. You can filter on, for example, both a hostname and a testname. .sp .BR page=PAGEPATH Include only tests from hosts found on the PAGEPATH page in the hosts.cfg file. .sp .BR net=NETWORK Include only tests from hosts with this NET: tag .sp .BR ip=IP Address Include only tests from hosts with this IP address. This is a regex, not CIDR. .sp .BR host=HOSTNAME Include only tests from the host HOSTNAME .sp .BR test=TESTNAME Include only tests with the testname TESTNAME .sp .BR color=COLORNAME Include only tests where the status color is COLORNAME .sp .BR tag=TAGNAME Include only hosts with a certain tag specified in the hosts.cfg(5) line. Note that only items known to xymon components are included here; arbitrary text is not included .sp .BR XMH_string=VALUE Include only hosts with a xymon-xmh(5) variable matching this value .sp Advanced Filtering .sp .BR msg=MESSAGE Include only tests with full content matching MESSAGE. Use "\\s" to escape spaces (or other PCRE strings) .sp .BR ackmsg=MESSAGE Include only tests with acknowledgement(s) MESSAGE. Use "\\s" to escape spaces (or other PCRE strings) .sp .BR dismsg=MESSAGE Include only tests that have been disabled with strings matching MESSAGE. Use "\\s" to escape spaces (or other PCRE strings). (It is most efficient to pair this with color=blue.) Timestamp Filters Certain fields (explained below) can be filtered with unix timestamps and with the following inequalities: >= > <= < = != These filters are: lastchange, logtime, validtime, acktime, disabletime The response is one line for each status that matches the CRITERIA, or all statuses if no criteria is specified. The line is composed of a number of fields, separated by a pipe-sign. You can select which fields to retrieve by listing them in the FIELDLIST. The following fields are available: .sp .BR hostname The name of the host .sp .BR testname The name of the test .sp .BR color Status color (green, yellow, red, blue, clear, purple) .sp .BR flags For network tests, the flags indicating details about the test (used by xymongen). .sp .BR lastchange Unix timestamp when the status color last changed. .sp .BR logtime Unix timestamp when the log message was received. .sp .BR validtime Unix timestamp when the log message is no longer valid (it goes purple at this time). .sp .BR acktime Either \-1 or Unix timestamp when an active acknowledgement expires. .sp .BR disabletime Either \-1 or Unix timestamp when the status is no longer disabled. .sp .BR sender IP address where the status was received from. .sp .BR cookie Either \-1 or the cookie value used to acknowledge an alert. .sp .BR line1 First line of status log. .sp .BR ackmsg Empty (if no acknowledgement is active), or the text of the acknowledge message. .sp .BR dismsg Empty (if the status is currently enabled), or the text of the disable message. .sp .BR msg The full text of the current status message. .sp .BR client Shows "Y" if there is client data available, "N" if not. .sp .BR clntstamp Timestamp when the last client message was received, in Unix "epoch" format. .sp .BR acklist List of the current acknowledgements for a test. This is a text string with multiple fields, delimited by a colon character. There are 5 fields: Timestamp for when the ack was generated and when it expires; the the "ack level"; the user who sent the ack; and the acknowledgement text. .sp .BR flapinfo Tells if the status is flapping. 5 fields, delimited by "/": A "0" if the status is not flapping and "1" if it is flapping; timestamp when the latest status change was recorded and when the first statuschange was recorded; and the two colors that the status is flapping between. .sp .BR stats Number of status-changes that have been recorded for this status since xymond was started. .sp .BR modifiers Lists all active modifiers for this status (i.e. updates sent using a "modify" command). .sp .BR XMH_* The XMH-tags refer to the Xymon .I hosts.cfg(5) configuration settings. A full list of these can be found in the .I xymon\-xmh(5) man-page. The ackmsg, dismsg and msg fields have certain characters encoded: Newline is "\\n", TAB is "\\t", carriage return is "\\r", a pipe-sign is "\\p", and a backslash is "\\\\". If the "fields" parameter is omitted, a default set of hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,line1 is used. .IP "xymondxboard" Retrieves an XML string with the summary of all status logs as for the "xymondboard" command. .IP "hostinfo [CRITERIA]" Retrieves the current configuration of a host (i.e. the .I hosts.cfg(5) definition). CRITERIA selects which host(s) to report, and is identical to the CRITERIA in the xymondboard command. The response is one line for each host that matches the CRITERIA, or all hosts if no criteria is specified. The line is composed of a number of fields, separated by a pipe-sign. The first two fields will always be the hostname and the IP-address. The remaining fields - if any - are the hosts.cfg tags in no particular order. .IP "download FILENAME" Download a file from the Xymon server\(aqs download directory. .IP "client[/COLLECTORID] HOSTNAME.OSTYPE [HOSTCLASS]" Used to send a "client" message to the Xymon server. Client messages are generated by the Xymon client; when sent to the Xymon server they are matched against the rules in the .I analysis.cfg(5) configuration file, and status messages are generated for the client-side tests. The COLLECTORID is used when sending client-data that are additions to the standard client data. The data will be concatenated with the normal client data. .IP "clientlog HOSTNAME [section=SECTIONNAME[,SECTIONNAME...]]" Retrieves the current raw client message last sent by HOSTNAME. The optional "section" filter is used to select specific sections of the client data. .IP "ping" Attempts to contact the Xymon server. If successful, the Xymon server version ID is reported. .IP "pullclient" This message is used when fetching client data via the "pull" mechanism implemented by .I xymonfetch(8) and .I msgcache(8) for clients that cannot connect directly to the Xymon server. .IP "ghostlist" Report a list of \fBghost\fR clients seen by the Xymon server. Ghosts are systems that report data to the Xymon server, but are not listed in the hosts.cfg file. .IP "schedule [TIMESTAMP COMMAND]" Schedules a command sent to the Xymon server for execution at a later time. E.g. used to schedule disabling of a host or service at sometime in the future. COMMAND is a complete Xymon command such as the ones listed above. TIMESTAMP is the Unix epoch time when the command will be executed. .br If no parameters are given, the currently scheduled tasks are listed in the response. The response is one line per scheduled command, with the job-id, the time when the command will be executed, the IP address from which this was sent, and the full command string. .br To cancel a previously scheduled command, \fB"schedule cancel JOBID"\fR can be used. JOBID is a number provided as the first item in the output from the schedule list. .IP "notes FILENAME" The message text will be stored in $XYMONHOME/notes/FILENAME which is then used as hyperlinks from hostnames or column names. This requires that the "storenotes" task is enabled in tasks.cfg (it is disabled by default). FILENAME cannot contain any directory path - these are stripped automatically. .IP "usermsg ID" These messages will be relayed directly to modules listening on the "user" channel of the Xymon daemon. This is intended for custom communication between client-side modules and the Xymon server. .IP "modify HOSTNAME.TESTNAME COLOR SOURCE CAUSE" Modify the color of a specific status, without generating a complete status message. This is for backend processors (e.g. RRD graphs) that can override the color of a status based on some criteria determined outside the normal flow of a status. E.g. the normal "conn" status may appear to be green since it merely checks on whether a host can be ping'ed or not; the RRD handler can then use a "modify" command to override this is the actual ping responsetime exceeds a given threshold. (See the "DS" configuration setting in .I analysis.cfg(5) for how to do this). SOURCE is some identification of the module that generates the "modify" message - future modifications must use the same source. There may be several sources that modify the same status (the most severe status then becomes the actual color of the status). CAUSE is a one-line text string explaining the reason for overriding the normal status color - it will be displayed on the status webpage. .SH EXAMPLE Send a normal status message to the Xymon server, using the standard Xymon protocol on TCP port 1984: .br $ $XYMON $XYMSRV "status www,foo,com.http green \(gadate\(ga Web OK" Send the same status message, but using HTTP protocol via the webserver\(aqs xymoncgimsg.cgi script: .br $ $XYMON http://bb.foo.com/cgi\-bin/xymoncgimsg.cgi "status www,foo,com.http green \(gadate\(ga Web OK" Use "query" message to determine the color of the "www" test, and restart Apache if it is red: .br $ WWW=\(ga$XYMON $XYMSRV "query www,foo,com.www" | awk \(aq{print $1}\(aq\(ga $ if [ "$WWW" = "red" ]; then /etc/init.d/apache restart; fi Use "config" message to update a local mytest.cfg file (but only if we get a response): .br $ $XYMON $XYMSRV "config mytest.cfg" >/tmp/mytest.cfg.new $ if [ \-s /tmp/mytest.cfg.new ]; then mv /tmp/mytest.cfg.new $XYMONHOME/etc/mytest.cfg fi Send a very large status message that has been built in the file "statusmsg.txt". Instead of providing it on the command-line, pass it via stdin to the xymon command: $ cat statusmsg.txt | $XYMON $XYMSRV "@" .SH "SEE ALSO" combostatus(1), hosts.cfg(5), xymonserver.cfg(5), xymon(7) xymon-4.3.30/common/Makefile0000664000076400007640000001147612266741164016155 0ustar rpmbuildrpmbuild# Xymon - common tools # PROGRAMS = xymongrep xymondigest xymon xymoncmd xymonlaunch xymoncfg CLIENTPROGRAMS = ../client/xymon ../client/xymonlaunch ../client/xymoncmd ../client/xymongrep ../client/xymoncfg ../client/xymondigest HOSTGREPOBJS = xymongrep.o HOSTSHOWOBJS = xymoncfg.o DIGESTOBJS = xymondigest.o XYMONOBJS = xymon.o LAUNCHOBJS = xymonlaunch.o CMDOBJS = xymoncmd.o XYMONCLIENTLIB = ../lib/libxymonclient.a XYMONCLIENTLIBS = $(XYMONCLIENTLIB) XYMONCLIENTCOMMLIB = ../lib/libxymonclientcomm.a XYMONCLIENTCOMMLIBS = $(XYMONCLIENTCOMMLIB) $(SSLLIBS) $(NETLIBS) $(LIBRTDEF) XYMONLIB = ../lib/libxymon.a XYMONLIBS = $(XYMONLIB) XYMONCOMMLIB = ../lib/libxymoncomm.a XYMONCOMMLIBS = $(XYMONCOMMLIB) $(SSLLIBS) $(NETLIBS) $(ZLIBLIBS) $(LIBRTDEF) XYMONTIMELIB = ../lib/libxymontime.a XYMONTIMELIBS = $(XYMONTIMELIB) $(LIBRTDEF) all: $(PROGRAMS) client: $(CLIENTPROGRAMS) xymongrep: $(HOSTGREPOBJS) $(XYMONCOMMLIB) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(HOSTGREPOBJS) $(XYMONCOMMLIBS) $(XYMONLIBS) ../client/xymongrep: $(HOSTGREPOBJS) $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(HOSTGREPOBJS) $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) xymoncfg: $(HOSTSHOWOBJS) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(HOSTSHOWOBJS) $(XYMONLIBS) ../client/xymoncfg: $(HOSTSHOWOBJS) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(HOSTSHOWOBJS) $(XYMONCLIENTLIBS) xymon: $(XYMONOBJS) $(XYMONCOMMLIB) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(XYMONOBJS) $(XYMONCOMMLIBS) $(XYMONLIBS) ../client/xymon: $(XYMONOBJS) $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(XYMONOBJS) $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) xymonlaunch: $(LAUNCHOBJS) $(XYMONTIMELIB) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(LAUNCHOBJS) $(XYMONTIMELIBS) $(XYMONLIBS) ../client/xymonlaunch: $(LAUNCHOBJS) $(XYMONTIMELIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(LAUNCHOBJS) $(XYMONTIMELIBS) $(XYMONCLIENTLIBS) xymoncmd: $(CMDOBJS) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(CMDOBJS) $(XYMONLIBS) ../client/xymoncmd: $(CMDOBJS) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(CMDOBJS) $(XYMONCLIENTLIBS) xymondigest: $(DIGESTOBJS) $(XYMONLIB) $(CC) $(CFLAGS) -o $@ $(DIGESTOBJS) $(XYMONCOMMLIBS) $(XYMONLIBS) ../client/xymondigest: $(DIGESTOBJS) $(XYMONCLIENTCOMMLIB) $(XYMONCLIENTLIB) $(CC) $(CFLAGS) -o $@ $(DIGESTOBJS) $(XYMONCLIENTCOMMLIBS) $(XYMONCLIENTLIBS) xymon.exe: xymon.c ../lib/strfunc.c ../lib/errormsg.c ../lib/environ.c ../lib/stackio.c ../lib/timefunc.c ../lib/memory.c ../lib/sendmsg.c ../lib/holidays.c ../lib/rbtr.c ../lib/msort.c $(CC) $(CFLAGS) -c xymon.c $(CC) $(CFLAGS) -DXYMONTOPDIR=\"$(XYMONTOPDIR)\" -DXYMONLOGDIR=\"$(XYMONLOGDIR)\" -DXYMONHOSTNAME=\"$(XYMONHOSTNAME)\" -DXYMONHOSTIP=\"$(XYMONHOSTIP)\" -DXYMONHOSTOS=\"$(XYMONHOSTOS)\" -DXYMONHOME=\"$(XYMONHOME)\" -c ../lib/environ.c $(CC) $(CFLAGS) -c ../lib/strfunc.c $(CC) $(CFLAGS) -c ../lib/errormsg.c $(CC) $(CFLAGS) -c ../lib/stackio.c $(CC) $(CFLAGS) -c ../lib/timefunc.c $(CC) $(CFLAGS) -c ../lib/memory.c $(CC) $(CFLAGS) -c ../lib/sendmsg.c $(CC) $(CFLAGS) -c ../lib/holidays.c $(CC) $(CFLAGS) -c ../lib/rbtr.c $(CC) $(CFLAGS) -c ../lib/msort.c $(CC) $(CFLAGS) -c ../lib/misc.c ar cr xymonwin32.a environ.o strfunc.o errormsg.o stackio.o timefunc.o memory.o sendmsg.o holidays.o rbtr.o msort.o misc.o ranlib xymonwin32.a || echo "" $(CC) -o $@ xymon.o xymonwin32.a ################################################ # Default compilation rules ################################################ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f *.o *.a *~ $(PROGRAMS) $(CLIENTPROGRAMS) install: install-bin install-man install-bin: $(PROGRAMS) ifndef PKGBUILD chown $(XYMONUSER) $(PROGRAMS) chgrp `$(IDTOOL) -g $(XYMONUSER)` $(PROGRAMS) chmod 755 $(PROGRAMS) endif cp -fp $(PROGRAMS) $(INSTALLROOT)$(INSTALLBINDIR)/ cd $(INSTALLROOT)$(INSTALLBINDIR)/; rm -f bb bbcmd bbhostgrep bbhostshow; ln -s xymon bb; ln -s xymoncmd bbcmd; ln -s xymongrep bbhostgrep; ln -s xymondigest bbdigest; ln -s xymoncfg bbhostshow install-man: ifndef PKGBUILD chown $(XYMONUSER) *.1 *.5 *.7 *.8 chgrp `$(IDTOOL) -g $(XYMONUSER)` *.1 *.5 *.7 *.8 chmod 644 *.1 *.5 *.7 *.8 endif mkdir -p $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man7 $(INSTALLROOT)$(MANROOT)/man8 ifndef PKGBUILD chown $(XYMONUSER) $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man7 $(INSTALLROOT)$(MANROOT)/man8 chgrp `$(IDTOOL) -g $(XYMONUSER)` $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man7 $(INSTALLROOT)$(MANROOT)/man8 chmod 755 $(INSTALLROOT)$(MANROOT)/man1 $(INSTALLROOT)$(MANROOT)/man5 $(INSTALLROOT)$(MANROOT)/man7 $(INSTALLROOT)$(MANROOT)/man8 endif cp -fp *.1 $(INSTALLROOT)$(MANROOT)/man1/ cp -fp *.5 $(INSTALLROOT)$(MANROOT)/man5/ cp -fp *.7 $(INSTALLROOT)$(MANROOT)/man7/ cp -fp *.8 $(INSTALLROOT)$(MANROOT)/man8/ xymon-4.3.30/common/xymoncfg.10000664000076400007640000000233013534041732016407 0ustar rpmbuildrpmbuild.TH XYMONCFG 1 "Version 4.3.30: 4 Sep 2019" "Xymon" .SH NAME xymoncfg \- output the full hosts.cfg file .SH SYNOPSIS .B "xymoncfg [--web] [--net] [filename]" .SH DESCRIPTION .I xymoncfg(1) dumps the full hosts.cfg file to stdout. It follows "include" tags in the hosts.cfg files, and prints the full contents as seen by the .I xymongen(1) and .I xymonnet(1) utilities. If no filename is given, xymoncfg displays the file pointed to by the HOSTSCFG environment variable. .SH OPTIONS .IP "--web" Show the hosts.cfg file following include statements as a Xymon web-server would. .IP "--net" Show the hosts.cfg file following include statements as done when running xymonnet. .IP "-s" Output only the lines that look like environment variable definitions, in a format suitable for use with Bourne-style shells (e.g. bash, ksh). You will probably not use this with the default hosts.cfg input file, but e.g. xymonserver.cfg. To define all the variables in xymonserver.cfg inside your shell script, you can use .br .br eval `xymoncfg -s /etc/xymon/xymonserver.cfg` .IP "-c" Similar to "-s", but for C-shell. .SH ENVIRONMENT VARIABLES .IP HOSTSCFG Filename for the .I hosts.cfg(5) file. .SH "SEE ALSO" hosts.cfg(5), xymonserver.cfg(5) xymon-4.3.30/common/xymonlaunch.c0000664000076400007640000005573112411755466017232 0ustar rpmbuildrpmbuild/* -*- mode:C; tab-width:8; intent-tabs-mode:1; c-basic-offset:8 -*- */ /*----------------------------------------------------------------------------*/ /* Xymon application launcher. */ /* */ /* This is used to launch various parts of the Xymon system. Some programs */ /* start up once and keep running, other must run at various intervals. */ /* */ /* Copyright (C) 2004-2011 Henrik Storner */ /* "CMD +/-" code and enable/disable enhancement by Martin Sperl 2010-2011 */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: xymonlaunch.c 7482 2014-09-28 09:56:06Z storner $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxymon.h" #include /* * config file format: * * [xymond] * CMD xymond --no-daemon * LOGFILE /var/log/xymond.log * * [xymongen] * CMD xymongen * INTERVAL 5m */ #define MAX_FAILS 5 typedef struct grouplist_t { char *groupname; int currentuse, maxuse; struct grouplist_t *next; } grouplist_t; typedef struct tasklist_t { char *key; int disabled; grouplist_t *group; char *cmd; int interval, maxruntime; char *logfile; char *envfile, *envarea, *onhostptn; pid_t pid; time_t laststart; int exitcode; int failcount; int cfload; /* Used while reloading a configuration */ int beingkilled; char *cronstr; /* pointer to cron string */ void *crondate; /* pointer to cron date-time structure */ int cronmin; /* minute value of the last sucessful cron execution attempt */ struct tasklist_t *depends; struct tasklist_t *next; struct tasklist_t *copy; } tasklist_t; tasklist_t *taskhead = NULL; tasklist_t *tasktail = NULL; grouplist_t *grouphead = NULL; volatile time_t nextcfgload = 0; volatile int running = 1; volatile int dologswitch = 0; volatile int forcereload=0; # define xfreenull(k) { if (k) { xfree(k); k=NULL;} } # define xfreeassign(k,p) { if (k) { xfree(k); } k=p; } # define xfreedup(k,p) { if (k) { xfree(k); } k=strdup(p); } void load_config(char *conffn) { static void *configfiles = NULL; tasklist_t *twalk, *curtask = NULL; FILE *fd; strbuffer_t *inbuf; char *p; char myhostname[256]; /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles) && (!forcereload)) { dbgprintf("No files modified, skipping reload of %s\n", conffn); return; } else { stackfclist(&configfiles); configfiles = NULL; } } errprintf("Loading tasklist configuration from %s\n", conffn); if (gethostname(myhostname, sizeof(myhostname)) != 0) { errprintf("Cannot get the local hostname, using 'localhost' (error: %s)\n", strerror(errno)); strcpy(myhostname, "localhost"); } /* The cfload flag: -1=delete task, 0=old task unchanged, 1=new/changed task */ for (twalk = taskhead; (twalk); twalk = twalk->next) { twalk->cfload = -1; twalk->group = NULL; /* Create a copy, but retain the settings and pointers are the same */ twalk->copy = xmalloc(sizeof(tasklist_t)); memcpy(twalk->copy,twalk,sizeof(tasklist_t)); /* These should get cleared */ twalk->copy->next = NULL; twalk->copy->copy = NULL; /* And clean the values of all others, so that we really can detect a difference */ twalk->disabled = 0; twalk->cmd = NULL; twalk->interval = 0; twalk->maxruntime = 0; twalk->group = NULL; twalk->logfile = NULL; twalk->envfile = NULL; twalk->envarea = NULL; twalk->onhostptn = NULL; twalk->cronstr = NULL; twalk->crondate = NULL; twalk->depends = NULL; } fd = stackfopen(conffn, "r", &configfiles); if (fd == NULL) { errprintf("Cannot open configuration file %s: %s\n", conffn, strerror(errno)); return; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; p = STRBUF(inbuf); if (*p == '[') { /* New task */ char *endp; /* get name */ p++; endp = strchr(p, ']'); if (endp == NULL) continue; *endp = '\0'; /* try to find the task */ for (twalk = taskhead; (twalk && (strcmp(twalk->key, p))); twalk = twalk->next); if (twalk) { curtask=twalk; } else { /* New task, just create it */ curtask = (tasklist_t *)calloc(1, sizeof(tasklist_t)); curtask->key = strdup(p); /* add it to the list */ if (taskhead == NULL) taskhead = curtask; else tasktail->next = curtask; tasktail = curtask; } /* mark task as configured */ curtask->cfload = 0; } else if (curtask && (strncasecmp(p, "CMD ", 4) == 0)) { p += 3; p += strspn(p, " \t"); /* Handle + - options as well */ if (*p == '+') { /* append to command */ if (curtask->cmd) { int l1 = strlen(curtask->cmd); int l2 = strlen(p); char *newcmd = xcalloc(1, l1+l2+1); strncpy(newcmd,curtask->cmd,l1); strncpy(newcmd+l1,p,l2); newcmd[l1]=' '; /* this also overwrites the + */ /* free and assign new */ xfreeassign(curtask->cmd,newcmd); } } else if (*p == '-') { /* remove from command */ if (curtask->cmd) { int l = strlen(p)-1; if (l > 0) { char *found; while((found = strstr(curtask->cmd,p+1)) != NULL) { /* doing a copy - can not use strcpy as we are overlapping */ char *s = found + l; while (*s) { *found=*s; found++; s++; } *found=0; } } else { errprintf("Configuration error, empty command removal (CMD -) for task %s\n", curtask->key); } } } else { xfreedup(curtask->cmd,p); } } else if (strncasecmp(p, "GROUP ", 6) == 0) { /* Note: GROUP can be used by itself to define a group, or inside a task definition */ char *groupname; int maxuse; grouplist_t *gwalk; p += 6; p += strspn(p, " \t"); groupname = p; p += strcspn(p, " \t"); if (isdigit((int) *p)) maxuse = atoi(p); else maxuse = 1; /* Find or create the grouplist entry */ for (gwalk = grouphead; (gwalk && (strcmp(gwalk->groupname, groupname))); gwalk = gwalk->next); if (gwalk == NULL) { gwalk = (grouplist_t *)malloc(sizeof(grouplist_t)); gwalk->groupname = strdup(groupname); gwalk->maxuse = maxuse; gwalk->currentuse = 0; gwalk->next = grouphead; grouphead = gwalk; } if (curtask) curtask->group = gwalk; } else if (curtask && (strncasecmp(p, "INTERVAL ", 9) == 0)) { char *tspec; p += 9; curtask->interval = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->interval *= 60; break; /* Minutes */ case 'h': curtask->interval *= 3600; break; /* Hours */ case 'd': curtask->interval *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "CRONDATE ", 9) == 0)) { p+= 9; xfreedup(curtask->cronstr,p); if (curtask->crondate) crondatefree(curtask->crondate); curtask->crondate = parse_cron_time(curtask->cronstr); if (!curtask->crondate) { errprintf("Can't parse cron date: %s->%s\n", curtask->key, curtask->cronstr); curtask->disabled = 1; } curtask->interval = -1; /* disable interval */ } else if (curtask && (strncasecmp(p, "MAXTIME ", 8) == 0)) { char *tspec; p += 8; curtask->maxruntime = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->maxruntime *= 60; break; /* Minutes */ case 'h': curtask->maxruntime *= 3600; break; /* Hours */ case 'd': curtask->maxruntime *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "LOGFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->logfile,p); } else if (curtask && (strncasecmp(p, "NEEDS ", 6) == 0)) { p += 6; p += strspn(p, " \t"); for (twalk = taskhead; (twalk && strcmp(twalk->key, p)); twalk = twalk->next); if (twalk) { curtask->depends = twalk; } else { errprintf("Configuration error, unknown dependency %s->%s\n", curtask->key, p); } } else if (curtask && (strncasecmp(p, "ENVFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->envfile,p); } else if (curtask && (strncasecmp(p, "ENVAREA ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->envarea,p); } else if (curtask && (strcasecmp(p, "DISABLED") == 0)) { curtask->disabled = 1; } else if (curtask && (strcasecmp(p, "ENABLED") == 0)) { curtask->disabled = 0; } else if (curtask && (strncasecmp(p, "ONHOST ", 7) == 0)) { regex_t cpattern; int status; p += 7; p += strspn(p, " \t"); xfreedup(curtask->onhostptn,p); /* Match the hostname against the pattern; if it doesnt match then disable the task */ status = regcomp(&cpattern, curtask->onhostptn, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status == 0) { status = regexec(&cpattern, myhostname, 0, NULL, 0); if (status == REG_NOMATCH) curtask->disabled = 1; } else { errprintf("ONHOST pattern '%s' is invalid\n", p); } } } stackfclose(fd); freestrbuffer(inbuf); /* Running tasks that have been deleted or changed are killed off now. */ for (twalk = taskhead; (twalk); twalk = twalk->next) { /* compare the current settings with the copy - if we have one */ if (twalk->cfload == 0) { if (twalk->copy) { /* compare the current version with the new version and decide if we have changed */ int changed=0; int reload=0; /* first the nummeric ones */ if (twalk->disabled!=twalk->copy->disabled) { changed++; } if (twalk->interval!=twalk->copy->interval) { changed++; } if (twalk->maxruntime!=twalk->copy->maxruntime) { changed++; } if (twalk->group!=twalk->copy->group) { changed++; reload++;} /* then the string versions */ #define twalkstrcmp(k,doreload) { \ if (twalk->k!=twalk->copy->k) { \ if (twalk->copy->k) { \ if (twalk->k) { \ if (strcmp(twalk->k,twalk->copy->k)) { \ changed++;reload+=doreload; \ } \ } else { \ changed++;reload+=doreload; \ } \ /* we can always delete the copy*/ \ xfree(twalk->copy->k); \ twalk->copy->k=NULL; \ } else { \ changed++;reload+=doreload; \ } \ } \ } twalkstrcmp(cmd,1); twalkstrcmp(logfile,1); twalkstrcmp(envfile,1); twalkstrcmp(envarea,1); twalkstrcmp(onhostptn,0); twalkstrcmp(cronstr,0); if ((twalk->copy->cronstr == NULL) && twalk->copy->crondate) { crondatefree(twalk->copy->crondate); twalk->copy->crondate = NULL; } /* we can release the copy now - not using xfree, as this releases it from the list making a mess...*/ xfreenull(twalk->copy); /* now make the decision for reloading - if we have changed, then we may assign cfload, - otherwise the entry does not exist any longer */ if (reload) { reload=1;} if (changed) { twalk->cfload=reload; } } else { /* new object, so we need to do this */ twalk->cfload=1; } } /* and based on this decide what to do */ switch (twalk->cfload) { case -1: /* Kill the task, if active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } /* And prepare to free this tasklist entry */ xfreenull(twalk->key); xfreenull(twalk->cmd); xfreenull(twalk->logfile); xfreenull(twalk->envfile); xfreenull(twalk->envarea); xfreenull(twalk->onhostptn); xfreenull(twalk->cronstr); if (twalk->crondate) crondatefree(twalk->crondate); break; case 0: /* Do nothing */ break; case 1: /* Bounce the task, if it is active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } break; } } /* First clean out dead tasks at the start of the list */ while (taskhead && (taskhead->cfload == -1)) { tasklist_t *tmp; tmp = taskhead; taskhead = taskhead->next; xfree(tmp); } /* Then unlink and free those inside the list */ twalk = taskhead; while (twalk && twalk->next) { tasklist_t *tmp; if (twalk->next->cfload == -1) { tmp = twalk->next; twalk->next = tmp->next; xfree(tmp); } else twalk = twalk->next; } if (taskhead == NULL) tasktail = NULL; else { tasktail = taskhead; while (tasktail->next) tasktail = tasktail->next; } /* Make sure group usage counts are correct (groups can change) */ for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group) twalk->group->currentuse = 0; } for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group && twalk->pid) twalk->group->currentuse++; } } void sig_handler(int signum) { switch (signum) { case SIGCHLD: break; case SIGHUP: nextcfgload = 0; dologswitch = 1; break; case SIGTERM: running = 0; break; } } int main(int argc, char *argv[]) { tasklist_t *twalk, *dwalk; grouplist_t *gwalk; int argi; int daemonize = 1; int verbose = 0; int dumpconfig = 0; struct stat st; char *config = NULL; char *logfn = NULL; char *pidfn = NULL; pid_t cpid; int status; struct sigaction sa; char *envarea = NULL; for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--no-daemon") == 0) { daemonize = 0; } else if (strcmp(argv[argi], "--verbose") == 0) { verbose = 1; } else if (argnmatch(argv[argi], "--config=")) { char *p = strchr(argv[argi], '='); config = strdup(expand_env(p+1)); } else if (argnmatch(argv[argi], "--log=")) { char *p = strchr(argv[argi], '='); logfn = strdup(expand_env(p+1)); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--pidfile=")) { char *p = strchr(argv[argi], '='); pidfn = strdup(expand_env(p+1)); } else if (strcmp(argv[argi], "--dump") == 0) { dumpconfig = 1; } else { fprintf(stderr,"%s: Unsupported argument: %s\n",argv[0],argv[argi]); fflush(stderr); return 1; } } /* Find config */ if (!config) { if (stat("/etc/tasks.cfg", &st) != -1) config = strdup("/etc/tasks.cfg"); else if (stat("/etc/xymon/tasks.cfg", &st) != -1) config = strdup("/etc/xymon/tasks.cfg"); else if (stat("/etc/xymon-client/clientlaunch.cfg", &st) != -1) config = strdup("/etc/xymon-client/clientlaunch.cfg"); else if (xgetenv("XYMONHOME")) { config = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen("/etc/tasks.cfg") + 1); sprintf(config, "%s/etc/tasks.cfg", xgetenv("XYMONHOME")); } if (config) dbgprintf("Using config file: %s\n", config); } if (!config || stat(config, &st) == -1) { fprintf(stderr,"%s: Error reading config file %s\n", argv[0], config); fflush(stderr); return 1; } /* Dump configuration */ if (dumpconfig) { forcereload=1; load_config(config); forcereload=0; for (gwalk = grouphead; (gwalk); gwalk = gwalk->next) { if (gwalk->maxuse > 1) printf("GROUP %s %d\n", gwalk->groupname, gwalk->maxuse); } printf("\n"); for (twalk = taskhead; (twalk); twalk = twalk->next) { printf("[%s]\n", twalk->key); printf("\tCMD %s\n", twalk->cmd); if (twalk->disabled) printf("\tDISABLED\n"); if (twalk->group) printf("\tGROUP %s\n", twalk->group->groupname); if (twalk->depends) printf("\tNEEDS %s\n", twalk->depends->key); if (twalk->interval > 0) printf("\tINTERVAL %d\n", twalk->interval); if (twalk->cronstr) printf("\tCRONDATE %s\n", twalk->cronstr); if (twalk->maxruntime) printf("\tMAXTIME %d\n", twalk->maxruntime); if (twalk->logfile) printf("\tLOGFILE %s\n", twalk->logfile); if (twalk->envfile) printf("\tENVFILE %s\n", twalk->envfile); if (twalk->envarea) printf("\tENVAREA %s\n", twalk->envarea); if (twalk->onhostptn) printf("\tONHOST %s\n", twalk->onhostptn); printf("\n"); } fflush(stdout); return 0; } /* Go daemon */ if (daemonize) { pid_t childpid; /* Become a daemon */ childpid = fork(); if (childpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (childpid > 0) { /* Parent exits */ if (pidfn) { FILE *pidfd = fopen(pidfn, "w"); if (pidfd) { fprintf(pidfd, "%d\n", (int)childpid); fclose(pidfd); } } exit(0); } /* Child (daemon) continues here */ setsid(); } /* If using a logfile, switch stdout and stderr to go there */ if (logfn) { /* Should we close stdin here ? No ... */ reopen_file("/dev/null", "r", stdin); reopen_file(logfn, "a", stdout); reopen_file(logfn, "a", stderr); } save_errbuf = 0; setup_signalhandler("xymonlaunch"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); errprintf("xymonlaunch starting\n"); while (running) { time_t now = gettimer(); struct timeval curtime; struct tm tt; int thisminute = -1; gettimeofday(&curtime, NULL); gmtime_r(&curtime.tv_sec, &tt); thisminute = tt.tm_min; if (now >= nextcfgload) { load_config(config); nextcfgload = (now + 30); } if (logfn && dologswitch) { reopen_file(logfn, "a", stdout); reopen_file(logfn, "a", stderr); dologswitch = 0; } /* Pick up children that have terminated */ while ((cpid = wait3(&status, WNOHANG, NULL)) > 0) { for (twalk = taskhead; (twalk && (twalk->pid != cpid)); twalk = twalk->next); if (twalk) { twalk->pid = 0; twalk->beingkilled = 0; if (WIFEXITED(status)) { twalk->exitcode = WEXITSTATUS(status); if (twalk->exitcode) { errprintf("Task %s terminated, status %d\n", twalk->key, twalk->exitcode); twalk->failcount++; } else { twalk->failcount = 0; } } else if (WIFSIGNALED(status)) { twalk->exitcode = -WTERMSIG(status); twalk->failcount++; errprintf("Task %s terminated by signal %d\n", twalk->key, abs(twalk->exitcode)); } if (twalk->group) twalk->group->currentuse--; /* Tasks that depend on this task should be killed ... */ for (dwalk = taskhead; (dwalk); dwalk = dwalk->next) { if ((dwalk->depends == twalk) && (dwalk->pid > 0)) { dwalk->beingkilled = 1; kill(dwalk->pid, SIGTERM); } } } } /* See what new tasks need to get going */ dbgprintf("\n"); dbgprintf("Starting tasklist scan\n"); crongettime(); for (twalk = taskhead; (twalk); twalk = twalk->next) { if ( (twalk->pid == 0) && !twalk->disabled && ( ((twalk->interval >= 0) && (now >= (twalk->laststart + twalk->interval))) || /* xymon interval condition */ (twalk->crondate && (twalk->cronmin != thisminute) && cronmatch(twalk->crondate) ) /* cron date, has not had run attempt this minute */ ) ) { if (twalk->depends && ((twalk->depends->pid == 0) || (twalk->depends->laststart > (now - 5)))) { dbgprintf("Postponing start of %s due to %s not yet running\n", twalk->key, twalk->depends->key); continue; } if (twalk->group && (twalk->group->currentuse >= twalk->group->maxuse)) { dbgprintf("Postponing start of %s due to group %s being busy\n", twalk->key, twalk->group->groupname); continue; } if ((twalk->failcount > MAX_FAILS) && ((twalk->laststart + 600) < now)) { dbgprintf("Releasing %s from failure hold\n", twalk->key); twalk->failcount = 0; } if (twalk->failcount > MAX_FAILS) { dbgprintf("Postponing start of %s due to multiple failures\n", twalk->key); continue; } if (twalk->laststart > (now - 5)) { dbgprintf("Postponing start of %s, will not try more than once in 5 seconds\n", twalk->key); continue; } dbgprintf("About to start task %s\n", twalk->key); twalk->laststart = now; if (twalk->crondate) twalk->cronmin = thisminute; twalk->pid = fork(); if (twalk->pid == 0) { /* Exec the task */ char *cmd; char **cmdargs = NULL; static char tasksleepenv[20],bbsleepenv[20]; /* Setup environment */ if (twalk->envfile) { dbgprintf("%s -> Loading environment from %s area %s\n", twalk->key, expand_env(twalk->envfile), (twalk->envarea ? twalk->envarea : "")); loadenv(expand_env(twalk->envfile), twalk->envarea); } /* Setup TASKSLEEP to match the interval */ sprintf(tasksleepenv, "TASKSLEEP=%d", twalk->interval); sprintf(bbsleepenv, "BBSLEEP=%d", twalk->interval); /* For compatibility */ putenv(tasksleepenv); putenv(bbsleepenv); /* Setup command line and arguments */ cmdargs = setup_commandargs(twalk->cmd, &cmd); /* Point stdout/stderr to a logfile, if requested */ if (twalk->logfile) { char *logfn = expand_env(twalk->logfile); dbgprintf("%s -> Assigning stdout/stderr to log '%s'\n", twalk->key, logfn); reopen_file(logfn, "a", stdout); reopen_file(logfn, "a", stderr); } /* Go! */ dbgprintf("%s -> Running '%s', XYMONHOME=%s\n", twalk->key, cmd, xgetenv("XYMONHOME")); execvp(cmd, cmdargs); /* Should never go here */ errprintf("Could not start task %s using command '%s': %s\n", twalk->key, cmd, strerror(errno)); exit(0); } else if (twalk->pid == -1) { /* Fork failed */ errprintf("Fork failed!\n"); twalk->pid = 0; } else { if (twalk->group) twalk->group->currentuse++; if (verbose) errprintf("Task %s started with PID %d\n", twalk->key, (int)twalk->pid); } } else if (twalk->pid > 0) { dbgprintf("Task %s active with PID %d\n", twalk->key, (int)twalk->pid); if (twalk->maxruntime && ((now - twalk->laststart) > twalk->maxruntime)) { errprintf("Killing hung task %s (PID %d) after %d seconds\n", twalk->key, (int)twalk->pid, (now - twalk->laststart)); kill(twalk->pid, (twalk->beingkilled ? SIGKILL : SIGTERM)); twalk->beingkilled = 1; /* Next time it's a real kill */ } } /* Crondate + our flag isn't set and we don't need to run... reset the minute value to the flag. */ /* This clears whenever the minute has changed */ if (twalk->crondate && (twalk->cronmin != -1) && !cronmatch(twalk->crondate)) twalk->cronmin = -1; } sleep(5); } /* Shutdown running tasks */ for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->pid) kill(twalk->pid, SIGTERM); } if (pidfn) unlink(pidfn); return 0; } xymon-4.3.30/demotool/0000775000076400007640000000000013534041774015035 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/demotool.c0000664000076400007640000003020011615341300017000 0ustar rpmbuildrpmbuild/*----------------------------------------------------------------------------*/ /* Xymon demonstration tool. */ /* */ /* This tool fakes several hosts that can be tested by Xymon, both with */ /* fake network services and fake client data. It is used to demonstrate */ /* features in Xymon. */ /* */ /* Copyright (C) 2005-2011 Henrik Storner */ /* */ /* This program is released under the GNU General Public License (GPL), */ /* version 2. See the file "COPYING" for details. */ /* */ /*----------------------------------------------------------------------------*/ static char rcsid[] = "$Id: demotool.c 6712 2011-07-31 21:01:52Z storner $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif char *CONFIGDIR = "/etc/hdemo"; struct sockaddr_in srvaddr; volatile int reconfig = 1; typedef struct netsvc_t { int listenfd; int delay; char *response; int respsize; struct netsvc_t *next; } netsvc_t; netsvc_t *nethead = NULL; typedef struct active_t { int fd; netsvc_t *svc; struct timeval rbegin; char *respbuf, *respptr; int readdone; int bytesleft; struct active_t *next; } active_t; active_t *acthead = NULL; typedef struct client_t { time_t lastupd; char *hostname; char *ostype; time_t bootup; double minload, maxload; char *msg; struct client_t *next; } client_t; client_t *clihead = NULL; static DIR *confdir = NULL; struct dirent *dent = NULL; static char *path = NULL; char *nextservice(char *dirname, char *svc) { struct stat st; char fn[PATH_MAX]; FILE *fd; char *result; if (dirname) { if (confdir) closedir(confdir); if (path) free(path); confdir = opendir(dirname); path = strdup(dirname); } do { do { dent = readdir(confdir); } while (dent && (*(dent->d_name) == '.')); if (!dent) { closedir(confdir); free(path); path = NULL; confdir = NULL; dent = NULL; return NULL; } sprintf(fn, "%s/%s/%s", path, dent->d_name, svc); } while ( (stat(fn, &st) == -1) || ((fd = fopen(fn, "r")) == NULL) ); result = (char *)malloc(st.st_size+1); fread(result, 1, st.st_size, fd); *(result + st.st_size) = '\0'; fclose(fd); return result; } char *svcattrib(char *attr) { struct stat st; char fn[PATH_MAX]; FILE *fd; char *result; if (!dent) return NULL; if (!attr) { sprintf(fn, "%s/%s", path, dent->d_name); return strdup(fn); } sprintf(fn, "%s/%s/%s", path, dent->d_name, attr); if (stat(fn, &st) == -1) return NULL; fd = fopen(fn, "r"); if (!fd) return NULL; result = (char *)calloc(1, st.st_size+1); fread(result, 1, st.st_size, fd); fclose(fd); return result; } void addtobuffer(char **buf, int *bufsz, char *newtext) { if (*buf == NULL) { *bufsz = strlen(newtext) + 4096; *buf = (char *) malloc(*bufsz); **buf = '\0'; } else if ((strlen(*buf) + strlen(newtext) + 1) > *bufsz) { *bufsz += strlen(newtext) + 4096; *buf = (char *) realloc(*buf, *bufsz); } strcat(*buf, newtext); } char *clientdata(char *cpath) { char *res = NULL; int ressz = 0; DIR *cdir; struct dirent *d; char fn[PATH_MAX]; struct stat st; int n; FILE *fd; char buf[4096]; cdir = opendir(cpath); while ((d = readdir(cdir)) != NULL) { if (strncmp(d->d_name, "client_", 7) != 0) continue; sprintf(fn, "%s/%s", cpath, d->d_name); if (stat(fn, &st) == -1) continue; fd = fopen(fn, "r"); if (fd == NULL) continue; sprintf(buf, "[%s]\n", d->d_name+7); addtobuffer(&res, &ressz, buf); while ((n = fread(buf, 1, sizeof(buf)-1, fd)) > 0) { *(buf+n) = '\0'; addtobuffer(&res, &ressz, buf); } fclose(fd); } closedir(cdir); if (!res) res = strdup(""); return res; } int timeafter(struct timeval *lim, struct timeval *now) { if (now->tv_sec > lim->tv_sec) return 1; if (now->tv_sec < lim->tv_sec) return 0; return (now->tv_usec >= lim->tv_usec); } void setuplisteners(void) { netsvc_t *nwalk; char *lspec; struct sockaddr_in laddr; nwalk = nethead; while (nwalk) { netsvc_t *tmp = nwalk; nwalk = nwalk->next; if (tmp->listenfd > 0) close(tmp->listenfd); if (tmp->response) free(tmp->response); free(tmp); } nethead = NULL; lspec = nextservice(CONFIGDIR, "listen"); while (lspec) { char *p, *listenip = NULL; int listenport = -1; int lsocket, opt; p = strchr(lspec, ':'); if (p) { *p = '\0'; p++; listenip = lspec; listenport = atoi(p); } if (listenip && (listenport > 0)) { memset(&laddr, 0, sizeof(laddr)); inet_aton(listenip, (struct in_addr *) &laddr.sin_addr.s_addr); laddr.sin_port = htons(listenport); laddr.sin_family = AF_INET; lsocket = socket(AF_INET, SOCK_STREAM, 0); if (lsocket != -1) { opt = 1; setsockopt(lsocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); fcntl(lsocket, F_SETFL, O_NONBLOCK); if ( (bind(lsocket, (struct sockaddr *)&laddr, sizeof(laddr)) != -1) && (listen(lsocket, 10) != -1) ) { netsvc_t *newitem = malloc(sizeof(netsvc_t)); newitem->listenfd = lsocket; newitem->response = svcattrib("response"); newitem->respsize = (newitem->response ? strlen(newitem->response) : 0); p = svcattrib("delay"); newitem->delay = (p ? atoi(p) : 0); newitem->next = nethead; nethead = newitem; } } } free(lspec); lspec = nextservice(NULL, "listen"); } } void setupclients(void) { client_t *cwalk; char *cspec; cwalk = clihead; while (cwalk) { client_t *tmp = cwalk; cwalk = cwalk->next; if (tmp->hostname) free(tmp->hostname); if (tmp->ostype) free(tmp->ostype); if (tmp->msg) free(tmp->msg); free(tmp); } clihead = NULL; cspec = nextservice(CONFIGDIR, "client"); while (cspec) { char *p; p = strchr(cspec, ':'); if (p) { client_t *newitem = (client_t *)malloc(sizeof(client_t)); *p = '\0'; newitem->lastupd = 0; newitem->hostname = strdup(cspec); newitem->ostype = strdup(p+1); while ((p = strchr(newitem->hostname, '.')) != NULL) *p = ','; p = svcattrib("uptime"); if (p) newitem->bootup = time(NULL) - 60*atoi(p); else newitem->bootup = time(NULL); p = svcattrib("minload"); if (p) newitem->minload = atof(p); else newitem->minload = 0.2; p = svcattrib("maxload"); if (p) newitem->maxload = atof(p); else newitem->maxload = 1.0; newitem->msg = clientdata(svcattrib(NULL)); newitem->next = clihead; clihead = newitem; } free(cspec); cspec = nextservice(NULL, "client"); } } void do_select(void) { fd_set readfds, writefds; int maxfd, n; netsvc_t *nwalk; active_t *awalk, *aprev; struct timeval now, start; struct timezone tz; struct timeval tmo; char rbuf[4096]; gettimeofday(&start, &tz); do { gettimeofday(&now, &tz); FD_ZERO(&readfds); FD_ZERO(&writefds); maxfd = -1; nwalk = nethead; while (nwalk) { if (nwalk->listenfd) { FD_SET(nwalk->listenfd, &readfds); if (nwalk->listenfd > maxfd) maxfd = nwalk->listenfd; } nwalk = nwalk->next; } awalk = acthead; while (awalk) { if (awalk->fd) { if (!awalk->readdone) { FD_SET(awalk->fd, &readfds); if (awalk->fd > maxfd) maxfd = awalk->fd; } if (timeafter(&awalk->rbegin, &now)) { FD_SET(awalk->fd, &writefds); if (awalk->fd > maxfd) maxfd = awalk->fd; } } awalk = awalk->next; } tmo.tv_sec = 0; tmo.tv_usec = 100000; n = select(maxfd+1, &readfds, &writefds, NULL, &tmo); } while ((n == 0) && ((now.tv_sec - start.tv_sec) < 10)); if (n <= 0) return; gettimeofday(&now, &tz); awalk = acthead; aprev = NULL; while (awalk) { if (awalk->fd && !awalk->readdone && FD_ISSET(awalk->fd, &readfds)) { n = read(awalk->fd, rbuf, sizeof(rbuf)); if (n <= 0) awalk->readdone = 1; } if (awalk->fd && awalk->respptr && FD_ISSET(awalk->fd, &writefds)) { n = write(awalk->fd, awalk->respptr, awalk->bytesleft); if (n > 0) { awalk->respptr += n; awalk->bytesleft -= n; } } else n = 0; if ((awalk->bytesleft == 0) || (n < 0)) { if (awalk->respbuf) free(awalk->respbuf); close(awalk->fd); awalk->fd = 0; } if (awalk->fd) { aprev = awalk; awalk = awalk->next; } else { active_t *tmp = awalk; awalk = awalk->next; if (aprev) aprev->next = awalk; else acthead = awalk; free(tmp); } } nwalk = nethead; while (nwalk) { int newfd; if (nwalk->listenfd && FD_ISSET(nwalk->listenfd, &readfds)) { while ((newfd = accept(nwalk->listenfd, NULL, 0)) > 0) { /* Pick up a new connection */ fcntl(newfd, F_SETFL, O_NONBLOCK); active_t *newitem = (active_t *)malloc(sizeof(active_t)); newitem->fd = newfd; newitem->rbegin.tv_sec = now.tv_sec + nwalk->delay; newitem->rbegin.tv_usec = now.tv_usec + (random() % 1000000); if (newitem->rbegin.tv_usec > 1000000) { newitem->rbegin.tv_usec -= 1000000; newitem->rbegin.tv_sec++; } newitem->svc = nwalk; if (nwalk->response) { newitem->respbuf = strdup(nwalk->response); newitem->respptr = newitem->respbuf; newitem->bytesleft = nwalk->respsize; } else { newitem->respbuf = NULL; newitem->respptr = NULL; newitem->bytesleft = 0; } newitem->readdone = 0; newitem->next = acthead; acthead = newitem; } } nwalk = nwalk->next; } } void do_clients(void) { client_t *cwalk; active_t *conn; time_t now = time(NULL); time_t uptime; int updays, uphours, upmins; int n; struct tm *tm; double curload; cwalk = clihead; while (cwalk && ((cwalk->lastupd + 60) > now)) cwalk = cwalk->next; if (!cwalk) return; cwalk->lastupd = now; tm = localtime(&now); uptime = now - cwalk->bootup; updays = uptime / 86400; uphours = (uptime % 86400) / 3600; upmins = (uptime % 3600) / 60; curload = cwalk->minload + ((random() % 1000) / 1000.0) * (cwalk->maxload - cwalk->minload); conn = malloc(sizeof(active_t)); conn->fd = socket(AF_INET, SOCK_STREAM, 0); fcntl(conn->fd, F_SETFL, O_NONBLOCK); conn->rbegin.tv_sec = now; conn->rbegin.tv_usec = 0; conn->svc = NULL; conn->respbuf = (char *)malloc(strlen(cwalk->msg) + 4096); sprintf(conn->respbuf, "client %s.%s\n[date]\n%s[uptime]\n %02d:%02d:%02d up %d days, %d:%02d, 1 users, load average: 0.21, %5.2f, 0.25\n\n%s\n", cwalk->hostname, cwalk->ostype, ctime(&now), tm->tm_hour, tm->tm_min, tm->tm_sec, updays, uphours, upmins, curload, cwalk->msg); conn->respptr = conn->respbuf; conn->bytesleft = strlen(conn->respbuf); conn->readdone = 0; n = connect(conn->fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr)); if ((n == 0) || ((n == -1) && (errno == EINPROGRESS))) { conn->next = acthead; acthead = conn; } else { close(conn->fd); free(conn->respbuf); free(conn); } } void sigmisc_handler(int signum) { if (signum == SIGHUP) reconfig = 1; } int main(int argc, char *argv[]) { int argi; struct sigaction sa; time_t lastconf = 0; memset(&srvaddr, 0, sizeof(srvaddr)); srvaddr.sin_port = htons(1984); srvaddr.sin_family = AF_INET; inet_aton("127.0.0.1", (struct in_addr *) &srvaddr.sin_addr.s_addr); for (argi = 1; (argi < argc); argi++) { if (strncmp(argv[argi], "--confdir=", 10) == 0) { char *p = strchr(argv[argi], '='); CONFIGDIR = strdup(p+1); } else if (strncmp(argv[argi], "--srvip=", 8) == 0) { char *p = strchr(argv[argi], '='); inet_aton(p+1, (struct in_addr *) &srvaddr.sin_addr.s_addr); } } memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigmisc_handler; sigaction(SIGHUP, &sa, NULL); while (1) { if (reconfig || (time(NULL) > (lastconf+60))) { printf("(Re)loading config\n"); setuplisteners(); setupclients(); reconfig = 0; lastconf = time(NULL); } do_clients(); do_select(); } return 0; } xymon-4.3.30/demotool/Makefile0000664000076400007640000000015111070452713016462 0ustar rpmbuildrpmbuildall: demotool demotool: demotool.o $(CC) $(CFLAGS) -o $@ $< $(NETLIBS) clean: rm -f *.o demotool *~ xymon-4.3.30/demotool/data/0000775000076400007640000000000013534041774015746 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/0000775000076400007640000000000013534041774017540 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/smtp/0000775000076400007640000000000013534041774020523 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/smtp/listen0000664000076400007640000000001711411662565021741 0ustar rpmbuildrpmbuild127.0.0.1:3025 xymon-4.3.30/demotool/data/democonf/smtp/response0000664000076400007640000000003111411662565022275 0ustar rpmbuildrpmbuild220 voodoo.hswn.dk ESMTP xymon-4.3.30/demotool/data/democonf/demohost/0000775000076400007640000000000013534041774021362 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/demohost/client_ps0000664000076400007640000003713011411662565023270 0ustar rpmbuildrpmbuild PID PPID USER STARTED S PRI %CPU TIME %MEM RSZ VSZ CMD 1 0 root Jan 23 S 23 0.0 00:00:01 0.0 532 1764 /sbin/init splash 2 1 root Jan 23 S 139 0.0 00:00:00 0.0 0 0 [migration/0] 3 1 root Jan 23 S 5 0.0 00:00:00 0.0 0 0 [ksoftirqd/0] 4 1 root Jan 23 S 139 0.0 00:00:00 0.0 0 0 [watchdog/0] 5 1 root Jan 23 S 29 0.0 00:00:05 0.0 0 0 [events/0] 6 1 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [khelper] 7 1 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [kthread] 9 7 root Jan 23 S 29 0.0 00:00:01 0.0 0 0 [kblockd/0] 10 7 root Jan 23 S 19 0.0 00:00:00 0.0 0 0 [kacpid] 11 7 root Jan 23 S 19 0.0 00:00:00 0.0 0 0 [kacpi_notify] 124 7 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [kseriod] 157 7 root Jan 23 S 24 0.0 00:00:21 0.0 0 0 [pdflush] 159 1 root Jan 23 S 24 0.0 00:00:27 0.0 0 0 [kswapd0] 160 7 root Jan 23 S 20 0.0 00:00:00 0.0 0 0 [aio/0] 1715 7 root Jan 23 S 25 0.0 00:00:00 0.0 0 0 [ata/0] 1795 7 root Jan 23 S 23 0.0 00:00:00 0.0 0 0 [scsi_eh_0] 1796 7 root Jan 23 S 23 0.0 00:00:00 0.0 0 0 [scsi_eh_1] 1825 7 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [khubd] 1838 7 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [khpsbpkt] 1854 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [knodemgrd_0] 1982 7 root Jan 23 S 29 0.0 00:00:02 0.0 0 0 [reiserfs/0] 2064 1 root Jan 23 S 24 0.0 00:00:00 0.0 544 1728 //sbin/logd 2228 1 root Jan 23 S 27 0.0 00:00:01 0.0 1260 2736 /sbin/udevd --daemon 2960 7 root Jan 23 S 26 0.0 00:00:00 0.0 0 0 [shpchpd] 3044 7 root Jan 23 S 23 0.0 00:00:00 0.0 0 0 [kpsmoused] 3455 1 dhcp Jan 23 S 25 0.0 00:00:00 0.0 840 2520 dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclient.eth0.leases eth0 3791 1 daemon Jan 23 S 24 0.0 00:00:00 0.0 388 1704 /sbin/portmap 3970 1 root Jan 23 S 23 0.0 00:00:00 0.0 1172 2672 /bin/login -- 3971 1 root Jan 23 S 23 0.0 00:00:00 0.0 508 1600 /sbin/getty 38400 tty2 3972 1 root Jan 23 S 23 0.0 00:00:00 0.0 508 1600 /sbin/getty 38400 tty3 3973 1 root Jan 23 S 23 0.0 00:00:00 0.0 500 1596 /sbin/getty 38400 tty4 3974 1 root Jan 23 S 23 0.0 00:00:00 0.0 504 1596 /sbin/getty 38400 tty5 3975 1 root Jan 23 S 23 0.0 00:00:00 0.0 508 1600 /sbin/getty 38400 tty6 4179 1 root Jan 23 S 23 0.0 00:00:00 0.0 1156 2200 /usr/sbin/acpid -c /etc/acpi/events -s /var/run/acpid.socket 4305 1 root Jan 23 S 24 0.0 00:01:19 0.0 508 1720 /bin/dd bs 1 if /proc/kmsg of /var/run/klogd/kmsg 4307 1 klog Jan 23 S 23 0.0 00:00:17 0.0 1288 2408 /sbin/klogd -P /var/run/klogd/kmsg 4326 1 102 Jan 23 S 24 0.0 00:00:01 0.0 856 2176 /usr/bin/dbus-daemon --system 4341 1 121 Jan 23 S 24 0.0 00:00:03 0.3 5556 7088 /usr/sbin/hald 4342 4341 root Jan 23 S 22 0.0 00:00:00 0.0 1064 2912 hald-runner 4348 4342 121 Jan 23 S 14 0.0 00:00:00 0.0 804 2020 /usr/lib/hal/hald-addon-acpi 4355 4342 121 Jan 23 S 24 0.0 00:00:09 0.0 808 2020 /usr/lib/hal/hald-addon-keyboard 4365 4342 121 Jan 23 S 24 0.0 00:00:19 0.0 916 2028 /usr/lib/hal/hald-addon-storage 4402 1 root Jan 23 S 24 0.0 00:00:00 0.1 1624 4176 /usr/sbin/openvpn --writepid /var/run/openvpn.client.pid --daemon ovpn-client --status /var/run/openvpn.client.status 10 --cd /etc/openvpn --config /etc/openvpn/client.conf 4466 1 root Jan 23 S 19 0.0 00:00:00 0.1 2528 21924 /usr/sbin/slapd 4495 1 root Jan 23 S 23 0.0 00:00:01 0.1 2272 5584 /usr/sbin/apt-index-watcher watch --syslog 4646 1 root Jan 23 S 23 0.0 00:00:00 0.0 680 1744 /usr/sbin/automount --pid-file=/var/run/autofs/_home.pid --timeout=1200 /home file /etc/auto.home 4654 1 root Jan 23 S 23 0.0 00:00:00 0.0 688 1748 /usr/sbin/automount --pid-file=/var/run/autofs/_var_netdisk.pid --timeout=300 /var/netdisk file /etc/auto.netdisk 4709 1 root Jan 23 S 14 0.0 00:00:00 0.0 504 1640 /usr/sbin/inetd 4726 1 ivman Jan 23 S 23 0.0 00:00:00 0.1 1640 4632 /usr/bin/ivman 4767 7 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [nfsd4] 4768 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4769 1 root Jan 23 S 14 0.0 00:00:00 0.0 0 0 [lockd] 4770 7 root Jan 23 S 29 0.0 00:00:30 0.0 0 0 [rpciod/0] 4771 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4772 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4773 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4774 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4775 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4776 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4777 1 root Jan 23 S 24 0.0 00:00:00 0.0 0 0 [nfsd] 4781 1 root Jan 23 S 14 0.0 00:00:00 0.0 284 1788 /usr/sbin/rpc.mountd 4857 1 root Jan 23 S 24 0.0 00:00:00 0.1 1620 4796 /usr/lib/postfix/master 4859 4857 postfix Jan 23 S 24 0.0 00:00:00 0.1 1700 4844 qmgr -l -t fifo -u -c 4893 1 root Jan 23 S 23 0.0 00:00:00 0.0 1064 4936 /usr/sbin/sshd 4972 1 root Jan 23 S 23 0.0 00:00:00 0.0 660 2684 /usr/bin/kdm 4986 1 statd Jan 23 S 24 0.0 00:00:00 0.0 720 1744 /sbin/rpc.statd 5009 1 root Jan 23 S 14 0.0 00:00:00 0.0 708 2068 /usr/sbin/hcid 5015 1 root Jan 23 S 14 0.0 00:00:00 0.0 496 1668 /usr/sbin/sdpd 5026 1 root Jan 23 S 15 0.0 00:00:00 0.0 468 1828 /usr/bin/hidd --search --master --server 5033 1 root Jan 23 S 29 0.0 00:00:00 0.0 0 0 [krfcommd] 5046 1 root Jan 23 S 24 0.0 00:00:00 0.0 300 1716 /sbin/mdadm --monitor --pid-file /var/run/mdadm.pid --mail root --daemonise --scan 5081 1 daemon Jan 23 S 23 0.0 00:00:00 0.0 468 1852 /usr/sbin/atd 5111 1 root Jan 23 S 23 0.0 00:00:00 0.0 856 2192 /usr/sbin/cron 5179 1 root Jan 23 S 20 0.0 00:00:00 0.0 164 1452 /opt/VMware/bin/vmnet-bridge -d /var/run/vmnet-bridge-0.pid /dev/vmnet0 eth0 5876 1 henrik Jan 23 S 24 0.0 00:00:00 0.0 444 2564 gpg-agent --daemon 5976 1 henrik Jan 23 S 23 0.0 00:00:00 0.0 464 2684 /opt/applix/axdata/axnet /tmp/.axnetipc -fork 17872 1 henrik Feb 02 S 24 0.0 00:00:00 0.0 444 2560 gpg-agent --daemon 3469 7 root Feb 05 S 24 0.0 00:00:20 0.0 0 0 [pdflush] 32003 1 hobbit Feb 07 S 23 0.0 00:00:05 0.0 444 1908 /usr/lib/hobbit/server/bin/hobbitlaunch --config=/usr/lib/hobbit/server/etc/hobbitlaunch.cfg --env=/usr/lib/hobbit/server/etc/hobbitserver.cfg --log=/var/log/hobbit/hobbitlaunch.log --pidfile=/var/log/hobbit/hobbitlaunch.pid 32004 32003 hobbit Feb 07 S 23 0.0 00:00:17 0.0 1256 4892 hobbitd --pidfile=/var/log/hobbit/hobbitd.pid --restart=/usr/lib/hobbit/server/tmp/hobbitd.chk --checkpoint-file=/usr/lib/hobbit/server/tmp/hobbitd.chk --checkpoint-interval=600 --log=/var/log/hobbit/hobbitd.log --admin-senders=127.0.0.1 127.0.0.1 --store-clientlogs=!msgs 32005 32003 hobbit Feb 07 S 23 0.0 00:00:00 0.0 540 2176 hobbitd_channel --channel=stachg --log=/var/log/hobbit/history.log hobbitd_history 32006 32003 hobbit Feb 07 S 23 0.0 00:00:00 0.0 588 2436 hobbitd_channel --channel=clichg --log=/var/log/hobbit/hostdata.log hobbitd_hostdata 32007 32003 hobbit Feb 07 S 23 0.0 00:00:00 0.0 604 2176 hobbitd_channel --channel=page --log=/var/log/hobbit/page.log hobbitd_alert --checkpoint-file=/usr/lib/hobbit/server/tmp/alert.chk --checkpoint-interval=600 32008 32003 hobbit Feb 07 S 24 0.0 00:00:02 0.0 548 2180 hobbitd_channel --channel=status --log=/var/log/hobbit/rrd-status.log hobbitd_rrd --rrddir=/var/lib/hobbit/rrd 32009 32003 hobbit Feb 07 S 24 0.0 00:00:00 0.0 512 2176 hobbitd_channel --channel=data --log=/var/log/hobbit/rrd-data.log hobbitd_rrd --rrddir=/var/lib/hobbit/rrd 32010 32003 hobbit Feb 07 S 23 0.0 00:00:02 0.0 600 2432 hobbitd_channel --channel=client --log=/var/log/hobbit/clientdata.log hobbitd_client 32015 32005 hobbit Feb 07 S 23 0.0 00:00:00 0.0 676 2320 hobbitd_history 32016 32008 hobbit Feb 07 S 23 0.0 00:00:19 0.0 1528 3896 hobbitd_rrd --rrddir=/var/lib/hobbit/rrd 32062 32010 hobbit Feb 07 S 23 0.0 00:00:01 0.0 1480 2872 hobbitd_client 32063 32009 hobbit Feb 07 S 23 0.0 00:00:08 0.0 1536 3896 hobbitd_rrd --rrddir=/var/lib/hobbit/rrd 32081 32006 hobbit Feb 07 S 23 0.0 00:00:00 0.0 640 2184 hobbitd_hostdata 20945 1 henrik Feb 08 S 24 0.0 00:00:00 0.0 444 2564 gpg-agent --daemon 27371 1 root Feb 09 S 23 0.0 00:00:07 1.1 18172 417020 /work/obm/jvm/bin/java -Xrs -Xmx256m -client -Djava.library.path=/work/obm/bin -cp /work/obm/bin:/work/obm/bin/obcs.jar:/work/obm/bin/obcs-lib.jar obcs /work/obm 12564 3970 henrik Feb 10 S 23 0.0 00:00:00 0.1 2044 3688 -bash 4352 1 henrik Feb 11 S 24 0.0 00:00:00 0.0 444 2564 gpg-agent --daemon 10421 1 cupsys Feb 15 S 14 0.0 00:00:00 0.1 2032 4568 /usr/sbin/cupsd 24441 1 root 07:35:51 S 14 0.0 00:00:00 0.1 2424 7984 /usr/sbin/apache2 -k start -DSSL 24442 24441 www-data 07:35:51 S 14 0.0 00:00:00 0.1 1796 7776 /usr/sbin/apache2 -k start -DSSL 24443 24441 www-data 07:35:51 S 5 0.0 00:00:00 0.2 3624 229728 /usr/sbin/apache2 -k start -DSSL 24455 24441 www-data 07:35:51 S 6 0.0 00:00:00 0.2 3916 230000 /usr/sbin/apache2 -k start -DSSL 24540 1 root 07:35:52 S 14 0.0 00:00:00 0.0 724 2960 /usr/bin/dirmngr --daemon --sh 24678 1 root 07:36:11 S 14 0.0 00:00:00 0.0 572 1648 /sbin/syslogd 29276 4857 postfix 12:35:42 S 23 0.0 00:00:00 0.1 1572 4808 pickup -l -t fifo -u -c 30177 32007 hobbit 13:23:44 S 24 0.0 00:00:00 0.0 984 2424 hobbitd_alert --checkpoint-file=/usr/lib/hobbit/server/tmp/alert.chk --checkpoint-interval=600 30326 4972 root 13:32:15 R 23 3.6 00:01:14 3.5 55148 62960 /usr/bin/X -br -nolisten tcp :0 vt7 -auth /var/run/xauth/A:0-FfyMdk 30327 4972 root 13:32:15 S 23 0.0 00:00:00 0.0 1412 3660 -:0 30336 30327 henrik 13:32:30 S 23 0.0 00:00:00 0.1 1608 3312 /bin/sh /usr/bin/startkde 30407 1 henrik 13:32:32 S 24 0.0 00:00:00 0.0 448 2564 gpg-agent --daemon 30416 30336 henrik 13:32:32 S 24 0.0 00:00:00 0.0 728 4480 /usr/bin/ssh-agent /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session /usr/bin/startkde 30417 30336 henrik 13:32:32 S 24 0.0 00:00:00 0.0 724 4480 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session /usr/bin/startkde 30420 1 henrik 13:32:32 S 23 0.0 00:00:00 0.0 628 2532 /usr/bin/dbus-launch --exit-with-session /usr/bin/startkde 30421 1 henrik 13:32:32 S 15 0.0 00:00:00 0.0 428 2056 /usr/bin/dbus-daemon --fork --print-pid 9 --print-address 7 --session 30452 1 henrik 13:32:33 S 23 0.0 00:00:00 0.0 140 1448 start_kdeinit --new-startup +kcminit_startup 30453 1 henrik 13:32:33 S 23 0.0 00:00:00 0.4 7692 24320 kdeinit Running... 30456 1 henrik 13:32:33 S 24 0.0 00:00:00 0.1 3008 23856 dcopserver [kdeinit] --nosid 30458 30453 henrik 13:32:33 S 24 0.0 00:00:00 0.5 8732 26016 klauncher [kdeinit] --new-startup 30460 1 henrik 13:32:35 S 24 0.0 00:00:00 0.9 14240 30340 kded [kdeinit] --new-startup 30466 30336 henrik 13:32:37 S 24 0.0 00:00:00 0.0 356 1584 kwrapper ksmserver 30468 1 henrik 13:32:37 S 24 0.0 00:00:00 0.6 9880 25568 ksmserver [kdeinit] 30469 30453 henrik 13:32:37 S 24 0.1 00:00:02 0.8 13480 28012 kwin [kdeinit] -session 10d8e66972000113665488500000147750000_1171801918_683812 30471 1 henrik 13:32:38 S 24 0.0 00:00:01 1.0 15824 29840 kdesktop [kdeinit] 30473 1 henrik 13:32:39 S 24 0.1 00:00:03 1.1 17564 32264 kicker [kdeinit] 30477 30453 henrik 13:32:39 S 24 0.0 00:00:00 0.5 8720 26460 kio_file [kdeinit] file /tmp/ksocket-henrik/klauncherztj4ca.slave-socket /tmp/ksocket-henrik/kdesktopUJZMlb.slave-socket 30480 30453 henrik 13:32:42 S 90 0.0 00:00:01 0.4 7724 21244 /usr/bin/artsd -F 10 -S 4096 -s 60 -m artsmessage -c drkonqi -l 3 -f 30489 1 henrik 13:32:43 S 24 0.0 00:00:00 0.6 9536 25324 kaccess [kdeinit] 30492 1 henrik 13:32:43 S 24 0.0 00:00:00 0.9 15096 29412 kmix [kdeinit] -session 10d8e66972000113137936700000076630078_1171801918_592291 30493 30453 henrik 13:32:43 S 24 0.0 00:00:01 0.6 9448 15276 gkrellm --sm-client-id 101af1c8105108000115942552700000054890012 30498 30453 henrik 13:32:44 S 24 0.0 00:00:00 0.3 6140 26788 xmms --sm-client-id 101af1c8105108000116094585300000054240022 30501 1 henrik 13:32:45 S 24 0.0 00:00:00 0.5 8456 13996 /opt/applix/axdata/axmain -helper 30500 4 8 -servicename axmain:henrik::0 30508 1 henrik 13:32:46 S 24 0.0 00:00:00 0.0 292 2864 applix 30510 1 henrik 13:32:46 S 24 0.0 00:00:00 0.8 12940 33268 knotify [kdeinit] 30516 1 henrik 13:32:47 S 24 0.1 00:00:03 0.9 14752 30436 adept_notifier 30518 1 henrik 13:32:48 S 24 0.0 00:00:00 0.7 11608 26404 klipper [kdeinit] 30520 1 henrik 13:32:48 S 24 0.0 00:00:00 0.9 14404 30680 korgac --miniicon korganizer 30727 1 henrik 13:41:55 S 23 0.0 00:00:00 0.1 1604 3312 /bin/sh /usr/lib/openoffice/program/soffice -impress -splash-pipe=5 30741 30727 henrik 13:41:58 S 24 1.5 00:00:22 6.4 100704 226848 /usr/lib/openoffice/program/soffice.bin -impress -splash-pipe=5 30813 30453 henrik 13:44:16 S 24 0.1 00:00:02 1.0 16532 32268 konsole [kdeinit] 30814 30813 henrik 13:44:17 S 24 0.0 00:00:00 0.1 2080 3688 /bin/bash 30821 30814 henrik 13:44:27 S 24 0.0 00:00:00 0.0 560 1588 ./demotool --confdir=/home/henrik/democonf/ 30822 30453 henrik 13:44:34 S 24 3.0 00:00:40 2.3 37272 126892 /usr/lib/firefox/firefox-bin 30827 1 henrik 13:44:34 S 24 0.0 00:00:00 0.1 2688 4500 /usr/lib/libgconf2-4/gconfd-2 13 30835 30822 henrik 13:44:37 Z 18 0.0 00:00:00 0.0 0 0 [netstat] 30861 30813 henrik 13:46:07 S 24 0.0 00:00:00 0.1 2088 3700 /bin/bash 31254 1 hobbit 14:03:49 S 19 0.0 00:00:00 0.0 1372 2984 sh -c vmstat 300 2 1>/usr/lib/hobbit/client/tmp/hobbit_vmstat.localhost.31226 2>&1; mv /usr/lib/hobbit/client/tmp/hobbit_vmstat.localhost.31226 /usr/lib/hobbit/client/tmp/hobbit_vmstat.localhost 31255 31254 hobbit 14:03:49 S 19 0.0 00:00:00 0.0 564 1852 vmstat 300 2 31298 30861 henrik 14:06:19 R 23 0.0 00:00:00 0.0 948 2480 ps -Aww -o pid,ppid,user,start,state,pri,pcpu,time,pmem,rsz,vsz,cmd xymon-4.3.30/demotool/data/democonf/demohost/client_df0000664000076400007640000000042311411662565023232 0ustar rpmbuildrpmbuildFilsystem 1024-blokke Brugt Tilbage Kapacitet Monteret på /dev/hda2 99511580 27342896 72168684 28% / procbususb 10240 108 10132 2% /proc/bus/usb /dev/hda3 47856164 44684240 3171924 94% /work xymon-4.3.30/demotool/data/democonf/demohost/client_ifconfig0000664000076400007640000000167011411662565024432 0ustar rpmbuildrpmbuildeth0 Link encap:Ethernet HWaddr 00:0E:A6:CE:D6:85 inet addr:172.16.10.100 Bcast:172.16.10.255 Mask:255.255.255.0 inet6 addr: fe80::20e:a6ff:fece:d685/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:15281037 errors:0 dropped:0 overruns:0 frame:0 TX packets:15371394 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:30021682 (28.6 MiB) TX bytes:3023884776 (2.8 GiB) Interrupt:209 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:1057321 errors:0 dropped:0 overruns:0 frame:0 TX packets:1057321 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:574807062 (548.1 MiB) TX bytes:574807062 (548.1 MiB) xymon-4.3.30/demotool/data/democonf/demohost/client_uname0000664000076400007640000000005411411662565023746 0ustar rpmbuildrpmbuildLinux osiris.hswn.dk 2.6.17-10-generic i686 xymon-4.3.30/demotool/data/democonf/demohost/client_ports0000664000076400007640000000506611411662565024020 0ustar rpmbuildrpmbuildActive Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:1984 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:40992 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:43203 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:3110 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:3080 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:720 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:3025 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:9011 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:9012 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:53526 127.0.0.1:1984 TIME_WAIT tcp 0 0 127.0.0.1:53527 127.0.0.1:1984 TIME_WAIT tcp 0 0 127.0.0.1:53530 127.0.0.1:1984 TIME_WAIT tcp 0 0 127.0.0.1:53528 127.0.0.1:1984 TIME_WAIT tcp 0 0 127.0.0.1:58561 127.0.0.1:1984 TIME_WAIT tcp 0 0 172.16.10.100:726 172.16.10.2:32775 ESTABLISHED tcp 0 0 172.16.10.100:881 172.16.10.2:2049 ESTABLISHED tcp 0 0 127.0.0.1:50756 127.0.0.1:80 ESTABLISHED tcp 0 0 127.0.0.1:50754 127.0.0.1:80 ESTABLISHED tcp6 0 0 :::389 :::* LISTEN tcp6 0 0 :::80 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::ffff:127.0.0.1:80 ::ffff:127.0.0.1:50754 ESTABLISHED tcp6 0 0 ::ffff:127.0.0.1:80 ::ffff:127.0.0.1:50756 ESTABLISHED tcp6 0 0 ::ffff:127.0.0.1:80 ::ffff:127.0.0.1:34951 TIME_WAIT tcp6 0 0 ::ffff:127.0.0.1:80 ::ffff:127.0.0.1:34953 TIME_WAIT tcp6 0 0 ::ffff:172.16.10.:52475 ::ffff:194.150.112.:443 ESTABLISHED xymon-4.3.30/demotool/data/democonf/demohost/client_top0000664000076400007640000004710711411662565023455 0ustar rpmbuildrpmbuildtop - 14:09:26 up 26 days, 13:28, 2 users, load average: 0.17, 0.20, 0.27 Tasks: 148 total, 2 running, 145 sleeping, 0 stopped, 1 zombie Cpu(s): 1.7%us, 0.3%sy, 1.0%ni, 96.7%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1555860k total, 1500132k used, 55728k free, 45216k buffers Swap: 1004020k total, 17684k used, 986336k free, 1205916k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 16 0 1764 532 448 S 0.0 0.0 0:01.53 init 2 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.24 ksoftirqd/0 4 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 5 root 10 -5 0 0 0 S 0.0 0.0 0:05.43 events/0 6 root 10 -5 0 0 0 S 0.0 0.0 0:00.01 khelper 7 root 10 -5 0 0 0 S 0.0 0.0 0:00.01 kthread 9 root 10 -5 0 0 0 S 0.0 0.0 0:01.89 kblockd/0 10 root 20 -5 0 0 0 S 0.0 0.0 0:00.00 kacpid 11 root 20 -5 0 0 0 S 0.0 0.0 0:00.00 kacpi_notify 124 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 kseriod 157 root 15 0 0 0 0 S 0.0 0.0 0:21.02 pdflush 159 root 15 0 0 0 0 S 0.0 0.0 0:27.35 kswapd0 160 root 19 -5 0 0 0 S 0.0 0.0 0:00.00 aio/0 1715 root 14 -5 0 0 0 S 0.0 0.0 0:00.00 ata/0 1795 root 16 -5 0 0 0 S 0.0 0.0 0:00.00 scsi_eh_0 1796 root 16 -5 0 0 0 S 0.0 0.0 0:00.00 scsi_eh_1 1825 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 khubd 1838 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 khpsbpkt 1854 root 15 0 0 0 0 S 0.0 0.0 0:00.00 knodemgrd_0 1982 root 10 -5 0 0 0 S 0.0 0.0 0:02.08 reiserfs/0 2064 root 15 0 1728 544 468 S 0.0 0.0 0:00.00 logd 2228 root 12 -4 2736 1260 452 S 0.0 0.1 0:01.00 udevd 2960 root 13 -5 0 0 0 S 0.0 0.0 0:00.00 shpchpd 3044 root 16 -5 0 0 0 S 0.0 0.0 0:00.00 kpsmoused 3455 dhcp 14 -2 2520 840 504 S 0.0 0.1 0:00.09 dhclient3 3791 daemon 15 0 1704 388 292 S 0.0 0.0 0:00.03 portmap 3970 root 16 0 2672 1172 908 S 0.0 0.1 0:00.01 login 3971 root 16 0 1600 508 432 S 0.0 0.0 0:00.00 getty 3972 root 16 0 1600 508 432 S 0.0 0.0 0:00.00 getty 3973 root 16 0 1596 500 432 S 0.0 0.0 0:00.00 getty 3974 root 16 0 1596 504 432 S 0.0 0.0 0:00.00 getty 3975 root 16 0 1600 508 432 S 0.0 0.0 0:00.00 getty 4179 root 16 0 2200 1156 640 S 0.0 0.1 0:00.00 acpid 4305 root 15 0 1720 508 420 S 0.0 0.0 1:19.87 dd 4307 klog 16 0 2408 1288 384 S 0.0 0.1 0:17.28 klogd 4326 messageb 15 0 2176 856 640 S 0.0 0.1 0:01.24 dbus-daemon 4341 haldaemo 16 0 7088 5556 1648 S 0.0 0.4 0:03.98 hald 4342 root 17 0 2912 1064 896 S 0.0 0.1 0:00.04 hald-runner 4348 haldaemo 25 0 2020 804 692 S 0.0 0.1 0:00.00 hald-addon-acpi 4355 haldaemo 15 0 2020 808 692 S 0.0 0.1 0:09.20 hald-addon-keyb 4365 haldaemo 16 0 2028 916 788 S 0.0 0.1 0:19.21 hald-addon-stor 4402 root 15 0 4176 1624 1168 S 0.0 0.1 0:00.98 openvpn 4466 root 20 0 21924 2528 1448 S 0.0 0.2 0:00.00 slapd 4495 root 16 0 5584 2272 2056 S 0.0 0.1 0:01.03 apt-index-watch 4646 root 16 0 1744 680 560 S 0.0 0.0 0:00.02 automount 4654 root 16 0 1748 688 560 S 0.0 0.0 0:00.04 automount 4709 root 25 0 1640 504 424 S 0.0 0.0 0:00.00 inetd 4726 ivman 16 0 4632 1640 1224 S 0.0 0.1 0:00.16 ivman 4767 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 nfsd4 4768 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4769 root 25 0 0 0 0 S 0.0 0.0 0:00.00 lockd 4770 root 10 -5 0 0 0 S 0.0 0.0 0:30.16 rpciod/0 4771 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4772 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4773 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4774 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4775 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4776 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4777 root 15 0 0 0 0 S 0.0 0.0 0:00.00 nfsd 4781 root 25 0 1788 284 176 S 0.0 0.0 0:00.00 rpc.mountd 4857 root 15 0 4796 1620 1300 S 0.0 0.1 0:00.72 master 4859 postfix 15 0 4844 1700 1372 S 0.0 0.1 0:00.21 qmgr 4893 root 16 0 4936 1064 728 S 0.0 0.1 0:00.02 sshd 4972 root 16 0 2684 660 520 S 0.0 0.0 0:00.00 kdm 4986 statd 15 0 1744 720 612 S 0.0 0.0 0:00.08 rpc.statd 5009 root 25 0 2068 708 612 S 0.0 0.0 0:00.00 hcid 5015 root 25 0 1668 496 428 S 0.0 0.0 0:00.00 sdpd 5026 root 24 0 1828 468 384 S 0.0 0.0 0:00.00 hidd 5033 root 10 -10 0 0 0 S 0.0 0.0 0:00.00 krfcommd 5046 root 15 0 1716 300 236 S 0.0 0.0 0:00.00 mdadm 5081 daemon 16 0 1852 468 348 S 0.0 0.0 0:00.00 atd 5111 root 16 0 2192 856 684 S 0.0 0.1 0:00.39 cron 5179 root 19 0 1452 164 104 S 0.0 0.0 0:00.00 vmnet-bridge 5876 henrik 15 0 2564 444 288 S 0.0 0.0 0:00.15 gpg-agent 5976 henrik 16 0 2684 464 340 S 0.0 0.0 0:00.00 axnet 17872 henrik 15 0 2560 444 288 S 0.0 0.0 0:00.13 gpg-agent 3469 root 15 0 0 0 0 S 0.0 0.0 0:20.02 pdflush 32003 hobbit 16 0 1908 444 348 S 0.0 0.0 0:05.14 hobbitlaunch 32004 hobbit 16 0 4992 1324 844 S 0.0 0.1 0:17.56 hobbitd 32005 hobbit 16 0 2176 540 444 S 0.0 0.0 0:00.00 hobbitd_channel 32006 hobbit 16 0 2436 588 468 S 0.0 0.0 0:00.00 hobbitd_channel 32007 hobbit 16 0 2176 604 504 S 0.0 0.0 0:00.41 hobbitd_channel 32008 hobbit 15 0 2180 548 448 S 0.0 0.0 0:02.05 hobbitd_channel 32009 hobbit 15 0 2176 512 432 S 0.0 0.0 0:00.21 hobbitd_channel 32010 hobbit 15 0 2432 600 476 S 0.0 0.0 0:02.93 hobbitd_channel 32015 hobbit 16 0 2320 696 508 S 0.0 0.0 0:00.03 hobbitd_history 32016 hobbit 16 0 3896 1528 800 S 0.0 0.1 0:19.16 hobbitd_rrd 32062 hobbit 16 0 2872 1480 712 S 0.0 0.1 0:01.24 hobbitd_client 32063 hobbit 15 0 3896 1580 844 S 0.0 0.1 0:08.32 hobbitd_rrd 32081 hobbit 16 0 2184 664 400 S 0.0 0.0 0:00.00 hobbitd_hostdat 20945 henrik 15 0 2564 444 288 S 0.0 0.0 0:00.06 gpg-agent 27371 root 16 0 407m 17m 7860 S 0.0 1.2 0:07.24 java 12564 henrik 16 0 3688 2044 1328 S 0.0 0.1 0:00.00 bash 4352 henrik 15 0 2564 444 288 S 0.0 0.0 0:00.04 gpg-agent 10421 cupsys 25 10 4568 2032 1484 S 0.0 0.1 0:00.02 cupsd 24441 root 25 10 7984 2424 1504 S 0.0 0.2 0:00.03 apache2 24442 www-data 25 10 7776 1796 872 S 0.0 0.1 0:00.04 apache2 24443 www-data 34 10 224m 3624 1520 S 0.0 0.2 0:00.22 apache2 24455 www-data 33 10 224m 3916 1564 S 0.0 0.3 0:00.19 apache2 24540 root 25 10 2960 724 536 S 0.0 0.0 0:00.03 dirmngr 24678 root 25 10 1648 572 460 S 0.0 0.0 0:00.07 syslogd 29276 postfix 16 0 4808 1572 1272 S 0.0 0.1 0:00.00 pickup 30177 hobbit 15 0 2424 1004 552 S 0.0 0.1 0:00.01 hobbitd_alert 30326 root 15 0 150m 51m 5720 S 0.0 3.4 1:16.79 Xorg 30327 root 16 0 3660 1412 1108 S 0.0 0.1 0:00.00 kdm 30336 henrik 16 0 3312 1608 1112 S 0.0 0.1 0:00.08 startkde 30407 henrik 15 0 2564 448 288 S 0.0 0.0 0:00.00 gpg-agent 30416 henrik 15 0 4480 728 456 S 0.0 0.0 0:00.00 ssh-agent 30417 henrik 15 0 4480 724 456 S 0.0 0.0 0:00.00 ssh-agent 30420 henrik 16 0 2532 628 500 S 0.0 0.0 0:00.00 dbus-launch 30421 henrik 24 0 2056 428 340 S 0.0 0.0 0:00.00 dbus-daemon 30452 henrik 16 0 1448 140 80 S 0.0 0.0 0:00.00 start_kdeinit 30453 henrik 16 0 24320 7692 6012 S 0.0 0.5 0:00.20 kdeinit 30456 henrik 15 0 23856 3008 1736 S 0.0 0.2 0:00.06 dcopserver 30458 henrik 15 0 26016 8732 7376 S 0.0 0.6 0:00.11 klauncher 30460 henrik 15 0 30340 13m 11m S 0.0 0.9 0:00.83 kded 30466 henrik 15 0 1584 356 288 S 0.0 0.0 0:00.00 kwrapper 30468 henrik 15 0 25568 9880 7884 S 0.0 0.6 0:00.10 ksmserver 30469 henrik 15 0 28012 13m 10m S 0.0 0.9 0:02.76 kwin 30471 henrik 15 0 29840 15m 12m S 0.0 1.0 0:01.46 kdesktop 30473 henrik 15 0 32264 17m 13m S 0.0 1.1 0:03.21 kicker 30477 henrik 15 0 26460 8720 6788 S 0.0 0.6 0:00.05 kio_file 30480 henrik -51 0 21244 7724 5532 S 0.0 0.5 0:01.18 artsd 30489 henrik 15 0 25324 9536 7576 S 0.0 0.6 0:00.21 kaccess 30492 henrik 15 0 29412 14m 11m S 0.0 1.0 0:00.30 kmix 30493 henrik 15 0 15276 9448 6684 S 0.0 0.6 0:01.32 gkrellm 30498 henrik 15 0 26788 6140 4916 R 0.0 0.4 0:00.33 xmms 30501 henrik 15 0 13996 8456 4588 S 0.0 0.5 0:00.18 axmain 30508 henrik 15 0 2864 292 112 S 0.0 0.0 0:00.00 applix 30510 henrik 15 0 33268 12m 9956 S 0.0 0.8 0:00.17 knotify 30516 henrik 15 0 30436 14m 10m S 0.0 0.9 0:03.36 adept_notifier 30518 henrik 15 0 26404 11m 9324 S 0.0 0.7 0:00.22 klipper 30520 henrik 15 0 30680 14m 11m S 0.0 0.9 0:00.48 korgac 30727 henrik 16 0 3312 1604 1108 S 0.0 0.1 0:00.00 soffice 30741 henrik 15 0 221m 98m 57m S 0.0 6.5 0:22.98 soffice.bin 30813 henrik 15 0 32532 16m 12m S 0.0 1.1 0:03.87 konsole 30814 henrik 15 0 3688 2080 1368 S 0.0 0.1 0:00.02 bash 30821 henrik 15 0 1588 620 468 S 0.0 0.0 0:00.07 demotool 30822 henrik 15 0 123m 36m 19m S 0.0 2.4 0:41.66 firefox-bin 30827 henrik 16 0 4500 2688 1928 S 0.0 0.2 0:00.11 gconfd-2 30835 henrik 21 0 0 0 0 Z 0.0 0.0 0:00.00 netstat 30861 henrik 15 0 3700 2088 1372 S 0.0 0.1 0:00.06 bash 31302 henrik 15 0 3704 2096 1368 S 0.0 0.1 0:00.03 bash 31303 henrik 15 0 2252 916 744 S 0.0 0.1 0:00.00 less 31384 hobbit 21 0 2984 1372 900 S 0.0 0.1 0:00.00 sh 31386 hobbit 21 0 1848 560 476 S 0.0 0.0 0:00.00 vmstat 31402 henrik 15 0 2240 1068 764 R 0.0 0.1 0:00.01 top xymon-4.3.30/demotool/data/democonf/demohost/client_ifstat0000664000076400007640000000167011411662565024140 0ustar rpmbuildrpmbuildeth0 Link encap:Ethernet HWaddr 00:0E:A6:CE:D6:85 inet addr:172.16.10.100 Bcast:172.16.10.255 Mask:255.255.255.0 inet6 addr: fe80::20e:a6ff:fece:d685/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:15281757 errors:0 dropped:0 overruns:0 frame:0 TX packets:15372376 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:30301551 (28.8 MiB) TX bytes:3024444136 (2.8 GiB) Interrupt:209 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:1057828 errors:0 dropped:0 overruns:0 frame:0 TX packets:1057828 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:575273824 (548.6 MiB) TX bytes:575273824 (548.6 MiB) xymon-4.3.30/demotool/data/democonf/demohost/client0000664000076400007640000000001711411662565022560 0ustar rpmbuildrpmbuilddemohost:linux xymon-4.3.30/demotool/data/democonf/demohost/client_free0000664000076400007640000000034611411662565023566 0ustar rpmbuildrpmbuild total used free shared buffers cached Mem: 1555860 1501240 54620 0 45168 1205488 -/+ buffers/cache: 250584 1305276 Swap: 1004020 17684 986336 xymon-4.3.30/demotool/data/democonf/demohost/client_mount0000664000076400007640000000163411411662565024010 0ustar rpmbuildrpmbuild/dev/hda2 on / type reiserfs (rw,notail) proc on /proc type proc (rw,noexec,nosuid,nodev) /sys on /sys type sysfs (rw,noexec,nosuid,nodev) varrun on /var/run type tmpfs (rw,noexec,nosuid,nodev,mode=0755) varlock on /var/lock type tmpfs (rw,noexec,nosuid,nodev,mode=1777) procbususb on /proc/bus/usb type usbfs (rw) udev on /dev type tmpfs (rw,mode=0755) devshm on /dev/shm type tmpfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) lrm on /lib/modules/2.6.17-10-generic/volatile type tmpfs (rw) /dev/hda3 on /work type reiserfs (rw) automount(pid4646) on /home type autofs (rw,fd=4,pgrp=4646,minproto=2,maxproto=4) automount(pid4654) on /var/netdisk type autofs (rw,fd=4,pgrp=4654,minproto=2,maxproto=4) nfsd on /proc/fs/nfsd type nfsd (rw) binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) voodoo:/export/home/henrik on /home/henrik type nfs (rw,intr,rsize=8192,wsize=8192,acregmin=30,addr=172.16.10.2) xymon-4.3.30/demotool/data/democonf/demohost/client_osversion0000664000076400007640000000065211411662565024674 0ustar rpmbuildrpmbuildUbuntu 6.10 LSB Version: core-2.0-noarch:core-3.0-noarch:core-3.1-noarch:core-2.0-ia32:core-3.0-ia32:core-3.1-ia32:cxx-2.0-noarch:cxx-3.0-noarch:cxx-3.1-noarch:cxx-2.0-ia32:cxx-3.0-ia32:cxx-3.1-ia32:graphics-2.0-noarch:graphics-3.0-noarch:graphics-3.1-noarch:graphics-2.0-ia32:graphics-3.0-ia32:graphics-3.1-ia32:desktop-3.1-noarch:desktop-3.1-ia32 Distributor ID: Ubuntu Description: Ubuntu 6.10 Release: 6.10 Codename: edgy xymon-4.3.30/demotool/data/democonf/demohost/client_vmstat0000664000076400007640000000047211411662565024163 0ustar rpmbuildrpmbuildprocs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 17684 53360 45180 1234716 0 0 9 15 6 7 3 0 97 0 1 0 17684 37164 45172 1211468 0 0 1 42 396 868 9 1 89 0 xymon-4.3.30/demotool/data/democonf/demohost/client_who0000664000076400007640000000010611411662565023434 0ustar rpmbuildrpmbuildhenrik :0 Aug 7 18:43 henrik :0 Aug 7 18:43 xymon-4.3.30/demotool/data/democonf/demohost/client_netstat0000664000076400007640000000441311411662565024326 0ustar rpmbuildrpmbuildIp: 16229988 total packets received 1 with invalid addresses 0 forwarded 0 incoming packets discarded 16229987 incoming packets delivered 16336618 requests sent out Icmp: 39210 ICMP messages received 1 input ICMP message failed. ICMP input histogram: destination unreachable: 6 timeout in transit: 50 echo requests: 23329 echo replies: 15825 23356 ICMP messages sent 0 ICMP messages failed ICMP output histogram: destination unreachable: 27 echo replies: 23329 Tcp: 123073 active connections openings 112585 passive connection openings 0 failed connection attempts 1157 connection resets received 3 connections established 16124654 segments received 15187852 segments send out 2410 segments retransmited 0 bad segments received. 1651 resets sent Udp: 56634 packets received 27 packets to unknown port received. 0 packet receive errors 1105170 packets sent TcpExt: 3 packets pruned from receive queue because of socket buffer overrun 115144 TCP sockets finished time wait in fast timer 7 time wait sockets recycled by time stamp 217719 delayed acks sent 95 delayed acks further delayed because of locked socket Quick ack mode was activated 1210 times 176240 packets directly queued to recvmsg prequeue. 100519 of bytes directly received from backlog 75086678 of bytes directly received from prequeue 12606169 packet headers predicted 36912 packets header predicted and directly queued to user 530302 acknowledgments not containing data received 6377012 predicted acknowledgments 1 times recovered from packet loss due to SACK data 154 congestion windows recovered after partial ack 0 TCP data loss events 18 timeouts after SACK recovery 2 fast retransmits 26 retransmits in slow start 537 other TCP timeouts 1 times receiver scheduled too late for direct processing 149 packets collapsed in receive queue due to low socket buffer 1297 DSACKs sent for old packets 1 DSACKs sent for out of order packets 14 DSACKs received 543 connections reset due to unexpected data 1053 connections reset due to early user close 240 connections aborted due to timeout xymon-4.3.30/demotool/data/democonf/demohost/client_route0000664000076400007640000000040411411662565023776 0ustar rpmbuildrpmbuildKernel IP routeing table Destination Gateway Genmask Flags MSS Window irtt Iface 172.16.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 172.16.10.254 0.0.0.0 UG 0 0 0 eth0 xymon-4.3.30/demotool/data/democonf/pop3/0000775000076400007640000000000013534041774020421 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/pop3/listen0000664000076400007640000000001711411662565021637 0ustar rpmbuildrpmbuild127.0.0.1:3110 xymon-4.3.30/demotool/data/democonf/pop3/response0000664000076400007640000000002111411662565022172 0ustar rpmbuildrpmbuild+OK Hello there. xymon-4.3.30/demotool/data/democonf/http/0000775000076400007640000000000013534041774020517 5ustar rpmbuildrpmbuildxymon-4.3.30/demotool/data/democonf/http/listen0000664000076400007640000000001711411662565021735 0ustar rpmbuildrpmbuild127.0.0.1:3080 xymon-4.3.30/demotool/data/democonf/http/response0000664000076400007640000000102211411662565022272 0ustar rpmbuildrpmbuildHTTP/1.1 200 OK Date: Wed, 24 Aug 2005 12:26:36 GMT Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-15 mod_ssl/2.0.54 OpenSSL/0.9.7e Last-Modified: Mon, 02 May 2005 06:06:34 GMT ETag: "add-2f4-6d082e80" Accept-Ranges: bytes Content-Type: text/html; charset=ISO-8859-1 This is the Demotool webpage

Welcome to the Demotool site!!

This is a sample webpage returned by the demotool utility to show what Hobbit is like

xymon-4.3.30/demotool/data/democonf/http/delay0000664000076400007640000000000211411662565021527 0ustar rpmbuildrpmbuild4 xymon-4.3.30/demotool/README0000664000076400007640000000044611412134025015702 0ustar rpmbuildrpmbuildREADME file for Demotool ====================== Instead of running local system command to get the system information. demotool will scan /etc/hdemo/data directory that containts demo data. How to install -------------- 1. make 2. mkdir /etc/hdemo 3. cp -rp data/* /etc/hdemo 4. ./demotool xymon-4.3.30/COPYING0000664000076400007640000004325412000054272014236 0ustar rpmbuildrpmbuild GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. xymon-4.3.30/README0000664000076400007640000000573513037533761014105 0ustar rpmbuildrpmbuildREADME file for Xymon ===================== What is it ? ------------ Xymon is a system for monitoring your network servers and applications. It is heavily inspired by the Big Brother tool, but is a complete re-implementation with a lot of added functionality and performance improvements. A slightly more detailed rationale for Xymon is in the docs/about.html file. NOTE: On Nov 10 2008, Hobbit was officially renamed to "Xymon". The name "Hobbit" is trademarked, and therefore cannot be used without permission from the trademark holders. How to install -------------- Detailed installation instructions are in the docs/install.html file. Essentially, it boils down to running ./configure make make install but do have a look at the install.html file for more detailed instructions. Documentation ------------- The docs/ directory holds information about the basic installation and configuration of Xymon. All of the tools and configuration files in Xymon have man-pages that are installed automatically when installing Xymon. The xymon(7) man page provides an introduction to Xymon and has pointers to the other man-pages of the package. License ------- Xymon is copyrighted (C) 2002-2017 by Henrik Storner. Xymon is Open Source software, made available under the GNU General Public License (GPL) version 2, with the explicit exemption that linking with the OpenSSL libraries is permitted. See the file COPYING for details. Xymon is released under the GPL, and therefore available free of charge. However, if you find it useful and want to encourage further development, I do have an Amazon wishlist at http://www.amazon.co.uk/ - just search for my mail-address (henrik@hswn.dk). A contribution in the form of a book, CD or DVD is appreciated. The following files are distributed with Xymon and used by Xymon, but written by others and are NOT licensed under the GPL: * The lib/rmd160c.c, lib/rmdconst.h, lib/rmdlocl.h and lib/ripemd.h files are Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com). The license is BSD-like, but see these files for the exact license. The version in Xymon was taken from the FreeBSD CVS archive. * The lib/md5.c and lib/md5.h files are (C) L. Peter Deutsch, available under a BSD-like license from http://sourceforge.net/projects/libmd5-rfc/ * The lib/sha1.c file is originally written by by Steve Reid and placed in the public domain. The version in Xymon was taken from the "mutt" mail client sources, so some changes were done by Thomas Roessler . Support ------- There is an open mailing list for discussing Xymon, asking questions about how to use Xymon, reporting bugs etc. You can subscribe to the list by sending an e-mail to xymon-subscribe@xymon.com or on the web http://lists.xymon.com/mailman/listinfo/xymon Please note that mail sent from addresses that are not subscribed to the list need to go through a moderator approval, and therefore may not show up on the list for some time.